plumbbob 0.8.13 → 0.8.17
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/.claude-plugin/plugin.json +1 -1
- package/dist/lib/agents.js +1 -1
- package/dist/lib/check.js +9 -6
- package/dist/lib/intent.js +20 -0
- package/dist/lib/orient.js +4 -3
- package/dist/verbs/checkpoint.js +30 -11
- package/dist/verbs/finish.js +24 -8
- package/node_modules/checkride/CHANGELOG.md +234 -0
- package/node_modules/checkride/README.md +134 -31
- package/node_modules/checkride/dist/adapters.d.ts +50 -1
- package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
- package/node_modules/checkride/dist/adapters.js +123 -7
- package/node_modules/checkride/dist/adapters.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/hook.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/hook.js +15 -1
- package/node_modules/checkride/dist/agent-setup/hook.js.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.d.ts +0 -1
- package/node_modules/checkride/dist/agent-setup/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/agent-setup/index.js.map +1 -1
- package/node_modules/checkride/dist/baseline/fallow.d.ts +64 -0
- package/node_modules/checkride/dist/baseline/fallow.d.ts.map +1 -0
- package/node_modules/checkride/dist/baseline/fallow.js +256 -0
- package/node_modules/checkride/dist/baseline/fallow.js.map +1 -0
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts +4 -6
- package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/fingerprint.js +9 -4
- package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -1
- package/node_modules/checkride/dist/baseline/index.d.ts +4 -5
- package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/baseline/index.js +2 -2
- package/node_modules/checkride/dist/baseline/index.js.map +1 -1
- package/node_modules/checkride/dist/{baseline/command.d.ts → baseline-command.d.ts} +11 -9
- package/node_modules/checkride/dist/baseline-command.d.ts.map +1 -0
- package/node_modules/checkride/dist/{baseline/command.js → baseline-command.js} +9 -7
- package/node_modules/checkride/dist/baseline-command.js.map +1 -0
- package/node_modules/checkride/dist/cli.d.ts.map +1 -1
- package/node_modules/checkride/dist/cli.js +95 -8
- package/node_modules/checkride/dist/cli.js.map +1 -1
- package/node_modules/checkride/dist/config.d.ts +37 -12
- package/node_modules/checkride/dist/config.d.ts.map +1 -1
- package/node_modules/checkride/dist/config.js +268 -60
- package/node_modules/checkride/dist/config.js.map +1 -1
- package/node_modules/checkride/dist/digest/digest.d.ts +0 -6
- package/node_modules/checkride/dist/digest/digest.d.ts.map +1 -1
- package/node_modules/checkride/dist/digest/digest.js +3 -3
- package/node_modules/checkride/dist/digest/digest.js.map +1 -1
- package/node_modules/checkride/dist/digest/index.d.ts +1 -2
- package/node_modules/checkride/dist/digest/index.d.ts.map +1 -1
- package/node_modules/checkride/dist/digest/index.js +1 -1
- package/node_modules/checkride/dist/digest/index.js.map +1 -1
- package/node_modules/checkride/dist/doctor.d.ts +14 -1
- package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
- package/node_modules/checkride/dist/doctor.js +124 -55
- package/node_modules/checkride/dist/doctor.js.map +1 -1
- package/node_modules/checkride/dist/init.d.ts +6 -0
- package/node_modules/checkride/dist/init.d.ts.map +1 -1
- package/node_modules/checkride/dist/init.js +347 -121
- package/node_modules/checkride/dist/init.js.map +1 -1
- package/node_modules/checkride/dist/links.d.ts.map +1 -1
- package/node_modules/checkride/dist/links.js +8 -9
- package/node_modules/checkride/dist/links.js.map +1 -1
- package/node_modules/checkride/dist/orchestrator.d.ts +56 -1
- package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
- package/node_modules/checkride/dist/orchestrator.js +506 -138
- package/node_modules/checkride/dist/orchestrator.js.map +1 -1
- package/node_modules/checkride/dist/pack.d.ts +76 -0
- package/node_modules/checkride/dist/pack.d.ts.map +1 -0
- package/node_modules/checkride/dist/pack.js +217 -0
- package/node_modules/checkride/dist/pack.js.map +1 -0
- package/node_modules/checkride/dist/pm/translate.d.ts +18 -10
- package/node_modules/checkride/dist/pm/translate.d.ts.map +1 -1
- package/node_modules/checkride/dist/pm/translate.js +27 -13
- package/node_modules/checkride/dist/pm/translate.js.map +1 -1
- package/node_modules/checkride/dist/smoke.d.ts +86 -0
- package/node_modules/checkride/dist/smoke.d.ts.map +1 -0
- package/node_modules/checkride/dist/smoke.js +346 -0
- package/node_modules/checkride/dist/smoke.js.map +1 -0
- package/node_modules/checkride/dist/snippets.d.ts +215 -0
- package/node_modules/checkride/dist/snippets.d.ts.map +1 -0
- package/node_modules/checkride/dist/snippets.js +360 -0
- package/node_modules/checkride/dist/snippets.js.map +1 -0
- package/node_modules/checkride/package.json +4 -2
- package/node_modules/checkride/schema/checkride.config.schema.json +11 -6
- package/package.json +3 -2
- package/skills/pb-build/SKILL.md +7 -0
- package/skills/pb-park/SKILL.md +3 -2
- package/skills/pb-plan/SKILL.md +30 -9
- package/skills/pb-refine/SKILL.md +21 -6
- package/skills/pb-step/SKILL.md +10 -5
- package/skills/pb-verify/SKILL.md +12 -1
- package/templates/intent.md +55 -11
- package/node_modules/checkride/dist/baseline/command.d.ts.map +0 -1
- package/node_modules/checkride/dist/baseline/command.js.map +0 -1
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in `smoke` check (D9) — a **liveness** probe of the built package, not a
|
|
3
|
+
* type check (runtime *shapes* stay attw's job; the slots don't overlap).
|
|
4
|
+
*
|
|
5
|
+
* It enumerates the manifest's `exports` subpaths (falling back to `main`),
|
|
6
|
+
* writes a self-contained probe script under `.check/`, and spawns a fresh
|
|
7
|
+
* `node` on it (never in-process — isolation, the per-check timeout, and the
|
|
8
|
+
* orchestrator's SIGTERM→SIGKILL reaping all apply, D16/C6). The probe asserts,
|
|
9
|
+
* for every literal subpath:
|
|
10
|
+
*
|
|
11
|
+
* - the built entry `await import()`s without throwing, and (for a dual
|
|
12
|
+
* package, i.e. a subpath carrying an explicit `require` condition) also
|
|
13
|
+
* `require()`s cleanly — both through package **self-reference**
|
|
14
|
+
* (`import '<pkg>/<subpath>'`), exercising the real `exports`-map resolution
|
|
15
|
+
* a consumer would hit (Q9);
|
|
16
|
+
* - every **value** export named in the matching dist `.d.ts` is present at
|
|
17
|
+
* runtime. Export names come from a conservative, dependency-free `.d.ts`
|
|
18
|
+
* scanner ({@link scanValueExports}) that errs toward *under*-collection: a
|
|
19
|
+
* missed name is only a weaker assertion, never a false failure.
|
|
20
|
+
*
|
|
21
|
+
* Wildcard (`./*`), `null` (blocked), and `.json` data subpaths (notably the
|
|
22
|
+
* near-universal `"./package.json"` export) carry no runtime module to probe, so
|
|
23
|
+
* they are skipped and counted in the JSON output. A missing built artifact is
|
|
24
|
+
* caught before spawning and reported with a "did `build` run?" hint.
|
|
25
|
+
*
|
|
26
|
+
* Returns a result the orchestrator persists to `.check/smoke.json`:
|
|
27
|
+
* stdout `{ ok: true, results: [...], skipped: [...] }` on success (exit 0)
|
|
28
|
+
* stdout `{ ok: false, results: [...], skipped: [...] }` on an import/export miss (exit 1)
|
|
29
|
+
* stdout `{ ok: false, error, ... }` on a setup failure (bad manifest, missing dist, crashed probe)
|
|
30
|
+
*/
|
|
31
|
+
import { existsSync } from 'node:fs';
|
|
32
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
33
|
+
import { join } from 'node:path';
|
|
34
|
+
import { pathToFileURL } from 'node:url';
|
|
35
|
+
function isRecord(value) {
|
|
36
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
37
|
+
}
|
|
38
|
+
/** Read `obj[key]` as a non-empty string, else null. */
|
|
39
|
+
function strField(manifest, key) {
|
|
40
|
+
const value = manifest[key];
|
|
41
|
+
return typeof value === 'string' && value ? value : null;
|
|
42
|
+
}
|
|
43
|
+
/** Strip a leading `./` so manifest targets compare/resolve on equal footing. */
|
|
44
|
+
function normalize(target) {
|
|
45
|
+
return target.startsWith('./') ? target.slice(2) : target;
|
|
46
|
+
}
|
|
47
|
+
function normalizeMaybe(target) {
|
|
48
|
+
return target === null ? null : normalize(target);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve a conditional `exports` value to its first string leaf, stepping only
|
|
52
|
+
* through the named conditions (in priority order) and recursing into nested
|
|
53
|
+
* condition objects. A bare string is unconditional and returns as-is; an
|
|
54
|
+
* unrecognized shape returns null (skipped — conservative on exotic maps).
|
|
55
|
+
*/
|
|
56
|
+
function resolveConditional(node, conditions) {
|
|
57
|
+
if (typeof node === 'string')
|
|
58
|
+
return node;
|
|
59
|
+
if (!isRecord(node))
|
|
60
|
+
return null;
|
|
61
|
+
for (const cond of conditions) {
|
|
62
|
+
if (cond in node) {
|
|
63
|
+
const resolved = resolveConditional(node[cond], conditions);
|
|
64
|
+
if (resolved !== null)
|
|
65
|
+
return resolved;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Normalize the `exports` field to `[subpath, value]` entries. A subpath map
|
|
72
|
+
* has keys starting with `.`; a bare string or a conditions-only object (no
|
|
73
|
+
* `.`-keys) is the sugar for the `.` subpath.
|
|
74
|
+
*/
|
|
75
|
+
function exportEntries(exportsField) {
|
|
76
|
+
if (typeof exportsField === 'string')
|
|
77
|
+
return [['.', exportsField]];
|
|
78
|
+
if (isRecord(exportsField)) {
|
|
79
|
+
const keys = Object.keys(exportsField);
|
|
80
|
+
if (keys.some((key) => key.startsWith('.')))
|
|
81
|
+
return keys.map((key) => [key, exportsField[key]]);
|
|
82
|
+
return [['.', exportsField]];
|
|
83
|
+
}
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
/** The `.d.ts` target for a subpath: its `types` condition, or the top-level `types`/`typings` for `.`. */
|
|
87
|
+
function resolveTypesFile(value, manifest, subpath) {
|
|
88
|
+
const conditioned = isRecord(value) ? normalizeMaybe(resolveConditional(value, ['types', 'typings'])) : null;
|
|
89
|
+
if (conditioned !== null)
|
|
90
|
+
return conditioned;
|
|
91
|
+
if (subpath === '.')
|
|
92
|
+
return normalizeMaybe(strField(manifest, 'types') ?? strField(manifest, 'typings'));
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The explicit `require`-condition target, or null. A dual package carries a
|
|
97
|
+
* `require` condition; a bare-string target is single-format and must NOT be
|
|
98
|
+
* require-probed (requiring an ESM file would throw — a false failure).
|
|
99
|
+
*/
|
|
100
|
+
function resolveRequireFile(value) {
|
|
101
|
+
const requireNode = isRecord(value) ? value['require'] : undefined;
|
|
102
|
+
if (requireNode === undefined)
|
|
103
|
+
return null;
|
|
104
|
+
return normalizeMaybe(resolveConditional(requireNode, ['import', 'module', 'default', 'require']));
|
|
105
|
+
}
|
|
106
|
+
/** Turn one `exports` entry into a target to probe, or a skip with its reason. */
|
|
107
|
+
function entryToTarget(subpath, value, name, manifest) {
|
|
108
|
+
if (subpath.includes('*'))
|
|
109
|
+
return { skip: { subpath, reason: 'wildcard subpath' } };
|
|
110
|
+
if (value === null)
|
|
111
|
+
return { skip: { subpath, reason: 'null (blocked) subpath' } };
|
|
112
|
+
const importFile = normalizeMaybe(resolveConditional(value, ['import', 'module', 'default']));
|
|
113
|
+
if (importFile?.includes('*'))
|
|
114
|
+
return { skip: { subpath, reason: 'wildcard target' } };
|
|
115
|
+
const requireFile = resolveRequireFile(value);
|
|
116
|
+
// A `.json` subpath — the near-universal `"./package.json": "./package.json"`,
|
|
117
|
+
// plus any other data export — is not a runtime module: `import()`ing it needs
|
|
118
|
+
// an `with { type: 'json' }` attribute the probe can't supply, and it carries
|
|
119
|
+
// no value exports to assert. Skip it like a wildcard/null subpath.
|
|
120
|
+
const probeTarget = importFile ?? requireFile;
|
|
121
|
+
if (probeTarget?.endsWith('.json')) {
|
|
122
|
+
return { skip: { subpath, reason: 'json data subpath' } };
|
|
123
|
+
}
|
|
124
|
+
const specifier = name === null ? null : subpath === '.' ? name : name + subpath.slice(1);
|
|
125
|
+
return {
|
|
126
|
+
target: {
|
|
127
|
+
subpath,
|
|
128
|
+
specifier,
|
|
129
|
+
importFile,
|
|
130
|
+
requireFile,
|
|
131
|
+
typesFile: resolveTypesFile(value, manifest, subpath),
|
|
132
|
+
hasRequire: requireFile !== null,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/** The single `main`-fallback target when a manifest has no `exports` field, or null when it has no `main`. */
|
|
137
|
+
function mainTarget(manifest) {
|
|
138
|
+
const main = strField(manifest, 'main');
|
|
139
|
+
if (main === null)
|
|
140
|
+
return null;
|
|
141
|
+
const typesFile = normalizeMaybe(strField(manifest, 'types') ?? strField(manifest, 'typings'));
|
|
142
|
+
return { subpath: '.', specifier: null, importFile: normalize(main), requireFile: null, typesFile, hasRequire: false };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Enumerate the smoke targets from a manifest (D9): every literal `exports`
|
|
146
|
+
* subpath, or the `main` entry when there is no `exports` field. Wildcard and
|
|
147
|
+
* `null` subpaths are skipped with a reason (they name no single file). The
|
|
148
|
+
* self-reference `specifier` is derived from the package `name`.
|
|
149
|
+
*/
|
|
150
|
+
export function enumerateExports(manifest) {
|
|
151
|
+
const exportsField = manifest['exports'];
|
|
152
|
+
if (exportsField === undefined || exportsField === null) {
|
|
153
|
+
const main = mainTarget(manifest);
|
|
154
|
+
return { targets: main ? [main] : [], skipped: [] };
|
|
155
|
+
}
|
|
156
|
+
const name = strField(manifest, 'name');
|
|
157
|
+
const targets = [];
|
|
158
|
+
const skipped = [];
|
|
159
|
+
for (const [subpath, value] of exportEntries(exportsField)) {
|
|
160
|
+
const result = entryToTarget(subpath, value, name, manifest);
|
|
161
|
+
if ('skip' in result)
|
|
162
|
+
skipped.push(result.skip);
|
|
163
|
+
else
|
|
164
|
+
targets.push(result.target);
|
|
165
|
+
}
|
|
166
|
+
return { targets, skipped };
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Strip comments so an `export` inside a JSDoc block or `//` line can't be
|
|
170
|
+
* mistaken for a real declaration. Block comments first (they can span lines),
|
|
171
|
+
* then line comments.
|
|
172
|
+
*/
|
|
173
|
+
function stripComments(dts) {
|
|
174
|
+
return dts.replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/[^\n]*/g, '');
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Only top-level (column-0) `export` declarations — never one nested inside a
|
|
178
|
+
* `declare namespace { … }`, which is indented in `.d.ts` emit. `function`,
|
|
179
|
+
* `const`, `class`, `enum` (optionally `abstract` for a class); the negative
|
|
180
|
+
* lookahead drops `const enum` (a const enum has no runtime object).
|
|
181
|
+
*/
|
|
182
|
+
const DECL_RE = /^export\s+declare\s+(?:abstract\s+)?(?:function|const|class|enum)\s+(?!enum\b)([A-Za-z_$][\w$]*)/gm;
|
|
183
|
+
/** A top-level `export { … }` block (optionally `export type { … }`, which is type-only). */
|
|
184
|
+
const NAMED_RE = /^export\s+(type\s+)?\{([^}]*)\}/gm;
|
|
185
|
+
/**
|
|
186
|
+
* The runtime name a single `export { … }` specifier binds, or null when it is
|
|
187
|
+
* type-only (`type X`) or not a plain identifier. An alias (`foo as bar`)
|
|
188
|
+
* resolves to the exported name (`bar`).
|
|
189
|
+
*/
|
|
190
|
+
function namedExportBinding(spec) {
|
|
191
|
+
const trimmed = spec.trim();
|
|
192
|
+
if (trimmed === '' || /^type\s/.test(trimmed))
|
|
193
|
+
return null;
|
|
194
|
+
const aliased = /\bas\s+([A-Za-z_$][\w$]*)$/.exec(trimmed);
|
|
195
|
+
const exported = aliased ? aliased[1] : trimmed;
|
|
196
|
+
return exported !== undefined && /^[A-Za-z_$][\w$]*$/.test(exported) ? exported : null;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Scan a dist `.d.ts` for the **value** exports a live module must expose (D9):
|
|
200
|
+
* `export declare function|const|class|enum` and the non-`type` specifiers of
|
|
201
|
+
* `export { … }` (aliases resolve to the exported name). Type-only forms —
|
|
202
|
+
* `export type`, `export interface`, `export type { … }`, and `{ type X }`
|
|
203
|
+
* specifiers — are excluded, as are `const enum`s and anything nested in a
|
|
204
|
+
* namespace. Conservative by design: it under-collects on exotic shapes rather
|
|
205
|
+
* than assert a name that isn't a runtime value.
|
|
206
|
+
*/
|
|
207
|
+
export function scanValueExports(dts) {
|
|
208
|
+
const source = stripComments(dts);
|
|
209
|
+
const names = new Set();
|
|
210
|
+
for (const match of source.matchAll(DECL_RE)) {
|
|
211
|
+
if (match[1])
|
|
212
|
+
names.add(match[1]);
|
|
213
|
+
}
|
|
214
|
+
for (const match of source.matchAll(NAMED_RE)) {
|
|
215
|
+
if (match[1])
|
|
216
|
+
continue; // `export type { … }` — the whole block is type-only.
|
|
217
|
+
for (const spec of (match[2] ?? '').split(',')) {
|
|
218
|
+
const binding = namedExportBinding(spec);
|
|
219
|
+
if (binding !== null)
|
|
220
|
+
names.add(binding);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return [...names].toSorted();
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* The generated probe's fixed body (see {@link checkSmoke}). String-concatenated
|
|
227
|
+
* — no template literals — so it survives being emitted from inside one. Runs as
|
|
228
|
+
* ESM (`.mjs`) for top-level `await import()`; `createRequire` covers the
|
|
229
|
+
* `require` condition of a dual package in the same process.
|
|
230
|
+
*/
|
|
231
|
+
const PROBE_BODY = [
|
|
232
|
+
"import { createRequire } from 'node:module';",
|
|
233
|
+
'const require = createRequire(import.meta.url);',
|
|
234
|
+
'const results = [];',
|
|
235
|
+
'for (const t of TARGETS) {',
|
|
236
|
+
' const r = { subpath: t.subpath, ok: true, errors: [] };',
|
|
237
|
+
' let mod = null;',
|
|
238
|
+
' try { mod = await import(t.importArg); }',
|
|
239
|
+
" catch (err) { r.ok = false; r.errors.push('import failed: ' + (err && err.message ? err.message : String(err))); }",
|
|
240
|
+
' if (mod) {',
|
|
241
|
+
' const missing = t.expected.filter((n) => !(n in mod));',
|
|
242
|
+
" if (missing.length) { r.ok = false; r.errors.push('missing value export(s): ' + missing.join(', ')); }",
|
|
243
|
+
' }',
|
|
244
|
+
' if (t.requireArg) {',
|
|
245
|
+
' try {',
|
|
246
|
+
' const cjs = require(t.requireArg);',
|
|
247
|
+
" const obj = cjs && (typeof cjs === 'object' || typeof cjs === 'function') ? cjs : {};",
|
|
248
|
+
' const missing = t.expected.filter((n) => !(n in obj));',
|
|
249
|
+
" if (missing.length) { r.ok = false; r.errors.push('missing value export(s) via require: ' + missing.join(', ')); }",
|
|
250
|
+
" } catch (err) { r.ok = false; r.errors.push('require failed: ' + (err && err.message ? err.message : String(err))); }",
|
|
251
|
+
' }',
|
|
252
|
+
' results.push(r);',
|
|
253
|
+
'}',
|
|
254
|
+
'const ok = results.every((r) => r.ok);',
|
|
255
|
+
"process.stdout.write(JSON.stringify({ ok, results }) + '\\n');",
|
|
256
|
+
'if (!ok) {',
|
|
257
|
+
" for (const r of results) for (const e of r.errors) process.stderr.write('smoke: ' + r.subpath + ': ' + e + '\\n');",
|
|
258
|
+
' process.exit(1);',
|
|
259
|
+
'}',
|
|
260
|
+
'',
|
|
261
|
+
].join('\n');
|
|
262
|
+
function errorOutcome(error, stderrDetail) {
|
|
263
|
+
return {
|
|
264
|
+
ok: false,
|
|
265
|
+
exit_code: 1,
|
|
266
|
+
stdout: `${JSON.stringify({ ok: false, error }, null, 2)}\n`,
|
|
267
|
+
stderr: `check-smoke: ${stderrDetail ?? error}\n`,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
/** Read and parse the manifest; a missing/unreadable/non-object file is a setup failure. */
|
|
271
|
+
async function readManifest(cwd) {
|
|
272
|
+
try {
|
|
273
|
+
const parsed = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf8'));
|
|
274
|
+
if (!isRecord(parsed))
|
|
275
|
+
return { ok: false, error: 'package.json is not an object' };
|
|
276
|
+
return { ok: true, manifest: parsed };
|
|
277
|
+
}
|
|
278
|
+
catch (err) {
|
|
279
|
+
return { ok: false, error: `could not read package.json: ${err instanceof Error ? err.message : String(err)}` };
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/** Build one probe entry for a target, reading its `.d.ts` for expected value names. */
|
|
283
|
+
async function planTarget(cwd, target) {
|
|
284
|
+
const importArg = target.specifier ?? (target.importFile !== null ? pathToFileURL(join(cwd, target.importFile)).href : '');
|
|
285
|
+
const requireArg = target.specifier !== null && target.hasRequire ? target.specifier : null;
|
|
286
|
+
let expected = [];
|
|
287
|
+
if (target.typesFile !== null && existsSync(join(cwd, target.typesFile))) {
|
|
288
|
+
expected = scanValueExports(await readFile(join(cwd, target.typesFile), 'utf8'));
|
|
289
|
+
}
|
|
290
|
+
return { subpath: target.subpath, importArg, requireArg, expected };
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* Run the `smoke` check against `cwd`. Reads the manifest, enumerates its
|
|
294
|
+
* targets, verifies the built artifacts exist (a miss is reported with a "did
|
|
295
|
+
* build run?" hint before anything is spawned), then writes and runs the probe
|
|
296
|
+
* through the injected `spawn`. Never throws: every setup failure resolves to a
|
|
297
|
+
* failing outcome.
|
|
298
|
+
*/
|
|
299
|
+
export async function checkSmoke(opts) {
|
|
300
|
+
const { cwd, spawn, timeoutSec } = opts;
|
|
301
|
+
const read = await readManifest(cwd);
|
|
302
|
+
if (!read.ok)
|
|
303
|
+
return errorOutcome(read.error);
|
|
304
|
+
const { targets, skipped } = enumerateExports(read.manifest);
|
|
305
|
+
if (targets.length === 0) {
|
|
306
|
+
return errorOutcome('no exports/main entry to smoke-test', 'no `exports` subpaths or `main` to import — nothing to smoke-test');
|
|
307
|
+
}
|
|
308
|
+
// A required built entry that isn't on disk means the artifact checks are
|
|
309
|
+
// running before a build produced `dist/` — the most common smoke failure.
|
|
310
|
+
// Catch it here with a friendly hint rather than a raw import error.
|
|
311
|
+
const missingDist = targets
|
|
312
|
+
.filter((t) => t.importFile !== null && !existsSync(join(cwd, t.importFile)))
|
|
313
|
+
.map((t) => t.importFile ?? '');
|
|
314
|
+
if (missingDist.length > 0) {
|
|
315
|
+
return errorOutcome(`built artifact(s) not found: ${missingDist.join(', ')}`, `built artifact(s) not found: ${missingDist.join(', ')} — did \`build\` run?`);
|
|
316
|
+
}
|
|
317
|
+
const plan = await Promise.all(targets.map((t) => planTarget(cwd, t)));
|
|
318
|
+
await mkdir(join(cwd, '.check'), { recursive: true });
|
|
319
|
+
const probePath = join(cwd, '.check', 'smoke-probe.mjs');
|
|
320
|
+
await writeFile(probePath, `const TARGETS = ${JSON.stringify(plan)};\n${PROBE_BODY}`);
|
|
321
|
+
const outcome = await spawn('node', [probePath], cwd, timeoutSec);
|
|
322
|
+
let payload = null;
|
|
323
|
+
try {
|
|
324
|
+
payload = JSON.parse(outcome.stdout);
|
|
325
|
+
}
|
|
326
|
+
catch {
|
|
327
|
+
// Probe crashed before printing valid JSON — handled below.
|
|
328
|
+
}
|
|
329
|
+
if (isRecord(payload) && typeof payload['ok'] === 'boolean') {
|
|
330
|
+
const results = payload['results'];
|
|
331
|
+
const merged = `${JSON.stringify({ ok: payload['ok'], results, skipped }, null, 2)}\n`;
|
|
332
|
+
if (payload['ok']) {
|
|
333
|
+
return {
|
|
334
|
+
ok: true,
|
|
335
|
+
exit_code: 0,
|
|
336
|
+
stdout: merged,
|
|
337
|
+
stderr: `check-smoke: ${plan.length} subpath(s) imported cleanly, all scanned value exports present\n`,
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return { ok: false, exit_code: 1, stdout: merged, stderr: outcome.stderr || 'check-smoke: one or more subpaths failed\n' };
|
|
341
|
+
}
|
|
342
|
+
// No parseable verdict: the probe process itself failed (crash, timeout, spawn error).
|
|
343
|
+
const detail = outcome.stderr.trim() || outcome.stdout.trim();
|
|
344
|
+
return errorOutcome(`smoke probe failed (exit ${outcome.exit_code})`, `smoke probe failed (exit ${outcome.exit_code})${detail ? `\n${detail}` : ''}`);
|
|
345
|
+
}
|
|
346
|
+
//# sourceMappingURL=smoke.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"smoke.js","sourceRoot":"","sources":["../src/smoke.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in `snippets` check.
|
|
3
|
+
*
|
|
4
|
+
* A doc snippet typecheck ported to match fascicle's `check-doc-snippets.mjs`
|
|
5
|
+
* byte-for-byte so the origin repo can adopt the slot verbatim (D11). It pulls
|
|
6
|
+
* fenced ```ts / ```typescript blocks out of `README.md` and the non-recursive
|
|
7
|
+
* `docs/*.md`, and typechecks only the ones explicitly opted in with an HTML
|
|
8
|
+
* comment on the line immediately above the fence:
|
|
9
|
+
*
|
|
10
|
+
* <!-- snippet: check -->
|
|
11
|
+
*
|
|
12
|
+
* Opt-in (rather than checking every fence) keeps the check honest: many doc
|
|
13
|
+
* fences are deliberately partial fragments that assert nothing about the API.
|
|
14
|
+
* A tagged snippet that fails to compile is documentation that lies — this
|
|
15
|
+
* turns that into a build failure. Opting the slot in but tagging *nothing* is
|
|
16
|
+
* a misconfiguration, not a vacuous pass, so zero tagged snippets is a hard
|
|
17
|
+
* error ({@link vacuousOptInError}; fascicle exits 2).
|
|
18
|
+
*
|
|
19
|
+
* The pure machinery — no filesystem, no spawning:
|
|
20
|
+
*
|
|
21
|
+
* - {@link extractSnippets} parses one doc's markdown into its ts/typescript
|
|
22
|
+
* fenced blocks, recording each block's start line and whether it is tagged;
|
|
23
|
+
* - {@link slugForDoc} / {@link snippetFileName} name the emitted scratch file
|
|
24
|
+
* for a block (`<slug>__<n>.ts`);
|
|
25
|
+
* - {@link planSnippets} folds a set of docs into the emission plan (the
|
|
26
|
+
* checked blocks to write, each mapped back to `<doc>:<line>`) plus the
|
|
27
|
+
* checked/skipped counts;
|
|
28
|
+
* - {@link generateSnippetTsconfig} builds the generated tsconfig (extends the
|
|
29
|
+
* repo's own, relaxes the three emit/style flags plus the composite-build
|
|
30
|
+
* fields a `tsc --build` project carries, embeds the caller's mode-specific
|
|
31
|
+
* `paths`).
|
|
32
|
+
*
|
|
33
|
+
* Execution (D12/Q1), consuming the primitives above:
|
|
34
|
+
*
|
|
35
|
+
* - {@link deriveSrcPaths} resolves **src mode**'s `paths` mapping: the repo's
|
|
36
|
+
* own tsconfig `paths` when present, else the `src/index.ts` convention,
|
|
37
|
+
* else null (the caller fails, recommending `snippets-dist`);
|
|
38
|
+
* - {@link checkSnippets} discovers the doc set, plans it, derives the mode's
|
|
39
|
+
* `paths`, emits the scratch files + generated tsconfig under
|
|
40
|
+
* `.check/doc-snippets/`, and typechecks them via a spawned
|
|
41
|
+
* `<pm> exec tsc --noEmit -p`, returning a {@link CheckOutcome} whose
|
|
42
|
+
* failure `stderr` carries tsc's raw output plus the `snippet -> source
|
|
43
|
+
* map:` legend.
|
|
44
|
+
*/
|
|
45
|
+
import type { CheckOutcome } from './links.js';
|
|
46
|
+
import type { PackageManager } from './pm/index.js';
|
|
47
|
+
/**
|
|
48
|
+
* The opt-in marker: an HTML comment `<!-- snippet: check -->` that must sit on
|
|
49
|
+
* the line immediately above a fence for its snippet to be typechecked. Exact
|
|
50
|
+
* fascicle regex (D11).
|
|
51
|
+
*/
|
|
52
|
+
export declare const CHECK_MARKER_RE: RegExp;
|
|
53
|
+
/** An opening fence — `ts` or `typescript` only, nothing else on the line (D11). */
|
|
54
|
+
export declare const FENCE_OPEN_RE: RegExp;
|
|
55
|
+
/** A closing fence: three backticks alone on the line. */
|
|
56
|
+
export declare const FENCE_CLOSE_RE: RegExp;
|
|
57
|
+
/**
|
|
58
|
+
* One `ts`/`typescript` fenced block extracted from a doc. `code` is the fence
|
|
59
|
+
* body verbatim (no trailing newline — step 8 appends one on write); `startLine`
|
|
60
|
+
* is the 1-based line of the opening fence; `checked` is true when a
|
|
61
|
+
* {@link CHECK_MARKER_RE} marker sits on the immediately-preceding line.
|
|
62
|
+
*/
|
|
63
|
+
export type Snippet = {
|
|
64
|
+
code: string;
|
|
65
|
+
startLine: number;
|
|
66
|
+
checked: boolean;
|
|
67
|
+
};
|
|
68
|
+
/** A doc to plan over: its repo-relative path and full text. */
|
|
69
|
+
export type DocInput = {
|
|
70
|
+
relPath: string;
|
|
71
|
+
text: string;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* One checked snippet in the emission plan: the scratch file to write
|
|
75
|
+
* (`<slug>__<n>.ts`), and the source doc + line it maps back to (the
|
|
76
|
+
* `snippet -> source map:` legend step 8 renders on failure).
|
|
77
|
+
*/
|
|
78
|
+
export type SnippetPlanEntry = {
|
|
79
|
+
name: string;
|
|
80
|
+
file: string;
|
|
81
|
+
line: number;
|
|
82
|
+
code: string;
|
|
83
|
+
};
|
|
84
|
+
/** The emission plan for a doc set: checked blocks to write, plus the counts. */
|
|
85
|
+
export type SnippetsPlan = {
|
|
86
|
+
entries: SnippetPlanEntry[];
|
|
87
|
+
checked: number;
|
|
88
|
+
skipped: number;
|
|
89
|
+
};
|
|
90
|
+
/** The two modes `snippets` runs in (D12): fast against `src`, or against built `dist/*.d.ts`. */
|
|
91
|
+
export type SnippetMode = 'src' | 'dist';
|
|
92
|
+
/** The generated tsconfig object (serialized to `.check/doc-snippets/tsconfig.json`). */
|
|
93
|
+
export type SnippetTsconfig = {
|
|
94
|
+
extends: string;
|
|
95
|
+
compilerOptions: {
|
|
96
|
+
paths: Record<string, string[]>;
|
|
97
|
+
noEmit: true;
|
|
98
|
+
verbatimModuleSyntax: false;
|
|
99
|
+
isolatedModules: false;
|
|
100
|
+
noPropertyAccessFromIndexSignature: false;
|
|
101
|
+
rootDir: '../..';
|
|
102
|
+
composite: false;
|
|
103
|
+
declaration: false;
|
|
104
|
+
declarationMap: false;
|
|
105
|
+
incremental: false;
|
|
106
|
+
};
|
|
107
|
+
include: string[];
|
|
108
|
+
exclude: string[];
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Select the doc files to check from a `docs/` directory listing (D11): always
|
|
112
|
+
* `README.md`, then every non-recursive `docs/*.md` entry, README first and the
|
|
113
|
+
* `docs/` entries in the order given. Pure — the caller does the (non-recursive)
|
|
114
|
+
* `readdir` and passes its entries; a plain entry list means a nested
|
|
115
|
+
* `docs/sub/x.md` never appears (its listing entry `sub` fails `.md`), matching
|
|
116
|
+
* fascicle's non-recursive `doc_files`.
|
|
117
|
+
*/
|
|
118
|
+
export declare function selectDocFiles(docsEntries: readonly string[]): string[];
|
|
119
|
+
/**
|
|
120
|
+
* Parse a doc's markdown into its `ts`/`typescript` fenced blocks (D11). A block
|
|
121
|
+
* is `checked` when a {@link CHECK_MARKER_RE} marker sits on the line immediately
|
|
122
|
+
* above its opening fence — a marker anywhere else does not count. Untagged
|
|
123
|
+
* blocks are still returned (the caller counts them as skipped). Semantics match
|
|
124
|
+
* fascicle's `extract_blocks` exactly.
|
|
125
|
+
*/
|
|
126
|
+
export declare function extractSnippets(text: string): Snippet[];
|
|
127
|
+
/**
|
|
128
|
+
* The scratch-file slug for a doc's repo-relative path: every non-alphanumeric
|
|
129
|
+
* run collapses to a single `_`, with leading/trailing `_` trimmed
|
|
130
|
+
* (`README.md` → `README_md`, `docs/guide.md` → `docs_guide_md`). Exact fascicle
|
|
131
|
+
* algorithm. Distinct docs in the discovered namespace (`README.md` plus the
|
|
132
|
+
* flat `docs/*.md`) map to distinct slugs, so their emitted files never collide.
|
|
133
|
+
*/
|
|
134
|
+
export declare function slugForDoc(relPath: string): string;
|
|
135
|
+
/**
|
|
136
|
+
* The scratch-file name for a block: `<slug>__<n>.ts`, where `n` is the block's
|
|
137
|
+
* 1-based position among *all* ts/typescript fences in its doc (checked or not) —
|
|
138
|
+
* so a skipped fence still advances the number, matching fascicle.
|
|
139
|
+
*/
|
|
140
|
+
export declare function snippetFileName(relPath: string, blockIndex: number): string;
|
|
141
|
+
/**
|
|
142
|
+
* Fold a set of docs into the emission plan: every checked block becomes a
|
|
143
|
+
* {@link SnippetPlanEntry} (named, mapped back to `<doc>:<line>`), untagged
|
|
144
|
+
* blocks bump `skipped`. The block index for naming counts all fences in a doc,
|
|
145
|
+
* so a checked block keeps its position even after skipped ones (fascicle
|
|
146
|
+
* parity). Pure — the caller reads the docs and writes the files.
|
|
147
|
+
*/
|
|
148
|
+
export declare function planSnippets(docs: readonly DocInput[]): SnippetsPlan;
|
|
149
|
+
/**
|
|
150
|
+
* The vacuous-opt-in guard (D11): a plan with no checked snippets is a hard
|
|
151
|
+
* error, not a vacuous green — opting the slot in obligates at least one tagged
|
|
152
|
+
* fence. Returns the error message for step 8 to surface (fascicle exits 2), or
|
|
153
|
+
* null when the plan has something to check.
|
|
154
|
+
*/
|
|
155
|
+
export declare function vacuousOptInError(plan: SnippetsPlan): string | null;
|
|
156
|
+
/**
|
|
157
|
+
* Build the generated tsconfig (D11): extend the repo's own config so the
|
|
158
|
+
* snippets inherit its strictness, then relax exactly the three flags that
|
|
159
|
+
* false-positive on illustrative snippets (`verbatimModuleSyntax`,
|
|
160
|
+
* `isolatedModules`, `noPropertyAccessFromIndexSignature`) while keeping the
|
|
161
|
+
* type-correctness flags that catch real API drift. `include` clears the parent's
|
|
162
|
+
* `.check` exclusion so the emitted `./*.ts` are seen; `paths` is the caller's
|
|
163
|
+
* mode-specific module resolution (src vs dist — Q1).
|
|
164
|
+
*
|
|
165
|
+
* A `tsc --build` project (composite, `rootDir`/`outDir` pinned to `src`/`dist`
|
|
166
|
+
* for project-reference emit) fails TS6059 on any *source* file outside its
|
|
167
|
+
* `rootDir` — and the generated snippets live under `.check/doc-snippets/`,
|
|
168
|
+
* while src mode's `paths` mapping pulls in a real source file elsewhere in the
|
|
169
|
+
* repo (dist mode's self-referenced `.d.ts` is exempt: a declaration file isn't
|
|
170
|
+
* subject to the same check). `rootDir: '../..'` re-scopes to `cwd` — the
|
|
171
|
+
* common ancestor of both — so either file satisfies it; `composite`/
|
|
172
|
+
* `declaration`/`declarationMap`/`incremental` are turned off since this is a
|
|
173
|
+
* one-shot typecheck, never a build. All four are no-ops on a plain
|
|
174
|
+
* (non-composite) project's tsconfig, so the override is harmless there too.
|
|
175
|
+
*/
|
|
176
|
+
export declare function generateSnippetTsconfig(opts: {
|
|
177
|
+
extendsPath: string;
|
|
178
|
+
paths: Record<string, string[]>;
|
|
179
|
+
}): SnippetTsconfig;
|
|
180
|
+
/** The compilation subprocess spawner — same signature as the orchestrator's `spawnCheck`. */
|
|
181
|
+
export type SnippetSpawn = (command: string, args: string[], cwd: string, timeoutSec?: number) => Promise<CheckOutcome>;
|
|
182
|
+
/**
|
|
183
|
+
* Derive the `paths` mapping **src mode** needs so `import { x } from
|
|
184
|
+
* '<pkg-name>'` resolves against source (Q1): the repo's own tsconfig `paths`
|
|
185
|
+
* when present (remapped two directories deeper, to where the generated
|
|
186
|
+
* tsconfig lives), else the `src/index.ts` convention (`<pkg-name>` maps to its
|
|
187
|
+
* root `src/index.ts`) when the manifest names the package and that file
|
|
188
|
+
* exists, else null — the caller turns a null into a failing outcome that
|
|
189
|
+
* recommends `snippets-dist` (whose dist-mode compilation needs no mapping at
|
|
190
|
+
* all: package self-reference through `exports` resolves the built types).
|
|
191
|
+
*/
|
|
192
|
+
export declare function deriveSrcPaths(opts: {
|
|
193
|
+
manifestName: string | null;
|
|
194
|
+
tsconfigPaths: Record<string, readonly string[]> | null;
|
|
195
|
+
hasSrcIndex: boolean;
|
|
196
|
+
}): Record<string, string[]> | null;
|
|
197
|
+
/**
|
|
198
|
+
* Run the `snippets` check against `cwd` in `mode` (D12: the `snippets` src
|
|
199
|
+
* adapter passes `'src'`, `snippets-dist` passes `'dist'`). Discovers the doc
|
|
200
|
+
* set, plans the checked snippets ({@link vacuousOptInError} applies first —
|
|
201
|
+
* zero tagged snippets is a hard error before anything is written), derives
|
|
202
|
+
* the mode's `paths` mapping, emits the scratch files plus a generated
|
|
203
|
+
* tsconfig under `.check/doc-snippets/`, and typechecks them through the
|
|
204
|
+
* injected `spawn`. A compile failure's `stderr` carries tsc's raw output plus
|
|
205
|
+
* the `snippet -> source map:` legend mapping each generated file back to
|
|
206
|
+
* `<doc>:<line>` (D11).
|
|
207
|
+
*/
|
|
208
|
+
export declare function checkSnippets(opts: {
|
|
209
|
+
cwd: string;
|
|
210
|
+
mode: SnippetMode;
|
|
211
|
+
pm: PackageManager;
|
|
212
|
+
spawn: SnippetSpawn;
|
|
213
|
+
timeoutSec?: number;
|
|
214
|
+
}): Promise<CheckOutcome>;
|
|
215
|
+
//# sourceMappingURL=snippets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"snippets.d.ts","sourceRoot":"","sources":["../src/snippets.ts"],"names":[],"mappings":"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"}
|