@nekostack/cli 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.
Files changed (80) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/LICENSE +202 -0
  3. package/README.md +89 -0
  4. package/bin/neko +6 -0
  5. package/dist/.build.tsbuildinfo +1 -0
  6. package/dist/.tsbuildinfo +1 -0
  7. package/dist/cli.d.ts +60 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +355 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/commands/init.d.ts +8 -0
  12. package/dist/commands/init.d.ts.map +1 -0
  13. package/dist/commands/init.js +11 -0
  14. package/dist/commands/init.js.map +1 -0
  15. package/dist/commands/schema/check.d.ts +55 -0
  16. package/dist/commands/schema/check.d.ts.map +1 -0
  17. package/dist/commands/schema/check.js +197 -0
  18. package/dist/commands/schema/check.js.map +1 -0
  19. package/dist/commands/schema/diff.d.ts +48 -0
  20. package/dist/commands/schema/diff.d.ts.map +1 -0
  21. package/dist/commands/schema/diff.js +245 -0
  22. package/dist/commands/schema/diff.js.map +1 -0
  23. package/dist/commands/schema/generate.d.ts +59 -0
  24. package/dist/commands/schema/generate.d.ts.map +1 -0
  25. package/dist/commands/schema/generate.js +135 -0
  26. package/dist/commands/schema/generate.js.map +1 -0
  27. package/dist/commands/schema/list.d.ts +50 -0
  28. package/dist/commands/schema/list.d.ts.map +1 -0
  29. package/dist/commands/schema/list.js +115 -0
  30. package/dist/commands/schema/list.js.map +1 -0
  31. package/dist/commands/schema/migrate/list.d.ts +65 -0
  32. package/dist/commands/schema/migrate/list.d.ts.map +1 -0
  33. package/dist/commands/schema/migrate/list.js +148 -0
  34. package/dist/commands/schema/migrate/list.js.map +1 -0
  35. package/dist/commands/schema/migrate/plan.d.ts +79 -0
  36. package/dist/commands/schema/migrate/plan.d.ts.map +1 -0
  37. package/dist/commands/schema/migrate/plan.js +255 -0
  38. package/dist/commands/schema/migrate/plan.js.map +1 -0
  39. package/dist/commands/schema/migrate/stub.d.ts +59 -0
  40. package/dist/commands/schema/migrate/stub.d.ts.map +1 -0
  41. package/dist/commands/schema/migrate/stub.js +195 -0
  42. package/dist/commands/schema/migrate/stub.js.map +1 -0
  43. package/dist/commands/schema/migrate/verify.d.ts +59 -0
  44. package/dist/commands/schema/migrate/verify.d.ts.map +1 -0
  45. package/dist/commands/schema/migrate/verify.js +268 -0
  46. package/dist/commands/schema/migrate/verify.js.map +1 -0
  47. package/dist/exit-codes.d.ts +47 -0
  48. package/dist/exit-codes.d.ts.map +1 -0
  49. package/dist/exit-codes.js +46 -0
  50. package/dist/exit-codes.js.map +1 -0
  51. package/dist/formatters/json.d.ts +25 -0
  52. package/dist/formatters/json.d.ts.map +1 -0
  53. package/dist/formatters/json.js +27 -0
  54. package/dist/formatters/json.js.map +1 -0
  55. package/dist/formatters/pretty.d.ts +131 -0
  56. package/dist/formatters/pretty.d.ts.map +1 -0
  57. package/dist/formatters/pretty.js +229 -0
  58. package/dist/formatters/pretty.js.map +1 -0
  59. package/dist/index.d.ts +2 -0
  60. package/dist/index.d.ts.map +1 -0
  61. package/dist/index.js +2 -0
  62. package/dist/index.js.map +1 -0
  63. package/dist/loaders/read-artifacts.d.ts +55 -0
  64. package/dist/loaders/read-artifacts.d.ts.map +1 -0
  65. package/dist/loaders/read-artifacts.js +99 -0
  66. package/dist/loaders/read-artifacts.js.map +1 -0
  67. package/dist/loaders/read-migrations.d.ts +70 -0
  68. package/dist/loaders/read-migrations.d.ts.map +1 -0
  69. package/dist/loaders/read-migrations.js +206 -0
  70. package/dist/loaders/read-migrations.js.map +1 -0
  71. package/dist/loaders/tsx-loader.d.ts +116 -0
  72. package/dist/loaders/tsx-loader.d.ts.map +1 -0
  73. package/dist/loaders/tsx-loader.js +250 -0
  74. package/dist/loaders/tsx-loader.js.map +1 -0
  75. package/dist/loaders/walk-workspace.d.ts +62 -0
  76. package/dist/loaders/walk-workspace.d.ts.map +1 -0
  77. package/dist/loaders/walk-workspace.js +133 -0
  78. package/dist/loaders/walk-workspace.js.map +1 -0
  79. package/docs/SCOPE.md +42 -0
  80. package/package.json +39 -0
