@skill-map/cli 0.33.0 → 0.34.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/cli.js +534 -219
- package/dist/cli.js.map +1 -1
- package/dist/index.js +510 -97
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.d.ts +19 -0
- package/dist/kernel/index.js +510 -97
- package/dist/kernel/index.js.map +1 -1
- package/dist/ui/{chunk-OKFHCQNJ.js → chunk-MHWM2642.js} +4 -4
- package/dist/ui/index.html +1 -1
- package/dist/ui/{main-H7FURBYT.js → main-4X6AAGKZ.js} +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -93,14 +93,15 @@ var Registry = class {
|
|
|
93
93
|
};
|
|
94
94
|
|
|
95
95
|
// kernel/orchestrator/index.ts
|
|
96
|
-
import { existsSync as
|
|
96
|
+
import { existsSync as existsSync11, statSync as statSync4 } from "fs";
|
|
97
|
+
import { isAbsolute as isAbsolute4, resolve as resolve10 } from "path";
|
|
97
98
|
import { Tiktoken as Tiktoken2 } from "js-tiktoken/lite";
|
|
98
99
|
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
|
|
99
100
|
|
|
100
101
|
// package.json
|
|
101
102
|
var package_default = {
|
|
102
103
|
name: "@skill-map/cli",
|
|
103
|
-
version: "0.
|
|
104
|
+
version: "0.34.0",
|
|
104
105
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
105
106
|
license: "MIT",
|
|
106
107
|
type: "module",
|
|
@@ -693,6 +694,391 @@ var ORCHESTRATOR_TEXTS = {
|
|
|
693
694
|
runScanRootMissing: "runScan: root path '{{root}}' does not exist or is not a directory"
|
|
694
695
|
};
|
|
695
696
|
|
|
697
|
+
// core/config/active-provider.ts
|
|
698
|
+
import { existsSync as existsSync5 } from "fs";
|
|
699
|
+
import { join as join6 } from "path";
|
|
700
|
+
|
|
701
|
+
// core/config/helper.ts
|
|
702
|
+
import { homedir as osHomedir } from "os";
|
|
703
|
+
import { isAbsolute as isAbsolute2, join as join5, resolve as resolve6 } from "path";
|
|
704
|
+
|
|
705
|
+
// kernel/config/loader.ts
|
|
706
|
+
import { existsSync as existsSync3, readFileSync as readFileSync5 } from "fs";
|
|
707
|
+
|
|
708
|
+
// kernel/i18n/config-loader.texts.ts
|
|
709
|
+
var CONFIG_LOADER_TEXTS = {
|
|
710
|
+
readFailure: "[config:{{layer}}] failed to read {{path}}: {{message}}",
|
|
711
|
+
invalidJson: "[config:{{layer}}] invalid JSON in {{path}}: {{message}}",
|
|
712
|
+
expectedObject: "[config:{{layer}}] expected a JSON object, got {{type}}; ignored",
|
|
713
|
+
unknownKey: "[config:{{layer}}] unknown key {{key}} ignored",
|
|
714
|
+
invalidValue: "[config:{{layer}}] invalid value at {{path}}: {{message}}",
|
|
715
|
+
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)."
|
|
716
|
+
};
|
|
717
|
+
|
|
718
|
+
// kernel/util/skill-map-paths.ts
|
|
719
|
+
import { join as join4 } from "path";
|
|
720
|
+
|
|
721
|
+
// core/paths/db-path.ts
|
|
722
|
+
import { join as join3, resolve as resolve5 } from "path";
|
|
723
|
+
var SKILL_MAP_DIR = ".skill-map";
|
|
724
|
+
var DB_FILENAME = "skill-map.db";
|
|
725
|
+
var LOCAL_SETTINGS_FILENAME = "settings.local.json";
|
|
726
|
+
var DEFAULT_DB_REL = `${SKILL_MAP_DIR}/${DB_FILENAME}`;
|
|
727
|
+
var GITIGNORE_ENTRIES = [
|
|
728
|
+
`${SKILL_MAP_DIR}/${LOCAL_SETTINGS_FILENAME}`,
|
|
729
|
+
`${SKILL_MAP_DIR}/${DB_FILENAME}`
|
|
730
|
+
];
|
|
731
|
+
|
|
732
|
+
// kernel/util/skill-map-paths.ts
|
|
733
|
+
var KERNEL_SKILL_MAP_DIR = SKILL_MAP_DIR;
|
|
734
|
+
var SETTINGS_FILENAME = "settings.json";
|
|
735
|
+
var LOCAL_SETTINGS_FILENAME2 = "settings.local.json";
|
|
736
|
+
function kernelSettingsPath(scopeRoot) {
|
|
737
|
+
return join4(scopeRoot, KERNEL_SKILL_MAP_DIR, SETTINGS_FILENAME);
|
|
738
|
+
}
|
|
739
|
+
function kernelLocalSettingsPath(scopeRoot) {
|
|
740
|
+
return join4(scopeRoot, KERNEL_SKILL_MAP_DIR, LOCAL_SETTINGS_FILENAME2);
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// kernel/util/strip-prototype-pollution.ts
|
|
744
|
+
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
|
|
745
|
+
"__proto__",
|
|
746
|
+
"constructor",
|
|
747
|
+
"prototype"
|
|
748
|
+
]);
|
|
749
|
+
function stripPrototypePollution(value) {
|
|
750
|
+
return strip(value);
|
|
751
|
+
}
|
|
752
|
+
function strip(value) {
|
|
753
|
+
if (value === null || value === void 0) return value;
|
|
754
|
+
if (typeof value !== "object") return value;
|
|
755
|
+
if (Array.isArray(value)) return value.map(strip);
|
|
756
|
+
const out = {};
|
|
757
|
+
for (const [k, v] of Object.entries(value)) {
|
|
758
|
+
if (FORBIDDEN_KEYS.has(k)) continue;
|
|
759
|
+
out[k] = strip(v);
|
|
760
|
+
}
|
|
761
|
+
return out;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
// config/defaults.json
|
|
765
|
+
var defaults_default = {
|
|
766
|
+
schemaVersion: 1,
|
|
767
|
+
autoMigrate: true,
|
|
768
|
+
allowEditSmFiles: false,
|
|
769
|
+
tokenizer: "cl100k_base",
|
|
770
|
+
providers: [],
|
|
771
|
+
roots: [],
|
|
772
|
+
ignore: [],
|
|
773
|
+
scan: {
|
|
774
|
+
tokenize: true,
|
|
775
|
+
strict: false,
|
|
776
|
+
followSymlinks: false,
|
|
777
|
+
maxFileSizeBytes: 1048576,
|
|
778
|
+
watch: {
|
|
779
|
+
debounceMs: 300
|
|
780
|
+
},
|
|
781
|
+
referencePaths: []
|
|
782
|
+
},
|
|
783
|
+
plugins: {},
|
|
784
|
+
history: {
|
|
785
|
+
share: false
|
|
786
|
+
},
|
|
787
|
+
jobs: {
|
|
788
|
+
ttlSeconds: 3600,
|
|
789
|
+
graceMultiplier: 3,
|
|
790
|
+
minimumTtlSeconds: 60,
|
|
791
|
+
perActionTtl: {},
|
|
792
|
+
perActionPriority: {},
|
|
793
|
+
retention: {
|
|
794
|
+
completed: 2592e3,
|
|
795
|
+
failed: null
|
|
796
|
+
}
|
|
797
|
+
},
|
|
798
|
+
i18n: {
|
|
799
|
+
locale: "en"
|
|
800
|
+
}
|
|
801
|
+
};
|
|
802
|
+
|
|
803
|
+
// kernel/config/loader.ts
|
|
804
|
+
var PROJECT_LOCAL_ONLY_KEYS = /* @__PURE__ */ new Set([
|
|
805
|
+
"allowEditSmFiles",
|
|
806
|
+
"scan.referencePaths"
|
|
807
|
+
]);
|
|
808
|
+
var DEFAULTS = defaults_default;
|
|
809
|
+
function loadConfig(opts) {
|
|
810
|
+
const cwd = opts.cwd;
|
|
811
|
+
const strict = opts.strict ?? false;
|
|
812
|
+
const warnings = [];
|
|
813
|
+
const sources = /* @__PURE__ */ new Map();
|
|
814
|
+
const validators = loadSchemaValidators();
|
|
815
|
+
let effective = structuredClone(DEFAULTS);
|
|
816
|
+
recordSources("", effective, sources, "defaults");
|
|
817
|
+
const filePairs = [
|
|
818
|
+
{ path: kernelSettingsPath(cwd), layer: "project" },
|
|
819
|
+
{ path: kernelLocalSettingsPath(cwd), layer: "project-local" }
|
|
820
|
+
];
|
|
821
|
+
for (const { path, layer } of filePairs) {
|
|
822
|
+
if (!existsSync3(path)) continue;
|
|
823
|
+
const partial = readJsonSafe(path, layer, warnings, strict);
|
|
824
|
+
if (partial === null) continue;
|
|
825
|
+
const cleaned = validateAndStrip(validators, partial, layer, warnings, strict);
|
|
826
|
+
if (layer !== "project-local") {
|
|
827
|
+
stripProjectLocalOnlyKeys(cleaned, layer, warnings, strict);
|
|
828
|
+
}
|
|
829
|
+
effective = deepMerge(effective, cleaned);
|
|
830
|
+
recordSources("", cleaned, sources, layer);
|
|
831
|
+
}
|
|
832
|
+
if (opts.overrides && Object.keys(opts.overrides).length > 0) {
|
|
833
|
+
const cleaned = validateAndStrip(validators, opts.overrides, "override", warnings, strict);
|
|
834
|
+
stripProjectLocalOnlyKeys(cleaned, "override", warnings, strict);
|
|
835
|
+
effective = deepMerge(effective, cleaned);
|
|
836
|
+
recordSources("", cleaned, sources, "override");
|
|
837
|
+
}
|
|
838
|
+
return { effective, sources, warnings };
|
|
839
|
+
}
|
|
840
|
+
function readJsonSafe(path, layer, warnings, strict) {
|
|
841
|
+
let text;
|
|
842
|
+
try {
|
|
843
|
+
text = readFileSync5(path, "utf8");
|
|
844
|
+
} catch (err) {
|
|
845
|
+
return reportAndSkip(
|
|
846
|
+
tx(CONFIG_LOADER_TEXTS.readFailure, { layer, path, message: formatErrorMessage(err) }),
|
|
847
|
+
warnings,
|
|
848
|
+
strict
|
|
849
|
+
);
|
|
850
|
+
}
|
|
851
|
+
try {
|
|
852
|
+
return JSON.parse(text);
|
|
853
|
+
} catch (err) {
|
|
854
|
+
return reportAndSkip(
|
|
855
|
+
tx(CONFIG_LOADER_TEXTS.invalidJson, { layer, path, message: formatErrorMessage(err) }),
|
|
856
|
+
warnings,
|
|
857
|
+
strict
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
function reportAndSkip(msg, warnings, strict) {
|
|
862
|
+
if (strict) throw new Error(msg);
|
|
863
|
+
warnings.push(msg);
|
|
864
|
+
return null;
|
|
865
|
+
}
|
|
866
|
+
function validateAndStrip(validators, raw, layer, warnings, strict) {
|
|
867
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
868
|
+
const msg = tx(CONFIG_LOADER_TEXTS.expectedObject, { layer, type: describeJsonType(raw) });
|
|
869
|
+
if (strict) throw new Error(msg);
|
|
870
|
+
warnings.push(msg);
|
|
871
|
+
return {};
|
|
872
|
+
}
|
|
873
|
+
const cloned = structuredClone(raw);
|
|
874
|
+
const validator = validators.getValidator("project-config");
|
|
875
|
+
if (validator(cloned)) return cloned;
|
|
876
|
+
for (const err of validator.errors ?? []) {
|
|
877
|
+
applyValidationError(cloned, err, layer, warnings, strict);
|
|
878
|
+
}
|
|
879
|
+
return cloned;
|
|
880
|
+
}
|
|
881
|
+
function applyValidationError(cloned, err, layer, warnings, strict) {
|
|
882
|
+
const path = err.instancePath ?? "";
|
|
883
|
+
if (err.keyword === "additionalProperties") {
|
|
884
|
+
const extra = err.params.additionalProperty;
|
|
885
|
+
deleteAtPath(cloned, path, extra);
|
|
886
|
+
const msg2 = tx(CONFIG_LOADER_TEXTS.unknownKey, { layer, key: joinSegments(path, extra) });
|
|
887
|
+
if (strict) throw new Error(msg2);
|
|
888
|
+
warnings.push(msg2);
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
const segments = path.split("/").filter(Boolean);
|
|
892
|
+
if (segments.length > 0) {
|
|
893
|
+
const last = segments.pop();
|
|
894
|
+
deleteAtPath(cloned, "/" + segments.join("/"), last);
|
|
895
|
+
}
|
|
896
|
+
const msg = tx(CONFIG_LOADER_TEXTS.invalidValue, {
|
|
897
|
+
layer,
|
|
898
|
+
path: path || "(root)",
|
|
899
|
+
message: err.message ?? err.keyword
|
|
900
|
+
});
|
|
901
|
+
if (strict) throw new Error(msg);
|
|
902
|
+
warnings.push(msg);
|
|
903
|
+
}
|
|
904
|
+
function describeJsonType(v) {
|
|
905
|
+
if (v === null) return "null";
|
|
906
|
+
if (Array.isArray(v)) return "array";
|
|
907
|
+
return typeof v;
|
|
908
|
+
}
|
|
909
|
+
function deleteAtPath(root, parentPath, key) {
|
|
910
|
+
if (containsForbidden(parentPath, key)) return;
|
|
911
|
+
const segments = parentPath.split("/").filter(Boolean);
|
|
912
|
+
let cur = root;
|
|
913
|
+
for (const seg of segments) {
|
|
914
|
+
if (!isPlainObject(cur)) return;
|
|
915
|
+
cur = cur[seg];
|
|
916
|
+
}
|
|
917
|
+
if (isPlainObject(cur)) delete cur[key];
|
|
918
|
+
}
|
|
919
|
+
function stripProjectLocalOnlyKeys(cloned, layer, warnings, strict) {
|
|
920
|
+
for (const dotKey of PROJECT_LOCAL_ONLY_KEYS) {
|
|
921
|
+
const segments = dotKey.split(".").filter(Boolean);
|
|
922
|
+
if (segments.length === 0) continue;
|
|
923
|
+
const leaf = segments.pop();
|
|
924
|
+
if (!keyPresentAtPath(cloned, segments, leaf)) continue;
|
|
925
|
+
const parentPath = "/" + segments.join("/");
|
|
926
|
+
deleteAtPath(cloned, parentPath, leaf);
|
|
927
|
+
const msg = tx(CONFIG_LOADER_TEXTS.projectLocalOnlyStripped, {
|
|
928
|
+
layer,
|
|
929
|
+
key: dotKey
|
|
930
|
+
});
|
|
931
|
+
if (strict) throw new Error(msg);
|
|
932
|
+
warnings.push(msg);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
function keyPresentAtPath(root, parentSegments, leaf) {
|
|
936
|
+
let cur = root;
|
|
937
|
+
for (const seg of parentSegments) {
|
|
938
|
+
if (!isPlainObject(cur)) return false;
|
|
939
|
+
cur = cur[seg];
|
|
940
|
+
}
|
|
941
|
+
return isPlainObject(cur) && Object.prototype.hasOwnProperty.call(cur, leaf);
|
|
942
|
+
}
|
|
943
|
+
function isPlainObject(v) {
|
|
944
|
+
return v !== null && typeof v === "object" && !Array.isArray(v);
|
|
945
|
+
}
|
|
946
|
+
function containsForbidden(parentPath, leaf) {
|
|
947
|
+
if (FORBIDDEN_KEYS.has(leaf)) return true;
|
|
948
|
+
for (const seg of parentPath.split("/")) {
|
|
949
|
+
if (FORBIDDEN_KEYS.has(seg)) return true;
|
|
950
|
+
}
|
|
951
|
+
return false;
|
|
952
|
+
}
|
|
953
|
+
function joinSegments(instancePath, leaf) {
|
|
954
|
+
const segments = instancePath.split("/").filter(Boolean);
|
|
955
|
+
return [...segments, leaf].join(".");
|
|
956
|
+
}
|
|
957
|
+
function deepMerge(target, source) {
|
|
958
|
+
const out = { ...target };
|
|
959
|
+
for (const [k, v] of Object.entries(source)) {
|
|
960
|
+
if (FORBIDDEN_KEYS.has(k)) continue;
|
|
961
|
+
out[k] = mergeValue(out[k], v);
|
|
962
|
+
}
|
|
963
|
+
return out;
|
|
964
|
+
}
|
|
965
|
+
function mergeValue(target, source) {
|
|
966
|
+
if (source === null || typeof source !== "object" || Array.isArray(source)) {
|
|
967
|
+
return source;
|
|
968
|
+
}
|
|
969
|
+
const targetSlot = target !== null && typeof target === "object" && !Array.isArray(target) ? target : {};
|
|
970
|
+
return deepMerge(targetSlot, source);
|
|
971
|
+
}
|
|
972
|
+
function recordSources(prefix, value, map, layer) {
|
|
973
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
974
|
+
if (prefix) map.set(prefix, layer);
|
|
975
|
+
return;
|
|
976
|
+
}
|
|
977
|
+
const entries = Object.entries(value);
|
|
978
|
+
if (entries.length === 0 && prefix) {
|
|
979
|
+
map.set(prefix, layer);
|
|
980
|
+
return;
|
|
981
|
+
}
|
|
982
|
+
for (const [k, v] of entries) {
|
|
983
|
+
const next = prefix ? `${prefix}.${k}` : k;
|
|
984
|
+
recordSources(next, v, map, layer);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
// core/config/dot-path.ts
|
|
989
|
+
var FORBIDDEN_SEGMENTS = /* @__PURE__ */ new Set([
|
|
990
|
+
"__proto__",
|
|
991
|
+
"constructor",
|
|
992
|
+
"prototype"
|
|
993
|
+
]);
|
|
994
|
+
var ForbiddenSegmentError = class extends Error {
|
|
995
|
+
constructor(segment, key) {
|
|
996
|
+
super(`forbidden config key segment "${segment}" in "${key}"`);
|
|
997
|
+
this.segment = segment;
|
|
998
|
+
this.key = key;
|
|
999
|
+
}
|
|
1000
|
+
segment;
|
|
1001
|
+
key;
|
|
1002
|
+
};
|
|
1003
|
+
function assertSafeSegments(segments, key) {
|
|
1004
|
+
for (const seg of segments) {
|
|
1005
|
+
if (FORBIDDEN_SEGMENTS.has(seg)) throw new ForbiddenSegmentError(seg, key);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
function getAtPath(obj, dotPath) {
|
|
1009
|
+
const segments = dotPath.split(".").filter(Boolean);
|
|
1010
|
+
assertSafeSegments(segments, dotPath);
|
|
1011
|
+
let cur = obj;
|
|
1012
|
+
for (const seg of segments) {
|
|
1013
|
+
if (cur && typeof cur === "object" && !Array.isArray(cur)) {
|
|
1014
|
+
cur = cur[seg];
|
|
1015
|
+
continue;
|
|
1016
|
+
}
|
|
1017
|
+
return void 0;
|
|
1018
|
+
}
|
|
1019
|
+
return cur;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
// core/config/atomic-write.ts
|
|
1023
|
+
import {
|
|
1024
|
+
closeSync,
|
|
1025
|
+
constants as fsConstants,
|
|
1026
|
+
existsSync as existsSync4,
|
|
1027
|
+
mkdirSync,
|
|
1028
|
+
openSync,
|
|
1029
|
+
readFileSync as readFileSync6,
|
|
1030
|
+
renameSync,
|
|
1031
|
+
unlinkSync,
|
|
1032
|
+
writeSync
|
|
1033
|
+
} from "fs";
|
|
1034
|
+
import { randomBytes } from "crypto";
|
|
1035
|
+
import { dirname as dirname3 } from "path";
|
|
1036
|
+
|
|
1037
|
+
// core/config/helper.ts
|
|
1038
|
+
function readConfigValue(key, opts) {
|
|
1039
|
+
const loaded = loadConfigForScope(opts);
|
|
1040
|
+
const value = getAtPath(loaded.effective, key);
|
|
1041
|
+
if (value === void 0) return opts.default;
|
|
1042
|
+
return value;
|
|
1043
|
+
}
|
|
1044
|
+
function loadConfigForScope(opts) {
|
|
1045
|
+
return loadConfig({
|
|
1046
|
+
cwd: opts.cwd,
|
|
1047
|
+
...opts.strict ? { strict: true } : {}
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// core/config/active-provider.ts
|
|
1052
|
+
var DETECTION_RULES = [
|
|
1053
|
+
{ providerId: "claude", marker: ".claude" },
|
|
1054
|
+
{ providerId: "gemini", marker: ".gemini" },
|
|
1055
|
+
{ providerId: "openai", marker: ".codex" },
|
|
1056
|
+
{ providerId: "openai", marker: "AGENTS.md" },
|
|
1057
|
+
{ providerId: "cursor", marker: ".cursor" }
|
|
1058
|
+
];
|
|
1059
|
+
function resolveActiveProvider(cwd) {
|
|
1060
|
+
const detected = detectProvidersFromFilesystem(cwd);
|
|
1061
|
+
const fromConfig = readConfigValue("activeProvider", { cwd });
|
|
1062
|
+
if (typeof fromConfig === "string" && fromConfig.length > 0) {
|
|
1063
|
+
return { resolved: fromConfig, source: "config", detected };
|
|
1064
|
+
}
|
|
1065
|
+
if (detected.length > 0) {
|
|
1066
|
+
return { resolved: detected[0], source: "autodetect", detected };
|
|
1067
|
+
}
|
|
1068
|
+
return { resolved: null, source: "none", detected };
|
|
1069
|
+
}
|
|
1070
|
+
function detectProvidersFromFilesystem(cwd) {
|
|
1071
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1072
|
+
const out = [];
|
|
1073
|
+
for (const rule of DETECTION_RULES) {
|
|
1074
|
+
if (seen.has(rule.providerId)) continue;
|
|
1075
|
+
if (!existsSync5(join6(cwd, rule.marker))) continue;
|
|
1076
|
+
seen.add(rule.providerId);
|
|
1077
|
+
out.push(rule.providerId);
|
|
1078
|
+
}
|
|
1079
|
+
return out;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
696
1082
|
// kernel/types.ts
|
|
697
1083
|
var ConfidenceTier = Object.freeze({
|
|
698
1084
|
HIGH: 0.9,
|
|
@@ -1001,6 +1387,9 @@ function dedupeLinks(links) {
|
|
|
1001
1387
|
existing.sources = [...existing.sources, src];
|
|
1002
1388
|
}
|
|
1003
1389
|
}
|
|
1390
|
+
if (link.confidence > existing.confidence) {
|
|
1391
|
+
existing.confidence = link.confidence;
|
|
1392
|
+
}
|
|
1004
1393
|
continue;
|
|
1005
1394
|
}
|
|
1006
1395
|
out.set(key, link);
|
|
@@ -1195,7 +1584,7 @@ function originatingNodeOf(link, priorNodePaths) {
|
|
|
1195
1584
|
function computeCacheDecision(opts) {
|
|
1196
1585
|
const applicableExtractors = opts.extractors.filter((ex) => {
|
|
1197
1586
|
if (!matchesKindPrecondition(ex, opts.kind)) return false;
|
|
1198
|
-
if (!matchesProviderPrecondition(ex, opts.provider)) return false;
|
|
1587
|
+
if (!matchesProviderPrecondition(ex, opts.provider, opts.activeProvider)) return false;
|
|
1199
1588
|
return true;
|
|
1200
1589
|
});
|
|
1201
1590
|
const applicableQualifiedIds = new Set(
|
|
@@ -1219,10 +1608,12 @@ function matchesKindPrecondition(ex, kind) {
|
|
|
1219
1608
|
return kindOnly === kind;
|
|
1220
1609
|
});
|
|
1221
1610
|
}
|
|
1222
|
-
function matchesProviderPrecondition(ex,
|
|
1611
|
+
function matchesProviderPrecondition(ex, nodeProvider, activeProvider) {
|
|
1223
1612
|
const providers = ex.precondition?.provider;
|
|
1224
1613
|
if (!providers || providers.length === 0) return true;
|
|
1225
|
-
|
|
1614
|
+
if (!providers.includes(nodeProvider)) return false;
|
|
1615
|
+
if (activeProvider === null) return false;
|
|
1616
|
+
return providers.includes(activeProvider);
|
|
1226
1617
|
}
|
|
1227
1618
|
function splitLegacy(applicableExtractors, applicableQualifiedIds, nodeHashCacheEligible) {
|
|
1228
1619
|
const cachedQualifiedIds = /* @__PURE__ */ new Set();
|
|
@@ -1323,6 +1714,75 @@ function classifyLinkSource(source, shortIdToQualified, cachedQualifiedIds, appl
|
|
|
1323
1714
|
return "obsolete";
|
|
1324
1715
|
}
|
|
1325
1716
|
|
|
1717
|
+
// kernel/trigger-normalize.ts
|
|
1718
|
+
function normalizeTrigger(source) {
|
|
1719
|
+
let out = source.normalize("NFD");
|
|
1720
|
+
out = out.replace(new RegExp("\\p{Mn}+", "gu"), "");
|
|
1721
|
+
out = out.toLowerCase();
|
|
1722
|
+
out = out.replace(/[-_\s]+/g, " ");
|
|
1723
|
+
out = out.replace(/ +/g, " ");
|
|
1724
|
+
return out.trim();
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1727
|
+
// kernel/orchestrator/lift-mention-confidence.ts
|
|
1728
|
+
function liftMentionConfidence(links, nodes) {
|
|
1729
|
+
if (!links.some((l) => l.kind === "mentions")) return;
|
|
1730
|
+
const byPath2 = /* @__PURE__ */ new Set();
|
|
1731
|
+
for (const node of nodes) byPath2.add(node.path);
|
|
1732
|
+
const byNormalizedName = indexByNormalizedName(nodes);
|
|
1733
|
+
for (const link of links) {
|
|
1734
|
+
if (link.kind !== "mentions") continue;
|
|
1735
|
+
if (isResolved(link, byPath2, byNormalizedName)) {
|
|
1736
|
+
link.confidence = 1;
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
function isResolved(link, byPath2, byNormalizedName) {
|
|
1741
|
+
const normalized = link.trigger?.normalizedTrigger;
|
|
1742
|
+
if (normalized) {
|
|
1743
|
+
const withoutSigil = normalized.replace(/^[/@]/, "").trim();
|
|
1744
|
+
if (byNormalizedName.has(withoutSigil)) return true;
|
|
1745
|
+
}
|
|
1746
|
+
if (byPath2.has(link.target)) return true;
|
|
1747
|
+
return false;
|
|
1748
|
+
}
|
|
1749
|
+
function indexByNormalizedName(nodes) {
|
|
1750
|
+
const out = /* @__PURE__ */ new Map();
|
|
1751
|
+
for (const node of nodes) {
|
|
1752
|
+
const raw = node.frontmatter?.["name"];
|
|
1753
|
+
const name = typeof raw === "string" ? raw : "";
|
|
1754
|
+
if (!name) continue;
|
|
1755
|
+
out.set(normalizeTrigger(name), true);
|
|
1756
|
+
}
|
|
1757
|
+
return out;
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
// kernel/orchestrator/post-walk-transforms.ts
|
|
1761
|
+
var POST_WALK_TRANSFORMS = [
|
|
1762
|
+
{
|
|
1763
|
+
id: "dedupe-links",
|
|
1764
|
+
description: "Collapse identical (source, target, kind, normalizedTrigger) edges across extractors; union sources[] and pick max confidence on merge.",
|
|
1765
|
+
run(links) {
|
|
1766
|
+
return dedupeLinks(links);
|
|
1767
|
+
}
|
|
1768
|
+
},
|
|
1769
|
+
{
|
|
1770
|
+
id: "lift-mention-confidence",
|
|
1771
|
+
description: "Bump resolved `mentions` links to confidence 1.0 once the full node graph is known (post-merge polish).",
|
|
1772
|
+
run(links, nodes) {
|
|
1773
|
+
liftMentionConfidence(links, nodes);
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
];
|
|
1777
|
+
function applyPostWalkTransforms(links, nodes, transforms = POST_WALK_TRANSFORMS) {
|
|
1778
|
+
let current = links;
|
|
1779
|
+
for (const transform of transforms) {
|
|
1780
|
+
const next = transform.run(current, nodes);
|
|
1781
|
+
if (next) current = next;
|
|
1782
|
+
}
|
|
1783
|
+
return current;
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1326
1786
|
// kernel/orchestrator/renames.ts
|
|
1327
1787
|
function findHighConfidenceRenames(opts) {
|
|
1328
1788
|
const ops = [];
|
|
@@ -1457,11 +1917,11 @@ function detectRenamesAndOrphans(prior, current, issues, silenced) {
|
|
|
1457
1917
|
|
|
1458
1918
|
// kernel/scan/walk-content.ts
|
|
1459
1919
|
import { readFile, readdir, lstat } from "fs/promises";
|
|
1460
|
-
import { join as
|
|
1920
|
+
import { join as join7, relative as relative2, sep } from "path";
|
|
1461
1921
|
|
|
1462
1922
|
// kernel/scan/ignore.ts
|
|
1463
|
-
import { existsSync as
|
|
1464
|
-
import { dirname as
|
|
1923
|
+
import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
|
|
1924
|
+
import { dirname as dirname4, resolve as resolve7 } from "path";
|
|
1465
1925
|
import { fileURLToPath } from "url";
|
|
1466
1926
|
import ignoreFactory from "ignore";
|
|
1467
1927
|
function buildIgnoreFilter(opts = {}) {
|
|
@@ -1493,18 +1953,18 @@ function loadDefaultsText() {
|
|
|
1493
1953
|
return cachedDefaults;
|
|
1494
1954
|
}
|
|
1495
1955
|
function readDefaultsFromDisk() {
|
|
1496
|
-
const here =
|
|
1956
|
+
const here = dirname4(fileURLToPath(import.meta.url));
|
|
1497
1957
|
const candidates = [
|
|
1498
|
-
|
|
1958
|
+
resolve7(here, "../../config/defaults/skillmapignore"),
|
|
1499
1959
|
// src/kernel/scan/ → src/config/defaults/
|
|
1500
|
-
|
|
1960
|
+
resolve7(here, "../config/defaults/skillmapignore"),
|
|
1501
1961
|
// dist/cli.js → dist/config/defaults/ (siblings)
|
|
1502
|
-
|
|
1962
|
+
resolve7(here, "config/defaults/skillmapignore")
|
|
1503
1963
|
];
|
|
1504
1964
|
for (const candidate of candidates) {
|
|
1505
|
-
if (
|
|
1965
|
+
if (existsSync6(candidate)) {
|
|
1506
1966
|
try {
|
|
1507
|
-
return
|
|
1967
|
+
return readFileSync7(candidate, "utf8");
|
|
1508
1968
|
} catch {
|
|
1509
1969
|
}
|
|
1510
1970
|
}
|
|
@@ -1514,29 +1974,6 @@ function readDefaultsFromDisk() {
|
|
|
1514
1974
|
|
|
1515
1975
|
// plugins/core/parsers/frontmatter-yaml/index.ts
|
|
1516
1976
|
import yaml from "js-yaml";
|
|
1517
|
-
|
|
1518
|
-
// kernel/util/strip-prototype-pollution.ts
|
|
1519
|
-
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set([
|
|
1520
|
-
"__proto__",
|
|
1521
|
-
"constructor",
|
|
1522
|
-
"prototype"
|
|
1523
|
-
]);
|
|
1524
|
-
function stripPrototypePollution(value) {
|
|
1525
|
-
return strip(value);
|
|
1526
|
-
}
|
|
1527
|
-
function strip(value) {
|
|
1528
|
-
if (value === null || value === void 0) return value;
|
|
1529
|
-
if (typeof value !== "object") return value;
|
|
1530
|
-
if (Array.isArray(value)) return value.map(strip);
|
|
1531
|
-
const out = {};
|
|
1532
|
-
for (const [k, v] of Object.entries(value)) {
|
|
1533
|
-
if (FORBIDDEN_KEYS.has(k)) continue;
|
|
1534
|
-
out[k] = strip(v);
|
|
1535
|
-
}
|
|
1536
|
-
return out;
|
|
1537
|
-
}
|
|
1538
|
-
|
|
1539
|
-
// plugins/core/parsers/frontmatter-yaml/index.ts
|
|
1540
1977
|
var FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
1541
1978
|
var frontmatterYamlParser = {
|
|
1542
1979
|
id: "frontmatter-yaml",
|
|
@@ -1668,7 +2105,7 @@ async function* walkRoot(root, current, filter, extensions) {
|
|
|
1668
2105
|
}
|
|
1669
2106
|
for (const entry of entries) {
|
|
1670
2107
|
const name = entry.name;
|
|
1671
|
-
const full =
|
|
2108
|
+
const full = join7(current, name);
|
|
1672
2109
|
const rel = relative2(root, full).split(sep).join("/");
|
|
1673
2110
|
if (filter.ignores(rel)) continue;
|
|
1674
2111
|
if (entry.isSymbolicLink()) continue;
|
|
@@ -1712,19 +2149,19 @@ function resolveProviderWalk(provider) {
|
|
|
1712
2149
|
}
|
|
1713
2150
|
|
|
1714
2151
|
// kernel/sidecar/parse.ts
|
|
1715
|
-
import { existsSync as
|
|
1716
|
-
import { dirname as
|
|
2152
|
+
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
2153
|
+
import { dirname as dirname5, resolve as resolve8 } from "path";
|
|
1717
2154
|
import { createRequire as createRequire3 } from "module";
|
|
1718
2155
|
import { Ajv2020 as Ajv20204 } from "ajv/dist/2020.js";
|
|
1719
2156
|
import yaml2 from "js-yaml";
|
|
1720
2157
|
function readSidecarFor(mdAbsolutePath) {
|
|
1721
2158
|
const sidecarPath = sidecarPathFor(mdAbsolutePath);
|
|
1722
|
-
if (!
|
|
2159
|
+
if (!existsSync7(sidecarPath)) {
|
|
1723
2160
|
return { parsed: null, present: false, issues: [] };
|
|
1724
2161
|
}
|
|
1725
2162
|
let raw;
|
|
1726
2163
|
try {
|
|
1727
|
-
raw =
|
|
2164
|
+
raw = readFileSync8(sidecarPath, "utf8");
|
|
1728
2165
|
} catch (err) {
|
|
1729
2166
|
return {
|
|
1730
2167
|
parsed: null,
|
|
@@ -1743,7 +2180,7 @@ function readSidecarFor(mdAbsolutePath) {
|
|
|
1743
2180
|
};
|
|
1744
2181
|
}
|
|
1745
2182
|
parsedYaml = stripPrototypePollution(parsedYaml);
|
|
1746
|
-
if (!
|
|
2183
|
+
if (!isPlainObject2(parsedYaml)) {
|
|
1747
2184
|
return {
|
|
1748
2185
|
parsed: null,
|
|
1749
2186
|
present: true,
|
|
@@ -1762,7 +2199,7 @@ function readSidecarFor(mdAbsolutePath) {
|
|
|
1762
2199
|
const root = parsedYaml;
|
|
1763
2200
|
const identityBlock = root["identity"];
|
|
1764
2201
|
const annotationsRaw = root["annotations"];
|
|
1765
|
-
const annotations =
|
|
2202
|
+
const annotations = isPlainObject2(annotationsRaw) ? Object.keys(annotationsRaw).length === 0 ? null : annotationsRaw : null;
|
|
1766
2203
|
return {
|
|
1767
2204
|
parsed: {
|
|
1768
2205
|
filePath: sidecarPath,
|
|
@@ -1782,7 +2219,7 @@ function sidecarPathFor(mdAbsolutePath) {
|
|
|
1782
2219
|
}
|
|
1783
2220
|
return `${mdAbsolutePath}.sm`;
|
|
1784
2221
|
}
|
|
1785
|
-
function
|
|
2222
|
+
function isPlainObject2(value) {
|
|
1786
2223
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1787
2224
|
}
|
|
1788
2225
|
var cachedSidecarValidator = null;
|
|
@@ -1792,10 +2229,10 @@ function getSidecarValidator() {
|
|
|
1792
2229
|
applyAjvFormats(ajv);
|
|
1793
2230
|
const specRoot = resolveSpecRoot2();
|
|
1794
2231
|
const annotationsSchema = JSON.parse(
|
|
1795
|
-
|
|
2232
|
+
readFileSync8(resolve8(specRoot, "schemas/annotations.schema.json"), "utf8")
|
|
1796
2233
|
);
|
|
1797
2234
|
const sidecarSchema = JSON.parse(
|
|
1798
|
-
|
|
2235
|
+
readFileSync8(resolve8(specRoot, "schemas/sidecar.schema.json"), "utf8")
|
|
1799
2236
|
);
|
|
1800
2237
|
ajv.addSchema(annotationsSchema);
|
|
1801
2238
|
cachedSidecarValidator = ajv.compile(sidecarSchema);
|
|
@@ -1805,7 +2242,7 @@ function resolveSpecRoot2() {
|
|
|
1805
2242
|
const require2 = createRequire3(import.meta.url);
|
|
1806
2243
|
try {
|
|
1807
2244
|
const indexPath = require2.resolve("@skill-map/spec/index.json");
|
|
1808
|
-
return
|
|
2245
|
+
return dirname5(indexPath);
|
|
1809
2246
|
} catch {
|
|
1810
2247
|
throw new Error(
|
|
1811
2248
|
"@skill-map/spec not resolvable: sidecar reader cannot load schemas."
|
|
@@ -1824,8 +2261,8 @@ function computeDriftStatus(args) {
|
|
|
1824
2261
|
}
|
|
1825
2262
|
|
|
1826
2263
|
// kernel/sidecar/discover-orphans.ts
|
|
1827
|
-
import { existsSync as
|
|
1828
|
-
import { join as
|
|
2264
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, statSync as statSync3 } from "fs";
|
|
2265
|
+
import { join as join8, relative as relative3, sep as sep2 } from "path";
|
|
1829
2266
|
function discoverOrphanSidecars(roots, shouldSkip) {
|
|
1830
2267
|
const out = [];
|
|
1831
2268
|
for (const root of roots) {
|
|
@@ -1841,7 +2278,7 @@ function walk(root, current, shouldSkip, out) {
|
|
|
1841
2278
|
return;
|
|
1842
2279
|
}
|
|
1843
2280
|
for (const entry of entries) {
|
|
1844
|
-
const full =
|
|
2281
|
+
const full = join8(current, entry.name);
|
|
1845
2282
|
const rel = relative3(root, full).split(sep2).join("/");
|
|
1846
2283
|
if (shouldSkip(rel)) continue;
|
|
1847
2284
|
if (entry.isSymbolicLink()) continue;
|
|
@@ -1852,7 +2289,7 @@ function walk(root, current, shouldSkip, out) {
|
|
|
1852
2289
|
if (!entry.isFile()) continue;
|
|
1853
2290
|
if (!entry.name.endsWith(".sm")) continue;
|
|
1854
2291
|
const expectedMd = `${full.slice(0, -".sm".length)}.md`;
|
|
1855
|
-
if (
|
|
2292
|
+
if (existsSync8(expectedMd) && safeIsFile(expectedMd)) continue;
|
|
1856
2293
|
out.push({ sidecarPath: full, relativePath: rel, expectedMdPath: expectedMd });
|
|
1857
2294
|
}
|
|
1858
2295
|
}
|
|
@@ -1865,51 +2302,15 @@ function safeIsFile(path) {
|
|
|
1865
2302
|
}
|
|
1866
2303
|
|
|
1867
2304
|
// kernel/sidecar/store.ts
|
|
1868
|
-
import { existsSync as
|
|
2305
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
|
|
1869
2306
|
import { dirname as dirname6, resolve as resolve9 } from "path";
|
|
1870
2307
|
import { createRequire as createRequire4 } from "module";
|
|
1871
2308
|
import { Ajv2020 as Ajv20205 } from "ajv/dist/2020.js";
|
|
1872
2309
|
import yaml3 from "js-yaml";
|
|
1873
2310
|
|
|
1874
|
-
// core/config/atomic-write.ts
|
|
1875
|
-
import {
|
|
1876
|
-
closeSync,
|
|
1877
|
-
constants as fsConstants,
|
|
1878
|
-
existsSync as existsSync6,
|
|
1879
|
-
mkdirSync,
|
|
1880
|
-
openSync,
|
|
1881
|
-
readFileSync as readFileSync7,
|
|
1882
|
-
renameSync,
|
|
1883
|
-
unlinkSync,
|
|
1884
|
-
writeSync
|
|
1885
|
-
} from "fs";
|
|
1886
|
-
import { randomBytes } from "crypto";
|
|
1887
|
-
import { dirname as dirname5 } from "path";
|
|
1888
|
-
|
|
1889
|
-
// core/config/helper.ts
|
|
1890
|
-
import { homedir as osHomedir } from "os";
|
|
1891
|
-
import { isAbsolute as isAbsolute2, join as join7, resolve as resolve8 } from "path";
|
|
1892
|
-
|
|
1893
|
-
// kernel/config/loader.ts
|
|
1894
|
-
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
1895
|
-
|
|
1896
|
-
// kernel/util/skill-map-paths.ts
|
|
1897
|
-
import { join as join6 } from "path";
|
|
1898
|
-
|
|
1899
|
-
// core/paths/db-path.ts
|
|
1900
|
-
import { join as join5, resolve as resolve7 } from "path";
|
|
1901
|
-
var SKILL_MAP_DIR = ".skill-map";
|
|
1902
|
-
var DB_FILENAME = "skill-map.db";
|
|
1903
|
-
var LOCAL_SETTINGS_FILENAME = "settings.local.json";
|
|
1904
|
-
var DEFAULT_DB_REL = `${SKILL_MAP_DIR}/${DB_FILENAME}`;
|
|
1905
|
-
var GITIGNORE_ENTRIES = [
|
|
1906
|
-
`${SKILL_MAP_DIR}/${LOCAL_SETTINGS_FILENAME}`,
|
|
1907
|
-
`${SKILL_MAP_DIR}/${DB_FILENAME}`
|
|
1908
|
-
];
|
|
1909
|
-
|
|
1910
2311
|
// kernel/orchestrator/node-build.ts
|
|
1911
2312
|
import { createHash } from "crypto";
|
|
1912
|
-
import { existsSync as
|
|
2313
|
+
import { existsSync as existsSync10 } from "fs";
|
|
1913
2314
|
import { isAbsolute as isAbsolute3, resolve as resolvePath } from "path";
|
|
1914
2315
|
import "js-tiktoken/lite";
|
|
1915
2316
|
import yaml4 from "js-yaml";
|
|
@@ -2073,11 +2474,11 @@ function resolveSidecarOverlay(relativePath, nodePathForIssue, roots, liveBodyHa
|
|
|
2073
2474
|
}
|
|
2074
2475
|
function resolveAbsoluteMdPath(relativePath, roots) {
|
|
2075
2476
|
if (isAbsolute3(relativePath)) {
|
|
2076
|
-
return
|
|
2477
|
+
return existsSync10(relativePath) ? relativePath : null;
|
|
2077
2478
|
}
|
|
2078
2479
|
for (const root of roots) {
|
|
2079
2480
|
const candidate = resolvePath(root, relativePath);
|
|
2080
|
-
if (
|
|
2481
|
+
if (existsSync10(candidate)) return candidate;
|
|
2081
2482
|
}
|
|
2082
2483
|
return null;
|
|
2083
2484
|
}
|
|
@@ -2230,6 +2631,7 @@ async function processRawNode(raw, provider, wctx, accum, claimedPaths, nextInde
|
|
|
2230
2631
|
extractors: wctx.opts.extractors,
|
|
2231
2632
|
kind,
|
|
2232
2633
|
provider: provider.id,
|
|
2634
|
+
activeProvider: wctx.opts.activeProvider,
|
|
2233
2635
|
nodePath: raw.path,
|
|
2234
2636
|
bodyHash,
|
|
2235
2637
|
sidecarAnnotationsHash,
|
|
@@ -2443,9 +2845,10 @@ async function runScanInternal(_kernel, options) {
|
|
|
2443
2845
|
priorIndex: setup.priorIndex,
|
|
2444
2846
|
priorExtractorRuns: setup.priorExtractorRuns,
|
|
2445
2847
|
providerFrontmatter: setup.providerFrontmatter,
|
|
2446
|
-
pluginStores: options.pluginStores
|
|
2848
|
+
pluginStores: options.pluginStores,
|
|
2849
|
+
activeProvider: resolveActiveProviderOption(options.activeProvider, options.roots)
|
|
2447
2850
|
});
|
|
2448
|
-
walked.internalLinks =
|
|
2851
|
+
walked.internalLinks = applyPostWalkTransforms(walked.internalLinks, walked.nodes);
|
|
2449
2852
|
recomputeLinkCounts(walked.nodes, walked.internalLinks);
|
|
2450
2853
|
recomputeExternalRefsCount(walked.nodes, walked.externalLinks, walked.cachedPaths);
|
|
2451
2854
|
await dispatchExtractorCompleted(exts.extractors, emitter, hookDispatcher);
|
|
@@ -2561,17 +2964,27 @@ function validateRoots(roots) {
|
|
|
2561
2964
|
throw new Error(ORCHESTRATOR_TEXTS.runScanRootEmptyArray);
|
|
2562
2965
|
}
|
|
2563
2966
|
for (const root of roots) {
|
|
2564
|
-
if (!
|
|
2967
|
+
if (!existsSync11(root) || !statSync4(root).isDirectory()) {
|
|
2565
2968
|
throw new Error(tx(ORCHESTRATOR_TEXTS.runScanRootMissing, { root }));
|
|
2566
2969
|
}
|
|
2567
2970
|
}
|
|
2568
2971
|
}
|
|
2972
|
+
function resolveActiveProviderOption(optionValue, roots) {
|
|
2973
|
+
if (optionValue !== void 0) return optionValue;
|
|
2974
|
+
for (const root of roots) {
|
|
2975
|
+
const absRoot = isAbsolute4(root) ? root : resolve10(root);
|
|
2976
|
+
if (!existsSync11(absRoot)) continue;
|
|
2977
|
+
const detected = resolveActiveProvider(absRoot).resolved;
|
|
2978
|
+
if (detected !== null) return detected;
|
|
2979
|
+
}
|
|
2980
|
+
return null;
|
|
2981
|
+
}
|
|
2569
2982
|
|
|
2570
2983
|
// kernel/scan/watcher.ts
|
|
2571
|
-
import { resolve as
|
|
2984
|
+
import { resolve as resolve11, relative as relative4, sep as sep3 } from "path";
|
|
2572
2985
|
import chokidar from "chokidar";
|
|
2573
2986
|
function createChokidarWatcher(opts) {
|
|
2574
|
-
const absRoots = opts.roots.map((r) =>
|
|
2987
|
+
const absRoots = opts.roots.map((r) => resolve11(opts.cwd, r));
|
|
2575
2988
|
const ignoreFilterOpt = opts.ignoreFilter;
|
|
2576
2989
|
const getFilter = ignoreFilterOpt === void 0 ? void 0 : typeof ignoreFilterOpt === "function" ? ignoreFilterOpt : () => ignoreFilterOpt;
|
|
2577
2990
|
const ignored = getFilter ? (path) => {
|