@monoes/monomindcli 2.1.9 → 2.3.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 (198) hide show
  1. package/.claude/commands/mastermind/createorg.md +24 -16
  2. package/.claude/commands/mastermind/master.md +23 -7
  3. package/.claude/commands/mastermind/runorg.md +3 -1
  4. package/.claude/commands/mastermind/stoporg.md +6 -3
  5. package/.claude/skills/mastermind-skills/code-quality-reviewer-prompt.md +3 -3
  6. package/.claude/skills/mastermind-skills/createorg.md +19 -24
  7. package/.claude/skills/mastermind-skills/debug.md +49 -4
  8. package/.claude/skills/mastermind-skills/design.md +11 -10
  9. package/.claude/skills/mastermind-skills/final-reviewer-prompt.md +144 -0
  10. package/.claude/skills/mastermind-skills/implementer-prompt.md +9 -4
  11. package/.claude/skills/mastermind-skills/org-settings.md +20 -2
  12. package/.claude/skills/mastermind-skills/orgs.md +40 -19
  13. package/.claude/skills/mastermind-skills/orgstatus.md +90 -41
  14. package/.claude/skills/mastermind-skills/plan.md +19 -0
  15. package/.claude/skills/mastermind-skills/skill-builder.md +171 -0
  16. package/.claude/skills/mastermind-skills/spec-reviewer-prompt.md +19 -2
  17. package/.claude/skills/mastermind-skills/stoporg.md +7 -5
  18. package/.claude/skills/mastermind-skills/taskdev.md +83 -15
  19. package/.claude/skills/mastermind-skills/tdd.md +30 -0
  20. package/dist/src/autopilot-state.js +6 -4
  21. package/dist/src/autopilot-state.js.map +1 -1
  22. package/dist/src/browser/dashboard/server.d.ts.map +1 -1
  23. package/dist/src/browser/dashboard/server.js +4 -1
  24. package/dist/src/browser/dashboard/server.js.map +1 -1
  25. package/dist/src/capabilities/manager.d.ts.map +1 -1
  26. package/dist/src/capabilities/manager.js +3 -1
  27. package/dist/src/capabilities/manager.js.map +1 -1
  28. package/dist/src/commands/agent-lifecycle.d.ts.map +1 -1
  29. package/dist/src/commands/agent-lifecycle.js +26 -0
  30. package/dist/src/commands/agent-lifecycle.js.map +1 -1
  31. package/dist/src/commands/agent-ops.d.ts.map +1 -1
  32. package/dist/src/commands/agent-ops.js +28 -46
  33. package/dist/src/commands/agent-ops.js.map +1 -1
  34. package/dist/src/commands/cleanup.d.ts +18 -0
  35. package/dist/src/commands/cleanup.d.ts.map +1 -1
  36. package/dist/src/commands/cleanup.js +120 -0
  37. package/dist/src/commands/cleanup.js.map +1 -1
  38. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  39. package/dist/src/commands/doctor-project-checks.js +13 -4
  40. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  41. package/dist/src/commands/hooks-routing-commands.d.ts.map +1 -1
  42. package/dist/src/commands/hooks-routing-commands.js +34 -18
  43. package/dist/src/commands/hooks-routing-commands.js.map +1 -1
  44. package/dist/src/commands/hooks-workers.d.ts.map +1 -1
  45. package/dist/src/commands/hooks-workers.js +8 -2
  46. package/dist/src/commands/hooks-workers.js.map +1 -1
  47. package/dist/src/commands/hooks.js +1 -1
  48. package/dist/src/commands/hooks.js.map +1 -1
  49. package/dist/src/commands/init-wizard.js +2 -2
  50. package/dist/src/commands/init-wizard.js.map +1 -1
  51. package/dist/src/commands/init.d.ts.map +1 -1
  52. package/dist/src/commands/init.js +54 -10
  53. package/dist/src/commands/init.js.map +1 -1
  54. package/dist/src/commands/mcp.js +4 -1
  55. package/dist/src/commands/mcp.js.map +1 -1
  56. package/dist/src/commands/memory-admin.d.ts.map +1 -1
  57. package/dist/src/commands/memory-admin.js +7 -1
  58. package/dist/src/commands/memory-admin.js.map +1 -1
  59. package/dist/src/commands/org-observe.d.ts +18 -0
  60. package/dist/src/commands/org-observe.d.ts.map +1 -0
  61. package/dist/src/commands/org-observe.js +295 -0
  62. package/dist/src/commands/org-observe.js.map +1 -0
  63. package/dist/src/commands/org.d.ts +9 -1
  64. package/dist/src/commands/org.d.ts.map +1 -1
  65. package/dist/src/commands/org.js +191 -9
  66. package/dist/src/commands/org.js.map +1 -1
  67. package/dist/src/commands/performance.js +4 -1
  68. package/dist/src/commands/performance.js.map +1 -1
  69. package/dist/src/commands/platforms.js +4 -1
  70. package/dist/src/commands/platforms.js.map +1 -1
  71. package/dist/src/commands/security-scan.js +8 -2
  72. package/dist/src/commands/security-scan.js.map +1 -1
  73. package/dist/src/commands/start.d.ts.map +1 -1
  74. package/dist/src/commands/start.js +4 -1
  75. package/dist/src/commands/start.js.map +1 -1
  76. package/dist/src/commands/swarm.js +5 -4
  77. package/dist/src/commands/swarm.js.map +1 -1
  78. package/dist/src/index.d.ts.map +1 -1
  79. package/dist/src/index.js +13 -3
  80. package/dist/src/index.js.map +1 -1
  81. package/dist/src/init/executor.d.ts.map +1 -1
  82. package/dist/src/init/executor.js +19 -5
  83. package/dist/src/init/executor.js.map +1 -1
  84. package/dist/src/init/settings-generator.d.ts.map +1 -1
  85. package/dist/src/init/settings-generator.js +8 -1
  86. package/dist/src/init/settings-generator.js.map +1 -1
  87. package/dist/src/knowledge/document-pipeline.js +3 -2
  88. package/dist/src/knowledge/document-pipeline.js.map +1 -1
  89. package/dist/src/mcp-tools/agent-tools.d.ts +1 -0
  90. package/dist/src/mcp-tools/agent-tools.d.ts.map +1 -1
  91. package/dist/src/mcp-tools/agent-tools.js +63 -20
  92. package/dist/src/mcp-tools/agent-tools.js.map +1 -1
  93. package/dist/src/mcp-tools/claims-tools.d.ts.map +1 -1
  94. package/dist/src/mcp-tools/claims-tools.js +3 -1
  95. package/dist/src/mcp-tools/claims-tools.js.map +1 -1
  96. package/dist/src/mcp-tools/config-tools.js +3 -2
  97. package/dist/src/mcp-tools/config-tools.js.map +1 -1
  98. package/dist/src/mcp-tools/daa-tools.js +3 -2
  99. package/dist/src/mcp-tools/daa-tools.js.map +1 -1
  100. package/dist/src/mcp-tools/embeddings-tools.d.ts.map +1 -1
  101. package/dist/src/mcp-tools/embeddings-tools.js +6 -2
  102. package/dist/src/mcp-tools/embeddings-tools.js.map +1 -1
  103. package/dist/src/mcp-tools/github-tools.js +35 -10
  104. package/dist/src/mcp-tools/github-tools.js.map +1 -1
  105. package/dist/src/mcp-tools/hive-mind-tools.d.ts.map +1 -1
  106. package/dist/src/mcp-tools/hive-mind-tools.js +24 -7
  107. package/dist/src/mcp-tools/hive-mind-tools.js.map +1 -1
  108. package/dist/src/mcp-tools/hooks-embedding.d.ts.map +1 -1
  109. package/dist/src/mcp-tools/hooks-embedding.js +13 -3
  110. package/dist/src/mcp-tools/hooks-embedding.js.map +1 -1
  111. package/dist/src/mcp-tools/hooks-intelligence.d.ts.map +1 -1
  112. package/dist/src/mcp-tools/hooks-intelligence.js +9 -3
  113. package/dist/src/mcp-tools/hooks-intelligence.js.map +1 -1
  114. package/dist/src/mcp-tools/hooks-routing.d.ts +1 -0
  115. package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
  116. package/dist/src/mcp-tools/hooks-routing.js +112 -10
  117. package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
  118. package/dist/src/mcp-tools/hooks-tools.d.ts.map +1 -1
  119. package/dist/src/mcp-tools/hooks-tools.js +2 -1
  120. package/dist/src/mcp-tools/hooks-tools.js.map +1 -1
  121. package/dist/src/mcp-tools/monograph-tools.d.ts.map +1 -1
  122. package/dist/src/mcp-tools/monograph-tools.js +8 -2
  123. package/dist/src/mcp-tools/monograph-tools.js.map +1 -1
  124. package/dist/src/mcp-tools/performance-tools.js +3 -2
  125. package/dist/src/mcp-tools/performance-tools.js.map +1 -1
  126. package/dist/src/mcp-tools/session-tools.d.ts.map +1 -1
  127. package/dist/src/mcp-tools/session-tools.js +15 -5
  128. package/dist/src/mcp-tools/session-tools.js.map +1 -1
  129. package/dist/src/mcp-tools/swarm-tools.d.ts.map +1 -1
  130. package/dist/src/mcp-tools/swarm-tools.js +4 -1
  131. package/dist/src/mcp-tools/swarm-tools.js.map +1 -1
  132. package/dist/src/mcp-tools/system-tools.js +6 -4
  133. package/dist/src/mcp-tools/system-tools.js.map +1 -1
  134. package/dist/src/mcp-tools/task-tools.d.ts +20 -0
  135. package/dist/src/mcp-tools/task-tools.d.ts.map +1 -1
  136. package/dist/src/mcp-tools/task-tools.js +38 -16
  137. package/dist/src/mcp-tools/task-tools.js.map +1 -1
  138. package/dist/src/mcp-tools/terminal-tools.d.ts +2 -0
  139. package/dist/src/mcp-tools/terminal-tools.d.ts.map +1 -1
  140. package/dist/src/mcp-tools/terminal-tools.js +68 -24
  141. package/dist/src/mcp-tools/terminal-tools.js.map +1 -1
  142. package/dist/src/memory/ewc-consolidation.d.ts.map +1 -1
  143. package/dist/src/memory/ewc-consolidation.js +6 -2
  144. package/dist/src/memory/ewc-consolidation.js.map +1 -1
  145. package/dist/src/memory/intelligence.d.ts.map +1 -1
  146. package/dist/src/memory/intelligence.js +32 -10
  147. package/dist/src/memory/intelligence.js.map +1 -1
  148. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  149. package/dist/src/memory/memory-bridge.js +16 -4
  150. package/dist/src/memory/memory-bridge.js.map +1 -1
  151. package/dist/src/memory/memory-crud.d.ts.map +1 -1
  152. package/dist/src/memory/memory-crud.js +26 -2
  153. package/dist/src/memory/memory-crud.js.map +1 -1
  154. package/dist/src/memory/memory-initializer.js +3 -2
  155. package/dist/src/memory/memory-initializer.js.map +1 -1
  156. package/dist/src/memory/memory-migrations.d.ts.map +1 -1
  157. package/dist/src/memory/memory-migrations.js +2 -0
  158. package/dist/src/memory/memory-migrations.js.map +1 -1
  159. package/dist/src/monovector/command-outcomes.d.ts.map +1 -1
  160. package/dist/src/monovector/command-outcomes.js +4 -1
  161. package/dist/src/monovector/command-outcomes.js.map +1 -1
  162. package/dist/src/orgrt/bus.d.ts.map +1 -1
  163. package/dist/src/orgrt/bus.js +4 -1
  164. package/dist/src/orgrt/bus.js.map +1 -1
  165. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  166. package/dist/src/orgrt/daemon.js +74 -19
  167. package/dist/src/orgrt/daemon.js.map +1 -1
  168. package/dist/src/orgrt/inbox.d.ts.map +1 -1
  169. package/dist/src/orgrt/inbox.js +3 -1
  170. package/dist/src/orgrt/inbox.js.map +1 -1
  171. package/dist/src/orgrt/reporting.d.ts +40 -0
  172. package/dist/src/orgrt/reporting.d.ts.map +1 -0
  173. package/dist/src/orgrt/reporting.js +127 -0
  174. package/dist/src/orgrt/reporting.js.map +1 -0
  175. package/dist/src/orgrt/session.d.ts +2 -0
  176. package/dist/src/orgrt/session.d.ts.map +1 -1
  177. package/dist/src/orgrt/session.js +10 -2
  178. package/dist/src/orgrt/session.js.map +1 -1
  179. package/dist/src/orgrt/templates.d.ts +16 -0
  180. package/dist/src/orgrt/templates.d.ts.map +1 -0
  181. package/dist/src/orgrt/templates.js +57 -0
  182. package/dist/src/orgrt/templates.js.map +1 -0
  183. package/dist/src/services/config-file-manager.d.ts.map +1 -1
  184. package/dist/src/services/config-file-manager.js +10 -1
  185. package/dist/src/services/config-file-manager.js.map +1 -1
  186. package/dist/src/transfer/storage/gcs.d.ts.map +1 -1
  187. package/dist/src/transfer/storage/gcs.js +6 -2
  188. package/dist/src/transfer/storage/gcs.js.map +1 -1
  189. package/dist/src/ui/orgs.html +32 -0
  190. package/dist/src/ui/server.mjs +25 -0
  191. package/dist/src/update/executor.d.ts.map +1 -1
  192. package/dist/src/update/executor.js +3 -1
  193. package/dist/src/update/executor.js.map +1 -1
  194. package/dist/src/update/rate-limiter.d.ts.map +1 -1
  195. package/dist/src/update/rate-limiter.js +3 -1
  196. package/dist/src/update/rate-limiter.js.map +1 -1
  197. package/dist/tsconfig.tsbuildinfo +1 -1
  198. package/package.json +2 -2
