release-skill 0.9.35 → 0.9.37
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/plugin.json +1 -1
- package/.codebuddy-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +2 -2
- package/.cursor-plugin/plugin.json +1 -1
- package/.kimi-plugin/plugin.json +1 -1
- package/.qoder-plugin/plugin.json +1 -1
- package/CHANGELOG.md +45 -0
- package/INSTALL.md +2 -2
- package/INSTALL.zh-CN.md +2 -2
- package/README.md +24 -9
- package/README.zh-CN.md +15 -9
- package/adapters/claude/.claude-plugin/plugin.json +1 -1
- package/adapters/claude/bin/release-skill.bundle.mjs +270 -58
- package/adapters/claude/schemas/.render-manifest.json +6 -2
- package/adapters/claude/skills/release-config/SKILL.md +36 -41
- package/adapters/claude/skills/release-docs/SKILL.md +38 -35
- package/adapters/claude/skills/release-finish/SKILL.md +2 -2
- package/adapters/claude/skills/release-help/SKILL.md +51 -41
- package/adapters/claude/skills/release-marketplace/SKILL.md +38 -46
- package/adapters/claude/skills/release-prepare/SKILL.md +19 -28
- package/adapters/claude/skills/release-publish/SKILL.md +29 -45
- package/adapters/codex/.codex-plugin/plugin.json +2 -2
- package/adapters/codex/bin/release-skill.bundle.mjs +270 -58
- package/adapters/codex/schemas/.render-manifest.json +6 -2
- package/adapters/codex/skills/release-config/SKILL.md +36 -41
- package/adapters/codex/skills/release-docs/SKILL.md +38 -35
- package/adapters/codex/skills/release-finish/SKILL.md +2 -2
- package/adapters/codex/skills/release-help/SKILL.md +51 -41
- package/adapters/codex/skills/release-marketplace/SKILL.md +38 -46
- package/adapters/codex/skills/release-prepare/SKILL.md +19 -28
- package/adapters/codex/skills/release-publish/SKILL.md +29 -45
- package/adapters/cursor/.cursor-plugin/plugin.json +1 -1
- package/adapters/cursor/bin/release-skill.bundle.mjs +270 -58
- package/adapters/cursor/schemas/.render-manifest.json +6 -2
- package/adapters/cursor/skills/release-config/SKILL.md +36 -41
- package/adapters/cursor/skills/release-docs/SKILL.md +38 -35
- package/adapters/cursor/skills/release-finish/SKILL.md +2 -2
- package/adapters/cursor/skills/release-help/SKILL.md +51 -41
- package/adapters/cursor/skills/release-marketplace/SKILL.md +38 -46
- package/adapters/cursor/skills/release-prepare/SKILL.md +19 -28
- package/adapters/cursor/skills/release-publish/SKILL.md +29 -45
- package/adapters/kimi/.kimi-plugin/plugin.json +1 -1
- package/adapters/kimi/bin/release-skill.bundle.mjs +270 -58
- package/adapters/kimi/schemas/.render-manifest.json +6 -2
- package/adapters/kimi/skills/release-config/SKILL.md +36 -41
- package/adapters/kimi/skills/release-docs/SKILL.md +38 -35
- package/adapters/kimi/skills/release-finish/SKILL.md +2 -2
- package/adapters/kimi/skills/release-help/SKILL.md +51 -41
- package/adapters/kimi/skills/release-marketplace/SKILL.md +38 -46
- package/adapters/kimi/skills/release-prepare/SKILL.md +19 -28
- package/adapters/kimi/skills/release-publish/SKILL.md +29 -45
- package/adapters/qoder/.qoder-plugin/plugin.json +1 -1
- package/adapters/qoder/bin/release-skill.bundle.mjs +270 -58
- package/adapters/qoder/schemas/.render-manifest.json +6 -2
- package/adapters/qoder/skills/release-config/SKILL.md +36 -41
- package/adapters/qoder/skills/release-docs/SKILL.md +38 -35
- package/adapters/qoder/skills/release-finish/SKILL.md +2 -2
- package/adapters/qoder/skills/release-help/SKILL.md +51 -41
- package/adapters/qoder/skills/release-marketplace/SKILL.md +38 -46
- package/adapters/qoder/skills/release-prepare/SKILL.md +19 -28
- package/adapters/qoder/skills/release-publish/SKILL.md +29 -45
- package/adapters/workbuddy/.codebuddy-plugin/plugin.json +1 -1
- package/adapters/workbuddy/bin/release-skill.bundle.mjs +270 -58
- package/adapters/workbuddy/schemas/.render-manifest.json +6 -2
- package/adapters/workbuddy/skills/release-config/SKILL.md +36 -41
- package/adapters/workbuddy/skills/release-docs/SKILL.md +38 -35
- package/adapters/workbuddy/skills/release-finish/SKILL.md +2 -2
- package/adapters/workbuddy/skills/release-help/SKILL.md +51 -41
- package/adapters/workbuddy/skills/release-marketplace/SKILL.md +38 -46
- package/adapters/workbuddy/skills/release-prepare/SKILL.md +19 -28
- package/adapters/workbuddy/skills/release-publish/SKILL.md +29 -45
- package/bin/release-skill.bundle.mjs +270 -58
- package/package.json +1 -1
- package/platform-manifest.json +4 -4
- package/references/.render-manifest.json +2 -2
- package/references/02-project-config.md +91 -8
- package/schemas/.render-manifest.json +6 -2
- package/skills/release-config/SKILL.md +36 -41
- package/skills/release-docs/SKILL.md +38 -35
- package/skills/release-finish/SKILL.md +2 -2
- package/skills/release-help/SKILL.md +51 -41
- package/skills/release-marketplace/SKILL.md +38 -46
- package/skills/release-prepare/SKILL.md +19 -28
- package/skills/release-publish/SKILL.md +29 -45
- package/skills-src/release-config/SKILL.md +36 -41
- package/skills-src/release-docs/SKILL.md +38 -35
- package/skills-src/release-finish/SKILL.md +2 -2
- package/skills-src/release-help/SKILL.md +51 -41
- package/skills-src/release-marketplace/SKILL.md +38 -46
- package/skills-src/release-prepare/SKILL.md +19 -28
- package/skills-src/release-publish/SKILL.md +29 -45
- package/src/adapters/plugin-marketplace.mjs +152 -43
- package/src/commands/post-release-local.mjs +41 -22
- package/src/commands/verify.mjs +123 -17
- package/src/core/skill-resource-closure.mjs +1 -1
|
@@ -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.9.
|
|
12
|
+
const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.9.37"});
|
|
13
13
|
// Build-time source digest for the BUNDLE_STALE freshness gate (see above).
|
|
14
|
-
const __bundleSourceDigest = "
|
|
14
|
+
const __bundleSourceDigest = "6eb7b6560da84252426dc5cfc81297a3d5d6d6101aecb1a8fbf3f35402892715";
|
|
15
15
|
|
|
16
16
|
var __create = Object.create;
|
|
17
17
|
var __defProp = Object.defineProperty;
|
|
@@ -113912,6 +113912,66 @@ function normalizeCodeBuddySkillsRel(skillsRaw) {
|
|
|
113912
113912
|
}
|
|
113913
113913
|
return rel;
|
|
113914
113914
|
}
|
|
113915
|
+
async function resolveCodexEntrySkillFile(pluginRoot, entrySkill, pluginName) {
|
|
113916
|
+
const { normalizeGenericSkillsRel: normalizeGenericSkillsRel2 } = await init_surface_host_bindings().then(() => surface_host_bindings_exports);
|
|
113917
|
+
if (!entrySkill || typeof entrySkill !== "string" || !SAFE_ID_RE.test(entrySkill)) {
|
|
113918
|
+
throw new Error(`unsafe entrySkill: "${entrySkill}"`);
|
|
113919
|
+
}
|
|
113920
|
+
const platform = getPlatform("codex");
|
|
113921
|
+
const manifestPath = await resolveContained(pluginRoot, platform.manifestPaths.plugin);
|
|
113922
|
+
let manifest;
|
|
113923
|
+
try {
|
|
113924
|
+
manifest = JSON.parse(await readFile26(manifestPath, "utf8"));
|
|
113925
|
+
} catch (err) {
|
|
113926
|
+
throw new Error(`Codex plugin manifest cannot be read: ${err.message}`);
|
|
113927
|
+
}
|
|
113928
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
113929
|
+
throw new Error("Codex plugin manifest must be an object");
|
|
113930
|
+
}
|
|
113931
|
+
const skillsRel = Object.hasOwn(manifest, "skills") ? normalizeGenericSkillsRel2(manifest.skills) : "skills";
|
|
113932
|
+
const skillsRoot = await resolveContained(pluginRoot, skillsRel);
|
|
113933
|
+
let skillsRootStat;
|
|
113934
|
+
try {
|
|
113935
|
+
skillsRootStat = await lstat37(skillsRoot);
|
|
113936
|
+
} catch {
|
|
113937
|
+
throw new Error(`Codex manifest skills root does not exist: ${manifest.skills ?? skillsRel}`);
|
|
113938
|
+
}
|
|
113939
|
+
if (skillsRootStat.isSymbolicLink() || !skillsRootStat.isDirectory()) {
|
|
113940
|
+
throw new Error(`Codex manifest skills root must be a real directory: ${manifest.skills ?? skillsRel}`);
|
|
113941
|
+
}
|
|
113942
|
+
const findCandidate = /* @__PURE__ */ __name(async (skillDirName) => {
|
|
113943
|
+
const skillDir = await resolveContained(pluginRoot, `${skillsRel}/${skillDirName}`);
|
|
113944
|
+
let skillDirStat;
|
|
113945
|
+
try {
|
|
113946
|
+
skillDirStat = await lstat37(skillDir);
|
|
113947
|
+
} catch (err) {
|
|
113948
|
+
if (err?.code === "ENOENT") return null;
|
|
113949
|
+
throw err;
|
|
113950
|
+
}
|
|
113951
|
+
if (skillDirStat.isSymbolicLink() || !skillDirStat.isDirectory()) {
|
|
113952
|
+
throw new Error(`Codex entry skill directory must be a real directory: ${skillsRel}/${skillDirName}`);
|
|
113953
|
+
}
|
|
113954
|
+
const skillFile = await resolveContained(pluginRoot, `${skillsRel}/${skillDirName}/SKILL.md`);
|
|
113955
|
+
let skillStat;
|
|
113956
|
+
try {
|
|
113957
|
+
skillStat = await lstat37(skillFile);
|
|
113958
|
+
} catch (err) {
|
|
113959
|
+
if (err?.code === "ENOENT") return null;
|
|
113960
|
+
throw err;
|
|
113961
|
+
}
|
|
113962
|
+
if (skillStat.isSymbolicLink() || !skillStat.isFile()) {
|
|
113963
|
+
throw new Error(`Codex entry skill must be a regular non-symlink file: ${skillsRel}/${skillDirName}/SKILL.md`);
|
|
113964
|
+
}
|
|
113965
|
+
return skillFile;
|
|
113966
|
+
}, "findCandidate");
|
|
113967
|
+
const shortNameEntry = await findCandidate(entrySkill);
|
|
113968
|
+
if (shortNameEntry) return shortNameEntry;
|
|
113969
|
+
if (pluginName && SAFE_ID_RE.test(pluginName)) {
|
|
113970
|
+
const prefixedEntry = await findCandidate(`${pluginName}-${entrySkill}`);
|
|
113971
|
+
if (prefixedEntry) return prefixedEntry;
|
|
113972
|
+
}
|
|
113973
|
+
throw new Error(`Codex entry skill not found: ${skillsRel}/${entrySkill}/SKILL.md`);
|
|
113974
|
+
}
|
|
113915
113975
|
async function resolveCodeBuddyEntrySkillFile(pluginRootReal, manifest, entrySkill) {
|
|
113916
113976
|
if (!entrySkill || typeof entrySkill !== "string" || !SAFE_ID_RE.test(entrySkill)) {
|
|
113917
113977
|
throw new Error(`unsafe entrySkill: "${entrySkill}"`);
|
|
@@ -115067,6 +115127,17 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
115067
115127
|
error: `entry skill not resolvable in snapshot: ${entryErr.message}`
|
|
115068
115128
|
});
|
|
115069
115129
|
}
|
|
115130
|
+
} else if (consumer === "codex") {
|
|
115131
|
+
const pluginRootForSkill = pluginRootForEntrySkill || snapshotDirReal;
|
|
115132
|
+
try {
|
|
115133
|
+
await resolveCodexEntrySkillFile(pluginRootForSkill, action.entrySkill, action.plugin);
|
|
115134
|
+
} catch (entryErr) {
|
|
115135
|
+
return createResult({
|
|
115136
|
+
actionType,
|
|
115137
|
+
status: ActionStatus.PREFLIGHT_FAILED,
|
|
115138
|
+
error: `entry skill not resolvable in snapshot: ${entryErr.message}`
|
|
115139
|
+
});
|
|
115140
|
+
}
|
|
115070
115141
|
} else {
|
|
115071
115142
|
const pluginRootForSkill = pluginRootForEntrySkill || snapshotDirReal;
|
|
115072
115143
|
let entrySkillFile = resolve22(pluginRootForSkill, "skills", action.entrySkill, "SKILL.md");
|
|
@@ -116181,42 +116252,59 @@ function createPluginMarketplaceAdapter(deps = {}) {
|
|
|
116181
116252
|
}
|
|
116182
116253
|
});
|
|
116183
116254
|
}
|
|
116184
|
-
|
|
116185
|
-
|
|
116186
|
-
|
|
116187
|
-
|
|
116188
|
-
|
|
116189
|
-
|
|
116255
|
+
if (consumer === "codex") {
|
|
116256
|
+
try {
|
|
116257
|
+
await resolveCodexEntrySkillFile(installPath, action.entrySkill, action.plugin);
|
|
116258
|
+
} catch (entryErr) {
|
|
116259
|
+
return createResult({
|
|
116260
|
+
actionType,
|
|
116261
|
+
status: ActionStatus.OBSERVED,
|
|
116262
|
+
observation: {
|
|
116263
|
+
installed: true,
|
|
116264
|
+
installPath,
|
|
116265
|
+
entrySkillFound: false,
|
|
116266
|
+
error: `entry skill not resolvable in installed plugin: ${entryErr.message}`
|
|
116267
|
+
}
|
|
116268
|
+
});
|
|
116190
116269
|
}
|
|
116191
|
-
}
|
|
116192
|
-
|
|
116193
|
-
|
|
116194
|
-
const prefixedPath = resolve22(
|
|
116195
|
-
installPath,
|
|
116196
|
-
"skills",
|
|
116197
|
-
`${action.plugin}-${action.entrySkill}`,
|
|
116198
|
-
"SKILL.md"
|
|
116199
|
-
);
|
|
116270
|
+
} else {
|
|
116271
|
+
let entrySkillPath = resolve22(installPath, "skills", action.entrySkill, "SKILL.md");
|
|
116272
|
+
let entrySkillFound = false;
|
|
116200
116273
|
try {
|
|
116201
|
-
const skillStat = await lstat37(
|
|
116274
|
+
const skillStat = await lstat37(entrySkillPath);
|
|
116202
116275
|
if (skillStat.isFile() && !skillStat.isSymbolicLink()) {
|
|
116203
|
-
entrySkillPath = prefixedPath;
|
|
116204
116276
|
entrySkillFound = true;
|
|
116205
116277
|
}
|
|
116206
116278
|
} catch {
|
|
116207
116279
|
}
|
|
116208
|
-
|
|
116209
|
-
|
|
116210
|
-
return createResult({
|
|
116211
|
-
actionType,
|
|
116212
|
-
status: ActionStatus.OBSERVED,
|
|
116213
|
-
observation: {
|
|
116214
|
-
installed: true,
|
|
116280
|
+
if (!entrySkillFound && action.plugin) {
|
|
116281
|
+
const prefixedPath = resolve22(
|
|
116215
116282
|
installPath,
|
|
116216
|
-
|
|
116217
|
-
|
|
116283
|
+
"skills",
|
|
116284
|
+
`${action.plugin}-${action.entrySkill}`,
|
|
116285
|
+
"SKILL.md"
|
|
116286
|
+
);
|
|
116287
|
+
try {
|
|
116288
|
+
const skillStat = await lstat37(prefixedPath);
|
|
116289
|
+
if (skillStat.isFile() && !skillStat.isSymbolicLink()) {
|
|
116290
|
+
entrySkillPath = prefixedPath;
|
|
116291
|
+
entrySkillFound = true;
|
|
116292
|
+
}
|
|
116293
|
+
} catch {
|
|
116218
116294
|
}
|
|
116219
|
-
}
|
|
116295
|
+
}
|
|
116296
|
+
if (!entrySkillFound) {
|
|
116297
|
+
return createResult({
|
|
116298
|
+
actionType,
|
|
116299
|
+
status: ActionStatus.OBSERVED,
|
|
116300
|
+
observation: {
|
|
116301
|
+
installed: true,
|
|
116302
|
+
installPath,
|
|
116303
|
+
entrySkillFound: false,
|
|
116304
|
+
error: `entry skill not found: skills/${action.entrySkill}/SKILL.md`
|
|
116305
|
+
}
|
|
116306
|
+
});
|
|
116307
|
+
}
|
|
116220
116308
|
}
|
|
116221
116309
|
let manifestDigest;
|
|
116222
116310
|
let manifestError = null;
|
|
@@ -116418,6 +116506,7 @@ var init_plugin_marketplace = __esm({
|
|
|
116418
116506
|
__name(normalizeKimiSkillsRel, "normalizeKimiSkillsRel");
|
|
116419
116507
|
__name(resolveKimiEntrySkillFile, "resolveKimiEntrySkillFile");
|
|
116420
116508
|
__name(normalizeCodeBuddySkillsRel, "normalizeCodeBuddySkillsRel");
|
|
116509
|
+
__name(resolveCodexEntrySkillFile, "resolveCodexEntrySkillFile");
|
|
116421
116510
|
__name(resolveCodeBuddyEntrySkillFile, "resolveCodeBuddyEntrySkillFile");
|
|
116422
116511
|
SUPPORTED_TYPES = [
|
|
116423
116512
|
ActionType.PLUGIN_MANIFEST_VALIDATE,
|
|
@@ -116458,6 +116547,14 @@ var init_plugin_marketplace = __esm({
|
|
|
116458
116547
|
});
|
|
116459
116548
|
|
|
116460
116549
|
// src/core/surface-host-bindings.mjs
|
|
116550
|
+
var surface_host_bindings_exports = {};
|
|
116551
|
+
__export(surface_host_bindings_exports, {
|
|
116552
|
+
deriveSurfaceHostBinding: () => deriveSurfaceHostBinding,
|
|
116553
|
+
groupSurfaceHostBindings: () => groupSurfaceHostBindings,
|
|
116554
|
+
normalizeGenericSkillsRel: () => normalizeGenericSkillsRel,
|
|
116555
|
+
normalizeSurfacePath: () => normalizeSurfacePath,
|
|
116556
|
+
pluginRootFromManifestRelativePath: () => pluginRootFromManifestRelativePath
|
|
116557
|
+
});
|
|
116461
116558
|
import { dirname as dirname10, isAbsolute as isAbsolute18, join as join19, normalize as normalize3, resolve as resolve23, sep as sep9 } from "node:path";
|
|
116462
116559
|
import { lstat as lstat38 } from "node:fs/promises";
|
|
116463
116560
|
function normalizeSurfacePath(rawPath) {
|
|
@@ -116586,6 +116683,49 @@ import { dirname as dirname11, join as join20, relative as relative18, isAbsolut
|
|
|
116586
116683
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
116587
116684
|
import { execFile as execFileCb7 } from "node:child_process";
|
|
116588
116685
|
import { promisify as promisify7 } from "node:util";
|
|
116686
|
+
function transportIdentityEntries(entries) {
|
|
116687
|
+
return entries.map(({ path: path43, type, mode, size, contentDigest }) => ({
|
|
116688
|
+
path: path43,
|
|
116689
|
+
type,
|
|
116690
|
+
mode: mode & ~WRITE_BITS,
|
|
116691
|
+
size,
|
|
116692
|
+
contentDigest
|
|
116693
|
+
}));
|
|
116694
|
+
}
|
|
116695
|
+
function compareInstallToFrozenTransport(frozenEntries, installedEntries) {
|
|
116696
|
+
const frozen = transportIdentityEntries(frozenEntries);
|
|
116697
|
+
const installed = transportIdentityEntries(installedEntries);
|
|
116698
|
+
const installedByPath = new Map(installed.map((entry) => [entry.path, entry]));
|
|
116699
|
+
const conflicts = [];
|
|
116700
|
+
for (const frozenEntry of frozen) {
|
|
116701
|
+
const installedEntry = installedByPath.get(frozenEntry.path);
|
|
116702
|
+
if (!installedEntry) {
|
|
116703
|
+
conflicts.push(`missing: ${frozenEntry.path}`);
|
|
116704
|
+
continue;
|
|
116705
|
+
}
|
|
116706
|
+
if (installedEntry.type !== frozenEntry.type) {
|
|
116707
|
+
conflicts.push(`type mismatch: ${frozenEntry.path}`);
|
|
116708
|
+
} else if (installedEntry.size !== frozenEntry.size || installedEntry.contentDigest !== frozenEntry.contentDigest) {
|
|
116709
|
+
conflicts.push(`content mismatch: ${frozenEntry.path}`);
|
|
116710
|
+
} else if (installedEntry.mode !== frozenEntry.mode) {
|
|
116711
|
+
conflicts.push(`mode mismatch: ${frozenEntry.path}`);
|
|
116712
|
+
}
|
|
116713
|
+
}
|
|
116714
|
+
const frozenPaths = new Set(frozen.map((entry) => entry.path));
|
|
116715
|
+
for (const installedEntry of installed) {
|
|
116716
|
+
if (!frozenPaths.has(installedEntry.path)) {
|
|
116717
|
+
conflicts.push(`extra: ${installedEntry.path}`);
|
|
116718
|
+
}
|
|
116719
|
+
}
|
|
116720
|
+
return conflicts;
|
|
116721
|
+
}
|
|
116722
|
+
function frozenSnapshotRelativePath(unit, actions, unitId) {
|
|
116723
|
+
if (typeof unit?.frozenSnapshot?.path === "string" && unit.frozenSnapshot.path.length > 0) {
|
|
116724
|
+
return unit.frozenSnapshot.path;
|
|
116725
|
+
}
|
|
116726
|
+
const action = (actions ?? []).find((item) => item.unitId === unitId && typeof item.parameters?.snapshotPath === "string" && item.parameters.snapshotPath.length > 0);
|
|
116727
|
+
return action?.parameters?.snapshotPath ?? null;
|
|
116728
|
+
}
|
|
116589
116729
|
async function verifyCursorHostDistributions({
|
|
116590
116730
|
plan,
|
|
116591
116731
|
root,
|
|
@@ -118161,16 +118301,65 @@ async function verifyRelease(options) {
|
|
|
118161
118301
|
}
|
|
118162
118302
|
const pluginDistCount = (surface.unit?.distributions ?? []).filter((d) => d.type !== "npm").length;
|
|
118163
118303
|
if (pluginDistCount === 1 && surface.frozenPluginRoot === ".") {
|
|
118164
|
-
const
|
|
118165
|
-
|
|
118166
|
-
|
|
118167
|
-
|
|
118168
|
-
|
|
118169
|
-
|
|
118170
|
-
|
|
118171
|
-
|
|
118172
|
-
|
|
118173
|
-
|
|
118304
|
+
const frozenRel = frozenSnapshotRelativePath(surface.unit, actions, surface.unitId);
|
|
118305
|
+
if (frozenRel) {
|
|
118306
|
+
const frozenDir = await resolveFrozenPath(root, frozenRel, "frozen snapshot path");
|
|
118307
|
+
const frozenClosure = await checkSkillResourceClosure({
|
|
118308
|
+
snapshotDir: frozenDir,
|
|
118309
|
+
host: surface.host,
|
|
118310
|
+
surfaceHostBindings: [{ surfaceId: surface.surfaceId, host: surface.host }]
|
|
118311
|
+
});
|
|
118312
|
+
const frozenReceipt = createSkillResourceClosureReceipt(frozenClosure, {
|
|
118313
|
+
unitId: surface.unitId,
|
|
118314
|
+
preparedAt: expectedUnitReceipt.preparedAt ?? null,
|
|
118315
|
+
exitCode: expectedUnitReceipt.exitCode ?? 0
|
|
118316
|
+
});
|
|
118317
|
+
assertSkillResourceClosureReceipt(
|
|
118318
|
+
expectedUnitReceipt,
|
|
118319
|
+
frozenReceipt,
|
|
118320
|
+
`unit "${surface.unitId}"`
|
|
118321
|
+
);
|
|
118322
|
+
const frozenSnap = await computeFrozenSnapshot(frozenDir, {
|
|
118323
|
+
excludeRootEntries: TRANSPORT_EXCLUSIONS
|
|
118324
|
+
});
|
|
118325
|
+
const installedSnap = await computeFrozenSnapshot(surface.installPath, {
|
|
118326
|
+
excludeRootEntries: TRANSPORT_EXCLUSIONS
|
|
118327
|
+
});
|
|
118328
|
+
const conflicts = compareInstallToFrozenTransport(
|
|
118329
|
+
frozenSnap.entries,
|
|
118330
|
+
installedSnap.entries
|
|
118331
|
+
);
|
|
118332
|
+
await evidence.append({
|
|
118333
|
+
phase: "verify",
|
|
118334
|
+
step: "skill-resource-closure",
|
|
118335
|
+
status: "install-comparison",
|
|
118336
|
+
unitId: surface.unitId,
|
|
118337
|
+
frozenInputDigest: frozenSnap.digest,
|
|
118338
|
+
installedInputDigest: installedSnap.digest,
|
|
118339
|
+
frozenModes: frozenSnap.entries.map((entry) => ({ path: entry.path, mode: entry.mode })),
|
|
118340
|
+
installedModes: installedSnap.entries.map((entry) => ({ path: entry.path, mode: entry.mode }))
|
|
118341
|
+
});
|
|
118342
|
+
if (conflicts.length > 0) {
|
|
118343
|
+
const listed = conflicts.slice(0, PAYLOAD_CONFLICT_REPORT_CAP2).join("; ");
|
|
118344
|
+
const overflow = conflicts.length > PAYLOAD_CONFLICT_REPORT_CAP2 ? `; and ${conflicts.length - PAYLOAD_CONFLICT_REPORT_CAP2} more conflicting path(s)` : "";
|
|
118345
|
+
throw new ReleaseError(
|
|
118346
|
+
POST_PUBLISH_VERIFY_FAILED,
|
|
118347
|
+
`installed plugin root differs in path, bytes, size, or non-write mode bits for unit "${surface.unitId}": ${listed}${overflow}`,
|
|
118348
|
+
{ unitId: surface.unitId, conflicts }
|
|
118349
|
+
);
|
|
118350
|
+
}
|
|
118351
|
+
} else {
|
|
118352
|
+
const observedReceipt = createSkillResourceClosureReceipt(closureResult, {
|
|
118353
|
+
unitId: surface.unitId,
|
|
118354
|
+
preparedAt: expectedUnitReceipt.preparedAt ?? null,
|
|
118355
|
+
exitCode: expectedUnitReceipt.exitCode ?? 0
|
|
118356
|
+
});
|
|
118357
|
+
assertSkillResourceClosureReceipt(
|
|
118358
|
+
expectedUnitReceipt,
|
|
118359
|
+
observedReceipt,
|
|
118360
|
+
`unit "${surface.unitId}"`
|
|
118361
|
+
);
|
|
118362
|
+
}
|
|
118174
118363
|
}
|
|
118175
118364
|
}
|
|
118176
118365
|
skillResourceClosureReceipts.push(createSkillResourceClosureReceipt(
|
|
@@ -118381,7 +118570,7 @@ async function verifyRelease(options) {
|
|
|
118381
118570
|
throw err;
|
|
118382
118571
|
}
|
|
118383
118572
|
}
|
|
118384
|
-
var execFile6, VERIFICATION_RESOLVED_TYPES, ADAPTER_ACTION_TYPE_MAP2, FIRST_RELEASE_BOOTSTRAP_MODE, EXTERNAL_MARKETPLACE_SHA_RE2, defaultNpmExecutor;
|
|
118573
|
+
var execFile6, VERIFICATION_RESOLVED_TYPES, WRITE_BITS, PAYLOAD_CONFLICT_REPORT_CAP2, ADAPTER_ACTION_TYPE_MAP2, FIRST_RELEASE_BOOTSTRAP_MODE, EXTERNAL_MARKETPLACE_SHA_RE2, defaultNpmExecutor;
|
|
118385
118574
|
var init_verify = __esm({
|
|
118386
118575
|
async "src/commands/verify.mjs"() {
|
|
118387
118576
|
init_src2();
|
|
@@ -118419,6 +118608,11 @@ var init_verify = __esm({
|
|
|
118419
118608
|
PASSED_MANUAL: "PASSED_MANUAL",
|
|
118420
118609
|
NOT_REQUIRED_UNCHANGED: "NOT_REQUIRED_UNCHANGED"
|
|
118421
118610
|
});
|
|
118611
|
+
WRITE_BITS = 146;
|
|
118612
|
+
PAYLOAD_CONFLICT_REPORT_CAP2 = 10;
|
|
118613
|
+
__name(transportIdentityEntries, "transportIdentityEntries");
|
|
118614
|
+
__name(compareInstallToFrozenTransport, "compareInstallToFrozenTransport");
|
|
118615
|
+
__name(frozenSnapshotRelativePath, "frozenSnapshotRelativePath");
|
|
118422
118616
|
__name(verifyCursorHostDistributions, "verifyCursorHostDistributions");
|
|
118423
118617
|
__name(verifyPublicSourceAuthorityReceiptOffline, "verifyPublicSourceAuthorityReceiptOffline");
|
|
118424
118618
|
ADAPTER_ACTION_TYPE_MAP2 = {
|
|
@@ -139649,7 +139843,7 @@ async function observeQoderPlugin(target, command2, env, run6) {
|
|
|
139649
139843
|
found
|
|
139650
139844
|
};
|
|
139651
139845
|
}
|
|
139652
|
-
async function readQoderManifest(root, label) {
|
|
139846
|
+
async function readQoderManifest(root, label, target) {
|
|
139653
139847
|
const candidates = [];
|
|
139654
139848
|
for (const manifestPath of [".qoder-plugin/plugin.json", ".claude-plugin/plugin.json"]) {
|
|
139655
139849
|
let text;
|
|
@@ -139663,10 +139857,11 @@ async function readQoderManifest(root, label) {
|
|
|
139663
139857
|
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest)) {
|
|
139664
139858
|
throw new Error(`${label} (${manifestPath}) did not return an object`);
|
|
139665
139859
|
}
|
|
139860
|
+
await assertQoderPluginManifest(target, manifest, `${label} (${manifestPath})`, root);
|
|
139666
139861
|
candidates.push({ manifestPath, manifest });
|
|
139667
139862
|
}
|
|
139668
139863
|
if (candidates.length === 0) throw new Error(`${label} has no native or compatible plugin manifest`);
|
|
139669
|
-
if (candidates.length === 2 && ["name", "version"
|
|
139864
|
+
if (candidates.length === 2 && ["name", "version"].some((field) => candidates[0].manifest[field] !== candidates[1].manifest[field])) {
|
|
139670
139865
|
throw new Error(`${label} does not match the frozen Qoder plugin identity and projection path: conflicting native and compatible manifests`);
|
|
139671
139866
|
}
|
|
139672
139867
|
return candidates[0];
|
|
@@ -139687,26 +139882,43 @@ async function assertFrozenQoderManifest(target, root) {
|
|
|
139687
139882
|
snapshotPath: target.snapshotPath,
|
|
139688
139883
|
expectedDigest: target.manifestDigest
|
|
139689
139884
|
});
|
|
139690
|
-
const { manifestPath, manifest } = await readQoderManifest(snapshotRoot, "frozen Qoder plugin manifest");
|
|
139885
|
+
const { manifestPath, manifest } = await readQoderManifest(snapshotRoot, "frozen Qoder plugin manifest", target);
|
|
139691
139886
|
const skills = await assertQoderPluginManifest(target, manifest, "frozen Qoder plugin manifest", snapshotRoot);
|
|
139692
139887
|
return { manifestPath, skills };
|
|
139693
139888
|
}
|
|
139694
139889
|
async function assertQoderHubEntry(target, marketplaceRoot) {
|
|
139695
|
-
|
|
139696
|
-
|
|
139697
|
-
|
|
139698
|
-
|
|
139699
|
-
|
|
139700
|
-
|
|
139701
|
-
|
|
139702
|
-
|
|
139703
|
-
|
|
139704
|
-
|
|
139705
|
-
|
|
139706
|
-
|
|
139707
|
-
|
|
139708
|
-
|
|
139890
|
+
let found = false;
|
|
139891
|
+
for (const indexPath of ["marketplace.json", ".claude-plugin/marketplace.json"]) {
|
|
139892
|
+
let text;
|
|
139893
|
+
try {
|
|
139894
|
+
text = await readFileContained(marketplaceRoot, indexPath, { encoding: "utf8" });
|
|
139895
|
+
} catch (error) {
|
|
139896
|
+
if (error?.code === "SFC2004" && error?.details?.kind === "missing-resource") continue;
|
|
139897
|
+
throw error;
|
|
139898
|
+
}
|
|
139899
|
+
found = true;
|
|
139900
|
+
const marketplace = parseJson2(text, `Qoder Hub marketplace manifest (${indexPath})`);
|
|
139901
|
+
if (!marketplace || typeof marketplace !== "object" || Array.isArray(marketplace) || marketplace.name !== target.marketplace || !Array.isArray(marketplace.plugins)) {
|
|
139902
|
+
throw new Error("Qoder Hub marketplace manifest does not match the frozen marketplace");
|
|
139903
|
+
}
|
|
139904
|
+
if (indexPath === ".claude-plugin/marketplace.json") {
|
|
139905
|
+
if (target.hub.githubHost !== "github.com" || typeof target.frozenTag !== "string" || target.frozenTag.length === 0) {
|
|
139906
|
+
throw new Error("Qoder compatible Hub entry requires a frozen GitHub tag identity");
|
|
139907
|
+
}
|
|
139908
|
+
await assertHubHostEntry({ ...target, host: "claude", pluginTag: target.frozenTag, githubHost: target.hub.githubHost }, marketplaceRoot);
|
|
139909
|
+
continue;
|
|
139910
|
+
}
|
|
139911
|
+
const matches = marketplace.plugins.filter((entry2) => entry2?.name === target.plugin);
|
|
139912
|
+
if (matches.length !== 1) {
|
|
139913
|
+
throw new Error(`Qoder Hub marketplace manifest must contain exactly one ${target.plugin} entry`);
|
|
139914
|
+
}
|
|
139915
|
+
const entry = matches[0];
|
|
139916
|
+
const source = entry.source;
|
|
139917
|
+
if (source?.source !== "url" || normalizeHubGitSource(source.url, target.hub.githubHost) !== target.pluginRepo || source.sha !== target.pluginCommit || entry.version !== void 0 && entry.version !== target.version || source.ref !== void 0 && (typeof target.frozenTag !== "string" || source.ref !== target.frozenTag)) {
|
|
139918
|
+
throw new Error("Qoder Hub entry does not match the frozen public source identity");
|
|
139919
|
+
}
|
|
139709
139920
|
}
|
|
139921
|
+
if (!found) throw new Error("Qoder Hub has no native or compatible marketplace manifest");
|
|
139710
139922
|
}
|
|
139711
139923
|
async function verifyQoderInstalledPayload({
|
|
139712
139924
|
target,
|
|
@@ -139715,7 +139927,7 @@ async function verifyQoderInstalledPayload({
|
|
|
139715
139927
|
frozenManifest,
|
|
139716
139928
|
verifyInstalledPayload
|
|
139717
139929
|
}) {
|
|
139718
|
-
const { manifestPath, manifest } = await readQoderManifest(installPath, "installed Qoder plugin manifest");
|
|
139930
|
+
const { manifestPath, manifest } = await readQoderManifest(installPath, "installed Qoder plugin manifest", target);
|
|
139719
139931
|
if (manifestPath !== frozenManifest.manifestPath) {
|
|
139720
139932
|
throw new Error("installed Qoder plugin manifest path differs from the frozen manifest selection");
|
|
139721
139933
|
}
|
package/package.json
CHANGED
package/platform-manifest.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
"schemaVersion": "1.0.0",
|
|
3
3
|
"platformId": "release-skill",
|
|
4
4
|
"platformName": "release-skill Plugin Platform",
|
|
5
|
-
"version": "0.9.
|
|
5
|
+
"version": "0.9.37",
|
|
6
6
|
"logicalRoot": "skills-src/",
|
|
7
|
-
"logicalRootDigest": "
|
|
8
|
-
"projectionDigest": "
|
|
9
|
-
"projectionId": "release-skill:platform:0.9.
|
|
7
|
+
"logicalRootDigest": "b76c623a055c6998a6909fc041b2646356f0d69cace4a43cb8edacefc248fb97",
|
|
8
|
+
"projectionDigest": "0d4b9972ee2ce6ce8eadfb075a90e89752a8f2b5f2becd53a6ae034029da8bad",
|
|
9
|
+
"projectionId": "release-skill:platform:0.9.37",
|
|
10
10
|
"manifestRequired": true,
|
|
11
11
|
"projectionSources": {
|
|
12
12
|
"skills-src-root": {
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"bytes": 16742
|
|
11
11
|
},
|
|
12
12
|
"02-project-config.md": {
|
|
13
|
-
"digest": "
|
|
14
|
-
"bytes":
|
|
13
|
+
"digest": "3e19eedbabb7e17d8afd4d9efc6a43309b7cc04e72866d44bd1afac787c8b462",
|
|
14
|
+
"bytes": 34998
|
|
15
15
|
},
|
|
16
16
|
"03-readme-quality.md": {
|
|
17
17
|
"digest": "d74e41052592443ebbd450d0ace5f9b9b19c7a94db50f952b17c1c5a4c5dc230",
|
|
@@ -124,19 +124,100 @@ policy: # 可选,安全策略
|
|
|
124
124
|
|
|
125
125
|
### 2.0 显式测试接入
|
|
126
126
|
|
|
127
|
-
`testIntake`
|
|
127
|
+
`testIntake` 为可选配置项,仅包含两个项目相对普通文件路径字段:`requirementsFile` 与 `resultFile`。路径经归一化后必须互异;`a/./b` 与 `a/b` 视为同一路径。配置加载时拒绝以下内容:
|
|
128
|
+
- 未知字段;
|
|
129
|
+
- 绝对路径;
|
|
130
|
+
- 包含 `..` 路径组件的路径;
|
|
131
|
+
- 以斜杠结尾的路径。
|
|
128
132
|
|
|
129
|
-
未声明 `testIntake`
|
|
133
|
+
未声明 `testIntake` 的项目维持原有 hook 机制、完整门控、缓存策略与发布路径,不引入 TEST、Graph 或 Registry 依赖。
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
`--test-selection incremental` 在 `prepare` 或冻结过程中均被拒绝,不得在任何准备阶段启用。该拒绝行为不延迟至冻结完成后。
|
|
132
136
|
|
|
133
|
-
|
|
137
|
+
#### 交互式 Skill 的接入职责
|
|
134
138
|
|
|
135
|
-
|
|
139
|
+
生产准备前,Skill 必须核对接入状态。若未声明 `testIntake`,系统默认触发公开 TEST 0.1.0 的 `skill-family-test:skill-family-test-plan`,随后在授权范围内调用 `skill-family-test:skill-family-test-run`。
|
|
136
140
|
|
|
137
|
-
|
|
141
|
+
跳过接入须满足以下条件:
|
|
142
|
+
- 基于本轮适用且范围匹配的明确同意;
|
|
143
|
+
- 必须先明确征询再作决定;
|
|
144
|
+
- 沉默、拒绝、仅普通发布预授权、旧轮次、其他项目、版本或范围不匹配均不可跳过;
|
|
145
|
+
- 本轮匹配的答复可复用。
|
|
138
146
|
|
|
139
|
-
|
|
147
|
+
不得将跳过表述为测试已达标,亦不得以跳过清除已声明的适用要求。
|
|
148
|
+
|
|
149
|
+
以下请求不新增接入义务:
|
|
150
|
+
- 只读请求;
|
|
151
|
+
- 非生产路径;
|
|
152
|
+
- marketplace-only 委托发布。
|
|
153
|
+
- 已冻结计划的批准、发布、对账与正式验证不追加接入义务。
|
|
154
|
+
|
|
155
|
+
直接非交互 CLI 支持可选 `testIntake`,不新增选择参数、同意文件 Schema 或身份认证。选择责任由实际交互的 Skill 承担,答复记入既有任务或执行计划。
|
|
156
|
+
|
|
157
|
+
#### 声明后的命令与要求适用范围
|
|
158
|
+
|
|
159
|
+
声明 `testIntake` 后,仅允许执行生产 `prepare` 命令。非生产 `prepare` 返回 `CONFIG_INVALID`,错误码为 `TEST_INTAKE_NON_PRODUCTION`。
|
|
160
|
+
|
|
161
|
+
`assess` 等其他命令仍可加载该配置。
|
|
162
|
+
|
|
163
|
+
轻量工作流(如 docs、config、marketplace)、`selectedUnits` 与无需发布的配置分支不免除项目级要求:未选中单元的单元级要求可不进入本轮,但项目级要求始终适用。
|
|
164
|
+
|
|
165
|
+
#### 核收原件与失败条件
|
|
166
|
+
|
|
167
|
+
`release` 仅核收原件,要求如下:
|
|
168
|
+
- 预冻结项必须存在一条可核验结果;
|
|
169
|
+
- 结果状态必须为 `executed`、`reused` 或由 owner 确认的 `not-applicable`;
|
|
170
|
+
- 结论必须为 `passed`;
|
|
171
|
+
- `acceptedBy` 与声明的 acceptor 一致;`not-applicable` 时与 owner 一致;
|
|
172
|
+
- 引用文件可读且摘要一致;
|
|
173
|
+
- 结果中的 `subjectDigest` 与 `requirementsSha256` 均必须绑定当前对象。
|
|
174
|
+
|
|
175
|
+
以下情况均不通过核收:
|
|
176
|
+
- 退出码为 0;
|
|
177
|
+
- 全局 PASS;
|
|
178
|
+
- 空证据;
|
|
179
|
+
- 状态为 `failed`、`incomplete`、`uncovered`;
|
|
180
|
+
- 未知字段;
|
|
181
|
+
- 提前将后续阶段项标记为完成;
|
|
182
|
+
- 未知失败原因(保持 `unknown`)。
|
|
183
|
+
|
|
184
|
+
安装、加载与业务证据须分开保存,不得合并为单一类别。
|
|
185
|
+
|
|
186
|
+
核收依据 `schemas/test-intake.schema.json` 定义的字段结构。
|
|
187
|
+
|
|
188
|
+
#### 首次生产 prepare、候选续接和输入漂移
|
|
189
|
+
|
|
190
|
+
首次生产 `prepare` 执行后,生成适用快照与 tarball,仅保存一份非正式候选:
|
|
191
|
+
- 路径:`.release-skill/runs/<run>/test-candidate.json`;
|
|
192
|
+
- 返回状态:`NEEDS_INPUT`(`GATE_FAILED`,退出码 13);
|
|
193
|
+
- 附带字段:`candidatePath`、`candidateSha256` 与 `subjectDigest`。
|
|
194
|
+
|
|
195
|
+
此时不写正式计划,也不进入 `PREPARED` 或 `FROZEN` 状态。
|
|
196
|
+
|
|
197
|
+
后续使用 `prepare --candidate <path>` 续接:
|
|
198
|
+
- 创建新运行目录;
|
|
199
|
+
- 不覆盖旧运行目录、旧证据或旧候选;
|
|
200
|
+
- 结果补齐并核验通过后,才写入正式计划。
|
|
201
|
+
|
|
202
|
+
当对象、配置、权威要求或其他实质输入发生变更时,返回 `TEST_CANDIDATE_REPREPARE`,原候选字节保持不变。
|
|
203
|
+
|
|
204
|
+
**仅当向仍绑定原对象的 `resultFile` 补入有效结果内容时,不视为输入漂移。**
|
|
205
|
+
|
|
206
|
+
首次候选、有效结果、正式计划与正式业务接受为不同阶段,不得将 `NEEDS_INPUT` 或工具成功改写为通过。
|
|
207
|
+
|
|
208
|
+
#### 后续计划与批准绑定
|
|
209
|
+
|
|
210
|
+
候选不可传给 `approve` 或 `publish`,亦不可将 `PARTIAL`、`PUBLISHED`、`VERIFIED` 或任何已成功的外部检查点修改为完成状态。
|
|
211
|
+
|
|
212
|
+
`ship` 在接受前保持持久状态 `NEW` 与 `testCandidate`,不重建候选。无 `testCandidate` 的 `NEW` 记录仍沿用原有准备路径。
|
|
213
|
+
|
|
214
|
+
正式计划中的可选字段 `testAcceptance` 进入当前计划版本的绑定摘要,记录层剥离不移除该字段。
|
|
215
|
+
|
|
216
|
+
替换结果、准则、范围或允许的限制将改变 plan digest,原批准不再适用。未改变这些原件的注释不会使批准失效。
|
|
217
|
+
|
|
218
|
+
无 `testAcceptance` 的计划保持原摘要路径。
|
|
219
|
+
|
|
220
|
+
`approve`、`publish` 与 `reconcile` 在执行前复核绑定原件;原件缺失或被改写时,动作失败并关闭,不重新批准,也不重放已成功的外部检查点。
|
|
140
221
|
|
|
141
222
|
### 2.1 本地发布收尾
|
|
142
223
|
|
|
@@ -247,7 +328,9 @@ releaseUnits:
|
|
|
247
328
|
|
|
248
329
|
Qoder 保持 build-only 分发边界,不新增发布计划内的 distribution 或安装检查点。本机收尾更新 Qoder 有四个前提:冻结计划已声明、用户显式选择、Hub 来源匹配、既有用户范围安装核对通过。流程不添加市场或执行首次安装。更新完成仅表示安装载荷已变更,不表示当前会话已加载新版,后续仍须重新加载或新开会话,并完成一次真实的只读业务调用。
|
|
249
330
|
|
|
250
|
-
|
|
331
|
+
在已核对的市场安装根内,分别读取 `marketplace.json` 的 `url` 来源与 `.claude-plugin/marketplace.json` 的 `github` 来源;至少一个存在,且所有存在候选都须有效并绑定同一冻结目标。根目录来源核对 `source.url/source.sha`;兼容来源沿现有 Claude 断言核对仓库、冻结标签、提交和版本。任一损坏或冲突均拒绝,不猜测优先级。
|
|
332
|
+
|
|
333
|
+
冻结与安装两侧均核验原生 `.qoder-plugin/plugin.json` 与 Claude 兼容 `.claude-plugin/plugin.json`:原生清单缺失时方可启用兼容清单,原生清单存在但无效时不得回退;两清单同时存在时,均须可解析为有效对象,以原生清单为优先。每个已存在候选(包括未选候选)都须核对目标 `name/version`;其 `skills` 必须为非空字符串,经 `Foundation 0.25.0` 的 `resolveContained` 解析为根内真实目录。跨候选只比较 `name/version`,允许各自合法 `skills` 不同;原生正常不能遮蔽兼容无效。安装侧结果须与冻结侧选定的相对清单路径及 `skills` 一致,不得忽略额外出现的损坏或冲突清单。写入前复验冻结快照摘要,安装后须完整比较声明载荷与冻结来源,现有 `external-marketplace-v1` 合同允许宿主额外文件,因此完整载荷比较不得替代双清单的独立核验。
|
|
251
334
|
|
|
252
335
|
0.9.21 起,同一声明也能执行 Claude、Codex、Kimi、CodeBuddy 和 WorkBuddy 的本机更新,无需恢复旧宿主 distribution。插件仓库、标签、提交和快照摘要必须来自冻结 unit 与对应标签动作。Claude、Codex 和 CodeBuddy 家族使用已有同源 Hub 市场;刷新前后分别核对宿主专用条目,安装后比较完整冻结载荷。CodeBuddy/WorkBuddy 只升级已有插件,并在插件写入前再次确认 Hub 分支未漂移。Kimi 直接使用冻结 GitHub Release 和终端交互,其只有仓库 URL 的 Hub 文件不承担标签或提交证明。启动进程保留三个代理变量 `http_proxy`、`https_proxy`、`all_proxy`。
|
|
253
336
|
|
|
@@ -17,6 +17,10 @@
|
|
|
17
17
|
"digest": "86c9cab024ebe9c7f8ec3358fcc12d05b8ed246ab59da2b0acc6a517f31274ea",
|
|
18
18
|
"bytes": 2488
|
|
19
19
|
},
|
|
20
|
+
"evidence-event-v2.schema.json": {
|
|
21
|
+
"digest": "693430e636afc85bf4a79e3f7bf3fb87254cbd62f2e3f35c35d6f84e5e8e0be1",
|
|
22
|
+
"bytes": 6058
|
|
23
|
+
},
|
|
20
24
|
"evidence-event.schema.json": {
|
|
21
25
|
"digest": "b7e14522a5aba818cab191545f23d2323be0e4c80566e9d3e4da576103a00490",
|
|
22
26
|
"bytes": 2390
|
|
@@ -34,8 +38,8 @@
|
|
|
34
38
|
"bytes": 57111
|
|
35
39
|
},
|
|
36
40
|
"release-run.schema.json": {
|
|
37
|
-
"digest": "
|
|
38
|
-
"bytes":
|
|
41
|
+
"digest": "26c44ddf1ed42f266a2ddee7f6132cee94c59593e37f24359c9c48f12612ec22",
|
|
42
|
+
"bytes": 21874
|
|
39
43
|
},
|
|
40
44
|
"test-intake.schema.json": {
|
|
41
45
|
"digest": "654e91ce518cb2b8aca84947d0c3bb8c4262ab047d86081e7e93dc07a9c6c739",
|