@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.
@@ -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, triageOutput?: 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
- const reason = detail || `Could not verify triage for #${ticketId}`;
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
- let triageOutput: string | undefined;
200
- if (!ticket.triageReady) {
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
- triageOutput = triage.stdout;
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
- let triageOutput: string | undefined;
477
- if (!scope.triageReady) {
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
- triageOutput = triage.stdout;
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, triageOutput?: 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
- const reason = detail || `Could not verify triage for #${ticketId}`;
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
- let triageOutput: string | undefined;
210
- if (!ticket.triageReady) {
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
- triageOutput = triage.stdout;
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
- let triageOutput: string | undefined;
500
- if (!scope.triageReady) {
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
- triageOutput = triage.stdout;
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, triageOutput?: 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
- const reason = detail || `Could not verify triage for #${ticketId}`;
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
- let triageOutput: string | undefined;
226
- if (!ready) {
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
- triageOutput = triage.stdout;
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, triageOutput?: 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
- const reason = detail || `Could not verify triage for #${ticketId}`;
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
- let triageOutput: string | undefined;
223
- if (!ready) {
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
- triageOutput = triage.stdout;
233
- }
234
- verifyTriage(ticketId, triageOutput);
208
+ verifyTriage(ticketId);
235
209
  }
236
210
  const result = await sandbox.run({
237
211
  name: "implementer",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snappedly-tools/shipyard",
3
- "version": "0.11.0-staging.36389018601",
3
+ "version": "0.11.1",
4
4
  "description": "Run AI coding agents in isolated sandboxes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",