@monoes/monomindcli 2.10.10 → 2.10.13

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 (233) hide show
  1. package/.claude/commands/mastermind/brain.md +14 -14
  2. package/.claude/commands/mastermind/help.md +2 -2
  3. package/.claude/commands/mastermind/master.md +24 -19
  4. package/.claude/commands/mastermind/memory.md +8 -8
  5. package/.claude/commands/mastermind/monoswarm.md +4 -4
  6. package/.claude/commands/mastermind.md +7 -7
  7. package/.claude/commands/truth/start.md +3 -3
  8. package/.claude/skills/mastermind/SKILL.md +7 -16
  9. package/.claude/skills/mastermind-debug/SKILL.md +3 -3
  10. package/.claude/skills/mastermind-design/SKILL.md +2 -0
  11. package/.claude/skills/mastermind-execute/SKILL.md +66 -11
  12. package/.claude/skills/mastermind-idea/SKILL.md +9 -2
  13. package/.claude/skills/mastermind-intake/SKILL.md +31 -7
  14. package/.claude/skills/mastermind-issue-detail/SKILL.md +70 -16
  15. package/.claude/skills/mastermind-issues/SKILL.md +111 -16
  16. package/.claude/skills/mastermind-liveness/SKILL.md +96 -26
  17. package/.claude/skills/mastermind-my-issues/SKILL.md +40 -8
  18. package/.claude/skills/mastermind-org/SKILL.md +2 -0
  19. package/.claude/skills/mastermind-plan/SKILL.md +7 -16
  20. package/.claude/skills/mastermind-plan-to-tasks/SKILL.md +132 -24
  21. package/.claude/skills/mastermind-protocol/SKILL.md +33 -22
  22. package/.claude/skills/mastermind-runorg/SKILL.md +22 -3
  23. package/.claude/skills/mastermind-skill-builder/SKILL.md +1 -1
  24. package/.claude/skills/mastermind-tasks/SKILL.md +5 -0
  25. package/.claude/skills/mastermind-techport/SKILL.md +1 -1
  26. package/.claude/skills/performance-analysis/SKILL.md +1 -1
  27. package/.claude/skills/verification-quality/SKILL.md +2 -3
  28. package/README.md +2 -2
  29. package/dist/src/commands/doc.js +2 -2
  30. package/dist/src/commands/doc.js.map +1 -1
  31. package/dist/src/commands/doctor-project-checks.d.ts.map +1 -1
  32. package/dist/src/commands/doctor-project-checks.js +20 -1
  33. package/dist/src/commands/doctor-project-checks.js.map +1 -1
  34. package/dist/src/commands/monograph.d.ts.map +1 -1
  35. package/dist/src/commands/monograph.js +11 -4
  36. package/dist/src/commands/monograph.js.map +1 -1
  37. package/dist/src/commands/org-observe.d.ts.map +1 -1
  38. package/dist/src/commands/org-observe.js +56 -6
  39. package/dist/src/commands/org-observe.js.map +1 -1
  40. package/dist/src/commands/org.d.ts +26 -0
  41. package/dist/src/commands/org.d.ts.map +1 -1
  42. package/dist/src/commands/org.js +144 -28
  43. package/dist/src/commands/org.js.map +1 -1
  44. package/dist/src/init/executor.d.ts.map +1 -1
  45. package/dist/src/init/executor.js +10 -9
  46. package/dist/src/init/executor.js.map +1 -1
  47. package/dist/src/init/settings-generator.d.ts.map +1 -1
  48. package/dist/src/init/settings-generator.js.map +1 -1
  49. package/dist/src/init/write-codex.d.ts.map +1 -1
  50. package/dist/src/init/write-codex.js.map +1 -1
  51. package/dist/src/knowledge/document-pipeline.d.ts +5 -0
  52. package/dist/src/knowledge/document-pipeline.d.ts.map +1 -1
  53. package/dist/src/knowledge/document-pipeline.js +32 -16
  54. package/dist/src/knowledge/document-pipeline.js.map +1 -1
  55. package/dist/src/mcp-tools/hooks-routing.d.ts +9 -0
  56. package/dist/src/mcp-tools/hooks-routing.d.ts.map +1 -1
  57. package/dist/src/mcp-tools/hooks-routing.js +12 -1
  58. package/dist/src/mcp-tools/hooks-routing.js.map +1 -1
  59. package/dist/src/mcp-tools/knowledge-tools.d.ts.map +1 -1
  60. package/dist/src/mcp-tools/knowledge-tools.js +105 -13
  61. package/dist/src/mcp-tools/knowledge-tools.js.map +1 -1
  62. package/dist/src/mcp-tools/memory-tools.d.ts +13 -0
  63. package/dist/src/mcp-tools/memory-tools.d.ts.map +1 -1
  64. package/dist/src/mcp-tools/memory-tools.js +257 -31
  65. package/dist/src/mcp-tools/memory-tools.js.map +1 -1
  66. package/dist/src/mcp-tools/monograph/health-tools.d.ts.map +1 -1
  67. package/dist/src/mcp-tools/monograph/health-tools.js +99 -42
  68. package/dist/src/mcp-tools/monograph/health-tools.js.map +1 -1
  69. package/dist/src/mcp-tools/monograph/impact-tools.d.ts.map +1 -1
  70. package/dist/src/mcp-tools/monograph/impact-tools.js +123 -51
  71. package/dist/src/mcp-tools/monograph/impact-tools.js.map +1 -1
  72. package/dist/src/mcp-tools/monograph/query-tools.d.ts.map +1 -1
  73. package/dist/src/mcp-tools/monograph/query-tools.js +113 -96
  74. package/dist/src/mcp-tools/monograph/query-tools.js.map +1 -1
  75. package/dist/src/mcp-tools/monograph/shared.d.ts +37 -4
  76. package/dist/src/mcp-tools/monograph/shared.d.ts.map +1 -1
  77. package/dist/src/mcp-tools/monograph/shared.js +75 -56
  78. package/dist/src/mcp-tools/monograph/shared.js.map +1 -1
  79. package/dist/src/memory/memory-bridge.d.ts +60 -1
  80. package/dist/src/memory/memory-bridge.d.ts.map +1 -1
  81. package/dist/src/memory/memory-bridge.js +172 -42
  82. package/dist/src/memory/memory-bridge.js.map +1 -1
  83. package/dist/src/memory/memory-kg.d.ts +495 -28
  84. package/dist/src/memory/memory-kg.d.ts.map +1 -1
  85. package/dist/src/memory/memory-kg.js +2186 -251
  86. package/dist/src/memory/memory-kg.js.map +1 -1
  87. package/dist/src/memory/query-router.d.ts +51 -0
  88. package/dist/src/memory/query-router.d.ts.map +1 -1
  89. package/dist/src/memory/query-router.js +38 -2
  90. package/dist/src/memory/query-router.js.map +1 -1
  91. package/dist/src/orgrt/agent-exec.d.ts.map +1 -1
  92. package/dist/src/orgrt/agent-exec.js +7 -0
  93. package/dist/src/orgrt/agent-exec.js.map +1 -1
  94. package/dist/src/orgrt/agent-runner.d.ts +26 -1
  95. package/dist/src/orgrt/agent-runner.d.ts.map +1 -1
  96. package/dist/src/orgrt/agent-runner.js +73 -22
  97. package/dist/src/orgrt/agent-runner.js.map +1 -1
  98. package/dist/src/orgrt/antigravity-runner.d.ts +1 -1
  99. package/dist/src/orgrt/antigravity-runner.d.ts.map +1 -1
  100. package/dist/src/orgrt/antigravity-runner.js +36 -19
  101. package/dist/src/orgrt/antigravity-runner.js.map +1 -1
  102. package/dist/src/orgrt/approvals.d.ts +26 -2
  103. package/dist/src/orgrt/approvals.d.ts.map +1 -1
  104. package/dist/src/orgrt/approvals.js +67 -7
  105. package/dist/src/orgrt/approvals.js.map +1 -1
  106. package/dist/src/orgrt/broker.d.ts +21 -2
  107. package/dist/src/orgrt/broker.d.ts.map +1 -1
  108. package/dist/src/orgrt/broker.js +56 -8
  109. package/dist/src/orgrt/broker.js.map +1 -1
  110. package/dist/src/orgrt/bus.d.ts +8 -0
  111. package/dist/src/orgrt/bus.d.ts.map +1 -1
  112. package/dist/src/orgrt/bus.js +27 -0
  113. package/dist/src/orgrt/bus.js.map +1 -1
  114. package/dist/src/orgrt/checkpoint-ops.d.ts.map +1 -1
  115. package/dist/src/orgrt/checkpoint-ops.js +15 -5
  116. package/dist/src/orgrt/checkpoint-ops.js.map +1 -1
  117. package/dist/src/orgrt/checkpoint.d.ts +42 -4
  118. package/dist/src/orgrt/checkpoint.d.ts.map +1 -1
  119. package/dist/src/orgrt/checkpoint.js +75 -4
  120. package/dist/src/orgrt/checkpoint.js.map +1 -1
  121. package/dist/src/orgrt/codex-runner.d.ts +1 -1
  122. package/dist/src/orgrt/codex-runner.d.ts.map +1 -1
  123. package/dist/src/orgrt/codex-runner.js +50 -23
  124. package/dist/src/orgrt/codex-runner.js.map +1 -1
  125. package/dist/src/orgrt/copilot-runner.d.ts +24 -2
  126. package/dist/src/orgrt/copilot-runner.d.ts.map +1 -1
  127. package/dist/src/orgrt/copilot-runner.js +257 -157
  128. package/dist/src/orgrt/copilot-runner.js.map +1 -1
  129. package/dist/src/orgrt/cross-org.d.ts +10 -3
  130. package/dist/src/orgrt/cross-org.d.ts.map +1 -1
  131. package/dist/src/orgrt/cross-org.js +225 -10
  132. package/dist/src/orgrt/cross-org.js.map +1 -1
  133. package/dist/src/orgrt/crush-runner.d.ts +22 -2
  134. package/dist/src/orgrt/crush-runner.d.ts.map +1 -1
  135. package/dist/src/orgrt/crush-runner.js +227 -120
  136. package/dist/src/orgrt/crush-runner.js.map +1 -1
  137. package/dist/src/orgrt/daemon.d.ts +77 -7
  138. package/dist/src/orgrt/daemon.d.ts.map +1 -1
  139. package/dist/src/orgrt/daemon.js +989 -385
  140. package/dist/src/orgrt/daemon.js.map +1 -1
  141. package/dist/src/orgrt/decisions.d.ts +2 -2
  142. package/dist/src/orgrt/decisions.d.ts.map +1 -1
  143. package/dist/src/orgrt/decisions.js +90 -18
  144. package/dist/src/orgrt/decisions.js.map +1 -1
  145. package/dist/src/orgrt/grok-runner.d.ts +29 -3
  146. package/dist/src/orgrt/grok-runner.d.ts.map +1 -1
  147. package/dist/src/orgrt/grok-runner.js +286 -150
  148. package/dist/src/orgrt/grok-runner.js.map +1 -1
  149. package/dist/src/orgrt/kimicode-runner.d.ts +5 -5
  150. package/dist/src/orgrt/kimicode-runner.d.ts.map +1 -1
  151. package/dist/src/orgrt/kimicode-runner.js +53 -32
  152. package/dist/src/orgrt/kimicode-runner.js.map +1 -1
  153. package/dist/src/orgrt/mailbox.d.ts +15 -0
  154. package/dist/src/orgrt/mailbox.d.ts.map +1 -1
  155. package/dist/src/orgrt/mailbox.js +29 -1
  156. package/dist/src/orgrt/mailbox.js.map +1 -1
  157. package/dist/src/orgrt/migrate.d.ts.map +1 -1
  158. package/dist/src/orgrt/migrate.js +8 -5
  159. package/dist/src/orgrt/migrate.js.map +1 -1
  160. package/dist/src/orgrt/opencode-runner.d.ts +1 -1
  161. package/dist/src/orgrt/opencode-runner.d.ts.map +1 -1
  162. package/dist/src/orgrt/opencode-runner.js +29 -3
  163. package/dist/src/orgrt/opencode-runner.js.map +1 -1
  164. package/dist/src/orgrt/org-memory.d.ts +19 -3
  165. package/dist/src/orgrt/org-memory.d.ts.map +1 -1
  166. package/dist/src/orgrt/org-memory.js +110 -38
  167. package/dist/src/orgrt/org-memory.js.map +1 -1
  168. package/dist/src/orgrt/pi-rpc-runner.d.ts +3 -1
  169. package/dist/src/orgrt/pi-rpc-runner.d.ts.map +1 -1
  170. package/dist/src/orgrt/pi-rpc-runner.js +35 -3
  171. package/dist/src/orgrt/pi-rpc-runner.js.map +1 -1
  172. package/dist/src/orgrt/pi-runner.d.ts +25 -2
  173. package/dist/src/orgrt/pi-runner.d.ts.map +1 -1
  174. package/dist/src/orgrt/pi-runner.js +271 -152
  175. package/dist/src/orgrt/pi-runner.js.map +1 -1
  176. package/dist/src/orgrt/policy.d.ts +1 -0
  177. package/dist/src/orgrt/policy.d.ts.map +1 -1
  178. package/dist/src/orgrt/policy.js +199 -39
  179. package/dist/src/orgrt/policy.js.map +1 -1
  180. package/dist/src/orgrt/provider.d.ts +4 -0
  181. package/dist/src/orgrt/provider.d.ts.map +1 -1
  182. package/dist/src/orgrt/provider.js +16 -0
  183. package/dist/src/orgrt/provider.js.map +1 -1
  184. package/dist/src/orgrt/qwen-rpc-runner.d.ts +3 -1
  185. package/dist/src/orgrt/qwen-rpc-runner.d.ts.map +1 -1
  186. package/dist/src/orgrt/qwen-rpc-runner.js +35 -3
  187. package/dist/src/orgrt/qwen-rpc-runner.js.map +1 -1
  188. package/dist/src/orgrt/qwen-runner.d.ts +30 -3
  189. package/dist/src/orgrt/qwen-runner.d.ts.map +1 -1
  190. package/dist/src/orgrt/qwen-runner.js +282 -142
  191. package/dist/src/orgrt/qwen-runner.js.map +1 -1
  192. package/dist/src/orgrt/role-slot.d.ts +88 -0
  193. package/dist/src/orgrt/role-slot.d.ts.map +1 -0
  194. package/dist/src/orgrt/role-slot.js +133 -0
  195. package/dist/src/orgrt/role-slot.js.map +1 -0
  196. package/dist/src/orgrt/runtime-options.d.ts +17 -0
  197. package/dist/src/orgrt/runtime-options.d.ts.map +1 -0
  198. package/dist/src/orgrt/runtime-options.js +32 -0
  199. package/dist/src/orgrt/runtime-options.js.map +1 -0
  200. package/dist/src/orgrt/scheduler-integration.d.ts +11 -0
  201. package/dist/src/orgrt/scheduler-integration.d.ts.map +1 -1
  202. package/dist/src/orgrt/scheduler-integration.js +75 -17
  203. package/dist/src/orgrt/scheduler-integration.js.map +1 -1
  204. package/dist/src/orgrt/scheduler.d.ts +4 -0
  205. package/dist/src/orgrt/scheduler.d.ts.map +1 -1
  206. package/dist/src/orgrt/scheduler.js +7 -1
  207. package/dist/src/orgrt/scheduler.js.map +1 -1
  208. package/dist/src/orgrt/server.d.ts +8 -3
  209. package/dist/src/orgrt/server.d.ts.map +1 -1
  210. package/dist/src/orgrt/server.js +48 -13
  211. package/dist/src/orgrt/server.js.map +1 -1
  212. package/dist/src/orgrt/session.d.ts +26 -2
  213. package/dist/src/orgrt/session.d.ts.map +1 -1
  214. package/dist/src/orgrt/session.js +98 -4
  215. package/dist/src/orgrt/session.js.map +1 -1
  216. package/dist/src/orgrt/task-dag.d.ts +5 -0
  217. package/dist/src/orgrt/task-dag.d.ts.map +1 -1
  218. package/dist/src/orgrt/task-dag.js +41 -0
  219. package/dist/src/orgrt/task-dag.js.map +1 -1
  220. package/dist/src/orgrt/test-loop.js +2 -2
  221. package/dist/src/orgrt/test-loop.js.map +1 -1
  222. package/dist/src/orgrt/types.d.ts +14 -2
  223. package/dist/src/orgrt/types.d.ts.map +1 -1
  224. package/dist/src/orgrt/types.js +15 -1
  225. package/dist/src/orgrt/types.js.map +1 -1
  226. package/dist/src/orgrt/vercel-runner.d.ts.map +1 -1
  227. package/dist/src/orgrt/vercel-runner.js +4 -0
  228. package/dist/src/orgrt/vercel-runner.js.map +1 -1
  229. package/dist/src/ui/routes-org.mjs +27 -7
  230. package/dist/src/ui/server.mjs +82 -48
  231. package/dist/tsconfig.tsbuildinfo +1 -1
  232. package/package.json +3 -2
  233. package/dist/src/ui/data/mastermind-sessions.json +0 -1
