@bjlee2024/claude-mem 13.4.9 → 13.4.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,8 @@ description: Build and query AI-powered knowledge bases from claude-mem observat
5
5
 
6
6
  # Knowledge Agent
7
7
 
8
+ > **Worker runtime only.** Knowledge agents are Chroma-backed and require the local worker. In `client` / `server-beta` mode the corpus tools return a guidance message and do nothing — use the **`mem-search`** skill (the `search` MCP tool) for memory recall against the server instead. Check your runtime with `npx @bjlee2024/claude-mem client status`.
9
+
8
10
  Build and query AI-powered knowledge bases from claude-mem observations.
9
11
 
10
12
  ## What Are Knowledge Agents?
@@ -20,9 +20,19 @@ Use when users ask for:
20
20
 
21
21
  ## Prerequisites
22
22
 
23
- The claude-mem worker must be running. The project must have claude-mem observations recorded.
23
+ The project must have claude-mem observations recorded. The data source depends on the **runtime**:
24
24
 
25
- **Resolve the worker port** (do this once at the start and reuse `$WORKER_PORT` in every curl call below):
25
+ - **worker mode** (default, local SQLite): the claude-mem worker must be running; this skill fetches from the local worker API and the local SQLite DB.
26
+ - **client / server-beta mode** (remote server): this skill fetches the timeline from the remote server via the `timeline` CLI command. The Token Economics section (which needs local-only token columns) is omitted in this mode.
27
+
28
+ **Detect the runtime first** (reuse `$CMEM_RUNTIME` below):
29
+
30
+ ```bash
31
+ CMEM_RUNTIME="$(node -e "try{const s=require(require('path').join(require('os').homedir(),'.claude-mem','settings.json'));process.stdout.write(String(s.CLAUDE_MEM_RUNTIME||'worker'));}catch{process.stdout.write('worker');}" 2>/dev/null || echo worker)"
32
+ echo "claude-mem runtime: $CMEM_RUNTIME"
33
+ ```
34
+
35
+ **Worker mode only — resolve the worker port** (reuse `$WORKER_PORT` in every curl call below):
26
36
 
27
37
  ```bash
28
38
  WORKER_PORT="${CLAUDE_MEM_WORKER_PORT:-$(node -e "const fs=require('fs'),p=require('path'),os=require('os');const uid=(typeof process.getuid==='function'?process.getuid():77);const fallback=String(37700+(uid%100));try{const s=JSON.parse(fs.readFileSync(p.join(os.homedir(),'.claude-mem','settings.json'),'utf-8'));process.stdout.write(String(s.CLAUDE_MEM_WORKER_PORT||fallback));}catch{process.stdout.write(fallback);}" 2>/dev/null)}"
@@ -55,20 +65,30 @@ If a worktree is detected, use `$parent_project` (the basename of the parent rep
55
65
 
56
66
  ### Step 2: Fetch the Full Timeline
57
67
 
58
- Use Bash to fetch the complete timeline from the claude-mem worker API:
68
+ Fetch the complete timeline. **Pick the branch matching `$CMEM_RUNTIME`:**
69
+
70
+ **Worker mode** (`$CMEM_RUNTIME` = `worker`) — fetch from the local worker API:
59
71
 
60
72
  ```bash
61
73
  curl -s "http://localhost:${WORKER_PORT}/api/context/inject?project=PROJECT_NAME&full=true"
