release-skill 0.1.4 → 0.1.5

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.
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "release-skill",
11
11
  "source": "./",
12
- "version": "0.1.4",
12
+ "version": "0.1.5",
13
13
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification"
14
14
  }
15
15
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "release-skill contributors"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "release-skill contributors"
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "defaultPrompt": [
21
21
  "Assess this project for release readiness.",
22
- "Prepare a release plan for version 0.1.4.",
22
+ "Prepare a release plan for version 0.1.5.",
23
23
  "Help me understand the release workflow."
24
24
  ]
25
25
  }
package/CHANGELOG.md CHANGED
@@ -3,6 +3,33 @@
3
3
  All notable changes to the `release-skill` plugin will be documented in this
4
4
  file. The format is based on [Keep a Changelog](https://keepachangelog.com/).
5
5
 
6
+ ## [0.1.5] - 2026-07-21
7
+
8
+ ### Added
9
+
10
+ - **Explicit marketplace install timeout (`timeoutMs`)**: Claude and Codex
11
+ plugin marketplace distributions now accept an optional `timeoutMs` integer
12
+ field (range 30,000--900,000 ms; default 300,000 ms). The resolved value is
13
+ frozen into each marketplace install action's `parameters.timeoutMs` during
14
+ `prepare`, making it part of the plan digest, approval binding, and plan
15
+ integrity. The `plugin-marketplace` adapter's marketplace add, plugin install,
16
+ and plugin list commands all use the same frozen timeout, replacing the
17
+ previous hardcoded 30-second limit that caused `PARTIAL` failures on real
18
+ network installations requiring 40--105 seconds.
19
+ - **Old plan backward compatibility**: plans created before v0.1.5 that lack
20
+ `parameters.timeoutMs` on marketplace install actions default to 300,000 ms,
21
+ so existing `PARTIAL` runs can be reconciled without upgrading the plan.
22
+
23
+ ### Fixed
24
+
25
+ - **Marketplace consumer install timeout**: v0.1.4 production releases hit
26
+ `PARTIAL` because Claude Code and Codex plugin marketplace add commands
27
+ required 40--105 seconds on real networks, while the adapter hardcoded a
28
+ 30-second subprocess timeout. The timeout is now explicitly configurable per
29
+ distribution and verified through injected-executor tests. Invalid values
30
+ (non-integer, non-finite, out-of-range) fail closed rather than being
31
+ silently clamped.
32
+
6
33
  ## [0.1.4] - 2026-07-19
7
34
 
8
35
  ### Added
package/INSTALL.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [简体中文](INSTALL.zh-CN.md)
4
4
 
5
- <!-- release-skill:release-version: 0.1.4 -->
5
+ <!-- release-skill:release-version: 0.1.5 -->
6
6
  ## Prerequisites
7
7
 
8
8
  - Node.js 22.0.0 or later
package/INSTALL.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](INSTALL.md)
4
4
 
5
- <!-- release-skill:release-version: 0.1.4 -->
5
+ <!-- release-skill:release-version: 0.1.5 -->
6
6
  ## 前置条件
7
7
 
8
8
  - Node.js 22.0.0 或更高版本
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [简体中文](README.zh-CN.md) · Installation: [English](INSTALL.md) / [简体中文](INSTALL.zh-CN.md)
4
4
 
5
- <!-- release-skill:release-version: 0.1.4 -->
5
+ <!-- release-skill:release-version: 0.1.5 -->
6
6
  Release preparation for Claude Code and Codex, with human-edited files kept intact.
7
7
 
8
8
  release-skill helps a maintainer answer three questions: what will be released,
@@ -11,7 +11,7 @@ reviewed artifacts first and publishes those same artifacts later; it does not
11
11
  regenerate a README or re-pack the live workspace at the last step.
12
12
 
13
13
  <!-- release-skill:capability:external-write-boundary -->
14
- > **Current boundary:** v0.1.4 is the current release. v0.1.1 completed a real production release
14
+ > **Current boundary:** v0.1.5 is the current release. v0.1.1 completed a real production release
15
15
  > to GitHub and npm — the first production-verified milestone — followed by
16
16
  > exact npm installation and Claude/Codex consumer installation verification
17
17
  > from the frozen Git ref; "current release" and "first production-verified
@@ -27,7 +27,7 @@ regenerate a README or re-pack the live workspace at the last step.
27
27
  > publish global preflight.
28
28
 
