@skill-map/cli 0.17.0 → 0.18.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/tutorial/sm-tutorial.md +8 -0
- package/dist/cli.js +8246 -5744
- package/dist/cli.js.map +1 -1
- package/dist/conformance/index.js +36 -14
- package/dist/conformance/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +529 -61
- package/dist/index.js.map +1 -1
- package/dist/kernel/index.d.ts +418 -85
- package/dist/kernel/index.js +529 -61
- package/dist/kernel/index.js.map +1 -1
- package/dist/migrations/002_sidecar_columns.sql +53 -0
- package/dist/migrations/003_drop_node_author.sql +20 -0
- package/dist/migrations/004_sidecar_root_json.sql +23 -0
- package/dist/migrations/005_node_favorites.sql +20 -0
- package/dist/ui/chunk-3R7E3HPC.js +7 -0
- package/dist/ui/chunk-JKJGGXCS.js +1025 -0
- package/dist/ui/chunk-SX2A3WBX.js +247 -0
- package/dist/ui/{chunk-WMWULWZX.js → chunk-TWZHUCAT.js} +1 -1
- package/dist/ui/chunk-UJOZYR5I.js +1 -0
- package/dist/ui/chunk-WTAL2RK4.js +1 -0
- package/dist/ui/{chunk-LUDNWV6G.js → chunk-Z3UJHHTC.js} +38 -38
- package/dist/ui/index.html +1 -1
- package/dist/ui/main-AAYGMON4.js +1 -0
- package/migrations/002_sidecar_columns.sql +53 -0
- package/migrations/003_drop_node_author.sql +20 -0
- package/migrations/004_sidecar_root_json.sql +23 -0
- package/migrations/005_node_favorites.sql +20 -0
- package/package.json +6 -6
- package/dist/ui/chunk-5ZGVBIPP.js +0 -1031
- package/dist/ui/chunk-BWUDZKB6.js +0 -247
- package/dist/ui/main-7LR4JN4M.js +0 -1
package/dist/kernel/index.js
CHANGED
|
@@ -94,15 +94,16 @@ var Registry = class {
|
|
|
94
94
|
|
|
95
95
|
// kernel/orchestrator.ts
|
|
96
96
|
import { createHash } from "crypto";
|
|
97
|
-
import { existsSync as
|
|
97
|
+
import { existsSync as existsSync6, statSync as statSync2 } from "fs";
|
|
98
|
+
import { isAbsolute as isAbsolute2, resolve as resolvePath } from "path";
|
|
98
99
|
import { Tiktoken } from "js-tiktoken/lite";
|
|
99
100
|
import cl100k_base from "js-tiktoken/ranks/cl100k_base";
|
|
100
|
-
import
|
|
101
|
+
import yaml4 from "js-yaml";
|
|
101
102
|
|
|
102
103
|
// package.json
|
|
103
104
|
var package_default = {
|
|
104
105
|
name: "@skill-map/cli",
|
|
105
|
-
version: "0.
|
|
106
|
+
version: "0.18.0",
|
|
106
107
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
107
108
|
license: "MIT",
|
|
108
109
|
type: "module",
|
|
@@ -160,15 +161,15 @@ var package_default = {
|
|
|
160
161
|
"pretest:ci": "tsup",
|
|
161
162
|
"pretest:coverage": "tsup",
|
|
162
163
|
"pretest:coverage:html": "tsup",
|
|
163
|
-
test: "tsc --noEmit && node --import tsx --test --test-reporter=spec 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts'",
|
|
164
|
-
"test:ci": "tsc --noEmit && node --import tsx --test 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts'",
|
|
165
|
-
"test:coverage": "tsc --noEmit && SKILL_MAP_SKIP_BENCHMARK=1 node --experimental-default-config-file --import tsx --test --experimental-test-coverage 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts'",
|
|
166
|
-
"test:coverage:html": "tsc --noEmit && SKILL_MAP_SKIP_BENCHMARK=1 c8 node --import tsx --test 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts'",
|
|
164
|
+
test: "tsc --noEmit && node --import tsx --test --test-reporter=spec 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts' 'server/**/*.test.ts'",
|
|
165
|
+
"test:ci": "tsc --noEmit && node --import tsx --test 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts' 'server/**/*.test.ts'",
|
|
166
|
+
"test:coverage": "tsc --noEmit && SKILL_MAP_SKIP_BENCHMARK=1 node --experimental-default-config-file --import tsx --test --experimental-test-coverage 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts' 'server/**/*.test.ts'",
|
|
167
|
+
"test:coverage:html": "tsc --noEmit && SKILL_MAP_SKIP_BENCHMARK=1 c8 node --import tsx --test 'test/**/*.test.ts' 'built-in-plugins/**/*.test.ts' 'kernel/**/*.test.ts' 'server/**/*.test.ts'",
|
|
167
168
|
clean: "rm -rf dist coverage"
|
|
168
169
|
},
|
|
169
170
|
dependencies: {
|
|
170
171
|
"@hono/node-server": "2.0.1",
|
|
171
|
-
"@skill-map/spec": "0.
|
|
172
|
+
"@skill-map/spec": "0.18.0",
|
|
172
173
|
ajv: "8.18.0",
|
|
173
174
|
"ajv-formats": "3.0.1",
|
|
174
175
|
chokidar: "5.0.0",
|
|
@@ -205,6 +206,174 @@ var package_default = {
|
|
|
205
206
|
}
|
|
206
207
|
};
|
|
207
208
|
|
|
209
|
+
// kernel/sidecar/parse.ts
|
|
210
|
+
import { existsSync, readFileSync } from "fs";
|
|
211
|
+
import { dirname, resolve } from "path";
|
|
212
|
+
import { createRequire } from "module";
|
|
213
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
214
|
+
import yaml from "js-yaml";
|
|
215
|
+
|
|
216
|
+
// kernel/util/ajv-interop.ts
|
|
217
|
+
import addFormatsModule from "ajv-formats";
|
|
218
|
+
var addFormats = addFormatsModule.default ?? addFormatsModule;
|
|
219
|
+
function applyAjvFormats(ajv) {
|
|
220
|
+
addFormats(ajv);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
// kernel/sidecar/parse.ts
|
|
224
|
+
function readSidecarFor(mdAbsolutePath) {
|
|
225
|
+
const sidecarPath = sidecarPathFor(mdAbsolutePath);
|
|
226
|
+
if (!existsSync(sidecarPath)) {
|
|
227
|
+
return { parsed: null, present: false, issues: [] };
|
|
228
|
+
}
|
|
229
|
+
let raw;
|
|
230
|
+
try {
|
|
231
|
+
raw = readFileSync(sidecarPath, "utf8");
|
|
232
|
+
} catch (err) {
|
|
233
|
+
return {
|
|
234
|
+
parsed: null,
|
|
235
|
+
present: true,
|
|
236
|
+
issues: [{ message: `cannot read ${sidecarPath}: ${err.message}` }]
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
let parsedYaml;
|
|
240
|
+
try {
|
|
241
|
+
parsedYaml = yaml.load(raw);
|
|
242
|
+
} catch (err) {
|
|
243
|
+
return {
|
|
244
|
+
parsed: null,
|
|
245
|
+
present: true,
|
|
246
|
+
issues: [{ message: `malformed YAML in ${sidecarPath}: ${err.message}` }]
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
if (!isPlainObject(parsedYaml)) {
|
|
250
|
+
return {
|
|
251
|
+
parsed: null,
|
|
252
|
+
present: true,
|
|
253
|
+
issues: [{ message: `sidecar root must be a YAML mapping at ${sidecarPath}` }]
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
const sidecarValidator = getSidecarValidator();
|
|
257
|
+
if (!sidecarValidator(parsedYaml)) {
|
|
258
|
+
const errors = (sidecarValidator.errors ?? []).map((e) => `${e.instancePath || "(root)"} ${e.message ?? e.keyword}`).join("; ");
|
|
259
|
+
return {
|
|
260
|
+
parsed: null,
|
|
261
|
+
present: true,
|
|
262
|
+
issues: [{ message: `sidecar schema validation failed at ${sidecarPath}: ${errors}` }]
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
const root = parsedYaml;
|
|
266
|
+
const forBlock = root["for"];
|
|
267
|
+
const annotationsRaw = root["annotations"];
|
|
268
|
+
const annotations = isPlainObject(annotationsRaw) ? Object.keys(annotationsRaw).length === 0 ? null : annotationsRaw : null;
|
|
269
|
+
return {
|
|
270
|
+
parsed: {
|
|
271
|
+
filePath: sidecarPath,
|
|
272
|
+
forBodyHash: String(forBlock["bodyHash"]),
|
|
273
|
+
forFrontmatterHash: String(forBlock["frontmatterHash"]),
|
|
274
|
+
forPath: String(forBlock["path"]),
|
|
275
|
+
annotations,
|
|
276
|
+
raw: root
|
|
277
|
+
},
|
|
278
|
+
present: true,
|
|
279
|
+
issues: []
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
function sidecarPathFor(mdAbsolutePath) {
|
|
283
|
+
if (mdAbsolutePath.endsWith(".md")) {
|
|
284
|
+
return `${mdAbsolutePath.slice(0, -".md".length)}.sm`;
|
|
285
|
+
}
|
|
286
|
+
return `${mdAbsolutePath}.sm`;
|
|
287
|
+
}
|
|
288
|
+
function isPlainObject(value) {
|
|
289
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
290
|
+
}
|
|
291
|
+
var cachedSidecarValidator = null;
|
|
292
|
+
function getSidecarValidator() {
|
|
293
|
+
if (cachedSidecarValidator) return cachedSidecarValidator;
|
|
294
|
+
const ajv = new Ajv2020({ strict: false, allErrors: true, allowUnionTypes: true });
|
|
295
|
+
applyAjvFormats(ajv);
|
|
296
|
+
const specRoot = resolveSpecRoot();
|
|
297
|
+
const annotationsSchema = JSON.parse(
|
|
298
|
+
readFileSync(resolve(specRoot, "schemas/annotations.schema.json"), "utf8")
|
|
299
|
+
);
|
|
300
|
+
const sidecarSchema = JSON.parse(
|
|
301
|
+
readFileSync(resolve(specRoot, "schemas/sidecar.schema.json"), "utf8")
|
|
302
|
+
);
|
|
303
|
+
ajv.addSchema(annotationsSchema);
|
|
304
|
+
cachedSidecarValidator = ajv.compile(sidecarSchema);
|
|
305
|
+
return cachedSidecarValidator;
|
|
306
|
+
}
|
|
307
|
+
function resolveSpecRoot() {
|
|
308
|
+
const require2 = createRequire(import.meta.url);
|
|
309
|
+
try {
|
|
310
|
+
const indexPath = require2.resolve("@skill-map/spec/index.json");
|
|
311
|
+
return dirname(indexPath);
|
|
312
|
+
} catch {
|
|
313
|
+
throw new Error(
|
|
314
|
+
"@skill-map/spec not resolvable \u2014 sidecar reader cannot load schemas."
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// kernel/sidecar/drift.ts
|
|
320
|
+
function computeDriftStatus(args) {
|
|
321
|
+
const bodyDrift = args.storedBodyHash !== args.liveBodyHash;
|
|
322
|
+
const fmDrift = args.storedFrontmatterHash !== args.liveFrontmatterHash;
|
|
323
|
+
if (bodyDrift && fmDrift) return "stale-both";
|
|
324
|
+
if (bodyDrift) return "stale-body";
|
|
325
|
+
if (fmDrift) return "stale-frontmatter";
|
|
326
|
+
return "fresh";
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// kernel/sidecar/discover-orphans.ts
|
|
330
|
+
import { existsSync as existsSync2, readdirSync, statSync } from "fs";
|
|
331
|
+
import { join, relative, sep } from "path";
|
|
332
|
+
function discoverOrphanSidecars(roots, shouldSkip) {
|
|
333
|
+
const out = [];
|
|
334
|
+
for (const root of roots) {
|
|
335
|
+
walk(root, root, shouldSkip ?? (() => false), out);
|
|
336
|
+
}
|
|
337
|
+
return out;
|
|
338
|
+
}
|
|
339
|
+
function walk(root, current, shouldSkip, out) {
|
|
340
|
+
let entries;
|
|
341
|
+
try {
|
|
342
|
+
entries = readdirSync(current, { withFileTypes: true, encoding: "utf8" });
|
|
343
|
+
} catch {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
for (const entry of entries) {
|
|
347
|
+
const full = join(current, entry.name);
|
|
348
|
+
const rel = relative(root, full).split(sep).join("/");
|
|
349
|
+
if (shouldSkip(rel)) continue;
|
|
350
|
+
if (entry.isSymbolicLink()) continue;
|
|
351
|
+
if (entry.isDirectory()) {
|
|
352
|
+
walk(root, full, shouldSkip, out);
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (!entry.isFile()) continue;
|
|
356
|
+
if (!entry.name.endsWith(".sm")) continue;
|
|
357
|
+
const expectedMd = `${full.slice(0, -".sm".length)}.md`;
|
|
358
|
+
if (existsSync2(expectedMd) && safeIsFile(expectedMd)) continue;
|
|
359
|
+
out.push({ sidecarPath: full, relativePath: rel, expectedMdPath: expectedMd });
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function safeIsFile(path) {
|
|
363
|
+
try {
|
|
364
|
+
return statSync(path).isFile();
|
|
365
|
+
} catch {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// kernel/sidecar/store.ts
|
|
371
|
+
import { existsSync as existsSync3, readFileSync as readFileSync2, renameSync, writeFileSync, unlinkSync } from "fs";
|
|
372
|
+
import { dirname as dirname2, resolve as resolve2 } from "path";
|
|
373
|
+
import { createRequire as createRequire2 } from "module";
|
|
374
|
+
import { Ajv2020 as Ajv20202 } from "ajv/dist/2020.js";
|
|
375
|
+
import yaml2 from "js-yaml";
|
|
376
|
+
|
|
208
377
|
// kernel/adapters/in-memory-progress.ts
|
|
209
378
|
var InMemoryProgressEmitter = class {
|
|
210
379
|
#listeners = /* @__PURE__ */ new Set();
|
|
@@ -253,20 +422,13 @@ function getActiveLogger() {
|
|
|
253
422
|
}
|
|
254
423
|
|
|
255
424
|
// kernel/adapters/plugin-loader.ts
|
|
256
|
-
import { createRequire } from "module";
|
|
257
|
-
import { existsSync, readFileSync, readdirSync } from "fs";
|
|
258
|
-
import { isAbsolute, join, relative, resolve } from "path";
|
|
425
|
+
import { createRequire as createRequire3 } from "module";
|
|
426
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
|
|
427
|
+
import { isAbsolute, join as join2, relative as relative2, resolve as resolve3 } from "path";
|
|
259
428
|
import { pathToFileURL } from "url";
|
|
260
|
-
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
429
|
+
import { Ajv2020 as Ajv20203 } from "ajv/dist/2020.js";
|
|
261
430
|
import semver from "semver";
|
|
262
431
|
|
|
263
|
-
// kernel/util/ajv-interop.ts
|
|
264
|
-
import addFormatsModule from "ajv-formats";
|
|
265
|
-
var addFormats = addFormatsModule.default ?? addFormatsModule;
|
|
266
|
-
function applyAjvFormats(ajv) {
|
|
267
|
-
addFormats(ajv);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
432
|
// kernel/i18n/plugin-store.texts.ts
|
|
271
433
|
var PLUGIN_STORE_TEXTS = {
|
|
272
434
|
kvValidationFailed: "plugin '{{pluginId}}' ctx.store.set('{{key}}', value): value violates declared schema ({{schemaPath}}) \u2014 {{errors}}",
|
|
@@ -361,28 +523,28 @@ var KNOWN_KINDS = /* @__PURE__ */ new Set(["provider", "extractor", "rule", "act
|
|
|
361
523
|
var KNOWN_KINDS_LIST = [...KNOWN_KINDS].join(" / ");
|
|
362
524
|
var HOOKABLE_TRIGGERS_LIST = HOOK_TRIGGERS.join(", ");
|
|
363
525
|
function installedSpecVersion() {
|
|
364
|
-
const require2 =
|
|
526
|
+
const require2 = createRequire3(import.meta.url);
|
|
365
527
|
const indexPath = require2.resolve("@skill-map/spec/index.json");
|
|
366
|
-
const pkgPath =
|
|
367
|
-
const pkg = JSON.parse(
|
|
528
|
+
const pkgPath = resolve3(indexPath, "..", "package.json");
|
|
529
|
+
const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
|
|
368
530
|
return pkg.version;
|
|
369
531
|
}
|
|
370
532
|
|
|
371
533
|
// kernel/adapters/schema-validators.ts
|
|
372
|
-
import { readFileSync as
|
|
373
|
-
import { dirname, resolve as
|
|
374
|
-
import { createRequire as
|
|
375
|
-
import { Ajv2020 as
|
|
534
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
535
|
+
import { dirname as dirname3, resolve as resolve4 } from "path";
|
|
536
|
+
import { createRequire as createRequire4 } from "module";
|
|
537
|
+
import { Ajv2020 as Ajv20204 } from "ajv/dist/2020.js";
|
|
376
538
|
function buildProviderFrontmatterValidator(providers) {
|
|
377
|
-
const specRoot =
|
|
378
|
-
const ajv = new
|
|
539
|
+
const specRoot = resolveSpecRoot2();
|
|
540
|
+
const ajv = new Ajv20204({
|
|
379
541
|
strict: false,
|
|
380
542
|
allErrors: true,
|
|
381
543
|
allowUnionTypes: true
|
|
382
544
|
});
|
|
383
545
|
applyAjvFormats(ajv);
|
|
384
|
-
const baseFile =
|
|
385
|
-
const baseSchema = JSON.parse(
|
|
546
|
+
const baseFile = resolve4(specRoot, "schemas/frontmatter/base.schema.json");
|
|
547
|
+
const baseSchema = JSON.parse(readFileSync4(baseFile, "utf8"));
|
|
386
548
|
ajv.addSchema(baseSchema);
|
|
387
549
|
registerProviderAuxiliarySchemas(ajv, providers);
|
|
388
550
|
const compiled = /* @__PURE__ */ new Map();
|
|
@@ -419,11 +581,11 @@ function registerProviderAuxiliarySchemas(ajv, providers) {
|
|
|
419
581
|
}
|
|
420
582
|
}
|
|
421
583
|
}
|
|
422
|
-
function
|
|
423
|
-
const require2 =
|
|
584
|
+
function resolveSpecRoot2() {
|
|
585
|
+
const require2 = createRequire4(import.meta.url);
|
|
424
586
|
try {
|
|
425
587
|
const indexPath = require2.resolve("@skill-map/spec/index.json");
|
|
426
|
-
return
|
|
588
|
+
return dirname3(indexPath);
|
|
427
589
|
} catch {
|
|
428
590
|
throw new Error(
|
|
429
591
|
"@skill-map/spec not resolvable \u2014 ensure the workspace is linked or the package is installed."
|
|
@@ -443,6 +605,195 @@ var ORCHESTRATOR_TEXTS = {
|
|
|
443
605
|
runScanRootMissing: "runScan: root path '{{root}}' does not exist or is not a directory"
|
|
444
606
|
};
|
|
445
607
|
|
|
608
|
+
// kernel/util/format-error.ts
|
|
609
|
+
function formatErrorMessage(err) {
|
|
610
|
+
return err instanceof Error ? err.message : String(err);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// kernel/scan/walk-content.ts
|
|
614
|
+
import { readFile, readdir, stat } from "fs/promises";
|
|
615
|
+
import { join as join3, relative as relative3, sep as sep2 } from "path";
|
|
616
|
+
|
|
617
|
+
// kernel/scan/ignore.ts
|
|
618
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
|
|
619
|
+
import { dirname as dirname4, resolve as resolve5 } from "path";
|
|
620
|
+
import { fileURLToPath } from "url";
|
|
621
|
+
import ignoreFactory from "ignore";
|
|
622
|
+
function buildIgnoreFilter(opts = {}) {
|
|
623
|
+
const ig = ignoreFactory();
|
|
624
|
+
if (opts.includeDefaults !== false) {
|
|
625
|
+
ig.add(loadDefaultsText());
|
|
626
|
+
}
|
|
627
|
+
if (opts.configIgnore && opts.configIgnore.length > 0) {
|
|
628
|
+
ig.add(opts.configIgnore);
|
|
629
|
+
}
|
|
630
|
+
if (opts.ignoreFileText && opts.ignoreFileText.length > 0) {
|
|
631
|
+
ig.add(opts.ignoreFileText);
|
|
632
|
+
}
|
|
633
|
+
return {
|
|
634
|
+
ignores(relativePath) {
|
|
635
|
+
if (relativePath === "" || relativePath === "." || relativePath === "./") {
|
|
636
|
+
return false;
|
|
637
|
+
}
|
|
638
|
+
const normalised = relativePath.replace(/^\.\//, "").replace(/\\/g, "/").replace(/^\//, "");
|
|
639
|
+
if (normalised === "") return false;
|
|
640
|
+
return ig.ignores(normalised);
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
var cachedDefaults = null;
|
|
645
|
+
function loadDefaultsText() {
|
|
646
|
+
if (cachedDefaults !== null) return cachedDefaults;
|
|
647
|
+
cachedDefaults = readDefaultsFromDisk();
|
|
648
|
+
return cachedDefaults;
|
|
649
|
+
}
|
|
650
|
+
function readDefaultsFromDisk() {
|
|
651
|
+
const here = dirname4(fileURLToPath(import.meta.url));
|
|
652
|
+
const candidates = [
|
|
653
|
+
resolve5(here, "../../config/defaults/skillmapignore"),
|
|
654
|
+
// src/kernel/scan/ → src/config/defaults/
|
|
655
|
+
resolve5(here, "../config/defaults/skillmapignore"),
|
|
656
|
+
// dist/cli.js → dist/config/defaults/ (siblings)
|
|
657
|
+
resolve5(here, "config/defaults/skillmapignore")
|
|
658
|
+
];
|
|
659
|
+
for (const candidate of candidates) {
|
|
660
|
+
if (existsSync5(candidate)) {
|
|
661
|
+
try {
|
|
662
|
+
return readFileSync5(candidate, "utf8");
|
|
663
|
+
} catch {
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
return "";
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// kernel/scan/parsers/frontmatter-yaml.ts
|
|
671
|
+
import yaml3 from "js-yaml";
|
|
672
|
+
var FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
|
|
673
|
+
var FORBIDDEN_FRONTMATTER_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
674
|
+
var frontmatterYamlParser = {
|
|
675
|
+
id: "frontmatter-yaml",
|
|
676
|
+
parse(raw, _path) {
|
|
677
|
+
const match = FRONTMATTER_RE.exec(raw);
|
|
678
|
+
if (!match) return { frontmatterRaw: "", frontmatter: {}, body: raw };
|
|
679
|
+
const frontmatterRaw = match[1];
|
|
680
|
+
const body = match[2];
|
|
681
|
+
const parsed = {};
|
|
682
|
+
try {
|
|
683
|
+
const doc = yaml3.load(frontmatterRaw, { schema: yaml3.JSON_SCHEMA });
|
|
684
|
+
if (doc && typeof doc === "object" && !Array.isArray(doc)) {
|
|
685
|
+
for (const [k, v] of Object.entries(doc)) {
|
|
686
|
+
if (FORBIDDEN_FRONTMATTER_KEYS.has(k)) continue;
|
|
687
|
+
parsed[k] = v;
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
} catch {
|
|
691
|
+
}
|
|
692
|
+
return { frontmatterRaw, frontmatter: parsed, body };
|
|
693
|
+
}
|
|
694
|
+
};
|
|
695
|
+
|
|
696
|
+
// kernel/scan/parsers/plain.ts
|
|
697
|
+
var plainParser = {
|
|
698
|
+
id: "plain",
|
|
699
|
+
parse(raw, _path) {
|
|
700
|
+
return { frontmatter: {}, frontmatterRaw: "", body: raw };
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
|
|
704
|
+
// kernel/scan/parsers/index.ts
|
|
705
|
+
var REGISTRY = /* @__PURE__ */ new Map([
|
|
706
|
+
[frontmatterYamlParser.id, frontmatterYamlParser],
|
|
707
|
+
[plainParser.id, plainParser]
|
|
708
|
+
]);
|
|
709
|
+
var FROZEN_IDS = new Set(REGISTRY.keys());
|
|
710
|
+
function getParser(id) {
|
|
711
|
+
return REGISTRY.get(id);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// kernel/scan/walk-content.ts
|
|
715
|
+
var UnknownParserError = class extends Error {
|
|
716
|
+
constructor(parserId) {
|
|
717
|
+
super(`Unknown parser id '${parserId}'. Built-in parsers: 'frontmatter-yaml', 'plain'.`);
|
|
718
|
+
this.name = "UnknownParserError";
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
async function* walkContent(roots, options) {
|
|
722
|
+
const parser = getParser(options.parser);
|
|
723
|
+
if (!parser) throw new UnknownParserError(options.parser);
|
|
724
|
+
const filter = options.ignoreFilter ?? buildIgnoreFilter();
|
|
725
|
+
const extensions = options.extensions;
|
|
726
|
+
for (const root of roots) {
|
|
727
|
+
for await (const file of walkRoot(root, root, filter, extensions)) {
|
|
728
|
+
const relPath = relative3(root, file).split(sep2).join("/");
|
|
729
|
+
let raw;
|
|
730
|
+
try {
|
|
731
|
+
raw = await readFile(file, "utf8");
|
|
732
|
+
} catch {
|
|
733
|
+
continue;
|
|
734
|
+
}
|
|
735
|
+
const parsed = parser.parse(raw, relPath);
|
|
736
|
+
yield {
|
|
737
|
+
path: relPath,
|
|
738
|
+
body: parsed.body,
|
|
739
|
+
frontmatterRaw: parsed.frontmatterRaw,
|
|
740
|
+
frontmatter: parsed.frontmatter
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
async function* walkRoot(root, current, filter, extensions) {
|
|
746
|
+
let entries;
|
|
747
|
+
try {
|
|
748
|
+
entries = await readdir(current, { withFileTypes: true, encoding: "utf8" });
|
|
749
|
+
} catch {
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
for (const entry of entries) {
|
|
753
|
+
const name = entry.name;
|
|
754
|
+
const full = join3(current, name);
|
|
755
|
+
const rel = relative3(root, full).split(sep2).join("/");
|
|
756
|
+
if (filter.ignores(rel)) continue;
|
|
757
|
+
if (entry.isSymbolicLink()) continue;
|
|
758
|
+
if (entry.isDirectory()) {
|
|
759
|
+
yield* walkRoot(root, full, filter, extensions);
|
|
760
|
+
} else if (entry.isFile() && hasMatchingExtension(name, extensions)) {
|
|
761
|
+
try {
|
|
762
|
+
const s = await stat(full);
|
|
763
|
+
if (s.isFile()) yield full;
|
|
764
|
+
} catch {
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
function hasMatchingExtension(name, extensions) {
|
|
770
|
+
for (const ext of extensions) {
|
|
771
|
+
if (name.endsWith(ext)) return true;
|
|
772
|
+
}
|
|
773
|
+
return false;
|
|
774
|
+
}
|
|
775
|
+
|
|
776
|
+
// kernel/extensions/provider.ts
|
|
777
|
+
var DEFAULT_READ_CONFIG = Object.freeze({
|
|
778
|
+
extensions: Object.freeze([".md"]),
|
|
779
|
+
parser: "frontmatter-yaml"
|
|
780
|
+
});
|
|
781
|
+
function resolveProviderWalk(provider) {
|
|
782
|
+
if (provider.walk) {
|
|
783
|
+
const walk2 = provider.walk.bind(provider);
|
|
784
|
+
return walk2;
|
|
785
|
+
}
|
|
786
|
+
const read = provider.read ?? DEFAULT_READ_CONFIG;
|
|
787
|
+
return (roots, options) => {
|
|
788
|
+
const walkOptions = {
|
|
789
|
+
extensions: read.extensions,
|
|
790
|
+
parser: read.parser
|
|
791
|
+
};
|
|
792
|
+
if (options?.ignoreFilter) walkOptions.ignoreFilter = options.ignoreFilter;
|
|
793
|
+
return walkContent(roots, walkOptions);
|
|
794
|
+
};
|
|
795
|
+
}
|
|
796
|
+
|
|
446
797
|
// kernel/orchestrator.ts
|
|
447
798
|
var SCANNED_BY = {
|
|
448
799
|
name: "skill-map",
|
|
@@ -505,14 +856,23 @@ async function runScanInternal(_kernel, options) {
|
|
|
505
856
|
emitter.emit(evt);
|
|
506
857
|
await hookDispatcher.dispatch("extractor.completed", evt);
|
|
507
858
|
}
|
|
508
|
-
const issues = await runRules(
|
|
859
|
+
const issues = await runRules(
|
|
860
|
+
exts.rules,
|
|
861
|
+
walked.nodes,
|
|
862
|
+
walked.internalLinks,
|
|
863
|
+
walked.orphanSidecars,
|
|
864
|
+
walked.sidecarRoots,
|
|
865
|
+
options.annotationContributions ?? [],
|
|
866
|
+
emitter,
|
|
867
|
+
hookDispatcher
|
|
868
|
+
);
|
|
509
869
|
for (const issue of walked.frontmatterIssues) issues.push(issue);
|
|
510
870
|
const renameOps = prior ? detectRenamesAndOrphans(prior, walked.nodes, issues) : [];
|
|
511
871
|
const stats = {
|
|
512
872
|
// `filesSkipped` is "files walked but not classified by any Provider".
|
|
513
873
|
// Today every walked file IS classified by its Provider (the `claude`
|
|
514
874
|
// Provider's `classify()` always returns a kind, falling back to
|
|
515
|
-
// `'
|
|
875
|
+
// `'markdown'`), so this is always 0. Wired now so the field shape is
|
|
516
876
|
// spec-conformant; meaningful once multiple Providers compete.
|
|
517
877
|
filesWalked: walked.filesWalked,
|
|
518
878
|
filesSkipped: 0,
|
|
@@ -547,7 +907,7 @@ function validateRoots(roots) {
|
|
|
547
907
|
throw new Error(ORCHESTRATOR_TEXTS.runScanRootEmptyArray);
|
|
548
908
|
}
|
|
549
909
|
for (const root of roots) {
|
|
550
|
-
if (!
|
|
910
|
+
if (!existsSync6(root) || !statSync2(root).isDirectory()) {
|
|
551
911
|
throw new Error(tx(ORCHESTRATOR_TEXTS.runScanRootMissing, { root }));
|
|
552
912
|
}
|
|
553
913
|
}
|
|
@@ -751,6 +1111,7 @@ async function walkAndExtract(opts) {
|
|
|
751
1111
|
const frontmatterIssues = [];
|
|
752
1112
|
const enrichmentBuffer = /* @__PURE__ */ new Map();
|
|
753
1113
|
const extractorRuns = [];
|
|
1114
|
+
const sidecarRoots = /* @__PURE__ */ new Map();
|
|
754
1115
|
let filesWalked = 0;
|
|
755
1116
|
let index = 0;
|
|
756
1117
|
const walkOptions = ignoreFilter ? { ignoreFilter } : {};
|
|
@@ -762,13 +1123,16 @@ async function walkAndExtract(opts) {
|
|
|
762
1123
|
else shortIdToQualified.set(ex.id, [qualified]);
|
|
763
1124
|
}
|
|
764
1125
|
for (const provider of providers) {
|
|
765
|
-
for await (const raw of provider
|
|
1126
|
+
for await (const raw of resolveProviderWalk(provider)(roots, walkOptions)) {
|
|
766
1127
|
filesWalked += 1;
|
|
767
1128
|
const bodyHash = sha256(raw.body);
|
|
768
1129
|
const frontmatterHash = sha256(canonicalFrontmatter(raw.frontmatter, raw.frontmatterRaw));
|
|
769
1130
|
const priorNode = priorNodesByPath.get(raw.path);
|
|
770
1131
|
const nodeHashCacheEligible = enableCache && prior !== null && priorNode !== void 0 && priorNode.bodyHash === bodyHash && priorNode.frontmatterHash === frontmatterHash;
|
|
771
1132
|
const kind = provider.classify(raw.path, raw.frontmatter);
|
|
1133
|
+
if (kind === null) {
|
|
1134
|
+
continue;
|
|
1135
|
+
}
|
|
772
1136
|
index += 1;
|
|
773
1137
|
const cacheDecision = computeCacheDecision({
|
|
774
1138
|
extractors,
|
|
@@ -796,10 +1160,21 @@ async function walkAndExtract(opts) {
|
|
|
796
1160
|
priorLinksByOriginating,
|
|
797
1161
|
priorFrontmatterIssuesByNode
|
|
798
1162
|
});
|
|
1163
|
+
reused.node.stability = null;
|
|
1164
|
+
reused.node.version = null;
|
|
1165
|
+
const reusedSidecarIssues = resolveAndApplySidecar(
|
|
1166
|
+
reused.node,
|
|
1167
|
+
raw.path,
|
|
1168
|
+
roots,
|
|
1169
|
+
bodyHash,
|
|
1170
|
+
frontmatterHash,
|
|
1171
|
+
sidecarRoots
|
|
1172
|
+
);
|
|
799
1173
|
nodes.push(reused.node);
|
|
800
1174
|
cachedPaths.add(reused.node.path);
|
|
801
1175
|
for (const link of reused.internalLinks) internalLinks.push(link);
|
|
802
1176
|
for (const issue of reused.frontmatterIssues) frontmatterIssues.push(issue);
|
|
1177
|
+
for (const issue of reusedSidecarIssues) frontmatterIssues.push(issue);
|
|
803
1178
|
for (const run of reused.extractorRuns) extractorRuns.push(run);
|
|
804
1179
|
emitter.emit(makeEvent("scan.progress", { index, path: raw.path, kind, cached: true }));
|
|
805
1180
|
continue;
|
|
@@ -835,6 +1210,15 @@ async function walkAndExtract(opts) {
|
|
|
835
1210
|
nodes.push(node);
|
|
836
1211
|
for (const issue of fresh.frontmatterIssues) frontmatterIssues.push(issue);
|
|
837
1212
|
}
|
|
1213
|
+
const sidecarIssues = resolveAndApplySidecar(
|
|
1214
|
+
node,
|
|
1215
|
+
raw.path,
|
|
1216
|
+
roots,
|
|
1217
|
+
bodyHash,
|
|
1218
|
+
frontmatterHash,
|
|
1219
|
+
sidecarRoots
|
|
1220
|
+
);
|
|
1221
|
+
for (const issue of sidecarIssues) frontmatterIssues.push(issue);
|
|
838
1222
|
emitter.emit(makeEvent("scan.progress", {
|
|
839
1223
|
index,
|
|
840
1224
|
path: raw.path,
|
|
@@ -869,6 +1253,7 @@ async function walkAndExtract(opts) {
|
|
|
869
1253
|
}
|
|
870
1254
|
}
|
|
871
1255
|
}
|
|
1256
|
+
const orphanSidecars = discoverOrphanSidecars(roots);
|
|
872
1257
|
return {
|
|
873
1258
|
nodes,
|
|
874
1259
|
internalLinks,
|
|
@@ -877,7 +1262,9 @@ async function walkAndExtract(opts) {
|
|
|
877
1262
|
frontmatterIssues,
|
|
878
1263
|
filesWalked,
|
|
879
1264
|
enrichments: [...enrichmentBuffer.values()],
|
|
880
|
-
extractorRuns
|
|
1265
|
+
extractorRuns,
|
|
1266
|
+
orphanSidecars,
|
|
1267
|
+
sidecarRoots
|
|
881
1268
|
};
|
|
882
1269
|
}
|
|
883
1270
|
function reuseCachedLink(link, shortIdToQualified, cachedQualifiedIds, applicableQualifiedIds) {
|
|
@@ -906,10 +1293,20 @@ function reuseCachedLink(link, shortIdToQualified, cachedQualifiedIds, applicabl
|
|
|
906
1293
|
if (obsoleteSources.length === 0) return link;
|
|
907
1294
|
return { ...link, sources: cachedSources };
|
|
908
1295
|
}
|
|
909
|
-
async function runRules(rules, nodes, internalLinks, emitter, hookDispatcher) {
|
|
1296
|
+
async function runRules(rules, nodes, internalLinks, orphanSidecars, sidecarRoots, annotationContributions, emitter, hookDispatcher) {
|
|
910
1297
|
const issues = [];
|
|
1298
|
+
const ruleOrphans = orphanSidecars.map((o) => ({
|
|
1299
|
+
relativePath: o.relativePath,
|
|
1300
|
+
expectedMdPath: o.expectedMdPath
|
|
1301
|
+
}));
|
|
911
1302
|
for (const rule of rules) {
|
|
912
|
-
const emitted = await rule.evaluate({
|
|
1303
|
+
const emitted = await rule.evaluate({
|
|
1304
|
+
nodes,
|
|
1305
|
+
links: internalLinks,
|
|
1306
|
+
orphanSidecars: ruleOrphans,
|
|
1307
|
+
sidecarRoots,
|
|
1308
|
+
annotationContributions
|
|
1309
|
+
});
|
|
913
1310
|
for (const issue of emitted) {
|
|
914
1311
|
const validated = validateIssue(rule, issue, emitter);
|
|
915
1312
|
if (validated) issues.push(validated);
|
|
@@ -1090,7 +1487,7 @@ function makeHookDispatcher(hooks, emitter) {
|
|
|
1090
1487
|
await hook.on(ctx);
|
|
1091
1488
|
} catch (err) {
|
|
1092
1489
|
const qualifiedId = qualifiedExtensionId(hook.pluginId, hook.id);
|
|
1093
|
-
const message =
|
|
1490
|
+
const message = formatErrorMessage(err);
|
|
1094
1491
|
emitter.emit(
|
|
1095
1492
|
makeEvent("extension.error", {
|
|
1096
1493
|
kind: "hook-error",
|
|
@@ -1135,7 +1532,6 @@ function buildHookContext(_hook, trigger, event) {
|
|
|
1135
1532
|
function buildNode(args) {
|
|
1136
1533
|
const bytesFrontmatter = Buffer.byteLength(args.frontmatterRaw, "utf8");
|
|
1137
1534
|
const bytesBody = Buffer.byteLength(args.body, "utf8");
|
|
1138
|
-
const metadata = pickMetadata(args.frontmatter);
|
|
1139
1535
|
const node = {
|
|
1140
1536
|
path: args.path,
|
|
1141
1537
|
kind: args.kind,
|
|
@@ -1153,9 +1549,8 @@ function buildNode(args) {
|
|
|
1153
1549
|
frontmatter: args.frontmatter,
|
|
1154
1550
|
title: pickString(args.frontmatter["name"]),
|
|
1155
1551
|
description: pickString(args.frontmatter["description"]),
|
|
1156
|
-
stability:
|
|
1157
|
-
version:
|
|
1158
|
-
author: pickString(args.frontmatter["author"])
|
|
1552
|
+
stability: null,
|
|
1553
|
+
version: null
|
|
1159
1554
|
};
|
|
1160
1555
|
if (args.encoder) {
|
|
1161
1556
|
node.tokens = countTokens(args.encoder, args.frontmatterRaw, args.body);
|
|
@@ -1176,24 +1571,88 @@ function canonicalFrontmatter(parsed, raw) {
|
|
|
1176
1571
|
if (!hasParsedKeys && hasRawText) {
|
|
1177
1572
|
return raw;
|
|
1178
1573
|
}
|
|
1179
|
-
return
|
|
1574
|
+
return yaml4.dump(parsed, {
|
|
1180
1575
|
sortKeys: true,
|
|
1181
1576
|
lineWidth: -1,
|
|
1182
1577
|
noRefs: true,
|
|
1183
1578
|
noCompatMode: true
|
|
1184
1579
|
});
|
|
1185
1580
|
}
|
|
1186
|
-
function
|
|
1187
|
-
const
|
|
1188
|
-
|
|
1581
|
+
function resolveAndApplySidecar(node, relativePath, roots, liveBodyHash, liveFrontmatterHash, sidecarRoots) {
|
|
1582
|
+
const issues = [];
|
|
1583
|
+
const mdAbs = resolveAbsoluteMdPath(relativePath, roots);
|
|
1584
|
+
if (mdAbs === null) {
|
|
1585
|
+
node.sidecar = { present: false };
|
|
1586
|
+
return issues;
|
|
1587
|
+
}
|
|
1588
|
+
const result = readSidecarFor(mdAbs);
|
|
1589
|
+
if (!result.present) {
|
|
1590
|
+
node.sidecar = { present: false };
|
|
1591
|
+
return issues;
|
|
1592
|
+
}
|
|
1593
|
+
if (result.parsed === null) {
|
|
1594
|
+
node.sidecar = { present: true, status: null, annotations: null, root: null };
|
|
1595
|
+
for (const parseIssue of result.issues) {
|
|
1596
|
+
issues.push({
|
|
1597
|
+
ruleId: "invalid-sidecar",
|
|
1598
|
+
severity: "warn",
|
|
1599
|
+
nodeIds: [node.path],
|
|
1600
|
+
message: parseIssue.message,
|
|
1601
|
+
data: { sidecarPath: relativePathFromRoots(mdAbs, roots) }
|
|
1602
|
+
});
|
|
1603
|
+
}
|
|
1604
|
+
return issues;
|
|
1605
|
+
}
|
|
1606
|
+
const status = computeDriftStatus({
|
|
1607
|
+
storedBodyHash: result.parsed.forBodyHash,
|
|
1608
|
+
storedFrontmatterHash: result.parsed.forFrontmatterHash,
|
|
1609
|
+
liveBodyHash,
|
|
1610
|
+
liveFrontmatterHash
|
|
1611
|
+
});
|
|
1612
|
+
applyAnnotationsOverlay(node, result.parsed);
|
|
1613
|
+
node.sidecar = {
|
|
1614
|
+
present: true,
|
|
1615
|
+
status,
|
|
1616
|
+
annotations: result.parsed.annotations,
|
|
1617
|
+
root: result.parsed.raw
|
|
1618
|
+
};
|
|
1619
|
+
sidecarRoots.set(node.path, result.parsed.raw);
|
|
1620
|
+
return issues;
|
|
1189
1621
|
}
|
|
1190
|
-
function
|
|
1191
|
-
|
|
1622
|
+
function applyAnnotationsOverlay(node, parsed) {
|
|
1623
|
+
const annotations = parsed.annotations;
|
|
1624
|
+
if (annotations === null) return;
|
|
1625
|
+
const stability = annotations["stability"];
|
|
1626
|
+
if (stability === "experimental" || stability === "stable" || stability === "deprecated") {
|
|
1627
|
+
node.stability = stability;
|
|
1628
|
+
}
|
|
1629
|
+
const version = annotations["version"];
|
|
1630
|
+
if (typeof version === "number" && Number.isInteger(version) && version >= 1) {
|
|
1631
|
+
node.version = version;
|
|
1632
|
+
}
|
|
1192
1633
|
}
|
|
1193
|
-
function
|
|
1194
|
-
if (
|
|
1634
|
+
function resolveAbsoluteMdPath(relativePath, roots) {
|
|
1635
|
+
if (isAbsolute2(relativePath)) {
|
|
1636
|
+
return existsSync6(relativePath) ? relativePath : null;
|
|
1637
|
+
}
|
|
1638
|
+
for (const root of roots) {
|
|
1639
|
+
const candidate = resolvePath(root, relativePath);
|
|
1640
|
+
if (existsSync6(candidate)) return candidate;
|
|
1641
|
+
}
|
|
1195
1642
|
return null;
|
|
1196
1643
|
}
|
|
1644
|
+
function relativePathFromRoots(absolutePath, roots) {
|
|
1645
|
+
for (const root of roots) {
|
|
1646
|
+
const abs = resolvePath(root);
|
|
1647
|
+
if (absolutePath.startsWith(`${abs}/`) || absolutePath.startsWith(`${abs}\\`)) {
|
|
1648
|
+
return absolutePath.slice(abs.length + 1).split(/[\\/]/).join("/");
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1651
|
+
return absolutePath;
|
|
1652
|
+
}
|
|
1653
|
+
function pickString(value) {
|
|
1654
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
1655
|
+
}
|
|
1197
1656
|
function buildExtractorContext(extractor, node, body, frontmatter, emitLink, enrichNode, store) {
|
|
1198
1657
|
const scope = extractor.scope;
|
|
1199
1658
|
return {
|
|
@@ -1340,16 +1799,16 @@ function assignSafe(target, source) {
|
|
|
1340
1799
|
}
|
|
1341
1800
|
|
|
1342
1801
|
// kernel/scan/watcher.ts
|
|
1343
|
-
import { resolve as
|
|
1802
|
+
import { resolve as resolve6, relative as relative4, sep as sep3 } from "path";
|
|
1344
1803
|
import chokidar from "chokidar";
|
|
1345
1804
|
function createChokidarWatcher(opts) {
|
|
1346
|
-
const absRoots = opts.roots.map((r) =>
|
|
1805
|
+
const absRoots = opts.roots.map((r) => resolve6(opts.cwd, r));
|
|
1347
1806
|
const ignoreFilterOpt = opts.ignoreFilter;
|
|
1348
1807
|
const getFilter = ignoreFilterOpt === void 0 ? void 0 : typeof ignoreFilterOpt === "function" ? ignoreFilterOpt : () => ignoreFilterOpt;
|
|
1349
1808
|
const ignored = getFilter ? (path) => {
|
|
1350
1809
|
const filter = getFilter();
|
|
1351
1810
|
if (!filter) return false;
|
|
1352
|
-
const rel =
|
|
1811
|
+
const rel = relativePathFromRoots2(path, absRoots);
|
|
1353
1812
|
if (rel === null) return false;
|
|
1354
1813
|
return filter.ignores(rel);
|
|
1355
1814
|
} : void 0;
|
|
@@ -1433,12 +1892,12 @@ function createChokidarWatcher(opts) {
|
|
|
1433
1892
|
};
|
|
1434
1893
|
return { ready, close };
|
|
1435
1894
|
}
|
|
1436
|
-
function
|
|
1895
|
+
function relativePathFromRoots2(absolute, absRoots) {
|
|
1437
1896
|
for (const root of absRoots) {
|
|
1438
|
-
const rel =
|
|
1897
|
+
const rel = relative4(root, absolute);
|
|
1439
1898
|
if (rel === "" || rel === ".") return "";
|
|
1440
|
-
if (!rel.startsWith("..") && !rel.startsWith(`..${
|
|
1441
|
-
return rel.split(
|
|
1899
|
+
if (!rel.startsWith("..") && !rel.startsWith(`..${sep3}`)) {
|
|
1900
|
+
return rel.split(sep3).join("/");
|
|
1442
1901
|
}
|
|
1443
1902
|
}
|
|
1444
1903
|
return null;
|
|
@@ -1689,7 +2148,16 @@ function parseLogLevel(value) {
|
|
|
1689
2148
|
|
|
1690
2149
|
// kernel/index.ts
|
|
1691
2150
|
function createKernel() {
|
|
1692
|
-
|
|
2151
|
+
let annotationKeys = Object.freeze([]);
|
|
2152
|
+
return {
|
|
2153
|
+
registry: new Registry(),
|
|
2154
|
+
getRegisteredAnnotationKeys() {
|
|
2155
|
+
return annotationKeys;
|
|
2156
|
+
},
|
|
2157
|
+
setRegisteredAnnotationKeys(entries) {
|
|
2158
|
+
annotationKeys = Object.freeze([...entries]);
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
1693
2161
|
}
|
|
1694
2162
|
export {
|
|
1695
2163
|
DuplicateExtensionError,
|