wicked-brain 0.4.7 → 0.4.8
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/README.md
CHANGED
|
@@ -127,6 +127,7 @@ Every operation uses **progressive loading** — the agent never pulls more than
|
|
|
127
127
|
| Skill | What it does |
|
|
128
128
|
|---|---|
|
|
129
129
|
| `wicked-brain:init` | Set up a new brain — creates structure, starts the server, and ingests your project in one shot |
|
|
130
|
+
| `wicked-brain:migrate` | Migrate a legacy flat brain at `~/.wicked-brain/` into the per-project layout |
|
|
130
131
|
| `wicked-brain:ingest` | Add source files — text extracted deterministically, binary docs read via LLM vision |
|
|
131
132
|
| `wicked-brain:search` | Parallel search across your brain and linked brains |
|
|
132
133
|
| `wicked-brain:read` | Progressive loading: depth 0 (stats), depth 1 (summary), depth 2 (full content) |
|
package/package.json
CHANGED
package/server/package.json
CHANGED
|
@@ -69,9 +69,28 @@ directory, not a project subdirectory), push back: explain the per-project
|
|
|
69
69
|
convention and suggest `~/.wicked-brain/projects/{project_name}` instead.
|
|
70
70
|
Only accept the flat path if the user explicitly insists.
|
|
71
71
|
|
|
72
|
-
### Step 2: Check for existing
|
|
72
|
+
### Step 2: Check for existing brains
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
#### 2a: Detect a flat brain at the parent path
|
|
75
|
+
|
|
76
|
+
If `~/.wicked-brain/brain.json` exists (note: `brain.json` at the flat parent
|
|
77
|
+
path, NOT inside a `projects/` subdirectory), this is a legacy flat brain from
|
|
78
|
+
before v0.4.7. Stop and tell the user:
|
|
79
|
+
|
|
80
|
+
"I found an existing flat brain at `~/.wicked-brain/`. The current layout puts
|
|
81
|
+
each project under `~/.wicked-brain/projects/{name}/`. I can migrate the flat
|
|
82
|
+
brain with `wicked-brain:migrate` before creating the new one. Migrate now?"
|
|
83
|
+
|
|
84
|
+
If yes, invoke `wicked-brain:migrate` with `flat_path=~/.wicked-brain` and
|
|
85
|
+
wait for it to complete before continuing.
|
|
86
|
+
|
|
87
|
+
If no, confirm the user wants to keep the flat brain and proceed (accept the
|
|
88
|
+
tradeoff: the new project brain will live under `projects/` but the old one
|
|
89
|
+
stays at the flat path).
|
|
90
|
+
|
|
91
|
+
#### 2b: Check target path
|
|
92
|
+
|
|
93
|
+
If `{brain_path}/_meta/config.json` already exists at the chosen target, tell the user:
|
|
75
94
|
"A brain already exists at `{brain_path}`. Do you want to re-initialize it (keeps existing chunks) or pick a different path?"
|
|
76
95
|
|
|
77
96
|
Stop and wait for their answer before continuing.
|
|
@@ -123,9 +142,12 @@ Write to `{brain_path}/_meta/config.json`:
|
|
|
123
142
|
}
|
|
124
143
|
```
|
|
125
144
|
|
|
126
|
-
`server_port: 4242` is the *preferred* port
|
|
127
|
-
|
|
128
|
-
|
|
145
|
+
`server_port: 4242` is the *preferred* starting port, not the guaranteed port.
|
|
146
|
+
When the server starts in Step 7, it probes from this value upward until it
|
|
147
|
+
finds a free port, then writes the **actual** port back to this same file.
|
|
148
|
+
If multiple project brains run at once, each gets a distinct port (4242, 4243,
|
|
149
|
+
4244, ...). Always re-read `_meta/config.json` after the server starts to get
|
|
150
|
+
the real port — never hardcode `4242` in downstream calls.
|
|
129
151
|
|
|
130
152
|
### Step 6: Initialize the event log
|
|
131
153
|
|
|
@@ -140,7 +162,22 @@ The server will pick a free port and write it back to `_meta/config.json`.
|
|
|
140
162
|
npx wicked-brain-server --brain {brain_path} &
|
|
141
163
|
```
|
|
142
164
|
|
|
143
|
-
|
|
165
|
+
Do NOT pass `--port` unless the user specifies one — let the server pick a
|
|
166
|
+
free port. After the process starts, **re-read `{brain_path}/_meta/config.json`**
|
|
167
|
+
to get the actual `server_port` the server bound to. Use that port for the
|
|
168
|
+
health check and all subsequent API calls.
|
|
169
|
+
|
|
170
|
+
Then health-check to confirm it's up before continuing:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
curl -s -X POST http://localhost:{actual_port}/api \
|
|
174
|
+
-H "Content-Type: application/json" \
|
|
175
|
+
-d '{"action":"health"}'
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Verify the response includes `"brain_id"` matching this brain's id — this
|
|
179
|
+
confirms you're talking to the right server (not an unrelated brain on the
|
|
180
|
+
same machine).
|
|
144
181
|
|
|
145
182
|
### Step 8: Ingest the project
|
|
146
183
|
|
|
@@ -53,12 +53,14 @@ Read `{brain_path}/_meta/config.json`. Look for a `source_path` key:
|
|
|
53
53
|
|
|
54
54
|
```json
|
|
55
55
|
{
|
|
56
|
-
"brain_path": "/Users/me/.wicked-brain",
|
|
57
|
-
"server_port":
|
|
56
|
+
"brain_path": "/Users/me/.wicked-brain/projects/my-project",
|
|
57
|
+
"server_port": 4242,
|
|
58
58
|
"source_path": "/Users/me/Projects/my-project"
|
|
59
59
|
}
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
(`server_port` is the preferred starting port — the server writes the actual bound port back to this field on startup.)
|
|
63
|
+
|
|
62
64
|
If `source_path` is **present** — LSP is configured. Proceed with calls.
|
|
63
65
|
|
|
64
66
|
If `source_path` is **missing** — LSP will fail. Fix it before continuing.
|
|
@@ -108,6 +110,78 @@ Symptoms that indicate missing or wrong `source_path`:
|
|
|
108
110
|
|
|
109
111
|
Check `source_path` in config. If it points at the brain directory (e.g., `~/.wicked-brain/...`) instead of the source project, that is wrong — the brain dir has no `tsconfig.json` or language config. Set it to the project root and restart.
|
|
110
112
|
|
|
113
|
+
## Warming LSP (important — read this before calling lsp-workspace-symbols)
|
|
114
|
+
|
|
115
|
+
**Language servers start lazily.** The brain server does NOT spawn language
|
|
116
|
+
servers on startup — they only spawn when a file-specific LSP action runs
|
|
117
|
+
against a file in `source_path` (`lsp-symbols`, `lsp-definition`, `lsp-hover`,
|
|
118
|
+
`lsp-references`, `lsp-implementation`, `lsp-call-hierarchy-in`,
|
|
119
|
+
`lsp-call-hierarchy-out`).
|
|
120
|
+
|
|
121
|
+
`lsp-workspace-symbols` and `lsp-health` do NOT trigger server spawn. They
|
|
122
|
+
only report on servers that are already running. If you call
|
|
123
|
+
`lsp-workspace-symbols` on a fresh brain server, you will get:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{"symbols":[],"error":"no_running_server"}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
This does NOT mean "no symbols exist in the project." It means "no language
|
|
130
|
+
server has been spawned yet." Do not report empty results to the user as
|
|
131
|
+
authoritative when you see this error code.
|
|
132
|
+
|
|
133
|
+
### Warm-up procedure
|
|
134
|
+
|
|
135
|
+
Before calling `lsp-workspace-symbols` for the first time on any brain server:
|
|
136
|
+
|
|
137
|
+
1. Pick a real source file in `source_path`. Prefer a main entry file — e.g.,
|
|
138
|
+
for TypeScript: `src/index.ts`, `src/main.ts`, or whichever file exists.
|
|
139
|
+
Use Glob against `{source_path}` to find one if unsure. Do NOT pass a file
|
|
140
|
+
that does not exist — the warm-up will silently fail.
|
|
141
|
+
|
|
142
|
+
2. Call a file-specific action to trigger `ensureReady`:
|
|
143
|
+
```bash
|
|
144
|
+
curl -s -X POST http://localhost:{port}/api \
|
|
145
|
+
-H "Content-Type: application/json" \
|
|
146
|
+
-d '{"action":"lsp-symbols","params":{"file":"{absolute_path_to_real_file}"}}'
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
3. Poll `lsp-health` until a server is `ready` (not `starting`):
|
|
150
|
+
```bash
|
|
151
|
+
curl -s -X POST http://localhost:{port}/api \
|
|
152
|
+
-H "Content-Type: application/json" \
|
|
153
|
+
-d '{"action":"lsp-health"}'
|
|
154
|
+
```
|
|
155
|
+
Expected ready response:
|
|
156
|
+
```json
|
|
157
|
+
{"servers":{"typescript":{"status":"ready","uptime":1234}}}
|
|
158
|
+
```
|
|
159
|
+
Retry up to 10 times with 500ms between attempts (5 seconds total). Large
|
|
160
|
+
projects can take several seconds to finish indexing.
|
|
161
|
+
|
|
162
|
+
**If 10 retries are exhausted without a `ready` state**, do NOT treat this
|
|
163
|
+
as success-with-empty-results. Check:
|
|
164
|
+
- `lsp-health` response — is the server in `starting` state? Extend the
|
|
165
|
+
poll to 30 retries (15 seconds) for very large projects.
|
|
166
|
+
- Is the server in `error` state? Read the `message` field and surface it
|
|
167
|
+
to the user. Common causes: missing `tsconfig.json` (wrong `source_path`),
|
|
168
|
+
language server binary not installed, or a crash loop (see
|
|
169
|
+
`language_server_crashed` in Step 4 below).
|
|
170
|
+
- Is the `servers` object still empty? The warm-up file action likely
|
|
171
|
+
failed silently — verify the file path exists and is inside `source_path`.
|
|
172
|
+
|
|
173
|
+
4. Now `lsp-workspace-symbols` will return real results.
|
|
174
|
+
|
|
175
|
+
### Interpreting `lsp-health` states
|
|
176
|
+
|
|
177
|
+
| State | Meaning | Action |
|
|
178
|
+
|-------|---------|--------|
|
|
179
|
+
| empty `servers` object | No language server spawned yet | Follow warm-up procedure above |
|
|
180
|
+
| `status: "starting"` | Server process spawned, still indexing | Wait and retry |
|
|
181
|
+
| `status: "ready"` | Ready to serve queries | Proceed |
|
|
182
|
+
| `status: "crashed"` | Crashed ≤3 times | Check diagnostics for the language server's stderr |
|
|
183
|
+
| `status: "error"` with `No Project` message | Wrong `source_path` | See source_path prerequisites above |
|
|
184
|
+
|
|
111
185
|
## When to Use
|
|
112
186
|
|
|
113
187
|
| You want to... | Action | Example |
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: wicked-brain:migrate
|
|
3
|
+
description: |
|
|
4
|
+
Migrate a flat brain at ~/.wicked-brain/ into the per-project layout at
|
|
5
|
+
~/.wicked-brain/projects/{name}/. Safe to run on already-migrated brains
|
|
6
|
+
(no-op). Auto-invoked by wicked-brain:init when a flat brain is detected.
|
|
7
|
+
|
|
8
|
+
Use when: "migrate my brain", "move brain to per-project layout",
|
|
9
|
+
"I have an old ~/.wicked-brain brain", or when init detects a flat brain.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# wicked-brain:migrate
|
|
13
|
+
|
|
14
|
+
You migrate a flat brain (all data directly under `~/.wicked-brain/`) into the
|
|
15
|
+
per-project layout (each brain under `~/.wicked-brain/projects/{project-name}/`).
|
|
16
|
+
This was the layout change introduced in v0.4.7.
|
|
17
|
+
|
|
18
|
+
## Cross-Platform Notes
|
|
19
|
+
|
|
20
|
+
Commands in this skill work on macOS, Linux, and Windows. Prefer your native
|
|
21
|
+
Read/Write/Glob tools over shell commands when possible.
|
|
22
|
+
|
|
23
|
+
- macOS/Linux home: `~`
|
|
24
|
+
- Windows home: `%USERPROFILE%`
|
|
25
|
+
|
|
26
|
+
## When to use
|
|
27
|
+
|
|
28
|
+
- User explicitly asks to migrate
|
|
29
|
+
- `wicked-brain:init` detected a flat brain and invoked this skill
|
|
30
|
+
- Another skill hit errors caused by the flat layout (e.g. port collisions
|
|
31
|
+
with a second project, meta-brain federation not working)
|
|
32
|
+
|
|
33
|
+
## Parameters
|
|
34
|
+
|
|
35
|
+
- **flat_path** (optional): path to the existing flat brain. Default: `~/.wicked-brain`
|
|
36
|
+
- **project_name** (optional): target project name. Default: asked interactively
|
|
37
|
+
|
|
38
|
+
## Multiple flat brains
|
|
39
|
+
|
|
40
|
+
This skill migrates **one** flat brain per invocation. If the user has several
|
|
41
|
+
flat brains in different locations (e.g. `~/.wicked-brain`, `~/work-brain`,
|
|
42
|
+
`~/.config/wicked-brain`), run `wicked-brain:migrate` once per source, passing
|
|
43
|
+
a different `flat_path` each time. Each becomes its own project brain — either
|
|
44
|
+
under the same `~/.wicked-brain/projects/` umbrella (recommended — pick
|
|
45
|
+
distinct project names) or under separate containers if the user prefers
|
|
46
|
+
isolation.
|
|
47
|
+
|
|
48
|
+
If the user asks "migrate all my brains," enumerate the flat brains you can
|
|
49
|
+
find first (`find ~ -maxdepth 3 -name brain.json 2>/dev/null` on macOS/Linux)
|
|
50
|
+
and confirm each with the user before running migration on it.
|
|
51
|
+
|
|
52
|
+
## Process
|
|
53
|
+
|
|
54
|
+
### Step 1: Detect what we're dealing with
|
|
55
|
+
|
|
56
|
+
Read `{flat_path}/brain.json` — if it does not exist, there is no flat brain
|
|
57
|
+
to migrate. Tell the user and stop.
|
|
58
|
+
|
|
59
|
+
Read `{flat_path}/brain.json` to get the brain's `id` and `name`. These become
|
|
60
|
+
the defaults for the target project.
|
|
61
|
+
|
|
62
|
+
Check whether `{flat_path}/projects/` already exists:
|
|
63
|
+
|
|
64
|
+
- **If `{flat_path}` looks like a pure container** (contains only a `projects/`
|
|
65
|
+
subdirectory and optionally `_meta/`) — this brain is already migrated.
|
|
66
|
+
Report "Already using per-project layout" and stop.
|
|
67
|
+
|
|
68
|
+
- **If `{flat_path}/brain.json` exists at the root AND `{flat_path}/projects/`
|
|
69
|
+
also exists** — mixed state. This is a real migration case. Continue.
|
|
70
|
+
|
|
71
|
+
- **If `{flat_path}/brain.json` exists and no `projects/` subdir** — standard
|
|
72
|
+
flat layout. Continue.
|
|
73
|
+
|
|
74
|
+
### Step 2: Confirm target with user
|
|
75
|
+
|
|
76
|
+
Ask the user:
|
|
77
|
+
|
|
78
|
+
1. "What should this project brain be called?" — Default: the `id` from
|
|
79
|
+
`{flat_path}/brain.json`, or basename of the current working directory.
|
|
80
|
+
2. "Target path?" — Default: `{flat_path}/projects/{project_name}`
|
|
81
|
+
|
|
82
|
+
If the target directory already exists AND is non-empty, stop and tell the
|
|
83
|
+
user: "A brain already exists at the target path. Pick a different name or
|
|
84
|
+
remove the existing brain manually."
|
|
85
|
+
|
|
86
|
+
### Step 3: Stop any running server on the flat brain
|
|
87
|
+
|
|
88
|
+
**Critical on Windows** — SQLite's `.brain.db` may be locked by a running server
|
|
89
|
+
process. Moving a locked file silently corrupts the migration.
|
|
90
|
+
|
|
91
|
+
1. Read `{flat_path}/_meta/server.pid` if it exists.
|
|
92
|
+
2. Check if the process is alive:
|
|
93
|
+
- macOS/Linux: `kill -0 {pid} 2>/dev/null`
|
|
94
|
+
- Windows: `tasklist /FI "PID eq {pid}" 2>nul | findstr {pid}`
|
|
95
|
+
3. If alive, stop it:
|
|
96
|
+
- macOS/Linux: `kill {pid}`
|
|
97
|
+
- Windows PowerShell: `Stop-Process -Id {pid}`
|
|
98
|
+
4. Wait 2 seconds for file handles to release.
|
|
99
|
+
5. Delete the stale PID file.
|
|
100
|
+
|
|
101
|
+
Also look for any other wicked-brain-server processes targeting this flat path
|
|
102
|
+
and stop them. On macOS/Linux: `pgrep -f "wicked-brain-server.*{flat_path}"`.
|
|
103
|
+
|
|
104
|
+
### Step 4: Create the target directory structure
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# macOS/Linux
|
|
108
|
+
mkdir -p {target_path}/_meta
|
|
109
|
+
```
|
|
110
|
+
```powershell
|
|
111
|
+
# Windows
|
|
112
|
+
New-Item -ItemType Directory -Force -Path "{target_path}\_meta"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Do NOT pre-create `raw/`, `chunks/`, `wiki/`, `memory/` — they'll be moved
|
|
116
|
+
over in Step 5.
|
|
117
|
+
|
|
118
|
+
### Step 5: Move data from flat to target
|
|
119
|
+
|
|
120
|
+
Move each of these directories/files from `{flat_path}` to `{target_path}`
|
|
121
|
+
(skip any that don't exist in the source):
|
|
122
|
+
|
|
123
|
+
- `brain.json`
|
|
124
|
+
- `raw/`
|
|
125
|
+
- `chunks/`
|
|
126
|
+
- `wiki/`
|
|
127
|
+
- `memory/`
|
|
128
|
+
- `.brain.db`
|
|
129
|
+
- `.brain.db-shm` (SQLite WAL shared memory, may not exist)
|
|
130
|
+
- `.brain.db-wal` (SQLite WAL log, may not exist)
|
|
131
|
+
|
|
132
|
+
macOS/Linux:
|
|
133
|
+
```bash
|
|
134
|
+
for item in brain.json raw chunks wiki memory .brain.db .brain.db-shm .brain.db-wal; do
|
|
135
|
+
if [ -e "{flat_path}/$item" ]; then
|
|
136
|
+
mv "{flat_path}/$item" "{target_path}/$item"
|
|
137
|
+
echo "moved $item"
|
|
138
|
+
fi
|
|
139
|
+
done
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Windows PowerShell:
|
|
143
|
+
```powershell
|
|
144
|
+
$items = "brain.json","raw","chunks","wiki","memory",".brain.db",".brain.db-shm",".brain.db-wal"
|
|
145
|
+
foreach ($item in $items) {
|
|
146
|
+
$src = Join-Path "{flat_path}" $item
|
|
147
|
+
if (Test-Path $src) {
|
|
148
|
+
Move-Item $src (Join-Path "{target_path}" $item)
|
|
149
|
+
Write-Host "moved $item"
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Do NOT move `_meta/`.** The flat brain's `_meta/config.json` references the
|
|
155
|
+
flat path and is about to be replaced. We'll write a fresh config in Step 6.
|
|
156
|
+
|
|
157
|
+
If the move fails partway through, stop immediately. Partial migrations leave
|
|
158
|
+
the brain in an unrecoverable state — tell the user what moved and what didn't,
|
|
159
|
+
and ask them to resolve manually before retrying.
|
|
160
|
+
|
|
161
|
+
### Step 6: Write the target's `_meta/config.json`
|
|
162
|
+
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"brain_path": "{target_path}",
|
|
166
|
+
"server_port": 4242,
|
|
167
|
+
"installed_clis": []
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
`server_port: 4242` is the *preferred starting port*, not the guaranteed port.
|
|
172
|
+
When the server starts in Step 7 it probes from this value upward and writes
|
|
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
|
|
175
|
+
calls. This matters especially when migrating while another brain is already
|
|
176
|
+
running on 4242.
|
|
177
|
+
|
|
178
|
+
If the flat brain's `_meta/config.json` had a `source_path` field, copy it over
|
|
179
|
+
to the new config — the LSP workspace root must follow the brain.
|
|
180
|
+
|
|
181
|
+
Initialize the event log:
|
|
182
|
+
- macOS/Linux: `touch {target_path}/_meta/log.jsonl`
|
|
183
|
+
- Windows: `New-Item -ItemType File -Force -Path "{target_path}\_meta\log.jsonl"`
|
|
184
|
+
|
|
185
|
+
### Step 7: Start the server against the new path (verification before cleanup)
|
|
186
|
+
|
|
187
|
+
**Ordering matters.** Do not delete the flat `_meta/` yet — if the new server
|
|
188
|
+
fails to start, you need to be able to restore. Start and verify the new
|
|
189
|
+
server first; only clean up the flat path after verification succeeds.
|
|
190
|
+
|
|
191
|
+
Do NOT pass `--port` — let the server pick a free port. It will write the
|
|
192
|
+
actual port back to `{target_path}/_meta/config.json`.
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
npx wicked-brain-server --brain "{target_path}" &
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Wait for the server to start, then re-read `{target_path}/_meta/config.json`
|
|
199
|
+
to get the bound port.
|
|
200
|
+
|
|
201
|
+
Health-check:
|
|
202
|
+
```bash
|
|
203
|
+
curl -s -X POST http://localhost:{port}/api \
|
|
204
|
+
-H "Content-Type: application/json" \
|
|
205
|
+
-d '{"action":"health"}'
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Verify the response includes `"brain_id"` matching the id from Step 1. If the
|
|
209
|
+
brain_id is different, the wrong server is responding — likely a stale process
|
|
210
|
+
on that port. Stop and diagnose before proceeding.
|
|
211
|
+
|
|
212
|
+
### Step 8: Verify the index still works
|
|
213
|
+
|
|
214
|
+
Run a stats call against the new server and confirm the document count is
|
|
215
|
+
non-zero (assuming the flat brain had any documents):
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
curl -s -X POST http://localhost:{port}/api \
|
|
219
|
+
-H "Content-Type: application/json" \
|
|
220
|
+
-d '{"action":"stats"}'
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
If document counts are zero but `.brain.db` was moved, the SQLite file may have
|
|
224
|
+
been truncated during the move or the server is looking at the wrong path.
|
|
225
|
+
**Do NOT proceed to Step 9.** Stop the new server and investigate — the flat
|
|
226
|
+
`_meta/` is still intact at this point, so you can roll back by moving files
|
|
227
|
+
back to `{flat_path}`.
|
|
228
|
+
|
|
229
|
+
### Step 9: Clean up the flat path (only after Steps 7 and 8 pass)
|
|
230
|
+
|
|
231
|
+
Do NOT run this step unless the health check AND stats check both succeeded.
|
|
232
|
+
This step is irreversible.
|
|
233
|
+
|
|
234
|
+
What's left at `{flat_path}` should now be:
|
|
235
|
+
|
|
236
|
+
- `_meta/` directory (old config, log, stale PID)
|
|
237
|
+
- Maybe a `projects/` subdirectory (if it existed before)
|
|
238
|
+
|
|
239
|
+
Verify this is the case before cleanup. If other files remain at the flat
|
|
240
|
+
path, stop and report them — they were not part of a standard flat brain and
|
|
241
|
+
the user needs to decide what to do with them.
|
|
242
|
+
|
|
243
|
+
Delete the flat `_meta/` directory:
|
|
244
|
+
- macOS/Linux: `rm -rf {flat_path}/_meta`
|
|
245
|
+
- Windows: `Remove-Item -Recurse -Force "{flat_path}\_meta"`
|
|
246
|
+
|
|
247
|
+
The flat path is now a pure container with only `projects/` beneath it.
|
|
248
|
+
|
|
249
|
+
### Step 10: Report
|
|
250
|
+
|
|
251
|
+
Tell the user:
|
|
252
|
+
|
|
253
|
+
"Migrated brain `{name}` from `{flat_path}` to `{target_path}`.
|
|
254
|
+
- {N} documents preserved
|
|
255
|
+
- Server running on port {port}
|
|
256
|
+
- `source_path`: {source_path or 'not set'}
|
|
257
|
+
|
|
258
|
+
The flat path `{flat_path}` is now a container for per-project brains. You can
|
|
259
|
+
create additional project brains under `{flat_path}/projects/` with `wicked-brain:init`."
|
|
260
|
+
|
|
261
|
+
## Rollback
|
|
262
|
+
|
|
263
|
+
If anything goes wrong before Step 9 (cleanup), the migration can be rolled
|
|
264
|
+
back by moving items back from `{target_path}` to `{flat_path}`. The flat
|
|
265
|
+
`_meta/` is still intact through Steps 1-8.
|
|
266
|
+
|
|
267
|
+
After Step 9 there is no clean rollback — the flat `_meta/` has been deleted.
|
|
268
|
+
Never run Step 9 until Steps 7 and 8 both pass.
|
|
@@ -30,18 +30,40 @@ For the brain path default:
|
|
|
30
30
|
|
|
31
31
|
## Process
|
|
32
32
|
|
|
33
|
-
### Step 1: Check current version
|
|
33
|
+
### Step 1: Check current installed version
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
wicked-brain-server --version 2>/dev/null || npx wicked-brain-server --version 2>/dev/null || echo "not installed"
|
|
38
|
-
```
|
|
35
|
+
The `wicked-brain-server` binary lives inside the globally installed `wicked-brain` npm package. Read its version directly from the installed package:
|
|
39
36
|
|
|
40
|
-
If that doesn't work, check the package directly:
|
|
41
37
|
```bash
|
|
42
|
-
npm list -g wicked-brain
|
|
38
|
+
npm list -g wicked-brain --json 2>/dev/null | python3 -c "
|
|
39
|
+
import json, sys
|
|
40
|
+
try:
|
|
41
|
+
d = json.load(sys.stdin)
|
|
42
|
+
deps = d.get('dependencies', {})
|
|
43
|
+
v = deps.get('wicked-brain', {}).get('version', 'not installed')
|
|
44
|
+
print(v)
|
|
45
|
+
except Exception:
|
|
46
|
+
print('not installed')
|
|
47
|
+
" 2>/dev/null || npm list -g wicked-brain --json 2>/dev/null | python -c "
|
|
48
|
+
import json, sys
|
|
49
|
+
try:
|
|
50
|
+
d = json.load(sys.stdin)
|
|
51
|
+
deps = d.get('dependencies', {})
|
|
52
|
+
v = deps.get('wicked-brain', {}).get('version', 'not installed')
|
|
53
|
+
print(v)
|
|
54
|
+
except Exception:
|
|
55
|
+
print('not installed')
|
|
56
|
+
"
|
|
43
57
|
```
|
|
44
58
|
|
|
59
|
+
If the result is `not installed`, the package was never globally installed (the
|
|
60
|
+
user may have been running via `npx` only). Treat this as "needs install" and
|
|
61
|
+
proceed to Step 4.
|
|
62
|
+
|
|
63
|
+
**Do NOT use `npx wicked-brain-server --version`** — it may return the version
|
|
64
|
+
of a stale cached npx copy, not the globally installed one that actually runs
|
|
65
|
+
when brain servers start.
|
|
66
|
+
|
|
45
67
|
### Step 2: Check latest version on npm
|
|
46
68
|
|
|
47
69
|
```bash
|
|
@@ -58,15 +80,45 @@ If an update is available, ask the user:
|
|
|
58
80
|
|
|
59
81
|
### Step 4: Update (if user approves)
|
|
60
82
|
|
|
61
|
-
|
|
83
|
+
**Critical:** `npx wicked-brain@latest` only runs the *installer* — it refreshes
|
|
84
|
+
the skill markdown files in your CLI's skills directory, but it does NOT update
|
|
85
|
+
the globally installed `wicked-brain-server` binary. The skills will then expect
|
|
86
|
+
features that the old server doesn't have, producing confusing errors.
|
|
62
87
|
|
|
63
|
-
|
|
88
|
+
Use `npm install -g` to update the actual binary:
|
|
64
89
|
|
|
65
90
|
```bash
|
|
66
|
-
|
|
91
|
+
npm install -g wicked-brain@latest 2>&1
|
|
67
92
|
```
|
|
68
93
|
|
|
69
|
-
|
|
94
|
+
On Windows PowerShell (no change needed):
|
|
95
|
+
```powershell
|
|
96
|
+
npm install -g wicked-brain@latest
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
If this fails with `EACCES` / permission denied:
|
|
100
|
+
- macOS/Linux: `sudo npm install -g wicked-brain@latest`
|
|
101
|
+
- Windows: re-run the shell as Administrator, or fix npm's global prefix per
|
|
102
|
+
npm docs. Do NOT silently skip — report the failure to the user and stop.
|
|
103
|
+
|
|
104
|
+
After a successful `npm install -g`, also run the installer to refresh skill
|
|
105
|
+
files in all detected CLIs (skills are copied from the installed package, not
|
|
106
|
+
downloaded separately):
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npx wicked-brain
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Step 4a: Verify the update landed
|
|
113
|
+
|
|
114
|
+
Re-run the Step 1 version check. The version reported MUST match the latest
|
|
115
|
+
version from Step 2. If it still shows the old version:
|
|
116
|
+
|
|
117
|
+
1. Check `which wicked-brain-server` (macOS/Linux) or `where wicked-brain-server` (Windows) — the shell may have cached a path to a different installation.
|
|
118
|
+
2. Clear npm's global cache: `npm cache clean --force`
|
|
119
|
+
3. Check if a different Node.js version (nvm, fnm, volta) is pinning a stale copy.
|
|
120
|
+
|
|
121
|
+
Do NOT proceed to Step 5 until version verification succeeds. Reporting a successful update while the binary is stale is the top failure mode of this skill.
|
|
70
122
|
|
|
71
123
|
### Step 5: Restart server if running
|
|
72
124
|
|