@hublo/sentinel 1.1.5 → 1.2.0-alpha.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/README.md +5 -4
- package/dist/bin/sentinel.js +47 -5
- package/dist/{chunk-RLVLDC5H.js → chunk-TWL6T237.js} +1033 -330
- package/dist/chunk-XSCDJZDY.js +26 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/roles/build/react-app.d.ts +116 -0
- package/dist/roles/build/react-app.js +111 -0
- package/lint/nest.json +358 -0
- package/lint/node.json +52 -0
- package/lint/react-lib.json +376 -0
- package/lint/react.json +474 -0
- package/lint/svelte.json +209 -0
- package/lint/tools.json +197 -0
- package/oxlint/nest.json +2 -355
- package/oxlint/node.json +3 -50
- package/oxlint/react-lib.json +2 -373
- package/oxlint/react.json +2 -471
- package/oxlint/svelte.json +3 -207
- package/oxlint/tools.json +3 -195
- package/package.json +21 -2
package/README.md
CHANGED
|
@@ -43,8 +43,8 @@ A large monorepo accumulates:
|
|
|
43
43
|
|
|
44
44
|
sentinel writes **standard config files** into a project (each just `extends` a sentinel preset) and runs the checks. Your editor and the tools read those **normal files natively**, they never call sentinel at runtime, so nothing is coupled to it or brittle.
|
|
45
45
|
|
|
46
|
-
> **Shipped today:** the **TypeScript**, **lint** and **
|
|
47
|
-
> snippets below illustrate the end state and land with their own ticket.
|
|
46
|
+
> **Shipped today:** the **TypeScript**, **lint**, **format**, **build** and **dev** tools. The
|
|
47
|
+
> `--test` snippets below illustrate the end state and land with their own ticket.
|
|
48
48
|
|
|
49
49
|
**Step 1 — put a module on sentinel** (once per module, by a dev; the files are committed). Run from the app dir; `--init` does it all, nothing is hand-edited:
|
|
50
50
|
|
|
@@ -151,6 +151,7 @@ pnpm dlx @hublo/sentinel@<exact-version> --inspect --typescript --module <name>
|
|
|
151
151
|
- [`docs/using-sentinel.md`](docs/using-sentinel.md) — every verb for every role, scoping a run to some files, what a fully adopted module looks like, and how versions move between modules.
|
|
152
152
|
- [`docs/lint-adoption.md`](docs/lint-adoption.md) — migrating a module from ESLint to Oxlint: the two steps, what `--init` writes and removes, the two react tiers, and the failures worth recognising.
|
|
153
153
|
- [`docs/format-adoption.md`](docs/format-adoption.md) — migrating a module from Prettier to oxfmt: why this config is materialized rather than a stub, how a module keeps its own formatting, and what did not survive the move.
|
|
154
|
+
- [`docs/build-adoption.md`](docs/build-adoption.md) — moving a React app's Vite toolchain into sentinel: what the config becomes, what sentinel owns versus what stays the app's, why overriding merges instead of spreading, and why an existing config is not rewritten.
|
|
154
155
|
- [`docs/typescript-adoption.md`](docs/typescript-adoption.md) — the adoption cheat sheet: the two adoption steps, the command model (verb x type x location), options, reading a report, and troubleshooting.
|
|
155
156
|
- [`docs/typescript-traces.md`](docs/typescript-traces.md) — a **generated, versioned** reference of live command + output traces (every verb, option, config result and edge case) against the mock monorepo. Regenerate after CLI changes with `pnpm docs:traces`.
|
|
156
157
|
|
|
@@ -376,9 +377,9 @@ VERBS --run execute the target's tool (--json for metrics + diagnosti
|
|
|
376
377
|
--report deprecated → --run --json
|
|
377
378
|
--status deprecated → --inspect
|
|
378
379
|
|
|
379
|
-
TYPES --lint --format --typescript --build --test
|
|
380
|
+
TYPES --lint --format --typescript --build --dev --test
|
|
380
381
|
--static-analysis --runtime-analysis --arch
|
|
381
|
-
(omit a type →
|
|
382
|
+
(omit a type → every type that TERMINATES; --dev never sweeps)
|
|
382
383
|
|
|
383
384
|
LOCATION in a MODULE dir → that module (do NOT pass --module)
|
|
384
385
|
at the workspace ROOT → --module <name> (one) · --ci (affected) · else all
|
package/dist/bin/sentinel.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
PRESET_NAMES,
|
|
4
|
+
PresetUnsupportedError,
|
|
5
|
+
SWEEPABLE_TARGETS,
|
|
4
6
|
TARGETS,
|
|
5
7
|
VERBS,
|
|
6
8
|
WORKSPACE_ROOT_MARKER,
|
|
7
9
|
availableTargets,
|
|
10
|
+
declaredPresetFor,
|
|
8
11
|
describeFramework,
|
|
9
12
|
dispatch,
|
|
10
13
|
ensureWorkspacePrep,
|
|
11
14
|
findWorkspaceRoot,
|
|
15
|
+
inspectWorkspacePrep,
|
|
12
16
|
palette,
|
|
13
17
|
readNxProjectName,
|
|
14
18
|
readOwnVersion,
|
|
@@ -16,7 +20,8 @@ import {
|
|
|
16
20
|
registerAdapters,
|
|
17
21
|
resolve,
|
|
18
22
|
resolveBin
|
|
19
|
-
} from "../chunk-
|
|
23
|
+
} from "../chunk-TWL6T237.js";
|
|
24
|
+
import "../chunk-XSCDJZDY.js";
|
|
20
25
|
|
|
21
26
|
// bin/sentinel.ts
|
|
22
27
|
import { program } from "commander";
|
|
@@ -144,6 +149,17 @@ async function runInit(ctx) {
|
|
|
144
149
|
});
|
|
145
150
|
worst = Math.max(worst, code);
|
|
146
151
|
} catch (error) {
|
|
152
|
+
if (error instanceof PresetUnsupportedError) {
|
|
153
|
+
if (ctx.targetsExplicit) {
|
|
154
|
+
process.stderr.write(
|
|
155
|
+
`
|
|
156
|
+
sentinel (${type}): this module's preset is "${error.preset}", and --${type} has no adapter for it. Pass --preset if it was detected wrongly (hoisted dependencies make detection fall back to "node").
|
|
157
|
+
`
|
|
158
|
+
);
|
|
159
|
+
worst = Math.max(worst, 1);
|
|
160
|
+
}
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
147
163
|
process.stderr.write(`
|
|
148
164
|
sentinel (${type}): ${asMessage(error)}
|
|
149
165
|
`);
|
|
@@ -196,8 +212,9 @@ async function analyse(params) {
|
|
|
196
212
|
}
|
|
197
213
|
for (const target of params.targets) {
|
|
198
214
|
let adapter;
|
|
215
|
+
const resolutionPreset = params.preset ?? declaredPresetFor(target, module.root) ?? preset2;
|
|
199
216
|
try {
|
|
200
|
-
adapter = resolve(target,
|
|
217
|
+
adapter = resolve(target, resolutionPreset, params.runner);
|
|
201
218
|
} catch (error) {
|
|
202
219
|
if (params.targetsExplicit) {
|
|
203
220
|
const reason = error instanceof Error ? error.message : String(error);
|
|
@@ -416,7 +433,7 @@ function statusCoverage(items) {
|
|
|
416
433
|
};
|
|
417
434
|
}
|
|
418
435
|
function presetShort(preset2) {
|
|
419
|
-
return typeof preset2 === "string" ? preset2.replace(
|
|
436
|
+
return typeof preset2 === "string" ? preset2.replace(/@hublo\/sentinel\/(typescript|tsconfig)\//, "") : "?";
|
|
420
437
|
}
|
|
421
438
|
function renderStatusRow(item, p) {
|
|
422
439
|
if (item.status === "unsupported") return renderUnsupportedRow(item, p);
|
|
@@ -438,6 +455,10 @@ function renderStatusSummary(items, p) {
|
|
|
438
455
|
}
|
|
439
456
|
|
|
440
457
|
// src/cli/run-verb.ts
|
|
458
|
+
function workspacePrep(cwd2) {
|
|
459
|
+
const root = findWorkspaceRoot(cwd2);
|
|
460
|
+
return root ? inspectWorkspacePrep(root) : [];
|
|
461
|
+
}
|
|
441
462
|
async function runVerb(ctx) {
|
|
442
463
|
const { modules, scope } = resolveContext(ctx.cwd, { module: ctx.module, ci: ctx.ci });
|
|
443
464
|
const out = palette(process.stdout);
|
|
@@ -482,7 +503,15 @@ async function runVerb(ctx) {
|
|
|
482
503
|
});
|
|
483
504
|
const summary = generateSummaries(results, ctx.targets);
|
|
484
505
|
if (ctx.json) {
|
|
485
|
-
const base = ctx.verb === "status" || ctx.verb === "inspect" ? {
|
|
506
|
+
const base = ctx.verb === "status" || ctx.verb === "inspect" ? {
|
|
507
|
+
...summary,
|
|
508
|
+
coverage: statusCoverage(summary.results),
|
|
509
|
+
// The root-level changes sentinel maintains, each with its justification checked
|
|
510
|
+
// NOW rather than described in a comment. They are the only thing sentinel does
|
|
511
|
+
// that nobody can see afterwards, and every one of them is temporary. See
|
|
512
|
+
// `inspectWorkspacePrep`.
|
|
513
|
+
...ctx.verb === "inspect" ? { workspace: workspacePrep(ctx.cwd) } : {}
|
|
514
|
+
} : summary;
|
|
486
515
|
const payload = ctx.toolArgs.length > 0 ? { ...base, toolArgs: ctx.toolArgs } : base;
|
|
487
516
|
process.stdout.write(JSON.stringify(payload, null, 2) + "\n");
|
|
488
517
|
} else if (ctx.verb === "status" || ctx.verb === "inspect" && modules.length > 1) {
|
|
@@ -493,6 +522,19 @@ async function runVerb(ctx) {
|
|
|
493
522
|
process.stdout.write(renderSummary(item, out) + "\n");
|
|
494
523
|
}
|
|
495
524
|
}
|
|
525
|
+
if (!ctx.json && ctx.verb === "inspect") {
|
|
526
|
+
const prep = workspacePrep(ctx.cwd);
|
|
527
|
+
if (prep.length > 0) {
|
|
528
|
+
process.stdout.write(`
|
|
529
|
+
sentinel maintains these at the workspace root:
|
|
530
|
+
`);
|
|
531
|
+
for (const entry of prep) {
|
|
532
|
+
process.stdout.write(` ${out.strong(entry.rule)}
|
|
533
|
+
${entry.reason}
|
|
534
|
+
`);
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
496
538
|
process.stderr.write(
|
|
497
539
|
err.dim(` ${modules.length} module(s) [${scope}] in ${Date.now() - started}ms
|
|
498
540
|
`)
|
|
@@ -624,7 +666,7 @@ if (opts.all && namedTargets.length > 0) {
|
|
|
624
666
|
`--all runs every target; drop the specific one(s): ${namedTargets.map((t) => `--${t}`).join(", ")}.`
|
|
625
667
|
);
|
|
626
668
|
}
|
|
627
|
-
var targets = opts.all || namedTargets.length === 0 ? [...
|
|
669
|
+
var targets = opts.all || namedTargets.length === 0 ? [...SWEEPABLE_TARGETS] : namedTargets;
|
|
628
670
|
var targetsExplicit = !(opts.all || namedTargets.length === 0);
|
|
629
671
|
var maxDiagnostics = Number(opts.maxDiagnostics);
|
|
630
672
|
if (!Number.isInteger(maxDiagnostics) || maxDiagnostics < 0) {
|