monomind 2.1.0 → 2.1.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.
Files changed (57) hide show
  1. package/README.md +77 -94
  2. package/package.json +3 -3
  3. package/packages/@monomind/cli/.claude/commands/mastermind/createorg.md +8 -9
  4. package/packages/@monomind/cli/.claude/helpers/handlers/capture-handler.cjs +24 -10
  5. package/packages/@monomind/cli/.claude/helpers/handlers/gates-handler.cjs +2 -2
  6. package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +29 -0
  7. package/packages/@monomind/cli/.claude/helpers/handlers/session-handler.cjs +35 -23
  8. package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +21 -0
  9. package/packages/@monomind/cli/.claude/helpers/utils/monograph.cjs +73 -2
  10. package/packages/@monomind/cli/.claude/skills/mastermind-skills/createorg.md +91 -701
  11. package/packages/@monomind/cli/.claude/skills/mastermind-skills/org-settings.md +46 -47
  12. package/packages/@monomind/cli/.claude/skills/mastermind-skills/runorg.md +12 -1
  13. package/packages/@monomind/cli/README.md +77 -94
  14. package/packages/@monomind/cli/dist/src/browser/workflow/store.d.ts +2 -2
  15. package/packages/@monomind/cli/dist/src/commands/browse.d.ts +1 -1
  16. package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +5 -0
  17. package/packages/@monomind/cli/dist/src/commands/org.js +46 -29
  18. package/packages/@monomind/cli/dist/src/commands/platforms.d.ts +1 -1
  19. package/packages/@monomind/cli/dist/src/init/executor.js +30 -6
  20. package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.d.ts +8 -8
  21. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/types.d.ts +31 -31
  22. package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +5 -1
  23. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +28 -3
  24. package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/prioritize-gaps.d.ts +36 -36
  25. package/packages/@monomind/cli/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts +4 -4
  26. package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.d.ts +12 -0
  27. package/packages/@monomind/cli/dist/src/memory/sona-optimizer.d.ts +12 -0
  28. package/packages/@monomind/cli/dist/src/orgrt/broker.d.ts +3 -1
  29. package/packages/@monomind/cli/dist/src/orgrt/broker.js +8 -3
  30. package/packages/@monomind/cli/dist/src/orgrt/bus.d.ts +5 -1
  31. package/packages/@monomind/cli/dist/src/orgrt/bus.js +5 -1
  32. package/packages/@monomind/cli/dist/src/orgrt/daemon.d.ts +35 -1
  33. package/packages/@monomind/cli/dist/src/orgrt/daemon.js +190 -21
  34. package/packages/@monomind/cli/dist/src/orgrt/forwarder.js +47 -10
  35. package/packages/@monomind/cli/dist/src/orgrt/inbox.d.ts +11 -0
  36. package/packages/@monomind/cli/dist/src/orgrt/inbox.js +56 -0
  37. package/packages/@monomind/cli/dist/src/orgrt/policy.d.ts +5 -1
  38. package/packages/@monomind/cli/dist/src/orgrt/policy.js +58 -5
  39. package/packages/@monomind/cli/dist/src/orgrt/server.d.ts +3 -2
  40. package/packages/@monomind/cli/dist/src/orgrt/server.js +31 -40
  41. package/packages/@monomind/cli/dist/src/orgrt/session.d.ts +11 -1
  42. package/packages/@monomind/cli/dist/src/orgrt/session.js +32 -1
  43. package/packages/@monomind/cli/dist/src/orgrt/test-loop.js +8 -8
  44. package/packages/@monomind/cli/dist/src/orgrt/types.d.ts +53 -53
  45. package/packages/@monomind/cli/dist/src/output.d.ts +29 -29
  46. package/packages/@monomind/cli/dist/src/output.js +10 -2
  47. package/packages/@monomind/cli/dist/src/pricing/model-pricing.d.ts +1 -1
  48. package/packages/@monomind/cli/dist/src/types.d.ts +2 -2
  49. package/packages/@monomind/cli/dist/src/ui/collector.mjs +20 -5
  50. package/packages/@monomind/cli/dist/src/ui/dashboard.html +465 -500
  51. package/packages/@monomind/cli/dist/src/ui/orgs-files.js +192 -0
  52. package/packages/@monomind/cli/dist/src/ui/orgs.html +21 -52
  53. package/packages/@monomind/cli/dist/src/ui/server.mjs +174 -164
  54. package/packages/@monomind/cli/package.json +12 -16
  55. package/packages/@monomind/cli/scripts/publish.sh +6 -0
  56. package/scripts/generate-agent-avatars.mjs +3 -3
  57. package/packages/@monomind/cli/dist/src/orgrt/live.html +0 -56
package/README.md CHANGED
@@ -1,12 +1,12 @@
1
1
  <p align="center">
2
- <img src="assets/banner.png" alt="Monomind" width="600" />
2
+ <img src="https://raw.githubusercontent.com/monoes/monomind/main/assets/banner.png" alt="Monomind" width="600" />
3
3
  </p>
4
4
 
5
5
  <h1 align="center">Monomind</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>Hire an AI team. Set a goal. Walk away.</strong><br/>
