@geonosis/doctor 1.1.0 → 1.2.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 CHANGED
@@ -17,6 +17,10 @@ question it could not ask is not a pass — and 2 when the run could not be made
17
17
  geonosis-doctor [--root <dir>] [--json] [--strict] [--baseline-against [<ref>]] [--oxlint <path>]
18
18
  ```
19
19
 
20
+ ## One check, asked alone
21
+
22
+ `geonosis-doctor --only loaded` runs that check and no other, in well under a second: a manifest read and a resolution per config. It exists because the doctor subsumed a consumer's own declared-vs-loaded script that lived in a 2.5 s local gate, and eleven seconds for seven checks cannot live there — so the question that catches a stale nested copy earliest had fallen out of the gate that runs most often (during.day, 2026-08-30: `bun add` across eleven workspaces left `packages/workflows` loading 1.0.0 against configs written for 1.1.0, and the script about to be deleted caught it). `--only loaded,runner` takes a list; a name the doctor does not have is refused with the seven it does. A `loaded` FAIL now says the remedy: remove the nested copies and reinstall.
23
+
20
24
  ## The seven checks
21
25
 
22
26
  ### `loaded` — declared ≠ loaded
@@ -919,7 +919,7 @@ var oneConfig = async ({
919
919
  }
920
920
  return held ? said("OK", `loaded ${loaded.version} = declared ${declared.spec} (${declared.at})`) : said(
921
921
  "FAIL",
922
- `loaded ${loaded.version}, declared ${declared.spec} (${declared.at}) \u2014 a nested copy at ${loaded.at}`
922
+ `loaded ${loaded.version}, declared ${declared.spec} (${declared.at}) \u2014 a nested copy at ${loaded.at}. Remove the nested copies (rm -rf <workspace>/node_modules/@geonosis) and reinstall; the linter is not running what the tree declares until then`
923
923
  );
924
924
  };
925
925
  var labelOf = (workspace) => workspace.relative === "" ? "root" : workspace.relative;
@@ -1276,28 +1276,37 @@ var countsOf = (findings) => findings.reduce((counts, one) => ({ ...counts, [one
1276
1276
  });
1277
1277
  var runDoctor = async ({
1278
1278
  baseline,
1279
+ only,
1279
1280
  oxlint,
1280
1281
  root,
1281
1282
  strict = false
1282
1283
  }) => {
1283
1284
  const configs = discoverConfigs(root);
1284
1285
  const workspaces = discoverWorkspaces(root);
1285
- const binary = oxlint ?? resolveOxlint(root);
1286
- const repoCorpus = repoCorpusOf(root);
1287
- const found = ordered([
1288
- ...await checkLoaded({ configs, root, workspaces }),
1289
- ...await exercisedOf({
1290
- configs,
1291
- oxlint: binary,
1292
- ...repoCorpus === void 0 ? {} : { repoCorpus },
1293
- root
1294
- }),
1295
- ...baselineOf({ baseline, root }),
1296
- ...checkRunner({ ratchet: readRatchet(root), workspaces }),
1297
- ...await checkObservability({ now: Date.now(), root }),
1298
- ...checkDrift({ root, workspaces }),
1299
- ...checkDeployed({ root })
1300
- ]);
1286
+ const asked = (check) => only === void 0 || only.includes(check);
1287
+ const runs = [
1288
+ ["loaded", () => checkLoaded({ configs, root, workspaces })],
1289
+ [
1290
+ "exercised",
1291
+ () => {
1292
+ const repoCorpus = repoCorpusOf(root);
1293
+ return exercisedOf({
1294
+ configs,
1295
+ oxlint: oxlint ?? resolveOxlint(root),
1296
+ ...repoCorpus === void 0 ? {} : { repoCorpus },
1297
+ root
1298
+ });
1299
+ }
1300
+ ],
1301
+ ["baseline", () => baselineOf({ baseline, root })],
1302
+ ["runner", () => checkRunner({ ratchet: readRatchet(root), workspaces })],
1303
+ ["observability", () => checkObservability({ now: Date.now(), root })],
1304
+ ["drift", () => checkDrift({ root, workspaces })],
1305
+ ["deployed", () => checkDeployed({ root })]
1306
+ ];
1307
+ const collected = [];
1308
+ for (const [check, run] of runs) if (asked(check)) collected.push(...await run());
1309
+ const found = ordered(collected);
1301
1310
  const findings = strict ? found.map((one) => one.verdict === "WARN" ? { ...one, verdict: "FAIL" } : one) : found;
1302
1311
  return {
1303
1312
  counts: countsOf(findings),
@@ -1330,13 +1339,17 @@ var sectionOf = (check, findings) => {
1330
1339
  var formatDoctor = ({ counts, findings, ok, root }) => [
1331
1340
  `geonosis-doctor \u2014 ${root}`,
1332
1341
  "",
1333
- ...CHECKS.flatMap((check) => sectionOf(check, findings)),
1334
- `${CHECKS.length} checks, ${findings.length} lines: ${counts.OK} ok, ${counts.WARN} warned, ${counts.SKIP} skipped, ${counts.UNJUDGED} unjudged, ${counts.FAIL} failed`,
1342
+ // A check nobody asked for (--only) said nothing; a section for it would read as a check that ran.
1343
+ ...CHECKS.filter((check) => findings.some((one) => one.check === check)).flatMap(
1344
+ (check) => sectionOf(check, findings)
1345
+ ),
1346
+ `${ranOf(findings)} ${ranOf(findings) === 1 ? "check" : "checks"}, ${findings.length} lines: ${counts.OK} ok, ${counts.WARN} warned, ${counts.SKIP} skipped, ${counts.UNJUDGED} unjudged, ${counts.FAIL} failed`,
1335
1347
  ok ? "doctor PASS \u2014 nothing here says the gates are measuring something other than what they claim." : "doctor FAIL \u2014 a line above is a gate reporting on something other than what it names, or a question this could not ask at all.",
1336
1348
  ""
1337
1349
  ].join("\n");
1338
1350
  var formatJson = (report) => `${JSON.stringify(report, null, 2)}