@@ -0,0 +1,133 @@
1
+ /** Fold only the SUPPLIED override fields onto `current`; every omitted
2
+ * field keeps its current effective value (including across repeated
3
+ * replacements — `current` is always the slot's effectiveRole, never the
4
+ * original org-definition role, so this naturally persists overrides
5
+ * through however many replacements have already happened). */
6
+ export function mergeEffectiveRoleConfig(current, overrides) {
7
+ const merged = {
8
+ ...current,
9
+ ...(overrides.runtime !== undefined ? { runtime: overrides.runtime } : {}),
10
+ };
11
+ if (overrides.model !== undefined || overrides.providerName !== undefined) {
12
+ merged.adapter_config = {
13
+ ...current.adapter_config,
14
+ ...(overrides.model !== undefined ? { model: overrides.model } : {}),
15
+ ...(overrides.providerName !== undefined ? { provider: overrides.providerName } : {}),
16
+ };
17
+ }
18
+ return merged;
19
+ }
20
+ /** The role's per-incarnation token ceiling when org_respawn_role omits
21
+ * `budgetTokens`: reuse the SAME allocator startup uses (daemon.ts's
22
+ * perRoleBudget computation), not the older even-split-only
23
+ * roleTokenBudget() helper. A role with its own budget_tokens override
24
+ * always gets that value; otherwise the remaining org budget (after
25
+ * subtracting every override) is split evenly across every role WITHOUT
26
+ * an override. */
27
+ export function computeReplacementBudget(def, roleId) {
28
+ const role = def.roles.find((r) => r.id === roleId);
29
+ if (!role)
30
+ throw new Error(`computeReplacementBudget: unknown role "${roleId}"`);
31
+ if (role.budget_tokens != null)
32
+ return role.budget_tokens;
33
+ const orgBudgetTokens = def.run_config.budget_tokens ?? 1_000_000;
34
+ const overriddenTokenSum = def.roles.reduce((sum, r) => sum + (r.budget_tokens ?? 0), 0);
35
+ const unoverriddenRoleCount = def.roles.filter((r) => r.budget_tokens == null).length;
36
+ return unoverriddenRoleCount > 0
37
+ ? Math.max(0, Math.floor((orgBudgetTokens - overriddenTokenSum) / unoverriddenRoleCount))
38
+ : 0;
39
+ }
40
+ const RUNTIME_KINDS = new Set([
41
+ 'claude',
42
+ 'kimicode',
43
+ 'opencode',
44
+ 'vercel',
45
+ 'codex',
46
+ 'antigravity',
47
+ 'grok',
48
+ 'qwen',
49
+ 'crush',
50
+ 'copilot',
51
+ 'pi',
52
+ 'pi-rpc',
53
+ 'qwen-rpc',
54
+ ]);
55
+ function boundedString(value, max) {
56
+ if (typeof value !== 'string')
57
+ return null;
58
+ const trimmed = value.trim();
59
+ if (!trimmed || trimmed.length > max)
60
+ return null;
61
+ return trimmed;
62
+ }
63
+ /** Validate and bound every field of an org_respawn_role call before any
64
+ * state change or preflight is attempted. See the design doc's "Validation
65
+ * rules" — limits chosen there: roleId 128, reason 1000, briefing 20000. */
66
+ export function validateRespawnInput(input) {
67
+ const raw = (input ?? {});
68
+ const roleId = boundedString(raw.roleId, 128);
69
+ if (!roleId)
70
+ return { ok: false, error: 'roleId is required (1-128 characters)' };
71
+ const reason = boundedString(raw.reason, 1000);
72
+ if (!reason)
73
+ return { ok: false, error: 'reason is required (1-1000 characters)' };
74
+ const briefing = boundedString(raw.briefing, 20_000);
75
+ if (!briefing)
76
+ return { ok: false, error: 'briefing is required (1-20000 characters)' };
77
+ let runtime;
78
+ if (raw.runtime !== undefined) {
79
+ if (typeof raw.runtime !== 'string' || !RUNTIME_KINDS.has(raw.runtime)) {
80
+ return { ok: false, error: `runtime must be one of: ${[...RUNTIME_KINDS].join(', ')}` };
81
+ }
82
+ runtime = raw.runtime;
83
+ }
84
+ let model;
85
+ if (raw.model !== undefined) {
86
+ const m = boundedString(raw.model, 256);
87
+ if (!m)
88
+ return { ok: false, error: 'model must be a non-empty string (max 256 characters)' };
89
+ model = m;
90
+ }
91
+ let providerName;
92
+ if (raw.providerName !== undefined) {
93
+ const p = boundedString(raw.providerName, 128);
94
+ if (!p)
95
+ return { ok: false, error: 'providerName must be a non-empty string (max 128 characters)' };
96
+ providerName = p;
97
+ }
98
+ let budgetTokens;
99
+ if (raw.budgetTokens !== undefined) {
100
+ const b = raw.budgetTokens;
101
+ if (typeof b !== 'number' || !Number.isSafeInteger(b) || b <= 0) {
102
+ return { ok: false, error: 'budgetTokens must be a positive integer' };
103
+ }
104
+ budgetTokens = b;
105
+ }
106
+ return {
107
+ ok: true,
108
+ value: { roleId, reason, briefing, runtime, model, providerName, budgetTokens },
109
+ };
110
+ }
111
+ /** Audit/status-safe view of a role's runtime config — never includes
112
+ * role.provider (which may carry apiKey/authToken/baseUrl). */
113
+ export function redactRoleConfig(role) {
114
+ const out = {};
115
+ if (role.runtime)
116
+ out.runtime = role.runtime;
117
+ if (role.adapter_config?.model)
118
+ out.model = role.adapter_config.model;
119
+ if (role.adapter_config?.provider)
120
+ out.providerName = role.adapter_config.provider;
121
+ return out;
122
+ }
123
+ export function buildRespawnReceipt(slot, maxRespawns, success, extra = {}) {
124
+ return {
125
+ success,
126
+ roleId: '',
127
+ generation: slot.generation,
128
+ respawnCount: slot.respawnCount,
129
+ respawnsRemaining: Math.max(0, maxRespawns - slot.respawnCount),
130
+ ...extra,
131
+ };
132
+ }
133
+ //# sourceMappingURL=role-slot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role-slot.js","sourceRoot":"","sources":["../../../src/orgrt/role-slot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export interface RuntimeOption {
2
+ id: string;
3
+ available: boolean;
4
+ binary?: string;
5
+ version?: string;
6
+ installHint?: string;
7
+ }
8
+ export interface NamedProviderOption {
9
+ name: string;
10
+ defaultModel?: string;
11
+ }
12
+ export interface RuntimeOptionsReceipt {
13
+ runtimes: RuntimeOption[];
14
+ namedProviders: NamedProviderOption[];
15
+ }
16
+ export declare function buildRuntimeOptions(searchFrom?: string): Promise<RuntimeOptionsReceipt>;
17
+ //# sourceMappingURL=runtime-options.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-options.d.ts","sourceRoot":"","sources":["../../../src/orgrt/runtime-options.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,cAAc,EAAE,mBAAmB,EAAE,CAAC;CACvC;AAED,wBAAsB,mBAAmB,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAsB7F"}
@@ -0,0 +1,32 @@
1
+ // packages/@monomind/cli/src/orgrt/runtime-options.ts
2
+ /** Data source for the org_list_runtime_options tool. Read-only: wraps
3
+ * runner-registry.ts's install/version detection and provider.ts's named
4
+ * provider config, applying the in-process-runtime correction and
5
+ * credential redaction the design calls for. See
6
+ * docs/mastermind/specs/2026-09-07-org-runtime-role-respawn-design.md. */
7
+ import { listConfiguredProviders } from './provider.js';
8
+ import { RUNNER_SPECS, scanInstalled } from './runner-registry.js';
9
+ export async function buildRuntimeOptions(searchFrom) {
10
+ const scan = await scanInstalled();
11
+ const specById = new Map(RUNNER_SPECS.map((s) => [s.id, s]));
12
+ const runtimes = scan.agents.map((entry) => {
13
+ const spec = specById.get(entry.id);
14
+ // In-process runtimes (spec.binary === null, e.g. vercel) have nothing to
15
+ // find on PATH — scanInstalled's installed:false for them is a false
16
+ // negative ("not installed"), not a real unavailability signal.
17
+ const available = spec?.binary === null ? true : entry.installed;
18
+ return {
19
+ id: entry.id,
20
+ available,
21
+ ...(entry.binary ? { binary: entry.binary } : {}),
22
+ ...(entry.version ? { version: entry.version } : {}),
23
+ ...(entry.install_hint ? { installHint: entry.install_hint } : {}),
24
+ };
25
+ });
26
+ const namedProviders = listConfiguredProviders(searchFrom).map((p) => ({
27
+ name: p.name,
28
+ ...(p.model ? { defaultModel: p.model } : {}),
29
+ }));
30
+ return { runtimes, namedProviders };
31
+ }
32
+ //# sourceMappingURL=runtime-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime-options.js","sourceRoot":"","sources":["../../../src/orgrt/runtime-options.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD;;;;2EAI2E;AAC3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAoBnE,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAAmB;IAC3D,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,QAAQ,GAAoB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QAC1D,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,EAAyC,CAAC,CAAC;QAC3E,0EAA0E;QAC1E,qEAAqE;QACrE,gEAAgE;QAChE,MAAM,SAAS,GAAG,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;QACjE,OAAO;YACL,EAAE,EAAE,KAAK,CAAC,EAAE;YACZ,SAAS;YACT,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACjD,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,MAAM,cAAc,GAA0B,uBAAuB,CAAC,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5F,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9C,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;AACtC,CAAC"}
@@ -16,4 +16,15 @@ export declare function scheduleBossRestart(daemon: OrgDaemon, name: string): vo
16
16
  * before capacity returns; `running` is compared by identity, not `name`,
