ttsc 0.12.4 → 0.13.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 (52) hide show
  1. package/cmd/ttsc/api_compile.go +15 -2
  2. package/cmd/ttsc/api_transform.go +15 -2
  3. package/cmd/ttsc/build.go +34 -4
  4. package/cmd/ttsc/filter.go +70 -0
  5. package/cmd/ttsc/filter_strips_unknown_forwarded_flag_test.go +61 -0
  6. package/cmd/ttsc/flags_gen.go +30 -0
  7. package/driver/program.go +105 -4
  8. package/driver/rewrite.go +39 -4
  9. package/lib/compiler/internal/project/resolveProjectConfig.js +18 -0
  10. package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
  11. package/lib/compiler/internal/runBuild.d.ts +5 -4
  12. package/lib/compiler/internal/runBuild.js +243 -47
  13. package/lib/compiler/internal/runBuild.js.map +1 -1
  14. package/lib/flags/parser.d.ts +63 -0
  15. package/lib/flags/parser.js +254 -0
  16. package/lib/flags/parser.js.map +1 -0
  17. package/lib/flags/schema.d.ts +147 -0
  18. package/lib/flags/schema.js +405 -0
  19. package/lib/flags/schema.js.map +1 -0
  20. package/lib/launcher/internal/prepareExecution.js +3 -0
  21. package/lib/launcher/internal/prepareExecution.js.map +1 -1
  22. package/lib/launcher/internal/runTtsc.js +71 -147
  23. package/lib/launcher/internal/runTtsc.js.map +1 -1
  24. package/lib/launcher/internal/runTtsx.js +104 -72
  25. package/lib/launcher/internal/runTtsx.js.map +1 -1
  26. package/lib/plugin/internal/loadProjectPlugins.js +58 -23
  27. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
  28. package/lib/structures/ITtscPlugin.d.ts +24 -0
  29. package/lib/structures/ITtscPluginCapabilities.d.ts +29 -0
  30. package/lib/structures/ITtscPluginCapabilities.js +3 -0
  31. package/lib/structures/ITtscPluginCapabilities.js.map +1 -0
  32. package/lib/structures/index.d.ts +1 -0
  33. package/lib/structures/index.js +1 -0
  34. package/lib/structures/index.js.map +1 -1
  35. package/lib/structures/internal/ITtscLoadedNativePlugin.d.ts +5 -0
  36. package/lib/structures/internal/TtscCommonOptions.d.ts +19 -0
  37. package/package.json +9 -9
  38. package/src/compiler/internal/project/resolveProjectConfig.ts +20 -0
  39. package/src/compiler/internal/runBuild.ts +288 -57
  40. package/src/flags/parser.ts +367 -0
  41. package/src/flags/schema.ts +570 -0
  42. package/src/launcher/internal/prepareExecution.ts +3 -0
  43. package/src/launcher/internal/runTtsc.ts +78 -136
  44. package/src/launcher/internal/runTtsx.ts +116 -74
  45. package/src/plugin/internal/loadProjectPlugins.ts +74 -27
  46. package/src/structures/ITtscPlugin.ts +26 -0
  47. package/src/structures/ITtscPluginCapabilities.ts +29 -0
  48. package/src/structures/index.ts +1 -0
  49. package/src/structures/internal/ITtscLoadedNativePlugin.ts +5 -0
  50. package/src/structures/internal/TtscCommonOptions.ts +19 -0
  51. package/utility/flags_gen.go +30 -0
  52. package/utility/host.go +43 -33