1339
1351
  `;
1352
+ var ranOf = (findings) => new Set(findings.map((one) => one.check)).size;
1340
1353
 
1341
1354
  export {
1342
1355
  CONFIG_FILE,
@@ -1,12 +1,13 @@
1
1
  import {
2
+ CHECKS,
2
3
  formatDoctor,
3
4
  formatJson,
4
5
  runDoctor
5
- } from "./chunk-CG2LN4VW.js";
6
+ } from "./chunk-ZJCUTDQW.js";
6
7
 
7
8
  // src/doctor-cli.ts
8
9
  import { resolve } from "path";
9
- var USAGE = `geonosis-doctor [--root <dir>] [--json] [--strict] [--baseline-against [<ref>]] [--oxlint <path>]
10
+ var USAGE = `geonosis-doctor [--root <dir>] [--only <check,\u2026>] [--json] [--strict] [--baseline-against [<ref>]] [--oxlint <path>]
10
11
 
11
12
  Five questions a version bump is not finished until something has asked. The first four are ways
12
13
  enforcement has reported green while measuring nothing; the fifth asks whether it is still there.
@@ -57,7 +58,7 @@ plugin-route-namespaced on its package root, while the shipped corpus says acme
57
58
  Exits 1 when any line is a FAIL or an UNJUDGED \u2014 a question this could not ask is not a pass \u2014 and
58
59
  2 when the run could not be made at all. --strict promotes every WARN to a FAIL. --json prints the
59
60
  whole report for a CI step to read.`;
60
- var VALUED = /* @__PURE__ */ new Set(["--oxlint", "--root"]);
61
+ var VALUED = /* @__PURE__ */ new Set(["--only", "--oxlint", "--root"]);
61
62
  var parseDoctorArgs = (argv, cwd) => {
62
63
  const read = {};
63
64
  let baseline;
@@ -85,9 +86,15 @@ var parseDoctorArgs = (argv, cwd) => {
85
86
  read[flag] = value;
86
87
  index += 1;
87
88
  }
89
+ const only = read["--only"]?.split(",").map((one) => one.trim()).filter((one) => one !== "");
90
+ const unknown = (only ?? []).filter((one) => !CHECKS.includes(one));
91
+ if (unknown.length > 0) {
92
+ throw new Error(`no check called ${unknown.join(", ")} \u2014 the checks are ${CHECKS.join(", ")}`);
93
+ }
88
94
  return {
89
95
  ...baseline === void 0 ? {} : { baseline },
90
96
  json,
97
+ ...only === void 0 || only.length === 0 ? {} : { only },
91
98
  ...read["--oxlint"] === void 0 ? {} : { oxlint: resolve(cwd, read["--oxlint"]) },
92
99
  root: resolve(cwd, read["--root"] ?? cwd),
93
100
  strict
package/dist/index.d.ts CHANGED
@@ -65,6 +65,8 @@ type DoctorOptions = {
65
65
  ref?: string;
66
66
  };
67
67
  oxlint?: string;
68
+ /** Run these checks and no other — one question, asked fast, belongs in a sub-second gate. */
69
+ only?: CheckName[];
68
70
  root: string;
69
71
  strict?: boolean;
70
72
  };
@@ -124,7 +126,7 @@ declare const discoverConfigs: (root: string) => DiscoveredConfig[];
124
126
  declare const discoverWorkspaces: (root: string) => Workspace[];
125
127
  declare const readRatchet: (root: string) => RatchetConfig | undefined;
126
128
 
127
- declare const runDoctor: ({ baseline, oxlint, root, strict, }: DoctorOptions) => Promise<DoctorReport>;
129
+ declare const runDoctor: ({ baseline, only, oxlint, root, strict, }: DoctorOptions) => Promise<DoctorReport>;
128
130
 
129
131
  /** Which kit package reads which block of `geonosis.json`. */
130
132
  declare const READERS: Record<string, string>;
package/dist/index.js CHANGED
@@ -34,7 +34,7 @@ import {
34
34
  resolveFrom,
35
35
  runDoctor,
36
36
  satisfies
37
- } from "./chunk-CG2LN4VW.js";
37
+ } from "./chunk-ZJCUTDQW.js";
38
38
  export {
39
39
  CHECKS,
40
40
  CONFIG_FILE,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geonosis/doctor",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "types": "./dist/index.d.ts",
5
5
  "description": "The adoption doctor — declared ≠ loaded, enabled ≠ exercised, a baseline that grew, a runner whose exit code is the only verdict.",
6
6
  "keywords": [
@@ -35,7 +35,7 @@
35
35
  "dist"
36
36
  ],
37
37
  "dependencies": {
38
- "@geonosis/lint-parity": "1.1.0"
38
+ "@geonosis/lint-parity": "1.2.0"
39
39
  },
40
40
  "peerDependencies": {
41
41
  "oxlint": ">=1.77"