opencode-ship 1.1.5 → 1.1.8

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/CHANGELOG.md CHANGED
@@ -2,6 +2,59 @@
2
2
 
3
3
  All notable changes to `opencode-ship` are recorded here.
4
4
 
5
+ ## 1.1.8 — Durable self-host routing correction (unreleased)
6
+
7
+ - **Deterministic controller entrypoint.** Build calls `ship_deliver` to
8
+ dispatch one `ship-controller` session per issue. Schema-v2 worktrees
9
+ refuse implementation until the durable workflow is linked.
10
+ - **Linked-worktree execution.** Builder, task review, commit verification,
11
+ verifier/CI binding, and dual-axis final review run in the registered
12
+ feature worktree while durable state stays in the Git common directory.
13
+ - **Audited abandon.** `delivery_abandon` records immutable intent and
14
+ completion around CAS-safe cleanup of a closed, unmerged attempt. It
15
+ never closes a PR and never marks Ready.
16
+ - Automated install, qualification, and rollout continue to pin exact
17
+ `opencode-ship@<X.Y.Z>` and never resolve `@latest`.
18
+
19
+ ## 1.1.7 — Stabilization and self-hosting
20
+
21
+ > Baseline: https://github.com/Viktorxyz/opencode-ship/issues/70.
22
+ > Corrective package: https://github.com/Viktorxyz/opencode-ship/issues/72.
23
+ > Authoritative plan: `docs/release/1.1.6-correction-plan.md`.
24
+
25
+ - **Truthful baseline before implementation.** `1.1.5` remains the current
26
+ npm `latest`, and `1.1.7` is the active unpublished correction. The immutable
27
+ tag `1.1.6` failed in `pack` before npm publish or GitHub Release. This entry
28
+ does not claim the `1.1.7` fixes have shipped or qualified, and `main` does
29
+ not yet contain its own installed `.opencode` control layer.
30
+ - **Bounded follow-up slices.** Runtime and release corrections, exact-version
31
+ self-host bootstrap, and automated exact-version update proposals will ship
32
+ as separate issue/worktree/PR lifecycles. Every automated install or update
33
+ pins `opencode-ship@<X.Y.Z>` and never resolves `@latest`.
34
+ - **Convergent merge and cleanup recovery.** A Ready manifest now reconciles a
35
+ PR that a maintainer already merged in GitHub instead of attempting a second
36
+ merge. Cleanup retries resume from their persisted stage, tolerate an
37
+ already-removed worktree, delete the branch with the existing CAS guard,
38
+ seal the manifest, and clear the Git-common-dir pending record.
39
+ - **Portable locks and bounded permissions.** Managed lock templates are
40
+ package-relative rather than npm-cache absolute paths. Build no longer
41
+ installs a broad `bash/* = allow` rule; destructive command denies remain
42
+ explicit while ordinary built-ins stay consumer-owned.
43
+ - **Release and package hardening.** The GitHub Release job checks out the
44
+ resolved release ref, `prepack` fails without installing missing tools,
45
+ `opencode-ship/core` publishes real declarations and the canonical package
46
+ version, and the stale `0.1.3` source literal is removed.
47
+ - **Release claims stay evidence-bound.** This entry becomes a released
48
+ changelog only after local verification, npm provenance, the GitHub Release,
49
+ qualification hashes, and a real self-host lifecycle all agree.
50
+
51
+ ## 1.1.6 — Qualification failed before publication
52
+
53
+ > Release workflow run: https://github.com/Viktorxyz/opencode-ship/actions/runs/33495352417.
54
+
55
+ - The immutable `1.1.6` tag failed in `pack` before npm publish or GitHub
56
+ Release. No npm package or GitHub Release was created.
57
+
5
58
  ## 1.1.5 — `ship-plan` is product-only
6
59
 
7
60
  > Branch: `feat/1.1.5-ship-plan-prompt`.
package/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  > npm-distributed OpenCode installer and delivery plugin: a single command materialises the lifecycle plugin, reviewer/verifier agents, and skills into any consumer repository, with a recoverable lock and never silently overwrites managed files.
4
4
  >
