@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.
Files changed (46) hide show
  1. package/README.md +4 -2
  2. package/dist/{chunk-NQRFVKCU.js → chunk-2SEMX2NX.js} +2 -2
  3. package/dist/{chunk-NQRFVKCU.js.map → chunk-2SEMX2NX.js.map} +1 -1
  4. package/dist/{chunk-57EEKW3R.js → chunk-BAP7BWQ2.js} +17 -8
  5. package/dist/chunk-BAP7BWQ2.js.map +1 -0
  6. package/dist/{chunk-HXSZM52J.js → chunk-IVE7QDGC.js} +17 -11
  7. package/dist/chunk-IVE7QDGC.js.map +1 -0
  8. package/dist/{chunk-JZUBT4WG.js → chunk-KSTSHZNH.js} +3 -3
  9. package/dist/{chunk-JZUBT4WG.js.map → chunk-KSTSHZNH.js.map} +1 -1
  10. package/dist/{createSandbox-DmbnWAZv.d.ts → createSandbox-Bqopwday.d.ts} +6 -4
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.js +58 -13
  13. package/dist/index.js.map +1 -1
  14. package/dist/integrations/github.js +1 -1
  15. package/dist/main.js +26 -7
  16. package/dist/main.js.map +1 -1
  17. package/dist/sandboxes/docker.js +2 -2
  18. package/dist/templates/parallel-planner/block-scope.sh +6 -0
  19. package/dist/templates/parallel-planner/handoff.sh +7 -2
  20. package/dist/templates/parallel-planner/main.mts +25 -14
  21. package/dist/templates/parallel-planner/setup.sh +8 -1
  22. package/dist/templates/parallel-planner/triage-prompt.md +3 -1
  23. package/dist/templates/parallel-planner-with-review/block-scope.sh +6 -0
  24. package/dist/templates/parallel-planner-with-review/handoff.sh +7 -2
  25. package/dist/templates/parallel-planner-with-review/main.mts +26 -15
  26. package/dist/templates/parallel-planner-with-review/setup.sh +8 -1
  27. package/dist/templates/parallel-planner-with-review/triage-prompt.md +3 -1
  28. package/dist/templates/sequential-reviewer/block-scope.sh +6 -0
  29. package/dist/templates/sequential-reviewer/handoff.sh +7 -2
  30. package/dist/templates/sequential-reviewer/main.mts +21 -14
  31. package/dist/templates/sequential-reviewer/setup.sh +8 -1
  32. package/dist/templates/sequential-reviewer/triage-prompt.md +3 -1
  33. package/dist/templates/shared/block-scope.sh +6 -0
  34. package/dist/templates/shared/handoff.sh +7 -2
  35. package/dist/templates/shared/setup.sh +8 -1
  36. package/dist/templates/shared/triage-prompt.md +3 -1
  37. package/dist/templates/simple-loop/block-scope.sh +6 -0
  38. package/dist/templates/simple-loop/handoff.sh +7 -2
  39. package/dist/templates/simple-loop/main.mts +20 -13
  40. package/dist/templates/simple-loop/setup.sh +8 -1
  41. package/dist/templates/simple-loop/triage-prompt.md +3 -1
  42. package/dist/workflow.d.ts +1 -1
  43. package/dist/workflow.js +2 -2
  44. package/package.json +1 -1
  45. package/dist/chunk-57EEKW3R.js.map +0 -1
  46. package/dist/chunk-HXSZM52J.js.map +0 -1
