Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,22 @@ OnlyOffice → `bin/onlyoffice/import-contact.go`; reading contacts → `bin/con
Never `contacts/…`, never `brainwrite.go` (that is `bin/brain/import-contact.go`).
Same rule for `var/` and `etc/` subdirs: `var/{subject}/…`, `etc/{subject}/…`.

**Standing rules:**
- **Go only, no Python** — new tooling is Go (shebang mains); Python never
returns to the pipeline.
- **Libs named by domain** — `internal/{domain}` / `pkg/{domain}` mirror their
`bin/{subject}`; files inside are concrete artifacts (`leaf.go`, `yaml.go`).
No output-type namespaces (`mdleaves`-style) — no `mdroot`/`mdcontent` creep.
- **docs/ = truth only** — what works or what is open; plans/proofs go to
Gitea issues, then get deleted here.
- **Non-goals (standing):** no behavior change to graph/search semantics;
no rework of the pluggable reasoner / CGO toolchain (D18/D21).

bin/ self-describing tools (singular, `{subject}/{verb}-{object}.go`)
bin/brain/ import-contact.go import-git.go search.go serve.go index.go add.go get.go stats.go eval.go watch.go
bin/contact/ list.go (read/normalize csv/vcf/mab → stdout/file)
bin/onlyoffice/ import-contact.go (reconcile contacts into OO CRM)
bin/chats/ sync.go import.go facts.go apply.go; libs in internal/chats
bin/chat/ sync.go import.go facts.go apply.go refresh-session.go; lib: internal/chat
bin/mail/ sync.go import.go convert-mbox.go ocr.go (lib: internal/mailsync)
bin/markdown/ split-leaf.go (H2 leaf split; lib: internal/markdown)
bin/jsonl/ stats.go (DuckDB quantiles / JSONL count; gcc CGO, not Zig)
Expand All @@ -63,7 +74,7 @@ bin/reasoner/ bench.go (D18 CPU OpenAI tool-call bench)
bin/facts/ extract.go audit.go audit-db.go prove-crm.go
bin/shell/ complete.go (flaggy completions dump, D23)
pkg/ public reusable Go (cli flaggy D23; repo; contact; duckdb; httpapi) — no 2dph deps
internal/ private 2dph Go (brain, chats, facts D16, gitlog, websearch, reasoner, mailsync, mailconv, corpuswatch, markdown)
internal/ private 2dph Go by domain (brain, chat, facts D16, gitlog, websearch, reasoner, mailsync, mailconv, corpuswatch, markdown)
bin/cgo/ zig zcc zc++ (CGO via zig cc, not gcc)
bin/stack/ start start-assistant stop status (compose + PicoClaw agent)
bin/docker-entrypoint container entrypoint (api: serve|search|watch|index|add|mail-sync)
Expand Down Expand Up @@ -149,7 +160,9 @@ duckdb-go (`pkg/duckdb`, `skills/duckdb/SKILL.md`), not Ladybug.
4. **Curasoft, edelweiss — no files, no mentions.** Remove all traces if found.
5. **Check git history before push.** If any commit contains leaks, rewrite
history (rebase + force push) AND delete affected GitHub releases/tags.
6. **`docs/chat-import-plan.md`** — reference Gitea issue, never embed secrets.
6. **Plans live in Gitea issues, not docs/.** docs/ holds only what is true
and current (design, runbook, roadmap). Historical plans/proofs are
archived as comments on their Gitea issue, then deleted from the repo.

## Communication

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ domain area it acts on:
| `bin/mail` | `sync.go` / `import.go` / `ocr.go` | mail ETL (Gmail/OO/M365) |
| `bin/web` | `search.go` | SearXNG second source |
| `bin/git` | `import.go` | commit history leafs |
| `bin/chats` | `sync.go` / `import.go` / `apply.go` | conversations |
| `bin/chat` | `sync.go` / `import.go` / `apply.go` | conversations |
| `bin/stack` | `start` / `status` / `stop` | compose dispatcher |

Go methods are executable (`go run` shebang); a few are thin bash launchers
Expand Down
29 changes: 0 additions & 29 deletions bin/chat

This file was deleted.

8 changes: 4 additions & 4 deletions bin/chats/apply.go → bin/chat/apply.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
//usr/bin/env go run -tags=chats_apply "$0" "$@"; exit
//go:build chats_apply
//
// bin/chats/apply.go - push extracted chat facts to OnlyOffice CRM.
// bin/chat/apply.go - push extracted chat facts to OnlyOffice CRM.
//
// ./bin/chats/apply.go [--dry-run]
// ./bin/chat/apply.go [--dry-run]
//
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
package main

import (
"os"

"github.com/eSlider/2dph/internal/chats"
"github.com/eSlider/2dph/internal/chat"
)

func main() {
os.Exit(chats.RunApply(os.Args[1:]))
os.Exit(chat.RunApply(os.Args[1:]))
}
4 changes: 2 additions & 2 deletions bin/chats/doc.go → bin/chat/doc.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Commands in this directory are shebang mains (sync.go, import.go, facts.go,
// apply.go), each behind an exclusive build tag so `go build ./bin/chats`
// does not see two mains. Shared code lives in internal/chats.
// apply.go), each behind an exclusive build tag so `go build ./bin/chat`
// does not see two mains. Shared code lives in internal/chat.
package main
8 changes: 4 additions & 4 deletions bin/chats/facts.go → bin/chat/facts.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//usr/bin/env go run -tags=chats_facts "$0" "$@"; exit
//go:build chats_facts
//
// bin/chats/facts.go - extract phone/email/linkedin facts from JSONL.
// bin/chat/facts.go - extract phone/email/linkedin facts from JSONL.
//
// ./bin/chats/facts.go
// ./bin/chat/facts.go
//
// Writes var/chats/facts/. Does not index the brain.
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
Expand All @@ -12,9 +12,9 @@ package main
import (
"os"

"github.com/eSlider/2dph/internal/chats"
"github.com/eSlider/2dph/internal/chat"
)

func main() {
os.Exit(chats.RunFacts(os.Args[1:]))
os.Exit(chat.RunFacts(os.Args[1:]))
}
8 changes: 4 additions & 4 deletions bin/chats/import.go → bin/chat/import.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
//usr/bin/env go run -tags=chats_import "$0" "$@"; exit
//go:build chats_import
//
// bin/chats/import.go - JSONL → markdown under var/chats/md/.
// bin/chat/import.go - JSONL → markdown under var/chats/md/.
//
// ./bin/chats/import.go
// ./bin/chat/import.go
//
// Conversion only. Brain ingest is bin/brain/index.go, not this command.
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
Expand All @@ -12,9 +12,9 @@ package main
import (
"os"

"github.com/eSlider/2dph/internal/chats"
"github.com/eSlider/2dph/internal/chat"
)

func main() {
os.Exit(chats.RunImport(os.Args[1:]))
os.Exit(chat.RunImport(os.Args[1:]))
}
48 changes: 48 additions & 0 deletions bin/chat/refresh-session.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//usr/bin/env go run "$0" "$@"; exit
//
// bin/chat/refresh-session.go - refresh LinkedIn MCP session from webtop CDP.
//
// ./bin/chat/refresh-session.go [--cdp URL] [--root DIR]
// [--container work-webtop] [--profile thorium-profile]
//
// Reads live cookies out of the running Thorium browser via CDP
// (Network.getAllCookies), copies the browser profile, rewrites cookies.json +
// source-state.json. Run before every linkedin sync.
package main

import (
"fmt"
"os"

"github.com/eSlider/2dph/internal/chat"
cliparse "github.com/eSlider/2dph/pkg/cli"
)

func main() {
os.Exit(run(os.Args[1:]))
}

func run(args []string) int {
var (
cdp string
root string
container string
profile string
)
p := cliparse.New("chat-refresh-session")
p.Description = "refresh LinkedIn session from webtop CDP (cookies.json + source-state.json)"
p.String(&cdp, "", "cdp", "CDP endpoint (default http://127.0.0.1:9222)")
p.String(&root, "", "root", "portable profile root (default /var/tmp/liprofile)")
p.String(&container, "", "container", "webtop container (default work-webtop)")
p.String(&profile, "", "profile", "browser profile dir (default thorium-profile)")
if err := cliparse.Parse(p, args); err != nil {
return cliparse.Fail(err)
}
if err := chat.RefreshLinkedInSession(chat.RefreshLinkedInSessionOpts{
CDP: cdp, Root: root, Container: container, Profile: profile,
}); err != nil {
fmt.Fprintf(os.Stderr, "chat-refresh-session: %v\n", err)
return 1
}
return 0
}
16 changes: 8 additions & 8 deletions bin/chats/sync.go → bin/chat/sync.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
//usr/bin/env go run -tags=chats_sync "$0" "$@"; exit
//go:build chats_sync
//
// bin/chats/sync.go - download chat messages to var/chats/<platform>/.
// bin/chat/sync.go - download chat messages to var/chats/<platform>/.
//
// ./bin/chats/sync.go telegram [--limit N] [--phone PHONE]
// ./bin/chats/sync.go linkedin [--limit N] [--refresh]
// ./bin/chat/sync.go telegram [--limit N] [--phone PHONE]
// ./bin/chat/sync.go linkedin [--limit N] [--refresh]
//
// NOTE: never run `gofmt -w` on this file — it breaks the shebang.
package main
Expand All @@ -13,26 +13,26 @@ import (
"fmt"
"os"

"github.com/eSlider/2dph/internal/chats"
"github.com/eSlider/2dph/internal/chat"
)

func main() {
if len(os.Args) < 2 {
fmt.Fprintln(os.Stderr, `usage: bin/chats/sync.go telegram|linkedin [flags]`)
fmt.Fprintln(os.Stderr, `usage: bin/chat/sync.go telegram|linkedin [flags]`)
os.Exit(2)
}
platform := os.Args[1]
args := os.Args[2:]
switch platform {
case "telegram":
os.Exit(chats.RunSyncTelegram(args))
os.Exit(chat.RunSyncTelegram(args))
case "linkedin":
os.Exit(chats.RunSyncLinkedIn(args))
os.Exit(chat.RunSyncLinkedIn(args))
case "whatsapp":
fmt.Fprintln(os.Stderr, "chats: WhatsApp sync is out of v1")
os.Exit(1)
case "help", "-h", "--help":
fmt.Fprintln(os.Stderr, `usage: bin/chats/sync.go telegram|linkedin [flags]
fmt.Fprintln(os.Stderr, `usage: bin/chat/sync.go telegram|linkedin [flags]
WhatsApp sync is out of v1.`)
return
default:
Expand Down
Loading
Loading