5
- > **Status:** `1.1.5` is on `npm dist-tag latest` and tightens the `ship-plan` primary planning agent so the Plan tab is product-only: it asks about the product, writes `.opencode/plans/*.md`, and stops. It never asks the user how to run the work (issues vs Task N, subagent vs inline, Tab / Build, `ship-deliver`), never mentions permission globs, and never offers to implement. From 1.1.4 `ship-plan` is the write-capable planning agent; OpenCode's built-in lowercase `plan` Tab is disabled. `1.1.3` supersedes the `1.1.2 stabilization` line by dropping the broken `permission: { "*": "deny" }` wildcard and adding a stale-pointer removal path so `update` cleans the orphan key on the first run. The `1.1.0` tag is immutable. Consumers of `opencode-delivery@0.1.x` should run `pnpm dlx opencode-ship@latest init` from the same checkout; migration recognises the legacy artifacts and adopts them when their bytes match.
5
+ > **Status:** `1.1.7` is the published stabilization and self-hosting correction. The immutable tag `1.1.6` failed in `pack` before npm publish or GitHub Release; no npm package or GitHub Release was created. `1.1.8` is the unpublished durable-routing correction: Build dispatches `ship_deliver`, schema-v2 execution binds to the linked worktree, and closed unmerged attempts can be abandoned with `delivery_abandon`. See [`docs/release/1.1.6-correction-plan.md`](docs/release/1.1.6-correction-plan.md).
6
6
  >
7
- > Consumers should use `opencode-ship@1.1.0` (or `@latest`) until `1.1.1` ships. The previous `1.0.0` is on `next`; consumers who pinned to `1.0.x` will continue to receive updates on that channel.
7
+ > Use an exact package version for reproducible installs and all self-hosting work. Never resolve `@latest` inside an automated release or self-host update. Prerelease candidates publish under `npm dist-tag next` until qualification promotes a stable pin.
8
8
 
9
9
  ---
10
10
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  ```sh
14
14
  # 1. Install managed files. No flags required.
15
- pnpm dlx opencode-ship@latest init
15
+ pnpm dlx opencode-ship@1.1.5 init
16
16
 
17
17
  # 2. Restart OpenCode in this repo.
18
18
 
@@ -70,11 +70,11 @@ The only source tree that ships in the npm tarball is `assets/`. Anything copied
70
70
  Once `opencode-ship` is published, consumers install with `pnpm dlx` (or `npx`) and never edit the file by hand:
71
71
 
72
72
  ```
73
- pnpm dlx opencode-ship@latest init # install managed files
74
- pnpm dlx opencode-ship@latest update # apply a packaged upgrade
75
- pnpm dlx opencode-ship@latest diff # preview what would change
76
- pnpm dlx opencode-ship@latest doctor # environment and lock audit
77
- pnpm dlx opencode-ship@latest uninstall # remove only the files still matching the lock
73
+ pnpm dlx opencode-ship@1.1.5 init # install managed files
74
+ pnpm dlx opencode-ship@1.1.5 update # apply a packaged upgrade
75
+ pnpm dlx opencode-ship@1.1.5 diff # preview what would change
76
+ pnpm dlx opencode-ship@1.1.5 doctor # environment and lock audit
77
+ pnpm dlx opencode-ship@1.1.5 uninstall # remove only the files still matching the lock
78
78
  ```
79
79
 
80
80
  If you want to try a pre-release tarball locally without publishing to npm:
@@ -109,13 +109,13 @@ These JSON Schemas are published and discoverable through the `exports` map:
109
109
 
110
110
  ### Legacy migration
111
111
 
112
- Existing consumers of `opencode-delivery@0.1.x` (commit-pinned shim) can run `pnpm dlx opencode-ship@latest init` from the same checkout. Migration recognises `.opencode/delivery.json`, `.opencode/delivery.lock.json`, the two canonical agents, and the generic plugin `.opencode/plugin/delivery.ts`, and adopts them when their bytes match. Legacy artifacts are preserved on disk so a downgrade remains possible; the installer does NOT modify Leo or any other consumer.
112
+ Existing consumers of `opencode-delivery@0.1.x` (commit-pinned shim) can run `pnpm dlx opencode-ship@1.1.5 init` from the same checkout. Migration recognises `.opencode/delivery.json`, `.opencode/delivery.lock.json`, the two canonical agents, and the generic plugin `.opencode/plugin/delivery.ts`, and adopts them when their bytes match. Legacy artifacts are preserved on disk so a downgrade remains possible; the installer does NOT modify Leo or any other consumer.
113
113
 
114
114
  `diff` is now strictly read-only; it reports every change but never writes to disk, even when the migration phase has a candidate seed-config to plant.
115
115
 
116
116
  ## Lifecycle
117
117
 
118
- 1. Begin a Build task: the delivery plugin immediately runs any queued post-merge cleanups. Failed cleanups are recorded in `ship.lock.json#cleanupPending` and retried at the next delivery task or plugin startup.
118
+ 1. Begin a Build task: the delivery plugin immediately runs any queued post-merge cleanups. Failed cleanups are recorded under `<git-common-dir>/opencode-ship/cleanup-pending.json` and retried at the next delivery task or plugin startup.
119
119
  2. Optional Deep Research checkpoint for non-trivial plans.