29
29
  <!-- release-skill:capability:safe-first-command -->
30
- > **Production path verified since the v0.1.1 milestone; v0.1.4 is the current
30
+ > **Production path verified since the v0.1.1 milestone; v0.1.5 is the current
31
31
  > release.** The npm-installed CLI is the supported user entry. Source checkout
32
32
  > is the development/contributor fallback.
33
33
  >
@@ -626,10 +626,12 @@ releaseUnits:
626
626
  plugin: my-plugin
627
627
  marketplace: my-plugin
628
628
  entrySkill: my-plugin-help
629
+ timeoutMs: 300000 # optional; range 30000-900000; default 300000
629
630
  - type: codex-plugin
630
631
  plugin: my-plugin
631
632
  marketplace: my-plugin
632
633
  entrySkill: my-plugin-help
634
+ timeoutMs: 300000 # optional; range 30000-900000; default 300000
633
635
  publicFiles:
634
636
  - from: packages/plugin/.claude-plugin/plugin.json
635
637
  to: .claude-plugin/plugin.json
@@ -676,6 +678,14 @@ the entry Skill, and all required public files. A CLI smoke (`smokeBin`) is
676
678
  optional for plugin units and only applies when the published npm package
677
679
  exposes a CLI binary.
678
680
 
681
+ Plugin distributions may declare `timeoutMs` (range 30,000--900,000 ms; default
682
+ 300,000 ms). This sets the subprocess timeout for the marketplace add, plugin
683
+ install, and plugin list commands. On real networks these commands can take
684
+ 40--105 seconds; the default 300-second timeout avoids false `PARTIAL` failures.
685
+ The resolved value is frozen into the plan and approved along with all other
686
+ action parameters. Old plans without `timeoutMs` default to 300,000 ms at
687
+ execution time for backward compatibility.
688
+
679
689
  ### PARTIAL recovery and reconcile
680
690
 
681
691
  When `publish` succeeds at some checkpoints but fails at others, the run enters
package/README.zh-CN.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [English](README.md) · 安装指南:[中文](INSTALL.zh-CN.md) / [English](INSTALL.md)
4
4
 
5
- <!-- release-skill:release-version: 0.1.4 -->
5
+ <!-- release-skill:release-version: 0.1.5 -->
6
6
  面向 Claude Code 和 Codex 的发布准备工具,完整保留人工维护的文件内容。
7
7
 
8
8
  release-skill 帮助维护者回答三个问题:准备发布什么、还有哪些检查未通过、最终
@@ -10,7 +10,7 @@ release-skill 帮助维护者回答三个问题:准备发布什么、还有哪
10
10
  最后一步重新生成 README、重新打包活动工作区或覆盖人工内容。
11
11
 
12
12
  <!-- release-skill:capability:external-write-boundary -->
13
- > **当前边界:** v0.1.4 是当前发布版本。v0.1.1 已完成 GitHub 与 npm 的
13
+ > **当前边界:** v0.1.5 是当前发布版本。v0.1.1 已完成 GitHub 与 npm 的
14
14
  > 真实生产发布,是首次生产验证的历史里程碑,并从冻结 Git ref 完成精确 npm
15
15
  > 安装及 Claude/Codex 消费者安装验证;“当前发布版本”与“首次生产验证里程碑”
16
16
  > 是两个不同的事实,不得混写成同一含义。同一工作流还通过了本地
@@ -22,7 +22,7 @@ release-skill 帮助维护者回答三个问题:准备发布什么、还有哪
22
22
  > 远端唯一性检查在 `publish` 全局预检执行。
23
23
 
24
24
  <!-- release-skill:capability:safe-first-command -->
25
- > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.1.4 是当前发布版本。**
25
+ > **生产路径自 v0.1.1 里程碑起已完成真实生产验证;v0.1.5 是当前发布版本。**
26
26
  > npm 安装的 CLI 是受支持的用户入口;源码 checkout 保留为开发/贡献者路径。
27
27
  >
28
28
  > **第一条命令:**
@@ -582,10 +582,12 @@ releaseUnits:
582
582
  plugin: my-plugin
583
583
  marketplace: my-plugin
584
584
  entrySkill: my-plugin-help
585
+ timeoutMs: 300000 # 可选;范围 30000–900000;默认 300000
585
586
  - type: codex-plugin
586
587
  plugin: my-plugin
587
588
  marketplace: my-plugin