17
17
  * so a stale retry can never spawn into a different run. */
18
18
  export declare function scheduleDeferredSpawn(daemon: OrgDaemon, name: string, running: RunningOrg, role: OrgRole, spawnRole: (role: OrgRole) => void): void;
19
+ /** Bug 4: a role deferred because the org is already at its
20
+ * run_config.max_concurrent_agents ceiling isn't abandoned either — poll
21
+ * until a slot frees up (another role in this org ends, crashes, or is
22
+ * stopped — activeRoleCount() recomputes live each check, so nothing here
23
+ * needs to explicitly track "a slot freed") and spawn it then. Same shape as
24
+ * scheduleDeferredSpawn's host-resource-pressure case, just gated on the
25
+ * org's own concurrency cap instead of waitForCapacity(). Bails quietly if
26
+ * the org is stopped (or restarted under the same name) before a slot
27
+ * frees; `running` is compared by identity, not `name`, so a stale retry can
28
+ * never spawn into a different run. */
29
+ export declare function scheduleConcurrencyDeferredSpawn(daemon: OrgDaemon, name: string, running: RunningOrg, role: OrgRole, spawnRole: (role: OrgRole) => void): void;
19
30
  //# sourceMappingURL=scheduler-integration.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler-integration.d.ts","sourceRoot":"","sources":["../../../src/orgrt/scheduler-integration.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C;6EAC6E;AAC7E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAW9D;AAED;;;;qCAIqC;AACrC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAuDzE;AAED;;;;;6DAK6D;AAC7D,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GACjC,IAAI,CAgEN"}
