@geonosis/doctor 1.4.0 → 2.1.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.
@@ -1,12 +1,99 @@
1
1
  import {
2
2
  CHECKS,
3
+ ENVELOPES_DIR,
3
4
  formatDoctor,
4
5
  formatJson,
5
6
  runDoctor
6
- } from "./chunk-R4OLFNI6.js";
7
+ } from "./chunk-R2R2OYH3.js";
7
8
 
8
9
  // src/doctor-cli.ts
10
+ import { fstatSync, statSync } from "fs";
9
11
  import { resolve } from "path";
12
+
13
+ // src/envelope-write.ts
14
+ import { mkdirSync, readFileSync, writeFileSync } from "fs";
15
+ import { dirname, join } from "path";
16
+ import { fileURLToPath } from "url";
17
+ var envelopePath = (root, tool) => join(root, ENVELOPES_DIR, `${tool}.json`);
18
+ var UnbalancedEnvelope = class extends Error {
19
+ constructor(message) {
20
+ super(message);
21
+ this.name = "UnbalancedEnvelope";
22
+ }
23
+ };
24
+ var isCount = (value) => Number.isSafeInteger(value) && value >= 0;
25
+ var unbalancedMessage = (envelope, next) => `${envelope.tool}: considered ${envelope.considered} but accounts for ${envelope.read + envelope.refused.length + envelope.excused.length} \u2014 ${envelope.read} read + ${envelope.refused.length} refused + ${envelope.excused.length} excused. A run that has lost count of its own inputs cannot say what it measured, so no verdict was rendered and no envelope was written. Next: ${next}`;
26
+ var writeEnvelope = ({
27
+ envelope,
28
+ next,
29
+ root
30
+ }) => {
31
+ if (envelope.tool.trim() === "") {
32
+ throw new UnbalancedEnvelope(
33
+ `an envelope with no tool name cannot be filed or reported against. Next: ${next}`
34
+ );
35
+ }
36
+ if (envelope.version.trim() === "") {
37
+ throw new UnbalancedEnvelope(
38
+ `${envelope.tool}: an envelope that cannot name the build that wrote it dates nothing, and a stale one reads exactly like a fresh one. Next: ${next}`
39
+ );
40
+ }
41
+ if (!isCount(envelope.considered) || !isCount(envelope.read)) {
42
+ throw new UnbalancedEnvelope(
43
+ `${envelope.tool}: considered ${envelope.considered} and read ${envelope.read} \u2014 a census is a whole number of things, and arithmetic over anything else balances by accident. Next: ${next}`
44
+ );
45
+ }
46
+ if (envelope.considered !== envelope.read + envelope.refused.length + envelope.excused.length) {
47
+ throw new UnbalancedEnvelope(unbalancedMessage(envelope, next));
48
+ }
49
+ const at = envelopePath(root, envelope.tool);
50
+ mkdirSync(dirname(at), { recursive: true });
51
+ writeFileSync(at, `${JSON.stringify(envelope, void 0, 2)}
52
+ `);
53
+ return at;
54
+ };
55
+ var UNKNOWN = "unknown";
56
+ var versionIn = (dir) => {
57
+ try {
58
+ const manifest = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
59
+ return typeof manifest.version === "string" ? manifest.version : void 0;
60
+ } catch {
61
+ return void 0;
62
+ }
63
+ };
64
+ var versionOf = (moduleUrl) => {
65
+ let dir = dirname(fileURLToPath(moduleUrl));
66
+ for (; ; ) {
67
+ const found = versionIn(dir);
68
+ if (found !== void 0) return found;
69
+ const up = dirname(dir);
70
+ if (up === dir) return UNKNOWN;
71
+ dir = up;
72
+ }
73
+ };
74
+ var DOCTOR_TOOL = "doctor";
75
+ var DOCTOR_NEXT = "geonosis-doctor --json and count the checks it printed \u2014 this run considered every question the tool has, and a check nobody asked for is excused by name rather than left out of the denominator";
76
+ var doctorEnvelope = ({
77
+ durationMs,
78
+ report
79
+ }) => {
80
+ const ran = new Set(report.ran);
81
+ return {
82
+ considered: CHECKS.length,
83
+ durationMs,
84
+ excused: CHECKS.filter((check) => !ran.has(check)).map((check) => ({
85
+ path: check,
86
+ reason: "not asked for by --only, so this run says nothing about it"
87
+ })),
88
+ findings: report.findings,
89
+ read: report.ran.length,
90
+ refused: [],
91
+ tool: DOCTOR_TOOL,
92
+ version: versionOf(import.meta.url)
93
+ };
94
+ };
95
+
96
+ // src/doctor-cli.ts
10
97
  var ABOUT = {
11
98
  baseline: `The ratchet's numbers at HEAD against another ref. A ratchet lowers its own baseline
12
99
  when a number shrinks, so nothing inside one checkout can see a branch raise one back
@@ -21,8 +108,9 @@ var ABOUT = {
21
108
  drift: `The gates that were set up and are no longer running: a CI job switched off by a
22
109
  condition that can never be true, a test file under a workspace with no test script, a
23
110
  script handing bun/node/tsx a file that is not on disk, a workspace bin nothing links,
24
- an integration directory the registry never names, a geonosis bin a git hook calls
25
- through pnpm/npx/bunx and therefore cannot start, a law over the ceiling its own
111
+ an integration directory the registry never names, a package lint script narrower
112
+ than the hook beside it, an allowBuilds entry naming one platform of a split package,
113
+ an observability package nothing composes, a law over the ceiling its own
26
114
  geonosis.json declared, nothing enabling the plugin in either scope, and a
27
115
  geonosis.json block no manifest declares a package for (or the reverse).`,
28
116
  envelope: `The arithmetic under every other line: for each .geonosis/envelopes/<tool>.json a gate
@@ -33,22 +121,46 @@ var ABOUT = {
33
121
  denominator. Reads the files and imports nothing of the tools that wrote them; no
34
122
  envelopes at all is a SKIP with the sentence.`,
35
123
  exercised: `Every rule a config enables, against the corpus the loaded plugin ships. A rule at
36
- "error" that can never fire is indistinguishable from a clean tree.`,
124
+ "error" that can never fire is indistinguishable from a clean tree. The line says what
125
+ its number is evidence ABOUT \u2014 the corpus and the probes, never this tree \u2014 and a rule
126
+ that PRESUMES an engine no manifest here declares is a WARN of its own: enabled where
127
+ the engine is absent it has no possible finding, which is the same green.`,
128
+ group: `The packages that are published on ONE version, asked of every workspace: one copy
129
+ repo-wide, and one number per workspace. A consumer carried @geonosis/visual-diff at
130
+ 1.1.0 and 1.4.0 in one tree while every other line read green, because they are all
131
+ scoped to the plugin a config names. Membership ships with the kit; a repo declares
132
+ its OWN held-together sets under doctor.groups in geonosis.json. Asked of the
133
+ resolver, never of find, and UNJUDGED when the tree installs none of the group.
134
+ It also reads what the ROOT declares: the door (@geonosis/cli, or the geonosis
135
+ metapackage) plus the bins the root's own scripts call by name, and nothing the door
136
+ already owns.`,
37
137
  loaded: `The plugin oxlint would LOAD from each config's directory, against the version that
38
138
  config's workspace DECLARES. oxlint resolves a jsPlugins specifier from the CONFIG
39
139
  FILE's directory, so a nested copy left behind by a per-workspace install runs while
40
140
  every manifest and the lockfile say otherwise \u2014 one consumer measured a whole bug
41
141
  report against 0.3.0 on a repo pinned to 0.4.0. Every copy is found by RESOLUTION,
42
- never by find: on pnpm the store keeps every version ever installed.`,
142
+ never by find: on pnpm the store keeps every version ever installed. It also reads
143
+ every committed git hook: a geonosis bin called through pnpm/npx/bunx cannot START,
144
+ because a hook's PATH carries no version-manager shim.`,
43
145
  observability: `The exporter named by the "observability" block in geonosis.json: is a sink
44
146
  configured, is its endpoint reachable (a HEAD with a short timeout), and did an event
45
147
  arrive inside maxAgeSeconds \u2014 read from the lastEventFile the sink writes, never from
46
148
  this tool importing the library it is checking. A deploy job reported success having
47
149
  deployed nothing and a /health answered ok over a dead database on the same
48
150
  afternoon; both left a green build and a silent project.`,
151
+ rails: `The egress an unattended run is bounded by, read back out of the settings that
152
+ actually LOAD rather than out of the file this repo rendered \u2014 D-038 one file over.
153
+ Claude Code merges sandbox.network.allowedDomains across the managed, user, project
154
+ and local scopes, and two measured things make a perfect render load as nothing: a
155
+ settings file that fails validation is SILENTLY ignored under -p, and a managed
156
+ allowManagedDomainsOnly makes every other scope's allow list ignored. deniedEgress in
157
+ .geonosis/rails-run.json is a GATE AT ZERO (D-025): one denied attempt fails, and it
158
+ is never a counter to hold flat.`,
49
159
  runner: `Workspaces whose test script's exit code is the only verdict. A pool exited 0 over
50
160
  suites it had just reported as failing, for weeks, in a consumer. A script with no
51
- test file under it is a SKIP \u2014 there is no result for an exit code to be wrong about.`
161
+ test file under it is a SKIP \u2014 there is no result for an exit code to be wrong about.
162
+ And whether anything here ever runs geonosis-ratchet --prove: a counter that has
163
+ never been seen reading its own planted finding reads exactly like a clean tree.`
52
164
  };
53
165
  var USAGE = `geonosis-doctor [--root <dir>] [--only <check,\u2026>] [--json] [--strict] [--baseline-against [<ref>]] [--oxlint <path>]
54
166
 
@@ -69,6 +181,10 @@ plugin-route-namespaced on its package root, while the shipped corpus says acme
69
181
 
70
182
  --print-config-shape every file this reads, and the keys it reads out of each
71
183
 
184
+ Every run writes .geonosis/envelopes/doctor.json: the ten checks CONSIDERED against the ones this
185
+ run read, with the rest excused by name, so a --only run can never read as a verdict about the whole
186
+ tree. The envelope check SKIPs that one file \u2014 this run is the one writing it.
187
+
72
188
  Exits 1 when any line is a FAIL or an UNJUDGED \u2014 a question this could not ask is not a pass \u2014 and
73
189
  2 when the run could not be made at all. --strict promotes every WARN to a FAIL. --json prints the
74
190
  whole report for a CI step to read.`;
@@ -115,11 +231,16 @@ var parseDoctorArgs = (argv, cwd) => {
115
231
  };
116
232
  };
117
233
  var CONFIG_SHAPE = `geonosis-doctor reads geonosis.json, geonosis.ratchet.json, .oxlintrc.json,
118
- pnpm-workspace.yaml and .claude/settings.json
234
+ pnpm-workspace.yaml, .claude/settings.json and this repo's committed git hooks
119
235
 
120
236
  geonosis.json \u2192 "law"
121
237
  file string? the law file to measure (default "CLAUDE.md")
122
238
  maxLines number? the ceiling. Undeclared means UNJUDGED, never a default it fires on
239
+ geonosis.json \u2192 "doctor"
240
+ corpus string? the reach corpus this repo ships for its own rule options
241
+ groups object[]? { name, packages } sets of this repo's OWN packages that must resolve
242
+ to one version; declared and empty is a refusal. The kit's own fixed
243
+ group is checked when this is absent
123
244
  geonosis.json \u2192 "observability"
124
245
  sink string where this repo sends its errors
125
246
  endpoint string the URL that must be reachable
@@ -140,8 +261,31 @@ geonosis.ratchet.json
140
261
  pnpm-workspace.yaml
141
262
  publicHoistPattern string[] the packages this repo claims are linked at the root, read as
142
263
  text; a "*" is the only wildcard and it spans "/"
143
- .claude/settings.json
144
- enabledPlugins object what installs the kit's plugin in THIS repo`;
264
+ lefthook.yml, .lefthook.yml, .husky/*, .githooks/*
265
+ every line, as text a geonosis bin run through pnpm/npx/bunx cannot START from a hook
266
+ geonosis.json \u2192 "rails.egress"
267
+ allow string[] the hosts an unattended run may reach. The rails line reads each one
268
+ back out of the settings that actually LOAD, never out of the file
269
+ this repo rendered
270
+ deny string[] the hosts it may never reach
271
+ .claude/settings.json, .claude/settings.local.json, ~/.claude/settings.json,
272
+ /Library/Application Support/ClaudeCode/managed-settings.json (/etc/claude-code on Linux)
273
+ enabledPlugins object what installs the kit's plugin in THIS repo
274
+ sandbox.network.allowedDomains string[] merged across every scope above; a managed
275
+ allowManagedDomainsOnly makes every other scope's list ignored
276
+ sandbox.network.deniedDomains string[] what this repo renders its deny list into
277
+ .geonosis/rails-run.json
278
+ deniedEgress object[] what a run reached for and was refused. A GATE AT ZERO (D-025): one
279
+ entry fails, and it is never a counter to hold flat`;
280
+ var sameFile = (fd, path) => {
281
+ try {
282
+ const open = fstatSync(fd);
283
+ const there = statSync(path);
284
+ return open.dev === there.dev && open.ino === there.ino;
285
+ } catch {
286
+ return false;
287
+ }
288
+ };
145
289
  var main = async () => {
146
290
  const argv = process.argv.slice(2);
147
291
  if (argv.includes("--help") || argv.includes("-h")) {
@@ -155,7 +299,21 @@ var main = async () => {
155
299
  return 0;
156
300
  }
157
301
  const { json, ...options } = parseDoctorArgs(argv, process.cwd());
302
+ const started = Date.now();
158
303
  const report = await runDoctor(options);
304
+ const at = envelopePath(options.root, "doctor");
305
+ if (sameFile(process.stdout.fd, at)) {
306
+ process.stderr.write(
307
+ `geonosis-doctor: stdout is ${ENVELOPES_DIR}/doctor.json, so no envelope was written \u2014 it would have overwritten the report redirected there. Send --json somewhere else and the envelope is written after every run.
308
+ `
309
+ );
310
+ } else {
311
+ writeEnvelope({
312
+ envelope: doctorEnvelope({ durationMs: Date.now() - started, report }),
313
+ next: DOCTOR_NEXT,
314
+ root: options.root
315
+ });
316
+ }
159
317
  process.stdout.write(json ? formatJson(report) : formatDoctor(report));
160
318
  return report.ok ? 0 : 1;
161
319
  };
package/dist/index.d.ts CHANGED
@@ -5,12 +5,13 @@ type Overrides = {
5
5
 
6
6
  /**
7
7
  * The questions a bump is not finished until something has asked, in the order a run asks them.
8
- * The first four are ways enforcement has reported green while measuring nothing; `envelope` asks
8
+ * The first five are ways enforcement has reported green while measuring nothing; `envelope` asks
9
9
  * the arithmetic underneath all of them — whether a gate read as many things as it was handed;
10
10
  * `drift` asks whether the gate is still there at all; `observability` and `deployed` ask the same
11
- * question one layer out — whether what was reported is what happened.
11
+ * question one layer out — whether what was reported is what happened; `rails` asks it of the
12
+ * settings an unattended run is bounded by, where a rendered file is not a loaded setting.
12
13
  */
13
- declare const CHECKS: readonly ["loaded", "exercised", "baseline", "runner", "envelope", "drift", "observability", "deployed"];
14
+ declare const CHECKS: readonly ["loaded", "group", "exercised", "baseline", "runner", "envelope", "drift", "observability", "deployed", "rails"];
14
15
  type CheckName = (typeof CHECKS)[number];
15
16
  /**
16
17
  * `SKIP` is a first-class answer and is printed like any other: a check whose line is missing reads
@@ -82,6 +83,8 @@ type DoctorOptions = {
82
83
  type DoctorReport = {
83
84
  counts: Record<Verdict, number>;
84
85
  findings: Finding[];
86
+ /** The checks this run asked. `--only` makes it a subset, and the envelope's denominator needs it. */
87
+ ran: CheckName[];
85
88
  /**
86
89
  * False as soon as one line is a FAIL or an UNJUDGED — after `--strict` has promoted the
87
90
  * warnings. "We could not tell" is not a pass; it is the quietest way there is of reading green.
@@ -137,6 +140,14 @@ declare const readRatchet: (root: string) => RatchetConfig | undefined;
137
140
 
138
141
  declare const runDoctor: ({ baseline, only, oxlint, root, strict, }: DoctorOptions) => Promise<DoctorReport>;
139
142
 
143
+ /** The file `create-geonosis --domains` writes, held against the scaffold's own name by a test. */
144
+ declare const COMPOSITION_ROOT = "src/platform.ts";
145
+ /**
146
+ * The floors, as data a consumer's tree can read — the same reason `FIXED_GROUP` ships as a list: a
147
+ * consumer has none of the kit's workspace globs to glob. `tooling/group-membership.test.ts` holds
148
+ * it against the workspace, so a foundation or a domain added tomorrow cannot arrive unasked.
149
+ */
150
+ declare const FLOOR_PACKAGES: readonly string[];
140
151
  /** Which kit package reads which block of `geonosis.json`. */
141
152
  declare const READERS: Record<string, string>;
142
153
  /**
@@ -180,7 +191,7 @@ declare const checkDrift: ({ readers, root, userSettings, workspaces, }: {
180
191
  * duplicated here on purpose: it is one comparison over three numbers, and it is the check.
181
192
  */
182
193
  declare const ENVELOPES_DIR = ".geonosis/envelopes";
183
- declare const NO_ENVELOPES = "no .geonosis/envelopes/*.json \u2014 the tools write one per run, so an absent envelope is a run nobody has made here yet, and it is not a balanced one";
194
+ declare const NO_ENVELOPES = "no .geonosis/envelopes/*.json \u2014 the tools write one per run, so an absent envelope is a run nobody has made here yet, and it is not a balanced one (this run\u2019s own doctor.json is not one of them: it is written after these checks, and balanced at write time)";
184
195
  declare const checkEnvelopes: ({ root }: {
185
196
  root: string;
186
197
  }) => Finding[];
@@ -209,6 +220,51 @@ declare const checkExercised: ({ config, corpus, entry, oxlint, repoCorpus, root
209
220
  root: string;
210
221
  }) => Promise<Finding>;
211
222
 
223
+ /**
224
+ * The packages that version as ONE number — the kit's method floor, as data a consumer's tree can
225
+ * read.
226
+ *
227
+ * It ships here rather than being derived where it is decided: a consumer has no
228
+ * `.changeset/config.json` and no workspace globs of the kit to glob, so the only form of this fact
229
+ * that survives an install is a list inside a published package. `tooling/group-membership.test.ts`
230
+ * holds it against the workspace and against every other door that names the group, so the list
231
+ * cannot drift from the floors it describes.
232
+ *
233
+ * Foundations and domains are absent on purpose (D-053): a floor package moves on a line of its
234
+ * own, and asking it to match this number would be the cadence coupling the floors exist to end.
235
+ */
236
+ declare const FIXED_GROUP: readonly string[];
237
+ /** A set of packages a repo declares must move together. The kit's own is the default. */
238
+ type HeldTogether = {
239
+ name: string;
240
+ packages: readonly string[];
241
+ };
242
+ declare const KIT_GROUP: HeldTogether;
243
+ /**
244
+ * The groups a repo declares for its OWN packages, under `doctor.groups` in `geonosis.json`. Law 6:
245
+ * the kit's group is the default and a repo that declares nothing gets it; a repo that declares the
246
+ * key and puts nothing in it is REFUSED, because "two copies are a bug" is a claim someone made and
247
+ * an empty list cannot hold it.
248
+ */
249
+ declare const declaredGroupsOf: (root: string) => HeldTogether[] | undefined;
250
+ /**
251
+ * #158 — the group question nothing asked.
252
+ *
253
+ * during.day carried `@geonosis/visual-diff` at 1.1.0 and 1.4.0 in one tree and every doctor line
254
+ * was green: `loaded` is scoped to the plugin a config names, so a second kit package at a second
255
+ * version is outside every question it asks. This is the consumer-side mirror of
256
+ * `geonosis-release published --group`.
257
+ *
258
+ * Asked of the RESOLVER from each workspace directory, never of `find` over `node_modules` — on
259
+ * pnpm the store keeps every version ever installed, so a count of directories answers nonsense on
260
+ * a correct tree.
261
+ */
262
+ declare const checkGroup: ({ groups, root, workspaces, }: {
263
+ groups?: readonly HeldTogether[];
264
+ root: string;
265
+ workspaces: Workspace[];
266
+ }) => Finding[];
267
+
212
268
  /** The scope this tool asks about. A config's other plugins are somebody else's release to check. */
213
269
  declare const SCOPE = "@geonosis/";
214
270
  /**
@@ -308,9 +364,10 @@ declare const relativeToRoot: (root: string, path: string) => string;
308
364
  * a WARN that names the wrong runner's sin is a line a reader learns to skip, and the lines it
309
365
  * teaches them to skip are the true ones next to it.
310
366
  */
311
- declare const checkRunner: ({ ratchet, workspaces, }: {
367
+ declare const checkRunner: ({ ratchet, root, workspaces, }: {
312
368
  ratchet?: RatchetConfig;
369
+ root: string;
313
370
  workspaces: Workspace[];
314
371
  }) => Finding[];
315
372
 
316
- export { CHECKS, CONFIG_FILE, type CheckName, DEPLOYED_FILE, type DiscoveredConfig, DoctorError, type DoctorOptions, type DoctorReport, ENVELOPES_DIR, type Finding, GEONOSIS_FILE, type LastEventRecord, MANIFEST_FILE, type Manifest, NOT_WRITTEN, NO_ENVELOPES, type ObservabilityConfig, RATCHET_FILE, READERS, type RatchetConfig, SCOPE, type Verdict, type Workspace, checkBaseline, checkDeployed, checkDrift, checkEnvelopes, checkExercised, checkLoaded, checkObservability, checkRunner, corpusOfPlugin, declaredFor, defaultRef, discoverConfigs, discoverWorkspaces, enabledRulesOf, formatDoctor, formatJson, packageDirOf, pluginVersionOf, readConfig, readRatchet, relativePath, relativeToRoot, repoCorpusOf, resolveFrom, runDoctor, satisfies };
373
+ export { CHECKS, COMPOSITION_ROOT, CONFIG_FILE, type CheckName, DEPLOYED_FILE, type DiscoveredConfig, DoctorError, type DoctorOptions, type DoctorReport, ENVELOPES_DIR, FIXED_GROUP, FLOOR_PACKAGES, type Finding, GEONOSIS_FILE, type HeldTogether, KIT_GROUP, type LastEventRecord, MANIFEST_FILE, type Manifest, NOT_WRITTEN, NO_ENVELOPES, type ObservabilityConfig, RATCHET_FILE, READERS, type RatchetConfig, SCOPE, type Verdict, type Workspace, checkBaseline, checkDeployed, checkDrift, checkEnvelopes, checkExercised, checkGroup, checkLoaded, checkObservability, checkRunner, corpusOfPlugin, declaredFor, declaredGroupsOf, defaultRef, discoverConfigs, discoverWorkspaces, enabledRulesOf, formatDoctor, formatJson, packageDirOf, pluginVersionOf, readConfig, readRatchet, relativePath, relativeToRoot, repoCorpusOf, resolveFrom, runDoctor, satisfies };
package/dist/index.js CHANGED
@@ -1,10 +1,14 @@
1
1
  import {
2
2
  CHECKS,
3
+ COMPOSITION_ROOT,
3
4
  CONFIG_FILE,
4
5
  DEPLOYED_FILE,
5
6
  DoctorError,
6
7
  ENVELOPES_DIR,
8
+ FIXED_GROUP,
9
+ FLOOR_PACKAGES,
7
10
  GEONOSIS_FILE,
11
+ KIT_GROUP,
8
12
  MANIFEST_FILE,
9
13
  NOT_WRITTEN,
10
14
  NO_ENVELOPES,
@@ -16,11 +20,13 @@ import {
16
20
  checkDrift,
17
21
  checkEnvelopes,
18
22
  checkExercised,
23
+ checkGroup,
19
24
  checkLoaded,
20
25
  checkObservability,
21
26
  checkRunner,
22
27
  corpusOfPlugin,
23
28
  declaredFor,
29
+ declaredGroupsOf,
24
30
  defaultRef,
25
31
  discoverConfigs,
26
32
  discoverWorkspaces,
@@ -37,14 +43,18 @@ import {
37
43
  resolveFrom,
38
44
  runDoctor,
39
45
  satisfies
40
- } from "./chunk-R4OLFNI6.js";
46
+ } from "./chunk-R2R2OYH3.js";
41
47
  export {
42
48
  CHECKS,
49
+ COMPOSITION_ROOT,
43
50
  CONFIG_FILE,
44
51
  DEPLOYED_FILE,
45
52
  DoctorError,
46
53
  ENVELOPES_DIR,
54
+ FIXED_GROUP,
55
+ FLOOR_PACKAGES,
47
56
  GEONOSIS_FILE,
57
+ KIT_GROUP,
48
58
  MANIFEST_FILE,
49
59
  NOT_WRITTEN,
50
60
  NO_ENVELOPES,
@@ -56,11 +66,13 @@ export {
56
66
  checkDrift,
57
67
  checkEnvelopes,
58
68
  checkExercised,
69
+ checkGroup,
59
70
  checkLoaded,
60
71
  checkObservability,
61
72
  checkRunner,
62
73
  corpusOfPlugin,
63
74
  declaredFor,
75
+ declaredGroupsOf,
64
76
  defaultRef,
65
77
  discoverConfigs,
66
78
  discoverWorkspaces,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geonosis/doctor",
3
- "version": "1.4.0",
3
+ "version": "2.1.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,10 @@
35
35
  "dist"
36
36
  ],
37
37
  "dependencies": {
38
- "@geonosis/lint-parity": "1.4.0"
38
+ "@geonosis/lint-parity": "2.1.0"
39
+ },
40
+ "devDependencies": {
41
+ "@geonosis/ratchet": "2.1.0"
39
42
  },
40
43
  "peerDependencies": {
41
44
  "oxlint": ">=1.77"