@snappedly-tools/shipyard 0.9.2 → 0.10.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/README.md +4 -2
- package/dist/{chunk-NQRFVKCU.js → chunk-2SEMX2NX.js} +2 -2
- package/dist/{chunk-NQRFVKCU.js.map → chunk-2SEMX2NX.js.map} +1 -1
- package/dist/{chunk-57EEKW3R.js → chunk-BAP7BWQ2.js} +17 -8
- package/dist/chunk-BAP7BWQ2.js.map +1 -0
- package/dist/{chunk-HXSZM52J.js → chunk-IVE7QDGC.js} +17 -11
- package/dist/chunk-IVE7QDGC.js.map +1 -0
- package/dist/{chunk-JZUBT4WG.js → chunk-KSTSHZNH.js} +3 -3
- package/dist/{chunk-JZUBT4WG.js.map → chunk-KSTSHZNH.js.map} +1 -1
- package/dist/{createSandbox-DmbnWAZv.d.ts → createSandbox-Bqopwday.d.ts} +6 -4
- package/dist/index.d.ts +2 -2
- package/dist/index.js +58 -13
- package/dist/index.js.map +1 -1
- package/dist/integrations/github.js +1 -1
- package/dist/main.js +26 -7
- package/dist/main.js.map +1 -1
- package/dist/sandboxes/docker.js +2 -2
- package/dist/templates/parallel-planner/block-scope.sh +6 -0
- package/dist/templates/parallel-planner/handoff.sh +7 -2
- package/dist/templates/parallel-planner/main.mts +25 -14
- package/dist/templates/parallel-planner/setup.sh +8 -1
- package/dist/templates/parallel-planner/triage-prompt.md +3 -1
- package/dist/templates/parallel-planner-with-review/block-scope.sh +6 -0
- package/dist/templates/parallel-planner-with-review/handoff.sh +7 -2
- package/dist/templates/parallel-planner-with-review/main.mts +26 -15
- package/dist/templates/parallel-planner-with-review/setup.sh +8 -1
- package/dist/templates/parallel-planner-with-review/triage-prompt.md +3 -1
- package/dist/templates/sequential-reviewer/block-scope.sh +6 -0
- package/dist/templates/sequential-reviewer/handoff.sh +7 -2
- package/dist/templates/sequential-reviewer/main.mts +21 -14
- package/dist/templates/sequential-reviewer/setup.sh +8 -1
- package/dist/templates/sequential-reviewer/triage-prompt.md +3 -1
- package/dist/templates/shared/block-scope.sh +6 -0
- package/dist/templates/shared/handoff.sh +7 -2
- package/dist/templates/shared/setup.sh +8 -1
- package/dist/templates/shared/triage-prompt.md +3 -1
- package/dist/templates/simple-loop/block-scope.sh +6 -0
- package/dist/templates/simple-loop/handoff.sh +7 -2
- package/dist/templates/simple-loop/main.mts +20 -13
- package/dist/templates/simple-loop/setup.sh +8 -1
- package/dist/templates/simple-loop/triage-prompt.md +3 -1
- package/dist/workflow.d.ts +1 -1
- package/dist/workflow.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-57EEKW3R.js.map +0 -1
- package/dist/chunk-HXSZM52J.js.map +0 -1
package/dist/sandboxes/docker.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { defaultImageName, docker } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
1
|
+
export { defaultImageName, docker } from '../chunk-KSTSHZNH.js';
|
|
2
|
+
import '../chunk-BAP7BWQ2.js';
|
|
3
3
|
//# sourceMappingURL=docker.js.map
|
|
4
4
|
//# sourceMappingURL=docker.js.map
|
|
@@ -108,6 +108,10 @@ Work was not handed off. To retry, resolve the problem, remove shipyard:blocked,
|
|
|
108
108
|
fi
|
|
109
109
|
|
|
110
110
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
111
|
+
if ! remove_issue_status "$root" ready-for-human; then
|
|
112
|
+
echo "Warning: could not clear spec triage status" >&2
|
|
113
|
+
status_synced=false
|
|
114
|
+
fi
|
|
111
115
|
if ! remove_issue_status "$root" shipyard:outstanding-tasks; then
|
|
112
116
|
echo "Warning: could not clear spec status" >&2
|
|
113
117
|
status_synced=false
|
|
@@ -122,9 +126,11 @@ else
|
|
|
122
126
|
fi
|
|
123
127
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
124
128
|
for affected_id in "${affected_ids[@]:1}"; do
|
|
129
|
+
remove_issue_status "$affected_id" ready-for-human || status=75
|
|
125
130
|
remove_issue_status "$affected_id" shipyard:pending || status=75
|
|
126
131
|
done
|
|
127
132
|
else
|
|
133
|
+
remove_issue_status "$root" ready-for-human || status=75
|
|
128
134
|
remove_issue_status "$root" shipyard:pending || status=75
|
|
129
135
|
fi
|
|
130
136
|
|
|
@@ -103,6 +103,7 @@ for ((i=1; i<${#scope_ids[@]}; i++)); do
|
|
|
103
103
|
echo "Could not mark ticket #${scope_ids[i]} complete; retry issue completion when GitHub is available" >&2
|
|
104
104
|
exit 75
|
|
105
105
|
fi
|
|
106
|
+
remove_issue_label "${scope_ids[i]}" ready-for-human
|
|
106
107
|
remove_issue_label "${scope_ids[i]}" shipyard:blocked
|
|
107
108
|
remove_issue_label "${scope_ids[i]}" shipyard:pending
|
|
108
109
|
done
|
|
@@ -128,7 +129,11 @@ if ! gh label create "$status_label" --repo "$repo" --color "$status_color" --de
|
|
|
128
129
|
echo "Warning: could not create $status_label" >&2
|
|
129
130
|
status_synced=false
|
|
130
131
|
fi
|
|
131
|
-
if
|
|
132
|
+
if gh issue edit "$issue" --repo "$repo" --add-label "$status_label"; then
|
|
133
|
+
if [[ "$status_label" == shipyard:complete ]]; then
|
|
134
|
+
remove_issue_label "$issue" ready-for-human
|
|
135
|
+
fi
|
|
136
|
+
else
|
|
132
137
|
if [[ "$branch" == "shipyard/issue-$issue" ]]; then
|
|
133
138
|
echo "Could not mark ticket #$issue complete; retry issue completion when GitHub is available" >&2
|
|
134
139
|
exit 75
|
|
@@ -170,6 +175,6 @@ if [[ "$status_synced" == true ]]; then
|
|
|
170
175
|
fi
|
|
171
176
|
done
|
|
172
177
|
else
|
|
173
|
-
echo "Warning: status labels need reconciliation;
|
|
178
|
+
echo "Warning: status labels need reconciliation; add shipyard to the ticket to retry" >&2
|
|
174
179
|
fi
|
|
175
180
|
printf '%s\n' "$url"
|
|
@@ -27,24 +27,27 @@ const roleModels = {
|
|
|
27
27
|
routine: readRoleModel("routine"),
|
|
28
28
|
strong: readRoleModel("strong"),
|
|
29
29
|
};
|
|
30
|
-
const
|
|
31
|
-
type
|
|
32
|
-
const
|
|
30
|
+
const REASONING_EFFORTS = shipyard.REASONING_EFFORTS;
|
|
31
|
+
type ReasoningEffort = shipyard.ReasoningEffort;
|
|
32
|
+
const readRoleReasoningEffort = (
|
|
33
33
|
role: ModelRole,
|
|
34
|
-
):
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const
|
|
34
|
+
): ReasoningEffort | undefined => {
|
|
35
|
+
const envName = `SHIPYARD_${role.toUpperCase()}_REASONING_EFFORT`;
|
|
36
|
+
const legacyName = `SHIPYARD_CODEX_${role.toUpperCase()}_REASONING_EFFORT`;
|
|
37
|
+
const sharedEffort = process.env[envName]?.trim();
|
|
38
|
+
const effort =
|
|
39
|
+
sharedEffort ||
|
|
40
|
+
(CODEX_PROVIDER ? process.env[legacyName]?.trim() : undefined);
|
|
38
41
|
if (!effort) return undefined;
|
|
39
|
-
if (!(
|
|
42
|
+
if (!(REASONING_EFFORTS as readonly string[]).includes(effort))
|
|
40
43
|
throw new Error(
|
|
41
|
-
`${envName} must be one of ${
|
|
44
|
+
`${sharedEffort ? envName : legacyName} must be one of ${REASONING_EFFORTS.join(", ")}; received "${effort}"`,
|
|
42
45
|
);
|
|
43
|
-
return effort as
|
|
46
|
+
return effort as ReasoningEffort;
|
|
44
47
|
};
|
|
45
48
|
const roleEfforts = {
|
|
46
|
-
routine:
|
|
47
|
-
strong:
|
|
49
|
+
routine: readRoleReasoningEffort("routine"),
|
|
50
|
+
strong: readRoleReasoningEffort("strong"),
|
|
48
51
|
};
|
|
49
52
|
const readCodexRoleModel = (role: ModelRole, defaultModel: AgentModel) => {
|
|
50
53
|
if (!CODEX_PROVIDER || typeof defaultModel === "string") return defaultModel;
|
|
@@ -166,6 +169,7 @@ const runWorker = async (scope: Scope, ticket: Ticket) => {
|
|
|
166
169
|
baseBranch: scope.branch,
|
|
167
170
|
sandbox: sandboxProvider,
|
|
168
171
|
hooks,
|
|
172
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
169
173
|
});
|
|
170
174
|
try {
|
|
171
175
|
await sandbox.run({
|
|
@@ -173,7 +177,7 @@ const runWorker = async (scope: Scope, ticket: Ticket) => {
|
|
|
173
177
|
maxIterations: 1,
|
|
174
178
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
175
179
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
176
|
-
promptArgs: { TASK_ID: ticket.id },
|
|
180
|
+
promptArgs: { TASK_ID: ticket.id, BASE_BRANCH: targetBranch },
|
|
177
181
|
});
|
|
178
182
|
verifyTriage(ticket.id);
|
|
179
183
|
const implementation = await sandbox.run({
|
|
@@ -212,6 +216,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
212
216
|
const plan = await shipyard.run({
|
|
213
217
|
hooks,
|
|
214
218
|
sandbox: sandboxProvider,
|
|
219
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
215
220
|
name: "planner",
|
|
216
221
|
branchStrategy: { type: "branch", branch: plannerBranch },
|
|
217
222
|
maxIterations: 1,
|
|
@@ -257,6 +262,8 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
257
262
|
repository,
|
|
258
263
|
"--add-label",
|
|
259
264
|
"shipyard:pending",
|
|
265
|
+
"--remove-label",
|
|
266
|
+
"shipyard",
|
|
260
267
|
]);
|
|
261
268
|
if (
|
|
262
269
|
scope.branch !==
|
|
@@ -271,6 +278,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
271
278
|
branch: scope.branch,
|
|
272
279
|
sandbox: sandboxProvider,
|
|
273
280
|
hooks,
|
|
281
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
274
282
|
});
|
|
275
283
|
await closeClean(seed);
|
|
276
284
|
const tickets = scope.tickets ?? [];
|
|
@@ -305,6 +313,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
305
313
|
branch: scope.branch,
|
|
306
314
|
sandbox: sandboxProvider,
|
|
307
315
|
hooks,
|
|
316
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
308
317
|
});
|
|
309
318
|
try {
|
|
310
319
|
for (const [index, outcome] of settled.entries()) {
|
|
@@ -430,6 +439,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
430
439
|
branch: scope.branch,
|
|
431
440
|
sandbox: sandboxProvider,
|
|
432
441
|
hooks,
|
|
442
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
433
443
|
});
|
|
434
444
|
let handoffEvidence: string;
|
|
435
445
|
try {
|
|
@@ -439,7 +449,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
439
449
|
maxIterations: 1,
|
|
440
450
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
441
451
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
442
|
-
promptArgs: { TASK_ID: id },
|
|
452
|
+
promptArgs: { TASK_ID: id, BASE_BRANCH: targetBranch },
|
|
443
453
|
});
|
|
444
454
|
verifyTriage(id);
|
|
445
455
|
const standalone = await integration.run({
|
|
@@ -477,6 +487,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
477
487
|
const publication = await shipyard.createSandbox({
|
|
478
488
|
branch: scope.branch,
|
|
479
489
|
sandbox: sandboxProvider,
|
|
490
|
+
copyToWorktree: [".shipyard/handoff.sh"],
|
|
480
491
|
});
|
|
481
492
|
try {
|
|
482
493
|
const scopeIds = [
|
|
@@ -18,7 +18,14 @@ if [[ -f package.json ]]; then
|
|
|
18
18
|
else manager=npm; fi
|
|
19
19
|
fi
|
|
20
20
|
case "$manager" in
|
|
21
|
-
npm)
|
|
21
|
+
npm)
|
|
22
|
+
if [[ -f package-lock.json ]]; then
|
|
23
|
+
if ! npm ci; then
|
|
24
|
+
echo "npm ci failed; installing from package.json without changing package-lock.json" >&2
|
|
25
|
+
npm install --no-package-lock
|
|
26
|
+
fi
|
|
27
|
+
else npm install --no-package-lock
|
|
28
|
+
fi ;;
|
|
22
29
|
pnpm) corepack pnpm install ;;
|
|
23
30
|
yarn) corepack yarn install ;;
|
|
24
31
|
bun)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Triage GitHub issue #{{TASK_ID}} before Shipyard implementation.
|
|
2
2
|
|
|
3
|
-
Follow `/triage` and the repository's
|
|
3
|
+
Follow `/triage` and the repository's triage label mapping. Read the full issue and comments. Verify the reported behavior against `origin/{{BASE_BRANCH}}`, the integration baseline. The checked-out task branch may contain unfinished changes from an earlier attempt. Do not close the issue as already complete based on the task branch or comments about that candidate.
|
|
4
|
+
|
|
5
|
+
Apply the appropriate category and state label and post the brief or triage notes required by the skill. The maintainer has authorized Shipyard to apply an evidence-based recommendation during this unattended intake. If a decision requires maintainer judgment, use `needs-triage` and record the question. Do not implement the issue or start a PR in this phase.
|
|
4
6
|
|
|
5
7
|
Report the applied state and evidence. Shipyard will independently re-read GitHub labels and implement only an open issue carrying both `shipyard` and the sole triage state `ready-for-agent`.
|
|
@@ -108,6 +108,10 @@ Work was not handed off. To retry, resolve the problem, remove shipyard:blocked,
|
|
|
108
108
|
fi
|
|
109
109
|
|
|
110
110
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
111
|
+
if ! remove_issue_status "$root" ready-for-human; then
|
|
112
|
+
echo "Warning: could not clear spec triage status" >&2
|
|
113
|
+
status_synced=false
|
|
114
|
+
fi
|
|
111
115
|
if ! remove_issue_status "$root" shipyard:outstanding-tasks; then
|
|
112
116
|
echo "Warning: could not clear spec status" >&2
|
|
113
117
|
status_synced=false
|
|
@@ -122,9 +126,11 @@ else
|
|
|
122
126
|
fi
|
|
123
127
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
124
128
|
for affected_id in "${affected_ids[@]:1}"; do
|
|
129
|
+
remove_issue_status "$affected_id" ready-for-human || status=75
|
|
125
130
|
remove_issue_status "$affected_id" shipyard:pending || status=75
|
|
126
131
|
done
|
|
127
132
|
else
|
|
133
|
+
remove_issue_status "$root" ready-for-human || status=75
|
|
128
134
|
remove_issue_status "$root" shipyard:pending || status=75
|
|
129
135
|
fi
|
|
130
136
|
|
|
@@ -103,6 +103,7 @@ for ((i=1; i<${#scope_ids[@]}; i++)); do
|
|
|
103
103
|
echo "Could not mark ticket #${scope_ids[i]} complete; retry issue completion when GitHub is available" >&2
|
|
104
104
|
exit 75
|
|
105
105
|
fi
|
|
106
|
+
remove_issue_label "${scope_ids[i]}" ready-for-human
|
|
106
107
|
remove_issue_label "${scope_ids[i]}" shipyard:blocked
|
|
107
108
|
remove_issue_label "${scope_ids[i]}" shipyard:pending
|
|
108
109
|
done
|
|
@@ -128,7 +129,11 @@ if ! gh label create "$status_label" --repo "$repo" --color "$status_color" --de
|
|
|
128
129
|
echo "Warning: could not create $status_label" >&2
|
|
129
130
|
status_synced=false
|
|
130
131
|
fi
|
|
131
|
-
if
|
|
132
|
+
if gh issue edit "$issue" --repo "$repo" --add-label "$status_label"; then
|
|
133
|
+
if [[ "$status_label" == shipyard:complete ]]; then
|
|
134
|
+
remove_issue_label "$issue" ready-for-human
|
|
135
|
+
fi
|
|
136
|
+
else
|
|
132
137
|
if [[ "$branch" == "shipyard/issue-$issue" ]]; then
|
|
133
138
|
echo "Could not mark ticket #$issue complete; retry issue completion when GitHub is available" >&2
|
|
134
139
|
exit 75
|
|
@@ -170,6 +175,6 @@ if [[ "$status_synced" == true ]]; then
|
|
|
170
175
|
fi
|
|
171
176
|
done
|
|
172
177
|
else
|
|
173
|
-
echo "Warning: status labels need reconciliation;
|
|
178
|
+
echo "Warning: status labels need reconciliation; add shipyard to the ticket to retry" >&2
|
|
174
179
|
fi
|
|
175
180
|
printf '%s\n' "$url"
|
|
@@ -27,24 +27,27 @@ const roleModels = {
|
|
|
27
27
|
routine: readRoleModel("routine"),
|
|
28
28
|
strong: readRoleModel("strong"),
|
|
29
29
|
};
|
|
30
|
-
const
|
|
31
|
-
type
|
|
32
|
-
const
|
|
30
|
+
const REASONING_EFFORTS = shipyard.REASONING_EFFORTS;
|
|
31
|
+
type ReasoningEffort = shipyard.ReasoningEffort;
|
|
32
|
+
const readRoleReasoningEffort = (
|
|
33
33
|
role: ModelRole,
|
|
34
|
-
):
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
const
|
|
34
|
+
): ReasoningEffort | undefined => {
|
|
35
|
+
const envName = `SHIPYARD_${role.toUpperCase()}_REASONING_EFFORT`;
|
|
36
|
+
const legacyName = `SHIPYARD_CODEX_${role.toUpperCase()}_REASONING_EFFORT`;
|
|
37
|
+
const sharedEffort = process.env[envName]?.trim();
|
|
38
|
+
const effort =
|
|
39
|
+
sharedEffort ||
|
|
40
|
+
(CODEX_PROVIDER ? process.env[legacyName]?.trim() : undefined);
|
|
38
41
|
if (!effort) return undefined;
|
|
39
|
-
if (!(
|
|
42
|
+
if (!(REASONING_EFFORTS as readonly string[]).includes(effort))
|
|
40
43
|
throw new Error(
|
|
41
|
-
`${envName} must be one of ${
|
|
44
|
+
`${sharedEffort ? envName : legacyName} must be one of ${REASONING_EFFORTS.join(", ")}; received "${effort}"`,
|
|
42
45
|
);
|
|
43
|
-
return effort as
|
|
46
|
+
return effort as ReasoningEffort;
|
|
44
47
|
};
|
|
45
48
|
const roleEfforts = {
|
|
46
|
-
routine:
|
|
47
|
-
strong:
|
|
49
|
+
routine: readRoleReasoningEffort("routine"),
|
|
50
|
+
strong: readRoleReasoningEffort("strong"),
|
|
48
51
|
};
|
|
49
52
|
const readCodexRoleModel = (role: ModelRole, defaultModel: AgentModel) => {
|
|
50
53
|
if (!CODEX_PROVIDER || typeof defaultModel === "string") return defaultModel;
|
|
@@ -144,7 +147,7 @@ const approved = (
|
|
|
144
147
|
throw new Error(
|
|
145
148
|
`${stage} has unresolved review findings: ${result.stdout.trim().slice(-1200)}`,
|
|
146
149
|
);
|
|
147
|
-
return complete(result, stage)
|
|
150
|
+
return `Review: APPROVED\n${complete(result, stage)}`;
|
|
148
151
|
};
|
|
149
152
|
class TicketFailures extends Error {
|
|
150
153
|
constructor(readonly failures: Array<{ id: string; reason: string }>) {
|
|
@@ -176,6 +179,7 @@ const runWorker = async (scope: Scope, ticket: Ticket) => {
|
|
|
176
179
|
baseBranch: scope.branch,
|
|
177
180
|
sandbox: sandboxProvider,
|
|
178
181
|
hooks,
|
|
182
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
179
183
|
});
|
|
180
184
|
try {
|
|
181
185
|
await sandbox.run({
|
|
@@ -183,7 +187,7 @@ const runWorker = async (scope: Scope, ticket: Ticket) => {
|
|
|
183
187
|
maxIterations: 1,
|
|
184
188
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
185
189
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
186
|
-
promptArgs: { TASK_ID: ticket.id },
|
|
190
|
+
promptArgs: { TASK_ID: ticket.id, BASE_BRANCH: targetBranch },
|
|
187
191
|
});
|
|
188
192
|
verifyTriage(ticket.id);
|
|
189
193
|
const implementation = await sandbox.run({
|
|
@@ -235,6 +239,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
235
239
|
const plan = await shipyard.run({
|
|
236
240
|
hooks,
|
|
237
241
|
sandbox: sandboxProvider,
|
|
242
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
238
243
|
name: "planner",
|
|
239
244
|
branchStrategy: { type: "branch", branch: plannerBranch },
|
|
240
245
|
maxIterations: 1,
|
|
@@ -280,6 +285,8 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
280
285
|
repository,
|
|
281
286
|
"--add-label",
|
|
282
287
|
"shipyard:pending",
|
|
288
|
+
"--remove-label",
|
|
289
|
+
"shipyard",
|
|
283
290
|
]);
|
|
284
291
|
if (
|
|
285
292
|
scope.branch !==
|
|
@@ -294,6 +301,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
294
301
|
branch: scope.branch,
|
|
295
302
|
sandbox: sandboxProvider,
|
|
296
303
|
hooks,
|
|
304
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
297
305
|
});
|
|
298
306
|
await closeClean(seed);
|
|
299
307
|
const tickets = scope.tickets ?? [];
|
|
@@ -328,6 +336,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
328
336
|
branch: scope.branch,
|
|
329
337
|
sandbox: sandboxProvider,
|
|
330
338
|
hooks,
|
|
339
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
331
340
|
});
|
|
332
341
|
try {
|
|
333
342
|
for (const [index, outcome] of settled.entries()) {
|
|
@@ -453,6 +462,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
453
462
|
branch: scope.branch,
|
|
454
463
|
sandbox: sandboxProvider,
|
|
455
464
|
hooks,
|
|
465
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
456
466
|
});
|
|
457
467
|
let handoffEvidence: string;
|
|
458
468
|
try {
|
|
@@ -462,7 +472,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
462
472
|
maxIterations: 1,
|
|
463
473
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
464
474
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
465
|
-
promptArgs: { TASK_ID: id },
|
|
475
|
+
promptArgs: { TASK_ID: id, BASE_BRANCH: targetBranch },
|
|
466
476
|
});
|
|
467
477
|
verifyTriage(id);
|
|
468
478
|
const standalone = await integration.run({
|
|
@@ -528,6 +538,7 @@ for (let iteration = 0; iteration < 10; iteration++) {
|
|
|
528
538
|
const publication = await shipyard.createSandbox({
|
|
529
539
|
branch: scope.branch,
|
|
530
540
|
sandbox: sandboxProvider,
|
|
541
|
+
copyToWorktree: [".shipyard/handoff.sh"],
|
|
531
542
|
});
|
|
532
543
|
try {
|
|
533
544
|
const scopeIds = [
|
|
@@ -18,7 +18,14 @@ if [[ -f package.json ]]; then
|
|
|
18
18
|
else manager=npm; fi
|
|
19
19
|
fi
|
|
20
20
|
case "$manager" in
|
|
21
|
-
npm)
|
|
21
|
+
npm)
|
|
22
|
+
if [[ -f package-lock.json ]]; then
|
|
23
|
+
if ! npm ci; then
|
|
24
|
+
echo "npm ci failed; installing from package.json without changing package-lock.json" >&2
|
|
25
|
+
npm install --no-package-lock
|
|
26
|
+
fi
|
|
27
|
+
else npm install --no-package-lock
|
|
28
|
+
fi ;;
|
|
22
29
|
pnpm) corepack pnpm install ;;
|
|
23
30
|
yarn) corepack yarn install ;;
|
|
24
31
|
bun)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Triage GitHub issue #{{TASK_ID}} before Shipyard implementation.
|
|
2
2
|
|
|
3
|
-
Follow `/triage` and the repository's
|
|
3
|
+
Follow `/triage` and the repository's triage label mapping. Read the full issue and comments. Verify the reported behavior against `origin/{{BASE_BRANCH}}`, the integration baseline. The checked-out task branch may contain unfinished changes from an earlier attempt. Do not close the issue as already complete based on the task branch or comments about that candidate.
|
|
4
|
+
|
|
5
|
+
Apply the appropriate category and state label and post the brief or triage notes required by the skill. The maintainer has authorized Shipyard to apply an evidence-based recommendation during this unattended intake. If a decision requires maintainer judgment, use `needs-triage` and record the question. Do not implement the issue or start a PR in this phase.
|
|
4
6
|
|
|
5
7
|
Report the applied state and evidence. Shipyard will independently re-read GitHub labels and implement only an open issue carrying both `shipyard` and the sole triage state `ready-for-agent`.
|
|
@@ -108,6 +108,10 @@ Work was not handed off. To retry, resolve the problem, remove shipyard:blocked,
|
|
|
108
108
|
fi
|
|
109
109
|
|
|
110
110
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
111
|
+
if ! remove_issue_status "$root" ready-for-human; then
|
|
112
|
+
echo "Warning: could not clear spec triage status" >&2
|
|
113
|
+
status_synced=false
|
|
114
|
+
fi
|
|
111
115
|
if ! remove_issue_status "$root" shipyard:outstanding-tasks; then
|
|
112
116
|
echo "Warning: could not clear spec status" >&2
|
|
113
117
|
status_synced=false
|
|
@@ -122,9 +126,11 @@ else
|
|
|
122
126
|
fi
|
|
123
127
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
124
128
|
for affected_id in "${affected_ids[@]:1}"; do
|
|
129
|
+
remove_issue_status "$affected_id" ready-for-human || status=75
|
|
125
130
|
remove_issue_status "$affected_id" shipyard:pending || status=75
|
|
126
131
|
done
|
|
127
132
|
else
|
|
133
|
+
remove_issue_status "$root" ready-for-human || status=75
|
|
128
134
|
remove_issue_status "$root" shipyard:pending || status=75
|
|
129
135
|
fi
|
|
130
136
|
|
|
@@ -103,6 +103,7 @@ for ((i=1; i<${#scope_ids[@]}; i++)); do
|
|
|
103
103
|
echo "Could not mark ticket #${scope_ids[i]} complete; retry issue completion when GitHub is available" >&2
|
|
104
104
|
exit 75
|
|
105
105
|
fi
|
|
106
|
+
remove_issue_label "${scope_ids[i]}" ready-for-human
|
|
106
107
|
remove_issue_label "${scope_ids[i]}" shipyard:blocked
|
|
107
108
|
remove_issue_label "${scope_ids[i]}" shipyard:pending
|
|
108
109
|
done
|
|
@@ -128,7 +129,11 @@ if ! gh label create "$status_label" --repo "$repo" --color "$status_color" --de
|
|
|
128
129
|
echo "Warning: could not create $status_label" >&2
|
|
129
130
|
status_synced=false
|
|
130
131
|
fi
|
|
131
|
-
if
|
|
132
|
+
if gh issue edit "$issue" --repo "$repo" --add-label "$status_label"; then
|
|
133
|
+
if [[ "$status_label" == shipyard:complete ]]; then
|
|
134
|
+
remove_issue_label "$issue" ready-for-human
|
|
135
|
+
fi
|
|
136
|
+
else
|
|
132
137
|
if [[ "$branch" == "shipyard/issue-$issue" ]]; then
|
|
133
138
|
echo "Could not mark ticket #$issue complete; retry issue completion when GitHub is available" >&2
|
|
134
139
|
exit 75
|
|
@@ -170,6 +175,6 @@ if [[ "$status_synced" == true ]]; then
|
|
|
170
175
|
fi
|
|
171
176
|
done
|
|
172
177
|
else
|
|
173
|
-
echo "Warning: status labels need reconciliation;
|
|
178
|
+
echo "Warning: status labels need reconciliation; add shipyard to the ticket to retry" >&2
|
|
174
179
|
fi
|
|
175
180
|
printf '%s\n' "$url"
|
|
@@ -22,24 +22,27 @@ const roleModels = {
|
|
|
22
22
|
routine: readRoleModel("routine"),
|
|
23
23
|
strong: readRoleModel("strong"),
|
|
24
24
|
};
|
|
25
|
-
const
|
|
26
|
-
type
|
|
27
|
-
const
|
|
25
|
+
const REASONING_EFFORTS = shipyard.REASONING_EFFORTS;
|
|
26
|
+
type ReasoningEffort = shipyard.ReasoningEffort;
|
|
27
|
+
const readRoleReasoningEffort = (
|
|
28
28
|
role: ModelRole,
|
|
29
|
-
):
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
const
|
|
29
|
+
): ReasoningEffort | undefined => {
|
|
30
|
+
const envName = `SHIPYARD_${role.toUpperCase()}_REASONING_EFFORT`;
|
|
31
|
+
const legacyName = `SHIPYARD_CODEX_${role.toUpperCase()}_REASONING_EFFORT`;
|
|
32
|
+
const sharedEffort = process.env[envName]?.trim();
|
|
33
|
+
const effort =
|
|
34
|
+
sharedEffort ||
|
|
35
|
+
(CODEX_PROVIDER ? process.env[legacyName]?.trim() : undefined);
|
|
33
36
|
if (!effort) return undefined;
|
|
34
|
-
if (!(
|
|
37
|
+
if (!(REASONING_EFFORTS as readonly string[]).includes(effort))
|
|
35
38
|
throw new Error(
|
|
36
|
-
`${envName} must be one of ${
|
|
39
|
+
`${sharedEffort ? envName : legacyName} must be one of ${REASONING_EFFORTS.join(", ")}; received "${effort}"`,
|
|
37
40
|
);
|
|
38
|
-
return effort as
|
|
41
|
+
return effort as ReasoningEffort;
|
|
39
42
|
};
|
|
40
43
|
const roleEfforts = {
|
|
41
|
-
routine:
|
|
42
|
-
strong:
|
|
44
|
+
routine: readRoleReasoningEffort("routine"),
|
|
45
|
+
strong: readRoleReasoningEffort("strong"),
|
|
43
46
|
};
|
|
44
47
|
const readCodexRoleModel = (role: ModelRole, defaultModel: AgentModel) => {
|
|
45
48
|
if (!CODEX_PROVIDER || typeof defaultModel === "string") return defaultModel;
|
|
@@ -176,11 +179,14 @@ for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
|
176
179
|
repository,
|
|
177
180
|
"--add-label",
|
|
178
181
|
"shipyard:pending",
|
|
182
|
+
"--remove-label",
|
|
183
|
+
"shipyard",
|
|
179
184
|
]);
|
|
180
185
|
const sandbox = await shipyard.createSandbox({
|
|
181
186
|
branch: issue.branch,
|
|
182
187
|
sandbox: sandboxProvider,
|
|
183
188
|
hooks,
|
|
189
|
+
copyToWorktree: [".shipyard/setup.sh"],
|
|
184
190
|
});
|
|
185
191
|
let evidence: string;
|
|
186
192
|
try {
|
|
@@ -192,7 +198,7 @@ for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
|
192
198
|
agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
|
|
193
199
|
maxIterations: 1,
|
|
194
200
|
promptFile: "./.shipyard/triage-prompt.md",
|
|
195
|
-
promptArgs: { TASK_ID: ticketId },
|
|
201
|
+
promptArgs: { TASK_ID: ticketId, BASE_BRANCH: targetBranch },
|
|
196
202
|
});
|
|
197
203
|
verifyTriage(ticketId);
|
|
198
204
|
}
|
|
@@ -237,7 +243,7 @@ for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
|
237
243
|
`Issue #${issue.id} has unresolved review findings: ${review.stdout.trim().slice(-1200)}`,
|
|
238
244
|
);
|
|
239
245
|
}
|
|
240
|
-
evidence = `${implementationEvidence}\n\n${reviewEvidence}`;
|
|
246
|
+
evidence = `${implementationEvidence}\n\nReview: APPROVED\n${reviewEvidence}`;
|
|
241
247
|
} finally {
|
|
242
248
|
await closeClean(sandbox);
|
|
243
249
|
}
|
|
@@ -245,6 +251,7 @@ for (let iteration = 0; iteration < MAX_ITERATIONS; iteration++) {
|
|
|
245
251
|
const publication = await shipyard.createSandbox({
|
|
246
252
|
branch: issue.branch,
|
|
247
253
|
sandbox: sandboxProvider,
|
|
254
|
+
copyToWorktree: [".shipyard/handoff.sh"],
|
|
248
255
|
});
|
|
249
256
|
try {
|
|
250
257
|
publicationUncertain = true;
|
|
@@ -18,7 +18,14 @@ if [[ -f package.json ]]; then
|
|
|
18
18
|
else manager=npm; fi
|
|
19
19
|
fi
|
|
20
20
|
case "$manager" in
|
|
21
|
-
npm)
|
|
21
|
+
npm)
|
|
22
|
+
if [[ -f package-lock.json ]]; then
|
|
23
|
+
if ! npm ci; then
|
|
24
|
+
echo "npm ci failed; installing from package.json without changing package-lock.json" >&2
|
|
25
|
+
npm install --no-package-lock
|
|
26
|
+
fi
|
|
27
|
+
else npm install --no-package-lock
|
|
28
|
+
fi ;;
|
|
22
29
|
pnpm) corepack pnpm install ;;
|
|
23
30
|
yarn) corepack yarn install ;;
|
|
24
31
|
bun)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Triage GitHub issue #{{TASK_ID}} before Shipyard implementation.
|
|
2
2
|
|
|
3
|
-
Follow `/triage` and the repository's
|
|
3
|
+
Follow `/triage` and the repository's triage label mapping. Read the full issue and comments. Verify the reported behavior against `origin/{{BASE_BRANCH}}`, the integration baseline. The checked-out task branch may contain unfinished changes from an earlier attempt. Do not close the issue as already complete based on the task branch or comments about that candidate.
|
|
4
|
+
|
|
5
|
+
Apply the appropriate category and state label and post the brief or triage notes required by the skill. The maintainer has authorized Shipyard to apply an evidence-based recommendation during this unattended intake. If a decision requires maintainer judgment, use `needs-triage` and record the question. Do not implement the issue or start a PR in this phase.
|
|
4
6
|
|
|
5
7
|
Report the applied state and evidence. Shipyard will independently re-read GitHub labels and implement only an open issue carrying both `shipyard` and the sole triage state `ready-for-agent`.
|
|
@@ -108,6 +108,10 @@ Work was not handed off. To retry, resolve the problem, remove shipyard:blocked,
|
|
|
108
108
|
fi
|
|
109
109
|
|
|
110
110
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
111
|
+
if ! remove_issue_status "$root" ready-for-human; then
|
|
112
|
+
echo "Warning: could not clear spec triage status" >&2
|
|
113
|
+
status_synced=false
|
|
114
|
+
fi
|
|
111
115
|
if ! remove_issue_status "$root" shipyard:outstanding-tasks; then
|
|
112
116
|
echo "Warning: could not clear spec status" >&2
|
|
113
117
|
status_synced=false
|
|
@@ -122,9 +126,11 @@ else
|
|
|
122
126
|
fi
|
|
123
127
|
if [[ "$branch" == "shipyard/spec-$root" ]]; then
|
|
124
128
|
for affected_id in "${affected_ids[@]:1}"; do
|
|
129
|
+
remove_issue_status "$affected_id" ready-for-human || status=75
|
|
125
130
|
remove_issue_status "$affected_id" shipyard:pending || status=75
|
|
126
131
|
done
|
|
127
132
|
else
|
|
133
|
+
remove_issue_status "$root" ready-for-human || status=75
|
|
128
134
|
remove_issue_status "$root" shipyard:pending || status=75
|
|
129
135
|
fi
|
|
130
136
|
|
|
@@ -103,6 +103,7 @@ for ((i=1; i<${#scope_ids[@]}; i++)); do
|
|
|
103
103
|
echo "Could not mark ticket #${scope_ids[i]} complete; retry issue completion when GitHub is available" >&2
|
|
104
104
|
exit 75
|
|
105
105
|
fi
|
|
106
|
+
remove_issue_label "${scope_ids[i]}" ready-for-human
|
|
106
107
|
remove_issue_label "${scope_ids[i]}" shipyard:blocked
|
|
107
108
|
remove_issue_label "${scope_ids[i]}" shipyard:pending
|
|
108
109
|
done
|
|
@@ -128,7 +129,11 @@ if ! gh label create "$status_label" --repo "$repo" --color "$status_color" --de
|
|
|
128
129
|
echo "Warning: could not create $status_label" >&2
|
|
129
130
|
status_synced=false
|
|
130
131
|
fi
|
|
131
|
-
if
|
|
132
|
+
if gh issue edit "$issue" --repo "$repo" --add-label "$status_label"; then
|
|
133
|
+
if [[ "$status_label" == shipyard:complete ]]; then
|
|
134
|
+
remove_issue_label "$issue" ready-for-human
|
|
135
|
+
fi
|
|
136
|
+
else
|
|
132
137
|
if [[ "$branch" == "shipyard/issue-$issue" ]]; then
|
|
133
138
|
echo "Could not mark ticket #$issue complete; retry issue completion when GitHub is available" >&2
|
|
134
139
|
exit 75
|
|
@@ -170,6 +175,6 @@ if [[ "$status_synced" == true ]]; then
|
|
|
170
175
|
fi
|
|
171
176
|
done
|
|
172
177
|
else
|
|
173
|
-
echo "Warning: status labels need reconciliation;
|
|
178
|
+
echo "Warning: status labels need reconciliation; add shipyard to the ticket to retry" >&2
|
|
174
179
|
fi
|
|
175
180
|
printf '%s\n' "$url"
|
|
@@ -18,7 +18,14 @@ if [[ -f package.json ]]; then
|
|
|
18
18
|
else manager=npm; fi
|
|
19
19
|
fi
|
|
20
20
|
case "$manager" in
|
|
21
|
-
npm)
|
|
21
|
+
npm)
|
|
22
|
+
if [[ -f package-lock.json ]]; then
|
|
23
|
+
if ! npm ci; then
|
|
24
|
+
echo "npm ci failed; installing from package.json without changing package-lock.json" >&2
|
|
25
|
+
npm install --no-package-lock
|
|
26
|
+
fi
|
|
27
|
+
else npm install --no-package-lock
|
|
28
|
+
fi ;;
|
|
22
29
|
pnpm) corepack pnpm install ;;
|
|
23
30
|
yarn) corepack yarn install ;;
|
|
24
31
|
bun)
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
Triage GitHub issue #{{TASK_ID}} before Shipyard implementation.
|
|
2
2
|
|
|
3
|
-
Follow `/triage` and the repository's
|
|
3
|
+
Follow `/triage` and the repository's triage label mapping. Read the full issue and comments. Verify the reported behavior against `origin/{{BASE_BRANCH}}`, the integration baseline. The checked-out task branch may contain unfinished changes from an earlier attempt. Do not close the issue as already complete based on the task branch or comments about that candidate.
|
|
4
|
+
|
|
5
|
+
Apply the appropriate category and state label and post the brief or triage notes required by the skill. The maintainer has authorized Shipyard to apply an evidence-based recommendation during this unattended intake. If a decision requires maintainer judgment, use `needs-triage` and record the question. Do not implement the issue or start a PR in this phase.
|
|
4
6
|
|
|
5
7
|
Report the applied state and evidence. Shipyard will independently re-read GitHub labels and implement only an open issue carrying both `shipyard` and the sole triage state `ready-for-agent`.
|