@@ -0,0 +1,570 @@
1
+ // SOURCE-OF-TRUTH FLAG SCHEMA for the ttsc / ttsx command-line surface.
2
+ //
3
+ // One declaration per flag, consumed by every layer that needs to know about
4
+ // the flag:
5
+ //
6
+ // * `packages/ttsc/src/flags/parser.ts` — runtime TS parsing engine used
7
+ // by `runTtsc.ts` and `runTtsx.ts`.
8
+ // * `packages/ttsc/scripts/gen-flags.cjs` — codegen that emits Go
9
+ // allow-lists and the docs table.
10
+ // * `packages/ttsc/cmd/ttsc/flags_gen.go` — generated Go allow-list shared
11
+ // by `cmd/ttsc/*.go` and
12
+ // `utility/host.go`.
13
+ // * `packages/lint/linthost/flags_gen.go` — generated Go allow-list shared
14
+ // by lint subcommand parsers.
15
+ // * `website/src/content/docs/ttsc/flags.mdx` — generated reference table.
16
+ //
17
+ // The generator runs from `pnpm format`; its committed output is the spec the
18
+ // Go side reads, just like the `gen_shims:hand-maintained` pattern from
19
+ // AGENTS.md §2.1. Editing the generated files by hand is rejected by the
20
+ // `format` check.
21
+
22
+ /**
23
+ * Subcommands the ttsc CLI dispatches to. The bare `"ttsc"` entry covers the
24
+ * default lane (no explicit subcommand, e.g. `ttsc -p tsconfig.json`).
25
+ */
26
+ export type TtscSubcommand =
27
+ | "ttsc"
28
+ | "build"
29
+ | "check"
30
+ | "fix"
31
+ | "format"
32
+ | "prepare"
33
+ | "clean";
34
+
35
+ /**
36
+ * Subcommands the ttsx CLI dispatches to. ttsx exposes a single lane today
37
+ * but the schema mirrors ttsc's shape so future subcommands plug in without a
38
+ * second engine.
39
+ */
40
+ export type TtsxSubcommand = "ttsx";
41
+
42
+ export type AnySubcommand = TtscSubcommand | TtsxSubcommand;
43
+
44
+ /**
45
+ * Layers a flag can be consumed by. The order reflects the runtime pipeline:
46
+ *
47
+ * launcher → runBuild → tsgo / native sidecars (host, lint).
48
+ *
49
+ * A flag must declare at least one consumer. `forwardTo` declares where the
50
+ * flag travels when the consuming layer does not absorb it (e.g. ttsc-owned
51
+ * flags that the JS launcher consumes and re-emits as different tsgo flags).
52
+ */
53
+ export type FlagLayer =
54
+ | "launcher" // JS layer (`runTtsc.ts` / `runTtsx.ts`)
55
+ | "runBuild" // JS layer (`runBuild.ts`) — internally adds the flag to tsgo
56
+ | "tsgo" // tsgo binary (TypeScript-Go option parser)
57
+ | "host" // native shared host (`utility/host.go`, `cmd/ttsc/build.go`)
58
+ | "lint"; // native lint subcommand (`packages/lint/linthost/*.go`)
59
+
60
+ /**
61
+ * Argument shape of a flag.
62
+ *
63
+ * * `boolean` — `--flag` / `--flag=true` / `--flag=false`. No value
64
+ * token is consumed.
65
+ * * `value` — `--flag value` or `--flag=value`. Required value.
66
+ * * `valueOptional` — `--flag` standalone is allowed; if followed by a
67
+ * non-flag token that token is consumed as the value.
68
+ * (Currently unused — declared for future flags like
69
+ * `--watch [path]`.)
70
+ */
71
+ export type FlagKind = "boolean" | "value" | "valueOptional";
72
+
73
+ /**
74
+ * Validation predicate for `value`-kind flags. `none` is the default
75
+ * (accept any string).
76
+ */
77
+ export type ValueValidator = "none" | "positiveInt";
78
+
79
+ /**
80
+ * One CLI flag's complete contract. Every layer's behaviour is structural —
81
+ * which subcommands accept the flag, where it is consumed, where it is
82
+ * forwarded, whether it is terminal (prints and exits) — so the next layer
83
+ * never silently drops the flag.
84
+ */
85
+ export interface FlagSpec {
86
+ /**
87
+ * Canonical flag name including leading dashes (`"--singleThreaded"`). The
88
+ * generator uses this as the map key in the Go allow-list and as the first
89
+ * column of the docs table.
90
+ */
91
+ readonly name: string;
92
+
93
+ /**
94
+ * Alternative spellings (`"-p"`, `"--project"` for `--tsconfig`). The
95
+ * parsing engine treats every alias as an equivalent of `name`.
96
+ */
97
+ readonly aliases?: readonly string[];
98
+
99
+ /** Argument shape: boolean / required value / optional value. */
100
+ readonly kind: FlagKind;
101
+
102
+ /**
103
+ * For `value` flags: optional validator. `positiveInt` mirrors the
104
+ * `--checkers minValue:1` constraint tsgo enforces.
105
+ */
106
+ readonly validator?: ValueValidator;
107
+
108
+ /** Subcommands that accept this flag. */
109
+ readonly subcommands: readonly AnySubcommand[];
110
+
111
+ /**
112
+ * Layers that read the flag into a typed option. Order matters only for
113
+ * documentation; the parsing engine merges across layers.
114
+ */
115
+ readonly consumedBy: readonly FlagLayer[];
116
+
117
+ /**
118
+ * Where the flag travels when the consuming layer does not absorb it.
119
+ * Default for any flag a layer does not consume is `"tsgo"` — i.e. the
120
+ * launcher forwards an unknown flag to tsgo via passthrough. Setting this
121
+ * to `undefined` while `consumedBy: ["launcher"]` is set means the flag is
122
+ * intentionally consumed-not-forwarded (e.g. ttsc-internal `--binary`).
123
+ */
124
+ readonly forwardTo?: FlagLayer;
125
+
126
+ /**
127
+ * Terminal flags ask the underlying tool to print something and exit
128
+ * (`--help`, `--version`, `--showConfig`, `--listFilesOnly`, `--all`,
129
+ * `--init`). ttsc must not wrap them in a pre-emit pass — that is how the
130
+ * `--showConfig prints twice` bug appeared (RC-2).
131
+ */
132
+ readonly terminal?: boolean;
133
+
134
+ /**
135
+ * `true` when ttsc may add this flag to tsgo internally and post-process
136
+ * the output. If the user also forwards the same flag, ttsc keeps the
137
+ * user-visible behaviour (no double-print, no swallowed output). The
138
+ * shadow check is structural rather than `passthrough.includes("…")`.
139
+ *
140
+ * Currently true for `--listEmittedFiles`, `--noEmit`, `--pretty`.
141
+ */
142
+ readonly internalShadow?: boolean;
143
+
144
+ /**
145
+ * Reserved for future use: native hosts that opt in via
146
+ * `capabilities.threadingArgs`. The flag travels to such hosts as a bare
147
+ * CLI argument; everything else routes through `--tsgo-args`.
148
+ */
149
+ readonly nativeCapability?: "threadingArgs";
150
+
151
+ /** Human description for `--help` and the docs table. */
152
+ readonly description: string;
153
+ }
154
+
155
+ /**
156
+ * Single source of truth for every flag the ttsc / ttsx CLI accepts. New
157
+ * flags are added here and only here; the generator rebuilds the parsers and
158
+ * the Go allow-lists from this table.
159
+ *
160
+ * Constraints enforced by the parser and the generator:
161
+ *
162
+ * 1. Every flag is uniquely identified by `name`; aliases must not collide
163
+ * with other flags' `name` or `aliases`.
164
+ * 2. A flag listed in `consumedBy: ["launcher"]` without a `forwardTo`
165
+ * consumes-not-forwards. The generator flags this in the docs and the
166
+ * Go allow-list so the boundary is explicit.
167
+ * 3. A flag with `subcommands` covering `clean` or `prepare` is parsed by
168
+ * the project-args lane; the parsing engine accepts the same flag in
169
+ * build / check / fix / format without a separate parser.
170
+ */
171
+ export const FLAG_SCHEMA: readonly FlagSpec[] = [
172
+ // -------------------------------------------------------------------------
173
+ // ttsc — terminal flags (print and exit; never wrapped in pre-emit pass)
174
+ // -------------------------------------------------------------------------
175
+ {
176
+ name: "--help",
177
+ aliases: ["-h"],
178
+ kind: "boolean",
179
+ subcommands: ["ttsc", "ttsx", "build", "check", "fix", "format"],
180
+ consumedBy: ["launcher"],
181
+ terminal: true,
182
+ description: "Show command help and exit.",
183
+ },
184
+ {
185
+ name: "--version",
186
+ aliases: ["-v"],
187
+ kind: "boolean",
188
+ subcommands: ["ttsc", "ttsx"],
189
+ consumedBy: ["launcher"],
190
+ terminal: true,
191
+ description: "Print the launcher version and exit.",
192
+ },
193
+
194
+ // -------------------------------------------------------------------------
195
+ // Project location: shared by every subcommand.
196
+ // -------------------------------------------------------------------------
197
+ {
198
+ name: "--tsconfig",
199
+ aliases: ["-p", "--project"],
200
+ kind: "value",
201
+ subcommands: [
202
+ "ttsc",
203
+ "ttsx",
204
+ "build",
205
+ "check",
206
+ "fix",
207
+ "format",
208
+ "prepare",
209
+ "clean",
210
+ ],
211
+ consumedBy: ["launcher", "host", "lint"],
212
+ description: "Resolve project settings from this tsconfig.",
213
+ },
214
+ {
215
+ name: "--cwd",
216
+ kind: "value",
217
+ subcommands: [
218
+ "ttsc",
219
+ "ttsx",
220
+ "build",
221
+ "check",
222
+ "fix",
223
+ "format",
224
+ "prepare",
225
+ "clean",
226
+ ],
227
+ consumedBy: ["launcher", "host", "lint"],
228
+ description: "Resolve project-relative paths from this directory.",
229
+ },
230
+
231
+ // -------------------------------------------------------------------------
232
+ // Emit / build mode.
233
+ // -------------------------------------------------------------------------
234
+ {
235
+ name: "--emit",
236
+ kind: "boolean",
237
+ subcommands: ["ttsc", "build", "check"],
238
+ consumedBy: ["launcher", "runBuild", "host", "lint"],
239
+ description: "Force emitted files during build.",
240
+ },
241
+ {
242
+ name: "--noEmit",
243
+ kind: "boolean",
244
+ subcommands: ["ttsc", "build", "check"],
245
+ consumedBy: ["launcher", "runBuild", "host", "lint"],
246
+ internalShadow: true,
247
+ description: "Force analysis-only build with no file writes.",
248
+ },
249
+ {
250
+ name: "--outDir",
251
+ kind: "value",
252
+ subcommands: ["ttsc", "build", "check"],
253
+ consumedBy: ["launcher", "host", "lint"],
254
+ description: "Override compilerOptions.outDir for this invocation.",
255
+ },
256
+
257
+ // -------------------------------------------------------------------------
258
+ // Watch mode (launcher only).
259
+ // -------------------------------------------------------------------------
260
+ {
261
+ name: "--watch",
262
+ aliases: ["-w"],
263
+ kind: "boolean",
264
+ subcommands: ["ttsc", "build", "check"],
265
+ consumedBy: ["launcher"],
266
+ description: "Rebuild when project files change.",
267
+ },
268
+ {
269
+ name: "--preserveWatchOutput",
270
+ kind: "boolean",
271
+ subcommands: ["ttsc", "build", "check"],
272
+ consumedBy: ["launcher"],
273
+ description: "Do not clear the screen between watch rebuilds.",
274
+ },
275
+
276
+ // -------------------------------------------------------------------------
277
+ // Output verbosity.
278
+ // -------------------------------------------------------------------------
279
+ {
280
+ name: "--quiet",
281
+ kind: "boolean",
282
+ subcommands: ["ttsc", "build", "check", "fix", "format"],
283
+ consumedBy: ["launcher", "host", "lint"],
284
+ description: "Keep build output quiet (default).",
285
+ },
286
+ {
287
+ name: "--verbose",
288
+ kind: "boolean",
289
+ subcommands: ["ttsc", "build", "check", "fix", "format"],
290
+ consumedBy: ["launcher", "host", "lint"],
291
+ description: "Print the build summary and emitted files.",
292
+ },
293
+
294
+ // -------------------------------------------------------------------------
295
+ // tsgo-binary / cache plumbing (consumed by launcher, not forwarded).
296
+ // -------------------------------------------------------------------------
297
+ {
298
+ name: "--binary",
299
+ kind: "value",
300
+ subcommands: [
301
+ "ttsc",
302
+ "ttsx",
303
+ "build",
304
+ "check",
305
+ "fix",
306
+ "format",
307
+ "prepare",
308
+ "clean",
309
+ ],
310
+ consumedBy: ["launcher"],
311
+ description: "Use an explicit tsgo binary.",
312
+ },
313
+ {
314
+ name: "--cache-dir",
315
+ kind: "value",
316
+ subcommands: [
317
+ "ttsc",
318
+ "ttsx",
319
+ "build",
320
+ "check",
321
+ "fix",
322
+ "format",
323
+ "prepare",
324
+ "clean",
325
+ ],
326
+ consumedBy: ["launcher"],
327
+ description: "Override the runner and source-plugin cache root.",
328
+ },
329
+
330
+ // -------------------------------------------------------------------------
331
+ // Threading (tsgo-native; lint host opts in via capability).
332
+ // -------------------------------------------------------------------------
333
+ {
334
+ name: "--singleThreaded",
335
+ kind: "boolean",
336
+ subcommands: ["ttsc", "ttsx", "build", "check", "fix", "format"],
337
+ consumedBy: ["launcher", "runBuild", "tsgo", "host", "lint"],
338
+ nativeCapability: "threadingArgs",
339
+ description: "Run TypeScript-Go single-threaded (one checker).",
340
+ },
341
+ {
342
+ name: "--checkers",
343
+ kind: "value",
344
+ validator: "positiveInt",
345
+ subcommands: ["ttsc", "ttsx", "build", "check", "fix", "format"],
346
+ consumedBy: ["launcher", "runBuild", "tsgo", "host", "lint"],
347
+ nativeCapability: "threadingArgs",
348
+ description: "Type-checker pool size (default: TypeScript-Go's).",
349
+ },
350
+
351
+ // -------------------------------------------------------------------------
352
+ // ttsx-specific options.
353
+ // -------------------------------------------------------------------------
354
+ {
355
+ name: "--require",
356
+ aliases: ["-r"],
357
+ kind: "value",
358
+ subcommands: ["ttsx"],
359
+ consumedBy: ["launcher"],
360
+ description: "Preload a module before the entrypoint (ttsx).",
361
+ },
362
+ {
363
+ name: "--no-plugins",
364
+ kind: "boolean",
365
+ subcommands: ["ttsx"],
366
+ consumedBy: ["launcher"],
367
+ description: "Build the project without ttsc plugins (ttsx).",
368
+ },
369
+
370
+ // -------------------------------------------------------------------------
371
+ // tsgo-internal flags ttsc adds itself; users may also forward them.
372
+ // Declaring them keeps the launcher's parser from treating them as
373
+ // unknown forwarded flags whose value token gets misclassified.
374
+ // -------------------------------------------------------------------------
375
+ {
376
+ name: "--listEmittedFiles",
377
+ kind: "boolean",
378
+ subcommands: ["ttsc", "build", "check"],
379
+ consumedBy: ["runBuild", "tsgo"],
380
+ forwardTo: "tsgo",
381
+ internalShadow: true,
382
+ description:
383
+ "Print the list of emitted files (forwarded to tsgo; ttsc keeps the lines when forwarded).",
384
+ },
385
+ {
386
+ name: "--pretty",
387
+ kind: "value",
388
+ subcommands: ["ttsc", "ttsx", "build", "check", "fix", "format"],
389
+ consumedBy: ["tsgo"],
390
+ forwardTo: "tsgo",
391
+ internalShadow: true,
392
+ description: "Toggle tsgo pretty-printed diagnostics (forwarded to tsgo).",
393
+ },
394
+ {
395
+ name: "--showConfig",
396
+ kind: "boolean",
397
+ subcommands: ["ttsc", "build", "check"],
398
+ consumedBy: ["tsgo"],
399
+ forwardTo: "tsgo",
400
+ terminal: true,
401
+ description: "Print the resolved tsconfig and exit (forwarded to tsgo).",
402
+ },
403
+ {
404
+ name: "--listFilesOnly",
405
+ kind: "boolean",
406
+ subcommands: ["ttsc", "build", "check"],
407
+ consumedBy: ["tsgo"],
408
+ forwardTo: "tsgo",
409
+ terminal: true,
410
+ description: "Print the project file list and exit (forwarded to tsgo).",
411
+ },
412
+ {
413
+ name: "--all",
414
+ kind: "boolean",
415
+ subcommands: ["ttsc", "build", "check"],
416
+ consumedBy: ["tsgo"],
417
+ forwardTo: "tsgo",
418
+ terminal: true,
419
+ description: "Print the full tsgo CLI help and exit.",
420
+ },
421
+ {
422
+ name: "--init",
423
+ kind: "boolean",
424
+ subcommands: ["ttsc", "build", "check"],
425
+ consumedBy: ["tsgo"],
426
+ forwardTo: "tsgo",
427
+ terminal: true,
428
+ description: "Write a starter tsconfig.json and exit (forwarded to tsgo).",
429
+ },
430
+
431
+ // -------------------------------------------------------------------------
432
+ // `--tsgo-args` — JSON-encoded passthrough envelope the launcher emits on
433
+ // the way down to native sidecars. The sidecars decode it back into the
434
+ // tsgo argv. Listed here so the schema describes every flag the Go layers
435
+ // accept, not just the user-facing ones.
436
+ // -------------------------------------------------------------------------
437
+ {
438
+ name: "--tsgo-args",
439
+ kind: "value",
440
+ subcommands: [
441
+ "ttsc",
442
+ "build",
443
+ "check",
444
+ "fix",
445
+ "format",
446
+ "prepare",
447
+ "clean",
448
+ ],
449
+ consumedBy: ["host", "lint"],
450
+ description:
451
+ "JSON-encoded tsgo passthrough argv (internal: emitted by runBuild).",
452
+ },
453
+ {
454
+ name: "--plugins-json",
455
+ kind: "value",
456
+ subcommands: ["build", "check", "fix", "format"],
457
+ consumedBy: ["host", "lint"],
458
+ description:
459
+ "JSON-encoded ttsc plugin manifest (internal: emitted by runBuild).",
460
+ },
461
+ {
462
+ name: "--manifest",
463
+ kind: "value",
464
+ subcommands: ["build"],
465
+ consumedBy: ["host"],
466
+ description:
467
+ "Write emitted file list as JSON to this path (host build only).",
468
+ },
469
+ {
470
+ name: "--file",
471
+ kind: "value",
472
+ subcommands: ["build", "check"],
473
+ consumedBy: ["lint"],
474
+ description:
475
+ "Absolute or cwd-relative path of the .ts file to transform (lint transform only).",
476
+ },
477
+ {
478
+ name: "--out",
479
+ kind: "value",
480
+ subcommands: ["build", "check"],
481
+ consumedBy: ["lint"],
482
+ description:
483
+ "Write transform output to PATH (lint transform only; default: stdout).",
484
+ },
485
+ ];
486
+
487
+ /**
488
+ * Lookup of `name` and every alias → its canonical FlagSpec. Built once at
489
+ * module load so the parsing engine has O(1) flag resolution.
490
+ */
491
+ export const FLAG_BY_NAME: ReadonlyMap<string, FlagSpec> = buildFlagIndex();
492
+
493
+ function buildFlagIndex(): ReadonlyMap<string, FlagSpec> {
494
+ const index = new Map<string, FlagSpec>();
495
+ for (const flag of FLAG_SCHEMA) {
496
+ register(index, flag.name, flag);
497
+ for (const alias of flag.aliases ?? []) {
498
+ register(index, alias, flag);
499
+ }
500
+ }
501
+ return index;
502
+ }
503
+
504
+ function register(
505
+ index: Map<string, FlagSpec>,
506
+ key: string,
507
+ flag: FlagSpec,
508
+ ): void {
509
+ const existing = index.get(key);
510
+ if (existing && existing !== flag) {
511
+ throw new Error(
512
+ `ttsc flag schema: duplicate token ${JSON.stringify(key)} claimed by ${existing.name} and ${flag.name}`,
513
+ );
514
+ }
515
+ index.set(key, flag);
516
+ }
517
+
518
+ /**
519
+ * Terminal flags as a derived set. Used by `runBuild.ts` to skip the
520
+ * pre-emit pass when one is present.
521
+ */
522
+ export const TERMINAL_FLAGS: ReadonlySet<string> = new Set(
523
+ FLAG_SCHEMA.flatMap((flag) =>
524
+ flag.terminal === true ? [flag.name, ...(flag.aliases ?? [])] : [],
525
+ ),
526
+ );
527
+
528
+ /**
529
+ * `internalShadow: true` flags as a derived set. Used by `runBuild.ts` to
530
+ * detect a user-forwarded copy of a flag ttsc adds internally so the
531
+ * post-processor does not eat the user's output.
532
+ */
533
+ export const INTERNAL_SHADOW_FLAGS: ReadonlySet<string> = new Set(
534
+ FLAG_SCHEMA.flatMap((flag) =>
535
+ flag.internalShadow === true ? [flag.name, ...(flag.aliases ?? [])] : [],
536
+ ),
537
+ );
538
+
539
+ /** Tokens (canonical name + aliases) accepted in `subcommand`. */
540
+ export function flagsForSubcommand(subcommand: AnySubcommand): FlagSpec[] {
541
+ return FLAG_SCHEMA.filter((flag) => flag.subcommands.includes(subcommand));
542
+ }
543
+
544
+ /**
545
+ * Allow-list map for the Go layer named `layer` (`"host"` or `"lint"`):
546
+ * flag-name (no leading dashes) → whether the flag takes a value token.
547
+ * The generator emits a literal Go map with the same shape, but this
548
+ * function is the runtime equivalent — used in tests to verify the
549
+ * generated Go matches the schema.
550
+ */
551
+ export function buildGoAllowList(layer: "host" | "lint"): Map<string, boolean> {
552
+ const out = new Map<string, boolean>();
553
+ for (const flag of FLAG_SCHEMA) {
554
+ if (!flag.consumedBy.includes(layer)) continue;
555
+ const takesValue = flag.kind === "value" || flag.kind === "valueOptional";
556
+ for (const name of [flag.name, ...(flag.aliases ?? [])]) {
557
+ const key = name.replace(/^--?/, "");
558
+ // The Go side strips the leading dashes; if two flags collide on the
559
+ // stripped key (e.g. `-p` vs `--project`), use the value-taking shape.
560
+ const existing = out.get(key);
561
+ if (existing !== undefined && existing !== takesValue) {
562
+ throw new Error(
563
+ `ttsc flag schema: conflicting Go allow-list entry for ${JSON.stringify(key)} on layer ${layer}`,
564
+ );
565
+ }
566
+ out.set(key, takesValue);
567
+ }
568
+ }
569
+ return out;
570
+ }
@@ -109,14 +109,17 @@ function buildProject(
109
109
  fs.mkdirSync(path.dirname(context.emitDir), { recursive: true });
110
110
  const result = runBuild({
111
111
  binary: options.binary,
112
+ checkers: options.checkers,
112
113
  cwd: context.root,
113
114
  emit: true,
114
115
  env: options.env,
115
116
  forceListEmittedFiles: true,
116
117
  cacheDir: context.pluginCacheDir,
117
118
  outDir: context.emitDir,
119
+ passthrough: options.passthrough,
118
120
  plugins: options.plugins,
119
121
  quiet: true,
122
+ singleThreaded: options.singleThreaded,
120
123
  tsconfig: context.tsconfig,
121
124
  });
122
125
  if (result.status === 0) {