120
120
  3. Find or create exactly one issue per PR.
121
121
  4. Discover the default branch and fetch it.
@@ -130,7 +130,7 @@ Existing consumers of `opencode-delivery@0.1.x` (commit-pinned shim) can run `pn
130
130
  13. Push and wait for required remote CI checks.
131
131
  14. Mark the PR Ready and stop.
132
132
  15. Explicit "merge it" re-runs the freshness checks and performs the squash merge.
133
- 16. The plugin immediately invokes `delivery_cleanup`; failures leave `cleanupPending` for the next session.
133
+ 16. The plugin immediately invokes `delivery_cleanup`; failures persist their next cleanup stage in the Git common dir for the next session.
134
134
 
135
135
  ## Exit codes
136
136
 
@@ -158,7 +158,7 @@ The shipped artifact is built by esbuild (`scripts/build.mjs`); self-contained `
158
158
  ## Status and licensing
159
159
 
160
160
  - **License:** MIT. See `LICENSE`.
161
- - **Versioning:** SemVer. v0.2.0 is the first npm-distributed release. v0.3.0 is the installer foundation. v0.4.0 adds the profile-aware installer foundation (`--profile` flag, lock schema v2, profile precedence) that issue #18 requires. v0.5.0 ships the engineering profile content (triage + grill-with-docs SKILL.md placeholders) required by issue #20. v0.6.0 ships the durable plan artifact + Plan Mode permission integration required by issue #21. v0.7.0 ships the M3 task loop contract (run store, task brief, Spec/Quality verdicts, 3-round breaker, commit binding, compaction context) required by issue #22. v0.8.0 ships the Ready gate contract (parallel Standards/Spec + verifier + CI on one HEAD) required by issue #23. v0.9.0 ships the transition matrix smoke (engineering installs all assets, lock tracks the active profile) required by issue #24. v1.0.0 promotes the dogfooded 0.10.0 to stable. v1.1.0 removes the legacy core profile and ships the one-liner init + setup-ship-workflow skill. v1.1.1 is the first fully self-hosting release (see `docs/release/1.1.1-stabilization-plan.md`).
161
+ - **Versioning:** SemVer. v0.2.0 is the first npm-distributed release. v0.3.0 is the installer foundation. v0.4.0 adds the profile-aware installer foundation (`--profile` flag, lock schema v2, profile precedence) that issue #18 requires. v0.5.0 ships the engineering profile content (triage + grill-with-docs SKILL.md placeholders) required by issue #20. v0.6.0 ships the durable plan artifact + Plan Mode permission integration required by issue #21. v0.7.0 ships the M3 task loop contract (run store, task brief, Spec/Quality verdicts, 3-round breaker, commit binding, compaction context) required by issue #22. v0.8.0 ships the Ready gate contract (parallel Standards/Spec + verifier + CI on one HEAD) required by issue #23. v0.9.0 ships the transition matrix smoke (engineering installs all assets, lock tracks the active profile) required by issue #24. v1.0.0 promotes the dogfooded 0.10.0 to stable. v1.1.0 removes the legacy core profile and ships the one-liner init + setup-ship-workflow skill. v1.1.1 began the self-hosting correction line; the immutable `1.1.6` failed before publication, `1.1.7` is the published stabilization correction, and `1.1.8` is the unpublished durable-routing correction (see `docs/release/1.1.6-correction-plan.md`).
162
162
  - **Compatibility:** the bundled plugin targets `@opencode-ai/plugin >= 1.15.5 < 2` and OpenCode `>= 1.15.5`.
163
163
 
164
164
  ## FAQ
@@ -1,6 +1,6 @@
1
1
  # Third-Party Notices
2
2
 
