release-skill 0.1.7 → 0.1.9
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 +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +27 -0
- package/CHANGELOG.md +56 -0
- package/INSTALL.md +73 -2
- package/INSTALL.zh-CN.md +94 -99
- package/README.md +65 -39
- package/README.zh-CN.md +92 -325
- package/adapters/claude/.claude-plugin/marketplace.json +1 -1
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +1114 -183
- package/adapters/claude/schemas/.render-manifest.json +4 -4
- package/adapters/claude/schemas/release-plan.schema.json +20 -2
- package/adapters/claude/schemas/release-project.schema.json +22 -4
- package/adapters/claude/schemas/release-run.schema.json +1 -0
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +1114 -183
- package/adapters/codex/schemas/.render-manifest.json +4 -4
- package/adapters/codex/schemas/release-plan.schema.json +20 -2
- package/adapters/codex/schemas/release-project.schema.json +22 -4
- package/adapters/codex/schemas/release-run.schema.json +1 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +27 -0
- package/adapters/kimi/bin/release-skill.bundle.mjs +84467 -0
- package/adapters/kimi/bin/release-skill.mjs +54 -0
- package/adapters/kimi/native/safe-write/binding.gyp +41 -0
- package/adapters/kimi/native/safe-write/prebuilds/darwin-arm64/safe_write.node +0 -0
- package/adapters/kimi/native/safe-write/prebuilds.json +24 -0
- package/adapters/kimi/native/safe-write/src/safe_write.cc +2032 -0
- package/adapters/kimi/schemas/.render-manifest.json +37 -0
- package/adapters/kimi/schemas/approval-record.schema.json +115 -0
- package/adapters/kimi/schemas/artifact-lock.schema.json +111 -0
- package/adapters/kimi/schemas/artifact-plan.schema.json +52 -0
- package/adapters/kimi/schemas/artifact-policy.schema.json +76 -0
- package/adapters/kimi/schemas/evidence-event.schema.json +89 -0
- package/adapters/kimi/schemas/release-plan.schema.json +878 -0
- package/adapters/kimi/schemas/release-project.schema.json +895 -0
- package/adapters/kimi/schemas/release-run.schema.json +343 -0
- package/adapters/kimi/skills/release-assess/SKILL.md +58 -0
- package/adapters/kimi/skills/release-help/SKILL.md +84 -0
- package/adapters/kimi/skills/release-prepare/SKILL.md +99 -0
- package/adapters/kimi/skills/release-publish/SKILL.md +64 -0
- package/adapters/kimi/skills/release-reconcile/SKILL.md +80 -0
- package/adapters/kimi/skills/release-setup/SKILL.md +102 -0
- package/adapters/kimi/skills/release-verify/SKILL.md +77 -0
- package/bin/release-skill-cli.mjs +16 -4
- package/bin/release-skill.bundle.mjs +1114 -183
- package/package.json +4 -2
- package/schemas/.render-manifest.json +4 -4
- package/schemas/release-plan.schema.json +20 -2
- package/schemas/release-project.schema.json +22 -4
- package/schemas/release-run.schema.json +1 -0
- package/src/adapters/contract.mjs +1 -0
- package/src/adapters/plugin-marketplace.mjs +1109 -49
- package/src/commands/assess.mjs +50 -1
- package/src/commands/prepare.mjs +65 -0
- package/src/commands/publish.mjs +3 -0
- package/src/commands/reconcile.mjs +3 -0
- package/src/commands/setup.mjs +10 -5
- package/src/commands/verify.mjs +16 -6
- package/src/core/plan.mjs +118 -0
- package/src/core/verification-gates.mjs +1 -1
- package/src/producers/build-adapters.mjs +38 -8
- package/src/snapshot/frozen.mjs +4 -3
|
@@ -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.1.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.1.9"});
|
|
13
13
|
|
|
14
14
|
var __create = Object.create;
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -16344,7 +16344,7 @@ async function walkDiscoveryFiles(root, maxDepth = 8) {
|
|
|
16344
16344
|
const absolute = join2(directory, child.name);
|
|
16345
16345
|
if (child.isDirectory()) {
|
|
16346
16346
|
if (!SKIP_DIRS.has(child.name)) await walk(absolute, depth + 1);
|
|
16347
|
-
} else if (child.isFile() && (child.name === "package.json" || child.name === "public-release.json" || child.name === "SKILL.md" || /^README(?:\.|$)/i.test(child.name) || /^LICENSE(?:\.|$)/i.test(child.name) || /^CHANGELOG(?:\.|$)/i.test(child.name) || absolute.endsWith("/.claude-plugin/plugin.json") || absolute.endsWith("/.codex-plugin/plugin.json") || absolute.endsWith("/.claude-plugin/marketplace.json") || absolute.endsWith("/.codex-plugin/marketplace.json"))) {
|
|
16347
|
+
} else if (child.isFile() && (child.name === "package.json" || child.name === "public-release.json" || child.name === "SKILL.md" || /^README(?:\.|$)/i.test(child.name) || /^LICENSE(?:\.|$)/i.test(child.name) || /^CHANGELOG(?:\.|$)/i.test(child.name) || absolute.endsWith("/.claude-plugin/plugin.json") || absolute.endsWith("/.codex-plugin/plugin.json") || absolute.endsWith("/.kimi-plugin/plugin.json") || absolute.endsWith("/.claude-plugin/marketplace.json") || absolute.endsWith("/.codex-plugin/marketplace.json"))) {
|
|
16348
16348
|
found.push(absolute);
|
|
16349
16349
|
}
|
|
16350
16350
|
}
|
|
@@ -16569,7 +16569,7 @@ async function discoverUnitGit(unitAbsDir, parentRoot) {
|
|
|
16569
16569
|
}
|
|
16570
16570
|
async function discoverFacts(root) {
|
|
16571
16571
|
const files = await walkDiscoveryFiles(root);
|
|
16572
|
-
const packageFiles = files.filter((path3) => basename(path3) === "package.json" && !/[\\/]adapters[\\/](?:claude|codex)[\\/]package\.json$/.test(path3));
|
|
16572
|
+
const packageFiles = files.filter((path3) => basename(path3) === "package.json" && !/[\\/]adapters[\\/](?:claude|codex|kimi)[\\/]package\.json$/.test(path3));
|
|
16573
16573
|
const pluginFiles = files.filter((path3) => path3.endsWith("/plugin.json"));
|
|
16574
16574
|
const marketplaceFiles = files.filter((path3) => path3.endsWith("/marketplace.json"));
|
|
16575
16575
|
const legacyReleaseFiles = files.filter((path3) => basename(path3) === "public-release.json");
|
|
@@ -16601,7 +16601,7 @@ async function discoverFacts(root) {
|
|
|
16601
16601
|
const value = await readJsonBounded(path3, "discovered plugin manifest");
|
|
16602
16602
|
manifests.push({
|
|
16603
16603
|
path: safeRelative(root, path3),
|
|
16604
|
-
host: path3.includes("/.claude-plugin/") ? "claude" : "codex",
|
|
16604
|
+
host: path3.includes("/.claude-plugin/") ? "claude" : path3.includes("/.kimi-plugin/") ? "kimi" : "codex",
|
|
16605
16605
|
kind: path3.endsWith("/marketplace.json") ? "marketplace" : "plugin",
|
|
16606
16606
|
name: typeof value.name === "string" ? value.name : null,
|
|
16607
16607
|
version: typeof value.version === "string" ? value.version : null
|
|
@@ -16620,7 +16620,7 @@ async function discoverFacts(root) {
|
|
|
16620
16620
|
return {
|
|
16621
16621
|
path: relPath,
|
|
16622
16622
|
name: skillIndex >= 0 ? segments[skillIndex + 1] ?? null : null,
|
|
16623
|
-
host: relPath.includes("/adapters/claude/") ? "claude" : relPath.includes("/adapters/codex/") ? "codex" : "shared"
|
|
16623
|
+
host: relPath.includes("/adapters/claude/") ? "claude" : relPath.includes("/adapters/codex/") ? "codex" : relPath.includes("/adapters/kimi/") ? "kimi" : "shared"
|
|
16624
16624
|
};
|
|
16625
16625
|
}).filter((item) => item.name).sort((a, b) => canonicalJson(a).localeCompare(canonicalJson(b)));
|
|
16626
16626
|
const unitGit = {};
|
|
@@ -16764,7 +16764,7 @@ function buildCandidates(facts) {
|
|
|
16764
16764
|
const ids = /* @__PURE__ */ new Set();
|
|
16765
16765
|
const knownFiles = new Set(facts.fileDigests.map((file) => file.path));
|
|
16766
16766
|
const manifestRoots = facts.manifests.map((manifest) => {
|
|
16767
|
-
const match = manifest.path.match(/^(.*?)(?:\/)?(?:\.claude-plugin|\.codex-plugin)\/(?:plugin|marketplace)\.json$/);
|
|
16767
|
+
const match = manifest.path.match(/^(.*?)(?:\/)?(?:\.claude-plugin|\.codex-plugin|\.kimi-plugin)\/(?:plugin|marketplace)\.json$/);
|
|
16768
16768
|
return { ...manifest, root: match?.[1] || "." };
|
|
16769
16769
|
});
|
|
16770
16770
|
const manifestOwners = /* @__PURE__ */ new Map();
|
|
@@ -16790,6 +16790,7 @@ function buildCandidates(facts) {
|
|
|
16790
16790
|
if (!pkg.private && pkg.name && !npmExplicitlyForbidden) distributions.push("npm");
|
|
16791
16791
|
if (pluginHosts.includes("claude")) distributions.push("claude-plugin");
|
|
16792
16792
|
if (pluginHosts.includes("codex")) distributions.push("codex-plugin");
|
|
16793
|
+
if (pluginHosts.includes("kimi")) distributions.push("kimi-plugin");
|
|
16793
16794
|
if (pkg.private && matchingLegacyUnits.length === 0 && facts.legacyReleaseConfigs.length > 0) continue;
|
|
16794
16795
|
if (pkg.private && distributions.length === 0) continue;
|
|
16795
16796
|
const unitGitEntry = unitGit[pkg.directory];
|
|
@@ -17496,6 +17497,7 @@ var init_setup = __esm({
|
|
|
17496
17497
|
".worktrees",
|
|
17497
17498
|
".claude",
|
|
17498
17499
|
".codex",
|
|
17500
|
+
".kimi",
|
|
17499
17501
|
".cache",
|
|
17500
17502
|
".tmp",
|
|
17501
17503
|
".pytest_cache",
|
|
@@ -18188,7 +18190,7 @@ function identifyTopology(config) {
|
|
|
18188
18190
|
const uniqueDistTypes = [...new Set(allDistTypes)];
|
|
18189
18191
|
let type = "unknown";
|
|
18190
18192
|
const hasNpm = uniqueDistTypes.includes("npm");
|
|
18191
|
-
const hasPlugin = uniqueDistTypes.includes("claude-plugin") || uniqueDistTypes.includes("codex-plugin");
|
|
18193
|
+
const hasPlugin = uniqueDistTypes.includes("claude-plugin") || uniqueDistTypes.includes("codex-plugin") || uniqueDistTypes.includes("kimi-plugin");
|
|
18192
18194
|
if (units.length === 0) {
|
|
18193
18195
|
type = "no-release-units";
|
|
18194
18196
|
} else if (units.length === 1) {
|
|
@@ -18398,6 +18400,53 @@ async function checkPluginManifests(root, config) {
|
|
|
18398
18400
|
}
|
|
18399
18401
|
}
|
|
18400
18402
|
}
|
|
18403
|
+
if (distributionTypes.has("kimi-plugin")) {
|
|
18404
|
+
const manifestPath = resolve7(unitRoot, ".kimi-plugin", "plugin.json");
|
|
18405
|
+
const displayPath = unitFile(unit, ".kimi-plugin/plugin.json");
|
|
18406
|
+
const exists = await fileExists(manifestPath);
|
|
18407
|
+
if (!exists) {
|
|
18408
|
+
gaps.push(
|
|
18409
|
+
createGap({
|
|
18410
|
+
scope: GapScope.PROFILE,
|
|
18411
|
+
category: GapCategory.MANIFEST,
|
|
18412
|
+
severity: Severity.ERROR,
|
|
18413
|
+
code: "KIMI_MANIFEST_MISSING",
|
|
18414
|
+
message: `\u53D1\u5E03\u5355\u5143 "${unit.id}" \u7F3A\u5C11 .kimi-plugin/plugin.json \u63D2\u4EF6\u6E05\u5355`,
|
|
18415
|
+
file: displayPath
|
|
18416
|
+
})
|
|
18417
|
+
);
|
|
18418
|
+
} else {
|
|
18419
|
+
try {
|
|
18420
|
+
const content = await readFile5(manifestPath, "utf8");
|
|
18421
|
+
const manifest = JSON.parse(content);
|
|
18422
|
+
const requiredFields = ["name", "version", "description"];
|
|
18423
|
+
const missingFields = requiredFields.filter((f) => !(f in manifest));
|
|
18424
|
+
if (missingFields.length > 0) {
|
|
18425
|
+
gaps.push(
|
|
18426
|
+
createGap({
|
|
18427
|
+
scope: GapScope.PROFILE,
|
|
18428
|
+
category: GapCategory.MANIFEST,
|
|
18429
|
+
severity: Severity.ERROR,
|
|
18430
|
+
code: "KIMI_MANIFEST_INCOMPLETE",
|
|
18431
|
+
message: `Kimi \u63D2\u4EF6\u6E05\u5355\u7F3A\u5C11\u5FC5\u586B\u5B57\u6BB5: ${missingFields.join(", ")}`,
|
|
18432
|
+
file: displayPath
|
|
18433
|
+
})
|
|
18434
|
+
);
|
|
18435
|
+
}
|
|
18436
|
+
} catch {
|
|
18437
|
+
gaps.push(
|
|
18438
|
+
createGap({
|
|
18439
|
+
scope: GapScope.PROFILE,
|
|
18440
|
+
category: GapCategory.MANIFEST,
|
|
18441
|
+
severity: Severity.ERROR,
|
|
18442
|
+
code: "KIMI_MANIFEST_INVALID",
|
|
18443
|
+
message: ".kimi-plugin/plugin.json \u89E3\u6790\u5931\u8D25",
|
|
18444
|
+
file: displayPath
|
|
18445
|
+
})
|
|
18446
|
+
);
|
|
18447
|
+
}
|
|
18448
|
+
}
|
|
18449
|
+
}
|
|
18401
18450
|
}
|
|
18402
18451
|
return gaps;
|
|
18403
18452
|
}
|
|
@@ -19481,7 +19530,7 @@ function validateGate(gate) {
|
|
|
19481
19530
|
if (!gate.scope || typeof gate.scope.unit !== "string") {
|
|
19482
19531
|
throw gateError(gate, "must declare scope.unit");
|
|
19483
19532
|
}
|
|
19484
|
-
if (gate.phase === "consumer-verify" && !["npm", "claude-plugin", "codex-plugin"].includes(gate.scope.distribution)) {
|
|
19533
|
+
if (gate.phase === "consumer-verify" && !["npm", "claude-plugin", "codex-plugin", "kimi-plugin"].includes(gate.scope.distribution)) {
|
|
19485
19534
|
throw gateError(gate, "consumer-verify must declare a supported scope.distribution");
|
|
19486
19535
|
}
|
|
19487
19536
|
if (!Array.isArray(gate.command) || gate.command.length === 0 || gate.command.some((value) => typeof value !== "string")) {
|
|
@@ -20567,6 +20616,97 @@ function validatePlanActionCompleteness(plan, options = {}) {
|
|
|
20567
20616
|
}
|
|
20568
20617
|
}
|
|
20569
20618
|
}
|
|
20619
|
+
const kimiDist = distributions.find((d) => d.type === "kimi-plugin");
|
|
20620
|
+
if (kimiDist) {
|
|
20621
|
+
const plugin = kimiDist.plugin;
|
|
20622
|
+
const marketplace = kimiDist.marketplace;
|
|
20623
|
+
const entrySkill = kimiDist.entrySkill;
|
|
20624
|
+
if (!plugin || !entrySkill) {
|
|
20625
|
+
failures.push(`unit "${unitId}": kimi-plugin distribution requires plugin and entrySkill`);
|
|
20626
|
+
}
|
|
20627
|
+
expectedCount++;
|
|
20628
|
+
const expectedActionId = `kimi-marketplace-install-${unitId}`;
|
|
20629
|
+
const kimiActions = actions.filter(
|
|
20630
|
+
(a) => a.unitId === unitId && a.type === "kimi-marketplace-install"
|
|
20631
|
+
);
|
|
20632
|
+
if (kimiActions.length === 0) {
|
|
20633
|
+
failures.push(
|
|
20634
|
+
`unit "${unitId}": kimi-plugin distribution declared but "kimi-marketplace-install" action is missing`
|
|
20635
|
+
);
|
|
20636
|
+
} else if (kimiActions.length > 1) {
|
|
20637
|
+
failures.push(
|
|
20638
|
+
`unit "${unitId}": duplicate kimi-marketplace-install actions (${kimiActions.length} found, expected 1)`
|
|
20639
|
+
);
|
|
20640
|
+
} else {
|
|
20641
|
+
const action = kimiActions[0];
|
|
20642
|
+
if (action.id !== expectedActionId) {
|
|
20643
|
+
failures.push(
|
|
20644
|
+
`unit "${unitId}", action "${action.id}": id is "${action.id}", expected "${expectedActionId}"`
|
|
20645
|
+
);
|
|
20646
|
+
}
|
|
20647
|
+
if (action.unitId !== unitId) {
|
|
20648
|
+
failures.push(
|
|
20649
|
+
`unit "${unitId}", action "${action.id}": unitId is "${action.unitId}", expected "${unitId}"`
|
|
20650
|
+
);
|
|
20651
|
+
}
|
|
20652
|
+
if (action.adapter !== "plugin-marketplace") {
|
|
20653
|
+
failures.push(
|
|
20654
|
+
`unit "${unitId}", action "${action.id}": adapter is "${action.adapter}", expected "plugin-marketplace"`
|
|
20655
|
+
);
|
|
20656
|
+
}
|
|
20657
|
+
if (action.status !== "PENDING") {
|
|
20658
|
+
failures.push(
|
|
20659
|
+
`unit "${unitId}", action "${action.id}": status is "${action.status ?? "(missing)"}", expected "PENDING"`
|
|
20660
|
+
);
|
|
20661
|
+
}
|
|
20662
|
+
_checkRequired(action, "parameters.consumer", action.parameters?.consumer, "kimi", unitId, failures);
|
|
20663
|
+
_checkRequired(action, "parameters.plugin", action.parameters?.plugin, plugin, unitId, failures);
|
|
20664
|
+
if (action.parameters?.marketplace !== void 0 && marketplace !== void 0 && action.parameters.marketplace !== marketplace) {
|
|
20665
|
+
failures.push(
|
|
20666
|
+
`unit "${unitId}", action "${action.id}": parameters.marketplace is "${action.parameters.marketplace}", expected optional legacy value "${marketplace}"`
|
|
20667
|
+
);
|
|
20668
|
+
}
|
|
20669
|
+
_checkRequired(action, "parameters.repo", action.parameters?.repo, publicRepo, unitId, failures);
|
|
20670
|
+
_checkRequired(action, "parameters.version", action.parameters?.version, targetVersion, unitId, failures);
|
|
20671
|
+
_checkRequired(action, "parameters.entrySkill", action.parameters?.entrySkill, entrySkill, unitId, failures);
|
|
20672
|
+
if (production) {
|
|
20673
|
+
_checkRequired(action, "parameters.snapshotPath", action.parameters?.snapshotPath, frozen?.path, unitId, failures);
|
|
20674
|
+
_checkRequired(action, "parameters.ref", action.parameters?.ref, expectedTag, unitId, failures);
|
|
20675
|
+
_checkRequired(action, "parameters.manifestDigest", action.parameters?.manifestDigest, frozen?.manifestDigest, unitId, failures);
|
|
20676
|
+
}
|
|
20677
|
+
{
|
|
20678
|
+
const raw = action.parameters?.timeoutMs;
|
|
20679
|
+
if (raw === void 0) {
|
|
20680
|
+
if (!options.legacyCompatibility) {
|
|
20681
|
+
failures.push(
|
|
20682
|
+
`unit "${unitId}", action "${action.id}": parameters.timeoutMs is missing, expected a valid timeout (30000-900000)`
|
|
20683
|
+
);
|
|
20684
|
+
}
|
|
20685
|
+
} else {
|
|
20686
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || !Number.isInteger(raw)) {
|
|
20687
|
+
failures.push(
|
|
20688
|
+
`unit "${unitId}", action "${action.id}": parameters.timeoutMs must be a finite integer, got: ${JSON.stringify(raw)}`
|
|
20689
|
+
);
|
|
20690
|
+
} else if (raw < 3e4 || raw > 9e5) {
|
|
20691
|
+
failures.push(
|
|
20692
|
+
`unit "${unitId}", action "${action.id}": parameters.timeoutMs must be between 30000 and 900000, got: ${raw}`
|
|
20693
|
+
);
|
|
20694
|
+
}
|
|
20695
|
+
}
|
|
20696
|
+
}
|
|
20697
|
+
_checkRequired(action, "expected.installed", action.expected?.installed, true, unitId, failures);
|
|
20698
|
+
_checkRequired(action, "expected.plugin", action.expected?.plugin, plugin, unitId, failures);
|
|
20699
|
+
_checkRequired(action, "expected.version", action.expected?.version, targetVersion, unitId, failures);
|
|
20700
|
+
_checkRequired(action, "expected.entrySkill", action.expected?.entrySkill, entrySkill, unitId, failures);
|
|
20701
|
+
if (production) {
|
|
20702
|
+
_checkRequired(action, "expected.consumer", action.expected?.consumer, "kimi", unitId, failures);
|
|
20703
|
+
_checkRequired(action, "expected.repo", action.expected?.repo, publicRepo, unitId, failures);
|
|
20704
|
+
_checkRequired(action, "expected.ref", action.expected?.ref, expectedTag, unitId, failures);
|
|
20705
|
+
_checkRequired(action, "expected.entrySkillFound", action.expected?.entrySkillFound, true, unitId, failures);
|
|
20706
|
+
_checkRequired(action, "expected.manifestDigest", action.expected?.manifestDigest, frozen?.manifestDigest, unitId, failures);
|
|
20707
|
+
}
|
|
20708
|
+
}
|
|
20709
|
+
}
|
|
20570
20710
|
if (branchStrategy === "initialize-default-branch") {
|
|
20571
20711
|
const oldBranch = productionConfig.expectedCurrentDefaultBranch;
|
|
20572
20712
|
const newBranch = frozen?.branch;
|
|
@@ -20670,6 +20810,7 @@ var init_plan = __esm({
|
|
|
20670
20810
|
"npm-publish": "npm",
|
|
20671
20811
|
"claude-marketplace-install": "plugin-marketplace",
|
|
20672
20812
|
"codex-marketplace-install": "plugin-marketplace",
|
|
20813
|
+
"kimi-marketplace-install": "plugin-marketplace",
|
|
20673
20814
|
"set-default-branch": "git-github"
|
|
20674
20815
|
};
|
|
20675
20816
|
REQUIRED_ACTION_TYPES = ["push-snapshot", "create-tag", "github-release"];
|
|
@@ -66791,6 +66932,7 @@ var init_contract2 = __esm({
|
|
|
66791
66932
|
// consumer marketplace install (production)
|
|
66792
66933
|
CLAUDE_MARKETPLACE_INSTALL: "claude-marketplace-install",
|
|
66793
66934
|
CODEX_MARKETPLACE_INSTALL: "codex-marketplace-install",
|
|
66935
|
+
KIMI_MARKETPLACE_INSTALL: "kimi-marketplace-install",
|
|
66794
66936
|
// default branch management
|
|
66795
66937
|
SET_DEFAULT_BRANCH: "set-default-branch"
|
|
66796
66938
|
});
|
|
@@ -73782,6 +73924,32 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
73782
73924
|
status: "PENDING"
|
|
73783
73925
|
});
|
|
73784
73926
|
}
|
|
73927
|
+
const kimiDist = (unit.distributions ?? []).find((d) => d.type === "kimi-plugin");
|
|
73928
|
+
if (kimiDist) {
|
|
73929
|
+
const identity = marketplaceIdentity(kimiDist);
|
|
73930
|
+
const kimiTimeoutMs = Number.isInteger(kimiDist.timeoutMs) ? kimiDist.timeoutMs : 3e5;
|
|
73931
|
+
actions.push({
|
|
73932
|
+
id: `kimi-marketplace-install-${unit.id}`,
|
|
73933
|
+
type: "kimi-marketplace-install",
|
|
73934
|
+
adapter: "plugin-marketplace",
|
|
73935
|
+
unitId: unit.id,
|
|
73936
|
+
parameters: {
|
|
73937
|
+
consumer: "kimi",
|
|
73938
|
+
plugin: identity.plugin,
|
|
73939
|
+
repo: unit.publicRepo,
|
|
73940
|
+
version,
|
|
73941
|
+
entrySkill: identity.entrySkill,
|
|
73942
|
+
timeoutMs: kimiTimeoutMs
|
|
73943
|
+
},
|
|
73944
|
+
expected: {
|
|
73945
|
+
installed: true,
|
|
73946
|
+
plugin: identity.plugin,
|
|
73947
|
+
version,
|
|
73948
|
+
entrySkill: identity.entrySkill
|
|
73949
|
+
},
|
|
73950
|
+
status: "PENDING"
|
|
73951
|
+
});
|
|
73952
|
+
}
|
|
73785
73953
|
}
|
|
73786
73954
|
return actions;
|
|
73787
73955
|
}
|
|
@@ -73979,6 +74147,40 @@ function buildExternalActions(unitResults, resolvedVersions, productionAssets) {
|
|
|
73979
74147
|
status: "PENDING"
|
|
73980
74148
|
});
|
|
73981
74149
|
}
|
|
74150
|
+
const kimiDist = (unit.distributions ?? []).find((d) => d.type === "kimi-plugin");
|
|
74151
|
+
if (kimiDist) {
|
|
74152
|
+
const identity = marketplaceIdentity(kimiDist);
|
|
74153
|
+
const kimiTimeoutMs = Number.isInteger(kimiDist.timeoutMs) ? kimiDist.timeoutMs : 3e5;
|
|
74154
|
+
actions.push({
|
|
74155
|
+
id: `kimi-marketplace-install-${unit.id}`,
|
|
74156
|
+
type: "kimi-marketplace-install",
|
|
74157
|
+
adapter: "plugin-marketplace",
|
|
74158
|
+
unitId: unit.id,
|
|
74159
|
+
parameters: {
|
|
74160
|
+
consumer: "kimi",
|
|
74161
|
+
plugin: identity.plugin,
|
|
74162
|
+
repo: unit.publicRepo,
|
|
74163
|
+
ref: resolvedTag,
|
|
74164
|
+
version: unitVersion,
|
|
74165
|
+
entrySkill: identity.entrySkill,
|
|
74166
|
+
snapshotPath: asset.snapshotPath,
|
|
74167
|
+
manifestDigest: asset.manifestDigest,
|
|
74168
|
+
timeoutMs: kimiTimeoutMs
|
|
74169
|
+
},
|
|
74170
|
+
expected: {
|
|
74171
|
+
installed: true,
|
|
74172
|
+
consumer: "kimi",
|
|
74173
|
+
plugin: identity.plugin,
|
|
74174
|
+
repo: unit.publicRepo,
|
|
74175
|
+
version: unitVersion,
|
|
74176
|
+
ref: resolvedTag,
|
|
74177
|
+
entrySkill: identity.entrySkill,
|
|
74178
|
+
entrySkillFound: true,
|
|
74179
|
+
manifestDigest: asset.manifestDigest
|
|
74180
|
+
},
|
|
74181
|
+
status: "PENDING"
|
|
74182
|
+
});
|
|
74183
|
+
}
|
|
73982
74184
|
}
|
|
73983
74185
|
return actions;
|
|
73984
74186
|
}
|
|
@@ -76099,7 +76301,8 @@ var init_reconcile = __esm({
|
|
|
76099
76301
|
"npm-publish",
|
|
76100
76302
|
"github-release",
|
|
76101
76303
|
"claude-marketplace-install",
|
|
76102
|
-
"codex-marketplace-install"
|
|
76304
|
+
"codex-marketplace-install",
|
|
76305
|
+
"kimi-marketplace-install"
|
|
76103
76306
|
];
|
|
76104
76307
|
ADAPTER_ACTION_TYPE_MAP = {
|
|
76105
76308
|
"push-commit": "git-push",
|
|
@@ -76109,11 +76312,13 @@ var init_reconcile = __esm({
|
|
|
76109
76312
|
"npm-publish": "npm-publish",
|
|
76110
76313
|
"github-release": "github-release",
|
|
76111
76314
|
"claude-marketplace-install": "claude-marketplace-install",
|
|
76112
|
-
"codex-marketplace-install": "codex-marketplace-install"
|
|
76315
|
+
"codex-marketplace-install": "codex-marketplace-install",
|
|
76316
|
+
"kimi-marketplace-install": "kimi-marketplace-install"
|
|
76113
76317
|
};
|
|
76114
76318
|
MARKETPLACE_TYPES = /* @__PURE__ */ new Set([
|
|
76115
76319
|
"claude-marketplace-install",
|
|
76116
|
-
"codex-marketplace-install"
|
|
76320
|
+
"codex-marketplace-install",
|
|
76321
|
+
"kimi-marketplace-install"
|
|
76117
76322
|
]);
|
|
76118
76323
|
__name(defaultClock2, "defaultClock");
|
|
76119
76324
|
__name(reconcileRelease, "reconcileRelease");
|
|
@@ -76704,7 +76909,9 @@ var init_git_github = __esm({
|
|
|
76704
76909
|
// src/adapters/plugin-marketplace.mjs
|
|
76705
76910
|
var plugin_marketplace_exports = {};
|
|
76706
76911
|
__export(plugin_marketplace_exports, {
|
|
76707
|
-
createPluginMarketplaceAdapter: () => createPluginMarketplaceAdapter
|
|
76912
|
+
createPluginMarketplaceAdapter: () => createPluginMarketplaceAdapter,
|
|
76913
|
+
readKimiManifest: () => readKimiManifest,
|
|
76914
|
+
resolveKimiEntrySkillFile: () => resolveKimiEntrySkillFile
|
|
76708
76915
|
});
|
|
76709
76916
|
import { execFile as execFileCb10 } from "node:child_process";
|
|
76710
76917
|
import { promisify as promisify10 } from "node:util";
|
|
@@ -76723,6 +76930,49 @@ function transportPayload(entries) {
|
|
|
76723
76930
|
contentDigest
|
|
76724
76931
|
}));
|
|
76725
76932
|
}
|
|
76933
|
+
function consumerTransportExclusions(consumer) {
|
|
76934
|
+
if (consumer === "claude") return [".in_use"];
|
|
76935
|
+
if (consumer === "codex" || consumer === "kimi") return [".git"];
|
|
76936
|
+
return [];
|
|
76937
|
+
}
|
|
76938
|
+
function extractDeclaredPluginSource(consumer, entry) {
|
|
76939
|
+
const rawSource = consumer === "claude" ? entry.source : entry.source?.source === "local" ? entry.source?.path : null;
|
|
76940
|
+
if (typeof rawSource !== "string" || rawSource.length === 0) {
|
|
76941
|
+
throw new Error(`marketplace plugin entry source must be a non-empty relative path${consumer === "codex" ? ' (object with source:"local")' : ""}, got ${JSON.stringify(entry.source)}`);
|
|
76942
|
+
}
|
|
76943
|
+
if (rawSource.startsWith("/") || rawSource.includes("..") || rawSource.includes("\\") || /^https?:\/\//i.test(rawSource)) {
|
|
76944
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76945
|
+
}
|
|
76946
|
+
const segments = rawSource.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
76947
|
+
if (segments.some((segment) => segment === "..")) {
|
|
76948
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76949
|
+
}
|
|
76950
|
+
return segments.length === 0 ? "." : segments.join("/");
|
|
76951
|
+
}
|
|
76952
|
+
async function resolveInstalledPayloadSubpath(snapshotDir, sourceEntries, action, consumer) {
|
|
76953
|
+
if (consumer === "kimi") return ".";
|
|
76954
|
+
const marketplaceRelative = consumer === "claude" ? ".claude-plugin/marketplace.json" : ".agents/plugins/marketplace.json";
|
|
76955
|
+
const anchored = sourceEntries.some((entry) => entry.type === "file" && entry.path === marketplaceRelative);
|
|
76956
|
+
if (!anchored) {
|
|
76957
|
+
throw new Error(`frozen snapshot is missing the marketplace manifest ${marketplaceRelative}`);
|
|
76958
|
+
}
|
|
76959
|
+
const result = await validateManifestFile(resolve19(snapshotDir, marketplaceRelative), ["name", "plugins"]);
|
|
76960
|
+
if (!result.valid) {
|
|
76961
|
+
throw new Error(`frozen snapshot ${marketplaceRelative} invalid: ${result.error}`);
|
|
76962
|
+
}
|
|
76963
|
+
if (result.manifest.name !== action.marketplace) {
|
|
76964
|
+
throw new Error(`marketplace manifest name "${result.manifest.name}" does not match action marketplace "${action.marketplace}"`);
|
|
76965
|
+
}
|
|
76966
|
+
const plugins = result.manifest.plugins;
|
|
76967
|
+
if (!Array.isArray(plugins)) {
|
|
76968
|
+
throw new Error(`${marketplaceRelative} must have a plugins[] array`);
|
|
76969
|
+
}
|
|
76970
|
+
const matches = plugins.filter((entry) => entry.name === action.plugin);
|
|
76971
|
+
if (matches.length !== 1) {
|
|
76972
|
+
throw new Error(`expected exactly one plugins[] entry with name "${action.plugin}", found ${matches.length}`);
|
|
76973
|
+
}
|
|
76974
|
+
return extractDeclaredPluginSource(consumer, matches[0]);
|
|
76975
|
+
}
|
|
76726
76976
|
async function verifyInstalledMarketplacePayload(action, context, installPath, consumer) {
|
|
76727
76977
|
const sourcePath = await resolveFrozenPath(
|
|
76728
76978
|
context.root,
|
|
@@ -76733,10 +76983,21 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
76733
76983
|
if (sourceSnapshot.digest !== action.manifestDigest) {
|
|
76734
76984
|
throw new Error("frozen marketplace snapshot digest no longer matches the plan");
|
|
76735
76985
|
}
|
|
76986
|
+
const payloadSubpath = await resolveInstalledPayloadSubpath(
|
|
76987
|
+
sourcePath,
|
|
76988
|
+
sourceSnapshot.entries,
|
|
76989
|
+
action,
|
|
76990
|
+
consumer
|
|
76991
|
+
);
|
|
76992
|
+
const prefix = payloadSubpath === "." ? null : `${payloadSubpath}/`;
|
|
76993
|
+
const authorityEntries = prefix === null ? sourceSnapshot.entries : sourceSnapshot.entries.filter((entry) => entry.path.startsWith(prefix)).map((entry) => ({ ...entry, path: entry.path.slice(prefix.length) }));
|
|
76994
|
+
if (authorityEntries.length === 0) {
|
|
76995
|
+
throw new Error("frozen snapshot contains no payload under the declared marketplace source");
|
|
76996
|
+
}
|
|
76736
76997
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
76737
|
-
excludeRootEntries: consumer
|
|
76998
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
76738
76999
|
});
|
|
76739
|
-
if (JSON.stringify(transportPayload(
|
|
77000
|
+
if (JSON.stringify(transportPayload(authorityEntries)) !== JSON.stringify(transportPayload(installedSnapshot.entries))) {
|
|
76740
77001
|
throw new Error("installed marketplace payload differs in path, bytes, size, or non-write mode bits");
|
|
76741
77002
|
}
|
|
76742
77003
|
return action.manifestDigest;
|
|
@@ -76753,6 +77014,356 @@ async function writeEvidenceAtomic(filePath, value) {
|
|
|
76753
77014
|
throw err;
|
|
76754
77015
|
}
|
|
76755
77016
|
}
|
|
77017
|
+
function normalizePlanForDigest(plan) {
|
|
77018
|
+
const normalized = { ...plan, status: "PREPARED" };
|
|
77019
|
+
if (Array.isArray(plan.externalActions)) {
|
|
77020
|
+
normalized.externalActions = plan.externalActions.map((action) => action && typeof action === "object" && !Array.isArray(action) ? { ...action, status: "PENDING" } : action);
|
|
77021
|
+
}
|
|
77022
|
+
return normalized;
|
|
77023
|
+
}
|
|
77024
|
+
function resolveBoundPlanDigest(context) {
|
|
77025
|
+
const plan = context?.plan;
|
|
77026
|
+
if (!plan || typeof plan !== "object" || Array.isArray(plan)) {
|
|
77027
|
+
throw new Error("context.plan is required to bind the kimi plan digest");
|
|
77028
|
+
}
|
|
77029
|
+
const carried = plan.digest;
|
|
77030
|
+
if (typeof carried !== "string" || !HEX_DIGEST_RE.test(carried)) {
|
|
77031
|
+
throw new Error("context.plan.digest must be a 64-char lowercase hex frozen plan digest");
|
|
77032
|
+
}
|
|
77033
|
+
const normalized = normalizePlanForDigest(plan);
|
|
77034
|
+
if (computePlanDigest(normalized) !== carried) {
|
|
77035
|
+
throw new Error("context.plan.digest does not match the normalized frozen plan (a non-lifecycle field was tampered)");
|
|
77036
|
+
}
|
|
77037
|
+
return carried;
|
|
77038
|
+
}
|
|
77039
|
+
function kimiAuthorityDir(context, planDigest, plugin) {
|
|
77040
|
+
if (!context?.root) {
|
|
77041
|
+
throw new Error("context.root is required for the kimi attestation authority");
|
|
77042
|
+
}
|
|
77043
|
+
if (!HEX_DIGEST_RE.test(planDigest)) {
|
|
77044
|
+
throw new Error("kimi attestation authority requires a 64-hex plan digest");
|
|
77045
|
+
}
|
|
77046
|
+
if (!SAFE_ID_RE.test(plugin)) {
|
|
77047
|
+
throw new Error(`kimi attestation authority requires a safe plugin id: "${plugin}"`);
|
|
77048
|
+
}
|
|
77049
|
+
const base = resolve19(context.root, ".release-skill", "kimi-attestations");
|
|
77050
|
+
const dir = resolve19(base, planDigest, plugin);
|
|
77051
|
+
const rel = relative16(base, dir);
|
|
77052
|
+
const sep4 = process.platform === "win32" ? "\\" : "/";
|
|
77053
|
+
if (rel === "" || rel === ".." || isAbsolute13(rel) || rel.startsWith(`..${sep4}`) || rel.split(sep4).some((segment) => segment === ".." || segment === "")) {
|
|
77054
|
+
throw new Error("kimi attestation authority path escapes its base");
|
|
77055
|
+
}
|
|
77056
|
+
return dir;
|
|
77057
|
+
}
|
|
77058
|
+
function buildKimiInstallUrl(repo, ref) {
|
|
77059
|
+
return `https://github.com/${repo}/releases/tag/${ref}`;
|
|
77060
|
+
}
|
|
77061
|
+
function buildKimiManualInstructions({ installUrl, plugin, version, ref, isolatedHome, attestationDir }) {
|
|
77062
|
+
return [
|
|
77063
|
+
`Kimi Code has no scriptable plugin-install CLI; installation is a manual, interactive step.`,
|
|
77064
|
+
`1) publish fails closed at this kimi checkpoint and leaves the run PARTIAL (the automated Git branch/tag, npm, and GitHub Release writes still complete first).`,
|
|
77065
|
+
`2) Launch Kimi Code with the ISOLATED home from this requirement so the managed copy lands inside it: set HOME="${isolatedHome}" and KIMI_CODE_HOME="${isolatedHome}". The plugin installs to "${isolatedHome}/plugins/managed/${plugin}/".`,
|
|
77066
|
+
`3) In that isolated Kimi Code session run: /plugins install ${installUrl} (pinned to frozen ref "${ref}", version ${version}; never install the bare repository URL). Confirm the trust prompt for plugin "${plugin}", then run /plugins reload (or /new).`,
|
|
77067
|
+
`4) Write the attestation JSON to: ${attestationDir}/${KIMI_ATTESTATION_FILE}. planDigest MUST be the frozen plan digest; payloadDigest MUST be the frozen snapshot payload digest; installPath MUST be the isolated managed directory above. attestedAt must not be in the future and expiresAt must be within 24 hours of attestedAt.`,
|
|
77068
|
+
` Required fields: consumer="kimi", plugin, version, entrySkill, repo, ref, installPath, planDigest, payloadDigest, attestedBy, attestedAt, expiresAt.`,
|
|
77069
|
+
`5) Re-run release-skill reconcile (promotes PARTIAL -> PUBLISHED) and then verify (-> VERIFIED). Both read the attestation from this same plan-digest-keyed authority directory, so a fresh run directory does not lose the proof.`,
|
|
77070
|
+
`An install into the ordinary ~/.kimi-code is NOT acceptable proof: the attested installPath must resolve inside this requirement's isolated KIMI_CODE_HOME managed root, otherwise verification fails closed.`
|
|
77071
|
+
];
|
|
77072
|
+
}
|
|
77073
|
+
async function readKimiManifest(pluginRootReal) {
|
|
77074
|
+
const candidates = [
|
|
77075
|
+
"kimi.plugin.json",
|
|
77076
|
+
join12(".kimi-plugin", "plugin.json")
|
|
77077
|
+
];
|
|
77078
|
+
for (const manifestRelative of candidates) {
|
|
77079
|
+
const manifestPath = resolve19(pluginRootReal, manifestRelative);
|
|
77080
|
+
let content;
|
|
77081
|
+
try {
|
|
77082
|
+
content = await readFile17(manifestPath, "utf8");
|
|
77083
|
+
} catch {
|
|
77084
|
+
continue;
|
|
77085
|
+
}
|
|
77086
|
+
let manifest;
|
|
77087
|
+
try {
|
|
77088
|
+
manifest = JSON.parse(content);
|
|
77089
|
+
} catch {
|
|
77090
|
+
throw new Error(`kimi plugin manifest ${manifestRelative} is not valid JSON`);
|
|
77091
|
+
}
|
|
77092
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
77093
|
+
throw new Error(`kimi plugin manifest ${manifestRelative} is not an object`);
|
|
77094
|
+
}
|
|
77095
|
+
return { manifest, manifestRelative };
|
|
77096
|
+
}
|
|
77097
|
+
throw new Error("no kimi plugin manifest found (expected kimi.plugin.json or .kimi-plugin/plugin.json)");
|
|
77098
|
+
}
|
|
77099
|
+
function normalizeKimiSkillsRel(skillsRaw) {
|
|
77100
|
+
if (typeof skillsRaw !== "string" || skillsRaw.length === 0) {
|
|
77101
|
+
throw new Error("kimi manifest skills must be a non-empty relative path when present");
|
|
77102
|
+
}
|
|
77103
|
+
if (skillsRaw.startsWith("/") || skillsRaw.includes("..") || skillsRaw.includes("\\") || /^https?:\/\//i.test(skillsRaw)) {
|
|
77104
|
+
throw new Error(`kimi manifest skills "${skillsRaw}" is not a safe relative path`);
|
|
77105
|
+
}
|
|
77106
|
+
let rel = skillsRaw.replace(/^\.\//, "");
|
|
77107
|
+
rel = rel.replace(/\/+$/, "");
|
|
77108
|
+
if (rel.split("/").some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
77109
|
+
throw new Error(`kimi manifest skills "${skillsRaw}" is not a safe relative path`);
|
|
77110
|
+
}
|
|
77111
|
+
return rel;
|
|
77112
|
+
}
|
|
77113
|
+
async function resolveKimiEntrySkillFile(pluginRootReal, manifest, entrySkill) {
|
|
77114
|
+
if (!entrySkill || typeof entrySkill !== "string" || !SAFE_ID_RE.test(entrySkill)) {
|
|
77115
|
+
throw new Error(`unsafe entrySkill: "${entrySkill}"`);
|
|
77116
|
+
}
|
|
77117
|
+
let entryAbs;
|
|
77118
|
+
if (manifest.skills === void 0 || manifest.skills === null) {
|
|
77119
|
+
entryAbs = resolve19(pluginRootReal, "SKILL.md");
|
|
77120
|
+
} else {
|
|
77121
|
+
const skillsRel = normalizeKimiSkillsRel(manifest.skills);
|
|
77122
|
+
const skillsRootAbs = skillsRel === "" ? pluginRootReal : resolve19(pluginRootReal, skillsRel);
|
|
77123
|
+
const skillsRootReal = await realpath11(skillsRootAbs).catch(() => null);
|
|
77124
|
+
if (!skillsRootReal) {
|
|
77125
|
+
throw new Error(`kimi manifest skills root does not exist: ${manifest.skills}`);
|
|
77126
|
+
}
|
|
77127
|
+
const skillsContainment = relative16(pluginRootReal, skillsRootReal);
|
|
77128
|
+
const sepK = process.platform === "win32" ? "\\" : "/";
|
|
77129
|
+
if (skillsContainment !== "" && (isAbsolute13(skillsContainment) || skillsContainment === ".." || skillsContainment.startsWith(`..${sepK}`))) {
|
|
77130
|
+
throw new Error(`kimi manifest skills "${manifest.skills}" escapes the plugin root after symlink resolution`);
|
|
77131
|
+
}
|
|
77132
|
+
entryAbs = resolve19(skillsRootReal, entrySkill, "SKILL.md");
|
|
77133
|
+
}
|
|
77134
|
+
let entryLexicalStat;
|
|
77135
|
+
try {
|
|
77136
|
+
entryLexicalStat = await lstat11(entryAbs);
|
|
77137
|
+
} catch {
|
|
77138
|
+
throw new Error(`kimi entry skill not found: ${relative16(pluginRootReal, entryAbs) || "SKILL.md"}`);
|
|
77139
|
+
}
|
|
77140
|
+
if (entryLexicalStat.isSymbolicLink()) {
|
|
77141
|
+
throw new Error("kimi entry skill must not be a symlink");
|
|
77142
|
+
}
|
|
77143
|
+
if (!entryLexicalStat.isFile()) {
|
|
77144
|
+
throw new Error("kimi entry skill is not a regular file");
|
|
77145
|
+
}
|
|
77146
|
+
const entryReal = await realpath11(entryAbs).catch(() => null);
|
|
77147
|
+
if (!entryReal) {
|
|
77148
|
+
throw new Error(`kimi entry skill not found: ${relative16(pluginRootReal, entryAbs) || "SKILL.md"}`);
|
|
77149
|
+
}
|
|
77150
|
+
const entryContainment = relative16(pluginRootReal, entryReal);
|
|
77151
|
+
const sepE = process.platform === "win32" ? "\\" : "/";
|
|
77152
|
+
if (entryContainment !== "" && (isAbsolute13(entryContainment) || entryContainment === ".." || entryContainment.startsWith(`..${sepE}`))) {
|
|
77153
|
+
throw new Error("kimi entry skill escapes the plugin root after symlink resolution");
|
|
77154
|
+
}
|
|
77155
|
+
return entryReal;
|
|
77156
|
+
}
|
|
77157
|
+
function validateKimiAttestation(attestation, action, isoNow, boundPlanDigest) {
|
|
77158
|
+
if (!attestation || typeof attestation !== "object" || Array.isArray(attestation)) {
|
|
77159
|
+
return { valid: false, error: "kimi attestation is not an object" };
|
|
77160
|
+
}
|
|
77161
|
+
const requiredStrings = ["plugin", "version", "entrySkill", "repo", "ref", "installPath", "payloadDigest", "planDigest", "attestedBy", "attestedAt", "expiresAt"];
|
|
77162
|
+
for (const field of requiredStrings) {
|
|
77163
|
+
if (typeof attestation[field] !== "string" || attestation[field].length === 0) {
|
|
77164
|
+
return { valid: false, error: `kimi attestation missing required field "${field}"` };
|
|
77165
|
+
}
|
|
77166
|
+
}
|
|
77167
|
+
if (attestation.consumer !== "kimi") {
|
|
77168
|
+
return { valid: false, error: `kimi attestation consumer "${attestation.consumer}" must be "kimi"` };
|
|
77169
|
+
}
|
|
77170
|
+
if (!HEX_DIGEST_RE.test(attestation.planDigest)) {
|
|
77171
|
+
return { valid: false, error: "kimi attestation planDigest must be a 64-char lowercase hex digest" };
|
|
77172
|
+
}
|
|
77173
|
+
if (attestation.planDigest !== boundPlanDigest) {
|
|
77174
|
+
return { valid: false, error: "kimi attestation planDigest does not match the frozen plan digest" };
|
|
77175
|
+
}
|
|
77176
|
+
if (attestation.plugin !== action.plugin) {
|
|
77177
|
+
return { valid: false, error: `kimi attestation plugin "${attestation.plugin}" does not match action plugin "${action.plugin}"` };
|
|
77178
|
+
}
|
|
77179
|
+
if (attestation.version !== action.version) {
|
|
77180
|
+
return { valid: false, error: `kimi attestation version "${attestation.version}" does not match action version "${action.version}"` };
|
|
77181
|
+
}
|
|
77182
|
+
if (attestation.entrySkill !== action.entrySkill) {
|
|
77183
|
+
return { valid: false, error: `kimi attestation entrySkill "${attestation.entrySkill}" does not match action entrySkill "${action.entrySkill}"` };
|
|
77184
|
+
}
|
|
77185
|
+
if (attestation.repo !== action.repo) {
|
|
77186
|
+
return { valid: false, error: `kimi attestation repo "${attestation.repo}" does not match action repo "${action.repo}"` };
|
|
77187
|
+
}
|
|
77188
|
+
const expectedRef = action.ref ?? `v${action.version}`;
|
|
77189
|
+
if (attestation.ref !== expectedRef) {
|
|
77190
|
+
return { valid: false, error: `kimi attestation ref "${attestation.ref}" does not match frozen ref "${expectedRef}"` };
|
|
77191
|
+
}
|
|
77192
|
+
if (attestation.payloadDigest !== action.manifestDigest) {
|
|
77193
|
+
return { valid: false, error: "kimi attestation payloadDigest does not match the frozen payload digest" };
|
|
77194
|
+
}
|
|
77195
|
+
const attestedMs = Date.parse(attestation.attestedAt);
|
|
77196
|
+
const expiresMs = Date.parse(attestation.expiresAt);
|
|
77197
|
+
const nowMs = Date.parse(isoNow);
|
|
77198
|
+
if (!Number.isFinite(attestedMs) || !Number.isFinite(expiresMs) || !Number.isFinite(nowMs)) {
|
|
77199
|
+
return { valid: false, error: "kimi attestation attestedAt/expiresAt must be valid ISO timestamps" };
|
|
77200
|
+
}
|
|
77201
|
+
if (attestedMs > nowMs) {
|
|
77202
|
+
return { valid: false, error: "kimi attestation attestedAt is in the future" };
|
|
77203
|
+
}
|
|
77204
|
+
if (expiresMs <= attestedMs) {
|
|
77205
|
+
return { valid: false, error: "kimi attestation expiresAt must be after attestedAt" };
|
|
77206
|
+
}
|
|
77207
|
+
if (expiresMs - attestedMs > KIMI_MAX_ATTESTATION_VALIDITY_MS) {
|
|
77208
|
+
return { valid: false, error: "kimi attestation validity must not exceed 24 hours" };
|
|
77209
|
+
}
|
|
77210
|
+
if (nowMs > expiresMs) {
|
|
77211
|
+
return { valid: false, error: "kimi attestation has expired" };
|
|
77212
|
+
}
|
|
77213
|
+
return { valid: true, error: null };
|
|
77214
|
+
}
|
|
77215
|
+
async function executeKimiManualRequirement(action, context) {
|
|
77216
|
+
const actionType = ActionType.KIMI_MARKETPLACE_INSTALL;
|
|
77217
|
+
let planDigest;
|
|
77218
|
+
try {
|
|
77219
|
+
planDigest = resolveBoundPlanDigest(context);
|
|
77220
|
+
} catch (planErr) {
|
|
77221
|
+
return createResult({
|
|
77222
|
+
actionType,
|
|
77223
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77224
|
+
error: `cannot bind kimi requirement to the frozen plan: ${planErr.message}`
|
|
77225
|
+
});
|
|
77226
|
+
}
|
|
77227
|
+
try {
|
|
77228
|
+
resolveTimeoutMs(action);
|
|
77229
|
+
} catch (timeoutErr) {
|
|
77230
|
+
return createResult({
|
|
77231
|
+
actionType,
|
|
77232
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77233
|
+
error: timeoutErr.message
|
|
77234
|
+
});
|
|
77235
|
+
}
|
|
77236
|
+
const ref = action.ref ?? `v${action.version}`;
|
|
77237
|
+
const installUrl = buildKimiInstallUrl(action.repo, ref);
|
|
77238
|
+
let attestationDir;
|
|
77239
|
+
try {
|
|
77240
|
+
attestationDir = kimiAuthorityDir(context, planDigest, action.plugin);
|
|
77241
|
+
} catch (dirErr) {
|
|
77242
|
+
return createResult({
|
|
77243
|
+
actionType,
|
|
77244
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77245
|
+
error: dirErr.message
|
|
77246
|
+
});
|
|
77247
|
+
}
|
|
77248
|
+
const kimiHome = resolve19(attestationDir, "kimi-home");
|
|
77249
|
+
const managedParent = resolve19(kimiHome, KIMI_MANAGED_SUBPATH);
|
|
77250
|
+
const managedInstallRoot = resolve19(managedParent, action.plugin);
|
|
77251
|
+
const instructions = buildKimiManualInstructions({
|
|
77252
|
+
installUrl,
|
|
77253
|
+
plugin: action.plugin,
|
|
77254
|
+
version: action.version,
|
|
77255
|
+
ref,
|
|
77256
|
+
isolatedHome: kimiHome,
|
|
77257
|
+
attestationDir
|
|
77258
|
+
});
|
|
77259
|
+
const requirement = {
|
|
77260
|
+
kind: "kimi-manual-install-requirement",
|
|
77261
|
+
consumer: "kimi",
|
|
77262
|
+
plugin: action.plugin,
|
|
77263
|
+
version: action.version,
|
|
77264
|
+
entrySkill: action.entrySkill,
|
|
77265
|
+
repo: action.repo,
|
|
77266
|
+
ref,
|
|
77267
|
+
installUrl,
|
|
77268
|
+
// (A) planDigest binds to the real frozen plan digest;
|
|
77269
|
+
// expectedPayloadDigest binds separately to the snapshot payload digest.
|
|
77270
|
+
planDigest,
|
|
77271
|
+
expectedPayloadDigest: action.manifestDigest,
|
|
77272
|
+
isolatedHome: kimiHome,
|
|
77273
|
+
kimiCodeHome: kimiHome,
|
|
77274
|
+
managedInstallRoot,
|
|
77275
|
+
attestationDir,
|
|
77276
|
+
attestationFile: KIMI_ATTESTATION_FILE,
|
|
77277
|
+
attestationTemplate: {
|
|
77278
|
+
consumer: "kimi",
|
|
77279
|
+
plugin: action.plugin,
|
|
77280
|
+
version: action.version,
|
|
77281
|
+
entrySkill: action.entrySkill,
|
|
77282
|
+
repo: action.repo,
|
|
77283
|
+
ref,
|
|
77284
|
+
installPath: managedInstallRoot,
|
|
77285
|
+
planDigest,
|
|
77286
|
+
payloadDigest: action.manifestDigest,
|
|
77287
|
+
attestedBy: "<person responsible for the manual install>",
|
|
77288
|
+
attestedAt: "<ISO 8601 now; must not be in the future>",
|
|
77289
|
+
expiresAt: "<ISO 8601; within 24h of attestedAt>"
|
|
77290
|
+
},
|
|
77291
|
+
instructions
|
|
77292
|
+
};
|
|
77293
|
+
try {
|
|
77294
|
+
await mkdir11(managedParent, { recursive: true, mode: 448 });
|
|
77295
|
+
} catch (mkdirErr) {
|
|
77296
|
+
return createResult({
|
|
77297
|
+
actionType,
|
|
77298
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77299
|
+
error: `cannot create kimi managed parent directory: ${mkdirErr.message}`
|
|
77300
|
+
});
|
|
77301
|
+
}
|
|
77302
|
+
const requirementPath = resolve19(attestationDir, KIMI_REQUIREMENT_FILE);
|
|
77303
|
+
let existing = null;
|
|
77304
|
+
let requirementMissing = false;
|
|
77305
|
+
try {
|
|
77306
|
+
const existingRaw = await readFile17(requirementPath, "utf8");
|
|
77307
|
+
try {
|
|
77308
|
+
existing = JSON.parse(existingRaw);
|
|
77309
|
+
} catch (parseErr) {
|
|
77310
|
+
return createResult({
|
|
77311
|
+
actionType,
|
|
77312
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77313
|
+
error: `existing kimi manual-install requirement is invalid JSON; refusing to overwrite: ${parseErr.message}`
|
|
77314
|
+
});
|
|
77315
|
+
}
|
|
77316
|
+
} catch (readErr) {
|
|
77317
|
+
if (readErr?.code === "ENOENT") {
|
|
77318
|
+
requirementMissing = true;
|
|
77319
|
+
} else {
|
|
77320
|
+
return createResult({
|
|
77321
|
+
actionType,
|
|
77322
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77323
|
+
error: `existing kimi manual-install requirement cannot be read; refusing to overwrite: ${readErr.message}`
|
|
77324
|
+
});
|
|
77325
|
+
}
|
|
77326
|
+
}
|
|
77327
|
+
if (!requirementMissing) {
|
|
77328
|
+
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
77329
|
+
return createResult({
|
|
77330
|
+
actionType,
|
|
77331
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77332
|
+
error: "existing kimi manual-install requirement is not an object; refusing to overwrite"
|
|
77333
|
+
});
|
|
77334
|
+
}
|
|
77335
|
+
const { createdAt: _existingCreatedAt, ...existingBody } = existing;
|
|
77336
|
+
if (canonicalJson(existingBody) !== canonicalJson(requirement)) {
|
|
77337
|
+
return createResult({
|
|
77338
|
+
actionType,
|
|
77339
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77340
|
+
error: "existing kimi manual-install requirement conflicts with the current frozen action; refusing to overwrite"
|
|
77341
|
+
});
|
|
77342
|
+
}
|
|
77343
|
+
} else {
|
|
77344
|
+
await writeEvidenceAtomic(requirementPath, { ...requirement, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
77345
|
+
}
|
|
77346
|
+
return createResult({
|
|
77347
|
+
actionType,
|
|
77348
|
+
status: ActionStatus.EXECUTED,
|
|
77349
|
+
observation: {
|
|
77350
|
+
installed: false,
|
|
77351
|
+
manualInstallRequired: true,
|
|
77352
|
+
consumer: "kimi",
|
|
77353
|
+
plugin: action.plugin,
|
|
77354
|
+
version: action.version,
|
|
77355
|
+
entrySkill: action.entrySkill,
|
|
77356
|
+
repo: action.repo,
|
|
77357
|
+
ref,
|
|
77358
|
+
installUrl,
|
|
77359
|
+
planDigest,
|
|
77360
|
+
attestationDir,
|
|
77361
|
+
kimiCodeHome: kimiHome,
|
|
77362
|
+
managedInstallRoot,
|
|
77363
|
+
instructions
|
|
77364
|
+
}
|
|
77365
|
+
});
|
|
77366
|
+
}
|
|
76756
77367
|
function validateSafeRef(ref) {
|
|
76757
77368
|
if (!ref || typeof ref !== "string") {
|
|
76758
77369
|
return { valid: false, error: "ref is required" };
|
|
@@ -76800,13 +77411,17 @@ function validateMarketplaceParams(params) {
|
|
|
76800
77411
|
return { valid: false, error: "parameters must be an object" };
|
|
76801
77412
|
}
|
|
76802
77413
|
const { consumer, plugin, marketplace, repo, version, entrySkill } = params;
|
|
76803
|
-
if (!["claude", "codex"].includes(consumer)) {
|
|
77414
|
+
if (!["claude", "codex", "kimi"].includes(consumer)) {
|
|
76804
77415
|
return { valid: false, error: `invalid consumer: "${consumer}"` };
|
|
76805
77416
|
}
|
|
76806
77417
|
if (!plugin || !SAFE_ID_RE.test(plugin)) {
|
|
76807
77418
|
return { valid: false, error: `unsafe plugin identifier: "${plugin}"` };
|
|
76808
77419
|
}
|
|
76809
|
-
if (
|
|
77420
|
+
if (consumer === "kimi") {
|
|
77421
|
+
if (marketplace !== void 0 && marketplace !== null && !SAFE_ID_RE.test(marketplace)) {
|
|
77422
|
+
return { valid: false, error: `unsafe marketplace identifier: "${marketplace}"` };
|
|
77423
|
+
}
|
|
77424
|
+
} else if (!marketplace || !SAFE_ID_RE.test(marketplace)) {
|
|
76810
77425
|
return { valid: false, error: `unsafe marketplace identifier: "${marketplace}"` };
|
|
76811
77426
|
}
|
|
76812
77427
|
if (!repo || !SAFE_REPO_RE.test(repo)) {
|
|
@@ -76945,7 +77560,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
76945
77560
|
status: ActionStatus.PREFLIGHT_PASSED
|
|
76946
77561
|
});
|
|
76947
77562
|
}
|
|
76948
|
-
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL) {
|
|
77563
|
+
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL) {
|
|
76949
77564
|
const validation = validateMarketplaceParams(action);
|
|
76950
77565
|
if (!validation.valid) {
|
|
76951
77566
|
return createResult({
|
|
@@ -77009,6 +77624,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77009
77624
|
}
|
|
77010
77625
|
const consumer = action.consumer;
|
|
77011
77626
|
let snapshotDirReal;
|
|
77627
|
+
let kimiSnapshotManifest = null;
|
|
77012
77628
|
try {
|
|
77013
77629
|
snapshotDirReal = await resolveFrozenPath(context.root, snapshotPath, "frozen snapshot path");
|
|
77014
77630
|
} catch (frozenErr) {
|
|
@@ -77018,120 +77634,157 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77018
77634
|
error: `frozen snapshot validation failed: ${frozenErr.message}`
|
|
77019
77635
|
});
|
|
77020
77636
|
}
|
|
77021
|
-
|
|
77022
|
-
|
|
77023
|
-
|
|
77024
|
-
|
|
77025
|
-
|
|
77026
|
-
|
|
77027
|
-
|
|
77028
|
-
|
|
77029
|
-
|
|
77030
|
-
|
|
77031
|
-
|
|
77032
|
-
|
|
77033
|
-
|
|
77034
|
-
|
|
77035
|
-
|
|
77036
|
-
|
|
77037
|
-
|
|
77038
|
-
|
|
77039
|
-
|
|
77040
|
-
|
|
77041
|
-
|
|
77042
|
-
|
|
77043
|
-
|
|
77044
|
-
|
|
77045
|
-
|
|
77046
|
-
|
|
77047
|
-
|
|
77048
|
-
return createResult({
|
|
77049
|
-
actionType,
|
|
77050
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77051
|
-
error: `expected exactly one plugins[] entry with name "${action.plugin}", found ${pluginEntry.length}`
|
|
77052
|
-
});
|
|
77053
|
-
}
|
|
77054
|
-
const entry = pluginEntry[0];
|
|
77055
|
-
const sourcePath = consumer === "claude" ? entry.source : entry.source?.source === "local" ? entry.source?.path : null;
|
|
77056
|
-
if (typeof sourcePath !== "string" || sourcePath.length === 0) {
|
|
77057
|
-
return createResult({
|
|
77058
|
-
actionType,
|
|
77059
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77060
|
-
error: `marketplace plugin entry source must be a non-empty relative path${consumer === "codex" ? ' (object with source:"local")' : ""}, got ${JSON.stringify(entry.source)}`
|
|
77061
|
-
});
|
|
77062
|
-
}
|
|
77063
|
-
if (sourcePath.startsWith("/") || sourcePath.includes("..") || sourcePath.includes("\\") || /^https?:\/\//i.test(sourcePath)) {
|
|
77064
|
-
return createResult({
|
|
77065
|
-
actionType,
|
|
77066
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77067
|
-
error: `marketplace plugin entry source "${sourcePath}" is not a safe relative path`
|
|
77068
|
-
});
|
|
77069
|
-
}
|
|
77070
|
-
const sourceDirAbs = resolve19(snapshotDirReal, sourcePath);
|
|
77071
|
-
const sourceDirReal = await realpath11(sourceDirAbs).catch(() => null);
|
|
77072
|
-
if (!sourceDirReal) {
|
|
77073
|
-
return createResult({
|
|
77074
|
-
actionType,
|
|
77075
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77076
|
-
error: `marketplace plugin entry source directory does not exist: ${sourcePath}`
|
|
77077
|
-
});
|
|
77078
|
-
}
|
|
77079
|
-
const sourceRelCheck = relative16(snapshotDirReal, sourceDirReal);
|
|
77080
|
-
if (sourceRelCheck.startsWith("..") || isAbsolute13(sourceRelCheck)) {
|
|
77081
|
-
return createResult({
|
|
77082
|
-
actionType,
|
|
77083
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77084
|
-
error: `marketplace plugin entry source "${sourcePath}" escapes the frozen snapshot`
|
|
77085
|
-
});
|
|
77086
|
-
}
|
|
77087
|
-
const manifestRelative = consumer === "claude" ? join12(sourcePath, ".claude-plugin", "plugin.json") : join12(sourcePath, ".codex-plugin", "plugin.json");
|
|
77088
|
-
const manifestPath = resolve19(snapshotDirReal, manifestRelative);
|
|
77089
|
-
const manifestResult = await validateManifestFile(manifestPath, ["name", "version"]);
|
|
77090
|
-
if (!manifestResult.valid) {
|
|
77091
|
-
return createResult({
|
|
77092
|
-
actionType,
|
|
77093
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77094
|
-
error: `frozen snapshot ${manifestRelative} invalid: ${manifestResult.error}`
|
|
77095
|
-
});
|
|
77096
|
-
}
|
|
77097
|
-
if (consumer === "claude" && entry.version !== action.version) {
|
|
77098
|
-
return createResult({
|
|
77099
|
-
actionType,
|
|
77100
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77101
|
-
error: `marketplace plugin entry version "${entry.version}" does not match action version "${action.version}"`
|
|
77102
|
-
});
|
|
77103
|
-
}
|
|
77104
|
-
const pluginManifestResult = await validateManifestFile(manifestPath, ["name", "version"]);
|
|
77105
|
-
if (!pluginManifestResult.valid) {
|
|
77106
|
-
return createResult({
|
|
77107
|
-
actionType,
|
|
77108
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77109
|
-
error: `frozen snapshot ${manifestRelative} invalid: ${pluginManifestResult.error}`
|
|
77110
|
-
});
|
|
77111
|
-
}
|
|
77112
|
-
if (pluginManifestResult.manifest.name !== entry.name) {
|
|
77113
|
-
return createResult({
|
|
77114
|
-
actionType,
|
|
77115
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77116
|
-
error: `plugin manifest name "${pluginManifestResult.manifest.name}" does not match marketplace entry name "${entry.name}"`
|
|
77117
|
-
});
|
|
77637
|
+
if (consumer === "kimi") {
|
|
77638
|
+
let kimiManifestResult;
|
|
77639
|
+
try {
|
|
77640
|
+
kimiManifestResult = await readKimiManifest(snapshotDirReal);
|
|
77641
|
+
} catch (manifestErr) {
|
|
77642
|
+
return createResult({
|
|
77643
|
+
actionType,
|
|
77644
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77645
|
+
error: `frozen snapshot kimi manifest invalid: ${manifestErr.message}`
|
|
77646
|
+
});
|
|
77647
|
+
}
|
|
77648
|
+
const kimiManifest = kimiManifestResult.manifest;
|
|
77649
|
+
if (typeof kimiManifest.name !== "string" || kimiManifest.name !== action.plugin) {
|
|
77650
|
+
return createResult({
|
|
77651
|
+
actionType,
|
|
77652
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77653
|
+
error: `plugin manifest name "${kimiManifest.name}" does not match action plugin "${action.plugin}"`
|
|
77654
|
+
});
|
|
77655
|
+
}
|
|
77656
|
+
if (typeof kimiManifest.version !== "string" || kimiManifest.version !== action.version) {
|
|
77657
|
+
return createResult({
|
|
77658
|
+
actionType,
|
|
77659
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77660
|
+
error: `plugin manifest version "${kimiManifest.version}" does not match action version "${action.version}"`
|
|
77661
|
+
});
|
|
77662
|
+
}
|
|
77663
|
+
kimiSnapshotManifest = kimiManifest;
|
|
77118
77664
|
}
|
|
77119
|
-
if (
|
|
77120
|
-
|
|
77121
|
-
|
|
77122
|
-
|
|
77123
|
-
|
|
77124
|
-
|
|
77665
|
+
if (consumer !== "kimi") {
|
|
77666
|
+
const marketplaceRelative = consumer === "claude" ? ".claude-plugin/marketplace.json" : ".agents/plugins/marketplace.json";
|
|
77667
|
+
const marketplacePath = resolve19(snapshotDirReal, marketplaceRelative);
|
|
77668
|
+
const marketplaceResult = await validateManifestFile(marketplacePath, ["name"]);
|
|
77669
|
+
if (!marketplaceResult.valid) {
|
|
77670
|
+
return createResult({
|
|
77671
|
+
actionType,
|
|
77672
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77673
|
+
error: `frozen snapshot ${marketplaceRelative} invalid: ${marketplaceResult.error}`
|
|
77674
|
+
});
|
|
77675
|
+
}
|
|
77676
|
+
if (marketplaceResult.manifest.name !== action.marketplace) {
|
|
77677
|
+
return createResult({
|
|
77678
|
+
actionType,
|
|
77679
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77680
|
+
error: `marketplace.json name "${marketplaceResult.manifest.name}" does not match action marketplace "${action.marketplace}"`
|
|
77681
|
+
});
|
|
77682
|
+
}
|
|
77683
|
+
const plugins = marketplaceResult.manifest.plugins;
|
|
77684
|
+
if (!Array.isArray(plugins)) {
|
|
77685
|
+
return createResult({
|
|
77686
|
+
actionType,
|
|
77687
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77688
|
+
error: `${marketplaceRelative} must have a plugins[] array`
|
|
77689
|
+
});
|
|
77690
|
+
}
|
|
77691
|
+
const pluginEntry = plugins.filter((p) => p.name === action.plugin);
|
|
77692
|
+
if (pluginEntry.length !== 1) {
|
|
77693
|
+
return createResult({
|
|
77694
|
+
actionType,
|
|
77695
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77696
|
+
error: `expected exactly one plugins[] entry with name "${action.plugin}", found ${pluginEntry.length}`
|
|
77697
|
+
});
|
|
77698
|
+
}
|
|
77699
|
+
const entry = pluginEntry[0];
|
|
77700
|
+
let sourcePath;
|
|
77701
|
+
try {
|
|
77702
|
+
sourcePath = extractDeclaredPluginSource(consumer, entry);
|
|
77703
|
+
} catch (sourceErr) {
|
|
77704
|
+
return createResult({
|
|
77705
|
+
actionType,
|
|
77706
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77707
|
+
error: sourceErr.message
|
|
77708
|
+
});
|
|
77709
|
+
}
|
|
77710
|
+
const sourceDirAbs = resolve19(snapshotDirReal, sourcePath);
|
|
77711
|
+
const sourceDirReal = await realpath11(sourceDirAbs).catch(() => null);
|
|
77712
|
+
if (!sourceDirReal) {
|
|
77713
|
+
return createResult({
|
|
77714
|
+
actionType,
|
|
77715
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77716
|
+
error: `marketplace plugin entry source directory does not exist: ${sourcePath}`
|
|
77717
|
+
});
|
|
77718
|
+
}
|
|
77719
|
+
const sourceRelCheck = relative16(snapshotDirReal, sourceDirReal);
|
|
77720
|
+
if (sourceRelCheck.startsWith("..") || isAbsolute13(sourceRelCheck)) {
|
|
77721
|
+
return createResult({
|
|
77722
|
+
actionType,
|
|
77723
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77724
|
+
error: `marketplace plugin entry source "${sourcePath}" escapes the frozen snapshot`
|
|
77725
|
+
});
|
|
77726
|
+
}
|
|
77727
|
+
const manifestRelative = consumer === "claude" ? join12(sourcePath, ".claude-plugin", "plugin.json") : join12(sourcePath, ".codex-plugin", "plugin.json");
|
|
77728
|
+
const manifestPath = resolve19(snapshotDirReal, manifestRelative);
|
|
77729
|
+
const manifestResult = await validateManifestFile(manifestPath, ["name", "version"]);
|
|
77730
|
+
if (!manifestResult.valid) {
|
|
77731
|
+
return createResult({
|
|
77732
|
+
actionType,
|
|
77733
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77734
|
+
error: `frozen snapshot ${manifestRelative} invalid: ${manifestResult.error}`
|
|
77735
|
+
});
|
|
77736
|
+
}
|
|
77737
|
+
if (consumer === "claude" && entry.version !== action.version) {
|
|
77738
|
+
return createResult({
|
|
77739
|
+
actionType,
|
|
77740
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77741
|
+
error: `marketplace plugin entry version "${entry.version}" does not match action version "${action.version}"`
|
|
77742
|
+
});
|
|
77743
|
+
}
|
|
77744
|
+
const pluginManifestResult = await validateManifestFile(manifestPath, ["name", "version"]);
|
|
77745
|
+
if (!pluginManifestResult.valid) {
|
|
77746
|
+
return createResult({
|
|
77747
|
+
actionType,
|
|
77748
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77749
|
+
error: `frozen snapshot ${manifestRelative} invalid: ${pluginManifestResult.error}`
|
|
77750
|
+
});
|
|
77751
|
+
}
|
|
77752
|
+
if (pluginManifestResult.manifest.name !== entry.name) {
|
|
77753
|
+
return createResult({
|
|
77754
|
+
actionType,
|
|
77755
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77756
|
+
error: `plugin manifest name "${pluginManifestResult.manifest.name}" does not match marketplace entry name "${entry.name}"`
|
|
77757
|
+
});
|
|
77758
|
+
}
|
|
77759
|
+
if (pluginManifestResult.manifest.version !== action.version) {
|
|
77760
|
+
return createResult({
|
|
77761
|
+
actionType,
|
|
77762
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77763
|
+
error: `plugin manifest version "${pluginManifestResult.manifest.version}" does not match action version "${action.version}"`
|
|
77764
|
+
});
|
|
77765
|
+
}
|
|
77125
77766
|
}
|
|
77126
|
-
|
|
77127
|
-
|
|
77128
|
-
|
|
77129
|
-
|
|
77130
|
-
|
|
77131
|
-
|
|
77132
|
-
|
|
77133
|
-
|
|
77134
|
-
|
|
77767
|
+
if (consumer === "kimi") {
|
|
77768
|
+
try {
|
|
77769
|
+
await resolveKimiEntrySkillFile(snapshotDirReal, kimiSnapshotManifest, action.entrySkill);
|
|
77770
|
+
} catch (entryErr) {
|
|
77771
|
+
return createResult({
|
|
77772
|
+
actionType,
|
|
77773
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77774
|
+
error: `entry skill not resolvable in snapshot: ${entryErr.message}`
|
|
77775
|
+
});
|
|
77776
|
+
}
|
|
77777
|
+
} else {
|
|
77778
|
+
const entrySkillFile = resolve19(snapshotDirReal, "skills", action.entrySkill, "SKILL.md");
|
|
77779
|
+
try {
|
|
77780
|
+
await stat5(entrySkillFile);
|
|
77781
|
+
} catch {
|
|
77782
|
+
return createResult({
|
|
77783
|
+
actionType,
|
|
77784
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77785
|
+
error: `entry skill not found in snapshot: skills/${action.entrySkill}/SKILL.md`
|
|
77786
|
+
});
|
|
77787
|
+
}
|
|
77135
77788
|
}
|
|
77136
77789
|
try {
|
|
77137
77790
|
const { digest: actualDigest } = await computeFrozenSnapshot(snapshotDirReal);
|
|
@@ -77255,7 +77908,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77255
77908
|
});
|
|
77256
77909
|
}
|
|
77257
77910
|
}
|
|
77258
|
-
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL) {
|
|
77911
|
+
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL) {
|
|
77259
77912
|
try {
|
|
77260
77913
|
assertIsolatedConsumerWritesAuthorized(context, actionType);
|
|
77261
77914
|
const validation = validateMarketplaceParams(action);
|
|
@@ -77280,6 +77933,9 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77280
77933
|
error: "context.runDir is required for marketplace install"
|
|
77281
77934
|
});
|
|
77282
77935
|
}
|
|
77936
|
+
if (action.consumer === "kimi") {
|
|
77937
|
+
return executeKimiManualRequirement(action, context);
|
|
77938
|
+
}
|
|
77283
77939
|
const consumer = action.consumer;
|
|
77284
77940
|
const runDir = context.runDir;
|
|
77285
77941
|
const isolatedHome = resolve19(runDir, "consumers", `${consumer}-${action.plugin}`);
|
|
@@ -77317,41 +77973,43 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77317
77973
|
});
|
|
77318
77974
|
}
|
|
77319
77975
|
const ref = action.ref ?? `v${action.version}`;
|
|
77320
|
-
let addOutput;
|
|
77321
|
-
|
|
77322
|
-
|
|
77323
|
-
|
|
77324
|
-
|
|
77325
|
-
|
|
77326
|
-
|
|
77327
|
-
|
|
77328
|
-
|
|
77329
|
-
|
|
77330
|
-
|
|
77331
|
-
|
|
77332
|
-
|
|
77333
|
-
|
|
77334
|
-
|
|
77976
|
+
let addOutput = null;
|
|
77977
|
+
if (consumer !== "kimi") {
|
|
77978
|
+
const marketplaceArgs = consumer === "claude" ? ["plugin", "marketplace", "add", `${action.repo}@${ref}`] : ["plugin", "marketplace", "add", action.repo, "--ref", ref, "--json"];
|
|
77979
|
+
try {
|
|
77980
|
+
const addResult = await exec(cliCmd, marketplaceArgs, { env, cwd: context.root, timeout: frozenTimeoutMs });
|
|
77981
|
+
if (consumer === "codex") {
|
|
77982
|
+
try {
|
|
77983
|
+
addOutput = JSON.parse(addResult.stdout);
|
|
77984
|
+
if (!addOutput || typeof addOutput !== "object") {
|
|
77985
|
+
return createResult({
|
|
77986
|
+
actionType,
|
|
77987
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77988
|
+
error: "marketplace add returned invalid JSON output"
|
|
77989
|
+
});
|
|
77990
|
+
}
|
|
77991
|
+
if (addOutput.marketplaceName !== action.marketplace) {
|
|
77992
|
+
return createResult({
|
|
77993
|
+
actionType,
|
|
77994
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
77995
|
+
error: `marketplace add marketplaceName "${addOutput.marketplaceName}" does not match action marketplace "${action.marketplace}"`
|
|
77996
|
+
});
|
|
77997
|
+
}
|
|
77998
|
+
} catch {
|
|
77335
77999
|
return createResult({
|
|
77336
78000
|
actionType,
|
|
77337
78001
|
status: ActionStatus.EXECUTE_FAILED,
|
|
77338
|
-
error:
|
|
78002
|
+
error: "marketplace add returned malformed JSON"
|
|
77339
78003
|
});
|
|
77340
78004
|
}
|
|
77341
|
-
} catch {
|
|
77342
|
-
return createResult({
|
|
77343
|
-
actionType,
|
|
77344
|
-
status: ActionStatus.EXECUTE_FAILED,
|
|
77345
|
-
error: "marketplace add returned malformed JSON"
|
|
77346
|
-
});
|
|
77347
78005
|
}
|
|
78006
|
+
} catch (addErr) {
|
|
78007
|
+
return createResult({
|
|
78008
|
+
actionType,
|
|
78009
|
+
status: ActionStatus.EXECUTE_FAILED,
|
|
78010
|
+
error: `marketplace add failed: ${addErr.message}`
|
|
78011
|
+
});
|
|
77348
78012
|
}
|
|
77349
|
-
} catch (addErr) {
|
|
77350
|
-
return createResult({
|
|
77351
|
-
actionType,
|
|
77352
|
-
status: ActionStatus.EXECUTE_FAILED,
|
|
77353
|
-
error: `marketplace add failed: ${addErr.message}`
|
|
77354
|
-
});
|
|
77355
78013
|
}
|
|
77356
78014
|
let installOutput;
|
|
77357
78015
|
const installArgs = consumer === "claude" ? ["plugin", "install", `${action.plugin}@${action.marketplace}`] : ["plugin", "add", `${action.plugin}@${action.marketplace}`, "--json"];
|
|
@@ -77489,6 +78147,10 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77489
78147
|
* For Codex: uses pluginId === "plugin@marketplace" match in installed array,
|
|
77490
78148
|
* reads installedPath from add/install output or list, verifies install dir
|
|
77491
78149
|
* is inside isolated HOME, computes real manifestDigest.
|
|
78150
|
+
*
|
|
78151
|
+
* For Kimi: uses name === plugin match in installed array, reads
|
|
78152
|
+
* installedPath from validated install evidence, verifies install dir
|
|
78153
|
+
* is inside isolated HOME, computes real manifestDigest.
|
|
77492
78154
|
*/
|
|
77493
78155
|
async observe(action, context) {
|
|
77494
78156
|
const { actionType } = action;
|
|
@@ -77529,7 +78191,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77529
78191
|
}
|
|
77530
78192
|
});
|
|
77531
78193
|
}
|
|
77532
|
-
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL) {
|
|
78194
|
+
if (actionType === ActionType.CLAUDE_MARKETPLACE_INSTALL || actionType === ActionType.CODEX_MARKETPLACE_INSTALL || actionType === ActionType.KIMI_MARKETPLACE_INSTALL) {
|
|
77533
78195
|
const consumer = action.consumer;
|
|
77534
78196
|
const runDir = context.runDir;
|
|
77535
78197
|
if (!runDir) {
|
|
@@ -77540,11 +78202,11 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77540
78202
|
});
|
|
77541
78203
|
}
|
|
77542
78204
|
const isolatedHome = resolve19(runDir, "consumers", `${consumer}-${action.plugin}`);
|
|
77543
|
-
const cliCmd = consumer === "claude" ? "claude" : "codex";
|
|
78205
|
+
const cliCmd = consumer === "claude" ? "claude" : consumer === "codex" ? "codex" : "kimi";
|
|
77544
78206
|
const baseEnv = { ...process.env, ...context.env ?? {} };
|
|
77545
78207
|
const env = {
|
|
77546
78208
|
...baseEnv,
|
|
77547
|
-
...consumer === "claude" ? { HOME: isolatedHome, CLAUDE_CONFIG_DIR: resolve19(isolatedHome, ".claude") } : { HOME: isolatedHome, CODEX_HOME: isolatedHome }
|
|
78209
|
+
...consumer === "claude" ? { HOME: isolatedHome, CLAUDE_CONFIG_DIR: resolve19(isolatedHome, ".claude") } : consumer === "codex" ? { HOME: isolatedHome, CODEX_HOME: isolatedHome } : { HOME: isolatedHome, KIMI_CODE_HOME: isolatedHome }
|
|
77548
78210
|
};
|
|
77549
78211
|
let frozenTimeoutMs;
|
|
77550
78212
|
try {
|
|
@@ -77557,6 +78219,236 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77557
78219
|
error: timeoutErr.message
|
|
77558
78220
|
});
|
|
77559
78221
|
}
|
|
78222
|
+
if (consumer === "kimi") {
|
|
78223
|
+
const expectedRef = action.ref ?? `v${action.version}`;
|
|
78224
|
+
let boundPlanDigest;
|
|
78225
|
+
try {
|
|
78226
|
+
boundPlanDigest = resolveBoundPlanDigest(context);
|
|
78227
|
+
} catch (planErr) {
|
|
78228
|
+
return createResult({
|
|
78229
|
+
actionType,
|
|
78230
|
+
status: ActionStatus.OBSERVED,
|
|
78231
|
+
observation: {
|
|
78232
|
+
installed: false,
|
|
78233
|
+
error: `cannot bind kimi observation to the frozen plan: ${planErr.message}`
|
|
78234
|
+
}
|
|
78235
|
+
});
|
|
78236
|
+
}
|
|
78237
|
+
let attestationDir;
|
|
78238
|
+
try {
|
|
78239
|
+
attestationDir = kimiAuthorityDir(context, boundPlanDigest, action.plugin);
|
|
78240
|
+
} catch (dirErr) {
|
|
78241
|
+
return createResult({
|
|
78242
|
+
actionType,
|
|
78243
|
+
status: ActionStatus.OBSERVED,
|
|
78244
|
+
observation: { installed: false, error: dirErr.message }
|
|
78245
|
+
});
|
|
78246
|
+
}
|
|
78247
|
+
let requirement = null;
|
|
78248
|
+
try {
|
|
78249
|
+
requirement = JSON.parse(await readFile17(resolve19(attestationDir, KIMI_REQUIREMENT_FILE), "utf8"));
|
|
78250
|
+
} catch {
|
|
78251
|
+
return createResult({
|
|
78252
|
+
actionType,
|
|
78253
|
+
status: ActionStatus.OBSERVED,
|
|
78254
|
+
observation: {
|
|
78255
|
+
installed: false,
|
|
78256
|
+
manualInstallRequired: true,
|
|
78257
|
+
error: "kimi manual-install requirement is missing; run execute first"
|
|
78258
|
+
}
|
|
78259
|
+
});
|
|
78260
|
+
}
|
|
78261
|
+
if (requirement.planDigest !== boundPlanDigest || requirement.plugin !== action.plugin || requirement.version !== action.version || requirement.entrySkill !== action.entrySkill || requirement.repo !== action.repo || requirement.ref !== expectedRef) {
|
|
78262
|
+
return createResult({
|
|
78263
|
+
actionType,
|
|
78264
|
+
status: ActionStatus.OBSERVED,
|
|
78265
|
+
observation: {
|
|
78266
|
+
installed: false,
|
|
78267
|
+
error: "kimi manual-install requirement does not match the frozen plan/action"
|
|
78268
|
+
}
|
|
78269
|
+
});
|
|
78270
|
+
}
|
|
78271
|
+
let attestation = null;
|
|
78272
|
+
try {
|
|
78273
|
+
attestation = JSON.parse(await readFile17(resolve19(attestationDir, KIMI_ATTESTATION_FILE), "utf8"));
|
|
78274
|
+
} catch {
|
|
78275
|
+
return createResult({
|
|
78276
|
+
actionType,
|
|
78277
|
+
status: ActionStatus.OBSERVED,
|
|
78278
|
+
observation: {
|
|
78279
|
+
installed: false,
|
|
78280
|
+
manualInstallRequired: true,
|
|
78281
|
+
installUrl: requirement.installUrl,
|
|
78282
|
+
attestationDir,
|
|
78283
|
+
error: `kimi attestation is missing; write ${resolve19(attestationDir, KIMI_ATTESTATION_FILE)} after the interactive install (${requirement.installUrl})`
|
|
78284
|
+
}
|
|
78285
|
+
});
|
|
78286
|
+
}
|
|
78287
|
+
const attestationCheck = validateKimiAttestation(attestation, action, (/* @__PURE__ */ new Date()).toISOString(), boundPlanDigest);
|
|
78288
|
+
if (!attestationCheck.valid) {
|
|
78289
|
+
return createResult({
|
|
78290
|
+
actionType,
|
|
78291
|
+
status: ActionStatus.OBSERVED,
|
|
78292
|
+
observation: { installed: false, error: attestationCheck.error }
|
|
78293
|
+
});
|
|
78294
|
+
}
|
|
78295
|
+
const kimiCodeHome = resolve19(attestationDir, "kimi-home");
|
|
78296
|
+
const kimiCodeHomeReal = await realpath11(kimiCodeHome).catch(() => null);
|
|
78297
|
+
if (!kimiCodeHomeReal) {
|
|
78298
|
+
return createResult({
|
|
78299
|
+
actionType,
|
|
78300
|
+
status: ActionStatus.OBSERVED,
|
|
78301
|
+
observation: {
|
|
78302
|
+
installed: false,
|
|
78303
|
+
error: `KIMI_CODE_HOME does not exist or cannot be resolved: ${kimiCodeHome}`
|
|
78304
|
+
}
|
|
78305
|
+
});
|
|
78306
|
+
}
|
|
78307
|
+
const managedRootReal = await realpath11(resolve19(kimiCodeHomeReal, KIMI_MANAGED_SUBPATH, action.plugin)).catch(() => null);
|
|
78308
|
+
if (!managedRootReal) {
|
|
78309
|
+
return createResult({
|
|
78310
|
+
actionType,
|
|
78311
|
+
status: ActionStatus.OBSERVED,
|
|
78312
|
+
observation: {
|
|
78313
|
+
installed: false,
|
|
78314
|
+
error: `kimi managed plugin root does not exist: ${resolve19(kimiCodeHomeReal, KIMI_MANAGED_SUBPATH, action.plugin)}`
|
|
78315
|
+
}
|
|
78316
|
+
});
|
|
78317
|
+
}
|
|
78318
|
+
const installPath2 = resolve19(attestation.installPath);
|
|
78319
|
+
let installPathStat;
|
|
78320
|
+
try {
|
|
78321
|
+
installPathStat = await lstat11(installPath2);
|
|
78322
|
+
} catch {
|
|
78323
|
+
return createResult({
|
|
78324
|
+
actionType,
|
|
78325
|
+
status: ActionStatus.OBSERVED,
|
|
78326
|
+
observation: { installed: false, error: `kimi install path does not exist: ${attestation.installPath}` }
|
|
78327
|
+
});
|
|
78328
|
+
}
|
|
78329
|
+
if (installPathStat.isSymbolicLink()) {
|
|
78330
|
+
return createResult({
|
|
78331
|
+
actionType,
|
|
78332
|
+
status: ActionStatus.OBSERVED,
|
|
78333
|
+
observation: { installed: false, error: `kimi install path must not be a symlink: ${attestation.installPath}` }
|
|
78334
|
+
});
|
|
78335
|
+
}
|
|
78336
|
+
if (!installPathStat.isDirectory()) {
|
|
78337
|
+
return createResult({
|
|
78338
|
+
actionType,
|
|
78339
|
+
status: ActionStatus.OBSERVED,
|
|
78340
|
+
observation: { installed: false, error: `kimi install path must be a directory: ${attestation.installPath}` }
|
|
78341
|
+
});
|
|
78342
|
+
}
|
|
78343
|
+
const installPathReal2 = await realpath11(installPath2).catch(() => null);
|
|
78344
|
+
if (!installPathReal2) {
|
|
78345
|
+
return createResult({
|
|
78346
|
+
actionType,
|
|
78347
|
+
status: ActionStatus.OBSERVED,
|
|
78348
|
+
observation: { installed: false, error: `kimi install path cannot be resolved: ${attestation.installPath}` }
|
|
78349
|
+
});
|
|
78350
|
+
}
|
|
78351
|
+
const sepK = process.platform === "win32" ? "\\" : "/";
|
|
78352
|
+
const relToManaged = relative16(managedRootReal, installPathReal2);
|
|
78353
|
+
if (relToManaged !== "" && (isAbsolute13(relToManaged) || relToManaged === ".." || relToManaged.startsWith(`..${sepK}`))) {
|
|
78354
|
+
return createResult({
|
|
78355
|
+
actionType,
|
|
78356
|
+
status: ActionStatus.OBSERVED,
|
|
78357
|
+
observation: {
|
|
78358
|
+
installed: false,
|
|
78359
|
+
error: `kimi install path escapes the managed root (${managedRootReal}): ${attestation.installPath}`
|
|
78360
|
+
}
|
|
78361
|
+
});
|
|
78362
|
+
}
|
|
78363
|
+
let manifestDigest2;
|
|
78364
|
+
try {
|
|
78365
|
+
manifestDigest2 = await verifyInstalledMarketplacePayload(action, context, installPathReal2, consumer);
|
|
78366
|
+
} catch (digestErr) {
|
|
78367
|
+
return createResult({
|
|
78368
|
+
actionType,
|
|
78369
|
+
status: ActionStatus.OBSERVED,
|
|
78370
|
+
observation: {
|
|
78371
|
+
installed: true,
|
|
78372
|
+
installPath: installPathReal2,
|
|
78373
|
+
error: `failed to bind installed kimi payload to frozen authority: ${digestErr.message}`
|
|
78374
|
+
}
|
|
78375
|
+
});
|
|
78376
|
+
}
|
|
78377
|
+
if (manifestDigest2 !== action.manifestDigest) {
|
|
78378
|
+
return createResult({
|
|
78379
|
+
actionType,
|
|
78380
|
+
status: ActionStatus.OBSERVED,
|
|
78381
|
+
observation: {
|
|
78382
|
+
installed: true,
|
|
78383
|
+
installPath: installPathReal2,
|
|
78384
|
+
error: "installed kimi payload digest does not match the frozen plan digest"
|
|
78385
|
+
}
|
|
78386
|
+
});
|
|
78387
|
+
}
|
|
78388
|
+
let installedManifest;
|
|
78389
|
+
let entrySkillFound2 = false;
|
|
78390
|
+
try {
|
|
78391
|
+
const readManifest = await readKimiManifest(installPathReal2);
|
|
78392
|
+
installedManifest = readManifest.manifest;
|
|
78393
|
+
await resolveKimiEntrySkillFile(installPathReal2, installedManifest, action.entrySkill);
|
|
78394
|
+
entrySkillFound2 = true;
|
|
78395
|
+
} catch (entryErr) {
|
|
78396
|
+
return createResult({
|
|
78397
|
+
actionType,
|
|
78398
|
+
status: ActionStatus.OBSERVED,
|
|
78399
|
+
observation: {
|
|
78400
|
+
installed: true,
|
|
78401
|
+
installPath: installPathReal2,
|
|
78402
|
+
manifestDigest: manifestDigest2,
|
|
78403
|
+
entrySkillFound: false,
|
|
78404
|
+
error: `kimi entry skill not resolvable in installed copy: ${entryErr.message}`
|
|
78405
|
+
}
|
|
78406
|
+
});
|
|
78407
|
+
}
|
|
78408
|
+
if (installedManifest.name !== action.plugin) {
|
|
78409
|
+
return createResult({
|
|
78410
|
+
actionType,
|
|
78411
|
+
status: ActionStatus.OBSERVED,
|
|
78412
|
+
observation: {
|
|
78413
|
+
installed: true,
|
|
78414
|
+
installPath: installPathReal2,
|
|
78415
|
+
manifestDigest: manifestDigest2,
|
|
78416
|
+
entrySkillFound: true,
|
|
78417
|
+
error: `installed kimi manifest name "${installedManifest.name}" does not match action plugin "${action.plugin}"`
|
|
78418
|
+
}
|
|
78419
|
+
});
|
|
78420
|
+
}
|
|
78421
|
+
if (installedManifest.version !== action.version) {
|
|
78422
|
+
return createResult({
|
|
78423
|
+
actionType,
|
|
78424
|
+
status: ActionStatus.OBSERVED,
|
|
78425
|
+
observation: {
|
|
78426
|
+
installed: true,
|
|
78427
|
+
installPath: installPathReal2,
|
|
78428
|
+
manifestDigest: manifestDigest2,
|
|
78429
|
+
entrySkillFound: true,
|
|
78430
|
+
error: `installed kimi manifest version "${installedManifest.version}" does not match action version "${action.version}"`
|
|
78431
|
+
}
|
|
78432
|
+
});
|
|
78433
|
+
}
|
|
78434
|
+
const observation2 = {
|
|
78435
|
+
installed: true,
|
|
78436
|
+
installPath: installPathReal2,
|
|
78437
|
+
entrySkillFound: true,
|
|
78438
|
+
entrySkill: action.entrySkill,
|
|
78439
|
+
manifestDigest: manifestDigest2,
|
|
78440
|
+
consumer,
|
|
78441
|
+
plugin: installedManifest.name,
|
|
78442
|
+
version: installedManifest.version,
|
|
78443
|
+
repo: action.repo,
|
|
78444
|
+
ref: expectedRef
|
|
78445
|
+
};
|
|
78446
|
+
return createResult({
|
|
78447
|
+
actionType,
|
|
78448
|
+
status: ActionStatus.OBSERVED,
|
|
78449
|
+
observation: observation2
|
|
78450
|
+
});
|
|
78451
|
+
}
|
|
77560
78452
|
let evidence = null;
|
|
77561
78453
|
try {
|
|
77562
78454
|
const evidenceRaw = await readFile17(resolve19(runDir, "evidence", `${consumer}-${action.plugin}`, "release-skill-install-evidence.json"), "utf8");
|
|
@@ -77581,7 +78473,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77581
78473
|
}
|
|
77582
78474
|
});
|
|
77583
78475
|
}
|
|
77584
|
-
const listArgs =
|
|
78476
|
+
const listArgs = ["plugin", "list", "--json"];
|
|
77585
78477
|
let listOutput;
|
|
77586
78478
|
try {
|
|
77587
78479
|
const result = await exec(cliCmd, listArgs, { env, cwd: context.root, timeout: frozenTimeoutMs });
|
|
@@ -77632,7 +78524,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77632
78524
|
});
|
|
77633
78525
|
}
|
|
77634
78526
|
installPath = found.installPath;
|
|
77635
|
-
} else {
|
|
78527
|
+
} else if (consumer === "codex") {
|
|
77636
78528
|
installPath = evidence.installOutput?.installedPath;
|
|
77637
78529
|
if (!installPath) {
|
|
77638
78530
|
return createResult({
|
|
@@ -77735,7 +78627,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77735
78627
|
} catch (digestErr) {
|
|
77736
78628
|
try {
|
|
77737
78629
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
77738
|
-
excludeRootEntries: consumer
|
|
78630
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
77739
78631
|
});
|
|
77740
78632
|
manifestDigest = installedSnapshot.digest;
|
|
77741
78633
|
} catch {
|
|
@@ -77756,7 +78648,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77756
78648
|
observation.plugin = idParts[0];
|
|
77757
78649
|
observation.marketplace = idParts.slice(1).join("@");
|
|
77758
78650
|
if (found.version) observation.version = found.version;
|
|
77759
|
-
} else {
|
|
78651
|
+
} else if (consumer === "codex") {
|
|
77760
78652
|
if (found.name) observation.plugin = found.name;
|
|
77761
78653
|
if (found.marketplaceName) observation.marketplace = found.marketplaceName;
|
|
77762
78654
|
if (found.version) observation.version = found.version;
|
|
@@ -77891,21 +78783,42 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77891
78783
|
}
|
|
77892
78784
|
});
|
|
77893
78785
|
}
|
|
77894
|
-
var execFile9, NAME4, SUPPORTED_TYPES, SAFE_ID_RE, SAFE_REPO_RE, STRICT_SEMVER_RE;
|
|
78786
|
+
var execFile9, NAME4, KIMI_REQUIREMENT_FILE, KIMI_ATTESTATION_FILE, KIMI_MANAGED_SUBPATH, KIMI_MAX_ATTESTATION_VALIDITY_MS, HEX_DIGEST_RE, SUPPORTED_TYPES, SAFE_ID_RE, SAFE_REPO_RE, STRICT_SEMVER_RE;
|
|
77895
78787
|
var init_plugin_marketplace = __esm({
|
|
77896
|
-
"src/adapters/plugin-marketplace.mjs"() {
|
|
78788
|
+
async "src/adapters/plugin-marketplace.mjs"() {
|
|
77897
78789
|
init_contract2();
|
|
77898
78790
|
init_frozen();
|
|
78791
|
+
await init_plan();
|
|
78792
|
+
init_digest();
|
|
77899
78793
|
execFile9 = promisify10(execFileCb10);
|
|
77900
78794
|
NAME4 = "plugin-marketplace";
|
|
77901
78795
|
__name(transportPayload, "transportPayload");
|
|
78796
|
+
__name(consumerTransportExclusions, "consumerTransportExclusions");
|
|
78797
|
+
__name(extractDeclaredPluginSource, "extractDeclaredPluginSource");
|
|
78798
|
+
__name(resolveInstalledPayloadSubpath, "resolveInstalledPayloadSubpath");
|
|
77902
78799
|
__name(verifyInstalledMarketplacePayload, "verifyInstalledMarketplacePayload");
|
|
77903
78800
|
__name(writeEvidenceAtomic, "writeEvidenceAtomic");
|
|
78801
|
+
KIMI_REQUIREMENT_FILE = "release-skill-kimi-manual-install.json";
|
|
78802
|
+
KIMI_ATTESTATION_FILE = "release-skill-kimi-attestation.json";
|
|
78803
|
+
KIMI_MANAGED_SUBPATH = join12("plugins", "managed");
|
|
78804
|
+
KIMI_MAX_ATTESTATION_VALIDITY_MS = 24 * 60 * 60 * 1e3;
|
|
78805
|
+
HEX_DIGEST_RE = /^[a-f0-9]{64}$/;
|
|
78806
|
+
__name(normalizePlanForDigest, "normalizePlanForDigest");
|
|
78807
|
+
__name(resolveBoundPlanDigest, "resolveBoundPlanDigest");
|
|
78808
|
+
__name(kimiAuthorityDir, "kimiAuthorityDir");
|
|
78809
|
+
__name(buildKimiInstallUrl, "buildKimiInstallUrl");
|
|
78810
|
+
__name(buildKimiManualInstructions, "buildKimiManualInstructions");
|
|
78811
|
+
__name(readKimiManifest, "readKimiManifest");
|
|
78812
|
+
__name(normalizeKimiSkillsRel, "normalizeKimiSkillsRel");
|
|
78813
|
+
__name(resolveKimiEntrySkillFile, "resolveKimiEntrySkillFile");
|
|
78814
|
+
__name(validateKimiAttestation, "validateKimiAttestation");
|
|
78815
|
+
__name(executeKimiManualRequirement, "executeKimiManualRequirement");
|
|
77904
78816
|
SUPPORTED_TYPES = [
|
|
77905
78817
|
ActionType.PLUGIN_MANIFEST_VALIDATE,
|
|
77906
78818
|
ActionType.PLUGIN_INSTALL_CHECK,
|
|
77907
78819
|
ActionType.CLAUDE_MARKETPLACE_INSTALL,
|
|
77908
|
-
ActionType.CODEX_MARKETPLACE_INSTALL
|
|
78820
|
+
ActionType.CODEX_MARKETPLACE_INSTALL,
|
|
78821
|
+
ActionType.KIMI_MARKETPLACE_INSTALL
|
|
77909
78822
|
];
|
|
77910
78823
|
SAFE_ID_RE = /^[a-z0-9][a-z0-9._-]*$/;
|
|
77911
78824
|
SAFE_REPO_RE = /^[a-zA-Z0-9][a-zA-Z0-9._-]*\/[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
|
|
@@ -78364,7 +79277,8 @@ async function verifyRelease(options) {
|
|
|
78364
79277
|
const actions = plan.externalActions ?? [];
|
|
78365
79278
|
const MARKETPLACE_TYPES3 = /* @__PURE__ */ new Set([
|
|
78366
79279
|
"claude-marketplace-install",
|
|
78367
|
-
"codex-marketplace-install"
|
|
79280
|
+
"codex-marketplace-install",
|
|
79281
|
+
"kimi-marketplace-install"
|
|
78368
79282
|
]);
|
|
78369
79283
|
for (const action of actions) {
|
|
78370
79284
|
const adapterActionType = ADAPTER_ACTION_TYPE_MAP2[action.type];
|
|
@@ -78453,7 +79367,7 @@ async function verifyRelease(options) {
|
|
|
78453
79367
|
{ actionId: action.id, observation: verifyResult.observation }
|
|
78454
79368
|
);
|
|
78455
79369
|
}
|
|
78456
|
-
const distribution = action.type === "claude-marketplace-install" ? "claude-plugin" : "codex-plugin";
|
|
79370
|
+
const distribution = action.type === "claude-marketplace-install" ? "claude-plugin" : action.type === "codex-marketplace-install" ? "codex-plugin" : "kimi-plugin";
|
|
78457
79371
|
const installPath = verifyResult.observation?.installPath;
|
|
78458
79372
|
consumerGateResults.push(...await runConsumerVerificationGates({
|
|
78459
79373
|
plan,
|
|
@@ -78465,9 +79379,12 @@ async function verifyRelease(options) {
|
|
|
78465
79379
|
fixedEnv: action.type === "claude-marketplace-install" ? {
|
|
78466
79380
|
HOME: resolve20(runDir, "consumers", `claude-${action.parameters.plugin}`),
|
|
78467
79381
|
CLAUDE_CONFIG_DIR: resolve20(runDir, "consumers", `claude-${action.parameters.plugin}`, ".claude")
|
|
78468
|
-
} : {
|
|
79382
|
+
} : action.type === "codex-marketplace-install" ? {
|
|
78469
79383
|
HOME: resolve20(runDir, "consumers", `codex-${action.parameters.plugin}`),
|
|
78470
79384
|
CODEX_HOME: resolve20(runDir, "consumers", `codex-${action.parameters.plugin}`)
|
|
79385
|
+
} : {
|
|
79386
|
+
HOME: resolve20(runDir, "consumers", `kimi-${action.parameters.plugin}`),
|
|
79387
|
+
KIMI_CODE_HOME: resolve20(runDir, "consumers", `kimi-${action.parameters.plugin}`)
|
|
78471
79388
|
}
|
|
78472
79389
|
}));
|
|
78473
79390
|
} else {
|
|
@@ -78628,7 +79545,8 @@ var init_verify = __esm({
|
|
|
78628
79545
|
"npm-publish": "npm-publish",
|
|
78629
79546
|
"github-release": "github-release",
|
|
78630
79547
|
"claude-marketplace-install": "claude-marketplace-install",
|
|
78631
|
-
"codex-marketplace-install": "codex-marketplace-install"
|
|
79548
|
+
"codex-marketplace-install": "codex-marketplace-install",
|
|
79549
|
+
"kimi-marketplace-install": "kimi-marketplace-install"
|
|
78632
79550
|
};
|
|
78633
79551
|
__name(defaultClock3, "defaultClock");
|
|
78634
79552
|
__name(matchesSubset2, "matchesSubset");
|
|
@@ -79345,7 +80263,8 @@ var init_publish = __esm({
|
|
|
79345
80263
|
"npm-publish",
|
|
79346
80264
|
"github-release",
|
|
79347
80265
|
"claude-marketplace-install",
|
|
79348
|
-
"codex-marketplace-install"
|
|
80266
|
+
"codex-marketplace-install",
|
|
80267
|
+
"kimi-marketplace-install"
|
|
79349
80268
|
];
|
|
79350
80269
|
ADAPTER_ACTION_TYPE_MAP3 = {
|
|
79351
80270
|
"push-commit": "git-push",
|
|
@@ -79355,11 +80274,13 @@ var init_publish = __esm({
|
|
|
79355
80274
|
"npm-publish": "npm-publish",
|
|
79356
80275
|
"github-release": "github-release",
|
|
79357
80276
|
"claude-marketplace-install": "claude-marketplace-install",
|
|
79358
|
-
"codex-marketplace-install": "codex-marketplace-install"
|
|
80277
|
+
"codex-marketplace-install": "codex-marketplace-install",
|
|
80278
|
+
"kimi-marketplace-install": "kimi-marketplace-install"
|
|
79359
80279
|
};
|
|
79360
80280
|
MARKETPLACE_TYPES2 = /* @__PURE__ */ new Set([
|
|
79361
80281
|
"claude-marketplace-install",
|
|
79362
|
-
"codex-marketplace-install"
|
|
80282
|
+
"codex-marketplace-install",
|
|
80283
|
+
"kimi-marketplace-install"
|
|
79363
80284
|
]);
|
|
79364
80285
|
__name(defaultClock4, "defaultClock");
|
|
79365
80286
|
__name(deepClone, "deepClone");
|
|
@@ -82756,6 +83677,12 @@ async function performEnvironmentChecks() {
|
|
|
82756
83677
|
required: false,
|
|
82757
83678
|
usage: "\u4EC5\u5F53\u8BA1\u5212\u58F0\u660E codex-plugin distribution \u65F6\u7528\u4E8E\u6D88\u8D39\u8005\u5B89\u88C5\u9A8C\u8BC1"
|
|
82758
83679
|
};
|
|
83680
|
+
const kimiCheck = await checkDependency("kimi", ["--version"]);
|
|
83681
|
+
checks.kimi = {
|
|
83682
|
+
...kimiCheck,
|
|
83683
|
+
required: false,
|
|
83684
|
+
usage: "\u4EC5\u5F53\u8BA1\u5212\u58F0\u660E kimi-plugin distribution \u65F6\u7528\u4E8E\u6D88\u8D39\u8005\u5B89\u88C5\u9A8C\u8BC1"
|
|
83685
|
+
};
|
|
82759
83686
|
return checks;
|
|
82760
83687
|
}
|
|
82761
83688
|
__name(performEnvironmentChecks, "performEnvironmentChecks");
|
|
@@ -82784,7 +83711,7 @@ function getCapabilityMaturity() {
|
|
|
82784
83711
|
publish: {
|
|
82785
83712
|
available: true,
|
|
82786
83713
|
mode: "controlled production (protocol-tested; no OS/network sandbox)",
|
|
82787
|
-
description: "Publishes frozen GitHub/npm artifacts and runs configured Claude/Codex consumer checkpoints with approval and exact digest confirmation"
|
|
83714
|
+
description: "Publishes frozen GitHub/npm artifacts and runs configured Claude/Codex/Kimi consumer checkpoints with approval and exact digest confirmation"
|
|
82788
83715
|
},
|
|
82789
83716
|
reconcile: {
|
|
82790
83717
|
available: true,
|
|
@@ -82794,7 +83721,7 @@ function getCapabilityMaturity() {
|
|
|
82794
83721
|
verify: {
|
|
82795
83722
|
available: true,
|
|
82796
83723
|
mode: "fresh consumer verification (protocol-tested; no OS/network sandbox)",
|
|
82797
|
-
description: "Recheck remote state, exact npm installation, CLI help, and configured Claude/Codex installs before VERIFIED"
|
|
83724
|
+
description: "Recheck remote state, exact npm installation, CLI help, and configured Claude/Codex/Kimi installs before VERIFIED"
|
|
82798
83725
|
}
|
|
82799
83726
|
};
|
|
82800
83727
|
}
|
|
@@ -82917,7 +83844,8 @@ if (!command || command === "help") {
|
|
|
82917
83844
|
authentication: "\u8FD0\u884C\u751F\u4EA7\u53D1\u5E03\u524D\u8FD8\u9700\u9A8C\u8BC1 gh auth\u3001Git HTTPS credential \u4E0E npm auth\uFF1Bhelp \u4E0D\u53D1\u8D77\u7F51\u7EDC\u8BA4\u8BC1\u68C0\u67E5\u3002",
|
|
82918
83845
|
conditionalConsumers: {
|
|
82919
83846
|
claude: "\u58F0\u660E claude-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528",
|
|
82920
|
-
codex: "\u58F0\u660E codex-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528"
|
|
83847
|
+
codex: "\u58F0\u660E codex-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528",
|
|
83848
|
+
kimi: "\u58F0\u660E kimi-plugin distribution \u65F6\u5FC5\u987B\u53EF\u7528"
|
|
82921
83849
|
}
|
|
82922
83850
|
}
|
|
82923
83851
|
},
|
|
@@ -82929,9 +83857,9 @@ if (!command || command === "help") {
|
|
|
82929
83857
|
prepare: "offline local writes; configured hooks/gates require their explicit side-effect acknowledgements",
|
|
82930
83858
|
docs: "read-only dry-run by default; write requires --write, exact --confirm-refresh, and --ack-local-document-write; never commits, pushes, or publishes",
|
|
82931
83859
|
onlinePrepare: "previous-public-baseline observation available; production mode freezes publish artifacts and fails closed on drift or unknown state",
|
|
82932
|
-
publish: "GitHub/npm plus configured Claude/Codex consumer checkpoints are protocol-tested without an OS/network sandbox; approval and exact digest confirmation required",
|
|
83860
|
+
publish: "GitHub/npm plus configured Claude/Codex/Kimi consumer checkpoints are protocol-tested without an OS/network sandbox; approval and exact digest confirmation required",
|
|
82933
83861
|
reconcile: "PARTIAL recovery is protocol-tested without an OS/network sandbox; remote conflicts require human intervention",
|
|
82934
|
-
verify: "fresh exact npm and Claude/Codex consumer installation checks are protocol-tested without an OS/network sandbox; configured consumer processes require explicit acknowledgement; success reaches VERIFIED"
|
|
83862
|
+
verify: "fresh exact npm and Claude/Codex/Kimi consumer installation checks are protocol-tested without an OS/network sandbox; configured consumer processes require explicit acknowledgement; success reaches VERIFIED"
|
|
82935
83863
|
},
|
|
82936
83864
|
recommendations: []
|
|
82937
83865
|
};
|
|
@@ -82958,6 +83886,9 @@ if (!command || command === "help") {
|
|
|
82958
83886
|
if (!checks.codex.available) {
|
|
82959
83887
|
output.recommendations.push("Install Codex CLI before releasing a configured codex-plugin distribution");
|
|
82960
83888
|
}
|
|
83889
|
+
if (!checks.kimi.available) {
|
|
83890
|
+
output.recommendations.push("Install Kimi Code CLI before releasing a configured kimi-plugin distribution");
|
|
83891
|
+
}
|
|
82961
83892
|
console.log(JSON.stringify(output, null, 2));
|
|
82962
83893
|
process.exit(readiness.status === "READY" ? 0 : 1);
|
|
82963
83894
|
} else {
|
|
@@ -83180,7 +84111,7 @@ if (command === "reconcile") {
|
|
|
83180
84111
|
const { reconcileRelease: reconcileRelease2 } = await init_reconcile().then(() => reconcile_exports);
|
|
83181
84112
|
const { createGitGithubAdapter: createGitGithubAdapter2 } = await Promise.resolve().then(() => (init_git_github(), git_github_exports));
|
|
83182
84113
|
const { createNpmAdapter: createNpmAdapter2 } = await Promise.resolve().then(() => (init_npm(), npm_exports));
|
|
83183
|
-
const { createPluginMarketplaceAdapter: createPluginMarketplaceAdapter2 } = await
|
|
84114
|
+
const { createPluginMarketplaceAdapter: createPluginMarketplaceAdapter2 } = await init_plugin_marketplace().then(() => plugin_marketplace_exports);
|
|
83184
84115
|
const { createPushSnapshotAdapter: createPushSnapshotAdapter2 } = await Promise.resolve().then(() => (init_push_snapshot(), push_snapshot_exports));
|
|
83185
84116
|
const { createAdapterRegistry: createAdapterRegistry2 } = await Promise.resolve().then(() => (init_contract2(), contract_exports));
|
|
83186
84117
|
const registry = createAdapterRegistry2([
|
|
@@ -83242,7 +84173,7 @@ if (command === "verify") {
|
|
|
83242
84173
|
const { verifyRelease: verifyRelease2 } = await init_verify().then(() => verify_exports);
|
|
83243
84174
|
const { createGitGithubAdapter: createGitGithubAdapter2 } = await Promise.resolve().then(() => (init_git_github(), git_github_exports));
|
|
83244
84175
|
const { createNpmAdapter: createNpmAdapter2 } = await Promise.resolve().then(() => (init_npm(), npm_exports));
|
|
83245
|
-
const { createPluginMarketplaceAdapter: createPluginMarketplaceAdapter2 } = await
|
|
84176
|
+
const { createPluginMarketplaceAdapter: createPluginMarketplaceAdapter2 } = await init_plugin_marketplace().then(() => plugin_marketplace_exports);
|
|
83246
84177
|
const { createPushSnapshotAdapter: createPushSnapshotAdapter2 } = await Promise.resolve().then(() => (init_push_snapshot(), push_snapshot_exports));
|
|
83247
84178
|
const { createAdapterRegistry: createAdapterRegistry2 } = await Promise.resolve().then(() => (init_contract2(), contract_exports));
|
|
83248
84179
|
const registry = createAdapterRegistry2([
|
|
@@ -83303,7 +84234,7 @@ if (command === "publish") {
|
|
|
83303
84234
|
const { publishRelease: publishRelease2 } = await init_publish().then(() => publish_exports);
|
|
83304
84235
|
const { createGitGithubAdapter: createGitGithubAdapter2 } = await Promise.resolve().then(() => (init_git_github(), git_github_exports));
|
|
83305
84236
|
const { createNpmAdapter: createNpmAdapter2 } = await Promise.resolve().then(() => (init_npm(), npm_exports));
|
|
83306
|
-
const { createPluginMarketplaceAdapter: createPluginMarketplaceAdapter2 } = await
|
|
84237
|
+
const { createPluginMarketplaceAdapter: createPluginMarketplaceAdapter2 } = await init_plugin_marketplace().then(() => plugin_marketplace_exports);
|
|
83307
84238
|
const { createPushSnapshotAdapter: createPushSnapshotAdapter2 } = await Promise.resolve().then(() => (init_push_snapshot(), push_snapshot_exports));
|
|
83308
84239
|
const { createAdapterRegistry: createAdapterRegistry2 } = await Promise.resolve().then(() => (init_contract2(), contract_exports));
|
|
83309
84240
|
const registry = createAdapterRegistry2([
|