1
+ {"version":3,"file":"scheduler-integration.d.ts","sourceRoot":"","sources":["../../../src/orgrt/scheduler-integration.ts"],"names":[],"mappings":"AAKA,OAAO,EAAmB,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAuC1C;6EAC6E;AAC7E,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAW9D;AAED;;;;qCAIqC;AACrC,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAuDzE;AAED;;;;;6DAK6D;AAC7D,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GACjC,IAAI,CAyCN;AAED;;;;;;;;;wCASwC;AACxC,wBAAgB,gCAAgC,CAC9C,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,UAAU,EACnB,IAAI,EAAE,OAAO,EACb,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,GACjC,IAAI,CA4CN"}
@@ -1,9 +1,30 @@
1
1
  // packages/@monomind/cli/src/orgrt/scheduler-integration.ts
2
2
  // Extracted from daemon.ts — auto-wake, boss restart, deferred role spawns.
3
3
  import { waitForCapacity } from '../utils/resource-governor.js';
4
- import { mailBody } from './cross-org.js';
5
- import { OrgDaemon } from './daemon.js';
4
+ import { pushMessage } from './cross-org.js';
5
+ import { activeRoleCount, OrgDaemon } from './daemon.js';
6
6
  import { drainInbox } from './inbox.js';
7
+ /** Shared by scheduleDeferredSpawn and scheduleConcurrencyDeferredSpawn: spawn
8
+ * the role now that its gate has cleared, then deliver any messages queued
9
+ * for it while it was deferred (drained BEFORE spawning to avoid a race with
10
+ * messages arriving during the spawn window). */
11
+ async function spawnNowAndDrain(daemon, name, running, role, spawnRole) {
12
+ const queued = drainInbox(daemon.root, name);
13
+ spawnRole(role);
14
+ for (const msg of queued) {
15
+ const agent = running.agents.get(msg.toRole);
16
+ if (agent && !agent.mailbox.isClosed) {
17
+ running.bus.emit({
18
+ type: 'xorg',
19
+ from: msg.fromQualified,
20
+ to: `${name}:${msg.toRole}`,
21
+ subject: msg.subject,
22
+ msg: msg.body,
23
+ });
24
+ await pushMessage(daemon, name, running, msg.toRole, msg.fromQualified, msg.subject, msg.body, `inbox-${msg.ts}-${Math.random().toString(36).slice(2, 8)}`);
25
+ }
26
+ }
27
+ }
7
28
  /** Start an offline org in the background so queued messages get drained.
8
29
  * Fire-and-forget — errors are logged but don't propagate to the sender. */
