@skill-map/cli 0.50.1 → 0.52.0

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/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // kernel/i18n/registry.texts.ts
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="66c91062-e32c-5685-861d-a744103465f8")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e78e8b63-f577-5c6a-9522-9187b69e1ed7")}catch(e){}}();
4
4
  var REGISTRY_TEXTS = {
5
5
  duplicateExtension: "Extension already registered: {{kind}}:{{qualifiedId}}",
6
6
  unknownKind: "Unknown extension kind: {{kind}}",
@@ -95,14 +95,14 @@ var Registry = class {
95
95
  };
96
96
 
97
97
  // kernel/orchestrator/index.ts
98
- import { existsSync as existsSync11, statSync as statSync4 } from "fs";
99
- import { isAbsolute as isAbsolute4, resolve as resolve11 } from "path";
98
+ import { existsSync as existsSync10, statSync as statSync4 } from "fs";
99
+ import { isAbsolute as isAbsolute3, resolve as resolve9 } from "path";
100
100
  import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
101
101
 
102
102
  // package.json
103
103
  var package_default = {
104
104
  name: "@skill-map/cli",
105
- version: "0.50.1",
105
+ version: "0.52.0",
106
106
  description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
107
107
  license: "MIT",
108
108
  type: "module",
@@ -698,364 +698,9 @@ var ORCHESTRATOR_TEXTS = {
698
698
  runScanRootMissing: "runScan: root path '{{root}}' does not exist or is not a directory"
699
699
  };
700
700
 
701
- // core/config/active-provider.ts
702
- import { existsSync as existsSync5 } from "fs";
703
- import { join as join6 } from "path";
704
-
705
- // core/config/helper.ts
706
- import { homedir as osHomedir } from "os";
707
- import { isAbsolute as isAbsolute2, join as join5, resolve as resolve6, sep } from "path";
708
-
709
- // kernel/config/loader.ts
710
- import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
711
-
712
- // kernel/i18n/config-loader.texts.ts
713
- var CONFIG_LOADER_TEXTS = {
714
- readFailure: "[config:{{layer}}] failed to read {{path}}: {{message}}",
715
- invalidJson: "[config:{{layer}}] invalid JSON in {{path}}: {{message}}",
716
- expectedObject: "[config:{{layer}}] expected a JSON object, got {{type}}; ignored",
717
- unknownKey: "[config:{{layer}}] unknown key {{key}} ignored",
718
- invalidValue: "[config:{{layer}}] invalid value at {{path}}: {{message}}",
719
- projectLocalOnlyStripped: "[config:{{layer}}] key {{key}} is project-local only; stripped from the committed project layer. Move it to .skill-map/settings.local.json (gitignored, per-checkout)."
720
- };
721
-
722
- // kernel/util/skill-map-paths.ts
723
- import { join as join4 } from "path";
724
-
725
- // core/paths/db-path.ts
726
- import { join as join3, resolve as resolve5 } from "path";
727
- var SKILL_MAP_DIR = ".skill-map";
728
- var DB_FILENAME = "skill-map.db";
729
- var LOCAL_SETTINGS_FILENAME = "settings.local.json";
730
- var DEFAULT_DB_REL = `${SKILL_MAP_DIR}/${DB_FILENAME}`;
731
- var GITIGNORE_ENTRIES = [
732
- `${SKILL_MAP_DIR}/${LOCAL_SETTINGS_FILENAME}`,
733
- `${SKILL_MAP_DIR}/${DB_FILENAME}`
734
- ];
735
-
736
- // kernel/util/skill-map-paths.ts
737
- var KERNEL_SKILL_MAP_DIR = SKILL_MAP_DIR;
738
- var SETTINGS_FILENAME = "settings.json";
739
- var LOCAL_SETTINGS_FILENAME2 = "settings.local.json";
740
- function kernelSettingsPath(scopeRoot) {
741
- return join4(scopeRoot, KERNEL_SKILL_MAP_DIR, SETTINGS_FILENAME);
742
- }
743
- function kernelLocalSettingsPath(scopeRoot) {
744
- return join4(scopeRoot, KERNEL_SKILL_MAP_DIR, LOCAL_SETTINGS_FILENAME2);
745
- }
746
-
747
- // kernel/util/strip-prototype-pollution.ts
748
- var FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
749
- "__proto__",
750
- "constructor",
751
- "prototype"
752
- ]);
753
- function stripPrototypePollution(value) {
754
- return strip(value);
755
- }
756
- function strip(value) {
757
- if (value === null || value === void 0) return value;
758
- if (typeof value !== "object") return value;
759
- if (Array.isArray(value)) return value.map(strip);
760
- const out = {};
761
- for (const [k, v] of Object.entries(value)) {
762
- if (FORBIDDEN_KEYS.has(k)) continue;
763
- out[k] = strip(v);
764
- }
765
- return out;
766
- }
767
-
768
- // config/defaults.json
769
- var defaults_default = {
770
- schemaVersion: 1,
771
- allowEditSmFiles: false,
772
- tokenizer: "cl100k_base",
773
- roots: [],
774
- ignore: [],
775
- scan: {
776
- tokenize: true,
777
- strict: false,
778
- maxFileSizeBytes: 1048576,
779
- maxNodes: 256,
780
- watch: {
781
- debounceMs: 300
782
- },
783
- referencePaths: []
784
- },
785
- plugins: {},
786
- jobs: {
787
- ttlSeconds: 3600,
788
- graceMultiplier: 3,
789
- minimumTtlSeconds: 60,
790
- perActionTtl: {},
791
- perActionPriority: {},
792
- retention: {
793
- completed: 2592e3,
794
- failed: null
795
- }
796
- }
797
- };
798
-
799
- // kernel/config/loader.ts
800
- var PROJECT_LOCAL_ONLY_KEYS = /* @__PURE__ */ new Set([
801
- "allowEditSmFiles",
802
- "scan.referencePaths"
803
- ]);
804
- var DEFAULTS = defaults_default;
805
- function loadConfig(opts) {
806
- const cwd = opts.cwd;
807
- const strict = opts.strict ?? false;
808
- const warnings = [];
809
- const sources = /* @__PURE__ */ new Map();
810
- const validators = loadSchemaValidators();
811
- let effective = structuredClone(DEFAULTS);
812
- recordSources("", effective, sources, "defaults");
813
- const filePairs = [
814
- { path: kernelSettingsPath(cwd), layer: "project" },
815
- { path: kernelLocalSettingsPath(cwd), layer: "project-local" }
816
- ];
817
- for (const { path, layer } of filePairs) {
818
- if (!existsSync3(path)) continue;
819
- const partial = readJsonSafe(path, layer, warnings, strict);
820
- if (partial === null) continue;
821
- const cleaned = validateAndStrip(validators, partial, layer, warnings, strict);
822
- if (layer !== "project-local") {
823
- stripProjectLocalOnlyKeys(cleaned, layer, warnings, strict);
824
- }
825
- effective = deepMerge(effective, cleaned);
826
- recordSources("", cleaned, sources, layer);
827
- }
828
- if (opts.overrides && Object.keys(opts.overrides).length > 0) {
829
- const cleaned = validateAndStrip(validators, opts.overrides, "override", warnings, strict);
830
- stripProjectLocalOnlyKeys(cleaned, "override", warnings, strict);
831
- effective = deepMerge(effective, cleaned);
832
- recordSources("", cleaned, sources, "override");
833
- }
834
- return { effective, sources, warnings };
835
- }
836
- function readJsonSafe(path, layer, warnings, strict) {
837
- let text;
838
- try {
839
- text = readFileSync5(path, "utf8");
840
- } catch (err) {
841
- return reportAndSkip(
842
- tx(CONFIG_LOADER_TEXTS.readFailure, { layer, path, message: formatErrorMessage(err) }),
843
- warnings,
844
- strict
845
- );
846
- }
847
- try {
848
- return JSON.parse(text);
849
- } catch (err) {
850
- return reportAndSkip(
851
- tx(CONFIG_LOADER_TEXTS.invalidJson, { layer, path, message: formatErrorMessage(err) }),
852
- warnings,
853
- strict
854
- );
855
- }
856
- }
857
- function reportAndSkip(msg, warnings, strict) {
858
- if (strict) throw new Error(msg);
859
- warnings.push(msg);
860
- return null;
861
- }
862
- function validateAndStrip(validators, raw, layer, warnings, strict) {
863
- if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
864
- const msg = tx(CONFIG_LOADER_TEXTS.expectedObject, { layer, type: describeJsonType(raw) });
865
- if (strict) throw new Error(msg);
866
- warnings.push(msg);
867
- return {};
868
- }
869
- const cloned = structuredClone(raw);
870
- const validator = validators.getValidator("project-config");
871
- if (validator(cloned)) return cloned;
872
- for (const err of validator.errors ?? []) {
873
- applyValidationError(cloned, err, layer, warnings, strict);
874
- }
875
- return cloned;
876
- }
877
- function applyValidationError(cloned, err, layer, warnings, strict) {
878
- const path = err.instancePath ?? "";
879
- if (err.keyword === "additionalProperties") {
880
- const extra = err.params.additionalProperty;
881
- deleteAtPath(cloned, path, extra);
882
- const msg2 = tx(CONFIG_LOADER_TEXTS.unknownKey, { layer, key: joinSegments(path, extra) });
883
- if (strict) throw new Error(msg2);
884
- warnings.push(msg2);
885
- return;
886
- }
887
- const segments = path.split("/").filter(Boolean);
888
- if (segments.length > 0) {
889
- const last = segments.pop();
890
- deleteAtPath(cloned, "/" + segments.join("/"), last);
891
- }
892
- const msg = tx(CONFIG_LOADER_TEXTS.invalidValue, {
893
- layer,
894
- path: path || "(root)",
895
- message: err.message ?? err.keyword
896
- });
897
- if (strict) throw new Error(msg);
898
- warnings.push(msg);
899
- }
900
- function describeJsonType(v) {
901
- if (v === null) return "null";
902
- if (Array.isArray(v)) return "array";
903
- return typeof v;
904
- }
905
- function deleteAtPath(root, parentPath, key) {
906
- if (containsForbidden(parentPath, key)) return;
907
- const segments = parentPath.split("/").filter(Boolean);
908
- let cur = root;
909
- for (const seg of segments) {
910
- if (!isPlainObject(cur)) return;
911
- cur = cur[seg];
912
- }
913
- if (isPlainObject(cur)) delete cur[key];
914
- }
915
- function stripProjectLocalOnlyKeys(cloned, layer, warnings, strict) {
916
- for (const dotKey of PROJECT_LOCAL_ONLY_KEYS) {
917
- const segments = dotKey.split(".").filter(Boolean);
918
- if (segments.length === 0) continue;
919
- const leaf = segments.pop();
920
- if (!keyPresentAtPath(cloned, segments, leaf)) continue;
921
- const parentPath = "/" + segments.join("/");
922
- deleteAtPath(cloned, parentPath, leaf);
923
- const msg = tx(CONFIG_LOADER_TEXTS.projectLocalOnlyStripped, {
924
- layer,
925
- key: dotKey
926
- });
927
- if (strict) throw new Error(msg);
928
- warnings.push(msg);
929
- }
930
- }
931
- function keyPresentAtPath(root, parentSegments, leaf) {
932
- let cur = root;
933
- for (const seg of parentSegments) {
934
- if (!isPlainObject(cur)) return false;
935
- cur = cur[seg];
936
- }
937
- return isPlainObject(cur) && Object.prototype.hasOwnProperty.call(cur, leaf);
938
- }
939
- function isPlainObject(v) {
940
- return v !== null && typeof v === "object" && !Array.isArray(v);
941
- }
942
- function containsForbidden(parentPath, leaf) {
943
- if (FORBIDDEN_KEYS.has(leaf)) return true;
944
- for (const seg of parentPath.split("/")) {
945
- if (FORBIDDEN_KEYS.has(seg)) return true;
946
- }
947
- return false;
948
- }
949
- function joinSegments(instancePath, leaf) {
950
- const segments = instancePath.split("/").filter(Boolean);
951
- return [...segments, leaf].join(".");
952
- }
953
- function deepMerge(target, source) {
954
- const out = { ...target };
955
- for (const [k, v] of Object.entries(source)) {
956
- if (FORBIDDEN_KEYS.has(k)) continue;
957
- out[k] = mergeValue(out[k], v);
958
- }
959
- return out;
960
- }
961
- function mergeValue(target, source) {
962
- if (source === null || typeof source !== "object" || Array.isArray(source)) {
963
- return source;
964
- }
965
- const targetSlot = target !== null && typeof target === "object" && !Array.isArray(target) ? target : {};
966
- return deepMerge(targetSlot, source);
967
- }
968
- function recordSources(prefix, value, map, layer) {
969
- if (value === null || typeof value !== "object" || Array.isArray(value)) {
970
- if (prefix) map.set(prefix, layer);
971
- return;
972
- }
973
- const entries = Object.entries(value);
974
- if (entries.length === 0 && prefix) {
975
- map.set(prefix, layer);
976
- return;
977
- }
978
- for (const [k, v] of entries) {
979
- const next = prefix ? `${prefix}.${k}` : k;
980
- recordSources(next, v, map, layer);
981
- }
982
- }
983
-
984
- // core/config/dot-path.ts
985
- var FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set([
986
- "__proto__",
987
- "constructor",
988
- "prototype"
989
- ]);
990
- var ForbiddenSegmentError = class extends Error {
991
- constructor(segment, key) {
992
- super(`forbidden config key segment "${segment}" in "${key}"`);
993
- this.segment = segment;
994
- this.key = key;
995
- }
996
- segment;
997
- key;
998
- };
999
- function assertSafeSegments(segments, key) {
1000
- for (const seg of segments) {
1001
- if (FORBIDDEN_SEGMENTS.has(seg)) throw new ForbiddenSegmentError(seg, key);
1002
- }
1003
- }
1004
- function getAtPath(obj, dotPath) {
1005
- const segments = dotPath.split(".").filter(Boolean);
1006
- assertSafeSegments(segments, dotPath);
1007
- let cur = obj;
1008
- for (const seg of segments) {
1009
- if (cur && typeof cur === "object" && !Array.isArray(cur)) {
1010
- cur = cur[seg];
1011
- continue;
1012
- }
1013
- return void 0;
1014
- }
1015
- return cur;
1016
- }
1017
-
1018
- // core/config/atomic-write.ts
1019
- import {
1020
- closeSync,
1021
- constants as fsConstants,
1022
- existsSync as existsSync4,
1023
- mkdirSync,
1024
- openSync,
1025
- readFileSync as readFileSync6,
1026
- renameSync,
1027
- unlinkSync,
1028
- writeSync
1029
- } from "fs";
1030
- import { randomBytes } from "crypto";
1031
- import { dirname as dirname3 } from "path";
1032
-
1033
- // core/config/helper.ts
1034
- function readConfigValue(key, opts) {
1035
- const loaded = loadConfigForScope(opts);
1036
- const value = getAtPath(loaded.effective, key);
1037
- if (value === void 0) return opts.default;
1038
- return value;
1039
- }
1040
- function loadConfigForScope(opts) {
1041
- return loadConfig({
1042
- cwd: opts.cwd,
1043
- ...opts.strict ? { strict: true } : {}
1044
- });
1045
- }
1046
-
1047
- // core/config/active-provider.ts
1048
- function resolveActiveProvider(cwd, providers = []) {
1049
- const detected = detectProvidersFromFilesystem(cwd, providers);
1050
- const fromConfig = readConfigValue("activeProvider", { cwd });
1051
- if (typeof fromConfig === "string" && fromConfig.length > 0) {
1052
- return { resolved: fromConfig, source: "config", detected };
1053
- }
1054
- if (detected.length > 0) {
1055
- return { resolved: detected[0], source: "autodetect", detected };
1056
- }
1057
- return { resolved: null, source: "none", detected };
1058
- }
701
+ // kernel/scan/detect-providers.ts
702
+ import { existsSync as existsSync3 } from "fs";
703
+ import { join as join3 } from "path";
1059
704
  function detectProvidersFromFilesystem(cwd, providers) {
1060
705
  const seen = /* @__PURE__ */ new Set();
1061
706
  const out = [];
@@ -1063,7 +708,7 @@ function detectProvidersFromFilesystem(cwd, providers) {
1063
708
  if (seen.has(provider.id)) continue;
1064
709
  const markers = provider.detect?.markers;
1065
710
  if (!markers || markers.length === 0) continue;
1066
- if (!markers.some((marker) => existsSync5(join6(cwd, marker)))) continue;
711
+ if (!markers.some((marker) => existsSync3(join3(cwd, marker)))) continue;
1067
712
  seen.add(provider.id);
1068
713
  out.push(provider.id);
1069
714
  }
@@ -1801,7 +1446,7 @@ function liftResolvedLinkConfidence(links, nodes, ctx) {
1801
1446
  const indexes = buildIndexes(nodes, ctx);
1802
1447
  for (const link of links) {
1803
1448
  if (link.confidence >= 1) continue;
1804
- const resolution = resolve7(link, indexes, ctx);
1449
+ const resolution = resolve5(link, indexes, ctx);
1805
1450
  if (resolution === "none") continue;
1806
1451
  link.confidence = ctx.reservedNodePaths.has(resolution) ? RESERVED_TARGET_CONFIDENCE : 1;
1807
1452
  link.resolvedTarget = resolution;
@@ -1818,7 +1463,7 @@ function buildIndexes(nodes, ctx) {
1818
1463
  }
1819
1464
  return { byPath: byPath2, byName, nodeByPath };
1820
1465
  }
1821
- function resolve7(link, indexes, ctx) {
1466
+ function resolve5(link, indexes, ctx) {
1822
1467
  if (indexes.byPath.has(link.target)) return link.target;
1823
1468
  return resolveByName(link, indexes, ctx);
1824
1469
  }
@@ -2202,11 +1847,11 @@ function detectRenamesAndOrphans(prior, current, issues, silenced) {
2202
1847
 
2203
1848
  // kernel/scan/walk-content.ts
2204
1849
  import { readFile, readdir, lstat } from "fs/promises";
2205
- import { join as join7, relative as relative2, sep as sep2 } from "path";
1850
+ import { join as join4, relative as relative2, sep } from "path";
2206
1851
 
2207
1852
  // kernel/scan/ignore.ts
2208
- import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
2209
- import { dirname as dirname4, resolve as resolve8 } from "path";
1853
+ import { existsSync as existsSync4, readFileSync as readFileSync5 } from "fs";
1854
+ import { dirname as dirname3, resolve as resolve6 } from "path";
2210
1855
  import { fileURLToPath } from "url";
2211
1856
  import ignoreFactory from "ignore";
2212
1857
  function buildIgnoreFilter(opts = {}) {
@@ -2238,18 +1883,18 @@ function loadDefaultsText() {
2238
1883
  return cachedDefaults;
2239
1884
  }
2240
1885
  function readDefaultsFromDisk() {
2241
- const here = dirname4(fileURLToPath(import.meta.url));
1886
+ const here = dirname3(fileURLToPath(import.meta.url));
2242
1887
  const candidates = [
2243
- resolve8(here, "../../config/defaults/skillmapignore"),
1888
+ resolve6(here, "../../config/defaults/skillmapignore"),
2244
1889
  // src/kernel/scan/ → src/config/defaults/
2245
- resolve8(here, "../config/defaults/skillmapignore"),
1890
+ resolve6(here, "../config/defaults/skillmapignore"),
2246
1891
  // dist/cli.js → dist/config/defaults/ (siblings)
2247
- resolve8(here, "config/defaults/skillmapignore")
1892
+ resolve6(here, "config/defaults/skillmapignore")
2248
1893
  ];
2249
1894
  for (const candidate of candidates) {
2250
- if (existsSync6(candidate)) {
1895
+ if (existsSync4(candidate)) {
2251
1896
  try {
2252
- return readFileSync7(candidate, "utf8");
1897
+ return readFileSync5(candidate, "utf8");
2253
1898
  } catch {
2254
1899
  }
2255
1900
  }
@@ -2259,6 +1904,29 @@ function readDefaultsFromDisk() {
2259
1904
 
2260
1905
  // plugins/core/parsers/frontmatter-yaml/index.ts
2261
1906
  import yaml from "js-yaml";
1907
+
1908
+ // kernel/util/strip-prototype-pollution.ts
1909
+ var FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
1910
+ "__proto__",
1911
+ "constructor",
1912
+ "prototype"
1913
+ ]);
1914
+ function stripPrototypePollution(value) {
1915
+ return strip(value);
1916
+ }
1917
+ function strip(value) {
1918
+ if (value === null || value === void 0) return value;
1919
+ if (typeof value !== "object") return value;
1920
+ if (Array.isArray(value)) return value.map(strip);
1921
+ const out = {};
1922
+ for (const [k, v] of Object.entries(value)) {
1923
+ if (FORBIDDEN_KEYS.has(k)) continue;
1924
+ out[k] = strip(v);
1925
+ }
1926
+ return out;
1927
+ }
1928
+
1929
+ // plugins/core/parsers/frontmatter-yaml/index.ts
2262
1930
  var FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
2263
1931
  var frontmatterYamlParser = {
2264
1932
  id: "frontmatter-yaml",
@@ -2360,7 +2028,7 @@ async function* walkContent(roots, options) {
2360
2028
  const sizeLimit = buildSizeLimit(options);
2361
2029
  for (const root of roots) {
2362
2030
  for await (const file of walkRoot(root, root, filter, extensions, sizeLimit)) {
2363
- const relPath = relative2(root, file).split(sep2).join("/");
2031
+ const relPath = relative2(root, file).split(sep).join("/");
2364
2032
  let raw;
2365
2033
  try {
2366
2034
  raw = await readFile(file, "utf8");
@@ -2399,8 +2067,8 @@ async function* walkRoot(root, current, filter, extensions, sizeLimit) {
2399
2067
  }
2400
2068
  for (const entry of entries) {
2401
2069
  const name = entry.name;
2402
- const full = join7(current, name);
2403
- const rel = relative2(root, full).split(sep2).join("/");
2070
+ const full = join4(current, name);
2071
+ const rel = relative2(root, full).split(sep).join("/");
2404
2072
  if (filter.ignores(rel)) continue;
2405
2073
  if (entry.isSymbolicLink()) continue;
2406
2074
  if (entry.isDirectory()) {
@@ -2452,19 +2120,19 @@ function resolveProviderWalk(provider) {
2452
2120
  }
2453
2121
 
2454
2122
  // kernel/sidecar/parse.ts
2455
- import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
2456
- import { dirname as dirname5, resolve as resolve9 } from "path";
2123
+ import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
2124
+ import { dirname as dirname4, resolve as resolve7 } from "path";
2457
2125
  import { createRequire as createRequire3 } from "module";
2458
2126
  import { Ajv2020 as Ajv20204 } from "ajv/dist/2020.js";
2459
2127
  import yaml2 from "js-yaml";
2460
2128
  function readSidecarFor(mdAbsolutePath) {
2461
2129
  const sidecarPath = sidecarPathFor(mdAbsolutePath);
2462
- if (!existsSync7(sidecarPath)) {
2130
+ if (!existsSync5(sidecarPath)) {
2463
2131
  return { parsed: null, present: false, issues: [] };
2464
2132
  }
2465
2133
  let raw;
2466
2134
  try {
2467
- raw = readFileSync8(sidecarPath, "utf8");
2135
+ raw = readFileSync6(sidecarPath, "utf8");
2468
2136
  } catch (err) {
2469
2137
  return {
2470
2138
  parsed: null,
@@ -2483,7 +2151,7 @@ function readSidecarFor(mdAbsolutePath) {
2483
2151
  };
2484
2152
  }
2485
2153
  parsedYaml = stripPrototypePollution(parsedYaml);
2486
- if (!isPlainObject2(parsedYaml)) {
2154
+ if (!isPlainObject(parsedYaml)) {
2487
2155
  return {
2488
2156
  parsed: null,
2489
2157
  present: true,
@@ -2502,7 +2170,7 @@ function readSidecarFor(mdAbsolutePath) {
2502
2170
  const root = parsedYaml;
2503
2171
  const identityBlock = root["identity"];
2504
2172
  const annotationsRaw = root["annotations"];
2505
- const annotations = isPlainObject2(annotationsRaw) ? Object.keys(annotationsRaw).length === 0 ? null : annotationsRaw : null;
2173
+ const annotations = isPlainObject(annotationsRaw) ? Object.keys(annotationsRaw).length === 0 ? null : annotationsRaw : null;
2506
2174
  return {
2507
2175
  parsed: {
2508
2176
  filePath: sidecarPath,
@@ -2522,7 +2190,7 @@ function sidecarPathFor(mdAbsolutePath) {
2522
2190
  }
2523
2191
  return `${mdAbsolutePath}.sm`;
2524
2192
  }
2525
- function isPlainObject2(value) {
2193
+ function isPlainObject(value) {
2526
2194
  return value !== null && typeof value === "object" && !Array.isArray(value);
2527
2195
  }
2528
2196
  var cachedSidecarValidator = null;
@@ -2532,10 +2200,10 @@ function getSidecarValidator() {
2532
2200
  applyAjvFormats(ajv);
2533
2201
  const specRoot = resolveSpecRoot2();
2534
2202
  const annotationsSchema = JSON.parse(
2535
- readFileSync8(resolve9(specRoot, "schemas/annotations.schema.json"), "utf8")
2203
+ readFileSync6(resolve7(specRoot, "schemas/annotations.schema.json"), "utf8")
2536
2204
  );
2537
2205
  const sidecarSchema = JSON.parse(
2538
- readFileSync8(resolve9(specRoot, "schemas/sidecar.schema.json"), "utf8")
2206
+ readFileSync6(resolve7(specRoot, "schemas/sidecar.schema.json"), "utf8")
2539
2207
  );
2540
2208
  ajv.addSchema(annotationsSchema);
2541
2209
  cachedSidecarValidator = ajv.compile(sidecarSchema);
@@ -2545,7 +2213,7 @@ function resolveSpecRoot2() {
2545
2213
  const require2 = createRequire3(import.meta.url);
2546
2214
  try {
2547
2215
  const indexPath = require2.resolve("@skill-map/spec/index.json");
2548
- return dirname5(indexPath);
2216
+ return dirname4(indexPath);
2549
2217
  } catch {
2550
2218
  throw new Error(
2551
2219
  "@skill-map/spec not resolvable: sidecar reader cannot load schemas."
@@ -2564,8 +2232,8 @@ function computeDriftStatus(args) {
2564
2232
  }
2565
2233
 
2566
2234
  // kernel/sidecar/discover-orphans.ts
2567
- import { existsSync as existsSync8, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
2568
- import { join as join8, relative as relative3, sep as sep3 } from "path";
2235
+ import { existsSync as existsSync6, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
2236
+ import { join as join5, relative as relative3, sep as sep2 } from "path";
2569
2237
  function discoverOrphanSidecars(roots, shouldSkip) {
2570
2238
  const out = [];
2571
2239
  for (const root of roots) {
@@ -2581,8 +2249,8 @@ function walk(root, current, shouldSkip, out) {
2581
2249
  return;
2582
2250
  }
2583
2251
  for (const entry of entries) {
2584
- const full = join8(current, entry.name);
2585
- const rel = relative3(root, full).split(sep3).join("/");
2252
+ const full = join5(current, entry.name);
2253
+ const rel = relative3(root, full).split(sep2).join("/");
2586
2254
  if (shouldSkip(rel)) continue;
2587
2255
  if (entry.isSymbolicLink()) continue;
2588
2256
  if (entry.isDirectory()) {
@@ -2592,7 +2260,7 @@ function walk(root, current, shouldSkip, out) {
2592
2260
  if (!entry.isFile()) continue;
2593
2261
  if (!entry.name.endsWith(".sm")) continue;
2594
2262
  const expectedMd = `${full.slice(0, -".sm".length)}.md`;
2595
- if (existsSync8(expectedMd) && safeIsFile(expectedMd)) continue;
2263
+ if (existsSync6(expectedMd) && safeIsFile(expectedMd)) continue;
2596
2264
  out.push({ sidecarPath: full, relativePath: rel, expectedMdPath: expectedMd });
2597
2265
  }
2598
2266
  }
@@ -2605,16 +2273,31 @@ function safeIsFile(path) {
2605
2273
  }
2606
2274
 
2607
2275
  // kernel/sidecar/store.ts
2608
- import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
2609
- import { dirname as dirname6, resolve as resolve10 } from "path";
2276
+ import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
2277
+ import { dirname as dirname6, resolve as resolve8 } from "path";
2610
2278
  import { createRequire as createRequire4 } from "module";
2611
2279
  import { Ajv2020 as Ajv20205 } from "ajv/dist/2020.js";
2612
2280
  import yaml3 from "js-yaml";
2613
2281
 
2282
+ // kernel/util/atomic-write.ts
2283
+ import {
2284
+ closeSync,
2285
+ constants as fsConstants,
2286
+ existsSync as existsSync7,
2287
+ mkdirSync,
2288
+ openSync,
2289
+ readFileSync as readFileSync7,
2290
+ renameSync,
2291
+ unlinkSync,
2292
+ writeSync
2293
+ } from "fs";
2294
+ import { randomBytes } from "crypto";
2295
+ import { dirname as dirname5 } from "path";
2296
+
2614
2297
  // kernel/orchestrator/node-build.ts
2615
2298
  import { createHash } from "crypto";
2616
- import { existsSync as existsSync10 } from "fs";
2617
- import { isAbsolute as isAbsolute3, resolve as resolvePath } from "path";
2299
+ import { existsSync as existsSync9 } from "fs";
2300
+ import { isAbsolute as isAbsolute2, resolve as resolvePath } from "path";
2618
2301
  import "js-tiktoken/lite";
2619
2302
  import yaml4 from "js-yaml";
2620
2303
 
@@ -2740,7 +2423,7 @@ function resolveSidecarOverlay(relativePath, nodePathForIssue, roots, liveBodyHa
2740
2423
  for (const parseIssue of result.issues) {
2741
2424
  issues.push({
2742
2425
  analyzerId: "invalid-sidecar",
2743
- severity: "warn",
2426
+ severity: "error",
2744
2427
  nodeIds: [nodePathForIssue],
2745
2428
  message: parseIssue.message,
2746
2429
  data: { sidecarPath: relativePathFromRoots(mdAbs, roots) }
@@ -2776,12 +2459,12 @@ function resolveSidecarOverlay(relativePath, nodePathForIssue, roots, liveBodyHa
2776
2459
  };
2777
2460
  }
2778
2461
  function resolveAbsoluteMdPath(relativePath, roots) {
2779
- if (isAbsolute3(relativePath)) {
2780
- return existsSync10(relativePath) ? relativePath : null;
2462
+ if (isAbsolute2(relativePath)) {
2463
+ return existsSync9(relativePath) ? relativePath : null;
2781
2464
  }
2782
2465
  for (const root of roots) {
2783
2466
  const candidate = resolvePath(root, relativePath);
2784
- if (existsSync10(candidate)) return candidate;
2467
+ if (existsSync9(candidate)) return candidate;
2785
2468
  }
2786
2469
  return null;
2787
2470
  }
@@ -3401,7 +3084,7 @@ function validateRoots(roots) {
3401
3084
  throw new Error(ORCHESTRATOR_TEXTS.runScanRootEmptyArray);
3402
3085
  }
3403
3086
  for (const root of roots) {
3404
- if (!existsSync11(root) || !statSync4(root).isDirectory()) {
3087
+ if (!existsSync10(root) || !statSync4(root).isDirectory()) {
3405
3088
  throw new Error(tx(ORCHESTRATOR_TEXTS.runScanRootMissing, { root }));
3406
3089
  }
3407
3090
  }
@@ -3409,19 +3092,19 @@ function validateRoots(roots) {
3409
3092
  function resolveActiveProviderOption(optionValue, roots, providers) {
3410
3093
  if (optionValue !== void 0) return optionValue;
3411
3094
  for (const root of roots) {
3412
- const absRoot = isAbsolute4(root) ? root : resolve11(root);
3413
- if (!existsSync11(absRoot)) continue;
3414
- const detected = resolveActiveProvider(absRoot, providers).resolved;
3095
+ const absRoot = isAbsolute3(root) ? root : resolve9(root);
3096
+ if (!existsSync10(absRoot)) continue;
3097
+ const detected = detectProvidersFromFilesystem(absRoot, providers)[0] ?? null;
3415
3098
  if (detected !== null) return detected;
3416
3099
  }
3417
3100
  return null;
3418
3101
  }
3419
3102
 
3420
3103
  // kernel/scan/watcher.ts
3421
- import { resolve as resolve12, relative as relative4, sep as sep4 } from "path";
3104
+ import { resolve as resolve10, relative as relative4, sep as sep3 } from "path";
3422
3105
  import chokidar from "chokidar";
3423
3106
  function createChokidarWatcher(opts) {
3424
- const absRoots = opts.roots.map((r) => resolve12(opts.cwd, r));
3107
+ const absRoots = opts.roots.map((r) => resolve10(opts.cwd, r));
3425
3108
  const ignoreFilterOpt = opts.ignoreFilter;
3426
3109
  const getFilter = ignoreFilterOpt === void 0 ? void 0 : typeof ignoreFilterOpt === "function" ? ignoreFilterOpt : () => ignoreFilterOpt;
3427
3110
  const ignored = getFilter ? (path) => {
@@ -3516,8 +3199,8 @@ function relativePathFromRoots2(absolute, absRoots) {
3516
3199
  for (const root of absRoots) {
3517
3200
  const rel = relative4(root, absolute);
3518
3201
  if (rel === "" || rel === ".") return "";
3519
- if (!rel.startsWith("..") && !rel.startsWith(`..${sep4}`)) {
3520
- return rel.split(sep4).join("/");
3202
+ if (!rel.startsWith("..") && !rel.startsWith(`..${sep3}`)) {
3203
+ return rel.split(sep3).join("/");
3521
3204
  }
3522
3205
  }
3523
3206
  return null;
@@ -3822,4 +3505,4 @@ export {
3822
3505
  runScanWithRenames
3823
3506
  };
3824
3507
  //# sourceMappingURL=index.js.map
3825
- //# debugId=66c91062-e32c-5685-861d-a744103465f8
3508
+ //# debugId=e78e8b63-f577-5c6a-9522-9187b69e1ed7