3
- `opencode-ship@1.1.5` ships the complete Matt Pocock and Superpowers
3
+ `opencode-ship@1.1.8` includes the complete Matt Pocock and Superpowers
4
4
  methodology under the MIT license, plus the Ship-owned installer,
5
5
  plugin, agents, and skills. The complete immutable pin list is in
6
6
  `vendor/sources.json`; the upstream snapshots are under
@@ -75,6 +75,7 @@ permission:
75
75
  delivery_issue_labels: allow
76
76
  delivery_issue_link: allow
77
77
  delivery_issue_close: ask
78
+ delivery_abandon: ask
78
79
  delivery_sync: allow
79
80
  delivery_publish: allow
80
81
  ship_plan_start: allow
@@ -89,7 +90,7 @@ permission:
89
90
  ship_final_review: deny
90
91
  ship_resume: allow
91
92
  ship_status: allow
92
- ship_deliver: allow
93
+ ship_deliver: deny
93
94
  ship_skill_discover: allow
94
95
  ship_skill_install: allow
95
96
  ship_skill_audit: allow
@@ -118,11 +119,13 @@ strong planner and task reviewer child sessions.
118
119
  5. On the final task, dispatch the parallel Standards + Spec
119
120
  final reviewers against the same HEAD, run the verifier
120
121
  in an independent session, and bind every gate to one HEAD.
121
- 6. On explicit user request, run the merge with a fresh gate
122
- recheck.
123
- 7. On resume, reconcile the durable state with the live Git
124
- state and never duplicate work already recorded in a
125
- commit trailer.
122
+ 6. On explicit user request, run the merge with a fresh gate
123
+ recheck.
124
+ 7. On resume, reconcile the durable state with the live Git
125
+ state and never duplicate work already recorded in a
126
+ commit trailer.
127
+ 8. After the user explicitly closes an unmerged PR and requests
128
+ abandon, call `delivery_abandon`. Never close the PR yourself.
126
129
 
127
130
  ## What you never do
128
131
 
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Start a delivery workflow. First checks the setup-pending marker, runs skill discovery, then triggers planning with the same-HEAD Ready and merge gates.
2
+ description: Start a delivery workflow. First checks the setup-pending marker, then dispatches the durable ship-controller through ship_deliver.
3
3
  ---
4
4
 
5
5
  # ship-deliver
@@ -25,31 +25,23 @@ If the marker is present:
25
25
 
26
26
  If the marker is absent, continue.
27
27
 
28
- ### 1. Skill discovery (mandatory)
28
+ ### 1. Dispatch the controller
29
29
 
30
- Before dispatching the planner, run the `skill-discovery` skill:
30
+ Call `ship_deliver` with the issue number. Do not implement the issue through the legacy `delivery_issue` / `delivery_worktree` / `delivery_pr` path.
31
31
 
32
- ```text
33
- npx skills find "<query from issue/plan>"
34
- ```
35
-
36
- Auto-install trusted sources (see `ship.config.json#skillDiscovery.trustedOwners`); present non-trusted candidates to the user. Limit to 5 auto-installs per dispatch.
32
+ 1. Check setup-pending.
33
+ 2. Call `ship_deliver(issueNumber)`.
34
+ 3. Surface the controller session and `wf-<issue>` workflow id.
35
+ 4. Await the explicit plan approval prompt.
36
+ 5. Resume only through `ship-controller`.
37
37
 
38
38
  ### 2. Plan + approve
39
39
 
40
- 1. Resolve or restore workflow state from `<git-common-dir>/opencode-ship/`.
41
- 2. Dispatch the strong planner (`openai/gpt-5.6-sol` by default) to produce a PlanV2 contract.
42
- 3. Wait for `ship_plan_approve` from the user. Never auto-approve.
43
- 4. Mirror the plan to the issue.
40
+ The controller starts or resumes durable workflow state, dispatches the planner, and waits for `ship_plan_approve`. Never auto-approve.
44
41
 
45
42
  ### 3. Execute
46
43
 
47
- Drive each task through:
48
-
49
- - cheap builder (`minimax/MiniMax-M3` by default) — implement + report
50
- - task reviewer (Spec + Quality) — verdict
51
- - controller commit + push
52
- - same-HEAD gate: Standards + Spec final reviews, verifier, required CI
44
+ The controller drives each task through the cheap builder, task reviewer, commit binding, and same-HEAD Standards + Spec + verifier + required CI gates.
53
45
 
