monomind 1.11.12 → 1.11.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 (222) hide show
  1. package/.claude/commands/mastermind/idea.md +1 -1
  2. package/.claude/commands/mastermind/master.md +1 -1
  3. package/.claude/skills/mastermind/_protocol.md +4 -4
  4. package/.claude/skills/mastermind/build.md +3 -3
  5. package/.claude/skills/mastermind/content.md +3 -3
  6. package/.claude/skills/mastermind/createorg.md +2 -2
  7. package/.claude/skills/mastermind/finance.md +3 -3
  8. package/.claude/skills/mastermind/marketing.md +3 -3
  9. package/.claude/skills/mastermind/ops.md +3 -3
  10. package/.claude/skills/mastermind/release.md +3 -3
  11. package/.claude/skills/mastermind/research.md +3 -3
  12. package/.claude/skills/mastermind/review.md +3 -3
  13. package/.claude/skills/mastermind/sales.md +3 -3
  14. package/package.json +1 -1
  15. package/packages/@monomind/cli/dist/src/init/statusline-generator.js +3 -3
  16. package/packages/@monomind/cli/dist/src/observability/replay-reader.d.ts +1 -1
  17. package/packages/@monomind/cli/dist/src/update/checker.js +24 -7
  18. package/packages/@monomind/cli/dist/src/update/index.js +3 -6
  19. package/packages/@monomind/cli/package.json +1 -1
  20. package/packages/@monomind/cli/dist/src/agents/halt-signal.d.ts +0 -25
  21. package/packages/@monomind/cli/dist/src/agents/halt-signal.js +0 -76
  22. package/packages/@monomind/cli/dist/src/agents/index.d.ts +0 -18
  23. package/packages/@monomind/cli/dist/src/agents/index.js +0 -13
  24. package/packages/@monomind/cli/dist/src/agents/managed-agent.d.ts +0 -41
  25. package/packages/@monomind/cli/dist/src/agents/managed-agent.js +0 -69
  26. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.d.ts +0 -23
  27. package/packages/@monomind/cli/dist/src/agents/prompt-experiment.js +0 -49
  28. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.d.ts +0 -22
  29. package/packages/@monomind/cli/dist/src/agents/prompt-version-manager.js +0 -80
  30. package/packages/@monomind/cli/dist/src/agents/registry-query.d.ts +0 -71
  31. package/packages/@monomind/cli/dist/src/agents/registry-query.js +0 -125
  32. package/packages/@monomind/cli/dist/src/agents/score-decay.d.ts +0 -19
  33. package/packages/@monomind/cli/dist/src/agents/score-decay.js +0 -22
  34. package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.d.ts +0 -13
  35. package/packages/@monomind/cli/dist/src/agents/shared-instructions-loader.js +0 -40
  36. package/packages/@monomind/cli/dist/src/agents/specialization-scorer.d.ts +0 -54
  37. package/packages/@monomind/cli/dist/src/agents/specialization-scorer.js +0 -212
  38. package/packages/@monomind/cli/dist/src/agents/termination-watcher.d.ts +0 -30
  39. package/packages/@monomind/cli/dist/src/agents/termination-watcher.js +0 -84
  40. package/packages/@monomind/cli/dist/src/agents/trigger-index.d.ts +0 -20
  41. package/packages/@monomind/cli/dist/src/agents/trigger-index.js +0 -38
  42. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.d.ts +0 -64
  43. package/packages/@monomind/cli/dist/src/agents/trigger-scanner.js +0 -308
  44. package/packages/@monomind/cli/dist/src/agents/version-diff.d.ts +0 -18
  45. package/packages/@monomind/cli/dist/src/agents/version-diff.js +0 -64
  46. package/packages/@monomind/cli/dist/src/agents/version-store.d.ts +0 -60
  47. package/packages/@monomind/cli/dist/src/agents/version-store.js +0 -235
  48. package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.d.ts +0 -45
  49. package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.js +0 -404
  50. package/packages/@monomind/cli/dist/src/commands/agent-wasm.d.ts +0 -14
  51. package/packages/@monomind/cli/dist/src/commands/agent-wasm.js +0 -333
  52. package/packages/@monomind/cli/dist/src/commands/ui.js +0 -68
  53. package/packages/@monomind/cli/dist/src/consensus/index.d.ts +0 -7
  54. package/packages/@monomind/cli/dist/src/consensus/index.js +0 -6
  55. package/packages/@monomind/cli/dist/src/context/context-provider.d.ts +0 -44
  56. package/packages/@monomind/cli/dist/src/context/context-provider.js +0 -25
  57. package/packages/@monomind/cli/dist/src/context/git-state-provider.d.ts +0 -12
  58. package/packages/@monomind/cli/dist/src/context/git-state-provider.js +0 -34
  59. package/packages/@monomind/cli/dist/src/context/index.d.ts +0 -12
  60. package/packages/@monomind/cli/dist/src/context/index.js +0 -12
  61. package/packages/@monomind/cli/dist/src/context/project-conventions-provider.d.ts +0 -15
  62. package/packages/@monomind/cli/dist/src/context/project-conventions-provider.js +0 -19
  63. package/packages/@monomind/cli/dist/src/context/prompt-assembler.d.ts +0 -26
  64. package/packages/@monomind/cli/dist/src/context/prompt-assembler.js +0 -93
  65. package/packages/@monomind/cli/dist/src/context/task-history-provider.d.ts +0 -24
  66. package/packages/@monomind/cli/dist/src/context/task-history-provider.js +0 -32
  67. package/packages/@monomind/cli/dist/src/context/user-preferences-provider.d.ts +0 -14
  68. package/packages/@monomind/cli/dist/src/context/user-preferences-provider.js +0 -27
  69. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.d.ts +0 -31
  70. package/packages/@monomind/cli/dist/src/dlq/dlq-reader.js +0 -81
  71. package/packages/@monomind/cli/dist/src/dlq/dlq-writer.d.ts +0 -24
  72. package/packages/@monomind/cli/dist/src/dlq/dlq-writer.js +0 -65
  73. package/packages/@monomind/cli/dist/src/dlq/index.d.ts +0 -10
  74. package/packages/@monomind/cli/dist/src/dlq/index.js +0 -7
  75. package/packages/@monomind/cli/dist/src/eval/dataset-manager.d.ts +0 -33
  76. package/packages/@monomind/cli/dist/src/eval/dataset-manager.js +0 -107
  77. package/packages/@monomind/cli/dist/src/eval/dataset-runner.d.ts +0 -23
  78. package/packages/@monomind/cli/dist/src/eval/dataset-runner.js +0 -59
  79. package/packages/@monomind/cli/dist/src/eval/index.d.ts +0 -10
  80. package/packages/@monomind/cli/dist/src/eval/index.js +0 -7
  81. package/packages/@monomind/cli/dist/src/eval/trace-collector.d.ts +0 -40
  82. package/packages/@monomind/cli/dist/src/eval/trace-collector.js +0 -102
  83. package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.d.ts +0 -68
  84. package/packages/@monomind/cli/dist/src/infrastructure/in-memory-repositories.js +0 -264
  85. package/packages/@monomind/cli/dist/src/interactive/interrupt.d.ts +0 -22
  86. package/packages/@monomind/cli/dist/src/interactive/interrupt.js +0 -71
  87. package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.d.ts +0 -25
  88. package/packages/@monomind/cli/dist/src/mcp/deprecation-injector.js +0 -48
  89. package/packages/@monomind/cli/dist/src/mcp/tool-registry.d.ts +0 -61
  90. package/packages/@monomind/cli/dist/src/mcp/tool-registry.js +0 -246
  91. package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.d.ts +0 -9
  92. package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.js +0 -230
  93. package/packages/@monomind/cli/dist/src/model/complexity-scorer.d.ts +0 -21
  94. package/packages/@monomind/cli/dist/src/model/complexity-scorer.js +0 -106
  95. package/packages/@monomind/cli/dist/src/model/index.d.ts +0 -4
  96. package/packages/@monomind/cli/dist/src/model/index.js +0 -4
  97. package/packages/@monomind/cli/dist/src/model/model-settings.d.ts +0 -22
  98. package/packages/@monomind/cli/dist/src/model/model-settings.js +0 -33
  99. package/packages/@monomind/cli/dist/src/model/model-tier-resolver.d.ts +0 -24
  100. package/packages/@monomind/cli/dist/src/model/model-tier-resolver.js +0 -65
  101. package/packages/@monomind/cli/dist/src/monovector/capabilities.d.ts +0 -34
  102. package/packages/@monomind/cli/dist/src/monovector/capabilities.js +0 -37
  103. package/packages/@monomind/cli/dist/src/orchestration/index.d.ts +0 -7
  104. package/packages/@monomind/cli/dist/src/orchestration/index.js +0 -6
  105. package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.d.ts +0 -11
  106. package/packages/@monomind/cli/dist/src/orchestration/mode-dispatcher.js +0 -31
  107. package/packages/@monomind/cli/dist/src/orchestration/routing-modes.d.ts +0 -68
  108. package/packages/@monomind/cli/dist/src/orchestration/routing-modes.js +0 -180
  109. package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.d.ts +0 -7
  110. package/packages/@monomind/cli/dist/src/plugins/tests/demo-plugin-store.js +0 -126
  111. package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.d.ts +0 -12
  112. package/packages/@monomind/cli/dist/src/plugins/tests/standalone-test.js +0 -188
  113. package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.d.ts +0 -7
  114. package/packages/@monomind/cli/dist/src/plugins/tests/test-plugin-store.js +0 -206
  115. package/packages/@monomind/cli/dist/src/runtime/headless.d.ts +0 -60
  116. package/packages/@monomind/cli/dist/src/runtime/headless.js +0 -284
  117. package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.d.ts +0 -50
  118. package/packages/@monomind/cli/dist/src/services/agentic-flow-bridge.js +0 -95
  119. package/packages/@monomind/cli/dist/src/services/container-worker-pool.d.ts +0 -197
  120. package/packages/@monomind/cli/dist/src/services/container-worker-pool.js +0 -623
  121. package/packages/@monomind/cli/dist/src/services/index.d.ts +0 -13
  122. package/packages/@monomind/cli/dist/src/services/index.js +0 -11
  123. package/packages/@monomind/cli/dist/src/services/worker-queue.d.ts +0 -201
  124. package/packages/@monomind/cli/dist/src/services/worker-queue.js +0 -594
  125. package/packages/@monomind/cli/dist/src/swarm/communication-graph.d.ts +0 -25
  126. package/packages/@monomind/cli/dist/src/swarm/communication-graph.js +0 -77
  127. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.d.ts +0 -31
  128. package/packages/@monomind/cli/dist/src/swarm/flow-enforcer.js +0 -61
  129. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.d.ts +0 -19
  130. package/packages/@monomind/cli/dist/src/swarm/flow-visualizer.js +0 -68
  131. package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.d.ts +0 -13
  132. package/packages/@monomind/cli/dist/src/transfer/deploy-seraphine.js +0 -205
  133. package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.d.ts +0 -12
  134. package/packages/@monomind/cli/dist/src/transfer/store/tests/standalone-test.js +0 -190
  135. package/packages/@monomind/cli/dist/src/transfer/test-seraphine.d.ts +0 -6
  136. package/packages/@monomind/cli/dist/src/transfer/test-seraphine.js +0 -105
  137. package/packages/@monomind/cli/dist/src/transfer/tests/test-store.d.ts +0 -7
  138. package/packages/@monomind/cli/dist/src/transfer/tests/test-store.js +0 -214
  139. package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.d.ts +0 -10
  140. package/packages/@monomind/cli/dist/src/workflow/condition-evaluator.js +0 -82
  141. package/packages/@monomind/cli/dist/src/workflow/context-resolver.d.ts +0 -12
  142. package/packages/@monomind/cli/dist/src/workflow/context-resolver.js +0 -23
  143. package/packages/@monomind/cli/dist/src/workflow/dag-builder.d.ts +0 -17
  144. package/packages/@monomind/cli/dist/src/workflow/dag-builder.js +0 -129
  145. package/packages/@monomind/cli/dist/src/workflow/dag-executor.d.ts +0 -9
  146. package/packages/@monomind/cli/dist/src/workflow/dag-executor.js +0 -116
  147. package/packages/@monomind/cli/dist/src/workflow/dag-types.d.ts +0 -41
  148. package/packages/@monomind/cli/dist/src/workflow/dag-types.js +0 -8
  149. package/packages/@monomind/cli/dist/src/workflow/dsl-parser.d.ts +0 -12
  150. package/packages/@monomind/cli/dist/src/workflow/dsl-parser.js +0 -20
  151. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.d.ts +0 -165
  152. package/packages/@monomind/cli/dist/src/workflow/dsl-schema.js +0 -82
  153. package/packages/@monomind/cli/dist/src/workflow/index.d.ts +0 -13
  154. package/packages/@monomind/cli/dist/src/workflow/index.js +0 -11
  155. package/packages/@monomind/cli/dist/src/workflow/template-engine.d.ts +0 -11
  156. package/packages/@monomind/cli/dist/src/workflow/template-engine.js +0 -40
  157. package/packages/@monomind/cli/dist/src/workflow/workflow-executor.d.ts +0 -29
  158. package/packages/@monomind/cli/dist/src/workflow/workflow-executor.js +0 -227
  159. package/packages/@monomind/guidance/dist/adversarial.d.ts +0 -284
  160. package/packages/@monomind/guidance/dist/adversarial.js +0 -572
  161. package/packages/@monomind/guidance/dist/analyzer.d.ts +0 -530
  162. package/packages/@monomind/guidance/dist/analyzer.js +0 -2518
  163. package/packages/@monomind/guidance/dist/artifacts.d.ts +0 -283
  164. package/packages/@monomind/guidance/dist/artifacts.js +0 -356
  165. package/packages/@monomind/guidance/dist/authority.d.ts +0 -290
  166. package/packages/@monomind/guidance/dist/authority.js +0 -558
  167. package/packages/@monomind/guidance/dist/capabilities.d.ts +0 -209
  168. package/packages/@monomind/guidance/dist/capabilities.js +0 -485
  169. package/packages/@monomind/guidance/dist/coherence.d.ts +0 -233
  170. package/packages/@monomind/guidance/dist/coherence.js +0 -372
  171. package/packages/@monomind/guidance/dist/compiler.d.ts +0 -87
  172. package/packages/@monomind/guidance/dist/compiler.js +0 -419
  173. package/packages/@monomind/guidance/dist/conformance-kit.d.ts +0 -225
  174. package/packages/@monomind/guidance/dist/conformance-kit.js +0 -629
  175. package/packages/@monomind/guidance/dist/continue-gate.d.ts +0 -214
  176. package/packages/@monomind/guidance/dist/continue-gate.js +0 -353
  177. package/packages/@monomind/guidance/dist/crypto-utils.d.ts +0 -17
  178. package/packages/@monomind/guidance/dist/crypto-utils.js +0 -24
  179. package/packages/@monomind/guidance/dist/evolution.d.ts +0 -282
  180. package/packages/@monomind/guidance/dist/evolution.js +0 -500
  181. package/packages/@monomind/guidance/dist/gates.d.ts +0 -79
  182. package/packages/@monomind/guidance/dist/gates.js +0 -302
  183. package/packages/@monomind/guidance/dist/gateway.d.ts +0 -206
  184. package/packages/@monomind/guidance/dist/gateway.js +0 -452
  185. package/packages/@monomind/guidance/dist/generators.d.ts +0 -153
  186. package/packages/@monomind/guidance/dist/generators.js +0 -682
  187. package/packages/@monomind/guidance/dist/headless.d.ts +0 -177
  188. package/packages/@monomind/guidance/dist/headless.js +0 -342
  189. package/packages/@monomind/guidance/dist/hooks.d.ts +0 -109
  190. package/packages/@monomind/guidance/dist/hooks.js +0 -347
  191. package/packages/@monomind/guidance/dist/index.d.ts +0 -205
  192. package/packages/@monomind/guidance/dist/index.js +0 -321
  193. package/packages/@monomind/guidance/dist/ledger.d.ts +0 -162
  194. package/packages/@monomind/guidance/dist/ledger.js +0 -375
  195. package/packages/@monomind/guidance/dist/manifest-validator.d.ts +0 -289
  196. package/packages/@monomind/guidance/dist/manifest-validator.js +0 -838
  197. package/packages/@monomind/guidance/dist/memory-gate.d.ts +0 -222
  198. package/packages/@monomind/guidance/dist/memory-gate.js +0 -382
  199. package/packages/@monomind/guidance/dist/meta-governance.d.ts +0 -265
  200. package/packages/@monomind/guidance/dist/meta-governance.js +0 -348
  201. package/packages/@monomind/guidance/dist/optimizer.d.ts +0 -104
  202. package/packages/@monomind/guidance/dist/optimizer.js +0 -329
  203. package/packages/@monomind/guidance/dist/persistence.d.ts +0 -189
  204. package/packages/@monomind/guidance/dist/persistence.js +0 -464
  205. package/packages/@monomind/guidance/dist/proof.d.ts +0 -185
  206. package/packages/@monomind/guidance/dist/proof.js +0 -238
  207. package/packages/@monomind/guidance/dist/retriever.d.ts +0 -116
  208. package/packages/@monomind/guidance/dist/retriever.js +0 -394
  209. package/packages/@monomind/guidance/dist/ruvbot-integration.d.ts +0 -370
  210. package/packages/@monomind/guidance/dist/ruvbot-integration.js +0 -738
  211. package/packages/@monomind/guidance/dist/temporal.d.ts +0 -426
  212. package/packages/@monomind/guidance/dist/temporal.js +0 -658
  213. package/packages/@monomind/guidance/dist/trust.d.ts +0 -283
  214. package/packages/@monomind/guidance/dist/trust.js +0 -473
  215. package/packages/@monomind/guidance/dist/truth-anchors.d.ts +0 -276
  216. package/packages/@monomind/guidance/dist/truth-anchors.js +0 -488
  217. package/packages/@monomind/guidance/dist/types.d.ts +0 -378
  218. package/packages/@monomind/guidance/dist/types.js +0 -10
  219. package/packages/@monomind/guidance/dist/uncertainty.d.ts +0 -372
  220. package/packages/@monomind/guidance/dist/uncertainty.js +0 -619
  221. package/packages/@monomind/guidance/dist/wasm-kernel.d.ts +0 -48
  222. package/packages/@monomind/guidance/dist/wasm-kernel.js +0 -158
