monomind 2.3.3 → 2.3.4
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 +37 -4
- package/package.json +1 -1
- package/packages/@monomind/cli/.claude/commands/mastermind/{approve.md → approvev1.md} +12 -9
- package/packages/@monomind/cli/.claude/commands/mastermind/help.md +18 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/master.md +3 -3
- package/packages/@monomind/cli/.claude/commands/mastermind/runorg.md +19 -107
- package/packages/@monomind/cli/.claude/commands/mastermind/runorgv1.md +159 -0
- package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +45 -2
- package/packages/@monomind/cli/.claude/helpers/handlers/session-restore-handler.cjs +25 -18
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/agents.md +5 -1
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/{approve.md → approvev1.md} +8 -5
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/env.md +7 -2
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/{heartbeat.md → heartbeatv1.md} +7 -4
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/inbox.md +14 -2
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/instance.md +3 -1
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/org-settings.md +4 -1
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/orgs.md +14 -13
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/orgstatus.md +19 -8
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/projects.md +3 -0
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/runorg.md +37 -725
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/runorgv1.md +731 -0
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/stoporg.md +10 -3
- package/packages/@monomind/cli/.claude/skills/mastermind-skills/tasks.md +4 -1
- package/packages/@monomind/cli/README.md +37 -4
- package/packages/@monomind/cli/dist/src/commands/cleanup.js +30 -8
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +23 -10
- package/packages/@monomind/cli/dist/src/commands/org-observe.js +30 -26
- package/packages/@monomind/cli/dist/src/commands/org.js +52 -2
- package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.js +0 -0
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +31 -12
- package/packages/@monomind/cli/dist/src/orgrt/daemon.js +45 -9
- package/packages/@monomind/cli/dist/src/orgrt/mailbox.d.ts +23 -0
- package/packages/@monomind/cli/dist/src/orgrt/mailbox.js +33 -1
- package/packages/@monomind/cli/dist/src/orgrt/migrate.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/orgrt/migrate.js +111 -0
- package/packages/@monomind/cli/dist/src/orgrt/reporting.js +8 -1
- package/packages/@monomind/cli/dist/src/orgrt/session.js +8 -2
- package/packages/@monomind/cli/dist/src/ui/dashboard.html +44 -0
- package/packages/@monomind/cli/dist/src/ui/orgs.html +2 -2
- package/packages/@monomind/cli/dist/src/ui/server.mjs +12 -1
- package/packages/@monomind/cli/package.json +2 -2
package/README.md
CHANGED
|
@@ -102,11 +102,25 @@ monomind org run content-team --task "Build and publish 3 blog posts per week"
|
|
|
102
102
|
# assigns work to role agents, coordinates until the task completes
|
|
103
103
|
# or you stop it. Every event streams into the dashboard above.
|
|
104
104
|
|
|
105
|
-
monomind org status content-team # runtime state
|
|
105
|
+
monomind org status content-team # runtime state (detects crashed daemons)
|
|
106
106
|
monomind org stop content-team # request a graceful stop
|
|
107
|
-
monomind org list # every org + status
|
|
107
|
+
monomind org list # every org + roles, schedule, status
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
+
### Observe, steer, and let it learn
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
monomind org logs content-team --follow # live event stream in the terminal
|
|
114
|
+
monomind org report content-team # outcome, per-role tokens vs budget, assets
|
|
115
|
+
monomind org questions content-team # what agents asked via ask_human
|
|
116
|
+
monomind org answer content-team q-123 "yes" # answer live or queued — no dashboard needed
|
|
117
|
+
monomind org create blog --template content-team --goal "3 posts/week" # scaffold from a template
|
|
118
|
+
monomind org validate blog # schema + structural checks before running
|
|
119
|
+
monomind org run blog --dry-run # preview each role's exact briefing
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Orgs are self-improving: the coordinator records every run's outcome (`org_complete`), the next run is briefed on it, and all agents can query accumulated cross-run memory with `org_recall` — a scheduled org gets smarter every cycle instead of starting cold. Crashed agent sessions restart automatically with backoff.
|
|
123
|
+
|
|
110
124
|
### What runs under the hood
|
|
111
125
|
|
|
112
126
|
| What | How |
|
|
@@ -196,9 +210,28 @@ monomind org run my-team # run your first AI org (see .monomind/orgs/sa
|
|
|
196
210
|
|
|
197
211
|
---
|
|
198
212
|
|
|
213
|
+
## 📚 Second Brain — Your Documents, Retrieved by Meaning
|
|
214
|
+
|
|
215
|
+
Drop documents (Markdown, TXT, PDF, DOCX) anywhere in your project and run `monomind init` — the Second Brain activates itself. No flags, no configuration, no accounts. Everything runs on your machine: a local embedding model (MiniLM via transformers.js) and a local SQLite vector store. **Your notes never leave your computer.**
|
|
216
|
+
|
|
217
|
+
From then on, every substantive prompt you type in Claude Code is automatically answered *with your own knowledge in context* — a hook retrieves the most relevant excerpts semantically (the always-on dashboard keeps the model warm, ~60ms per lookup) and injects them before Claude starts thinking. Ask "when do new parents get time off" and the parental-leave section of your handbook is already on the table, even though you never used the word "leave".
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
monomind doc ingest ./notes # index documents (init + session-start do this automatically)
|
|
221
|
+
monomind doc search -q "pricing psychology in checkout" # semantic search, by meaning not keywords
|
|
222
|
+
monomind doc list # what's indexed
|
|
223
|
+
monomind doc export # portable OKF bundle — move your brain between machines
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Retrieval quality is a tested invariant, not a hope: a golden-set eval (paraphrase queries against notes written in different vocabulary) runs in CI with an 80% recall bar.
|
|
227
|
+
|
|
228
|
+
> **Privacy note:** the embedding model (~90MB) is fetched once from HuggingFace's CDN when your first document is indexed, then cached locally forever. That download is the only outbound request the Second Brain ever makes — your documents and queries never leave your machine. Offline at first index? Search degrades gracefully to keyword matching and `monomind doctor` tells you how to warm up later.
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
199
232
|
## 🧠 Memory That Persists
|
|
200
233
|
|
|
201
|
-
Every session, every agent, every org writes to a persistent memory store — a
|
|
234
|
+
Every session, every agent, every org writes to a persistent memory store that survives across sessions — text plus embedding vectors in local SQLite (better-sqlite3, pure-WASM fallback), embedded by a local model. No cloud vector database, no API keys, no data transmission. The next time you run anything, Monomind already knows what was built, what failed, and which patterns work.
|
|
202
235
|
|
|
203
236
|
```mermaid
|
|
204
237
|
graph TD
|
|
@@ -217,7 +250,7 @@ graph TD
|
|
|
217
250
|
|
|
218
251
|
```bash
|
|
219
252
|
monomind memory store "key insight" --namespace my-project
|
|
220
|
-
monomind memory search "auth implementation" #
|
|
253
|
+
monomind memory search "auth implementation" # semantic (local embeddings) with keyword fallback
|
|
221
254
|
```
|
|
222
255
|
|
|
223
256
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monomind",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.4",
|
|
4
4
|
"description": "Open-source CLI extension for Claude Code. Adds an MCP server with a codebase knowledge graph, persistent memory, multi-agent coordination, and reusable slash commands. MIT licensed, runs locally, no data leaves your machine.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
<!-- Review and action pending approval requests from agents in a running org. -->
|
|
1
|
+
<!-- LEGACY-ORG-V1 — Review and action pending approval requests from agents in a running v1 (prompt-orchestrated) org. Reach it only via /mastermind:approvev1. -->
|
|
2
|
+
|
|
3
|
+
> **LEGACY-ORG-V1 (2026-07): v2 approvals arrive as question events in the dashboard Human Input tab — no command needed.**
|
|
4
|
+
> This file-based approval queue applies only to v1 orgs not yet migrated off the `board_id`/`topology` config shape. Reach this legacy path only via `/mastermind:approvev1`.
|
|
2
5
|
|
|
3
6
|
**If $ARGUMENTS is empty:** Output the following and wait.
|
|
4
7
|
|
|
5
8
|
---
|
|
6
9
|
|
|
7
|
-
**MASTERMIND: APPROVE**
|
|
10
|
+
**MASTERMIND: APPROVE (v1, legacy)**
|
|
8
11
|
|
|
9
|
-
Review and action pending approval requests from agents running inside
|
|
12
|
+
Review and action pending approval requests from agents running inside a v1 (prompt-orchestrated) autonomous org. Agents request human approval before executing sensitive actions (publishing content, sending emails, making purchases, modifying infrastructure). v2 orgs surface approvals directly in the dashboard Human Input tab — no command needed.
|
|
10
13
|
|
|
11
14
|
**Usage:**
|
|
12
15
|
|
|
13
16
|
```
|
|
14
|
-
/mastermind:
|
|
15
|
-
/mastermind:
|
|
16
|
-
/mastermind:
|
|
17
|
-
/mastermind:
|
|
17
|
+
/mastermind:approvev1 --org <name> List all pending approvals
|
|
18
|
+
/mastermind:approvev1 --org <name> --action approve --id <id>
|
|
19
|
+
/mastermind:approvev1 --org <name> --action reject --id <id> --reason "Too risky"
|
|
20
|
+
/mastermind:approvev1 --org <name> --action inspect --id <id>
|
|
18
21
|
```
|
|
19
22
|
|
|
20
23
|
**Options:**
|
|
@@ -23,7 +26,7 @@ Review and action pending approval requests from agents running inside an autono
|
|
|
23
26
|
`--id <approval_id>` — specific approval to approve/reject/inspect
|
|
24
27
|
`--reason <text>` — reason for rejection (optional)
|
|
25
28
|
|
|
26
|
-
No running orgs yet? Run `/mastermind:createorg` then `/mastermind:runorg
|
|
29
|
+
No running orgs yet? Run `/mastermind:createorg` then `/mastermind:runorgv1` (v1 orgs only — v2 orgs use `/mastermind:runorg`).
|
|
27
30
|
|
|
28
31
|
---
|
|
29
32
|
|
|
@@ -74,7 +77,7 @@ curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "
|
|
|
74
77
|
'{type:"session:start",session:$session,domain:"ops",prompt:("Approve requests for org: "+$org),mode:"confirm",project:$proj,ts:(now*1000|floor)}')" || true
|
|
75
78
|
```
|
|
76
79
|
|
|
77
|
-
Invoke `Skill("mastermind-skills:
|
|
80
|
+
Invoke `Skill("mastermind-skills:approvev1")` passing: brain_context, org_name, action, approval_id, reason, caller: "command".
|
|
78
81
|
|
|
79
82
|
After skill returns: note the status. Emit `session:complete`:
|
|
80
83
|
```bash
|
|
@@ -18,6 +18,24 @@ Quick reference for all Mastermind skills and CLI commands available in this pro
|
|
|
18
18
|
| `mastermind:swarm` | Swarm coordination reference — topologies, strategies, init patterns |
|
|
19
19
|
| `mastermind:memory` | Memory CLI quick reference |
|
|
20
20
|
|
|
21
|
+
## Org Runtime (v2 default)
|
|
22
|
+
|
|
23
|
+
| Command | Description |
|
|
24
|
+
|-------|-------------|
|
|
25
|
+
| `/mastermind:createorg` | Define and save an org (always v2-shaped) |
|
|
26
|
+
| `/mastermind:runorg` | Start a saved org via the Org Runtime v2 daemon (`monomind org run`/`serve`) — auto-migrates v1-shaped configs first |
|
|
27
|
+
| `/mastermind:stoporg` | Stop a running scheduled org loop |
|
|
28
|
+
| `/mastermind:orgstatus` | Detailed status for a single org |
|
|
29
|
+
| `/mastermind:orgs` | List all saved orgs |
|
|
30
|
+
|
|
31
|
+
### Legacy v1 (marker `LEGACY-ORG-V1` — reachable only under these explicit names)
|
|
32
|
+
|
|
33
|
+
| Command | Description |
|
|
34
|
+
|-------|-------------|
|
|
35
|
+
| `/mastermind:runorgv1` | Legacy prompt-orchestrated org runner — superseded by `/mastermind:runorg` |
|
|
36
|
+
| `/mastermind:approvev1` | Legacy approval queue for v1 orgs — v2 approvals arrive as dashboard question events instead |
|
|
37
|
+
| `/mastermind:heartbeatv1` | Legacy manual agent wake-up for v1 orgs — v2 roles are live SDK sessions with no wake cycle |
|
|
38
|
+
|
|
21
39
|
## Core CLI Commands
|
|
22
40
|
|
|
23
41
|
```bash
|
|
@@ -118,7 +118,7 @@ digraph mastermind_routing {
|
|
|
118
118
|
| Inspect or manage brain memory | `Skill("mastermind-skills:brain")` |
|
|
119
119
|
| Technical portfolio, project state assessment | `Skill("mastermind-skills:techport")` |
|
|
120
120
|
| Define/run an agent organization | `Skill("mastermind-skills:createorg")` / `Skill("mastermind-skills:runorg")` |
|
|
121
|
-
| Review and action pending agent approval requests | `Skill("mastermind-skills:
|
|
121
|
+
| Review and action pending agent approval requests | `Skill("mastermind-skills:approvev1")` (v1 orgs only — v2 approvals arrive in the dashboard Human Input tab) |
|
|
122
122
|
| Autonomous build + review until clean | `Skill("mastermind-skills:autodev")` |
|
|
123
123
|
| Isolate work in a git worktree | `Skill("mastermind-skills:worktree")` |
|
|
124
124
|
| Write or improve a mastermind skill | `Skill("mastermind-skills:skill-builder")` |
|
|
@@ -253,8 +253,8 @@ Describe your goal. Mastermind identifies the relevant domains, spawns specialis
|
|
|
253
253
|
|
|
254
254
|
**Persistent agent orgs** — named teams that coordinate across sessions
|
|
255
255
|
`/mastermind:createorg` — define an org: roles, hierarchy, goal
|
|
256
|
-
`/mastermind:runorg` — start a saved org
|
|
257
|
-
`/mastermind:
|
|
256
|
+
`/mastermind:runorg` — start a saved org via the Org Runtime v2 daemon (auto-migrates v1 configs); legacy prompt-orchestrated path: `/mastermind:runorgv1`
|
|
257
|
+
`/mastermind:approvev1` — review and action pending approval requests from running org agents (v1 orgs only — v2 approvals arrive in the dashboard Human Input tab)
|
|
258
258
|
|
|
259
259
|
**Autonomous & advanced**
|
|
260
260
|
`/mastermind:autodev` — research → build → review loop until clean (`--tillend` supported)
|
|
@@ -1,28 +1,14 @@
|
|
|
1
|
-
<!-- Start a saved org
|
|
1
|
+
<!-- Start a saved org via the Org Runtime v2 daemon (monomind org run/serve). Validates the config, auto-migrates v1-shaped configs, starts the daemon, and confirms liveness. The legacy prompt-orchestrated path lives at /mastermind:runorgv1. -->
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> This prompt-orchestrated path has no delivery guarantees and no ground-truth event stream.
|
|
5
|
-
> It remains only for orgs not yet migrated. New orgs MUST use the daemon.
|
|
6
|
-
|
|
7
|
-
**If $ARGUMENTS is empty:** List saved orgs and display the following.
|
|
3
|
+
**If $ARGUMENTS is empty:** Output the following and wait.
|
|
8
4
|
|
|
9
5
|
---
|
|
10
6
|
|
|
11
7
|
**MASTERMIND: RUN ORG**
|
|
12
8
|
|
|
13
|
-
Running an org starts
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
**Scheduled org** (created with `--schedule`): sets the org to `active` and runs the first iteration immediately. Subsequent iterations are self-scheduled via ScheduleWakeup. The loop stops cleanly within one interval after `/mastermind:stoporg --org <name>`.
|
|
18
|
-
|
|
19
|
-
**Your saved orgs:**
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npx -y monomind@latest org list 2>/dev/null \
|
|
23
|
-
|| ls .monomind/orgs/*.json 2>/dev/null | grep -vE -- '-(state|goals|threads|activity|approvals|members|secrets|budgets|routines|issues|projects|workspaces|worktrees|environments|plugins|adapters|join-requests|bootstrap|project-workspaces|approval-comments|skills)\.json$' | xargs -I{} basename {} .json 2>/dev/null \
|
|
24
|
-
|| echo "(none — run /mastermind:createorg to define one)"
|
|
25
|
-
```
|
|
9
|
+
Running an org starts it through the Org Runtime v2 daemon. Every role becomes
|
|
10
|
+
a live SDK session; the daemon forwards dashboard events itself — no boss
|
|
11
|
+
agent, no monotask board, no manual curl emissions.
|
|
26
12
|
|
|
27
13
|
**Usage:**
|
|
28
14
|
|
|
@@ -30,130 +16,56 @@ npx -y monomind@latest org list 2>/dev/null \
|
|
|
30
16
|
/mastermind:runorg --org <name>
|
|
31
17
|
|
|
32
18
|
/mastermind:runorg --org content-team --task "Publish the Q2 product roundup post by Friday"
|
|
33
|
-
|
|
34
|
-
/mastermind:runorg --org research-pod "Focus this week on competitor pricing changes"
|
|
35
19
|
```
|
|
36
20
|
|
|
37
21
|
**Options:**
|
|
38
22
|
`--org <name>` — which saved org to start (required; prompted if omitted)
|
|
39
23
|
`--task <task>` — override the org's default goal for this run
|
|
40
|
-
Any remaining text is passed as additional context to the boss agent.
|
|
41
24
|
|
|
42
25
|
No orgs yet? Run `/mastermind:createorg` to define one.
|
|
43
26
|
|
|
44
|
-
|
|
27
|
+
Your saved orgs:
|
|
45
28
|
|
|
46
|
-
|
|
29
|
+
```bash
|
|
30
|
+
npx -y monomind@latest org list 2>/dev/null || echo "(none — run /mastermind:createorg to define one)"
|
|
31
|
+
```
|
|
47
32
|
|
|
48
33
|
---
|
|
49
34
|
|
|
50
|
-
**
|
|
51
|
-
|
|
52
|
-
Scan `$ARGUMENTS` for these flags and store their values. Remove them from the argument string before Step 1:
|
|
53
|
-
|
|
54
|
-
| Flag | Variable | Default |
|
|
55
|
-
|---|---|---|
|
|
56
|
-
| `--rep <N>` | `current_rep = N` | absent |
|
|
57
|
-
| `--loop <id>` | `LOOP_ID = id` | absent |
|
|
58
|
-
| `--tillend` | `tillend_mode = true` | false |
|
|
59
|
-
| `--maxruns <N>` | `tillend_maxruns = N` | 50 |
|
|
60
|
-
| `--wait <N>` | `wait_seconds = N` | 60 |
|
|
61
|
-
| `--repeat <N>` | `repeat_count = N` | 0 |
|
|
62
|
-
|
|
63
|
-
⚠️ **CRITICAL — CONTINUATION RUNS DO NOT SKIP WORK.** When `--rep N` is present, this is a scheduled continuation triggered by ScheduleWakeup. The org's FULL work cycle MUST still execute every time: session variables → session:start event → Skill("mastermind-skills:runorg") → session:complete event. NEVER short-circuit or skip the org work because `--rep` is present. The `--rep` / `--loop` flags are only consumed by `Skill("mastermind-skills:_repeat")` at the end.
|
|
35
|
+
**If $ARGUMENTS is non-empty:** Execute the flow below.
|
|
64
36
|
|
|
65
37
|
---
|
|
66
38
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
From the remaining `$ARGUMENTS` (after loop flags removed in Step 0):
|
|
39
|
+
Parse `$ARGUMENTS` for:
|
|
70
40
|
- `--org <name>` → org_name = <name>
|
|
71
|
-
- `--task <task>` → task_override = <task> (if omitted, task_override = null — the skill uses org's stored goal)
|
|
72
|
-
- Remaining text = additional context passed to the boss agent
|
|
41
|
+
- `--task <task>` → task_override = <task> (if omitted, task_override = null — the skill uses the org's stored goal)
|
|
73
42
|
|
|
74
43
|
If `--org` is not provided, list saved orgs and ask which to run:
|
|
75
44
|
```bash
|
|
76
|
-
|
|
77
|
-
if [ -z "$orgs" ]; then
|
|
78
|
-
echo "No saved orgs found. Run /mastermind:createorg first."
|
|
79
|
-
exit 1
|
|
80
|
-
fi
|
|
81
|
-
echo "$orgs"
|
|
82
|
-
```
|
|
83
|
-
Ask: "Which org would you like to start? Available: <list from above>"
|
|
84
|
-
|
|
85
|
-
Verify the org file exists before proceeding:
|
|
86
|
-
```bash
|
|
87
|
-
[ -f ".monomind/orgs/${org_name}.json" ] || { echo "Org '${org_name}' not found."; exit 1; }
|
|
45
|
+
npx -y monomind@latest org list 2>/dev/null || echo "(none — run /mastermind:createorg to define one)"
|
|
88
46
|
```
|
|
89
|
-
If the file does not exist, stop and suggest running `/mastermind:createorg --name ${org_name}`.
|
|
90
47
|
|
|
91
48
|
Load brain context for the `ops` domain (follow _protocol.md Brain Load Procedure, namespace: `ops`).
|
|
92
49
|
|
|
93
|
-
|
|
50
|
+
Generate a session ID:
|
|
94
51
|
```bash
|
|
95
52
|
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
53
|
+
session_id="mm-$(date -u +%Y%m%dT%H%M%S)"
|
|
96
54
|
CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$REPO_ROOT/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
|
|
97
|
-
# Reuse the loop's original sessionId for continuation runs (keeps all reps under one session)
|
|
98
|
-
if [ -n "${LOOP_ID:-}" ] && [ -f ".monomind/loops/${LOOP_ID}.json" ]; then
|
|
99
|
-
session_id=$(jq -r '.sessionId // empty' ".monomind/loops/${LOOP_ID}.json" 2>/dev/null)
|
|
100
|
-
fi
|
|
101
|
-
session_id="${session_id:-mm-$(date -u +%Y%m%dT%H%M%S)}"
|
|
102
55
|
```
|
|
103
56
|
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/.monomind/dashboard-token" 2>/dev/null || true)" \
|
|
107
|
-
-H "Content-Type: application/json" \
|
|
108
|
-
-d "$(jq -cn \
|
|
109
|
-
--arg session "$session_id" \
|
|
110
|
-
--arg org "$org_name" \
|
|
111
|
-
--arg proj "$REPO_ROOT" \
|
|
112
|
-
'{type:"session:start",session:$session,domain:"ops",prompt:("Running org: "+$org),mode:"auto",project:$proj,ts:(now*1000|floor)}')" || true
|
|
113
|
-
```
|
|
57
|
+
Invoke `Skill("mastermind-skills:runorg")` passing: org_name: `$org_name`, task: task_override, session_id: `$session_id`, caller: "command".
|
|
114
58
|
|
|
115
|
-
|
|
116
|
-
```bash
|
|
117
|
-
curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/.monomind/dashboard-token" 2>/dev/null || true)" \
|
|
118
|
-
-H "Content-Type: application/json" \
|
|
119
|
-
-d "$(jq -cn \
|
|
120
|
-
--arg session "$session_id" \
|
|
121
|
-
--arg org "$org_name" \
|
|
122
|
-
--arg proj "$REPO_ROOT" \
|
|
123
|
-
'{type:"domain:dispatch",session:$session,domain:"ops",cmd:("Starting org "+$org+" as persistent daemon"),project:$proj,ts:(now*1000|floor)}')" || true
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Invoke `Skill("mastermind-skills:runorg")` passing: brain_context, org_name: `$org_name`, session_id: `$session_id`, task: task_override, caller: "command".
|
|
127
|
-
|
|
128
|
-
After the skill spawns the boss agent and returns: note the status. Emit `session:complete`:
|
|
59
|
+
After skill returns: emit `session:complete`:
|
|
129
60
|
```bash
|
|
130
61
|
curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/.monomind/dashboard-token" 2>/dev/null || true)" \
|
|
131
62
|
-H "Content-Type: application/json" \
|
|
132
63
|
-d "$(jq -cn \
|
|
133
64
|
--arg session "$session_id" \
|
|
134
65
|
--arg status "<status>" \
|
|
135
|
-
|
|
136
|
-
'{type:"session:complete",session:$session,domain:"ops",status:$status,domains:["ops"],project:$proj,ts:(now*1000|floor)}')" || true
|
|
66
|
+
'{type:"session:complete",session:$session,domain:"ops",status:$status,domains:["ops"],ts:(now*1000|floor)}')" || true
|
|
137
67
|
```
|
|
138
68
|
|
|
139
69
|
Follow _protocol.md Brain Write Procedure for domain `ops`.
|
|
140
70
|
|
|
141
|
-
|
|
142
|
-
**MANDATORY — invoke `Skill("mastermind-skills:_repeat")` now.** This is required regardless of how the skill above completed, regardless of whether you think the work is done, regardless of whether you plan to end your response. For `--repeat N`: the count is non-negotiable — all N runs must happen. For `--tillend`: only a verified empty round (confirmed by git diff) stops the loop. Do not end your response without invoking this skill.
|
|
143
|
-
|
|
144
|
-
After the REPEAT POSTAMBLE completes, if a loop was started or continued (LOOP_ID is set), write the org name into the loop state file so the dashboard can detect running status:
|
|
145
|
-
```bash
|
|
146
|
-
if [ -n "${LOOP_ID:-}" ]; then
|
|
147
|
-
LOOP_FILE=".monomind/loops/${LOOP_ID}.json"
|
|
148
|
-
if [ -f "$LOOP_FILE" ]; then
|
|
149
|
-
python3 -c "
|
|
150
|
-
import json, sys
|
|
151
|
-
f = sys.argv[1]; org = sys.argv[2]
|
|
152
|
-
d = json.load(open(f))
|
|
153
|
-
if 'orgName' not in d:
|
|
154
|
-
d['orgName'] = org
|
|
155
|
-
open(f, 'w').write(json.dumps(d, indent=2))
|
|
156
|
-
" "$LOOP_FILE" "${org_name}" 2>/dev/null || true
|
|
157
|
-
fi
|
|
158
|
-
fi
|
|
159
|
-
```
|
|
71
|
+
Invoke `Skill("mastermind-skills:_repeat")` now to execute the REPEAT POSTAMBLE. This is a required tool call — do not skip it.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<!-- LEGACY-ORG-V1 — Start a saved org as a persistent, prompt-orchestrated agent organization. The boss agent coordinates all roles; agents pick up tasks from a shared board and run until stopped. Reach it only via /mastermind:runorgv1. -->
|
|
2
|
+
|
|
3
|
+
> **LEGACY-ORG-V1 (2026-07): superseded by `monomind org run <name>` (SDK org runtime v2), delegated to by default via `/mastermind:runorg`.**
|
|
4
|
+
> This prompt-orchestrated path has no delivery guarantees and no ground-truth event stream.
|
|
5
|
+
> It remains only for orgs not yet migrated. New orgs MUST use the daemon. Reach this legacy path only via `/mastermind:runorgv1`.
|
|
6
|
+
|
|
7
|
+
**If $ARGUMENTS is empty:** List saved orgs and display the following.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
**MASTERMIND: RUN ORG**
|
|
12
|
+
|
|
13
|
+
Running an org starts an autonomous agent organization. There are two modes:
|
|
14
|
+
|
|
15
|
+
**Persistent org** (no schedule): a boss agent loads the org definition, assigns work to specialists from a shared board, and loops indefinitely. Stop with `/mastermind:stoporg --org <name>`.
|
|
16
|
+
|
|
17
|
+
**Scheduled org** (created with `--schedule`): sets the org to `active` and runs the first iteration immediately. Subsequent iterations are self-scheduled via ScheduleWakeup. The loop stops cleanly within one interval after `/mastermind:stoporg --org <name>`.
|
|
18
|
+
|
|
19
|
+
**Your saved orgs:**
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx -y monomind@latest org list 2>/dev/null \
|
|
23
|
+
|| ls .monomind/orgs/*.json 2>/dev/null | grep -vE -- '-(state|goals|threads|activity|approvals|members|secrets|budgets|routines|issues|projects|workspaces|worktrees|environments|plugins|adapters|join-requests|bootstrap|project-workspaces|approval-comments|skills)\.json$' | xargs -I{} basename {} .json 2>/dev/null \
|
|
24
|
+
|| echo "(none — run /mastermind:createorg to define one)"
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Usage:**
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
/mastermind:runorgv1 --org <name>
|
|
31
|
+
|
|
32
|
+
/mastermind:runorgv1 --org content-team --task "Publish the Q2 product roundup post by Friday"
|
|
33
|
+
|
|
34
|
+
/mastermind:runorgv1 --org research-pod "Focus this week on competitor pricing changes"
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Options:**
|
|
38
|
+
`--org <name>` — which saved org to start (required; prompted if omitted)
|
|
39
|
+
`--task <task>` — override the org's default goal for this run
|
|
40
|
+
Any remaining text is passed as additional context to the boss agent.
|
|
41
|
+
|
|
42
|
+
No orgs yet? Run `/mastermind:createorg` to define one.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
**If $ARGUMENTS is non-empty:** Execute the flow below.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
**STEP 0 — Extract loop-control flags (do this FIRST, before any other parsing)**
|
|
51
|
+
|
|
52
|
+
Scan `$ARGUMENTS` for these flags and store their values. Remove them from the argument string before Step 1:
|
|
53
|
+
|
|
54
|
+
| Flag | Variable | Default |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| `--rep <N>` | `current_rep = N` | absent |
|
|
57
|
+
| `--loop <id>` | `LOOP_ID = id` | absent |
|
|
58
|
+
| `--tillend` | `tillend_mode = true` | false |
|
|
59
|
+
| `--maxruns <N>` | `tillend_maxruns = N` | 50 |
|
|
60
|
+
| `--wait <N>` | `wait_seconds = N` | 60 |
|
|
61
|
+
| `--repeat <N>` | `repeat_count = N` | 0 |
|
|
62
|
+
|
|
63
|
+
⚠️ **CRITICAL — CONTINUATION RUNS DO NOT SKIP WORK.** When `--rep N` is present, this is a scheduled continuation triggered by ScheduleWakeup. The org's FULL work cycle MUST still execute every time: session variables → session:start event → Skill("mastermind-skills:runorgv1") → session:complete event. NEVER short-circuit or skip the org work because `--rep` is present. The `--rep` / `--loop` flags are only consumed by `Skill("mastermind-skills:_repeat")` at the end.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
**STEP 1 — Parse org-specific flags**
|
|
68
|
+
|
|
69
|
+
From the remaining `$ARGUMENTS` (after loop flags removed in Step 0):
|
|
70
|
+
- `--org <name>` → org_name = <name>
|
|
71
|
+
- `--task <task>` → task_override = <task> (if omitted, task_override = null — the skill uses org's stored goal)
|
|
72
|
+
- Remaining text = additional context passed to the boss agent
|
|
73
|
+
|
|
74
|
+
If `--org` is not provided, list saved orgs and ask which to run:
|
|
75
|
+
```bash
|
|
76
|
+
orgs=$(ls .monomind/orgs/*.json 2>/dev/null | xargs -I{} basename {} .json 2>/dev/null)
|
|
77
|
+
if [ -z "$orgs" ]; then
|
|
78
|
+
echo "No saved orgs found. Run /mastermind:createorg first."
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
81
|
+
echo "$orgs"
|
|
82
|
+
```
|
|
83
|
+
Ask: "Which org would you like to start? Available: <list from above>"
|
|
84
|
+
|
|
85
|
+
Verify the org file exists before proceeding:
|
|
86
|
+
```bash
|
|
87
|
+
[ -f ".monomind/orgs/${org_name}.json" ] || { echo "Org '${org_name}' not found."; exit 1; }
|
|
88
|
+
```
|
|
89
|
+
If the file does not exist, stop and suggest running `/mastermind:createorg --name ${org_name}`.
|
|
90
|
+
|
|
91
|
+
Load brain context for the `ops` domain (follow _protocol.md Brain Load Procedure, namespace: `ops`).
|
|
92
|
+
|
|
93
|
+
Resolve session ID and project root:
|
|
94
|
+
```bash
|
|
95
|
+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
|
|
96
|
+
CTRL_URL=$(jq -r '.url // "http://localhost:4242"' "$REPO_ROOT/.monomind/control.json" 2>/dev/null || echo "http://localhost:4242")
|
|
97
|
+
# Reuse the loop's original sessionId for continuation runs (keeps all reps under one session)
|
|
98
|
+
if [ -n "${LOOP_ID:-}" ] && [ -f ".monomind/loops/${LOOP_ID}.json" ]; then
|
|
99
|
+
session_id=$(jq -r '.sessionId // empty' ".monomind/loops/${LOOP_ID}.json" 2>/dev/null)
|
|
100
|
+
fi
|
|
101
|
+
session_id="${session_id:-mm-$(date -u +%Y%m%dT%H%M%S)}"
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Emit `session:start` to dashboard:
|
|
105
|
+
```bash
|
|
106
|
+
curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/.monomind/dashboard-token" 2>/dev/null || true)" \
|
|
107
|
+
-H "Content-Type: application/json" \
|
|
108
|
+
-d "$(jq -cn \
|
|
109
|
+
--arg session "$session_id" \
|
|
110
|
+
--arg org "$org_name" \
|
|
111
|
+
--arg proj "$REPO_ROOT" \
|
|
112
|
+
'{type:"session:start",session:$session,domain:"ops",prompt:("Running org: "+$org),mode:"auto",project:$proj,ts:(now*1000|floor)}')" || true
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Emit `domain:dispatch`:
|
|
116
|
+
```bash
|
|
117
|
+
curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/.monomind/dashboard-token" 2>/dev/null || true)" \
|
|
118
|
+
-H "Content-Type: application/json" \
|
|
119
|
+
-d "$(jq -cn \
|
|
120
|
+
--arg session "$session_id" \
|
|
121
|
+
--arg org "$org_name" \
|
|
122
|
+
--arg proj "$REPO_ROOT" \
|
|
123
|
+
'{type:"domain:dispatch",session:$session,domain:"ops",cmd:("Starting org "+$org+" as persistent daemon"),project:$proj,ts:(now*1000|floor)}')" || true
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Invoke `Skill("mastermind-skills:runorgv1")` passing: brain_context, org_name: `$org_name`, session_id: `$session_id`, task: task_override, caller: "command".
|
|
127
|
+
|
|
128
|
+
After the skill spawns the boss agent and returns: note the status. Emit `session:complete`:
|
|
129
|
+
```bash
|
|
130
|
+
curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}/.monomind/dashboard-token" 2>/dev/null || true)" \
|
|
131
|
+
-H "Content-Type: application/json" \
|
|
132
|
+
-d "$(jq -cn \
|
|
133
|
+
--arg session "$session_id" \
|
|
134
|
+
--arg status "<status>" \
|
|
135
|
+
--arg proj "$REPO_ROOT" \
|
|
136
|
+
'{type:"session:complete",session:$session,domain:"ops",status:$status,domains:["ops"],project:$proj,ts:(now*1000|floor)}')" || true
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Follow _protocol.md Brain Write Procedure for domain `ops`.
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
**MANDATORY — invoke `Skill("mastermind-skills:_repeat")` now.** This is required regardless of how the skill above completed, regardless of whether you think the work is done, regardless of whether you plan to end your response. For `--repeat N`: the count is non-negotiable — all N runs must happen. For `--tillend`: only a verified empty round (confirmed by git diff) stops the loop. Do not end your response without invoking this skill.
|
|
143
|
+
|
|
144
|
+
After the REPEAT POSTAMBLE completes, if a loop was started or continued (LOOP_ID is set), write the org name into the loop state file so the dashboard can detect running status:
|
|
145
|
+
```bash
|
|
146
|
+
if [ -n "${LOOP_ID:-}" ]; then
|
|
147
|
+
LOOP_FILE=".monomind/loops/${LOOP_ID}.json"
|
|
148
|
+
if [ -f "$LOOP_FILE" ]; then
|
|
149
|
+
python3 -c "
|
|
150
|
+
import json, sys
|
|
151
|
+
f = sys.argv[1]; org = sys.argv[2]
|
|
152
|
+
d = json.load(open(f))
|
|
153
|
+
if 'orgName' not in d:
|
|
154
|
+
d['orgName'] = org
|
|
155
|
+
open(f, 'w').write(json.dumps(d, indent=2))
|
|
156
|
+
" "$LOOP_FILE" "${org_name}" 2>/dev/null || true
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
```
|
|
@@ -326,8 +326,23 @@ module.exports = {
|
|
|
326
326
|
// when the server is down or still warming.
|
|
327
327
|
try {
|
|
328
328
|
var sbPrompt = String(prompt || '');
|
|
329
|
-
// Skip slash commands and
|
|
330
|
-
|
|
329
|
+
// Skip slash commands and low-content prompts — injection would be
|
|
330
|
+
// noise. A prompt earns injection only when it carries at least two
|
|
331
|
+
// substantive terms ("what is next" / "ok go ahead" / "thanks" carry
|
|
332
|
+
// zero-to-one and must stay quiet; a real question about the project
|
|
333
|
+
// clears this easily).
|
|
334
|
+
var _SB_FILLER = new Set(['what', 'whats', 'is', 'are', 'was', 'were', 'the', 'this', 'that', 'these', 'those',
|
|
335
|
+
'next', 'now', 'then', 'and', 'but', 'for', 'not', 'you', 'your', 'can', 'could', 'should', 'would', 'will',
|
|
336
|
+
'lets', 'let', 'make', 'made', 'making', 'please', 'okay', 'yes', 'yeah', 'sure', 'thanks', 'thank',
|
|
337
|
+
'ahead', 'continue', 'proceed', 'more', 'again', 'how', 'why', 'when', 'where', 'who', 'which',
|
|
338
|
+
'with', 'about', 'from', 'into', 'onto', 'over', 'under', 'all', 'any', 'some', 'one', 'two', 'just',
|
|
339
|
+
'like', 'want', 'need', 'get', 'got', 'here', 'there', 'still', 'also', 'too', 'very', 'really',
|
|
340
|
+
'them', 'they', 'their', 'theirs', 'its', 'our', 'ours', 'him', 'her', 'his', 'hers',
|
|
341
|
+
'order', 'done', 'doing', 'did', 'does', 'goes', 'going', 'went', 'come', 'came', 'good', 'great', 'nice', 'fine']);
|
|
342
|
+
var _sbSubstantive = sbPrompt.toLowerCase().split(/[^a-z0-9]+/).filter(function(t) {
|
|
343
|
+
return t.length >= 3 && !_SB_FILLER.has(t);
|
|
344
|
+
});
|
|
345
|
+
if (_sbSubstantive.length >= 2 && sbPrompt.charAt(0) !== '/') {
|
|
331
346
|
var sbKnowledgeDir = path.join(CWD, '.monomind', 'knowledge');
|
|
332
347
|
if (fs.existsSync(path.join(sbKnowledgeDir, 'chunks.jsonl'))) {
|
|
333
348
|
var sbHits = null;
|
|
@@ -366,6 +381,34 @@ module.exports = {
|
|
|
366
381
|
'second-brain-inject'
|
|
367
382
|
);
|
|
368
383
|
}
|
|
384
|
+
// Relevance floor: injecting weak matches pollutes every prompt's
|
|
385
|
+
// context — below 0.35 the excerpt is more likely noise than help.
|
|
386
|
+
if (sbHits) sbHits = sbHits.filter(function(h) { return (h.score || 0) >= 0.35; });
|
|
387
|
+
|
|
388
|
+
// Telemetry: append one JSONL line per evaluated prompt so the
|
|
389
|
+
// thresholds above can be tuned from real usage (and misses can
|
|
390
|
+
// seed the golden-set eval). Prompt text is NOT logged.
|
|
391
|
+
try {
|
|
392
|
+
var sbMetricsDir = path.join(CWD, '.monomind', 'metrics');
|
|
393
|
+
fs.mkdirSync(sbMetricsDir, { recursive: true });
|
|
394
|
+
var sbMetricsFile = path.join(sbMetricsDir, 'second-brain.jsonl');
|
|
395
|
+
try {
|
|
396
|
+
if (fs.existsSync(sbMetricsFile) && fs.statSync(sbMetricsFile).size > 512 * 1024) {
|
|
397
|
+
var sbOld = fs.readFileSync(sbMetricsFile, 'utf-8').trim().split('\n');
|
|
398
|
+
fs.writeFileSync(sbMetricsFile, sbOld.slice(-500).join('\n') + '\n', 'utf-8');
|
|
399
|
+
}
|
|
400
|
+
} catch (_) {}
|
|
401
|
+
fs.appendFileSync(sbMetricsFile, JSON.stringify({
|
|
402
|
+
ts: Date.now(),
|
|
403
|
+
method: sbMethod,
|
|
404
|
+
hits: sbHits ? sbHits.length : 0,
|
|
405
|
+
topScore: sbHits && sbHits[0] ? Number((sbHits[0].score || 0).toFixed(3)) : null,
|
|
406
|
+
promptLen: sbPrompt.length,
|
|
407
|
+
terms: _sbSubstantive.length,
|
|
408
|
+
injected: !!(sbHits && sbHits.length > 0),
|
|
409
|
+
}) + '\n', 'utf-8');
|
|
410
|
+
} catch (_) { /* telemetry never blocks */ }
|
|
411
|
+
|
|
369
412
|
if (sbHits && sbHits.length > 0) {
|
|
370
413
|
var sbLines = ['[SECOND_BRAIN] ' + sbHits.length + ' relevant excerpt(s) (' + sbMethod + ') from the project knowledge base:'];
|
|
371
414
|
for (var sbI = 0; sbI < sbHits.length; sbI++) {
|
|
@@ -358,6 +358,17 @@ module.exports = {
|
|
|
358
358
|
var _kbLastCheck = 0;
|
|
359
359
|
try { _kbLastCheck = JSON.parse(fs.readFileSync(_kbMarkerPath, 'utf-8')).ts || 0; } catch (_) {}
|
|
360
360
|
if (Date.now() - _kbLastCheck > 30 * 60 * 1000) {
|
|
361
|
+
// Marker BEFORE the scan (not only when dirty): the 2000-stat walk
|
|
362
|
+
// itself is what needs rate-limiting — on a clean tree it used to
|
|
363
|
+
// re-run on every single session start. Fail-closed: skip when the
|
|
364
|
+
// marker can't be written, so an unwritable disk can't cause
|
|
365
|
+
// per-session scans either.
|
|
366
|
+
var _kbMarkerOk = false;
|
|
367
|
+
try {
|
|
368
|
+
fs.writeFileSync(_kbMarkerPath, JSON.stringify({ ts: Date.now() }), 'utf-8');
|
|
369
|
+
_kbMarkerOk = true;
|
|
370
|
+
} catch (_) {}
|
|
371
|
+
if (!_kbMarkerOk) throw new Error('reindex marker unwritable — skipping scan');
|
|
361
372
|
// Cheap bounded scan: any document changed since the last ingest?
|
|
362
373
|
var _DOC_EXT = { '.md': 1, '.txt': 1, '.pdf': 1, '.docx': 1 };
|
|
363
374
|
var _kbDirty = false;
|
|
@@ -380,24 +391,20 @@ module.exports = {
|
|
|
380
391
|
};
|
|
381
392
|
_kbWalk(CWD, 0);
|
|
382
393
|
if (_kbDirty) {
|
|
383
|
-
var
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
});
|
|
398
|
-
_kbChild.unref();
|
|
399
|
-
console.log('[KNOWLEDGE_REINDEX] changed documents detected — re-ingesting in background');
|
|
400
|
-
}
|
|
394
|
+
var _kbSpawn = require('child_process').spawn;
|
|
395
|
+
var _kbChild = _kbSpawn('npx', ['-y', 'monomind@latest', 'doc', 'ingest', '.'], {
|
|
396
|
+
cwd: CWD,
|
|
397
|
+
detached: true,
|
|
398
|
+
stdio: 'ignore',
|
|
399
|
+
env: process.env,
|
|
400
|
+
shell: process.platform === 'win32',
|
|
401
|
+
windowsHide: true,
|
|
402
|
+
});
|
|
403
|
+
// Without an error listener, a missing npx binary emits an
|
|
404
|
+
// unhandled 'error' event and crashes the whole session-start hook.
|
|
405
|
+
_kbChild.on('error', function () { /* npx unavailable — reindex on a later session */ });
|
|
406
|
+
_kbChild.unref();
|
|
407
|
+
console.log('[KNOWLEDGE_REINDEX] changed documents detected — re-ingesting in background');
|
|
401
408
|
}
|
|
402
409
|
}
|
|
403
410
|
}
|