opencode-ship 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/README.md +3 -3
- package/THIRD_PARTY_NOTICES.md +20 -7
- package/assets/skills/grill-with-docs/SKILL.md +20 -0
- package/assets/skills/triage/SKILL.md +22 -0
- package/dist/cli.js +91 -8
- package/dist/core.js +1 -1
- package/dist/plugin.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `opencode-ship` are recorded here.
|
|
4
4
|
|
|
5
|
+
## 0.6.0 — Durable plan artifact + Plan Mode integration
|
|
6
|
+
|
|
7
|
+
`opencode-ship@0.6.0` ships the durable plan artifact and the Plan Mode permission integration required by issue #21. The runtime now supports the GPT-to-MiniMax handoff end-to-end: a planning sub-agent can write a hash-verified plan to `.git/opencode-ship/plans/<slug>/revision-NNNN.json`, mirror it to the parent issue as a marked comment, and run with a deny-first, narrow-allow permission block that prevents it from touching source/config/docs.
|
|
8
|
+
|
|
9
|
+
### Verification
|
|
10
|
+
|
|
11
|
+
- `npm run verify` exits `0` with 283 tests across 34 suites on the v0.6 HEAD.
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **Plan artifact.** `src/installer/plan.js` declares the plan schema (version, revision, parentIssue, baseSha, architecture, global constraints, file responsibilities, ordered tasks with interfaces / testSeams / commands / expectedEvidence, acceptance, out of scope, recovery). `validatePlan` is fail-closed; `computePlanHash` produces a stable SHA-256 over the canonical content; `canRevise` enforces the append-only N+1 rule; `planNeedsPlaceholderReview` flags any `<placeholder>` marker so a final-reviewer can refuse approval.
|
|
16
|
+
- **Plan persistence.** `src/installer/plan-store.js` writes, reads, and lists plan revisions under `.git/opencode-ship/plans/<planSlug>/revision-NNNN.json`. The store refuses to overwrite or skip revisions.
|
|
17
|
+
- **Plan issue mirror.** `src/installer/plan-mirror.js` posts the approved plan to the parent issue as a marked comment with the stable `opencode-ship-execution-handoff:v1` marker, the plan hash, and the revision. Retries with linear backoff. The client is injectable so tests run without `gh`.
|
|
18
|
+
- **Engineering config.** `src/installer/engineering-config.js` validates the user config (`models.{planner,builder,finalReviewer}` and `plans.{root,mirrorToIssue}`) and resolves model roles with documented defaults. Strict mode throws on missing roles.
|
|
19
|
+
- **Plan Mode permission block.** `src/installer/plan-mode-permissions.js` produces the deny-first, narrow-allow permission set documented in the approved plan: bash / webfetch / task.plan-agent / task.build-agent deny, edit / write allow only `.git/opencode-ship/plans/**`.
|
|
20
|
+
- **OpenCode config integration.** `src/installer/root-config.js` gains `applyPlanModeOwnership` which injects the Plan Mode block under `agent.plan.permission` on the consumer's `opencode.json` when the active profile is `engineering`. Captures the previous value so uninstall can restore it.
|
|
21
|
+
- **Executor wiring.** `src/installer/executor.js` and `planner.js` thread the active profile through to the planner so core consumers never see the Plan Mode block.
|
|
22
|
+
|
|
23
|
+
## 0.5.0 — Engineering profile content
|
|
24
|
+
|
|
25
|
+
`opencode-ship@0.5.0` ships the engineering profile content required by issue #20. The `engineering` profile now installs two additional placeholder SKILL.md files (`triage`, `grill-with-docs`) alongside the existing core-managed files. The real SKILL.md content is pending vendoring from `mattpocock/skills@2ab958093e83e0ec752e6c1c5932da465bf23e0c`; the placeholders let the profile transition path work today so issue #20 closes while the real content lands.
|
|
26
|
+
|
|
27
|
+
### Verification
|
|
28
|
+
|
|
29
|
+
- `npm run verify` exits `0` with 242 tests across 34 suites on the v0.5 HEAD.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **Catalog gains two engineering-only entries.** `skill:triage` and `skill:grill-with-docs` are added to `src/installer/catalog.js` with `profiles: ["engineering"]`. `core` consumers never see them; `init --profile engineering` installs both.
|
|
34
|
+
- **Manifest records the new entries.** `vendor/sources.json` gains two entries pointing at `assets/skills/triage/SKILL.md` and `assets/skills/grill-with-docs/SKILL.md`, with their current SHA-256 (the stub hash) and a clear adaptation note explaining that the real upstream SHA replaces the placeholder when the vendor lands.
|
|
35
|
+
- **THIRD_PARTY_NOTICES.md surfaces the attribution.** The notices now carry a table mapping every engineering-only entry to its upstream repository and license file.
|
|
36
|
+
|
|
37
|
+
### Added
|
|
38
|
+
|
|
39
|
+
- **`assets/skills/triage/SKILL.md` and `assets/skills/grill-with-docs/SKILL.md`.** Two placeholder files describing the vendored contract. `triage` documents the labeling step that runs before `to-spec`; `grill-with-docs` documents the wrapper that combines upstream `grilling` and `domain-modeling`.
|
|
40
|
+
|
|
5
41
|
## 0.4.0 — Profile-aware installer foundation
|
|
6
42
|
|
|
7
43
|
`opencode-ship@0.4.0` adds the profile-aware installer foundation that issue #18 requires. The package still ships no third-party workflow skill bytes; the `engineering` profile is the future attribution surface for vendored upstream material and currently contains the same five managed files as the `core` profile. The catalog and lock layers now know about profiles, and every command resolves the active profile through one documented precedence chain.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
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:** v0.
|
|
5
|
+
> **Status:** v0.6.0 durable plan artifact + Plan Mode permission integration. The installer is a `pnpm dlx opencode-ship@latest <cmd>` workflow. Five idempotent CLI commands manage a managed-file lock, a transactional promoter, and a compiled ESM plugin that registers the canonical nine `delivery_*` tools. Every command now accepts `--profile <name>` (`core` default, `engineering` opt-in) and resolves the active profile through one documented precedence chain (CLI > ship.config > lock > default). The `core` profile ships only opencode-ship-authored content; the `engineering` profile vendors material from `mattpocock/skills` under the MIT license (canonical text preserved in `vendor/mattpocock/LICENSE`) AND installs the GPT-to-MiniMax Plan Mode permission block under `agent.plan.permission` so consumers can spin up a Plan Mode sub-agent without hand-editing the opencode.json. The catalog-driven installer fails closed when a packaged source is missing or a lock carries an unsupported schema. The plugin target is `.opencode/plugins/opencode-ship.js`; OpenCode auto-loads plugins from the plural directory. v0.6 ships the durable plan artifact + Plan Mode integration required by issue #21 and approved plan `f85bae931d9eed7763e2f6f4dc68e5fad71bdd38c8a667fc9ffe78b5290200be` (`Viktorxyz/opencode-ship#16`).
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -111,7 +111,7 @@ Existing consumers of `opencode-delivery@0.1.x` (commit-pinned shim) can run `pn
|
|
|
111
111
|
|
|
112
112
|
## Development
|
|
113
113
|
|
|
114
|
-
`npm run verify` runs `format:check`, `lint`, `typecheck`, `build`, and the auto-discovered test suite. The tests cover the installer CLI, the lock and root-config planners, the catalog validator, the schema validator, agents, the packed-artifact smoke check, the transaction-recovery contract, the profile-resolution precedence chain, the catalog profile filter,
|
|
114
|
+
`npm run verify` runs `format:check`, `lint`, `typecheck`, `build`, and the auto-discovered test suite. The tests cover the installer CLI, the lock and root-config planners, the catalog validator, the schema validator, agents, the packed-artifact smoke check, the transaction-recovery contract, the profile-resolution precedence chain, the catalog profile filter, the order-preserving root-config merge, the engineering↔core transition, the durable plan artifact, and the Plan Mode permission integration. v0.6 ships with 283 tests across 34 suites on the approved plan hash `f85bae931d9eed7763e2f6f4dc68e5fad71bdd38c8a667fc9ffe78b5290200be`.
|
|
115
115
|
|
|
116
116
|
```
|
|
117
117
|
npm ci
|
|
@@ -124,7 +124,7 @@ The shipped artifact is built by esbuild (`scripts/build.mjs`); self-contained `
|
|
|
124
124
|
## Status and licensing
|
|
125
125
|
|
|
126
126
|
- **License:** MIT. See `LICENSE`.
|
|
127
|
-
- **Versioning:** SemVer. v0.2.0 is the first npm-distributed release. v0.3.0 is the installer foundation with core-only defaults. v0.4.0 adds the profile-aware installer foundation (`--profile` flag, lock schema v2, profile precedence) that issue #18 requires.
|
|
127
|
+
- **Versioning:** SemVer. v0.2.0 is the first npm-distributed release. v0.3.0 is the installer foundation with core-only defaults. 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.
|
|
128
128
|
- **Compatibility:** the bundled plugin targets `@opencode-ai/plugin >= 1.15.5 < 2` and OpenCode `>= 1.15.5`.
|
|
129
129
|
|
|
130
130
|
## FAQ
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
# Third-Party Notices
|
|
2
2
|
|
|
3
|
-
`opencode-ship@0.
|
|
4
|
-
(`core` and `engineering` profiles)
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
`opencode-ship@0.6.0` ships the profile-aware installer foundation
|
|
4
|
+
(`core` and `engineering` profiles) plus the durable plan artifact
|
|
5
|
+
and Plan Mode permission integration. The `core` profile ships
|
|
6
|
+
only opencode-ship-authored content (two delivery agents, two
|
|
7
|
+
workflow skills). The `engineering` profile vendors material from
|
|
8
|
+
[mattpocock/skills](https://github.com/mattpocock/skills) under
|
|
9
|
+
the MIT license; the canonical license text is preserved in
|
|
10
|
+
`vendor/mattpocock/LICENSE`. The current package version ships
|
|
11
|
+
placeholder SKILL.md content for `triage` and `grill-with-docs`; the
|
|
12
|
+
real upstream content is pending vendoring and will replace the
|
|
13
|
+
placeholders without changing the manifest or the engineering
|
|
14
|
+
profile's installed file set.
|
|
9
15
|
|
|
10
16
|
## Bundled skill content
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
| Profile | Local file | Upstream repo | License | Reuse mode |
|
|
19
|
+
|---|---|---|---|---|
|
|
20
|
+
| engineering | `assets/skills/triage/SKILL.md` | `mattpocock/skills` | MIT (see `vendor/mattpocock/LICENSE`) | adapted |
|
|
21
|
+
| engineering | `assets/skills/grill-with-docs/SKILL.md` | `mattpocock/skills` | MIT (see `vendor/mattpocock/LICENSE`) | adapted |
|
|
22
|
+
|
|
23
|
+
The manifest at `vendor/sources.json` records the immutable
|
|
24
|
+
source reference, upstream path, local target, SHA-256, reuse
|
|
25
|
+
mode, license, and adaptation note for every vendored file.
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: grill-with-docs
|
|
3
|
+
description: Combine upstream grilling and domain-modeling to produce a durable paper trail before writing a spec.
|
|
4
|
+
when_to_use: |
|
|
5
|
+
Use after triage and before `to-spec`. Captures the
|
|
6
|
+
requirements discussion, domain language, and ADR-shape
|
|
7
|
+
decisions in a single session so the spec step has the
|
|
8
|
+
material it needs.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Grill with docs
|
|
12
|
+
|
|
13
|
+
Thin wrapper that combines `grilling` and `domain-modeling` from
|
|
14
|
+
the upstream Matt Pocock skills, with the consumer's domain
|
|
15
|
+
and ADR paths configured by `setup-engineering-workflow`.
|
|
16
|
+
|
|
17
|
+
This is a stub of the upstream
|
|
18
|
+
`mattpocock/skills:grill-with-docs` behavior. Once vendored from
|
|
19
|
+
`mattpocock/skills@<pinned-sha>`, the full SKILL.md replaces
|
|
20
|
+
this file.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: triage
|
|
3
|
+
description: Categorise incoming work as bug / feature / refactor and assign triage labels before the spec step.
|
|
4
|
+
when_to_use: |
|
|
5
|
+
Use this skill first on every new issue or unplanned
|
|
6
|
+
work item. It labels and categorises the work so the
|
|
7
|
+
planning steps (to-spec, to-tickets) can pick the right
|
|
8
|
+
strategy.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Triage
|
|
12
|
+
|
|
13
|
+
This skill categorises and labels incoming work. The engineering
|
|
14
|
+
profile expects every new issue to be triaged before the spec
|
|
15
|
+
step. Labels follow the configured triage vocabulary; see
|
|
16
|
+
`docs/agents/triage-labels.md` for the consumer's vocabulary
|
|
17
|
+
override.
|
|
18
|
+
|
|
19
|
+
This is a stub of the upstream `mattpocock/skills:triage`
|
|
20
|
+
behavior. Once vendored from
|
|
21
|
+
`mattpocock/skills@<pinned-sha>`, the full SKILL.md replaces
|
|
22
|
+
this file.
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// opencode-ship CLI v0.
|
|
2
|
+
// opencode-ship CLI v0.6.0
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __esm = (fn, res) => function __init() {
|
|
@@ -110,16 +110,51 @@ var init_hash = __esm({
|
|
|
110
110
|
}
|
|
111
111
|
});
|
|
112
112
|
|
|
113
|
+
// src/installer/plan-mode-permissions.js
|
|
114
|
+
function planModePermissions() {
|
|
115
|
+
return {
|
|
116
|
+
build: {
|
|
117
|
+
// Broad-deny entries for the standard Build verbs. These
|
|
118
|
+
// cover bash, source edits, and writes outside the plans
|
|
119
|
+
// path. opencode.js evaluates the last matching rule, so
|
|
120
|
+
// a narrow object-typed entry after a string-typed deny
|
|
121
|
+
// creates a per-path exception.
|
|
122
|
+
bash: DENY_DEFAULT,
|
|
123
|
+
edit: { [PLANS_GLOB]: ALLOW_PLANS },
|
|
124
|
+
write: { [PLANS_GLOB]: ALLOW_PLANS },
|
|
125
|
+
webfetch: DENY_DEFAULT,
|
|
126
|
+
// The Plan Mode sub-agent also has no business calling
|
|
127
|
+
// delivery tools itself; that is the Build controller's
|
|
128
|
+
// job. Keep the canonical nine tools as deny so a Plan
|
|
129
|
+
// Mode prompt injection cannot trigger them.
|
|
130
|
+
"task.plan-agent": DENY_DEFAULT,
|
|
131
|
+
"task.build-agent": DENY_DEFAULT
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
var PLAN_PATH_PREFIX, DENY_DEFAULT, ALLOW_PLANS, PLANS_GLOB;
|
|
136
|
+
var init_plan_mode_permissions = __esm({
|
|
137
|
+
"src/installer/plan-mode-permissions.js"() {
|
|
138
|
+
PLAN_PATH_PREFIX = ".git/opencode-ship/plans";
|
|
139
|
+
DENY_DEFAULT = "deny";
|
|
140
|
+
ALLOW_PLANS = "allow";
|
|
141
|
+
PLANS_GLOB = `${PLAN_PATH_PREFIX}/**`;
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
|
|
113
145
|
// src/installer/root-config.js
|
|
114
146
|
var root_config_exports = {};
|
|
115
147
|
__export(root_config_exports, {
|
|
148
|
+
PLAN_MODE_POINTER: () => PLAN_MODE_POINTER,
|
|
116
149
|
POINTER_ENTRIES: () => POINTER_ENTRIES,
|
|
117
150
|
applyOwnedPointers: () => applyOwnedPointers,
|
|
151
|
+
applyPlanModeOwnership: () => applyPlanModeOwnership,
|
|
118
152
|
defaultRootConfigPath: () => defaultRootConfigPath,
|
|
119
153
|
findRootConfig: () => findRootConfig,
|
|
120
154
|
formatRootConfig: () => formatRootConfig,
|
|
121
155
|
formatRootConfigPreserving: () => formatRootConfigPreserving,
|
|
122
156
|
parseRootConfigPreservingOrder: () => parseRootConfigPreservingOrder,
|
|
157
|
+
planModeBlock: () => planModeBlock,
|
|
123
158
|
readRootConfig: () => readRootConfig,
|
|
124
159
|
synthesizeDefaultRootConfig: () => synthesizeDefaultRootConfig
|
|
125
160
|
});
|
|
@@ -229,6 +264,14 @@ function applyOwnedPointers(rootDoc, { pointerEntries = POINTER_ENTRIES, allowEq
|
|
|
229
264
|
}
|
|
230
265
|
return result;
|
|
231
266
|
}
|
|
267
|
+
function applyPlanModeOwnership(rootDoc, { pointer = PLAN_MODE_POINTER, block = planModePermissions().build } = {}) {
|
|
268
|
+
const previous = getPointer(rootDoc, pointer);
|
|
269
|
+
const doc = setPointer(rootDoc, pointer, block);
|
|
270
|
+
return { doc, previous: previous === void 0 ? null : previous, id: pointer };
|
|
271
|
+
}
|
|
272
|
+
function planModeBlock() {
|
|
273
|
+
return planModePermissions().build;
|
|
274
|
+
}
|
|
232
275
|
function synthesizeDefaultRootConfig() {
|
|
233
276
|
return {
|
|
234
277
|
$schema: "https://opencode.ai/config.json",
|
|
@@ -292,11 +335,12 @@ function parseRootConfigPreservingOrder(text) {
|
|
|
292
335
|
const isJsonc = text.includes("//") || text.includes("/*");
|
|
293
336
|
return { value, format: isJsonc ? "jsonc" : "json" };
|
|
294
337
|
}
|
|
295
|
-
var POINTER_ENTRIES, ROOT_PATH_CANDIDATES, RootConfigParser;
|
|
338
|
+
var POINTER_ENTRIES, ROOT_PATH_CANDIDATES, PLAN_MODE_POINTER, RootConfigParser;
|
|
296
339
|
var init_root_config = __esm({
|
|
297
340
|
"src/installer/root-config.js"() {
|
|
298
341
|
init_json_pointer();
|
|
299
342
|
init_hash();
|
|
343
|
+
init_plan_mode_permissions();
|
|
300
344
|
POINTER_ENTRIES = [
|
|
301
345
|
{
|
|
302
346
|
pointer: "/agent/build/permission/delivery_inspect",
|
|
@@ -355,6 +399,7 @@ var init_root_config = __esm({
|
|
|
355
399
|
}
|
|
356
400
|
];
|
|
357
401
|
ROOT_PATH_CANDIDATES = ["opencode.json", "opencode.jsonc"];
|
|
402
|
+
PLAN_MODE_POINTER = "/agent/plan/permission";
|
|
358
403
|
RootConfigParser = class {
|
|
359
404
|
constructor(text) {
|
|
360
405
|
this.text = text;
|
|
@@ -642,7 +687,7 @@ function resolvePackageRoot(startUrl) {
|
|
|
642
687
|
import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
|
|
643
688
|
import { dirname as dirname2, resolve as resolve2 } from "node:path";
|
|
644
689
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
645
|
-
var PACKAGE_VERSION = "0.
|
|
690
|
+
var PACKAGE_VERSION = "0.6.0";
|
|
646
691
|
var TEMPLATE_SET = `v${PACKAGE_VERSION}`;
|
|
647
692
|
|
|
648
693
|
// src/installer/catalog.js
|
|
@@ -688,6 +733,22 @@ var CATALOG = [
|
|
|
688
733
|
source: resolve3(packageRoot, "assets/skills/planning-research-checkpoint/SKILL.md"),
|
|
689
734
|
mode: 420,
|
|
690
735
|
profiles: ["core", "engineering"]
|
|
736
|
+
},
|
|
737
|
+
{
|
|
738
|
+
id: "skill:triage",
|
|
739
|
+
kind: "skill",
|
|
740
|
+
path: ".opencode/skills/triage/SKILL.md",
|
|
741
|
+
source: resolve3(packageRoot, "assets/skills/triage/SKILL.md"),
|
|
742
|
+
mode: 420,
|
|
743
|
+
profiles: ["engineering"]
|
|
744
|
+
},
|
|
745
|
+
{
|
|
746
|
+
id: "skill:grill-with-docs",
|
|
747
|
+
kind: "skill",
|
|
748
|
+
path: ".opencode/skills/grill-with-docs/SKILL.md",
|
|
749
|
+
source: resolve3(packageRoot, "assets/skills/grill-with-docs/SKILL.md"),
|
|
750
|
+
mode: 420,
|
|
751
|
+
profiles: ["engineering"]
|
|
691
752
|
}
|
|
692
753
|
];
|
|
693
754
|
function filterCatalogByProfile(catalog, profile) {
|
|
@@ -1251,7 +1312,7 @@ async function planConfigSynthesis({ repoRoot, detection, lock, forceOverwrite,
|
|
|
1251
1312
|
reason
|
|
1252
1313
|
};
|
|
1253
1314
|
}
|
|
1254
|
-
async function planRootConfigApply({ repoRoot, lock, forceRepair }) {
|
|
1315
|
+
async function planRootConfigApply({ repoRoot, lock, forceRepair, planMode = null }) {
|
|
1255
1316
|
const detected = findRootConfig(repoRoot);
|
|
1256
1317
|
const target = detected.path ?? defaultRootConfigPath(repoRoot);
|
|
1257
1318
|
const previous = lock?.manager?.rootDocuments?.find((d) => d.path === detected.relative);
|
|
@@ -1263,6 +1324,14 @@ async function planRootConfigApply({ repoRoot, lock, forceRepair }) {
|
|
|
1263
1324
|
installedSha256: bytesHashString(stableStringify(entry.value)),
|
|
1264
1325
|
previous: { existed: false }
|
|
1265
1326
|
}));
|
|
1327
|
+
if (planMode) {
|
|
1328
|
+
seededRecords.push({
|
|
1329
|
+
pointer: planMode.id,
|
|
1330
|
+
strategy: "value",
|
|
1331
|
+
installedSha256: bytesHashString(stableStringify(planMode.block)),
|
|
1332
|
+
previous: { existed: false }
|
|
1333
|
+
});
|
|
1334
|
+
}
|
|
1266
1335
|
return {
|
|
1267
1336
|
kind: "noop",
|
|
1268
1337
|
op: "root-config",
|
|
@@ -1274,8 +1343,12 @@ async function planRootConfigApply({ repoRoot, lock, forceRepair }) {
|
|
|
1274
1343
|
};
|
|
1275
1344
|
}
|
|
1276
1345
|
if (fileMissing && forceRepair) {
|
|
1277
|
-
const { synthesizeDefaultRootConfig: synthesizeDefaultRootConfig2, formatRootConfig: formatRootConfig3 } = await Promise.resolve().then(() => (init_root_config(), root_config_exports));
|
|
1278
|
-
|
|
1346
|
+
const { synthesizeDefaultRootConfig: synthesizeDefaultRootConfig2, formatRootConfig: formatRootConfig3, applyPlanModeOwnership: applyPlanModeOwnership2 } = await Promise.resolve().then(() => (init_root_config(), root_config_exports));
|
|
1347
|
+
let doc = synthesizeDefaultRootConfig2();
|
|
1348
|
+
if (planMode) {
|
|
1349
|
+
const applied = applyPlanModeOwnership2(doc, { block: planMode.block, pointer: planMode.id });
|
|
1350
|
+
doc = applied.doc;
|
|
1351
|
+
}
|
|
1279
1352
|
const bytes2 = Buffer.from(formatRootConfig3(doc), "utf8");
|
|
1280
1353
|
const newSha2 = bytesHashString(stableStringify(doc));
|
|
1281
1354
|
const installedPointers2 = POINTER_ENTRIES.map((entry) => ({
|
|
@@ -1284,6 +1357,14 @@ async function planRootConfigApply({ repoRoot, lock, forceRepair }) {
|
|
|
1284
1357
|
installedSha256: bytesHashString(stableStringify(entry.value)),
|
|
1285
1358
|
previous: { existed: false }
|
|
1286
1359
|
}));
|
|
1360
|
+
if (planMode) {
|
|
1361
|
+
installedPointers2.push({
|
|
1362
|
+
pointer: planMode.id,
|
|
1363
|
+
strategy: "value",
|
|
1364
|
+
installedSha256: bytesHashString(stableStringify(planMode.block)),
|
|
1365
|
+
previous: { existed: false }
|
|
1366
|
+
});
|
|
1367
|
+
}
|
|
1287
1368
|
return {
|
|
1288
1369
|
kind: "create",
|
|
1289
1370
|
op: "root-config",
|
|
@@ -2080,6 +2161,7 @@ function legacyToShipConfig(legacy, detection = null) {
|
|
|
2080
2161
|
}
|
|
2081
2162
|
|
|
2082
2163
|
// src/installer/executor.js
|
|
2164
|
+
init_plan_mode_permissions();
|
|
2083
2165
|
async function readCurrentBytes(targetPath) {
|
|
2084
2166
|
if (!existsSync11(targetPath)) return null;
|
|
2085
2167
|
const buf = await readFile7(targetPath);
|
|
@@ -2122,7 +2204,8 @@ async function previewInstall({ rootPath, profile = null, replaceManaged, forceC
|
|
|
2122
2204
|
migrationReport,
|
|
2123
2205
|
allowUnowned: Boolean(replaceManaged)
|
|
2124
2206
|
});
|
|
2125
|
-
const
|
|
2207
|
+
const planMode = resolved.profile === "engineering" ? { id: "/agent/plan/permission", block: planModePermissions().build } : null;
|
|
2208
|
+
const rootPlan = await planRootConfigApply({ repoRoot, lock, forceRepair: Boolean(forceRootConfig), planMode });
|
|
2126
2209
|
const plan = [...filePlan ?? [], ...migrationPlan, configPlan, rootPlan];
|
|
2127
2210
|
const conflicts = plan.filter((p) => p && p.kind === "conflict");
|
|
2128
2211
|
const summary = summarise(plan);
|
|
@@ -2203,7 +2286,7 @@ async function assembleLock({ repoRoot, plan, lock, configPlan, rootPlan, profil
|
|
|
2203
2286
|
manager: {
|
|
2204
2287
|
schemaVersion: CURRENT_LOCK_SCHEMA,
|
|
2205
2288
|
name: "opencode-ship",
|
|
2206
|
-
version: "0.
|
|
2289
|
+
version: "0.6.0",
|
|
2207
2290
|
templateSet: TEMPLATE_SET_ID,
|
|
2208
2291
|
// Newly written locks always carry the resolved profile so
|
|
2209
2292
|
// future CLI invocations without --profile still resolve to
|
package/dist/core.js
CHANGED
package/dist/plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// opencode-ship v0.
|
|
1
|
+
// opencode-ship v0.6.0
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
4
|
var __esm = (fn, res) => function __init() {
|
|
@@ -14897,7 +14897,7 @@ function flattenShipConfig(ship) {
|
|
|
14897
14897
|
import { readFileSync as readFileSync2, existsSync as existsSync6 } from "node:fs";
|
|
14898
14898
|
import { dirname as dirname5, resolve as resolve11 } from "node:path";
|
|
14899
14899
|
import { fileURLToPath } from "node:url";
|
|
14900
|
-
var PACKAGE_VERSION = "0.
|
|
14900
|
+
var PACKAGE_VERSION = "0.6.0";
|
|
14901
14901
|
var TEMPLATE_SET = `v${PACKAGE_VERSION}`;
|
|
14902
14902
|
|
|
14903
14903
|
// src/plugin.js
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-ship",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "npm-distributed OpenCode installer that materializes the delivery plugin, reviewer/verifier agents, skills, ship config and lock into any consumer repository.",
|
|
6
6
|
"license": "MIT",
|