release-skill 0.1.8 → 0.1.10
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 +1 -1
- package/CHANGELOG.md +68 -0
- package/INSTALL.md +4 -4
- package/INSTALL.zh-CN.md +4 -4
- package/README.md +34 -22
- package/README.zh-CN.md +26 -18
- 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 +87 -17
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +87 -17
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +87 -17
- package/bin/release-skill.bundle.mjs +87 -17
- package/package.json +1 -1
- package/src/adapters/plugin-marketplace.mjs +127 -21
- package/src/core/baseline.mjs +11 -0
- package/src/snapshot/frozen.mjs +30 -5
|
@@ -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.10"});
|
|
13
13
|
|
|
14
14
|
var __create = Object.create;
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -17816,7 +17816,8 @@ var init_baseline = __esm({
|
|
|
17816
17816
|
".release-skill/lock",
|
|
17817
17817
|
".release-skill/lock-audit",
|
|
17818
17818
|
".release-skill/runs",
|
|
17819
|
-
".release-skill/transactions"
|
|
17819
|
+
".release-skill/transactions",
|
|
17820
|
+
".release-skill/kimi-attestations"
|
|
17820
17821
|
];
|
|
17821
17822
|
RESERVED_CONTROL_PREFIXES = [
|
|
17822
17823
|
...CONTROL_PLANE_PREFIXES,
|
|
@@ -19013,14 +19014,30 @@ async function computeFrozenSnapshot(snapshotDir, { excludeRootEntries = [] } =
|
|
|
19013
19014
|
throw frozenError("frozen snapshot root must be a real directory");
|
|
19014
19015
|
}
|
|
19015
19016
|
const entries = [];
|
|
19016
|
-
const
|
|
19017
|
+
const excludedRootNames = /* @__PURE__ */ new Set();
|
|
19018
|
+
const excludedPathPrefixes = [];
|
|
19019
|
+
for (const entry of excludeRootEntries) {
|
|
19020
|
+
if (typeof entry !== "string") {
|
|
19021
|
+
throw frozenError("frozen snapshot exclusion entries must be strings");
|
|
19022
|
+
}
|
|
19023
|
+
const segments = entry.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
19024
|
+
if (segments.length === 0 || entry.startsWith("/") || entry.includes("\\") || segments.some((segment) => segment === "..")) {
|
|
19025
|
+
throw frozenError(`frozen snapshot exclusion entry is not a safe relative path: ${JSON.stringify(entry)}`);
|
|
19026
|
+
}
|
|
19027
|
+
if (segments.length === 1) {
|
|
19028
|
+
excludedRootNames.add(segments[0]);
|
|
19029
|
+
} else {
|
|
19030
|
+
excludedPathPrefixes.push(segments.join("/"));
|
|
19031
|
+
}
|
|
19032
|
+
}
|
|
19017
19033
|
async function walk(dir) {
|
|
19018
19034
|
const children = await readdir3(dir, { withFileTypes: true });
|
|
19019
19035
|
children.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
19020
19036
|
for (const child of children) {
|
|
19021
|
-
if (dir === root &&
|
|
19037
|
+
if (dir === root && excludedRootNames.has(child.name)) continue;
|
|
19022
19038
|
const absolute = join3(dir, child.name);
|
|
19023
19039
|
const rel = relative7(root, absolute).split("\\").join("/");
|
|
19040
|
+
if (excludedPathPrefixes.some((prefix) => rel === prefix || rel.startsWith(`${prefix}/`))) continue;
|
|
19024
19041
|
const st = await lstat5(absolute);
|
|
19025
19042
|
if (st.isSymbolicLink()) {
|
|
19026
19043
|
throw frozenError(`frozen snapshot contains symlink: ${rel}`);
|
|
@@ -76930,6 +76947,50 @@ function transportPayload(entries) {
|
|
|
76930
76947
|
contentDigest
|
|
76931
76948
|
}));
|
|
76932
76949
|
}
|
|
76950
|
+
function consumerTransportExclusions(consumer) {
|
|
76951
|
+
if (consumer === "claude") return [".in_use"];
|
|
76952
|
+
if (consumer === "codex") return [".git", ".codex-plugin/migrated-command-skills"];
|
|
76953
|
+
if (consumer === "kimi") return [".git"];
|
|
76954
|
+
return [];
|
|
76955
|
+
}
|
|
76956
|
+
function extractDeclaredPluginSource(consumer, entry) {
|
|
76957
|
+
const rawSource = consumer === "claude" ? entry.source : entry.source?.source === "local" ? entry.source?.path : null;
|
|
76958
|
+
if (typeof rawSource !== "string" || rawSource.length === 0) {
|
|
76959
|
+
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)}`);
|
|
76960
|
+
}
|
|
76961
|
+
if (rawSource.startsWith("/") || rawSource.includes("..") || rawSource.includes("\\") || /^https?:\/\//i.test(rawSource)) {
|
|
76962
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76963
|
+
}
|
|
76964
|
+
const segments = rawSource.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
76965
|
+
if (segments.some((segment) => segment === "..")) {
|
|
76966
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76967
|
+
}
|
|
76968
|
+
return segments.length === 0 ? "." : segments.join("/");
|
|
76969
|
+
}
|
|
76970
|
+
async function resolveInstalledPayloadSubpath(snapshotDir, sourceEntries, action, consumer) {
|
|
76971
|
+
if (consumer === "kimi") return ".";
|
|
76972
|
+
const marketplaceRelative = consumer === "claude" ? ".claude-plugin/marketplace.json" : ".agents/plugins/marketplace.json";
|
|
76973
|
+
const anchored = sourceEntries.some((entry) => entry.type === "file" && entry.path === marketplaceRelative);
|
|
76974
|
+
if (!anchored) {
|
|
76975
|
+
throw new Error(`frozen snapshot is missing the marketplace manifest ${marketplaceRelative}`);
|
|
76976
|
+
}
|
|
76977
|
+
const result = await validateManifestFile(resolve19(snapshotDir, marketplaceRelative), ["name", "plugins"]);
|
|
76978
|
+
if (!result.valid) {
|
|
76979
|
+
throw new Error(`frozen snapshot ${marketplaceRelative} invalid: ${result.error}`);
|
|
76980
|
+
}
|
|
76981
|
+
if (result.manifest.name !== action.marketplace) {
|
|
76982
|
+
throw new Error(`marketplace manifest name "${result.manifest.name}" does not match action marketplace "${action.marketplace}"`);
|
|
76983
|
+
}
|
|
76984
|
+
const plugins = result.manifest.plugins;
|
|
76985
|
+
if (!Array.isArray(plugins)) {
|
|
76986
|
+
throw new Error(`${marketplaceRelative} must have a plugins[] array`);
|
|
76987
|
+
}
|
|
76988
|
+
const matches = plugins.filter((entry) => entry.name === action.plugin);
|
|
76989
|
+
if (matches.length !== 1) {
|
|
76990
|
+
throw new Error(`expected exactly one plugins[] entry with name "${action.plugin}", found ${matches.length}`);
|
|
76991
|
+
}
|
|
76992
|
+
return extractDeclaredPluginSource(consumer, matches[0]);
|
|
76993
|
+
}
|
|
76933
76994
|
async function verifyInstalledMarketplacePayload(action, context, installPath, consumer) {
|
|
76934
76995
|
const sourcePath = await resolveFrozenPath(
|
|
76935
76996
|
context.root,
|
|
@@ -76940,10 +77001,21 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
76940
77001
|
if (sourceSnapshot.digest !== action.manifestDigest) {
|
|
76941
77002
|
throw new Error("frozen marketplace snapshot digest no longer matches the plan");
|
|
76942
77003
|
}
|
|
77004
|
+
const payloadSubpath = await resolveInstalledPayloadSubpath(
|
|
77005
|
+
sourcePath,
|
|
77006
|
+
sourceSnapshot.entries,
|
|
77007
|
+
action,
|
|
77008
|
+
consumer
|
|
77009
|
+
);
|
|
77010
|
+
const prefix = payloadSubpath === "." ? null : `${payloadSubpath}/`;
|
|
77011
|
+
const authorityEntries = prefix === null ? sourceSnapshot.entries : sourceSnapshot.entries.filter((entry) => entry.path.startsWith(prefix)).map((entry) => ({ ...entry, path: entry.path.slice(prefix.length) }));
|
|
77012
|
+
if (authorityEntries.length === 0) {
|
|
77013
|
+
throw new Error("frozen snapshot contains no payload under the declared marketplace source");
|
|
77014
|
+
}
|
|
76943
77015
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
76944
|
-
excludeRootEntries: consumer
|
|
77016
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
76945
77017
|
});
|
|
76946
|
-
if (JSON.stringify(transportPayload(
|
|
77018
|
+
if (JSON.stringify(transportPayload(authorityEntries)) !== JSON.stringify(transportPayload(installedSnapshot.entries))) {
|
|
76947
77019
|
throw new Error("installed marketplace payload differs in path, bytes, size, or non-write mode bits");
|
|
76948
77020
|
}
|
|
76949
77021
|
return action.manifestDigest;
|
|
@@ -77643,19 +77715,14 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77643
77715
|
});
|
|
77644
77716
|
}
|
|
77645
77717
|
const entry = pluginEntry[0];
|
|
77646
|
-
|
|
77647
|
-
|
|
77648
|
-
|
|
77649
|
-
|
|
77650
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77651
|
-
error: `marketplace plugin entry source must be a non-empty relative path${consumer === "codex" ? ' (object with source:"local")' : ""}, got ${JSON.stringify(entry.source)}`
|
|
77652
|
-
});
|
|
77653
|
-
}
|
|
77654
|
-
if (sourcePath.startsWith("/") || sourcePath.includes("..") || sourcePath.includes("\\") || /^https?:\/\//i.test(sourcePath)) {
|
|
77718
|
+
let sourcePath;
|
|
77719
|
+
try {
|
|
77720
|
+
sourcePath = extractDeclaredPluginSource(consumer, entry);
|
|
77721
|
+
} catch (sourceErr) {
|
|
77655
77722
|
return createResult({
|
|
77656
77723
|
actionType,
|
|
77657
77724
|
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77658
|
-
error:
|
|
77725
|
+
error: sourceErr.message
|
|
77659
77726
|
});
|
|
77660
77727
|
}
|
|
77661
77728
|
const sourceDirAbs = resolve19(snapshotDirReal, sourcePath);
|
|
@@ -78578,7 +78645,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78578
78645
|
} catch (digestErr) {
|
|
78579
78646
|
try {
|
|
78580
78647
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
78581
|
-
excludeRootEntries: consumer
|
|
78648
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
78582
78649
|
});
|
|
78583
78650
|
manifestDigest = installedSnapshot.digest;
|
|
78584
78651
|
} catch {
|
|
@@ -78744,6 +78811,9 @@ var init_plugin_marketplace = __esm({
|
|
|
78744
78811
|
execFile9 = promisify10(execFileCb10);
|
|
78745
78812
|
NAME4 = "plugin-marketplace";
|
|
78746
78813
|
__name(transportPayload, "transportPayload");
|
|
78814
|
+
__name(consumerTransportExclusions, "consumerTransportExclusions");
|
|
78815
|
+
__name(extractDeclaredPluginSource, "extractDeclaredPluginSource");
|
|
78816
|
+
__name(resolveInstalledPayloadSubpath, "resolveInstalledPayloadSubpath");
|
|
78747
78817
|
__name(verifyInstalledMarketplacePayload, "verifyInstalledMarketplacePayload");
|
|
78748
78818
|
__name(writeEvidenceAtomic, "writeEvidenceAtomic");
|
|
78749
78819
|
KIMI_REQUIREMENT_FILE = "release-skill-kimi-manual-install.json";
|
|
@@ -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.10"});
|
|
13
13
|
|
|
14
14
|
var __create = Object.create;
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -17816,7 +17816,8 @@ var init_baseline = __esm({
|
|
|
17816
17816
|
".release-skill/lock",
|
|
17817
17817
|
".release-skill/lock-audit",
|
|
17818
17818
|
".release-skill/runs",
|
|
17819
|
-
".release-skill/transactions"
|
|
17819
|
+
".release-skill/transactions",
|
|
17820
|
+
".release-skill/kimi-attestations"
|
|
17820
17821
|
];
|
|
17821
17822
|
RESERVED_CONTROL_PREFIXES = [
|
|
17822
17823
|
...CONTROL_PLANE_PREFIXES,
|
|
@@ -19013,14 +19014,30 @@ async function computeFrozenSnapshot(snapshotDir, { excludeRootEntries = [] } =
|
|
|
19013
19014
|
throw frozenError("frozen snapshot root must be a real directory");
|
|
19014
19015
|
}
|
|
19015
19016
|
const entries = [];
|
|
19016
|
-
const
|
|
19017
|
+
const excludedRootNames = /* @__PURE__ */ new Set();
|
|
19018
|
+
const excludedPathPrefixes = [];
|
|
19019
|
+
for (const entry of excludeRootEntries) {
|
|
19020
|
+
if (typeof entry !== "string") {
|
|
19021
|
+
throw frozenError("frozen snapshot exclusion entries must be strings");
|
|
19022
|
+
}
|
|
19023
|
+
const segments = entry.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
19024
|
+
if (segments.length === 0 || entry.startsWith("/") || entry.includes("\\") || segments.some((segment) => segment === "..")) {
|
|
19025
|
+
throw frozenError(`frozen snapshot exclusion entry is not a safe relative path: ${JSON.stringify(entry)}`);
|
|
19026
|
+
}
|
|
19027
|
+
if (segments.length === 1) {
|
|
19028
|
+
excludedRootNames.add(segments[0]);
|
|
19029
|
+
} else {
|
|
19030
|
+
excludedPathPrefixes.push(segments.join("/"));
|
|
19031
|
+
}
|
|
19032
|
+
}
|
|
19017
19033
|
async function walk(dir) {
|
|
19018
19034
|
const children = await readdir3(dir, { withFileTypes: true });
|
|
19019
19035
|
children.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
19020
19036
|
for (const child of children) {
|
|
19021
|
-
if (dir === root &&
|
|
19037
|
+
if (dir === root && excludedRootNames.has(child.name)) continue;
|
|
19022
19038
|
const absolute = join3(dir, child.name);
|
|
19023
19039
|
const rel = relative7(root, absolute).split("\\").join("/");
|
|
19040
|
+
if (excludedPathPrefixes.some((prefix) => rel === prefix || rel.startsWith(`${prefix}/`))) continue;
|
|
19024
19041
|
const st = await lstat5(absolute);
|
|
19025
19042
|
if (st.isSymbolicLink()) {
|
|
19026
19043
|
throw frozenError(`frozen snapshot contains symlink: ${rel}`);
|
|
@@ -76930,6 +76947,50 @@ function transportPayload(entries) {
|
|
|
76930
76947
|
contentDigest
|
|
76931
76948
|
}));
|
|
76932
76949
|
}
|
|
76950
|
+
function consumerTransportExclusions(consumer) {
|
|
76951
|
+
if (consumer === "claude") return [".in_use"];
|
|
76952
|
+
if (consumer === "codex") return [".git", ".codex-plugin/migrated-command-skills"];
|
|
76953
|
+
if (consumer === "kimi") return [".git"];
|
|
76954
|
+
return [];
|
|
76955
|
+
}
|
|
76956
|
+
function extractDeclaredPluginSource(consumer, entry) {
|
|
76957
|
+
const rawSource = consumer === "claude" ? entry.source : entry.source?.source === "local" ? entry.source?.path : null;
|
|
76958
|
+
if (typeof rawSource !== "string" || rawSource.length === 0) {
|
|
76959
|
+
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)}`);
|
|
76960
|
+
}
|
|
76961
|
+
if (rawSource.startsWith("/") || rawSource.includes("..") || rawSource.includes("\\") || /^https?:\/\//i.test(rawSource)) {
|
|
76962
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76963
|
+
}
|
|
76964
|
+
const segments = rawSource.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
76965
|
+
if (segments.some((segment) => segment === "..")) {
|
|
76966
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76967
|
+
}
|
|
76968
|
+
return segments.length === 0 ? "." : segments.join("/");
|
|
76969
|
+
}
|
|
76970
|
+
async function resolveInstalledPayloadSubpath(snapshotDir, sourceEntries, action, consumer) {
|
|
76971
|
+
if (consumer === "kimi") return ".";
|
|
76972
|
+
const marketplaceRelative = consumer === "claude" ? ".claude-plugin/marketplace.json" : ".agents/plugins/marketplace.json";
|
|
76973
|
+
const anchored = sourceEntries.some((entry) => entry.type === "file" && entry.path === marketplaceRelative);
|
|
76974
|
+
if (!anchored) {
|
|
76975
|
+
throw new Error(`frozen snapshot is missing the marketplace manifest ${marketplaceRelative}`);
|
|
76976
|
+
}
|
|
76977
|
+
const result = await validateManifestFile(resolve19(snapshotDir, marketplaceRelative), ["name", "plugins"]);
|
|
76978
|
+
if (!result.valid) {
|
|
76979
|
+
throw new Error(`frozen snapshot ${marketplaceRelative} invalid: ${result.error}`);
|
|
76980
|
+
}
|
|
76981
|
+
if (result.manifest.name !== action.marketplace) {
|
|
76982
|
+
throw new Error(`marketplace manifest name "${result.manifest.name}" does not match action marketplace "${action.marketplace}"`);
|
|
76983
|
+
}
|
|
76984
|
+
const plugins = result.manifest.plugins;
|
|
76985
|
+
if (!Array.isArray(plugins)) {
|
|
76986
|
+
throw new Error(`${marketplaceRelative} must have a plugins[] array`);
|
|
76987
|
+
}
|
|
76988
|
+
const matches = plugins.filter((entry) => entry.name === action.plugin);
|
|
76989
|
+
if (matches.length !== 1) {
|
|
76990
|
+
throw new Error(`expected exactly one plugins[] entry with name "${action.plugin}", found ${matches.length}`);
|
|
76991
|
+
}
|
|
76992
|
+
return extractDeclaredPluginSource(consumer, matches[0]);
|
|
76993
|
+
}
|
|
76933
76994
|
async function verifyInstalledMarketplacePayload(action, context, installPath, consumer) {
|
|
76934
76995
|
const sourcePath = await resolveFrozenPath(
|
|
76935
76996
|
context.root,
|
|
@@ -76940,10 +77001,21 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
76940
77001
|
if (sourceSnapshot.digest !== action.manifestDigest) {
|
|
76941
77002
|
throw new Error("frozen marketplace snapshot digest no longer matches the plan");
|
|
76942
77003
|
}
|
|
77004
|
+
const payloadSubpath = await resolveInstalledPayloadSubpath(
|
|
77005
|
+
sourcePath,
|
|
77006
|
+
sourceSnapshot.entries,
|
|
77007
|
+
action,
|
|
77008
|
+
consumer
|
|
77009
|
+
);
|
|
77010
|
+
const prefix = payloadSubpath === "." ? null : `${payloadSubpath}/`;
|
|
77011
|
+
const authorityEntries = prefix === null ? sourceSnapshot.entries : sourceSnapshot.entries.filter((entry) => entry.path.startsWith(prefix)).map((entry) => ({ ...entry, path: entry.path.slice(prefix.length) }));
|
|
77012
|
+
if (authorityEntries.length === 0) {
|
|
77013
|
+
throw new Error("frozen snapshot contains no payload under the declared marketplace source");
|
|
77014
|
+
}
|
|
76943
77015
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
76944
|
-
excludeRootEntries: consumer
|
|
77016
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
76945
77017
|
});
|
|
76946
|
-
if (JSON.stringify(transportPayload(
|
|
77018
|
+
if (JSON.stringify(transportPayload(authorityEntries)) !== JSON.stringify(transportPayload(installedSnapshot.entries))) {
|
|
76947
77019
|
throw new Error("installed marketplace payload differs in path, bytes, size, or non-write mode bits");
|
|
76948
77020
|
}
|
|
76949
77021
|
return action.manifestDigest;
|
|
@@ -77643,19 +77715,14 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77643
77715
|
});
|
|
77644
77716
|
}
|
|
77645
77717
|
const entry = pluginEntry[0];
|
|
77646
|
-
|
|
77647
|
-
|
|
77648
|
-
|
|
77649
|
-
|
|
77650
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77651
|
-
error: `marketplace plugin entry source must be a non-empty relative path${consumer === "codex" ? ' (object with source:"local")' : ""}, got ${JSON.stringify(entry.source)}`
|
|
77652
|
-
});
|
|
77653
|
-
}
|
|
77654
|
-
if (sourcePath.startsWith("/") || sourcePath.includes("..") || sourcePath.includes("\\") || /^https?:\/\//i.test(sourcePath)) {
|
|
77718
|
+
let sourcePath;
|
|
77719
|
+
try {
|
|
77720
|
+
sourcePath = extractDeclaredPluginSource(consumer, entry);
|
|
77721
|
+
} catch (sourceErr) {
|
|
77655
77722
|
return createResult({
|
|
77656
77723
|
actionType,
|
|
77657
77724
|
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77658
|
-
error:
|
|
77725
|
+
error: sourceErr.message
|
|
77659
77726
|
});
|
|
77660
77727
|
}
|
|
77661
77728
|
const sourceDirAbs = resolve19(snapshotDirReal, sourcePath);
|
|
@@ -78578,7 +78645,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78578
78645
|
} catch (digestErr) {
|
|
78579
78646
|
try {
|
|
78580
78647
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
78581
|
-
excludeRootEntries: consumer
|
|
78648
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
78582
78649
|
});
|
|
78583
78650
|
manifestDigest = installedSnapshot.digest;
|
|
78584
78651
|
} catch {
|
|
@@ -78744,6 +78811,9 @@ var init_plugin_marketplace = __esm({
|
|
|
78744
78811
|
execFile9 = promisify10(execFileCb10);
|
|
78745
78812
|
NAME4 = "plugin-marketplace";
|
|
78746
78813
|
__name(transportPayload, "transportPayload");
|
|
78814
|
+
__name(consumerTransportExclusions, "consumerTransportExclusions");
|
|
78815
|
+
__name(extractDeclaredPluginSource, "extractDeclaredPluginSource");
|
|
78816
|
+
__name(resolveInstalledPayloadSubpath, "resolveInstalledPayloadSubpath");
|
|
78747
78817
|
__name(verifyInstalledMarketplacePayload, "verifyInstalledMarketplacePayload");
|
|
78748
78818
|
__name(writeEvidenceAtomic, "writeEvidenceAtomic");
|
|
78749
78819
|
KIMI_REQUIREMENT_FILE = "release-skill-kimi-manual-install.json";
|
|
@@ -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.10"});
|
|
13
13
|
|
|
14
14
|
var __create = Object.create;
|
|
15
15
|
var __defProp = Object.defineProperty;
|
|
@@ -17816,7 +17816,8 @@ var init_baseline = __esm({
|
|
|
17816
17816
|
".release-skill/lock",
|
|
17817
17817
|
".release-skill/lock-audit",
|
|
17818
17818
|
".release-skill/runs",
|
|
17819
|
-
".release-skill/transactions"
|
|
17819
|
+
".release-skill/transactions",
|
|
17820
|
+
".release-skill/kimi-attestations"
|
|
17820
17821
|
];
|
|
17821
17822
|
RESERVED_CONTROL_PREFIXES = [
|
|
17822
17823
|
...CONTROL_PLANE_PREFIXES,
|
|
@@ -19013,14 +19014,30 @@ async function computeFrozenSnapshot(snapshotDir, { excludeRootEntries = [] } =
|
|
|
19013
19014
|
throw frozenError("frozen snapshot root must be a real directory");
|
|
19014
19015
|
}
|
|
19015
19016
|
const entries = [];
|
|
19016
|
-
const
|
|
19017
|
+
const excludedRootNames = /* @__PURE__ */ new Set();
|
|
19018
|
+
const excludedPathPrefixes = [];
|
|
19019
|
+
for (const entry of excludeRootEntries) {
|
|
19020
|
+
if (typeof entry !== "string") {
|
|
19021
|
+
throw frozenError("frozen snapshot exclusion entries must be strings");
|
|
19022
|
+
}
|
|
19023
|
+
const segments = entry.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
19024
|
+
if (segments.length === 0 || entry.startsWith("/") || entry.includes("\\") || segments.some((segment) => segment === "..")) {
|
|
19025
|
+
throw frozenError(`frozen snapshot exclusion entry is not a safe relative path: ${JSON.stringify(entry)}`);
|
|
19026
|
+
}
|
|
19027
|
+
if (segments.length === 1) {
|
|
19028
|
+
excludedRootNames.add(segments[0]);
|
|
19029
|
+
} else {
|
|
19030
|
+
excludedPathPrefixes.push(segments.join("/"));
|
|
19031
|
+
}
|
|
19032
|
+
}
|
|
19017
19033
|
async function walk(dir) {
|
|
19018
19034
|
const children = await readdir3(dir, { withFileTypes: true });
|
|
19019
19035
|
children.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
|
|
19020
19036
|
for (const child of children) {
|
|
19021
|
-
if (dir === root &&
|
|
19037
|
+
if (dir === root && excludedRootNames.has(child.name)) continue;
|
|
19022
19038
|
const absolute = join3(dir, child.name);
|
|
19023
19039
|
const rel = relative7(root, absolute).split("\\").join("/");
|
|
19040
|
+
if (excludedPathPrefixes.some((prefix) => rel === prefix || rel.startsWith(`${prefix}/`))) continue;
|
|
19024
19041
|
const st = await lstat5(absolute);
|
|
19025
19042
|
if (st.isSymbolicLink()) {
|
|
19026
19043
|
throw frozenError(`frozen snapshot contains symlink: ${rel}`);
|
|
@@ -76930,6 +76947,50 @@ function transportPayload(entries) {
|
|
|
76930
76947
|
contentDigest
|
|
76931
76948
|
}));
|
|
76932
76949
|
}
|
|
76950
|
+
function consumerTransportExclusions(consumer) {
|
|
76951
|
+
if (consumer === "claude") return [".in_use"];
|
|
76952
|
+
if (consumer === "codex") return [".git", ".codex-plugin/migrated-command-skills"];
|
|
76953
|
+
if (consumer === "kimi") return [".git"];
|
|
76954
|
+
return [];
|
|
76955
|
+
}
|
|
76956
|
+
function extractDeclaredPluginSource(consumer, entry) {
|
|
76957
|
+
const rawSource = consumer === "claude" ? entry.source : entry.source?.source === "local" ? entry.source?.path : null;
|
|
76958
|
+
if (typeof rawSource !== "string" || rawSource.length === 0) {
|
|
76959
|
+
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)}`);
|
|
76960
|
+
}
|
|
76961
|
+
if (rawSource.startsWith("/") || rawSource.includes("..") || rawSource.includes("\\") || /^https?:\/\//i.test(rawSource)) {
|
|
76962
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76963
|
+
}
|
|
76964
|
+
const segments = rawSource.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
76965
|
+
if (segments.some((segment) => segment === "..")) {
|
|
76966
|
+
throw new Error(`marketplace plugin entry source "${rawSource}" is not a safe relative path`);
|
|
76967
|
+
}
|
|
76968
|
+
return segments.length === 0 ? "." : segments.join("/");
|
|
76969
|
+
}
|
|
76970
|
+
async function resolveInstalledPayloadSubpath(snapshotDir, sourceEntries, action, consumer) {
|
|
76971
|
+
if (consumer === "kimi") return ".";
|
|
76972
|
+
const marketplaceRelative = consumer === "claude" ? ".claude-plugin/marketplace.json" : ".agents/plugins/marketplace.json";
|
|
76973
|
+
const anchored = sourceEntries.some((entry) => entry.type === "file" && entry.path === marketplaceRelative);
|
|
76974
|
+
if (!anchored) {
|
|
76975
|
+
throw new Error(`frozen snapshot is missing the marketplace manifest ${marketplaceRelative}`);
|
|
76976
|
+
}
|
|
76977
|
+
const result = await validateManifestFile(resolve19(snapshotDir, marketplaceRelative), ["name", "plugins"]);
|
|
76978
|
+
if (!result.valid) {
|
|
76979
|
+
throw new Error(`frozen snapshot ${marketplaceRelative} invalid: ${result.error}`);
|
|
76980
|
+
}
|
|
76981
|
+
if (result.manifest.name !== action.marketplace) {
|
|
76982
|
+
throw new Error(`marketplace manifest name "${result.manifest.name}" does not match action marketplace "${action.marketplace}"`);
|
|
76983
|
+
}
|
|
76984
|
+
const plugins = result.manifest.plugins;
|
|
76985
|
+
if (!Array.isArray(plugins)) {
|
|
76986
|
+
throw new Error(`${marketplaceRelative} must have a plugins[] array`);
|
|
76987
|
+
}
|
|
76988
|
+
const matches = plugins.filter((entry) => entry.name === action.plugin);
|
|
76989
|
+
if (matches.length !== 1) {
|
|
76990
|
+
throw new Error(`expected exactly one plugins[] entry with name "${action.plugin}", found ${matches.length}`);
|
|
76991
|
+
}
|
|
76992
|
+
return extractDeclaredPluginSource(consumer, matches[0]);
|
|
76993
|
+
}
|
|
76933
76994
|
async function verifyInstalledMarketplacePayload(action, context, installPath, consumer) {
|
|
76934
76995
|
const sourcePath = await resolveFrozenPath(
|
|
76935
76996
|
context.root,
|
|
@@ -76940,10 +77001,21 @@ async function verifyInstalledMarketplacePayload(action, context, installPath, c
|
|
|
76940
77001
|
if (sourceSnapshot.digest !== action.manifestDigest) {
|
|
76941
77002
|
throw new Error("frozen marketplace snapshot digest no longer matches the plan");
|
|
76942
77003
|
}
|
|
77004
|
+
const payloadSubpath = await resolveInstalledPayloadSubpath(
|
|
77005
|
+
sourcePath,
|
|
77006
|
+
sourceSnapshot.entries,
|
|
77007
|
+
action,
|
|
77008
|
+
consumer
|
|
77009
|
+
);
|
|
77010
|
+
const prefix = payloadSubpath === "." ? null : `${payloadSubpath}/`;
|
|
77011
|
+
const authorityEntries = prefix === null ? sourceSnapshot.entries : sourceSnapshot.entries.filter((entry) => entry.path.startsWith(prefix)).map((entry) => ({ ...entry, path: entry.path.slice(prefix.length) }));
|
|
77012
|
+
if (authorityEntries.length === 0) {
|
|
77013
|
+
throw new Error("frozen snapshot contains no payload under the declared marketplace source");
|
|
77014
|
+
}
|
|
76943
77015
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
76944
|
-
excludeRootEntries: consumer
|
|
77016
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
76945
77017
|
});
|
|
76946
|
-
if (JSON.stringify(transportPayload(
|
|
77018
|
+
if (JSON.stringify(transportPayload(authorityEntries)) !== JSON.stringify(transportPayload(installedSnapshot.entries))) {
|
|
76947
77019
|
throw new Error("installed marketplace payload differs in path, bytes, size, or non-write mode bits");
|
|
76948
77020
|
}
|
|
76949
77021
|
return action.manifestDigest;
|
|
@@ -77643,19 +77715,14 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
77643
77715
|
});
|
|
77644
77716
|
}
|
|
77645
77717
|
const entry = pluginEntry[0];
|
|
77646
|
-
|
|
77647
|
-
|
|
77648
|
-
|
|
77649
|
-
|
|
77650
|
-
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77651
|
-
error: `marketplace plugin entry source must be a non-empty relative path${consumer === "codex" ? ' (object with source:"local")' : ""}, got ${JSON.stringify(entry.source)}`
|
|
77652
|
-
});
|
|
77653
|
-
}
|
|
77654
|
-
if (sourcePath.startsWith("/") || sourcePath.includes("..") || sourcePath.includes("\\") || /^https?:\/\//i.test(sourcePath)) {
|
|
77718
|
+
let sourcePath;
|
|
77719
|
+
try {
|
|
77720
|
+
sourcePath = extractDeclaredPluginSource(consumer, entry);
|
|
77721
|
+
} catch (sourceErr) {
|
|
77655
77722
|
return createResult({
|
|
77656
77723
|
actionType,
|
|
77657
77724
|
status: ActionStatus.PREFLIGHT_FAILED,
|
|
77658
|
-
error:
|
|
77725
|
+
error: sourceErr.message
|
|
77659
77726
|
});
|
|
77660
77727
|
}
|
|
77661
77728
|
const sourceDirAbs = resolve19(snapshotDirReal, sourcePath);
|
|
@@ -78578,7 +78645,7 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
78578
78645
|
} catch (digestErr) {
|
|
78579
78646
|
try {
|
|
78580
78647
|
const installedSnapshot = await computeFrozenSnapshot(installPath, {
|
|
78581
|
-
excludeRootEntries: consumer
|
|
78648
|
+
excludeRootEntries: consumerTransportExclusions(consumer)
|
|
78582
78649
|
});
|
|
78583
78650
|
manifestDigest = installedSnapshot.digest;
|
|
78584
78651
|
} catch {
|
|
@@ -78744,6 +78811,9 @@ var init_plugin_marketplace = __esm({
|
|
|
78744
78811
|
execFile9 = promisify10(execFileCb10);
|
|
78745
78812
|
NAME4 = "plugin-marketplace";
|
|
78746
78813
|
__name(transportPayload, "transportPayload");
|
|
78814
|
+
__name(consumerTransportExclusions, "consumerTransportExclusions");
|
|
78815
|
+
__name(extractDeclaredPluginSource, "extractDeclaredPluginSource");
|
|
78816
|
+
__name(resolveInstalledPayloadSubpath, "resolveInstalledPayloadSubpath");
|
|
78747
78817
|
__name(verifyInstalledMarketplacePayload, "verifyInstalledMarketplacePayload");
|
|
78748
78818
|
__name(writeEvidenceAtomic, "writeEvidenceAtomic");
|
|
78749
78819
|
KIMI_REQUIREMENT_FILE = "release-skill-kimi-manual-install.json";
|