9
- Autonomous Claude Code orchestration with persistent memory, self-coordinating agent orgs, and a codebase knowledge graph.
8
+ <strong>An open-source MCP server that extends Claude Code with a codebase knowledge graph, persistent memory, and multi-agent coordination.</strong><br/>
9
+ MIT licensed &middot; Fully local &middot; No data leaves your machine
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -30,126 +30,106 @@
30
30
 
31
31
  ## What is Monomind?
32
32
 
33
- Claude Code is already powerful. Monomind makes it **run itself**.
33
+ Monomind is an **open-source CLI and MCP server** that plugs into Claude Code via the standard [Model Context Protocol](https://modelcontextprotocol.io/). It adds capabilities that Claude Code doesn't ship with out of the box:
34
34
 
35
- Install once. Wire it into Claude Code. Then instead of prompting Claude to do individual tasks, you tell Monomind what outcome you want and it assembles a team, coordinates the work, and delivers.
35
+ - **Codebase knowledge graph** tree-sitter parses your code into a SQLite-backed graph of files, functions, classes, and their relationships. Query imports, callers, and blast radius before making changes.
36
+ - **Persistent memory** — a JSON pattern store with episodic recall that survives across sessions. Agents and orgs share context without re-prompting.
37
+ - **Multi-agent coordination** — in-session, spawn ad-hoc agent teams via Claude Code's Task tool; for persistent background work, `monomind org run` starts a real SDK-backed daemon with policy-gated role agents and a live dashboard.
38
+ - **Reusable slash commands** — 30+ development workflows (build, review, debug, TDD, architecture) available as `/mastermind:*` commands inside Claude Code.
36
39
 
37
40
  ```bash
38
- # Assemble an AI content team and let it run
39
- /mastermind:createorg content-team "publish 3 SEO-optimized posts per week"
40
- /mastermind:runorg --org content-team
41
-
42
- # Or run the autonomous code improvement loop
43
- /mastermind:autodev --tillend --focus security
41
+ npm install -g monomind # MIT licensed, runs entirely on your machine
42
+ cd your-project && monomind init
43
+ claude mcp add monomind -- npx -y monomind@latest mcp start
44
44
  ```
45
45
 
46
- That's it. Come back later.
46
+ ### Trust & Security
47
+
48
+ | Concern | Answer |
49
+ |---|---|
50
+ | **License** | [MIT](LICENSE) — use it however you want |
51
+ | **Data privacy** | Everything runs locally — your code and memory store never leave your machine. The one exception: crash reporting is on by default (`monomind crash-reporting disable` to opt out) — a hard crash in monomind/mono-agent/monotask/mono-clip files a GitHub issue on that tool's own repo via the GitHub API. That's the only network call Monomind itself makes; it never phones a monoes-controlled server. |
52
+ | **Dependencies** | Standard npm packages (tree-sitter, better-sqlite3, sql.js, zod). tree-sitter and better-sqlite3 are native (prebuilt) Node addons, not pure JS/WASM — sql.js is WASM. No post-install scripts that download code. |
53
+ | **Permissions** | Registers as an MCP server — Claude Code controls what tools are available and prompts you before executing anything sensitive. |
54
+ | **Source** | Fully open. Read every line at [github.com/monoes/monomind](https://github.com/monoes/monomind). |
55
+ | **Maintenance** | Active development, regular releases on npm. |
47
56
 
48
57
  ---
49
58
 
50
59
  ## 🏢 Autonomous Organizations
51
60
 
52
- > **This is the headline feature.** Build a persistent AI organization — roles, hierarchy, shared task board and start it as a background daemon that runs without you.
61
+ > **This is the headline feature.** `monomind org run` starts a persistent, SDK-backed daemon that runs an autonomous agent organization — roles, hierarchy, policy-gated tool access, a live dashboard until you stop it.
53
62
 
54
63
  ### The idea
55
64
 
56
- Every business function needs a team. Monomind lets you design that team in one command, then run it forever. The org persists across sessions. It checkpoints, recovers from failures, and coordinates its agents through a shared task board all automatically.
65
+ Every business function needs a team. Define the org once as a JSON file — goal, roles, who reports to whom, per-role tool/file/budget policy — then run it as a real background daemon backed by the Claude Agent SDK. It persists across sessions, streams live into the dashboard Claude Code auto-starts for the project, and can discover and message other Monomind orgs running on the same machine.
57
66
 
58
67
  ```mermaid
59
68
  flowchart TD
60
69
  U(["You"])
61
- CO["/mastermind:createorg\nDefine goal + roles"]
62
- RO["/mastermind:runorg\nStart daemon"]
63
- BOSS["Boss Agent\ncoordinator"]
64
- W["Writer\nContent Creator"]
70
+ DEF["org.json\nGoal + roles + policy"]
71
+ RUN["monomind org run\nStart SDK daemon"]
72
+ BOSS["Boss Agent\nAgent SDK session"]
73
+ W["Writer"]
65
74
  S["SEO Specialist"]
66
75
  R["Reviewer"]
67
- M["Growth Marketer"]
68
- BOARD[("Shared\nTask Board")]
69
- MEM[("Persistent\nMemory")]
76
+ DASH[("Dashboard\n:4242\nauto-started by\nClaude Code hook")]
77
+ XORG[("Other orgs\ncross-process")]
70
78
 
71
- U --> CO --> RO --> BOSS
79
+ U --> DEF --> RUN --> BOSS
72
80
  BOSS -->|spawns| W
73
81
  BOSS -->|spawns| S
74
82
  BOSS -->|spawns| R
75
- BOSS -->|spawns| M
76
- BOSS <-->|claims + reports| BOARD
77
- W <-->|stores output| MEM
78
- S <-->|reads context| MEM
83
+ RUN -->|forwards events| DASH
84
+ RUN <-.->|--cross-process| XORG
79
85
 
80
86
  style BOSS fill:#00D2AA22,stroke:#00D2AA
81
- style BOARD fill:#F59E0B22,stroke:#F59E0B
82
- style MEM fill:#8B5CF622,stroke:#8B5CF6
87
+ style DASH fill:#F59E0B22,stroke:#F59E0B
88
+ style XORG fill:#8B5CF622,stroke:#8B5CF6
83
89
  ```
84
90
 
85
- ### Two commands to a running org
86
-
87
- **Step 1 — Design it:**
88
-
89
- ```
90
- / mastermind:createorg content-team
91
- "Build and publish 3 blog posts per week on AI dev tools"
92
-
93
- Deriving roles from goal...
94
-
95
- ╔ ORG: content-team
96
- ║ TOPOLOGY: star (5 roles)
97
-
98
- boss → coordinator
99
- writer → Content Creator
100
- reviewer → reviewer
101
- marketer → Growth Hacker
102
- seo → SEO Specialist
91
+ ### Run one
103
92
 
104
- Type "go" to save, or describe changes.
105
- go
93
+ ```bash
94
+ # .monomind/orgs/<name>.json defines the org: goal, roles, policy.
95
+ # See .monomind/orgs/sample-team.json in a fresh `monomind init` for a working example.
96
+ # Open the project in Claude Code first — a SessionStart hook auto-launches
97
+ # the dashboard at http://localhost:4242 if it isn't already running.
106
98
 
107
- Saved .monomind/orgs/content-team.json
108
- → Run: /mastermind:runorg --org content-team
109
- ```
99
+ monomind org run content-team --task "Build and publish 3 blog posts per week"
110
100
 
111
- **Step 2 Start it:**
101
+ # Boss agent (Claude Agent SDK session) spawns, reads the org goal,
102
+ # assigns work to role agents, coordinates until the task completes
103
+ # or you stop it. Every event streams into the dashboard above.
112
104
 
113
- ```bash
114
- /mastermind:runorg --org content-team
115
-
116
- # Boss agent spawns in background
117
- # Coordinates all roles via shared task board
118
- # Checkpoints every 30 minutes
119
- # Loops until you stop it
105
+ monomind org status content-team # runtime state
106
+ monomind org stop content-team # request a graceful stop
107
+ monomind org list # every org + status
120
108
  ```
121
109
 
122
110
  ### What runs under the hood
123
111
 
124
112
  | What | How |
125
113
  |---|---|
126
- | **Boss agent** | Coordinator type, no supervisor owns the goal |
127
- | **Role agents** | Spawned on demand, specialized by task type |
128
- | **Task board** | Todo Doing Done, shared across all agents |
129
- | **Memory** | All output stored in an org-scoped memory namespace |
130
- | **Checkpoint** | State saved every 30 min survives crashes and restarts |
131
- | **Governance** | `auto` (free), `board` (approve sensitive), `strict` (approve all external actions) |
132
-
133
- ### Topology is auto-derived
134
-
135
- ```mermaid
136
- graph LR
137
- A["1-3 roles"] -->|mesh| B["All-to-all\ndirect comms"]
138
- C["4-6 roles"] -->|star| D["Boss to workers\nfan-out"]
139
- E["7+ roles"] -->|hierarchical| F["Boss to leads to workers\nmiddle management"]
140
- ```
114
+ | **OrgDaemon** | Hosts one or more orgs in a single process; real Claude Agent SDK sessions per role, not simulated |
115
+ | **PolicyEngine** | Per-role gates on tool access, file read/write scope, web access, token budget — enforced, with a full audit trail |
116
+ | **Dashboard** | `org run` forwards every event to the control server on `:4242` (found via `.monomind/control.json`) — that server is auto-launched by a Claude Code SessionStart hook, not by any CLI command; there's no separate per-org dashboard process |
117
+ | **Cross-process comms** | `--cross-process` (default on) lets orgs on different `monomind` processes/projects discover and message each other |
118
+ | **Scheduling** | `monomind org serve` hosts orgs whose definition has a `schedule` field, running them on interval |
141
119
 
142
120
  ### Org management commands
143
121
 
144
122
  ```bash
145
- /mastermind:createorg <name> "<goal>" # design org from a goal
146
- /mastermind:runorg --org <name> # start as background daemon
147
- /mastermind:orgs # list all orgs + status
148
- /mastermind:orgstatus --org <name> # detailed status for one org
149
- /mastermind:stoporg --org <name> # stop a running org
150
- /mastermind:approve # review pending approval requests
123
+ monomind org run <name> [--task "..."] [--cross-process] # start a daemon
124
+ monomind org stop <name> # request a running org to stop
125
+ monomind org status [name] # runtime state for one or all orgs
126
+ monomind org list # list every org + status
127
+ monomind org serve [--cross-process] # host-only mode, runs scheduled orgs
128
+ monomind org delete <name> # remove an org
151
129
  ```
152
130
 
131
+ > **Note:** the older `/mastermind:createorg` + `/mastermind:runorg` prompt-orchestrated flow is deprecated — it has no delivery guarantees or ground-truth event stream. It still runs for orgs not yet migrated, but new orgs should use `monomind org run` directly against a hand-authored `.monomind/orgs/<name>.json`.
132
+
153
133
  ---
154
134
 
155
135
  ## ⚡ The Autonomous Build Loop
@@ -200,17 +180,17 @@ cd your-project
200
180
  monomind init
201
181
 
202
182
  # 3. Wire into Claude Code as an MCP server
203
- claude mcp add monomind npx monomind mcp start
183
+ claude mcp add monomind -- npx -y monomind@latest mcp start
204
184
 
205
185
  # 4. Health check
206
186
  monomind doctor --fix
207
187
  ```
208
188
 
209
- Open Claude Code. You now have 80+ slash commands available:
189
+ Open Claude Code. You now have 49 `/mastermind:*` workflows available:
210
190
 
211
191
  ```bash
212
192
  /mastermind:autodev --tillend # start autonomous code loop
213
- /mastermind:createorg my-team # create your first AI org
193
+ monomind org run my-team # run your first AI org (see .monomind/orgs/sample-team.json)
214
194
  /mastermind:help # show all commands
215
195
  ```
216
196
 
@@ -262,7 +242,7 @@ Before touching any file, Monomind queries **Monograph** — a SQLite-backed kno
262
242
 
263
243
  ## 🎣 Hooks & Workers
264
244
 
265
- Monomind wires 22 hook events into Claude Code. Every edit, task, command, and session fires hooks that log patterns, route agents, and train the intelligence system.
245
+ Monomind wires 29 hook subcommands into Claude Code across edit, task, command, and session lifecycle events logging patterns, routing agents, and feeding the intelligence system.
266
246
 
267
247
  ```mermaid
268
248
  flowchart LR
@@ -296,7 +276,7 @@ const result = await fence.detect(userInput);
296
276
 
297
277
  ---
298
278
 
299
- ## 📋 80+ Slash Commands
279
+ ## 📋 49 Mastermind Commands
300
280
 
301
281
  Everything runs from inside Claude Code via slash commands. Here's the highlight reel:
302
282
 
@@ -315,9 +295,9 @@ Everything runs from inside Claude Code via slash commands. Here's the highlight
315
295
  ### Organizations
316
296
  | Command | What it does |
317
297
  |---|---|
318
- | `/mastermind:createorg` | Design an autonomous agent org |
319
- | `/mastermind:runorg` | Start it as a background daemon |
320
- | `/mastermind:orgs` | List all orgs + status |
298
+ | `monomind org run <name>` | Start an org as a real SDK-backed daemon |
299
+ | `monomind org status` / `list` | Runtime state for one or all orgs |
300
+ | `monomind org stop <name>` | Request a graceful stop |
321
301
  | `/mastermind:approve` | Action pending approval requests |
322
302
 
323
303
  ### Business Domains
@@ -329,7 +309,7 @@ Everything runs from inside Claude Code via slash commands. Here's the highlight
329
309
  | `/mastermind:finance` | Budgets, invoicing, modeling |
330
310
  | `/mastermind:ops` | Operations and workflow automation |
331
311
 
332
- **[→ Full reference (80+ commands)](https://monoes.github.io/monomind/#slash)**
312
+ **[→ Full reference (49 commands)](https://monoes.github.io/monomind/#slash)**
333
313
 
334
314
  ---
335
315
 
@@ -351,24 +331,27 @@ graph TD
351
331
  CC["Claude Code"]
352
332
  MCP["MCP Server\nmonomind mcp start"]
353
333
  D["Background Workers\n(@monomind/hooks, in-process)"]
334
+ ORG["OrgDaemon\nmonomind org run\nreal SDK sessions"]
354
335
 
355
- CC <-->|"MCP tools: monograph, memory, swarm"| MCP
336
+ CC <-->|"MCP tools: monograph, memory"| MCP
356
337
  MCP <--> D
357
338
 
358
339
  D --> ADB[("Memory store\npatterns + episodes")]
359
340
  D --> MG[("Monograph\ncode graph")]
360
- D --> HK["Hooks\n22 event types"]
361
- D --> SW["Swarm\n4 topologies\n3 consensus strategies"]
341
+ D --> HK["Hooks\n29 subcommands"]
362
342
 
363
- CC -->|"Task tool - spawns agents"| AG["Agent Swarm\narchitect, coder\ntester, reviewer\nsecurity, perf"]
343
+ CC -->|"Task tool - spawns agents"| AG["In-session agents\narchitect, coder\ntester, reviewer\nsecurity, perf"]
364
344
  AG <-->|reads and writes| ADB
345
+ ORG -->|"spawns, policy-gated"| RA["Role agents"]
346
+ ORG <-->|reads and writes| ADB
365
347
 
366
348
  style CC fill:#00D2AA22,stroke:#00D2AA
367
349
  style AG fill:#8B5CF622,stroke:#8B5CF6
368
350
  style ADB fill:#F59E0B22,stroke:#F59E0B
351
+ style ORG fill:#F59E0B22,stroke:#F59E0B
369
352
  ```
370
353
 
371
- **Claude Code handles all execution.** MCP tools only coordinate. Your data never leaves your machine.
354
+ **Claude Code's Task tool drives in-session multi-agent work; `monomind org run` drives persistent background orgs.** Your data never leaves your machine.
372
355
 
373
356
  ---
374
357
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "monomind",
3
- "version": "2.1.0",
4
- "description": "Monomind - Power toolkit for Claude Code. Autonomous agent orgs, codebase knowledge graph, keyword-routed specialist prompts, and 80+ slash commands. One init, then walk away.",
3
+ "version": "2.1.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",
7
7
  "bin": {
@@ -140,7 +140,7 @@
140
140
  "devDependencies": {
141
141
  "@types/node": "^20.0.0",
142
142
  "tsx": "^4.21.0",
143
- "typescript": "^5.0.0",
143
+ "typescript": "^7.0.2",
144
144
  "vite": ">=8.0.16",
145
145
  "vitest": "^4.1.4"
146
146
  },
@@ -1,4 +1,4 @@
1
- <!-- Define and save an autonomous agent organization — roles, hierarchy, and communication topology. Suggest or confirm roles, then persist the org for use with runorg. -->
1
+ <!-- Define and save an autonomous agent organization (Org Runtime v2) — roles and hierarchy. Suggest or confirm roles, then persist the org config for `monomind org run`/`serve`. -->
2
2
 
3
3
  **If $ARGUMENTS is empty:** Output the following and wait.
4
4
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  **MASTERMIND: CREATE ORG**
8
8
 
9
- An org is a named, persistent agent team — not a one-shot Mastermind run. Once created, the org runs autonomously across sessions: a boss agent coordinates specialists who pick up tasks from a shared board, execute them, and loop until stopped.
9
+ An org is a named, persistent agent team, run by the Org Runtime v2 daemon — not a one-shot Mastermind run and not a Task-tool-spawned boss. Once created, every role in the config starts as its own live agent session the moment you run the org; roles message each other directly (no shared task board) and the org keeps running until stopped.
10
10
 
11
11
  Use orgs when the work is ongoing, not single-shot. A content team that ships 10 posts a month. A research squad that runs competitive scans weekly. A dev team with a permanent backlog.
12
12
 
@@ -25,16 +25,15 @@ Use orgs when the work is ongoing, not single-shot. A content team that ships 10
25
25
  ```
26
26
 
27
27
  **Options:**
28
- `--name <slug>` — org identifier used with `/mastermind:runorg` (derived from goal if omitted)
28
+ `--name <slug>` — org identifier used with `monomind org run <name>` (derived from goal if omitted)
29
29
  `--roles <list>` — explicit role list (e.g. "boss, writer, reviewer, marketer")
30
- `--schedule <interval>` — make this a self-scheduling loop org (e.g. `"every 30 minutes"`, `"every hour"`, `"daily"`)
30
+ `--schedule <interval>` — daemon schedule for `monomind org serve` to pick up, e.g. `"30m"`, `"2h"`, `"1440m"` for daily (omit for a manual, one-shot org)
31
31
  `--auto` — skip confirmation, create immediately
32
32
  `--confirm` — always ask before saving (default)
33
- `--delete <name>` — delete a saved org and all associated data files
34
- `--list` — list all saved orgs with their status
33
+ `--delete <name>` — delete a saved org and all associated data files (`monomind org delete <name> --yes`)
34
+ `--list` — list all saved orgs with their status (`monomind org list`)
35
35
 
36
- Once created, start the org with `/mastermind:runorg --org <name>`.
37
- For scheduled orgs: `runorg` activates the loop; `stoporg` stops it; `orgs` lists all.
36
+ Once created, start the org with `monomind org run <name>` (foreground, one-shot) or let `monomind org serve` pick it up if `--schedule` was set. Check status with `monomind org status <name>`; stop with `monomind org stop <name>`.
38
37
 
39
38
  ---
40
39
 
@@ -47,7 +46,7 @@ Parse `$ARGUMENTS` for:
47
46
  - `--confirm` flag → mode = confirm
48
47
  - `--name <name>` → org_name = <name> (must match `^[a-z0-9][a-z0-9-]{0,63}$`; if omitted, derived from goal)
49
48
  - `--roles <desc>` → roles_desc = <desc> (explicit role list, e.g. "boss, writer, reviewer, marketer")
50
- - `--schedule <interval>` → schedule = <interval> (e.g. `"every 30 minutes"`, `"every hour"`, `"daily"`; triggers loop org generation)
49
+ - `--schedule <interval>` → schedule = <interval>, daemon format only: `"<N>s"`, `"<N>m"`, or `"<N>h"` (e.g. `"30m"`, `"2h"`) — this is passed straight into `parseSchedule()` in `orgrt/scheduler.ts`, whose regex `^(\d+)\s*(s|m|h)$` rejects anything else (e.g. `"every 30 minutes"`, `"daily"`) and silently leaves the org unscheduled
51
50
  - `--delete <name>` → delete_mode = true, delete_name = <name>
52
51
  - `--list` flag → list_mode = true
53
52
  - Remaining text = prompt (goal description)
@@ -41,6 +41,18 @@ function subagentKey(hookInput) {
41
41
  return crypto.createHash('md5').update(String(raw)).digest('hex').slice(0, 16);
42
42
  }
43
43
 
44
+ // Determine subagent success from its result summary — errors/failures/
45
+ // exceptions indicate failure. Shared by the Monograph `success` column and
46
+ // the intelligence.feedback() call below, so both use one definition.
47
+ function deriveSubagentSuccess(summary) {
48
+ if (!summary) return true;
49
+ var sumLower = summary.toLowerCase();
50
+ if (sumLower.includes('error') || sumLower.includes('failed') || sumLower.includes('exception') || sumLower.includes('fatal')) {
51
+ return false;
52
+ }
53
+ return true;
54
+ }
55
+
44
56
  // Delete snap-*.json files older than SNAP_MAX_AGE_MS — orphaned when a
45
57
  // SubagentStop never arrived (crash, forced-stop) or was matched to a
46
58
  // different snapshot before keyed matching existed.
@@ -345,6 +357,17 @@ async function handleSubagentStop(hookInput) {
345
357
  + (session ? ' · sess=' + session : '')
346
358
  + (org ? ' · ' + org + '/' + runId : ''));
347
359
 
360
+ // Feed the real per-subagent success/failure signal into the same
361
+ // intelligence-outcomes.jsonl that session-handler.cjs's SessionEnd
362
+ // heuristic reads (via outcomesSignal) to veto a commit-based "success".
363
+ // Without this, that veto path never fires — SubagentStop is the only
364
+ // remaining event that carries a genuine failure signal, since post-task
365
+ // (TeammateIdle/TaskCompleted) is dead code (those aren't valid Claude
366
+ // Code hook events and are stripped from settings.json on init).
367
+ try {
368
+ require('../intelligence.cjs').feedback(deriveSubagentSuccess(summary));
369
+ } catch (e) { /* non-fatal — feedback recording must never block subagent-stop */ }
370
+
348
371
  if (!org && !session) {
349
372
  // No active org or session — log to general capture file only
350
373
  // P2-26: rotate — was a pure appendFileSync with no cap, unlike
@@ -486,16 +509,7 @@ async function handleSubagentStop(hookInput) {
486
509
  tokens_in: totalTin || 0,
487
510
  tokens_out: totalTout || 0,
488
511
  cost_usd: costUsd || 0,
489
- success: (function() {
490
- // Determine success from result summary — errors/failures/exceptions indicate failure
491
- if (summary) {
492
- var sumLower = summary.toLowerCase();
493
- if (sumLower.includes('error') || sumLower.includes('failed') || sumLower.includes('exception') || sumLower.includes('fatal')) {
494
- return 0;
495
- }
496
- }
497
- return 1;
498
- })(),
512
+ success: deriveSubagentSuccess(summary) ? 1 : 0,
499
513
  duration_ms: snap.ts ? (Date.now() - snap.ts) : 0,
500
514
  timestamp: Date.now(),
501
515
  });
@@ -6,7 +6,7 @@
6
6
  * @monomind/guidance package it mirrored has been removed.
7
7
  *
8
8
  * Gates enforced at runtime:
9
- * pre-bash → destructive-ops (require-confirmation block)
9
+ * pre-bash → destructive-ops (hard block; no confirm-and-proceed path exists)
10
10
  * pre-write → secrets (block)
11
11
  */
12
12
 
@@ -60,7 +60,7 @@ function checkDestructive(command) {
60
60
  return {
61
61
  triggered: true,
62
62
  matched: match[0],
63
- reason: `Destructive operation detected: "${match[0]}". Confirm this is intentional and document a rollback plan before proceeding.`,
63
+ reason: `Destructive operation blocked: "${match[0]}". This hook always blocks (Claude Code's PreToolUse protocol has no confirm-and-proceed path) — there is no way to run this exact command after confirming. If it's genuinely intended, use a non-destructive equivalent instead (e.g. move the target aside, or scope the operation more narrowly).`,
64
64
  };
65
65
  }
66
66
  }
@@ -299,6 +299,35 @@ module.exports = {
299
299
  console.log('[CODEBASE] Graph index ' + mapData.graphStaleness.commitsBehind + ' commits behind HEAD — run monograph build');
300
300
  }
301
301
  }
302
+ // Graph gate connectivity nudge — the pre-search/pre-bash gate
303
+ // (utils/monograph.cjs _graphGateShouldBlock) hard-blocks the first
304
+ // Grep/Glob/bash-grep-or-find call each session until a real
305
+ // monograph_query/monograph_suggest call fires. If that block was
306
+ // never followed by a real graph call, the monomind MCP server is
307
+ // most likely not connected this session (config present but
308
+ // unapproved/not started) — surface it once so the user can fix the
309
+ // actual cause instead of the gate silently degrading to a no-op.
310
+ var graphGateFile = path.join(CWD, '.monomind', 'graph-gate-state.json');
311
+ var mcpWarnFile = path.join(CWD, '.monomind', 'mcp-not-connected-warned.json');
312
+ if (fs.existsSync(graphGateFile) && fs.statSync(graphGateFile).size < 4096) {
313
+ var gateState = JSON.parse(fs.readFileSync(graphGateFile, 'utf-8'));
314
+ var gateSessId = String((hCtx.hookInput && (hCtx.hookInput.sessionId || hCtx.hookInput.session_id)) || '');
315
+ if (gateState && gateState.sessionId === gateSessId && gateState.blockedOnce && !gateState.queried) {
316
+ var alreadyWarnedMcp = false;
317
+ if (fs.existsSync(mcpWarnFile)) {
318
+ try {
319
+ var mcpWarnData = JSON.parse(fs.readFileSync(mcpWarnFile, 'utf-8'));
320
+ if (mcpWarnData && mcpWarnData.sessionId === gateSessId) alreadyWarnedMcp = true;
321
+ } catch (e) { /* corrupt — warn again to be safe */ }
322
+ }
323
+ if (!alreadyWarnedMcp) {
324
+ console.log('[MCP] The graph gate blocked a search but no monograph_query/monograph_suggest call followed — the monomind MCP server is likely not connected this session. Run `claude mcp add monomind -- npx monomind@latest mcp start` (then restart), or approve the .mcp.json trust prompt if one is pending.');
325
+ try {
326
+ fs.writeFileSync(mcpWarnFile, JSON.stringify({ sessionId: gateSessId, warnedAt: new Date().toISOString() }));
327
+ } catch (e) { /* non-fatal */ }
328
+ }
329
+ }
330
+ }
302
331
  // Deep dive findings (god nodes, high-degree files from background analysis)
303
332
  var deepdiveFile = path.join(metricsDir, 'deepdive.json');
304
333
  if (fs.existsSync(deepdiveFile) && fs.statSync(deepdiveFile).size < 32768) {
@@ -41,34 +41,46 @@ module.exports = {
41
41
  if (fs.existsSync(lastRoutePath) && (function() { try { return fs.statSync(lastRoutePath).size <= MAX_ROUTE; } catch(_) { return false; } }())) {
42
42
  var lastRoute = JSON.parse(fs.readFileSync(lastRoutePath, 'utf-8'));
43
43
 
44
- // Derive sessionSuccess from git commits (strongest signal: user committed = success)
44
+ // Derive sessionSuccess. A commit alone is not proof of success — a
45
+ // session can commit a partial fix and then hit repeated failures —
46
+ // so recent intelligence-outcomes are checked FIRST and can veto a
47
+ // commit-based "true" when they show a majority of failures.
45
48
  try {
46
49
  var execSync = require('child_process').execSync;
47
- var recentCommits = execSync('git log --oneline --since="30 minutes ago" 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' }).trim();
48
- if (recentCommits.length > 0) {
49
- sessionSuccess = true;
50
+
51
+ var outcomesSignal = null; // majority success/failure from intelligence-outcomes, if any
52
+ var outcomesPath = path.join(CWD, '.monomind', 'data', 'intelligence-outcomes.jsonl');
53
+ var MAX_OUTCOMES = 512 * 1024;
54
+ if (fs.existsSync(outcomesPath) && (function() { try { return fs.statSync(outcomesPath).size <= MAX_OUTCOMES; } catch(_) { return false; } }())) {
55
+ var windowMs = 30 * 60 * 1000;
56
+ var cutoff = Date.now() - windowMs;
57
+ var outcomeLines = fs.readFileSync(outcomesPath, 'utf-8').trim().split('\n').filter(Boolean);
58
+ var recent = outcomeLines.map(function(l) {
59
+ try { return JSON.parse(l); } catch { return null; }
60
+ }).filter(function(e) { return e && e.ts && e.ts >= cutoff; });
61
+ if (recent.length > 0) {
62
+ var failures = recent.filter(function(e) { return e.success === false; }).length;
63
+ outcomesSignal = failures / recent.length < 0.5;
64
+ }
65
+ }
66
+
67
+ if (outcomesSignal === false) {
68
+ // Recent tool/command outcomes were majority failures — this
69
+ // overrides a commit, since committing doesn't undo those failures.
70
+ sessionSuccess = false;
50
71
  } else {
51
- // No commits check if files were modified (work in progress, not failure)
52
- var gitStatus = execSync('git diff --name-only 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' }).trim();
53
- // Modified files = probably still working; no changes at all = exploration or failure
54
- if (gitStatus.length === 0) {
55
- // Fall back to intelligence-outcomes as a weak signal
56
- var outcomesPath = path.join(CWD, '.monomind', 'data', 'intelligence-outcomes.jsonl');
57
- var MAX_OUTCOMES = 512 * 1024;
58
- if (fs.existsSync(outcomesPath) && (function() { try { return fs.statSync(outcomesPath).size <= MAX_OUTCOMES; } catch(_) { return false; } }())) {
59
- var windowMs = 30 * 60 * 1000;
60
- var cutoff = Date.now() - windowMs;
61
- var outcomeLines = fs.readFileSync(outcomesPath, 'utf-8').trim().split('\n').filter(Boolean);
62
- var recent = outcomeLines.map(function(l) {
63
- try { return JSON.parse(l); } catch { return null; }
64
- }).filter(function(e) { return e && e.ts && e.ts >= cutoff; });
65
- if (recent.length > 0) {
66
- var failures = recent.filter(function(e) { return e.success === false; }).length;
67
- sessionSuccess = failures / recent.length < 0.5;
68
- }
72
+ var recentCommits = execSync('git log --oneline --since="30 minutes ago" 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' }).trim();
73
+ if (recentCommits.length > 0) {
74
+ sessionSuccess = true;
75
+ } else {
76
+ // No commits check if files were modified (work in progress, not failure)
77
+ var gitStatus = execSync('git diff --name-only 2>/dev/null || true', { cwd: CWD, timeout: 3000, encoding: 'utf-8' }).trim();
78
+ // Modified files = probably still working; no changes at all = exploration or failure
79
+ if (gitStatus.length === 0 && outcomesSignal !== null) {
80
+ sessionSuccess = outcomesSignal;
69
81
  }
82
+ // else: modified files exist, or no evidence either way (leave null)
70
83
  }
71
- // else: modified files exist — work in progress, not evidence either way (leave null)
72
84
  }
73
85
  } catch (e) { /* non-critical — leave null (no evidence) */ }
74
86
 
@@ -55,6 +55,7 @@ const {
55
55
  getMonographSuggestions, getMonographNeighbors,
56
56
  _recordGraphTelemetry, _injectCompactGraphMap,
57
57
  _findAffectedTests, _maybeRebuildMonograph,
58
+ _graphGateShouldBlock, _graphGateMarkQueried,
58
59
  } = monograph;
59
60
 
60
61
  const {
@@ -409,6 +410,15 @@ const handlers = {
409
410
  var isGrep = /\b(?:grep|rg|ag)\b/.test(cmd);
410
411
  var isFind = /\b(?:find|fd)\b/.test(cmd) && !isGrep;
411
412
  if (isGrep || isFind) {
413
+ var sessIdGate = String((hCtx.hookInput && (hCtx.hookInput.sessionId || hCtx.hookInput.session_id)) || '');
414
+ if (_graphGateShouldBlock(sessIdGate)) {
415
+ process.stderr.write(JSON.stringify({
416
+ decision: 'block',
417
+ reason: '[graph-gate] Call mcp__monomind__monograph_query or monograph_suggest before grep/rg/find for code exploration (CLAUDE.md). This blocks once per session — after your first monograph call (or this one warning), Bash grep/find work normally for the rest of the session.',
418
+ }) + '\n');
419
+ process.exitCode = 2;
420
+ return;
421
+ }
412
422
  var graphAssisted = false;
413
423
  if (_isGraphFresh()) {
414
424
  try {
@@ -659,6 +669,15 @@ const handlers = {
659
669
 
660
670
  'pre-search': () => {
661
671
  var tool = hCtx.toolName || '';
672
+ var sessIdGate = String((hCtx.hookInput && (hCtx.hookInput.sessionId || hCtx.hookInput.session_id)) || '');
673
+ if (_graphGateShouldBlock(sessIdGate)) {
674
+ process.stderr.write(JSON.stringify({
675
+ decision: 'block',
676
+ reason: '[graph-gate] Call mcp__monomind__monograph_query or monograph_suggest before ' + (tool || 'Grep/Glob') + ' for code exploration (CLAUDE.md). This blocks once per session — after your first monograph call (or this one warning), search tools work normally for the rest of the session.',
677
+ }) + '\n');
678
+ process.exitCode = 2;
679
+ return;
680
+ }
662
681
  var graphResolved = false;
663
682
  try {
664
683
  var grepPattern = (typeof toolInput === 'object' && toolInput !== null)
@@ -817,6 +836,8 @@ const handlers = {
817
836
  'post-graph-tool': () => {
818
837
  // Record monograph MCP tool calls as graph wins
819
838
  _recordGraphTelemetry('monograph_call');
839
+ var sessIdGate = String((hCtx.hookInput && (hCtx.hookInput.sessionId || hCtx.hookInput.session_id)) || '');
840
+ _graphGateMarkQueried(sessIdGate);
820
841
  },
821
842
 
822
843
  'graph-status': () => {