588
589
  entrySkill: my-plugin-help
590
+ timeoutMs: 300000 # 可选;范围 30000–900000;默认 300000
589
591
  publicFiles:
590
592
  - from: packages/plugin/.claude-plugin/plugin.json
591
593
  to: .claude-plugin/plugin.json
@@ -631,6 +633,12 @@ releaseUnits:
631
633
  入口 Skill 和全部 required public files。CLI 冒烟(`smokeBin`)对插件单元
632
634
  是可选项,仅当发布包同时暴露 CLI 二进制时才适用。
633
635
 
636
+ 插件分发可声明 `timeoutMs`(范围 30,000–900,000 毫秒;默认 300,000 毫秒),
637
+ 用于设置 marketplace add、plugin install 和 plugin list 三条命令的子进程超时。
638
+ 真实网络下这些命令可能需要 40–105 秒;默认 300 秒超时避免误报 `PARTIAL`。
639
+ 解析后的值冻结到计划中,与其他动作参数一起接受批准。无 `timeoutMs` 的旧计划
640
+ 在执行时默认回退到 300,000 毫秒以保证向后兼容。
641
+
634
642
  ### PARTIAL 恢复与 reconcile
635
643
 
636
644
  当 `publish` 在部分检查点成功但在其他检查点失败时,运行进入 `PARTIAL`
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "name": "release-skill",
11
11
  "source": "./",
12
- "version": "0.1.4",
12
+ "version": "0.1.5",
13
13
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification"
14
14
  }
15
15
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "release-skill contributors"
@@ -19947,7 +19947,7 @@ async function writePlanImmutable(planPath, plan) {
19947
19947
  }
19948
19948
  return { planPath, planDigest };
19949
19949
  }
