@monoes/monomindcli 2.16.3 → 2.16.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 (134) hide show
  1. package/.claude/commands/mastermind/createorg.md +2 -2
  2. package/.claude/commands/mastermind/help.md +5 -11
  3. package/.claude/commands/mastermind/master.md +1 -2
  4. package/.claude/commands/mastermind/orgs.md +1 -1
  5. package/.claude/commands/mastermind/orgstatus.md +1 -1
  6. package/.claude/commands/mastermind/runorg.md +2 -2
  7. package/.claude/commands/mastermind/stoporg.md +7 -11
  8. package/.claude/helpers/agent-registry.cjs +434 -0
  9. package/.claude/helpers/handlers/pick-core.cjs +20 -2
  10. package/.claude/helpers/handlers/session-restore-handler.cjs +4 -1
  11. package/.claude/helpers/jev-catalog.cjs +7 -3
  12. package/.claude/helpers/jev-picker.cjs +3 -1
  13. package/.claude/helpers/pick-rank.cjs +90 -4
  14. package/.claude/skills/mastermind-agents/SKILL.md +31 -38
  15. package/.claude/skills/mastermind-createorg/SKILL.md +3 -3
  16. package/.claude/skills/mastermind-env/SKILL.md +4 -18
  17. package/.claude/skills/mastermind-inbox/SKILL.md +31 -52
  18. package/.claude/skills/mastermind-instance/SKILL.md +7 -5
  19. package/.claude/skills/mastermind-new-agent/SKILL.md +3 -3
  20. package/.claude/skills/mastermind-org-settings/SKILL.md +3 -4
  21. package/.claude/skills/mastermind-orgs/SKILL.md +26 -32
  22. package/.claude/skills/mastermind-orgstatus/SKILL.md +49 -140
  23. package/.claude/skills/mastermind-runorg/SKILL.md +13 -13
  24. package/.claude/skills/mastermind-stoporg/SKILL.md +7 -62
  25. package/.claude/skills/mastermind-tasks/SKILL.md +6 -8
  26. package/README.md +28 -43
  27. package/dist/src/agents/registry-builder.d.ts +57 -21
  28. package/dist/src/agents/registry-builder.d.ts.map +1 -1
  29. package/dist/src/agents/registry-builder.js +41 -341
  30. package/dist/src/agents/registry-builder.js.map +1 -1
  31. package/dist/src/agents/registry-freshness.d.ts +4 -4
  32. package/dist/src/agents/registry-freshness.d.ts.map +1 -1
  33. package/dist/src/agents/registry-freshness.js +11 -60
  34. package/dist/src/agents/registry-freshness.js.map +1 -1
  35. package/dist/src/commands/doc.d.ts.map +1 -1
  36. package/dist/src/commands/doc.js +6 -15
  37. package/dist/src/commands/doc.js.map +1 -1
  38. package/dist/src/commands/doctor-pick-checks.d.ts.map +1 -1
  39. package/dist/src/commands/doctor-pick-checks.js +9 -41
  40. package/dist/src/commands/doctor-pick-checks.js.map +1 -1
  41. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  42. package/dist/src/commands/doctor-project-checks.js +7 -5
  43. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  44. package/dist/src/commands/hooks-routing-commands.d.ts.map +1 -1
  45. package/dist/src/commands/hooks-routing-commands.js +4 -3
  46. package/dist/src/commands/hooks-routing-commands.js.map +1 -1
  47. package/dist/src/commands/init-upgrade.d.ts.map +1 -1
  48. package/dist/src/commands/init-upgrade.js +4 -0
  49. package/dist/src/commands/init-upgrade.js.map +1 -1
  50. package/dist/src/commands/init-wizard.d.ts.map +1 -1
  51. package/dist/src/commands/init-wizard.js +7 -2
  52. package/dist/src/commands/init-wizard.js.map +1 -1
  53. package/dist/src/commands/init.d.ts.map +1 -1
  54. package/dist/src/commands/init.js +16 -27
  55. package/dist/src/commands/init.js.map +1 -1
  56. package/dist/src/commands/monograph.d.ts.map +1 -1
  57. package/dist/src/commands/monograph.js +16 -21
  58. package/dist/src/commands/monograph.js.map +1 -1
  59. package/dist/src/commands/org.js +1 -1
  60. package/dist/src/commands/org.js.map +1 -1
  61. package/dist/src/decision/jev.d.ts +4 -0
  62. package/dist/src/decision/jev.d.ts.map +1 -1
  63. package/dist/src/decision/jev.js.map +1 -1
  64. package/dist/src/decision/pick-real.d.ts +93 -0
  65. package/dist/src/decision/pick-real.d.ts.map +1 -0
  66. package/dist/src/decision/pick-real.js +253 -0
  67. package/dist/src/decision/pick-real.js.map +1 -0
  68. package/dist/src/decision/picks.d.ts +1 -0
  69. package/dist/src/decision/picks.d.ts.map +1 -1
  70. package/dist/src/decision/picks.js +1 -0
  71. package/dist/src/decision/picks.js.map +1 -1
  72. package/dist/src/init/embeddings-step.d.ts +23 -0
  73. package/dist/src/init/embeddings-step.d.ts.map +1 -0
  74. package/dist/src/init/embeddings-step.js +53 -0
  75. package/dist/src/init/embeddings-step.js.map +1 -0
  76. package/dist/src/init/executor.d.ts.map +1 -1
  77. package/dist/src/init/executor.js +9 -1
  78. package/dist/src/init/executor.js.map +1 -1
  79. package/dist/src/init/helpers-generator.d.ts.map +1 -1
  80. package/dist/src/init/helpers-generator.js +4 -0
  81. package/dist/src/init/helpers-generator.js.map +1 -1
  82. package/dist/src/init/project-indexes.d.ts +19 -0
  83. package/dist/src/init/project-indexes.d.ts.map +1 -0
  84. package/dist/src/init/project-indexes.js +44 -0
  85. package/dist/src/init/project-indexes.js.map +1 -0
  86. package/dist/src/init/shared.d.ts +7 -2
  87. package/dist/src/init/shared.d.ts.map +1 -1
  88. package/dist/src/init/shared.js +7 -6
  89. package/dist/src/init/shared.js.map +1 -1
  90. package/dist/src/init/types.d.ts +13 -2
  91. package/dist/src/init/types.d.ts.map +1 -1
  92. package/dist/src/init/types.js +11 -3
  93. package/dist/src/init/types.js.map +1 -1
  94. package/dist/src/init/upgrade.d.ts +3 -0
  95. package/dist/src/init/upgrade.d.ts.map +1 -1
  96. package/dist/src/init/upgrade.js +21 -6
  97. package/dist/src/init/upgrade.js.map +1 -1
  98. package/dist/src/init/write-antigravity.d.ts +1 -0
  99. package/dist/src/init/write-antigravity.d.ts.map +1 -1
  100. package/dist/src/init/write-antigravity.js +19 -1
  101. package/dist/src/init/write-antigravity.js.map +1 -1
  102. package/dist/src/init/write-claude.d.ts.map +1 -1
  103. package/dist/src/init/write-claude.js +8 -5
  104. package/dist/src/init/write-claude.js.map +1 -1
  105. package/dist/src/mcp-tools/embeddings-tools.d.ts.map +1 -1
  106. package/dist/src/mcp-tools/embeddings-tools.js +14 -5
  107. package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
  108. package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
  109. package/dist/src/mcp-tools/hooks-routing.js +4 -3
  110. package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
  111. package/dist/src/mcp-tools/monograph/build-tools.d.ts.map +1 -1
  112. package/dist/src/mcp-tools/monograph/build-tools.js +16 -9
  113. package/dist/src/mcp-tools/monograph/build-tools.js.map +1 -1
  114. package/dist/src/memory/embedding-operations.d.ts +0 -4
  115. package/dist/src/memory/embedding-operations.d.ts.map +1 -1
  116. package/dist/src/memory/embedding-operations.js +11 -85
  117. package/dist/src/memory/embedding-operations.js.map +1 -1
  118. package/dist/src/memory/memory-bridge.d.ts +7 -0
  119. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  120. package/dist/src/memory/memory-bridge.js +15 -0
  121. package/dist/src/memory/memory-bridge.js.map +1 -1
  122. package/dist/src/orgrt/bash-timeout.d.ts +17 -0
  123. package/dist/src/orgrt/bash-timeout.d.ts.map +1 -1
  124. package/dist/src/orgrt/bash-timeout.js +15 -0
  125. package/dist/src/orgrt/bash-timeout.js.map +1 -1
  126. package/dist/src/orgrt/session.d.ts.map +1 -1
  127. package/dist/src/orgrt/session.js +5 -2
  128. package/dist/src/orgrt/session.js.map +1 -1
  129. package/dist/src/orgrt/task-match.d.ts +3 -1
  130. package/dist/src/orgrt/task-match.d.ts.map +1 -1
  131. package/dist/src/orgrt/task-match.js +12 -4
  132. package/dist/src/orgrt/task-match.js.map +1 -1
  133. package/dist/tsconfig.tsbuildinfo +1 -1
  134. package/package.json +5 -5