62
74
  ```
63
75
 
64
- This returns the entire compressed timeline -- every observation, session boundary, and summary across the project's full history. The response is pre-formatted markdown optimized for LLM consumption.
76
+ This returns the entire compressed timeline as pre-formatted markdown optimized for LLM consumption.
77
+
78
+ **Client / server-beta mode** (`$CMEM_RUNTIME` = `client` or `server-beta`) — fetch from the remote server via the CLI (handles auth, project resolution, and pagination):
79
+
80
+ ```bash
81
+ npx @bjlee2024/claude-mem timeline --project PROJECT_NAME
82
+ ```
83
+
84
+ This prints JSON `{ "observations": [ { id, kind, content, metadata: { title, subtitle, narrative, facts, concepts, files_read, files_modified }, createdAtEpoch, ... } ] }`, oldest-first, including session summaries (`kind: "summary"`). Use the `metadata.*` fields as the per-observation title/narrative/etc. and `createdAtEpoch` for timestamps. (Omit `--project` to use the current repo.)
65
85
 
66
86
  **Token estimates:** The full timeline size depends on the project's history:
67
87
  - Small project (< 1,000 observations): ~20-50K tokens
68
88
  - Medium project (1,000-10,000 observations): ~50-300K tokens
69
89
  - Large project (10,000-35,000 observations): ~300-750K tokens
70
90
 
71
- If the response is empty or returns an error, the worker may not be running or the project name may be wrong. Try `curl -s "http://localhost:${WORKER_PORT}/api/search?query=*&limit=1"` to verify the worker is healthy.
91
+ If the response is empty or errors: in worker mode the worker may not be running or the project name may be wrong (`curl -s "http://localhost:${WORKER_PORT}/api/search?query=*&limit=1"` to verify); in client/server mode run `npx @bjlee2024/claude-mem client status` to check server reachability and the resolved project.
72
92
 
73
93
  ### Step 3: Estimate Token Count
74
94
 
@@ -84,7 +104,11 @@ Wait for user confirmation before continuing if the timeline exceeds 100K tokens
84
104
 
85
105
  ### Step 4: Analyze with a Subagent
86
106
 
87
- Deploy an Agent (using the Task tool) with the full timeline and the following analysis prompt. Pass the ENTIRE timeline as context to the agent. The agent should also be instructed to query the SQLite database at `~/.claude-mem/claude-mem.db` for the Token Economics section.
107
+ Deploy an Agent (using the Task tool) with the full timeline and the following analysis prompt. Pass the ENTIRE timeline as context to the agent.
108
+
109
+ **Token Economics (section 8) is worker-mode only.** The local SQLite columns it needs (`discovery_tokens`, `source_tool`, `prompt_number`, …) do not exist server-side.
110
+ - **worker mode:** keep section 8 and instruct the agent to query `~/.claude-mem/claude-mem.db`.
111
+ - **client / server-beta mode:** OMIT section 8 entirely. Drop the SQLite paragraph from the agent prompt and replace section 8 with a single line: "_Token Economics is unavailable in server/client mode (token data is not persisted server-side)._"
88
112
 
89
113
  **Agent prompt:**
90
114
 
@@ -195,8 +219,9 @@ Tell the user:
195
219
 
196
220
  ## Error Handling
197
221
 
198
- - **Empty timeline:** "No observations found for project 'X'. Check the project name with: `curl -s \"http://localhost:${WORKER_PORT}/api/search?query=*&limit=1\"`"
199
- - **Worker not running:** "The claude-mem worker is not responding on port ${WORKER_PORT}. Start it with your usual method or check `ps aux | grep worker-service`."
222
+ - **Empty timeline (worker mode):** "No observations found for project 'X'. Check the project name with: `curl -s \"http://localhost:${WORKER_PORT}/api/search?query=*&limit=1\"`"
223
+ - **Worker not running (worker mode):** "The claude-mem worker is not responding on port ${WORKER_PORT}. Start it with your usual method or check `ps aux | grep worker-service`."
224
+ - **Empty / unreachable (client/server mode):** run `npx @bjlee2024/claude-mem client status` to verify the server URL, API key, reachability, and resolved project. An empty result usually means the wrong `--project` name or that this project has no observations on the server yet.
200
225
  - **Timeline too large:** For projects with 50,000+ observations, the timeline may exceed context limits. Suggest using date range filtering: `curl -s "http://localhost:${WORKER_PORT}/api/context/inject?project=X&full=true"` -- the current endpoint returns all observations; for extremely large projects, the user may want to analyze in time-windowed segments.
201
226
 
202
227
  ## Example
@@ -24,11 +24,18 @@ If the user wants a single sweeping report, use `timeline-report` instead. This
24
24
 
25
25
  ## Prerequisites
26
26
 
27
- - claude-mem worker running
28
27
  - Project has at least one ISO week of observations (the pipeline degenerates gracefully — even N=1 works)
29
28
  - A clean output directory the user is comfortable writing into
29
+ - **Runtime:** works in `worker` mode (local SQLite worker) and in `client` / `server-beta` mode (remote server). The data source differs in Step 2; Steps 3+ are identical.
30
30
 