9
30
  export function autoWake(daemon, name) {
@@ -95,21 +116,7 @@ export function scheduleDeferredSpawn(daemon, name, running, role, spawnRole) {
95
116
  });
96
117
  // Drain messages queued while the role was deferred BEFORE spawning
97
118
  // to prevent race condition where messages arrive during spawn window
98
- const queued = drainInbox(daemon.root, name);
99
- spawnRole(role);
100
- for (const msg of queued) {
101
- const agent = running.agents.get(msg.toRole);
102
- if (agent && !agent.mailbox.isClosed) {
103
- running.bus.emit({
104
- type: 'xorg',
105
- from: msg.fromQualified,
106
- to: `${name}:${msg.toRole}`,
107
- subject: msg.subject,
108
- msg: msg.body,
109
- });
110
- agent.mailbox.push(mailBody(daemon.root, name, running, `[message from ${msg.fromQualified}] subject: ${msg.subject}`, msg.body, `inbox-${msg.ts}-${Math.random().toString(36).slice(2, 8)}`));
111
- }
112
- }
119
+ await spawnNowAndDrain(daemon, name, running, role, spawnRole);
113
120
  return;
114
121
  }
115
122
  running.bus.emit({
@@ -131,4 +138,55 @@ export function scheduleDeferredSpawn(daemon, name, running, role, spawnRole) {
131
138
  });
132
139
  })().catch((err) => console.error(`org ${name}: deferred spawn of "${role.id}" failed:`, err instanceof Error ? err.message : err));
