release-skill 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +1 -1
- package/CHANGELOG.md +17 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +12 -9
- package/README.zh-CN.md +12 -9
- 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 +326 -70
- package/adapters/claude/schemas/release-plan.schema.json +9 -0
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +326 -70
- package/adapters/codex/schemas/release-plan.schema.json +9 -0
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +326 -70
- package/adapters/kimi/schemas/release-plan.schema.json +9 -0
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +326 -70
- package/adapters/workbuddy/schemas/release-plan.schema.json +9 -0
- package/bin/release-skill.bundle.mjs +326 -70
- package/package.json +1 -1
- package/schemas/release-plan.schema.json +9 -0
- package/src/commands/lineage.mjs +101 -32
- package/src/commands/prepare.mjs +59 -1
- package/src/commands/publish.mjs +10 -1
- package/src/core/skill-resource-closure.mjs +240 -10
- package/src/platforms/registry.mjs +12 -0
|
@@ -9,9 +9,9 @@ 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.6.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.6.2"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "12dcb7942e6587f1321c3f81625b0bc3f1dd64afe978ddf8084bf1a5824de23a";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -23549,13 +23549,13 @@ var require_cross_spawn = __commonJS({
|
|
|
23549
23549
|
var cp2 = __require("child_process");
|
|
23550
23550
|
var parse2 = require_parse();
|
|
23551
23551
|
var enoent = require_enoent();
|
|
23552
|
-
function
|
|
23552
|
+
function spawn5(command2, args2, options) {
|
|
23553
23553
|
const parsed = parse2(command2, args2, options);
|
|
23554
23554
|
const spawned = cp2.spawn(parsed.command, parsed.args, parsed.options);
|
|
23555
23555
|
enoent.hookChildProcess(spawned, parsed);
|
|
23556
23556
|
return spawned;
|
|
23557
23557
|
}
|
|
23558
|
-
__name(
|
|
23558
|
+
__name(spawn5, "spawn");
|
|
23559
23559
|
function spawnSync2(command2, args2, options) {
|
|
23560
23560
|
const parsed = parse2(command2, args2, options);
|
|
23561
23561
|
const result = cp2.spawnSync(parsed.command, parsed.args, parsed.options);
|
|
@@ -23563,8 +23563,8 @@ var require_cross_spawn = __commonJS({
|
|
|
23563
23563
|
return result;
|
|
23564
23564
|
}
|
|
23565
23565
|
__name(spawnSync2, "spawnSync");
|
|
23566
|
-
module.exports =
|
|
23567
|
-
module.exports.spawn =
|
|
23566
|
+
module.exports = spawn5;
|
|
23567
|
+
module.exports.spawn = spawn5;
|
|
23568
23568
|
module.exports.sync = spawnSync2;
|
|
23569
23569
|
module.exports._parse = parse2;
|
|
23570
23570
|
module.exports._enoent = enoent;
|
|
@@ -32218,7 +32218,7 @@ var init_report = __esm({
|
|
|
32218
32218
|
init_closure();
|
|
32219
32219
|
init_errors3();
|
|
32220
32220
|
init_validation();
|
|
32221
|
-
PACKAGE_META = Object.freeze({ "name": "release-skill", "version": "0.6.
|
|
32221
|
+
PACKAGE_META = Object.freeze({ "name": "release-skill", "version": "0.6.2" });
|
|
32222
32222
|
REPORT_RENDERER_VERSION = PACKAGE_META.version;
|
|
32223
32223
|
SUPPORTED_REPORT_LOCALES = Object.freeze(["zh-CN", "en-US"]);
|
|
32224
32224
|
EXECUTION_STATUSES = Object.freeze([
|
|
@@ -35543,6 +35543,9 @@ function assertRegistry(registry = PLATFORMS) {
|
|
|
35543
35543
|
if (!platform.buildAdapter || typeof platform.buildAdapter !== "object") {
|
|
35544
35544
|
throw new Error(`platform registry: ${label} buildAdapter must be an object`);
|
|
35545
35545
|
}
|
|
35546
|
+
if (typeof platform.buildAdapter.name !== "string" || platform.buildAdapter.name.length === 0) {
|
|
35547
|
+
throw new Error(`platform registry: ${label} buildAdapter needs a non-empty name (its adapter directory name)`);
|
|
35548
|
+
}
|
|
35546
35549
|
if (!VALID_LIST_OUTPUTS.has(platform.jsonProtocol?.listOutput)) {
|
|
35547
35550
|
throw new Error(`platform registry: ${label} has illegal jsonProtocol.listOutput "${platform.jsonProtocol?.listOutput}"`);
|
|
35548
35551
|
}
|
|
@@ -35730,6 +35733,9 @@ var init_registry2 = __esm({
|
|
|
35730
35733
|
schemaRequiredFields: Object.freeze(["plugin", "marketplace", "entrySkill"]),
|
|
35731
35734
|
skillRendering: Object.freeze({ mode: "verbatim", preamble: null, placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
35732
35735
|
buildAdapter: Object.freeze({
|
|
35736
|
+
// D6: explicit adapter directory name (adapters/claude/); assertRegistry
|
|
35737
|
+
// requires this on every platform.
|
|
35738
|
+
name: "claude",
|
|
35733
35739
|
pluginDirName: ".claude-plugin",
|
|
35734
35740
|
templateFileName: "plugin.json",
|
|
35735
35741
|
marketplaceFileName: "marketplace.json",
|
|
@@ -35787,6 +35793,8 @@ var init_registry2 = __esm({
|
|
|
35787
35793
|
schemaRequiredFields: Object.freeze(["plugin", "marketplace", "entrySkill"]),
|
|
35788
35794
|
skillRendering: Object.freeze({ mode: "substitute", preamble: "codex", placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
35789
35795
|
buildAdapter: Object.freeze({
|
|
35796
|
+
// D6: explicit adapter directory name (adapters/codex/).
|
|
35797
|
+
name: "codex",
|
|
35790
35798
|
pluginDirName: ".codex-plugin",
|
|
35791
35799
|
templateFileName: "plugin.json",
|
|
35792
35800
|
marketplaceFileName: null,
|
|
@@ -35843,6 +35851,8 @@ var init_registry2 = __esm({
|
|
|
35843
35851
|
schemaRequiredFields: Object.freeze(["plugin", "entrySkill"]),
|
|
35844
35852
|
skillRendering: Object.freeze({ mode: "substitute", preamble: "kimi", placeholder: "${CLAUDE_PLUGIN_ROOT}" }),
|
|
35845
35853
|
buildAdapter: Object.freeze({
|
|
35854
|
+
// D6: explicit adapter directory name (adapters/kimi/).
|
|
35855
|
+
name: "kimi",
|
|
35846
35856
|
pluginDirName: ".kimi-plugin",
|
|
35847
35857
|
templateFileName: "plugin.json",
|
|
35848
35858
|
marketplaceFileName: null,
|
|
@@ -41707,7 +41717,7 @@ function trimCandidate(value) {
|
|
|
41707
41717
|
function isPathToken(value) {
|
|
41708
41718
|
const token = trimCandidate(value);
|
|
41709
41719
|
if (!token || GLOB_PATTERN.test(token)) return false;
|
|
41710
|
-
return BARE_PREFIXES.some((prefix) => token.startsWith(prefix)) || EXPLICIT_PREFIXES.some((prefix) => token.startsWith(prefix)) || SOURCE_TREE_PATTERN.test(token) || MACHINE_ABSOLUTE_PATTERN.test(token);
|
|
41720
|
+
return BARE_PREFIXES.some((prefix) => token.startsWith(prefix)) || EXPLICIT_PREFIXES.some((prefix) => token.startsWith(prefix)) || HOME_DIRECTORY_PATTERN.test(token) || SOURCE_TREE_PATTERN.test(token) || MACHINE_ABSOLUTE_PATTERN.test(token);
|
|
41711
41721
|
}
|
|
41712
41722
|
function scanSnippet(snippet, line, sourceOnly, results, seen) {
|
|
41713
41723
|
const candidates = snippet.match(/(?:"[^"\n]+"|'[^'\n]+'|[^\s"'`()\[\],;]+)/gu) ?? [];
|
|
@@ -41732,15 +41742,14 @@ function extractPathTokens(content) {
|
|
|
41732
41742
|
inFence = !inFence;
|
|
41733
41743
|
continue;
|
|
41734
41744
|
}
|
|
41735
|
-
|
|
41736
|
-
if (inFence) scanSnippet(line, lineNumber, sourceOnly, results, seen);
|
|
41745
|
+
if (inFence) scanSnippet(line, lineNumber, SOURCE_ONLY_MARKER.test(line), results, seen);
|
|
41737
41746
|
for (const match of line.matchAll(/`([^`]+)`/gu)) {
|
|
41738
|
-
scanSnippet(match[1], lineNumber,
|
|
41747
|
+
scanSnippet(match[1], lineNumber, SOURCE_ONLY_MARKER.test(match[1]), results, seen);
|
|
41739
41748
|
}
|
|
41740
41749
|
for (const match of line.matchAll(/\]\(([^)]+)\)/gu)) {
|
|
41741
41750
|
const target = match[1].trim().split(/[?#]/u)[0];
|
|
41742
41751
|
if (!/^(?:https?:|#)/iu.test(target)) {
|
|
41743
|
-
scanSnippet(target, lineNumber,
|
|
41752
|
+
scanSnippet(target, lineNumber, SOURCE_ONLY_MARKER.test(match[1]), results, seen);
|
|
41744
41753
|
}
|
|
41745
41754
|
}
|
|
41746
41755
|
}
|
|
@@ -41761,6 +41770,14 @@ function classifyReference(token, skillRoot, pluginRoot, scanRoot2) {
|
|
|
41761
41770
|
absoluteTarget: token
|
|
41762
41771
|
};
|
|
41763
41772
|
}
|
|
41773
|
+
if (HOME_DIRECTORY_PATTERN.test(token)) {
|
|
41774
|
+
return {
|
|
41775
|
+
classification: CLASSIFICATION.HOME_DIRECTORY,
|
|
41776
|
+
resolutionRoot: "(home)",
|
|
41777
|
+
resolvedTarget: token,
|
|
41778
|
+
absoluteTarget: token
|
|
41779
|
+
};
|
|
41780
|
+
}
|
|
41764
41781
|
if (SOURCE_TREE_PATTERN.test(token)) {
|
|
41765
41782
|
return {
|
|
41766
41783
|
classification: CLASSIFICATION.SOURCE_BACKJUMP,
|
|
@@ -41806,8 +41823,26 @@ async function inspectRegularFile(root, target) {
|
|
|
41806
41823
|
}
|
|
41807
41824
|
return { code: null };
|
|
41808
41825
|
}
|
|
41826
|
+
async function collectRegularFiles(dir, results) {
|
|
41827
|
+
let entries;
|
|
41828
|
+
try {
|
|
41829
|
+
entries = await readdir8(dir, { withFileTypes: true });
|
|
41830
|
+
} catch (error) {
|
|
41831
|
+
if (error.code === "ENOENT") return;
|
|
41832
|
+
throw error;
|
|
41833
|
+
}
|
|
41834
|
+
for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
|
|
41835
|
+
if (entry.isSymbolicLink()) continue;
|
|
41836
|
+
const absolute = join12(dir, entry.name);
|
|
41837
|
+
if (entry.isDirectory()) {
|
|
41838
|
+
await collectRegularFiles(absolute, results);
|
|
41839
|
+
} else if (entry.isFile()) {
|
|
41840
|
+
results.push(absolute);
|
|
41841
|
+
}
|
|
41842
|
+
}
|
|
41843
|
+
}
|
|
41809
41844
|
function inferSurfaceHost(surfaceId, defaultHost) {
|
|
41810
|
-
const match =
|
|
41845
|
+
const match = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
|
|
41811
41846
|
return match?.[1] ?? defaultHost;
|
|
41812
41847
|
}
|
|
41813
41848
|
function receiptProjection(result) {
|
|
@@ -41818,6 +41853,7 @@ function receiptProjection(result) {
|
|
|
41818
41853
|
skillCount: result.skillCount,
|
|
41819
41854
|
referenceCount: result.referenceCount,
|
|
41820
41855
|
sourceOnlyCount: result.sourceOnlyCount,
|
|
41856
|
+
sourceOnlyReferences: result.sourceOnlyReferences,
|
|
41821
41857
|
findingCount: result.findings.length
|
|
41822
41858
|
};
|
|
41823
41859
|
}
|
|
@@ -41894,8 +41930,23 @@ async function checkSkillResourceClosure({
|
|
|
41894
41930
|
const skillPaths = await discoverSkills(scanRoot2);
|
|
41895
41931
|
const findings = [];
|
|
41896
41932
|
const surfaceMap = /* @__PURE__ */ new Map();
|
|
41933
|
+
const skillsBySurface = /* @__PURE__ */ new Map();
|
|
41934
|
+
const resolvedResourcesBySurface = /* @__PURE__ */ new Map();
|
|
41935
|
+
const referencedTargetsBySurface = /* @__PURE__ */ new Map();
|
|
41936
|
+
const resourceReferencesBySurface = /* @__PURE__ */ new Map();
|
|
41937
|
+
const sourceOnlyReferences = [];
|
|
41897
41938
|
let referenceCount = 0;
|
|
41898
41939
|
let sourceOnlyCount = 0;
|
|
41940
|
+
const recordSourceOnlyExemption = /* @__PURE__ */ __name((surface, skill, pathToken) => {
|
|
41941
|
+
sourceOnlyCount += 1;
|
|
41942
|
+
surface.sourceOnlyCount += 1;
|
|
41943
|
+
sourceOnlyReferences.push({
|
|
41944
|
+
skill,
|
|
41945
|
+
line: pathToken.line,
|
|
41946
|
+
reference: pathToken.token,
|
|
41947
|
+
surface: surface.id
|
|
41948
|
+
});
|
|
41949
|
+
}, "recordSourceOnlyExemption");
|
|
41899
41950
|
for (const skill of skillPaths) {
|
|
41900
41951
|
const skillRoot = resolveSkillRoot(skill, scanRoot2);
|
|
41901
41952
|
const pluginRoot = resolvePluginRoot(skill, scanRoot2);
|
|
@@ -41910,6 +41961,8 @@ async function checkSkillResourceClosure({
|
|
|
41910
41961
|
};
|
|
41911
41962
|
surface.skillCount += 1;
|
|
41912
41963
|
surfaceMap.set(surfaceId, surface);
|
|
41964
|
+
if (!skillsBySurface.has(surfaceId)) skillsBySurface.set(surfaceId, []);
|
|
41965
|
+
skillsBySurface.get(surfaceId).push(skill);
|
|
41913
41966
|
const content = await readFile12(resolve16(scanRoot2, skill), "utf8");
|
|
41914
41967
|
for (const pathToken of extractPathTokens(content)) {
|
|
41915
41968
|
referenceCount += 1;
|
|
@@ -41932,8 +41985,7 @@ async function checkSkillResourceClosure({
|
|
|
41932
41985
|
};
|
|
41933
41986
|
if (classification.classification === CLASSIFICATION.SOURCE_BACKJUMP) {
|
|
41934
41987
|
if (pathToken.sourceOnly) {
|
|
41935
|
-
|
|
41936
|
-
surface.sourceOnlyCount += 1;
|
|
41988
|
+
recordSourceOnlyExemption(surface, skill, pathToken);
|
|
41937
41989
|
} else {
|
|
41938
41990
|
findings.push({ ...findingBase, code: FINDING_CODE.SOURCE_BACKJUMP });
|
|
41939
41991
|
}
|
|
@@ -41943,6 +41995,10 @@ async function checkSkillResourceClosure({
|
|
|
41943
41995
|
findings.push({ ...findingBase, code: FINDING_CODE.MACHINE_ABSOLUTE_PATH });
|
|
41944
41996
|
continue;
|
|
41945
41997
|
}
|
|
41998
|
+
if (classification.classification === CLASSIFICATION.HOME_DIRECTORY) {
|
|
41999
|
+
findings.push({ ...findingBase, code: FINDING_CODE.HOME_DIRECTORY_SEARCH });
|
|
42000
|
+
continue;
|
|
42001
|
+
}
|
|
41946
42002
|
if (classification.classification === CLASSIFICATION.OUT_OF_BOUNDS) {
|
|
41947
42003
|
findings.push({ ...findingBase, code: FINDING_CODE.OUT_OF_BOUNDS });
|
|
41948
42004
|
continue;
|
|
@@ -41954,14 +42010,112 @@ async function checkSkillResourceClosure({
|
|
|
41954
42010
|
);
|
|
41955
42011
|
if (inspection.code) {
|
|
41956
42012
|
if (pathToken.sourceOnly && inspection.code === FINDING_CODE.RESOURCE_MISSING) {
|
|
41957
|
-
|
|
41958
|
-
surface.sourceOnlyCount += 1;
|
|
42013
|
+
recordSourceOnlyExemption(surface, skill, pathToken);
|
|
41959
42014
|
} else {
|
|
41960
42015
|
findings.push({ ...findingBase, code: inspection.code });
|
|
41961
42016
|
}
|
|
42017
|
+
continue;
|
|
42018
|
+
}
|
|
42019
|
+
const relativeResource = relativeStable(pluginRoot, classification.absoluteTarget);
|
|
42020
|
+
if (!resolvedResourcesBySurface.has(surfaceId)) {
|
|
42021
|
+
resolvedResourcesBySurface.set(surfaceId, /* @__PURE__ */ new Map());
|
|
42022
|
+
referencedTargetsBySurface.set(surfaceId, /* @__PURE__ */ new Set());
|
|
42023
|
+
resourceReferencesBySurface.set(surfaceId, /* @__PURE__ */ new Map());
|
|
42024
|
+
}
|
|
42025
|
+
resolvedResourcesBySurface.get(surfaceId).set(relativeResource, classification.absoluteTarget);
|
|
42026
|
+
referencedTargetsBySurface.get(surfaceId).add(classification.absoluteTarget);
|
|
42027
|
+
const resourceReferences = resourceReferencesBySurface.get(surfaceId);
|
|
42028
|
+
if (!resourceReferences.has(relativeResource)) resourceReferences.set(relativeResource, []);
|
|
42029
|
+
resourceReferences.get(relativeResource).push({
|
|
42030
|
+
surface: surfaceId,
|
|
42031
|
+
skill,
|
|
42032
|
+
line: pathToken.line
|
|
42033
|
+
});
|
|
42034
|
+
}
|
|
42035
|
+
}
|
|
42036
|
+
const contentDigestCache = /* @__PURE__ */ new Map();
|
|
42037
|
+
const digestOfTarget = /* @__PURE__ */ __name(async (absoluteTarget) => {
|
|
42038
|
+
if (!contentDigestCache.has(absoluteTarget)) {
|
|
42039
|
+
contentDigestCache.set(
|
|
42040
|
+
absoluteTarget,
|
|
42041
|
+
digestDocument({ content: await readFile12(absoluteTarget, "utf8") })
|
|
42042
|
+
);
|
|
42043
|
+
}
|
|
42044
|
+
return contentDigestCache.get(absoluteTarget);
|
|
42045
|
+
}, "digestOfTarget");
|
|
42046
|
+
const surfaceIds = [...resolvedResourcesBySurface.keys()].sort((a, b) => a.localeCompare(b));
|
|
42047
|
+
for (let i = 0; i < surfaceIds.length; i += 1) {
|
|
42048
|
+
for (let j = i + 1; j < surfaceIds.length; j += 1) {
|
|
42049
|
+
const [leftId, rightId] = [surfaceIds[i], surfaceIds[j]];
|
|
42050
|
+
const left = resolvedResourcesBySurface.get(leftId);
|
|
42051
|
+
const right = resolvedResourcesBySurface.get(rightId);
|
|
42052
|
+
const commonPaths = [...left.keys()].filter((path15) => right.has(path15)).sort((a, b) => a.localeCompare(b));
|
|
42053
|
+
for (const resourcePath of commonPaths) {
|
|
42054
|
+
const [leftDigest, rightDigest] = await Promise.all([
|
|
42055
|
+
digestOfTarget(left.get(resourcePath)),
|
|
42056
|
+
digestOfTarget(right.get(resourcePath))
|
|
42057
|
+
]);
|
|
42058
|
+
if (leftDigest === rightDigest) continue;
|
|
42059
|
+
const rightSurface = surfaceMap.get(rightId);
|
|
42060
|
+
const driftReferences = [];
|
|
42061
|
+
const seenReference = /* @__PURE__ */ new Set();
|
|
42062
|
+
for (const surfaceId of [leftId, rightId]) {
|
|
42063
|
+
for (const ref of resourceReferencesBySurface.get(surfaceId)?.get(resourcePath) ?? []) {
|
|
42064
|
+
const key = `${ref.surface}\0${ref.skill}\0${ref.line}`;
|
|
42065
|
+
if (seenReference.has(key)) continue;
|
|
42066
|
+
seenReference.add(key);
|
|
42067
|
+
driftReferences.push({ surface: ref.surface, skill: ref.skill, line: ref.line });
|
|
42068
|
+
}
|
|
42069
|
+
}
|
|
42070
|
+
driftReferences.sort((a, b) => a.surface.localeCompare(b.surface) || a.skill.localeCompare(b.skill) || a.line - b.line);
|
|
42071
|
+
findings.push({
|
|
42072
|
+
host: rightSurface.host,
|
|
42073
|
+
surface: rightId,
|
|
42074
|
+
skill: null,
|
|
42075
|
+
line: null,
|
|
42076
|
+
reference: resourcePath,
|
|
42077
|
+
classification: CLASSIFICATION.RESOURCE_DRIFT,
|
|
42078
|
+
resolutionRoot: rightId,
|
|
42079
|
+
resolvedTarget: resourcePath,
|
|
42080
|
+
surfaces: [leftId, rightId],
|
|
42081
|
+
references: driftReferences,
|
|
42082
|
+
code: FINDING_CODE.RESOURCE_DRIFT
|
|
42083
|
+
});
|
|
42084
|
+
}
|
|
42085
|
+
}
|
|
42086
|
+
}
|
|
42087
|
+
for (const surfaceId of [...skillsBySurface.keys()].sort((a, b) => a.localeCompare(b))) {
|
|
42088
|
+
if (!ADAPTER_SURFACE_PATTERN.test(surfaceId)) continue;
|
|
42089
|
+
const surface = surfaceMap.get(surfaceId);
|
|
42090
|
+
const surfaceRootAbsolute = resolve16(scanRoot2, surfaceId);
|
|
42091
|
+
const referencedTargets = referencedTargetsBySurface.get(surfaceId) ?? /* @__PURE__ */ new Set();
|
|
42092
|
+
const stale = [];
|
|
42093
|
+
for (const skill of skillsBySurface.get(surfaceId)) {
|
|
42094
|
+
const skillDir = resolve16(scanRoot2, dirname7(skill));
|
|
42095
|
+
for (const closureDir of CLOSURE_RESOURCE_DIRS) {
|
|
42096
|
+
const files = [];
|
|
42097
|
+
await collectRegularFiles(join12(skillDir, closureDir), files);
|
|
42098
|
+
for (const absolute of files) {
|
|
42099
|
+
if (referencedTargets.has(absolute)) continue;
|
|
42100
|
+
const relativeResource = relativeStable(surfaceRootAbsolute, absolute);
|
|
42101
|
+
stale.push({
|
|
42102
|
+
host: surface.host,
|
|
42103
|
+
surface: surfaceId,
|
|
42104
|
+
skill,
|
|
42105
|
+
line: null,
|
|
42106
|
+
reference: relativeResource,
|
|
42107
|
+
classification: CLASSIFICATION.STALE_RESOURCE,
|
|
42108
|
+
resolutionRoot: surfaceId,
|
|
42109
|
+
resolvedTarget: relativeResource,
|
|
42110
|
+
code: FINDING_CODE.STALE_RESOURCE
|
|
42111
|
+
});
|
|
42112
|
+
}
|
|
41962
42113
|
}
|
|
41963
42114
|
}
|
|
42115
|
+
stale.sort((a, b) => a.skill.localeCompare(b.skill) || a.resolvedTarget.localeCompare(b.resolvedTarget));
|
|
42116
|
+
findings.push(...stale);
|
|
41964
42117
|
}
|
|
42118
|
+
sourceOnlyReferences.sort((a, b) => a.skill.localeCompare(b.skill) || a.line - b.line || a.reference.localeCompare(b.reference));
|
|
41965
42119
|
if (snapshotError) {
|
|
41966
42120
|
findings.push({
|
|
41967
42121
|
host,
|
|
@@ -41984,18 +42138,29 @@ async function checkSkillResourceClosure({
|
|
|
41984
42138
|
skillCount: skillPaths.length,
|
|
41985
42139
|
referenceCount,
|
|
41986
42140
|
sourceOnlyCount,
|
|
42141
|
+
sourceOnlyReferences,
|
|
41987
42142
|
findings
|
|
41988
42143
|
};
|
|
41989
42144
|
result.receiptDigest = digestDocument(receiptProjection(result));
|
|
41990
42145
|
return result;
|
|
41991
42146
|
}
|
|
41992
|
-
|
|
42147
|
+
function evaluateDeclaredHostSurfaceCoverage(expectedHosts, surfaces) {
|
|
42148
|
+
const missing = [];
|
|
42149
|
+
for (const expectedHost of [...new Set(expectedHosts ?? [])].sort((a, b) => a.localeCompare(b))) {
|
|
42150
|
+
const surface = (surfaces ?? []).find((item) => item.host === expectedHost);
|
|
42151
|
+
if (!surface || !(surface.skillCount >= 1)) {
|
|
42152
|
+
missing.push({ host: expectedHost, skillCount: surface?.skillCount ?? 0 });
|
|
42153
|
+
}
|
|
42154
|
+
}
|
|
42155
|
+
return { passed: missing.length === 0, missing };
|
|
42156
|
+
}
|
|
42157
|
+
var CHECKER_VERSION, BARE_PREFIXES, EXPLICIT_PREFIXES, SOURCE_TREE_PATTERN, MACHINE_ABSOLUTE_PATTERN, HOME_DIRECTORY_PATTERN, ADAPTER_SURFACE_PATTERN, CLOSURE_RESOURCE_DIRS, GLOB_PATTERN, SOURCE_ONLY_MARKER, TRANSPORT_EXCLUSIONS, CLASSIFICATION, FINDING_CODE;
|
|
41993
42158
|
var init_skill_resource_closure = __esm({
|
|
41994
42159
|
"src/core/skill-resource-closure.mjs"() {
|
|
41995
42160
|
init_src();
|
|
41996
42161
|
init_errors();
|
|
41997
42162
|
init_frozen();
|
|
41998
|
-
CHECKER_VERSION = "skill-resource-closure-
|
|
42163
|
+
CHECKER_VERSION = "skill-resource-closure-v2";
|
|
41999
42164
|
BARE_PREFIXES = ["references/", "assets/", "schemas/", "examples/", "scripts/"];
|
|
42000
42165
|
EXPLICIT_PREFIXES = [
|
|
42001
42166
|
"<plugin-root>/",
|
|
@@ -42007,6 +42172,9 @@ var init_skill_resource_closure = __esm({
|
|
|
42007
42172
|
];
|
|
42008
42173
|
SOURCE_TREE_PATTERN = /(?:^|\/)packages\/[A-Za-z0-9._-]+(?:\/|$)/u;
|
|
42009
42174
|
MACHINE_ABSOLUTE_PATTERN = /^(?:\/(?:Users|home|root|tmp|var|etc|opt)(?:\/|$)|[A-Za-z]:[\\/])/u;
|
|
42175
|
+
HOME_DIRECTORY_PATTERN = /^(?:~|\$HOME|\$\{HOME\})\/.+/u;
|
|
42176
|
+
ADAPTER_SURFACE_PATTERN = /^adapters\/([^/]+)$/u;
|
|
42177
|
+
CLOSURE_RESOURCE_DIRS = Object.freeze(["references", "assets", "schemas", "examples", "scripts"]);
|
|
42010
42178
|
GLOB_PATTERN = /[*?\[]/u;
|
|
42011
42179
|
SOURCE_ONLY_MARKER = /(?:\bsource-only\b|仅源码包)/iu;
|
|
42012
42180
|
TRANSPORT_EXCLUSIONS = Object.freeze([
|
|
@@ -42020,7 +42188,10 @@ var init_skill_resource_closure = __esm({
|
|
|
42020
42188
|
PLUGIN_ROOT: "plugin_root",
|
|
42021
42189
|
SOURCE_BACKJUMP: "source_backjump",
|
|
42022
42190
|
MACHINE_ABSOLUTE: "machine_absolute",
|
|
42023
|
-
|
|
42191
|
+
HOME_DIRECTORY: "home_directory",
|
|
42192
|
+
OUT_OF_BOUNDS: "out_of_bounds",
|
|
42193
|
+
RESOURCE_DRIFT: "resource_drift",
|
|
42194
|
+
STALE_RESOURCE: "stale_resource"
|
|
42024
42195
|
});
|
|
42025
42196
|
FINDING_CODE = Object.freeze({
|
|
42026
42197
|
SNAPSHOT_UNSAFE: "SNAPSHOT_UNSAFE",
|
|
@@ -42028,8 +42199,11 @@ var init_skill_resource_closure = __esm({
|
|
|
42028
42199
|
RESOURCE_NOT_REGULAR_FILE: "RESOURCE_NOT_REGULAR_FILE",
|
|
42029
42200
|
SOURCE_BACKJUMP: "SOURCE_BACKJUMP",
|
|
42030
42201
|
MACHINE_ABSOLUTE_PATH: "MACHINE_ABSOLUTE_PATH",
|
|
42202
|
+
HOME_DIRECTORY_SEARCH: "HOME_DIRECTORY_SEARCH",
|
|
42031
42203
|
OUT_OF_BOUNDS: "OUT_OF_BOUNDS",
|
|
42032
|
-
SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED"
|
|
42204
|
+
SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED",
|
|
42205
|
+
RESOURCE_DRIFT: "RESOURCE_DRIFT",
|
|
42206
|
+
STALE_RESOURCE: "STALE_RESOURCE"
|
|
42033
42207
|
});
|
|
42034
42208
|
__name(toPosix, "toPosix");
|
|
42035
42209
|
__name(relativeStable, "relativeStable");
|
|
@@ -42044,12 +42218,14 @@ var init_skill_resource_closure = __esm({
|
|
|
42044
42218
|
__name(stripExplicitPrefix, "stripExplicitPrefix");
|
|
42045
42219
|
__name(classifyReference, "classifyReference");
|
|
42046
42220
|
__name(inspectRegularFile, "inspectRegularFile");
|
|
42221
|
+
__name(collectRegularFiles, "collectRegularFiles");
|
|
42047
42222
|
__name(inferSurfaceHost, "inferSurfaceHost");
|
|
42048
42223
|
__name(receiptProjection, "receiptProjection");
|
|
42049
42224
|
__name(createSkillResourceClosureReceipt, "createSkillResourceClosureReceipt");
|
|
42050
42225
|
__name(assertSkillResourceClosureReceipt, "assertSkillResourceClosureReceipt");
|
|
42051
42226
|
__name(evaluateConsumerSkillResourceClosureReceipts, "evaluateConsumerSkillResourceClosureReceipts");
|
|
42052
42227
|
__name(checkSkillResourceClosure, "checkSkillResourceClosure");
|
|
42228
|
+
__name(evaluateDeclaredHostSurfaceCoverage, "evaluateDeclaredHostSurfaceCoverage");
|
|
42053
42229
|
}
|
|
42054
42230
|
});
|
|
42055
42231
|
|
|
@@ -72000,7 +72176,7 @@ var require_escape3 = __commonJS({
|
|
|
72000
72176
|
var require_lib36 = __commonJS({
|
|
72001
72177
|
"../../node_modules/.pnpm/@npmcli+promise-spawn@8.0.3/node_modules/@npmcli/promise-spawn/lib/index.js"(exports, module) {
|
|
72002
72178
|
"use strict";
|
|
72003
|
-
var { spawn:
|
|
72179
|
+
var { spawn: spawn5 } = __require("child_process");
|
|
72004
72180
|
var os4 = __require("os");
|
|
72005
72181
|
var which = require_lib35();
|
|
72006
72182
|
var escape2 = require_escape3();
|
|
@@ -72027,7 +72203,7 @@ var require_lib36 = __commonJS({
|
|
|
72027
72203
|
const resultError = getResult(erOpts);
|
|
72028
72204
|
reject(Object.assign(er, resultError));
|
|
72029
72205
|
}, "rejectWithOpts");
|
|
72030
|
-
const proc =
|
|
72206
|
+
const proc = spawn5(cmd, args2, opts);
|
|
72031
72207
|
promise.stdin = proc.stdin;
|
|
72032
72208
|
promise.process = proc;
|
|
72033
72209
|
proc.on("error", rejectWithOpts);
|
|
@@ -72533,7 +72709,7 @@ var require_which3 = __commonJS({
|
|
|
72533
72709
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/spawn.js
|
|
72534
72710
|
var require_spawn = __commonJS({
|
|
72535
72711
|
"../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/spawn.js"(exports, module) {
|
|
72536
|
-
var
|
|
72712
|
+
var spawn5 = require_lib36();
|
|
72537
72713
|
var promiseRetry = require_promise_retry();
|
|
72538
72714
|
var { log } = require_lib21();
|
|
72539
72715
|
var makeError = require_make_error();
|
|
@@ -72558,7 +72734,7 @@ var require_spawn = __commonJS({
|
|
|
72558
72734
|
if (number !== 1) {
|
|
72559
72735
|
log.silly("git", `Retrying git command: ${args2.join(" ")} attempt # ${number}`);
|
|
72560
72736
|
}
|
|
72561
|
-
return
|
|
72737
|
+
return spawn5(gitPath, args2, makeOpts(opts)).catch((er) => {
|
|
72562
72738
|
const gitError = makeError(er);
|
|
72563
72739
|
if (!gitError.shouldRetry(number)) {
|
|
72564
72740
|
throw gitError;
|
|
@@ -72682,7 +72858,7 @@ var require_lines_to_revs = __commonJS({
|
|
|
72682
72858
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/revs.js
|
|
72683
72859
|
var require_revs = __commonJS({
|
|
72684
72860
|
"../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/revs.js"(exports, module) {
|
|
72685
|
-
var
|
|
72861
|
+
var spawn5 = require_spawn();
|
|
72686
72862
|
var { LRUCache } = require_commonjs3();
|
|
72687
72863
|
var linesToRevs = require_lines_to_revs();
|
|
72688
72864
|
var revsCache = new LRUCache({
|
|
@@ -72696,7 +72872,7 @@ var require_revs = __commonJS({
|
|
|
72696
72872
|
return cached;
|
|
72697
72873
|
}
|
|
72698
72874
|
}
|
|
72699
|
-
const { stdout } = await
|
|
72875
|
+
const { stdout } = await spawn5(["ls-remote", repo], opts);
|
|
72700
72876
|
const revs = linesToRevs(stdout.trim().split("\n"));
|
|
72701
72877
|
revsCache.set(repo, revs);
|
|
72702
72878
|
return revs;
|
|
@@ -73240,7 +73416,7 @@ var require_clone2 = __commonJS({
|
|
|
73240
73416
|
var { parse: parse2 } = __require("url");
|
|
73241
73417
|
var path15 = __require("path");
|
|
73242
73418
|
var getRevs = require_revs();
|
|
73243
|
-
var
|
|
73419
|
+
var spawn5 = require_spawn();
|
|
73244
73420
|
var { isWindows } = require_utils4();
|
|
73245
73421
|
var pickManifest = require_lib39();
|
|
73246
73422
|
var fs = __require("fs/promises");
|
|
@@ -73294,7 +73470,7 @@ var require_clone2 = __commonJS({
|
|
|
73294
73470
|
var other = /* @__PURE__ */ __name((repo, revDoc, target, opts) => {
|
|
73295
73471
|
const shallow = maybeShallow(repo, opts);
|
|
73296
73472
|
const fetchOrigin = ["fetch", "origin", revDoc.rawRef].concat(shallow ? ["--depth=1"] : []);
|
|
73297
|
-
const git3 = /* @__PURE__ */ __name((args2) =>
|
|
73473
|
+
const git3 = /* @__PURE__ */ __name((args2) => spawn5(args2, { ...opts, cwd: target }), "git");
|
|
73298
73474
|
return fs.mkdir(target, { recursive: true }).then(() => git3(["init"])).then(() => isWindows(opts) ? git3(["config", "--local", "--add", "core.longpaths", "true"]) : null).then(() => git3(["remote", "add", "origin", repo])).then(() => git3(fetchOrigin)).then(() => git3(["checkout", revDoc.sha])).then(() => updateSubmodules(target, opts)).then(() => revDoc.sha);
|
|
73299
73475
|
}, "other");
|
|
73300
73476
|
var branch = /* @__PURE__ */ __name((repo, revDoc, target, opts) => {
|
|
@@ -73312,7 +73488,7 @@ var require_clone2 = __commonJS({
|
|
|
73312
73488
|
if (isWindows(opts)) {
|
|
73313
73489
|
args2.push("--config", "core.longpaths=true");
|
|
73314
73490
|
}
|
|
73315
|
-
return
|
|
73491
|
+
return spawn5(args2, opts).then(() => revDoc.sha);
|
|
73316
73492
|
}, "branch");
|
|
73317
73493
|
var plain = /* @__PURE__ */ __name((repo, revDoc, target, opts) => {
|
|
73318
73494
|
const args2 = [
|
|
@@ -73327,14 +73503,14 @@ var require_clone2 = __commonJS({
|
|
|
73327
73503
|
if (isWindows(opts)) {
|
|
73328
73504
|
args2.push("--config", "core.longpaths=true");
|
|
73329
73505
|
}
|
|
73330
|
-
return
|
|
73506
|
+
return spawn5(args2, opts).then(() => revDoc.sha);
|
|
73331
73507
|
}, "plain");
|
|
73332
73508
|
var updateSubmodules = /* @__PURE__ */ __name(async (target, opts) => {
|
|
73333
73509
|
const hasSubmodules = await fs.stat(`${target}/.gitmodules`).then(() => true).catch(() => false);
|
|
73334
73510
|
if (!hasSubmodules) {
|
|
73335
73511
|
return null;
|
|
73336
73512
|
}
|
|
73337
|
-
return
|
|
73513
|
+
return spawn5([
|
|
73338
73514
|
"submodule",
|
|
73339
73515
|
"update",
|
|
73340
73516
|
"-q",
|
|
@@ -73345,7 +73521,7 @@ var require_clone2 = __commonJS({
|
|
|
73345
73521
|
var unresolved = /* @__PURE__ */ __name((repo, ref, target, opts) => {
|
|
73346
73522
|
const lp = isWindows(opts) ? ["--config", "core.longpaths=true"] : [];
|
|
73347
73523
|
const cloneArgs = ["clone", "--mirror", "-q", repo, target + "/.git"];
|
|
73348
|
-
const git3 = /* @__PURE__ */ __name((args2) =>
|
|
73524
|
+
const git3 = /* @__PURE__ */ __name((args2) => spawn5(args2, { ...opts, cwd: target }), "git");
|
|
73349
73525
|
return fs.mkdir(target, { recursive: true }).then(() => git3(cloneArgs.concat(lp))).then(() => git3(["init"])).then(() => git3(["checkout", ref])).then(() => updateSubmodules(target, opts)).then(() => git3(["rev-parse", "--revs-only", "HEAD"])).then(({ stdout }) => stdout.trim());
|
|
73350
73526
|
}, "unresolved");
|
|
73351
73527
|
}
|
|
@@ -73382,8 +73558,8 @@ var require_find = __commonJS({
|
|
|
73382
73558
|
// ../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/is-clean.js
|
|
73383
73559
|
var require_is_clean = __commonJS({
|
|
73384
73560
|
"../../node_modules/.pnpm/@npmcli+git@6.0.3/node_modules/@npmcli/git/lib/is-clean.js"(exports, module) {
|
|
73385
|
-
var
|
|
73386
|
-
module.exports = (opts = {}) =>
|
|
73561
|
+
var spawn5 = require_spawn();
|
|
73562
|
+
module.exports = (opts = {}) => spawn5(["status", "--porcelain=v1", "-uno"], opts).then((res) => !res.stdout.trim().split(/\r?\n+/).map((l) => l.trim()).filter((l) => l).length);
|
|
73387
73563
|
}
|
|
73388
73564
|
});
|
|
73389
73565
|
|
|
@@ -97074,7 +97250,11 @@ async function prepareRelease(options) {
|
|
|
97074
97250
|
snapshotDir: manifest.outputDir,
|
|
97075
97251
|
host: "root"
|
|
97076
97252
|
});
|
|
97077
|
-
const receipt = createSkillResourceClosureReceipt(closureResult, {
|
|
97253
|
+
const receipt = createSkillResourceClosureReceipt(closureResult, {
|
|
97254
|
+
unitId: unit.id,
|
|
97255
|
+
preparedAt: freezeTimestamp ?? null,
|
|
97256
|
+
exitCode: 0
|
|
97257
|
+
});
|
|
97078
97258
|
skillResourceClosureResults.push(receipt);
|
|
97079
97259
|
if (closureResult.findings.length > 0) {
|
|
97080
97260
|
await evidence.append({
|
|
@@ -97087,7 +97267,10 @@ async function prepareRelease(options) {
|
|
|
97087
97267
|
line: f.line,
|
|
97088
97268
|
reference: f.reference,
|
|
97089
97269
|
classification: f.classification,
|
|
97090
|
-
code: f.code
|
|
97270
|
+
code: f.code,
|
|
97271
|
+
// D4: RESOURCE_DRIFT findings localize via references (the
|
|
97272
|
+
// finding's own skill/line stay null for a cross-surface drift).
|
|
97273
|
+
...f.references ? { references: f.references } : {}
|
|
97091
97274
|
}))
|
|
97092
97275
|
});
|
|
97093
97276
|
throw new ReleaseError(
|
|
@@ -97100,6 +97283,33 @@ async function prepareRelease(options) {
|
|
|
97100
97283
|
}
|
|
97101
97284
|
);
|
|
97102
97285
|
}
|
|
97286
|
+
const expectedHosts = (unit.distributions ?? []).map((distribution) => PLATFORMS.find((platform) => platform.distributionType === distribution.type)).filter(Boolean).map((platform) => platform.buildAdapter.name);
|
|
97287
|
+
const hostCoverage = evaluateDeclaredHostSurfaceCoverage(
|
|
97288
|
+
expectedHosts,
|
|
97289
|
+
closureResult.surfaces
|
|
97290
|
+
);
|
|
97291
|
+
if (!hostCoverage.passed) {
|
|
97292
|
+
await evidence.append({
|
|
97293
|
+
phase: "skill-resource-closure",
|
|
97294
|
+
status: "blocking",
|
|
97295
|
+
unitId: unit.id,
|
|
97296
|
+
reason: "declared-host-surface-missing",
|
|
97297
|
+
missingHosts: hostCoverage.missing
|
|
97298
|
+
});
|
|
97299
|
+
throw new ReleaseError(
|
|
97300
|
+
GATE_FAILED,
|
|
97301
|
+
`skill resource closure gate failed for unit "${unit.id}": declared host surface(s) missing or empty: ${hostCoverage.missing.map((item) => item.host).join(", ")}`,
|
|
97302
|
+
{
|
|
97303
|
+
unitId: unit.id,
|
|
97304
|
+
missingHosts: hostCoverage.missing,
|
|
97305
|
+
observedSurfaces: closureResult.surfaces.map((surface) => ({
|
|
97306
|
+
id: surface.id,
|
|
97307
|
+
host: surface.host,
|
|
97308
|
+
skillCount: surface.skillCount
|
|
97309
|
+
}))
|
|
97310
|
+
}
|
|
97311
|
+
);
|
|
97312
|
+
}
|
|
97103
97313
|
await evidence.append({
|
|
97104
97314
|
phase: "skill-resource-closure",
|
|
97105
97315
|
status: "completed",
|
|
@@ -97109,6 +97319,10 @@ async function prepareRelease(options) {
|
|
|
97109
97319
|
skillCount: receipt.skillCount,
|
|
97110
97320
|
referenceCount: closureResult.referenceCount,
|
|
97111
97321
|
sourceOnlyCount: closureResult.sourceOnlyCount,
|
|
97322
|
+
// D2: per-reference exemption detail for approval/audit review —
|
|
97323
|
+
// evidence-layer only; the receipt object (and its digest binding)
|
|
97324
|
+
// is intentionally left unchanged.
|
|
97325
|
+
sourceOnlyReferences: closureResult.sourceOnlyReferences,
|
|
97112
97326
|
findingCount: 0,
|
|
97113
97327
|
receiptDigest: closureResult.receiptDigest
|
|
97114
97328
|
});
|
|
@@ -98779,7 +98993,11 @@ async function publishRelease(options) {
|
|
|
98779
98993
|
{ unitId, findings: closureResult.findings }
|
|
98780
98994
|
);
|
|
98781
98995
|
}
|
|
98782
|
-
const observed = createSkillResourceClosureReceipt(closureResult, {
|
|
98996
|
+
const observed = createSkillResourceClosureReceipt(closureResult, {
|
|
98997
|
+
unitId,
|
|
98998
|
+
preparedAt: expected.preparedAt ?? null,
|
|
98999
|
+
exitCode: expected.exitCode ?? 0
|
|
99000
|
+
});
|
|
98783
99001
|
assertSkillResourceClosureReceipt(expected, observed, `unit "${unitId}"`);
|
|
98784
99002
|
}
|
|
98785
99003
|
await evidence.append({
|
|
@@ -107381,13 +107599,14 @@ __export(lineage_exports, {
|
|
|
107381
107599
|
listReleaseTags: () => listReleaseTags,
|
|
107382
107600
|
objectExists: () => objectExists,
|
|
107383
107601
|
parseArgs: () => parseArgs,
|
|
107602
|
+
parseCommitIdent: () => parseCommitIdent,
|
|
107384
107603
|
parseReleaseTag: () => parseReleaseTag,
|
|
107385
107604
|
parseSemverVersion: () => parseSemverVersion2,
|
|
107386
107605
|
readCommitMeta: () => readCommitMeta,
|
|
107387
107606
|
rebuildLineage: () => rebuildLineage,
|
|
107388
107607
|
runLineageCommand: () => runLineageCommand
|
|
107389
107608
|
});
|
|
107390
|
-
import { execFile as execFileCb16 } from "node:child_process";
|
|
107609
|
+
import { execFile as execFileCb16, spawn as spawn4 } from "node:child_process";
|
|
107391
107610
|
import { promisify as promisify20 } from "node:util";
|
|
107392
107611
|
function parseSemverVersion2(version) {
|
|
107393
107612
|
if (typeof version !== "string") {
|
|
@@ -107441,6 +107660,26 @@ async function git2(root, args2, options = {}) {
|
|
|
107441
107660
|
});
|
|
107442
107661
|
return stdout.trim();
|
|
107443
107662
|
}
|
|
107663
|
+
async function gitRaw(root, args2, options = {}) {
|
|
107664
|
+
const { stdout } = await execFile17("git", args2, {
|
|
107665
|
+
cwd: root,
|
|
107666
|
+
encoding: "utf8",
|
|
107667
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
107668
|
+
...options
|
|
107669
|
+
});
|
|
107670
|
+
return stdout;
|
|
107671
|
+
}
|
|
107672
|
+
function parseCommitIdent(line) {
|
|
107673
|
+
if (typeof line !== "string") {
|
|
107674
|
+
throw new Error(`commit ident line must be a string, got ${typeof line}`);
|
|
107675
|
+
}
|
|
107676
|
+
const match = line.match(/^(.*) <([^>]*)> (\d+) ([+-]\d{4})$/);
|
|
107677
|
+
if (!match) {
|
|
107678
|
+
throw new Error(`unparseable commit ident line (fail-closed): "${line}"`);
|
|
107679
|
+
}
|
|
107680
|
+
const [, name, email, ts, tz] = match;
|
|
107681
|
+
return { name, email, ts, tz };
|
|
107682
|
+
}
|
|
107444
107683
|
async function getLocalTags(root) {
|
|
107445
107684
|
const output = await git2(root, ["tag", "-l", "--format=%(refname:short) %(objectname)"]);
|
|
107446
107685
|
if (!output) return [];
|
|
@@ -107473,40 +107712,32 @@ async function objectExists(root, sha) {
|
|
|
107473
107712
|
}
|
|
107474
107713
|
}
|
|
107475
107714
|
async function readCommitMeta(root, commitSha) {
|
|
107476
|
-
const raw = await
|
|
107477
|
-
const
|
|
107478
|
-
|
|
107479
|
-
|
|
107480
|
-
let inBody = false;
|
|
107481
|
-
for (const line of lines) {
|
|
107482
|
-
if (inBody) {
|
|
107483
|
-
messageLines.push(line);
|
|
107484
|
-
continue;
|
|
107485
|
-
}
|
|
107486
|
-
if (line === "") {
|
|
107487
|
-
inBody = true;
|
|
107488
|
-
continue;
|
|
107489
|
-
}
|
|
107490
|
-
const colon = line.indexOf(" ");
|
|
107491
|
-
if (colon === -1) continue;
|
|
107492
|
-
const key = line.slice(0, colon);
|
|
107493
|
-
const value = line.slice(colon + 1);
|
|
107494
|
-
headers[key] = value;
|
|
107715
|
+
const raw = await gitRaw(root, ["cat-file", "commit", commitSha]);
|
|
107716
|
+
const separator = raw.indexOf("\n\n");
|
|
107717
|
+
if (separator === -1) {
|
|
107718
|
+
throw new Error(`malformed commit object ${commitSha}: missing header/message separator`);
|
|
107495
107719
|
}
|
|
107496
|
-
const message =
|
|
107497
|
-
const
|
|
107498
|
-
const
|
|
107720
|
+
const message = raw.slice(separator + 2);
|
|
107721
|
+
const headers = {};
|
|
107722
|
+
for (const line of raw.slice(0, separator).split("\n")) {
|
|
107723
|
+
if (line.startsWith(" ")) continue;
|
|
107724
|
+
const space = line.indexOf(" ");
|
|
107725
|
+
if (space === -1) continue;
|
|
107726
|
+
headers[line.slice(0, space)] = line.slice(space + 1);
|
|
107727
|
+
}
|
|
107728
|
+
const author = parseCommitIdent(headers.author ?? "");
|
|
107729
|
+
const committer = parseCommitIdent(headers.committer ?? "");
|
|
107499
107730
|
return {
|
|
107500
107731
|
message,
|
|
107501
107732
|
author: {
|
|
107502
|
-
name:
|
|
107503
|
-
email:
|
|
107504
|
-
date:
|
|
107733
|
+
name: author.name,
|
|
107734
|
+
email: author.email,
|
|
107735
|
+
date: `${author.ts} ${author.tz}`
|
|
107505
107736
|
},
|
|
107506
107737
|
committer: {
|
|
107507
|
-
name:
|
|
107508
|
-
email:
|
|
107509
|
-
date:
|
|
107738
|
+
name: committer.name,
|
|
107739
|
+
email: committer.email,
|
|
107740
|
+
date: `${committer.ts} ${committer.tz}`
|
|
107510
107741
|
}
|
|
107511
107742
|
};
|
|
107512
107743
|
}
|
|
@@ -107591,7 +107822,7 @@ async function analyzeLineage(root) {
|
|
|
107591
107822
|
async function createRebuiltCommit(root, treeSha, parentSha, message, identity2) {
|
|
107592
107823
|
const args2 = ["commit-tree", treeSha];
|
|
107593
107824
|
if (parentSha) args2.push("-p", parentSha);
|
|
107594
|
-
args2.push("-
|
|
107825
|
+
args2.push("-F", "-");
|
|
107595
107826
|
const env = {
|
|
107596
107827
|
...process.env,
|
|
107597
107828
|
GIT_AUTHOR_NAME: identity2.author.name,
|
|
@@ -107601,8 +107832,31 @@ async function createRebuiltCommit(root, treeSha, parentSha, message, identity2)
|
|
|
107601
107832
|
GIT_COMMITTER_EMAIL: identity2.committer.email,
|
|
107602
107833
|
GIT_COMMITTER_DATE: identity2.committer.date
|
|
107603
107834
|
};
|
|
107604
|
-
|
|
107605
|
-
|
|
107835
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
107836
|
+
const child = spawn4("git", args2, { cwd: root, env });
|
|
107837
|
+
let stdout = "";
|
|
107838
|
+
let stderr = "";
|
|
107839
|
+
child.stdout.setEncoding("utf8");
|
|
107840
|
+
child.stderr.setEncoding("utf8");
|
|
107841
|
+
child.stdout.on("data", (chunk) => {
|
|
107842
|
+
stdout += chunk;
|
|
107843
|
+
});
|
|
107844
|
+
child.stderr.on("data", (chunk) => {
|
|
107845
|
+
stderr += chunk;
|
|
107846
|
+
});
|
|
107847
|
+
child.on("error", rejectPromise);
|
|
107848
|
+
child.on("close", (code) => {
|
|
107849
|
+
if (code !== 0) {
|
|
107850
|
+
rejectPromise(new Error(`git commit-tree failed (exit ${code}): ${stderr.trim()}`));
|
|
107851
|
+
return;
|
|
107852
|
+
}
|
|
107853
|
+
resolvePromise(stdout.trim());
|
|
107854
|
+
});
|
|
107855
|
+
child.stdin.on("error", () => {
|
|
107856
|
+
});
|
|
107857
|
+
child.stdin.write(message);
|
|
107858
|
+
child.stdin.end();
|
|
107859
|
+
});
|
|
107606
107860
|
}
|
|
107607
107861
|
async function rebuildLineage(root, options = {}) {
|
|
107608
107862
|
const { dryRun = false } = options;
|
|
@@ -107729,6 +107983,8 @@ var init_lineage = __esm({
|
|
|
107729
107983
|
__name(compareSemverVersions2, "compareSemverVersions");
|
|
107730
107984
|
__name(parseReleaseTag, "parseReleaseTag");
|
|
107731
107985
|
__name(git2, "git");
|
|
107986
|
+
__name(gitRaw, "gitRaw");
|
|
107987
|
+
__name(parseCommitIdent, "parseCommitIdent");
|
|
107732
107988
|
__name(getLocalTags, "getLocalTags");
|
|
107733
107989
|
__name(listReleaseTags, "listReleaseTags");
|
|
107734
107990
|
__name(getCommitTreeHash, "getCommitTreeHash");
|