@@ -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 ! gh issue edit "$issue" --repo "$repo" --add-label "$status_label"; then
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; retaining ticket activation" >&2
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 CODEX_REASONING_EFFORTS = shipyard.CODEX_REASONING_EFFORTS;
26
- type CodexReasoningEffort = shipyard.CodexReasoningEffort;
27
- const readCodexReasoningEffort = (
25
+ const REASONING_EFFORTS = shipyard.REASONING_EFFORTS;
26
+ type ReasoningEffort = shipyard.ReasoningEffort;
27
+ const readRoleReasoningEffort = (
28
28
  role: ModelRole,
29
- ): CodexReasoningEffort | undefined => {
30
- if (!CODEX_PROVIDER) return undefined;
31
- const envName = `SHIPYARD_CODEX_${role.toUpperCase()}_REASONING_EFFORT`;
32
- const effort = process.env[envName]?.trim();
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 (!(CODEX_REASONING_EFFORTS as readonly string[]).includes(effort))
37
+ if (!(REASONING_EFFORTS as readonly string[]).includes(effort))
35
38
  throw new Error(
36
- `${envName} must be one of ${CODEX_REASONING_EFFORTS.join(", ")}; received "${effort}"`,
39
+ `${sharedEffort ? envName : legacyName} must be one of ${REASONING_EFFORTS.join(", ")}; received "${effort}"`,
37
40
  );
38
- return effort as CodexReasoningEffort;
41
+ return effort as ReasoningEffort;
39
42
  };
40
43
  const roleEfforts = {
41
- routine: readCodexReasoningEffort("routine"),
42
- strong: readCodexReasoningEffort("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;
@@ -173,11 +176,14 @@ for (let iteration = 0; iteration < 3; iteration++) {
173
176
  repository,
174
177
  "--add-label",
175
178
  "shipyard:pending",
179
+ "--remove-label",
180
+ "shipyard",
176
181
  ]);
177
182
  const sandbox = await shipyard.createSandbox({
178
183
  branch: issue.branch,
179
184
  sandbox: sandboxProvider,
180
185
  hooks,
186
+ copyToWorktree: [".shipyard/setup.sh"],
181
187
  });
182
188
  let evidence: string;
183
189
  try {
@@ -189,7 +195,7 @@ for (let iteration = 0; iteration < 3; iteration++) {
189
195
  agent: roleAgent("routine", shipyard.CODEX_MODELS.routine),
190
196
  maxIterations: 1,
191
197
  promptFile: "./.shipyard/triage-prompt.md",
192
- promptArgs: { TASK_ID: ticketId },
198
+ promptArgs: { TASK_ID: ticketId, BASE_BRANCH: targetBranch },
193
199
  });
194
200
  verifyTriage(ticketId);
195
201
  }
@@ -225,6 +231,7 @@ for (let iteration = 0; iteration < 3; iteration++) {
225
231
  const publication = await shipyard.createSandbox({
226
232
  branch: issue.branch,
227
233
  sandbox: sandboxProvider,
234
+ copyToWorktree: [".shipyard/handoff.sh"],
228
235
  });
229
236
  try {
230
237
  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) npm install ;;
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 `docs/agents/triage.md` label mapping. Read the full issue and comments, verify its claim against the codebase, then 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.
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`.
@@ -1,6 +1,6 @@
1
1
  import { U as CoordinatorStorage, V as CoordinatorStorageTransaction, X as Assignment, W as WorkBrief, Y as RepositoryPolicy, Z as AgentSelection, _ as RevisionReference, $ as CheckEvidence, a0 as Finding, a1 as ReviewAxis, a2 as PhaseResult, a3 as FindingSeverity, a4 as ReviewEvidence, a5 as WorkflowCoordinator, I as GitHubPublication, a6 as WorkflowJob, a7 as DispatchResult, a8 as BranchLease, K as GitHubPublicationResult, O as GitHubPullRequestSnapshot, a9 as DispatchIntent, aa as WorkflowPhase, ab as RepositoryControl, D as GitHubIssueSnapshot, x as GitHubCommentSnapshot, ac as PostgresQueryClient } from './publication-BPoy_M9M.js';
2
2
  export { ad as AcquireBranchLeaseInput, ae as AgentModelRoles, af as AgentRole, ag as Authorization, ah as BranchProtectionState, ai as CheckCommand, aj as CheckStatus, ak as ClarificationReply, al as CloseSourceIssueOptions, am as CompletionInput, an as CompletionResult, ao as ContractValidationError, ap as CoordinatorClock, aq as CreateAssignmentInput, ar as CreateRepositoryPolicyInput, as as CreateWorkBriefInput, at as DispatchBlockReason, au as DispatchRequest, av as DispatchStatus, aw as EffectExecution, ax as EffectIntent, ay as EffectOperationContext, az as EffectStatus, aA as EventIgnoreReason, aB as EventStatus, aC as FindingDisposition, aD as HandoffCandidate, aE as HandoffOutcome, aF as HandoffPacket, aG as HandoffReadinessInput, aH as HandoffReadinessResult, aI as HumanApproval, aJ as HumanHandoffPublisher, aK as HumanReviewDecision, H as HumanReviewDecisionInput, aL as HumanReviewRoundTripOptions, aM as HumanReviewRoundTripResult, aN as InMemoryTriageStore, aO as InfrastructureFailureInput, aP as InfrastructureRetryResult, aQ as IngestResult, aR as JobControl, aS as LeaseBusyError, aT as LeaseLostError, aU as LifecycleState, aV as MergeCandidateOptions, aW as MergeResult, aX as MergeTransport, aY as PhaseBudget, aZ as PhaseOutcome, a_ as PhaseResultSubmission, a$ as PostgresConnection, b0 as PostgresCoordinatorStorage, b1 as PostgresCoordinatorStorageOptions, b2 as PostgresQueryResult, b3 as PostgresTriageStore, b4 as PostgresTriageStoreOptions, b5 as PrepareHandoffOptions, b6 as PublishEffectInput, b7 as RepairBudgetUsage, b8 as RepairRequestResult, b9 as RiskLevel, ba as RunTriageOptions, bb as SchedulePhaseInput, bc as SchedulePhaseResult, bd as SourceIssueCloser, be as SourceIssueClosureResult, bf as SourceReference, bg as StoredEvent, bh as SubmitPhaseResultInput, bi as TransitionContext, bj as TriageAssessment, bk as TriageCategory, bl as TriageInvestigationRequest, bm as TriageInvestigator, bn as TriageOutcome, bo as TriageRecord, bp as TriageResult, bq as TriageSource, br as TriageSourceConflict, bs as TriageStore, bt as VerificationPlan, bu as WORKFLOW_CONTRACT_VERSION, bv as WorkIdentity, bw as WorkItemKind, bx as WorkKey, by as WorkRisk, bz as WorkScope, bA as WorkerPolicy, bB as WorkflowCoordinatorOptions, bC as WorkflowEventInput, bD as closeSourceIssue, bE as completeSourceIssue, bF as createAssignment, bG as createRepositoryPolicy, bH as createWorkBrief, bI as defaultTriageInvestigator, bJ as evaluateHandoffReadiness, bK as isAuthorizationAllowed, bL as mergeProtectedCandidate, bM as parseCheckEvidence, bN as parsePhaseResult, bO as parseRepositoryPolicy, bP as parseWorkBrief, bQ as prepareHumanHandoff, bR as processHumanReviewDecision, bS as requireTransition, bT as resolveAgentSelection, bU as resolveHumanReviewDecision, bV as runTriage } from './publication-BPoy_M9M.js';
3
- import { l as OutputDefinition, A as AgentProvider, j as CreateSandboxOptions, a as Sandbox, p as RunOptions, q as RunResult } from './createSandbox-DmbnWAZv.js';
3
+ import { l as OutputDefinition, A as AgentProvider, j as CreateSandboxOptions, a as Sandbox, r as RunOptions, s as RunResult } from './createSandbox-Bqopwday.js';
4
4
  import { S as SandboxProvider } from './SandboxProvider-oUAwYlWm.js';
5
5
  import '@standard-schema/spec';
6
6
 
package/dist/workflow.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { extractStructuredOutput } from './chunk-Z5C4LHVP.js';
2
- import { parseWorkBrief, parseRepositoryPolicy, createAssignment, parsePhaseResult, sameWorkIdentity, sameRevision, requireTransition, deepFreeze, resolveAgentSelection, isAuthorizationAllowed, PostgresWorkflowPhaseRecordStore, isBlockingFinding, requiredCheckNames } from './chunk-NQRFVKCU.js';
3
- export { ContractValidationError, InMemoryTriageStore, PostgresTriageStore, PostgresWorkflowPhaseRecordStore, WORKFLOW_CONTRACT_VERSION, closeSourceIssue, completeSourceIssue, createAssignment, createRepositoryPolicy, createWorkBrief, defaultInvestigator as defaultTriageInvestigator, evaluateHandoffReadiness, isAuthorizationAllowed, mergeProtectedCandidate, parseCheckEvidence, parsePhaseResult, parseRepositoryPolicy, parseWorkBrief, prepareHumanHandoff, processHumanReviewDecision, requireTransition, resolveAgentSelection, resolveHumanReviewDecision, runTriage } from './chunk-NQRFVKCU.js';
2
+ import { parseWorkBrief, parseRepositoryPolicy, createAssignment, parsePhaseResult, sameWorkIdentity, sameRevision, requireTransition, deepFreeze, resolveAgentSelection, isAuthorizationAllowed, PostgresWorkflowPhaseRecordStore, isBlockingFinding, requiredCheckNames } from './chunk-2SEMX2NX.js';
3
+ export { ContractValidationError, InMemoryTriageStore, PostgresTriageStore, PostgresWorkflowPhaseRecordStore, WORKFLOW_CONTRACT_VERSION, closeSourceIssue, completeSourceIssue, createAssignment, createRepositoryPolicy, createWorkBrief, defaultInvestigator as defaultTriageInvestigator, evaluateHandoffReadiness, isAuthorizationAllowed, mergeProtectedCandidate, parseCheckEvidence, parsePhaseResult, parseRepositoryPolicy, parseWorkBrief, prepareHumanHandoff, processHumanReviewDecision, requireTransition, resolveAgentSelection, resolveHumanReviewDecision, runTriage } from './chunk-2SEMX2NX.js';
4
4
  import { randomUUID, createHash } from 'crypto';
5
5
 
6
6
  // src/workflow/coordinator/in-memory-storage.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snappedly-tools/shipyard",
3
- "version": "0.9.2",
3
+ "version": "0.10.0",
4
4
  "description": "Run AI coding agents in isolated sandboxes",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",