@hublo/sentinel 1.0.1 → 1.0.2

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.
@@ -1,5 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ FLAVOURS,
4
+ TARGETS,
5
+ VERBS,
3
6
  availableTargets,
4
7
  describeFramework,
5
8
  dispatch,
@@ -11,7 +14,7 @@ import {
11
14
  registerAdapters,
12
15
  resolve,
13
16
  resolveBin
14
- } from "../chunk-HKGCWPRT.js";
17
+ } from "../chunk-SK6E5EM4.js";
15
18
 
16
19
  // bin/sentinel.ts
17
20
  import { program } from "commander";
@@ -106,20 +109,6 @@ function resolveContext(cwd2, opts2) {
106
109
  );
107
110
  }
108
111
 
109
- // src/core/domain.ts
110
- var VERBS = ["run", "inspect", "init", "migrate", "report", "status"];
111
- var TARGETS = [
112
- "lint",
113
- "format",
114
- "typescript",
115
- "build",
116
- "test",
117
- "static-analysis",
118
- "runtime-analysis",
119
- "arch"
120
- ];
121
- var FLAVOURS = ["react", "nest", "svelte", "node"];
122
-
123
112
  // src/core/orchestrate.ts
124
113
  async function analyse(params) {
125
114
  const results = [];
@@ -141,14 +130,6 @@ async function analyse(params) {
141
130
  );
142
131
  }
143
132
  }
