ttsc 0.19.2 → 0.20.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 (178) hide show
  1. package/README.md +7 -5
  2. package/cmd/graphdump/main.go +2 -4
  3. package/cmd/ttsc/filter.go +12 -4
  4. package/cmd/ttsc/filter_resolves_flag_names_case_insensitively_test.go +53 -0
  5. package/cmd/ttsc/flags_gen.go +3 -3
  6. package/cmd/ttscgraph/dump.go +5 -7
  7. package/cmd/ttscgraph/run_dump_emits_only_checker_verified_member_relations_test.go +118 -0
  8. package/cmd/ttscgraph/serve.go +58 -308
  9. package/cmd/ttscgraph/serve_session_keeps_base_url_fallback_unchanged_test.go +49 -0
  10. package/cmd/ttscgraph/serve_session_keeps_esm_directory_candidate_unchanged_test.go +61 -0
  11. package/cmd/ttscgraph/serve_session_keeps_exports_blocked_file_candidates_unchanged_test.go +64 -0
  12. package/cmd/ttscgraph/serve_session_keeps_inactive_conditional_export_unchanged_test.go +66 -0
  13. package/cmd/ttscgraph/serve_session_keeps_lower_priority_module_candidate_unchanged_test.go +67 -0
  14. package/cmd/ttscgraph/serve_session_keeps_lower_priority_paths_pattern_unchanged_test.go +58 -0
  15. package/cmd/ttscgraph/serve_session_keeps_nonlongest_root_dirs_candidate_unchanged_test.go +54 -0
  16. package/cmd/ttscgraph/serve_session_reloads_commonjs_package_entry_for_esm_test.go +50 -0
  17. package/cmd/ttscgraph/serve_session_reloads_module_suffix_candidate_test.go +41 -0
  18. package/cmd/ttscgraph/serve_session_reloads_superseding_module_candidates_test.go +216 -0
  19. package/cmd/ttscgraph/serve_session_retries_failed_dump_test.go +103 -0
  20. package/driver/graph.go +12 -6
  21. package/driver/lsp.go +30 -0
  22. package/driver/program.go +37 -1
  23. package/driver/resolution_candidates.go +819 -0
  24. package/driver/windowsjunction/windowsjunction.go +40 -0
  25. package/go.mod +2 -0
  26. package/internal/graph/build.go +45 -11
  27. package/internal/graph/dump.go +312 -108
  28. package/internal/graph/dump_checkout_paths_are_stable_test.go +210 -0
  29. package/internal/graph/dump_diagnostics_ride_the_generation_that_built_it_test.go +9 -3
  30. package/internal/graph/dump_paths.go +172 -0
  31. package/internal/graph/dump_paths_are_portable_and_injective_test.go +93 -0
  32. package/internal/graph/dump_schema_version_matches_the_typescript_client_test.go +1 -1
  33. package/internal/graph/dump_uses_ecma_line_terminators_test.go +87 -0
  34. package/internal/graph/duplicate_variable_object_members_keep_first_declaration_test.go +61 -0
  35. package/internal/graph/edges.go +220 -5
  36. package/internal/graph/enum_members_carry_their_names_on_the_enum_node_test.go +131 -0
  37. package/internal/graph/graph.go +177 -5
  38. package/internal/graph/line_model.go +122 -0
  39. package/internal/graph/literals.go +175 -0
  40. package/internal/graph/literals_are_absent_when_the_type_admits_more_than_it_can_name_test.go +74 -0
  41. package/internal/graph/literals_cover_enum_members_the_graph_has_no_nodes_for_test.go +79 -0
  42. package/internal/graph/literals_do_not_depend_on_declaration_line_wrapping_test.go +84 -0
  43. package/internal/graph/literals_render_every_value_in_typescript_source_form_test.go +77 -0
  44. package/internal/graph/literals_resolve_through_alias_indirection_test.go +64 -0
  45. package/internal/graph/member_relation_edges_follow_checker_validity_test.go +85 -0
  46. package/internal/graph/member_relation_edges_preserve_checker_boundaries_test.go +191 -0
  47. package/internal/graph/member_relation_edges_reject_checker_invalid_pairs_test.go +119 -0
  48. package/internal/graph/node_ids_preserve_hash_bearing_components_test.go +41 -0
  49. package/internal/graph/node_modifiers_emit_union_strings_test.go +4 -1
  50. package/internal/graph/object_literal_members_ride_on_the_snapshot_test.go +192 -0
  51. package/internal/graph/object_member_signatures_preserve_literal_whitespace_test.go +67 -0
  52. package/internal/graph/object_members.go +229 -0
  53. package/internal/graph/provenance.go +88 -30
  54. package/internal/graph/source_texts_cover_every_resident_program_source_test.go +73 -0
  55. package/internal/graphsymbols/position_helpers_follow_ecma_line_terminators_test.go +66 -0
  56. package/internal/graphsymbols/provider.go +26 -91
  57. package/internal/lspserver/lsp_clean_didopen_refreshes_compiler_state_test.go +144 -0
  58. package/internal/lspserver/lsp_completion.go +109 -0
  59. package/internal/lspserver/lsp_completion_gate_never_refuses_a_matching_line_test.go +50 -0
  60. package/internal/lspserver/lsp_completion_hints_longest_trigger_wins_test.go +149 -0
  61. package/internal/lspserver/lsp_completion_hints_nearest_trigger_wins_test.go +37 -0
  62. package/internal/lspserver/lsp_completion_merges_into_upstream_response_test.go +149 -0
  63. package/internal/lspserver/lsp_completion_nearest_hint_replaces_nearest_filter_test.go +43 -0
  64. package/internal/lspserver/lsp_completion_preserves_completion_list_extensions_test.go +99 -0
  65. package/internal/lspserver/lsp_completion_refuses_hints_inside_a_string_literal_test.go +69 -0
  66. package/internal/lspserver/lsp_completion_replaces_full_filter_in_rank_order_test.go +85 -0
  67. package/internal/lspserver/lsp_completion_request.go +455 -0
  68. package/internal/lspserver/lsp_completion_scope.go +530 -0
  69. package/internal/lspserver/lsp_completion_scope_bench_test.go +41 -0
  70. package/internal/lspserver/lsp_completion_scope_classifies_regex_statement_and_operator_boundaries_test.go +39 -0
  71. package/internal/lspserver/lsp_completion_scope_ignores_jsdoc_bytes_in_literals_test.go +108 -0
  72. package/internal/lspserver/lsp_completion_scope_refuses_regex_hints_test.go +52 -0
  73. package/internal/lspserver/lsp_completion_trigger_uses_last_rune_test.go +24 -0
  74. package/internal/lspserver/lsp_deleted_watched_file_withdraws_plugin_diagnostics_test.go +110 -0
  75. package/internal/lspserver/lsp_didsave_keeps_the_incremental_changed_uri_path_test.go +78 -0
  76. package/internal/lspserver/lsp_hints_absence_is_not_an_error_test.go +46 -0
  77. package/internal/lspserver/lsp_hints_refresh_coalesces_concurrent_requests_test.go +82 -0
  78. package/internal/lspserver/lsp_hints_refresh_ignores_a_superseded_generation_test.go +40 -0
  79. package/internal/lspserver/lsp_hints_refresh_keeps_each_producer_isolated_test.go +64 -0
  80. package/internal/lspserver/lsp_hints_refresh_replaces_the_session_snapshot_test.go +66 -0
  81. package/internal/lspserver/lsp_hints_refresh_scheduled_by_editor_events_test.go +90 -0
  82. package/internal/lspserver/lsp_hints_refresh_serves_completion_while_running_test.go +91 -0
  83. package/internal/lspserver/lsp_index_byte_from_bounds_its_search_start_test.go +38 -0
  84. package/internal/lspserver/lsp_initialize_constrains_position_encoding_to_utf16_test.go +205 -0
  85. package/internal/lspserver/lsp_late_completion_trigger_is_reported_once_test.go +105 -0
  86. package/internal/lspserver/lsp_native_completion_hints_decode_flat_lint_wire_test.go +66 -0
  87. package/internal/lspserver/lsp_native_completion_hints_grouped_compatibility_boundary_test.go +60 -0
  88. package/internal/lspserver/lsp_native_plugin_source.go +315 -2
  89. package/internal/lspserver/lsp_native_resident.go +304 -0
  90. package/internal/lspserver/lsp_plugin.go +85 -8
  91. package/internal/lspserver/lsp_plugin_completion_resolve_stays_local_test.go +82 -0
  92. package/internal/lspserver/lsp_position_conversions_span_astral_and_combining_runes_test.go +119 -0
  93. package/internal/lspserver/lsp_proxy.go +601 -9
  94. package/internal/lspserver/lsp_refresh.go +70 -0
  95. package/internal/lspserver/lsp_resident_falls_back_when_serve_unsupported_test.go +43 -0
  96. package/internal/lspserver/lsp_resident_maps_verb_args_test.go +34 -0
  97. package/internal/lspserver/lsp_server.go +13 -1
  98. package/internal/lspserver/lsp_watched_file_changes_reach_compiler_caches_test.go +172 -0
  99. package/lib/TtscCompiler.d.ts +3 -1
  100. package/lib/TtscCompiler.js +5 -1
  101. package/lib/TtscCompiler.js.map +1 -1
  102. package/lib/TtscService.d.ts +13 -3
  103. package/lib/TtscService.js +6 -6
  104. package/lib/TtscService.js.map +1 -1
  105. package/lib/compiler/internal/project/readConfigJson.d.ts +30 -0
  106. package/lib/compiler/internal/project/readConfigJson.js +208 -0
  107. package/lib/compiler/internal/project/readConfigJson.js.map +1 -0
  108. package/lib/compiler/internal/project/readProjectConfig.js +53 -149
  109. package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
  110. package/lib/compiler/internal/residentTransformProcess.d.ts +15 -2
  111. package/lib/compiler/internal/residentTransformProcess.js +159 -39
  112. package/lib/compiler/internal/residentTransformProcess.js.map +1 -1
  113. package/lib/compiler/internal/runBuild.d.ts +6 -0
  114. package/lib/compiler/internal/runBuild.js +143 -44
  115. package/lib/compiler/internal/runBuild.js.map +1 -1
  116. package/lib/compiler/internal/startResidentTransform.d.ts +5 -1
  117. package/lib/compiler/internal/startResidentTransform.js +3 -1
  118. package/lib/compiler/internal/startResidentTransform.js.map +1 -1
  119. package/lib/compiler/internal/transformProjectInMemory.js +12 -2
  120. package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
  121. package/lib/flags/parser.d.ts +19 -0
  122. package/lib/flags/parser.js +78 -36
  123. package/lib/flags/parser.js.map +1 -1
  124. package/lib/flags/schema.d.ts +49 -11
  125. package/lib/flags/schema.js +94 -22
  126. package/lib/flags/schema.js.map +1 -1
  127. package/lib/internal/assertSafeExplicitCacheDirectory.d.ts +5 -0
  128. package/lib/internal/assertSafeExplicitCacheDirectory.js +26 -0
  129. package/lib/internal/assertSafeExplicitCacheDirectory.js.map +1 -0
  130. package/lib/launcher/internal/runTtsc.js +107 -69
  131. package/lib/launcher/internal/runTtsc.js.map +1 -1
  132. package/lib/launcher/internal/runTtsx.js +28 -41
  133. package/lib/launcher/internal/runTtsx.js.map +1 -1
  134. package/lib/launcher/internal/runtimeHooks.d.ts +15 -0
  135. package/lib/launcher/internal/runtimeHooks.js +18 -1
  136. package/lib/launcher/internal/runtimeHooks.js.map +1 -1
  137. package/lib/launcher/internal/watchTopology.d.ts +43 -0
  138. package/lib/launcher/internal/watchTopology.js +360 -0
  139. package/lib/launcher/internal/watchTopology.js.map +1 -0
  140. package/lib/plugin/internal/buildSourcePlugin.d.ts +14 -3
  141. package/lib/plugin/internal/buildSourcePlugin.js +247 -61
  142. package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
  143. package/lib/plugin/internal/loadProjectPlugins.js +63 -2
  144. package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
  145. package/lib/structures/ITtscCompilerTransformation.d.ts +16 -0
  146. package/lib/structures/internal/ITtscParsedProjectConfig.d.ts +2 -0
  147. package/package.json +8 -8
  148. package/shim/ast/shim.go +48 -3
  149. package/shim/astnav/go.mod +14 -0
  150. package/shim/astnav/go.sum +20 -0
  151. package/shim/astnav/shim.go +15 -0
  152. package/shim/checker/shim.go +113 -0
  153. package/shim/core/shim.go +47 -0
  154. package/shim/diagnosticwriter/lint.go +50 -0
  155. package/src/TtscCompiler.ts +5 -1
  156. package/src/TtscService.ts +37 -10
  157. package/src/compiler/internal/project/readConfigJson.ts +209 -0
  158. package/src/compiler/internal/project/readProjectConfig.ts +62 -158
  159. package/src/compiler/internal/residentTransformProcess.ts +197 -39
  160. package/src/compiler/internal/runBuild.ts +169 -47
  161. package/src/compiler/internal/startResidentTransform.ts +12 -1
  162. package/src/compiler/internal/transformProjectInMemory.ts +12 -1
  163. package/src/flags/parser.ts +113 -42
  164. package/src/flags/schema.ts +113 -31
  165. package/src/internal/assertSafeExplicitCacheDirectory.ts +29 -0
  166. package/src/launcher/internal/runTtsc.ts +117 -68
  167. package/src/launcher/internal/runTtsx.ts +29 -44
  168. package/src/launcher/internal/runtimeHooks.ts +30 -2
  169. package/src/launcher/internal/watchTopology.ts +466 -0
  170. package/src/plugin/internal/buildSourcePlugin.ts +326 -64
  171. package/src/plugin/internal/loadProjectPlugins.ts +80 -2
  172. package/src/structures/ITtscCompilerTransformation.ts +17 -0
  173. package/src/structures/internal/ITtscParsedProjectConfig.ts +2 -0
  174. package/tools/shim_audit/baseline.json +0 -3
  175. package/tools/shim_audit/main.go +42 -14
  176. package/tools/shim_audit/shim_dir_coverage_test.go +25 -0
  177. package/utility/flags_gen.go +3 -3
  178. package/utility/host.go +9 -3
