@geonosis/doctor 1.0.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/LICENSE +202 -0
- package/README.md +167 -0
- package/bin/geonosis-doctor.mjs +4 -0
- package/dist/chunk-R4AHDFE3.js +1122 -0
- package/dist/doctor-cli.js +109 -0
- package/dist/index.d.ts +255 -0
- package/dist/index.js +68 -0
- package/package.json +49 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatDoctor,
|
|
3
|
+
formatJson,
|
|
4
|
+
runDoctor
|
|
5
|
+
} from "./chunk-R4AHDFE3.js";
|
|
6
|
+
|
|
7
|
+
// src/doctor-cli.ts
|
|
8
|
+
import { resolve } from "path";
|
|
9
|
+
var USAGE = `geonosis-doctor [--root <dir>] [--json] [--strict] [--baseline-against [<ref>]] [--oxlint <path>]
|
|
10
|
+
|
|
11
|
+
Five questions a version bump is not finished until something has asked. The first four are ways
|
|
12
|
+
enforcement has reported green while measuring nothing; the fifth asks whether it is still there.
|
|
13
|
+
|
|
14
|
+
loaded The plugin oxlint would LOAD from each config's directory, against the version that
|
|
15
|
+
config's workspace DECLARES. oxlint resolves a jsPlugins specifier from the CONFIG
|
|
16
|
+
FILE's directory, so a nested copy left behind by a per-workspace install runs while
|
|
17
|
+
every manifest and the lockfile say otherwise \u2014 one consumer measured a whole bug
|
|
18
|
+
report against 0.3.0 on a repo pinned to 0.4.0. Every copy is found by RESOLUTION,
|
|
19
|
+
never by find: on pnpm the store keeps every version ever installed.
|
|
20
|
+
|
|
21
|
+
exercised Every rule a config enables, against the corpus the loaded plugin ships. A rule at
|
|
22
|
+
"error" that can never fire is indistinguishable from a clean tree.
|
|
23
|
+
|
|
24
|
+
baseline The ratchet's numbers at HEAD against another ref. A ratchet lowers its own baseline
|
|
25
|
+
when a number shrinks, so nothing inside one checkout can see a branch raise one back
|
|
26
|
+
up. OFF unless asked for: it is the only check that runs git, and this tool is run
|
|
27
|
+
over repos other people are working in.
|
|
28
|
+
|
|
29
|
+
runner Workspaces whose test script's exit code is the only verdict. A pool exited 0 over
|
|
30
|
+
suites it had just reported as failing, for weeks, in a consumer.
|
|
31
|
+
|
|
32
|
+
observability
|
|
33
|
+
The exporter named by the "observability" block in geonosis.json: is a sink
|
|
34
|
+
configured, is its endpoint reachable (a HEAD with a short timeout), and did an event
|
|
35
|
+
arrive inside maxAgeSeconds \u2014 read from the lastEventFile the sink writes, never from
|
|
36
|
+
this tool importing the library it is checking. A deploy job reported success having
|
|
37
|
+
deployed nothing and a /health answered ok over a dead database on the same
|
|
38
|
+
afternoon; both left a green build and a silent project.
|
|
39
|
+
drift The gates that were set up and are no longer running: a CI job switched off by a
|
|
40
|
+
condition that can never be true, a test file under a workspace with no test script,
|
|
41
|
+
an integration directory the registry never names, a law over the ceiling its own
|
|
42
|
+
geonosis.json set, no .claude/settings.json installing the plugin, and a
|
|
43
|
+
geonosis.json block whose package is not installed (or the reverse).
|
|
44
|
+
|
|
45
|
+
exercised reads the corpus the loaded plugin ships, and \u2014 when geonosis.json names one under
|
|
46
|
+
doctor.corpus \u2014 the corpus THIS repo ships for its own options. Three rules cannot be answered any
|
|
47
|
+
other way: layer-walls fires on a repo's own layer names, no-brand-names on its brand, and
|
|
48
|
+
plugin-route-namespaced on its package root, while the shipped corpus says acme and layers/core.
|
|
49
|
+
|
|
50
|
+
Exits 1 when any line is a FAIL, 2 when the run could not be made at all. --strict promotes every
|
|
51
|
+
WARN to a FAIL. --json prints the whole report for a CI step to read.`;
|
|
52
|
+
var VALUED = /* @__PURE__ */ new Set(["--oxlint", "--root"]);
|
|
53
|
+
var parseDoctorArgs = (argv, cwd) => {
|
|
54
|
+
const read = {};
|
|
55
|
+
let baseline;
|
|
56
|
+
let json = false;
|
|
57
|
+
let strict = false;
|
|
58
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
59
|
+
const flag = argv[index] ?? "";
|
|
60
|
+
const value = argv[index + 1];
|
|
61
|
+
if (flag === "--json") {
|
|
62
|
+
json = true;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (flag === "--strict") {
|
|
66
|
+
strict = true;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (flag === "--baseline-against") {
|
|
70
|
+
const named = value === void 0 || value.startsWith("--") ? void 0 : value;
|
|
71
|
+
baseline = { ref: named };
|
|
72
|
+
if (named !== void 0) index += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (!VALUED.has(flag)) throw new Error(`unknown argument "${flag}"`);
|
|
76
|
+
if (value === void 0 || value.startsWith("--")) throw new Error(`${flag} needs a value`);
|
|
77
|
+
read[flag] = value;
|
|
78
|
+
index += 1;
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
...baseline === void 0 ? {} : { baseline },
|
|
82
|
+
json,
|
|
83
|
+
...read["--oxlint"] === void 0 ? {} : { oxlint: resolve(cwd, read["--oxlint"]) },
|
|
84
|
+
root: resolve(cwd, read["--root"] ?? cwd),
|
|
85
|
+
strict
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
var main = async () => {
|
|
89
|
+
const argv = process.argv.slice(2);
|
|
90
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
91
|
+
process.stdout.write(`${USAGE}
|
|
92
|
+
`);
|
|
93
|
+
return 0;
|
|
94
|
+
}
|
|
95
|
+
const { json, ...options } = parseDoctorArgs(argv, process.cwd());
|
|
96
|
+
const report = await runDoctor(options);
|
|
97
|
+
process.stdout.write(json ? formatJson(report) : formatDoctor(report));
|
|
98
|
+
return report.ok ? 0 : 1;
|
|
99
|
+
};
|
|
100
|
+
try {
|
|
101
|
+
process.exit(await main());
|
|
102
|
+
} catch (error) {
|
|
103
|
+
process.stderr.write(`geonosis-doctor: ${error.message}
|
|
104
|
+
`);
|
|
105
|
+
process.exit(2);
|
|
106
|
+
}
|
|
107
|
+
export {
|
|
108
|
+
parseDoctorArgs
|
|
109
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The five questions a bump is not finished until something has asked, in the order a run asks
|
|
3
|
+
* them. The first four are ways enforcement has reported green while measuring nothing; the fifth
|
|
4
|
+
* asks whether the gate is still there at all.
|
|
5
|
+
*/
|
|
6
|
+
declare const CHECKS: readonly ["loaded", "exercised", "baseline", "runner", "drift", "observability"];
|
|
7
|
+
type CheckName = (typeof CHECKS)[number];
|
|
8
|
+
/**
|
|
9
|
+
* `SKIP` is a first-class answer and is printed like any other: a check whose line is missing reads
|
|
10
|
+
* as a check that passed, and that is the failure this whole package is about.
|
|
11
|
+
*/
|
|
12
|
+
type Verdict = 'FAIL' | 'OK' | 'SKIP' | 'WARN';
|
|
13
|
+
type Finding = {
|
|
14
|
+
check: CheckName;
|
|
15
|
+
message: string;
|
|
16
|
+
/** The config, manifest, baseline or plugin this line is about, relative to the root. */
|
|
17
|
+
subject: string;
|
|
18
|
+
verdict: Verdict;
|
|
19
|
+
};
|
|
20
|
+
/** A question that could not be asked at all. Never a verdict — a refusal. */
|
|
21
|
+
declare class DoctorError extends Error {
|
|
22
|
+
constructor(message: string);
|
|
23
|
+
}
|
|
24
|
+
type Manifest = {
|
|
25
|
+
dependencies?: Record<string, string>;
|
|
26
|
+
devDependencies?: Record<string, string>;
|
|
27
|
+
name?: string;
|
|
28
|
+
optionalDependencies?: Record<string, string>;
|
|
29
|
+
peerDependencies?: Record<string, string>;
|
|
30
|
+
scripts?: Record<string, string>;
|
|
31
|
+
};
|
|
32
|
+
type Workspace = {
|
|
33
|
+
dir: string;
|
|
34
|
+
manifest: Manifest;
|
|
35
|
+
/** Relative to the root, `/`-separated; the root workspace is the empty string. */
|
|
36
|
+
relative: string;
|
|
37
|
+
};
|
|
38
|
+
type DiscoveredConfig = {
|
|
39
|
+
dir: string;
|
|
40
|
+
/** Why this config could not be read. A config nobody can parse is a finding, never a skip. */
|
|
41
|
+
error?: string;
|
|
42
|
+
jsPlugins: string[];
|
|
43
|
+
path: string;
|
|
44
|
+
relative: string;
|
|
45
|
+
rules: Record<string, unknown>;
|
|
46
|
+
};
|
|
47
|
+
type RatchetConfig = {
|
|
48
|
+
baseline: string;
|
|
49
|
+
counters: Record<string, unknown>[];
|
|
50
|
+
};
|
|
51
|
+
type DoctorOptions = {
|
|
52
|
+
/**
|
|
53
|
+
* Present only when a baseline comparison was asked for, because making one is the one part of
|
|
54
|
+
* this tool that runs git — and the release check runs the doctor inside repos other sessions
|
|
55
|
+
* are working in. `ref` absent means `origin/main` if the repo has one.
|
|
56
|
+
*/
|
|
57
|
+
baseline?: {
|
|
58
|
+
ref?: string;
|
|
59
|
+
};
|
|
60
|
+
oxlint?: string;
|
|
61
|
+
root: string;
|
|
62
|
+
strict?: boolean;
|
|
63
|
+
};
|
|
64
|
+
type DoctorReport = {
|
|
65
|
+
counts: Record<Verdict, number>;
|
|
66
|
+
findings: Finding[];
|
|
67
|
+
/** False as soon as one line is a FAIL — after `--strict` has promoted the warnings. */
|
|
68
|
+
ok: boolean;
|
|
69
|
+
root: string;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* `origin/main`, when the repo has one. Never invented: a comparison against a ref that is not
|
|
74
|
+
* there would either crash or, worse, be reported as a comparison that found nothing.
|
|
75
|
+
*/
|
|
76
|
+
declare const defaultRef: (root: string) => string | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* The rail a PreToolUse guard never was.
|
|
79
|
+
*
|
|
80
|
+
* A ratchet lowers its OWN baseline whenever a number shrinks, which is what locks a win in — and
|
|
81
|
+
* it is also what lets a branch write any number it likes and stay green on every gate it runs.
|
|
82
|
+
* Nothing inside one checkout can tell the difference. Only the same file at another ref can.
|
|
83
|
+
*/
|
|
84
|
+
declare const checkBaseline: ({ ref, root }: {
|
|
85
|
+
ref: string;
|
|
86
|
+
root: string;
|
|
87
|
+
}) => Finding[];
|
|
88
|
+
|
|
89
|
+
declare const CONFIG_FILE = ".oxlintrc.json";
|
|
90
|
+
declare const MANIFEST_FILE = "package.json";
|
|
91
|
+
declare const RATCHET_FILE = "geonosis.ratchet.json";
|
|
92
|
+
/** `/`-separated, so a subject reads the same on every platform and sorts the way a path should. */
|
|
93
|
+
declare const relativePath: (root: string, path: string) => string;
|
|
94
|
+
declare const readConfig: (path: string, root: string) => DiscoveredConfig;
|
|
95
|
+
declare const discoverConfigs: (root: string) => DiscoveredConfig[];
|
|
96
|
+
declare const discoverWorkspaces: (root: string) => Workspace[];
|
|
97
|
+
declare const readRatchet: (root: string) => RatchetConfig | undefined;
|
|
98
|
+
|
|
99
|
+
declare const runDoctor: ({ baseline, oxlint, root, strict, }: DoctorOptions) => Promise<DoctorReport>;
|
|
100
|
+
|
|
101
|
+
/** Which kit package reads which block of `geonosis.json`. */
|
|
102
|
+
declare const READERS: Record<string, string>;
|
|
103
|
+
/**
|
|
104
|
+
* What has drifted since the gates were set up.
|
|
105
|
+
*
|
|
106
|
+
* Every line here is something that reads as green from the outside: a job that cannot run, a suite
|
|
107
|
+
* nothing runs, a directory nothing reaches, a law nobody finishes, a plugin nobody installed, a
|
|
108
|
+
* block nothing reads. The other four checks ask whether a gate measures what it names; this one
|
|
109
|
+
* asks whether it is still there at all.
|
|
110
|
+
*/
|
|
111
|
+
declare const checkDrift: ({ readers, root, workspaces, }: {
|
|
112
|
+
/**
|
|
113
|
+
* Which package reads which block. It is a parameter so a test can name one that can NEVER be
|
|
114
|
+
* installed: a fixture that turns on whether some real package happens to be present on the base
|
|
115
|
+
* it runs against goes green for a reason that is not the code, and red the day that package
|
|
116
|
+
* ships — which is exactly what this one did.
|
|
117
|
+
*/
|
|
118
|
+
readers?: Record<string, string>;
|
|
119
|
+
root: string;
|
|
120
|
+
workspaces: Workspace[];
|
|
121
|
+
}) => Finding[];
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* The rules of one plugin a config actually turns on. A rule NAMED in a config is not a rule
|
|
125
|
+
* enabled by it — `"off"` is how a config records a rule it decided against, and counting those as
|
|
126
|
+
* enabled would report every one of them as firing nowhere, which is exactly what they do.
|
|
127
|
+
*/
|
|
128
|
+
declare const enabledRulesOf: (rules: Record<string, unknown>, plugin: string) => string[];
|
|
129
|
+
/**
|
|
130
|
+
* Enabled is not exercised. A rule at "error" over a tree with no violation of it, and a rule at
|
|
131
|
+
* "error" that can never fire at all, produce the identical green — one consumer ran
|
|
132
|
+
* `no-raw-html-atoms` that way for months with 136 raw elements in the tree. The corpus is the one
|
|
133
|
+
* place where the difference is visible, so the question is asked there, under THIS config's
|
|
134
|
+
* options, because the options are usually where the reach went.
|
|
135
|
+
*/
|
|
136
|
+
declare const checkExercised: ({ config, corpus, oxlint, repoCorpus, root, }: {
|
|
137
|
+
config: DiscoveredConfig;
|
|
138
|
+
corpus: string;
|
|
139
|
+
oxlint: string;
|
|
140
|
+
/** The corpus this repo ships for its OWN options, when `geonosis.json` declares one. */
|
|
141
|
+
repoCorpus?: string;
|
|
142
|
+
root: string;
|
|
143
|
+
}) => Finding;
|
|
144
|
+
|
|
145
|
+
/** The scope this tool asks about. A config's other plugins are somebody else's release to check. */
|
|
146
|
+
declare const SCOPE = "@geonosis/";
|
|
147
|
+
/**
|
|
148
|
+
* Whether the version that loaded is the version the manifest asked for — or `undefined` when the
|
|
149
|
+
* range is one this cannot read. A range it cannot judge is a REFUSAL, never a pass: "the check ran
|
|
150
|
+
* and said nothing" is the shape every gate in this kit exists to stop.
|
|
151
|
+
*/
|
|
152
|
+
declare const satisfies: (version: string, spec: string) => boolean | undefined;
|
|
153
|
+
/**
|
|
154
|
+
* What the repo SAYS this config's plugin should be: the nearest manifest, walking up from the
|
|
155
|
+
* config, that names the package in any dependency block — ending at the root's. A workspace that
|
|
156
|
+
* declares nothing inherits the root's pin, which is what a hoisted install actually installed.
|
|
157
|
+
*/
|
|
158
|
+
declare const declaredFor: ({ dir, specifier, workspaces, }: {
|
|
159
|
+
dir: string;
|
|
160
|
+
specifier: string;
|
|
161
|
+
workspaces: Workspace[];
|
|
162
|
+
}) => {
|
|
163
|
+
at: string;
|
|
164
|
+
spec: string;
|
|
165
|
+
} | undefined;
|
|
166
|
+
declare const checkLoaded: ({ configs, root, workspaces, }: {
|
|
167
|
+
configs: DiscoveredConfig[];
|
|
168
|
+
root: string;
|
|
169
|
+
workspaces: Workspace[];
|
|
170
|
+
}) => Promise<Finding[]>;
|
|
171
|
+
|
|
172
|
+
/** The record a sink writes on every capture. `@geonosis/observability` exports the same shape. */
|
|
173
|
+
type LastEventRecord = {
|
|
174
|
+
at?: unknown;
|
|
175
|
+
id?: unknown;
|
|
176
|
+
release?: unknown;
|
|
177
|
+
sink?: unknown;
|
|
178
|
+
};
|
|
179
|
+
type ObservabilityConfig = {
|
|
180
|
+
/** Where reports go. `https://eu.i.posthog.com`, an OTLP collector, a self-hosted host. */
|
|
181
|
+
endpoint?: string;
|
|
182
|
+
/** Where the sink writes its `LastEventRecord`, relative to the root. */
|
|
183
|
+
lastEventFile?: string;
|
|
184
|
+
/** How old the last event may be before this is a finding. */
|
|
185
|
+
maxAgeSeconds?: number;
|
|
186
|
+
/** The command that plants an error and proves it arrived. Named here, never run from here. */
|
|
187
|
+
probe?: string;
|
|
188
|
+
/** What kind of sink this repo runs: `posthog`, `otlp`, `memory`, … */
|
|
189
|
+
sink?: string;
|
|
190
|
+
};
|
|
191
|
+
declare const checkObservability: ({ now, root, }: {
|
|
192
|
+
now: number;
|
|
193
|
+
root: string;
|
|
194
|
+
}) => Promise<Finding[]>;
|
|
195
|
+
|
|
196
|
+
declare const GEONOSIS_FILE = "geonosis.json";
|
|
197
|
+
/**
|
|
198
|
+
* The reach corpus a repo ships for ITS OWN options, if it declares one.
|
|
199
|
+
*
|
|
200
|
+
* `exercised` asks whether an enabled rule can fire at all, against the corpus the PLUGIN ships.
|
|
201
|
+
* That answers for most rules and cannot answer for the ones whose reach is a repo's vocabulary:
|
|
202
|
+
* `layer-walls` fires on this repo's layer names, `no-brand-names` on its brand,
|
|
203
|
+
* `plugin-route-namespaced` on its package root. The plugin's corpus says `acme` and `layers/core`,
|
|
204
|
+
* so it is no evidence either way — and those rules read as firing nowhere in a tree that enforces
|
|
205
|
+
* them perfectly well.
|
|
206
|
+
*
|
|
207
|
+
* A repo answers for its own options by shipping fixtures in its own vocabulary and naming, in that
|
|
208
|
+
* corpus's own manifest, exactly which rules it is evidence about.
|
|
209
|
+
*/
|
|
210
|
+
declare const repoCorpusOf: (root: string) => string | undefined;
|
|
211
|
+
|
|
212
|
+
declare const formatDoctor: ({ counts, findings, ok, root }: DoctorReport) => string;
|
|
213
|
+
declare const formatJson: (report: DoctorReport) => string;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* What oxlint would load, asked the only way that answers on every package manager.
|
|
217
|
+
*
|
|
218
|
+
* oxlint resolves a `jsPlugins` specifier from the CONFIG FILE's directory, not the working
|
|
219
|
+
* directory, so the question is asked from a directory and never from the process's cwd. And it is
|
|
220
|
+
* asked of the RESOLVER: counting copies with `find` is a bun/npm check only — on pnpm the entries
|
|
221
|
+
* under `node_modules/@scope/` are symlinks into `.pnpm/`, which keeps every version ever
|
|
222
|
+
* installed, so the same count answers 7 on a correct tree and 0 with the store excluded.
|
|
223
|
+
*/
|
|
224
|
+
declare const resolveFrom: (dir: string, specifier: string) => string;
|
|
225
|
+
/** The package a resolved entry point belongs to: up until a manifest claims the name. */
|
|
226
|
+
declare const packageDirOf: (entry: string, name: string) => string;
|
|
227
|
+
/**
|
|
228
|
+
* The version the plugin itself declares — `meta.version`, the number a diagnostic would carry,
|
|
229
|
+
* read by importing the module exactly as oxlint does. The manifest beside it is a different
|
|
230
|
+
* claim, and when the two disagree the one that ran is the one that matters.
|
|
231
|
+
*/
|
|
232
|
+
declare const pluginVersionOf: (entry: string) => Promise<string>;
|
|
233
|
+
/** Where a plugin keeps the corpus it is evidence by, if it ships one at all. */
|
|
234
|
+
declare const corpusOfPlugin: (from: string, specifier: string) => string;
|
|
235
|
+
/**
|
|
236
|
+
* A resolved path, said relative to the root. Both sides are realpath'd first: a resolver returns
|
|
237
|
+
* the real path, and on macOS a temp root under `/var/folders` is a symlink to `/private/var`, so
|
|
238
|
+
* the naive answer is a relative path that climbs out of the repo and back in.
|
|
239
|
+
*/
|
|
240
|
+
declare const relativeToRoot: (root: string, path: string) => string;
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* A test runner's exit code is not a verdict; its summary is.
|
|
244
|
+
*
|
|
245
|
+
* `@cloudflare/vitest-pool-workers` exited 0 over suites it had just reported as failing, for
|
|
246
|
+
* weeks, in a consumer — so every gate that trusted the status read green over red. The fix is a
|
|
247
|
+
* runner that writes its own report and something that reads it; this says which workspaces have
|
|
248
|
+
* neither.
|
|
249
|
+
*/
|
|
250
|
+
declare const checkRunner: ({ ratchet, workspaces, }: {
|
|
251
|
+
ratchet?: RatchetConfig;
|
|
252
|
+
workspaces: Workspace[];
|
|
253
|
+
}) => Finding[];
|
|
254
|
+
|
|
255
|
+
export { CHECKS, CONFIG_FILE, type CheckName, type DiscoveredConfig, DoctorError, type DoctorOptions, type DoctorReport, type Finding, GEONOSIS_FILE, type LastEventRecord, MANIFEST_FILE, type Manifest, type ObservabilityConfig, RATCHET_FILE, READERS, type RatchetConfig, SCOPE, type Verdict, type Workspace, checkBaseline, checkDrift, checkExercised, checkLoaded, checkObservability, checkRunner, corpusOfPlugin, declaredFor, defaultRef, discoverConfigs, discoverWorkspaces, enabledRulesOf, formatDoctor, formatJson, packageDirOf, pluginVersionOf, readConfig, readRatchet, relativePath, relativeToRoot, repoCorpusOf, resolveFrom, runDoctor, satisfies };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CHECKS,
|
|
3
|
+
CONFIG_FILE,
|
|
4
|
+
DoctorError,
|
|
5
|
+
GEONOSIS_FILE,
|
|
6
|
+
MANIFEST_FILE,
|
|
7
|
+
RATCHET_FILE,
|
|
8
|
+
READERS,
|
|
9
|
+
SCOPE,
|
|
10
|
+
checkBaseline,
|
|
11
|
+
checkDrift,
|
|
12
|
+
checkExercised,
|
|
13
|
+
checkLoaded,
|
|
14
|
+
checkObservability,
|
|
15
|
+
checkRunner,
|
|
16
|
+
corpusOfPlugin,
|
|
17
|
+
declaredFor,
|
|
18
|
+
defaultRef,
|
|
19
|
+
discoverConfigs,
|
|
20
|
+
discoverWorkspaces,
|
|
21
|
+
enabledRulesOf,
|
|
22
|
+
formatDoctor,
|
|
23
|
+
formatJson,
|
|
24
|
+
packageDirOf,
|
|
25
|
+
pluginVersionOf,
|
|
26
|
+
readConfig,
|
|
27
|
+
readRatchet,
|
|
28
|
+
relativePath,
|
|
29
|
+
relativeToRoot,
|
|
30
|
+
repoCorpusOf,
|
|
31
|
+
resolveFrom,
|
|
32
|
+
runDoctor,
|
|
33
|
+
satisfies
|
|
34
|
+
} from "./chunk-R4AHDFE3.js";
|
|
35
|
+
export {
|
|
36
|
+
CHECKS,
|
|
37
|
+
CONFIG_FILE,
|
|
38
|
+
DoctorError,
|
|
39
|
+
GEONOSIS_FILE,
|
|
40
|
+
MANIFEST_FILE,
|
|
41
|
+
RATCHET_FILE,
|
|
42
|
+
READERS,
|
|
43
|
+
SCOPE,
|
|
44
|
+
checkBaseline,
|
|
45
|
+
checkDrift,
|
|
46
|
+
checkExercised,
|
|
47
|
+
checkLoaded,
|
|
48
|
+
checkObservability,
|
|
49
|
+
checkRunner,
|
|
50
|
+
corpusOfPlugin,
|
|
51
|
+
declaredFor,
|
|
52
|
+
defaultRef,
|
|
53
|
+
discoverConfigs,
|
|
54
|
+
discoverWorkspaces,
|
|
55
|
+
enabledRulesOf,
|
|
56
|
+
formatDoctor,
|
|
57
|
+
formatJson,
|
|
58
|
+
packageDirOf,
|
|
59
|
+
pluginVersionOf,
|
|
60
|
+
readConfig,
|
|
61
|
+
readRatchet,
|
|
62
|
+
relativePath,
|
|
63
|
+
relativeToRoot,
|
|
64
|
+
repoCorpusOf,
|
|
65
|
+
resolveFrom,
|
|
66
|
+
runDoctor,
|
|
67
|
+
satisfies
|
|
68
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@geonosis/doctor",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "The adoption doctor — declared ≠ loaded, enabled ≠ exercised, a baseline that grew, a runner whose exit code is the only verdict.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"oxlint",
|
|
7
|
+
"lint",
|
|
8
|
+
"doctor",
|
|
9
|
+
"monorepo",
|
|
10
|
+
"adoption",
|
|
11
|
+
"ratchet",
|
|
12
|
+
"ci"
|
|
13
|
+
],
|
|
14
|
+
"homepage": "https://github.com/microcompanies/geonosis/tree/main/packages/doctor",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/microcompanies/geonosis.git",
|
|
18
|
+
"directory": "packages/doctor"
|
|
19
|
+
},
|
|
20
|
+
"license": "Apache-2.0",
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "dist/index.js",
|
|
23
|
+
"bin": {
|
|
24
|
+
"geonosis-doctor": "bin/geonosis-doctor.mjs"
|
|
25
|
+
},
|
|
26
|
+
"exports": {
|
|
27
|
+
".": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"bin",
|
|
31
|
+
"dist"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@geonosis/lint-parity": "1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"oxlint": ">=1.77"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=22"
|
|
41
|
+
},
|
|
42
|
+
"publishConfig": {
|
|
43
|
+
"access": "public"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsup",
|
|
47
|
+
"typecheck": "tsc --noEmit"
|
|
48
|
+
}
|
|
49
|
+
}
|