mirror of
https://github.com/stablyai/orca.git
synced 2026-10-28 16:02:55 +00:00
#14397 split `shared/types.ts` into 46 per-domain modules but kept the path as a re-export barrel so the import sites did not have to change. This removes the barrel: every consumer now imports from the module that actually declares the type, and `src/shared/types.ts` is deleted. Barrels hide where a type lives, make every consumer look like it depends on the whole domain, and let an unrelated edit invalidate a module that ~2,000 files transitively import. 2,323 import declarations across 2,321 files. Rewritten mechanically: each specifier was resolved to an absolute path via the TypeScript AST and recomputed, rather than string-substituted, so alias forms (`@/../../shared/ types`) and per-specifier `type` modifiers survive. Four cases the mechanical pass had to handle, each found by a gate rather than by reading the diff: - Modules inside `src/shared` import the barrel as `./types`, not `shared/types`. A pre-filter on the latter string skipped 176 of them and left imports dangling at a deleted file, which surfaced as confusing `Property 'x' is optional in type 'Repo' but required in Pick<Repo, ...>` errors rather than "module not found". - The barrel RENAMED one type on the way through (`WorkspaceSource as WorkspaceCreateTelemetrySource`), so the original name in the owning module has to be re-aliased at each consumer. - Three test files put `;(globalThis as ...)` on the line after the import. TypeScript parses that `;` as the import statement's terminator, so replacing through `statement.getEnd()` deletes it and breaks ASI. The rewrite now stops at the module specifier. - A file that already imported directly from a module got a SECOND import from it, because the barrel re-exported those same names — which trips `import/no-duplicates` under `--deny-warnings`. A post-pass merges declarations sharing a specifier and type-only-ness; the `import type` plus `import` pair from one module is left alone, since that form is allowed. Splitting one barrel import into several genuinely adds lines, which pushed `terminal-layout-pty-ownership.ts` to 301 counted lines: its 107-character import must wrap, and neither local type collapses onto one line (101 and 116 characters). Rather than contort a type declaration to fit a line budget, `collectLeafIds` and `pruneLeaves` move to `terminal-pane-layout-tree.ts` — they are pure structural operations on the layout tree and independent of PTY ownership. `visible-worktrees.ts` similarly loses its own mini-barrel re-export of `isDefaultBranchWorkspace`, with the four real consumers repointed at the declaring module. No `max-lines` bypass added. Verified: cold `tsc --noEmit` green on node, cli, and web (buildinfo deleted first — these projects are `composite: true` and reuse stale caches); the full `pnpm lint` green, not just bare oxlint — the narrower local check is what let the duplicate imports reach CI; max-lines ratchet OK at 344.
112 lines
4.3 KiB
TypeScript
112 lines
4.3 KiB
TypeScript
/**
|
|
* Phase 5 of the terminal model/view architecture: main-side terminal query
|
|
* authority.
|
|
*
|
|
* The delivery decision is the reply decision: main answers a query iff the
|
|
* hidden-delivery gate dropped the chunk that carried it. This module owns
|
|
* the responder kill-switch predicate and the main-side mirror of the
|
|
* renderer's native-Windows-ConPTY determination, recorded per PTY at spawn
|
|
* so the runtime emulator can register the DA1 override before byte zero.
|
|
*/
|
|
import type { GlobalSettings } from '../../shared/global-settings-types'
|
|
import { isWslUncPath } from '../../shared/wsl-paths'
|
|
import {
|
|
isHiddenPtyDeliveryGateEnabled,
|
|
shouldDropHiddenRendererPtyData
|
|
} from '../ipc/pty-hidden-delivery-gate'
|
|
|
|
export type TerminalModelQueryAuthoritySettings = Pick<
|
|
GlobalSettings,
|
|
'terminalMainSideEffectAuthority' | 'terminalHiddenDeliveryGate' | 'terminalModelQueryAuthority'
|
|
>
|
|
|
|
/** Responder kill switch: requires BOTH Phase-4 gate switches (no marks/drops
|
|
* exist without them) plus the Phase-5-specific independent off switch. */
|
|
export function isTerminalModelQueryAuthorityEnabled(
|
|
settings: TerminalModelQueryAuthoritySettings | null | undefined
|
|
): boolean {
|
|
return isHiddenPtyDeliveryGateEnabled(settings) && settings?.terminalModelQueryAuthority !== false
|
|
}
|
|
|
|
/** Per-chunk reply-ownership predicate, evaluated once at ingestion in
|
|
* OrcaRuntimeService.onPtyData — the same module state and tick as the
|
|
* hidden-gate drop sites, so "chunk dropped" and "main answers" cannot
|
|
* diverge for live chunks. Remote view subscribers (mobile/web/remote
|
|
* desktop xterms on the multiplexed stream) keep view authority, so main
|
|
* yields while one is attached. */
|
|
export function shouldModelAnswerHiddenPtyQueries(opts: {
|
|
ptyId: string
|
|
settings: TerminalModelQueryAuthoritySettings | null | undefined
|
|
hasRemoteViewSubscriber: boolean
|
|
}): boolean {
|
|
return (
|
|
isTerminalModelQueryAuthorityEnabled(opts.settings) &&
|
|
!opts.hasRemoteViewSubscriber &&
|
|
shouldDropHiddenRendererPtyData(opts.ptyId, opts.settings)
|
|
)
|
|
}
|
|
|
|
/** Main-side mirror of the renderer's isLocalNativeWindowsPty
|
|
* (windows-pty-compatibility.ts), computed from spawn-time facts: local or
|
|
* daemon provider (no SSH connection), win32 host, and not a WSL shell. */
|
|
export function isNativeWindowsLocalPtySpawn(opts: {
|
|
connectionId: string | null | undefined
|
|
cwd: string | null | undefined
|
|
shellOverride: string | null | undefined
|
|
platform?: NodeJS.Platform
|
|
}): boolean {
|
|
if ((opts.platform ?? process.platform) !== 'win32') {
|
|
return false
|
|
}
|
|
if (opts.connectionId) {
|
|
return false
|
|
}
|
|
if (isWslUncPath(opts.cwd ?? '')) {
|
|
return false
|
|
}
|
|
if (/(?:^|[/\\])wsl(?:\.exe)?$/i.test(opts.shellOverride ?? '')) {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// Why module state (pattern of pty-hidden-delivery-gate.ts): pty.ts records
|
|
// the determination at spawn, the runtime consults it at emulator creation.
|
|
// Daemon-adopted PTYs from a previous app run carry no mark — acceptable:
|
|
// ConPTY's blocking DA1 only fires at spawn, which happened in a prior life.
|
|
const nativeWindowsConptyPtys = new Set<string>()
|
|
|
|
// Why installers: the mark lands after the awaited spawn response, but daemon
|
|
// stream data (warm-reattach flush) can lazy-create the runtime emulator
|
|
// first. The runtime registers an installer so marking retrofits the DA1
|
|
// override onto an existing emulator; installation is idempotent emulator-side.
|
|
type ConptyDa1OverrideInstaller = (ptyId: string) => void
|
|
const conptyDa1OverrideInstallers = new Set<ConptyDa1OverrideInstaller>()
|
|
|
|
export function registerConptyDa1OverrideInstaller(installer: ConptyDa1OverrideInstaller): void {
|
|
conptyDa1OverrideInstallers.add(installer)
|
|
}
|
|
|
|
export function markNativeWindowsConptyPty(id: string): void {
|
|
nativeWindowsConptyPtys.add(id)
|
|
for (const installer of conptyDa1OverrideInstallers) {
|
|
installer(id)
|
|
}
|
|
}
|
|
|
|
export function isNativeWindowsConptyPty(id: string): boolean {
|
|
return nativeWindowsConptyPtys.has(id)
|
|
}
|
|
|
|
/** Wired into clearProviderPtyState so every PTY teardown path releases the
|
|
* spawn record. */
|
|
export function clearNativeWindowsConptyPty(id: string): void {
|
|
nativeWindowsConptyPtys.delete(id)
|
|
}
|
|
|
|
/** Test seam: reset module state between tests. */
|
|
export function _resetTerminalModelQueryAuthorityForTest(): void {
|
|
nativeWindowsConptyPtys.clear()
|
|
conptyDa1OverrideInstallers.clear()
|
|
}
|