wicked-brain 0.4.8 → 0.4.10

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-brain",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "type": "module",
5
5
  "description": "Digital brain as skills for AI coding CLIs — no vector DB, no embeddings, no infrastructure",
6
6
  "keywords": [
@@ -96,6 +96,7 @@ const actions = {
96
96
  backlinks: (p) => ({ links: db.backlinks(p.id) }),
97
97
  forward_links: (p) => ({ links: db.forwardLinks(p.id) }),
98
98
  stats: () => db.stats(),
99
+ memory_stats: () => db.memoryStats(),
99
100
  candidates: (p) => ({ candidates: db.candidates(p) }),
100
101
  symbols: async (p) => {
101
102
  // Prefer LSP workspace symbols (structured, language-aware)
@@ -421,7 +421,51 @@ export class SqliteSearch {
421
421
  // in-memory or inaccessible
422
422
  }
423
423
 
424
- return { total, chunks, wiki, memory, last_indexed, db_size };
424
+ return {
425
+ total,
426
+ chunks,
427
+ wiki,
428
+ memory,
429
+ memory_breakdown: this.memoryStats(),
430
+ last_indexed,
431
+ db_size,
432
+ };
433
+ }
434
+
435
+ /**
436
+ * Breakdown of memory documents by type, tier, and age.
437
+ * Parses frontmatter from `memory/%` rows. Missing fields count as "unknown".
438
+ * Age buckets: <1d, 1-7d, 7-30d, 30-90d, >90d.
439
+ */
440
+ memoryStats() {
441
+ const rows = this.#db.prepare(`
442
+ SELECT frontmatter, indexed_at FROM documents WHERE path LIKE 'memory/%'
443
+ `).all();
444
+
445
+ const by_type = {};
446
+ const by_tier = {};
447
+ const by_age = { "<1d": 0, "1-7d": 0, "7-30d": 0, "30-90d": 0, ">90d": 0 };
448
+ const now = Date.now();
449
+ const DAY = 86400000;
450
+
451
+ for (const row of rows) {
452
+ const fm = row.frontmatter || "";
453
+ const typeMatch = fm.match(/^type:\s*(\S+)/m);
454
+ const tierMatch = fm.match(/^tier:\s*(\S+)/m);
455
+ const type = typeMatch ? typeMatch[1].replace(/["']/g, "") : "unknown";
456
+ const tier = tierMatch ? tierMatch[1].replace(/["']/g, "") : "unknown";
457
+ by_type[type] = (by_type[type] ?? 0) + 1;
458
+ by_tier[tier] = (by_tier[tier] ?? 0) + 1;
459
+
460
+ const age = now - (row.indexed_at ?? now);
461
+ if (age < DAY) by_age["<1d"]++;
462
+ else if (age < 7 * DAY) by_age["1-7d"]++;
463
+ else if (age < 30 * DAY) by_age["7-30d"]++;
464
+ else if (age < 90 * DAY) by_age["30-90d"]++;
465
+ else by_age[">90d"]++;
466
+ }
467
+
468
+ return { total: rows.length, by_type, by_tier, by_age };
425
469
  }
426
470
 
427
471
  health() {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wicked-brain-server",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "type": "module",
5
5
  "description": "SQLite FTS5 search server for wicked-brain digital knowledge bases",
6
6
  "keywords": [
@@ -9,8 +9,15 @@ Factory skill for wicked-brain agents. Lists available agents and dispatches the
9
9
 
10
10
  ## Config
11
11
 
12
- Read `_meta/config.json` for brain path and server port.
13
- If it doesn't exist, trigger wicked-brain:init.
12
+ Resolve the brain config via the shared resolution in
13
+ wicked-brain:init § "Resolving the brain config". In short: try
14
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
15
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
16
+ wicked-brain:init. Read the resolved file for brain path and server port.
17
+
18
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
19
+ against the current working directory and brain files will end up in the
20
+ project root.
14
21
 
15
22
  ## Parameters
16
23
 
@@ -25,8 +25,15 @@ For the brain path default:
25
25
 
26
26
  ## Config
27
27
 
28
- Read `_meta/config.json` for brain path and server port.
29
- If it doesn't exist, trigger wicked-brain:init.
28
+ Resolve the brain config via the shared resolution in
29
+ wicked-brain:init § "Resolving the brain config". In short: try
30
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
31
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
32
+ wicked-brain:init. Read the resolved file for brain path and server port.
33
+
34
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
35
+ against the current working directory and brain files will end up in the
36
+ project root.
30
37
 
31
38
  ## Process
32
39
 
@@ -9,8 +9,15 @@ Writes a contextual `## wicked-brain` section into the active CLI/IDE's agent co
9
9
 
10
10
  ## Config
11
11
 
12
- Read `_meta/config.json` for brain path and server port.
13
- If it doesn't exist, trigger wicked-brain:init.
12
+ Resolve the brain config via the shared resolution in
13
+ wicked-brain:init § "Resolving the brain config". In short: try
14
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
15
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
16
+ wicked-brain:init. Read the resolved file for brain path and server port.
17
+
18
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
19
+ against the current working directory and brain files will end up in the
20
+ project root.
14
21
 
15
22
  ## Process
16
23
 
@@ -24,8 +24,15 @@ For the brain path default:
24
24
 
25
25
  ## Config
26
26
 
27
- Read `_meta/config.json` for brain path and server port.
28
- If it doesn't exist, trigger wicked-brain:init.
27
+ Resolve the brain config via the shared resolution in
28
+ wicked-brain:init § "Resolving the brain config". In short: try
29
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
30
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
31
+ wicked-brain:init. Read the resolved file for brain path and server port.
32
+
33
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
34
+ against the current working directory and brain files will end up in the
35
+ project root.
29
36
 
30
37
  ## Parameters
31
38
 
@@ -24,8 +24,15 @@ For the brain path default:
24
24
 
25
25
  ## Config
26
26
 
27
- Read `_meta/config.json` for brain path and server port.
28
- If it doesn't exist, trigger wicked-brain:init.
27
+ Resolve the brain config via the shared resolution in
28
+ wicked-brain:init § "Resolving the brain config". In short: try
29
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
30
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
31
+ wicked-brain:init. Read the resolved file for brain path and server port.
32
+
33
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
34
+ against the current working directory and brain files will end up in the
35
+ project root.
29
36
 
30
37
  ## Process
31
38
 
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: wicked-brain:forget
3
+ description: |
4
+ Archive or delete a memory (or any indexed document) by id or path.
5
+ Removes the document from the FTS index and renames the file with an
6
+ `.archived-{timestamp}` suffix so the data is recoverable.
7
+
8
+ Use when: "forget this memory", "archive this", "drop this decision",
9
+ "remove from brain", "brain forget".
10
+ ---
11
+
12
+ # wicked-brain:forget
13
+
14
+ Archive or hard-delete a memory by id or path. Wraps the server `remove` action
15
+ and the archive-rename convention used by wicked-brain:agent dispatch consolidate.
16
+
17
+ ## Cross-Platform Notes
18
+
19
+ - Uses `curl` for server API calls (Windows 10+, macOS, Linux)
20
+ - Uses agent-native Read/Bash tools for file ops — no Unix-only shell features
21
+ - Paths always use forward slashes
22
+
23
+ ## Config
24
+
25
+ Resolve the brain config via the shared resolution in
26
+ wicked-brain:init § "Resolving the brain config". In short: try
27
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
28
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
29
+ wicked-brain:init. Read the resolved file for brain path and server port.
30
+
31
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
32
+ against the current working directory and brain files will end up in the
33
+ project root.
34
+
35
+ ## Parameters
36
+
37
+ - **id** (required if `path` not given): document id as returned by search
38
+ - **path** (required if `id` not given): path relative to the brain root (e.g. `memory/jwt-decision.md`)
39
+ - **mode** (optional, default `archive`): `archive` (rename file + remove from index, recoverable) or `delete` (rename + remove + final deletion is still left to the user — this skill never unlinks files)
40
+ - **reason** (optional): short string recorded in the log for auditability
41
+
42
+ This skill never hard-deletes a file. `delete` mode still renames with
43
+ `.archived-{timestamp}` — actual `rm` is a human decision.
44
+
45
+ ## Process
46
+
47
+ ### Step 1: Resolve id and path
48
+
49
+ If only `id` is given, find the path by calling search or reading the id (ids
50
+ are of the form `{path}` or `{path}::{fragment}` in this brain). If only `path`
51
+ is given, the id is normally the same string for top-level documents.
52
+
53
+ ### Step 2: Confirm the document exists
54
+
55
+ Read the file at `{brain_path}/{path}` to verify it is present and (if it is a
56
+ memory) inspect its frontmatter so the log entry can record type/tier.
57
+
58
+ ### Step 3: Remove from index
59
+
60
+ ```bash
61
+ curl -s -X POST http://localhost:{port}/api \
62
+ -H "Content-Type: application/json" \
63
+ -d '{"action":"remove","params":{"id":"{id}"}}'
64
+ ```
65
+
66
+ ### Step 4: Archive the file
67
+
68
+ Rename the file in-place with an `.archived-{unix-ms}` suffix.
69
+
70
+ macOS / Linux:
71
+ ```bash
72
+ mv "{brain_path}/{path}" "{brain_path}/{path}.archived-$(date +%s)"
73
+ ```
74
+
75
+ Windows (PowerShell):
76
+ ```powershell
77
+ Rename-Item "{brain_path}/{path}" "{path}.archived-$([DateTimeOffset]::UtcNow.ToUnixTimeSeconds())"
78
+ ```
79
+
80
+ Prefer the agent-native Bash tool on the current platform; both forms produce a
81
+ recoverable archive marker.
82
+
83
+ ### Step 5: Log the forget event
84
+
85
+ Append to `{brain_path}/_meta/log.jsonl`:
86
+
87
+ ```json
88
+ {"ts":"{ISO}","op":"memory_forget","path":"{path}","id":"{id}","mode":"{mode}","reason":"{reason}","author":"agent:forget"}
89
+ ```
90
+
91
+ ### Step 6: Report
92
+
93
+ Report: path, id, previous frontmatter type/tier (if memory), archive filename,
94
+ and whether index removal succeeded. Always surface the archive path so the
95
+ user can restore it by renaming back.
96
+
97
+ ## Recovery
98
+
99
+ To restore an archived memory, rename the `.archived-{ts}` file back to its
100
+ original name. The file watcher will pick it up and re-index automatically.
@@ -25,8 +25,15 @@ For the brain path default:
25
25
 
26
26
  ## Config
27
27
 
28
- Read `{brain_path}/_meta/config.json` for brain path and server port.
29
- If it doesn't exist, trigger wicked-brain:init.
28
+ Resolve the brain config via the shared resolution in
29
+ wicked-brain:init § "Resolving the brain config". In short: try
30
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
31
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
32
+ wicked-brain:init. Read the resolved file for brain path and server port.
33
+
34
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
35
+ against the current working directory and brain files will end up in the
36
+ project root.
30
37
 
31
38
  ## Parameters
32
39
 
@@ -45,7 +52,8 @@ curl -s -f -X POST http://localhost:{port}/api \
45
52
  ```
46
53
 
47
54
  If this fails (connection refused or non-2xx), invoke `wicked-brain:server` to start it
48
- before continuing. Re-read `_meta/config.json` after the server starts to get the
55
+ before continuing. Re-read `{brain_path}/_meta/config.json` (the resolved
56
+ config from the Config section above) after the server starts to get the
49
57
  actual port it bound to.
50
58
 
51
59
  ### Step 1: Assess scope
@@ -400,7 +408,7 @@ Archived files are invisible to the file watcher, so the server won't clean them
400
408
 
401
409
  ### Step 5: Record source path
402
410
 
403
- After ingesting a directory, write the absolute source path to `_meta/config.json`
411
+ After ingesting a directory, write the absolute source path to the resolved `{brain_path}/_meta/config.json`
404
412
  so the brain server can use it as the LSP workspace root (enabling symbol lookup,
405
413
  go-to-definition, and diagnostics for the ingested project):
406
414
 
@@ -47,6 +47,30 @@ For the brain path default:
47
47
  - macOS/Linux: `~/.wicked-brain/projects/{project_name}`
48
48
  - Windows: `%USERPROFILE%\.wicked-brain\projects\{project_name}`
49
49
 
50
+ ## Resolving the brain config
51
+
52
+ **This section is the canonical resolution logic. Other skills point here —
53
+ keep it authoritative.** Never read a bare relative `_meta/config.json`: the
54
+ model will resolve it against the current working directory and brain files
55
+ will land in the project root.
56
+
57
+ To locate the brain config for the current session:
58
+
59
+ 1. Compute `{cwd_basename}` — the basename of the current working directory,
60
+ lowercased, with non-alphanumerics replaced by hyphens.
61
+ 2. Try `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first
62
+ (Windows: `%USERPROFILE%\.wicked-brain\projects\{cwd_basename}\_meta\config.json`).
63
+ 3. If that file doesn't exist, fall back to the legacy flat path
64
+ `~/.wicked-brain/_meta/config.json` (Windows:
65
+ `%USERPROFILE%\.wicked-brain\_meta\config.json`).
66
+ 4. If neither exists, trigger `wicked-brain:init`.
67
+ 5. Read the resolved file. It contains `brain_path` and `server_port` (and
68
+ optionally `source_path`). All subsequent operations use these values —
69
+ never hardcode the port or path.
70
+
71
+ Any skill that needs to read, write, or reference `_meta/config.json` MUST use
72
+ this resolution. Never compute `_meta/config.json` against the project's `cwd`.
73
+
50
74
  ## When to use
51
75
 
52
76
  - User explicitly asks to create/initialize a brain
@@ -25,8 +25,15 @@ For the brain path default:
25
25
 
26
26
  ## Config
27
27
 
28
- Read `_meta/config.json` for brain path and server port.
29
- If it doesn't exist, trigger wicked-brain:init.
28
+ Resolve the brain config via the shared resolution in
29
+ wicked-brain:init § "Resolving the brain config". In short: try
30
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
31
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
32
+ wicked-brain:init. Read the resolved file for brain path and server port.
33
+
34
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
35
+ against the current working directory and brain files will end up in the
36
+ project root.
30
37
 
31
38
  ## Process
32
39
 
@@ -40,8 +40,15 @@ whether the language server process is running and review its stderr logs.
40
40
 
41
41
  ## Config
42
42
 
43
- Read `_meta/config.json` for brain path and server port.
44
- If it doesn't exist, trigger wicked-brain:init.
43
+ Resolve the brain config via the shared resolution in
44
+ wicked-brain:init § "Resolving the brain config". In short: try
45
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
46
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
47
+ wicked-brain:init. Read the resolved file for brain path and server port.
48
+
49
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
50
+ against the current working directory and brain files will end up in the
51
+ project root.
45
52
 
46
53
  ## Prerequisites — Source Path
47
54
 
@@ -72,7 +79,7 @@ If `source_path` is **missing** — LSP will fail. Fix it before continuing.
72
79
  wicked-brain:ingest source=/path/to/project
73
80
  ```
74
81
 
75
- **Option B** — Write it manually to `_meta/config.json`, then restart the server:
82
+ **Option B** — Write it manually to the resolved `{brain_path}/_meta/config.json` (from the Config section), then restart the server:
76
83
  ```bash
77
84
  # Read current config, add source_path, write back
78
85
  python3 -c "
@@ -269,7 +276,7 @@ If installation fails, report to the user:
269
276
  | `language_server_crashed` | The server crashed 3 times. Report to user, suggest checking the language server logs. |
270
277
  | `unsupported_language` | No known language server for this file extension. |
271
278
  | `lsp_timeout` | The language server took too long. May be initializing a large project. Retry once. |
272
- | `file_outside_workspace` | The file isn't under `source_path`. Check `_meta/config.json` — `source_path` must be the project root that contains the file. Set it and restart the server with `--source`. |
279
+ | `file_outside_workspace` | The file isn't under `source_path`. Check the resolved `{brain_path}/_meta/config.json` — `source_path` must be the project root that contains the file. Set it and restart the server with `--source`. |
273
280
 
274
281
  ### Step 5: Use results
275
282
 
@@ -21,8 +21,15 @@ Store and recall experiential learnings in the brain's memory system.
21
21
 
22
22
  ## Config
23
23
 
24
- Read `_meta/config.json` for brain path and server port.
25
- If it doesn't exist, trigger wicked-brain:init.
24
+ Resolve the brain config via the shared resolution in
25
+ wicked-brain:init § "Resolving the brain config". In short: try
26
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
27
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
28
+ wicked-brain:init. Read the resolved file for brain path and server port.
29
+
30
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
31
+ against the current working directory and brain files will end up in the
32
+ project root.
26
33
 
27
34
  ## Parameters
28
35
 
@@ -171,7 +171,7 @@ and ask them to resolve manually before retrying.
171
171
  `server_port: 4242` is the *preferred starting port*, not the guaranteed port.
172
172
  When the server starts in Step 7 it probes from this value upward and writes
173
173
  the actual bound port back to this same file. After Step 7, always re-read
174
- `_meta/config.json` to get the real port — never hardcode `4242` in downstream
174
+ `{target_path}/_meta/config.json` to get the real port — never hardcode `4242` in downstream
175
175
  calls. This matters especially when migrating while another brain is already
176
176
  running on 4242.
177
177
 
@@ -14,8 +14,15 @@ You answer questions from the brain's content by dispatching a query subagent.
14
14
 
15
15
  ## Config
16
16
 
17
- Read `_meta/config.json` for brain path and server port.
18
- If it doesn't exist, trigger wicked-brain:init.
17
+ Resolve the brain config via the shared resolution in
18
+ wicked-brain:init § "Resolving the brain config". In short: try
19
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
20
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
21
+ wicked-brain:init. Read the resolved file for brain path and server port.
22
+
23
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
24
+ against the current working directory and brain files will end up in the
25
+ project root.
19
26
 
20
27
  ## Parameters
21
28
 
@@ -15,7 +15,15 @@ more than the user or calling skill needs.
15
15
 
16
16
  ## Config
17
17
 
18
- Read the brain path from `_meta/config.json`. If it doesn't exist, trigger wicked-brain:init.
18
+ Resolve the brain config via the shared resolution in
19
+ wicked-brain:init § "Resolving the brain config". In short: try
20
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
21
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
22
+ wicked-brain:init. Read the resolved file for brain path and server port.
23
+
24
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
25
+ against the current working directory and brain files will end up in the
26
+ project root.
19
27
 
20
28
  ## Parameters
21
29
 
@@ -21,8 +21,15 @@ Scan chunks and memories with thin tagging and expand their `contains:` with syn
21
21
 
22
22
  ## Config
23
23
 
24
- Read `_meta/config.json` for brain path and server port.
25
- If it doesn't exist, trigger wicked-brain:init.
24
+ Resolve the brain config via the shared resolution in
25
+ wicked-brain:init § "Resolving the brain config". In short: try
26
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
27
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
28
+ wicked-brain:init. Read the resolved file for brain path and server port.
29
+
30
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
31
+ against the current working directory and brain files will end up in the
32
+ project root.
26
33
 
27
34
  ## Parameters
28
35
 
@@ -0,0 +1,97 @@
1
+ ---
2
+ name: wicked-brain:review
3
+ description: |
4
+ Browse stored memories with filters on type, tier, and recency. Read-only —
5
+ use wicked-brain:forget to archive or wicked-brain:agent dispatch consolidate
6
+ to promote.
7
+
8
+ Use when: "review my memories", "browse decisions", "what have I stored",
9
+ "list recent gotchas", "brain review".
10
+ ---
11
+
12
+ # wicked-brain:review
13
+
14
+ Filtered browse over the memory store. Combines the server `memory_stats` and
15
+ `recent_memories` actions with agent-side frontmatter filtering to render a
16
+ compact, navigable list.
17
+
18
+ ## Cross-Platform Notes
19
+
20
+ - Uses `curl` for server API calls (Windows 10+, macOS, Linux)
21
+ - File reads use the agent-native Read tool
22
+ - Paths always use forward slashes
23
+
24
+ ## Config
25
+
26
+ Resolve the brain config via the shared resolution in
27
+ wicked-brain:init § "Resolving the brain config". In short: try
28
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
29
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
30
+ wicked-brain:init. Read the resolved file for brain path and server port.
31
+
32
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
33
+ against the current working directory and brain files will end up in the
34
+ project root.
35
+
36
+ ## Parameters
37
+
38
+ - **filter_type** (optional): `decision`, `pattern`, `preference`, `gotcha`, or `discovery`
39
+ - **filter_tier** (optional): `working`, `episodic`, or `semantic`
40
+ - **days** (optional, default 30): only include memories indexed within this many days
41
+ - **limit** (optional, default 20): max results
42
+ - **depth** (optional, default 0): 0=frontmatter only, 1=+summary line, 2=full content
43
+
44
+ ## Process
45
+
46
+ ### Step 1: Fetch breakdown
47
+
48
+ Start with the aggregate view so the user can see the landscape before the list:
49
+
50
+ ```bash
51
+ curl -s -X POST http://localhost:{port}/api \
52
+ -H "Content-Type: application/json" \
53
+ -d '{"action":"memory_stats"}'
54
+ ```
55
+
56
+ Render `total`, `by_type`, `by_tier`, `by_age` as a one-line header.
57
+
58
+ ### Step 2: Fetch candidates
59
+
60
+ ```bash
61
+ curl -s -X POST http://localhost:{port}/api \
62
+ -H "Content-Type: application/json" \
63
+ -d '{"action":"recent_memories","params":{"days":{days},"limit":{limit * 3}}}'
64
+ ```
65
+
66
+ Over-fetch by 3x so agent-side type/tier filtering still returns a useful page.
67
+
68
+ ### Step 3: Filter
69
+
70
+ For each returned memory, parse its frontmatter. Drop any memory whose `type`
71
+ or `tier` does not match `filter_type` / `filter_tier` when those parameters
72
+ are set. Stop once `limit` matches are collected.
73
+
74
+ ### Step 4: Render
75
+
76
+ For each matching memory, render at the requested depth:
77
+
78
+ - **Depth 0**: `{path} — type={type} tier={tier} importance={importance} age={age}`
79
+ - **Depth 1**: depth 0 line + first 3 lines of content
80
+ - **Depth 2**: depth 0 line + full content
81
+
82
+ Age is derived from `indexed_at` relative to now (`Xd` / `Xh`).
83
+
84
+ ### Step 5: Suggest next actions
85
+
86
+ After the list, suggest one of:
87
+ - `wicked-brain:forget path=…` to archive a specific entry
88
+ - `wicked-brain:agent dispatch consolidate` to promote patterns and drop expired entries
89
+ - `wicked-brain:retag` if many entries have thin `contains:` arrays
90
+
91
+ ## Notes
92
+
93
+ - Review is read-only. It never mutates the index or files.
94
+ - For semantic search (content keywords) use `wicked-brain:search` or the
95
+ `recall` mode of `wicked-brain:memory` — review is for browsing by metadata.
96
+ - If no filters are given and `days=30`, this is effectively "show me what I
97
+ have been remembering lately, grouped by type and tier".
@@ -26,8 +26,15 @@ For the brain path default:
26
26
 
27
27
  ## Config
28
28
 
29
- Read `_meta/config.json` for brain path and server port.
30
- If it doesn't exist, trigger wicked-brain:init.
29
+ Resolve the brain config via the shared resolution in
30
+ wicked-brain:init § "Resolving the brain config". In short: try
31
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
32
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
33
+ wicked-brain:init. Read the resolved file for brain path and server port.
34
+
35
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
36
+ against the current working directory and brain files will end up in the
37
+ project root.
31
38
 
32
39
  ## Parameters
33
40
 
@@ -18,8 +18,23 @@ platform differences, alternatives are shown. Your native tools (Read, Write,
18
18
  Grep, Glob) work everywhere — prefer them over shell commands when possible.
19
19
 
20
20
  For the brain path default:
21
- - macOS/Linux: ~/.wicked-brain
22
- - Windows: %USERPROFILE%\.wicked-brain
21
+ - macOS/Linux: `~/.wicked-brain/projects/{cwd_basename}`
22
+ - Windows: `%USERPROFILE%\.wicked-brain\projects\{cwd_basename}`
23
+
24
+ ## Config
25
+
26
+ Resolve the brain config via the shared resolution in
27
+ wicked-brain:init § "Resolving the brain config". In short: try
28
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
29
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
30
+ wicked-brain:init. Read the resolved file to get `brain_path` and `server_port`.
31
+
32
+ If the calling skill already passed `brain_path`, use that directly instead of
33
+ re-resolving.
34
+
35
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
36
+ against the current working directory and brain files will end up in the
37
+ project root.
23
38
 
24
39
  ## When to use
25
40
 
@@ -48,7 +63,7 @@ For the brain path default:
48
63
  - Or use Python: `python3 -c "import os; os.kill({pid}, 0)" 2>/dev/null || python -c "import os; os.kill({pid}, 0)"`
49
64
 
50
65
  c. If the process is dead or no PID file, start the server.
51
- Also pass `--source` if `source_path` is set in `_meta/config.json`
66
+ Also pass `--source` if `source_path` is set in `{brain_path}/_meta/config.json`
52
67
  (this roots LSP language servers at the ingested project so symbol
53
68
  lookup and go-to-definition work correctly):
54
69
  ```bash
@@ -24,8 +24,15 @@ For the brain path default:
24
24
 
25
25
  ## Config
26
26
 
27
- Read `_meta/config.json` for brain path and server port.
28
- If it doesn't exist, trigger wicked-brain:init.
27
+ Resolve the brain config via the shared resolution in
28
+ wicked-brain:init § "Resolving the brain config". In short: try
29
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
30
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
31
+ wicked-brain:init. Read the resolved file for brain path and server port.
32
+
33
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
34
+ against the current working directory and brain files will end up in the
35
+ project root.
29
36
 
30
37
  ## Parameters
31
38
 
@@ -25,8 +25,15 @@ For the brain path default:
25
25
 
26
26
  ## Config
27
27
 
28
- Read `_meta/config.json` for brain path and server port.
29
- If it doesn't exist, trigger wicked-brain:init.
28
+ Resolve the brain config via the shared resolution in
29
+ wicked-brain:init § "Resolving the brain config". In short: try
30
+ `~/.wicked-brain/projects/{cwd_basename}/_meta/config.json` first, fall back
31
+ to `~/.wicked-brain/_meta/config.json` (legacy flat), else trigger
32
+ wicked-brain:init. Read the resolved file for brain path and server port.
33
+
34
+ Do NOT read a bare relative `_meta/config.json` — the model will resolve it
35
+ against the current working directory and brain files will end up in the
36
+ project root.
30
37
 
31
38
  ## Synonym File
32
39