@monoes/monomindcli 2.3.3 → 2.4.0

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.
Files changed (69) hide show
  1. package/.claude/commands/mastermind/{approve.md → approvev1.md} +12 -9
  2. package/.claude/commands/mastermind/help.md +18 -0
  3. package/.claude/commands/mastermind/master.md +3 -3
  4. package/.claude/commands/mastermind/runorg.md +19 -107
  5. package/.claude/commands/mastermind/runorgv1.md +159 -0
  6. package/.claude/helpers/handlers/route-handler.cjs +50 -4
  7. package/.claude/helpers/handlers/session-restore-handler.cjs +25 -18
  8. package/.claude/skills/mastermind-skills/agents.md +5 -1
  9. package/.claude/skills/mastermind-skills/{approve.md → approvev1.md} +8 -5
  10. package/.claude/skills/mastermind-skills/env.md +7 -2
  11. package/.claude/skills/mastermind-skills/{heartbeat.md → heartbeatv1.md} +7 -4
  12. package/.claude/skills/mastermind-skills/inbox.md +14 -2
  13. package/.claude/skills/mastermind-skills/instance.md +3 -1
  14. package/.claude/skills/mastermind-skills/org-settings.md +4 -1
  15. package/.claude/skills/mastermind-skills/orgs.md +14 -13
  16. package/.claude/skills/mastermind-skills/orgstatus.md +19 -8
  17. package/.claude/skills/mastermind-skills/projects.md +3 -0
  18. package/.claude/skills/mastermind-skills/runorg.md +37 -725
  19. package/.claude/skills/mastermind-skills/runorgv1.md +731 -0
  20. package/.claude/skills/mastermind-skills/stoporg.md +10 -3
  21. package/.claude/skills/mastermind-skills/tasks.md +4 -1
  22. package/README.md +37 -4
  23. package/dist/src/commands/cleanup.d.ts.map +1 -1
  24. package/dist/src/commands/cleanup.js +30 -8
  25. package/dist/src/commands/cleanup.js.map +1 -1
  26. package/dist/src/commands/doc.d.ts.map +1 -1
  27. package/dist/src/commands/doc.js +36 -8
  28. package/dist/src/commands/doc.js.map +1 -1
  29. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  30. package/dist/src/commands/doctor-project-checks.js +23 -10
  31. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  32. package/dist/src/commands/org-observe.d.ts.map +1 -1
  33. package/dist/src/commands/org-observe.js +30 -26
  34. package/dist/src/commands/org-observe.js.map +1 -1
  35. package/dist/src/commands/org.d.ts.map +1 -1
  36. package/dist/src/commands/org.js +52 -2
  37. package/dist/src/commands/org.js.map +1 -1
  38. package/dist/src/index.d.ts.map +1 -1
  39. package/dist/src/index.js +7 -0
  40. package/dist/src/index.js.map +1 -1
  41. package/dist/src/knowledge/document-pipeline.d.ts +2 -0
  42. package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
  43. package/dist/src/knowledge/document-pipeline.js +148 -45
  44. package/dist/src/knowledge/document-pipeline.js.map +1 -1
  45. package/dist/src/memory/memory-bridge.d.ts +9 -0
  46. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  47. package/dist/src/memory/memory-bridge.js +115 -68
  48. package/dist/src/memory/memory-bridge.js.map +1 -1
  49. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  50. package/dist/src/orgrt/daemon.js +45 -9
  51. package/dist/src/orgrt/daemon.js.map +1 -1
  52. package/dist/src/orgrt/mailbox.d.ts +23 -0
  53. package/dist/src/orgrt/mailbox.d.ts.map +1 -1
  54. package/dist/src/orgrt/mailbox.js +33 -1
  55. package/dist/src/orgrt/mailbox.js.map +1 -1
  56. package/dist/src/orgrt/migrate.d.ts +26 -0
  57. package/dist/src/orgrt/migrate.d.ts.map +1 -0
  58. package/dist/src/orgrt/migrate.js +111 -0
  59. package/dist/src/orgrt/migrate.js.map +1 -0
  60. package/dist/src/orgrt/reporting.js +8 -1
  61. package/dist/src/orgrt/reporting.js.map +1 -1
  62. package/dist/src/orgrt/session.d.ts.map +1 -1
  63. package/dist/src/orgrt/session.js +8 -2
  64. package/dist/src/orgrt/session.js.map +1 -1
  65. package/dist/src/ui/dashboard.html +44 -0
  66. package/dist/src/ui/orgs.html +2 -2
  67. package/dist/src/ui/server.mjs +25 -4
  68. package/dist/tsconfig.tsbuildinfo +1 -1
  69. package/package.json +2 -2