144
- const ctx = {
145
- module: module.name,
146
- cwd: module.root,
147
- flavour: flavour2,
148
- ci: params.ci,
149
- fix: params.fix,
150
- maxDiagnostics: params.maxDiagnostics
151
- };
152
133
  for (const target of params.targets) {
153
134
  let adapter;
154
135
  try {
@@ -167,13 +148,22 @@ async function analyse(params) {
167
148
  }
168
149
  continue;
169
150
  }
151
+ const effectiveFlavour = params.flavour ?? adapter.declaredFlavour?.(module.root) ?? flavour2;
152
+ const ctx = {
153
+ module: module.name,
154
+ cwd: module.root,
155
+ flavour: effectiveFlavour,
156
+ ci: params.ci,
157
+ fix: params.fix,
158
+ maxDiagnostics: params.maxDiagnostics
159
+ };
170
160
  try {
171
161
  if (params.verb === "run") {
172
162
  if (params.modules.length > 1) {
173
163
  const err = palette(process.stderr);
174
164
  process.stderr.write(
175
165
  `
176
- ${err.accent("\u25B6")} ${err.strong(module.name)} ${err.dim(`(${flavour2})`)} ${target}
166
+ ${err.accent("\u25B6")} ${err.strong(module.name)} ${err.dim(`(${effectiveFlavour})`)} ${target}
177
167
  `
178
168
  );
179
169
  }
@@ -181,7 +171,7 @@ async function analyse(params) {
181
171
  results.push({
182
172
  project: module.name,
183
173
  target,
184
- flavour: flavour2,
174
+ flavour: effectiveFlavour,
185
175
  ok: result.ok,
186
176
  status: result.ok ? "ok" : "failed",
187
177
  data: {}
@@ -192,7 +182,7 @@ async function analyse(params) {
192
182
  results.push({
193
183
  project: module.name,
194
184
  target,
195
- flavour: flavour2,
185
+ flavour: effectiveFlavour,
196
186
  ok: result.ok,
197
187
  status: result.ok ? "ok" : "failed",
198
188
  data: result.metrics ?? {}
@@ -203,7 +193,7 @@ async function analyse(params) {
203
193
  results.push({
204
194
  project: module.name,
205
195
  target,
206
- flavour: flavour2,
196
+ flavour: effectiveFlavour,
207
197
  ok: true,
208
198
  status: "ok",
209
199
  data: config
@@ -214,7 +204,7 @@ async function analyse(params) {
214
204
  results.push({
215
205
  project: module.name,
216
206
  target,
217
- flavour: flavour2,
207
+ flavour: effectiveFlavour,
218
208
  ok,
219
209
  status: ok ? "ok" : "failed",
220
210
  data: status
@@ -226,7 +216,7 @@ async function analyse(params) {
226
216
  results.push({
227
217
  project: module.name,
228
218
  target,
229
- flavour: flavour2,
219
+ flavour: effectiveFlavour,
230
220
  ok: false,
231
221
  status: "failed",
232
222
  data: { error: message }
@@ -529,8 +519,13 @@ async function runVerb() {
529
519
  maxDiagnostics,
530
520
  ci: Boolean(opts.ci),
531
521
  fix: Boolean(opts.fix),
532
- onProgress: (done, total, name) => process.stderr.write(err.dim(` [${done}/${total}] ${name}
533
- `))
522
+ // Per-module progress is a HUMAN affordance: it tells someone staring at a slow sweep
523
+ // that it is alive. On this monorepo's 441 projects it is 441 lines that bury the four
524
+ // that matter, and it is pure noise in a captured log. So emit it only for an
525
+ // interactive terminal; a pipe, CI, or a generated trace gets the results and the
526
+ // one-line summary, which is all any of them can use.
527
+ onProgress: process.stderr.isTTY ? (done, total, name) => process.stderr.write(err.dim(` [${done}/${total}] ${name}
528
+ `)) : void 0
534
529
  });
535
530
  const summary = generateSummaries(results, targets);
536
531
  if (opts.json && verb !== "run") {
@@ -62,6 +62,20 @@ var BaseAdapter = class {
62
62
  }
63
63
  };
64
64
 
65
+ // src/core/domain.ts
66
+ var VERBS = ["run", "inspect", "init", "migrate", "report", "status"];
67
+ var TARGETS = [
68
+ "lint",
69
+ "format",
70
+ "typescript",
71
+ "build",
72
+ "test",
73
+ "static-analysis",
74
+ "runtime-analysis",
75
+ "arch"
76
+ ];
77
+ var FLAVOURS = ["react", "nest", "svelte", "node"];
78
+
65
79
  // src/shared/color.ts
66
80
  import { styleText } from "util";
67
81
  function palette(stream) {
@@ -294,6 +308,20 @@ var TscAdapter = class extends BaseAdapter {
294
308
  appliesTo(_flavour) {
295
309
  return true;
296
310
  }
311
+ /**
312
+ * The flavour read from the committed `extends` chain
313
+ * (`@hublo/sentinel/tsconfig/nest` -> `nest`), or undefined when the module has not
314
+ * adopted a preset, so the engine falls back to dependency detection.
315
+ *
316
+ * This is the same detection-free read `--status` uses, and it is why an adopted React app
317
+ * reports `react` even in a monorepo that hoists `react` to the root.
318
+ */
319
+ declaredFlavour(cwd) {
320
+ const { preset } = readTsconfigAdoption(cwd);
321
+ if (!preset) return void 0;
322
+ const name = preset.slice(preset.lastIndexOf("/") + 1);
323
+ return FLAVOURS.includes(name) ? name : void 0;
324
+ }
297
325
  /**
298
326
  * Plan `--init`: make the module extend the sentinel preset with a THIN,
299
327
  * conformant stub, route type-checking through the CLI, and pin the
@@ -745,8 +773,9 @@ async function dispatch(opts) {
745
773
  if (opts.verb !== "init") {
746
774
  throw new Error(`dispatch handles --init only; --${opts.verb} routes through analyse()`);
747
775
  }
748
- const flavour = resolveFlavour(opts);
749
- const adapter = resolve(opts.target, flavour, opts.runner);
776
+ const detected = resolveFlavour(opts);
777
+ const adapter = resolve(opts.target, detected, opts.runner);
778
+ const flavour = opts.flavour ?? adapter.declaredFlavour?.(opts.cwd) ?? detected;
750
779
  const context = { cwd: opts.cwd, flavour };
751
780
  const plan = await adapter.plan(context);
752
781
  if (plan.blocked) {
@@ -772,6 +801,9 @@ export {
772
801
  availableTargets,
773
802
  resolve,
774
803
  BaseAdapter,
804
+ VERBS,
805
+ TARGETS,
806
+ FLAVOURS,
775
807
  palette,
776
808
  readOwnPackage,
777
809
  readOwnVersion,
@@ -783,4 +815,4 @@ export {
783
815
  detectFramework,
784
816
  dispatch
785
817
  };
786
- //# sourceMappingURL=chunk-HKGCWPRT.js.map
818
+ //# sourceMappingURL=chunk-SK6E5EM4.js.map
package/dist/index.d.ts CHANGED
@@ -169,6 +169,17 @@ interface Adapter {
169
169
  * adapters can share a (target, runner) if they specialise different flavours.
170
170
  */
171
171
  appliesTo(flavour: Flavour): boolean;
172
+ /**
173
+ * The flavour this module has COMMITTED to, read from its own config, or undefined when
174
+ * it has not adopted a preset yet. Optional: an adapter implements it only when its tool's
175
+ * config states the flavour unambiguously.
176
+ *
177
+ * The engine prefers this over dependency detection, because in a monorepo dependencies are
178
+ * hoisted to the root: `host-admin` declares no `react`, so detection honestly answers
179
+ * `node` while the committed `extends` says `.../tsconfig/react`. Reporting the detected
180
+ * value there would show every adopted module as `node`, which is simply untrue.
181
+ */
182
+ declaredFlavour?(cwd: string): Flavour | undefined;
172
183
  /**
173
184
  * Plan what `--init` should write, as declarative operations (see
174
185
  * `FileOperation`). Given a normalized `UpdateContext`, the adapter may READ the
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  registerAdapters,
8
8
  resolve,
9
9
  setDefaultRunner
10
- } from "./chunk-HKGCWPRT.js";
10
+ } from "./chunk-SK6E5EM4.js";
11
11
  export {
12
12
  BaseAdapter,
13
13
  all,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hublo/sentinel",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "One CLI that guards code health across Hublo repos: shared lint/typescript/build/test presets, static & dynamic analysis, and architecture checks.",
5
5
  "type": "module",
6
6
  "license": "MIT",