wicked-brain 0.4.13 → 0.4.15
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
|
@@ -36,26 +36,33 @@ export class FileWatcher {
|
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
start() {
|
|
39
|
+
const brainDirs = ["chunks", "wiki", "memory"];
|
|
40
|
+
|
|
39
41
|
// Build initial hash map
|
|
40
|
-
this.#scanAndHash(
|
|
41
|
-
this.#scanAndHash("wiki");
|
|
42
|
-
this.#scanAndHash("memory");
|
|
42
|
+
for (const dir of brainDirs) this.#scanAndHash(dir);
|
|
43
43
|
|
|
44
44
|
// Watch directories
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (!
|
|
45
|
+
const unwatched = [];
|
|
46
|
+
for (const dir of brainDirs) {
|
|
47
|
+
if (!this.#tryWatch(dir)) unwatched.push(dir);
|
|
48
|
+
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
50
|
+
// Retry directories that were missing at startup (check every 3s, stop after 30s)
|
|
51
|
+
if (unwatched.length > 0) {
|
|
52
|
+
const pending = new Set(unwatched);
|
|
53
|
+
let elapsed = 0;
|
|
54
|
+
const retryInterval = setInterval(() => {
|
|
55
|
+
elapsed += 3000;
|
|
56
|
+
for (const dir of pending) {
|
|
57
|
+
if (this.#tryWatch(dir)) {
|
|
58
|
+
this.#scanAndHash(dir);
|
|
59
|
+
pending.delete(dir);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (pending.size === 0 || elapsed >= 30000) clearInterval(retryInterval);
|
|
63
|
+
}, 3000);
|
|
64
|
+
// Don't keep the process alive just for retries
|
|
65
|
+
retryInterval.unref();
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
// Watch registered project directories
|
|
@@ -84,6 +91,24 @@ export class FileWatcher {
|
|
|
84
91
|
}
|
|
85
92
|
}
|
|
86
93
|
|
|
94
|
+
/** Try to set up fs.watch for a brain subdirectory. Returns true on success. */
|
|
95
|
+
#tryWatch(dir) {
|
|
96
|
+
const absDir = join(this.#brainPath, dir);
|
|
97
|
+
if (!existsSync(absDir)) return false;
|
|
98
|
+
try {
|
|
99
|
+
const watcher = watch(absDir, { recursive: true }, (eventType, filename) => {
|
|
100
|
+
if (!filename || !filename.endsWith(".md")) return;
|
|
101
|
+
const relPath = normalizePath(`${dir}/${filename}`);
|
|
102
|
+
this.#debounce(relPath, () => this.#handleChange(relPath));
|
|
103
|
+
});
|
|
104
|
+
this.#watchers.push(watcher);
|
|
105
|
+
return true;
|
|
106
|
+
} catch {
|
|
107
|
+
// recursive watch not supported (Linux) — polling fallback handles it
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
87
112
|
stop() {
|
|
88
113
|
for (const w of this.#watchers) w.close();
|
|
89
114
|
this.#watchers = [];
|
package/server/package.json
CHANGED
|
@@ -120,24 +120,59 @@ directory, not a project subdirectory), push back: explain the per-project
|
|
|
120
120
|
convention and suggest `~/.wicked-brain/projects/{project_name}` instead.
|
|
121
121
|
Only accept the flat path if the user explicitly insists.
|
|
122
122
|
|
|
123
|
-
###
|
|
123
|
+
### The `projects/` infix is mandatory — do not invent alternate layouts
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
The ONLY valid brain path under the default container is
|
|
126
|
+
`~/.wicked-brain/projects/{name}/`. Common misreadings to avoid:
|
|
127
|
+
|
|
128
|
+
- ❌ `~/.wicked-brain/{name}/` — missing the `projects/` segment. Not valid.
|
|
129
|
+
- ❌ `~/.{name}-brain/` — sibling directory. Not the convention.
|
|
130
|
+
- ❌ `~/.wicked-brain/projects/{name}/projects/{subname}/` — nested brains. Not supported.
|
|
126
131
|
|
|
127
|
-
If `~/.wicked-brain/
|
|
128
|
-
|
|
129
|
-
|
|
132
|
+
If the user asks "why not `~/.wicked-brain/{name}`?" the answer is: the `projects/`
|
|
133
|
+
segment is a deliberate namespace. The parent `~/.wicked-brain/` is a container
|
|
134
|
+
that may hold other metadata (linked brain indexes, federation config, etc.),
|
|
135
|
+
and every brain lives under `projects/` to keep that clean.
|
|
130
136
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
Do not improvise alternate layouts when you hit an obstacle. If the documented
|
|
138
|
+
path is occupied, invoke the migration flow (Step 2a) — do not pick a sibling
|
|
139
|
+
directory or a nested path.
|
|
134
140
|
|
|
135
|
-
|
|
136
|
-
|
|
141
|
+
### Step 2: Check for existing brains
|
|
142
|
+
|
|
143
|
+
#### 2a: Detect a flat brain at the parent path
|
|
137
144
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
145
|
+
**Check first, before anything else:** does `~/.wicked-brain/brain.json` exist?
|
|
146
|
+
(That is `brain.json` at the flat parent path, NOT inside `projects/`.) If yes,
|
|
147
|
+
this is a legacy flat brain from before v0.4.7 and you **MUST STOP** the init
|
|
148
|
+
flow and resolve it before continuing.
|
|
149
|
+
|
|
150
|
+
Read `~/.wicked-brain/brain.json` to find the existing brain's name, then tell
|
|
151
|
+
the user exactly this (substituting the real name):
|
|
152
|
+
|
|
153
|
+
> "Heads up — there's already a legacy flat brain at `~/.wicked-brain/` named
|
|
154
|
+
> `{existing_name}`. The current layout puts each project under
|
|
155
|
+
> `~/.wicked-brain/projects/{name}/`, so I can't just create a new brain at the
|
|
156
|
+
> parent path without clobbering it. You have two options:
|
|
157
|
+
>
|
|
158
|
+
> 1. **Migrate** the existing `{existing_name}` brain to
|
|
159
|
+
> `~/.wicked-brain/projects/{existing_name}/` first, then create the new
|
|
160
|
+
> `{project_name}` brain alongside it. Recommended.
|
|
161
|
+
> 2. **Keep** the flat `{existing_name}` brain where it is and create the new
|
|
162
|
+
> brain at `~/.wicked-brain/projects/{project_name}/`. This works but leaves
|
|
163
|
+
> the old brain in a legacy layout.
|
|
164
|
+
>
|
|
165
|
+
> Which do you want?"
|
|
166
|
+
|
|
167
|
+
Do NOT propose any other options. Do NOT suggest a sibling directory like
|
|
168
|
+
`~/.wicked-bus-brain`. Do NOT suggest nesting inside the existing brain. Do NOT
|
|
169
|
+
proceed with overwriting `~/.wicked-brain/brain.json` under any circumstances.
|
|
170
|
+
|
|
171
|
+
If the user picks option 1, invoke `wicked-brain:migrate` with
|
|
172
|
+
`flat_path=~/.wicked-brain` and wait for it to complete before continuing.
|
|
173
|
+
|
|
174
|
+
If the user picks option 2, proceed with the new brain at
|
|
175
|
+
`~/.wicked-brain/projects/{project_name}/` — the flat brain stays untouched.
|
|
141
176
|
|
|
142
177
|
#### 2b: Check target path
|
|
143
178
|
|
|
@@ -154,17 +189,18 @@ Use your native Write tool to create these directories (write a `.gitkeep` place
|
|
|
154
189
|
- `{brain_path}/chunks/inferred`
|
|
155
190
|
- `{brain_path}/wiki/concepts`
|
|
156
191
|
- `{brain_path}/wiki/topics`
|
|
192
|
+
- `{brain_path}/memory`
|
|
157
193
|
- `{brain_path}/_meta`
|
|
158
194
|
|
|
159
195
|
Shell equivalents if needed:
|
|
160
196
|
```bash
|
|
161
197
|
# macOS/Linux
|
|
162
198
|
mkdir -p {brain_path}/raw {brain_path}/chunks/extracted {brain_path}/chunks/inferred \
|
|
163
|
-
{brain_path}/wiki/concepts {brain_path}/wiki/topics {brain_path}/_meta
|
|
199
|
+
{brain_path}/wiki/concepts {brain_path}/wiki/topics {brain_path}/memory {brain_path}/_meta
|
|
164
200
|
```
|
|
165
201
|
```powershell
|
|
166
202
|
# Windows PowerShell
|
|
167
|
-
New-Item -ItemType Directory -Force -Path "{brain_path}\raw","{brain_path}\chunks\extracted","{brain_path}\chunks\inferred","{brain_path}\wiki\concepts","{brain_path}\wiki\topics","{brain_path}\_meta"
|
|
203
|
+
New-Item -ItemType Directory -Force -Path "{brain_path}\raw","{brain_path}\chunks\extracted","{brain_path}\chunks\inferred","{brain_path}\wiki\concepts","{brain_path}\wiki\topics","{brain_path}\memory","{brain_path}\_meta"
|
|
168
204
|
```
|
|
169
205
|
|
|
170
206
|
### Step 4: Write brain.json
|
|
@@ -17,7 +17,7 @@ Store and recall experiential learnings in the brain's memory system.
|
|
|
17
17
|
- Uses `curl` for server API calls (available on Windows 10+, macOS, Linux)
|
|
18
18
|
- File writes use agent-native tools (Write/Edit), not shell commands
|
|
19
19
|
- Path separator: always use forward slashes in `contains:` and `path` fields
|
|
20
|
-
- Brain path default: `~/.wicked-brain` (macOS/Linux), `%USERPROFILE%\.wicked-brain` (Windows)
|
|
20
|
+
- Brain path default: `~/.wicked-brain/projects/{project-name}` (macOS/Linux), `%USERPROFILE%\.wicked-brain\projects\{project-name}` (Windows)
|
|
21
21
|
|
|
22
22
|
## Config
|
|
23
23
|
|