@@ -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 an autonomous org. Agents request human approval before executing sensitive actions (publishing content, sending emails, making purchases, modifying infrastructure).
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:approve --org <name> List all pending approvals
15
- /mastermind:approve --org <name> --action approve --id <id>
16
- /mastermind:approve --org <name> --action reject --id <id> --reason "Too risky"
17
- /mastermind:approve --org <name> --action inspect --id <id>
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:approve")` passing: brain_context, org_name, action, approval_id, reason, caller: "command".
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:approve")` |
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; boss agent assigns work to all roles
257
- `/mastermind:approve` — review and action pending approval requests from running org agents
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 as a persistent autonomous agent organization. The boss agent coordinates all roles; agents pick up tasks from a shared board and run until stopped. -->
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
- > **DEPRECATED (2026-07): superseded by `monomind org run <name>` (SDK org runtime v2).**
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 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
- ```
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
- **If $ARGUMENTS is non-empty:** Execute the flow below.
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
- **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: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
- **STEP 1 — Parse org-specific flags**
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
- 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; }
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
- Resolve session ID and project root:
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
- 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
- ```
57
+ Invoke `Skill("mastermind-skills:runorg")` passing: org_name: `$org_name`, task: task_override, session_id: `$session_id`, caller: "command".
114
58
 
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: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
- --arg proj "$REPO_ROOT" \
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 trivial prompts — injection would be noise.
330
- if (sbPrompt.length >= 12 && sbPrompt.charAt(0) !== '/') {
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;
@@ -353,7 +368,10 @@ module.exports = {
353
368
  if (sbResp.ok) {
354
369
  var sbData = await sbResp.json();
355
370
  if (sbData && Array.isArray(sbData.results) && sbData.results.length > 0) {
356
- sbHits = sbData.results.map(function(r) { return { key: r.key, value: r.content, score: r.score, metadata: {} }; });
371
+ sbHits = sbData.results.map(function(r) {
372
+ var src = (r.tags || []).find(function(t) { return t.indexOf('src:') === 0; });
373
+ return { key: r.key, value: r.content, score: r.score, global: !!r.global, metadata: src ? { filePath: src.slice(4) } : {} };
374
+ });
357
375
  sbMethod = sbData.method === 'semantic' ? 'semantic' : 'keyword';
358
376
  }
359
377
  }
@@ -366,13 +384,41 @@ module.exports = {
366
384
  'second-brain-inject'
367
385
  );
368
386
  }
387
+ // Relevance floor: injecting weak matches pollutes every prompt's
388
+ // context — below 0.35 the excerpt is more likely noise than help.
389
+ if (sbHits) sbHits = sbHits.filter(function(h) { return (h.score || 0) >= 0.35; });
390
+
391
+ // Telemetry: append one JSONL line per evaluated prompt so the
392
+ // thresholds above can be tuned from real usage (and misses can
393
+ // seed the golden-set eval). Prompt text is NOT logged.
394
+ try {
395
+ var sbMetricsDir = path.join(CWD, '.monomind', 'metrics');
396
+ fs.mkdirSync(sbMetricsDir, { recursive: true });
397
+ var sbMetricsFile = path.join(sbMetricsDir, 'second-brain.jsonl');
398
+ try {
399
+ if (fs.existsSync(sbMetricsFile) && fs.statSync(sbMetricsFile).size > 512 * 1024) {
400
+ var sbOld = fs.readFileSync(sbMetricsFile, 'utf-8').trim().split('\n');
401
+ fs.writeFileSync(sbMetricsFile, sbOld.slice(-500).join('\n') + '\n', 'utf-8');
402
+ }
403
+ } catch (_) {}
404
+ fs.appendFileSync(sbMetricsFile, JSON.stringify({
405
+ ts: Date.now(),
406
+ method: sbMethod,
407
+ hits: sbHits ? sbHits.length : 0,
408
+ topScore: sbHits && sbHits[0] ? Number((sbHits[0].score || 0).toFixed(3)) : null,
409
+ promptLen: sbPrompt.length,
410
+ terms: _sbSubstantive.length,
411
+ injected: !!(sbHits && sbHits.length > 0),
412
+ }) + '\n', 'utf-8');
413
+ } catch (_) { /* telemetry never blocks */ }
414
+
369
415
  if (sbHits && sbHits.length > 0) {
370
416
  var sbLines = ['[SECOND_BRAIN] ' + sbHits.length + ' relevant excerpt(s) (' + sbMethod + ') from the project knowledge base:'];
371
417
  for (var sbI = 0; sbI < sbHits.length; sbI++) {
372
418
  var sbH = sbHits[sbI];
373
419
  var sbSrc = (sbH.metadata && sbH.metadata.filePath) ? String(sbH.metadata.filePath).split('/').slice(-2).join('/') : sbH.key;
374
420
  var sbText = String(sbH.value || '').replace(/\s+/g, ' ').slice(0, 240);
375
- sbLines.push(' • [' + sbSrc + '] ' + sbText);
421
+ sbLines.push(' • [' + sbSrc + (sbH.global ? ' · global' : '') + '] ' + sbText);
376
422
  }
377
423
  sbLines.push(' (deeper lookup: mcp__monomind__knowledge_search or `monomind doc search -q "..."`)');
378
424
  console.log(sbLines.join('\n'));
@@ -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 _kbMarkerOk = false;
384
- try {
385
- fs.writeFileSync(_kbMarkerPath, JSON.stringify({ ts: Date.now() }), 'utf-8');
386
- _kbMarkerOk = true;
387
- } catch (_) {}
388
- if (_kbMarkerOk) {
389
- var _kbSpawn = require('child_process').spawn;
390
- var _kbChild = _kbSpawn('npx', ['-y', 'monomind@latest', 'doc', 'ingest', '.'], {
391
- cwd: CWD,
392
- detached: true,
393
- stdio: 'ignore',
394
- env: process.env,
395
- shell: process.platform === 'win32',
396
- windowsHide: true,
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
  }
@@ -51,12 +51,15 @@ stateFile=".monomind/orgs/${org_name}-state.json"
51
51
 
52
52
  jq -r '(.roles // [])[] | "• [\(.id)] \(.title) agent=\(.agent_type) reports_to=\(.reports_to // "none")"' "$orgFile"
53
53
 
54
+ # LEGACY-ORG-V1: the state file's per-agent heartbeat tracking is a v1 concept —
55
+ # v2 orgs report live status via `monomind org status`/`org report` instead.
54
56
  # Overlay runtime status from state file if present
55
57
  if [ -f "$stateFile" ]; then
56
58
  echo ""
57
59
  echo "RUNTIME STATUS:"
58
60
  jq -r '.agents // {} | to_entries[] | " \(.key): \(.value.status // "unknown") last_beat=\(.value.last_heartbeat // "never")"' "$stateFile" 2>/dev/null || true
59
61
  fi
62
+ # end LEGACY-ORG-V1
60
63
  ```
61
64
 
62
65
  Render as table:
@@ -134,6 +137,7 @@ curl -s -X POST "${CTRL_URL}/api/mastermind/event" -H "x-monomind-token: $(cat "
134
137
 
135
138
  ### pause / resume
136
139
 
140
+ <!-- LEGACY-ORG-V1: the agent state/heartbeat file this pauses is a v1 concept. -->
137
141
  Update state file:
138
142
 
139
143
  ```bash
@@ -169,7 +173,7 @@ org: <org_name>
169
173
  agents_count: <N>
170
174
  ```
171
175
 
172
- Print summary and any suggested next actions (e.g. "Run /mastermind:heartbeat to trigger a manual heartbeat for this agent").
176
+ Print summary and any suggested next actions (e.g. "Run /mastermind:heartbeatv1 to trigger a manual heartbeat for this agent").
173
177
 
174
178
  ---
175
179
 
@@ -1,13 +1,16 @@
1
1
  ---
2
- name: mastermind-approve
3
- description: Mastermind approve — review and action pending approval requests from agents in a running org. Agents can request human approval before proceeding with sensitive actions.
2
+ name: mastermind-approvev1
3
+ description: "LEGACY-ORG-V1 (2026-07): v2 approvals arrive as question events in the dashboard Human Input tab — no skill needed. Mastermind approvev1 — review and action pending approval requests from agents in a running v1 (prompt-orchestrated) org. Agents can request human approval before proceeding with sensitive actions. Reach it only via `/mastermind:approvev1`."
4
4
  type: domain-skill
5
5
  default_mode: confirm
6
6
  ---
7
7
 
8
- # Mastermind Approve
8
+ # Mastermind Approve (v1, legacy)
9
9
 
10
- This skill is invoked by `mastermind:approve` or directly via `/mastermind:approve`.
10
+ > **LEGACY-ORG-V1 file-based approval queue for prompt-orchestrated v1 orgs. Reach it only via `/mastermind:approvev1`.**
11
+ > v2 approvals arrive as `question` events in the dashboard Human Input tab — there is no v2 approve skill, the dashboard UI is the approval surface. This skill remains only for orgs not yet migrated off the v1 `board_id`/`topology` config shape.
12
+
13
+ This skill is invoked by `mastermind:approvev1` or directly via `/mastermind:approvev1`.
11
14
 
12
15
  ---
13
16
 
@@ -150,7 +153,7 @@ jq --arg id "$approval_id" \
150
153
 
151
154
  2. Emit `org:approval:requested` event to dashboard (so the human is notified).
152
155
 
153
- 3. Poll for the approval decision — check the approvals file first (authoritative, updated by both the dashboard UI and `/mastermind:approve`), then fall back to memory:
156
+ 3. Poll for the approval decision — check the approvals file first (authoritative, updated by both the dashboard UI and `/mastermind:approvev1`), then fall back to memory:
154
157
  ```bash
155
158
  approvalsFile=".monomind/orgs/${orgName}-approvals.json"
156
159
  while true; do