31
- **Resolve the worker port** (do this once, reuse `$WORKER_PORT`):
31
+ **Detect the runtime first** (reuse `$CMEM_RUNTIME`):
32
+
33
+ ```bash
34
+ CMEM_RUNTIME="$(node -e "try{const s=require(require('path').join(require('os').homedir(),'.claude-mem','settings.json'));process.stdout.write(String(s.CLAUDE_MEM_RUNTIME||'worker'));}catch{process.stdout.write('worker');}" 2>/dev/null || echo worker)"
35
+ echo "claude-mem runtime: $CMEM_RUNTIME"
36
+ ```
37
+
38
+ **Worker mode only — resolve the worker port** (reuse `$WORKER_PORT`):
32
39
 
33
40
  ```bash
34
41
  WORKER_PORT="${CLAUDE_MEM_WORKER_PORT:-$(node -e "const fs=require('fs'),p=require('path'),os=require('os');const uid=(typeof process.getuid==='function'?process.getuid():77);const fallback=String(37700+(uid%100));try{const s=JSON.parse(fs.readFileSync(p.join(os.homedir(),'.claude-mem','settings.json'),'utf-8'));process.stdout.write(String(s.CLAUDE_MEM_WORKER_PORT||fallback));}catch{process.stdout.write(fallback);}" 2>/dev/null)}"
@@ -53,6 +60,10 @@ echo "$parent_project"
53
60
 
54
61
  ### Step 2: Fetch the Full Timeline and Save It
55
62
 
63
+ Produce `.scratch/cm-timeline.md` (a markdown timeline with `### Mon DD, YYYY` date headers and per-observation lines). **Pick the branch matching `$CMEM_RUNTIME`:**
64
+
65
+ **Worker mode** — fetch the pre-rendered markdown directly:
66
+
56
67
  ```bash
57
68
  mkdir -p .scratch
58
69
  curl -s "http://localhost:${WORKER_PORT}/api/context/inject?project=PROJECT_NAME&full=true" \
@@ -60,7 +71,33 @@ curl -s "http://localhost:${WORKER_PORT}/api/context/inject?project=PROJECT_NAME
60
71
  wc -l .scratch/cm-timeline.md
61
72
  ```
62
73
 
63
- Sanity-check: confirm the file is non-empty and has the expected structure (preamble, then date headers like `### Mon DD, YYYY`, then numeric observation lines `<id> <time> <emoji> <title>` and session boundary lines `S<n> <prompt> (Mon DD at HH:MMpm)`).
74
+ **Client / server-beta mode** fetch JSON from the server and render it into the same markdown shape so Steps 3+ work unchanged:
75
+
76
+ ```bash
77
+ mkdir -p .scratch
78
+ npx @bjlee2024/claude-mem timeline --project PROJECT_NAME > .scratch/cm-timeline.json
79
+ node -e '
80
+ const fs=require("fs");
81
+ const obs=JSON.parse(fs.readFileSync(".scratch/cm-timeline.json","utf8")).observations||[];
82
+ const EMOJI={bugfix:"🔴",feature:"🟣",refactor:"🔄",change:"✅",discovery:"🔵",decision:"⚖️",summary:"📝",observation:"🔵"};
83
+ const out=[]; let day="";
84
+ for(const o of obs){
85
+ const d=new Date(o.createdAtEpoch||0);
86
+ const hdr=d.toLocaleDateString("en-US",{month:"short",day:"2-digit",year:"numeric"});
87
+ if(hdr!==day){day=hdr; out.push("", "### "+hdr, "");}
88
+ const m=o.metadata||{};
89
+ const t=m.title||(o.content||"").split("\n")[0].slice(0,80)||o.kind;
90
+ const time=d.toLocaleTimeString("en-US",{hour:"numeric",minute:"2-digit"});
91
+ out.push(`${o.id} ${time} ${EMOJI[m.type||o.kind]||"🔵"} ${t}`);
92
+ }
93
+ fs.writeFileSync(".scratch/cm-timeline.md", out.join("\n"));
94
+ '
95
+ wc -l .scratch/cm-timeline.md
96
+ ```
97
+
98
+ Sanity-check: confirm the file is non-empty and has the expected structure (date headers like `### Mon DD, YYYY`, then observation lines `<id> <time> <emoji> <title>`). (In client/server mode session-boundary `S<n>` lines are absent — the split-by-week logic keys off the `### date` headers, so this is fine.)
99
+
100
+ If empty/unreachable in client/server mode: `npx @bjlee2024/claude-mem client status` to verify server URL, key, reachability, and resolved project.
64
101
 
65
102
  ### Step 3: Split the Timeline Into Per-ISO-Week Files
66
103