You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
tsconfig.scripts.json claims to match apps/console/tsconfig.node.json's option set but omits allowImportingTsExtensions — the shared vite-*.ts files are green in one program, red in the other #4926
Observation-class finding, dormant today. Filed while implementing objectui#4854; not fixed there (out of scope, and the PR routed around it instead).
The claim, and where it stops holding
tsconfig.scripts.json's header states the invariant explicitly:
Two of the files here (scripts/vite-crypto-stub.ts, scripts/vite-maplibre-worker.ts) ARE already compiled, by apps/console/tsconfig.node.json … They are deliberately NOT excluded below … The cost of the overlap is paid by matching that project's option set (strict, ESNext, bundler resolution, and notably NO noImplicitReturns), so a shared file cannot be green in one project and red in the other.
The option sets do not in fact match. apps/console/tsconfig.node.json:30 sets "allowImportingTsExtensions": true (its header explains why: the console's config imports carry real .ts extensions so Vite's configLoader: 'native' can load them — objectui#3384). tsconfig.scripts.json sets no such option, and its compilerOptions are spelled out rather than inherited, so nothing supplies it.
Measured
tsconfig.scripts.json sets "noEmit": true, so allowImportingTsExtensions is legal there; it is simply absent. The divergence is invisible today only because no .ts file under scripts/ currently writes a specifier ending in .ts — the two named shared files import nothing relative, and scripts/__tests__/*.ts spell their imports extensionless.
It surfaces the moment anything under scripts/ reaches the console's build config. Adding a test there that statically imported apps/console/vite.config.ts produced, from pnpm type-check:scripts:
apps/console/vite.config.ts(16,32): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
apps/console/vite.config.ts(17,36): error TS5097: An import path can only end with a '.ts' extension when 'allowImportingTsExtensions' is enabled.
Lines 16 and 17 are the pre-existing imports of scripts/vite-crypto-stub.ts and scripts/vite-maplibre-worker.ts — the exact two files the header names as deliberately shared, red in one program while tsc -b apps/console/tsconfig.node.json --force stays green on the same bytes. That is the shape the header says the matched option set prevents.
Why it is filed rather than fixed
PR for objectui#4854 needed to evaluate the console's config from a scripts/__tests__ test. It assembles the specifier at runtime instead, which keeps apps/console/vite.config.ts out of the scripts program entirely — the program boundary the header is really defending. Widening a shared tsconfig as a rider on a build-hook PR is the wrong place for the decision, so it is left here.
Two options for whoever picks it up, neither obviously free:
Add "allowImportingTsExtensions": true to tsconfig.scripts.json, restoring the stated invariant. Cheap, and it makes the header true again.
Decide the invariant is narrower than written — the option is a property of how the console loads its config, not of the shared files — and correct the header instead, naming allowImportingTsExtensions as a deliberate difference with its reason.
Either way, scripts/__tests__/scripts-type-check.test.ts is where the choice should be pinned; it already asserts noEmit/strict/composite on this project and would be the natural home for an option-parity assertion against apps/console/tsconfig.node.json, which is what would have caught this.
Nothing a user hits, nothing red on main — hence finding and no pm:queue.
Triage (concentrated finding round): promoted finding → pm:queue. Route suggestion (dev verifies against the two headers): option 1 — add allowImportingTsExtensions: true to tsconfig.scripts.json, restoring the stated invariant (it is legal under noEmit: true and the divergence is the only gap the header's claim has) — plus the option-parity assertion in scripts-type-check.test.ts against apps/console/tsconfig.node.json, which is what would have caught this. Option 2 (narrow the invariant in prose) only if measurement shows the option genuinely misbehaves in the scripts program.
Claim: PM loop round 7
Session: session_019b5UBNMtTzKbVtZZGvFuxe
Branch: claude/issue-4926-scripts-tsconfig-option-parity
Worktree: objectui-issue-4926
Domain: domain:devx (@ objectui, seat #5748)
File surface: tsconfig.scripts.json (expected landing); apps/console/tsconfig.node.json read-only unless you report why otherwise
Container & model: S, mode:subagent, model: sonnet
Clause-②: no
Serial constraints cleared: in-flight 0 at round open. Co-dispatched: #5174 batch 3 (content/docs/** + the doc-snippet ledger) and #4850 (two source files' eslint comments) — both disjoint. ⚠️ Note #4820 landed 09:43Z (PR #5966) and touched the roottsconfig.json; your branch must start from a main containing it (cb83cec1a). Different file, but the same tsconfig graph — ⛔ do not work from a stale base.
PM-verified premises on origin/main @ 2aff580b5 — re-verify before editing
tsconfig.scripts.json claims to match that project's option set
✅ its own header: "The cost of the overlap is paid by matching that project's option set (strict, ESNext, bundler resolution, and notably NO noImplicitReturns), so a shared file cannot be green in one project and red in the other"
So the declared-vs-actual divergence is real: the file states an invariant ("a shared file cannot be green in one project and red in the other") that its own option list does not deliver.
⚠️ PM mechanism assumption — MEASURE THIS FIRST, I could not confirm it
The card's stated consequence is that the shared vite-*.ts files are "green in one program, red in the other". I could not reproduce that. A grep for .ts-extension relative imports in scripts/vite-crypto-stub.ts, scripts/vite-maplibre-worker.ts and apps/console/vite.config.ts returned nothing — so as far as I could measure, the divergence today is latent: the option is missing, but nothing currently uses the spelling that needs it.
⚠️ My grep only matched ./-relative forms and may simply have missed the real site — apps/console/tsconfig.node.json's own comment says "TypeScript needs allowImportingTsExtensions to accept that spelling", which implies something does use it. Find where, or establish that nothing does. Your answer changes the card:
If a real red exists → this is a live defect; fix it and show the before/after.
If it is latent → this is invariant restoration, not a bug fix. Still worth doing (a config asserting a parity it does not have is the failure class this repo keeps filing), but ⛔ say so plainly rather than implying you fixed a live break. ⛔ Do not manufacture a failing case to justify the change.
Either way, state which you found, with the command that showed it. A positive control is required: pair any zero with a pattern certain to be present.
Direction
Bring tsconfig.scripts.json's option set into actual agreement with the parity it claims. ⛔ Do not "fix" it by weakening the claim in the comment and leaving the options diverged unless you can show that adding the option is wrong — and if you conclude that, stop and report rather than editing prose to match a gap.
⛔ Do not restructure the file to extends anything: its header explains at length why it deliberately does not, and that reasoning (tsconfig.base.json's exclude would make the pin tests compile vacuously) is not this card's to overturn.
⛔ Scope: this one option-set divergence. Other differences between the two projects are findings to file, not this PR's work — and if you find any, check whether the header's claim needs narrowing too, and report it.
Gates
No dispatch-gates.mjs in this repo — derive from your actual diff. At minimum pnpm type-check:scripts (the program this file defines), apps/console's type-check (the other side of the shared files), scripts/__tests__ and Lint. check-type-check-coverage.mjs is directly relevant — run it. Judge changeset vs none against the repo's own rule by runningcheck-changeset-presence.mjs; ⛔ no skip-changeset label (never a real mechanism here, per #4912/#3724).
{
"issue": 4926,
"status": "done",
"branch": "claude/issue-4926-scripts-tsconfig-option-parity",
"pr": "#5974",
"premise_still_valid": true,
"summary": "Added "allowImportingTsExtensions": true to tsconfig.scripts.json (legal under its existing noEmit: true) so its option set actually matches apps/console/tsconfig.node.json as the header claims, and expanded the header to name the option. Added an option-parity assertion test in scripts/tests/scripts-type-check.test.ts that reads both parsed tsconfigs and asserts strict/module/moduleResolution/allowImportingTsExtensions/absence-of-noImplicitReturns agree, scoped only to the options the header itself claims are matched. Did not restructure to extends anything and touched no other option differences.",
"tests": "Mechanism finding: divergence is LATENT, not live — pnpm type-check:scripts is green both before and after (EXIT=0 both times); neither shared file (scripts/vite-crypto-stub.ts, scripts/vite-maplibre-worker.ts) itself carries a .ts-extension import. Found where allowImportingTsExtensions actually IS exercised (PM's ./-relative grep missed it): grep -n \"scripts/vite-\" apps/console/vite.config.ts shows lines 17-19 import the shared files via ../../scripts/vite-*.ts with explicit .ts extensions -- inside apps/console/tsconfig.node.json's own program, not tsconfig.scripts.json's (include is scripts/**/*.ts only). Reproduced the issue's exact repro via a scratch tsconfig (not committed) widening include to also cover apps/console/vite.config.ts: reran tsc and got the same three TS5097 errors the issue quoted, confirming the mechanism without manufacturing a permanent failing test. Positive control for the grep: it matched the known-present specifiers on the first try (no zero-result to pair). Gates run at head 2ce7ee4: pnpm type-check:scripts EXIT=0 clean; pnpm --filter '@object-ui/console^...' build EXIT=0 then pnpm --filter '@object-ui/console' type-check (tsc --noEmit && tsc -b tsconfig.node.json --force) EXIT=0 clean; npx vitest run scripts/__tests__ --maxWorkers=2 -- 62 test files, 1665 tests, all passing (scripts-type-check.test.ts now 9/9, was 8/8); node scripts/check-type-check-coverage.mjs -- '✅ type-check coverage: 45/46 via type-check, 0 via their own build, 0 known-broken (0 errors outstanding), 1 not compiled.' / '✅ test type-check coverage: 41/41 packages compile their tests...'; node scripts/check-changeset-presence.mjs -- '✅ No source of a released package changed in this range, so no changeset is owed.' (2 files changed, 0 under a released package's src/); node scripts/check-control-bytes.mjs -- '✅ check-control-bytes: OK'; npx eslint scripts/__tests__/scripts-type-check.test.ts --no-inline-config -- 0 errors. Reverse-verification done on the COMMITTED fix: git checkout origin/main -- tsconfig.scripts.json (removing the option) then reran the new test -- it failed with the expected assertion message ('tsconfig.scripts.json must set "allowImportingTsExtensions": true...'); restored via git checkout HEAD -- tsconfig.scripts.json, reran, 9/9 green again, working tree clean.",
"open_questions": [],
"out_of_scope_findings": []
}
os-dev-report (marker HTML-comment form was stripped by the sanitizer on the previous comment — reposting with the marker as literal text per dispatch instructions)
{
"issue": 4926,
"status": "done",
"branch": "claude/issue-4926-scripts-tsconfig-option-parity",
"pr": "#5974",
"premise_still_valid": true,
"summary": "Added "allowImportingTsExtensions": true to tsconfig.scripts.json (legal under its existing noEmit: true) so its option set actually matches apps/console/tsconfig.node.json as the header claims, and expanded the header to name the option. Added an option-parity assertion test in scripts/tests/scripts-type-check.test.ts that reads both parsed tsconfigs and asserts strict/module/moduleResolution/allowImportingTsExtensions/absence-of-noImplicitReturns agree, scoped only to the options the header itself claims are matched. Did not restructure to extends anything and touched no other option differences.",
"tests": "Mechanism finding: divergence is LATENT, not live — pnpm type-check:scripts is green both before and after (EXIT=0 both times); neither shared file (scripts/vite-crypto-stub.ts, scripts/vite-maplibre-worker.ts) itself carries a .ts-extension import. Found where allowImportingTsExtensions actually IS exercised (PM's ./-relative grep missed it): grep -n \"scripts/vite-\" apps/console/vite.config.ts shows lines 17-19 import the shared files via ../../scripts/vite-*.ts with explicit .ts extensions -- inside apps/console/tsconfig.node.json's own program, not tsconfig.scripts.json's (include is scripts/**/*.ts only). Reproduced the issue's exact repro via a scratch tsconfig (not committed) widening include to also cover apps/console/vite.config.ts: reran tsc and got the same three TS5097 errors the issue quoted, confirming the mechanism without manufacturing a permanent failing test. Positive control for the grep: it matched the known-present specifiers on the first try (no zero-result to pair). Gates run at head 2ce7ee4: pnpm type-check:scripts EXIT=0 clean; pnpm --filter '@object-ui/console^...' build EXIT=0 then pnpm --filter '@object-ui/console' type-check (tsc --noEmit && tsc -b tsconfig.node.json --force) EXIT=0 clean; npx vitest run scripts/__tests__ --maxWorkers=2 -- 62 test files, 1665 tests, all passing (scripts-type-check.test.ts now 9/9, was 8/8); node scripts/check-type-check-coverage.mjs -- '✅ type-check coverage: 45/46 via type-check, 0 via their own build, 0 known-broken (0 errors outstanding), 1 not compiled.' / '✅ test type-check coverage: 41/41 packages compile their tests...'; node scripts/check-changeset-presence.mjs -- '✅ No source of a released package changed in this range, so no changeset is owed.' (2 files changed, 0 under a released package's src/); node scripts/check-control-bytes.mjs -- '✅ check-control-bytes: OK'; npx eslint scripts/__tests__/scripts-type-check.test.ts --no-inline-config -- 0 errors. Reverse-verification done on the COMMITTED fix: git checkout origin/main -- tsconfig.scripts.json (removing the option) then reran the new test -- it failed with the expected assertion message ('tsconfig.scripts.json must set "allowImportingTsExtensions": true...'); restored via git checkout HEAD -- tsconfig.scripts.json, reran, 9/9 green again, working tree clean.",
"open_questions": [],
"out_of_scope_findings": []
}
ACCEPT — PR #5974. Landing on CI convergence, under the maintainer's auto-merge authorisation.
Reviewer of record: domain:devx @ objectui seat (#5748), round R7, PM session session_019b5UBNMtTzKbVtZZGvFuxe. Verified against the diff — ⛔ not against the report.
"allowImportingTsExtensions": true added, with its legality stated and checked: it requires noEmit / emitDeclarationOnly / rewriteRelativeImportExtensions, and this project sets noEmit: true
⛔ no extends restructure
confirmed in the diff — the header's long explanation of why it deliberately does not extend is untouched
⛔ no other option touched
confirmed
CI
converging at review time; landing gated on every check green, ⛔ not the required subset
⚠️ The dev corrected the PM. Recording it, because I got it wrong in the dispatch order
I wrote that I could not reproduce the card's consequence and that the divergence looked latent, flagging that my grep matched only ./-relative forms and might have missed the real site. It did. The dev found it:
apps/console/vite.config.ts:17-19 imports the shared files as ../../scripts/vite-crypto-stub.ts and ../../scripts/vite-maplibre-worker.ts — with explicit .ts extensions (objectui#3384). That is what allowImportingTsExtensions exists for here, and my pattern could never have matched it.
But the dev also confirmed the half I got right, and did not overstate it: those imports live in apps/console/tsconfig.node.json's program, not tsconfig.scripts.json's (whose include is scripts/**/*.ts only). So pnpm type-check:scripts is green both before and after — the divergence is genuinely latent, and the PR says so plainly rather than implying a live break was fixed. Exactly the distinction the dispatch asked for.
The right call on how to prove it
The dispatch forbade manufacturing a failing case. The dev reproduced the issue's exact TS5097 errors through a scratch tsconfig that was not committed, widening include to reach apps/console/vite.config.ts — demonstrating the mechanism without leaving a permanent artificial red behind. That is the distinction between evidence and theatre, and it got it right.
Accepted scope deviation — the parity test
The card asked for one option; the PR also adds a parity assertion comparing both parsed tsconfigs. Accepted, and it is the better deliverable. The header asserted "a shared file cannot be green in one project and red in the other" — a declared invariant with nothing enforcing it, which is exactly how this divergence survived. The test converts declared into enforced, which is this repo's recurring theme and #4926's own thesis.
It is also correctly scoped: it asserts only the axes the header names (strict, module, moduleResolution, allowImportingTsExtensions, and the deliberate absence of noImplicitReturns), and its docblock states why it does not assert the rest — composite, outDir, rootDir, allowJs, target, emit differ by design, and asserting them equal would recreate the very extends trap the header warns about. A blanket "options must match" assertion would have been the lazy version and would have been wrong.
Two details worth naming: noImplicitReturns is asserted falsy on both sides rather than "both truthy", so divergence in either direction is caught; and the console-side assertion carries a message telling a future reader that if it is what broke, the fix belongs in tsconfig.scripts.json, not in the test.
Reverse verification — on the committed fix, not a sketch
git checkout origin/main -- tsconfig.scripts.json (removing the option) → the new test failed with its intended assertion message → restored → 9/9 green, working tree clean. The ablation was run against what actually ships.
Landing
Path fork checked against the actual file list before touching ready: tsconfig.scripts.json and scripts/__tests__/** are not governed surface. Maintainer's ruling, in-session 2026-08-24, verbatim:
授权 auto-merge(推荐)
⚠️ Cross-card note for the landing order: #5410 is in flight and edits scripts/__tests__/check-phantom-dependencies.test.ts, compiled by the program this PR just changed. The change is permissive (allowImportingTsExtensions only widens what is accepted), so it should not disturb it — but if #5410 reports a configuration-shaped compile failure, this PR is the first thing to look at.
Activity
os-support-ai commentedon Aug 19, 2026
Triage (concentrated finding round): promoted
finding→pm:queue. Route suggestion (dev verifies against the two headers): option 1 — addallowImportingTsExtensions: truetotsconfig.scripts.json, restoring the stated invariant (it is legal undernoEmit: trueand the divergence is the only gap the header's claim has) — plus the option-parity assertion inscripts-type-check.test.tsagainstapps/console/tsconfig.node.json, which is what would have caught this. Option 2 (narrow the invariant in prose) only if measurement shows the option genuinely misbehaves in the scripts program.本评论来自分诊座位 Routine (session
session_018euHiF12oV8iSfYdjVioUF).Generated by Claude Code
yinlianghui-tw commentedon Aug 24, 2026
Claim: PM loop round 7⚠️ Note #4820 landed 09:43Z (PR #5966) and touched the root
Session:
session_019b5UBNMtTzKbVtZZGvFuxeBranch:
claude/issue-4926-scripts-tsconfig-option-parityWorktree:
objectui-issue-4926Domain:
domain:devx(@ objectui, seat #5748)File surface:
tsconfig.scripts.json(expected landing);apps/console/tsconfig.node.jsonread-only unless you report why otherwiseContainer & model: S,
mode:subagent,model: sonnetClause-②: no
Serial constraints cleared: in-flight 0 at round open. Co-dispatched: #5174 batch 3 (
content/docs/**+ the doc-snippet ledger) and #4850 (two source files' eslint comments) — both disjoint.tsconfig.json; your branch must start from amaincontaining it (cb83cec1a). Different file, but the same tsconfig graph — ⛔ do not work from a stale base.PM-verified premises on
origin/main@2aff580b5— re-verify before editingtsconfig.scripts.jsonomitsallowImportingTsExtensionsapps/console/tsconfig.node.jsondeclares it"allowImportingTsExtensions": trueat :30tsconfig.scripts.jsonclaims to match that project's option setnoImplicitReturns), so a shared file cannot be green in one project and red in the other"scripts/vite-crypto-stub.ts,scripts/vite-maplibre-worker.tsSo the declared-vs-actual divergence is real: the file states an invariant ("a shared file cannot be green in one project and red in the other") that its own option list does not deliver.
The card's stated consequence is that the shared
vite-*.tsfiles are "green in one program, red in the other". I could not reproduce that. A grep for.ts-extension relative imports inscripts/vite-crypto-stub.ts,scripts/vite-maplibre-worker.tsandapps/console/vite.config.tsreturned nothing — so as far as I could measure, the divergence today is latent: the option is missing, but nothing currently uses the spelling that needs it../-relative forms and may simply have missed the real site —apps/console/tsconfig.node.json's own comment says "TypeScript needsallowImportingTsExtensionsto accept that spelling", which implies something does use it. Find where, or establish that nothing does. Your answer changes the card:Either way, state which you found, with the command that showed it. A positive control is required: pair any zero with a pattern certain to be present.
Direction
Bring
tsconfig.scripts.json's option set into actual agreement with the parity it claims. ⛔ Do not "fix" it by weakening the claim in the comment and leaving the options diverged unless you can show that adding the option is wrong — and if you conclude that, stop and report rather than editing prose to match a gap.⛔ Do not restructure the file to
extendsanything: its header explains at length why it deliberately does not, and that reasoning (tsconfig.base.json'sexcludewould make the pin tests compile vacuously) is not this card's to overturn.⛔ Scope: this one option-set divergence. Other differences between the two projects are findings to file, not this PR's work — and if you find any, check whether the header's claim needs narrowing too, and report it.
Gates
No
dispatch-gates.mjsin this repo — derive from your actual diff. At minimumpnpm type-check:scripts(the program this file defines),apps/console'stype-check(the other side of the shared files),scripts/__tests__and Lint.check-type-check-coverage.mjsis directly relevant — run it. Judge changeset vs none against the repo's own rule by runningcheck-changeset-presence.mjs; ⛔ noskip-changesetlabel (never a real mechanism here, per #4912/#3724).Generated by Claude Code
yinlianghui-tw commentedon Aug 24, 2026
{
"issue": 4926,
"status": "done",
"branch": "claude/issue-4926-scripts-tsconfig-option-parity",
"pr": "#5974",
"premise_still_valid": true,
"summary": "Added "allowImportingTsExtensions": true to tsconfig.scripts.json (legal under its existing noEmit: true) so its option set actually matches apps/console/tsconfig.node.json as the header claims, and expanded the header to name the option. Added an option-parity assertion test in scripts/tests/scripts-type-check.test.ts that reads both parsed tsconfigs and asserts strict/module/moduleResolution/allowImportingTsExtensions/absence-of-noImplicitReturns agree, scoped only to the options the header itself claims are matched. Did not restructure to extends anything and touched no other option differences.",
"tests": "Mechanism finding: divergence is LATENT, not live —
pnpm type-check:scriptsis green both before and after (EXIT=0 both times); neither shared file (scripts/vite-crypto-stub.ts, scripts/vite-maplibre-worker.ts) itself carries a .ts-extension import. Found where allowImportingTsExtensions actually IS exercised (PM's ./-relative grep missed it):grep -n \"scripts/vite-\" apps/console/vite.config.tsshows lines 17-19 import the shared files via../../scripts/vite-*.tswith explicit .ts extensions -- inside apps/console/tsconfig.node.json's own program, not tsconfig.scripts.json's (include is scripts/**/*.ts only). Reproduced the issue's exact repro via a scratch tsconfig (not committed) widening include to also cover apps/console/vite.config.ts: reran tsc and got the same three TS5097 errors the issue quoted, confirming the mechanism without manufacturing a permanent failing test. Positive control for the grep: it matched the known-present specifiers on the first try (no zero-result to pair). Gates run at head 2ce7ee4:pnpm type-check:scriptsEXIT=0 clean;pnpm --filter '@object-ui/console^...' buildEXIT=0 thenpnpm --filter '@object-ui/console' type-check(tsc --noEmit && tsc -b tsconfig.node.json --force) EXIT=0 clean;npx vitest run scripts/__tests__ --maxWorkers=2-- 62 test files, 1665 tests, all passing (scripts-type-check.test.ts now 9/9, was 8/8);node scripts/check-type-check-coverage.mjs-- '✅ type-check coverage: 45/46 viatype-check, 0 via their own build, 0 known-broken (0 errors outstanding), 1 not compiled.' / '✅ test type-check coverage: 41/41 packages compile their tests...';node scripts/check-changeset-presence.mjs-- '✅ No source of a released package changed in this range, so no changeset is owed.' (2 files changed, 0 under a released package's src/);node scripts/check-control-bytes.mjs-- '✅ check-control-bytes: OK';npx eslint scripts/__tests__/scripts-type-check.test.ts --no-inline-config-- 0 errors. Reverse-verification done on the COMMITTED fix:git checkout origin/main -- tsconfig.scripts.json(removing the option) then reran the new test -- it failed with the expected assertion message ('tsconfig.scripts.json must set "allowImportingTsExtensions": true...'); restored viagit checkout HEAD -- tsconfig.scripts.json, reran, 9/9 green again, working tree clean.","open_questions": [],
"out_of_scope_findings": []
}
Generated by Claude Code
yinlianghui-tw commentedon Aug 24, 2026
os-dev-report (marker HTML-comment form was stripped by the sanitizer on the previous comment — reposting with the marker as literal text per dispatch instructions)
{
"issue": 4926,
"status": "done",
"branch": "claude/issue-4926-scripts-tsconfig-option-parity",
"pr": "#5974",
"premise_still_valid": true,
"summary": "Added "allowImportingTsExtensions": true to tsconfig.scripts.json (legal under its existing noEmit: true) so its option set actually matches apps/console/tsconfig.node.json as the header claims, and expanded the header to name the option. Added an option-parity assertion test in scripts/tests/scripts-type-check.test.ts that reads both parsed tsconfigs and asserts strict/module/moduleResolution/allowImportingTsExtensions/absence-of-noImplicitReturns agree, scoped only to the options the header itself claims are matched. Did not restructure to extends anything and touched no other option differences.",
"tests": "Mechanism finding: divergence is LATENT, not live —
pnpm type-check:scriptsis green both before and after (EXIT=0 both times); neither shared file (scripts/vite-crypto-stub.ts, scripts/vite-maplibre-worker.ts) itself carries a .ts-extension import. Found where allowImportingTsExtensions actually IS exercised (PM's ./-relative grep missed it):grep -n \"scripts/vite-\" apps/console/vite.config.tsshows lines 17-19 import the shared files via../../scripts/vite-*.tswith explicit .ts extensions -- inside apps/console/tsconfig.node.json's own program, not tsconfig.scripts.json's (include is scripts/**/*.ts only). Reproduced the issue's exact repro via a scratch tsconfig (not committed) widening include to also cover apps/console/vite.config.ts: reran tsc and got the same three TS5097 errors the issue quoted, confirming the mechanism without manufacturing a permanent failing test. Positive control for the grep: it matched the known-present specifiers on the first try (no zero-result to pair). Gates run at head 2ce7ee4:pnpm type-check:scriptsEXIT=0 clean;pnpm --filter '@object-ui/console^...' buildEXIT=0 thenpnpm --filter '@object-ui/console' type-check(tsc --noEmit && tsc -b tsconfig.node.json --force) EXIT=0 clean;npx vitest run scripts/__tests__ --maxWorkers=2-- 62 test files, 1665 tests, all passing (scripts-type-check.test.ts now 9/9, was 8/8);node scripts/check-type-check-coverage.mjs-- '✅ type-check coverage: 45/46 viatype-check, 0 via their own build, 0 known-broken (0 errors outstanding), 1 not compiled.' / '✅ test type-check coverage: 41/41 packages compile their tests...';node scripts/check-changeset-presence.mjs-- '✅ No source of a released package changed in this range, so no changeset is owed.' (2 files changed, 0 under a released package's src/);node scripts/check-control-bytes.mjs-- '✅ check-control-bytes: OK';npx eslint scripts/__tests__/scripts-type-check.test.ts --no-inline-config-- 0 errors. Reverse-verification done on the COMMITTED fix:git checkout origin/main -- tsconfig.scripts.json(removing the option) then reran the new test -- it failed with the expected assertion message ('tsconfig.scripts.json must set "allowImportingTsExtensions": true...'); restored viagit checkout HEAD -- tsconfig.scripts.json, reran, 9/9 green again, working tree clean.","open_questions": [],
"out_of_scope_findings": []
}
Generated by Claude Code
yinlianghui-tw commentedon Aug 24, 2026
ACCEPT — PR #5974. Landing on CI convergence, under the maintainer's auto-merge authorisation.
Reviewer of record:
domain:devx@ objectui seat (#5748), round R7, PM sessionsession_019b5UBNMtTzKbVtZZGvFuxe. Verified against the diff — ⛔ not against the report.tsconfig.scripts.json+scripts/__tests__/scripts-type-check.test.ts"allowImportingTsExtensions": trueadded, with its legality stated and checked: it requiresnoEmit/emitDeclarationOnly/rewriteRelativeImportExtensions, and this project setsnoEmit: trueextendsrestructurerequiredsubsetI wrote that I could not reproduce the card's consequence and that the divergence looked latent, flagging that my grep matched only
./-relative forms and might have missed the real site. It did. The dev found it:apps/console/vite.config.ts:17-19imports the shared files as../../scripts/vite-crypto-stub.tsand../../scripts/vite-maplibre-worker.ts— with explicit.tsextensions (objectui#3384). That is whatallowImportingTsExtensionsexists for here, and my pattern could never have matched it.But the dev also confirmed the half I got right, and did not overstate it: those imports live in
apps/console/tsconfig.node.json's program, nottsconfig.scripts.json's (whoseincludeisscripts/**/*.tsonly). Sopnpm type-check:scriptsis green both before and after — the divergence is genuinely latent, and the PR says so plainly rather than implying a live break was fixed. Exactly the distinction the dispatch asked for.The right call on how to prove it
The dispatch forbade manufacturing a failing case. The dev reproduced the issue's exact TS5097 errors through a scratch tsconfig that was not committed, widening
includeto reachapps/console/vite.config.ts— demonstrating the mechanism without leaving a permanent artificial red behind. That is the distinction between evidence and theatre, and it got it right.Accepted scope deviation — the parity test
The card asked for one option; the PR also adds a parity assertion comparing both parsed tsconfigs. Accepted, and it is the better deliverable. The header asserted "a shared file cannot be green in one project and red in the other" — a declared invariant with nothing enforcing it, which is exactly how this divergence survived. The test converts declared into enforced, which is this repo's recurring theme and #4926's own thesis.
It is also correctly scoped: it asserts only the axes the header names (
strict,module,moduleResolution,allowImportingTsExtensions, and the deliberate absence ofnoImplicitReturns), and its docblock states why it does not assert the rest —composite,outDir,rootDir,allowJs,target, emit differ by design, and asserting them equal would recreate the veryextendstrap the header warns about. A blanket "options must match" assertion would have been the lazy version and would have been wrong.Two details worth naming:
noImplicitReturnsis asserted falsy on both sides rather than "both truthy", so divergence in either direction is caught; and the console-side assertion carries a message telling a future reader that if it is what broke, the fix belongs intsconfig.scripts.json, not in the test.Reverse verification — on the committed fix, not a sketch
git checkout origin/main -- tsconfig.scripts.json(removing the option) → the new test failed with its intended assertion message → restored → 9/9 green, working tree clean. The ablation was run against what actually ships.Landing
Path fork checked against the actual file list before touching ready:
tsconfig.scripts.jsonandscripts/__tests__/**are not governed surface. Maintainer's ruling, in-session 2026-08-24, verbatim:scripts/__tests__/check-phantom-dependencies.test.ts, compiled by the program this PR just changed. The change is permissive (allowImportingTsExtensionsonly widens what is accepted), so it should not disturb it — but if #5410 reports a configuration-shaped compile failure, this PR is the first thing to look at.Generated by Claude Code