@@ -12,7 +12,8 @@
12
12
  */
13
13
  var redaction = require('./redact-secrets.cjs');
14
14
  // Keyword ranking builds the candidate shortlist (and is every caller's fallback).
15
- var shortlist = require('./pick-rank.cjs').shortlist;
15
+ var pickRank = require('./pick-rank.cjs');
16
+ var shortlist = pickRank.shortlist;
16
17
 
17
18
  var TYPESAFE_BASE_URL = 'https://api.typesafe.ai';
18
19
  var DEFAULT_MODEL = 'jev-latest';
@@ -380,6 +381,7 @@ module.exports = {
380
381
  ask: ask,
381
382
  probe: probe,
382
383
  shortlist: shortlist,
384
+ withoutExclusions: pickRank.withoutExclusions,
383
385
  pick: pick,
384
386
  acceptAgent: acceptAgent,
385
387
  acceptSkills: acceptSkills,
@@ -13,6 +13,18 @@
13
13
  * the item matches. An item marked `pick: 'low'` (admin/meta skills, from
14
14
  * `pick: low` frontmatter) keeps LOW_PICK_FACTOR of its score, so it surfaces
15
15
  * only when the task names it. Equal scores keep catalog order.
16
+ *
17
+ * Exclusions (English only, query side only): words the task explicitly
18
+ * rules out do not count ("anything pending rather than release" must not
19
+ * pick release-manager). withoutExclusions() drops each cue and the words in
20
+ * its scope before tokenizing. Cues: "rather than", "other than", "instead
21
+ * of", "apart from", "aside from", "except", "besides", "excluding",
22
+ * "without", "not", "no", "nor", "don't"/"dont". The scope ends at clause
23
+ * punctuation (. , ; : ! ? brackets, dashes), at "but"/"then"/"so", at
24
+ * "and" once a word was dropped ("or"/"nor" keep excluding: "without CI or
25
+ * staging"), or after SCOPE_WORDS content words. Problem descriptions are not
26
+ * exclusions: "not"/"no" after a copula or auxiliary ("is not loading",
27
+ * "are no tests", "does not"), "not only", and "don't know/see/get/..." stay.
16
28
  */
17
29
 
18
30
  var K1 = 1.2;
@@ -26,10 +38,10 @@ var LOW_PICK_FACTOR = 0.35;
26
38
 
27
39
  var STOPWORDS = new Set(
28
40
  (
29
- 'a about above after again against all also am an and any are as at be because been before being below ' +
30
- 'between both but by can could did do does doing down during each etc every few for from further had has ' +
41
+ 'a about above after again against all also am an and any anything are as at be because been before being below ' +
42
+ 'between both but by can could did do does doing down during each else etc every everything few for from further had has ' +
31
43
  'have having he her here hers him his how i if in into is it its itself just me more most must my no nor ' +
32
- 'not now of off on once only or other our ours out over own per please same she should so some such than ' +
44
+ 'not nothing now of off on once only or other our ours out over own per please same she should so some something such than ' +
33
45
  'that the their theirs them then there these they this those through to too under until up upon us very ' +
34
46
  'via was we were what when where which while who whom why will with within without would you your yours'
35
47
  ).split(' '),
@@ -111,6 +123,78 @@ function tokens(text) {
111
123
  return words(text).filter(isContent).map(stem);
112
124
  }
113
125
 
126
+ // Content words an exclusion cue rules out at most.
127
+ var SCOPE_WORDS = 4;
128
+ var CLAUSE_SPLIT = /[.,;:!?()[\]{}<>|\n\r\u2013\u2014]+|\s-+\s/;
129
+ var SINGLE_CUES = new Set('except besides excluding without not no nor dont'.split(' '));
130
+ var PAIR_CUES = { rather: 'than', other: 'than', instead: 'of', apart: 'from', aside: 'from', don: 't' };
131
+ // "is not loading", "are no tests", "does not work": a description, not an exclusion.
132
+ var DESCRIBES = new Set(
133
+ ('am is are was were be been being does did has have had can could will would get gets got ' +
134
+ 'isn aren wasn weren doesn didn hasn haven hadn won wouldn couldn there').split(' '),
135
+ );
136
+ // "don't know why the build fails" describes a problem too.
137
+ var DONT_DESCRIBES = new Set('know understand see get think remember why how'.split(' '));
138
+ var SCOPE_ENDS = new Set('but then so'.split(' '));
139
+
140
+ /** Words the cue at ws[i] spans (0: no cue there). */
141
+ function cueAt(ws, i) {
142
+ var w = ws[i];
143
+ var next = ws[i + 1];
144
+ if (PAIR_CUES[w] && next === PAIR_CUES[w]) {
145
+ if (w === 'don' && DONT_DESCRIBES.has(ws[i + 2])) return 0;
146
+ return 2;
147
+ }
148
+ if (!SINGLE_CUES.has(w)) return 0;
149
+ if ((w === 'dont' || (w === 'not' && ws[i - 1] === 'do')) && DONT_DESCRIBES.has(next)) return 0;
150
+ if ((w === 'not' || w === 'no') && (DESCRIBES.has(ws[i - 1]) || next === 'only')) return 0;
151
+ return 1;
152
+ }
153
+
154
+ /** `text` minus the exclusion cues and the words they rule out (see the file
155
+ * header), clause breaks kept as ". ". Lowercased; a text without cues keeps
156
+ * every word. */
157
+ function withoutExclusions(text) {
158
+ return String(text || '')
159
+ .toLowerCase()
160
+ .replace(/\u2019/g, "'")
161
+ .split(CLAUSE_SPLIT)
162
+ .map(function (clause) {
163
+ var ws = clause.match(/[\p{L}\p{N}]+/gu) || [];
164
+ var out = [];
165
+ var left = 0;
166
+ var dropped = 0;
167
+ for (var i = 0; i < ws.length; i++) {
168
+ var n = cueAt(ws, i);
169
+ if (n) {
170
+ i += n - 1;
171
+ left = SCOPE_WORDS;
172
+ dropped = 0;
173
+ continue;
174
+ }
175
+ var w = ws[i];
176
+ if (left > 0) {
177
+ if (SCOPE_ENDS.has(w) || (w === 'and' && dropped > 0)) left = 0;
178
+ else {
179
+ if (isContent(w)) {
180
+ left--;
181
+ dropped++;
182
+ }
183
+ continue;
184
+ }
185
+ }
186
+ out.push(w);
187
+ }
188
+ return out.join(' ');
189
+ })
190
+ .join('. ');
191
+ }
192
+
193
+ /** tokens() of a task: the words it rules out dropped first. */
194
+ function queryTokens(text) {
195
+ return tokens(withoutExclusions(text));
196
+ }
197
+
114
198
  /** Leading id segments ("engineering-", "mastermind:", "analysis:") that are
115
199
  * shared by >= PREFIX_MIN_SHARED ids or equal the item's category. */
116
200
  function categoryPrefixes(items) {
@@ -190,7 +274,7 @@ function scoreDoc(index, doc, query) {
190
274
  * overlap). Equal scores keep catalog order. */
191
275
  function shortlist(query, items, limit, include) {
192
276
  var index = indexFor(items);
193
- var q = Array.from(new Set(tokens(query)));
277
+ var q = Array.from(new Set(queryTokens(query)));
194
278
  var scored = items.map(function (item, i) {
195
279
  return { item: item, index: i, score: scoreDoc(index, index.docs[i], q) };
196
280
  });
@@ -217,5 +301,7 @@ function shortlist(query, items, limit, include) {
217
301
  module.exports = {
218
302
  stem: stem,
219
303
  tokens: tokens,
304
+ queryTokens: queryTokens,
305
+ withoutExclusions: withoutExclusions,
220
306
  shortlist: shortlist,
221
307
  };
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mastermind-agents
3
- description: Mastermind agents — list, inspect, hire, pause, and remove agents in a running org. Shows status, last heartbeat, adapter config, and burn rate per agent.
3
+ description: Mastermind agents — list, inspect, hire, and remove agents in an org, and pause or resume the org. Shows each role, its adapter config, and the org's live runtime status.
4
4
  type: domain-skill
5
5
  default_mode: confirm
6
6
  pick: low
@@ -44,23 +44,18 @@ If no orgs exist, print: "No orgs found. Run /mastermind:createorg to define one
44
44
 
45
45
  ### list (default)
46
46
 
47
- Display all agents in the org with status from state file:
47
+ Display all agents in the org, then the org's live runtime status:
48
48
 
49
49
  ```bash
50
50
  orgFile=".monomind/orgs/${org_name}.json"
51
- stateFile=".monomind/orgs/${org_name}-state.json"
52
-
53
- jq -r '(.roles // [])[] | "• [\(.id)] \(.title) agent=\(.agent_type) reports_to=\(.reports_to // "none")"' "$orgFile"
54
-
55
- # LEGACY-ORG-V1: the state file's per-agent heartbeat tracking is a v1 concept —
56
- # v2 orgs report live status via `monomind org status`/`org report` instead.
57
- # Overlay runtime status from state file if present
58
- if [ -f "$stateFile" ]; then
59
- echo ""
60
- echo "RUNTIME STATUS:"
61
- jq -r '.agents // {} | to_entries[] | " \(.key): \(.value.status // "unknown") last_beat=\(.value.last_heartbeat // "never")"' "$stateFile" 2>/dev/null || true
62
- fi
63
- # end LEGACY-ORG-V1
51
+
52
+ jq -r '(.roles // [])[] | "• [\(.id)] \(.title) type=\(.type // "specialist") reports_to=\(.reports_to // "none")"' "$orgFile"
53
+
54
+ # Live runtime status (running/stopped/crashed, current run) — per-role
55
+ # activity for a run is in `monomind org report <org>`.
56
+ echo ""
57
+ echo "RUNTIME STATUS:"
58
+ npx -y monomind@latest org status "$org_name" 2>/dev/null || echo " (not available — is monomind installed?)"
64
59
  ```
65
60
 
66
61
  Render as table:
@@ -68,26 +63,28 @@ Render as table:
68
63
  ```
69
64
  AGENTS — org: <org_name>
70
65
  ──────────────────────────────────────────────────────
71
- ID TITLE AGENT TYPE STATUS LAST HEARTBEAT
72
- boss CEO / Boss coordinator running 2 min ago
73
- content-writer Content Writer Content Creator idle 8 min ago
74
- reviewer Content Reviewer reviewer waiting 8 min ago
66
+ ID TITLE TYPE REPORTS TO
67
+ boss CEO / Boss boss none
68
+ content-writer Content Writer specialist boss
69
+ reviewer Content Reviewer reviewer boss
75
70
  ...
76
71
  ```
77
72
 
78
73
  ### inspect
79
74
 
80
- Show full config + responsibilities + communication edges for a single agent:
75
+ Show the full role config (responsibilities, adapter config) and who it reports to / who reports to it:
81
76
 
82
77
  ```bash
83
78
  jq --arg id "$agent_id" '(.roles // [])[] | select(.id == $id)' "$orgFile"
84
- jq --arg id "$agent_id" '(.communication // [])[] | select(.from == $id or .to == $id)' "$orgFile"
79
+ jq -r --arg id "$agent_id" '(.roles // [])[] | select(.reports_to == $id) | " direct report: \(.id)"' "$orgFile"
85
80
  ```
86
81
 
87
82
  ### hire
88
83
 
89
84
  Add a new role to the org. Prompt the user for:
90
- - `id` (slug, e.g. `seo-lead`), `title` (display name), `agent_type` (from mapping table in createorg.md), `responsibilities` (comma-separated), `reports_to` (role id or null)
85
+ - `id` (slug, e.g. `seo-lead`), `title` (display name), `role_type` → the role's `type` (`specialist`, or a domain synonym such as `reviewer` / `researcher` — free text; only `boss` is special, and an org has exactly one root), `responsibilities` (comma-separated), `reports_to` (an existing role id — a hired role is never the root)
86
+
87
+ Write the Org Runtime role shape (`RoleSchema` in `packages/@monomind/cli/src/orgrt/types.ts`): `type`, never the legacy `agent_type` key — a role carrying `agent_type` makes the whole config read as the retired v1 format.
91
88
 
92
89
  **Adapter/model selection** — present this picker:
93
90
 
@@ -114,33 +111,29 @@ adapter_model="${selected_model:-claude-sonnet-5}"
114
111
  tmp="${orgFile}.tmp"
115
112
  jq --arg id "$agent_id" \
116
113
  --arg title "$title" \
117
- --arg agent_type "$agent_type" \
118
- --arg reports_to "${reports_to:-}" \
114
+ --arg type "${role_type:-specialist}" \
115
+ --arg reports_to "$reports_to" \
119
116
  --arg model "$adapter_model" \
120
117
  --argjson resp "$(echo "$responsibilities" | jq -R 'split(",") | map(ltrimstr(" "))')" \
121
- '.roles += [{"id":$id,"title":$title,"agent_type":$agent_type,
118
+ '.roles += [{"id":$id,"title":$title,"type":$type,
122
119
  "responsibilities":$resp,
123
- "reports_to":($reports_to|if .=="" then null else . end),
120
+ "reports_to":$reports_to,
124
121
  "adapter_config":{"model":$model,"max_tokens":8192}}]' \
125
122
  "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
126
- echo "Hired: $title ($agent_type) → adapter: $adapter_model"
123
+ echo "Hired: $title (${role_type:-specialist}) → adapter: $adapter_model"
124
+ npx -y monomind@latest org validate "$org_name"
127
125
  ```
128
126
 
129
127
  ### pause / resume
130
128
 
131
- <!-- LEGACY-ORG-V1: the agent state/heartbeat file this pauses is a v1 concept. -->
132
- Update state file:
129
+ The Org Runtime pauses and resumes a whole org, not a single role — message
130
+ delivery is suspended while it is paused:
133
131
 
134
132
  ```bash
135
- stateFile=".monomind/orgs/${org_name}-state.json"
136
- [ ! -f "$stateFile" ] && echo '{"agents":{}}' > "$stateFile"
137
- tmp="${stateFile}.tmp"
138
- jq --arg id "$agent_id" --arg status "paused" \
139
- '.agents[$id].status = $status | .agents[$id].updated_at = (now|todate)' \
140
- "$stateFile" > "$tmp" && mv "$tmp" "$stateFile"
133
+ npx -y monomind@latest org pause "$org_name" # or: org resume "$org_name"
141
134
  ```
142
135
 
143
- Emit `org:agent:paused` / `org:agent:resumed` event.
136
+ To take one role out of the org, use `remove`.
144
137
 
145
138
  ### remove
146
139
 
@@ -148,7 +141,7 @@ Confirm with user, then remove role from org config:
148
141
 
149
142
  ```bash
150
143
  tmp="${orgFile}.tmp"
151
- jq --arg id "$agent_id" '.roles = [(.roles // [])[] | select(.id != $id)] | .communication = [(.communication // [])[] | select(.from != $id and .to != $id)]' \
144
+ jq --arg id "$agent_id" '.roles = [(.roles // [])[] | select(.id != $id)]' \
152
145
  "$orgFile" > "$tmp" && mv "$tmp" "$orgFile"
153
146
  ```
154
147
 
@@ -164,7 +157,7 @@ org: <org_name>
164
157
  agents_count: <N>
165
158
  ```
166
159
 
167
- Print summary and any suggested next actions (e.g. "Run /mastermind:heartbeatv1 to trigger a manual heartbeat for this agent").
160
+ Print summary and any suggested next actions (e.g. "Check live status with `monomind org status <org_name>`").
168
161
 
169
162
  ---
170
163
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mastermind-createorg
3
- description: Mastermind createorg — design and persist an autonomous agent organization (Org Runtime v2) as a `.monomind/orgs/<name>.json` config that `monomind org run/serve` loads directly. Supports optional --schedule flag for daemon-scheduled orgs.
3
+ description: Mastermind createorg — design and persist an autonomous agent organization (Org Runtime) as a `.monomind/orgs/<name>.json` config that `monomind org run/serve` loads directly. Supports optional --schedule flag for daemon-scheduled orgs.
4
4
  type: domain-skill
5
5
  default_mode: confirm
6
6
  ---
@@ -9,7 +9,7 @@ default_mode: confirm
9
9
 
10
10
  This skill is invoked by `mastermind:createorg` or directly via `/mastermind:createorg`.
11
11
 
12
- Org Runtime v2 (`packages/@monomind/cli/src/orgrt/`) is a Node daemon, not a Task-tool-spawned boss agent. Every role in the config becomes a live SDK agent session (`@anthropic-ai/claude-agent-sdk` `query()`) the moment the org starts — there is no task board, no per-role generated `.claude/agents/*.md` file, and no communication-topology array. Roles address each other directly with the `org_send` tool using their `id` (or `<org>:<id>` cross-org). This skill's only job is to produce a config that validates against `OrgDefSchema` (`packages/@monomind/cli/src/orgrt/types.ts`).
12
+ The Org Runtime (`packages/@monomind/cli/src/orgrt/`) is a Node daemon, not a Task-tool-spawned boss agent. Every role in the config becomes a live SDK agent session (`@anthropic-ai/claude-agent-sdk` `query()`) the moment the org starts — there is no task board, no per-role generated `.claude/agents/*.md` file, and no communication-topology array. Roles address each other directly with the `org_send` tool using their `id` (or `<org>:<id>` cross-org). This skill's only job is to produce a config that validates against `OrgDefSchema` (`packages/@monomind/cli/src/orgrt/types.ts`).
13
13
 
14
14
  ---
15
15
 
@@ -71,7 +71,7 @@ Exactly one role must have `reports_to: null`. If the user's role list has none,
71
71
 
72
72
  A role is **persona-based** if its title is a named real person, a well-known fictional character, or a celebrity/historical figure referred to by name. An org is persona-based if ≥50% of its roles are character names, or the goal/prompt contains `panel`, `debate`, `simulation`, `roleplay`, `celebrity`, `character`, `virtual [name]`, `impersonate`, `as [name]`.
73
73
 
74
- Persona roles work the same as any other role in v2 — there is no separate `agent_type`/subagent registry to resolve against. Put the character depth directly into `responsibilities` (fed into the agent's role briefing by `buildRolePrompt` in `orgrt/session.ts`, alongside the role's `skills` and `instructions_file`, if set — see Step 2.3): write 3-6 specific, voice-defining responsibilities drawn from the character's known career, positions, and communication style, not generic duties. For a living public figure, base it on documented public behavior — do not invent positions they haven't taken.
74
+ Persona roles work the same as any other role — there is no separate `agent_type`/subagent registry to resolve against. Put the character depth directly into `responsibilities` (fed into the agent's role briefing by `buildRolePrompt` in `orgrt/session.ts`, alongside the role's `skills` and `instructions_file`, if set — see Step 2.3): write 3-6 specific, voice-defining responsibilities drawn from the character's known career, positions, and communication style, not generic duties. For a living public figure, base it on documented public behavior — do not invent positions they haven't taken.
75
75
 
76
76
  **Step 2.2b — Seed each non-persona role from the agent registry.**
77
77
 
@@ -82,18 +82,6 @@ echo " namespace: org:${org_name}"
82
82
  npx monomind@latest memory list --namespace "org:${org_name}" 2>/dev/null | wc -l | xargs echo " stored entries:"
83
83
  echo ""
84
84
 
85
- # LEGACY-ORG-V1: board_id/*_col_id only exist on the pre-v2 board-backed org shape
86
- # Board config
87
- echo "TASK BOARD"
88
- echo "──────────"
89
- board_id=$(jq -r '.board_id // "NOT CONFIGURED"' "$orgFile")
90
- echo " board_id: $board_id"
91
- echo " todo_col: $(jq -r '.todo_col_id // "NOT CONFIGURED"' "$orgFile")"
92
- echo " doing_col: $(jq -r '.doing_col_id // "NOT CONFIGURED"' "$orgFile")"
93
- echo " done_col: $(jq -r '.done_col_id // "NOT CONFIGURED"' "$orgFile")"
94
- echo ""
95
- # end LEGACY-ORG-V1 board block
96
-
97
85
  # Run config
98
86
  echo "RUN CONFIG"
99
87
  echo "──────────"
@@ -132,12 +120,10 @@ for key in ANTHROPIC_API_KEY; do
132
120
  fi
133
121
  done
134
122
 
135
- # LEGACY-ORG-V1: board_id belongs to the legacy v1 runner — see runorgv1. Org
136
- # Runtime v2 configs have no board_id at all, so this check only applies to
137
- # orgs still running the v1 board-backed shape.
138
- board_id=$(jq -r '.board_id // empty' "$orgFile")
139
- [ -z "$board_id" ] && { echo " ✗ MISSING: board_id — boards belong to the legacy v1 runner, see runorgv1"; errors=$((errors + 1)); } || echo " ✓ board_id"
140
- # end LEGACY-ORG-V1
123
+ # Check the config against the runtime schema and structural invariants
124
+ npx -y monomind@latest org validate "$org_name" >/dev/null 2>&1 \
125
+ && echo " ✓ config valid (monomind org validate)" \
126
+ || { echo " ✗ INVALID config — run: monomind org validate $org_name"; errors=$((errors + 1)); }
141
127
 
142
128
  # Check roles
143
129
  role_count=$(jq '.roles | length' "$orgFile")
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mastermind-inbox
3
- description: Mastermind inbox — unified view of everything that needs human attention across all orgs: pending approvals, running heartbeats, active task assignments, and budget alerts. The single place to check before starting work.
3
+ description: Mastermind inbox — unified view of everything that needs human attention across all orgs: pending tool approvals, running orgs, active task assignments, and budget alerts. The single place to check before starting work.
4
4
  type: domain-skill
5
5
  default_mode: auto
6
6
  pick: low
@@ -53,25 +53,20 @@ total_alerts=0
53
53
  for org in $orgs; do
54
54
  orgFile=".monomind/orgs/${org}.json"
55
55
  stateFile=".monomind/orgs/${org}-state.json"
56
- approvalsFile=".monomind/orgs/${org}-approvals.json"
56
+ approvalsFile=".monomind/orgs/${org}/approvals.json"
57
+ rtFile=".monomind/orgs/${org}/runtime.json"
57
58
 
58
- # LEGACY-ORG-V1: approvals files only exist for the v1 prompt-orchestrated
59
- # runner — see runorgv1 / approvev1.
60
- # 1. Pending approvals
59
+ # 1. Pending tool approvals (the runtime's queue — `monomind org approvals <org>`)
61
60
  if [ -f "$approvalsFile" ]; then
62
- pending=$(jq '[(.approvals // [])[] | select(.status == "pending")] | length' "$approvalsFile" 2>/dev/null || echo 0)
61
+ pending=$(jq '[(.approvals // [])[] | select(.approved == null)] | length' "$approvalsFile" 2>/dev/null || echo 0)
63
62
  total_approvals=$((total_approvals + pending))
64
63
  fi
65
- # end LEGACY-ORG-V1
66
-
67
- # LEGACY-ORG-V1: state-file "heartbeats" are the v1 scheduler's running-agent
68
- # tracking — v2 runs live under .monomind/orgs/<name>/run-*/bus.jsonl instead.
69
- # 2. Running agents (active heartbeats)
70
- if [ -f "$stateFile" ]; then
71
- running=$(jq '[.agents // {} | to_entries[] | select(.value.status == "running")] | length' "$stateFile" 2>/dev/null || echo 0)
72
- total_heartbeats=$((total_heartbeats + running))
64
+
65
+ # 2. Running orgs (runtime.json status "running" with a live pid)
66
+ rt_pid=$(jq -r 'if .status == "running" then (.pid // 0) else 0 end' "$rtFile" 2>/dev/null || echo 0)
67
+ if [ "$rt_pid" -gt 0 ] && kill -0 "$rt_pid" 2>/dev/null; then
68
+ total_heartbeats=$((total_heartbeats + 1))
73
69
  fi
74
- # end LEGACY-ORG-V1
75
70
 
76
71
  # 3. Budget alerts
77
72
  budget=$(jq -r '.run_config.budget_tokens // 0' "$orgFile" 2>/dev/null || echo 0)
@@ -97,36 +92,32 @@ echo "║ MASTERMIND INBOX ║"
97
92
  echo "╚══════════════════════════════════════════════════════╝"
98
93
  echo ""
99
94
  echo " 🔴 APPROVALS NEEDED: $total_approvals"
100
- echo " 🟡 AGENTS RUNNING: $total_heartbeats"
95
+ echo " 🟡 ORGS RUNNING: $total_heartbeats"
101
96
  echo " 🟠 BUDGET ALERTS: $total_alerts"
102
97
  echo ""
103
98
 
104
99
  for org in $orgs; do
105
100
  orgFile=".monomind/orgs/${org}.json"
106
101
  stateFile=".monomind/orgs/${org}-state.json"
107
- approvalsFile=".monomind/orgs/${org}-approvals.json"
102
+ approvalsFile=".monomind/orgs/${org}/approvals.json"
103
+ rtFile=".monomind/orgs/${org}/runtime.json"
108
104
 
109
105
  has_items=0
110
106
 
111
- # LEGACY-ORG-V1: approvals belong to the v1 prompt-orchestrated runner
112
- # Pending approvals
107
+ # Pending tool approvals
113
108
  if [ -f "$approvalsFile" ]; then
114
- pending_approvals=$(jq -r '(.approvals // [])[] | select(.status == "pending") | " [APPROVAL] [\(.id)] \(.agent_id): \(.title) risk=\(.risk_level // "low")"' \
109
+ pending_approvals=$(jq -r '(.approvals // [])[] | select(.approved == null) | " [APPROVAL] \(.roleId): \(.action)\(if .requestId then " [\(.requestId)]" else "" end)"' \
115
110
  "$approvalsFile" 2>/dev/null)
116
111
  [ -n "$pending_approvals" ] && { has_items=1; echo "ORG: $org"; echo "$pending_approvals"; }
117
112
  fi
118
- # end LEGACY-ORG-V1
119
-
120
- # LEGACY-ORG-V1: state-file heartbeats are the v1 scheduler's tracking
121
- # Running agents
122
- if [ -f "$stateFile" ]; then
123
- running_agents=$(jq -r '
124
- .agents // {} | to_entries[] | select(.value.status == "running") |
125
- " [RUNNING] [\(.key)] since=\(.value.last_heartbeat // "unknown")"
126
- ' "$stateFile" 2>/dev/null)
127
- [ -n "$running_agents" ] && { has_items=1; [ $has_items -eq 1 ] || echo "ORG: $org"; echo "$running_agents"; }
113
+
114
+ # Running org
115
+ rt_pid=$(jq -r 'if .status == "running" then (.pid // 0) else 0 end' "$rtFile" 2>/dev/null || echo 0)
116
+ if [ "$rt_pid" -gt 0 ] && kill -0 "$rt_pid" 2>/dev/null; then
117
+ [ $has_items -eq 1 ] || echo "ORG: $org"
118
+ has_items=1
119
+ echo " [RUNNING] run=$(jq -r '.run // "?"' "$rtFile") since=$(jq -r '.updated // "unknown"' "$rtFile")"
128
120
  fi
129
- # end LEGACY-ORG-V1
130
121
 
131
122
  [ $has_items -eq 1 ] && echo ""
132
123
  done
@@ -138,34 +129,21 @@ fi
138
129
 
139
130
  ### filter: approvals only
140
131
 
141
- <!-- LEGACY-ORG-V1: approvals belong to the v1 prompt-orchestrated runner — see runorgv1 / approvev1. -->
142
132
  ```bash
143
133
  for org in $orgs; do
144
- approvalsFile=".monomind/orgs/${org}-approvals.json"
145
- [ -f "$approvalsFile" ] || continue
134
+ [ -f ".monomind/orgs/${org}/approvals.json" ] || continue
146
135
  echo "=== $org ==="
147
- jq -r '(.approvals // [])[] | select(.status == "pending") |
148
- "[\(.id)] \(.agent_id): \(.title)\n Action: \(.action)\n Risk: \(.risk_level // "low")\n → /mastermind:approvev1 --org '"$org"' --action approve --approval-id \(.id)"
149
- ' "$approvalsFile" 2>/dev/null || echo " No pending approvals."
136
+ npx -y monomind@latest org approvals "$org"
150
137
  echo ""
151
138
  done
152
139
  ```
153
140
 
154
141
  ### filter: heartbeats only
155
142
 
156
- <!-- LEGACY-ORG-V1: state-file heartbeats are the v1 scheduler's running-agent tracking. -->
157
- Show currently running agent heartbeats across all orgs:
143
+ Show the orgs that are running now:
158
144
 
159
145
  ```bash
160
- for org in $orgs; do
161
- stateFile=".monomind/orgs/${org}-state.json"
162
- [ -f "$stateFile" ] || continue
163
- running=$(jq -r '
164
- .agents // {} | to_entries[] | select(.value.status == "running") |
165
- " [\(.key)] since=\(.value.last_heartbeat // "?")"
166
- ' "$stateFile" 2>/dev/null)
167
- [ -n "$running" ] && { echo "=== $org ==="; echo "$running"; echo ""; }
168
- done
146
+ npx -y monomind@latest org status
169
147
  ```
170
148
 
171
149
  ### filter: alerts only
@@ -193,11 +171,12 @@ done
193
171
  From the inbox, the user can directly:
194
172
 
195
173
  ```bash
196
- # Approve a pending request:
197
- /mastermind:approvev1 --org <org> --action approve --approval-id <id>
174
+ # Approve or deny a pending tool request:
175
+ monomind org approve <org> <role> "<action>"
176
+ monomind org deny <org> <role> "<action>"
198
177
 
199
- # Stop a running agent:
200
- /mastermind-agents --org <org> --action pause --agent-id <id>
178
+ # Stop a running org:
179
+ monomind org stop <org>
201
180
 
202
181
  # Check costs:
203
182
  /mastermind:costs --org <org> --action report
@@ -85,8 +85,9 @@ echo " Active orgs: $orgs"
85
85
 
86
86
  ### heartbeats
87
87
 
88
- <!-- LEGACY-ORG-V1: role-level heartbeat scheduling is a v1 org concept — v2 orgs run on `schedule` via the daemon instead. -->
89
- List all agents across all orgs that have scheduled heartbeats:
88
+ The Org Runtime does not read role-level `heartbeat` fields — orgs run on their
89
+ top-level `schedule` under `monomind org serve`. This lists any role `heartbeat`
90
+ fields still present in org config files:
90
91
 
91
92
  ```bash
92
93
  echo "SCHEDULER HEARTBEATS"
@@ -118,13 +119,14 @@ for orgF in .monomind/orgs/*.json; do
118
119
  done
119
120
  done
120
121
 
121
- [ "$found" -eq 0 ] && echo " No scheduled heartbeat agents found. Configure via /mastermind:heartbeatv1."
122
+ [ "$found" -eq 0 ] && echo " No role heartbeat fields found. Orgs run on their top-level schedule via: monomind org serve"
122
123
  ```
123
124
 
124
125
  ### toggle-heartbeat
125
126
 
126
- <!-- LEGACY-ORG-V1: role-level heartbeat scheduling is a v1 org concept. -->
127
- Enable or disable the scheduler heartbeat for a specific agent:
127
+ Flip the role-level `heartbeat.enabled` field for a specific agent. The Org
128
+ Runtime ignores this field — to change when an org runs, edit its `schedule`
129
+ with `/mastermind-org-settings`:
128
130
 
129
131
  ```bash
130
132
  [ -z "$agent_id" ] && { echo "ERROR: --agent-id required."; exit 1; }
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mastermind-new-agent
3
- description: Mastermind new-agent — wizard to hire/create a new agent within an org. Configures runtime, model, role name, reports_to hierarchy, responsibilities, skill assignments (found with `monomind org skills search`), and budget. Writes a valid Org Runtime v2 role to the org config file and validates it.
3
+ description: Mastermind new-agent — wizard to hire/create a new agent within an org. Configures runtime, model, role name, reports_to hierarchy, responsibilities, skill assignments (found with `monomind org skills search`), and budget. Writes a valid Org Runtime role to the org config file and validates it.
4
4
  type: domain-skill
5
5
  default_mode: confirm
6
6
  pick: low
@@ -10,7 +10,7 @@ pick: low
10
10
 
11
11
  This skill is invoked by `mastermind:new-agent` or directly via `/mastermind-new-agent`.
12
12
 
13
- It writes one role in the Org Runtime v2 shape (`RoleSchema` in `packages/@monomind/cli/src/orgrt/types.ts`) — the same shape `mastermind-createorg` produces — and runs `monomind org validate` on the result. There is no `adapter` object, heartbeat or per-role system prompt in v2: the runtime reads `runtime`, `adapter_config.model`, `responsibilities`, `skills` and `skill_pool`.
13
+ It writes one role in the Org Runtime shape (`RoleSchema` in `packages/@monomind/cli/src/orgrt/types.ts`) — the same shape `mastermind-createorg` produces — and runs `monomind org validate` on the result. There is no `adapter` object, heartbeat or per-role system prompt in the org config: the runtime reads `runtime`, `adapter_config.model`, `responsibilities`, `skills` and `skill_pool`.
14
14
 
15
15
  ---
16
16
 
@@ -82,7 +82,7 @@ Pin 1–3 that define the role in `skills`; put the ones it needs only for some
82
82
  ### list-runtimes
83
83
 
84
84
  ```bash
85
- echo "ORG RUNTIME v2 RUNTIMES (latest model)"
85
+ echo "ORG RUNTIME RUNTIMES (latest model)"
86
86
  echo "────────────────────────────────────────────────────────"
87
87
  cat <<'RUNTIMES'
88
88
  claude claude-sonnet-5 (default; also claude-opus-5, claude-fable-5-1, claude-haiku-4-5-20251001)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: mastermind-org-settings
3
- description: Mastermind org-settings — edit Org Runtime v2 configuration (name, goal, schedule, budget_tokens, memory_namespace, max_turns_per_message), export org as portable JSON, and import an org from a previously exported file.
3
+ description: Mastermind org-settings — edit Org Runtime configuration (name, goal, schedule, budget_tokens, memory_namespace, max_turns_per_message), export org as portable JSON, and import an org from a previously exported file.
4
4
  type: domain-skill
5
5
  default_mode: confirm
6
6
  pick: low
@@ -10,10 +10,9 @@ pick: low
10
10
 
11
11
  This skill is invoked by `mastermind:org-settings` or directly via `/mastermind-org-settings`.
12
12
 
13
- It edits `.monomind/orgs/<org_name>.json` in place, and only ever touches fields that `OrgDefSchema` (`packages/@monomind/cli/src/orgrt/types.ts`) actually defines — every field listed below is read by the daemon (`org.ts`/`daemon.ts`/`session.ts`) at `monomind org run`/`serve` time. Its primary edit flow targets v2 fields only: `name`, `goal`, `schedule`, and `run_config` (`budget_tokens`, `memory_namespace`, `max_turns_per_message`). Role edits are not yet supported by this skill's `edit` action — `roles` is shown read-only via `show`.
13
+ It edits `.monomind/orgs/<org_name>.json` in place, and only ever touches fields that `OrgDefSchema` (`packages/@monomind/cli/src/orgrt/types.ts`) actually defines — every field listed below is read by the daemon (`org.ts`/`daemon.ts`/`session.ts`) at `monomind org run`/`serve` time. Its primary edit flow targets these fields only: `name`, `goal`, `schedule`, and `run_config` (`budget_tokens`, `memory_namespace`, `max_turns_per_message`). Role edits are not yet supported by this skill's `edit` action — `roles` is shown read-only via `show`.
14
14
 
15
- <!-- LEGACY-ORG-V1: remove this note when v1 orgs are gone -->
16
- There is no `topology`, `governance`, `alert_threshold`, or `ceo_adapter` in Org Runtime v2 — those were v1 board/prompt-orchestration fields with no runtime effect and have been removed from this skill's edit surface. Use `/mastermind-org-settings` only for v2-shaped orgs; v1 orgs must go through `monomind org migrate` first.
15
+ There is no `topology`, `governance`, `alert_threshold`, or `ceo_adapter` in the org config — those are legacy fields with no runtime effect and are not part of this skill's edit surface. If an org's config file still carries them (the legacy format), convert it with `monomind org migrate <name>` first.
17
16
 
18
17
  ---
19
18