release-skill 0.7.3 → 0.7.4

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -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.7.3"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.4"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "0e814c8b806446476595498baed8b129ca3cb024e3b922049db5774f022c90be";
14
+ const __bundleSourceDigest = "94f8a4247206a95c5365d48448b1cce5e47d4fc42a711ac72e761565bc2dcb69";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -36390,8 +36390,13 @@ function getPlatform(id) {
36390
36390
  if (!platform) throw new Error(`unknown platform: ${id}`);
36391
36391
  return platform;
36392
36392
  }
36393
+ function resolveSkillProjectionSurfaceHost(surfaceId, registry = PLATFORMS) {
36394
+ const platform = registry.find((item) => item.skillProjectionSurface === surfaceId);
36395
+ return platform?.buildAdapter?.name ?? null;
36396
+ }
36393
36397
  function assertRegistry(registry = PLATFORMS) {
36394
36398
  const seen = /* @__PURE__ */ new Set();
36399
+ const seenSkillProjectionSurfaces = /* @__PURE__ */ new Set();
36395
36400
  for (const platform of registry) {
36396
36401
  const label = platform?.id ?? "<missing id>";
36397
36402
  if (typeof platform?.id !== "string" || platform.id.length === 0) {
@@ -36440,6 +36445,16 @@ function assertRegistry(registry = PLATFORMS) {
36440
36445
  if (typeof platform.buildAdapter.name !== "string" || platform.buildAdapter.name.length === 0) {
36441
36446
  throw new Error(`platform registry: ${label} buildAdapter needs a non-empty name (its adapter directory name)`);
36442
36447
  }
36448
+ if (typeof platform.skillProjectionSurface !== "string" || !SKILL_PROJECTION_SURFACE_PATTERN.test(platform.skillProjectionSurface)) {
36449
+ throw new Error(`platform registry: ${label} skillProjectionSurface must match platforms/<slug>`);
36450
+ }
36451
+ if (seenSkillProjectionSurfaces.has(platform.skillProjectionSurface)) {
36452
+ throw new Error(`platform registry: duplicate skillProjectionSurface "${platform.skillProjectionSurface}"; aliases must be unique`);
36453
+ }
36454
+ seenSkillProjectionSurfaces.add(platform.skillProjectionSurface);
36455
+ if (resolveSkillProjectionSurfaceHost(platform.skillProjectionSurface, registry) !== platform.buildAdapter.name) {
36456
+ throw new Error(`platform registry: ${label} skillProjectionSurface must map to buildAdapter.name`);
36457
+ }
36443
36458
  if (!VALID_LIST_OUTPUTS.has(platform.jsonProtocol?.listOutput)) {
36444
36459
  throw new Error(`platform registry: ${label} has illegal jsonProtocol.listOutput "${platform.jsonProtocol?.listOutput}"`);
36445
36460
  }
@@ -36567,7 +36582,7 @@ function resolveCapabilityConflicts(platform) {
36567
36582
  }
36568
36583
  return { hasConflict: false, conflicts: [] };
36569
36584
  }
36570
- var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES;
36585
+ var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES, SKILL_PROJECTION_SURFACE_PATTERN;
36571
36586
  var init_registry2 = __esm({
36572
36587
  async "src/platforms/registry.mjs"() {
36573
36588
  await init_kimi();
@@ -36582,6 +36597,7 @@ var init_registry2 = __esm({
36582
36597
  __name(codexCrossValidateListEntry, "codexCrossValidateListEntry");
36583
36598
  CLAUDE = Object.freeze({
36584
36599
  id: "claude",
36600
+ skillProjectionSurface: "platforms/claude-code",
36585
36601
  distributionType: "claude-plugin",
36586
36602
  actionType: "claude-marketplace-install",
36587
36603
  // Runtime adapter implementing this platform's marketplace-install action.
@@ -36646,6 +36662,7 @@ var init_registry2 = __esm({
36646
36662
  });
36647
36663
  CODEX = Object.freeze({
36648
36664
  id: "codex",
36665
+ skillProjectionSurface: "platforms/codex",
36649
36666
  distributionType: "codex-plugin",
36650
36667
  actionType: "codex-marketplace-install",
36651
36668
  adapter: "plugin-marketplace",
@@ -36706,6 +36723,7 @@ var init_registry2 = __esm({
36706
36723
  });
36707
36724
  KIMI = Object.freeze({
36708
36725
  id: "kimi",
36726
+ skillProjectionSurface: "platforms/kimi-code",
36709
36727
  distributionType: "kimi-plugin",
36710
36728
  actionType: "kimi-marketplace-install",
36711
36729
  adapter: "plugin-marketplace",
@@ -36765,6 +36783,7 @@ var init_registry2 = __esm({
36765
36783
  });
36766
36784
  CODEBUDDY = Object.freeze({
36767
36785
  id: "codebuddy",
36786
+ skillProjectionSurface: "platforms/workbuddy",
36768
36787
  distributionType: "codebuddy-plugin",
36769
36788
  actionType: "codebuddy-marketplace-install",
36770
36789
  adapter: "plugin-marketplace",
@@ -36847,7 +36866,9 @@ var init_registry2 = __esm({
36847
36866
  VALID_OUTPUT_PROTOCOLS = /* @__PURE__ */ new Set(["structured", "text", "none"]);
36848
36867
  VALID_IDENTITY_EVIDENCE = /* @__PURE__ */ new Set(["list-record", "install-output", "filesystem-payload", "human-attestation"]);
36849
36868
  VALID_DEGRADATION_POLICIES = /* @__PURE__ */ new Set(["block", "human-attestation", "human-attestation-with-fallback"]);
36869
+ SKILL_PROJECTION_SURFACE_PATTERN = /^platforms\/[a-z0-9]+(?:-[a-z0-9]+)*$/u;
36850
36870
  __name(getPlatform, "getPlatform");
36871
+ __name(resolveSkillProjectionSurfaceHost, "resolveSkillProjectionSurfaceHost");
36851
36872
  __name(assertRegistry, "assertRegistry");
36852
36873
  assertRegistry();
36853
36874
  __name(resolvePlatformRoute, "resolvePlatformRoute");
@@ -44399,8 +44420,13 @@ async function collectRegularFiles(dir, results) {
44399
44420
  }
44400
44421
  }
44401
44422
  function inferSurfaceHost(surfaceId, defaultHost) {
44402
- const match = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
44403
- return match?.[1] ?? defaultHost;
44423
+ const adapterMatch = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
44424
+ if (adapterMatch) return adapterMatch[1];
44425
+ const platformMatch = PLATFORM_SURFACE_PATTERN.exec(surfaceId);
44426
+ if (platformMatch) {
44427
+ return resolveSkillProjectionSurfaceHost(surfaceId) ?? `unknown-platform:${platformMatch[1]}`;
44428
+ }
44429
+ return defaultHost;
44404
44430
  }
44405
44431
  function receiptProjection(result) {
44406
44432
  return {
@@ -44509,6 +44535,7 @@ async function checkSkillResourceClosure({
44509
44535
  const pluginRoot = resolvePluginRoot(skill, scanRoot2);
44510
44536
  const surfaceId = relativeStable(scanRoot2, pluginRoot);
44511
44537
  const surfaceHost = inferSurfaceHost(surfaceId, host);
44538
+ const firstSkillOnSurface = !surfaceMap.has(surfaceId);
44512
44539
  const surface = surfaceMap.get(surfaceId) ?? {
44513
44540
  id: surfaceId,
44514
44541
  host: surfaceHost,
@@ -44518,6 +44545,19 @@ async function checkSkillResourceClosure({
44518
44545
  };
44519
44546
  surface.skillCount += 1;
44520
44547
  surfaceMap.set(surfaceId, surface);
44548
+ if (firstSkillOnSurface && PLATFORM_SURFACE_PATTERN.test(surfaceId) && resolveSkillProjectionSurfaceHost(surfaceId) === null) {
44549
+ findings.push({
44550
+ host: surfaceHost,
44551
+ surface: surfaceId,
44552
+ skill: null,
44553
+ line: null,
44554
+ reference: surfaceId,
44555
+ classification: CLASSIFICATION.UNKNOWN_PLATFORM_SURFACE,
44556
+ resolutionRoot: surfaceId,
44557
+ resolvedTarget: surfaceId,
44558
+ code: FINDING_CODE.UNKNOWN_PLATFORM_SURFACE
44559
+ });
44560
+ }
44521
44561
  if (!skillsBySurface.has(surfaceId)) skillsBySurface.set(surfaceId, []);
44522
44562
  skillsBySurface.get(surfaceId).push(skill);
44523
44563
  const content = await readFile12(resolve17(scanRoot2, skill), "utf8");
@@ -44711,13 +44751,14 @@ function evaluateDeclaredHostSurfaceCoverage(expectedHosts, surfaces) {
44711
44751
  }
44712
44752
  return { passed: missing.length === 0, missing };
44713
44753
  }
44714
- 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;
44754
+ var CHECKER_VERSION, BARE_PREFIXES, EXPLICIT_PREFIXES, SOURCE_TREE_PATTERN, MACHINE_ABSOLUTE_PATTERN, HOME_DIRECTORY_PATTERN, ADAPTER_SURFACE_PATTERN, PLATFORM_SURFACE_PATTERN, CLOSURE_RESOURCE_DIRS, GLOB_PATTERN, SOURCE_ONLY_MARKER, TRANSPORT_EXCLUSIONS, CLASSIFICATION, FINDING_CODE;
44715
44755
  var init_skill_resource_closure = __esm({
44716
- "src/core/skill-resource-closure.mjs"() {
44756
+ async "src/core/skill-resource-closure.mjs"() {
44717
44757
  init_src();
44718
44758
  init_errors3();
44719
44759
  init_frozen();
44720
- CHECKER_VERSION = "skill-resource-closure-v2";
44760
+ await init_registry2();
44761
+ CHECKER_VERSION = "skill-resource-closure-v3";
44721
44762
  BARE_PREFIXES = ["references/", "assets/", "schemas/", "examples/", "scripts/"];
44722
44763
  EXPLICIT_PREFIXES = [
44723
44764
  "<plugin-root>/",
@@ -44731,6 +44772,7 @@ var init_skill_resource_closure = __esm({
44731
44772
  MACHINE_ABSOLUTE_PATTERN = /^(?:\/(?:Users|home|root|tmp|var|etc|opt)(?:\/|$)|[A-Za-z]:[\\/])/u;
44732
44773
  HOME_DIRECTORY_PATTERN = /^(?:~|\$HOME|\$\{HOME\})\/.+/u;
44733
44774
  ADAPTER_SURFACE_PATTERN = /^adapters\/([^/]+)$/u;
44775
+ PLATFORM_SURFACE_PATTERN = /^platforms\/(.+)$/u;
44734
44776
  CLOSURE_RESOURCE_DIRS = Object.freeze(["references", "assets", "schemas", "examples", "scripts"]);
44735
44777
  GLOB_PATTERN = /[*?\[]/u;
44736
44778
  SOURCE_ONLY_MARKER = /(?:\bsource-only\b|仅源码包)/iu;
@@ -44748,7 +44790,8 @@ var init_skill_resource_closure = __esm({
44748
44790
  HOME_DIRECTORY: "home_directory",
44749
44791
  OUT_OF_BOUNDS: "out_of_bounds",
44750
44792
  RESOURCE_DRIFT: "resource_drift",
44751
- STALE_RESOURCE: "stale_resource"
44793
+ STALE_RESOURCE: "stale_resource",
44794
+ UNKNOWN_PLATFORM_SURFACE: "unknown_platform_surface"
44752
44795
  });
44753
44796
  FINDING_CODE = Object.freeze({
44754
44797
  SNAPSHOT_UNSAFE: "SNAPSHOT_UNSAFE",
@@ -44760,7 +44803,8 @@ var init_skill_resource_closure = __esm({
44760
44803
  OUT_OF_BOUNDS: "OUT_OF_BOUNDS",
44761
44804
  SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED",
44762
44805
  RESOURCE_DRIFT: "RESOURCE_DRIFT",
44763
- STALE_RESOURCE: "STALE_RESOURCE"
44806
+ STALE_RESOURCE: "STALE_RESOURCE",
44807
+ UNKNOWN_PLATFORM_SURFACE: "UNKNOWN_PLATFORM_SURFACE"
44764
44808
  });
44765
44809
  __name(toPosix, "toPosix");
44766
44810
  __name(relativeStable, "relativeStable");
@@ -100763,7 +100807,7 @@ var init_prepare = __esm({
100763
100807
  init_evidence();
100764
100808
  await init_plan();
100765
100809
  init_digest();
100766
- init_skill_resource_closure();
100810
+ await init_skill_resource_closure();
100767
100811
  init_public_map();
100768
100812
  init_public_path();
100769
100813
  init_scan();
@@ -102785,7 +102829,7 @@ var init_publish = __esm({
102785
102829
  init_baseline2();
102786
102830
  init_previous_public_baseline();
102787
102831
  init_evidence();
102788
- init_skill_resource_closure();
102832
+ await init_skill_resource_closure();
102789
102833
  init_checkpoints();
102790
102834
  await init_run();
102791
102835
  init_errors3();
@@ -105332,7 +105376,7 @@ var init_verify = __esm({
105332
105376
  init_public_path();
105333
105377
  init_npm();
105334
105378
  init_verification_gates();
105335
- init_skill_resource_closure();
105379
+ await init_skill_resource_closure();
105336
105380
  init_checkpoints();
105337
105381
  init_installation_contract();
105338
105382
  init_npm_entry_closure();
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -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.7.3"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.4"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "0e814c8b806446476595498baed8b129ca3cb024e3b922049db5774f022c90be";
14
+ const __bundleSourceDigest = "94f8a4247206a95c5365d48448b1cce5e47d4fc42a711ac72e761565bc2dcb69";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -36390,8 +36390,13 @@ function getPlatform(id) {
36390
36390
  if (!platform) throw new Error(`unknown platform: ${id}`);
36391
36391
  return platform;
36392
36392
  }
36393
+ function resolveSkillProjectionSurfaceHost(surfaceId, registry = PLATFORMS) {
36394
+ const platform = registry.find((item) => item.skillProjectionSurface === surfaceId);
36395
+ return platform?.buildAdapter?.name ?? null;
36396
+ }
36393
36397
  function assertRegistry(registry = PLATFORMS) {
36394
36398
  const seen = /* @__PURE__ */ new Set();
36399
+ const seenSkillProjectionSurfaces = /* @__PURE__ */ new Set();
36395
36400
  for (const platform of registry) {
36396
36401
  const label = platform?.id ?? "<missing id>";
36397
36402
  if (typeof platform?.id !== "string" || platform.id.length === 0) {
@@ -36440,6 +36445,16 @@ function assertRegistry(registry = PLATFORMS) {
36440
36445
  if (typeof platform.buildAdapter.name !== "string" || platform.buildAdapter.name.length === 0) {
36441
36446
  throw new Error(`platform registry: ${label} buildAdapter needs a non-empty name (its adapter directory name)`);
36442
36447
  }
36448
+ if (typeof platform.skillProjectionSurface !== "string" || !SKILL_PROJECTION_SURFACE_PATTERN.test(platform.skillProjectionSurface)) {
36449
+ throw new Error(`platform registry: ${label} skillProjectionSurface must match platforms/<slug>`);
36450
+ }
36451
+ if (seenSkillProjectionSurfaces.has(platform.skillProjectionSurface)) {
36452
+ throw new Error(`platform registry: duplicate skillProjectionSurface "${platform.skillProjectionSurface}"; aliases must be unique`);
36453
+ }
36454
+ seenSkillProjectionSurfaces.add(platform.skillProjectionSurface);
36455
+ if (resolveSkillProjectionSurfaceHost(platform.skillProjectionSurface, registry) !== platform.buildAdapter.name) {
36456
+ throw new Error(`platform registry: ${label} skillProjectionSurface must map to buildAdapter.name`);
36457
+ }
36443
36458
  if (!VALID_LIST_OUTPUTS.has(platform.jsonProtocol?.listOutput)) {
36444
36459
  throw new Error(`platform registry: ${label} has illegal jsonProtocol.listOutput "${platform.jsonProtocol?.listOutput}"`);
36445
36460
  }
@@ -36567,7 +36582,7 @@ function resolveCapabilityConflicts(platform) {
36567
36582
  }
36568
36583
  return { hasConflict: false, conflicts: [] };
36569
36584
  }
36570
- var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES;
36585
+ var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES, SKILL_PROJECTION_SURFACE_PATTERN;
36571
36586
  var init_registry2 = __esm({
36572
36587
  async "src/platforms/registry.mjs"() {
36573
36588
  await init_kimi();
@@ -36582,6 +36597,7 @@ var init_registry2 = __esm({
36582
36597
  __name(codexCrossValidateListEntry, "codexCrossValidateListEntry");
36583
36598
  CLAUDE = Object.freeze({
36584
36599
  id: "claude",
36600
+ skillProjectionSurface: "platforms/claude-code",
36585
36601
  distributionType: "claude-plugin",
36586
36602
  actionType: "claude-marketplace-install",
36587
36603
  // Runtime adapter implementing this platform's marketplace-install action.
@@ -36646,6 +36662,7 @@ var init_registry2 = __esm({
36646
36662
  });
36647
36663
  CODEX = Object.freeze({
36648
36664
  id: "codex",
36665
+ skillProjectionSurface: "platforms/codex",
36649
36666
  distributionType: "codex-plugin",
36650
36667
  actionType: "codex-marketplace-install",
36651
36668
  adapter: "plugin-marketplace",
@@ -36706,6 +36723,7 @@ var init_registry2 = __esm({
36706
36723
  });
36707
36724
  KIMI = Object.freeze({
36708
36725
  id: "kimi",
36726
+ skillProjectionSurface: "platforms/kimi-code",
36709
36727
  distributionType: "kimi-plugin",
36710
36728
  actionType: "kimi-marketplace-install",
36711
36729
  adapter: "plugin-marketplace",
@@ -36765,6 +36783,7 @@ var init_registry2 = __esm({
36765
36783
  });
36766
36784
  CODEBUDDY = Object.freeze({
36767
36785
  id: "codebuddy",
36786
+ skillProjectionSurface: "platforms/workbuddy",
36768
36787
  distributionType: "codebuddy-plugin",
36769
36788
  actionType: "codebuddy-marketplace-install",
36770
36789
  adapter: "plugin-marketplace",
@@ -36847,7 +36866,9 @@ var init_registry2 = __esm({
36847
36866
  VALID_OUTPUT_PROTOCOLS = /* @__PURE__ */ new Set(["structured", "text", "none"]);
36848
36867
  VALID_IDENTITY_EVIDENCE = /* @__PURE__ */ new Set(["list-record", "install-output", "filesystem-payload", "human-attestation"]);
36849
36868
  VALID_DEGRADATION_POLICIES = /* @__PURE__ */ new Set(["block", "human-attestation", "human-attestation-with-fallback"]);
36869
+ SKILL_PROJECTION_SURFACE_PATTERN = /^platforms\/[a-z0-9]+(?:-[a-z0-9]+)*$/u;
36850
36870
  __name(getPlatform, "getPlatform");
36871
+ __name(resolveSkillProjectionSurfaceHost, "resolveSkillProjectionSurfaceHost");
36851
36872
  __name(assertRegistry, "assertRegistry");
36852
36873
  assertRegistry();
36853
36874
  __name(resolvePlatformRoute, "resolvePlatformRoute");
@@ -44399,8 +44420,13 @@ async function collectRegularFiles(dir, results) {
44399
44420
  }
44400
44421
  }
44401
44422
  function inferSurfaceHost(surfaceId, defaultHost) {
44402
- const match = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
44403
- return match?.[1] ?? defaultHost;
44423
+ const adapterMatch = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
44424
+ if (adapterMatch) return adapterMatch[1];
44425
+ const platformMatch = PLATFORM_SURFACE_PATTERN.exec(surfaceId);
44426
+ if (platformMatch) {
44427
+ return resolveSkillProjectionSurfaceHost(surfaceId) ?? `unknown-platform:${platformMatch[1]}`;
44428
+ }
44429
+ return defaultHost;
44404
44430
  }
44405
44431
  function receiptProjection(result) {
44406
44432
  return {
@@ -44509,6 +44535,7 @@ async function checkSkillResourceClosure({
44509
44535
  const pluginRoot = resolvePluginRoot(skill, scanRoot2);
44510
44536
  const surfaceId = relativeStable(scanRoot2, pluginRoot);
44511
44537
  const surfaceHost = inferSurfaceHost(surfaceId, host);
44538
+ const firstSkillOnSurface = !surfaceMap.has(surfaceId);
44512
44539
  const surface = surfaceMap.get(surfaceId) ?? {
44513
44540
  id: surfaceId,
44514
44541
  host: surfaceHost,
@@ -44518,6 +44545,19 @@ async function checkSkillResourceClosure({
44518
44545
  };
44519
44546
  surface.skillCount += 1;
44520
44547
  surfaceMap.set(surfaceId, surface);
44548
+ if (firstSkillOnSurface && PLATFORM_SURFACE_PATTERN.test(surfaceId) && resolveSkillProjectionSurfaceHost(surfaceId) === null) {
44549
+ findings.push({
44550
+ host: surfaceHost,
44551
+ surface: surfaceId,
44552
+ skill: null,
44553
+ line: null,
44554
+ reference: surfaceId,
44555
+ classification: CLASSIFICATION.UNKNOWN_PLATFORM_SURFACE,
44556
+ resolutionRoot: surfaceId,
44557
+ resolvedTarget: surfaceId,
44558
+ code: FINDING_CODE.UNKNOWN_PLATFORM_SURFACE
44559
+ });
44560
+ }
44521
44561
  if (!skillsBySurface.has(surfaceId)) skillsBySurface.set(surfaceId, []);
44522
44562
  skillsBySurface.get(surfaceId).push(skill);
44523
44563
  const content = await readFile12(resolve17(scanRoot2, skill), "utf8");
@@ -44711,13 +44751,14 @@ function evaluateDeclaredHostSurfaceCoverage(expectedHosts, surfaces) {
44711
44751
  }
44712
44752
  return { passed: missing.length === 0, missing };
44713
44753
  }
44714
- 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;
44754
+ var CHECKER_VERSION, BARE_PREFIXES, EXPLICIT_PREFIXES, SOURCE_TREE_PATTERN, MACHINE_ABSOLUTE_PATTERN, HOME_DIRECTORY_PATTERN, ADAPTER_SURFACE_PATTERN, PLATFORM_SURFACE_PATTERN, CLOSURE_RESOURCE_DIRS, GLOB_PATTERN, SOURCE_ONLY_MARKER, TRANSPORT_EXCLUSIONS, CLASSIFICATION, FINDING_CODE;
44715
44755
  var init_skill_resource_closure = __esm({
44716
- "src/core/skill-resource-closure.mjs"() {
44756
+ async "src/core/skill-resource-closure.mjs"() {
44717
44757
  init_src();
44718
44758
  init_errors3();
44719
44759
  init_frozen();
44720
- CHECKER_VERSION = "skill-resource-closure-v2";
44760
+ await init_registry2();
44761
+ CHECKER_VERSION = "skill-resource-closure-v3";
44721
44762
  BARE_PREFIXES = ["references/", "assets/", "schemas/", "examples/", "scripts/"];
44722
44763
  EXPLICIT_PREFIXES = [
44723
44764
  "<plugin-root>/",
@@ -44731,6 +44772,7 @@ var init_skill_resource_closure = __esm({
44731
44772
  MACHINE_ABSOLUTE_PATTERN = /^(?:\/(?:Users|home|root|tmp|var|etc|opt)(?:\/|$)|[A-Za-z]:[\\/])/u;
44732
44773
  HOME_DIRECTORY_PATTERN = /^(?:~|\$HOME|\$\{HOME\})\/.+/u;
44733
44774
  ADAPTER_SURFACE_PATTERN = /^adapters\/([^/]+)$/u;
44775
+ PLATFORM_SURFACE_PATTERN = /^platforms\/(.+)$/u;
44734
44776
  CLOSURE_RESOURCE_DIRS = Object.freeze(["references", "assets", "schemas", "examples", "scripts"]);
44735
44777
  GLOB_PATTERN = /[*?\[]/u;
44736
44778
  SOURCE_ONLY_MARKER = /(?:\bsource-only\b|仅源码包)/iu;
@@ -44748,7 +44790,8 @@ var init_skill_resource_closure = __esm({
44748
44790
  HOME_DIRECTORY: "home_directory",
44749
44791
  OUT_OF_BOUNDS: "out_of_bounds",
44750
44792
  RESOURCE_DRIFT: "resource_drift",
44751
- STALE_RESOURCE: "stale_resource"
44793
+ STALE_RESOURCE: "stale_resource",
44794
+ UNKNOWN_PLATFORM_SURFACE: "unknown_platform_surface"
44752
44795
  });
44753
44796
  FINDING_CODE = Object.freeze({
44754
44797
  SNAPSHOT_UNSAFE: "SNAPSHOT_UNSAFE",
@@ -44760,7 +44803,8 @@ var init_skill_resource_closure = __esm({
44760
44803
  OUT_OF_BOUNDS: "OUT_OF_BOUNDS",
44761
44804
  SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED",
44762
44805
  RESOURCE_DRIFT: "RESOURCE_DRIFT",
44763
- STALE_RESOURCE: "STALE_RESOURCE"
44806
+ STALE_RESOURCE: "STALE_RESOURCE",
44807
+ UNKNOWN_PLATFORM_SURFACE: "UNKNOWN_PLATFORM_SURFACE"
44764
44808
  });
44765
44809
  __name(toPosix, "toPosix");
44766
44810
  __name(relativeStable, "relativeStable");
@@ -100763,7 +100807,7 @@ var init_prepare = __esm({
100763
100807
  init_evidence();
100764
100808
  await init_plan();
100765
100809
  init_digest();
100766
- init_skill_resource_closure();
100810
+ await init_skill_resource_closure();
100767
100811
  init_public_map();
100768
100812
  init_public_path();
100769
100813
  init_scan();
@@ -102785,7 +102829,7 @@ var init_publish = __esm({
102785
102829
  init_baseline2();
102786
102830
  init_previous_public_baseline();
102787
102831
  init_evidence();
102788
- init_skill_resource_closure();
102832
+ await init_skill_resource_closure();
102789
102833
  init_checkpoints();
102790
102834
  await init_run();
102791
102835
  init_errors3();
@@ -105332,7 +105376,7 @@ var init_verify = __esm({
105332
105376
  init_public_path();
105333
105377
  init_npm();
105334
105378
  init_verification_gates();
105335
- init_skill_resource_closure();
105379
+ await init_skill_resource_closure();
105336
105380
  init_checkpoints();
105337
105381
  init_installation_contract();
105338
105382
  init_npm_entry_closure();
@@ -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.7.3"});
12
+ const __bundlePkg = Object.freeze({"name":"release-skill","version":"0.7.4"});
13
13
  // Build-time source digest for the BUNDLE_STALE freshness gate (see above).
14
- const __bundleSourceDigest = "0e814c8b806446476595498baed8b129ca3cb024e3b922049db5774f022c90be";
14
+ const __bundleSourceDigest = "94f8a4247206a95c5365d48448b1cce5e47d4fc42a711ac72e761565bc2dcb69";
15
15
 
16
16
  var __create = Object.create;
17
17
  var __defProp = Object.defineProperty;
@@ -36390,8 +36390,13 @@ function getPlatform(id) {
36390
36390
  if (!platform) throw new Error(`unknown platform: ${id}`);
36391
36391
  return platform;
36392
36392
  }
36393
+ function resolveSkillProjectionSurfaceHost(surfaceId, registry = PLATFORMS) {
36394
+ const platform = registry.find((item) => item.skillProjectionSurface === surfaceId);
36395
+ return platform?.buildAdapter?.name ?? null;
36396
+ }
36393
36397
  function assertRegistry(registry = PLATFORMS) {
36394
36398
  const seen = /* @__PURE__ */ new Set();
36399
+ const seenSkillProjectionSurfaces = /* @__PURE__ */ new Set();
36395
36400
  for (const platform of registry) {
36396
36401
  const label = platform?.id ?? "<missing id>";
36397
36402
  if (typeof platform?.id !== "string" || platform.id.length === 0) {
@@ -36440,6 +36445,16 @@ function assertRegistry(registry = PLATFORMS) {
36440
36445
  if (typeof platform.buildAdapter.name !== "string" || platform.buildAdapter.name.length === 0) {
36441
36446
  throw new Error(`platform registry: ${label} buildAdapter needs a non-empty name (its adapter directory name)`);
36442
36447
  }
36448
+ if (typeof platform.skillProjectionSurface !== "string" || !SKILL_PROJECTION_SURFACE_PATTERN.test(platform.skillProjectionSurface)) {
36449
+ throw new Error(`platform registry: ${label} skillProjectionSurface must match platforms/<slug>`);
36450
+ }
36451
+ if (seenSkillProjectionSurfaces.has(platform.skillProjectionSurface)) {
36452
+ throw new Error(`platform registry: duplicate skillProjectionSurface "${platform.skillProjectionSurface}"; aliases must be unique`);
36453
+ }
36454
+ seenSkillProjectionSurfaces.add(platform.skillProjectionSurface);
36455
+ if (resolveSkillProjectionSurfaceHost(platform.skillProjectionSurface, registry) !== platform.buildAdapter.name) {
36456
+ throw new Error(`platform registry: ${label} skillProjectionSurface must map to buildAdapter.name`);
36457
+ }
36443
36458
  if (!VALID_LIST_OUTPUTS.has(platform.jsonProtocol?.listOutput)) {
36444
36459
  throw new Error(`platform registry: ${label} has illegal jsonProtocol.listOutput "${platform.jsonProtocol?.listOutput}"`);
36445
36460
  }
@@ -36567,7 +36582,7 @@ function resolveCapabilityConflicts(platform) {
36567
36582
  }
36568
36583
  return { hasConflict: false, conflicts: [] };
36569
36584
  }
36570
- var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES;
36585
+ var CLAUDE, CODEX, KIMI, CODEBUDDY, PLATFORMS, VALID_DISTRIBUTION_TYPES, VALID_ACTION_TYPES, VALID_SOURCE_FORMS, VALID_MARKETPLACE_REF_FORMS, VALID_LIST_OUTPUTS, VALID_CLI_OUTPUTS, VALID_ENTRY_VERSION_BINDING, VALID_INSTALL_METHODS, VALID_REF_STRENGTHS, VALID_OUTPUT_PROTOCOLS, VALID_IDENTITY_EVIDENCE, VALID_DEGRADATION_POLICIES, SKILL_PROJECTION_SURFACE_PATTERN;
36571
36586
  var init_registry2 = __esm({
36572
36587
  async "src/platforms/registry.mjs"() {
36573
36588
  await init_kimi();
@@ -36582,6 +36597,7 @@ var init_registry2 = __esm({
36582
36597
  __name(codexCrossValidateListEntry, "codexCrossValidateListEntry");
36583
36598
  CLAUDE = Object.freeze({
36584
36599
  id: "claude",
36600
+ skillProjectionSurface: "platforms/claude-code",
36585
36601
  distributionType: "claude-plugin",
36586
36602
  actionType: "claude-marketplace-install",
36587
36603
  // Runtime adapter implementing this platform's marketplace-install action.
@@ -36646,6 +36662,7 @@ var init_registry2 = __esm({
36646
36662
  });
36647
36663
  CODEX = Object.freeze({
36648
36664
  id: "codex",
36665
+ skillProjectionSurface: "platforms/codex",
36649
36666
  distributionType: "codex-plugin",
36650
36667
  actionType: "codex-marketplace-install",
36651
36668
  adapter: "plugin-marketplace",
@@ -36706,6 +36723,7 @@ var init_registry2 = __esm({
36706
36723
  });
36707
36724
  KIMI = Object.freeze({
36708
36725
  id: "kimi",
36726
+ skillProjectionSurface: "platforms/kimi-code",
36709
36727
  distributionType: "kimi-plugin",
36710
36728
  actionType: "kimi-marketplace-install",
36711
36729
  adapter: "plugin-marketplace",
@@ -36765,6 +36783,7 @@ var init_registry2 = __esm({
36765
36783
  });
36766
36784
  CODEBUDDY = Object.freeze({
36767
36785
  id: "codebuddy",
36786
+ skillProjectionSurface: "platforms/workbuddy",
36768
36787
  distributionType: "codebuddy-plugin",
36769
36788
  actionType: "codebuddy-marketplace-install",
36770
36789
  adapter: "plugin-marketplace",
@@ -36847,7 +36866,9 @@ var init_registry2 = __esm({
36847
36866
  VALID_OUTPUT_PROTOCOLS = /* @__PURE__ */ new Set(["structured", "text", "none"]);
36848
36867
  VALID_IDENTITY_EVIDENCE = /* @__PURE__ */ new Set(["list-record", "install-output", "filesystem-payload", "human-attestation"]);
36849
36868
  VALID_DEGRADATION_POLICIES = /* @__PURE__ */ new Set(["block", "human-attestation", "human-attestation-with-fallback"]);
36869
+ SKILL_PROJECTION_SURFACE_PATTERN = /^platforms\/[a-z0-9]+(?:-[a-z0-9]+)*$/u;
36850
36870
  __name(getPlatform, "getPlatform");
36871
+ __name(resolveSkillProjectionSurfaceHost, "resolveSkillProjectionSurfaceHost");
36851
36872
  __name(assertRegistry, "assertRegistry");
36852
36873
  assertRegistry();
36853
36874
  __name(resolvePlatformRoute, "resolvePlatformRoute");
@@ -44399,8 +44420,13 @@ async function collectRegularFiles(dir, results) {
44399
44420
  }
44400
44421
  }
44401
44422
  function inferSurfaceHost(surfaceId, defaultHost) {
44402
- const match = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
44403
- return match?.[1] ?? defaultHost;
44423
+ const adapterMatch = ADAPTER_SURFACE_PATTERN.exec(surfaceId);
44424
+ if (adapterMatch) return adapterMatch[1];
44425
+ const platformMatch = PLATFORM_SURFACE_PATTERN.exec(surfaceId);
44426
+ if (platformMatch) {
44427
+ return resolveSkillProjectionSurfaceHost(surfaceId) ?? `unknown-platform:${platformMatch[1]}`;
44428
+ }
44429
+ return defaultHost;
44404
44430
  }
44405
44431
  function receiptProjection(result) {
44406
44432
  return {
@@ -44509,6 +44535,7 @@ async function checkSkillResourceClosure({
44509
44535
  const pluginRoot = resolvePluginRoot(skill, scanRoot2);
44510
44536
  const surfaceId = relativeStable(scanRoot2, pluginRoot);
44511
44537
  const surfaceHost = inferSurfaceHost(surfaceId, host);
44538
+ const firstSkillOnSurface = !surfaceMap.has(surfaceId);
44512
44539
  const surface = surfaceMap.get(surfaceId) ?? {
44513
44540
  id: surfaceId,
44514
44541
  host: surfaceHost,
@@ -44518,6 +44545,19 @@ async function checkSkillResourceClosure({
44518
44545
  };
44519
44546
  surface.skillCount += 1;
44520
44547
  surfaceMap.set(surfaceId, surface);
44548
+ if (firstSkillOnSurface && PLATFORM_SURFACE_PATTERN.test(surfaceId) && resolveSkillProjectionSurfaceHost(surfaceId) === null) {
44549
+ findings.push({
44550
+ host: surfaceHost,
44551
+ surface: surfaceId,
44552
+ skill: null,
44553
+ line: null,
44554
+ reference: surfaceId,
44555
+ classification: CLASSIFICATION.UNKNOWN_PLATFORM_SURFACE,
44556
+ resolutionRoot: surfaceId,
44557
+ resolvedTarget: surfaceId,
44558
+ code: FINDING_CODE.UNKNOWN_PLATFORM_SURFACE
44559
+ });
44560
+ }
44521
44561
  if (!skillsBySurface.has(surfaceId)) skillsBySurface.set(surfaceId, []);
44522
44562
  skillsBySurface.get(surfaceId).push(skill);
44523
44563
  const content = await readFile12(resolve17(scanRoot2, skill), "utf8");
@@ -44711,13 +44751,14 @@ function evaluateDeclaredHostSurfaceCoverage(expectedHosts, surfaces) {
44711
44751
  }
44712
44752
  return { passed: missing.length === 0, missing };
44713
44753
  }
44714
- 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;
44754
+ var CHECKER_VERSION, BARE_PREFIXES, EXPLICIT_PREFIXES, SOURCE_TREE_PATTERN, MACHINE_ABSOLUTE_PATTERN, HOME_DIRECTORY_PATTERN, ADAPTER_SURFACE_PATTERN, PLATFORM_SURFACE_PATTERN, CLOSURE_RESOURCE_DIRS, GLOB_PATTERN, SOURCE_ONLY_MARKER, TRANSPORT_EXCLUSIONS, CLASSIFICATION, FINDING_CODE;
44715
44755
  var init_skill_resource_closure = __esm({
44716
- "src/core/skill-resource-closure.mjs"() {
44756
+ async "src/core/skill-resource-closure.mjs"() {
44717
44757
  init_src();
44718
44758
  init_errors3();
44719
44759
  init_frozen();
44720
- CHECKER_VERSION = "skill-resource-closure-v2";
44760
+ await init_registry2();
44761
+ CHECKER_VERSION = "skill-resource-closure-v3";
44721
44762
  BARE_PREFIXES = ["references/", "assets/", "schemas/", "examples/", "scripts/"];
44722
44763
  EXPLICIT_PREFIXES = [
44723
44764
  "<plugin-root>/",
@@ -44731,6 +44772,7 @@ var init_skill_resource_closure = __esm({
44731
44772
  MACHINE_ABSOLUTE_PATTERN = /^(?:\/(?:Users|home|root|tmp|var|etc|opt)(?:\/|$)|[A-Za-z]:[\\/])/u;
44732
44773
  HOME_DIRECTORY_PATTERN = /^(?:~|\$HOME|\$\{HOME\})\/.+/u;
44733
44774
  ADAPTER_SURFACE_PATTERN = /^adapters\/([^/]+)$/u;
44775
+ PLATFORM_SURFACE_PATTERN = /^platforms\/(.+)$/u;
44734
44776
  CLOSURE_RESOURCE_DIRS = Object.freeze(["references", "assets", "schemas", "examples", "scripts"]);
44735
44777
  GLOB_PATTERN = /[*?\[]/u;
44736
44778
  SOURCE_ONLY_MARKER = /(?:\bsource-only\b|仅源码包)/iu;
@@ -44748,7 +44790,8 @@ var init_skill_resource_closure = __esm({
44748
44790
  HOME_DIRECTORY: "home_directory",
44749
44791
  OUT_OF_BOUNDS: "out_of_bounds",
44750
44792
  RESOURCE_DRIFT: "resource_drift",
44751
- STALE_RESOURCE: "stale_resource"
44793
+ STALE_RESOURCE: "stale_resource",
44794
+ UNKNOWN_PLATFORM_SURFACE: "unknown_platform_surface"
44752
44795
  });
44753
44796
  FINDING_CODE = Object.freeze({
44754
44797
  SNAPSHOT_UNSAFE: "SNAPSHOT_UNSAFE",
@@ -44760,7 +44803,8 @@ var init_skill_resource_closure = __esm({
44760
44803
  OUT_OF_BOUNDS: "OUT_OF_BOUNDS",
44761
44804
  SYMLINK_NOT_ALLOWED: "SYMLINK_NOT_ALLOWED",
44762
44805
  RESOURCE_DRIFT: "RESOURCE_DRIFT",
44763
- STALE_RESOURCE: "STALE_RESOURCE"
44806
+ STALE_RESOURCE: "STALE_RESOURCE",
44807
+ UNKNOWN_PLATFORM_SURFACE: "UNKNOWN_PLATFORM_SURFACE"
44764
44808
  });
44765
44809
  __name(toPosix, "toPosix");
44766
44810
  __name(relativeStable, "relativeStable");
@@ -100763,7 +100807,7 @@ var init_prepare = __esm({
100763
100807
  init_evidence();
100764
100808
  await init_plan();
100765
100809
  init_digest();
100766
- init_skill_resource_closure();
100810
+ await init_skill_resource_closure();
100767
100811
  init_public_map();
100768
100812
  init_public_path();
100769
100813
  init_scan();
@@ -102785,7 +102829,7 @@ var init_publish = __esm({
102785
102829
  init_baseline2();
102786
102830
  init_previous_public_baseline();
102787
102831
  init_evidence();
102788
- init_skill_resource_closure();
102832
+ await init_skill_resource_closure();
102789
102833
  init_checkpoints();
102790
102834
  await init_run();
102791
102835
  init_errors3();
@@ -105332,7 +105376,7 @@ var init_verify = __esm({
105332
105376
  init_public_path();
105333
105377
  init_npm();
105334
105378
  init_verification_gates();
105335
- init_skill_resource_closure();
105379
+ await init_skill_resource_closure();
105336
105380
  init_checkpoints();
105337
105381
  init_installation_contract();
105338
105382
  init_npm_entry_closure();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "release-skill",
3
- "version": "0.7.3",
3
+ "version": "0.7.4",
4
4
  "description": "Safe preparation and frozen GitHub/npm production publishing with full happy end verification",
5
5
  "author": {
6
6
  "name": "广州市风荷科技有限公司"
@@ -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.7.3",
5
+ "version": "0.7.4",
6
6
  "logicalRoot": "skills-src/",
7
7
  "logicalRootDigest": "3767fc36f42ca561f5e839cea7b7e5bc16d08c47867b5bd6086f25efd0cb0f06",
8
8
  "projectionDigest": "419f7f9601015459956e10aae74f42240ab2ac248238ff7494f3e761643d1749",
9
- "projectionId": "release-skill:platform:0.7.3",
9
+ "projectionId": "release-skill:platform:0.7.4",
10
10
  "manifestRequired": true,
11
11
  "projectionSources": {
12
12
  "skills-src-root": {