refactor(daemon): split src/daemon/types.ts into request types and session state
Summary
Closes #2338. src/daemon/types.ts served the dispatch request shape and the live session record from one file, and sat in the only daemon type cycle. Three modules replace it:
src/daemon/daemon-request-wire.ts—DaemonWireRequest: nointernalkey, no property path toSessionStateorDeviceLease, satisfying the wire-only requirement in #2338.src/daemon/daemon-request.ts—DaemonRequest= wire +internal(DaemonRequestInternalstays unexported), plusDaemonResponse/DaemonResponseData/DaemonInvokeFn/DaemonArtifact.src/daemon/session-state.ts—SessionState,SessionRef,SessionScope,SessionRuntimeHints, and the interaction-surface shapes.
For F1 (#2341): DaemonWireRequest lives under src/, so a journal package cannot import it under R11. The importable equivalent is DaemonRequest/DaemonRequestMeta from @agent-device/kernel/contracts, which already carry all four fields the journal reads (command, flags, meta.requestId, meta.clientArtifactPaths).
The cycle is cut by ref-frame-slot.ts, declared below both ref-frame.ts and session-state.ts. It owns the frame value (class still unexported, so the type stays nominal and unconstructible outside); ref-frame.ts keeps every transition and session.refFrame write — R7 rows refFrame and snapshotScopeSource are unchanged.
No behavior change; no re-export shim at the old path. 408 files touched, 386 of them import-line-only — the rename/move exemption applies to the diff budget.
R9 type cycles (production graph), measured on the current base b4ebd77: 19 → 18. src/daemon/ref-frame.ts ↔ src/daemon/types.ts is gone; the other 18 are byte-identical, so no new cycle appeared. Largest cycle unchanged at 6 files (packages/provider-webdriver/*).
Production importer split after the change: 197 files — 82 request-only, 42 state-only, 73 both (issue baseline: 79/35/83).
Path-keyed gates follow the declarations, in one final chore(gates) commit: the daemon-modularity external-importer ratchet (membership unchanged — client/client-normalizers.ts and remote/daemon-artifacts.ts, both on daemon-request.ts) and the wire-compat closure waivers. R7 now finds SessionState by its declaration rather than a recorded path, because the same function measures the merge-base tree.
Three test files already over the 1,000-line ratchet gain one import line each and shed one redundant line to stay at base length — no assertion weakened. Splitting them along the modules they mirror is tracked in #2353.
Validation
Rebased onto b4ebd77. One conflict, in daemon/deferred-interaction-outcome.ts: #2347 retargeted runPostGestureStabilityLoop to @agent-device/capture-kit/post-gesture-stability while this PR split the type import on the next line — resolved by taking both. (The earlier rebase onto 835af32 had one conflict in handlers/session-app-source-deployment.ts, resolved the same way.)
Tested at 6f2fe7b (the pushed head) after pnpm install --frozen-lockfile && pnpm build.
pnpm check:affected --run: format, lint, typecheck, layering, di-seams, fallow, gate-manifest, build, package, integration and macos-coverage all pass. Layering guard green against merge-base b4ebd77: R7 (31 fields classified), R9 (largest cycle 6), R10 (R7 pressure at base, 2 external importers). Fallow: no issues in 408 changed files.
vitest-related: 3149 passed, 3 failed, none from this change. app-log-session-resource.test.ts > unwritable tombstone… and durable-capture-resource.test.ts > an unconfirmed failed-adoption cleanup… fail identically on origin/main in this container, which runs as root, so their chmod-based unwritable-tombstone setup cannot deny a write. cli-config-trust.test.ts > project config rejects remote connection fields… is untouched by this diff and passes in isolation here — a load artifact of the local run. CI is the authority on all three.
The type-level test is src/daemon/__tests__/daemon-request-wire.test.ts; I verified it fails tsc when an internal/SessionState path is reintroduced.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Ujrc8LYmvM249WY8921J1Y
Generated by Claude Code