133
140
  }
141
+ /** Bug 4: a role deferred because the org is already at its
142
+ * run_config.max_concurrent_agents ceiling isn't abandoned either — poll
143
+ * until a slot frees up (another role in this org ends, crashes, or is
144
+ * stopped — activeRoleCount() recomputes live each check, so nothing here
145
+ * needs to explicitly track "a slot freed") and spawn it then. Same shape as
146
+ * scheduleDeferredSpawn's host-resource-pressure case, just gated on the
147
+ * org's own concurrency cap instead of waitForCapacity(). Bails quietly if
148
+ * the org is stopped (or restarted under the same name) before a slot
149
+ * frees; `running` is compared by identity, not `name`, so a stale retry can
150
+ * never spawn into a different run. */
151
+ export function scheduleConcurrencyDeferredSpawn(daemon, name, running, role, spawnRole) {
152
+ const MAX_ATTEMPTS = 180; // ~15 min at 5s intervals before giving up loudly
153
+ const POLL_MS = 5_000;
154
+ (async () => {
155
+ for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {
156
+ await new Promise((resolve) => {
157
+ const t = setTimeout(resolve, POLL_MS);
158
+ t.unref?.();
159
+ });
160
+ if (daemon.orgs.get(name) !== running)
161
+ return; // org stopped/restarted — abandon quietly
162
+ const limit = running.def.run_config.max_concurrent_agents;
163
+ if (limit == null || activeRoleCount(running) < limit) {
164
+ running.bus.emit({
165
+ type: 'audit',
166
+ from: role.id,
167
+ reason: 'concurrency-recovered',
168
+ msg: `a concurrency slot freed up after ${attempt} retr${attempt === 1 ? 'y' : 'ies'} — spawning deferred role "${role.id}"`,
169
+ });
170
+ await spawnNowAndDrain(daemon, name, running, role, spawnRole);
171
+ return;
172
+ }
173
+ running.bus.emit({
174
+ type: 'audit',
175
+ from: role.id,
176
+ reason: 'concurrency-limit',
177
+ msg: `still at the max_concurrent_agents ceiling (attempt ${attempt}/${MAX_ATTEMPTS}) — retrying "${role.id}" spawn`,
178
+ });
179
+ }
180
+ const missing = daemon.abandoned.get(name) ?? new Set();
181
+ missing.add(role.id);
182
+ daemon.abandoned.set(name, missing);
183
+ daemon.persistState(name, 'running', running.run);
184
+ running.bus.emit({
185
+ type: 'audit',
186
+ from: role.id,
187
+ reason: 'concurrency-abandoned',
188
+ msg: `giving up spawning "${role.id}" after ${MAX_ATTEMPTS} retries at the max_concurrent_agents ceiling — org will run without this role until manually restarted`,
189
+ });
190
+ })().catch((err) => console.error(`org ${name}: concurrency-deferred spawn of "${role.id}" failed:`, err instanceof Error ? err.message : err));
191
+ }
134
192
  //# sourceMappingURL=scheduler-integration.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler-integration.js","sourceRoot":"","sources":["../../../src/orgrt/scheduler-integration.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler-integration.js","sourceRoot":"","sources":["../../../src/orgrt/scheduler-integration.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,10 @@ export declare function parseSchedule(s: string | number | null | undefined): nu
