@covibes/zeroshot 5.3.0 → 5.4.1

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 (119) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +8 -385
  3. package/cli/index.js +108 -4615
  4. package/package.json +16 -125
  5. package/CHANGELOG.md +0 -537
  6. package/cli/commands/providers.js +0 -150
  7. package/cli/lib/first-run.js +0 -211
  8. package/cli/lib/update-checker.js +0 -281
  9. package/cli/message-formatter-utils.js +0 -75
  10. package/cli/message-formatters-normal.js +0 -253
  11. package/cli/message-formatters-watch.js +0 -181
  12. package/cluster-templates/base-templates/debug-workflow.json +0 -375
  13. package/cluster-templates/base-templates/full-workflow.json +0 -697
  14. package/cluster-templates/base-templates/single-worker.json +0 -63
  15. package/cluster-templates/base-templates/worker-validator.json +0 -152
  16. package/cluster-templates/conductor-bootstrap.json +0 -124
  17. package/docker/zeroshot-cluster/Dockerfile +0 -152
  18. package/docker/zeroshot-cluster/pre-baked-deps.json +0 -28
  19. package/lib/completion.js +0 -174
  20. package/lib/docker-config.js +0 -212
  21. package/lib/id-detector.js +0 -53
  22. package/lib/provider-detection.js +0 -59
  23. package/lib/provider-names.js +0 -56
  24. package/lib/settings.js +0 -405
  25. package/lib/stream-json-parser.js +0 -10
  26. package/scripts/fix-node-pty-permissions.js +0 -75
  27. package/scripts/record-demo.sh +0 -279
  28. package/scripts/test-install.sh +0 -40
  29. package/scripts/validate-templates.js +0 -100
  30. package/src/agent/agent-config.js +0 -193
  31. package/src/agent/agent-context-builder.js +0 -335
  32. package/src/agent/agent-hook-executor.js +0 -402
  33. package/src/agent/agent-lifecycle.js +0 -683
  34. package/src/agent/agent-stuck-detector.js +0 -256
  35. package/src/agent/agent-task-executor.js +0 -1431
  36. package/src/agent/agent-trigger-evaluator.js +0 -67
  37. package/src/agent/output-extraction.js +0 -200
  38. package/src/agent/output-reformatter.js +0 -175
  39. package/src/agent/schema-utils.js +0 -111
  40. package/src/agent-wrapper.js +0 -570
  41. package/src/agents/git-pusher-agent.json +0 -20
  42. package/src/attach/attach-client.js +0 -438
  43. package/src/attach/attach-server.js +0 -543
  44. package/src/attach/index.js +0 -35
  45. package/src/attach/protocol.js +0 -220
  46. package/src/attach/ring-buffer.js +0 -121
  47. package/src/attach/socket-discovery.js +0 -267
  48. package/src/claude-task-runner.js +0 -523
  49. package/src/config-router.js +0 -80
  50. package/src/config-validator.js +0 -1660
  51. package/src/copy-worker.js +0 -43
  52. package/src/github.js +0 -139
  53. package/src/isolation-manager.js +0 -1381
  54. package/src/ledger.js +0 -614
  55. package/src/logic-engine.js +0 -223
  56. package/src/message-bus-bridge.js +0 -139
  57. package/src/message-bus.js +0 -249
  58. package/src/name-generator.js +0 -232
  59. package/src/orchestrator.js +0 -2519
  60. package/src/preflight.js +0 -485
  61. package/src/process-metrics.js +0 -566
  62. package/src/providers/anthropic/cli-builder.js +0 -45
  63. package/src/providers/anthropic/index.js +0 -134
  64. package/src/providers/anthropic/models.js +0 -23
  65. package/src/providers/anthropic/output-parser.js +0 -159
  66. package/src/providers/base-provider.js +0 -181
  67. package/src/providers/capabilities.js +0 -51
  68. package/src/providers/google/cli-builder.js +0 -55
  69. package/src/providers/google/index.js +0 -116
  70. package/src/providers/google/models.js +0 -24
  71. package/src/providers/google/output-parser.js +0 -92
  72. package/src/providers/index.js +0 -75
  73. package/src/providers/openai/cli-builder.js +0 -122
  74. package/src/providers/openai/index.js +0 -135
  75. package/src/providers/openai/models.js +0 -21
  76. package/src/providers/openai/output-parser.js +0 -129
  77. package/src/schemas/sub-cluster.js +0 -156
  78. package/src/status-footer.js +0 -980
  79. package/src/sub-cluster-wrapper.js +0 -560
  80. package/src/task-runner.js +0 -30
  81. package/src/template-resolver.js +0 -369
  82. package/src/tui/CHANGES.txt +0 -133
  83. package/src/tui/LAYOUT.md +0 -261
  84. package/src/tui/README.txt +0 -192
  85. package/src/tui/TWO-LEVEL-NAVIGATION.md +0 -186
  86. package/src/tui/data-poller.js +0 -325
  87. package/src/tui/demo.js +0 -208
  88. package/src/tui/formatters.js +0 -128
  89. package/src/tui/index.js +0 -193
  90. package/src/tui/keybindings.js +0 -383
  91. package/src/tui/layout.js +0 -334
  92. package/src/tui/renderer.js +0 -194
  93. package/task-lib/attachable-watcher.js +0 -272
  94. package/task-lib/claude-recovery.js +0 -119
  95. package/task-lib/commands/clean.js +0 -50
  96. package/task-lib/commands/get-log-path.js +0 -23
  97. package/task-lib/commands/kill.js +0 -32
  98. package/task-lib/commands/list.js +0 -105
  99. package/task-lib/commands/logs.js +0 -411
  100. package/task-lib/commands/resume.js +0 -42
  101. package/task-lib/commands/run.js +0 -57
  102. package/task-lib/commands/schedule.js +0 -105
  103. package/task-lib/commands/scheduler-cmd.js +0 -96
  104. package/task-lib/commands/schedules.js +0 -98
  105. package/task-lib/commands/status.js +0 -44
  106. package/task-lib/commands/unschedule.js +0 -16
  107. package/task-lib/completion.js +0 -9
  108. package/task-lib/config.js +0 -10
  109. package/task-lib/name-generator.js +0 -230
  110. package/task-lib/package.json +0 -3
  111. package/task-lib/runner.js +0 -144
  112. package/task-lib/scheduler.js +0 -252
  113. package/task-lib/store.js +0 -230
  114. package/task-lib/tui/formatters.js +0 -166
  115. package/task-lib/tui/index.js +0 -197
  116. package/task-lib/tui/layout.js +0 -111
  117. package/task-lib/tui/renderer.js +0 -119
  118. package/task-lib/tui.js +0 -384
  119. package/task-lib/watcher.js +0 -188
