@skill-map/cli 0.50.1 → 0.51.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 +155 -79
- package/dist/conformance/index.js +13 -25
- package/dist/index.js +91 -408
- package/dist/kernel/index.js +91 -408
- package/dist/ui/chunk-2GXE52AJ.js +123 -0
- package/dist/ui/chunk-KHRNVLJW.js +1 -0
- package/dist/ui/{chunk-DQEAPUE5.js → chunk-OZTRR4M7.js} +31 -68
- package/dist/ui/{chunk-4N5LGWJ4.js → chunk-Q5YJKCTP.js} +1 -1
- package/dist/ui/chunk-RCT3JSFL.js +1 -0
- package/dist/ui/{chunk-DOWLJNMD.js → chunk-VBTLX7GH.js} +13 -13
- package/dist/ui/index.html +8 -2
- package/dist/ui/{main-I3HSF6GU.js → main-N7D2YBEX.js} +3 -3
- package/dist/ui/{styles-O3EXBCXH.css → styles-RG7Y33BT.css} +1 -1
- package/package.json +1 -1
- package/dist/ui/chunk-76APRPAZ.js +0 -123
- package/dist/ui/chunk-FQQYWQV6.js +0 -1
- package/dist/ui/chunk-OYCCFH2S.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// cli/entry.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]="
|
|
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]="1a42a4ca-6765-5a66-abc9-6b57464bc9c6")}catch(e){}}();
|
|
4
4
|
import { existsSync as existsSync33 } from "fs";
|
|
5
5
|
import { Builtins, Cli as Cli2 } from "clipanion";
|
|
6
6
|
|
|
@@ -246,7 +246,7 @@ function bucketByKind(kind, instance, bag) {
|
|
|
246
246
|
// package.json
|
|
247
247
|
var package_default = {
|
|
248
248
|
name: "@skill-map/cli",
|
|
249
|
-
version: "0.
|
|
249
|
+
version: "0.51.0",
|
|
250
250
|
description: "skill-map reference implementation \u2014 kernel + CLI + adapters.",
|
|
251
251
|
license: "MIT",
|
|
252
252
|
type: "module",
|
|
@@ -3987,7 +3987,7 @@ var nodeSupersedeAction = {
|
|
|
3987
3987
|
}
|
|
3988
3988
|
};
|
|
3989
3989
|
|
|
3990
|
-
//
|
|
3990
|
+
// kernel/update-check/index.ts
|
|
3991
3991
|
var SEMVER_SHAPE_RE = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
|
|
3992
3992
|
async function fetchLatestVersion(pkg, opts) {
|
|
3993
3993
|
const controller = new AbortController();
|
|
@@ -4122,9 +4122,9 @@ function ansiFor(opts) {
|
|
|
4122
4122
|
import { randomUUID } from "crypto";
|
|
4123
4123
|
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync5 } from "fs";
|
|
4124
4124
|
import { homedir } from "os";
|
|
4125
|
-
import { join as
|
|
4125
|
+
import { join as join3 } from "path";
|
|
4126
4126
|
|
|
4127
|
-
//
|
|
4127
|
+
// kernel/util/atomic-write.ts
|
|
4128
4128
|
import {
|
|
4129
4129
|
closeSync,
|
|
4130
4130
|
constants as fsConstants,
|
|
@@ -4182,17 +4182,31 @@ function writeJsonAtomic(path, content) {
|
|
|
4182
4182
|
}
|
|
4183
4183
|
|
|
4184
4184
|
// core/paths/db-path.ts
|
|
4185
|
-
import { join, resolve as resolve6 } from "path";
|
|
4185
|
+
import { join as join2, resolve as resolve6 } from "path";
|
|
4186
|
+
|
|
4187
|
+
// kernel/util/skill-map-paths.ts
|
|
4188
|
+
import { join } from "path";
|
|
4186
4189
|
var SKILL_MAP_DIR = ".skill-map";
|
|
4190
|
+
var KERNEL_SKILL_MAP_DIR = SKILL_MAP_DIR;
|
|
4191
|
+
var SETTINGS_FILENAME = "settings.json";
|
|
4192
|
+
var LOCAL_SETTINGS_FILENAME = "settings.local.json";
|
|
4193
|
+
function kernelSettingsPath(scopeRoot) {
|
|
4194
|
+
return join(scopeRoot, KERNEL_SKILL_MAP_DIR, SETTINGS_FILENAME);
|
|
4195
|
+
}
|
|
4196
|
+
function kernelLocalSettingsPath(scopeRoot) {
|
|
4197
|
+
return join(scopeRoot, KERNEL_SKILL_MAP_DIR, LOCAL_SETTINGS_FILENAME);
|
|
4198
|
+
}
|
|
4199
|
+
|
|
4200
|
+
// core/paths/db-path.ts
|
|
4187
4201
|
var DB_FILENAME = "skill-map.db";
|
|
4188
4202
|
var JOBS_DIRNAME = "jobs";
|
|
4189
4203
|
var PLUGINS_DIRNAME = "plugins";
|
|
4190
|
-
var
|
|
4191
|
-
var
|
|
4204
|
+
var SETTINGS_FILENAME2 = "settings.json";
|
|
4205
|
+
var LOCAL_SETTINGS_FILENAME2 = "settings.local.json";
|
|
4192
4206
|
var IGNORE_FILENAME = ".skillmapignore";
|
|
4193
4207
|
var DEFAULT_DB_REL = `${SKILL_MAP_DIR}/${DB_FILENAME}`;
|
|
4194
4208
|
var GITIGNORE_ENTRIES = [
|
|
4195
|
-
`${SKILL_MAP_DIR}/${
|
|
4209
|
+
`${SKILL_MAP_DIR}/${LOCAL_SETTINGS_FILENAME2}`,
|
|
4196
4210
|
`${SKILL_MAP_DIR}/${DB_FILENAME}`
|
|
4197
4211
|
];
|
|
4198
4212
|
function resolveDbPath(options) {
|
|
@@ -4209,23 +4223,23 @@ function defaultProjectPluginsDir(ctx) {
|
|
|
4209
4223
|
return resolve6(ctx.cwd, SKILL_MAP_DIR, PLUGINS_DIRNAME);
|
|
4210
4224
|
}
|
|
4211
4225
|
function defaultDbPath(scopeRoot) {
|
|
4212
|
-
return
|
|
4226
|
+
return join2(scopeRoot, SKILL_MAP_DIR, DB_FILENAME);
|
|
4213
4227
|
}
|
|
4214
4228
|
function defaultSettingsPath(scopeRoot) {
|
|
4215
|
-
return
|
|
4229
|
+
return join2(scopeRoot, SKILL_MAP_DIR, SETTINGS_FILENAME2);
|
|
4216
4230
|
}
|
|
4217
4231
|
function defaultLocalSettingsPath(scopeRoot) {
|
|
4218
|
-
return
|
|
4232
|
+
return join2(scopeRoot, SKILL_MAP_DIR, LOCAL_SETTINGS_FILENAME2);
|
|
4219
4233
|
}
|
|
4220
4234
|
function defaultIgnoreFilePath(scopeRoot) {
|
|
4221
|
-
return
|
|
4235
|
+
return join2(scopeRoot, IGNORE_FILENAME);
|
|
4222
4236
|
}
|
|
4223
4237
|
|
|
4224
4238
|
// cli/util/user-settings-store.ts
|
|
4225
4239
|
var FILENAME = "settings.json";
|
|
4226
4240
|
var SCHEMA_VERSION = 1;
|
|
4227
4241
|
function userSettingsFilePath() {
|
|
4228
|
-
return
|
|
4242
|
+
return join3(homedir(), SKILL_MAP_DIR, FILENAME);
|
|
4229
4243
|
}
|
|
4230
4244
|
function defaultSettings() {
|
|
4231
4245
|
return { schemaVersion: SCHEMA_VERSION, updateCheck: {}, telemetry: {} };
|
|
@@ -4264,7 +4278,7 @@ function backfillSubObjects(settings) {
|
|
|
4264
4278
|
};
|
|
4265
4279
|
}
|
|
4266
4280
|
function writeUserSettings(patch) {
|
|
4267
|
-
const dir =
|
|
4281
|
+
const dir = join3(homedir(), SKILL_MAP_DIR);
|
|
4268
4282
|
const path = userSettingsFilePath();
|
|
4269
4283
|
try {
|
|
4270
4284
|
const current = readUserSettings();
|
|
@@ -5361,18 +5375,6 @@ var CONFIG_LOADER_TEXTS = {
|
|
|
5361
5375
|
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)."
|
|
5362
5376
|
};
|
|
5363
5377
|
|
|
5364
|
-
// kernel/util/skill-map-paths.ts
|
|
5365
|
-
import { join as join3 } from "path";
|
|
5366
|
-
var KERNEL_SKILL_MAP_DIR = SKILL_MAP_DIR;
|
|
5367
|
-
var SETTINGS_FILENAME2 = "settings.json";
|
|
5368
|
-
var LOCAL_SETTINGS_FILENAME2 = "settings.local.json";
|
|
5369
|
-
function kernelSettingsPath(scopeRoot) {
|
|
5370
|
-
return join3(scopeRoot, KERNEL_SKILL_MAP_DIR, SETTINGS_FILENAME2);
|
|
5371
|
-
}
|
|
5372
|
-
function kernelLocalSettingsPath(scopeRoot) {
|
|
5373
|
-
return join3(scopeRoot, KERNEL_SKILL_MAP_DIR, LOCAL_SETTINGS_FILENAME2);
|
|
5374
|
-
}
|
|
5375
|
-
|
|
5376
5378
|
// config/defaults.json
|
|
5377
5379
|
var defaults_default = {
|
|
5378
5380
|
schemaVersion: 1,
|
|
@@ -5830,11 +5832,20 @@ var FilesystemSidecarStore = class {
|
|
|
5830
5832
|
* files in the repo and entries are tiny).
|
|
5831
5833
|
*/
|
|
5832
5834
|
#locks = /* @__PURE__ */ new Map();
|
|
5835
|
+
/** Injected consent gate, see {@link TSidecarConsentGate}. */
|
|
5836
|
+
#consentGate;
|
|
5837
|
+
/**
|
|
5838
|
+
* @param consentGate the write-consent gate, invoked first inside
|
|
5839
|
+
* `applyPatch`. Production wires
|
|
5840
|
+
* `core/config/sidecar-consent.ts:ensureSidecarWritesAllowed`; tests
|
|
5841
|
+
* wire the same function (to exercise the real config-backed gate)
|
|
5842
|
+
* or a stub.
|
|
5843
|
+
*/
|
|
5844
|
+
constructor(consentGate) {
|
|
5845
|
+
this.#consentGate = consentGate;
|
|
5846
|
+
}
|
|
5833
5847
|
async applyPatch(sidecarAbsPath, changes, consent) {
|
|
5834
|
-
|
|
5835
|
-
confirm: consent.confirm,
|
|
5836
|
-
cwd: consent.cwd
|
|
5837
|
-
});
|
|
5848
|
+
this.#consentGate(consent);
|
|
5838
5849
|
const prev = this.#locks.get(sidecarAbsPath) ?? Promise.resolve();
|
|
5839
5850
|
let release;
|
|
5840
5851
|
const settled = new Promise((res) => {
|
|
@@ -7858,7 +7869,7 @@ function rowToContribution(row) {
|
|
|
7858
7869
|
};
|
|
7859
7870
|
}
|
|
7860
7871
|
|
|
7861
|
-
//
|
|
7872
|
+
// kernel/adapters/sqlite/schema-fingerprint.ts
|
|
7862
7873
|
import { createHash } from "crypto";
|
|
7863
7874
|
import { existsSync as existsSync10, readFileSync as readFileSync10 } from "fs";
|
|
7864
7875
|
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
@@ -9334,7 +9345,7 @@ var BumpCommand = class extends SmCommand {
|
|
|
9334
9345
|
* the staging missed).
|
|
9335
9346
|
*/
|
|
9336
9347
|
async #executePending(plan, cwd, ansi) {
|
|
9337
|
-
const store = new FilesystemSidecarStore();
|
|
9348
|
+
const store = new FilesystemSidecarStore(ensureSidecarWritesAllowed);
|
|
9338
9349
|
const ctx = defaultRuntimeContext();
|
|
9339
9350
|
const consent = {
|
|
9340
9351
|
confirm: this.yes,
|
|
@@ -9480,7 +9491,7 @@ function buildBumpedOutcome(item, sidecarPath) {
|
|
|
9480
9491
|
if (item.report.createdSidecar === true) outcome.createdSidecar = true;
|
|
9481
9492
|
return outcome;
|
|
9482
9493
|
}
|
|
9483
|
-
async function applyBumpWrites(item, consent, store = new FilesystemSidecarStore()) {
|
|
9494
|
+
async function applyBumpWrites(item, consent, store = new FilesystemSidecarStore(ensureSidecarWritesAllowed)) {
|
|
9484
9495
|
let sidecarPath;
|
|
9485
9496
|
try {
|
|
9486
9497
|
for (const w of item.writes) {
|
|
@@ -11423,20 +11434,9 @@ function trimRedundantPath(message, primary) {
|
|
|
11423
11434
|
import { existsSync as existsSync16 } from "fs";
|
|
11424
11435
|
import { Command as Command4, Option as Option4 } from "clipanion";
|
|
11425
11436
|
|
|
11426
|
-
//
|
|
11437
|
+
// kernel/scan/detect-providers.ts
|
|
11427
11438
|
import { existsSync as existsSync15 } from "fs";
|
|
11428
11439
|
import { join as join10 } from "path";
|
|
11429
|
-
function resolveActiveProvider(cwd, providers = []) {
|
|
11430
|
-
const detected = detectProvidersFromFilesystem(cwd, providers);
|
|
11431
|
-
const fromConfig = readConfigValue("activeProvider", { cwd });
|
|
11432
|
-
if (typeof fromConfig === "string" && fromConfig.length > 0) {
|
|
11433
|
-
return { resolved: fromConfig, source: "config", detected };
|
|
11434
|
-
}
|
|
11435
|
-
if (detected.length > 0) {
|
|
11436
|
-
return { resolved: detected[0], source: "autodetect", detected };
|
|
11437
|
-
}
|
|
11438
|
-
return { resolved: null, source: "none", detected };
|
|
11439
|
-
}
|
|
11440
11440
|
function detectProvidersFromFilesystem(cwd, providers) {
|
|
11441
11441
|
const seen = /* @__PURE__ */ new Set();
|
|
11442
11442
|
const out = [];
|
|
@@ -11451,6 +11451,19 @@ function detectProvidersFromFilesystem(cwd, providers) {
|
|
|
11451
11451
|
return out;
|
|
11452
11452
|
}
|
|
11453
11453
|
|
|
11454
|
+
// core/config/active-provider.ts
|
|
11455
|
+
function resolveActiveProvider(cwd, providers = []) {
|
|
11456
|
+
const detected = detectProvidersFromFilesystem(cwd, providers);
|
|
11457
|
+
const fromConfig = readConfigValue("activeProvider", { cwd });
|
|
11458
|
+
if (typeof fromConfig === "string" && fromConfig.length > 0) {
|
|
11459
|
+
return { resolved: fromConfig, source: "config", detected };
|
|
11460
|
+
}
|
|
11461
|
+
if (detected.length > 0) {
|
|
11462
|
+
return { resolved: detected[0], source: "autodetect", detected };
|
|
11463
|
+
}
|
|
11464
|
+
return { resolved: null, source: "none", detected };
|
|
11465
|
+
}
|
|
11466
|
+
|
|
11454
11467
|
// cli/util/path-display.ts
|
|
11455
11468
|
import { isAbsolute as isAbsolute4, relative as pathRelative } from "path";
|
|
11456
11469
|
function relativeIfBelow(path, cwd) {
|
|
@@ -16982,7 +16995,7 @@ function resolveActiveProviderOption(optionValue, roots, providers) {
|
|
|
16982
16995
|
for (const root of roots) {
|
|
16983
16996
|
const absRoot = isAbsolute7(root) ? root : resolve28(root);
|
|
16984
16997
|
if (!existsSync23(absRoot)) continue;
|
|
16985
|
-
const detected =
|
|
16998
|
+
const detected = detectProvidersFromFilesystem(absRoot, providers)[0] ?? null;
|
|
16986
16999
|
if (detected !== null) return detected;
|
|
16987
17000
|
}
|
|
16988
17001
|
return null;
|
|
@@ -22272,7 +22285,7 @@ var IntentionalFailCommand = class extends SmCommand {
|
|
|
22272
22285
|
throw new Error(INTENTIONAL_FAIL_TEXTS.errorMessage);
|
|
22273
22286
|
}, 0);
|
|
22274
22287
|
await new Promise((resolve40) => setTimeout(resolve40, 5e3));
|
|
22275
|
-
return
|
|
22288
|
+
return ExitCode.Issues;
|
|
22276
22289
|
}
|
|
22277
22290
|
};
|
|
22278
22291
|
|
|
@@ -22341,6 +22354,25 @@ var SCAN_TEXTS = {
|
|
|
22341
22354
|
persistedTo: " {{dbPath}}\n",
|
|
22342
22355
|
/** Body line for dry-run mode, same indent, marker tail. */
|
|
22343
22356
|
wouldPersist: " would persist to {{dbPath}} (dry-run)\n",
|
|
22357
|
+
/**
|
|
22358
|
+
* Count-row nouns for the `{{counts}}` block in `scannedSummary`.
|
|
22359
|
+
* The caller selects the singular / plural form on `count === 1`
|
|
22360
|
+
* (English plural rule), so both forms live in the catalog instead of
|
|
22361
|
+
* being hand-suffixed with `s` at the call site (per the i18n
|
|
22362
|
+
* contract: catalog strings, no `${word}s` interpolation). `info` is
|
|
22363
|
+
* uncountable in English (no `infos`), so it carries a single form;
|
|
22364
|
+
* `countNoIssues` is the all-clean placeholder.
|
|
22365
|
+
*/
|
|
22366
|
+
countNodeNounSingular: "node",
|
|
22367
|
+
countNodeNounPlural: "nodes",
|
|
22368
|
+
countLinkNounSingular: "link",
|
|
22369
|
+
countLinkNounPlural: "links",
|
|
22370
|
+
countErrorNounSingular: "error",
|
|
22371
|
+
countErrorNounPlural: "errors",
|
|
22372
|
+
countWarningNounSingular: "warning",
|
|
22373
|
+
countWarningNounPlural: "warnings",
|
|
22374
|
+
countInfoNoun: "info",
|
|
22375
|
+
countNoIssues: "0 issues",
|
|
22344
22376
|
/**
|
|
22345
22377
|
* Cap-hit notice, printed when the walker stopped accepting nodes
|
|
22346
22378
|
* because `--max-nodes` (or the `scan.maxNodes` setting) was reached.
|
|
@@ -23422,27 +23454,29 @@ function fillSeverityBucket(bucket, nodeIds) {
|
|
|
23422
23454
|
function formatScanCounts(opts) {
|
|
23423
23455
|
const { nodes, links, severities, ansi } = opts;
|
|
23424
23456
|
const parts = [
|
|
23425
|
-
`${nodes} ${
|
|
23426
|
-
`${links} ${
|
|
23457
|
+
`${nodes} ${countNoun(nodes, SCAN_TEXTS.countNodeNounSingular, SCAN_TEXTS.countNodeNounPlural)}`,
|
|
23458
|
+
`${links} ${countNoun(links, SCAN_TEXTS.countLinkNounSingular, SCAN_TEXTS.countLinkNounPlural)}`
|
|
23427
23459
|
];
|
|
23428
23460
|
const total = severities.errors + severities.warns + severities.info;
|
|
23429
23461
|
if (total === 0) {
|
|
23430
|
-
parts.push(ansi.dim(
|
|
23462
|
+
parts.push(ansi.dim(SCAN_TEXTS.countNoIssues));
|
|
23431
23463
|
} else {
|
|
23432
23464
|
if (severities.errors > 0) {
|
|
23433
|
-
|
|
23465
|
+
const noun = countNoun(severities.errors, SCAN_TEXTS.countErrorNounSingular, SCAN_TEXTS.countErrorNounPlural);
|
|
23466
|
+
parts.push(ansi.red(`${severities.errors} ${noun}`));
|
|
23434
23467
|
}
|
|
23435
23468
|
if (severities.warns > 0) {
|
|
23436
|
-
|
|
23469
|
+
const noun = countNoun(severities.warns, SCAN_TEXTS.countWarningNounSingular, SCAN_TEXTS.countWarningNounPlural);
|
|
23470
|
+
parts.push(ansi.yellow(`${severities.warns} ${noun}`));
|
|
23437
23471
|
}
|
|
23438
23472
|
if (severities.info > 0) {
|
|
23439
|
-
parts.push(ansi.dim(`${severities.info}
|
|
23473
|
+
parts.push(ansi.dim(`${severities.info} ${SCAN_TEXTS.countInfoNoun}`));
|
|
23440
23474
|
}
|
|
23441
23475
|
}
|
|
23442
23476
|
return parts.join(" \xB7 ");
|
|
23443
23477
|
}
|
|
23444
|
-
function
|
|
23445
|
-
return count === 1 ?
|
|
23478
|
+
function countNoun(count, singular, plural) {
|
|
23479
|
+
return count === 1 ? singular : plural;
|
|
23446
23480
|
}
|
|
23447
23481
|
|
|
23448
23482
|
// cli/commands/scan-compare.ts
|
|
@@ -23888,11 +23922,10 @@ var SERVER_TEXTS = {
|
|
|
23888
23922
|
// here (after static + SPA fallback have had their turn).
|
|
23889
23923
|
unknownPath: "Not found: {{path}}.",
|
|
23890
23924
|
// ---- sidecar bump route (routes/sidecar.ts) ------------------------------
|
|
23891
|
-
// 409 refusal when a fresh node is bumped without `force`.
|
|
23892
|
-
// `sidecar-fresh
|
|
23893
|
-
//
|
|
23894
|
-
//
|
|
23895
|
-
// affinity with the CLI's bump verb).
|
|
23925
|
+
// 409 refusal when a fresh node is bumped without `force`. Dispatch
|
|
23926
|
+
// is via the typed `ConflictError` (`code: 'sidecar-fresh'`), so the
|
|
23927
|
+
// `sidecar-fresh:` prefix is NOT load-bearing; it stays only for
|
|
23928
|
+
// log-grep affinity with the CLI's bump verb.
|
|
23896
23929
|
sidecarFreshRefusal: "sidecar-fresh: Node is fresh; pass force:true to bump anyway.",
|
|
23897
23930
|
// 400 envelopes thrown by `parseBody` when the request payload is
|
|
23898
23931
|
// malformed. Each branch has its own key so the UI / log can
|
|
@@ -23920,9 +23953,9 @@ var SERVER_TEXTS = {
|
|
|
23920
23953
|
// dropped half the pipeline. Same gate the `?fresh=1` GET applies.
|
|
23921
23954
|
scanPostRequiresFullPipeline: "POST /api/scan cannot run while the server was started with --no-built-ins or --no-plugins (would persist a partial DB).",
|
|
23922
23955
|
// 409, another scan (watcher batch or another POST) is in flight.
|
|
23923
|
-
//
|
|
23924
|
-
// `scan-busy
|
|
23925
|
-
//
|
|
23956
|
+
// Dispatch is via the typed `ConflictError` (`code: 'scan-busy'`), so
|
|
23957
|
+
// the `scan-busy:` prefix is NOT load-bearing; it stays only for
|
|
23958
|
+
// log-grep affinity with the CLI's `sm scan` verb.
|
|
23926
23959
|
scanPostBusy: "scan-busy: Another scan is already in flight; retry once it finishes.",
|
|
23927
23960
|
// 500, DB missing on a write path. Read paths degrade to empty
|
|
23928
23961
|
// shapes; mutations cannot persist without a DB so they fail fast.
|
|
@@ -24535,6 +24568,7 @@ function registerHealthRoute(app, deps) {
|
|
|
24535
24568
|
var DEFAULT_LIMIT = 100;
|
|
24536
24569
|
var MAX_LIMIT = 1e3;
|
|
24537
24570
|
var BFF_MAX_BULK_CONTRIBUTIONS = 200;
|
|
24571
|
+
var MAX_WS_CLIENTS = 64;
|
|
24538
24572
|
|
|
24539
24573
|
// server/routes/issues.ts
|
|
24540
24574
|
function registerIssuesRoute(app, deps) {
|
|
@@ -24767,7 +24801,7 @@ function registerNodesRoutes(app, deps) {
|
|
|
24767
24801
|
const tags = result?.tags ?? [];
|
|
24768
24802
|
if (!bundle) {
|
|
24769
24803
|
throw new HTTPException7(404, {
|
|
24770
|
-
message: tx(SERVER_TEXTS.nodeNotFound, { path: nodePath })
|
|
24804
|
+
message: tx(SERVER_TEXTS.nodeNotFound, { path: sanitizeForTerminal(nodePath) })
|
|
24771
24805
|
});
|
|
24772
24806
|
}
|
|
24773
24807
|
const decoratedNode = { ...bundle.node, isFavorite, contributions, tags };
|
|
@@ -26057,7 +26091,7 @@ async function runPersistedScan(c, deps) {
|
|
|
26057
26091
|
});
|
|
26058
26092
|
} catch (err) {
|
|
26059
26093
|
if (err instanceof ScanBusyError) {
|
|
26060
|
-
throw new
|
|
26094
|
+
throw new ConflictError({ code: "scan-busy", message: SERVER_TEXTS.scanPostBusy });
|
|
26061
26095
|
}
|
|
26062
26096
|
throw err;
|
|
26063
26097
|
}
|
|
@@ -26250,7 +26284,7 @@ function registerSidecarRoutes(app, deps) {
|
|
|
26250
26284
|
}
|
|
26251
26285
|
const result = invokeBump2(node, absPath, body);
|
|
26252
26286
|
if (result.report.ok === false && result.report.reason === "fresh") {
|
|
26253
|
-
throw new
|
|
26287
|
+
throw new ConflictError({ code: "sidecar-fresh", message: SERVER_TEXTS.sidecarFreshRefusal });
|
|
26254
26288
|
}
|
|
26255
26289
|
if (result.report.ok === true && result.report.noop === true) {
|
|
26256
26290
|
const envelope2 = {
|
|
@@ -26265,7 +26299,7 @@ function registerSidecarRoutes(app, deps) {
|
|
|
26265
26299
|
};
|
|
26266
26300
|
return c.json(envelope2);
|
|
26267
26301
|
}
|
|
26268
|
-
const store = new FilesystemSidecarStore();
|
|
26302
|
+
const store = new FilesystemSidecarStore(ensureSidecarWritesAllowed);
|
|
26269
26303
|
try {
|
|
26270
26304
|
for (const w of result.writes ?? []) {
|
|
26271
26305
|
if (w.kind === "sidecar") {
|
|
@@ -26533,6 +26567,14 @@ var LoopbackGateError = class extends HTTPException16 {
|
|
|
26533
26567
|
this.code = init.code;
|
|
26534
26568
|
}
|
|
26535
26569
|
};
|
|
26570
|
+
var ConflictError = class extends HTTPException16 {
|
|
26571
|
+
code;
|
|
26572
|
+
constructor(init) {
|
|
26573
|
+
super(409, { message: init.message });
|
|
26574
|
+
this.name = "ConflictError";
|
|
26575
|
+
this.code = init.code;
|
|
26576
|
+
}
|
|
26577
|
+
};
|
|
26536
26578
|
function createApp(deps) {
|
|
26537
26579
|
const app = new Hono();
|
|
26538
26580
|
const configService = new ConfigService({
|
|
@@ -26609,16 +26651,12 @@ function createApp(deps) {
|
|
|
26609
26651
|
});
|
|
26610
26652
|
return app;
|
|
26611
26653
|
}
|
|
26612
|
-
function codeForStatus(status
|
|
26654
|
+
function codeForStatus(status) {
|
|
26613
26655
|
if (status === 404) return "not-found";
|
|
26614
26656
|
if (status === 400) return "bad-query";
|
|
26615
26657
|
if (status === 403) return "locked";
|
|
26616
26658
|
if (status === 412) return "confirm-required";
|
|
26617
26659
|
if (status === 413) return "payload-too-large";
|
|
26618
|
-
if (status === 409) {
|
|
26619
|
-
if (message.startsWith("scan-busy:")) return "scan-busy";
|
|
26620
|
-
return "sidecar-fresh";
|
|
26621
|
-
}
|
|
26622
26660
|
return "internal";
|
|
26623
26661
|
}
|
|
26624
26662
|
function formatError2(err, c) {
|
|
@@ -26655,12 +26693,23 @@ function formatError2(err, c) {
|
|
|
26655
26693
|
};
|
|
26656
26694
|
return c.json(envelope, 403);
|
|
26657
26695
|
}
|
|
26696
|
+
if (err instanceof ConflictError) {
|
|
26697
|
+
const envelope = {
|
|
26698
|
+
ok: false,
|
|
26699
|
+
error: {
|
|
26700
|
+
code: err.code,
|
|
26701
|
+
message: err.message,
|
|
26702
|
+
details: null
|
|
26703
|
+
}
|
|
26704
|
+
};
|
|
26705
|
+
return c.json(envelope, 409);
|
|
26706
|
+
}
|
|
26658
26707
|
if (err instanceof HTTPException16) {
|
|
26659
26708
|
const status = err.status;
|
|
26660
26709
|
const envelope = {
|
|
26661
26710
|
ok: false,
|
|
26662
26711
|
error: {
|
|
26663
|
-
code: codeForStatus(status
|
|
26712
|
+
code: codeForStatus(status),
|
|
26664
26713
|
message: err.message,
|
|
26665
26714
|
details: null
|
|
26666
26715
|
}
|
|
@@ -26711,6 +26760,7 @@ function formatInternalErrorFallThrough(err, c) {
|
|
|
26711
26760
|
var MAX_BUFFERED_BYTES = 4 * 1024 * 1024;
|
|
26712
26761
|
var CLOSE_CODE_GOING_AWAY = 1001;
|
|
26713
26762
|
var CLOSE_CODE_MESSAGE_TOO_BIG = 1009;
|
|
26763
|
+
var CLOSE_CODE_TRY_AGAIN_LATER = 1013;
|
|
26714
26764
|
var READY_STATE_OPEN = 1;
|
|
26715
26765
|
var WsBroadcaster = class {
|
|
26716
26766
|
#clients = /* @__PURE__ */ new Set();
|
|
@@ -26733,6 +26783,13 @@ var WsBroadcaster = class {
|
|
|
26733
26783
|
}
|
|
26734
26784
|
return;
|
|
26735
26785
|
}
|
|
26786
|
+
if (this.#clients.size >= MAX_WS_CLIENTS) {
|
|
26787
|
+
try {
|
|
26788
|
+
ws.close(CLOSE_CODE_TRY_AGAIN_LATER, "too many connections");
|
|
26789
|
+
} catch {
|
|
26790
|
+
}
|
|
26791
|
+
return;
|
|
26792
|
+
}
|
|
26736
26793
|
this.#clients.add(ws);
|
|
26737
26794
|
}
|
|
26738
26795
|
/**
|
|
@@ -26979,14 +27036,19 @@ function validatePort(port) {
|
|
|
26979
27036
|
return null;
|
|
26980
27037
|
}
|
|
26981
27038
|
function validateHost(host, devCors) {
|
|
26982
|
-
if (
|
|
27039
|
+
if (isLoopbackHost(host)) return null;
|
|
27040
|
+
if (devCors) {
|
|
26983
27041
|
return {
|
|
26984
27042
|
code: "host-dev-cors-rejected",
|
|
26985
27043
|
message: `--dev-cors requires a loopback --host (got ${host})`,
|
|
26986
27044
|
value: host
|
|
26987
27045
|
};
|
|
26988
27046
|
}
|
|
26989
|
-
return
|
|
27047
|
+
return {
|
|
27048
|
+
code: "host-not-loopback",
|
|
27049
|
+
message: `--host must be a loopback address; multi-host serve is not supported pre-1.0 (got ${host})`,
|
|
27050
|
+
value: host
|
|
27051
|
+
};
|
|
26990
27052
|
}
|
|
26991
27053
|
function validateWatcher(noWatcher, noBuiltIns, _noPlugins) {
|
|
26992
27054
|
if (noWatcher) return null;
|
|
@@ -27274,6 +27336,14 @@ var SERVE_TEXTS = {
|
|
|
27274
27336
|
*/
|
|
27275
27337
|
hostDevCorsRejected: "{{glyph}} sm serve: --dev-cors requires a loopback --host (got {{host}}).\n {{hint}}\n",
|
|
27276
27338
|
hostDevCorsRejectedHint: "Use --host 127.0.0.1 (or ::1) when --dev-cors is set. Multi-host serve reopens after v0.6.0 (Decision #119).",
|
|
27339
|
+
/**
|
|
27340
|
+
* §3.1b error block when `--host` is any non-loopback address (without
|
|
27341
|
+
* `--dev-cors`). The BFF is loopback-only and unauthenticated pre-1.0
|
|
27342
|
+
* (Decision #119), so binding off-loopback is refused outright rather
|
|
27343
|
+
* than relying on the DNS-rebinding gate as the sole control.
|
|
27344
|
+
*/
|
|
27345
|
+
hostNotLoopback: "{{glyph}} sm serve: --host must be a loopback address (got {{host}}).\n {{hint}}\n",
|
|
27346
|
+
hostNotLoopbackHint: "Use --host 127.0.0.1 (or ::1). The server has no auth and is loopback-only; multi-host serve reopens after v0.6.0 (Decision #119).",
|
|
27277
27347
|
/**
|
|
27278
27348
|
* §3.1b error block when `--port` falls outside the [0, 65535] range.
|
|
27279
27349
|
* Hint names the accepted range so the operator can re-run.
|
|
@@ -27822,6 +27892,12 @@ function formatValidationError(err, ansi) {
|
|
|
27822
27892
|
host: sanitizeForTerminal(err.value),
|
|
27823
27893
|
hint: ansi.dim(SERVE_TEXTS.hostDevCorsRejectedHint)
|
|
27824
27894
|
});
|
|
27895
|
+
case "host-not-loopback":
|
|
27896
|
+
return tx(SERVE_TEXTS.hostNotLoopback, {
|
|
27897
|
+
glyph: errGlyph,
|
|
27898
|
+
host: sanitizeForTerminal(err.value),
|
|
27899
|
+
hint: ansi.dim(SERVE_TEXTS.hostNotLoopbackHint)
|
|
27900
|
+
});
|
|
27825
27901
|
case "port-out-of-range":
|
|
27826
27902
|
return tx(SERVE_TEXTS.portOutOfRange, {
|
|
27827
27903
|
glyph: errGlyph,
|
|
@@ -28414,7 +28490,7 @@ var SidecarRefreshCommand = class extends SmCommand {
|
|
|
28414
28490
|
);
|
|
28415
28491
|
return ExitCode.Ok;
|
|
28416
28492
|
}
|
|
28417
|
-
const store = new FilesystemSidecarStore();
|
|
28493
|
+
const store = new FilesystemSidecarStore(ensureSidecarWritesAllowed);
|
|
28418
28494
|
try {
|
|
28419
28495
|
await store.applyPatch(
|
|
28420
28496
|
sidecarAbsPath,
|
|
@@ -28701,7 +28777,7 @@ var SidecarAnnotateCommand = class extends SmCommand {
|
|
|
28701
28777
|
return ExitCode.Error;
|
|
28702
28778
|
}
|
|
28703
28779
|
}
|
|
28704
|
-
const store = new FilesystemSidecarStore();
|
|
28780
|
+
const store = new FilesystemSidecarStore(ensureSidecarWritesAllowed);
|
|
28705
28781
|
try {
|
|
28706
28782
|
await store.applyPatch(
|
|
28707
28783
|
sidecarAbsPath,
|
|
@@ -29490,4 +29566,4 @@ function resolveBareDefault() {
|
|
|
29490
29566
|
process.exit(ExitCode.Error);
|
|
29491
29567
|
}
|
|
29492
29568
|
//# sourceMappingURL=cli.js.map
|
|
29493
|
-
//# debugId=
|
|
29569
|
+
//# debugId=1a42a4ca-6765-5a66-abc9-6b57464bc9c6
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// conformance/index.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]="
|
|
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]="cc85d6cc-8968-5fbd-b7b7-eab3d298263d")}catch(e){}}();
|
|
4
4
|
import { spawnSync } from "child_process";
|
|
5
5
|
import { cpSync, existsSync, mkdtempSync, readdirSync, readFileSync, rmSync, statSync } from "fs";
|
|
6
6
|
import { tmpdir } from "os";
|
|
7
|
-
import { isAbsolute, join as
|
|
7
|
+
import { isAbsolute, join as join2, relative, resolve } from "path";
|
|
8
8
|
|
|
9
9
|
// kernel/util/format-error.ts
|
|
10
10
|
function formatErrorMessage(err) {
|
|
@@ -12,20 +12,8 @@ function formatErrorMessage(err) {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
// kernel/util/skill-map-paths.ts
|
|
15
|
-
import { join
|
|
16
|
-
|
|
17
|
-
// core/paths/db-path.ts
|
|
18
|
-
import { join, resolve } from "path";
|
|
15
|
+
import { join } from "path";
|
|
19
16
|
var SKILL_MAP_DIR = ".skill-map";
|
|
20
|
-
var DB_FILENAME = "skill-map.db";
|
|
21
|
-
var LOCAL_SETTINGS_FILENAME = "settings.local.json";
|
|
22
|
-
var DEFAULT_DB_REL = `${SKILL_MAP_DIR}/${DB_FILENAME}`;
|
|
23
|
-
var GITIGNORE_ENTRIES = [
|
|
24
|
-
`${SKILL_MAP_DIR}/${LOCAL_SETTINGS_FILENAME}`,
|
|
25
|
-
`${SKILL_MAP_DIR}/${DB_FILENAME}`
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
// kernel/util/skill-map-paths.ts
|
|
29
17
|
var KERNEL_SKILL_MAP_DIR = SKILL_MAP_DIR;
|
|
30
18
|
|
|
31
19
|
// kernel/util/tx.ts
|
|
@@ -127,9 +115,9 @@ function pickSafeEnv(source) {
|
|
|
127
115
|
function runConformanceCase(options) {
|
|
128
116
|
const raw = readFileSync(options.casePath, "utf8");
|
|
129
117
|
const c = JSON.parse(raw);
|
|
130
|
-
const fixturesRoot = options.fixturesRoot ??
|
|
118
|
+
const fixturesRoot = options.fixturesRoot ?? join2(options.specRoot, "conformance", "fixtures");
|
|
131
119
|
const safeId = c.id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 32);
|
|
132
|
-
const scope = mkdtempSync(
|
|
120
|
+
const scope = mkdtempSync(join2(tmpdir(), `sm-conformance-${safeId}-`));
|
|
133
121
|
const setupEnv = disableEnv(c.setup);
|
|
134
122
|
try {
|
|
135
123
|
const priorFailure = runPriorScansSetup(c, options, scope, fixturesRoot, setupEnv);
|
|
@@ -201,9 +189,9 @@ function replaceFixture(scope, fixturesRoot, fixture) {
|
|
|
201
189
|
assertContained(fixturesRoot, fixture, "fixture");
|
|
202
190
|
for (const entry of readdirSync(scope)) {
|
|
203
191
|
if (entry === KERNEL_SKILL_MAP_DIR) continue;
|
|
204
|
-
rmSync(
|
|
192
|
+
rmSync(join2(scope, entry), { recursive: true, force: true });
|
|
205
193
|
}
|
|
206
|
-
const src =
|
|
194
|
+
const src = join2(fixturesRoot, fixture);
|
|
207
195
|
cpSync(src, scope, { recursive: true });
|
|
208
196
|
}
|
|
209
197
|
function assertContained(root, rel, label) {
|
|
@@ -212,7 +200,7 @@ function assertContained(root, rel, label) {
|
|
|
212
200
|
tx(CONFORMANCE_RUNNER_TEXTS.pathMustBeRelative, { label, path: rel, anchor: root })
|
|
213
201
|
);
|
|
214
202
|
}
|
|
215
|
-
const abs =
|
|
203
|
+
const abs = resolve(root, rel);
|
|
216
204
|
const r = relative(root, abs);
|
|
217
205
|
if (r.startsWith("..") || isAbsolute(r)) {
|
|
218
206
|
throw new Error(
|
|
@@ -239,7 +227,7 @@ function evaluateAssertion(a, ctx) {
|
|
|
239
227
|
} catch (err) {
|
|
240
228
|
return { ok: false, type: a.type, reason: formatErrorMessage(err) };
|
|
241
229
|
}
|
|
242
|
-
const abs =
|
|
230
|
+
const abs = resolve(ctx.scope, a.path);
|
|
243
231
|
return existsSync(abs) ? { ok: true, type: a.type } : {
|
|
244
232
|
ok: false,
|
|
245
233
|
type: a.type,
|
|
@@ -253,8 +241,8 @@ function evaluateAssertion(a, ctx) {
|
|
|
253
241
|
} catch (err) {
|
|
254
242
|
return { ok: false, type: a.type, reason: formatErrorMessage(err) };
|
|
255
243
|
}
|
|
256
|
-
const fixturePath =
|
|
257
|
-
const targetPath =
|
|
244
|
+
const fixturePath = join2(ctx.fixturesRoot, a.fixture);
|
|
245
|
+
const targetPath = resolve(ctx.scope, a.path);
|
|
258
246
|
if (!existsSync(targetPath)) {
|
|
259
247
|
return {
|
|
260
248
|
ok: false,
|
|
@@ -415,7 +403,7 @@ function deepEqual(a, b) {
|
|
|
415
403
|
return false;
|
|
416
404
|
}
|
|
417
405
|
function assertSpecRoot(specRoot) {
|
|
418
|
-
const indexPath =
|
|
406
|
+
const indexPath = join2(specRoot, "index.json");
|
|
419
407
|
if (!existsSync(indexPath) || !statSync(indexPath).isFile()) {
|
|
420
408
|
throw new Error(tx(CONFORMANCE_RUNNER_TEXTS.specRootMissingIndex, { specRoot }));
|
|
421
409
|
}
|
|
@@ -425,4 +413,4 @@ export {
|
|
|
425
413
|
runConformanceCase
|
|
426
414
|
};
|
|
427
415
|
//# sourceMappingURL=index.js.map
|
|
428
|
-
//# debugId=
|
|
416
|
+
//# debugId=cc85d6cc-8968-5fbd-b7b7-eab3d298263d
|