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 +53 -0
- package/README.md +12 -12
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/assets/agents/ship-controller.md +9 -6
- package/assets/commands/ship-deliver.md +13 -28
- package/assets/skills/delivery-workflow/SKILL.md +19 -26
- package/dist/cli.js +20 -15
- package/dist/core.d.ts +601 -1
- package/dist/core.js +471 -36
- package/dist/plugin.js +1145 -549
- package/package.json +2 -1
- package/tests/plugin/expected-tools.mjs +6 -4
- package/tests/plugin/plugin-load.test.mjs +4 -4
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
|
+
> **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
|
-
>
|
|
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@
|
|
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@
|
|
74
|
-
pnpm dlx opencode-ship@
|
|
75
|
-
pnpm dlx opencode-ship@
|
|
76
|
-
pnpm dlx opencode-ship@
|
|
77
|
-
pnpm dlx opencode-ship@
|
|
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@
|
|
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
|
|
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
|
|
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
|
|
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
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Third-Party Notices
|
|
2
2
|
|
|
3
|
-
`opencode-ship@1.1.
|
|
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:
|
|
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
|
-
|
|
123
|
-
7. On resume, reconcile the durable state with the live Git
|
|
124
|
-
|
|
125
|
-
|
|
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,
|
|
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.
|
|
28
|
+
### 1. Dispatch the controller
|
|
29
29
|
|
|
30
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
|
29
|
-
| 2.
|
|
30
|
-
| 3.
|
|
31
|
-
| 4.
|
|
32
|
-
| 5.
|
|
33
|
-
| 6.
|
|
34
|
-
| 7.
|
|
35
|
-
| 8.
|
|
36
|
-
| 9.
|
|
37
|
-
| 10.
|
|
38
|
-
|
|
39
|
-
|
|
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,
|
|
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
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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: (
|
|
2744
|
+
onSeparator: (sep3, offset, length) => {
|
|
2738
2745
|
if (currentParent.type === "property") {
|
|
2739
|
-
if (
|
|
2746
|
+
if (sep3 === ":") {
|
|
2740
2747
|
currentParent.colonOffset = offset;
|
|
2741
|
-
} else if (
|
|
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.
|
|
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
|
-
|
|
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
|