package/dist/cli.js ADDED
@@ -0,0 +1,355 @@
1
+ /**
2
+ * `@nekostack/cli` argv-parse + dispatch entry (v0.7 Step 25).
3
+ *
4
+ * This module is the testable CLI surface — `buildCli()` constructs a
5
+ * configured commander program; `dispatch(argv)` parses an argv array
6
+ * and returns the intended exit code without calling `process.exit`;
7
+ * `run(argv)` is the production entry that wraps `dispatch` and exits
8
+ * the process. The split exists so the in-process test harness
9
+ * (Step 33) can drive the CLI without subprocess spawn (CLI plan
10
+ * Decision #9): tests call `dispatch`, capture stdout/stderr through
11
+ * injected writers, and assert on the returned exit code.
12
+ *
13
+ * All four schema verbs — `list` (Step 29), `diff` (Step 30),
14
+ * `check` (Step 31), and `generate` (Step 32) — are now wired to
15
+ * real dispatches against the schema-side handlers exposed by
16
+ * `@nekostack/schema/cli`. No placeholders remain.
17
+ *
18
+ * Exit codes follow the locked enum from [`./exit-codes.ts`](./exit-codes.ts)
19
+ * (CLI plan Decision #6). `process.exit` is called exactly once,
20
+ * from `run()`, the production entry. `dispatch()` itself never
21
+ * exits the process — every code path returns an `EXIT_CODES`
22
+ * value.
23
+ */
24
+ import { createRequire } from "node:module";
25
+ import { Command, CommanderError } from "commander";
26
+ import { runInit } from "./commands/init.js";
27
+ import { runCheck } from "./commands/schema/check.js";
28
+ import { runDiff } from "./commands/schema/diff.js";
29
+ import { runGenerate } from "./commands/schema/generate.js";
30
+ import { runList } from "./commands/schema/list.js";
31
+ import { runMigrateList } from "./commands/schema/migrate/list.js";
32
+ import { runMigratePlan } from "./commands/schema/migrate/plan.js";
33
+ import { runMigrateStub } from "./commands/schema/migrate/stub.js";
34
+ import { runMigrateVerify } from "./commands/schema/migrate/verify.js";
35
+ import { EXIT_CODES } from "./exit-codes.js";
36
+ // Re-export so existing call sites that imported the enum from
37
+ // `cli.ts` keep compiling without churn. `exit-codes.ts` is the
38
+ // source of truth.
39
+ export { EXIT_CODES };
40
+ const require = createRequire(import.meta.url);
41
+ const pkg = require("../package.json");
42
+ // =============================================================================
43
+ // Builder
44
+ // =============================================================================
45
+ const SCHEMA_VERBS = [
46
+ "list",
47
+ "diff",
48
+ "check",
49
+ "generate",
50
+ "migrate",
51
+ ];
52
+ /**
53
+ * Locked v0.8 `migrate` subcommand verbs (Decision #5 of the v0.8
54
+ * phase plan + the user-locked surface: `list / plan / verify /
55
+ * stub`). No `apply`, no `--force`. The verbs are declared in this
56
+ * order under the `migrate` group; the help-screen test asserts the
57
+ * declaration order is the contract.
58
+ */
59
+ const MIGRATE_VERBS = ["list", "plan", "verify", "stub"];
60
+ export function buildCli(opts = {}) {
61
+ const writeOut = opts.stdout ?? ((s) => process.stdout.write(s));
62
+ const writeErr = opts.stderr ?? ((s) => process.stderr.write(s));
63
+ const program = new Command()
64
+ .name("neko")
65
+ .description("NekoStack developer CLI")
66
+ .version(opts.version ?? pkg.version, "-v, --version", "print the @nekostack/cli version and exit")
67
+ .helpOption("-h, --help", "show help and exit")
68
+ .exitOverride()
69
+ .configureOutput({
70
+ writeOut,
71
+ writeErr,
72
+ outputError: (s, write) => write(s),
73
+ });
74
+ program
75
+ .command("init <name>")
76
+ .description("scaffold a new NekoStack project from a starter template")
77
+ .allowExcessArguments(false)
78
+ .action(async (name) => {
79
+ const code = await runInit({
80
+ name,
81
+ stdout: writeOut,
82
+ });
83
+ if (code !== EXIT_CODES.SUCCESS) {
84
+ throw new CommandActionError(code);
85
+ }
86
+ });
87
+ // `schema` command group — all four verbs (`list`, `diff`,
88
+ // `check`, `generate`) wired to real dispatches against the
89
+ // schema-side handlers exposed by `@nekostack/schema/cli`.
90
+ const schema = program
91
+ .command("schema")
92
+ .description("schema commands — list / diff / check / generate (v0.7) + migrate (v0.8)")
93
+ .exitOverride()
94
+ .configureOutput({
95
+ writeOut,
96
+ writeErr,
97
+ outputError: (s, write) => write(s),
98
+ });
99
+ schema
100
+ .command("list")
101
+ .description("enumerate registry entries")
102
+ .allowExcessArguments(false)
103
+ .option("--root <path>", "workspace root", process.cwd())
104
+ .option("--json", "machine-readable JSON output", false)
105
+ .option("--quiet", "suppress non-essential stderr output", false)
106
+ .action(async (cmdOpts) => {
107
+ const code = await runList({
108
+ root: cmdOpts.root,
109
+ json: cmdOpts.json,
110
+ quiet: cmdOpts.quiet,
111
+ stdout: writeOut,
112
+ stderr: writeErr,
113
+ });
114
+ if (code !== EXIT_CODES.SUCCESS) {
115
+ throw new CommandActionError(code);
116
+ }
117
+ });
118
+ schema
119
+ .command("diff <a> <b>")
120
+ .description("classify a → b as breaking / additive / cosmetic; <a>/<b> are schemaId / schemaId@version / file path")
121
+ .allowExcessArguments(false)
122
+ .option("--root <path>", "workspace root", process.cwd())
123
+ .option("--json", "machine-readable JSON output", false)
124
+ .action(async (a, b, cmdOpts) => {
125
+ const code = await runDiff({
126
+ root: cmdOpts.root,
127
+ a,
128
+ b,
129
+ json: cmdOpts.json,
130
+ stdout: writeOut,
131
+ stderr: writeErr,
132
+ });
133
+ if (code !== EXIT_CODES.SUCCESS) {
134
+ throw new CommandActionError(code);
135
+ }
136
+ });
137
+ schema
138
+ .command("check [pattern]")
139
+ .description("freshness gate — exit nonzero on stale / breaking / integrity-error artifacts")
140
+ .allowExcessArguments(false)
141
+ .option("--root <path>", "workspace root", process.cwd())
142
+ .option("--json", "machine-readable JSON output", false)
143
+ .option("--quiet", "suppress non-essential stderr output", false)
144
+ .action(async (pattern, cmdOpts) => {
145
+ const code = await runCheck({
146
+ root: cmdOpts.root,
147
+ ...(pattern !== undefined ? { pattern } : {}),
148
+ json: cmdOpts.json,
149
+ quiet: cmdOpts.quiet,
150
+ stdout: writeOut,
151
+ stderr: writeErr,
152
+ });
153
+ if (code !== EXIT_CODES.SUCCESS) {
154
+ throw new CommandActionError(code);
155
+ }
156
+ });
157
+ schema
158
+ .command("generate [pattern]")
159
+ .description("regenerate artifacts for matching schema files")
160
+ .allowExcessArguments(false)
161
+ .option("--root <path>", "workspace root", process.cwd())
162
+ .option("--json", "machine-readable JSON output", false)
163
+ .option("--quiet", "suppress non-essential stderr output", false)
164
+ .action(async (pattern, cmdOpts) => {
165
+ const code = await runGenerate({
166
+ root: cmdOpts.root,
167
+ ...(pattern !== undefined ? { pattern } : {}),
168
+ json: cmdOpts.json,
169
+ quiet: cmdOpts.quiet,
170
+ stdout: writeOut,
171
+ stderr: writeErr,
172
+ });
173
+ if (code !== EXIT_CODES.SUCCESS) {
174
+ throw new CommandActionError(code);
175
+ }
176
+ });
177
+ // ---------------------------------------------------------------------------
178
+ // `schema migrate` subgroup — v0.8 verbs (list / plan / verify / stub).
179
+ //
180
+ // Hard-locked: no `apply` verb, no `--force` flag (`stub` refuses to
181
+ // overwrite unconditionally). `migration.transform` is never invoked
182
+ // here — the four command modules carry static-scan tests proving
183
+ // it, and Master plan Decision #1 plus v0.8 INVARIANTS keep the
184
+ // schema package pure.
185
+ // ---------------------------------------------------------------------------
186
+ const migrate = schema
187
+ .command("migrate")
188
+ .description("v0.8 migrate commands — list / plan / verify / stub")
189
+ .exitOverride()
190
+ .configureOutput({
191
+ writeOut,
192
+ writeErr,
193
+ outputError: (s, write) => write(s),
194
+ });
195
+ migrate
196
+ .command("list")
197
+ .description("enumerate registered migrations")
198
+ .allowExcessArguments(false)
199
+ .option("--root <path>", "workspace root", process.cwd())
200
+ .option("--json", "machine-readable JSON output", false)
201
+ .option("--quiet", "suppress non-essential stderr output", false)
202
+ .action(async (cmdOpts) => {
203
+ const code = await runMigrateList({
204
+ root: cmdOpts.root,
205
+ json: cmdOpts.json,
206
+ quiet: cmdOpts.quiet,
207
+ stdout: writeOut,
208
+ stderr: writeErr,
209
+ });
210
+ if (code !== EXIT_CODES.SUCCESS) {
211
+ throw new CommandActionError(code);
212
+ }
213
+ });
214
+ migrate
215
+ .command("plan <schemaId> <fromVersion> <toVersion>")
216
+ .description("compute the migration chain (or no-migration-needed plan) for a (schemaId, fromVersion, toVersion) triple")
217
+ .allowExcessArguments(false)
218
+ .option("--root <path>", "workspace root", process.cwd())
219
+ .option("--json", "machine-readable JSON output", false)
220
+ .option("--quiet", "suppress non-essential stderr output", false)
221
+ .action(async (schemaId, fromVersion, toVersion, cmdOpts) => {
222
+ const code = await runMigratePlan({
223
+ root: cmdOpts.root,
224
+ schemaId,
225
+ fromVersion,
226
+ toVersion,
227
+ json: cmdOpts.json,
228
+ quiet: cmdOpts.quiet,
229
+ stdout: writeOut,
230
+ stderr: writeErr,
231
+ });
232
+ if (code !== EXIT_CODES.SUCCESS) {
233
+ throw new CommandActionError(code);
234
+ }
235
+ });
236
+ migrate
237
+ .command("verify")
238
+ .description("classify every registered migration as bound / cosmetic_drift / drift / missing_endpoint")
239
+ .allowExcessArguments(false)
240
+ .option("--root <path>", "workspace root", process.cwd())
241
+ .option("--json", "machine-readable JSON output", false)
242
+ .option("--quiet", "suppress non-essential stderr output", false)
243
+ .action(async (cmdOpts) => {
244
+ const code = await runMigrateVerify({
245
+ root: cmdOpts.root,
246
+ json: cmdOpts.json,
247
+ quiet: cmdOpts.quiet,
248
+ stdout: writeOut,
249
+ stderr: writeErr,
250
+ });
251
+ if (code !== EXIT_CODES.SUCCESS) {
252
+ throw new CommandActionError(code);
253
+ }
254
+ });
255
+ migrate
256
+ .command("stub <schemaId> <fromVersion> <toVersion>")
257
+ .description("generate a skeleton migration file (refuses to overwrite an existing file)")
258
+ .allowExcessArguments(false)
259
+ .option("--root <path>", "workspace root", process.cwd())
260
+ .option("--json", "machine-readable JSON output", false)
261
+ .option("--quiet", "suppress non-essential stderr output", false)
262
+ .action(async (schemaId, fromVersion, toVersion, cmdOpts) => {
263
+ const code = await runMigrateStub({
264
+ root: cmdOpts.root,
265
+ schemaId,
266
+ fromVersion,
267
+ toVersion,
268
+ json: cmdOpts.json,
269
+ quiet: cmdOpts.quiet,
270
+ stdout: writeOut,
271
+ stderr: writeErr,
272
+ });
273
+ if (code !== EXIT_CODES.SUCCESS) {
274
+ throw new CommandActionError(code);
275
+ }
276
+ });
277
+ return program;
278
+ }
279
+ /**
280
+ * Carries a chosen `ExitCode` out of a commander `.action()` callback.
281
+ * Action callbacks can't return values that commander surfaces, so a
282
+ * non-zero outcome travels back to `dispatch()` via a throw. The
283
+ * error is plain control-flow — never logged or surfaced to the user.
284
+ */
285
+ class CommandActionError extends Error {
286
+ exitCode;
287
+ constructor(exitCode) {
288
+ super(`Command action returned exit code ${exitCode}`);
289
+ this.exitCode = exitCode;
290
+ this.name = "CommandActionError";
291
+ }
292
+ }
293
+ // =============================================================================
294
+ // Dispatch
295
+ // =============================================================================
296
+ /**
297
+ * Parse `argv` (the user-supplied arguments — what would normally be
298
+ * `process.argv.slice(2)`) and run the matched command. Returns the
299
+ * intended exit code; never calls `process.exit`. The bin entry's
300
+ * `run()` wraps this to actually exit the process.
301
+ *
302
+ * The `writers` slice lets the in-process test harness capture stdout
303
+ * / stderr by passing string-collector functions. When omitted,
304
+ * commander writes through `process.stdout` / `process.stderr` as
305
+ * usual.
306
+ */
307
+ export async function dispatch(argv, opts = {}) {
308
+ const program = buildCli(opts);
309
+ try {
310
+ await program.parseAsync(argv, { from: "user" });
311
+ return EXIT_CODES.SUCCESS;
312
+ }
313
+ catch (err) {
314
+ if (err instanceof CommandActionError) {
315
+ return err.exitCode;
316
+ }
317
+ if (err instanceof CommanderError) {
318
+ return mapCommanderError(err);
319
+ }
320
+ // Unexpected programmer error — re-throw so it surfaces during
321
+ // development. The CLI dispatch path will gain an explicit
322
+ // "unexpected error" mapping when a real verb introduces a
323
+ // surface that could throw beyond `Issue`s.
324
+ throw err;
325
+ }
326
+ }
327
+ function mapCommanderError(err) {
328
+ // commander's own codes for help / version are success.
329
+ if (err.code === "commander.helpDisplayed" ||
330
+ err.code === "commander.help" ||
331
+ err.code === "commander.version") {
332
+ return EXIT_CODES.SUCCESS;
333
+ }
334
+ // Everything else commander reports is an argv-shape problem — bad
335
+ // flag, missing argument, unknown command, unknown option, etc.
336
+ return EXIT_CODES.USAGE_ERROR;
337
+ }
338
+ // =============================================================================
339
+ // Bin entry
340
+ // =============================================================================
341
+ /**
342
+ * Production entry — called by `bin/neko`. Dispatches and calls
343
+ * `process.exit` with the returned code. Never returns.
344
+ *
345
+ * Tests do NOT call this — they call `dispatch` directly and assert
346
+ * on the returned `ExitCode`. The CLI plan's Decision #9 (in-process
347
+ * harness) explicitly avoids subprocess spawn, so the only path that
348
+ * touches `process.exit` is this one, and it's called only when the
349
+ * bin shebang script imports the built `dist/cli.js`.
350
+ */
351
+ export async function run(argv = process.argv) {
352
+ const code = await dispatch(argv.slice(2));
353
+ process.exit(code);
354
+ }
355
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { type ExitCode } from "../exit-codes.js";
2
+ export interface InitOptions {
3
+ name: string;
4
+ cwd?: string;
5
+ stdout?: (s: string) => void;
6
+ }
7
+ export declare function runInit(opts: InitOptions): Promise<ExitCode>;
8
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAMD,wBAAsB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAMlE"}
@@ -0,0 +1,11 @@
1
+ import { EXIT_CODES } from "../exit-codes.js";
2
+ // neko init requires the NekoStack monorepo in v1.0 (the project templates
3
+ // and the @nekostack/templates scaffolder are not yet published to npm).
4
+ // The command is registered so help text and command discovery work correctly;
5
+ // the implementation will be wired in a future release once those packages ship.
6
+ export async function runInit(opts) {
7
+ process.stderr.write("neko init is not yet available in the standalone npm package.\n" +
8
+ "Use the NekoStack monorepo directly: https://github.com/cmclicker/NekoStack\n");
9
+ return EXIT_CODES.LOGICAL_FAILURE;
10
+ }
11
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAiB,MAAM,kBAAkB,CAAC;AAQ7D,2EAA2E;AAC3E,yEAAyE;AACzE,+EAA+E;AAC/E,iFAAiF;AACjF,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiB;IAC7C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,iEAAiE;QAC/D,+EAA+E,CAClF,CAAC;IACF,OAAO,UAAU,CAAC,eAAe,CAAC;AACpC,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * `neko schema check [pattern]` command implementation (v0.7 Step 31).
3
+ *
4
+ * Third real schema verb. Replaces the Step 25 placeholder.
5
+ *
6
+ * Flow:
7
+ * 1. Walk the workspace + build the registry (shared prelude with
8
+ * `list` / `diff`).
9
+ * 2. Compute the set of generated/ directories implied by the
10
+ * loaded source files: for every `<dir>/<basename>.schema.ts`,
11
+ * `<dir>/generated/` is read. The set is deduplicated so a
12
+ * workspace with N schemas in one directory only reads
13
+ * `<dir>/generated/` once.
14
+ * 3. `loadCommittedArtifacts` reads each generated/ directory.
15
+ * Per-artifact paths are re-prefixed with their source
16
+ * directory so the merged `CommittedArtifact[]` has unique
17
+ * workspace-relative paths (otherwise two `user.types.ts`
18
+ * files in different subtrees would collide).
19
+ * 4. `checkHandler({ registry, committedArtifacts })` classifies
20
+ * each artifact via the two-hash matrix.
21
+ * 5. Format + exit:
22
+ * - `--json` → `{ verdicts, summary: { clean, cosmetic_drift,
23
+ * stale, integrity_error } }` to stdout.
24
+ * - default → per-status tally header + verdict rows via
25
+ * `formatCheckPretty`.
26
+ * - any `integrity_error` → `INTEGRITY_ERROR` (4).
27
+ * - any `stale` → `LOGICAL_FAILURE` (1).
28
+ * - otherwise (only `clean` / `cosmetic_drift` / empty) →
29
+ * `SUCCESS` (0).
30
+ *
31
+ * `--quiet` suppresses non-essential stderr only (v0.7 doesn't yet
32
+ * produce any non-essential stderr from this verb, but the flag is
33
+ * accepted for forward compatibility with the locked CLI surface).
34
+ * The primary verdict output goes to stdout in both pretty and JSON
35
+ * modes and is NEVER suppressed.
36
+ *
37
+ * Pure: no `process.exit`, no `console.*`, no direct `process.stdout`
38
+ * / `process.stderr` writes. The caller injects writers.
39
+ *
40
+ * `checkHandler` failures classify in two layers:
41
+ * - any issue with `code === "integrity_error"` → INTEGRITY_ERROR
42
+ * - everything else (schema_not_found, version_not_found) →
43
+ * LOGICAL_FAILURE
44
+ */
45
+ import { type ExitCode } from "../../exit-codes.js";
46
+ export interface RunCheckOptions {
47
+ readonly root: string;
48
+ readonly pattern?: string;
49
+ readonly json: boolean;
50
+ readonly quiet: boolean;
51
+ readonly stdout: (s: string) => void;
52
+ readonly stderr: (s: string) => void;
53
+ }
54
+ export declare function runCheck(opts: RunCheckOptions): Promise<ExitCode>;
55
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../src/commands/schema/check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAWH,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAehE,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,QAAQ,CAAC,CA8CvE"}
@@ -0,0 +1,197 @@
1
+ /**
2
+ * `neko schema check [pattern]` command implementation (v0.7 Step 31).
3
+ *
4
+ * Third real schema verb. Replaces the Step 25 placeholder.
5
+ *
6
+ * Flow:
7
+ * 1. Walk the workspace + build the registry (shared prelude with
8
+ * `list` / `diff`).
9
+ * 2. Compute the set of generated/ directories implied by the
10
+ * loaded source files: for every `<dir>/<basename>.schema.ts`,
11
+ * `<dir>/generated/` is read. The set is deduplicated so a
12
+ * workspace with N schemas in one directory only reads
13
+ * `<dir>/generated/` once.
14
+ * 3. `loadCommittedArtifacts` reads each generated/ directory.
15
+ * Per-artifact paths are re-prefixed with their source
16
+ * directory so the merged `CommittedArtifact[]` has unique
17
+ * workspace-relative paths (otherwise two `user.types.ts`
18
+ * files in different subtrees would collide).
19
+ * 4. `checkHandler({ registry, committedArtifacts })` classifies
20
+ * each artifact via the two-hash matrix.
21
+ * 5. Format + exit:
22
+ * - `--json` → `{ verdicts, summary: { clean, cosmetic_drift,
23
+ * stale, integrity_error } }` to stdout.
24
+ * - default → per-status tally header + verdict rows via
25
+ * `formatCheckPretty`.
26
+ * - any `integrity_error` → `INTEGRITY_ERROR` (4).
27
+ * - any `stale` → `LOGICAL_FAILURE` (1).
28
+ * - otherwise (only `clean` / `cosmetic_drift` / empty) →
29
+ * `SUCCESS` (0).
30
+ *
31
+ * `--quiet` suppresses non-essential stderr only (v0.7 doesn't yet
32
+ * produce any non-essential stderr from this verb, but the flag is
33
+ * accepted for forward compatibility with the locked CLI surface).
34
+ * The primary verdict output goes to stdout in both pretty and JSON
35
+ * modes and is NEVER suppressed.
36
+ *
37
+ * Pure: no `process.exit`, no `console.*`, no direct `process.stdout`
38
+ * / `process.stderr` writes. The caller injects writers.
39
+ *
40
+ * `checkHandler` failures classify in two layers:
41
+ * - any issue with `code === "integrity_error"` → INTEGRITY_ERROR
42
+ * - everything else (schema_not_found, version_not_found) →
43
+ * LOGICAL_FAILURE
44
+ */
45
+ import { isAbsolute, resolve, sep } from "node:path";
46
+ import { buildRegistry, checkHandler, } from "@nekostack/schema/cli";
47
+ import { EXIT_CODES } from "../../exit-codes.js";
48
+ import { formatJson } from "../../formatters/json.js";
49
+ import { formatCheckPretty, formatIssuesPretty, formatLoadFailuresPretty, } from "../../formatters/pretty.js";
50
+ import { loadCommittedArtifacts } from "../../loaders/read-artifacts.js";
51
+ import { walkWorkspace } from "../../loaders/walk-workspace.js";
52
+ export async function runCheck(opts) {
53
+ // 1. Walk + buildRegistry prelude.
54
+ const walk = await walkWorkspace({
55
+ root: opts.root,
56
+ ...(opts.pattern !== undefined ? { pattern: opts.pattern } : {}),
57
+ });
58
+ if (walk.failures.length > 0) {
59
+ writeLoadFailures(opts, walk.failures);
60
+ return EXIT_CODES.IO_ERROR;
61
+ }
62
+ const reg = buildRegistry(walk.entries);
63
+ if (!reg.success) {
64
+ writeIssues(opts, reg.issues);
65
+ return EXIT_CODES.LOGICAL_FAILURE;
66
+ }
67
+ // 2. Read committed artifacts from each implied generated/ dir.
68
+ const rootAbs = isAbsolute(opts.root) ? opts.root : resolve(opts.root);
69
+ const committedArtifacts = await readWorkspaceArtifacts(rootAbs, walk.entries);
70
+ // 3. Run the freshness handler.
71
+ const result = checkHandler({
72
+ registry: reg.data,
73
+ committedArtifacts,
74
+ });
75
+ if (!result.success) {
76
+ writeIssues(opts, result.issues);
77
+ return pickHandlerFailureExitCode(result.issues);
78
+ }
79
+ // 4. Format output + pick exit code from verdicts.
80
+ const summary = tallyVerdicts(result.data.verdicts);
81
+ if (opts.json) {
82
+ opts.stdout(formatJson({
83
+ verdicts: result.data.verdicts,
84
+ summary,
85
+ }));
86
+ }
87
+ else {
88
+ opts.stdout(formatCheckPretty(result.data.verdicts));
89
+ }
90
+ return pickVerdictExitCode(summary);
91
+ }
92
+ // =============================================================================
93
+ // Generated-directory discovery + artifact merge
94
+ // =============================================================================
95
+ /**
96
+ * Compute the set of `<source-dir>/generated/` directories implied
97
+ * by the loaded entries, read each via {@link loadCommittedArtifacts},
98
+ * and merge into one workspace-relative `CommittedArtifact[]`. Each
99
+ * artifact's `path` is re-prefixed with the workspace-relative
100
+ * generated-directory so paths are unique across the workspace.
101
+ */
102
+ async function readWorkspaceArtifacts(rootAbs, entries) {
103
+ // Compute and dedupe `<dir>/generated/` per entry. `sourcePath` is
104
+ // workspace-relative forward-slash; we slice off the basename and
105
+ // append "generated".
106
+ const generatedRelDirs = new Set();
107
+ for (const entry of entries) {
108
+ const sourcePath = entry.sourcePath;
109
+ const lastSlash = sourcePath.lastIndexOf("/");
110
+ const dir = lastSlash >= 0 ? sourcePath.slice(0, lastSlash) : "";
111
+ const generated = dir === "" ? "generated" : `${dir}/generated`;
112
+ generatedRelDirs.add(generated);
113
+ }
114
+ const out = [];
115
+ for (const relDir of generatedRelDirs) {
116
+ const absDir = resolve(rootAbs, relDir.split("/").join(sep));
117
+ const arts = await loadCommittedArtifacts(absDir);
118
+ for (const a of arts) {
119
+ // `loadCommittedArtifacts` returns paths relative to `absDir`.
120
+ // Re-prefix with `relDir` to produce a workspace-relative path,
121
+ // forward-slash normalized.
122
+ out.push({
123
+ path: `${relDir}/${a.path}`,
124
+ content: a.content,
125
+ });
126
+ }
127
+ }
128
+ return out;
129
+ }
130
+ function tallyVerdicts(verdicts) {
131
+ let clean = 0;
132
+ let cosmeticDrift = 0;
133
+ let stale = 0;
134
+ let integrityError = 0;
135
+ for (const v of verdicts) {
136
+ switch (v.status) {
137
+ case "clean":
138
+ clean += 1;
139
+ break;
140
+ case "cosmetic_drift":
141
+ cosmeticDrift += 1;
142
+ break;
143
+ case "stale":
144
+ stale += 1;
145
+ break;
146
+ case "integrity_error":
147
+ integrityError += 1;
148
+ break;
149
+ }
150
+ }
151
+ return {
152
+ clean,
153
+ cosmetic_drift: cosmeticDrift,
154
+ stale,
155
+ integrity_error: integrityError,
156
+ };
157
+ }
158
+ function pickVerdictExitCode(summary) {
159
+ if (summary.integrity_error > 0)
160
+ return EXIT_CODES.INTEGRITY_ERROR;
161
+ if (summary.stale > 0)
162
+ return EXIT_CODES.LOGICAL_FAILURE;
163
+ return EXIT_CODES.SUCCESS;
164
+ }
165
+ function pickHandlerFailureExitCode(issues) {
166
+ for (const i of issues) {
167
+ if (i.code === "integrity_error")
168
+ return EXIT_CODES.INTEGRITY_ERROR;
169
+ }
170
+ return EXIT_CODES.LOGICAL_FAILURE;
171
+ }
172
+ // =============================================================================
173
+ // Failure output helpers
174
+ // =============================================================================
175
+ function writeLoadFailures(opts, failures) {
176
+ if (opts.json) {
177
+ opts.stdout(formatJson({
178
+ failures: failures.map((f) => ({
179
+ path: f.path,
180
+ reason: f.reason,
181
+ message: f.message,
182
+ })),
183
+ }));
184
+ }
185
+ else {
186
+ opts.stderr(formatLoadFailuresPretty(failures));
187
+ }
188
+ }
189
+ function writeIssues(opts, issues) {
190
+ if (opts.json) {
191
+ opts.stdout(formatJson({ issues }));
192
+ }
193
+ else {
194
+ opts.stderr(formatIssuesPretty(issues));
195
+ }
196
+ }
197
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/commands/schema/check.ts"],"names":[],"mappings":"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"}