@@ -38,7 +38,6 @@
38
38
  "ESCAPE|checker|UnionType",
39
39
  "ESCAPE|checker|UniqueESSymbolType",
40
40
  "ESCAPE|checker|VerbosityContext",
41
- "ESCAPE|core|ECMALineStarts",
42
41
  "ESCAPE|core|LimitedSemaphore",
43
42
  "ESCAPE|core|ModuleDetectionKind",
44
43
  "ESCAPE|core|ModuleResolutionKind",
@@ -190,7 +189,6 @@
190
189
  "FUNC|ast|IsAutoAccessorPropertyDeclaration",
191
190
  "FUNC|ast|IsAwaitExpression",
192
191
  "FUNC|ast|IsBigIntLiteral",
193
- "FUNC|ast|IsBinaryExpression",
194
192
  "FUNC|ast|IsBinaryOperator",
195
193
  "FUNC|ast|IsBindableObjectDefinePropertyCall",
196
194
  "FUNC|ast|IsBindableStaticAccessExpression",
@@ -646,7 +644,6 @@
646
644
  "FUNC|ast|WalkUpBindingElementsAndPatterns",
647
645
  "FUNC|checker|CompareTypes",
648
646
  "FUNC|checker|FormatTypeFlags",
649
- "FUNC|checker|GetDeclarationModifierFlagsFromSymbol",
650
647
  "FUNC|checker|GetResolvedSignatureForSignatureHelp",
