@@ -6,6 +6,83 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66
77Forest is a graph-native knowledge base CLI that captures unstructured ideas and automatically links them using a hybrid scoring algorithm combining semantic embeddings and lexical similarity. All data is stored in a single SQLite database (` forest.db ` ).
88
9+ ## Agent-First TLDR Standard
10+
11+ Forest implements the ** TLDR Standard (v0.1)** for agent ingestion - a minimal, parseable command metadata format designed for AI agents.
12+
13+ ### Quick Start for Agents
14+
15+ ``` bash
16+ # Discover all commands
17+ forest --tldr
18+
19+ # Get detailed command metadata (ASCII format)
20+ forest capture --tldr
21+ forest edges propose --tldr
22+
23+ # Get JSON format for programmatic parsing
24+ forest --tldr=json
25+ forest search --tldr=json
26+ ```
27+
28+ ### TLDR Format
29+
30+ ** ASCII mode** (default): Single-pass parseable KEY: value pairs
31+ ```
32+ CMD: capture
33+ PURPOSE: Create a new note and optionally auto-link into the graph
34+ INPUTS: ARGS(title,body,tags),STDIN,FILE
35+ OUTPUTS: node record,edges summary,optional preview
36+ SIDE_EFFECTS: writes to SQLite DB,computes embeddings,creates/updates edges
37+ FLAGS: --title=STR|note title;--body=STR|note body;--stdin=BOOL=false|read entire stdin as body
38+ EXAMPLES: forest capture --stdin < note.md|forest capture --title "Idea" --body "Text"
39+ RELATED: explore,edges.propose,node.read
40+ ```
41+
42+ ** JSON mode** (` --tldr=json ` ): Same data, structured format
43+ ``` json
44+ {
45+ "CMD" : " capture" ,
46+ "PURPOSE" : " Create a new note and optionally auto-link into the graph" ,
47+ "INPUTS" : [" ARGS(title,body,tags)" , " STDIN" , " FILE" ],
48+ "FLAGS" : [{"name" : " title" , "type" : " STR" , "default" : null , "desc" : " note title" }],
49+ ...
50+ }
51+ ```
52+
53+ ### Implementation Details
54+
55+ - ** Location** : ` src/cli/tldr.ts ` - Central registry of all command metadata
56+ - ** Discovery** : Every command accepts ` --tldr ` or ` --tldr=json `
57+ - ** Global index** : ` forest --tldr ` lists all available commands
58+ - ** Per-command** : ` forest <command> --tldr ` shows detailed metadata
59+
60+ ### Benefits for Agents
61+
62+ 1 . ** Zero-shot discovery** : Learn entire CLI surface in one round-trip
63+ 2 . ** Minimal tokens** : Compact format optimized for context windows
64+ 3 . ** Predictable parsing** : Fixed schema, no free-form text
65+ 4 . ** Self-documenting** : FLAGS includes types, defaults, and descriptions
66+ 5 . ** Cross-reference** : RELATED field enables command discovery
67+
68+ ### TLDR Generators & Full Spec
69+
70+ Forest implements TLDR v0.1 as a reference. Full spec and universal documentation generators available at:
71+
72+ ** ` tldr-agent-spec/ ` ** - Standalone repository with:
73+ - Complete specification (` docs/spec-v0.1.md ` )
74+ - Three universal generators (bash, node, python)
75+ - Validation tools
76+ - Forest reference implementation
77+
78+ ** Quick validation** :
79+ ``` bash
80+ cd tldr-agent-spec
81+ ./scripts/tldr-doc-gen.sh forest --validate
82+ ```
83+
84+ ** For full TLDR documentation** : See ` tldr-agent-spec/README.md `
85+
986## Development Commands
1087
1188``` bash
@@ -19,6 +96,12 @@ npm run dev -- capture --stdin < test.txt
1996npm run dev -- health
2097npm run dev -- stats
2198
99+ # Running the API server
100+ bun run dev:server # Start on default port 3000 (dual-stack IPv4/IPv6)
101+ FOREST_PORT=8080 bun run dev:server # Custom port
102+ FOREST_HOST=0.0.0.0 bun run dev:server # IPv4 only
103+ forest serve --port 3000 --host :: # Via CLI (requires Bun)
104+
22105# After building
23106forest < command> # Uses the compiled dist/index.js
24107```
@@ -50,13 +133,14 @@ forest tags rename [old] [new] # Rename a tag
50133forest tags stats # Tag statistics
51134forest export graphviz # Export as DOT
52135forest export json # Export as JSON
136+ forest search ["query"] # Semantic search using embeddings
53137forest stats # Graph statistics and health
54138forest health # System health check
55139forest admin:recompute-embeddings # Recompute embeddings
56140```
57141
58142Commands are modular:
59- - ** Individual commands** : ` src/cli/commands/{capture,explore,stats,health,admin-recompute-embeddings}.ts `
143+ - ** Individual commands** : ` src/cli/commands/{capture,explore,search, stats,health,admin-recompute-embeddings}.ts `
60144- ** Subcommand groups** : ` node ` , ` edges ` , ` tags ` , ` export ` use ` register*Commands() ` pattern
61145
62146Each command file exports a factory function:
@@ -71,6 +155,67 @@ export function registerNodeCommands(cli: ClercInstance, clerc: ClercModule) {
71155}
72156```
73157
158+ ### 3-Layer Architecture: CLI/API Feature Parity
159+
160+ Forest uses a ** 3-layer architecture** to maintain feature parity between the CLI and REST API:
161+
162+ ```
163+ ┌─────────────────────────────────────────────────────┐
164+ │ CLI Layer (src/cli/commands/) │
165+ │ • Parses command-line arguments │
166+ │ • Formats human-readable output │
167+ │ • Handles --json flag for machine output │
168+ │ └──> Calls Core Layer │
169+ └─────────────────────────────────────────────────────┘
170+ ↓
171+ ┌─────────────────────────────────────────────────────┐
172+ │ Core Layer (src/core/) ⭐ SINGLE SOURCE OF TRUTH │
173+ │ • Pure business logic functions │
174+ │ • No I/O dependencies (no HTTP, no CLI formatting) │
175+ │ • Returns typed data structures │
176+ │ • Examples: semanticSearchCore(), createNodeCore() │
177+ └─────────────────────────────────────────────────────┘
178+ ↑
179+ ┌─────────────────────────────────────────────────────┐
180+ │ API Layer (src/server/routes/) │
181+ │ • Handles HTTP requests and validation │
182+ │ • Parses query params and request bodies │
183+ │ • Formats JSON responses with envelope pattern │
184+ │ └──> Calls Core Layer │
185+ └─────────────────────────────────────────────────────┘
186+ ```
187+
188+ ** Key Principle** : Both CLI and API call the ** same core functions** . This ensures:
189+ 1 . Features are available in both interfaces
190+ 2 . Business logic is never duplicated
191+ 3 . Bug fixes apply universally
192+ 4 . Testing can focus on core logic
193+
194+ ** Example - Semantic Search** :
195+ - ✅ ` src/core/search.ts ` - ` semanticSearchCore(query, options) ` - business logic
196+ - ✅ ` src/cli/commands/search.ts ` - Calls ` semanticSearchCore() ` , formats table output
197+ - ✅ ` src/server/routes/search.ts ` - Calls ` semanticSearchCore() ` , returns JSON
198+
199+ ** Example - Node Capture** :
200+ - ✅ ` src/core/nodes.ts ` - ` createNodeCore(data) ` - business logic
201+ - ⚠️ ` src/cli/commands/capture.ts ` - Currently reimplements logic (needs refactoring)
202+ - ✅ ` src/server/routes/nodes.ts ` - Calls ` createNodeCore() `
203+
204+ ** Adding a New Feature - Checklist** :
205+ When implementing a new feature that should be available in both CLI and API:
206+
207+ 1 . ✅ ** Core logic first** : Implement in ` src/core/*.ts ` as a pure function
208+ 2 . ✅ ** API route** : Create/update route in ` src/server/routes/*.ts ` that calls core function
209+ 3 . ✅ ** CLI command** : Create/update command in ` src/cli/commands/*.ts ` that calls core function
210+ 4 . ✅ ** Register routes** : Add to ` src/server/index.ts ` and ` src/cli/index.ts `
211+ 5 . ✅ ** Test both interfaces** : Verify identical behavior in CLI and API
212+ 6 . ✅ ** Update docs** : Add command to CLAUDE.md command list
213+
214+ ** Anti-Pattern to Avoid** :
215+ ❌ Implementing business logic directly in CLI commands or API routes
216+ ❌ Copy-pasting logic between CLI and API
217+ ❌ Having different behavior/validation in CLI vs API
218+
74219### Database Layer (src/lib/db.ts)
75220
76221Uses ** sql.js** (SQLite compiled to WASM) with in-memory database persisted to disk on mutation.
@@ -156,6 +301,22 @@ FOREST_EMBED_PROVIDER=local forest capture --stdin < test.txt # Local embedding
156301FOREST_EMBED_PROVIDER=openai OPENAI_API_KEY=... forest capture --stdin < test.txt
157302```
158303
304+ ** Server configuration via environment variables:**
305+ - ` FOREST_PORT ` - Server port (default: 3000)
306+ - ` FOREST_HOST ` - Server hostname (default: ` :: ` for dual-stack IPv4/IPv6)
307+ - ` :: ` - Dual-stack mode, listens on both IPv4 and IPv6
308+ - ` 0.0.0.0 ` - IPv4 only
309+ - ` localhost ` - Localhost only (may prefer IPv4 or IPv6 depending on OS)
310+ - ` FOREST_DB_PATH ` - Database file path (default: ` forest.db ` in cwd)
311+ - ` FOREST_EMBED_PROVIDER ` - Embedding provider (default: ` local ` )
312+
313+ ** Network connectivity:**
314+ The server defaults to dual-stack mode (` :: ` ) which accepts connections on both:
315+ - IPv4: ` http://localhost:3000 ` , ` http://127.0.0.1:3000 `
316+ - IPv6: ` http://[::1]:3000 `
317+
318+ This prevents connection delays when clients (like Bun's fetch) try IPv6 first.
319+
159320## Database Schema
160321
161322``` sql
0 commit comments