54
46
  ### 4. Ready
55
47
 
@@ -57,27 +49,20 @@ Stop at Ready. Surface PR URL, worktree path, verifier SHA, and the explicit-mer
57
49
 
58
50
  ### 5. Merge
59
51
 
60
- On explicit `merge it`: fresh gate recheck, squash merge, cleanup, core downgrade, uninstall, root-config byte restoration.
52
+ On explicit `merge it`: fresh gate recheck, squash merge, and cleanup.
61
53
 
62
54
  ## Hard rules
63
55
 
64
56
  - **Never skip the setup gate.** If the marker is present, refuse to plan.
65
- - **Never skip skill discovery.** The discovery is part of the autonomous-uplift contract.
66
57
  - **Never auto-approve a plan.** The user always reviews the plan.
67
58
  - **Never mark Ready or merge without a passing Standards review, a passing Spec review, a passing verifier run, and a passing required-CI check, all bound to one HEAD.**
68
59
  - **Never force-push, hard-reset, stash, or `git worktree remove`.**
69
60
  - **Never use `gh api` or raw shell on GitHub.** Use the typed `delivery_*` tools.
70
-
71
- ## Single-shot research checkpoint
72
-
73
- If you decide the task is non-trivial, pause once and **ask the user** whether to run Deep Research before generating any prompt. The default save-tokens path is "no research, continue with the plan as written". Only on explicit "yes" do you generate a draft Deep Research prompt and run the research; summarize the relevant findings inline and continue. Do not write to `docs/research/` unless the findings materially shape an ADR; ADR storage is the project's call, not yours. Continue only after the user confirms or declines.
74
-
75
- The full procedure lives in the `planning-research-checkpoint` skill. Do not duplicate the prompt-generation logic here — just trigger the skill and respect its ask-first policy.
61
+ - **Never abandon an attempt without an explicit user request after the PR is closed unmerged.** The controller may then call `delivery_abandon`.
76
62
 
77
63
  ## Stop conditions
78
64
 
79
65
  - Setup pending: stop, run setup, then re-dispatch.
80
66
  - Ready reached: stop. Surface the PR URL, the worktree path, the recorded verifier SHA, and the explicit-merge instruction.
81
- - `merge it` requested and gates are fresh: perform the squash merge. Surface the merge SHA. The plugin will queue immediate cleanup; if cleanup fails it is recorded as `cleanupPending` and retried on the next Build task.
67
+ - `merge it` requested and gates are fresh: perform the squash merge. Surface the merge SHA.
82
68
  - Any gate fails after one re-run: stop. Surface the failing tool, the failing input, and the recorded evidence.
83
- - Unexpected lifecycle error (missing-manifest, head-changed, ci-failing): stop. Surface the error envelope.
@@ -5,7 +5,7 @@ description: Orchestrates the canonical delivery lifecycle from issue creation t
5
5
 
6
6
  # delivery-workflow
7
7
 
8
- You drive the opencode-ship package from a one-line user request to a green, conflict-free, ready-to-merge pull request.
8
+ You drive the opencode-ship package from a one-line user request to a green, conflict-free, ready-to-merge pull request by dispatching the durable controller.
9
9
 
10
10
  ## When you trigger
11
11
 
@@ -17,6 +17,7 @@ You drive the opencode-ship package from a one-line user request to a green, con
17
17
  - "Clean up my worktree" / "Tidy old worktrees" — entry point for next-task cleanup
18
18
 
19
19
  Do **not** trigger on:
20
+
20
21
  - Read-only questions ("explain issue N")
21
22
  - Plain chat about the project's domain model
22
23
  - Typo / doc one-liners that do not deserve a PR
@@ -25,40 +26,32 @@ Do **not** trigger on:
25
26
 
26
27
  | Step | Tool | Notes |
27
28
  |---|---|---|