651
648
  "FUNC|checker|GetSingleVariableOfVariableStatement",
652
649
  "FUNC|checker|IsExternalModuleSymbol",
@@ -69,8 +69,9 @@ import (
69
69
 
70
70
  const internalPrefix = "github.com/microsoft/typescript-go/internal/"
71
71
 
72
- // shimDirs maps each shim directory to its upstream internal package suffix.
73
- // Kept explicit (rather than globbed) so a new shim dir is a conscious add.
72
+ // shimDirs maps each full re-export shim directory to its upstream internal
73
+ // package suffix. Kept explicit (rather than globbed) so a new shim dir is a
74
+ // conscious add.
74
75
  var shimDirs = map[string]string{
75
76
  "ast": "ast",
76
77
  "bundled": "bundled",
@@ -90,6 +91,13 @@ var shimDirs = map[string]string{
90
91
  "vfs/osvfs": "vfs/osvfs",
91
92
  }
92
93
 
94
+ // linknameShimDirs maps deliberately partial go:linkname bridges. They are
95
+ // scanned for their actual references and are covered by the directory gate,
96
+ // but do not claim to re-export every public symbol in the upstream package.
97
+ var linknameShimDirs = map[string]string{
98
+ "astnav": "astnav",
99
+ }
100
+
93
101
  // auditOnlyInternal lists upstream internal packages that shim sources
94
102
  // reference — go:linkname targets and blank imports that compile them into
95
103
  // consumer binaries — without owning a shim directory of their own. They are
@@ -202,12 +210,12 @@ var linknameRe = regexp.MustCompile(`(?m)^//go:linkname\s+\S+\s+` +
202
210
  func scanShimReachable(shimRoot string) (reachable, error) {
203
211
  r := reachable{}
204
212
  fset := token.NewFileSet()
205
- for dir := range shimDirs {
213
+ scanDir := func(dir string) error {
206
214
  paths, _ := filepath.Glob(filepath.Join(shimRoot, dir, "*.go"))
207
215
  for _, p := range paths {
208
216
  src, err := os.ReadFile(p)
209
217
  if err != nil {
210
- return nil, err
218
+ return err
211
219
  }
212
220
  // linkname directives live in comments, so scan raw text too.
213
221
  for _, m := range linknameRe.FindAllStringSubmatch(string(src), -1) {
@@ -215,7 +223,7 @@ func scanShimReachable(shimRoot string) (reachable, error) {
215
223
  }
216
224
  f, err := parser.ParseFile(fset, p, src, parser.SkipObjectResolution)
217
225
  if err != nil {
218
- return nil, fmt.Errorf("%s: %w", p, err)
226
+ return fmt.Errorf("%s: %w", p, err)
219
227
  }
220
228
  // alias map: local import name -> internal pkg suffix
221
229
  alias := map[string]string{}
@@ -246,6 +254,17 @@ func scanShimReachable(shimRoot string) (reachable, error) {
246
254
  return true
247
255
  })
248
256
  }
257
+ return nil
258
+ }
259
+ for dir := range shimDirs {
260
+ if err := scanDir(dir); err != nil {
261
+ return nil, err
262
+ }
263
+ }
264
+ for dir := range linknameShimDirs {
265
+ if err := scanDir(dir); err != nil {
266
+ return nil, err
267
+ }
249
268
  }
250
269
  return r, nil
251
270
  }
@@ -489,10 +508,11 @@ func hasShimSource(dir string) bool {
489
508
  }
490
509
 
491
510
  // checkShimDirCoverage fails if any sub-directory of the shim root (at ANY
492
- // depth) that contains non-test Go source is not registered in shimDirs. This
493
- // keeps the audit's package list honest: a newly-added shim — including a
494
- // NESTED package like vfs/osvfs that a non-recursive, immediate-children scan
495
- // would miss — cannot escape the gate by omission.
511
+ // depth) that contains non-test Go source is not registered as either a full
512
+ // re-export or an intentionally partial go:linkname bridge. This keeps the
513
+ // audit's package list honest: a newly-added shim — including a NESTED package
514
+ // like vfs/osvfs that a non-recursive, immediate-children scan would miss —
515
+ // cannot escape the gate by omission.
496
516
  func checkShimDirCoverage(shimRoot string) error {
497
517
  var unmapped []string
498
518
  var walk func(dir, rel string) error
@@ -509,7 +529,7 @@ func checkShimDirCoverage(shimRoot string) error {
509
529
  if rel != "" {
510
530
  childRel = rel + "/" + e.Name()
511
531
  }
512
- if _, ok := shimDirs[childRel]; !ok && hasShimSource(filepath.Join(dir, e.Name())) {
532
+ if !isRegisteredShimDir(childRel) && hasShimSource(filepath.Join(dir, e.Name())) {
513
533
  unmapped = append(unmapped, childRel)
514
534
  }
515
535
  if err := walk(filepath.Join(dir, e.Name()), childRel); err != nil {
@@ -523,12 +543,20 @@ func checkShimDirCoverage(shimRoot string) error {
523
543
  }
524
544
  if len(unmapped) > 0 {
525
545
  sort.Strings(unmapped)
526
- return fmt.Errorf("shim dir(s) not registered in shimDirs (would escape the audit): %s\n"+
527
- " add them to shimDirs in tools/shim_audit/main.go", strings.Join(unmapped, ", "))
546
+ return fmt.Errorf("shim dir(s) not registered for audit coverage: %s\n"+
547
+ " add a full re-export to shimDirs or a deliberate bridge to linknameShimDirs in tools/shim_audit/main.go", strings.Join(unmapped, ", "))
528
548
  }
529
549
  return nil
530
550
  }
531
551
 
552
+ func isRegisteredShimDir(dir string) bool {
553
+ if _, ok := shimDirs[dir]; ok {
554
+ return true
555
+ }
556
+ _, ok := linknameShimDirs[dir]
557
+ return ok
558
+ }
559
+
532
560
  // loadInner loads the upstream internal packages via go/types, anchored in a
533
561
  // shim module that requires typescript-go (same trick gen_shims uses).
534
562
  func loadInner(anchorDir string) (map[string]*packages.Package, error) {
@@ -784,8 +812,8 @@ func main() {
784
812
  shimRoot := flag.String("shim", "./shim", "shim root directory")
785
813
  flag.Parse()
786
814
 
787
- // A shim directory that is not registered in shimDirs would silently escape
788
- // every check — close that hole before doing anything else.
815
+ // A shim directory that is not registered for audit coverage would silently
816
+ // escape every check — close that hole before doing anything else.
789
817
  if err := checkShimDirCoverage(*shimRoot); err != nil {
790
818
  fmt.Fprintln(os.Stderr, "shim_audit:", err)
791
819
  os.Exit(2)
@@ -0,0 +1,25 @@
1
+ package main
2
+
3
+ import "testing"
4
+
5
+ // TestCheckShimDirCoverageIncludesAstnav keeps astnav's partial linkname bridge
6
+ // inside the audit's explicit coverage model without claiming a full re-export.
7
+ //
8
+ // 1. Assert astnav is deliberately classified as a partial bridge.
9
+ // 2. Scan the repository shim root with the same coverage gate as the CLI.
10
+ // 3. Confirm its one linkname target remains visible to reachability scanning.
11
+ func TestCheckShimDirCoverageIncludesAstnav(t *testing.T) {
12
+ if got := linknameShimDirs["astnav"]; got != "astnav" {
13
+ t.Fatalf("linknameShimDirs[astnav] = %q, want astnav", got)
14
+ }
15
+ if err := checkShimDirCoverage("../../shim"); err != nil {
16
+ t.Fatal(err)
17
+ }
18
+ reachable, err := scanShimReachable("../../shim")
19
+ if err != nil {
20
+ t.Fatal(err)
21
+ }
22
+ if !reachable.has("astnav", "GetTouchingToken") {
23
+ t.Fatal("astnav.GetTouchingToken is not reachable")
24
+ }
25
+ }
@@ -17,13 +17,13 @@ var HostFlagAllowList = map[string]bool{
17
17
  "cwd": true,
18
18
  "emit": false,
19
19
  "manifest": true,
20
- "noEmit": false,
21
- "outDir": true,
20
+ "noemit": false,
21
+ "outdir": true,
22
22
  "p": true,
23
23
  "plugins-json": true,
24
24
  "project": true,
25
25
  "quiet": false,
26
- "singleThreaded": false,
26
+ "singlethreaded": false,
27
27
  "tsconfig": true,
28
28
  "tsgo-args": true,
29
29
  "verbose": false,
package/utility/host.go CHANGED
@@ -264,12 +264,18 @@ func filterHostArgs(args []string) []string {
264
264
  return filtered
265
265
  }
266
266
 
267
- // flagName strips the leading "--" from a flag argument and reports whether
268
- // the flag carries an inline value (i.e. the argument contains "=").
267
+ // flagName strips the leading "--" from a flag argument, lower-cases the
268
+ // result, and reports whether the flag carries an inline value (i.e. the
269
+ // argument contains "=").
270
+ //
271
+ // Lower-casing is the same normalization `normalizeFlagToken` in
272
+ // packages/ttsc/src/flags/schema.ts applies, and the generated
273
+ // HostFlagAllowList keys are produced by it, so this layer recognises exactly
274
+ // the spellings the launcher and the compiler do.
269
275
  func flagName(arg string) (string, bool) {
270
276
  name := strings.TrimPrefix(arg, "--")
271
277
  before, _, found := strings.Cut(name, "=")
272
- return before, found
278
+ return strings.ToLower(before), found
273
279
  }
274
280
 
275
281
  // loadUtilityProgram parses plugins JSON, sets the linked-plugin environment