4
4
  export declare class OrgScheduler {
5
5
  private runFn;
6
6
  private timers;
7
+ /** Current interval per org. A catch-up fired from an old run's `finally`
8
+ * reads this rather than the intervalMs its closure captured, so an org
9
+ * rescheduled mid-run gets its new interval, not the replaced one. */
10
+ private intervals;
7
11
  private running;
8
12
  /** Orgs whose tick arrived mid-run. A dropped tick meant an org that overruns
9
13
  * its interval — a 200m cycle on a 2h schedule — idled until the *next*
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/orgrt/scheduler.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAOlF;AAED,+GAA+G;AAC/G,qBAAa,YAAY;IAUX,OAAO,CAAC,KAAK;IATzB,OAAO,CAAC,MAAM,CAAqD;IACnE,OAAO,CAAC,OAAO,CAAqB;IACpC;;;;oFAIgF;IAChF,OAAO,CAAC,OAAO,CAAqB;IAEpC,YAAoB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAAI;IAElF;;;;;;8BAM0B;IAC1B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAQ,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAgDnF;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAKzB;IAED,IAAI,IAAI,IAAI,CAEX;CACF"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/orgrt/scheduler.ts"],"names":[],"mappings":"AAEA,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAOlF;AAED,+GAA+G;AAC/G,qBAAa,YAAY;IAcX,OAAO,CAAC,KAAK;IAbzB,OAAO,CAAC,MAAM,CAAqD;IACnE;;2EAEuE;IACvE,OAAO,CAAC,SAAS,CAA6B;IAC9C,OAAO,CAAC,OAAO,CAAqB;IACpC;;;;oFAIgF;IAChF,OAAO,CAAC,OAAO,CAAqB;IAEpC,YAAoB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,EAAI;IAElF;;;;;;8BAM0B;IAC1B,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,UAAQ,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAiDnF;IAED,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAMzB;IAED,IAAI,IAAI,IAAI,CAEX;CACF"}
@@ -15,6 +15,10 @@ export function parseSchedule(s) {
15
15
  export class OrgScheduler {
16
16
  runFn;
17
17
  timers = new Map();
18
+ /** Current interval per org. A catch-up fired from an old run's `finally`
19
+ * reads this rather than the intervalMs its closure captured, so an org
20
+ * rescheduled mid-run gets its new interval, not the replaced one. */
21
+ intervals = new Map();
18
22
  running = new Set();
19
23
  /** Orgs whose tick arrived mid-run. A dropped tick meant an org that overruns
20
24
  * its interval — a 200m cycle on a 2h schedule — idled until the *next*
@@ -34,6 +38,7 @@ export class OrgScheduler {
34
38
  * everything at once. */
35
39
  add(name, intervalMs, runNow = false, sinceLastRunMs) {
36
40
  this.remove(name);
41
+ this.intervals.set(name, intervalMs);
37
42
  const fire = async () => {
38
43
  if (this.running.has(name)) {
39
44
  this.pending.add(name);
@@ -41,7 +46,7 @@ export class OrgScheduler {
41
46
  } // catch up when it ends
42
47
  this.running.add(name);
43
48
  try {
44
- await this.runFn(name, intervalMs);
49
+ await this.runFn(name, this.intervals.get(name) ?? intervalMs);
45
50
  }
46
51
  catch (err) {
47
52
  console.error(`[org-scheduler] ${name}: scheduled run failed:`, err);
@@ -88,6 +93,7 @@ export class OrgScheduler {
88
93
  if (t)
89
94
  clearInterval(t);
90
95
  this.timers.delete(name);
96
+ this.intervals.delete(name);
91
97
  this.pending.delete(name); // an unscheduled org has no tick to catch up on
92
98
  }
93
99
  stop() {
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/orgrt/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/orgrt/scheduler.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,10 @@ import type { OrgDaemon } from './daemon.js';
2
2
  export interface OrgServer {
3
3
  port: number;
4
4
  close: () => void;
5
- credential: string;
5
+ /** Authorizes the human-decision routes (approvals, gates, answers, human
6
+ * messages) and, as a superset, everything else. Never published to the
7
+ * broker registry — see broker.ts's defaultOperatorDir(). */
8
+ operatorCredential: string;
6
9
  }
7
10
  export interface ServerOpts {
8
11
  /** Filter tool audit events by tool name or decision (allow|deny) */
@@ -13,6 +16,8 @@ export interface ServerOpts {
13
16
  }
14
17
  /** Minimal HTTP listener for cross-process org message delivery.
15
18
  * Binds an ephemeral port (pass 0) so the daemon can register it with the broker.
16
- * Requires an auth credential on all POST requests (generated at startup, shared via broker). */
17
- export declare function startOrgServer(daemon: OrgDaemon, port?: number, credential?: string): Promise<OrgServer>;
19
+ * Two credentials gate requests: each hosted org's agent credential (published
20
+ * via the broker; unlocks delivery/status routes) and the operator credential
21
+ * (generated here unless supplied; unlocks OPERATOR_ROUTES as well). */
22
+ export declare function startOrgServer(daemon: OrgDaemon, port?: number, operatorCredential?: string): Promise<OrgServer>;
18
23
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/orgrt/server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAGD,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,WAAW,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,CAAC;CAC9D;AAwCD;;kGAEkG;AAClG,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,SAAI,EACR,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,SAAS,CAAC,CA4MpB"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../../src/orgrt/server.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;kEAE8D;IAC9D,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAcD,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,WAAW,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;KAAE,CAAC;CAC9D;AAwCD;;;;yEAIyE;AACzE,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,IAAI,SAAI,EACR,kBAAkB,CAAC,EAAE,MAAM,GAC1B,OAAO,CAAC,SAAS,CAAC,CAmOpB"}
@@ -2,6 +2,16 @@
2
2
  // monolean: stripped to xdeliver-only — live UI, WS fanout, and redundant REST
3
3
  // endpoints deleted; the control server at :4242 handles all of those.
4
4
  import http from 'node:http';
5
+ /** Routes that act with HUMAN authority. Only the operator credential unlocks
6
+ * them; a per-org agent credential (the one in the broker registry, readable
7
+ * by every org process and agent subprocess on the machine) gets 403 so a role
8
+ * can never approve its own gates. */
9
+ const OPERATOR_ROUTES = new Set([
10
+ '/api/set-approval',
11
+ '/api/resolve-gate',
12
+ '/api/answer-question',
13
+ '/api/human-message',
14
+ ]);
5
15
  const MAX_BODY = 1_000_000; // 1MB — prevents OOM from oversized POSTs
6
16
  /** Parse a JSON POST body with a size guard. Rejects oversized or malformed bodies. */
7
17
  function parseBody(req) {
@@ -40,22 +50,34 @@ function json(res, status, data) {
40
50
  }
41
51
  /** Minimal HTTP listener for cross-process org message delivery.
42
52
  * Binds an ephemeral port (pass 0) so the daemon can register it with the broker.
43
- * Requires an auth credential on all POST requests (generated at startup, shared via broker). */
44
- export async function startOrgServer(daemon, port = 0, credential) {
53
+ * Two credentials gate requests: each hosted org's agent credential (published
54
+ * via the broker; unlocks delivery/status routes) and the operator credential
55
+ * (generated here unless supplied; unlocks OPERATOR_ROUTES as well). */
56
+ export async function startOrgServer(daemon, port = 0, operatorCredential) {
45
57
  const { randomUUID, timingSafeEqual } = await import('node:crypto');
46
- const cred = credential ?? randomUUID();
58
+ const operatorCred = operatorCredential ?? randomUUID();
47
59
  // SEC-2: timing-safe credential comparison. The previous `!==` compared
48
60
  // header-supplied bytes against the secret byte-for-byte and short-circuited
49
61
  // on the first mismatched character — a remote attacker could time the
50
62
  // response to recover the secret one byte at a time. Buffer.from + length
51
63
  // gate + timingSafeEqual runs in constant time.
52
- const safeCred = (supplied) => {
64
+ const safeEq = (supplied, expected) => {
53
65
  const a = Buffer.from(String(supplied ?? ''));
54
- const b = Buffer.from(cred);
66
+ const b = Buffer.from(expected);
55
67
  if (a.length !== b.length)
56
68
  return false;
57
69
  return timingSafeEqual(a, b);
58
70
  };
71
+ const isOperator = (supplied) => safeEq(supplied, operatorCred);
72
+ /** Operator, or any org currently hosted by this daemon. */
73
+ const isAgentOrOperator = (supplied) => {
74
+ if (isOperator(supplied))
75
+ return true;
76
+ for (const org of daemon.orgs.values())
77
+ if (org.credential && safeEq(supplied, org.credential))
78
+ return true;
79
+ return false;
80
+ };
59
81
  // SEC-3: DNS-rebinding / cross-origin defence. Mirrors ui/server.mjs's
60
82
  // _allowedHosts + Origin allow-list. Default to loopback; override via env
61
83
  // for users running the daemon behind a port-forwarder or in a container.
@@ -89,7 +111,7 @@ export async function startOrgServer(daemon, port = 0, credential) {
89
111
  const corsOrigin = allowedOrigin(req.headers.origin);
90
112
  // SSE endpoint for live bus event streaming (dashboard integration)
91
113
  if (req.method === 'GET' && req.url === '/api/events') {
92
- if (!safeCred(req.headers['x-monomind-cred'])) {
114
+ if (!isAgentOrOperator(req.headers['x-monomind-cred'])) {
93
115
  json(res, 401, { ok: false, error: 'unauthorized' });
94
116
  return;
95
117
  }
@@ -110,7 +132,7 @@ export async function startOrgServer(daemon, port = 0, credential) {
110
132
  }
111
133
  // GET endpoint for org status snapshot (dashboard initial load)
112
134
  if (req.method === 'GET' && req.url?.startsWith('/api/status')) {
113
- if (!safeCred(req.headers['x-monomind-cred'])) {
135
+ if (!isAgentOrOperator(req.headers['x-monomind-cred'])) {
114
136
  json(res, 401, { ok: false, error: 'unauthorized' });
115
137
  return;
116
138
  }
@@ -123,20 +145,26 @@ export async function startOrgServer(daemon, port = 0, credential) {
123
145
  res.end('not found');
124
146
  return;
125
147
  }
126
- // Auth gate — all POST endpoints require the daemon credential
127
- if (!safeCred(req.headers['x-monomind-cred'])) {
148
+ // Auth gate — every POST needs a credential this daemon recognizes, and
149
+ // the human-decision routes need the operator credential specifically.
150
+ const supplied = req.headers['x-monomind-cred'];
151
+ if (!isAgentOrOperator(supplied)) {
128
152
  json(res, 401, { ok: false, error: 'unauthorized' });
129
153
  return;
130
154
  }
155
+ if (OPERATOR_ROUTES.has(req.url ?? '') && !isOperator(supplied)) {
156
+ json(res, 403, { ok: false, error: 'forbidden: operator credential required' });
157
+ return;
158
+ }
131
159
  (async () => {
132
160
  const payload = await parseBody(req);
133
161
  if (req.url === '/api/xdeliver') {
134
- const { toOrg, toRole, fromOrg, fromRole, subject, body: b, } = payload;
162
+ const { toOrg, toRole, fromOrg, fromRole, fromCredential, subject, body: b, } = payload;
135
163
  if (!toOrg || !toRole || !fromOrg || !fromRole) {
136
164
  json(res, 400, { ok: false, error: 'toOrg, toRole, fromOrg, fromRole are required' });
137
165
  return;
138
166
  }
139
- const result = daemon.receiveRemote(toOrg, toRole, `${fromOrg}:${fromRole}`, subject ?? '', b ?? '');
167
+ const result = await daemon.receiveRemote(toOrg, toRole, `${fromOrg}:${fromRole}`, subject ?? '', b ?? '', fromCredential);
140
168
  json(res, result.ok ? 200 : 404, result);
141
169
  }
142
170
  else if (req.url === '/api/human-message') {
@@ -190,7 +218,14 @@ export async function startOrgServer(daemon, port = 0, credential) {
190
218
  // users running inside containers / port-forwarders that genuinely need
191
219
  // remote connections.
192
220
  const bindHost = process.env.MONOMIND_ORG_SERVER_HOST ?? '127.0.0.1';
193
- await new Promise((r) => server.listen(port, bindHost, r));
221
+ await new Promise((resolve, reject) => {
222
+ const onError = (err) => reject(err);
223
+ server.once('error', onError);
224
+ server.listen(port, bindHost, () => {
225
+ server.removeListener('error', onError);
226
+ resolve();
227
+ });
228
+ });
194
229
  const actual = server.address().port;
195
230
  actualPort = actual;
196
231
  // Wire bus events from all running orgs to SSE clients
@@ -215,7 +250,7 @@ export async function startOrgServer(daemon, port = 0, credential) {
215
250
  sseClients.clear();
216
251
  server.close();
217
252
  },
218
- credential: cred,
253
+ operatorCredential: operatorCred,
219
254
  };
220
255
  }
221
256
  //# sourceMappingURL=server.js.map