@@ -1,623 +0,0 @@
1
- /**
2
- * Container Worker Pool
3
- * Docker-based worker pool for high-throughput headless execution.
4
- *
5
- * ADR-020: Headless Worker Integration Architecture - Phase 3
6
- * - Manages pool of Docker containers for isolated worker execution
7
- * - Supports dynamic scaling based on workload
8
- * - Provides container lifecycle management
9
- * - Integrates with WorkerQueue for task distribution
10
- *
11
- * Key Features:
12
- * - Container pooling with configurable size
13
- * - Health checking and auto-recovery
14
- * - Resource limits (CPU, memory)
15
- * - Volume mounting for workspace access
16
- * - Network isolation per worker type
17
- */
18
- import { EventEmitter } from 'events';
19
- import { spawn, exec, execFile } from 'child_process';
20
- import { promisify } from 'util';
21
- import { existsSync, mkdirSync } from 'fs';
22
- import { join } from 'path';
23
- const execAsync = promisify(exec);
24
- const execFileAsync = promisify(execFile);
25
- /** Allowlist: registry/name:tag with optional digest — no shell metacharacters */
26
- const DOCKER_IMAGE_RE = /^[a-zA-Z0-9][a-zA-Z0-9.\-_/:@]*$/;
27
- function validateDockerImage(image) {
28
- if (!DOCKER_IMAGE_RE.test(image)) {
29
- throw new Error(`Invalid Docker image name: "${image}"`);
30
- }
31
- }
32
- // ============================================
33
- // Constants
34
- // ============================================
35
- const DEFAULT_CONFIG = {
36
- maxContainers: 3,
37
- minContainers: 1,
38
- image: 'ghcr.io/nokhodian/monomind-headless:latest',
39
- resources: {
40
- cpus: '2',
41
- memory: '4g',
42
- },
43
- healthCheckIntervalMs: 30000,
44
- idleTimeoutMs: 300000, // 5 minutes
45
- workspacePath: '/workspace',
46
- statePath: '.monomind/container-pool',
47
- defaultSandbox: 'strict',
48
- };
49
- // ============================================
50
- // ContainerWorkerPool Class
51
- // ============================================
52
- /**
53
- * ContainerWorkerPool - Manages Docker containers for headless worker execution
54
- */
55
- export class ContainerWorkerPool extends EventEmitter {
56
- config;
57
- projectRoot;
58
- containers = new Map();
59
- taskQueue = [];
60
- healthCheckTimer;
61
- idleCheckTimer;
62
- dockerAvailable = null;
63
- initialized = false;
64
- isShuttingDown = false;
65
- exitHandlersRegistered = false;
66
- constructor(projectRoot, config) {
67
- super();
68
- this.projectRoot = projectRoot;
69
- this.config = { ...DEFAULT_CONFIG, ...config };
70
- // Ensure state directory exists
71
- const stateDir = join(projectRoot, this.config.statePath);
72
- if (!existsSync(stateDir)) {
73
- mkdirSync(stateDir, { recursive: true });
74
- }
75
- }
76
- // ============================================
77
- // Public API
78
- // ============================================
79
- /**
80
- * Initialize the container pool
81
- */
82
- async initialize() {
83
- if (this.initialized) {
84
- return true;
85
- }
86
- // Check Docker availability
87
- this.dockerAvailable = await this.checkDockerAvailable();
88
- if (!this.dockerAvailable) {
89
- this.emit('warning', { message: 'Docker not available - container pool disabled' });
90
- return false;
91
- }
92
- // Pull image if needed
93
- await this.ensureImage();
94
- // Create minimum containers
95
- await this.scaleToMinimum();
96
- // Start health check timer
97
- this.startHealthChecks();
98
- // Start idle check timer
99
- this.startIdleChecks();
100
- // Register exit handlers for cleanup
101
- this.registerExitHandlers();
102
- this.initialized = true;
103
- this.emit('initialized', { containers: this.containers.size });
104
- return true;
105
- }
106
- /**
107
- * Register process exit handlers to clean up containers
108
- */
109
- registerExitHandlers() {
110
- if (this.exitHandlersRegistered)
111
- return;
112
- const cleanup = async () => {
113
- if (!this.isShuttingDown) {
114
- await this.shutdown();
115
- }
116
- };
117
- process.once('SIGTERM', cleanup);
118
- process.once('SIGINT', cleanup);
119
- process.once('beforeExit', cleanup);
120
- this.exitHandlersRegistered = true;
121
- }
122
- /**
123
- * Execute a worker in a container
124
- */
125
- async execute(options) {
126
- if (!this.initialized) {
127
- await this.initialize();
128
- }
129
- if (!this.dockerAvailable) {
130
- return this.createErrorResult(options.workerType, 'Docker not available');
131
- }
132
- // Try to get a ready container
133
- const container = this.getReadyContainer();
134
- if (container) {
135
- return this.executeInContainer(container, options);
136
- }
137
- // No ready containers - check if we can create more
138
- if (this.containers.size < this.config.maxContainers) {
139
- const newContainer = await this.createContainer();
140
- if (newContainer) {
141
- return this.executeInContainer(newContainer, options);
142
- }
143
- }
144
- // Queue the task
145
- const MAX_TASK_QUEUE = 500;
146
- if (this.taskQueue.length >= MAX_TASK_QUEUE) {
147
- return this.createErrorResult(options.workerType, 'Task queue is full');
148
- }
149
- return new Promise((resolve, reject) => {
150
- this.taskQueue.push({
151
- options,
152
- resolve,
153
- reject,
154
- queuedAt: new Date(),
155
- });
156
- this.emit('taskQueued', {
157
- workerType: options.workerType,
158
- queuePosition: this.taskQueue.length,
159
- });
160
- });
161
- }
162
- /**
163
- * Scale pool for batch execution
164
- */
165
- async scaleForBatch(workerCount) {
166
- const targetSize = Math.min(workerCount, this.config.maxContainers);
167
- const currentSize = this.containers.size;
168
- if (targetSize > currentSize) {
169
- const toCreate = targetSize - currentSize;
170
- const createPromises = [];
171
- for (let i = 0; i < toCreate; i++) {
172
- createPromises.push(this.createContainer());
173
- }
174
- await Promise.all(createPromises);
175
- this.emit('scaled', { from: currentSize, to: this.containers.size });
176
- }
177
- }
178
- /**
179
- * Get pool status
180
- */
181
- getStatus() {
182
- const containers = Array.from(this.containers.values());
183
- return {
184
- totalContainers: containers.length,
185
- readyContainers: containers.filter(c => c.state === 'ready').length,
186
- busyContainers: containers.filter(c => c.state === 'busy').length,
187
- unhealthyContainers: containers.filter(c => c.state === 'unhealthy').length,
188
- queuedTasks: this.taskQueue.length,
189
- containers,
190
- dockerAvailable: this.dockerAvailable ?? false,
191
- lastHealthCheck: undefined, // Will be set by health check
192
- };
193
- }
194
- /**
195
- * Shutdown the pool
196
- */
197
- async shutdown() {
198
- if (this.isShuttingDown)
199
- return;
200
- this.isShuttingDown = true;
201
- // Stop timers
202
- if (this.healthCheckTimer) {
203
- clearInterval(this.healthCheckTimer);
204
- this.healthCheckTimer = undefined;
205
- }
206
- if (this.idleCheckTimer) {
207
- clearInterval(this.idleCheckTimer);
208
- this.idleCheckTimer = undefined;
209
- }
210
- // Reject queued tasks
211
- for (const task of this.taskQueue) {
212
- task.reject(new Error('Pool shutting down'));
213
- }
214
- this.taskQueue = [];
215
- // Terminate all containers with timeout
216
- const terminatePromises = [];
217
- for (const [id] of this.containers) {
218
- terminatePromises.push(this.terminateContainer(id).catch(() => {
219
- // Ignore errors during shutdown
220
- }));
221
- }
222
- // Wait for all containers with 30s timeout
223
- await Promise.race([
224
- Promise.all(terminatePromises),
225
- new Promise(resolve => setTimeout(resolve, 30000)),
226
- ]);
227
- this.initialized = false;
228
- this.emit('shutdown', {});
229
- }
230
- // ============================================
231
- // Private Methods - Container Lifecycle
232
- // ============================================
233
- /**
234
- * Check if Docker is available (async)
235
- */
236
- async checkDockerAvailable() {
237
- try {
238
- await execAsync('docker --version', { timeout: 5000 });
239
- await execAsync('docker info', { timeout: 10000 });
240
- return true;
241
- }
242
- catch {
243
- return false;
244
- }
245
- }
246
- /**
247
- * Ensure the container image exists (async)
248
- */
249
- async ensureImage() {
250
- try {
251
- validateDockerImage(this.config.image);
252
- await execFileAsync('docker', ['image', 'inspect', this.config.image], { timeout: 10000 });
253
- }
254
- catch {
255
- // Image not found, try to pull
256
- this.emit('imagePull', { image: this.config.image });
257
- try {
258
- await execFileAsync('docker', ['pull', this.config.image], { timeout: 300000 });
259
- }
260
- catch (error) {
261
- this.emit('warning', { message: `Failed to pull image: ${error}` });
262
- // Continue anyway - might work with local image
263
- }
264
- }
265
- }
266
- /**
267
- * Create a new container
268
- */
269
- async createContainer() {
270
- const id = `cf-worker-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
271
- const name = `monomind-worker-${id}`;
272
- const containerInfo = {
273
- id,
274
- name,
275
- state: 'creating',
276
- createdAt: new Date(),
277
- executionCount: 0,
278
- healthCheckFailures: 0,
279
- };
280
- this.containers.set(id, containerInfo);
281
- this.emit('containerCreating', { id, name });
282
- try {
283
- // Build docker run command with hardening flags.
284
- // Without these flags the container ran with default capabilities and
285
- // privilege escalation enabled — combined with a writable host mount
286
- // that is JSON-parsed by the daemon, this was a container-to-host RCE
287
- // chain (claims.json/daemon-state.json could be rewritten from inside).
288
- const stateMount = join(this.projectRoot, this.config.statePath);
289
- const args = [
290
- 'run', '-d',
291
- '--name', name,
292
- // Resource limits
293
- '--cpus', this.config.resources.cpus,
294
- '--memory', this.config.resources.memory,
295
- '--pids-limit', '256',
296
- // Privilege & capability hardening
297
- '--security-opt', 'no-new-privileges:true',
298
- '--cap-drop', 'ALL',
299
- '--user', '1000:1000',
300
- '--ipc', 'none',
301
- // Mounts: workspace read-only, state read-only by default with a
302
- // narrow rw output channel for the worker to write back results.
303
- '-v', `${this.projectRoot}:${this.config.workspacePath}:ro`,
304
- '-v', `${stateMount}:/root/.monomind:ro`,
305
- '-v', `${join(stateMount, 'output')}:/output:rw`,
306
- // tmpfs for /tmp without exec
307
- '--tmpfs', '/tmp:rw,noexec,nosuid,size=64m',
308
- '-w', this.config.workspacePath,
309
- ];
310
- // Add environment variables.
311
- // SECURITY: ANTHROPIC_API_KEY is intentionally NOT injected via -e here.
312
- // Visible via `docker inspect` and process listings on the host, and
313
- // exfiltrable by indirect prompt injection via process.env. Containers
314
- // that need API access must use a host-side proxy. Set
315
- // MONOMIND_CONTAINER_PASS_ANTHROPIC_KEY=1 to opt back in for trusted
316
- // single-tenant deployments.
317
- const env = {
318
- ...this.config.env,
319
- CLAUDE_CODE_HEADLESS: 'true',
320
- CLAUDE_CODE_SANDBOX_MODE: this.config.defaultSandbox,
321
- };
322
- if (process.env.MONOMIND_CONTAINER_PASS_ANTHROPIC_KEY === '1' && process.env.ANTHROPIC_API_KEY) {
323
- env.ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
324
- }
325
- for (const [key, value] of Object.entries(env)) {
326
- if (value) {
327
- args.push('-e', `${key}=${value}`);
328
- }
329
- }
330
- // Add network if specified
331
- if (this.config.network) {
332
- args.push('--network', this.config.network);
333
- }
334
- // Add image and entrypoint to keep container running
335
- args.push(this.config.image, 'tail', '-f', '/dev/null');
336
- // Create the container (async)
337
- const { stdout } = await execFileAsync('docker', args, { timeout: 60000 });
338
- const containerId = stdout.trim();
339
- containerInfo.state = 'ready';
340
- this.emit('containerCreated', { id, name, containerId });
341
- return containerInfo;
342
- }
343
- catch (error) {
344
- this.containers.delete(id);
345
- this.emit('containerError', { id, error: String(error) });
346
- return null;
347
- }
348
- }
349
- /**
350
- * Terminate a container (async)
351
- */
352
- async terminateContainer(id) {
353
- const container = this.containers.get(id);
354
- if (!container)
355
- return;
356
- container.state = 'terminated';
357
- try {
358
- await execFileAsync('docker', ['rm', '-f', container.name], { timeout: 30000 });
359
- }
360
- catch {
361
- // Ignore removal errors
362
- }
363
- this.containers.delete(id);
364
- this.emit('containerTerminated', { id, name: container.name });
365
- }
366
- /**
367
- * Get a ready container
368
- */
369
- getReadyContainer() {
370
- for (const container of this.containers.values()) {
371
- if (container.state === 'ready') {
372
- return container;
373
- }
374
- }
375
- return null;
376
- }
377
- /**
378
- * Scale to minimum containers
379
- */
380
- async scaleToMinimum() {
381
- const current = this.containers.size;
382
- const needed = this.config.minContainers - current;
383
- if (needed > 0) {
384
- const createPromises = [];
385
- for (let i = 0; i < needed; i++) {
386
- createPromises.push(this.createContainer());
387
- }
388
- await Promise.all(createPromises);
389
- }
390
- }
391
- // ============================================
392
- // Private Methods - Execution
393
- // ============================================
394
- /**
395
- * Execute worker in a specific container
396
- */
397
- async executeInContainer(container, options) {
398
- const startTime = Date.now();
399
- const executionId = `${options.workerType}_${startTime}_${Math.random().toString(36).slice(2, 8)}`;
400
- container.state = 'busy';
401
- container.workerType = options.workerType;
402
- container.lastUsedAt = new Date();
403
- this.emit('executionStart', { executionId, containerId: container.id, workerType: options.workerType });
404
- try {
405
- // Build the command to run inside container
406
- const command = this.buildWorkerCommand(options);
407
- // Execute in container with timeout
408
- const timeoutMs = options.timeoutMs || 300000;
409
- const output = await this.execInContainer(container.name, command, timeoutMs);
410
- container.state = 'ready';
411
- container.executionCount++;
412
- const result = {
413
- success: true,
414
- output: output,
415
- parsedOutput: this.tryParseJson(output),
416
- durationMs: Date.now() - startTime,
417
- model: options.model || 'sonnet',
418
- sandboxMode: options.sandbox || this.config.defaultSandbox,
419
- workerType: options.workerType,
420
- timestamp: new Date(),
421
- executionId,
422
- };
423
- this.emit('executionComplete', result);
424
- // Process queue
425
- this.processQueue();
426
- return result;
427
- }
428
- catch (error) {
429
- container.state = 'ready';
430
- const result = this.createErrorResult(options.workerType, error instanceof Error ? error.message : String(error));
431
- result.executionId = executionId;
432
- result.durationMs = Date.now() - startTime;
433
- this.emit('executionError', result);
434
- // Process queue
435
- this.processQueue();
436
- return result;
437
- }
438
- }
439
- /**
440
- * Execute command in container
441
- */
442
- async execInContainer(containerName, command, timeoutMs) {
443
- return new Promise((resolve, reject) => {
444
- const args = ['exec', containerName, ...command];
445
- const child = spawn('docker', args, {
446
- stdio: ['pipe', 'pipe', 'pipe'],
447
- });
448
- let stdout = '';
449
- let stderr = '';
450
- let timedOut = false;
451
- let exited = false;
452
- child.once('exit', () => { exited = true; });
453
- const timeout = setTimeout(() => {
454
- timedOut = true;
455
- child.kill('SIGTERM');
456
- setTimeout(() => {
457
- if (!exited) {
458
- child.kill('SIGKILL');
459
- }
460
- }, 5000);
461
- }, timeoutMs);
462
- child.stdout?.on('data', (data) => {
463
- stdout += data.toString();
464
- });
465
- child.stderr?.on('data', (data) => {
466
- stderr += data.toString();
467
- });
468
- child.on('close', (code) => {
469
- clearTimeout(timeout);
470
- if (timedOut) {
471
- reject(new Error(`Execution timed out after ${timeoutMs}ms`));
472
- return;
473
- }
474
- if (code !== 0) {
475
- reject(new Error(stderr || `Process exited with code ${code}`));
476
- return;
477
- }
478
- resolve(stdout);
479
- });
480
- child.on('error', (error) => {
481
- clearTimeout(timeout);
482
- reject(error);
483
- });
484
- });
485
- }
486
- /**
487
- * Build worker command for container execution
488
- */
489
- buildWorkerCommand(options) {
490
- // Use npx to run monomind daemon trigger
491
- return [
492
- 'npx', 'monomind@latest',
493
- 'daemon', 'trigger',
494
- '-w', options.workerType,
495
- '--headless',
496
- ];
497
- }
498
- /**
499
- * Process queued tasks
500
- */
501
- processQueue() {
502
- while (this.taskQueue.length > 0) {
503
- const container = this.getReadyContainer();
504
- if (!container)
505
- break;
506
- const task = this.taskQueue.shift();
507
- if (task) {
508
- this.executeInContainer(container, task.options)
509
- .then(task.resolve)
510
- .catch(task.reject);
511
- }
512
- }
513
- }
514
- // ============================================
515
- // Private Methods - Health & Maintenance
516
- // ============================================
517
- /**
518
- * Start health check timer
519
- */
520
- startHealthChecks() {
521
- this.healthCheckTimer = setInterval(async () => {
522
- await this.runHealthChecks();
523
- }, this.config.healthCheckIntervalMs);
524
- this.healthCheckTimer.unref();
525
- }
526
- /**
527
- * Run health checks on all containers
528
- */
529
- async runHealthChecks() {
530
- for (const [id, container] of this.containers) {
531
- if (container.state === 'terminated')
532
- continue;
533
- try {
534
- // Check if container is running (async)
535
- const { stdout } = await execFileAsync('docker', ['inspect', '-f', '{{.State.Running}}', container.name], { timeout: 10000 });
536
- const output = stdout.trim();
537
- if (output !== 'true') {
538
- container.healthCheckFailures++;
539
- if (container.healthCheckFailures >= 3) {
540
- container.state = 'unhealthy';
541
- this.emit('containerUnhealthy', { id, name: container.name });
542
- // Remove and replace
543
- await this.terminateContainer(id);
544
- if (this.containers.size < this.config.minContainers) {
545
- await this.createContainer();
546
- }
547
- }
548
- }
549
- else {
550
- container.healthCheckFailures = 0;
551
- }
552
- }
553
- catch {
554
- container.healthCheckFailures++;
555
- }
556
- }
557
- this.emit('healthCheckComplete', { containers: this.containers.size });
558
- }
559
- /**
560
- * Start idle check timer
561
- */
562
- startIdleChecks() {
563
- this.idleCheckTimer = setInterval(async () => {
564
- await this.runIdleChecks();
565
- }, 60000); // Check every minute
566
- this.idleCheckTimer.unref();
567
- }
568
- /**
569
- * Terminate idle containers above minimum
570
- */
571
- async runIdleChecks() {
572
- const now = Date.now();
573
- const readyContainers = Array.from(this.containers.values())
574
- .filter(c => c.state === 'ready')
575
- .sort((a, b) => (a.lastUsedAt?.getTime() || 0) - (b.lastUsedAt?.getTime() || 0));
576
- // Keep minimum containers
577
- const toTerminate = readyContainers.slice(this.config.minContainers);
578
- for (const container of toTerminate) {
579
- const lastUsed = container.lastUsedAt?.getTime() || container.createdAt.getTime();
580
- if (now - lastUsed > this.config.idleTimeoutMs) {
581
- await this.terminateContainer(container.id);
582
- this.emit('containerIdleTerminated', { id: container.id, name: container.name });
583
- }
584
- }
585
- }
586
- // ============================================
587
- // Private Methods - Utilities
588
- // ============================================
589
- /**
590
- * Try to parse JSON from output
591
- */
592
- tryParseJson(output) {
593
- try {
594
- const jsonMatch = output.match(/\{[\s\S]*\}/);
595
- if (jsonMatch) {
596
- return JSON.parse(jsonMatch[0]);
597
- }
598
- return JSON.parse(output.trim());
599
- }
600
- catch {
601
- return undefined;
602
- }
603
- }
604
- /**
605
- * Create an error result
606
- */
607
- createErrorResult(workerType, error) {
608
- return {
609
- success: false,
610
- output: '',
611
- durationMs: 0,
612
- model: 'unknown',
613
- sandboxMode: this.config.defaultSandbox,
614
- workerType,
615
- timestamp: new Date(),
616
- executionId: `error_${Date.now()}`,
617
- error,
618
- };
619
- }
620
- }
621
- // Export default
622
- export default ContainerWorkerPool;
623
- //# sourceMappingURL=container-worker-pool.js.map
@@ -1,13 +0,0 @@
1
- /**
2
- * CLI Services Index
3
- * Central registry for all background services
4
- */
5
- export { WorkerDaemon, getDaemon, startDaemon, stopDaemon, type WorkerType, } from './worker-daemon.js';
6
- export { HeadlessWorkerExecutor, HEADLESS_WORKER_TYPES, HEADLESS_WORKER_CONFIGS, LOCAL_WORKER_TYPES, LOCAL_WORKER_CONFIGS, ALL_WORKER_CONFIGS, isHeadlessWorker, isLocalWorker, getModelId, getWorkerConfig, type HeadlessWorkerType, type LocalWorkerType, type HeadlessWorkerConfig, type HeadlessExecutionResult, type HeadlessExecutorConfig, type HeadlessOptions, type PoolStatus, type SandboxMode, type ModelType, type OutputFormat, type ExecutionMode, type WorkerPriority, type WorkerConfig, } from './headless-worker-executor.js';
7
- export { ContainerWorkerPool, type ContainerInfo, type ContainerPoolConfig, type ContainerExecutionOptions, type ContainerPoolStatus, type ContainerState, } from './container-worker-pool.js';
8
- export { WorkerQueue, type QueueTask, type WorkerQueueConfig, type QueueStats, type WorkerRegistration, type TaskStatus, } from './worker-queue.js';
9
- export type { default as WorkerDaemonType, DaemonConfig } from './worker-daemon.js';
10
- export type { default as HeadlessWorkerExecutorType } from './headless-worker-executor.js';
11
- export type { default as ContainerWorkerPoolType } from './container-worker-pool.js';
12
- export type { default as WorkerQueueType } from './worker-queue.js';
13
- //# sourceMappingURL=index.d.ts.map
@@ -1,11 +0,0 @@
1
- /**
2
- * CLI Services Index
3
- * Central registry for all background services
4
- */
5
- export { WorkerDaemon, getDaemon, startDaemon, stopDaemon, } from './worker-daemon.js';
6
- export { HeadlessWorkerExecutor, HEADLESS_WORKER_TYPES, HEADLESS_WORKER_CONFIGS, LOCAL_WORKER_TYPES, LOCAL_WORKER_CONFIGS, ALL_WORKER_CONFIGS, isHeadlessWorker, isLocalWorker, getModelId, getWorkerConfig, } from './headless-worker-executor.js';
7
- // Container Worker Pool (Phase 3)
8
- export { ContainerWorkerPool, } from './container-worker-pool.js';
9
- // Worker Queue (Phase 4)
10
- export { WorkerQueue, } from './worker-queue.js';
11
- //# sourceMappingURL=index.js.map