28
- | 1. Cleanup old worktrees | `delivery_inspect` for each manifest, recovery scan, `delivery_cleanup` for provably-merged ones | Runs immediately after a successful merge; retries on next Build task if interrupted |
29
- | 2. Offer research checkpoint | (this skill) | Single-shot per session; offer only if the plan is non-trivial |
30
- | 3. Find or create the issue | `delivery_issue` | Always idempotent; never create a duplicate |
31
- | 4. Create a worktree | `delivery_worktree` | Refuse overwrites; refuse dirty tree |
32
- | 5. Implement | (consumer-owned) | Stay inside the worktree |
33
- | 6. Commit + push | (consumer-owned `git`) | Use Conventional Commits |
34
- | 7. Open draft PR | `delivery_pr` | `Closes #N` is added automatically |
35
- | 8. Sync with default branch | (consumer-owned `git`) | Merge `origin/main` into the feature branch; never rebase a published branch |
36
- | 9. Review | `task reviewer:delivery-reviewer` | Re-run if HEAD changed |
37
- | 10. Verify | `task verifier:delivery-verifier` | Same final HEAD required |
38
- | 11. Mark Ready | `delivery_ready` | Refreshes checks; refuses if any gate is stale |
39
- | 12. Stop at Ready | (this skill) | Do not merge without an explicit user request |
40
- | 13. Merge (only on explicit request) | `delivery_merge` | Re-checks base, head, and mergeability |
41
- | 14. Immediate cleanup | `delivery_cleanup` | Runs automatically right after a successful merge |
29
+ | 1. Cleanup merged worktrees | `delivery_inspect` / `delivery_cleanup` | Only for provably merged attempts |
30
+ | 2. Setup gate | `/ship-deliver` | Refuse if `.opencode/ship.setup-pending.json` exists |
31
+ | 3. Dispatch controller | `ship_deliver` | Canonical Build-to-controller entrypoint |
32
+ | 4. Plan + approve | controller / `ship_plan_approve` | Never auto-approve |
33
+ | 5. Execute in linked worktree | controller | Builder, task review, commit, verifier, CI, dual-axis final review |
34
+ | 6. Ready | `delivery_ready` | Controller-owned; same-HEAD gates required |
35
+ | 7. Stop at Ready | (this skill) | Do not merge without an explicit user request |
36
+ | 8. Merge | `delivery_merge` | Explicit user request only |
37
+ | 9. Cleanup | `delivery_cleanup` | After a successful merge |
38
+ | 10. Abandon closed unmerged attempts | `delivery_abandon` | Only after the user explicitly closes the PR and requests abandon |
39
+
40
+ Do not call `delivery_worktree`, `delivery_pr`, `delivery_ready`, or `delivery_merge` from Build to implement an issue. Those mutations belong to `ship-controller` after `ship_deliver`.
42
41
 
43
42
  ## Hard rules
44
43
 
45
- 1. Every PR carries a `Closes #N` reference. If the issue does not exist, create it first.
44
+ 1. Every PR carries a `Closes #N` reference. If the issue does not exist, the controller creates it first.
46
45
  2. The lifecycle stops at Ready by default. An explicit "merge it" is the only thing that triggers `delivery_merge`.
47
- 3. Force-push, hard-reset, stash, and `git worktree remove` are denied to you. Use `delivery_worktree` and `delivery_cleanup` instead.
46
+ 3. Force-push, hard-reset, stash, and `git worktree remove` are denied. Use typed cleanup/abandon tools.
48
47
  4. You never edit `main` directly. You never bypass the reviewer/verifier gates.
49
- 5. The typed `delivery_*` tools are the only sanctioned way to mutate GitHub state. Do not invoke `gh pr merge`, `gh api`, or raw Git plumbing directly.
48
+ 5. The typed tools are the only sanctioned way to mutate GitHub state. Do not invoke `gh pr merge`, `gh api`, or raw Git plumbing directly.
50
49
  6. When a gate fails, fix the cause and re-run only the failed gate; never skip.
51
50
  7. If `delivery_merge` returns a `MergeError`, surface it verbatim. Do not invent a workaround.
52
51
 
53
- ## Single-shot research checkpoint
54
-
55
- If you decide the task is non-trivial, pause once and **ask the user** whether to run Deep Research before generating any prompt. The default save-tokens path is "no research, continue with the plan as written". Only on explicit "yes" do you generate a draft Deep Research prompt and run the research; summarize the relevant findings inline and continue. Do not write to `docs/research/` unless the findings materially shape an ADR; ADR storage is the project's call, not yours. Continue only after the user confirms or declines.
56
-
57
- The full procedure lives in the `planning-research-checkpoint` skill. Do not duplicate the prompt-generation logic here — just trigger the skill and respect its ask-first policy.
58
-
59
52
  ## Stop conditions
60
53
 
