@snappedly-tools/shipyard 0.11.0-staging.36389018601 → 0.11.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.
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/templates/parallel-planner/main.mts +8 -38
- package/dist/templates/parallel-planner-with-review/main.mts +8 -38
- package/dist/templates/sequential-reviewer/main.mts +5 -31
- package/dist/templates/simple-loop/main.mts +5 -31
- package/package.json +1 -1
|
@@ -96,7 +96,7 @@ const closeClean = async (sandbox: {
|
|
|
96
96
|
if (preservedWorktreePath)
|
|
97
97
|
throw new Error(`Sandbox has uncommitted work at ${preservedWorktreePath}`);
|
|
98
98
|
};
|
|
99
|
-
const verifyTriage = (ticketId: string
|
|
99
|
+
const verifyTriage = (ticketId: string) => {
|
|
100
100
|
try {
|
|
101
101
|
execFileSync("bash", [".shipyard/verify-triage.sh", ticketId, repository], {
|
|
102
102
|
encoding: "utf8",
|
|
@@ -105,31 +105,9 @@ const verifyTriage = (ticketId: string, triageOutput?: string) => {
|
|
|
105
105
|
const detail = (error as { stderr?: string | Buffer }).stderr
|
|
106
106
|
?.toString()
|
|
107
107
|
.trim();
|
|
108
|
-
|
|
109
|
-
const output = triageOutput?.trim();
|
|
110
|
-
throw new Error(
|
|
111
|
-
output ? `${reason}; triage output: ${output.slice(-1200)}` : reason,
|
|
112
|
-
);
|
|
108
|
+
throw new Error(detail || `Could not verify triage for #${ticketId}`);
|
|
113
109
|
}
|
|
114
110
|
};
|
|
115
|
-
const verifyTriageAccess = async (
|
|
116
|
-
sandbox: {
|
|
117
|
-
exec: (
|
|
118
|
-
command: string,
|
|
119
|
-
) => Promise<{ exitCode: number; stdout: string; stderr: string }>;
|
|
120
|
-
},
|
|
121
|
-
ticketId: string,
|
|
122
|
-
) => {
|
|
123
|
-
if (!/^\d+$/.test(ticketId))
|
|
124
|
-
throw new Error(`Invalid issue number: ${ticketId}`);
|
|
125
|
-
const result = await sandbox.exec(
|
|
126
|
-
`gh issue view ${ticketId} --repo ${repository} --json number --jq .number`,
|
|
127
|
-
);
|
|
128
|
-
if (result.exitCode !== 0)
|
|
129
|
-
throw new Error(
|
|
130
|
-
`Cannot triage issue #${ticketId}: GitHub access failed in the sandbox: ${result.stderr.trim() || result.stdout.trim() || `exit ${result.exitCode}`}`,
|
|
131
|
-
);
|
|
132
|
-
};
|
|
133
111
|
const planSchema = z.object({ issues: z.array(z.object({ id: z.string() })) });
|
|
134
112
|
type Ticket = {
|
|
135
113
|
id: string;
|
|
@@ -196,19 +174,15 @@ const runWorker = async (scope: Scope, ticket: Ticket) => {
|
|
|
196
174
|
copyToWorktree: [".shipyard/setup.sh"],
|
|
197
175
|
});
|
|
198
176
|
try {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
await verifyTriageAccess(sandbox, ticket.id);
|
|
202
|
-
const triage = await sandbox.run({
|
|
177
|
+
if (!ticket.triageReady)
|
|
178
|
+
await sandbox.run({
|
|
203
179
|
name: `triage #${ticket.id}`,
|
|
204
180
|
maxIterations: 1,
|
|
205
181
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
206
182
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
207
183
|
promptArgs: { TASK_ID: ticket.id, BASE_BRANCH: targetBranch },
|
|
208
184
|
});
|
|
209
|
-
|
|
210
|
-
}
|
|
211
|
-
verifyTriage(ticket.id, triageOutput);
|
|
185
|
+
verifyTriage(ticket.id);
|
|
212
186
|
const implementation = await sandbox.run({
|
|
213
187
|
name: "implementer",
|
|
214
188
|
maxIterations: 100,
|
|
@@ -473,19 +447,15 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
473
447
|
let handoffEvidence: string;
|
|
474
448
|
try {
|
|
475
449
|
if (scope.kind === "standalone") {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
await verifyTriageAccess(integration, id);
|
|
479
|
-
const triage = await integration.run({
|
|
450
|
+
if (!scope.triageReady)
|
|
451
|
+
await integration.run({
|
|
480
452
|
name: `triage #${id}`,
|
|
481
453
|
maxIterations: 1,
|
|
482
454
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
483
455
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
484
456
|
promptArgs: { TASK_ID: id, BASE_BRANCH: targetBranch },
|
|
485
457
|
});
|
|
486
|
-
|
|
487
|
-
}
|
|
488
|
-
verifyTriage(id, triageOutput);
|
|
458
|
+
verifyTriage(id);
|
|
489
459
|
const standalone = await integration.run({
|
|
490
460
|
name: "implementer",
|
|
491
461
|
maxIterations: 100,
|
|
@@ -96,7 +96,7 @@ const closeClean = async (sandbox: {
|
|
|
96
96
|
if (preservedWorktreePath)
|
|
97
97
|
throw new Error(`Sandbox has uncommitted work at ${preservedWorktreePath}`);
|
|
98
98
|
};
|
|
99
|
-
const verifyTriage = (ticketId: string
|
|
99
|
+
const verifyTriage = (ticketId: string) => {
|
|
100
100
|
try {
|
|
101
101
|
execFileSync("bash", [".shipyard/verify-triage.sh", ticketId, repository], {
|
|
102
102
|
encoding: "utf8",
|
|
@@ -105,31 +105,9 @@ const verifyTriage = (ticketId: string, triageOutput?: string) => {
|
|
|
105
105
|
const detail = (error as { stderr?: string | Buffer }).stderr
|
|
106
106
|
?.toString()
|
|
107
107
|
.trim();
|
|
108
|
-
|
|
109
|
-
const output = triageOutput?.trim();
|
|
110
|
-
throw new Error(
|
|
111
|
-
output ? `${reason}; triage output: ${output.slice(-1200)}` : reason,
|
|
112
|
-
);
|
|
108
|
+
throw new Error(detail || `Could not verify triage for #${ticketId}`);
|
|
113
109
|
}
|
|
114
110
|
};
|
|
115
|
-
const verifyTriageAccess = async (
|
|
116
|
-
sandbox: {
|
|
117
|
-
exec: (
|
|
118
|
-
command: string,
|
|
119
|
-
) => Promise<{ exitCode: number; stdout: string; stderr: string }>;
|
|
120
|
-
},
|
|
121
|
-
ticketId: string,
|
|
122
|
-
) => {
|
|
123
|
-
if (!/^\d+$/.test(ticketId))
|
|
124
|
-
throw new Error(`Invalid issue number: ${ticketId}`);
|
|
125
|
-
const result = await sandbox.exec(
|
|
126
|
-
`gh issue view ${ticketId} --repo ${repository} --json number --jq .number`,
|
|
127
|
-
);
|
|
128
|
-
if (result.exitCode !== 0)
|
|
129
|
-
throw new Error(
|
|
130
|
-
`Cannot triage issue #${ticketId}: GitHub access failed in the sandbox: ${result.stderr.trim() || result.stdout.trim() || `exit ${result.exitCode}`}`,
|
|
131
|
-
);
|
|
132
|
-
};
|
|
133
111
|
const planSchema = z.object({ issues: z.array(z.object({ id: z.string() })) });
|
|
134
112
|
type Ticket = {
|
|
135
113
|
id: string;
|
|
@@ -206,19 +184,15 @@ const runWorker = async (scope: Scope, ticket: Ticket) => {
|
|
|
206
184
|
copyToWorktree: [".shipyard/setup.sh"],
|
|
207
185
|
});
|
|
208
186
|
try {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
await verifyTriageAccess(sandbox, ticket.id);
|
|
212
|
-
const triage = await sandbox.run({
|
|
187
|
+
if (!ticket.triageReady)
|
|
188
|
+
await sandbox.run({
|
|
213
189
|
name: `triage #${ticket.id}`,
|
|
214
190
|
maxIterations: 1,
|
|
215
191
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
216
192
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
217
193
|
promptArgs: { TASK_ID: ticket.id, BASE_BRANCH: targetBranch },
|
|
218
194
|
});
|
|
219
|
-
|
|
220
|
-
}
|
|
221
|
-
verifyTriage(ticket.id, triageOutput);
|
|
195
|
+
verifyTriage(ticket.id);
|
|
222
196
|
const implementation = await sandbox.run({
|
|
223
197
|
name: "implementer",
|
|
224
198
|
maxIterations: 100,
|
|
@@ -496,19 +470,15 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
496
470
|
let handoffEvidence: string;
|
|
497
471
|
try {
|
|
498
472
|
if (scope.kind === "standalone") {
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
await verifyTriageAccess(integration, id);
|
|
502
|
-
const triage = await integration.run({
|
|
473
|
+
if (!scope.triageReady)
|
|
474
|
+
await integration.run({
|
|
503
475
|
name: `triage #${id}`,
|
|
504
476
|
maxIterations: 1,
|
|
505
477
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
506
478
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
507
479
|
promptArgs: { TASK_ID: id, BASE_BRANCH: targetBranch },
|
|
508
480
|
});
|
|
509
|
-
|
|
510
|
-
}
|
|
511
|
-
verifyTriage(id, triageOutput);
|
|
481
|
+
verifyTriage(id);
|
|
512
482
|
const standalone = await integration.run({
|
|
513
483
|
name: "implementer",
|
|
514
484
|
maxIterations: 100,
|
|
@@ -93,7 +93,7 @@ const closeClean = async (sandbox: {
|
|
|
93
93
|
if (preservedWorktreePath)
|
|
94
94
|
throw new Error(`Sandbox has uncommitted work at ${preservedWorktreePath}`);
|
|
95
95
|
};
|
|
96
|
-
const verifyTriage = (ticketId: string
|
|
96
|
+
const verifyTriage = (ticketId: string) => {
|
|
97
97
|
try {
|
|
98
98
|
execFileSync("bash", [".shipyard/verify-triage.sh", ticketId, repository], {
|
|
99
99
|
encoding: "utf8",
|
|
@@ -102,31 +102,9 @@ const verifyTriage = (ticketId: string, triageOutput?: string) => {
|
|
|
102
102
|
const detail = (error as { stderr?: string | Buffer }).stderr
|
|
103
103
|
?.toString()
|
|
104
104
|
.trim();
|
|
105
|
-
|
|
106
|
-
const output = triageOutput?.trim();
|
|
107
|
-
throw new Error(
|
|
108
|
-
output ? `${reason}; triage output: ${output.slice(-1200)}` : reason,
|
|
109
|
-
);
|
|
105
|
+
throw new Error(detail || `Could not verify triage for #${ticketId}`);
|
|
110
106
|
}
|
|
111
107
|
};
|
|
112
|
-
const verifyTriageAccess = async (
|
|
113
|
-
sandbox: {
|
|
114
|
-
exec: (
|
|
115
|
-
command: string,
|
|
116
|
-
) => Promise<{ exitCode: number; stdout: string; stderr: string }>;
|
|
117
|
-
},
|
|
118
|
-
ticketId: string,
|
|
119
|
-
) => {
|
|
120
|
-
if (!/^\d+$/.test(ticketId))
|
|
121
|
-
throw new Error(`Invalid issue number: ${ticketId}`);
|
|
122
|
-
const result = await sandbox.exec(
|
|
123
|
-
`gh issue view ${ticketId} --repo ${repository} --json number --jq .number`,
|
|
124
|
-
);
|
|
125
|
-
if (result.exitCode !== 0)
|
|
126
|
-
throw new Error(
|
|
127
|
-
`Cannot triage issue #${ticketId}: GitHub access failed in the sandbox: ${result.stderr.trim() || result.stdout.trim() || `exit ${result.exitCode}`}`,
|
|
128
|
-
);
|
|
129
|
-
};
|
|
130
108
|
|
|
131
109
|
const handoffEvidence = (stdout: string): string | undefined =>
|
|
132
110
|
[...stdout.matchAll(/<handoff>([\s\S]*?)<\/handoff>/g)].at(-1)?.[1]?.trim();
|
|
@@ -222,19 +200,15 @@ for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
|
222
200
|
? issue.tickets?.find((ticket) => ticket.id === ticketId)
|
|
223
201
|
?.triageReady
|
|
224
202
|
: issue.triageReady;
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
await verifyTriageAccess(sandbox, ticketId);
|
|
228
|
-
const triage = await sandbox.run({
|
|
203
|
+
if (!ready)
|
|
204
|
+
await sandbox.run({
|
|
229
205
|
name: `triage #${ticketId}`,
|
|
230
206
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
231
207
|
maxIterations: 1,
|
|
232
208
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
233
209
|
promptArgs: { TASK_ID: ticketId, BASE_BRANCH: targetBranch },
|
|
234
210
|
});
|
|
235
|
-
|
|
236
|
-
}
|
|
237
|
-
verifyTriage(ticketId, triageOutput);
|
|
211
|
+
verifyTriage(ticketId);
|
|
238
212
|
}
|
|
239
213
|
const implement = await sandbox.run({
|
|
240
214
|
name: "implementer",
|
|
@@ -92,7 +92,7 @@ const closeClean = async (sandbox: {
|
|
|
92
92
|
if (preservedWorktreePath)
|
|
93
93
|
throw new Error(`Sandbox has uncommitted work at ${preservedWorktreePath}`);
|
|
94
94
|
};
|
|
95
|
-
const verifyTriage = (ticketId: string
|
|
95
|
+
const verifyTriage = (ticketId: string) => {
|
|
96
96
|
try {
|
|
97
97
|
execFileSync("bash", [".shipyard/verify-triage.sh", ticketId, repository], {
|
|
98
98
|
encoding: "utf8",
|
|
@@ -101,31 +101,9 @@ const verifyTriage = (ticketId: string, triageOutput?: string) => {
|
|
|
101
101
|
const detail = (error as { stderr?: string | Buffer }).stderr
|
|
102
102
|
?.toString()
|
|
103
103
|
.trim();
|
|
104
|
-
|
|
105
|
-
const output = triageOutput?.trim();
|
|
106
|
-
throw new Error(
|
|
107
|
-
output ? `${reason}; triage output: ${output.slice(-1200)}` : reason,
|
|
108
|
-
);
|
|
104
|
+
throw new Error(detail || `Could not verify triage for #${ticketId}`);
|
|
109
105
|
}
|
|
110
106
|
};
|
|
111
|
-
const verifyTriageAccess = async (
|
|
112
|
-
sandbox: {
|
|
113
|
-
exec: (
|
|
114
|
-
command: string,
|
|
115
|
-
) => Promise<{ exitCode: number; stdout: string; stderr: string }>;
|
|
116
|
-
},
|
|
117
|
-
ticketId: string,
|
|
118
|
-
) => {
|
|
119
|
-
if (!/^\d+$/.test(ticketId))
|
|
120
|
-
throw new Error(`Invalid issue number: ${ticketId}`);
|
|
121
|
-
const result = await sandbox.exec(
|
|
122
|
-
`gh issue view ${ticketId} --repo ${repository} --json number --jq .number`,
|
|
123
|
-
);
|
|
124
|
-
if (result.exitCode !== 0)
|
|
125
|
-
throw new Error(
|
|
126
|
-
`Cannot triage issue #${ticketId}: GitHub access failed in the sandbox: ${result.stderr.trim() || result.stdout.trim() || `exit ${result.exitCode}`}`,
|
|
127
|
-
);
|
|
128
|
-
};
|
|
129
107
|
|
|
130
108
|
const blockScope = (
|
|
131
109
|
scope: { id: string; branch: string; tickets?: Array<{ id: string }> },
|
|
@@ -219,19 +197,15 @@ for (let iteration = 0; iteration < 3; iteration++) {
|
|
|
219
197
|
? issue.tickets?.find((ticket) => ticket.id === ticketId)
|
|
220
198
|
?.triageReady
|
|
221
199
|
: issue.triageReady;
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
await verifyTriageAccess(sandbox, ticketId);
|
|
225
|
-
const triage = await sandbox.run({
|
|
200
|
+
if (!ready)
|
|
201
|
+
await sandbox.run({
|
|
226
202
|
name: `triage #${ticketId}`,
|
|
227
203
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
228
204
|
maxIterations: 1,
|
|
229
205
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
230
206
|
promptArgs: { TASK_ID: ticketId, BASE_BRANCH: targetBranch },
|
|
231
207
|
});
|
|
232
|
-
|
|
233
|
-
}
|
|
234
|
-
verifyTriage(ticketId, triageOutput);
|
|
208
|
+
verifyTriage(ticketId);
|
|
235
209
|
}
|
|
236
210
|
const result = await sandbox.run({
|
|
237
211
|
name: "implementer",
|