19950
- function validatePlanActionCompleteness(plan) {
19950
+ function validatePlanActionCompleteness(plan, options = {}) {
19951
19951
  const failures = [];
19952
19952
  if (!plan || typeof plan !== "object") {
19953
19953
  return { passed: false, details: { failures: ["plan is null or not an object"], expectedCount: 0, actualCount: 0 } };
@@ -20254,6 +20254,26 @@ function validatePlanActionCompleteness(plan) {
20254
20254
  _checkRequired(action, "parameters.ref", action.parameters?.ref, expectedTag, unitId, failures);
20255
20255
  _checkRequired(action, "parameters.manifestDigest", action.parameters?.manifestDigest, frozen?.manifestDigest, unitId, failures);
20256
20256
  }
20257
+ {
20258
+ const raw = action.parameters?.timeoutMs;
20259
+ if (raw === void 0) {
20260
+ if (!options.legacyCompatibility) {
20261
+ failures.push(
20262
+ `unit "${unitId}", action "${action.id}": parameters.timeoutMs is missing, expected a valid timeout (30000-900000)`
20263
+ );
20264
+ }
20265
+ } else {
20266
+ if (typeof raw !== "number" || !Number.isFinite(raw) || !Number.isInteger(raw)) {
20267
+ failures.push(
20268
+ `unit "${unitId}", action "${action.id}": parameters.timeoutMs must be a finite integer, got: ${JSON.stringify(raw)}`
20269
+ );
20270
+ } else if (raw < 3e4 || raw > 9e5) {
20271
+ failures.push(
20272
+ `unit "${unitId}", action "${action.id}": parameters.timeoutMs must be between 30000 and 900000, got: ${raw}`
20273
+ );
20274
+ }
20275
+ }
20276
+ }
20257
20277
  _checkRequired(action, "expected.installed", action.expected?.installed, true, unitId, failures);
20258
20278
  _checkRequired(action, "expected.plugin", action.expected?.plugin, plugin, unitId, failures);
20259
20279
  _checkRequired(action, "expected.marketplace", action.expected?.marketplace, marketplace, unitId, failures);
@@ -20322,6 +20342,26 @@ function validatePlanActionCompleteness(plan) {
20322
20342
  _checkRequired(action, "parameters.ref", action.parameters?.ref, expectedTag, unitId, failures);
20323
20343
  _checkRequired(action, "parameters.manifestDigest", action.parameters?.manifestDigest, frozen?.manifestDigest, unitId, failures);
20324
20344
  }
20345
+ {
20346
+ const raw = action.parameters?.timeoutMs;
20347
+ if (raw === void 0) {
20348
+ if (!options.legacyCompatibility) {
20349
+ failures.push(
20350
+ `unit "${unitId}", action "${action.id}": parameters.timeoutMs is missing, expected a valid timeout (30000-900000)`
20351
+ );
20352
+ }
20353
+ } else {
20354
+ if (typeof raw !== "number" || !Number.isFinite(raw) || !Number.isInteger(raw)) {
20355
+ failures.push(
20356
+ `unit "${unitId}", action "${action.id}": parameters.timeoutMs must be a finite integer, got: ${JSON.stringify(raw)}`
20357
+ );
20358
+ } else if (raw < 3e4 || raw > 9e5) {
20359
+ failures.push(
20360
+ `unit "${unitId}", action "${action.id}": parameters.timeoutMs must be between 30000 and 900000, got: ${raw}`
20361
+ );
20362
+ }
20363
+ }
20364
+ }
20325
20365
  _checkRequired(action, "expected.installed", action.expected?.installed, true, unitId, failures);
20326
20366
  _checkRequired(action, "expected.plugin", action.expected?.plugin, plugin, unitId, failures);
20327
20367
  _checkRequired(action, "expected.marketplace", action.expected?.marketplace, marketplace, unitId, failures);
@@ -68159,6 +68199,7 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68159
68199
  const claudeDist = (unit.distributions ?? []).find((d) => d.type === "claude-plugin");
68160
68200
  if (claudeDist) {
68161
68201
  const identity = marketplaceIdentity(claudeDist);
68202
+ const claudeTimeoutMs = Number.isInteger(claudeDist.timeoutMs) ? claudeDist.timeoutMs : 3e5;
68162
68203
  actions.push({
68163
68204
  id: `claude-marketplace-install-${unit.id}`,
68164
68205
  type: "claude-marketplace-install",
@@ -68170,7 +68211,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68170
68211
  marketplace: identity.marketplace,
68171
68212
  repo: unit.publicRepo,
68172
68213
  version,
68173
- entrySkill: identity.entrySkill
68214
+ entrySkill: identity.entrySkill,
68215
+ timeoutMs: claudeTimeoutMs
68174
68216
  },
68175
68217
  expected: {
68176
68218
  installed: true,
@@ -68185,6 +68227,7 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68185
68227
  const codexDist = (unit.distributions ?? []).find((d) => d.type === "codex-plugin");
68186
68228
  if (codexDist) {
68187
68229
  const identity = marketplaceIdentity(codexDist);
68230
+ const codexTimeoutMs = Number.isInteger(codexDist.timeoutMs) ? codexDist.timeoutMs : 3e5;
68188
68231
  actions.push({
68189
68232
  id: `codex-marketplace-install-${unit.id}`,
68190
68233
  type: "codex-marketplace-install",
@@ -68196,7 +68239,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68196
68239
  marketplace: identity.marketplace,
68197
68240
  repo: unit.publicRepo,
68198
68241
  version,
68199
- entrySkill: identity.entrySkill
68242
+ entrySkill: identity.entrySkill,
68243
+ timeoutMs: codexTimeoutMs
68200
68244
  },
68201
68245
  expected: {
68202
68246
  installed: true,
@@ -68336,6 +68380,7 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68336
68380
  const claudeDist = (unit.distributions ?? []).find((d) => d.type === "claude-plugin");
68337
68381
  if (claudeDist) {
68338
68382
  const identity = marketplaceIdentity(claudeDist);
68383
+ const claudeTimeoutMs = Number.isInteger(claudeDist.timeoutMs) ? claudeDist.timeoutMs : 3e5;
68339
68384
  actions.push({
68340
68385
  id: `claude-marketplace-install-${unit.id}`,
68341
68386
  type: "claude-marketplace-install",
@@ -68350,7 +68395,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68350
68395
  version: unitVersion,
68351
68396
  entrySkill: identity.entrySkill,
68352
68397
  snapshotPath: asset.snapshotPath,
68353
- manifestDigest: asset.manifestDigest
68398
+ manifestDigest: asset.manifestDigest,
68399
+ timeoutMs: claudeTimeoutMs
68354
68400
  },
68355
68401
  expected: {
68356
68402
  installed: true,
@@ -68370,6 +68416,7 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68370
68416
  const codexDist = (unit.distributions ?? []).find((d) => d.type === "codex-plugin");
68371
68417
  if (codexDist) {
68372
68418
  const identity = marketplaceIdentity(codexDist);
68419
+ const codexTimeoutMs = Number.isInteger(codexDist.timeoutMs) ? codexDist.timeoutMs : 3e5;
68373
68420
  actions.push({
68374
68421
  id: `codex-marketplace-install-${unit.id}`,
68375
68422
  type: "codex-marketplace-install",
@@ -68384,7 +68431,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
68384
68431
  version: unitVersion,
68385
68432
  entrySkill: identity.entrySkill,
68386
68433
  snapshotPath: asset.snapshotPath,
68387
- manifestDigest: asset.manifestDigest
68434
+ manifestDigest: asset.manifestDigest,
68435
+ timeoutMs: codexTimeoutMs
68388
68436
  },
68389
68437
  expected: {
68390
68438
  installed: true,
@@ -69526,7 +69574,7 @@ async function reconcileRelease(options) {
69526
69574
  }
69527
69575
  await evidence.append({ phase: "safety-gate", gate: "plan-digest", status: "passed" });
69528
69576
  await evidence.append({ phase: "safety-gate", gate: "action-completeness", status: "started" });
69529
- const completenessResult = validatePlanActionCompleteness(plan);
69577
+ const completenessResult = validatePlanActionCompleteness(plan, { legacyCompatibility: true });
69530
69578
  if (!completenessResult.passed) {
69531
69579
  await evidence.append({
69532
69580
  phase: "safety-gate",
@@ -71194,6 +71242,23 @@ function validateMarketplaceParams(params) {
71194
71242
  }
71195
71243
  return { valid: true, error: null };
71196
71244
  }
71245
+ function resolveTimeoutMs(action) {
71246
+ const raw = action?.timeoutMs;
71247
+ if (raw === void 0) {
71248
+ return 3e5;
71249
+ }
71250
+ if (raw === null || typeof raw !== "number" || !Number.isFinite(raw) || !Number.isInteger(raw)) {
71251
+ throw new Error(
71252
+ `action.timeoutMs must be a finite integer, got: ${JSON.stringify(raw)}`
71253
+ );
71254
+ }
71255
+ if (raw < 3e4 || raw > 9e5) {
71256
+ throw new Error(
71257
+ `action.timeoutMs must be between 30000 and 900000, got: ${raw}`
71258
+ );
71259
+ }
71260
+ return raw;
71261
+ }
71197
71262
  async function run4(cmd, args2, options = {}) {
71198
71263
  return execFile9(cmd, args2, {
71199
71264
  shell: false,
@@ -71663,11 +71728,21 @@ function createPluginMarketplaceAdapter(deps = {}) {
71663
71728
  ...baseEnv,
71664
71729
  ...consumer === "claude" ? { HOME: isolatedHome, CLAUDE_CONFIG_DIR: resolve18(isolatedHome, ".claude") } : { HOME: isolatedHome, CODEX_HOME: isolatedHome }
71665
71730
  };
71731
+ let frozenTimeoutMs;
71732
+ try {
71733
+ frozenTimeoutMs = resolveTimeoutMs(action);
71734
+ } catch (timeoutErr) {
71735
+ return createResult({
71736
+ actionType,
71737
+ status: ActionStatus.EXECUTE_FAILED,
71738
+ error: timeoutErr.message
71739
+ });
71740
+ }
71666
71741
  const ref = action.ref ?? `v${action.version}`;
71667
71742
  let addOutput;
71668
71743
  const marketplaceArgs = consumer === "claude" ? ["plugin", "marketplace", "add", `${action.repo}@${ref}`] : ["plugin", "marketplace", "add", action.repo, "--ref", ref, "--json"];
71669
71744
  try {
71670
- const addResult = await exec(cliCmd, marketplaceArgs, { env, cwd: context.root });
71745
+ const addResult = await exec(cliCmd, marketplaceArgs, { env, cwd: context.root, timeout: frozenTimeoutMs });
71671
71746
  if (consumer === "codex") {
71672
71747
  try {
71673
71748
  addOutput = JSON.parse(addResult.stdout);
@@ -71703,7 +71778,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
71703
71778
  let installOutput;
71704
71779
  const installArgs = consumer === "claude" ? ["plugin", "install", `${action.plugin}@${action.marketplace}`] : ["plugin", "add", `${action.plugin}@${action.marketplace}`, "--json"];
71705
71780
  try {
71706
- const installResult = await exec(cliCmd, installArgs, { env, cwd: context.root });
71781
+ const installResult = await exec(cliCmd, installArgs, { env, cwd: context.root, timeout: frozenTimeoutMs });
71707
71782
  if (consumer === "codex") {
71708
71783
  try {
71709
71784
  installOutput = JSON.parse(installResult.stdout);
@@ -71893,6 +71968,17 @@ function createPluginMarketplaceAdapter(deps = {}) {
71893
71968
  ...baseEnv,
71894
71969
  ...consumer === "claude" ? { HOME: isolatedHome, CLAUDE_CONFIG_DIR: resolve18(isolatedHome, ".claude") } : { HOME: isolatedHome, CODEX_HOME: isolatedHome }
71895
71970
  };
71971
+ let frozenTimeoutMs;
71972
+ try {
71973
+ frozenTimeoutMs = resolveTimeoutMs(action);
71974
+ } catch (timeoutErr) {
71975
+ return createResult({
71976
+ actionType,
71977
+ status: ActionStatus.OBSERVED,
71978
+ observation: { installed: false, error: timeoutErr.message },
71979
+ error: timeoutErr.message
71980
+ });
71981
+ }
71896
71982
  let evidence = null;
71897
71983
  try {
71898
71984
  const evidenceRaw = await readFile16(resolve18(runDir, "evidence", `${consumer}-${action.plugin}`, "release-skill-install-evidence.json"), "utf8");
@@ -71920,7 +72006,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
71920
72006
  const listArgs = consumer === "claude" ? ["plugin", "list", "--json"] : ["plugin", "list", "--json"];
71921
72007
  let listOutput;
71922
72008
  try {
71923
- const result = await exec(cliCmd, listArgs, { env, cwd: context.root });
72009
+ const result = await exec(cliCmd, listArgs, { env, cwd: context.root, timeout: frozenTimeoutMs });
71924
72010
  listOutput = JSON.parse(result.stdout);
71925
72011
  } catch (listErr) {
71926
72012
  return createResult({
@@ -72248,6 +72334,7 @@ var init_plugin_marketplace = __esm({
72248
72334
  STRICT_SEMVER_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
72249
72335
  __name(validateSafeRef, "validateSafeRef");
72250
72336
  __name(validateMarketplaceParams, "validateMarketplaceParams");
72337
+ __name(resolveTimeoutMs, "resolveTimeoutMs");
72251
72338
  __name(run4, "run");
72252
72339
  __name(validateManifestFile, "validateManifestFile");
72253
72340
  __name(checkRequiredFiles, "checkRequiredFiles");
@@ -72668,7 +72755,7 @@ async function verifyRelease(options) {
72668
72755
  }
72669
72756
  validateApproval(plan, approval, { clock: clockFn, requireUnexpired: false });
72670
72757
  }
72671
- const completenessResult = validatePlanActionCompleteness(plan);
72758
+ const completenessResult = validatePlanActionCompleteness(plan, { legacyCompatibility: true });
72672
72759
  if (!completenessResult.passed) {
72673
72760
  throw new ReleaseError(
72674
72761
  GATE_FAILED,
@@ -200,6 +200,12 @@
200
200
  },
201
201
  "smokeExpectedJson": {
202
202
  "type": "object"
203
+ },
204
+ "timeoutMs": {
205
+ "type": "integer",
206
+ "minimum": 30000,
207
+ "maximum": 900000,
208
+ "description": "Timeout in milliseconds for plugin marketplace install commands. Only valid for claude-plugin and codex-plugin distributions."
203
209
  }
204
210
  },
205
211
  "allOf": [
@@ -219,6 +225,23 @@
219
225
  ]
220
226
  }
221
227
  },
228
+ {
229
+ "if": {
230
+ "required": [
231
+ "timeoutMs"
232
+ ]
233
+ },
234
+ "then": {
235
+ "properties": {
236
+ "type": {
237
+ "enum": [
238
+ "claude-plugin",
239
+ "codex-plugin"
240
+ ]
241
+ }
242
+ }
243
+ }
244
+ },
222
245
  {
223
246
  "if": {
224
247
  "properties": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "release-skill contributors"
@@ -19,7 +19,7 @@
19
19
  ],
20
20
  "defaultPrompt": [
21
21
  "Assess this project for release readiness.",
22
- "Prepare a release plan for version 0.1.4.",
22
+ "Prepare a release plan for version 0.1.5.",
23
23
  "Help me understand the release workflow."
24
24
  ]
25
25
  }