61
54
  - Ready reached: stop. Surface the PR URL, the worktree path, the recorded verifier SHA, and the explicit-merge instruction.
62
- - `merge it` requested and gates are fresh: perform the squash merge. Surface the merge SHA. The plugin will queue immediate cleanup; if cleanup fails it is recorded as `cleanupPending` and retried on the next Build task.
55
+ - `merge it` requested and gates are fresh: perform the squash merge. Surface the merge SHA.
63
56
  - Any gate fails after one re-run: stop. Surface the failing tool, the failing input, and the recorded evidence.
64
- - Unexpected lifecycle error (missing-manifest, head-changed, ci-failing): stop. Surface the error envelope.
57
+ - Unexpected lifecycle error (missing-manifest, missing-workflow-link, head-changed, ci-failing): stop. Surface the error envelope.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // opencode-ship CLI v1.1.5
2
+ // opencode-ship CLI v1.1.8
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __esm = (fn, res) => function __init() {
@@ -110,7 +110,7 @@ import { fileURLToPath as fileURLToPath2 } from "node:url";
110
110
  var PACKAGE_VERSION, TEMPLATE_SET;
111
111
  var init_version = __esm({
112
112
  "src/version.js"() {
113
- PACKAGE_VERSION = "1.1.5";
113
+ PACKAGE_VERSION = "1.1.8";
114
114
  TEMPLATE_SET = `v${PACKAGE_VERSION}`;
115
115
  }
116
116
  });
@@ -119,6 +119,7 @@ var init_version = __esm({
119
119
  var catalog_exports = {};
120
120
  __export(catalog_exports, {
121
121
  CATALOG: () => CATALOG,
122
+ PACKAGE_ROOT: () => PACKAGE_ROOT,
122
123
  PACKAGE_VERSION: () => PACKAGE_VERSION,
123
124
  TEMPLATE_SET_ID: () => TEMPLATE_SET_ID,
124
125
  filterCatalogByProfile: () => filterCatalogByProfile,
@@ -205,7 +206,7 @@ function validateCatalog({ catalog = CATALOG } = {}) {
205
206
  }
206
207
  return catalog;
207
208
  }
208
- var TEMPLATE_SET_ID, packageRoot, MATT_SKILLS, SUPER_SKILLS, ENGINEERING_AGENTS, ENGINEERING_COMMANDS, CATALOG, ALLOWED_KINDS;
209
+ var TEMPLATE_SET_ID, packageRoot, PACKAGE_ROOT, MATT_SKILLS, SUPER_SKILLS, ENGINEERING_AGENTS, ENGINEERING_COMMANDS, CATALOG, ALLOWED_KINDS;
209
210
  var init_catalog = __esm({
210
211
  "src/installer/catalog.js"() {
211
212
  init_package_root();
@@ -213,6 +214,7 @@ var init_catalog = __esm({
213
214
  init_profile();
214
215
  TEMPLATE_SET_ID = TEMPLATE_SET;
215
216
  packageRoot = resolvePackageRoot(import.meta.url);
217
+ PACKAGE_ROOT = packageRoot;
216
218
  MATT_SKILLS = [
217
219
  "engineering-workflow",
218
220
  "grilling",
@@ -1731,7 +1733,7 @@ init_catalog();
1731
1733
  init_version();
1732
1734
  import { existsSync as existsSync13 } from "node:fs";
1733
1735
  import { mkdir as mkdir6, readFile as readFile9, rename as rename5, unlink as unlink3, writeFile as writeFile6 } from "node:fs/promises";
1734
- import { dirname as dirname8, resolve as resolve12 } from "node:path";
1736
+ import { dirname as dirname8, relative as relative2, resolve as resolve12, sep as sep2 } from "node:path";
1735
1737
 
1736
1738
  // src/installer/planner.js
1737
1739
  init_catalog();
@@ -1767,6 +1769,7 @@ var CONTROLLER_TASK_ALLOW = [
1767
1769
  "delivery-verifier"
1768
1770
  ];
1769
1771
  var PUBLIC_TOOL_IDS = [
1772
+ "delivery_abandon",
1770
1773
  "delivery_cleanup",
1771
1774
  "delivery_github_read",
1772
1775
  "delivery_inspect",
@@ -1783,6 +1786,7 @@ var PUBLIC_TOOL_IDS = [
1783
1786
  "delivery_sync",
1784
1787
  "delivery_verify",
1785
1788
  "delivery_worktree",
1789
+ "ship_deliver",
1786
1790
  "ship_final_review",
1787
1791
  "ship_plan_approve",
1788
1792
  "ship_plan_start",
@@ -1807,6 +1811,7 @@ var BUILD_TOOL_ALLOW = [
1807
1811
  "delivery_pr",
1808
1812
  "delivery_ready",
1809
1813
  "delivery_worktree",
1814
+ "ship_deliver",
1810
1815
  "ship_status",
1811
1816
  "ship_resume"
1812
1817
  ];
@@ -1814,6 +1819,7 @@ var BUILD_TOOL_ASK = [
1814
1819
  "ship_plan_approve",
1815
1820
  "delivery_merge",
1816
1821
  "delivery_issue_close",
1822
+ "delivery_abandon",
1817
1823
  "ship_skill_install"
1818
1824
  ];
1819
1825
  var CONTROLLER_TOOL_ALLOW = [
@@ -1844,7 +1850,8 @@ var CONTROLLER_TOOL_ALLOW = [
1844
1850
  var CONTROLLER_TOOL_ASK = [
1845
1851
  "ship_plan_approve",
1846
1852
  "delivery_merge",
1847
- "delivery_issue_close"
1853
+ "delivery_issue_close",
1854
+ "delivery_abandon"
1848
1855
  ];
1849
1856
  var H = "git";
1850
1857
  var RESET = "--hard";
@@ -1867,8 +1874,8 @@ var FORBIDDEN_BASH_GLOBS_CONTROLLER = [
1867
1874
  "rm -rf *",
1868
1875
  "rm -rf /*"
1869
1876
  ];
1870
- function denyMap(globs) {
1871
- const out = { "*": "allow" };
1877
+ function denyMap(globs, allowByDefault = true) {
1878
+ const out = allowByDefault ? { "*": "allow" } : {};
1872
1879
  for (const g of globs) out[g] = "deny";
1873
1880
  return out;
1874
1881
  }
@@ -1893,7 +1900,7 @@ function rootPermissionMatrix() {
1893
1900
  "delivery-verifier": "allow"
1894
1901
  },
1895
1902
  bash: {
1896
- ...denyMap(FORBIDDEN_BASH_GLOBS),
1903
+ ...denyMap(FORBIDDEN_BASH_GLOBS, false),
1897
1904
  "rm *": "ask"
1898
1905
  }
1899
1906
  },
@@ -2734,11 +2741,11 @@ function parseTree(text, errors = [], options = ParseOptions.DEFAULT) {
2734
2741
  onValue({ type: getNodeType(value), offset, length, parent: currentParent, value });
2735
2742
  ensurePropertyComplete(offset + length);
2736
2743
  },
2737
- onSeparator: (sep2, offset, length) => {
2744
+ onSeparator: (sep3, offset, length) => {
2738
2745
  if (currentParent.type === "property") {
2739
- if (sep2 === ":") {
2746
+ if (sep3 === ":") {
2740
2747
  currentParent.colonOffset = offset;
2741
- } else if (sep2 === ",") {
2748
+ } else if (sep3 === ",") {
2742
2749
  ensurePropertyComplete(offset);
2743
2750
  }
2744
2751
  }
@@ -5249,7 +5256,7 @@ async function assembleLock({ repoRoot, plan, lock, configPlan, rootPlan, profil
5249
5256
  manager: {
5250
5257
  schemaVersion: CURRENT_LOCK_SCHEMA,
5251
5258
  name: "opencode-ship",
5252
- version: "1.1.5",
5259
+ version: "1.1.8",
5253
5260
  templateSet: TEMPLATE_SET_ID,
5254
5261
  profile: resolvedProfile,
5255
5262
  appliedAt: (/* @__PURE__ */ new Date()).toISOString(),
@@ -5390,9 +5397,7 @@ function serializePlan(plan) {
5390
5397
  }
5391
5398
  function relativeTemplate(source) {
5392
5399
  if (typeof source !== "string") return source;
5393
- const prefix = `${process.cwd()}/`;
5394
- if (source.startsWith(prefix)) return source.slice(prefix.length);
5395
- return source;
5400
+ return relative2(PACKAGE_ROOT, source).split(sep2).join("/");
5396
5401
  }
5397
5402
 
5398
5403
  // src/installer/commands/doctor.js