heyio 3.4.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CODE_OF_CONDUCT.md +83 -0
- package/LICENSE +21 -0
- package/README.md +203 -151
- package/dist/daemon/cli.js +7153 -0
- package/dist/daemon/index.js +6421 -0
- package/dist/web/assets/index-CbptHIYU.js +520 -0
- package/{public → dist/web}/index.html +1 -1
- package/package.json +45 -48
- package/dist/api/middleware/auth.d.ts +0 -14
- package/dist/api/middleware/auth.d.ts.map +0 -1
- package/dist/api/middleware/auth.js +0 -130
- package/dist/api/middleware/auth.js.map +0 -1
- package/dist/api/notifications.d.ts +0 -14
- package/dist/api/notifications.d.ts.map +0 -1
- package/dist/api/notifications.js +0 -114
- package/dist/api/notifications.js.map +0 -1
- package/dist/api/routes/activity.d.ts +0 -3
- package/dist/api/routes/activity.d.ts.map +0 -1
- package/dist/api/routes/activity.js +0 -28
- package/dist/api/routes/activity.js.map +0 -1
- package/dist/api/routes/attachments.d.ts +0 -3
- package/dist/api/routes/attachments.d.ts.map +0 -1
- package/dist/api/routes/attachments.js +0 -83
- package/dist/api/routes/attachments.js.map +0 -1
- package/dist/api/routes/config.d.ts +0 -3
- package/dist/api/routes/config.d.ts.map +0 -1
- package/dist/api/routes/config.js +0 -107
- package/dist/api/routes/config.js.map +0 -1
- package/dist/api/routes/conversations.d.ts +0 -3
- package/dist/api/routes/conversations.d.ts.map +0 -1
- package/dist/api/routes/conversations.js +0 -25
- package/dist/api/routes/conversations.js.map +0 -1
- package/dist/api/routes/health.d.ts +0 -3
- package/dist/api/routes/health.d.ts.map +0 -1
- package/dist/api/routes/health.js +0 -39
- package/dist/api/routes/health.js.map +0 -1
- package/dist/api/routes/inbox.d.ts +0 -3
- package/dist/api/routes/inbox.d.ts.map +0 -1
- package/dist/api/routes/inbox.js +0 -139
- package/dist/api/routes/inbox.js.map +0 -1
- package/dist/api/routes/schedules.d.ts +0 -3
- package/dist/api/routes/schedules.d.ts.map +0 -1
- package/dist/api/routes/schedules.js +0 -116
- package/dist/api/routes/schedules.js.map +0 -1
- package/dist/api/routes/skills.d.ts +0 -2
- package/dist/api/routes/skills.d.ts.map +0 -1
- package/dist/api/routes/skills.js +0 -127
- package/dist/api/routes/skills.js.map +0 -1
- package/dist/api/routes/squads.d.ts +0 -3
- package/dist/api/routes/squads.d.ts.map +0 -1
- package/dist/api/routes/squads.js +0 -578
- package/dist/api/routes/squads.js.map +0 -1
- package/dist/api/routes/usage.d.ts +0 -3
- package/dist/api/routes/usage.d.ts.map +0 -1
- package/dist/api/routes/usage.js +0 -55
- package/dist/api/routes/usage.js.map +0 -1
- package/dist/api/routes/wiki.d.ts +0 -2
- package/dist/api/routes/wiki.d.ts.map +0 -1
- package/dist/api/routes/wiki.js +0 -75
- package/dist/api/routes/wiki.js.map +0 -1
- package/dist/api/server.d.ts +0 -7
- package/dist/api/server.d.ts.map +0 -1
- package/dist/api/server.js +0 -183
- package/dist/api/server.js.map +0 -1
- package/dist/config.d.ts +0 -3
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js +0 -3
- package/dist/config.js.map +0 -1
- package/dist/copilot/client.d.ts +0 -5
- package/dist/copilot/client.d.ts.map +0 -1
- package/dist/copilot/client.js +0 -38
- package/dist/copilot/client.js.map +0 -1
- package/dist/copilot/health-monitor.d.ts +0 -14
- package/dist/copilot/health-monitor.d.ts.map +0 -1
- package/dist/copilot/health-monitor.js +0 -70
- package/dist/copilot/health-monitor.js.map +0 -1
- package/dist/copilot/orchestrator.d.ts +0 -5
- package/dist/copilot/orchestrator.d.ts.map +0 -1
- package/dist/copilot/orchestrator.js +0 -227
- package/dist/copilot/orchestrator.js.map +0 -1
- package/dist/copilot/tools.d.ts +0 -80
- package/dist/copilot/tools.d.ts.map +0 -1
- package/dist/copilot/tools.js +0 -1067
- package/dist/copilot/tools.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -94
- package/dist/index.js.map +0 -1
- package/dist/logging/logger.d.ts +0 -6
- package/dist/logging/logger.d.ts.map +0 -1
- package/dist/logging/logger.js +0 -33
- package/dist/logging/logger.js.map +0 -1
- package/dist/models/index.d.ts +0 -6
- package/dist/models/index.d.ts.map +0 -1
- package/dist/models/index.js +0 -4
- package/dist/models/index.js.map +0 -1
- package/dist/models/pricing.d.ts +0 -25
- package/dist/models/pricing.d.ts.map +0 -1
- package/dist/models/pricing.js +0 -96
- package/dist/models/pricing.js.map +0 -1
- package/dist/models/registry.d.ts +0 -34
- package/dist/models/registry.d.ts.map +0 -1
- package/dist/models/registry.js +0 -109
- package/dist/models/registry.js.map +0 -1
- package/dist/models/token-tracker.d.ts +0 -41
- package/dist/models/token-tracker.d.ts.map +0 -1
- package/dist/models/token-tracker.js +0 -103
- package/dist/models/token-tracker.js.map +0 -1
- package/dist/scheduler/engine.d.ts +0 -12
- package/dist/scheduler/engine.d.ts.map +0 -1
- package/dist/scheduler/engine.js +0 -128
- package/dist/scheduler/engine.js.map +0 -1
- package/dist/skills/discover.d.ts +0 -22
- package/dist/skills/discover.d.ts.map +0 -1
- package/dist/skills/discover.js +0 -228
- package/dist/skills/discover.js.map +0 -1
- package/dist/skills/index.d.ts +0 -5
- package/dist/skills/index.d.ts.map +0 -1
- package/dist/skills/index.js +0 -3
- package/dist/skills/index.js.map +0 -1
- package/dist/skills/store.d.ts +0 -56
- package/dist/skills/store.d.ts.map +0 -1
- package/dist/skills/store.js +0 -154
- package/dist/skills/store.js.map +0 -1
- package/dist/squad/agent.d.ts +0 -65
- package/dist/squad/agent.d.ts.map +0 -1
- package/dist/squad/agent.js +0 -544
- package/dist/squad/agent.js.map +0 -1
- package/dist/squad/autonomy.d.ts +0 -16
- package/dist/squad/autonomy.d.ts.map +0 -1
- package/dist/squad/autonomy.js +0 -63
- package/dist/squad/autonomy.js.map +0 -1
- package/dist/squad/event-bus.d.ts +0 -22
- package/dist/squad/event-bus.d.ts.map +0 -1
- package/dist/squad/event-bus.js +0 -56
- package/dist/squad/event-bus.js.map +0 -1
- package/dist/squad/execution/index.d.ts +0 -14
- package/dist/squad/execution/index.d.ts.map +0 -1
- package/dist/squad/execution/index.js +0 -8
- package/dist/squad/execution/index.js.map +0 -1
- package/dist/squad/execution/instance.d.ts +0 -45
- package/dist/squad/execution/instance.d.ts.map +0 -1
- package/dist/squad/execution/instance.js +0 -165
- package/dist/squad/execution/instance.js.map +0 -1
- package/dist/squad/execution/planning.d.ts +0 -20
- package/dist/squad/execution/planning.d.ts.map +0 -1
- package/dist/squad/execution/planning.js +0 -62
- package/dist/squad/execution/planning.js.map +0 -1
- package/dist/squad/execution/pr.d.ts +0 -15
- package/dist/squad/execution/pr.d.ts.map +0 -1
- package/dist/squad/execution/pr.js +0 -109
- package/dist/squad/execution/pr.js.map +0 -1
- package/dist/squad/execution/review.d.ts +0 -21
- package/dist/squad/execution/review.d.ts.map +0 -1
- package/dist/squad/execution/review.js +0 -157
- package/dist/squad/execution/review.js.map +0 -1
- package/dist/squad/execution/runner.d.ts +0 -52
- package/dist/squad/execution/runner.d.ts.map +0 -1
- package/dist/squad/execution/runner.js +0 -93
- package/dist/squad/execution/runner.js.map +0 -1
- package/dist/squad/execution/tasks.d.ts +0 -22
- package/dist/squad/execution/tasks.d.ts.map +0 -1
- package/dist/squad/execution/tasks.js +0 -111
- package/dist/squad/execution/tasks.js.map +0 -1
- package/dist/squad/execution/worktree.d.ts +0 -27
- package/dist/squad/execution/worktree.d.ts.map +0 -1
- package/dist/squad/execution/worktree.js +0 -141
- package/dist/squad/execution/worktree.js.map +0 -1
- package/dist/squad/hiring.d.ts +0 -57
- package/dist/squad/hiring.d.ts.map +0 -1
- package/dist/squad/hiring.js +0 -588
- package/dist/squad/hiring.js.map +0 -1
- package/dist/squad/index.d.ts +0 -8
- package/dist/squad/index.d.ts.map +0 -1
- package/dist/squad/index.js +0 -6
- package/dist/squad/index.js.map +0 -1
- package/dist/squad/manager.d.ts +0 -58
- package/dist/squad/manager.d.ts.map +0 -1
- package/dist/squad/manager.js +0 -351
- package/dist/squad/manager.js.map +0 -1
- package/dist/squad/model-selector.d.ts +0 -29
- package/dist/squad/model-selector.d.ts.map +0 -1
- package/dist/squad/model-selector.js +0 -64
- package/dist/squad/model-selector.js.map +0 -1
- package/dist/squad/name-generator.d.ts +0 -16
- package/dist/squad/name-generator.d.ts.map +0 -1
- package/dist/squad/name-generator.js +0 -111
- package/dist/squad/name-generator.js.map +0 -1
- package/dist/squad/roles/templates.d.ts +0 -7
- package/dist/squad/roles/templates.d.ts.map +0 -1
- package/dist/squad/roles/templates.js +0 -104
- package/dist/squad/roles/templates.js.map +0 -1
- package/dist/squad/skill-parser.d.ts +0 -36
- package/dist/squad/skill-parser.d.ts.map +0 -1
- package/dist/squad/skill-parser.js +0 -90
- package/dist/squad/skill-parser.js.map +0 -1
- package/dist/squad/source-resolver.d.ts +0 -20
- package/dist/squad/source-resolver.d.ts.map +0 -1
- package/dist/squad/source-resolver.js +0 -51
- package/dist/squad/source-resolver.js.map +0 -1
- package/dist/store/activity.d.ts +0 -51
- package/dist/store/activity.d.ts.map +0 -1
- package/dist/store/activity.js +0 -197
- package/dist/store/activity.js.map +0 -1
- package/dist/store/conversations.d.ts +0 -25
- package/dist/store/conversations.d.ts.map +0 -1
- package/dist/store/conversations.js +0 -76
- package/dist/store/conversations.js.map +0 -1
- package/dist/store/db.d.ts +0 -5
- package/dist/store/db.d.ts.map +0 -1
- package/dist/store/db.js +0 -290
- package/dist/store/db.js.map +0 -1
- package/dist/store/inbox.d.ts +0 -67
- package/dist/store/inbox.d.ts.map +0 -1
- package/dist/store/inbox.js +0 -192
- package/dist/store/inbox.js.map +0 -1
- package/dist/store/schedules.d.ts +0 -53
- package/dist/store/schedules.d.ts.map +0 -1
- package/dist/store/schedules.js +0 -160
- package/dist/store/schedules.js.map +0 -1
- package/dist/wiki/index.d.ts +0 -3
- package/dist/wiki/index.d.ts.map +0 -1
- package/dist/wiki/index.js +0 -2
- package/dist/wiki/index.js.map +0 -1
- package/dist/wiki/store.d.ts +0 -81
- package/dist/wiki/store.d.ts.map +0 -1
- package/dist/wiki/store.js +0 -270
- package/dist/wiki/store.js.map +0 -1
- package/node_modules/@io/shared/dist/config.d.ts +0 -26
- package/node_modules/@io/shared/dist/config.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/config.js +0 -53
- package/node_modules/@io/shared/dist/config.js.map +0 -1
- package/node_modules/@io/shared/dist/constants.d.ts +0 -19
- package/node_modules/@io/shared/dist/constants.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/constants.js +0 -51
- package/node_modules/@io/shared/dist/constants.js.map +0 -1
- package/node_modules/@io/shared/dist/index.d.ts +0 -12
- package/node_modules/@io/shared/dist/index.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/index.js +0 -3
- package/node_modules/@io/shared/dist/index.js.map +0 -1
- package/node_modules/@io/shared/dist/types/agents.d.ts +0 -3
- package/node_modules/@io/shared/dist/types/agents.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/agents.js +0 -2
- package/node_modules/@io/shared/dist/types/agents.js.map +0 -1
- package/node_modules/@io/shared/dist/types/api.d.ts +0 -33
- package/node_modules/@io/shared/dist/types/api.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/api.js +0 -2
- package/node_modules/@io/shared/dist/types/api.js.map +0 -1
- package/node_modules/@io/shared/dist/types/attachments.d.ts +0 -10
- package/node_modules/@io/shared/dist/types/attachments.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/attachments.js +0 -2
- package/node_modules/@io/shared/dist/types/attachments.js.map +0 -1
- package/node_modules/@io/shared/dist/types/events.d.ts +0 -44
- package/node_modules/@io/shared/dist/types/events.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/events.js +0 -2
- package/node_modules/@io/shared/dist/types/events.js.map +0 -1
- package/node_modules/@io/shared/dist/types/history.d.ts +0 -33
- package/node_modules/@io/shared/dist/types/history.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/history.js +0 -2
- package/node_modules/@io/shared/dist/types/history.js.map +0 -1
- package/node_modules/@io/shared/dist/types/messages.d.ts +0 -15
- package/node_modules/@io/shared/dist/types/messages.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/messages.js +0 -2
- package/node_modules/@io/shared/dist/types/messages.js.map +0 -1
- package/node_modules/@io/shared/dist/types/squads.d.ts +0 -46
- package/node_modules/@io/shared/dist/types/squads.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/squads.js +0 -2
- package/node_modules/@io/shared/dist/types/squads.js.map +0 -1
- package/node_modules/@io/shared/dist/types/tokens.d.ts +0 -19
- package/node_modules/@io/shared/dist/types/tokens.d.ts.map +0 -1
- package/node_modules/@io/shared/dist/types/tokens.js +0 -2
- package/node_modules/@io/shared/dist/types/tokens.js.map +0 -1
- package/node_modules/@io/shared/package.json +0 -18
- package/node_modules/@io/shared/src/config.ts +0 -85
- package/node_modules/@io/shared/src/constants.ts +0 -54
- package/node_modules/@io/shared/src/index.ts +0 -46
- package/node_modules/@io/shared/src/types/agents.ts +0 -3
- package/node_modules/@io/shared/src/types/api.ts +0 -35
- package/node_modules/@io/shared/src/types/attachments.ts +0 -9
- package/node_modules/@io/shared/src/types/events.ts +0 -86
- package/node_modules/@io/shared/src/types/history.ts +0 -37
- package/node_modules/@io/shared/src/types/messages.ts +0 -15
- package/node_modules/@io/shared/src/types/squads.ts +0 -56
- package/node_modules/@io/shared/src/types/tokens.ts +0 -19
- package/node_modules/@io/shared/tsconfig.json +0 -9
- package/node_modules/@io/shared/tsconfig.tsbuildinfo +0 -1
- package/public/assets/index-CoSJG-14.js +0 -510
- package/public/assets/index-CoSJG-14.js.map +0 -1
- /package/{public → dist/web}/assets/index-B6F0UZkW.css +0 -0
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { createChildLogger } from '../../logging/logger.js';
|
|
2
|
-
import { getEventBus } from '../event-bus.js';
|
|
3
|
-
import { selectModelForRole } from '../model-selector.js';
|
|
4
|
-
import { addInboxEntry } from '../../store/inbox.js';
|
|
5
|
-
import { transitionInstance } from './instance.js';
|
|
6
|
-
import { executeRework } from './tasks.js';
|
|
7
|
-
const logger = () => createChildLogger('review');
|
|
8
|
-
const MAX_REVIEW_CYCLES = 5;
|
|
9
|
-
/**
|
|
10
|
-
* Gated review cycle:
|
|
11
|
-
* 1. Lead reviews all task results
|
|
12
|
-
* 2. If lead rejects → identifies tasks to rework, specialists rework in parallel
|
|
13
|
-
* 3. If lead approves → QA/veto reviews
|
|
14
|
-
* 4. If QA rejects → same rework loop
|
|
15
|
-
* 5. Max 5 cycles total, then fail to inbox
|
|
16
|
-
*/
|
|
17
|
-
export async function reviewWork(params) {
|
|
18
|
-
const log = logger();
|
|
19
|
-
const { instance, runtime, objective } = params;
|
|
20
|
-
await transitionInstance(instance.id, 'reviewing');
|
|
21
|
-
const teamLead = runtime.members.get('technical-pm');
|
|
22
|
-
if (!teamLead)
|
|
23
|
-
throw new Error('No team lead for review');
|
|
24
|
-
// Track review activity under this instance
|
|
25
|
-
teamLead.setInstanceId(instance.id);
|
|
26
|
-
if (instance.worktree) {
|
|
27
|
-
teamLead.setWorkingDir(instance.worktree.path);
|
|
28
|
-
}
|
|
29
|
-
// Find veto/QA members
|
|
30
|
-
const vetoMembers = [...runtime.members.entries()].filter(([role]) => {
|
|
31
|
-
const skill = runtime.skills.get(role);
|
|
32
|
-
return skill?.veto && role !== 'technical-pm';
|
|
33
|
-
});
|
|
34
|
-
let cycles = 0;
|
|
35
|
-
while (cycles < MAX_REVIEW_CYCLES) {
|
|
36
|
-
cycles++;
|
|
37
|
-
log.info({ instanceId: instance.id, cycle: cycles }, 'Review cycle');
|
|
38
|
-
await getEventBus().emit({
|
|
39
|
-
id: crypto.randomUUID(),
|
|
40
|
-
timestamp: new Date(),
|
|
41
|
-
type: 'instance:review_cycle',
|
|
42
|
-
squadId: instance.squadId,
|
|
43
|
-
instanceId: instance.id,
|
|
44
|
-
data: { cycle: cycles, maxCycles: MAX_REVIEW_CYCLES },
|
|
45
|
-
});
|
|
46
|
-
// Build task summary for reviewer
|
|
47
|
-
const taskSummary = instance.tasks
|
|
48
|
-
.map((t) => `- [${t.status}] ${t.description} (${t.assignedTo})\n Result: ${(t.result ?? 'No result').slice(0, 1000)}`)
|
|
49
|
-
.join('\n\n');
|
|
50
|
-
// Step 1: Team Lead reviews
|
|
51
|
-
const reviewModel = selectModelForRole('technical-pm', 'review');
|
|
52
|
-
if (teamLead.getModel() !== reviewModel) {
|
|
53
|
-
await teamLead.switchModel(reviewModel);
|
|
54
|
-
}
|
|
55
|
-
const leadReview = await teamLead.send(`Review all completed work for this objective:\n\nObjective: ${objective}\n\nTask results:\n${taskSummary}\n\nBefore deciding, use your tools to VERIFY the work exists on disk:\n- Use read_file to check that expected files were created/modified\n- Use run_command to run tests or check file structure (e.g., "ls -la", "cat <file>", "npm test")\n\nDo NOT trust the task results text alone — verify actual changes exist.\n\nAfter verifying, reply with one of:\n- "APPROVED" if work is verified on disk and meets the objective\n- "REWORK:" followed by a JSON array of objects with "taskId" and "feedback" for each task that needs revision. Example:\nREWORK: [{"taskId": "abc-123", "feedback": "File was not actually written to disk"}]`);
|
|
56
|
-
if (leadReview.toUpperCase().includes('APPROVED')) {
|
|
57
|
-
// Step 2: QA/veto review (gated behind lead approval)
|
|
58
|
-
if (vetoMembers.length === 0) {
|
|
59
|
-
log.info({ instanceId: instance.id }, 'No veto members, lead approval is final');
|
|
60
|
-
return { approved: true, cycles };
|
|
61
|
-
}
|
|
62
|
-
for (const [role, agent] of vetoMembers) {
|
|
63
|
-
agent.setInstanceId(instance.id);
|
|
64
|
-
if (instance.worktree) {
|
|
65
|
-
agent.setWorkingDir(instance.worktree.path);
|
|
66
|
-
}
|
|
67
|
-
const qaModel = selectModelForRole(role, 'review');
|
|
68
|
-
if (agent.getModel() !== qaModel) {
|
|
69
|
-
await agent.switchModel(qaModel);
|
|
70
|
-
}
|
|
71
|
-
const qaReview = await agent.send(`As QA, review the following completed work:\n\nObjective: ${objective}\n\nTask results:\n${taskSummary}\n\nBefore deciding, use your tools to VERIFY the work on disk:\n- Use read_file to inspect the actual files\n- Use run_command to run tests or linting\n\nDo NOT rely on task result text alone — verify real changes exist.\n\nReply with:\n- "APPROVED" if verified and satisfactory\n- "REWORK:" followed by a JSON array of objects with "taskId" and "feedback" for tasks that need revision.`);
|
|
72
|
-
if (qaReview.toUpperCase().includes('REWORK:')) {
|
|
73
|
-
// QA rejected — parse rework instructions and loop
|
|
74
|
-
const reworkTasks = parseReworkInstructions(qaReview, instance.tasks);
|
|
75
|
-
if (reworkTasks.length > 0) {
|
|
76
|
-
log.info({ instanceId: instance.id, cycle: cycles, rejectedBy: role, reworkCount: reworkTasks.length }, 'QA rejected, reworking');
|
|
77
|
-
await transitionInstance(instance.id, 'working');
|
|
78
|
-
await executeRework({ instance, runtime, reworkTasks });
|
|
79
|
-
await transitionInstance(instance.id, 'reviewing');
|
|
80
|
-
}
|
|
81
|
-
break; // Back to top of review loop
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// If we didn't break (all QA approved), we're done
|
|
85
|
-
if (!leadReview.toUpperCase().includes('REWORK:')) {
|
|
86
|
-
// Check that we actually reached this point without a QA rejection
|
|
87
|
-
const allQaApproved = true; // If we didn't break, all approved
|
|
88
|
-
if (allQaApproved) {
|
|
89
|
-
log.info({ instanceId: instance.id, cycles }, 'All reviewers approved');
|
|
90
|
-
return { approved: true, cycles };
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
else if (leadReview.toUpperCase().includes('REWORK:')) {
|
|
95
|
-
// Lead rejected — parse rework and loop
|
|
96
|
-
const reworkTasks = parseReworkInstructions(leadReview, instance.tasks);
|
|
97
|
-
if (reworkTasks.length > 0) {
|
|
98
|
-
log.info({ instanceId: instance.id, cycle: cycles, reworkCount: reworkTasks.length }, 'Lead rejected, reworking');
|
|
99
|
-
await transitionInstance(instance.id, 'working');
|
|
100
|
-
await executeRework({ instance, runtime, reworkTasks });
|
|
101
|
-
await transitionInstance(instance.id, 'reviewing');
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
// Couldn't parse rework instructions — treat as approved to avoid infinite loop
|
|
105
|
-
log.warn({ instanceId: instance.id }, 'Could not parse rework instructions, treating as approved');
|
|
106
|
-
return { approved: true, cycles };
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
// Ambiguous response — treat as approved
|
|
111
|
-
log.warn({ instanceId: instance.id }, 'Ambiguous review response, treating as approved');
|
|
112
|
-
return { approved: true, cycles };
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
// Exhausted review cycles — send to inbox
|
|
116
|
-
const failureReason = `Failed to pass review after ${MAX_REVIEW_CYCLES} cycles for objective: ${objective}`;
|
|
117
|
-
log.error({ instanceId: instance.id }, failureReason);
|
|
118
|
-
await addInboxEntry({
|
|
119
|
-
squadId: instance.squadId,
|
|
120
|
-
instanceId: instance.id,
|
|
121
|
-
kind: 'note',
|
|
122
|
-
title: `Review failed: ${objective.slice(0, 60)}`,
|
|
123
|
-
content: `Instance ${instance.id} exhausted ${MAX_REVIEW_CYCLES} review/rework cycles without reaching approval.\n\nObjective: ${objective}\n\nFinal task states:\n${instance.tasks.map((t) => `- [${t.status}] ${t.description}: ${(t.result ?? 'no result').slice(0, 200)}`).join('\n')}`,
|
|
124
|
-
});
|
|
125
|
-
return { approved: false, cycles, failureReason };
|
|
126
|
-
}
|
|
127
|
-
/**
|
|
128
|
-
* Parse rework instructions from a review response.
|
|
129
|
-
* Expects JSON array after "REWORK:" with {taskId, feedback} objects.
|
|
130
|
-
* Falls back to assigning feedback to all non-done tasks if parsing fails.
|
|
131
|
-
*/
|
|
132
|
-
function parseReworkInstructions(response, tasks) {
|
|
133
|
-
const reworkMatch = response.match(/REWORK:\s*(\[[\s\S]*?\])/i);
|
|
134
|
-
if (reworkMatch) {
|
|
135
|
-
try {
|
|
136
|
-
const parsed = JSON.parse(reworkMatch[1]);
|
|
137
|
-
if (Array.isArray(parsed)) {
|
|
138
|
-
return parsed
|
|
139
|
-
.filter((item) => item.taskId && item.feedback)
|
|
140
|
-
.map((item) => ({
|
|
141
|
-
taskId: item.taskId,
|
|
142
|
-
feedback: item.feedback,
|
|
143
|
-
}));
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
catch {
|
|
147
|
-
// Fall through to fallback
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
// Fallback: extract plain-text feedback and apply to all completed tasks
|
|
151
|
-
const feedbackMatch = response.match(/REWORK:\s*([\s\S]+)/i);
|
|
152
|
-
const feedback = feedbackMatch?.[1]?.trim() ?? 'Please review and fix issues.';
|
|
153
|
-
return tasks
|
|
154
|
-
.filter((t) => t.status === 'done' || t.status === 'failed')
|
|
155
|
-
.map((t) => ({ taskId: t.id, feedback }));
|
|
156
|
-
}
|
|
157
|
-
//# sourceMappingURL=review.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/squad/execution/review.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import type { Squad } from '@io/shared';
|
|
2
|
-
import { type SquadRuntime } from '../manager.js';
|
|
3
|
-
import { type Instance, type PrResult } from './index.js';
|
|
4
|
-
export interface RunResult {
|
|
5
|
-
instanceId: string;
|
|
6
|
-
success: boolean;
|
|
7
|
-
pr?: PrResult | null;
|
|
8
|
-
error?: string;
|
|
9
|
-
}
|
|
10
|
-
export interface InitResult {
|
|
11
|
-
instance: Instance;
|
|
12
|
-
runtime: SquadRuntime;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Initialize an instance: boot the squad runtime and persist the instance to DB.
|
|
16
|
-
* This is the critical part that MUST succeed before we tell the user "started."
|
|
17
|
-
*/
|
|
18
|
-
export declare function initInstance(params: {
|
|
19
|
-
squad: Squad;
|
|
20
|
-
objective: string;
|
|
21
|
-
issueRef?: string;
|
|
22
|
-
}): Promise<InitResult>;
|
|
23
|
-
/**
|
|
24
|
-
* Execute an already-initialized instance through its full lifecycle:
|
|
25
|
-
* planning → tasks → review → PR → cleanup
|
|
26
|
-
*/
|
|
27
|
-
export declare function executeInstance(params: {
|
|
28
|
-
instance: Instance;
|
|
29
|
-
runtime: SquadRuntime;
|
|
30
|
-
squad: Squad;
|
|
31
|
-
objective: string;
|
|
32
|
-
attachments?: Array<{
|
|
33
|
-
type: 'file';
|
|
34
|
-
path: string;
|
|
35
|
-
displayName?: string;
|
|
36
|
-
}>;
|
|
37
|
-
}): Promise<RunResult>;
|
|
38
|
-
/**
|
|
39
|
-
* Run a full instance lifecycle (init + execute).
|
|
40
|
-
* Convenience wrapper for callers that don't need to split the phases.
|
|
41
|
-
*/
|
|
42
|
-
export declare function runInstance(params: {
|
|
43
|
-
squad: Squad;
|
|
44
|
-
objective: string;
|
|
45
|
-
issueRef?: string;
|
|
46
|
-
attachments?: Array<{
|
|
47
|
-
type: 'file';
|
|
48
|
-
path: string;
|
|
49
|
-
displayName?: string;
|
|
50
|
-
}>;
|
|
51
|
-
}): Promise<RunResult>;
|
|
52
|
-
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../../src/squad/execution/runner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,OAAO,EAAE,KAAK,YAAY,EAA8B,MAAM,eAAe,CAAC;AAC9E,OAAO,EACN,KAAK,QAAQ,EACb,KAAK,QAAQ,EAOb,MAAM,YAAY,CAAC;AAIpB,MAAM,WAAW,SAAS;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IAC1B,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE;IAC1C,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,UAAU,CAAC,CAatB;AAED;;;GAGG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC7C,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E,GAAG,OAAO,CAAC,SAAS,CAAC,CAsErB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE;IACzC,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC1E,GAAG,OAAO,CAAC,SAAS,CAAC,CAMrB"}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import { createChildLogger } from '../../logging/logger.js';
|
|
2
|
-
import { bootSquad, getSquadRuntime } from '../manager.js';
|
|
3
|
-
import { cleanupInstance, createInstance, createPullRequest, executeTasks, planInstance, reviewWork, } from './index.js';
|
|
4
|
-
const logger = () => createChildLogger('runner');
|
|
5
|
-
/**
|
|
6
|
-
* Initialize an instance: boot the squad runtime and persist the instance to DB.
|
|
7
|
-
* This is the critical part that MUST succeed before we tell the user "started."
|
|
8
|
-
*/
|
|
9
|
-
export async function initInstance(params) {
|
|
10
|
-
const { squad, objective, issueRef } = params;
|
|
11
|
-
// Ensure squad is booted
|
|
12
|
-
let runtime = getSquadRuntime(squad.id);
|
|
13
|
-
if (!runtime) {
|
|
14
|
-
runtime = await bootSquad(squad);
|
|
15
|
-
}
|
|
16
|
-
// Create instance (persists to DB + creates worktree)
|
|
17
|
-
const instance = await createInstance({ squad, issueRef, objective });
|
|
18
|
-
return { instance, runtime };
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Execute an already-initialized instance through its full lifecycle:
|
|
22
|
-
* planning → tasks → review → PR → cleanup
|
|
23
|
-
*/
|
|
24
|
-
export async function executeInstance(params) {
|
|
25
|
-
const log = logger();
|
|
26
|
-
const { instance, runtime, squad, objective, attachments } = params;
|
|
27
|
-
log.info({ instanceId: instance.id }, 'Starting instance execution');
|
|
28
|
-
try {
|
|
29
|
-
// Team Lead plans
|
|
30
|
-
await planInstance({ instance, runtime, objective, attachments });
|
|
31
|
-
if (instance.abortController.signal.aborted) {
|
|
32
|
-
return { instanceId: instance.id, success: false, error: 'Cancelled' };
|
|
33
|
-
}
|
|
34
|
-
if (instance.tasks.length === 0) {
|
|
35
|
-
log.warn({ instanceId: instance.id }, 'No tasks generated from planning');
|
|
36
|
-
return {
|
|
37
|
-
instanceId: instance.id,
|
|
38
|
-
success: false,
|
|
39
|
-
error: 'Planning produced no actionable tasks',
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
// Execute tasks in parallel
|
|
43
|
-
await executeTasks({ instance, runtime });
|
|
44
|
-
if (instance.abortController.signal.aborted) {
|
|
45
|
-
return { instanceId: instance.id, success: false, error: 'Cancelled' };
|
|
46
|
-
}
|
|
47
|
-
// Gated review/rework cycles
|
|
48
|
-
const reviewResult = await reviewWork({ instance, runtime, objective });
|
|
49
|
-
if (instance.abortController.signal.aborted) {
|
|
50
|
-
return { instanceId: instance.id, success: false, error: 'Cancelled' };
|
|
51
|
-
}
|
|
52
|
-
if (!reviewResult.approved) {
|
|
53
|
-
await cleanupInstance(instance.id, squad);
|
|
54
|
-
return {
|
|
55
|
-
instanceId: instance.id,
|
|
56
|
-
success: false,
|
|
57
|
-
error: reviewResult.failureReason ?? 'Review failed',
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
// Create PR
|
|
61
|
-
const prTitle = objective.slice(0, 72);
|
|
62
|
-
const pr = await createPullRequest({ instance, title: prTitle, squadName: squad.name });
|
|
63
|
-
// Cleanup (if no PR was created — otherwise keep the branch for review)
|
|
64
|
-
if (!pr) {
|
|
65
|
-
await cleanupInstance(instance.id, squad);
|
|
66
|
-
}
|
|
67
|
-
return {
|
|
68
|
-
instanceId: instance.id,
|
|
69
|
-
success: true,
|
|
70
|
-
pr,
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
catch (err) {
|
|
74
|
-
const errMsg = err instanceof Error ? err.message : String(err);
|
|
75
|
-
log.error({ instanceId: instance.id, error: errMsg.slice(0, 300) }, 'Instance execution failed');
|
|
76
|
-
await cleanupInstance(instance.id, squad);
|
|
77
|
-
return {
|
|
78
|
-
instanceId: instance.id,
|
|
79
|
-
success: false,
|
|
80
|
-
error: errMsg.slice(0, 500),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Run a full instance lifecycle (init + execute).
|
|
86
|
-
* Convenience wrapper for callers that don't need to split the phases.
|
|
87
|
-
*/
|
|
88
|
-
export async function runInstance(params) {
|
|
89
|
-
const { squad, objective, issueRef, attachments } = params;
|
|
90
|
-
const { instance, runtime } = await initInstance({ squad, objective, issueRef });
|
|
91
|
-
return executeInstance({ instance, runtime, squad, objective, attachments });
|
|
92
|
-
}
|
|
93
|
-
//# sourceMappingURL=runner.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/squad/execution/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { SquadRuntime } from '../manager.js';
|
|
2
|
-
import { type Instance } from './instance.js';
|
|
3
|
-
/**
|
|
4
|
-
* Execute all tasks in parallel.
|
|
5
|
-
* No per-task review — that's handled by the review phase.
|
|
6
|
-
*/
|
|
7
|
-
export declare function executeTasks(params: {
|
|
8
|
-
instance: Instance;
|
|
9
|
-
runtime: SquadRuntime;
|
|
10
|
-
}): Promise<void>;
|
|
11
|
-
/**
|
|
12
|
-
* Execute tasks that need rework (called during review cycles).
|
|
13
|
-
*/
|
|
14
|
-
export declare function executeRework(params: {
|
|
15
|
-
instance: Instance;
|
|
16
|
-
runtime: SquadRuntime;
|
|
17
|
-
reworkTasks: Array<{
|
|
18
|
-
taskId: string;
|
|
19
|
-
feedback: string;
|
|
20
|
-
}>;
|
|
21
|
-
}): Promise<void>;
|
|
22
|
-
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../../src/squad/execution/tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,OAAO,EAAE,KAAK,QAAQ,EAAyC,MAAM,eAAe,CAAC;AAIrF;;;GAGG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE;IAC1C,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC3C,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,WAAW,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD,GAAG,OAAO,CAAC,IAAI,CAAC,CA8ChB"}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
import { createChildLogger } from '../../logging/logger.js';
|
|
2
|
-
import { selectModelForTask } from '../model-selector.js';
|
|
3
|
-
import { transitionInstance } from './instance.js';
|
|
4
|
-
const logger = () => createChildLogger('task-exec');
|
|
5
|
-
/**
|
|
6
|
-
* Execute all tasks in parallel.
|
|
7
|
-
* No per-task review — that's handled by the review phase.
|
|
8
|
-
*/
|
|
9
|
-
export async function executeTasks(params) {
|
|
10
|
-
const log = logger();
|
|
11
|
-
const { instance, runtime } = params;
|
|
12
|
-
if (!instance.worktree) {
|
|
13
|
-
throw new Error('Cannot execute tasks: no worktree available. Instance has no working directory for agents.');
|
|
14
|
-
}
|
|
15
|
-
await transitionInstance(instance.id, 'working');
|
|
16
|
-
const teamLead = runtime.members.get('technical-pm');
|
|
17
|
-
if (!teamLead)
|
|
18
|
-
throw new Error('No team lead for task execution');
|
|
19
|
-
// Execute all tasks concurrently
|
|
20
|
-
await Promise.all(instance.tasks
|
|
21
|
-
.filter((task) => task.status !== 'done')
|
|
22
|
-
.map((task) => executeTask(task, instance, runtime, log)));
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Execute tasks that need rework (called during review cycles).
|
|
26
|
-
*/
|
|
27
|
-
export async function executeRework(params) {
|
|
28
|
-
const log = logger();
|
|
29
|
-
const { instance, runtime, reworkTasks } = params;
|
|
30
|
-
await Promise.all(reworkTasks.map(async ({ taskId, feedback }) => {
|
|
31
|
-
const task = instance.tasks.find((t) => t.id === taskId);
|
|
32
|
-
if (!task)
|
|
33
|
-
return;
|
|
34
|
-
task.retryCount++;
|
|
35
|
-
task.status = 'in_progress';
|
|
36
|
-
const agent = runtime.members.get(task.assignedTo);
|
|
37
|
-
if (!agent) {
|
|
38
|
-
task.status = 'failed';
|
|
39
|
-
task.result = `No agent with role '${task.assignedTo}' available.`;
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
// Track activity under this instance
|
|
43
|
-
agent.setInstanceId(instance.id);
|
|
44
|
-
const workingDir = instance.worktree?.path ?? '';
|
|
45
|
-
if (workingDir) {
|
|
46
|
-
agent.setWorkingDir(workingDir);
|
|
47
|
-
}
|
|
48
|
-
const model = selectModelForTask(task.modelTier, task.retryCount);
|
|
49
|
-
if (agent.getModel() !== model) {
|
|
50
|
-
await agent.switchModel(model);
|
|
51
|
-
}
|
|
52
|
-
try {
|
|
53
|
-
const workingDir = instance.worktree?.path ?? '';
|
|
54
|
-
const result = await agent.send(`Your previous work on "${task.description}" needs revision.\n\nFeedback: ${feedback}\n\n${workingDir ? `Working directory: ${workingDir}\n\n` : ''}Please address this feedback. Write/edit code and run tests to verify.\n\nIMPORTANT: Do NOT run git commands, create commits, or make PRs — the system handles that after review.`);
|
|
55
|
-
task.result = result;
|
|
56
|
-
task.status = 'done';
|
|
57
|
-
log.info({ taskId: task.id, retryCount: task.retryCount }, 'Rework task completed');
|
|
58
|
-
}
|
|
59
|
-
catch (err) {
|
|
60
|
-
log.error({ err, taskId: task.id }, 'Rework task failed');
|
|
61
|
-
task.status = 'failed';
|
|
62
|
-
task.result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
63
|
-
}
|
|
64
|
-
}));
|
|
65
|
-
}
|
|
66
|
-
async function executeTask(task, instance, runtime, log) {
|
|
67
|
-
log.info({ taskId: task.id, assignedTo: task.assignedTo, modelTier: task.modelTier }, 'Executing task');
|
|
68
|
-
task.status = 'in_progress';
|
|
69
|
-
const agent = runtime.members.get(task.assignedTo);
|
|
70
|
-
if (!agent) {
|
|
71
|
-
log.warn({ role: task.assignedTo }, 'No agent for assigned role');
|
|
72
|
-
task.result = `No agent with role '${task.assignedTo}' available.`;
|
|
73
|
-
task.status = 'failed';
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
// Track activity under this instance and set working directory for tools
|
|
77
|
-
agent.setInstanceId(instance.id);
|
|
78
|
-
const workingDir = instance.worktree?.path ?? '';
|
|
79
|
-
if (workingDir) {
|
|
80
|
-
agent.setWorkingDir(workingDir);
|
|
81
|
-
}
|
|
82
|
-
const model = selectModelForTask(task.modelTier, task.retryCount);
|
|
83
|
-
if (agent.getModel() !== model) {
|
|
84
|
-
await agent.switchModel(model);
|
|
85
|
-
}
|
|
86
|
-
try {
|
|
87
|
-
const workingDir = instance.worktree?.path ?? '';
|
|
88
|
-
const taskPrompt = buildTaskPrompt(task, workingDir, instance);
|
|
89
|
-
const result = await agent.send(taskPrompt);
|
|
90
|
-
task.result = result;
|
|
91
|
-
task.status = 'done';
|
|
92
|
-
log.info({ taskId: task.id }, 'Task completed');
|
|
93
|
-
}
|
|
94
|
-
catch (err) {
|
|
95
|
-
log.error({ err, taskId: task.id }, 'Task execution failed');
|
|
96
|
-
task.status = 'failed';
|
|
97
|
-
task.result = `Error: ${err instanceof Error ? err.message : String(err)}`;
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
function buildTaskPrompt(task, workingDir, instance) {
|
|
101
|
-
const parts = ['You have been assigned the following task:', `\nTask: ${task.description}`];
|
|
102
|
-
if (workingDir) {
|
|
103
|
-
parts.push(`\nWorking directory: ${workingDir}`);
|
|
104
|
-
}
|
|
105
|
-
if (instance.issueRef) {
|
|
106
|
-
parts.push(`\nRelated issue: ${instance.issueRef}`);
|
|
107
|
-
}
|
|
108
|
-
parts.push('\nComplete the task by writing code and tests in the working directory. Use your available tools to read, write, and test code.', '\n\nIMPORTANT RULES:', '\n- Do NOT run git commands (commit, push, branch, checkout, etc.) — the system handles all git operations after review.', '\n- Do NOT create pull requests or attempt to merge anything.', '\n- Do NOT modify files outside the working directory.', '\n- Focus ONLY on writing/editing code and running tests to verify your work.', '\n\nWhen done, report a brief summary of what you changed.');
|
|
109
|
-
return parts.join('');
|
|
110
|
-
}
|
|
111
|
-
//# sourceMappingURL=tasks.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../../src/squad/execution/tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
export interface WorktreeInfo {
|
|
2
|
-
path: string;
|
|
3
|
-
branch: string;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Create a git worktree for an instance.
|
|
7
|
-
* Branch naming: io/{squad-name}/{short-id}
|
|
8
|
-
* Always fetches latest from remote before creating the worktree.
|
|
9
|
-
*/
|
|
10
|
-
export declare function createWorktree(params: {
|
|
11
|
-
repoPath: string;
|
|
12
|
-
squadName: string;
|
|
13
|
-
instanceId: string;
|
|
14
|
-
}): Promise<WorktreeInfo>;
|
|
15
|
-
/**
|
|
16
|
-
* Remove a git worktree and delete its branch.
|
|
17
|
-
*/
|
|
18
|
-
export declare function removeWorktree(params: {
|
|
19
|
-
repoPath: string;
|
|
20
|
-
worktreePath: string;
|
|
21
|
-
branch: string;
|
|
22
|
-
}): Promise<void>;
|
|
23
|
-
/**
|
|
24
|
-
* List all IO-managed worktrees for a repository.
|
|
25
|
-
*/
|
|
26
|
-
export declare function listWorktrees(repoPath: string): Promise<WorktreeInfo[]>;
|
|
27
|
-
//# sourceMappingURL=worktree.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../../src/squad/execution/worktree.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,YAAY,CAAC,CAwCxB;AAyCD;;GAEG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;CACf,GAAG,OAAO,CAAC,IAAI,CAAC,CA4BhB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAyB7E"}
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
import { exec as execCb } from 'node:child_process';
|
|
2
|
-
import { existsSync, rmSync } from 'node:fs';
|
|
3
|
-
import { join } from 'node:path';
|
|
4
|
-
import { promisify } from 'node:util';
|
|
5
|
-
import { createChildLogger } from '../../logging/logger.js';
|
|
6
|
-
const exec = promisify(execCb);
|
|
7
|
-
const logger = () => createChildLogger('worktree');
|
|
8
|
-
/**
|
|
9
|
-
* Create a git worktree for an instance.
|
|
10
|
-
* Branch naming: io/{squad-name}/{short-id}
|
|
11
|
-
* Always fetches latest from remote before creating the worktree.
|
|
12
|
-
*/
|
|
13
|
-
export async function createWorktree(params) {
|
|
14
|
-
const log = logger();
|
|
15
|
-
const shortId = params.instanceId.slice(0, 8);
|
|
16
|
-
const branch = `io/${params.squadName}/${shortId}`;
|
|
17
|
-
const worktreePath = join(params.repoPath, '..', '.io-worktrees', `${params.squadName}-${shortId}`);
|
|
18
|
-
// Ensure the repo is a git repository
|
|
19
|
-
if (!existsSync(join(params.repoPath, '.git'))) {
|
|
20
|
-
throw new Error(`Not a git repository: ${params.repoPath}`);
|
|
21
|
-
}
|
|
22
|
-
// Fetch latest from remote to ensure we branch from up-to-date code
|
|
23
|
-
const startPoint = await fetchLatestMainRef(params.repoPath);
|
|
24
|
-
log.info({ startPoint }, 'Fetched latest remote ref for worktree');
|
|
25
|
-
// Create the worktree with a new branch from the latest remote HEAD
|
|
26
|
-
try {
|
|
27
|
-
await exec(`git worktree add -b "${branch}" "${worktreePath}" "${startPoint}"`, {
|
|
28
|
-
cwd: params.repoPath,
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
// Branch might already exist — try without -b
|
|
33
|
-
try {
|
|
34
|
-
await exec(`git worktree add "${worktreePath}" "${branch}"`, {
|
|
35
|
-
cwd: params.repoPath,
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
catch (innerErr) {
|
|
39
|
-
throw new Error(`Failed to create worktree: ${innerErr instanceof Error ? innerErr.message : String(innerErr)}`);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
log.info({ worktreePath, branch }, 'Worktree created');
|
|
43
|
-
return { path: worktreePath, branch };
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Fetch the latest from the remote and return the ref to branch from.
|
|
47
|
-
* Detects the default branch (main/master) from the remote HEAD.
|
|
48
|
-
*/
|
|
49
|
-
async function fetchLatestMainRef(repoPath) {
|
|
50
|
-
try {
|
|
51
|
-
await exec('git fetch origin', { cwd: repoPath });
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
// Fetch failed (offline, no remote, etc.) — fall back to local HEAD
|
|
55
|
-
return 'HEAD';
|
|
56
|
-
}
|
|
57
|
-
// Determine the default branch from the remote
|
|
58
|
-
try {
|
|
59
|
-
const { stdout } = await exec('git symbolic-ref refs/remotes/origin/HEAD', {
|
|
60
|
-
cwd: repoPath,
|
|
61
|
-
});
|
|
62
|
-
const remoteHead = stdout.trim();
|
|
63
|
-
if (remoteHead) {
|
|
64
|
-
return remoteHead;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
// symbolic-ref not set — try common branch names
|
|
69
|
-
}
|
|
70
|
-
// Fallback: try origin/main, then origin/master
|
|
71
|
-
for (const candidate of ['origin/main', 'origin/master']) {
|
|
72
|
-
try {
|
|
73
|
-
await exec(`git rev-parse --verify ${candidate}`, { cwd: repoPath });
|
|
74
|
-
return candidate;
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
continue;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Last resort: local HEAD
|
|
81
|
-
return 'HEAD';
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Remove a git worktree and delete its branch.
|
|
85
|
-
*/
|
|
86
|
-
export async function removeWorktree(params) {
|
|
87
|
-
const log = logger();
|
|
88
|
-
try {
|
|
89
|
-
await exec(`git worktree remove "${params.worktreePath}" --force`, {
|
|
90
|
-
cwd: params.repoPath,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
catch {
|
|
94
|
-
// Worktree might already be removed; try cleaning up the directory
|
|
95
|
-
if (existsSync(params.worktreePath)) {
|
|
96
|
-
rmSync(params.worktreePath, { recursive: true, force: true });
|
|
97
|
-
}
|
|
98
|
-
// Prune worktree references
|
|
99
|
-
try {
|
|
100
|
-
await exec('git worktree prune', { cwd: params.repoPath });
|
|
101
|
-
}
|
|
102
|
-
catch {
|
|
103
|
-
// ignore
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
// Delete the branch
|
|
107
|
-
try {
|
|
108
|
-
await exec(`git branch -D "${params.branch}"`, { cwd: params.repoPath });
|
|
109
|
-
}
|
|
110
|
-
catch {
|
|
111
|
-
// Branch might not exist or be checked out elsewhere
|
|
112
|
-
}
|
|
113
|
-
log.info({ branch: params.branch }, 'Worktree removed');
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* List all IO-managed worktrees for a repository.
|
|
117
|
-
*/
|
|
118
|
-
export async function listWorktrees(repoPath) {
|
|
119
|
-
try {
|
|
120
|
-
const { stdout } = await exec('git worktree list --porcelain', { cwd: repoPath });
|
|
121
|
-
const worktrees = [];
|
|
122
|
-
const blocks = stdout.split('\n\n');
|
|
123
|
-
for (const block of blocks) {
|
|
124
|
-
const lines = block.trim().split('\n');
|
|
125
|
-
const pathLine = lines.find((l) => l.startsWith('worktree '));
|
|
126
|
-
const branchLine = lines.find((l) => l.startsWith('branch '));
|
|
127
|
-
if (pathLine && branchLine) {
|
|
128
|
-
const path = pathLine.replace('worktree ', '');
|
|
129
|
-
const branch = branchLine.replace('branch refs/heads/', '');
|
|
130
|
-
if (branch.startsWith('io/')) {
|
|
131
|
-
worktrees.push({ path, branch });
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return worktrees;
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
return [];
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
//# sourceMappingURL=worktree.js.map
|