@@ -0,0 +1,295 @@
1
+ // packages/@monomind/cli/src/commands/org-observe.ts
2
+ // Read-side org subcommands (logs / report) + template scaffolding (create).
3
+ // Kept out of org.ts to respect the 500-line file ceiling.
4
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
5
+ import { join } from 'node:path';
6
+ import { output } from '../output.js';
7
+ import { ORG_DIR, OrgDefSchema } from '../orgrt/types.js';
8
+ import { formatEvent, listRunDirs, readHistory, readRunEvents, summarizeRun } from '../orgrt/reporting.js';
9
+ import { ORG_TEMPLATES, buildFromTemplate } from '../orgrt/templates.js';
10
+ import { parseSchedule } from '../orgrt/scheduler.js';
11
+ import { listOrgConfigFiles, validateOrgName } from './org.js';
12
+ const log = (text) => { console.log(text); };
13
+ /** Validate org config(s) against OrgDefSchema — the exact parse `org run`/`org serve`
14
+ * perform — plus the structural invariants the runtime assumes but the schema can't
15
+ * express (single root role, resolvable reports_to, unique ids, parseable schedule). */
16
+ export const validateAction = async (ctx) => {
17
+ const orgsDir = join(ctx.cwd || process.cwd(), ORG_DIR);
18
+ let files;
19
+ if (ctx.args[0]) {
20
+ const validated = validateOrgName(ctx.args[0]);
21
+ if (!validated.ok)
22
+ return validated.result;
23
+ files = [`${validated.name}.json`];
24
+ }
25
+ else {
26
+ if (!existsSync(orgsDir))
27
+ return { success: false, message: 'no orgs directory — create an org first with /mastermind:createorg' };
28
+ files = listOrgConfigFiles(orgsDir);
29
+ if (!files.length)
30
+ return { success: false, message: 'no org configs found' };
31
+ }
32
+ let failed = 0;
33
+ for (const f of files) {
34
+ const stem = f.replace(/\.json$/, '');
35
+ const path = join(orgsDir, f);
36
+ const errors = [];
37
+ const warnings = [];
38
+ if (!existsSync(path)) {
39
+ log(output.error(`${stem}: not found (${path})`));
40
+ failed++;
41
+ continue;
42
+ }
43
+ try {
44
+ const def = OrgDefSchema.parse(JSON.parse(readFileSync(path, 'utf8')));
45
+ const ids = def.roles.map(r => r.id);
46
+ const dupes = ids.filter((id, i) => ids.indexOf(id) !== i);
47
+ if (dupes.length)
48
+ errors.push(`duplicate role id(s): ${[...new Set(dupes)].join(', ')}`);
49
+ const roots = def.roles.filter(r => r.reports_to === null);
50
+ if (roots.length === 0)
51
+ errors.push('no root role — exactly one role must have reports_to: null');
52
+ if (roots.length > 1)
53
+ errors.push(`multiple root roles (${roots.map(r => r.id).join(', ')}) — exactly one may have reports_to: null`);
54
+ for (const r of def.roles) {
55
+ if (r.reports_to !== null && !ids.includes(r.reports_to))
56
+ errors.push(`role "${r.id}": reports_to "${r.reports_to}" matches no role id`);
57
+ if (r.reports_to === r.id)
58
+ errors.push(`role "${r.id}" reports to itself`);
59
+ }
60
+ if (def.schedule != null && parseSchedule(def.schedule) === null)
61
+ errors.push(`schedule "${def.schedule}" is not parseable — use "<N>s", "<N>m", or "<N>h"`);
62
+ if (def.name !== stem)
63
+ warnings.push(`def.name "${def.name}" differs from filename — the runtime addresses this org as "${stem}"`);
64
+ }
65
+ catch (err) {
66
+ errors.push(err instanceof Error ? err.message : String(err));
67
+ }
68
+ for (const w of warnings)
69
+ log(output.warning(`${stem}: ${w}`));
70
+ if (errors.length) {
71
+ failed++;
72
+ for (const e of errors)
73
+ log(output.error(`${stem}: ${e}`));
74
+ }
75
+ else {
76
+ log(output.success(`${stem}: valid${warnings.length ? ` (${warnings.length} warning(s))` : ''}`));
77
+ }
78
+ }
79
+ return failed
80
+ ? { success: false, message: `${failed} of ${files.length} org config(s) failed validation` }
81
+ : { success: true, message: `${files.length} org config(s) valid` };
82
+ };
83
+ const resolveRun = (cwd, name, runFlag) => {
84
+ if (typeof runFlag === 'string' && runFlag)
85
+ return runFlag;
86
+ return listRunDirs(cwd, name)[0] ?? null;
87
+ };
88
+ /** `org logs <name> [--run id] [--role r] [--follow]` — formatted bus.jsonl tail. */
89
+ export const logsAction = async (ctx, name) => {
90
+ const run = resolveRun(ctx.cwd, name, ctx.flags['run']);
91
+ if (!run)
92
+ return { success: false, message: `no runs found for org ${name} — start one with: monomind org run ${name}` };
93
+ const file = join(ctx.cwd, ORG_DIR, name, run, 'bus.jsonl');
94
+ const roleFilter = typeof ctx.flags['role'] === 'string' ? ctx.flags['role'] : null;
95
+ const show = (e) => {
96
+ if (roleFilter && e.from !== roleFilter && e.to !== roleFilter)
97
+ return;
98
+ log(formatEvent(e));
99
+ };
100
+ log(output.info(`org ${name} — ${run}${roleFilter ? ` (role: ${roleFilter})` : ''}`));
101
+ let seenLines = 0;
102
+ const drain = () => {
103
+ if (!existsSync(file))
104
+ return;
105
+ const lines = readFileSync(file, 'utf8').split('\n').filter(Boolean);
106
+ for (const l of lines.slice(seenLines)) {
107
+ try {
108
+ show(JSON.parse(l));
109
+ seenLines++;
110
+ }
111
+ catch {
112
+ break;
113
+ } // partial line mid-append — retry it next tick
114
+ }
115
+ };
116
+ drain();
117
+ if (ctx.flags['follow'] !== true)
118
+ return { success: true };
119
+ log(output.info('following — Ctrl-C to stop'));
120
+ await new Promise(resolve => {
121
+ const iv = setInterval(drain, 500);
122
+ process.once('SIGINT', () => { clearInterval(iv); resolve(); });
123
+ process.once('SIGTERM', () => { clearInterval(iv); resolve(); });
124
+ });
125
+ return { success: true };
126
+ };
127
+ /** `org report <name> [--run id] [--all]` — summarize a run (or list run history). */
128
+ export const reportAction = async (ctx, name) => {
129
+ if (ctx.flags['all'] === true) {
130
+ const history = readHistory(ctx.cwd, name);
131
+ if (!history.length)
132
+ return { success: false, message: `no run history for org ${name}` };
133
+ log(output.info(`org ${name} — ${history.length} recorded run(s):`));
134
+ for (const h of history) {
135
+ const dur = h.durationMs != null ? `${Math.round(h.durationMs / 1000)}s` : '?';
136
+ const outcome = h.outcome ? `${h.outcome.status}: ${h.outcome.summary.slice(0, 60)}` : 'no outcome recorded';
137
+ log(output.info(` • ${h.run} ${dur} ${h.totalTokens} tokens ${h.messages} msgs — ${outcome}`));
138
+ }
139
+ return { success: true };
140
+ }
141
+ const run = resolveRun(ctx.cwd, name, ctx.flags['run']);
142
+ if (!run)
143
+ return { success: false, message: `no runs found for org ${name}` };
144
+ const events = readRunEvents(ctx.cwd, name, run);
145
+ if (!events.length)
146
+ return { success: false, message: `run ${run} has no recorded events` };
147
+ const s = summarizeRun(events);
148
+ // Per-role budget ceiling: same split the daemon applies (budget ÷ role count),
149
+ // with any explicit policy.maxTokens override. Missing/unreadable config → no ceilings.
150
+ let perRoleBudget = null;
151
+ const roleCeiling = new Map();
152
+ try {
153
+ const def = OrgDefSchema.parse(JSON.parse(readFileSync(join(ctx.cwd, ORG_DIR, `${name}.json`), 'utf8')));
154
+ perRoleBudget = Math.floor((def.run_config.budget_tokens ?? 1_000_000) / def.roles.length);
155
+ for (const r of def.roles) {
156
+ const max = r.policy?.maxTokens;
157
+ roleCeiling.set(r.id, max ?? perRoleBudget);
158
+ }
159
+ }
160
+ catch { /* config gone or invalid — report without budget context */ }
161
+ const budgetNote = (id, tokens) => {
162
+ const cap = roleCeiling.get(id);
163
+ if (!cap)
164
+ return '';
165
+ const pct = Math.round((tokens / cap) * 100);
166
+ return ` (${pct}% of ${cap}${pct >= 100 ? ' — EXHAUSTED' : pct >= 80 ? ' — near limit' : ''})`;
167
+ };
168
+ log(output.info(`ORG REPORT — ${name} / ${run}`));
169
+ log(output.info(` Duration: ${s.durationMs != null ? `${Math.round(s.durationMs / 1000)}s` : '?'} Events: ${s.events} Messages: ${s.messages}${s.xorgMessages ? ` (+${s.xorgMessages} cross-org)` : ''}`));
170
+ log(output.info(` Tokens: ${s.totalTokens}${perRoleBudget ? ` (budget: ${perRoleBudget}/role)` : ''}${s.totalCostUsd ? ` Cost: $${s.totalCostUsd.toFixed(4)}` : ''}`));
171
+ if (s.outcome)
172
+ log(output.success(` Outcome: ${s.outcome.status} (by ${s.outcome.by}) — ${s.outcome.summary}`));
173
+ else
174
+ log(output.warning(' Outcome: not recorded (coordinator never called org_complete)'));
175
+ log(output.info(' Roles:'));
176
+ for (const [id, r] of Object.entries(s.roles)) {
177
+ log(output.info(` ${r.crashed ? '✗' : '•'} ${id}: ${r.messagesSent} msgs, ${r.toolsAllowed} tools${r.toolsDenied ? ` (${r.toolsDenied} denied)` : ''}, ${r.tokens} tokens${budgetNote(id, r.tokens)}${r.crashed ? ' — CRASHED' : ''}`));
178
+ }
179
+ if (s.assets.length) {
180
+ log(output.info(` Assets (${s.assets.length}):`));
181
+ for (const a of s.assets.slice(0, 20))
182
+ log(output.info(` 📄 ${a}`));
183
+ if (s.assets.length > 20)
184
+ log(output.info(` … and ${s.assets.length - 20} more`));
185
+ }
186
+ return { success: true };
187
+ };
188
+ const readQuestions = (cwd, name) => {
189
+ try {
190
+ return JSON.parse(readFileSync(join(cwd, ORG_DIR, name, 'questions.json'), 'utf8')).questions ?? [];
191
+ }
192
+ catch {
193
+ return [];
194
+ }
195
+ };
196
+ /** `org questions <name> [--all]` — list pending (or all) ask_human questions. */
197
+ export const questionsAction = async (ctx, name) => {
198
+ const all = readQuestions(ctx.cwd, name);
199
+ const shown = ctx.flags['all'] === true ? all : all.filter(q => q.answer === null);
200
+ if (!shown.length) {
201
+ log(output.info(all.length ? `No pending questions for org ${name} (${all.length} answered — use --all).` : `No questions recorded for org ${name}.`));
202
+ return { success: true };
203
+ }
204
+ for (const q of shown) {
205
+ const when = new Date(q.ts).toISOString().replace('T', ' ').slice(0, 16);
206
+ log(output.info(`${q.answer === null ? '❓' : '✓'} [${q.questionId}] ${when} ${q.role}: ${q.question}`));
207
+ if (q.answer !== null)
208
+ log(output.info(` ↳ ${q.answer}`));
209
+ }
210
+ if (shown.some(q => q.answer === null))
211
+ log(output.info(`\nAnswer with: monomind org answer ${name} <question-id> "your answer"`));
212
+ return { success: true };
213
+ };
214
+ /** `org answer <name> <question-id> <answer...>` — answer a pending ask_human question.
215
+ * Delivers live via the hosting daemon's /api/answer-question when the org is running
216
+ * (broker lookup); otherwise records the answer and queues it for the next run. */
217
+ export const answerAction = async (ctx, name) => {
218
+ const questionId = ctx.args[1];
219
+ const answer = ctx.args.slice(2).join(' ').trim();
220
+ if (!questionId || !answer)
221
+ return { success: false, message: `usage: monomind org answer ${name} <question-id> "answer text"` };
222
+ const questions = readQuestions(ctx.cwd, name);
223
+ const q = questions.find(x => x.questionId === questionId);
224
+ if (!q) {
225
+ log(output.error(`Question "${questionId}" not found for org ${name} — list with: monomind org questions ${name}`));
226
+ return { success: false, message: 'question not found' };
227
+ }
228
+ if (q.answer !== null)
229
+ return { success: false, message: `question "${questionId}" was already answered` };
230
+ // Live path: the hosting daemon updates questions.json and pushes into the role's mailbox.
231
+ const { lookupOrg } = await import('../orgrt/broker.js');
232
+ const remote = lookupOrg(name);
233
+ if (remote) {
234
+ try {
235
+ const res = await fetch(`${remote.url}/api/answer-question`, {
236
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
237
+ body: JSON.stringify({ org: name, role: q.role, questionId, answer }),
238
+ signal: AbortSignal.timeout(10_000),
239
+ });
240
+ const data = await res.json().catch(() => ({}));
241
+ if (res.ok && data.ok) {
242
+ log(output.success(`Answer delivered to ${name}:${q.role} (live).`));
243
+ return { success: true };
244
+ }
245
+ log(output.warning(`Live delivery rejected (${data.error ?? res.status}) — falling back to offline queue.`));
246
+ }
247
+ catch (err) {
248
+ log(output.warning(`Hosting daemon unreachable (${err instanceof Error ? err.message : 'error'}) — falling back to offline queue.`));
249
+ }
250
+ }
251
+ // Offline path: mirror daemon.answerQuestion's org-not-running branch.
252
+ const updated = questions.map(x => x.questionId === questionId ? { ...x, answer, answeredAt: Date.now() } : x);
253
+ const dest = join(ctx.cwd, ORG_DIR, name, 'questions.json');
254
+ const tmp = `${dest}.${process.pid}.tmp`;
255
+ writeFileSync(tmp, JSON.stringify({ questions: updated }, null, 2));
256
+ const { renameSync } = await import('node:fs');
257
+ renameSync(tmp, dest);
258
+ const { queueMessage } = await import('../orgrt/inbox.js');
259
+ queueMessage(ctx.cwd, name, {
260
+ fromQualified: 'human', toRole: q.role,
261
+ subject: `answer:${questionId}`,
262
+ body: `question: ${q.question}\n\nanswer: ${answer}`,
263
+ ts: Date.now(),
264
+ });
265
+ log(output.success(`Answer recorded — ${name}:${q.role} receives it when the org next runs.`));
266
+ return { success: true };
267
+ };
268
+ /** `org create <name> --template <t> [--goal g] [--schedule s]` — scaffold a config from a template. */
269
+ export const createAction = async (ctx, name) => {
270
+ const templateName = typeof ctx.flags['template'] === 'string' ? ctx.flags['template'] : '';
271
+ if (!templateName) {
272
+ log(output.info(`Available templates: ${Object.keys(ORG_TEMPLATES).join(', ')}`));
273
+ return { success: false, message: 'usage: monomind org create <name> --template <template> [--goal "..."] [--schedule 30m]' };
274
+ }
275
+ const def = buildFromTemplate(templateName, name, typeof ctx.flags['goal'] === 'string' ? ctx.flags['goal'] : undefined);
276
+ if (!def) {
277
+ log(output.error(`Unknown template "${templateName}" — available: ${Object.keys(ORG_TEMPLATES).join(', ')}`));
278
+ return { success: false, message: 'unknown template' };
279
+ }
280
+ if (typeof ctx.flags['schedule'] === 'string')
281
+ def.schedule = ctx.flags['schedule'];
282
+ const file = join(ctx.cwd, ORG_DIR, `${name}.json`);
283
+ if (existsSync(file) && ctx.flags['force'] !== true) {
284
+ log(output.error(`Org "${name}" already exists — pass --force to overwrite.`));
285
+ return { success: false, message: 'org exists' };
286
+ }
287
+ OrgDefSchema.parse(def); // templates must always produce a runnable config
288
+ const { mkdirSync } = await import('node:fs');
289
+ mkdirSync(join(ctx.cwd, ORG_DIR), { recursive: true });
290
+ writeFileSync(file, JSON.stringify(def, null, 2) + '\n', 'utf8');
291
+ log(output.success(`Org "${name}" created from template "${templateName}" (${def.roles.length} roles).`));
292
+ log(output.info(` Edit the goal/roles in ${file}, then: monomind org run ${name}`));
293
+ return { success: true };
294
+ };
295
+ //# sourceMappingURL=org-observe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"org-observe.js","sourceRoot":"","sources":["../../../src/commands/org-observe.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,12 @@
1
- import type { Command } from '../types.js';
1
+ import type { Command, CommandResult } from '../types.js';
2
+ export declare function validateOrgName(name: string | undefined): {
3
+ ok: true;
4
+ name: string;
5
+ } | {
6
+ ok: false;
7
+ result: CommandResult;
8
+ };
9
+ export declare function listOrgConfigFiles(orgsDir: string): string[];
2
10
  /** Remove a lingering stopfile so a fresh `org run` doesn't self-terminate. */
