AGENTS.md
Guidance for AI coding agents working in this repository. Document only reflects what exists in code/docs.
Project Type
- Language: Go
- CLI: Cobra executed via charmbracelet/fang
- Module path:
git.secluded.site/np - Binary name:
np
Development Commands (Taskfile)
- Format:
task fmt(installs and runs gofumpt) - Lint:
task lint(golangci-lint) - Static analysis:
task staticcheck - Tests:
task test(go test -v ./...) - Vulnerabilities:
task vuln(govulncheck) - License compliance:
task reuse(REUSE) - Build:
task build(produces./np, injects version via ldflags) - Run:
task run -- <flags>(runs with ldflags) - Docs:
task docs(generates CLI docs via internal/tools/docgen) - Pack:
task pack(UPX compressesnp) - Clean:
task clean/task clean-all - Release:
task release(interactive semver release with gum/svu) - Full check:
task(default runs fmt, lint, staticcheck, test, vuln, reuse)
Single test:
go test -v -run TestName ./path/to/package
Repository Layout
main.go: wires fang.Execute(RootCmd) and sets version from build infocmd/: Cobra commands- Root and top-level:
a(archive),m(monitor/TUI stub),p(plan printout stub),r(resume),s(start) cmd/g/: goal command group;g(show stub),g s(set goal stub with -t/-d)cmd/t/: task command group;t(list stub with status filter flag),t a(add stub),t u(update stub)
- Root and top-level:
internal/:db/: Badger wrapper: options, tx helpers, key builders, path hashinggoal/: goal document + storetask/: task types + store (status index, deterministic IDs)event/: event types + store + payload builderstimeutil/: clocks and UTC helperstestutil/: temp DB and test clockstools/docgen/: CLI doc generator
docs/: additional design docs (e.g.,Potential schema.md)
CLI Commands (current state)
Commands exist and are registered, but most are stubs that print placeholder output:
np s # start session (stub)
np a # archive session (stub)
np p # print plan (stub)
np r # resume session (stub)
np m # monitor TUI (stub)
np g # goal (stub); np g s -t -d flags defined
np t # tasks (stub); -s status flag defined; t a/u files exist as stubs
Fang is used for execution/versioning; Cobra provides the command tree.
Data Layer and Storage
Implemented under internal/db, internal/goal, internal/task, internal/event.
- Database options (internal/db/options.go)
- Default path:
os.UserConfigDir()/nasin-pali/data - Retries:
MaxTxnRetries(default 5) with exponentialConflictBackoff(default 10ms) SyncWritesdefaults to true when not ReadOnly- No-op logger by default; Badger logger bridged via adapter
- Default path:
- Database helpers (internal/db/db.go)
View(ctx, fn)for read-only;Update(ctx, fn)for read-write with retries- Txn helpers:
Get,Set,Delete,GetJSON,SetJSON,Exists,Iterate,IncrementUint64 - Errors normalized:
ErrClosed,ErrReadOnly,ErrKeyNotFound,ErrTxnAborted - Iterator uses prefix scans;
IterateOptions{Prefix, Reverse, PrefetchValues} - Value log size set to 64 MiB when writable
- Keyspace builders (internal/db/keys.go)
- Meta/schema:
meta/schema_version - Per-directory:
dir/{dir_hash}/active,dir/{dir_hash}/archived/{ts_hex}/{sid} - Global indexes:
idx/active/{sid},idx/archived/{ts_hex}/{sid} - Per-session:
s/{sid}/meta,s/{sid}/goal,s/{sid}/task/{id} - Status index:
s/{sid}/idx/status/{status}/{id} - Events:
s/{sid}/meta/evt_seq(counter),s/{sid}/evt/{seq_hex}; prefixes for scans exist
- Meta/schema:
- Path handling (internal/db/path.go)
CanonicalizeDir: abs + EvalSymlinks + Clean + ToSlash; lowercase on WindowsDirHash: blake3-256 of canonical path (hex)ParentWalk: yields canonical parents up to root
- Encoding helpers (internal/db/encoding.go)
- Big-endian u64 encode/decode;
Uint64Hexfor zero-padded lower-hex
- Big-endian u64 encode/decode;
Domain Stores
- Goal (internal/goal)
- Document:
{title, description, updated_at}(UTC) - Store:
Get,Exists,Set; title is trimmed and required - Transaction-scoped
TxnStoremirrors operations
- Document:
- Task (internal/task)
- Status:
pending,in_progress,completed,failed,cancelledwith validation helpers - Task:
{id, title, description, status, created_at, updated_at, created_seq}(UTC) - ID:
GenerateID(sid, title, description)uses blake3 of normalized (trim + squash spaces) title/description + sid; first 6 hex - Store:
Create,Get,Update,UpdateStatus,Delete,List,ListByStatus,Exists - Maintains status membership keys; sorts by
created_seq, thencreated_at, thenid
- Status:
- Event (internal/event)
- Types:
goal_set,goal_updated,task_added,task_updated,task_status_changed - Record:
{seq, at, type, reason?, cmd, payload};reasonoptional;cmdrequired and trimmed - Store:
Append,List(supportsAfterandLimit),LatestSequence - Sequence stored as 8-byte big-endian counter at
s/{sid}/meta/evt_seq; keys use hex-encoded seq - Payload helpers in
payloads.gobuild stable snapshots for events
- Types:
All stores accept an optional timeutil.Clock; default is a UTC system clock. timeutil.EnsureUTC normalizes timestamps.
Testing
- Tests live under
internal/*_test.go(goal, task, event) - Helpers:
testutil.OpenDB(t)opens a temp Badger DB with cleanup;testutil.SequenceClockyields deterministic times - Run:
task testorgo test -v ./... - Example single test pattern:
go test -v -run TestName ./internal/task
Doc Generation
- Tool:
internal/tools/docgen(cobra/doc based) task docsruns two invocations: one tree underdocs/cli/, and a single-file referencedocs/llm-reference.md- Note: the Taskfile passes
-exclude mbutdocgenhas no-excludeflag; adjust if this causes failures
Output Format for LLMs
- Status icons: ☐ pending, ⟳ in progress, ☑ completed, ☒ failed, ⊗ cancelled (only show failed/cancelled in legend when present)
- Commands that change state should print the full plan immediately (current CLI commands are stubs)
Conventions
- Formatting: gofumpt (not
go fmt) - Errors and validation follow idiomatic Go patterns visible in stores
- All source files include SPDX headers; source is AGPL-3.0-or-later; docs/config are CC0-1.0
Gotchas
task docsmay fail due to-excludeflag unsupported by docgendb.OptionssetsSyncWrites=trueby default when not read-only (durability over throughput)- Event sequence counter is raw 8-byte big-endian; do not store decimal strings
- Windows: directory canonicalization lowercases paths; hashes derive from canonicalized form
Implementation Status
- CLI commands exist but are stubs that print placeholders
- Data layer (db, goal, task, event) is implemented with tests; session orchestration and wiring from CLI to stores is not yet implemented
docs/Potential schema.mdcaptures intended end-state for sessions, indexes, and events; use as design context, not as a guarantee