release-skill 0.4.0 → 0.4.2
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/.claude-plugin/marketplace.json +6 -2
- package/.claude-plugin/plugin.json +2 -2
- package/.codebuddy-plugin/plugin.json +2 -2
- package/.codex-plugin/plugin.json +4 -4
- package/.kimi-plugin/plugin.json +3 -3
- package/CHANGELOG.md +28 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/LICENSE +183 -18
- package/NOTICE +4 -2
- package/README.md +37 -21
- package/README.zh-CN.md +27 -18
- package/adapters/claude/.claude-plugin/marketplace.json +6 -2
- package/adapters/claude/.claude-plugin/plugin.json +2 -2
- package/adapters/claude/bin/release-skill.bundle.mjs +100 -18
- package/adapters/claude/schemas/release-plan.schema.json +5 -0
- package/adapters/claude/schemas/release-project.schema.json +5 -0
- package/adapters/claude/skills/release-setup/SKILL.md +6 -0
- package/adapters/codex/.codex-plugin/plugin.json +4 -4
- package/adapters/codex/bin/release-skill.bundle.mjs +100 -18
- package/adapters/codex/schemas/release-plan.schema.json +5 -0
- package/adapters/codex/schemas/release-project.schema.json +5 -0
- package/adapters/codex/skills/release-setup/SKILL.md +6 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +3 -3
- package/adapters/kimi/bin/release-skill.bundle.mjs +100 -18
- package/adapters/kimi/schemas/release-plan.schema.json +5 -0
- package/adapters/kimi/schemas/release-project.schema.json +5 -0
- package/adapters/kimi/skills/release-setup/SKILL.md +6 -0
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +2 -2
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +100 -18
- package/adapters/workbuddy/schemas/release-plan.schema.json +5 -0
- package/adapters/workbuddy/schemas/release-project.schema.json +5 -0
- package/adapters/workbuddy/skills/release-setup/SKILL.md +6 -0
- package/bin/release-skill.bundle.mjs +100 -18
- package/package.json +2 -2
- package/schemas/release-plan.schema.json +5 -0
- package/schemas/release-project.schema.json +5 -0
- package/skills/release-setup/SKILL.md +6 -0
- package/skills-src/release-setup/SKILL.md +6 -0
- package/src/adapters/npm.mjs +31 -0
- package/src/adapters/plugin-marketplace.mjs +21 -5
- package/src/commands/prepare.mjs +19 -13
- package/src/core/plan.mjs +4 -3
- package/src/platforms/codebuddy.mjs +92 -10
- package/src/platforms/registry.mjs +4 -3
|
@@ -98,6 +98,12 @@ node -e 'const fs=require("node:fs");const [c,p,a]=process.argv.slice(1).map(x=>
|
|
|
98
98
|
node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
|
|
99
99
|
```
|
|
100
100
|
|
|
101
|
+
## publisher 字段与个人片段泄漏策略
|
|
102
|
+
|
|
103
|
+
setup 生成的 `.release-skill/project.yaml` 中 `publisher` 是**已批准的公开发布身份**:它是人工确认的对外发布署名,属于公开面的一部分,而非需要隐藏的私有信息。
|
|
104
|
+
|
|
105
|
+
若目标仓库用“个人片段”类泄漏策略扫描仓树,而该策略按片段匹配恰好覆盖到 `publisher` 字段,正确做法不是删除或改写策略,而是由贡献者在**本地、gitignore 的个人片段 overlay** 中为该规则声明位置豁免(如 `approvedPlacements`:限定 `publisher` 所在的确切文件路径与行键前缀)。豁免只放行已批准的放置位置,其余出现照常命中;overlay 不入库,个人片段本身不进 committed 策略。
|
|
106
|
+
|
|
101
107
|
## 故障路由
|
|
102
108
|
|
|
103
109
|
- `NEEDS_INPUT`:审阅紧凑摘要;有冲突先修正权威事实并重跑。
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-skill",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "广州市风荷科技有限公司"
|
|
7
7
|
},
|
|
8
|
-
"license": "
|
|
8
|
+
"license": "Apache-2.0",
|
|
9
9
|
"skills": [
|
|
10
10
|
"./skills/"
|
|
11
11
|
]
|
|
@@ -9,7 +9,7 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
|
|
|
9
9
|
// Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
|
|
10
10
|
const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
|
|
11
11
|
// Package identity injected at build time — closure-independent --version probe.
|
|
12
|
-
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.4.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.4.2"});
|
|
13
13
|
|
|
14
14
|
var __create = Object.create;
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -17400,6 +17400,19 @@ function normalizePlanForDigest2(plan) {
|
|
|
17400
17400
|
}
|
|
17401
17401
|
return normalized;
|
|
17402
17402
|
}
|
|
17403
|
+
function resolveCodeBuddyMarketplace(action) {
|
|
17404
|
+
const marketplace = action?.marketplace ?? CODEBUDDY_MARKETPLACE_NAME;
|
|
17405
|
+
if (typeof marketplace !== "string" || marketplace.length === 0) {
|
|
17406
|
+
throw new Error(`codebuddy marketplace must be a non-empty string when declared, got ${JSON.stringify(action?.marketplace)}`);
|
|
17407
|
+
}
|
|
17408
|
+
return marketplace;
|
|
17409
|
+
}
|
|
17410
|
+
function resolveCodeBuddyMarketplaceSource(action) {
|
|
17411
|
+
if (action?.marketplace === void 0 || action?.marketplace === null) {
|
|
17412
|
+
return CODEBUDDY_MARKETPLACE_SOURCE;
|
|
17413
|
+
}
|
|
17414
|
+
return typeof action.marketplaceSource === "string" && action.marketplaceSource.length > 0 ? action.marketplaceSource : null;
|
|
17415
|
+
}
|
|
17403
17416
|
async function resolveCodeBuddyBoundPlanDigest(context) {
|
|
17404
17417
|
const plan = context?.plan;
|
|
17405
17418
|
if (!plan || typeof plan !== "object" || Array.isArray(plan)) {
|
|
@@ -17440,12 +17453,14 @@ function buildCodeBuddyManualInstructions({
|
|
|
17440
17453
|
version,
|
|
17441
17454
|
ref,
|
|
17442
17455
|
attestationDir,
|
|
17443
|
-
requiresInstalledClosure
|
|
17456
|
+
requiresInstalledClosure,
|
|
17457
|
+
marketplace,
|
|
17458
|
+
marketplaceSource
|
|
17444
17459
|
}) {
|
|
17445
17460
|
return [
|
|
17446
17461
|
`CodeBuddy/WorkBuddy \u63D2\u4EF6\u5B89\u88C5\u65E0\u6CD5\u9501\u5B9A\u51BB\u7ED3 ref\uFF08codebuddy CLI marketplace add/install \u6CA1\u6709 ref \u9009\u9879\uFF0C\u8DDF\u8E2A\u9ED8\u8BA4\u5206\u652F\uFF09\uFF0C\u56E0\u6B64\u5B89\u88C5\u662F\u9700\u8981\u4EBA\u5DE5\u7ED3\u679C\u8BC1\u660E\u7684\u624B\u52A8\u6B65\u9AA4\u3002`,
|
|
17447
17462
|
`1) publish \u5B8C\u6210\u6240\u6709\u8FDC\u7AEF\u5199\u5165\u540E\u8FDB\u5165 PUBLISHED \u72B6\u6001\uFF08\u81EA\u52A8\u5316 Git \u5206\u652F/\u6807\u7B7E\u3001npm \u548C GitHub Release \u5199\u5165\u5DF2\u5B8C\u6210\uFF09\u3002\u6B64 codebuddy \u68C0\u67E5\u70B9\u6807\u8BB0\u4E3A\u9700\u8981\u4EBA\u5DE5\u5B89\u88C5\u3002`,
|
|
17448
|
-
`2) \u4ECE\u7EDF\u4E00\u5E02\u573A "${
|
|
17463
|
+
`2) \u4ECE\u7EDF\u4E00\u5E02\u573A "${marketplace}"${marketplaceSource ? ` (${marketplaceSource})` : ""} \u5B89\u88C5 ${plugin}\u3002\u786E\u8BA4\u5B89\u88C5\u7684\u63D2\u4EF6\u7248\u672C\u7B49\u4E8E\u51BB\u7ED3\u7248\u672C ${version}\u3002`,
|
|
17449
17464
|
`3) \u5C06\u4EBA\u5DE5\u7ED3\u679C JSON \u5199\u5165: ${attestationDir}/${CODEBUDDY_ATTESTATION_FILE}`,
|
|
17450
17465
|
` \u5FC5\u586B\u5B57\u6BB5: platform="codebuddy", version, planDigest\uFF08\u51BB\u7ED3\u8BA1\u5212\u6458\u8981\uFF09, result("passed" \u6216 "failed"), actor\uFF08\u786E\u8BA4\u4EBA\uFF09, confirmedAt\uFF08ISO 8601 \u65F6\u95F4\u6233\uFF09${requiresInstalledClosure ? '\uFF0CinstallChannel("desktop" \u6216 "cli")\uFF0CinstallPath\uFF08\u5B9E\u9645\u5B89\u88C5\u540E\u7684\u63D2\u4EF6\u76EE\u5F55\uFF09' : ""}`,
|
|
17451
17466
|
` \u53EF\u9009\u5B57\u6BB5: note\uFF08\u5907\u6CE8\uFF09`,
|
|
@@ -17509,12 +17524,29 @@ function validateCodeBuddyAttestation(attestation, action, isoNow, boundPlanDige
|
|
|
17509
17524
|
return { valid: false, error: 'codebuddy attestation installPath must not contain path traversal ("..")', normalized: null };
|
|
17510
17525
|
}
|
|
17511
17526
|
if (normalized.installChannel === "cli") {
|
|
17512
|
-
|
|
17527
|
+
let resolvedMarketplace;
|
|
17528
|
+
try {
|
|
17529
|
+
resolvedMarketplace = resolveCodeBuddyMarketplace(action);
|
|
17530
|
+
} catch (resolveErr) {
|
|
17531
|
+
return { valid: false, error: resolveErr.message, normalized: null };
|
|
17532
|
+
}
|
|
17533
|
+
const expectedSuffix = `.workbuddy/plugins/marketplaces/${resolvedMarketplace}/plugins/${action.plugin}`;
|
|
17513
17534
|
if (!normalized.installPath.endsWith(expectedSuffix)) {
|
|
17514
17535
|
return { valid: false, error: `codebuddy CLI attestation installPath must end with "${expectedSuffix}", got "${normalized.installPath}"`, normalized: null };
|
|
17515
17536
|
}
|
|
17516
17537
|
}
|
|
17517
17538
|
}
|
|
17539
|
+
if (normalized.marketplace !== void 0) {
|
|
17540
|
+
let resolvedMarketplace;
|
|
17541
|
+
try {
|
|
17542
|
+
resolvedMarketplace = resolveCodeBuddyMarketplace(action);
|
|
17543
|
+
} catch (resolveErr) {
|
|
17544
|
+
return { valid: false, error: resolveErr.message, normalized: null };
|
|
17545
|
+
}
|
|
17546
|
+
if (normalized.marketplace !== resolvedMarketplace) {
|
|
17547
|
+
return { valid: false, error: `codebuddy attestation marketplace "${normalized.marketplace}" does not match the resolved marketplace "${resolvedMarketplace}"`, normalized: null };
|
|
17548
|
+
}
|
|
17549
|
+
}
|
|
17518
17550
|
if (normalized.result !== "passed" && normalized.result !== "failed") {
|
|
17519
17551
|
return { valid: false, error: `codebuddy attestation result "${normalized.result}" must be "passed" or "failed"`, normalized: null };
|
|
17520
17552
|
}
|
|
@@ -17607,6 +17639,17 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17607
17639
|
});
|
|
17608
17640
|
}
|
|
17609
17641
|
const ref = action.ref ?? `v${action.version}`;
|
|
17642
|
+
let marketplace;
|
|
17643
|
+
try {
|
|
17644
|
+
marketplace = resolveCodeBuddyMarketplace(action);
|
|
17645
|
+
} catch (marketplaceErr) {
|
|
17646
|
+
return createResult({
|
|
17647
|
+
actionType,
|
|
17648
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
17649
|
+
error: marketplaceErr.message
|
|
17650
|
+
});
|
|
17651
|
+
}
|
|
17652
|
+
const marketplaceSource = resolveCodeBuddyMarketplaceSource(action);
|
|
17610
17653
|
let attestationDir;
|
|
17611
17654
|
try {
|
|
17612
17655
|
attestationDir = codebuddyAuthorityDir(context, planDigest, action.plugin);
|
|
@@ -17622,7 +17665,9 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17622
17665
|
version: action.version,
|
|
17623
17666
|
ref,
|
|
17624
17667
|
attestationDir,
|
|
17625
|
-
requiresInstalledClosure: Boolean(context.plan?.skillResourceClosure)
|
|
17668
|
+
requiresInstalledClosure: Boolean(context.plan?.skillResourceClosure),
|
|
17669
|
+
marketplace,
|
|
17670
|
+
marketplaceSource
|
|
17626
17671
|
});
|
|
17627
17672
|
const requirement = {
|
|
17628
17673
|
kind: "codebuddy-manual-install-requirement",
|
|
@@ -17632,6 +17677,8 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17632
17677
|
repo: action.repo,
|
|
17633
17678
|
ref,
|
|
17634
17679
|
entrySkill: action.entrySkill,
|
|
17680
|
+
marketplace,
|
|
17681
|
+
...marketplaceSource ? { marketplaceSource } : {},
|
|
17635
17682
|
planDigest,
|
|
17636
17683
|
attestationDir,
|
|
17637
17684
|
attestationFile: CODEBUDDY_ATTESTATION_FILE,
|
|
@@ -17644,7 +17691,7 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17644
17691
|
confirmedAt: "<ISO 8601 timestamp>",
|
|
17645
17692
|
...context.plan?.skillResourceClosure ? {
|
|
17646
17693
|
installChannel: '<"desktop" or "cli">',
|
|
17647
|
-
installPath: `<actual .workbuddy/plugins/marketplaces/${
|
|
17694
|
+
installPath: `<actual .workbuddy/plugins/marketplaces/${marketplace}/plugins/${action.plugin} directory>`
|
|
17648
17695
|
} : {},
|
|
17649
17696
|
note: "<optional note>"
|
|
17650
17697
|
},
|
|
@@ -17736,6 +17783,8 @@ var init_codebuddy = __esm({
|
|
|
17736
17783
|
CODEBUDDY_ATTESTATION_FILE = "release-skill-codebuddy-attestation.json";
|
|
17737
17784
|
CODEBUDDY_MARKETPLACE_NAME = "artifact-skill-set";
|
|
17738
17785
|
CODEBUDDY_MARKETPLACE_SOURCE = "https://github.com/ifoohoo/artifact-skill-set";
|
|
17786
|
+
__name(resolveCodeBuddyMarketplace, "resolveCodeBuddyMarketplace");
|
|
17787
|
+
__name(resolveCodeBuddyMarketplaceSource, "resolveCodeBuddyMarketplaceSource");
|
|
17739
17788
|
CODEBUDDY_PLUGIN_MANIFEST_RELATIVE = join4(".codebuddy-plugin", "plugin.json");
|
|
17740
17789
|
CODEBUDDY_MAX_ATTESTATION_VALIDITY_MS = 24 * 60 * 60 * 1e3;
|
|
17741
17790
|
__name(resolveCodeBuddyBoundPlanDigest, "resolveCodeBuddyBoundPlanDigest");
|
|
@@ -18465,9 +18514,10 @@ var init_registry = __esm({
|
|
|
18465
18514
|
marketplace: ".claude-plugin/marketplace.json"
|
|
18466
18515
|
}),
|
|
18467
18516
|
marketplaceSourceForm: null,
|
|
18468
|
-
// codebuddy installs from a unified marketplace
|
|
18469
|
-
//
|
|
18470
|
-
// ./codebuddy.mjs); the
|
|
18517
|
+
// codebuddy installs from a unified marketplace whose identity is optional
|
|
18518
|
+
// on the action: a distribution may declare `marketplace` to override the
|
|
18519
|
+
// default constant in ./codebuddy.mjs (resolveCodeBuddyMarketplace); the
|
|
18520
|
+
// entry-version binding does not apply either way (null = N/A).
|
|
18471
18521
|
marketplaceEntryCarriesVersion: null,
|
|
18472
18522
|
// codebuddy has no marketplace add that can pin a frozen ref (attestation
|
|
18473
18523
|
// loop instead), so the marketplace ref form does not apply (null = N/A).
|
|
@@ -71134,6 +71184,7 @@ function extractManifestFromTarball(tarballBuffer, expected) {
|
|
|
71134
71184
|
}
|
|
71135
71185
|
let offset = 0;
|
|
71136
71186
|
let manifest = null;
|
|
71187
|
+
let readme = null;
|
|
71137
71188
|
while (offset + 512 <= data.length) {
|
|
71138
71189
|
let allZero = true;
|
|
71139
71190
|
for (let i = 0; i < 512; i++) {
|
|
@@ -71183,6 +71234,20 @@ function extractManifestFromTarball(tarballBuffer, expected) {
|
|
|
71183
71234
|
throw new Error(`tarball manifest version "${manifest.version}" does not match expected "${expected.version}"`);
|
|
71184
71235
|
}
|
|
71185
71236
|
}
|
|
71237
|
+
if (entryName.toLowerCase() === "package/readme.md") {
|
|
71238
|
+
if (readme) throw new Error("tarball contains conflicting package README entries");
|
|
71239
|
+
if (!(typeFlag === 0 || typeFlag === 48)) {
|
|
71240
|
+
throw new Error("tarball package README must be a regular file");
|
|
71241
|
+
}
|
|
71242
|
+
const bodyStart = offset + 512;
|
|
71243
|
+
const bodyEnd = bodyStart + size;
|
|
71244
|
+
if (bodyEnd > data.length) throw new Error("frozen npm tarball entry exceeds archive bounds");
|
|
71245
|
+
if (size > 10 * 1024 * 1024) throw new Error("tarball package README is unreasonably large");
|
|
71246
|
+
readme = {
|
|
71247
|
+
content: data.subarray(bodyStart, bodyEnd).toString("utf8"),
|
|
71248
|
+
filename: entryName.slice("package/".length)
|
|
71249
|
+
};
|
|
71250
|
+
}
|
|
71186
71251
|
const nextOffset = offset + 512 + Math.ceil(size / 512) * 512;
|
|
71187
71252
|
if (!Number.isSafeInteger(nextOffset) || nextOffset > data.length) {
|
|
71188
71253
|
throw new Error("frozen npm tarball entry exceeds archive bounds");
|
|
@@ -71190,6 +71255,10 @@ function extractManifestFromTarball(tarballBuffer, expected) {
|
|
|
71190
71255
|
offset = nextOffset;
|
|
71191
71256
|
}
|
|
71192
71257
|
if (!manifest) throw new Error("tarball does not contain package/package.json");
|
|
71258
|
+
if (readme) {
|
|
71259
|
+
manifest.readme = readme.content;
|
|
71260
|
+
manifest.readmeFilename = readme.filename;
|
|
71261
|
+
}
|
|
71193
71262
|
return manifest;
|
|
71194
71263
|
}
|
|
71195
71264
|
async function verifyFrozenNpmTarballIdentity(action, root) {
|
|
@@ -74248,15 +74317,16 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
74248
74317
|
try {
|
|
74249
74318
|
attestation = JSON.parse(await readFile18(resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE), "utf8"));
|
|
74250
74319
|
} catch {
|
|
74320
|
+
const marketplaceSource = resolveCodeBuddyMarketplaceSource(action);
|
|
74251
74321
|
return createResult({
|
|
74252
74322
|
actionType,
|
|
74253
74323
|
status: ActionStatus.OBSERVED,
|
|
74254
74324
|
observation: {
|
|
74255
74325
|
installed: false,
|
|
74256
74326
|
manualInstallRequired: true,
|
|
74257
|
-
marketplaceSource:
|
|
74327
|
+
...marketplaceSource ? { marketplaceSource } : {},
|
|
74258
74328
|
attestationDir,
|
|
74259
|
-
error: `codebuddy attestation is missing; write ${resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE)} after the manual install (marketplace ${
|
|
74329
|
+
error: `codebuddy attestation is missing; write ${resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE)} after the manual install${marketplaceSource ? ` (marketplace ${marketplaceSource})` : ""}`
|
|
74260
74330
|
}
|
|
74261
74331
|
});
|
|
74262
74332
|
}
|
|
@@ -74309,7 +74379,17 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
74309
74379
|
});
|
|
74310
74380
|
}
|
|
74311
74381
|
const normalizedPath = normalizedAttestation.installPath.replaceAll("\\", "/");
|
|
74312
|
-
|
|
74382
|
+
let resolvedMarketplace;
|
|
74383
|
+
try {
|
|
74384
|
+
resolvedMarketplace = resolveCodeBuddyMarketplace(action);
|
|
74385
|
+
} catch (resolveErr) {
|
|
74386
|
+
return createResult({
|
|
74387
|
+
actionType,
|
|
74388
|
+
status: ActionStatus.OBSERVED,
|
|
74389
|
+
observation: { installed: false, error: resolveErr.message }
|
|
74390
|
+
});
|
|
74391
|
+
}
|
|
74392
|
+
const expectedSuffix = `.workbuddy/plugins/marketplaces/${resolvedMarketplace}/plugins/${action.plugin}`;
|
|
74313
74393
|
if (!normalizedPath.endsWith(expectedSuffix)) {
|
|
74314
74394
|
return createResult({
|
|
74315
74395
|
actionType,
|
|
@@ -80868,7 +80948,6 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
80868
80948
|
for (const platform of PLATFORMS) {
|
|
80869
80949
|
const dist = frozenUnitDists ? frozenUnitDists.find((d) => d.type === platform.distributionType) : (unit.distributions ?? []).find((d) => d.type === platform.distributionType);
|
|
80870
80950
|
if (!dist) continue;
|
|
80871
|
-
const requiresMarketplace = platform.schemaRequiredFields.includes("marketplace");
|
|
80872
80951
|
const timeoutMs = Number.isInteger(dist.timeoutMs) ? dist.timeoutMs : 3e5;
|
|
80873
80952
|
const externalMarketplace = dist.marketplaceRepo !== void 0 && dist.marketplaceRepo !== null;
|
|
80874
80953
|
const marketplaceSourceType = dist.marketplaceSourceType ?? (externalMarketplace ? "standalone-index" : "bundled-family");
|
|
@@ -80902,7 +80981,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
80902
80981
|
parameters: {
|
|
80903
80982
|
consumer: platform.id,
|
|
80904
80983
|
plugin: dist.plugin,
|
|
80905
|
-
...
|
|
80984
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
80985
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
80906
80986
|
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
80907
80987
|
version,
|
|
80908
80988
|
entrySkill: dist.entrySkill,
|
|
@@ -80929,7 +81009,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
80929
81009
|
expected: {
|
|
80930
81010
|
installed: true,
|
|
80931
81011
|
plugin: dist.plugin,
|
|
80932
|
-
...
|
|
81012
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
81013
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
80933
81014
|
version,
|
|
80934
81015
|
entrySkill: dist.entrySkill,
|
|
80935
81016
|
...externalMarketplace ? { marketplaceLocation: "external", repo: dist.marketplaceRepo } : {}
|
|
@@ -81066,7 +81147,6 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
81066
81147
|
for (const platform of PLATFORMS) {
|
|
81067
81148
|
const dist = frozenUnitDists ? frozenUnitDists.find((d) => d.type === platform.distributionType) : (unit.distributions ?? []).find((d) => d.type === platform.distributionType);
|
|
81068
81149
|
if (!dist) continue;
|
|
81069
|
-
const requiresMarketplace = platform.schemaRequiredFields.includes("marketplace");
|
|
81070
81150
|
const timeoutMs = Number.isInteger(dist.timeoutMs) ? dist.timeoutMs : 3e5;
|
|
81071
81151
|
const externalMarketplace = dist.marketplaceRepo !== void 0 && dist.marketplaceRepo !== null;
|
|
81072
81152
|
const freeze = externalMarketplace ? externalFreezes.get(`${unit.id} ${dist.type}`) : null;
|
|
@@ -81100,7 +81180,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
81100
81180
|
parameters: {
|
|
81101
81181
|
consumer: platform.id,
|
|
81102
81182
|
plugin: dist.plugin,
|
|
81103
|
-
...
|
|
81183
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
81184
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
81104
81185
|
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
81105
81186
|
ref: externalMarketplace ? freeze.ref : resolvedTag,
|
|
81106
81187
|
version: unitVersion,
|
|
@@ -81139,7 +81220,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
81139
81220
|
installed: true,
|
|
81140
81221
|
consumer: platform.id,
|
|
81141
81222
|
plugin: dist.plugin,
|
|
81142
|
-
...
|
|
81223
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
81224
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
81143
81225
|
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
81144
81226
|
version: unitVersion,
|
|
81145
81227
|
ref: externalMarketplace ? freeze.ref : resolvedTag,
|
|
@@ -398,6 +398,11 @@
|
|
|
398
398
|
"minLength": 1,
|
|
399
399
|
"pattern": "^[a-z0-9][a-z0-9._-]*$"
|
|
400
400
|
},
|
|
401
|
+
"marketplaceSource": {
|
|
402
|
+
"type": "string",
|
|
403
|
+
"minLength": 1,
|
|
404
|
+
"description": "消费者添加统一市场所用的来源 URL(如 codebuddy plugin marketplace add);可选,仅在可知时声明"
|
|
405
|
+
},
|
|
401
406
|
"marketplaceRepo": {
|
|
402
407
|
"type": "string",
|
|
403
408
|
"pattern": "^[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*$",
|
|
@@ -191,6 +191,11 @@
|
|
|
191
191
|
"minLength": 1,
|
|
192
192
|
"pattern": "^[a-z0-9][a-z0-9._-]*$"
|
|
193
193
|
},
|
|
194
|
+
"marketplaceSource": {
|
|
195
|
+
"type": "string",
|
|
196
|
+
"minLength": 1,
|
|
197
|
+
"description": "消费者添加统一市场所用的来源 URL(如 codebuddy plugin marketplace add);可选,仅在可知时声明"
|
|
198
|
+
},
|
|
194
199
|
"marketplaceRepo": {
|
|
195
200
|
"type": "string",
|
|
196
201
|
"pattern": "^[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*$",
|
|
@@ -91,6 +91,12 @@ node -e 'const fs=require("node:fs");const [c,p,a]=process.argv.slice(1).map(x=>
|
|
|
91
91
|
node -e 'require("node:fs").rmSync(process.argv[1],{recursive:true,force:false})' "$SETUP_SESSION"
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
+
## publisher 字段与个人片段泄漏策略
|
|
95
|
+
|
|
96
|
+
setup 生成的 `.release-skill/project.yaml` 中 `publisher` 是**已批准的公开发布身份**:它是人工确认的对外发布署名,属于公开面的一部分,而非需要隐藏的私有信息。
|
|
97
|
+
|
|
98
|
+
若目标仓库用“个人片段”类泄漏策略扫描仓树,而该策略按片段匹配恰好覆盖到 `publisher` 字段,正确做法不是删除或改写策略,而是由贡献者在**本地、gitignore 的个人片段 overlay** 中为该规则声明位置豁免(如 `approvedPlacements`:限定 `publisher` 所在的确切文件路径与行键前缀)。豁免只放行已批准的放置位置,其余出现照常命中;overlay 不入库,个人片段本身不进 committed 策略。
|
|
99
|
+
|
|
94
100
|
## 故障路由
|
|
95
101
|
|
|
96
102
|
- `NEEDS_INPUT`:审阅紧凑摘要;有冲突先修正权威事实并重跑。
|
|
@@ -9,7 +9,7 @@ const __bundlePkgRoot = __bundleResolve(__bundleDirname(__bundleFileURLToPath(im
|
|
|
9
9
|
// Provide a real require() for CJS packages bundled into ESM (e.g. yaml, ajv).
|
|
10
10
|
const __bundleRealRequire = __bundleCreateRequire(import.meta.url);
|
|
11
11
|
// Package identity injected at build time — closure-independent --version probe.
|
|
12
|
-
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.4.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.4.2"});
|
|
13
13
|
|
|
14
14
|
var __create = Object.create;
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -17400,6 +17400,19 @@ function normalizePlanForDigest2(plan) {
|
|
|
17400
17400
|
}
|
|
17401
17401
|
return normalized;
|
|
17402
17402
|
}
|
|
17403
|
+
function resolveCodeBuddyMarketplace(action) {
|
|
17404
|
+
const marketplace = action?.marketplace ?? CODEBUDDY_MARKETPLACE_NAME;
|
|
17405
|
+
if (typeof marketplace !== "string" || marketplace.length === 0) {
|
|
17406
|
+
throw new Error(`codebuddy marketplace must be a non-empty string when declared, got ${JSON.stringify(action?.marketplace)}`);
|
|
17407
|
+
}
|
|
17408
|
+
return marketplace;
|
|
17409
|
+
}
|
|
17410
|
+
function resolveCodeBuddyMarketplaceSource(action) {
|
|
17411
|
+
if (action?.marketplace === void 0 || action?.marketplace === null) {
|
|
17412
|
+
return CODEBUDDY_MARKETPLACE_SOURCE;
|
|
17413
|
+
}
|
|
17414
|
+
return typeof action.marketplaceSource === "string" && action.marketplaceSource.length > 0 ? action.marketplaceSource : null;
|
|
17415
|
+
}
|
|
17403
17416
|
async function resolveCodeBuddyBoundPlanDigest(context) {
|
|
17404
17417
|
const plan = context?.plan;
|
|
17405
17418
|
if (!plan || typeof plan !== "object" || Array.isArray(plan)) {
|
|
@@ -17440,12 +17453,14 @@ function buildCodeBuddyManualInstructions({
|
|
|
17440
17453
|
version,
|
|
17441
17454
|
ref,
|
|
17442
17455
|
attestationDir,
|
|
17443
|
-
requiresInstalledClosure
|
|
17456
|
+
requiresInstalledClosure,
|
|
17457
|
+
marketplace,
|
|
17458
|
+
marketplaceSource
|
|
17444
17459
|
}) {
|
|
17445
17460
|
return [
|
|
17446
17461
|
`CodeBuddy/WorkBuddy \u63D2\u4EF6\u5B89\u88C5\u65E0\u6CD5\u9501\u5B9A\u51BB\u7ED3 ref\uFF08codebuddy CLI marketplace add/install \u6CA1\u6709 ref \u9009\u9879\uFF0C\u8DDF\u8E2A\u9ED8\u8BA4\u5206\u652F\uFF09\uFF0C\u56E0\u6B64\u5B89\u88C5\u662F\u9700\u8981\u4EBA\u5DE5\u7ED3\u679C\u8BC1\u660E\u7684\u624B\u52A8\u6B65\u9AA4\u3002`,
|
|
17447
17462
|
`1) publish \u5B8C\u6210\u6240\u6709\u8FDC\u7AEF\u5199\u5165\u540E\u8FDB\u5165 PUBLISHED \u72B6\u6001\uFF08\u81EA\u52A8\u5316 Git \u5206\u652F/\u6807\u7B7E\u3001npm \u548C GitHub Release \u5199\u5165\u5DF2\u5B8C\u6210\uFF09\u3002\u6B64 codebuddy \u68C0\u67E5\u70B9\u6807\u8BB0\u4E3A\u9700\u8981\u4EBA\u5DE5\u5B89\u88C5\u3002`,
|
|
17448
|
-
`2) \u4ECE\u7EDF\u4E00\u5E02\u573A "${
|
|
17463
|
+
`2) \u4ECE\u7EDF\u4E00\u5E02\u573A "${marketplace}"${marketplaceSource ? ` (${marketplaceSource})` : ""} \u5B89\u88C5 ${plugin}\u3002\u786E\u8BA4\u5B89\u88C5\u7684\u63D2\u4EF6\u7248\u672C\u7B49\u4E8E\u51BB\u7ED3\u7248\u672C ${version}\u3002`,
|
|
17449
17464
|
`3) \u5C06\u4EBA\u5DE5\u7ED3\u679C JSON \u5199\u5165: ${attestationDir}/${CODEBUDDY_ATTESTATION_FILE}`,
|
|
17450
17465
|
` \u5FC5\u586B\u5B57\u6BB5: platform="codebuddy", version, planDigest\uFF08\u51BB\u7ED3\u8BA1\u5212\u6458\u8981\uFF09, result("passed" \u6216 "failed"), actor\uFF08\u786E\u8BA4\u4EBA\uFF09, confirmedAt\uFF08ISO 8601 \u65F6\u95F4\u6233\uFF09${requiresInstalledClosure ? '\uFF0CinstallChannel("desktop" \u6216 "cli")\uFF0CinstallPath\uFF08\u5B9E\u9645\u5B89\u88C5\u540E\u7684\u63D2\u4EF6\u76EE\u5F55\uFF09' : ""}`,
|
|
17451
17466
|
` \u53EF\u9009\u5B57\u6BB5: note\uFF08\u5907\u6CE8\uFF09`,
|
|
@@ -17509,12 +17524,29 @@ function validateCodeBuddyAttestation(attestation, action, isoNow, boundPlanDige
|
|
|
17509
17524
|
return { valid: false, error: 'codebuddy attestation installPath must not contain path traversal ("..")', normalized: null };
|
|
17510
17525
|
}
|
|
17511
17526
|
if (normalized.installChannel === "cli") {
|
|
17512
|
-
|
|
17527
|
+
let resolvedMarketplace;
|
|
17528
|
+
try {
|
|
17529
|
+
resolvedMarketplace = resolveCodeBuddyMarketplace(action);
|
|
17530
|
+
} catch (resolveErr) {
|
|
17531
|
+
return { valid: false, error: resolveErr.message, normalized: null };
|
|
17532
|
+
}
|
|
17533
|
+
const expectedSuffix = `.workbuddy/plugins/marketplaces/${resolvedMarketplace}/plugins/${action.plugin}`;
|
|
17513
17534
|
if (!normalized.installPath.endsWith(expectedSuffix)) {
|
|
17514
17535
|
return { valid: false, error: `codebuddy CLI attestation installPath must end with "${expectedSuffix}", got "${normalized.installPath}"`, normalized: null };
|
|
17515
17536
|
}
|
|
17516
17537
|
}
|
|
17517
17538
|
}
|
|
17539
|
+
if (normalized.marketplace !== void 0) {
|
|
17540
|
+
let resolvedMarketplace;
|
|
17541
|
+
try {
|
|
17542
|
+
resolvedMarketplace = resolveCodeBuddyMarketplace(action);
|
|
17543
|
+
} catch (resolveErr) {
|
|
17544
|
+
return { valid: false, error: resolveErr.message, normalized: null };
|
|
17545
|
+
}
|
|
17546
|
+
if (normalized.marketplace !== resolvedMarketplace) {
|
|
17547
|
+
return { valid: false, error: `codebuddy attestation marketplace "${normalized.marketplace}" does not match the resolved marketplace "${resolvedMarketplace}"`, normalized: null };
|
|
17548
|
+
}
|
|
17549
|
+
}
|
|
17518
17550
|
if (normalized.result !== "passed" && normalized.result !== "failed") {
|
|
17519
17551
|
return { valid: false, error: `codebuddy attestation result "${normalized.result}" must be "passed" or "failed"`, normalized: null };
|
|
17520
17552
|
}
|
|
@@ -17607,6 +17639,17 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17607
17639
|
});
|
|
17608
17640
|
}
|
|
17609
17641
|
const ref = action.ref ?? `v${action.version}`;
|
|
17642
|
+
let marketplace;
|
|
17643
|
+
try {
|
|
17644
|
+
marketplace = resolveCodeBuddyMarketplace(action);
|
|
17645
|
+
} catch (marketplaceErr) {
|
|
17646
|
+
return createResult({
|
|
17647
|
+
actionType,
|
|
17648
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
17649
|
+
error: marketplaceErr.message
|
|
17650
|
+
});
|
|
17651
|
+
}
|
|
17652
|
+
const marketplaceSource = resolveCodeBuddyMarketplaceSource(action);
|
|
17610
17653
|
let attestationDir;
|
|
17611
17654
|
try {
|
|
17612
17655
|
attestationDir = codebuddyAuthorityDir(context, planDigest, action.plugin);
|
|
@@ -17622,7 +17665,9 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17622
17665
|
version: action.version,
|
|
17623
17666
|
ref,
|
|
17624
17667
|
attestationDir,
|
|
17625
|
-
requiresInstalledClosure: Boolean(context.plan?.skillResourceClosure)
|
|
17668
|
+
requiresInstalledClosure: Boolean(context.plan?.skillResourceClosure),
|
|
17669
|
+
marketplace,
|
|
17670
|
+
marketplaceSource
|
|
17626
17671
|
});
|
|
17627
17672
|
const requirement = {
|
|
17628
17673
|
kind: "codebuddy-manual-install-requirement",
|
|
@@ -17632,6 +17677,8 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17632
17677
|
repo: action.repo,
|
|
17633
17678
|
ref,
|
|
17634
17679
|
entrySkill: action.entrySkill,
|
|
17680
|
+
marketplace,
|
|
17681
|
+
...marketplaceSource ? { marketplaceSource } : {},
|
|
17635
17682
|
planDigest,
|
|
17636
17683
|
attestationDir,
|
|
17637
17684
|
attestationFile: CODEBUDDY_ATTESTATION_FILE,
|
|
@@ -17644,7 +17691,7 @@ async function executeCodeBuddyManualRequirement(action, context) {
|
|
|
17644
17691
|
confirmedAt: "<ISO 8601 timestamp>",
|
|
17645
17692
|
...context.plan?.skillResourceClosure ? {
|
|
17646
17693
|
installChannel: '<"desktop" or "cli">',
|
|
17647
|
-
installPath: `<actual .workbuddy/plugins/marketplaces/${
|
|
17694
|
+
installPath: `<actual .workbuddy/plugins/marketplaces/${marketplace}/plugins/${action.plugin} directory>`
|
|
17648
17695
|
} : {},
|
|
17649
17696
|
note: "<optional note>"
|
|
17650
17697
|
},
|
|
@@ -17736,6 +17783,8 @@ var init_codebuddy = __esm({
|
|
|
17736
17783
|
CODEBUDDY_ATTESTATION_FILE = "release-skill-codebuddy-attestation.json";
|
|
17737
17784
|
CODEBUDDY_MARKETPLACE_NAME = "artifact-skill-set";
|
|
17738
17785
|
CODEBUDDY_MARKETPLACE_SOURCE = "https://github.com/ifoohoo/artifact-skill-set";
|
|
17786
|
+
__name(resolveCodeBuddyMarketplace, "resolveCodeBuddyMarketplace");
|
|
17787
|
+
__name(resolveCodeBuddyMarketplaceSource, "resolveCodeBuddyMarketplaceSource");
|
|
17739
17788
|
CODEBUDDY_PLUGIN_MANIFEST_RELATIVE = join4(".codebuddy-plugin", "plugin.json");
|
|
17740
17789
|
CODEBUDDY_MAX_ATTESTATION_VALIDITY_MS = 24 * 60 * 60 * 1e3;
|
|
17741
17790
|
__name(resolveCodeBuddyBoundPlanDigest, "resolveCodeBuddyBoundPlanDigest");
|
|
@@ -18465,9 +18514,10 @@ var init_registry = __esm({
|
|
|
18465
18514
|
marketplace: ".claude-plugin/marketplace.json"
|
|
18466
18515
|
}),
|
|
18467
18516
|
marketplaceSourceForm: null,
|
|
18468
|
-
// codebuddy installs from a unified marketplace
|
|
18469
|
-
//
|
|
18470
|
-
// ./codebuddy.mjs); the
|
|
18517
|
+
// codebuddy installs from a unified marketplace whose identity is optional
|
|
18518
|
+
// on the action: a distribution may declare `marketplace` to override the
|
|
18519
|
+
// default constant in ./codebuddy.mjs (resolveCodeBuddyMarketplace); the
|
|
18520
|
+
// entry-version binding does not apply either way (null = N/A).
|
|
18471
18521
|
marketplaceEntryCarriesVersion: null,
|
|
18472
18522
|
// codebuddy has no marketplace add that can pin a frozen ref (attestation
|
|
18473
18523
|
// loop instead), so the marketplace ref form does not apply (null = N/A).
|
|
@@ -71134,6 +71184,7 @@ function extractManifestFromTarball(tarballBuffer, expected) {
|
|
|
71134
71184
|
}
|
|
71135
71185
|
let offset = 0;
|
|
71136
71186
|
let manifest = null;
|
|
71187
|
+
let readme = null;
|
|
71137
71188
|
while (offset + 512 <= data.length) {
|
|
71138
71189
|
let allZero = true;
|
|
71139
71190
|
for (let i = 0; i < 512; i++) {
|
|
@@ -71183,6 +71234,20 @@ function extractManifestFromTarball(tarballBuffer, expected) {
|
|
|
71183
71234
|
throw new Error(`tarball manifest version "${manifest.version}" does not match expected "${expected.version}"`);
|
|
71184
71235
|
}
|
|
71185
71236
|
}
|
|
71237
|
+
if (entryName.toLowerCase() === "package/readme.md") {
|
|
71238
|
+
if (readme) throw new Error("tarball contains conflicting package README entries");
|
|
71239
|
+
if (!(typeFlag === 0 || typeFlag === 48)) {
|
|
71240
|
+
throw new Error("tarball package README must be a regular file");
|
|
71241
|
+
}
|
|
71242
|
+
const bodyStart = offset + 512;
|
|
71243
|
+
const bodyEnd = bodyStart + size;
|
|
71244
|
+
if (bodyEnd > data.length) throw new Error("frozen npm tarball entry exceeds archive bounds");
|
|
71245
|
+
if (size > 10 * 1024 * 1024) throw new Error("tarball package README is unreasonably large");
|
|
71246
|
+
readme = {
|
|
71247
|
+
content: data.subarray(bodyStart, bodyEnd).toString("utf8"),
|
|
71248
|
+
filename: entryName.slice("package/".length)
|
|
71249
|
+
};
|
|
71250
|
+
}
|
|
71186
71251
|
const nextOffset = offset + 512 + Math.ceil(size / 512) * 512;
|
|
71187
71252
|
if (!Number.isSafeInteger(nextOffset) || nextOffset > data.length) {
|
|
71188
71253
|
throw new Error("frozen npm tarball entry exceeds archive bounds");
|
|
@@ -71190,6 +71255,10 @@ function extractManifestFromTarball(tarballBuffer, expected) {
|
|
|
71190
71255
|
offset = nextOffset;
|
|
71191
71256
|
}
|
|
71192
71257
|
if (!manifest) throw new Error("tarball does not contain package/package.json");
|
|
71258
|
+
if (readme) {
|
|
71259
|
+
manifest.readme = readme.content;
|
|
71260
|
+
manifest.readmeFilename = readme.filename;
|
|
71261
|
+
}
|
|
71193
71262
|
return manifest;
|
|
71194
71263
|
}
|
|
71195
71264
|
async function verifyFrozenNpmTarballIdentity(action, root) {
|
|
@@ -74248,15 +74317,16 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
74248
74317
|
try {
|
|
74249
74318
|
attestation = JSON.parse(await readFile18(resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE), "utf8"));
|
|
74250
74319
|
} catch {
|
|
74320
|
+
const marketplaceSource = resolveCodeBuddyMarketplaceSource(action);
|
|
74251
74321
|
return createResult({
|
|
74252
74322
|
actionType,
|
|
74253
74323
|
status: ActionStatus.OBSERVED,
|
|
74254
74324
|
observation: {
|
|
74255
74325
|
installed: false,
|
|
74256
74326
|
manualInstallRequired: true,
|
|
74257
|
-
marketplaceSource:
|
|
74327
|
+
...marketplaceSource ? { marketplaceSource } : {},
|
|
74258
74328
|
attestationDir,
|
|
74259
|
-
error: `codebuddy attestation is missing; write ${resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE)} after the manual install (marketplace ${
|
|
74329
|
+
error: `codebuddy attestation is missing; write ${resolve21(attestationDir, CODEBUDDY_ATTESTATION_FILE)} after the manual install${marketplaceSource ? ` (marketplace ${marketplaceSource})` : ""}`
|
|
74260
74330
|
}
|
|
74261
74331
|
});
|
|
74262
74332
|
}
|
|
@@ -74309,7 +74379,17 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
74309
74379
|
});
|
|
74310
74380
|
}
|
|
74311
74381
|
const normalizedPath = normalizedAttestation.installPath.replaceAll("\\", "/");
|
|
74312
|
-
|
|
74382
|
+
let resolvedMarketplace;
|
|
74383
|
+
try {
|
|
74384
|
+
resolvedMarketplace = resolveCodeBuddyMarketplace(action);
|
|
74385
|
+
} catch (resolveErr) {
|
|
74386
|
+
return createResult({
|
|
74387
|
+
actionType,
|
|
74388
|
+
status: ActionStatus.OBSERVED,
|
|
74389
|
+
observation: { installed: false, error: resolveErr.message }
|
|
74390
|
+
});
|
|
74391
|
+
}
|
|
74392
|
+
const expectedSuffix = `.workbuddy/plugins/marketplaces/${resolvedMarketplace}/plugins/${action.plugin}`;
|
|
74313
74393
|
if (!normalizedPath.endsWith(expectedSuffix)) {
|
|
74314
74394
|
return createResult({
|
|
74315
74395
|
actionType,
|
|
@@ -80868,7 +80948,6 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
80868
80948
|
for (const platform of PLATFORMS) {
|
|
80869
80949
|
const dist = frozenUnitDists ? frozenUnitDists.find((d) => d.type === platform.distributionType) : (unit.distributions ?? []).find((d) => d.type === platform.distributionType);
|
|
80870
80950
|
if (!dist) continue;
|
|
80871
|
-
const requiresMarketplace = platform.schemaRequiredFields.includes("marketplace");
|
|
80872
80951
|
const timeoutMs = Number.isInteger(dist.timeoutMs) ? dist.timeoutMs : 3e5;
|
|
80873
80952
|
const externalMarketplace = dist.marketplaceRepo !== void 0 && dist.marketplaceRepo !== null;
|
|
80874
80953
|
const marketplaceSourceType = dist.marketplaceSourceType ?? (externalMarketplace ? "standalone-index" : "bundled-family");
|
|
@@ -80902,7 +80981,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
80902
80981
|
parameters: {
|
|
80903
80982
|
consumer: platform.id,
|
|
80904
80983
|
plugin: dist.plugin,
|
|
80905
|
-
...
|
|
80984
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
80985
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
80906
80986
|
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
80907
80987
|
version,
|
|
80908
80988
|
entrySkill: dist.entrySkill,
|
|
@@ -80929,7 +81009,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
80929
81009
|
expected: {
|
|
80930
81010
|
installed: true,
|
|
80931
81011
|
plugin: dist.plugin,
|
|
80932
|
-
...
|
|
81012
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
81013
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
80933
81014
|
version,
|
|
80934
81015
|
entrySkill: dist.entrySkill,
|
|
80935
81016
|
...externalMarketplace ? { marketplaceLocation: "external", repo: dist.marketplaceRepo } : {}
|
|
@@ -81066,7 +81147,6 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
81066
81147
|
for (const platform of PLATFORMS) {
|
|
81067
81148
|
const dist = frozenUnitDists ? frozenUnitDists.find((d) => d.type === platform.distributionType) : (unit.distributions ?? []).find((d) => d.type === platform.distributionType);
|
|
81068
81149
|
if (!dist) continue;
|
|
81069
|
-
const requiresMarketplace = platform.schemaRequiredFields.includes("marketplace");
|
|
81070
81150
|
const timeoutMs = Number.isInteger(dist.timeoutMs) ? dist.timeoutMs : 3e5;
|
|
81071
81151
|
const externalMarketplace = dist.marketplaceRepo !== void 0 && dist.marketplaceRepo !== null;
|
|
81072
81152
|
const freeze = externalMarketplace ? externalFreezes.get(`${unit.id} ${dist.type}`) : null;
|
|
@@ -81100,7 +81180,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
81100
81180
|
parameters: {
|
|
81101
81181
|
consumer: platform.id,
|
|
81102
81182
|
plugin: dist.plugin,
|
|
81103
|
-
...
|
|
81183
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
81184
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
81104
81185
|
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
81105
81186
|
ref: externalMarketplace ? freeze.ref : resolvedTag,
|
|
81106
81187
|
version: unitVersion,
|
|
@@ -81139,7 +81220,8 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets, e
|
|
|
81139
81220
|
installed: true,
|
|
81140
81221
|
consumer: platform.id,
|
|
81141
81222
|
plugin: dist.plugin,
|
|
81142
|
-
...
|
|
81223
|
+
...dist.marketplace !== void 0 ? { marketplace: dist.marketplace } : {},
|
|
81224
|
+
...dist.marketplaceSource !== void 0 ? { marketplaceSource: dist.marketplaceSource } : {},
|
|
81143
81225
|
repo: externalMarketplace ? dist.marketplaceRepo : unit.publicRepo,
|
|
81144
81226
|
version: unitVersion,
|
|
81145
81227
|
ref: externalMarketplace ? freeze.ref : resolvedTag,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "release-skill",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "广州市风荷科技有限公司"
|
|
@@ -94,5 +94,5 @@
|
|
|
94
94
|
"codex",
|
|
95
95
|
"kimi-code"
|
|
96
96
|
],
|
|
97
|
-
"license": "
|
|
97
|
+
"license": "Apache-2.0"
|
|
98
98
|
}
|
|
@@ -398,6 +398,11 @@
|
|
|
398
398
|
"minLength": 1,
|
|
399
399
|
"pattern": "^[a-z0-9][a-z0-9._-]*$"
|
|
400
400
|
},
|
|
401
|
+
"marketplaceSource": {
|
|
402
|
+
"type": "string",
|
|
403
|
+
"minLength": 1,
|
|
404
|
+
"description": "消费者添加统一市场所用的来源 URL(如 codebuddy plugin marketplace add);可选,仅在可知时声明"
|
|
405
|
+
},
|
|
401
406
|
"marketplaceRepo": {
|
|
402
407
|
"type": "string",
|
|
403
408
|
"pattern": "^[a-z0-9][a-z0-9._-]*/[a-z0-9][a-z0-9._-]*$",
|