3
11
  export declare const clearStopfile: (cwd: string, name: string) => void;
4
12
  export declare const orgCommand: Command;
@@ -1 +1 @@
1
- {"version":3,"file":"org.d.ts","sourceRoot":"","sources":["../../../src/commands/org.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAiC,MAAM,aAAa,CAAC;AAsC1E,+EAA+E;AAC/E,eAAO,MAAM,aAAa,QAAS,MAAM,QAAQ,MAAM,KAAG,IAEzD,CAAC;AAsOF,eAAO,MAAM,UAAU,EAAE,OA4CxB,CAAC;eAEa,UAAU"}
1
+ {"version":3,"file":"org.d.ts","sourceRoot":"","sources":["../../../src/commands/org.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAkB,aAAa,EAAE,MAAM,aAAa,CAAC;AAa1E,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAO3H;AAaD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAG5D;AAED,+EAA+E;AAC/E,eAAO,MAAM,aAAa,QAAS,MAAM,QAAQ,MAAM,KAAG,IAEzD,CAAC;AAkUF,eAAO,MAAM,UAAU,EAAE,OA6HxB,CAAC;eAEa,UAAU"}
@@ -4,13 +4,13 @@ import { join, resolve } from 'node:path';
4
4
  import { output } from '../output.js';
5
5
  import { OrgDaemon } from '../orgrt/daemon.js';
6
6
  import { startOrgServer } from '../orgrt/server.js';
7
- import { ORG_DIR } from '../orgrt/types.js';
7
+ import { ORG_DIR, OrgDefSchema } from '../orgrt/types.js';
8
8
  const log = (text) => { console.log(text); };
9
9
  /** Org names are used to build filesystem paths under .monomind/orgs — reject
10
10
  * anything that isn't a plain identifier to prevent path traversal (e.g.
11
11
  * `monomind org stop '../../../../tmp/x'`). */
12
12
  const ORG_NAME_RE = /^[a-z0-9][a-z0-9_-]*$/i;
13
- function validateOrgName(name) {
13
+ export function validateOrgName(name) {
14
14
  if (!name)
15
15
  return { ok: false, result: { success: false, message: 'org name required' } };
16
16
  if (!ORG_NAME_RE.test(name)) {
@@ -30,7 +30,7 @@ const ORG_ARTIFACT_SUFFIXES = [
30
30
  '-plugins', '-adapters', '-join-requests', '-bootstrap', '-project-workspaces',
31
31
  '-approval-comments', '-skills',
32
32
  ];
33
- function listOrgConfigFiles(orgsDir) {
33
+ export function listOrgConfigFiles(orgsDir) {
34
34
  return readdirSync(orgsDir)
35
35
  .filter(f => f.endsWith('.json') && !f.startsWith('._') && !ORG_ARTIFACT_SUFFIXES.some(suf => f.includes(suf)));
36
36
  }
@@ -53,6 +53,32 @@ const runAction = async (ctx) => {
53
53
  const taskFlag = ctx.flags['task'];
54
54
  if (Array.isArray(taskFlag))
55
55
  return { success: false, message: '--task was passed more than once — pass it exactly once' };
56
+ // Fail before any side effects (inbox server) when the org doesn't exist.
57
+ const orgsDir = join(ctx.cwd, ORG_DIR);
58
+ if (!existsSync(join(orgsDir, `${name}.json`))) {
59
+ const known = existsSync(orgsDir) ? listOrgConfigFiles(orgsDir).map(f => f.replace(/\.json$/, '')) : [];
60
+ log(output.error(`Org not found: ${name}${known.length ? ` — available: ${known.join(', ')}` : ' — create one with /mastermind:createorg'}`));
61
+ return { success: false, message: 'org not found' };
62
+ }
63
+ if (ctx.flags['dryRun'] === true) {
64
+ // Validate + preview each role's actual briefing without spawning sessions.
65
+ try {
66
+ const def = OrgDefSchema.parse(JSON.parse(readFileSync(join(orgsDir, `${name}.json`), 'utf8')));
67
+ const { buildRolePrompt } = await import('../orgrt/session.js');
68
+ const roster = def.roles.map(r => r.id);
69
+ const perRole = Math.floor((def.run_config.budget_tokens ?? 1_000_000) / def.roles.length);
70
+ log(output.info(`DRY RUN — org ${name}: ${def.roles.length} roles, ${perRole} tokens each, goal: ${taskFlag ?? def.goal}`));
71
+ for (const role of def.roles) {
72
+ log(output.info(`\n─── ${role.id} (${role.title || role.type})${role.adapter_config?.model ? ` [${role.adapter_config.model}]` : ''} ───`));
73
+ log(buildRolePrompt(role, { name: def.name, goal: taskFlag ?? def.goal }, roster));
74
+ }
75
+ return { success: true, message: 'dry run complete — no sessions started' };
76
+ }
77
+ catch (err) {
78
+ log(output.error(`Config invalid: ${err instanceof Error ? err.message : String(err)}`));
79
+ return { success: false, message: 'invalid org config' };
80
+ }
81
+ }
56
82
  const crossProcess = ctx.flags['crossProcess'] !== false;
57
83
  const daemon = new OrgDaemon(ctx.cwd, { crossProcess });
58
84
  let srv;
@@ -60,7 +86,20 @@ const runAction = async (ctx) => {
60
86
  srv = await startOrgServer(daemon, 0);
61
87
  daemon.setInboxUrl(`http://127.0.0.1:${srv.port}`);
62
88
  }
63
- const running = await daemon.startOrg(name, taskFlag);
89
+ let running;
90
+ try {
91
+ running = await daemon.startOrg(name, taskFlag);
92
+ }
93
+ catch (err) {
94
+ // Don't leave the inbox server holding the event loop open on a failed start.
95
+ srv?.close();
96
+ await daemon.stopAll().catch(() => { });
97
+ const detail = err instanceof Error ? err.message : String(err);
98
+ const hint = err instanceof Error && err.name === 'ZodError'
99
+ ? ` — run "monomind org validate ${name}" for details` : '';
100
+ log(output.error(`Could not start org ${name}: ${detail}${hint}`));
101
+ return { success: false, message: 'org start failed' };
102
+ }
64
103
  log(output.info(`org ${name} running (${running.def.roles.length} agents, run ${running.run}) — Ctrl-C or "monomind org stop ${name}" to stop`));
65
104
  // stopfile poll lets `org stop` work from another terminal;
66
105
  // clear any stale stopfile from a previous run before polling
@@ -79,18 +118,41 @@ const runAction = async (ctx) => {
79
118
  srv?.close();
80
119
  return { success: true, message: `org ${name} stopped` };
81
120
  };
121
+ /** True when runtime.json records a running org whose recorded pid is still alive. */
122
+ const isOrgRunning = (cwd, name) => {
123
+ try {
124
+ const rt = JSON.parse(readFileSync(join(cwd, ORG_DIR, name, 'runtime.json'), 'utf8'));
125
+ if (rt.status !== 'running' || !rt.pid)
126
+ return false;
127
+ process.kill(rt.pid, 0); // throws if the pid is gone (crashed daemon left a stale file)
128
+ return true;
129
+ }
130
+ catch {
131
+ return false;
132
+ }
133
+ };
82
134
  const stopAction = async (ctx) => {
83
135
  const validated = validateOrgName(ctx.args[0]);
84
136
  if (!validated.ok)
85
137
  return validated.result;
86
138
  const name = validated.name;
139
+ if (!existsSync(join(ctx.cwd, ORG_DIR, `${name}.json`))) {
140
+ log(output.error(`Org not found: ${name}`));
141
+ return { success: false, message: 'org not found' };
142
+ }
87
143
  const { writeFileSync, mkdirSync } = await import('node:fs');
88
144
  mkdirSync(join(ctx.cwd, ORG_DIR, name), { recursive: true });
89
145
  writeFileSync(join(ctx.cwd, ORG_DIR, name, 'stop'), new Date().toISOString());
90
146
  return { success: true, message: `stop requested for ${name} (daemon exits within 2s)` };
91
147
  };
92
148
  const statusAction = async (ctx) => {
93
- const name = ctx.args[0];
149
+ let name;
150
+ if (ctx.args[0]) {
151
+ const validated = validateOrgName(ctx.args[0]);
152
+ if (!validated.ok)
153
+ return validated.result;
154
+ name = validated.name;
155
+ }
94
156
  const orgDir = join(ctx.cwd, ORG_DIR);
95
157
  const targets = name ? [name] : (existsSync(orgDir)
96
158
  ? listOrgConfigFiles(orgDir).map(f => f.replace(/\.json$/, ''))
@@ -107,6 +169,17 @@ const statusAction = async (ctx) => {
107
169
  continue;
108
170
  }
109
171
  }
172
+ // A "running" record whose pid is gone means the daemon died without its
173
+ // stopOrg cleanup — surface that instead of reporting it as still running.
174
+ if (state.status === 'running' && state.pid) {
175
+ try {
176
+ process.kill(state.pid, 0);
177
+ }
178
+ catch {
179
+ log(output.warning(`${t}: crashed (runtime.json says running but pid ${state.pid} is gone)${state.run ? ` — run ${state.run}` : ''} — close it out with "monomind org mark-complete ${t}"`));
180
+ continue;
181
+ }
182
+ }
110
183
  log(output.info(`${t}: ${state.status}${state.run ? ` (run ${state.run}, pid ${state.pid})` : ''}`));
111
184
  }
112
185
  return { success: true };
@@ -198,8 +271,27 @@ const listAction = async (ctx) => {
198
271
  return { success: true };
199
272
  }
200
273
  log(output.info(`Found ${configs.length} org(s):`));
201
- for (const f of configs)
202
- log(output.info(` • ${f.replace('.json', '')}`));
274
+ for (const f of configs) {
275
+ const stem = f.replace(/\.json$/, '');
276
+ let detail = '';
277
+ try {
278
+ const def = JSON.parse(readFileSync(join(orgsDir, f), 'utf8'));
279
+ const roles = Array.isArray(def.roles) ? def.roles.length : 0;
280
+ const sched = def.schedule ? `every ${def.schedule}` : 'manual';
281
+ let status = 'never run';
282
+ try {
283
+ status = JSON.parse(readFileSync(join(orgsDir, stem, 'runtime.json'), 'utf8')).status ?? status;
284
+ }
285
+ catch { /* no runtime state yet */ }
286
+ const goal = typeof def.goal === 'string' && def.goal
287
+ ? ` — ${def.goal.length > 60 ? `${def.goal.slice(0, 57)}...` : def.goal}` : '';
288
+ detail = ` (${roles} role${roles === 1 ? '' : 's'}, ${sched}, ${status})${goal}`;
289
+ }
290
+ catch {
291
+ detail = ' (unreadable config — run `monomind org validate`)';
292
+ }
293
+ log(output.info(` • ${stem}${detail}`));
294
+ }
203
295
  return { success: true };
204
296
  };
205
297
  const deleteAction = async (ctx) => {
@@ -225,6 +317,10 @@ const deleteAction = async (ctx) => {
225
317
  log(output.error(`Org not found: ${orgName}`));
226
318
  return { success: false, message: 'org not found' };
227
319
  }
320
+ if (isOrgRunning(cwd, orgName) && ctx.flags['force'] !== true) {
321
+ log(output.error(`Org "${orgName}" is currently running — stop it first (monomind org stop ${orgName}) or pass --force.`));
322
+ return { success: false, message: 'org is running' };
323
+ }
228
324
  let removed = 0;
229
325
  for (const suf of ['', ...ORG_ARTIFACT_SUFFIXES]) {
230
326
  for (const ext of ['.json', '.jsonl']) {
@@ -298,6 +394,7 @@ export const orgCommand = {
298
394
  options: [
299
395
  { name: 'task', description: 'Override the org goal for this run', type: 'string' },
300
396
  { name: 'cross-process', description: 'Discover and message orgs hosted by other monomind processes on this machine (default true)', type: 'boolean', default: true },
397
+ { name: 'dry-run', description: 'Validate and print each role\'s briefing without starting any agent sessions', type: 'boolean' },
301
398
  ],
302
399
  examples: [{ command: 'monomind org run growth --task "weekly report"', description: 'Run the growth org once with a task' }],
303
400
  action: runAction,
@@ -316,10 +413,95 @@ export const orgCommand = {
316
413
  options: [{ name: 'times', short: 'n', description: 'Iterations', type: 'number', default: 5 }],
317
414
  action: testLoopAction,
318
415
  },
416
+ {
417
+ name: 'logs', description: 'Show (or follow) the formatted event log of an org run',
418
+ options: [
419
+ { name: 'run', description: 'Run id (default: latest)', type: 'string' },
420
+ { name: 'role', description: 'Only events from/to this role', type: 'string' },
421
+ { name: 'follow', short: 'f', description: 'Keep tailing until Ctrl-C', type: 'boolean' },
422
+ ],
423
+ examples: [{ command: 'monomind org logs growth --follow', description: 'Live-tail the latest run' }],
424
+ action: async (ctx) => {
425
+ const v = validateOrgName(ctx.args[0]);
426
+ if (!v.ok)
427
+ return v.result;
428
+ const { logsAction } = await import('./org-observe.js');
429
+ return logsAction(ctx, v.name);
430
+ },
431
+ },
432
+ {
433
+ name: 'report', description: 'Summarize an org run: outcome, per-role activity, tokens, assets, crashes',
434
+ options: [
435
+ { name: 'run', description: 'Run id (default: latest)', type: 'string' },
436
+ { name: 'all', description: 'List all recorded runs from history', type: 'boolean' },
437
+ ],
438
+ examples: [{ command: 'monomind org report growth', description: 'Report on the latest run' }],
439
+ action: async (ctx) => {
440
+ const v = validateOrgName(ctx.args[0]);
441
+ if (!v.ok)
442
+ return v.result;
443
+ const { reportAction } = await import('./org-observe.js');
444
+ return reportAction(ctx, v.name);
445
+ },
446
+ },
447
+ {
448
+ name: 'questions', description: 'List pending ask_human questions from an org\'s agents',
449
+ options: [{ name: 'all', description: 'Include answered questions', type: 'boolean' }],
450
+ examples: [{ command: 'monomind org questions growth', description: 'Show unanswered questions' }],
451
+ action: async (ctx) => {
452
+ const v = validateOrgName(ctx.args[0]);
453
+ if (!v.ok)
454
+ return v.result;
455
+ const { questionsAction } = await import('./org-observe.js');
456
+ return questionsAction(ctx, v.name);
457
+ },
458
+ },
459
+ {
460
+ name: 'answer', description: 'Answer a pending ask_human question (live if the org is running, queued otherwise)',
461
+ examples: [{ command: 'monomind org answer growth q-123-ab "yes, ship it"', description: 'Answer question q-123-ab' }],
462
+ action: async (ctx) => {
463
+ const v = validateOrgName(ctx.args[0]);
464
+ if (!v.ok)
465
+ return v.result;
466
+ const { answerAction } = await import('./org-observe.js');
467
+ return answerAction(ctx, v.name);
468
+ },
469
+ },
470
+ {
471
+ name: 'create', description: 'Scaffold an org config from a starter template',
472
+ options: [
473
+ { name: 'template', description: 'content-team | dev-team | research-pod', type: 'string' },
474
+ { name: 'goal', description: 'Org goal (defaults to the template\'s placeholder)', type: 'string' },
475
+ { name: 'schedule', description: 'Daemon schedule, e.g. 30m or 2h', type: 'string' },
476
+ { name: 'force', description: 'Overwrite an existing org config', type: 'boolean' },
477
+ ],
478
+ examples: [{ command: 'monomind org create blog --template content-team --goal "3 posts/week"', description: 'Create a content org' }],
479
+ action: async (ctx) => {
480
+ const v = validateOrgName(ctx.args[0]);
481
+ if (!v.ok)
482
+ return v.result;
483
+ const { createAction } = await import('./org-observe.js');
484
+ return createAction(ctx, v.name);
485
+ },
486
+ },
487
+ {
488
+ name: 'validate', description: 'Validate org config(s) against the runtime schema and structural invariants',
489
+ examples: [
490
+ { command: 'monomind org validate growth', description: 'Validate one org config' },
491
+ { command: 'monomind org validate', description: 'Validate every org config in the project' },
492
+ ],
493
+ action: async (ctx) => {
494
+ const { validateAction } = await import('./org-observe.js');
495
+ return validateAction(ctx);
496
+ },
497
+ },
319
498
  { name: 'list', description: 'List all orgs in the current project', action: listAction },
320
499
  {
321
500
  name: 'delete', description: 'Delete an org and all its data',
322
- options: [{ name: 'yes', short: 'y', description: 'Skip confirmation', type: 'boolean' }],
501
+ options: [
502
+ { name: 'yes', short: 'y', description: 'Skip confirmation', type: 'boolean' },
503
+ { name: 'force', description: 'Delete even if the org appears to be running', type: 'boolean' },
504
+ ],
323
505
  action: deleteAction,
324
506
  },
325
507
  { name: 'mark-complete', description: 'Manually close a stale/crashed run', action: markCompleteAction },
@@ -329,7 +511,7 @@ export const orgCommand = {
329
511
  // index.ts's dispatcher never prints result.message on a failed action —
330
512
  // it only exits with result.exitCode — so this must log itself or bare
331
513
  // `monomind org` exits silently with code 1 and zero output.
332
- const message = 'usage: monomind org <run|stop|status|serve|test-loop|list|delete|mark-complete>';
514
+ const message = 'usage: monomind org <run|stop|status|serve|test-loop|logs|report|questions|answer|create|validate|list|delete|mark-complete>';
333
515
  log(output.error(message));
334
516
  return { success: false, message };
335
517
  },