@@ -1,570 +0,0 @@
1
- // @ts-nocheck
2
- /**
3
- * AgentWrapper - Manages agent lifecycle and claude-zeroshots execution
4
- *
5
- * Provides:
6
- * - Agent state machine (idle -> evaluating -> building context -> executing -> idle)
7
- * - Trigger evaluation via LogicEngine
8
- * - Context building from ledger
9
- * - claude-zeroshots spawning and monitoring
10
- * - Hook execution (onStart, onComplete, onError)
11
- */
12
-
13
- const LogicEngine = require('./logic-engine');
14
- const { validateAgentConfig } = require('./agent/agent-config');
15
- const { loadSettings, validateModelAgainstMax } = require('../lib/settings');
16
- const { normalizeProviderName } = require('../lib/provider-names');
17
- const { getProvider } = require('./providers');
18
- const { buildContext } = require('./agent/agent-context-builder');
19
- const { findMatchingTrigger, evaluateTrigger } = require('./agent/agent-trigger-evaluator');
20
- const { executeHook } = require('./agent/agent-hook-executor');
21
- const {
22
- spawnClaudeTask,
23
- followClaudeTaskLogs,
24
- waitForTaskReady,
25
- spawnClaudeTaskIsolated,
26
- getClaudeTasksPath,
27
- parseResultOutput,
28
- killTask,
29
- } = require('./agent/agent-task-executor');
30
- const {
31
- start: lifecycleStart,
32
- stop: lifecycleStop,
33
- handleMessage: lifecycleHandleMessage,
34
- executeTriggerAction: lifecycleExecuteTriggerAction,
35
- executeTask: lifecycleExecuteTask,
36
- startLivenessCheck: lifecycleStartLivenessCheck,
37
- stopLivenessCheck: lifecycleStopLivenessCheck,
38
- } = require('./agent/agent-lifecycle');
39
-
40
- class AgentWrapper {
41
- /**
42
- * @param {any} config - Agent configuration
43
- * @param {any} messageBus - Message bus instance
44
- * @param {any} cluster - Cluster instance
45
- * @param {any} options - Options
46
- */
47
- constructor(config, messageBus, cluster, options = {}) {
48
- // Validate and normalize configuration
49
- const normalizedConfig = validateAgentConfig(config, options);
50
-
51
- this.id = normalizedConfig.id;
52
- this.role = normalizedConfig.role;
53
- this.modelConfig = normalizedConfig.modelConfig;
54
- this.config = normalizedConfig;
55
- this.messageBus = messageBus;
56
- this.cluster = cluster;
57
- this.logicEngine = new LogicEngine(messageBus, cluster);
58
-
59
- this.state = 'idle';
60
- this.iteration = 0;
61
- this.maxIterations = normalizedConfig.maxIterations;
62
- this.timeout = normalizedConfig.timeout;
63
- /** @type {any} */
64
- this.currentTask = null;
65
- /** @type {string | null} */
66
- this.currentTaskId = null; // Track spawned task ID for resume capability
67
- /** @type {number | null} */
68
- this.processPid = null; // Track process PID for resource monitoring
69
- this.running = false;
70
- /** @type {Function | null} */
71
- this.unsubscribe = null;
72
- /** @type {number | null} */
73
- this.lastTaskEndTime = null; // Track when last task completed (for context filtering)
74
-
75
- // LIVENESS DETECTION - Track output freshness to detect stuck agents
76
- /** @type {number | null} */
77
- this.lastOutputTime = null; // Timestamp of last output received
78
- /** @type {NodeJS.Timeout | null} */
79
- this.livenessCheckInterval = null; // Interval for health checks
80
- this.staleDuration = normalizedConfig.staleDuration;
81
- this.enableLivenessCheck = normalizedConfig.enableLivenessCheck;
82
-
83
- // MOCK SUPPORT - Inject mock spawn function for testing
84
- // When set, _spawnClaudeTask uses this instead of real ct CLI
85
- // Priority: options.mockSpawnFn (legacy) > options.taskRunner (new DI pattern)
86
- if (options.mockSpawnFn) {
87
- this.mockSpawnFn = options.mockSpawnFn;
88
- } else if (options.taskRunner) {
89
- // TaskRunner DI - create mockSpawnFn wrapper
90
- const taskRunner = options.taskRunner;
91
- this.mockSpawnFn = (args, { context }) => {
92
- const spec = this._resolveModelSpec();
93
- return taskRunner.run(context, {
94
- agentId: this.id,
95
- model: this._selectModel(),
96
- modelSpec: spec,
97
- provider: this._resolveProvider(),
98
- });
99
- };
100
- } else {
101
- this.mockSpawnFn = null;
102
- }
103
-
104
- this.testMode = options.testMode || false;
105
- this.quiet = options.quiet || false;
106
-
107
- // ISOLATION SUPPORT - Run tasks inside Docker container
108
- this.isolation = options.isolation || null;
109
-
110
- // WORKTREE SUPPORT - Run tasks in git worktree (lightweight isolation without Docker)
111
- this.worktree = options.worktree || null;
112
- }
113
-
114
- /**
115
- * Log message (respects quiet mode)
116
- * @private
117
- */
118
- _log(...args) {
119
- if (!this.quiet) {
120
- console.log(...args);
121
- }
122
- }
123
-
124
- _resolveProvider() {
125
- const settings = loadSettings();
126
- const clusterConfig = this.cluster?.config || {};
127
-
128
- const resolved =
129
- clusterConfig.forceProvider ||
130
- this.config.provider ||
131
- clusterConfig.defaultProvider ||
132
- settings.defaultProvider ||
133
- 'claude';
134
-
135
- return normalizeProviderName(resolved) || 'claude';
136
- }
137
-
138
- _resolveModelSpec() {
139
- const settings = loadSettings();
140
- const providerName = this._resolveProvider();
141
- const provider = getProvider(providerName);
142
- const clusterConfig = this.cluster?.config || {};
143
- const providerSettings = settings.providerSettings?.[providerName] || {};
144
- const levelOverrides = providerSettings.levelOverrides || {};
145
- const minLevel = providerSettings.minLevel;
146
- const maxLevel = providerSettings.maxLevel;
147
- const forcedLevel =
148
- clusterConfig.forceProvider === providerName ? clusterConfig.forceLevel : null;
149
-
150
- const applyReasoningOverride = (spec, override) => {
151
- if (!override) return spec;
152
- return { ...spec, reasoningEffort: override };
153
- };
154
-
155
- if (this.modelConfig.type === 'rules') {
156
- for (const rule of this.modelConfig.rules) {
157
- if (this._matchesIterationRange(rule.iterations)) {
158
- if (rule.model) {
159
- return {
160
- level: 'custom',
161
- model: rule.model,
162
- reasoningEffort: rule.reasoningEffort || this.config.reasoningEffort,
163
- };
164
- }
165
- if (rule.modelLevel) {
166
- const level = provider.validateLevel(rule.modelLevel, minLevel, maxLevel);
167
- const spec = provider.resolveModelSpec(level, levelOverrides);
168
- return applyReasoningOverride(
169
- { ...spec, level },
170
- rule.reasoningEffort || this.config.reasoningEffort
171
- );
172
- }
173
- }
174
- }
175
-
176
- throw new Error(
177
- `Agent ${this.id}: No model rule matched iteration ${this.iteration}. ` +
178
- `Add a catch-all rule like { "iterations": "all", "modelLevel": "level2" }`
179
- );
180
- }
181
-
182
- if (this.modelConfig.model) {
183
- return {
184
- level: 'custom',
185
- model: this.modelConfig.model,
186
- reasoningEffort: this.config.reasoningEffort,
187
- };
188
- }
189
-
190
- if (forcedLevel) {
191
- const level = provider.validateLevel(forcedLevel, minLevel, maxLevel);
192
- const spec = provider.resolveModelSpec(level, levelOverrides);
193
- return applyReasoningOverride({ ...spec, level }, this.config.reasoningEffort);
194
- }
195
-
196
- if (this.modelConfig.modelLevel) {
197
- const level = provider.validateLevel(this.modelConfig.modelLevel, minLevel, maxLevel);
198
- const spec = provider.resolveModelSpec(level, levelOverrides);
199
- return applyReasoningOverride({ ...spec, level }, this.config.reasoningEffort);
200
- }
201
-
202
- const defaultLevel = providerSettings.defaultLevel || provider.getDefaultLevel();
203
- const level = provider.validateLevel(defaultLevel, minLevel, maxLevel);
204
- const spec = provider.resolveModelSpec(level, levelOverrides);
205
- return applyReasoningOverride({ ...spec, level }, this.config.reasoningEffort);
206
- }
207
-
208
- /**
209
- * Publish a message to the message bus, always including sender_model
210
- * @private
211
- */
212
- _publish(message) {
213
- this.messageBus.publish({
214
- ...message,
215
- cluster_id: this.cluster.id,
216
- sender: this.id,
217
- sender_model: this._selectModel(),
218
- sender_provider: this._resolveProvider(),
219
- });
220
- }
221
-
222
- /**
223
- * Publish agent lifecycle event to message bus (visible in zeroshot logs)
224
- * @private
225
- */
226
- _publishLifecycle(event, details = {}) {
227
- this._publish({
228
- topic: 'AGENT_LIFECYCLE',
229
- receiver: 'system',
230
- content: {
231
- text: `${this.id}: ${event}`,
232
- data: {
233
- event,
234
- agent: this.id,
235
- role: this.role,
236
- state: this.state,
237
- model: this._selectModel(),
238
- provider: this._resolveProvider(),
239
- ...details,
240
- },
241
- },
242
- });
243
- }
244
-
245
- /**
246
- * Select model based on current iteration and agent config
247
- * Enforces legacy maxModel/minModel for Claude's haiku/sonnet/opus
248
- * @returns {string|null}
249
- * @private
250
- */
251
- _selectModel() {
252
- const spec = this._resolveModelSpec();
253
- const settings = loadSettings();
254
- const maxModel = settings.maxModel || 'sonnet';
255
- const minModel = settings.minModel || null;
256
-
257
- if (spec.model && ['opus', 'sonnet', 'haiku'].includes(spec.model)) {
258
- return validateModelAgainstMax(spec.model, maxModel, minModel);
259
- }
260
-
261
- return spec.model || null;
262
- }
263
-
264
- /**
265
- * Check if current iteration matches the range pattern
266
- * @param {string} pattern - e.g., "1", "1-3", "5+", "all"
267
- * @returns {boolean}
268
- * @private
269
- */
270
- _matchesIterationRange(pattern) {
271
- if (pattern === 'all') return true;
272
-
273
- const current = this.iteration;
274
-
275
- // Exact match: "3"
276
- if (/^\d+$/.test(pattern)) {
277
- return current === parseInt(pattern);
278
- }
279
-
280
- // Range: "1-3"
281
- const rangeMatch = pattern.match(/^(\d+)-(\d+)$/);
282
- if (rangeMatch) {
283
- const [, start, end] = rangeMatch;
284
- return current >= parseInt(start) && current <= parseInt(end);
285
- }
286
-
287
- // Open-ended: "5+"
288
- const openMatch = pattern.match(/^(\d+)\+$/);
289
- if (openMatch) {
290
- const [, start] = openMatch;
291
- return current >= parseInt(start);
292
- }
293
-
294
- throw new Error(
295
- `Agent ${this.id}: Invalid iteration pattern '${pattern}'. ` +
296
- `Valid formats: "1", "1-3", "5+", "all"`
297
- );
298
- }
299
-
300
- /**
301
- * Select prompt based on current iteration and agent config
302
- * @returns {string|null} System prompt string, or null if no prompt configured
303
- * @private
304
- */
305
- _selectPrompt() {
306
- const promptConfig = this.config.promptConfig;
307
-
308
- // No prompt configured
309
- if (!promptConfig) {
310
- return null;
311
- }
312
-
313
- // Backward compatibility: static prompt
314
- if (promptConfig.type === 'static') {
315
- return promptConfig.system;
316
- }
317
-
318
- // Dynamic rules: evaluate based on iteration
319
- for (const rule of promptConfig.rules) {
320
- if (this._matchesIterationRange(rule.match)) {
321
- return rule.system;
322
- }
323
- }
324
-
325
- // No match: fail fast
326
- throw new Error(
327
- `Agent ${this.id}: No prompt rule matched iteration ${this.iteration}. ` +
328
- `Add a catch-all rule like { "match": "all", "system": "..." }`
329
- );
330
- }
331
-
332
- /**
333
- * Start the agent (begin listening for triggers)
334
- */
335
- start() {
336
- return lifecycleStart(this);
337
- }
338
-
339
- /**
340
- * Stop the agent
341
- */
342
- stop() {
343
- return lifecycleStop(this);
344
- }
345
-
346
- /**
347
- * Handle incoming message
348
- * @private
349
- */
350
- _handleMessage(message) {
351
- return lifecycleHandleMessage(this, message);
352
- }
353
-
354
- /**
355
- * Find trigger matching the message topic
356
- * @private
357
- */
358
- _findMatchingTrigger(message) {
359
- return findMatchingTrigger({
360
- triggers: this.config.triggers,
361
- message,
362
- });
363
- }
364
-
365
- /**
366
- * Evaluate trigger logic
367
- * @private
368
- */
369
- _evaluateTrigger(trigger, message) {
370
- const agent = {
371
- id: this.id,
372
- role: this.role,
373
- iteration: this.iteration,
374
- cluster_id: this.cluster.id,
375
- };
376
-
377
- return evaluateTrigger({
378
- trigger,
379
- message,
380
- agent,
381
- logicEngine: this.logicEngine,
382
- });
383
- }
384
-
385
- /**
386
- * Execute trigger action
387
- * @private
388
- */
389
- _executeTriggerAction(trigger, message) {
390
- return lifecycleExecuteTriggerAction(this, trigger, message);
391
- }
392
-
393
- /**
394
- * Execute claude-zeroshots with built context
395
- * Retries disabled by default. Set agent config `maxRetries` to enable (e.g., 3).
396
- * @private
397
- */
398
- _executeTask(triggeringMessage) {
399
- return lifecycleExecuteTask(this, triggeringMessage);
400
- }
401
-
402
- /**
403
- * Build context from ledger based on contextStrategy
404
- * @private
405
- */
406
- _buildContext(triggeringMessage) {
407
- return buildContext({
408
- id: this.id,
409
- role: this.role,
410
- iteration: this.iteration,
411
- config: this.config,
412
- messageBus: this.messageBus,
413
- cluster: this.cluster,
414
- lastTaskEndTime: this.lastTaskEndTime,
415
- triggeringMessage,
416
- selectedPrompt: this._selectPrompt(),
417
- // Pass isolation state for conditional git restriction
418
- worktree: this.worktree,
419
- isolation: this.isolation,
420
- });
421
- }
422
-
423
- /**
424
- * Spawn claude-zeroshots process and stream output via message bus
425
- * @private
426
- */
427
- _spawnClaudeTask(context) {
428
- return spawnClaudeTask(this, context);
429
- }
430
-
431
- /**
432
- * Wait for task to be registered in ct storage
433
- * @private
434
- */
435
- _waitForTaskReady(taskId, maxRetries = 10, delayMs = 200) {
436
- return waitForTaskReady(this, taskId, maxRetries, delayMs);
437
- }
438
-
439
- /**
440
- * Follow claude-zeroshots logs until completion, streaming to message bus
441
- * Reads log file directly for reliable streaming
442
- * @private
443
- */
444
- _followClaudeTaskLogs(taskId) {
445
- return followClaudeTaskLogs(this, taskId);
446
- }
447
-
448
- /**
449
- * Get path to claude-zeroshots executable
450
- * @private
451
- */
452
- _getClaudeTasksPath() {
453
- return getClaudeTasksPath();
454
- }
455
-
456
- /**
457
- * Spawn claude-zeroshots inside Docker container (isolation mode)
458
- * Runs Claude CLI inside the container for full isolation
459
- * @private
460
- */
461
- _spawnClaudeTaskIsolated(context) {
462
- return spawnClaudeTaskIsolated(this, context);
463
- }
464
-
465
- /**
466
- * Kill current task
467
- * @private
468
- */
469
- _killTask() {
470
- return killTask(this);
471
- }
472
-
473
- /**
474
- * Execute a hook
475
- * THROWS on failure - no silent errors
476
- * @private
477
- */
478
- _executeHook(hookName, context) {
479
- const hook = this.config.hooks?.[hookName];
480
- return executeHook({
481
- hook,
482
- agent: this,
483
- message: context.triggeringMessage,
484
- result: context.result,
485
- messageBus: this.messageBus,
486
- cluster: this.cluster,
487
- orchestrator: this.orchestrator,
488
- });
489
- }
490
-
491
- /**
492
- * Parse agent output to extract structured result data
493
- * GENERIC - returns whatever structured output the agent provides
494
- * Works with any agent schema (planner, validator, worker, etc.)
495
- * Falls back to reformatting if extraction fails
496
- * @private
497
- */
498
- _parseResultOutput(output) {
499
- return parseResultOutput(this, output);
500
- }
501
-
502
- /**
503
- * Resume agent task with context from previous failure
504
- * Called by Orchestrator.resume() to continue where we left off
505
- * @param {String} resumeContext - Context describing what to resume
506
- */
507
- async resume(resumeContext) {
508
- if (!this.running) {
509
- throw new Error(`Agent ${this.id} is not running. Start it first.`);
510
- }
511
-
512
- if (this.state !== 'idle') {
513
- throw new Error(`Agent ${this.id} is busy (state: ${this.state}). Wait for current task.`);
514
- }
515
-
516
- this._log(`[${this.id}] Resuming task...`);
517
-
518
- // Create a synthetic triggering message for resume
519
- const triggeringMessage = {
520
- cluster_id: this.cluster.id,
521
- topic: 'AGENT_RESUME',
522
- sender: 'system',
523
- content: {
524
- text: resumeContext,
525
- },
526
- };
527
-
528
- // Execute the task with resume context
529
- await this._executeTask(triggeringMessage);
530
- }
531
-
532
- /**
533
- * Get current agent state
534
- */
535
- getState() {
536
- const modelSpec = this._resolveModelSpec();
537
- return {
538
- id: this.id,
539
- role: this.role,
540
- model: this._selectModel(),
541
- provider: this._resolveProvider(),
542
- modelSpec,
543
- state: this.state,
544
- iteration: this.iteration,
545
- maxIterations: this.maxIterations,
546
- currentTask: this.currentTask ? true : false,
547
- currentTaskId: this.currentTaskId,
548
- pid: this.processPid,
549
- };
550
- }
551
-
552
- /**
553
- * Start monitoring agent output liveness
554
- * Detects when agent produces no output for configured staleDuration
555
- * @private
556
- */
557
- _startLivenessCheck() {
558
- return lifecycleStartLivenessCheck(this);
559
- }
560
-
561
- /**
562
- * Stop liveness monitoring
563
- * @private
564
- */
565
- _stopLivenessCheck() {
566
- return lifecycleStopLivenessCheck(this);
567
- }
568
- }
569
-
570
- module.exports = AgentWrapper;
@@ -1,20 +0,0 @@
1
- {
2
- "id": "git-pusher",
3
- "role": "completion-detector",
4
- "modelLevel": "level2",
5
- "triggers": [
6
- {
7
- "topic": "VALIDATION_RESULT",
8
- "logic": {
9
- "engine": "javascript",
10
- "script": "const validators = cluster.getAgentsByRole('validator'); const lastPush = ledger.findLast({ topic: 'IMPLEMENTATION_READY' }); if (!lastPush) return false; if (validators.length === 0) return true; const results = ledger.query({ topic: 'VALIDATION_RESULT', since: lastPush.timestamp }); if (results.length < validators.length) return false; const allApproved = results.every(r => r.content?.data?.approved === 'true' || r.content?.data?.approved === true); if (!allApproved) return false; const hasRealEvidence = results.every(r => { const criteria = r.content?.data?.criteriaResults || []; return criteria.every(c => { return c.evidence?.command && typeof c.evidence?.exitCode === 'number' && c.evidence?.output?.length > 10; }); }); return hasRealEvidence;"
11
- },
12
- "action": "execute_task"
13
- }
14
- ],
15
- "prompt": "\ud83d\udea8 CRITICAL: ALL VALIDATORS APPROVED. YOU MUST CREATE A PR AND GET IT MERGED. DO NOT STOP UNTIL THE PR IS MERGED. \ud83d\udea8\n\n## MANDATORY STEPS - EXECUTE EACH ONE IN ORDER - DO NOT SKIP ANY STEP\n\n### STEP 1: Stage ALL changes (MANDATORY)\n```bash\ngit add -A\n```\nRun this command. Do not skip it.\n\n### STEP 2: Check what's staged\n```bash\ngit status\n```\nRun this. If nothing to commit, output JSON with pr_url: null and stop.\n\n### STEP 3: Commit the changes (MANDATORY if there are changes)\n```bash\ngit commit -m \"feat: implement #{{issue_number}} - {{issue_title}}\"\n```\nRun this command. Do not skip it.\n\n### STEP 4: Push to origin (MANDATORY)\n```bash\ngit push -u origin HEAD\n```\nRun this. If it fails, check the error and fix it.\n\n\u26a0\ufe0f AFTER PUSH YOU ARE NOT DONE! CONTINUE TO STEP 5! \u26a0\ufe0f\n\n### STEP 5: CREATE THE PR (MANDATORY - YOU MUST RUN THIS COMMAND)\n```bash\ngh pr create --title \"feat: {{issue_title}}\" --body \"Closes #{{issue_number}}\"\n```\n\ud83d\udea8 YOU MUST RUN `gh pr create`! Outputting a link is NOT creating a PR! \ud83d\udea8\nThe push output shows a \"Create a pull request\" link - IGNORE IT.\nYou MUST run the `gh pr create` command above. Save the actual PR URL from the output.\n\n\u26a0\ufe0f AFTER PR CREATION YOU ARE NOT DONE! CONTINUE TO STEP 6! \u26a0\ufe0f\n\n### STEP 6: MERGE THE PR (MANDATORY - THIS IS NOT OPTIONAL)\n```bash\ngh pr merge --merge --auto\n```\nThis sets auto-merge. If it fails (e.g., no auto-merge enabled), try:\n```bash\ngh pr merge --merge\n```\n\n\ud83d\udea8 IF MERGE FAILS DUE TO CONFLICTS - YOU MUST RESOLVE THEM:\na) Pull latest main and rebase:\n ```bash\n git fetch origin main\n git rebase origin/main\n ```\nb) If conflicts appear - RESOLVE THEM IMMEDIATELY:\n - Read the conflicting files\n - Make intelligent decisions about what code to keep\n - Edit the files to resolve conflicts\n - `git add <resolved-files>`\n - `git rebase --continue`\nc) Force push the resolved branch:\n ```bash\n git push --force-with-lease\n ```\nd) Retry merge:\n ```bash\n gh pr merge --merge\n ```\n\nREPEAT UNTIL MERGED. DO NOT GIVE UP. DO NOT SKIP. THE PR MUST BE MERGED.\nIf merge is blocked by CI, wait and retry. If blocked by reviews, set auto-merge.\n\n## CRITICAL RULES\n- Execute EVERY step in order (1, 2, 3, 4, 5, 6)\n- Do NOT skip git add -A\n- Do NOT skip git commit\n- Do NOT skip gh pr create - THE TASK IS NOT DONE UNTIL PR EXISTS\n- Do NOT skip gh pr merge - THE TASK IS NOT DONE UNTIL PR IS MERGED\n- If push fails, debug and fix it\n- If PR creation fails, debug and fix it\n- If merge fails, debug and fix it\n- DO NOT OUTPUT JSON UNTIL PR IS ACTUALLY MERGED\n- A link from git push is NOT a PR - you must run gh pr create\n\n## Final Output\nONLY after the PR is MERGED, output:\n```json\n{\"pr_url\": \"https://github.com/owner/repo/pull/123\", \"pr_number\": 123, \"merged\": true}\n```\n\nIf truly no changes exist, output:\n```json\n{\"pr_url\": null, \"pr_number\": null, \"merged\": false}\n```",
16
- "output": {
17
- "topic": "PR_CREATED",
18
- "publishAfter": "CLUSTER_COMPLETE"
19
- }
20
- }