opencode-ship 0.2.1 → 0.3.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/dist/core.js CHANGED
@@ -1,4 +1,4 @@
1
- // opencode-ship/core v0.2.1
1
+ // opencode-ship/core v0.3.0
2
2
 
3
3
  // src/adapter.js
4
4
  import { readFile, writeFile, mkdir, rename } from "node:fs/promises";
package/dist/plugin.js CHANGED
@@ -1,4 +1,4 @@
1
- // opencode-ship v0.2.1
1
+ // opencode-ship v0.3.0
2
2
  var __defProp = Object.defineProperty;
3
3
  var __getOwnPropNames = Object.getOwnPropertyNames;
4
4
  var __esm = (fn, res) => function __init() {
@@ -46,14 +46,20 @@ __export(lock_exports, {
46
46
  CURRENT_LOCK_SCHEMA: () => CURRENT_LOCK_SCHEMA,
47
47
  computeIntegrity: () => computeIntegrity,
48
48
  lockPath: () => lockPath,
49
+ lockSchemaRevision: () => lockSchemaRevision,
49
50
  migrateLegacyLock: () => migrateLegacyLock,
50
51
  readLock: () => readLock2,
52
+ readValidatedLock: () => readValidatedLock,
51
53
  validateIntegrity: () => validateIntegrity,
54
+ validateLock: () => validateLock,
52
55
  writeLock: () => writeLock
53
56
  });
54
57
  import { readFile as readFile4, writeFile as writeFile4, rename as rename4, mkdir as mkdir4 } from "node:fs/promises";
55
58
  import { existsSync as existsSync4 } from "node:fs";
56
59
  import { dirname as dirname4, resolve as resolve8 } from "node:path";
60
+ function lockSchemaRevision() {
61
+ return CURRENT_LOCK_SCHEMA;
62
+ }
57
63
  function lockPath(repoRoot) {
58
64
  return resolve8(repoRoot, ".opencode", "ship.lock.json");
59
65
  }
@@ -91,6 +97,68 @@ async function validateIntegrity(lock) {
91
97
  const expected = computeIntegrity(lock).lockSha256;
92
98
  return expected === lock.integrity.lockSha256;
93
99
  }
100
+ function validateLock(rawLock) {
101
+ if (rawLock === null || rawLock === void 0) {
102
+ return { ok: true, kind: "missing", issues: [] };
103
+ }
104
+ if (typeof rawLock !== "object" || Array.isArray(rawLock)) {
105
+ return { ok: false, kind: "shape", issues: ["lock root must be an object"] };
106
+ }
107
+ const issues = [];
108
+ let kind = "ok";
109
+ if (rawLock.contractVersion !== CURRENT_LOCK_SCHEMA) {
110
+ issues.push(`unsupported contractVersion: ${JSON.stringify(rawLock.contractVersion)} (expected ${CURRENT_LOCK_SCHEMA})`);
111
+ kind = "schema";
112
+ }
113
+ const manager = rawLock.manager;
114
+ if (manager === void 0) {
115
+ issues.push("manager section missing");
116
+ kind = kind === "ok" ? "shape" : kind;
117
+ } else if (typeof manager !== "object" || manager === null) {
118
+ issues.push("manager section must be an object");
119
+ kind = kind === "ok" ? "shape" : kind;
120
+ } else if (manager.schemaVersion !== CURRENT_LOCK_SCHEMA) {
121
+ issues.push(`unsupported manager.schemaVersion: ${JSON.stringify(manager.schemaVersion)} (expected ${CURRENT_LOCK_SCHEMA})`);
122
+ kind = "schema";
123
+ } else if (manager.name !== "opencode-ship") {
124
+ issues.push(`unknown manager.name: ${JSON.stringify(manager.name)}`);
125
+ kind = "shape";
126
+ }
127
+ if (!rawLock.files || !Array.isArray(rawLock.files)) {
128
+ issues.push("files must be an array");
129
+ kind = kind === "ok" ? "shape" : kind;
130
+ }
131
+ if (!rawLock.integrity || typeof rawLock.integrity !== "object") {
132
+ issues.push("integrity section missing");
133
+ kind = kind === "ok" ? "shape" : kind;
134
+ } else {
135
+ const expected = computeIntegrity(rawLock).lockSha256;
136
+ if (expected !== rawLock.integrity.lockSha256) {
137
+ issues.push(`integrity mismatch: stored ${rawLock.integrity.lockSha256} != computed ${expected}`);
138
+ kind = "integrity";
139
+ }
140
+ }
141
+ return { ok: issues.length === 0, kind, issues };
142
+ }
143
+ async function readValidatedLock(repoRoot) {
144
+ const path = lockPath(repoRoot);
145
+ if (!existsSync4(path)) {
146
+ return { kind: "missing", lock: null, issues: [] };
147
+ }
148
+ let raw;
149
+ try {
150
+ const text = await readFile4(path, "utf8");
151
+ raw = JSON.parse(text);
152
+ } catch (e) {
153
+ return {
154
+ kind: "integrity",
155
+ lock: null,
156
+ issues: [`unable to parse lock JSON: ${e?.message ?? String(e)}`]
157
+ };
158
+ }
159
+ const validation = validateLock(raw);
160
+ return { kind: validation.kind, lock: validation.ok ? raw : null, issues: validation.issues };
161
+ }
94
162
  async function migrateLegacyLock(repoRoot) {
95
163
  const legacy = resolve8(repoRoot, ".opencode", "delivery.lock.json");
96
164
  if (!existsSync4(legacy)) return null;
@@ -12540,7 +12608,7 @@ function tool(input) {
12540
12608
  tool.schema = external_exports;
12541
12609
 
12542
12610
  // src/plugin.js
12543
- import { resolve as resolve11 } from "node:path";
12611
+ import { resolve as resolve12 } from "node:path";
12544
12612
  import { readFile as readFile5 } from "node:fs/promises";
12545
12613
 
12546
12614
  // src/adapter.js
@@ -12765,7 +12833,7 @@ function parseRepoSlug(slug) {
12765
12833
 
12766
12834
  // src/drivers/gh-cli.js
12767
12835
  function defaultRunner(cwd, env) {
12768
- return (args) => new Promise((resolve12, reject2) => {
12836
+ return (args) => new Promise((resolve13, reject2) => {
12769
12837
  const proc = spawn("gh", args, {
12770
12838
  cwd,
12771
12839
  env,
@@ -12777,7 +12845,7 @@ function defaultRunner(cwd, env) {
12777
12845
  proc.stdout.on("data", (d) => stdout += d.toString());
12778
12846
  proc.stderr.on("data", (d) => stderr += d.toString());
12779
12847
  proc.on("error", reject2);
12780
- proc.on("close", (status) => resolve12({ status: status ?? -1, stdout, stderr }));
12848
+ proc.on("close", (status) => resolve13({ status: status ?? -1, stdout, stderr }));
12781
12849
  });
12782
12850
  }
12783
12851
  function viewFields() {
@@ -14207,7 +14275,7 @@ import { dirname as dirname3, resolve as resolve7 } from "node:path";
14207
14275
  // schema/ship-config.schema.json
14208
14276
  var ship_config_schema_default = {
14209
14277
  $schema: "https://json-schema.org/draft/2020-12/schema",
14210
- $id: "https://github.com/Viktorxyz/opencode-delivery/schema/ship-config.schema.json",
14278
+ $id: "https://github.com/Viktorxyz/opencode-ship/schema/ship-config.schema.json",
14211
14279
  title: "opencode-ship user config",
14212
14280
  type: "object",
14213
14281
  required: ["schemaVersion"],
@@ -14805,8 +14873,14 @@ function flattenShipConfig(ship) {
14805
14873
  return adapter;
14806
14874
  }
14807
14875
 
14876
+ // src/version.js
14877
+ import { readFileSync as readFileSync2, existsSync as existsSync6 } from "node:fs";
14878
+ import { dirname as dirname5, resolve as resolve11 } from "node:path";
14879
+ import { fileURLToPath } from "node:url";
14880
+ var PACKAGE_VERSION = "0.3.0";
14881
+ var TEMPLATE_SET = `v${PACKAGE_VERSION}`;
14882
+
14808
14883
  // src/plugin.js
14809
- var VERSION = "0.2.1";
14810
14884
  var toolDefs = [
14811
14885
  ["delivery_inspect", "Inspect a manifest and a project-local doctor report.", "inspect"],
14812
14886
  ["delivery_issue", "Find or create the issue for a delivery task.", "issue"],
@@ -14843,7 +14917,7 @@ async function resolveRepoSlug(repoRoot, detection, config2) {
14843
14917
  const fromConfig = config2?.value?.project?.repository;
14844
14918
  if (typeof fromConfig === "string" && fromConfig.includes("/")) return fromConfig;
14845
14919
  if (detection?.repository) return detection.repository;
14846
- const gitConfig = await readFile5(resolve11(repoRoot, ".git/config"), "utf8").catch(() => null);
14920
+ const gitConfig = await readFile5(resolve12(repoRoot, ".git/config"), "utf8").catch(() => null);
14847
14921
  if (gitConfig) {
14848
14922
  const m = gitConfig.match(/url\s*=\s*.*?github\.com[:/]([^/]+)\/([^/\s]+?)(?:\.git)?\b/);
14849
14923
  if (m) return `${m[1]}/${m[2]}`;
@@ -14875,7 +14949,7 @@ async function bestEffortCleanupQueue(repoRoot, adapter) {
14875
14949
  return { pending, manifestTasks: tasks.map((t) => t.taskId), ...out };
14876
14950
  }
14877
14951
  async function buildRuntime(worktree) {
14878
- const repoRootAbs = resolve11(worktree ?? process.cwd());
14952
+ const repoRootAbs = resolve12(worktree ?? process.cwd());
14879
14953
  const detection = detectProject(repoRootAbs);
14880
14954
  const legacyAdapter = await loadAdapter(repoRootAbs);
14881
14955
  const config2 = await loadConfig(repoRootAbs);
@@ -14898,7 +14972,7 @@ async function buildRuntime(worktree) {
14898
14972
  repoSlug: repoSlug ?? "owner/repo",
14899
14973
  owner,
14900
14974
  driver,
14901
- packageVersion: VERSION,
14975
+ packageVersion: PACKAGE_VERSION,
14902
14976
  lastTaskId: null,
14903
14977
  cleanupQueueOnStartup: cleanup,
14904
14978
  recover: () => recoverManifestAfterCrash
@@ -40,7 +40,7 @@ with three surfaces:
40
40
 
41
41
  Five output classes are installer-managed and recorded in the lock:
42
42
 
43
- - `.opencode/plugin/opencode-ship.js` — the bundled plugin.
43
+ - `.opencode/plugins/opencode-ship.js` — the bundled plugin.
44
44
  - `.opencode/agents/delivery-reviewer.md`,
45
45
  `.opencode/agents/delivery-verifier.md`.
46
46
  - `.opencode/skills/delivery-workflow/SKILL.md`,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-ship",
3
- "version": "0.2.1",
3
+ "version": "0.3.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",
@@ -17,6 +17,10 @@
17
17
  "node": ">=22.6.0",
18
18
  "opencode": ">=1.15.5"
19
19
  },
20
+ "publishConfig": {
21
+ "access": "public",
22
+ "provenance": true
23
+ },
20
24
  "peerDependencies": {
21
25
  "@opencode-ai/plugin": ">=1.15.5 <2"
22
26
  },
@@ -43,6 +47,7 @@
43
47
  "assets",
44
48
  "schema",
45
49
  "docs",
50
+ "THIRD_PARTY_NOTICES.md",
46
51
  "README.md",
47
52
  "CHANGELOG.md",
48
53
  "LICENSE"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/Viktorxyz/opencode-delivery/schema/project-adapter.schema.json",
3
+ "$id": "https://github.com/Viktorxyz/opencode-ship/schema/project-adapter.schema.json",
4
4
  "title": "opencode-ship project adapter",
5
5
  "type": "object",
6
6
  "required": ["contractVersion"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/Viktorxyz/opencode-delivery/schema/ship-config.schema.json",
3
+ "$id": "https://github.com/Viktorxyz/opencode-ship/schema/ship-config.schema.json",
4
4
  "title": "opencode-ship user config",
5
5
  "type": "object",
6
6
  "required": ["schemaVersion"],
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
- "$id": "https://github.com/Viktorxyz/opencode-delivery/schema/ship-lock.schema.json",
3
+ "$id": "https://github.com/Viktorxyz/opencode-ship/schema/ship-lock.schema.json",
4
4
  "title": "opencode-ship install lock",
5
5
  "type": "object",
6
6
  "required": ["contractVersion", "manager", "files", "integrity"],