diff --git a/.device-evidence/CHECKLIST.md b/.device-evidence/CHECKLIST.md index 4dc48e688f..eb1bfb1d19 100644 --- a/.device-evidence/CHECKLIST.md +++ b/.device-evidence/CHECKLIST.md @@ -99,9 +99,11 @@ appended warning: ### Proof the review asked for on this lane The false-attribution class is covered by unit tests rather than a device run, because the device -cannot show a cache hit on command: `src/daemon/__tests__/capture-disclosure-target-activation.test.ts` -pins that a cache-reused tree discloses nothing, and -`src/daemon/interaction/internal/__tests__/interaction-target-activation-disclosure.test.ts` pins that +cannot show a cache hit on command: `packages/daemon/src/__tests__/selector-capture-runtime.test.ts` +drives a session-snapshot cache hit and pins that the consumed tree earns no repair proof and +discloses nothing, `packages/daemon/src/__tests__/capture-disclosure-target-activation.test.ts` +pins that the response builder never borrows a repair the stored snapshot happens to carry, and +`src/__tests__/daemon-composition/interaction/interaction-capture-disclosure.test.ts` pins that a press which consumed no capture is not disclosed against an older tree. ## Why the live activation lane is manual diff --git a/.fallowrc.json b/.fallowrc.json index f41e7f33e9..d82e00a3d3 100644 --- a/.fallowrc.json +++ b/.fallowrc.json @@ -29,9 +29,6 @@ "scripts/patch-xcuitest-runner-icon.ts", "scripts/write-xcuitest-cache-metadata.ts", "scripts/xcuitest-build-settings.ts", - // The 11a-4 residue scan runs by hand (and from CI prose until R11 in #3546 owns - // the rule); nothing in the dependency graph imports it. - "scripts/daemon-edge-residue-scan.mjs", "packages/capture-kit/src/ios-snapshot-engine/replay.ts", // #1596 regression fixture: runs as a real `node --experimental-strip-types` // subprocess (test/integration/daemon-replace-exit-flush.test.ts), so @@ -68,7 +65,7 @@ "scripts/help-conformance-sample-outputs.d.mts", "scripts/help-conformance-runner-output.d.mts" ], - "dynamicallyLoaded": ["src/daemon/interaction/index.ts"], + "dynamicallyLoaded": ["packages/daemon/src/interaction/index.ts"], "ignoreDependencies": [ "@theme", // @agent-device/maestro owns the source import, while the published root @@ -158,7 +155,7 @@ }, { // Daemon route handlers are reached only through the dynamic `import()` table in request-handler-chain.ts, which --production analysis cannot follow to a consumer. - "file": "src/daemon/handlers/{human-control,lease,session,snapshot,react-native,record-trace}.ts", + "file": "packages/daemon/src/handlers/{human-control,lease,session,snapshot,react-native,record-trace}.ts", "exports": [ "handleHumanControlCommand", "handleLeaseCommands", @@ -170,7 +167,7 @@ }, { // The interaction facade exposes #2178's deferred route handlers plus the existing ref mutation response consumed by help conformance. Fallow's production graph cannot follow the request-handler-chain dynamic imports, so this exact list is the facade contract. - "file": "src/daemon/interaction/index.ts", + "file": "packages/daemon/src/interaction/index.ts", "exports": ["refMutationAdmissionResponse", "handleFindCommands", "handleInteractionCommands"] }, { @@ -243,7 +240,7 @@ "exports": ["IS_PREDICATE_USAGE_HINT"] }, { - // Workspace-package symbols whose only consumers are test-tree files, which --production analysis does not see. Each import is the package specifier, so the façade entry is load-bearing: parseTargetAnnotationV1Payload from src/daemon/__tests__/session-target-evidence.test.ts, MAESTRO_COMPAT_* from src/cli/parser/__tests__/maestro-support-matrix.test.ts, SCRIPT_FLAG_COMMANDS/scriptFlagEntries from src/commands/replay/script-flag-admission.test.ts (the #3197 two-way drift guard between the .ad grammar and the CLI schema). + // Workspace-package symbols whose only consumers are test-tree files, which --production analysis does not see. Each import is the package specifier, so the façade entry is load-bearing: parseTargetAnnotationV1Payload from packages/selectors/src/target-evidence.test.ts, MAESTRO_COMPAT_* from src/cli/parser/__tests__/maestro-support-matrix.test.ts, SCRIPT_FLAG_COMMANDS/scriptFlagEntries from src/commands/replay/script-flag-admission.test.ts (the #3197 two-way drift guard between the .ad grammar and the CLI schema). "file": "packages/{ad-script,maestro,capture-kit}/src/index.ts", "exports": [ "parseTargetAnnotationV1Payload", @@ -254,7 +251,7 @@ ] }, { - // src/daemon/__tests__/request-runtime-binding.test.ts drives the daemon's exact bind through the recovery authority, whose cancellation race is what rejects; production reaches it only through finishRecoveredDurableCapture and recoverDurableCaptureResource in the same package. + // packages/daemon/src/__tests__/request-runtime-binding.test.ts drives the daemon's exact bind through the recovery authority, whose cancellation race is what rejects; production reaches it only through finishRecoveredDurableCapture and recoverDurableCaptureResource in the same package. "file": "packages/capture-kit/src/durable-capture/index.ts", "exports": ["acquireDurableCaptureRecoveryAuthorityBeforeDeadline"] }, diff --git a/AGENTS.md b/AGENTS.md index d0b0631dde..6fdd5c7442 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -49,11 +49,11 @@ Read the declaration rather than maintaining a prose copy: - commands and their surface, runtime-use, batch, and timeout traits: `packages/command-registry/src/registry.ts` -- daemon route ownership and request-policy traits: `src/daemon/daemon-command-registry.ts` +- daemon route ownership and request-policy traits: `packages/daemon/src/daemon-command-registry.ts` - interaction paths and guarantees: `packages/contracts/src/interaction-guarantees.ts` - canonical command names: `packages/command-registry/src/catalog.ts` - device runtime-use declarations and fact admission: - `packages/command-registry/src/registry.ts`, `src/daemon/runtime-admission.ts`, and + `packages/command-registry/src/registry.ts`, `packages/daemon/src/runtime-admission.ts`, and `src/platform-runtime-gateway.ts` - common command input fields, and which surface may write an input key (model, operator, retired): `src/commands/common-input-fields.ts` and `src/commands/input-audience.ts` @@ -110,7 +110,7 @@ under `contracts/fixtures/`. ## Runtime and diagnostics seams Diagnostics use `@agent-device/host-kit/diagnostics`. Request diagnostics belong in the session request log; -session artifact paths come from `src/daemon/session-artifact-paths.ts`. App/device logs remain in `app.log`; +session artifact paths come from `packages/daemon/src/session-artifact-paths.ts`. App/device logs remain in `app.log`; Apple runner and xcodebuild output remains in `runner.log`. Normalize failures with `normalizeError` and preserve `hint`, `diagnosticId`, `logPath`, and typed diff --git a/docs/adr/0003-daemon-command-registry.md b/docs/adr/0003-daemon-command-registry.md index db927c1a3f..2b92ac543d 100644 --- a/docs/adr/0003-daemon-command-registry.md +++ b/docs/adr/0003-daemon-command-registry.md @@ -21,7 +21,7 @@ to public command identity, and it required duplicate command sets to stay align Keep public command identity in `src/command-catalog.ts` and public input/output contracts in `src/commands/**`. -Add `src/daemon/daemon-command-registry.ts` as the daemon-side source of truth for command route +Add `packages/daemon/src/daemon-command-registry.ts` as the daemon-side source of truth for command route ownership and daemon request-policy traits. Request modules consume predicate functions from the registry instead of recreating command string sets. Handler modules own execution logic only; they do not export duplicate coverage tables to prove route membership. @@ -67,7 +67,7 @@ exposed through named predicates — a property that survives a projected/derive derived daemon registry is therefore permitted **only if** it preserves all of the following invariants: 1. **Daemon-owned declaration.** Route and request-policy traits are declared in a daemon-owned facet - (under `src/daemon/`) and *composed* into the registration — never inlined as fields on the public + (under `packages/daemon/src/`) and *composed* into the registration — never inlined as fields on the public command contract in `src/commands/**` or `src/command-catalog.ts`. Co-locating a registration *call* is fine; co-locating *ownership* of daemon policy in the public surface is the contamination this ADR rejected (see Alternatives, "Keep daemon groups in `src/command-catalog.ts`"). @@ -85,5 +85,5 @@ derived daemon registry is therefore permitted **only if** it preserves all of t A single flat public descriptor whose daemon fields leak into public views is **not** permitted — that is the "collapse daemon policy into a public command registry" failure this ADR exists to prevent. Compose facets owned by their domains; derive the registry from them. Until that derivation lands and is pinned -by the registry tests, the hand-authored `src/daemon/daemon-command-registry.ts` remains the source of +by the registry tests, the hand-authored `packages/daemon/src/daemon-command-registry.ts` remains the source of truth and the operating rule in `AGENTS.md` is unchanged. diff --git a/docs/adr/0004-ios-snapshot-backend-strategy.md b/docs/adr/0004-ios-snapshot-backend-strategy.md index 81e31875ef..56ba3ba989 100644 --- a/docs/adr/0004-ios-snapshot-backend-strategy.md +++ b/docs/adr/0004-ios-snapshot-backend-strategy.md @@ -115,7 +115,7 @@ facet in `@agent-device/capture-kit` owns snapshot policy generally rather than stated as a duration budget; the loop derives the deadline from the window's `markedAt` itself, so the budget is always spent from the action and a caller has no absolute instant it could get wrong. - `src/daemon/session-snapshot-freshness.ts` keeps only what needs a session: reading and retiring + `packages/daemon/src/session-snapshot-freshness.ts` keeps only what needs a session: reading and retiring the window on store-owned `SessionState`, and choosing the comparison baseline from snapshot lineage. It remains the declared R7 owner of `androidSnapshotFreshness`. - **Timeout evidence.** Whether a capture failed because the hierarchy never arrived is decided @@ -145,12 +145,12 @@ facet in `@agent-device/capture-kit` owns snapshot policy generally rather than `scripts/layering/snapshot-presentation-boundary.test.ts` enforces the direction, but only across the roots `snapshot-policy` declares in `scripts/layering/architecture-ownership.ts`: nothing in -that snapshot tree may import `src/daemon/`, while the overlay modules beside the tree sit outside +that snapshot tree may import `packages/daemon/src/`, while the overlay modules beside the tree sit outside those roots and are outside that gate. It carries a positive control, because a filter that stopped matching would look identical to a boundary being obeyed. The residual call sites #1983 also named are audited and deliberately left in place. -`src/daemon/direct-ios-selector.ts` carries no presentation policy: `isLocalIosRunnerSession` and +`packages/daemon/src/direct-ios-selector.ts` carries no presentation policy: `isLocalIosRunnerSession` and `readSimpleIosSelectorTarget` are session routing (device family, provider ownership, the stabilization window), while `deriveDirectIosNodeSelector` and `isDirectIosSelectorFallbackError` are selector derivation and ADR 0011 delegation-on-error. The latter two are pure and diff --git a/docs/adr/0008-command-descriptor-registry.md b/docs/adr/0008-command-descriptor-registry.md index 241cca57f9..d5c467f710 100644 --- a/docs/adr/0008-command-descriptor-registry.md +++ b/docs/adr/0008-command-descriptor-registry.md @@ -24,7 +24,7 @@ Accepted A command's identity is restated, by hand, across roughly ten tables that must stay aligned by convention: `PUBLIC_COMMANDS` (`src/command-catalog.ts`), the per-command metadata and family facets (`src/commands/**`), the capability matrix (`src/core/capabilities.ts`), the daemon command registry -(`src/daemon/daemon-command-registry.ts`, ADR 0003), the structured-batch allowlist +(`packages/daemon/src/daemon-command-registry.ts`, ADR 0003), the structured-batch allowlist (`src/batch-policy.ts`), the MCP exposure sets, the Node client interface and impl (`src/client-types.ts`, `src/client.ts`), and the generic-dispatch `switch` (`src/core/dispatch.ts`, whose `default: throw` makes a missing or renamed command a runtime error, not a compile error). Adding one command touches ~24 files, the diff --git a/docs/adr/0012-interactive-replay.md b/docs/adr/0012-interactive-replay.md index 741f33dda4..5943a08081 100644 --- a/docs/adr/0012-interactive-replay.md +++ b/docs/adr/0012-interactive-replay.md @@ -730,7 +730,7 @@ path — no text editing, no silent similarity-heal. **Core mechanism — the healed script IS `session.actions`.** No new splice engine. `session.actions` already accumulates every executed action for the session's lifetime -(`src/daemon/session-action-recorder.ts:37`, unconditional push), and the divergence refusal is +(`packages/daemon/src/session-action-recorder.ts:92`, unconditional push), and the divergence refusal is pre-dispatch (target verification refuses before the device action, decision 3), so a divergent step is never pushed. Across a repair session: original steps that verified and dispatched land in `session.actions`; the divergent step is absent (refused pre-dispatch, never recorded); the agent's @@ -766,13 +766,13 @@ works" and "healed scripts are always valid": steps are re-executed during the repair replay; only if recording is armed from the start do they land in `session.actions` with fresh `target-v1` evidence. Arming late yields a hybrid healed script (an annotated corrective step glued to a bare, unannotated prefix) that re-diverges on its own next replay - (`src/daemon/interaction/internal/interaction-common.ts:64-65` attaches evidence only when `recordSession` was + (`packages/daemon/src/interaction/internal/interaction-common.ts:64-65` attaches evidence only when `recordSession` was true when the step ran). - **R2 — `--from` continuation only; never re-run the full replay on the same session.** After a divergence at step N and the corrective action, the agent must continue with `replay --from k --plan-digest `, not a fresh full `replay`. A full re-replay on the same session re-appends the already-recorded prefix `1..N-1` to `session.actions` — duplication, because - `session-action-recorder.ts:37` pushes unconditionally and replay dispatch does not inject `noRecord`. + `session-action-recorder.ts:92` pushes unconditionally and replay dispatch does not inject `noRecord`. The two sub-flows differ in `k`: app-state uses `k = N` (re-run the unchanged step after fixing state); selector-drift uses `k = N + 1` (the agent already performed step N manually; do not re-run it). - **R3 — a mechanical `repairHint` on the divergence payload gates the sub-flow; no LLM-only routing.** @@ -808,8 +808,8 @@ works" and "healed scripts are always valid": instead of leaving it to agent judgment. - **R4 — corrective actions must materialize to selector form; the writer fails loudly on a bare `@ref` cross-session export.** A `press @e12` normally resolves a `selectorChain` at runtime - (`src/daemon/interaction/internal/interaction-touch-targets.ts`), which `buildOptimizedActions` - (`src/daemon/session-script-writer.ts:69-83`) rewrites to a selector line. If no `selectorChain` was + (`packages/daemon/src/interaction/internal/interaction-touch-targets.ts`), which `buildOptimizedActions` + (`packages/daemon/src/session-script-writer.ts:368-377`) rewrites to a selector line. If no `selectorChain` was captured, the writer must refuse to emit a bare `@ref` line into a persisted `.ad` — a session-bound ref will not resolve in a fresh run. It **fails loudly**: an error surfaced to the user with a non-zero exit, never a swallowed or silently-dropped line (existing session-write paths swallow such failures; @@ -893,7 +893,7 @@ by construction. The healed `.ad` is written only when the repair ends (below) a - The healed `.ad` is published when a teardown commits the transaction at state `COMPLETE` — normally the agent's own `close`/`close --save-script `, but any teardown of a completed transaction commits (see the commit state machine below) — reusing the existing `session.actions` serializer - (`SessionScriptWriter.write`, `src/daemon/session-script-writer.ts:30-52`) over the post-watermark slice + (`SessionScriptWriter.write`, `packages/daemon/src/session-script-writer.ts:120-158`) over the post-watermark slice only (R6). When no `` path is given, the default is the **`.healed.ad` sibling**: the original script's path with its `.ad` extension replaced by `.healed.ad` (e.g. `flows/login.ad` → `flows/login.healed.ad`), @@ -943,7 +943,7 @@ a separate naming change, not part of this decision. **Scope: this refusal is uniform across repair AND ordinary recording, not repair-only.** Everything above is written in the context of decision 6's repair-armed heal, but `publishHealedScriptAtomically` -(`src/daemon/session-script-writer.ts`) is the single publish primitive `SessionScriptWriter.write` calls +(`packages/daemon/src/session-script-writer.ts`) is the single publish primitive `SessionScriptWriter.write` calls for every `--save-script` target, with no repair-armed-vs-ordinary branch — a repair-armed heal (`saveScriptBoundary` set) and an ordinary, non-repair `open --save-script`/`close --save-script` recording (`saveScriptBoundary` absent) publish through the exact same exclusive `linkSync`. Before this @@ -1002,10 +1002,10 @@ The tombstone itself expires after its bounded window, after which the key is fu > Provenance travels as `internal.replayPlanStep`, stamped by `invokeResolvedReplayAction` > (`src/daemon/handlers/session-replay-action-runtime.ts`) — the single point every plan step is > dispatched, so the marker covers annotated and unannotated steps alike. `internal` is a daemon-only -> channel (`toDaemonRequest`, `src/daemon/server/http-rpc-methods.ts`, never copies it off the wire), so +> channel (`toDaemonRequest`, `packages/daemon/src/server/http-rpc-methods.ts`, never copies it off the wire), so > authored provenance cannot be spoofed by a client; this is the same channel `replayTargetGuard` and > `findResolvedTarget` already use. The rule is written once, in `isInteractiveObservation` -> (`src/daemon/session-action-recorder.ts`), and both recording call sites consume it. +> (`packages/daemon/src/session-action-recorder.ts`), and both recording call sites consume it. > > **2. The corrective-read trap: why even out-of-band reads need an opt-in.** Excluding every out-of-band > read is still not safe on its own: a divergence's **correction** can itself be a read. In the wave-3 E3 drift, the diverged step **was** a `get`, so its corrective replacement is a @@ -1044,11 +1044,11 @@ The tombstone itself expires after its bounded window, after which the key is fu > > **4. How the rule projects across CLI/Node/MCP surfaces.** The exclusion is enforced at a single > daemon-side choke point — `isExcludedRepairSegmentObservation` in `recordActionEntry` -> (`src/daemon/session-action-recorder.ts`), gated on `session.saveScriptBoundary !== undefined` (set ONLY +> (`packages/daemon/src/session-action-recorder.ts`), gated on `session.saveScriptBoundary !== undefined` (set ONLY > by a repair-armed `replay --save-script`; an ordinary, non-repair `open --save-script`/`close --save-script` > authoring recording never sets it — see decision 6's "Scope" note above) and on the entry's > `interactiveObservation` marker, which both recording call sites -> (`src/daemon/selector-recording.ts` for `get`/`is`/read-only `find`, `src/daemon/snapshot-runtime.ts` for +> (`packages/daemon/src/selector-recording.ts` for `get`/`is`/read-only `find`, `packages/daemon/src/snapshot-runtime.ts` for > `snapshot`) compute from the shared `isInteractiveObservation` predicate rather than each re-deriving it. > Every surface reaches this same function because every surface's request reaches the same daemon. > @@ -1159,8 +1159,8 @@ above and the gates they name are the authoritative record of current behavior. At acceptance, replay was deterministic. `.ad` scripts were plain text — one action per line, `#` comments, and a `context platform=... device=... theme=...` header (`src/replay/script.ts`) — recorded -via `open --save-script` (`src/daemon/session-action-recorder.ts`, -`src/daemon/session-script-writer.ts`) or hand-written, and executed step-by-step by +via `open --save-script` (`packages/daemon/src/session-action-recorder.ts`, +`packages/daemon/src/session-script-writer.ts`) or hand-written, and executed step-by-step by `runReplayScriptFile` (`src/daemon/handlers/session-replay-runtime.ts`) under the daemon's `replay`/`test` commands (`src/daemon/handlers/session-replay.ts`). Recorded touch/fill/get targets are selector chains with @@ -1289,15 +1289,15 @@ both `.ad` and Maestro paths) grounds the same conclusions from the caller's sea "Retry with --debug and inspect diagnostics log for details." (`defaultHintForCode`, `src/kernel/errors.ts:253-254`). - **Recordings contain zero verification steps.** The script writer strips every recorded `snapshot` - action (`buildOptimizedActions`, `src/daemon/session-script-writer.ts:69`: `if (action.command === + action (`buildOptimizedActions`, `packages/daemon/src/session-script-writer.ts:315`: `if (action.command === 'snapshot') continue;` — only synthetic ref-scoped snapshots are re-inserted, as resolution aids, not - observations), and the record-time flag allowlist (`SANITIZED_FLAG_KEYS`, - `src/daemon/session-action-recorder.ts:46-77`) carries neither `settle`/`settleQuietMs` nor `verify`, + observations), and the record-time flag allowlist (`RECORDED_FLAG_KEYS` from the flag + declarations' `recorded` field, `packages/daemon/src/session-action-recorder.ts:367-381`) carries neither `settle`/`settleQuietMs` nor `verify`, so `--settle`/`--verify` are dropped from recorded steps. A recording therefore replays actions with no outcome observation at all — exactly the gap decision 3's record-time identity evidence fills. A related, currently under-used precedent: recorded `@ref` steps already carry an optional identity -hint in the `.ad` file. `appendRefLabel` (`src/daemon/session-script-writer.ts:235-240`) writes the +hint in the `.ad` file. `appendRefLabel` (`packages/daemon/src/session-script-writer.ts:532-537`) writes the node's label as a trailing token, parsed back into `action.result.refLabel` (`src/replay/script.ts:269,295,315`). Today that label is used only as a fallback LOOKUP key (`tryResolveRefNode`'s `fallbackLabel`, `resolution.ts:393,413-430`) when the ref itself fails to diff --git a/docs/adr/0014-session-ref-frame-lifetime.md b/docs/adr/0014-session-ref-frame-lifetime.md index fb2059f088..de18c5de87 100644 --- a/docs/adr/0014-session-ref-frame-lifetime.md +++ b/docs/adr/0014-session-ref-frame-lifetime.md @@ -20,7 +20,7 @@ ref-frame vocabulary is promoted into `CONTEXT.md`. issuance scope) — kept separate from the latest operational observation (`session.snapshot`). The frame is one value on `SessionState`, replaced whole by a transition and never edited in place; its type is nominal (`#`-private fields), so no module outside - `src/daemon/ref-frame.ts` can construct a frame, edit one, or derive one from an existing + `packages/daemon/src/ref-frame.ts` can construct a frame, edit one, or derive one from an existing frame. What the type cannot judge is a whole frame moved unchanged — clearing the field, or assigning another session's frame — which the field-owner gate still covers. - A complete snapshot activates an `all` frame; `find`, settled diffs, and replay divergence diff --git a/docs/adr/0016-active-session-script-publication.md b/docs/adr/0016-active-session-script-publication.md index c1ee8c4a74..0e35791b69 100644 --- a/docs/adr/0016-active-session-script-publication.md +++ b/docs/adr/0016-active-session-script-publication.md @@ -2,8 +2,8 @@ ## Status -Accepted; implemented on `main` (`src/daemon/handlers/session-script-publication.ts`, -`src/daemon/session-script-active-publication.ts`), including the #1349 identity-level +Accepted; implemented on `main` (`packages/daemon/src/handlers/session-script-publication.ts`, +`packages/daemon/src/session-script-active-publication.ts`), including the #1349 identity-level destination-guard amendment. ## Rules at a glance diff --git a/docs/adr/0018-unified-event-journal.md b/docs/adr/0018-unified-event-journal.md index b77bb38d92..6f7f4d3fb0 100644 --- a/docs/adr/0018-unified-event-journal.md +++ b/docs/adr/0018-unified-event-journal.md @@ -64,7 +64,7 @@ redaction discipline, and sink (inventoried 2026-07-24): three request-lifecycle points plus `SessionStore.recordAction`, read only by the public `events` command. `action.recorded` is already a projection of `session.actions` pushes — the model this ADR generalizes. Crucially, not every append happens inside a request: - `finalizeRepairTeardown` (`src/daemon/session-store.ts`) records a synthesized `close` action + `finalizeRepairTeardown` (`packages/daemon/src/session-store.ts`) records a synthesized `close` action during idle reap or daemon shutdown, with — per its own comment — "no live request here." 3. **Progress streaming** (`src/request/progress.ts`, `src/daemon/request-progress-protocol.ts`). A closed, typed `RequestProgressEvent` union emitted through a single-sink `AsyncLocalStorage` @@ -85,7 +85,7 @@ usage at all — the codebase already avoids implicit pub/sub, which this design The channels overlap but share nothing: no common envelope, no shared kind vocabulary, and consumers couple to emit sites by string. The sharpest instance: agent-cost's `runnerRoundTrips` is `countDiagnosticEventsByPhase(['ios_runner_command_send', 'ios_runner_readiness_preflight'])` -(`src/daemon/request-router.ts`) — a hand-picked name list a new runner phase can silently drift +(`packages/daemon/src/request-router.ts`) — a hand-picked name list a new runner phase can silently drift from. That violates two established repo rules: *what enumerates N?* (nothing enumerates round-trip phases), and *categories come from recorded fields, never parsed names*. @@ -325,7 +325,7 @@ gets built. inconsistency, and three write paths. Kept as the migration's first independently useful step instead. - **Merge `upload-progress` and `app-events` in:** rejected. Upload progress is a local - byte-counter callback that never crosses the request scope; `src/daemon/app-events.ts` is a deep-link + byte-counter callback that never crosses the request scope; `packages/daemon/src/app-events.ts` is a deep-link builder for the `trigger-app-event` command, not an event channel. ## Validation required for implementation diff --git a/docs/adr/0019-request-bound-platform-runtime.md b/docs/adr/0019-request-bound-platform-runtime.md index 45bd0f0d83..4caa37e04e 100644 --- a/docs/adr/0019-request-bound-platform-runtime.md +++ b/docs/adr/0019-request-bound-platform-runtime.md @@ -24,7 +24,7 @@ is accepted. Completed 2026-08-27 through #2070–#2072. Every descriptor now declares `none`, `host`, `inventory`, or `device-runtime`; capability buckets and the legacy execution shape are gone. -Production `src/daemon/**` has zero dependencies on concrete platform implementations, enforced by +Production `packages/daemon/src/**` has zero dependencies on concrete platform implementations, enforced by R65. The per-command cutover table was retired after completion as required by section 6; R66 now enforces the permanent facts-only admission and runtime-proof invariants without naming historical routes or handler functions. @@ -830,7 +830,7 @@ helper stops follow the owning platform module's lifecycle policy, and close-tim neutral owner services. R65 is the daemon-side end-state enforcement: its planted-red AST tests reject every dependency edge — static, -dynamic, re-export, and type-only — from production `src/daemon/**` modules (test files excluded, +dynamic, re-export, and type-only — from production `packages/daemon/src/**` modules (test files excluded, matching the layering scanner's scope) to `src/platforms/**` and concrete `@agent-device/platform-*` packages. R13 governs concrete package imports across the whole tree, while `retired-platforms-zone` prevents the old root seam from being recreated; platform freedom is @@ -841,13 +841,13 @@ therefore structurally enforced rather than periodically measured. Some request-path work asks the host machine something without ever taking a device runtime: concrete local readiness, boot-time and runner-session observation, and open-target classification. Those asks now cross the daemon boundary as one required dependency, -`DaemonPlatformServices` (`src/daemon/platform-services.ts`), assembled by the daemon runtime's +`DaemonPlatformServices` (`packages/daemon/src/platform-services.ts`), assembled by the daemon runtime's root-composition module in `src/daemon-composition.ts` — which reaches the concrete adapters through `src/platform-runtime-daemon-services.ts` behind a function-scoped `await import` — and threaded composition → `startDaemonRuntime` deps → `RequestRouterDeps` → the request execution scope → the handlers and consumers. Stale-claim reconciliation gets the same treatment for the one act it may not perform itself: the composition supplies the `ClaimRecoveryGatewayFactory` -the daemon declares in `src/daemon/device/claim-recovery-gateway.ts`, built from +the daemon declares in `packages/daemon/src/device/claim-recovery-gateway.ts`, built from `src/platform-runtime-claim-recovery.ts` (likewise deferred), and the daemon keeps the transaction — what to rebuild from (the dead owner's recorded state dir), in what order, and when to dispose it. @@ -937,7 +937,7 @@ baseline and are open for revision or rejection. **Daemon top-level footprint.** `git ls-tree --name-only origin/main src/daemon/ | grep -E '\.ts$' | grep -vE '\.test\.ts$' | wc -l` measured 199 production files at `e624ef9d3f`. Proposed -target: ≤ 60. `src/daemon/**` is a permanent zone under R65; the target is about what remains +target: ≤ 60. `packages/daemon/src/**` is a permanent zone under R65; the target is about what remains there, not about retiring the directory. **Entry-to-platform hop count.** Corrected 2026-09-03, re-measured for #2278 at `27a97ee619`: diff --git a/docs/adr/0022-daemon-platform-runtime-coupling.md b/docs/adr/0022-daemon-platform-runtime-coupling.md index f0976e5726..2e00200e3a 100644 --- a/docs/adr/0022-daemon-platform-runtime-coupling.md +++ b/docs/adr/0022-daemon-platform-runtime-coupling.md @@ -8,17 +8,17 @@ and points at the gates rather than restating the inventory. Amended 2026-10-11 by #3431: the daemon-runtime composition edges this ADR classified (the gateway/diagnostics/resource-cleanup/lifecycle edges, the provider-runtime -hubs, and the platform-services and claim-recovery dynamic edges) moved out of `src/daemon/` into +hubs, and the platform-services and claim-recovery dynamic edges) moved out of `packages/daemon/src/` into the process-root composition module `src/daemon-composition.ts`, which R76 does not see because it is no longer a daemon-zone importer. #3430 then routed the leaked selector-query edge -(`src/daemon/direct-ios-selector.ts`) through the request-bound runtime binding, so the R76 +(`packages/daemon/src/direct-ios-selector.ts`) through the request-bound runtime binding, so the R76 inventory is empty; with nothing left to classify, the same change collapsed R76 to a plain ban on the coupling and deleted the classification machinery, per the rule's own kill criterion. The section-2 outcomes below remain the record of how each was classified. ## 1. Context -The platform-package migration removed direct production dependencies from `src/daemon/**` to +The platform-package migration removed direct production dependencies from `packages/daemon/src/**` to concrete platform code (R65: zero such imports in every form). What it did not prove is that every remaining platform-aware responsibility belongs in the daemon. At the audit baseline (`658f822c`) nine daemon files held 13 production imports of root `src/platform-runtime-*.ts` @@ -36,7 +36,7 @@ or owning issue. #2278 audited all four concerns at `27a97ee619`. `DAEMON_PLATFORM_RUNTIME_EDGES` in [`scripts/layering/daemon-platform-runtime-inventory.ts`](../../scripts/layering/daemon-platform-runtime-inventory.ts) is now empty, so the classification table and its symbol-drift and staleness passes are deleted - and R76 bans the coupling outright — any production `src/daemon/**` import of the family or of a + and R76 bans the coupling outright — any production `packages/daemon/src/**` import of the family or of a root hub that reaches it is a violation. The categories and outcomes below remain the record of how each edge was judged and retired): - **Composition-essential** — assembling neutral runtime implementations at the process root. @@ -64,7 +64,7 @@ or owning issue. #2278 audited all four concerns at `27a97ee619`. are daemon-policy-essential. Selector production and lifecycle participation stay separate. - **#2333 (done)** — lifecycle participation of platform resource owners. The `apple-runner-owner` and `operation-host` edges are retired; `daemon-runtime.ts` now holds - only the typed `PlatformOwnerLifecycle` contract (`src/daemon/platform-owner-lifecycle.ts`), + only the typed `PlatformOwnerLifecycle` contract (`packages/daemon/src/platform-owner-lifecycle.ts`), composed at the root by `platform-runtime-daemon-lifecycle.ts`, which is the sole importer of the Apple runner owner, the Android snapshot-helper and Web orphan cleanups, and legacy app-log marker recovery. The `resource-cleanup` edge stays, reclassified @@ -86,11 +86,11 @@ or owning issue. #2278 audited all four concerns at `27a97ee619`. 3. **Session state and store authority are measured as a symbol-level overlay and ratcheted on the handler-owned slice.** At `27a97ee619` the overlay is 112 `SessionState` shape edges and 68 `SessionStore` authority edges repo-wide, of which 14 shape / 22 authority files are - handler-owned (`src/daemon/handlers/**`). Gate rule **R75 `session-authority-overlay`** + handler-owned (`packages/daemon/src/handlers/**`). Gate rule **R75 `session-authority-overlay`** (reference measured via `measureRatchets` in `scripts/layering/ratchet-reference.ts`) holds the handler-owned file sets at or under the merge-base: handler code may lose files from either set, never gain them. The ratchet is added now that the edges are classified; - cross-module reads outside `src/daemon/handlers/**` are owned by the logical-module + cross-module reads outside `packages/daemon/src/handlers/**` are owned by the logical-module declarations (R7/R10) and are not ratcheted here. 4. **The entry-to-platform hop trace was re-run with hop roles** diff --git a/docs/adr/0023-end-state-hop-trace.md b/docs/adr/0023-end-state-hop-trace.md index 84fddb1da9..0b75f3cbd8 100644 --- a/docs/adr/0023-end-state-hop-trace.md +++ b/docs/adr/0023-end-state-hop-trace.md @@ -20,7 +20,7 @@ that reading. - **Unit**: one distinct production `.ts` file entered on the call path, counted once even if re-entered (a lazy `import()` of an already-counted file is not a new hop). Type-only imports and files that only supply types are not hops. -- **Range**: from the daemon's HTTP entry file (`src/daemon/server/http-server.ts`) through the +- **Range**: from the daemon's HTTP entry file (`packages/daemon/src/server/http-server.ts`) through the file that issues the concrete platform call, inclusive of both endpoints. For `press`/Android that is the serial-scoped `adb shell input tap` invocation; for `snapshot`/iOS it is the `socket.write` to the in-simulator AX bridge (primary arm) or the `fetch()` to the XCTest @@ -59,7 +59,7 @@ that reading. 41 files: 11 pass-through, 5 translation, 5 policy, 19 orchestration, 1 terminal (adapter). The request spine also runs side-calls that are not hops — they execute on every request but are -not the call that continues toward the platform boundary: `src/daemon/server/daemon-idle-reap.ts` +not the call that continues toward the platform boundary: `packages/daemon/src/server/daemon-idle-reap.ts` (`cancel()` resets the liveness timer as a sibling of `dispatchRequest`), `packages/host-kit/src/internal/transport.ts` (`timingSafeStringEqual` compares the auth token before the continuation), and `packages/host-kit/src/internal/request-cancel.ts` @@ -67,22 +67,22 @@ before the continuation), and `packages/host-kit/src/internal/request-cancel.ts` | # | File | Hand-off | Role | Delete-test | |---|------|----------|------|-------------| -| 1 | `src/daemon/server/http-server.ts` | parses `/rpc`, resolves the token; calls injected `handleRequest` | pass-through | KEEP — HTTP entry boundary | -| 2 | `src/daemon/server/daemon-runtime.ts` | `handleRequest`: in-flight count, cancels idle reap, `dispatchRequest` | orchestration | KEEP — request lifecycle orchestration | -| 3 | `src/daemon/request-router.ts` | auth, flag guards, scope creation, locked execution, handler chain | orchestration | KEEP — request admission + dispatch core | +| 1 | `packages/daemon/src/server/http-server.ts` | parses `/rpc`, resolves the token; calls injected `handleRequest` | pass-through | KEEP — HTTP entry boundary | +| 2 | `packages/daemon/src/server/daemon-runtime.ts` | `handleRequest`: in-flight count, cancels idle reap, `dispatchRequest` | orchestration | KEEP — request lifecycle orchestration | +| 3 | `packages/daemon/src/request-router.ts` | auth, flag guards, scope creation, locked execution, handler chain | orchestration | KEEP — request admission + dispatch core | | 4 | `packages/host-kit/src/internal/diagnostics.ts` | `withDiagnosticsScope` wraps the request task | pass-through | KEEP — per-request diagnostic attribution | | 5 | `src/request/device-inventory-context.ts` | `withDeviceInventoryContext` wraps the task | pass-through | KEEP — request-scoped device inventory context | | 6 | `src/core/dispatch-resolve.ts` | `withResolveTargetDeviceCacheScope` wraps the task | orchestration | KEEP — per-request target-resolution cache | -| 7 | `src/daemon/request-execution-scope.ts` | `createRequestExecutionScope`; `runLocked`/`runAdmitted` | orchestration | KEEP — scoped execution + lock/claim admission | +| 7 | `packages/daemon/src/request-execution-scope.ts` | `createRequestExecutionScope`; `runLocked`/`runAdmitted` | orchestration | KEEP — scoped execution + lock/claim admission | | 8 | `src/provider-device-runtime.ts` | `withProviderDeviceRuntimeScope` (`AsyncLocalStorage.run`) | pass-through | KEEP — provider-runtime scope boundary | -| 9 | `src/daemon/request-handler-chain.ts` | `runRequestHandlerChain` routes to the interaction handler | orchestration | KEEP — command routing | -| 10 | `src/daemon/interaction/index.ts` | route facade delegates to `handleInteractionCommands` | orchestration | KEEP — shared interaction route facade | -| 11 | `src/daemon/interaction/internal/interaction.ts` | switches `press` to `dispatchTargetedTouchViaRuntime` | policy | KEEP — touch command routing | -| 12 | `src/daemon/interaction/internal/interaction-touch-press.ts` | admits the touch, dispatches the runtime interaction | orchestration | KEEP — press admission + orchestration | -| 13 | `src/daemon/interaction/internal/interaction-touch-prepare.ts` | `prepareTouchDispatch` → `resolveBoundTouchRuntime` | translation | KEEP — shared admission + bind seam | -| 14 | `src/daemon/touch-runtime.ts` | resolves the plan, `bind(device, tapPointUse)` | orchestration | KEEP — tap runtime binding | -| 15 | `src/daemon/runtime-admission.ts` | `admitRuntimeOperations`: `inspectFacts`, per-op admission | policy | KEEP — per-operation admission | -| 16 | `src/daemon/request-runtime-binding.ts` | `bindDevice`: per-device-cached `gateway.bind` | orchestration | KEEP — device runtime binding | +| 9 | `packages/daemon/src/request-handler-chain.ts` | `runRequestHandlerChain` routes to the interaction handler | orchestration | KEEP — command routing | +| 10 | `packages/daemon/src/interaction/index.ts` | route facade delegates to `handleInteractionCommands` | orchestration | KEEP — shared interaction route facade | +| 11 | `packages/daemon/src/interaction/internal/interaction.ts` | switches `press` to `dispatchTargetedTouchViaRuntime` | policy | KEEP — touch command routing | +| 12 | `packages/daemon/src/interaction/internal/interaction-touch-press.ts` | admits the touch, dispatches the runtime interaction | orchestration | KEEP — press admission + orchestration | +| 13 | `packages/daemon/src/interaction/internal/interaction-touch-prepare.ts` | `prepareTouchDispatch` → `resolveBoundTouchRuntime` | translation | KEEP — shared admission + bind seam | +| 14 | `packages/daemon/src/touch-runtime.ts` | resolves the plan, `bind(device, tapPointUse)` | orchestration | KEEP — tap runtime binding | +| 15 | `packages/daemon/src/runtime-admission.ts` | `admitRuntimeOperations`: `inspectFacts`, per-op admission | policy | KEEP — per-operation admission | +| 16 | `packages/daemon/src/request-runtime-binding.ts` | `bindDevice`: per-device-cached `gateway.bind` | orchestration | KEEP — device runtime binding | | 17 | `src/platform-runtime-gateway.ts` | `loadLocal` → `loadHost` → `loadRuntime` | orchestration | KEEP — gateway boundary | | 18 | `src/platform-runtime.ts` | wires the android module, supplies `loadHost` | pass-through | KEEP — declared ADR §1/§2 registry boundary | | 19 | `src/platform-runtime-operation-host.ts` | `createPlatformRuntimeHost` assembles the host | orchestration | KEEP — host composition | @@ -90,12 +90,12 @@ before the continuation), and `packages/host-kit/src/internal/request-cancel.ts` | 21 | `packages/platform-android/src/runtime.ts` | `bind`: `inspectFacts` (fan-out site), builds the tap operation | orchestration | KEEP — android runtime owner | | 22 | `packages/contracts/src/local-interactor-operation-set.ts` | `bindLocalInteractorOperationSet` → `bindLocalTouchInteractor` | translation | KEEP — tap op mapped to the interactor | | 23 | `src/daemon/device-claim-admission.ts` | `admit`: owner claim rule; ordinary owner | policy | KEEP — device claim admission | -| 24 | `src/daemon/interaction/internal/interaction-touch-runtime.ts` | `dispatchRuntimeInteraction` → `createInteractionRuntimeForRoute` | orchestration | KEEP — interaction runtime dispatch | -| 25 | `src/daemon/interaction/internal/interaction-runtime.ts` | `createInteractionAgentDevice` with the executor backend | orchestration | KEEP — agent device construction | +| 24 | `packages/daemon/src/interaction/internal/interaction-touch-runtime.ts` | `dispatchRuntimeInteraction` → `createInteractionRuntimeForRoute` | orchestration | KEEP — interaction runtime dispatch | +| 25 | `packages/daemon/src/interaction/internal/interaction-runtime.ts` | `createInteractionAgentDevice` with the executor backend | orchestration | KEEP — agent device construction | | 26 | `src/runtime.ts` | `createAgentDevice`: backend + `bindCommands` | orchestration | KEEP — agent device facade | | 27 | `src/commands/index.ts` | `bindCommands` → `bindInteractionCommands` | orchestration | KEEP — command catalog boundary | | 28 | `src/commands/interaction/runtime/index.ts` | `bindInteractionCommands`: `press` → `pressCommand` | orchestration | KEEP — nine-command binding surface | -| 29 | `src/daemon/interaction/internal/interaction-touch-android-readiness.ts` | `runWithAndroidDialogReadinessCheck` wraps `run` | policy | KEEP — blocking-dialog readiness gate | +| 29 | `packages/daemon/src/interaction/internal/interaction-touch-android-readiness.ts` | `runWithAndroidDialogReadinessCheck` wraps `run` | policy | KEEP — blocking-dialog readiness gate | | 30 | `src/commands/interaction/runtime/interactions.ts` | `pressCommand` → `tapCommand`: resolve target, `backend.tap` | orchestration | KEEP — tap command execution | | 31 | `src/commands/interaction/runtime/resolution.ts` | `resolveInteractionTarget` applies guards, returns the point | translation | KEEP — tap target resolution | | 32 | `packages/contracts/src/interactor-operation-binding.ts` | `interactorFor` resolves the local interactor | translation | KEEP — shared interactor resolution seam | @@ -125,11 +125,11 @@ only by its named composition module per ADR Decision §1). `tv-remote`, `viewport` (each `-runtime.ts`). **Response path (not hops).** 8 files execute only after the platform call: -`src/daemon/interaction/internal/interaction-touch-response.ts`, -`src/daemon/interaction/internal/interaction-common.ts`, -`src/daemon/interaction-surface-signature.ts`, `src/daemon/request-finalization.ts`, -`src/daemon/session-event-log.ts`, `src/daemon/session-snapshot.ts`, -`src/daemon/recording-gestures.ts`, `src/daemon/deferred-interaction-outcome.ts`. +`packages/daemon/src/interaction/internal/interaction-touch-response.ts`, +`packages/daemon/src/interaction/internal/interaction-common.ts`, +`packages/daemon/src/interaction-surface-signature.ts`, `packages/daemon/src/request-finalization.ts`, +`packages/session-journal/src/session-event-log.ts`, `packages/daemon/src/session-snapshot.ts`, +`packages/daemon/src/recording-gestures.ts`, `packages/daemon/src/deferred-interaction-outcome.ts`. **Forks not followed**: `request-platform-provider-context.ts` (the call is guarded by the router's early return for a bare local daemon — zero runtimes + non-web), @@ -149,31 +149,31 @@ captures join it). Shared prefix 30 files; primary arm 47 distinct (30 + 17); fallback arm 49 distinct (30 + 19); 66 distinct files across the union. The request spine's side-calls — the idle-reap reset, the auth comparison, the cancellation gate, and the Android freshness guard/clear -(`src/daemon/session-snapshot-freshness.ts`, a guard read plus a post-capture clear that no-ops +(`packages/daemon/src/session-snapshot-freshness.ts`, a guard read plus a post-capture clear that no-ops on iOS) — run on this prefix as siblings of the continuation and are not counted. ### Shared prefix (entry → fork) | # | File | Hand-off | Role | Delete-test | |---|------|----------|------|-------------| -| 1 | `src/daemon/server/http-server.ts` | parses `/rpc`, resolves the token; calls injected `handleRequest` | pass-through | KEEP — HTTP entry boundary | -| 2 | `src/daemon/server/daemon-runtime.ts` | `handleRequest`: in-flight count, cancels idle reap, `dispatchRequest` | orchestration | KEEP — request lifecycle orchestration | -| 3 | `src/daemon/request-router.ts` | auth, flag guards, scope creation, locked execution, handler chain | orchestration | KEEP — request admission + dispatch core | +| 1 | `packages/daemon/src/server/http-server.ts` | parses `/rpc`, resolves the token; calls injected `handleRequest` | pass-through | KEEP — HTTP entry boundary | +| 2 | `packages/daemon/src/server/daemon-runtime.ts` | `handleRequest`: in-flight count, cancels idle reap, `dispatchRequest` | orchestration | KEEP — request lifecycle orchestration | +| 3 | `packages/daemon/src/request-router.ts` | auth, flag guards, scope creation, locked execution, handler chain | orchestration | KEEP — request admission + dispatch core | | 4 | `packages/host-kit/src/internal/diagnostics.ts` | `withDiagnosticsScope` wraps the request task | pass-through | KEEP — per-request diagnostic attribution | | 5 | `src/request/device-inventory-context.ts` | `withDeviceInventoryContext` wraps the task | pass-through | KEEP — request-scoped device inventory context | | 6 | `src/core/dispatch-resolve.ts` | `withResolveTargetDeviceCacheScope` wraps the task | orchestration | KEEP — per-request target-resolution cache | -| 7 | `src/daemon/request-execution-scope.ts` | `createRequestExecutionScope`; `runLocked`/`runAdmitted` | orchestration | KEEP — scoped execution + lock/claim admission | +| 7 | `packages/daemon/src/request-execution-scope.ts` | `createRequestExecutionScope`; `runLocked`/`runAdmitted` | orchestration | KEEP — scoped execution + lock/claim admission | | 8 | `src/provider-device-runtime.ts` | `withProviderDeviceRuntimeScope` (`AsyncLocalStorage.run`) | pass-through | KEEP — provider-runtime scope boundary | -| 9 | `src/daemon/request-handler-chain.ts` | `runRequestHandlerChain` routes `snapshot` to `runSnapshotHandler` | orchestration | KEEP — command routing | -| 10 | `src/daemon/handlers/snapshot.ts` | `handleSnapshotCommands` routes the plain arm | policy | KEEP — snapshot command routing | -| 11 | `src/daemon/snapshot-runtime.ts` | `dispatchSnapshotViaRuntime` → `params.execute` | pass-through | KEEP — snapshot execute seam (route tests pin it) | -| 12 | `src/daemon/snapshot-command-runtime.ts` | resolves the bound capture; wires session/backend; runs the op | orchestration | KEEP — capture wiring + recording | -| 13 | `src/daemon/deferred-interaction-outcome.ts` | `resolveDeferredInteractionOutcome` before a fresh capture | policy | KEEP — pending-outcome settlement (may short-circuit) | -| 14 | `src/daemon/snapshot-capture.ts` | `resolveSnapshotScope` + the capture attempt | orchestration | KEEP — capture attempt + scope resolution | -| 15 | `src/daemon/snapshot-session.ts` | `resolveSessionDevice` for the capture | translation | KEEP — snapshot session/device resolution | -| 16 | `src/daemon/snapshot-runtime-binding.ts` | `resolveBoundSnapshotCaptureRuntime`: admit-then-bind | policy | KEEP — ADR 0019 §9 admit-then-bind seam | -| 17 | `src/daemon/session-runtime-admission.ts` | `admitRuntimePlan` (fan-out site) / `requireRuntimeBinding` | policy | KEEP — runtime plan fact admission | -| 18 | `src/daemon/request-runtime-binding.ts` | `bindDevice`: per-device-cached `gateway.bind` | orchestration | KEEP — device runtime binding | +| 9 | `packages/daemon/src/request-handler-chain.ts` | `runRequestHandlerChain` routes `snapshot` to `runSnapshotHandler` | orchestration | KEEP — command routing | +| 10 | `packages/daemon/src/handlers/snapshot.ts` | `handleSnapshotCommands` routes the plain arm | policy | KEEP — snapshot command routing | +| 11 | `packages/daemon/src/snapshot-runtime.ts` | `dispatchSnapshotViaRuntime` → `params.execute` | pass-through | KEEP — snapshot execute seam (route tests pin it) | +| 12 | `packages/daemon/src/snapshot-command-runtime.ts` | resolves the bound capture; wires session/backend; runs the op | orchestration | KEEP — capture wiring + recording | +| 13 | `packages/daemon/src/deferred-interaction-outcome.ts` | `resolveDeferredInteractionOutcome` before a fresh capture | policy | KEEP — pending-outcome settlement (may short-circuit) | +| 14 | `packages/daemon/src/snapshot-capture.ts` | `resolveSnapshotScope` + the capture attempt | orchestration | KEEP — capture attempt + scope resolution | +| 15 | `packages/daemon/src/snapshot-session.ts` | `resolveSessionDevice` for the capture | translation | KEEP — snapshot session/device resolution | +| 16 | `packages/daemon/src/snapshot-runtime-binding.ts` | `resolveBoundSnapshotCaptureRuntime`: admit-then-bind | policy | KEEP — ADR 0019 §9 admit-then-bind seam | +| 17 | `packages/daemon/src/session-runtime-admission.ts` | `admitRuntimePlan` (fan-out site) / `requireRuntimeBinding` | policy | KEEP — runtime plan fact admission | +| 18 | `packages/daemon/src/request-runtime-binding.ts` | `bindDevice`: per-device-cached `gateway.bind` | orchestration | KEEP — device runtime binding | | 19 | `src/platform-runtime-gateway.ts` | `loadLocal` → `loadHost` → `loadRuntime` | orchestration | KEEP — gateway boundary | | 20 | `src/platform-runtime.ts` | wires the apple module, supplies `loadHost` | pass-through | KEEP — declared ADR §1/§2 registry boundary | | 21 | `src/platform-runtime-operation-host.ts` | `createPlatformRuntimeHost` assembles the host | orchestration | KEEP — host composition | @@ -242,10 +242,10 @@ Re-entry: arm B #4 enters `packages/platform-apple/src/index.ts` (shared #22) vi above, as side-calls of the admission step. **Response path (not hops).** 22 files execute only after the platform call: -`src/daemon/ref-frame.ts`, `src/daemon/session-action-recorder.ts`, -`src/daemon/snapshot-quality-latch.ts`, `src/daemon/request-finalization.ts`, -`src/daemon/session-event-request.ts`, `src/daemon/session-snapshot.ts` (lineage), -`src/daemon/sparse-fallback-screenshot.ts`, `src/core/snapshot-state.ts`, +`packages/daemon/src/ref-frame.ts`, `packages/daemon/src/session-action-recorder.ts`, +`packages/daemon/src/snapshot-quality-latch.ts`, `packages/daemon/src/request-finalization.ts`, +`packages/session-journal/src/session-event-request.ts`, `packages/daemon/src/session-snapshot.ts` (lineage), +`packages/daemon/src/sparse-fallback-screenshot.ts`, `src/core/snapshot-state.ts`, `packages/contracts/src/capture.ts`, `packages/platform-apple/src/runner/snapshot-presentation.ts`, `src/snapshot/ios-snapshot-runtime.ts`, the `packages/capture-kit/src/ios-snapshot-engine/` modules (engine, invariants, geometry, geometry-policy, projection, graph, diff --git a/docs/adr/0033-collocation-decision-table.md b/docs/adr/0033-collocation-decision-table.md index e559470837..16f9bf7494 100644 --- a/docs/adr/0033-collocation-decision-table.md +++ b/docs/adr/0033-collocation-decision-table.md @@ -79,7 +79,7 @@ already owns the operations behind the vocabulary. | `src/diagnostics.ts` | keep | The diagnostics seam every zone imports (AGENTS.md mandates it); highest fan-in in the repo is what a substrate looks like, not misplacement. | | `src/internal/request-cancel.ts` | keep | Request-cancellation mechanics AGENTS.md routes to `host-kit/request`; internal beside its facade is already the collocation. | | `src/request.ts` | keep | Cross-layer request contracts AGENTS.md names as a host-kit seam; consumers span every zone. | -| `src/session-paths.ts` | keep | Session-artifact path grammar the daemon, cli, and platforms all resolve; AGENTS.md keeps the path *policy* in `src/daemon/session-artifact-paths.ts`, which consumes this. | +| `src/session-paths.ts` | keep | Session-artifact path grammar the daemon, cli, and platforms all resolve; AGENTS.md keeps the path *policy* in `packages/daemon/src/session-artifact-paths.ts`, which consumes this. | ### kernel @@ -133,7 +133,7 @@ the whole `daemon-contracts` zone has moved into `packages/daemon-contracts` — package derive the zone, so every moved file's `ROOT_MODULE_ZONES` row is gone. The daemon ⇄ client shared files that remain here (`provider-credential-fingerprint.ts`) trace to #2559, which relocated the shared contracts **to the process root** so the client stops -importing `src/daemon/` at all; R78 keeps any client→daemon +importing `packages/daemon/src/` at all; R78 keeps any client→daemon edge at zero runtime and a five-line recorded type-only residue, and #3288's `daemon-contracts` zone was the declaration of that shared-below-both ownership — the extraction makes it physical, with R11 and the package's dependency edges holding the same boundary. Rows on @@ -152,7 +152,7 @@ optimal. | `src/platform-runtime-resource-cleanup.ts` | retain for this batch | Same path-keyed R13/ADR 0022 seam. | | `src/provider-credential-fingerprint.ts` | keep (type extracted) | Daemon ⇄ client shared contract from the same #2559 decision as `daemon-policy-file.ts`; #3288 declares its zone beside the provider composition that reads the credentials it fingerprints. PR 6 of the daemon extraction moved only the `DaemonProviderCredentials` declaration to `packages/daemon-contracts` (`./provider-credentials`), the same shared-below-both landing as the policy file; the fingerprinting implementation stays here because it reads the installed-plugin manifest. | | `src/provider-limrun-runtime.ts` | keep | Proposed → provider-limrun, but there is no seam: the class's constructor self-builds the root dependency factory (`src/sdk/limrun-runtime-dependencies.ts`), which is the ADR 0019 composition seam — it loads the root's adb-host binder, core Android interactor, and platform-runtime app-state helpers that the package must not import. Moving the class means moving that composition, which is design, not a move. | -| `src/request-progress-protocol.ts` | moved → `packages/daemon-contracts/src/request-progress-protocol.ts` | Daemon ⇄ client shared contract from the same #2559 decision — the client reads it statically (`daemon-client-progress.ts`) and the server through `src/daemon/server/`, so only #2559's shared-placement boundary and the wire-compat ledgers pin it; declared `daemon-contracts` by #3288 and now physically placed by the extraction. Contracts was considered and R18 keeps contracts free of envelope validation mechanics. The wire-ledger keys moved with the file. | +| `src/request-progress-protocol.ts` | moved → `packages/daemon-contracts/src/request-progress-protocol.ts` | Daemon ⇄ client shared contract from the same #2559 decision — the client reads it statically (`daemon-client-progress.ts`) and the server through `packages/daemon/src/server/`, so only #2559's shared-placement boundary and the wire-compat ledgers pin it; declared `daemon-contracts` by #3288 and now physically placed by the extraction. Contracts was considered and R18 keeps contracts free of envelope validation mechanics. The wire-ledger keys moved with the file. | | `src/runtime-command-surface.ts` | moved → `src/command-runtime/runtime-command-surface.ts` ([#3299](https://github.com/callstack/agent-device/pull/3299)) | Physical move landed with `runtime-factory.ts` as one assembly group: the command-surface binding sits beside the factory it composes, under the folder that derives its `command-runtime` zone, so `topFolder` replaces the per-file `ROOT_MODULE_ZONES` row. | | `src/runtime-factory.ts` | moved → `src/command-runtime/runtime-factory.ts` ([#3299](https://github.com/callstack/agent-device/pull/3299)) | Physical move landed: the runtime assembly now lives under the folder that derives its `command-runtime` zone, with the same row deletion through folder-derived ownership. | @@ -188,6 +188,23 @@ files have no seam (published facade, public-type collision, root dependency fac moved there by [#3297](https://github.com/callstack/agent-device/pull/3297)) are now `packages/daemon-contracts/src/` behind narrow per-file subpath exports. +## The daemon package's export surface + +`@agent-device/daemon` publishes a façade, not importer reach: one named subpath per +production/script consumer — a subpath that only tests import is not production surface. +Everything else a root test reaches lives under the `./testing/` namespace: named +`./testing/` entries for production modules tests drive, named `./testing/` +entries, and, per fixture folder, a `./testing//*` pattern whose target template +reconstructs the source path. Never a wildcard that also exposes production modules. R11 +refuses any `./testing/` import from a non-test file, so root production code cannot import +a module the package publishes for tests (a package test double reached through the +boundary is production code depending on a fake), and root production imports are limited +to the named production surface. The exports keys stay exact except the per-folder fixture +patterns; `resolveWorkspaceSpecifier` (layering model) owns Node's exports semantics — the +layering edges, the depgraph, mutation ownership, and R11's named-surface check call it, and +the Stryker alias table orders its Vite first-match list to resolve in exactly its order — +so every lane gives a specifier the module id Node's exports resolution gives it. + ## Refuted alternatives - **Move every ≥80% community match into its dominant zone.** Rejected: the measure is diff --git a/docs/agents/cli-flags.md b/docs/agents/cli-flags.md index b06eb28d27..d15af0578c 100644 --- a/docs/agents/cli-flags.md +++ b/docs/agents/cli-flags.md @@ -28,7 +28,7 @@ Thread a flag only through the layers that consume it: interface exposes it. 6. `src/client/client-normalizers.ts`: update daemon flag normalization only when the request still needs a public-to-internal translation. -7. `src/daemon/context.ts` and `src/daemon/dispatch-context.ts`: add the field only when it flows into +7. `packages/daemon/src/context.ts` and `packages/daemon/src/dispatch-context.ts`: add the field only when it flows into platform dispatch. 8. Handler/platform modules: thread the option only after the command surface, grammar, and projection prove it belongs there. diff --git a/docs/agents/test-audit.md b/docs/agents/test-audit.md index c9e9af4c29..b6d2ef3351 100644 --- a/docs/agents/test-audit.md +++ b/docs/agents/test-audit.md @@ -50,7 +50,7 @@ Plant the production edit representing the claimed bug: the pre-edit body must s ## Dispatching subagents -Run parallel read-only lanes with exclusive edit ownership: subsystem lanes (per platform package, `src/daemon`, core packages, `scripts/**`), one cross-cutting junk-pattern sweep, one never-run inventory (Vitest includes, `node --test` globs, gate ids). Mandate in every prompt: READ-ONLY; read the production owner and name the bug; verify skip guards and runner/gate ownership; paste the retention list; false positives cost more than misses. +Run parallel read-only lanes with exclusive edit ownership: subsystem lanes (per platform package, `packages/daemon`, core packages, `scripts/**`), one cross-cutting junk-pattern sweep, one never-run inventory (Vitest includes, `node --test` globs, gate ids). Mandate in every prompt: READ-ONLY; read the production owner and name the bug; verify skip guards and runner/gate ownership; paste the retention list; false positives cost more than misses. ## Landing diff --git a/docs/agents/testing.md b/docs/agents/testing.md index e049a264e3..e922b0e81a 100644 --- a/docs/agents/testing.md +++ b/docs/agents/testing.md @@ -68,12 +68,11 @@ Read the entry file before running a lane. Do not copy its environment matrix he ## Shared test utilities Before creating fixtures, look in `@agent-device/test-kit/` (generic) and -`src/daemon/__tests__/support/` (daemon-shaped). Import named builders -from the module that defines them; avoid importing -unrelated helpers through a barrel. Shared `DeviceInfo`, session, snapshot, store, runtime-fact, -and mocked-binary values belong in a sibling fixture module, not in repeated test literals. -`PROPERTY_RUNS` and the touch-point/rect arbitraries live in -`@agent-device/selectors/snapshot-geometry-fixtures`, not `src/__tests__/test-utils/`; +`packages/daemon/src/__tests__/support/` (daemon-shaped). Import named builders from their +defining module, never through a barrel. Shared `DeviceInfo`, session, snapshot, store, +runtime-fact, and mocked-binary values belong in a sibling fixture module, not in repeated +test literals. `PROPERTY_RUNS` and the touch-point/rect arbitraries live in +`@agent-device/selectors/snapshot-geometry-fixtures`; `makeSnapshotState` lives in `@agent-device/capture-kit/snapshot-state-fixtures`. Use `mkdtempForTest` or `mkdtempForTestSync`. Global setup redirects `TMPDIR` for the run and @@ -134,7 +133,7 @@ Run `pnpm depgraph affected` before touching a high-fan-in module: ```sh pnpm depgraph affected packages/host-kit/src/command.ts -pnpm depgraph affected src/daemon/ref-frame.ts --json --limit 25 +pnpm depgraph affected packages/daemon/src/ref-frame.ts --json --limit 25 ``` Use its dependent, command, and guarantee-cell report to scope inspection. `pnpm check:affected --run` diff --git a/examples/sdk/tsconfig.json b/examples/sdk/tsconfig.json index f90c5dd2fe..483a3f32d9 100644 --- a/examples/sdk/tsconfig.json +++ b/examples/sdk/tsconfig.json @@ -39,6 +39,7 @@ { "path": "../../packages/capture-kit" }, { "path": "../../packages/command-registry" }, { "path": "../../packages/contracts" }, + { "path": "../../packages/daemon" }, { "path": "../../packages/daemon-contracts" }, { "path": "../../packages/device-selection" }, { "path": "../../packages/host-kit" }, diff --git a/fallow-baselines/health.json b/fallow-baselines/health.json index 5fe587874b..e5e6afe7f0 100644 --- a/fallow-baselines/health.json +++ b/fallow-baselines/health.json @@ -25,22 +25,22 @@ "count": 1 } }, - "src/daemon/interaction/internal/find.ts": { + "packages/daemon/src/interaction/internal/find.ts": { "complexity_moderate": { "count": 1 } }, - "src/daemon/handlers/snapshot-settings.ts": { + "packages/daemon/src/handlers/snapshot-settings.ts": { "complexity_moderate": { "count": 1 } }, - "src/daemon/recording-gestures.ts": { + "packages/daemon/src/recording-gestures.ts": { "complexity_moderate": { "count": 1 } }, - "src/daemon/session-selector.ts": { + "packages/daemon/src/session-selector.ts": { "complexity_moderate": { "count": 1 } @@ -80,13 +80,13 @@ "target_keys": [ "src/daemon-client/daemon-client.ts:high impact", "src/cli/parser/args.ts:high impact", - "src/daemon/lease-context.ts:high impact", + "packages/daemon/src/lease-context.ts:high impact", "packages/replay-port/src/daemon-port/session-replay-heal.ts:high impact", - "src/daemon/context.ts:high impact", - "src/daemon/handlers/session.ts:complexity", + "packages/daemon/src/context.ts:high impact", + "packages/daemon/src/handlers/session.ts:complexity", "packages/selectors/src/internal/predicates.ts:high impact", "packages/provision-kit/src/boot-diagnostics.ts:complexity", - "src/daemon/session-routing.ts:high impact", + "packages/daemon/src/session-routing.ts:high impact", "src/commands/cli-grammar/common.ts:high impact", "packages/kernel/src/success-text.ts:high impact", "src/cli.ts:complexity", @@ -95,8 +95,8 @@ "packages/kernel/src/rect-center.ts:high impact", "packages/platform-apple/src/core/app-launch.ts:complexity", "packages/kernel/src/record.ts:high impact", - "src/daemon/daemon-command-registry.ts:high impact", - "src/daemon/handlers/session-doctor-output.ts:high impact", + "packages/daemon/src/daemon-command-registry.ts:high impact", + "packages/daemon/src/handlers/session-doctor-output.ts:high impact", "packages/platform-apple/src/core/perf-xml.ts:high impact", "src/client/screenshot-result.ts:high impact", "packages/platform-web/src/json-utils.ts:high impact", diff --git a/oxlint.config.ts b/oxlint.config.ts index c2b9e03fa8..822051a174 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -124,7 +124,7 @@ export default defineConfig({ { files: [ 'src/daemon-client/daemon-client-rpc.ts', - 'src/daemon/downloadable-artifact-http.ts', + 'packages/daemon/src/downloadable-artifact-http.ts', 'src/remote/remote-request-diagnostics.ts', 'src/remote/upload-stream.ts', ], @@ -135,7 +135,7 @@ export default defineConfig({ }, { files: [ - 'src/daemon/replay/internal/__tests__/session-replay-target-verification-runtime.test.ts', + 'packages/daemon/src/__tests__/replay-target/session-replay-target-verification-runtime.test.ts', ], rules: { 'unicorn/prefer-string-raw': 'off', diff --git a/package.json b/package.json index b43df4efa5..23706027fb 100644 --- a/package.json +++ b/package.json @@ -293,6 +293,7 @@ "@agent-device/capture-kit": "workspace:*", "@agent-device/command-registry": "workspace:*", "@agent-device/contracts": "workspace:*", + "@agent-device/daemon": "workspace:*", "@agent-device/daemon-contracts": "workspace:*", "@agent-device/device-selection": "workspace:*", "@agent-device/host-kit": "workspace:*", diff --git a/packages/ad-replay/src/internal/__tests__/step-loop.test.ts b/packages/ad-replay/src/internal/__tests__/step-loop.test.ts index bb2ce6a98f..bf274b8d32 100644 --- a/packages/ad-replay/src/internal/__tests__/step-loop.test.ts +++ b/packages/ad-replay/src/internal/__tests__/step-loop.test.ts @@ -14,7 +14,7 @@ import type { TargetAnnotationV1 } from '@agent-device/contracts/replay'; * `packages/replay-port/src/daemon-port/native-command.ts` (`runReplayCommand`) does. The equivalent * daemon-level assertions (full `SessionStore`/`runReplayCommand` round * trip, including the `--keep-session` live-session postcondition) live in - * `src/daemon/__tests__/replay-runtime/session-replay-runtime-keep-session.test.ts` + * `packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-keep-session.test.ts` * (renamed from `session-replay-terminal-lifecycle.test.ts` by the #1555 * structural-quality review — see that file's own header for the rationale); * this file covers the SAME suppression decision at the cheaper, diff --git a/packages/ad-script/src/internal/open-script.ts b/packages/ad-script/src/internal/open-script.ts index 63ac8fc755..816f1a46e0 100644 --- a/packages/ad-script/src/internal/open-script.ts +++ b/packages/ad-script/src/internal/open-script.ts @@ -14,7 +14,7 @@ import { * (or falls back to) that accumulation. Two independent daemon/package call * sites needed exactly this scan and, before this move, each carried its own * copy: `packages/ad-replay/src/internal/inspect.ts`'s plan-digest platform - * precedence, and `src/daemon/replay-device-selection.ts`'s + * precedence, and `packages/daemon/src/replay-device-selection.ts`'s * `readScriptReplaySelection` (fused into its own single pass alongside an * app-target scan). A `src/` root file cannot become a façade dependency * (R11), and a workspace package may not reach back into root `src/` either diff --git a/packages/capture-kit/src/mobile-snapshot-semantics.test.ts b/packages/capture-kit/src/mobile-snapshot-semantics.test.ts index d5b939df62..e263131c4b 100644 --- a/packages/capture-kit/src/mobile-snapshot-semantics.test.ts +++ b/packages/capture-kit/src/mobile-snapshot-semantics.test.ts @@ -644,7 +644,7 @@ test('mobile presentation does not let contradictory scroll indicator add hidden }); // #1542: isConfirmedOnScreenProbe is the pure geometry boundary the off-screen -// refusal double-check's direct probe (src/daemon/offscreen-target-probe.ts) +// refusal double-check's direct probe (packages/daemon/src/offscreen-target-probe.ts) // reduces its confirm/don't-confirm decision to, once it has a fresh, // tree-independent read of the target. Each branch below is proved with a // counterfactual per docs/agents/testing.md — see the comment on each test diff --git a/packages/capture-kit/src/mobile-snapshot-semantics.ts b/packages/capture-kit/src/mobile-snapshot-semantics.ts index 23d21cd508..7ef629c4a3 100644 --- a/packages/capture-kit/src/mobile-snapshot-semantics.ts +++ b/packages/capture-kit/src/mobile-snapshot-semantics.ts @@ -84,7 +84,7 @@ function analyzeMobileSnapshotVisibility(nodes: SnapshotNode[]): { /** * #1542: the pure geometry boundary the off-screen refusal double-check's - * direct probe (`src/daemon/offscreen-target-probe.ts`) reduces its decision + * direct probe (`packages/daemon/src/offscreen-target-probe.ts`) reduces its decision * to, once it has a fresh, tree-independent read of one element. A probe * confirms the element genuinely on-screen only when BOTH hold: XCTest's own * live hit-test says `hittable`, AND the tap point sits inside the root diff --git a/packages/capture-kit/src/snapshot-chrome.ts b/packages/capture-kit/src/snapshot-chrome.ts index 10c897c520..f1d993259d 100644 --- a/packages/capture-kit/src/snapshot-chrome.ts +++ b/packages/capture-kit/src/snapshot-chrome.ts @@ -375,7 +375,7 @@ export function collectSettleChromeRefs( * only excludes nodes whose OWN type is `keyboard` still leaks every key and * assistant control as "discriminating" evidence. * - * Used by `src/daemon/interaction-surface-signature.ts`'s post-gesture + * Used by `packages/daemon/src/interaction-surface-signature.ts`'s post-gesture * baseline-distrust discriminating-overlap classification (#1542 defect 2, * #1563 review): that comparison operates on flat signature entries with no * ref-selection budget of its own, so it needs the ref set directly rather diff --git a/packages/command-registry/src/registry.ts b/packages/command-registry/src/registry.ts index 8b0ce02337..d6d2467d2b 100644 --- a/packages/command-registry/src/registry.ts +++ b/packages/command-registry/src/registry.ts @@ -136,7 +136,7 @@ export type DescriptorCatalogRecord = { /** * The literal union of every command whose `daemon.route` is `'session'`. - * Drives `SESSION_COMMAND_HANDLER_IMPLS` in `src/daemon/handlers/session.ts`: adding a + * Drives `SESSION_COMMAND_HANDLER_IMPLS` in `packages/daemon/src/handlers/session.ts`: adding a * session-routed descriptor without a matching handler table entry is a compile error rather * than a runtime routing gap caught only by `expectHandlerResponse`. */ @@ -165,7 +165,7 @@ export type DescriptorDaemonRouteCommandName = // --------------------------------------------------------------------------- // Daemon request-policy trait bundles — copied VERBATIM from -// src/daemon/daemon-command-registry.ts (DAEMON_COMMAND_DESCRIPTORS). +// packages/daemon/src/daemon-command-registry.ts (DAEMON_COMMAND_DESCRIPTORS). // --------------------------------------------------------------------------- const ADMISSION_AND_LOCK_EXEMPT = { @@ -508,7 +508,9 @@ export const RAW_COMMAND_DESCRIPTORS = [ { name: 'human_control', deviceClaimPolicy: 'none', - ...(ownerFilesEnabled ? { ownerFiles: ['src/daemon/handlers/human-control.ts'] as const } : {}), + ...(ownerFilesEnabled + ? { ownerFiles: ['packages/daemon/src/handlers/human-control.ts'] as const } + : {}), catalog: { group: 'internal', key: 'humanControl' }, recordsSessionAction: false, daemon: { @@ -526,7 +528,9 @@ export const RAW_COMMAND_DESCRIPTORS = [ { name: 'lease_allocate', deviceClaimPolicy: 'none', - ...(ownerFilesEnabled ? { ownerFiles: ['src/daemon/handlers/lease.ts'] as const } : {}), + ...(ownerFilesEnabled + ? { ownerFiles: ['packages/daemon/src/handlers/lease.ts'] as const } + : {}), catalog: { group: 'internal', key: 'leaseAllocate' }, recordsSessionAction: false, daemon: { @@ -541,7 +545,9 @@ export const RAW_COMMAND_DESCRIPTORS = [ { name: 'lease_heartbeat', deviceClaimPolicy: 'none', - ...(ownerFilesEnabled ? { ownerFiles: ['src/daemon/handlers/lease.ts'] as const } : {}), + ...(ownerFilesEnabled + ? { ownerFiles: ['packages/daemon/src/handlers/lease.ts'] as const } + : {}), catalog: { group: 'internal', key: 'leaseHeartbeat' }, recordsSessionAction: false, daemon: { @@ -557,7 +563,9 @@ export const RAW_COMMAND_DESCRIPTORS = [ { name: 'lease_release', deviceClaimPolicy: 'none', - ...(ownerFilesEnabled ? { ownerFiles: ['src/daemon/handlers/lease.ts'] as const } : {}), + ...(ownerFilesEnabled + ? { ownerFiles: ['packages/daemon/src/handlers/lease.ts'] as const } + : {}), catalog: { group: 'internal', key: 'leaseRelease' }, recordsSessionAction: false, daemon: { @@ -592,7 +600,7 @@ export const RAW_COMMAND_DESCRIPTORS = [ name: 'session_list', deviceClaimPolicy: 'none', ...(ownerFilesEnabled - ? { ownerFiles: ['src/daemon/session-lifecycle/internal/inventory.ts'] as const } + ? { ownerFiles: ['packages/daemon/src/session-lifecycle/internal/inventory.ts'] as const } : {}), catalog: { group: 'internal', key: 'sessionList' }, recordsSessionAction: false, @@ -610,7 +618,7 @@ export const RAW_COMMAND_DESCRIPTORS = [ name: 'session_save_script', deviceClaimPolicy: 'none', ...(ownerFilesEnabled - ? { ownerFiles: ['src/daemon/handlers/session-script-publication.ts'] as const } + ? { ownerFiles: ['packages/daemon/src/handlers/session-script-publication.ts'] as const } : {}), catalog: { group: 'internal', key: 'sessionSaveScript' }, recordsSessionAction: false, @@ -887,8 +895,8 @@ export const RAW_COMMAND_DESCRIPTORS = [ ...(ownerFilesEnabled ? { ownerFiles: [ - 'src/daemon/handlers/session-runtime-command.ts', - 'src/daemon/handlers/session-runtime-port-reverse.ts', + 'packages/daemon/src/handlers/session-runtime-command.ts', + 'packages/daemon/src/handlers/session-runtime-port-reverse.ts', ] as const, } : {}), @@ -953,7 +961,7 @@ export const RAW_COMMAND_DESCRIPTORS = [ name: 'install_source', deviceClaimPolicy: 'transient-exclusive', ...(ownerFilesEnabled - ? { ownerFiles: ['src/daemon/handlers/session-app-source-deployment.ts'] as const } + ? { ownerFiles: ['packages/daemon/src/handlers/session-app-source-deployment.ts'] as const } : {}), catalog: { group: 'internal', @@ -971,7 +979,7 @@ export const RAW_COMMAND_DESCRIPTORS = [ name: 'release_materialized_paths', deviceClaimPolicy: 'none', ...(ownerFilesEnabled - ? { ownerFiles: ['src/daemon/handlers/session-app-source-deployment.ts'] as const } + ? { ownerFiles: ['packages/daemon/src/handlers/session-app-source-deployment.ts'] as const } : {}), catalog: { group: 'internal', key: 'releaseMaterializedPaths' }, recordsSessionAction: false, @@ -1502,7 +1510,9 @@ export const RAW_COMMAND_DESCRIPTORS = [ }, { name: 'scroll', - ...(ownerFilesEnabled ? { ownerFiles: ['src/daemon/scroll-runtime.ts'] as const } : {}), + ...(ownerFilesEnabled + ? { ownerFiles: ['packages/daemon/src/scroll-runtime.ts'] as const } + : {}), catalog: { group: 'public' }, frameworkTier: 'core', // R53 retires this command's capability bucket and its `dispatch` leaf together: admission is @@ -1551,7 +1561,7 @@ export const RAW_COMMAND_DESCRIPTORS = [ ? { ownerFiles: [ 'src/commands/capture/screenshot.ts', - 'src/daemon/screenshot-runtime.ts', + 'packages/daemon/src/screenshot-runtime.ts', ] as const, } : {}), diff --git a/packages/contracts/src/app-state.ts b/packages/contracts/src/app-state.ts index 746fcc4078..73f2952dbf 100644 --- a/packages/contracts/src/app-state.ts +++ b/packages/contracts/src/app-state.ts @@ -3,7 +3,7 @@ import type { SessionSurface } from './session-surface.ts'; /** * Closed result of the `appstate` command, grounded in the daemon handler's - * success returns (src/daemon/handlers/session-appstate.ts `handleAppStateCommand`). + * success returns (packages/daemon/src/handlers/session-appstate.ts `handleAppStateCommand`). * A discriminated union on `platform`: * - Apple (`ios` / `macos`) session state, with iOS-only device locators that * the previous hand-written mirror omitted; and diff --git a/packages/contracts/src/clipboard.ts b/packages/contracts/src/clipboard.ts index 646acdb99c..17571c32be 100644 --- a/packages/contracts/src/clipboard.ts +++ b/packages/contracts/src/clipboard.ts @@ -1,6 +1,6 @@ /** * Closed result of the `clipboard` command. Mirrors the session runtime's - * literal return exactly (`src/daemon/handlers/session-clipboard.ts`): a + * literal return exactly (`packages/daemon/src/handlers/session-clipboard.ts`): a * discriminated union on `action`. `read` returns the clipboard `text`; `write` * reports the written `textLength` plus the `successText` message. The handler * spreads nothing else, so each branch is closed. diff --git a/packages/contracts/src/device.ts b/packages/contracts/src/device.ts index e135856f58..a04e38e296 100644 --- a/packages/contracts/src/device.ts +++ b/packages/contracts/src/device.ts @@ -8,7 +8,7 @@ import type { TargetShutdownResult } from './target-shutdown-contract.ts'; /** * Closed result of the `boot` command. Mirrors the daemon handler's only - * success return EXACTLY (src/daemon/handlers/session-boot.ts via + * success return EXACTLY (packages/daemon/src/handlers/session-boot.ts via * session-device-status-response.ts) — the fixed * object literal `{ platform, target, device, id, kind, booted }` plus the * additive `appleOs` discriminant, emitted only for Apple devices. @@ -33,7 +33,7 @@ export type BootCommandResult = { /** * Closed result of the `shutdown` command. Mirrors the daemon handler's success - * return EXACTLY (src/daemon/handlers/session-shutdown.ts via + * return EXACTLY (packages/daemon/src/handlers/session-shutdown.ts via * session-device-status-response.ts) — the fixed object * literal `{ platform, target, device, id, kind, shutdown }` plus the additive * `appleOs` discriminant (Apple devices only). The `shutdown` field is the raw diff --git a/packages/contracts/src/dispatch-disclosure.fixtures.ts b/packages/contracts/src/dispatch-disclosure.fixtures.ts index 441205541c..6a35323f7e 100644 --- a/packages/contracts/src/dispatch-disclosure.fixtures.ts +++ b/packages/contracts/src/dispatch-disclosure.fixtures.ts @@ -38,7 +38,7 @@ export const DISPATCH_DISCLOSURE_TABLE_PATH = path.join( */ export const DISPATCH_DISCLOSURE_DRIVER_OWNERS: Readonly> = { 'daemon.': 'src/__tests__/daemon-composition/interaction/interaction-dispatch-disclosure.test.ts', - 'daemon.scroll-no-progress': 'src/daemon/__tests__/scroll-movement.test.ts', + 'daemon.scroll-no-progress': 'packages/daemon/src/__tests__/scroll-movement.test.ts', 'daemon.route.': 'src/__tests__/daemon-composition/request-dispatch-disclosure.test.ts', 'post-action-guard.': 'src/__tests__/daemon-composition/interaction/interaction-dispatch-disclosure.test.ts', diff --git a/packages/contracts/src/interaction-guarantees.ts b/packages/contracts/src/interaction-guarantees.ts index 59da90fb15..021b6b03c8 100644 --- a/packages/contracts/src/interaction-guarantees.ts +++ b/packages/contracts/src/interaction-guarantees.ts @@ -179,7 +179,7 @@ const RUNTIME_TREE_TARGET_STABILITY: GuaranteeEnforcement = { // (interaction-response-construction-guard.test.ts) keeps new branches on it. const SHARED_RESPONSE_CONSTRUCTION: GuaranteeEnforcement = { kind: 'runtime', - via: 'src/daemon/interaction/internal/interaction-touch-response.ts#buildInteractionResponseData', + via: 'packages/daemon/src/interaction/internal/interaction-touch-response.ts#buildInteractionResponseData', }; // runtime-selector, runtime-ref, and coordinate share this waiver: all three finalize through @@ -192,7 +192,7 @@ const TAP_OUTCOME_NOT_OBSERVED_GAP: GuaranteeEnforcement = { trackingIssue: TAP_OUTCOME_NOT_OBSERVED_GAP_ISSUE, }; -// Both Maestro-compatible fast paths (src/daemon/interaction/internal/interaction-touch-direct-ios.ts) +// Both Maestro-compatible fast paths (packages/daemon/src/interaction/internal/interaction-touch-direct-ios.ts) // dispatch ONE fused XCTest runner request (`command: 'tap'` with a selectorKey/selectorValue) built // in packages/platform-apple/src/interactions.ts#tapElementSelector — not the separate // packages/maestro/ flow-script engine, which drives standalone `.yaml` Maestro flows and never @@ -205,7 +205,7 @@ const DIRECT_IOS_SINGLE_QUERY_READINESS: GuaranteeEnforcement = { // Shares the SAME reasoning as TAP_OUTCOME_NOT_OBSERVED_GAP: the tap outcome is not observed on the // success path here either. The shared ambiguous-XCTest-failure corroboration -// (src/daemon/interaction/internal/interaction-ios-tap-outcome.ts#corroborateIosTapFailure) is +// (packages/daemon/src/interaction/internal/interaction-ios-tap-outcome.ts#corroborateIosTapFailure) is // invoked identically from this fast path and from the tree-based runtime dispatch, but only ever // reconsiders a THROWN error — it never validates a call that returned success, so it is not a // baseline outcome claim for either path. @@ -282,7 +282,7 @@ const RUNTIME_TREE_SHARED_GUARANTEES = { responseConstruction: SHARED_RESPONSE_CONSTRUCTION, responseIdentity: { kind: 'runtime', - via: 'src/daemon/interaction/internal/interaction-touch-targets.ts#interactionResultExtra', + via: 'packages/daemon/src/interaction/internal/interaction-touch-targets.ts#interactionResultExtra', }, verifyEvidence: { kind: 'runtime', @@ -390,7 +390,7 @@ export const INTERACTION_DISPATCH_PATHS: Record { const sourcePaths = [ - new URL('../../../packages/capture-kit/src/durable-capture/store.ts', import.meta.url), + new URL('../../../../packages/capture-kit/src/durable-capture/store.ts', import.meta.url), ]; for (const sourcePath of sourcePaths) { const source = fs.readFileSync(sourcePath, 'utf8'); diff --git a/src/daemon/__tests__/audio-probe-resource-recovery.test.ts b/packages/daemon/src/__tests__/audio-probe-resource-recovery.test.ts similarity index 100% rename from src/daemon/__tests__/audio-probe-resource-recovery.test.ts rename to packages/daemon/src/__tests__/audio-probe-resource-recovery.test.ts diff --git a/src/daemon/__tests__/back-runtime.test.ts b/packages/daemon/src/__tests__/back-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/back-runtime.test.ts rename to packages/daemon/src/__tests__/back-runtime.test.ts diff --git a/src/daemon/__tests__/capture-disclosure-target-activation-fact.ts b/packages/daemon/src/__tests__/capture-disclosure-target-activation-fact.ts similarity index 100% rename from src/daemon/__tests__/capture-disclosure-target-activation-fact.ts rename to packages/daemon/src/__tests__/capture-disclosure-target-activation-fact.ts diff --git a/src/daemon/__tests__/capture-disclosure-target-activation.test.ts b/packages/daemon/src/__tests__/capture-disclosure-target-activation.test.ts similarity index 100% rename from src/daemon/__tests__/capture-disclosure-target-activation.test.ts rename to packages/daemon/src/__tests__/capture-disclosure-target-activation.test.ts diff --git a/src/daemon/__tests__/config.test.ts b/packages/daemon/src/__tests__/config.test.ts similarity index 100% rename from src/daemon/__tests__/config.test.ts rename to packages/daemon/src/__tests__/config.test.ts diff --git a/src/daemon/__tests__/context.test.ts b/packages/daemon/src/__tests__/context.test.ts similarity index 100% rename from src/daemon/__tests__/context.test.ts rename to packages/daemon/src/__tests__/context.test.ts diff --git a/src/daemon/__tests__/daemon-command-registry.test.ts b/packages/daemon/src/__tests__/daemon-command-registry.test.ts similarity index 100% rename from src/daemon/__tests__/daemon-command-registry.test.ts rename to packages/daemon/src/__tests__/daemon-command-registry.test.ts diff --git a/src/daemon/__tests__/daemon-policy.test.ts b/packages/daemon/src/__tests__/daemon-policy.test.ts similarity index 100% rename from src/daemon/__tests__/daemon-policy.test.ts rename to packages/daemon/src/__tests__/daemon-policy.test.ts diff --git a/src/daemon/__tests__/daemon-request-wire.test.ts b/packages/daemon/src/__tests__/daemon-request-wire.test.ts similarity index 100% rename from src/daemon/__tests__/daemon-request-wire.test.ts rename to packages/daemon/src/__tests__/daemon-request-wire.test.ts diff --git a/src/daemon/__tests__/daemon-runtime-app-log.test.ts b/packages/daemon/src/__tests__/daemon-runtime-app-log.test.ts similarity index 100% rename from src/daemon/__tests__/daemon-runtime-app-log.test.ts rename to packages/daemon/src/__tests__/daemon-runtime-app-log.test.ts diff --git a/src/daemon/__tests__/daemon-stop.test.ts b/packages/daemon/src/__tests__/daemon-stop.test.ts similarity index 100% rename from src/daemon/__tests__/daemon-stop.test.ts rename to packages/daemon/src/__tests__/daemon-stop.test.ts diff --git a/src/daemon/__tests__/deferred-interaction-outcome.test.ts b/packages/daemon/src/__tests__/deferred-interaction-outcome.test.ts similarity index 100% rename from src/daemon/__tests__/deferred-interaction-outcome.test.ts rename to packages/daemon/src/__tests__/deferred-interaction-outcome.test.ts diff --git a/src/daemon/__tests__/device-selection-stub.ts b/packages/daemon/src/__tests__/device-selection-stub.ts similarity index 100% rename from src/daemon/__tests__/device-selection-stub.ts rename to packages/daemon/src/__tests__/device-selection-stub.ts diff --git a/src/daemon/__tests__/direct-ios-selector.test.ts b/packages/daemon/src/__tests__/direct-ios-selector.test.ts similarity index 100% rename from src/daemon/__tests__/direct-ios-selector.test.ts rename to packages/daemon/src/__tests__/direct-ios-selector.test.ts diff --git a/src/daemon/__tests__/execution-plan.test.ts b/packages/daemon/src/__tests__/execution-plan.test.ts similarity index 100% rename from src/daemon/__tests__/execution-plan.test.ts rename to packages/daemon/src/__tests__/execution-plan.test.ts diff --git a/src/daemon/__tests__/filesystem-boundary-faults.test.ts b/packages/daemon/src/__tests__/filesystem-boundary-faults.test.ts similarity index 100% rename from src/daemon/__tests__/filesystem-boundary-faults.test.ts rename to packages/daemon/src/__tests__/filesystem-boundary-faults.test.ts diff --git a/src/daemon/__tests__/focus-runtime.test.ts b/packages/daemon/src/__tests__/focus-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/focus-runtime.test.ts rename to packages/daemon/src/__tests__/focus-runtime.test.ts diff --git a/src/daemon/__tests__/fold-runtime.test.ts b/packages/daemon/src/__tests__/fold-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/fold-runtime.test.ts rename to packages/daemon/src/__tests__/fold-runtime.test.ts diff --git a/src/daemon/__tests__/generic-route-runtime-completeness.test.ts b/packages/daemon/src/__tests__/generic-route-runtime-completeness.test.ts similarity index 100% rename from src/daemon/__tests__/generic-route-runtime-completeness.test.ts rename to packages/daemon/src/__tests__/generic-route-runtime-completeness.test.ts diff --git a/src/daemon/__tests__/host-lease-http.test.ts b/packages/daemon/src/__tests__/host-lease-http.test.ts similarity index 100% rename from src/daemon/__tests__/host-lease-http.test.ts rename to packages/daemon/src/__tests__/host-lease-http.test.ts diff --git a/src/daemon/__tests__/http-server-artifacts.coverage.ts b/packages/daemon/src/__tests__/http-server-artifacts.coverage.ts similarity index 100% rename from src/daemon/__tests__/http-server-artifacts.coverage.ts rename to packages/daemon/src/__tests__/http-server-artifacts.coverage.ts diff --git a/src/daemon/__tests__/http-server-artifacts.test.ts b/packages/daemon/src/__tests__/http-server-artifacts.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-artifacts.test.ts rename to packages/daemon/src/__tests__/http-server-artifacts.test.ts diff --git a/src/daemon/__tests__/http-server-rpc-admission.test.ts b/packages/daemon/src/__tests__/http-server-rpc-admission.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-rpc-admission.test.ts rename to packages/daemon/src/__tests__/http-server-rpc-admission.test.ts diff --git a/src/daemon/__tests__/http-server-rpc-handler-failure.test.ts b/packages/daemon/src/__tests__/http-server-rpc-handler-failure.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-rpc-handler-failure.test.ts rename to packages/daemon/src/__tests__/http-server-rpc-handler-failure.test.ts diff --git a/src/daemon/__tests__/http-server-rpc-invalid-body.test.ts b/packages/daemon/src/__tests__/http-server-rpc-invalid-body.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-rpc-invalid-body.test.ts rename to packages/daemon/src/__tests__/http-server-rpc-invalid-body.test.ts diff --git a/src/daemon/__tests__/http-server-rpc-lifetime.test.ts b/packages/daemon/src/__tests__/http-server-rpc-lifetime.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-rpc-lifetime.test.ts rename to packages/daemon/src/__tests__/http-server-rpc-lifetime.test.ts diff --git a/src/daemon/__tests__/http-server-rpc-unowned-failure.test.ts b/packages/daemon/src/__tests__/http-server-rpc-unowned-failure.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-rpc-unowned-failure.test.ts rename to packages/daemon/src/__tests__/http-server-rpc-unowned-failure.test.ts diff --git a/src/daemon/__tests__/http-server-rpc-validation.test.ts b/packages/daemon/src/__tests__/http-server-rpc-validation.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-rpc-validation.test.ts rename to packages/daemon/src/__tests__/http-server-rpc-validation.test.ts diff --git a/src/daemon/__tests__/http-server-rpc.fixtures.ts b/packages/daemon/src/__tests__/http-server-rpc.fixtures.ts similarity index 100% rename from src/daemon/__tests__/http-server-rpc.fixtures.ts rename to packages/daemon/src/__tests__/http-server-rpc.fixtures.ts diff --git a/src/daemon/__tests__/http-server-tenant-trust.test.ts b/packages/daemon/src/__tests__/http-server-tenant-trust.test.ts similarity index 100% rename from src/daemon/__tests__/http-server-tenant-trust.test.ts rename to packages/daemon/src/__tests__/http-server-tenant-trust.test.ts diff --git a/src/daemon/__tests__/human-control-fixtures.ts b/packages/daemon/src/__tests__/human-control-fixtures.ts similarity index 100% rename from src/daemon/__tests__/human-control-fixtures.ts rename to packages/daemon/src/__tests__/human-control-fixtures.ts diff --git a/src/daemon/__tests__/human-control-http.test.ts b/packages/daemon/src/__tests__/human-control-http.test.ts similarity index 100% rename from src/daemon/__tests__/human-control-http.test.ts rename to packages/daemon/src/__tests__/human-control-http.test.ts diff --git a/src/daemon/__tests__/human-control-router-fixture.ts b/packages/daemon/src/__tests__/human-control-router-fixture.ts similarity index 100% rename from src/daemon/__tests__/human-control-router-fixture.ts rename to packages/daemon/src/__tests__/human-control-router-fixture.ts diff --git a/src/daemon/__tests__/install-source-resolution.test.ts b/packages/daemon/src/__tests__/install-source-resolution.test.ts similarity index 100% rename from src/daemon/__tests__/install-source-resolution.test.ts rename to packages/daemon/src/__tests__/install-source-resolution.test.ts diff --git a/src/daemon/__tests__/interaction-get-runtime-fixture.ts b/packages/daemon/src/__tests__/interaction-get-runtime-fixture.ts similarity index 100% rename from src/daemon/__tests__/interaction-get-runtime-fixture.ts rename to packages/daemon/src/__tests__/interaction-get-runtime-fixture.ts diff --git a/src/daemon/__tests__/interaction-surface-baseline-evidence.test.ts b/packages/daemon/src/__tests__/interaction-surface-baseline-evidence.test.ts similarity index 100% rename from src/daemon/__tests__/interaction-surface-baseline-evidence.test.ts rename to packages/daemon/src/__tests__/interaction-surface-baseline-evidence.test.ts diff --git a/src/daemon/__tests__/interaction-surface-signature.test.ts b/packages/daemon/src/__tests__/interaction-surface-signature.test.ts similarity index 99% rename from src/daemon/__tests__/interaction-surface-signature.test.ts rename to packages/daemon/src/__tests__/interaction-surface-signature.test.ts index e2100079c3..23d20e2b68 100644 --- a/src/daemon/__tests__/interaction-surface-signature.test.ts +++ b/packages/daemon/src/__tests__/interaction-surface-signature.test.ts @@ -226,7 +226,7 @@ test('classifyBaselineSurfaceEvidence excludes keyboard DESCENDANTS and window S /** * A keyboard-window subtree: a `[Keyboard]` container plus a SIBLING "Next * keyboard" assistant button under the same window — matches the shape in - * `src/daemon/__tests__/post-gesture-stabilization-fixtures.ts`'s + * `packages/daemon/src/__tests__/post-gesture-stabilization-fixtures.ts`'s * `keyboardWindowNodes` (kept local here rather than imported: this file's * fixtures are raw node literals consumed directly by * `buildInteractionSurfaceSignature`, not `SnapshotState`-wrapped like that diff --git a/src/daemon/__tests__/interactor-resolution.test.ts b/packages/daemon/src/__tests__/interactor-resolution.test.ts similarity index 100% rename from src/daemon/__tests__/interactor-resolution.test.ts rename to packages/daemon/src/__tests__/interactor-resolution.test.ts diff --git a/src/daemon/__tests__/internal-observation.test.ts b/packages/daemon/src/__tests__/internal-observation.test.ts similarity index 100% rename from src/daemon/__tests__/internal-observation.test.ts rename to packages/daemon/src/__tests__/internal-observation.test.ts diff --git a/src/daemon/__tests__/ios-comparison-key-fixture.ts b/packages/daemon/src/__tests__/ios-comparison-key-fixture.ts similarity index 100% rename from src/daemon/__tests__/ios-comparison-key-fixture.ts rename to packages/daemon/src/__tests__/ios-comparison-key-fixture.ts diff --git a/src/daemon/__tests__/is-predicates.test.ts b/packages/daemon/src/__tests__/is-predicates.test.ts similarity index 100% rename from src/daemon/__tests__/is-predicates.test.ts rename to packages/daemon/src/__tests__/is-predicates.test.ts diff --git a/src/daemon/__tests__/keyboard-runtime.test.ts b/packages/daemon/src/__tests__/keyboard-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/keyboard-runtime.test.ts rename to packages/daemon/src/__tests__/keyboard-runtime.test.ts diff --git a/src/daemon/__tests__/lease-context.test.ts b/packages/daemon/src/__tests__/lease-context.test.ts similarity index 100% rename from src/daemon/__tests__/lease-context.test.ts rename to packages/daemon/src/__tests__/lease-context.test.ts diff --git a/src/daemon/__tests__/lease-in-flight-work.test.ts b/packages/daemon/src/__tests__/lease-in-flight-work.test.ts similarity index 100% rename from src/daemon/__tests__/lease-in-flight-work.test.ts rename to packages/daemon/src/__tests__/lease-in-flight-work.test.ts diff --git a/src/daemon/__tests__/lease-lifecycle.test.ts b/packages/daemon/src/__tests__/lease-lifecycle.test.ts similarity index 100% rename from src/daemon/__tests__/lease-lifecycle.test.ts rename to packages/daemon/src/__tests__/lease-lifecycle.test.ts diff --git a/src/daemon/__tests__/lease-registry-scope.test.ts b/packages/daemon/src/__tests__/lease-registry-scope.test.ts similarity index 100% rename from src/daemon/__tests__/lease-registry-scope.test.ts rename to packages/daemon/src/__tests__/lease-registry-scope.test.ts diff --git a/src/daemon/__tests__/lease-registry.test.ts b/packages/daemon/src/__tests__/lease-registry.test.ts similarity index 100% rename from src/daemon/__tests__/lease-registry.test.ts rename to packages/daemon/src/__tests__/lease-registry.test.ts diff --git a/src/daemon/__tests__/legacy-snapshot-capture-fixture.ts b/packages/daemon/src/__tests__/legacy-snapshot-capture-fixture.ts similarity index 100% rename from src/daemon/__tests__/legacy-snapshot-capture-fixture.ts rename to packages/daemon/src/__tests__/legacy-snapshot-capture-fixture.ts diff --git a/src/daemon/__tests__/macos-app-lease.test.ts b/packages/daemon/src/__tests__/macos-app-lease.test.ts similarity index 100% rename from src/daemon/__tests__/macos-app-lease.test.ts rename to packages/daemon/src/__tests__/macos-app-lease.test.ts diff --git a/src/daemon/__tests__/managed-session-artifact-path.test.ts b/packages/daemon/src/__tests__/managed-session-artifact-path.test.ts similarity index 100% rename from src/daemon/__tests__/managed-session-artifact-path.test.ts rename to packages/daemon/src/__tests__/managed-session-artifact-path.test.ts diff --git a/src/daemon/__tests__/materialized-path-registry.test.ts b/packages/daemon/src/__tests__/materialized-path-registry.test.ts similarity index 100% rename from src/daemon/__tests__/materialized-path-registry.test.ts rename to packages/daemon/src/__tests__/materialized-path-registry.test.ts diff --git a/src/daemon/__tests__/moving-target-baseline.test.ts b/packages/daemon/src/__tests__/moving-target-baseline.test.ts similarity index 100% rename from src/daemon/__tests__/moving-target-baseline.test.ts rename to packages/daemon/src/__tests__/moving-target-baseline.test.ts diff --git a/src/daemon/__tests__/offscreen-target-probe.test.ts b/packages/daemon/src/__tests__/offscreen-target-probe.test.ts similarity index 100% rename from src/daemon/__tests__/offscreen-target-probe.test.ts rename to packages/daemon/src/__tests__/offscreen-target-probe.test.ts diff --git a/src/daemon/__tests__/open-device-contention-wait.test.ts b/packages/daemon/src/__tests__/open-device-contention-wait.test.ts similarity index 100% rename from src/daemon/__tests__/open-device-contention-wait.test.ts rename to packages/daemon/src/__tests__/open-device-contention-wait.test.ts diff --git a/src/daemon/__tests__/orientation-runtime.test.ts b/packages/daemon/src/__tests__/orientation-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/orientation-runtime.test.ts rename to packages/daemon/src/__tests__/orientation-runtime.test.ts diff --git a/src/daemon/__tests__/platform-services-fixture.ts b/packages/daemon/src/__tests__/platform-services-fixture.ts similarity index 100% rename from src/daemon/__tests__/platform-services-fixture.ts rename to packages/daemon/src/__tests__/platform-services-fixture.ts diff --git a/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts b/packages/daemon/src/__tests__/post-gesture-no-effect-claim.test.ts similarity index 100% rename from src/daemon/__tests__/post-gesture-no-effect-claim.test.ts rename to packages/daemon/src/__tests__/post-gesture-no-effect-claim.test.ts diff --git a/src/daemon/__tests__/post-gesture-stabilization-fixtures.ts b/packages/daemon/src/__tests__/post-gesture-stabilization-fixtures.ts similarity index 100% rename from src/daemon/__tests__/post-gesture-stabilization-fixtures.ts rename to packages/daemon/src/__tests__/post-gesture-stabilization-fixtures.ts diff --git a/src/daemon/__tests__/post-gesture-stabilization-verdict.test.ts b/packages/daemon/src/__tests__/post-gesture-stabilization-verdict.test.ts similarity index 100% rename from src/daemon/__tests__/post-gesture-stabilization-verdict.test.ts rename to packages/daemon/src/__tests__/post-gesture-stabilization-verdict.test.ts diff --git a/src/daemon/__tests__/post-gesture-stabilization.test.ts b/packages/daemon/src/__tests__/post-gesture-stabilization.test.ts similarity index 100% rename from src/daemon/__tests__/post-gesture-stabilization.test.ts rename to packages/daemon/src/__tests__/post-gesture-stabilization.test.ts diff --git a/src/daemon/__tests__/provider-device-admission.test.ts b/packages/daemon/src/__tests__/provider-device-admission.test.ts similarity index 100% rename from src/daemon/__tests__/provider-device-admission.test.ts rename to packages/daemon/src/__tests__/provider-device-admission.test.ts diff --git a/src/daemon/__tests__/provider-lease-expiry.test.ts b/packages/daemon/src/__tests__/provider-lease-expiry.test.ts similarity index 100% rename from src/daemon/__tests__/provider-lease-expiry.test.ts rename to packages/daemon/src/__tests__/provider-lease-expiry.test.ts diff --git a/src/daemon/__tests__/recording-gestures.test.ts b/packages/daemon/src/__tests__/recording-gestures.test.ts similarity index 100% rename from src/daemon/__tests__/recording-gestures.test.ts rename to packages/daemon/src/__tests__/recording-gestures.test.ts diff --git a/src/daemon/__tests__/recording-timing.test.ts b/packages/daemon/src/__tests__/recording-timing.test.ts similarity index 100% rename from src/daemon/__tests__/recording-timing.test.ts rename to packages/daemon/src/__tests__/recording-timing.test.ts diff --git a/src/daemon/__tests__/ref-frame.test.ts b/packages/daemon/src/__tests__/ref-frame.test.ts similarity index 100% rename from src/daemon/__tests__/ref-frame.test.ts rename to packages/daemon/src/__tests__/ref-frame.test.ts diff --git a/src/daemon/__tests__/ref-snapshot-flag-policy.test.ts b/packages/daemon/src/__tests__/ref-snapshot-flag-policy.test.ts similarity index 100% rename from src/daemon/__tests__/ref-snapshot-flag-policy.test.ts rename to packages/daemon/src/__tests__/ref-snapshot-flag-policy.test.ts diff --git a/src/daemon/__tests__/replay-device-selection.test.ts b/packages/daemon/src/__tests__/replay-device-selection.test.ts similarity index 100% rename from src/daemon/__tests__/replay-device-selection.test.ts rename to packages/daemon/src/__tests__/replay-device-selection.test.ts diff --git a/src/daemon/__tests__/replay-divergence/replay-session-fixture.ts b/packages/daemon/src/__tests__/replay-divergence/replay-session-fixture.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/replay-session-fixture.ts rename to packages/daemon/src/__tests__/replay-divergence/replay-session-fixture.ts diff --git a/src/daemon/__tests__/replay-divergence/session-replay-divergence-android-occlusion.test.ts b/packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-android-occlusion.test.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/session-replay-divergence-android-occlusion.test.ts rename to packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-android-occlusion.test.ts diff --git a/src/daemon/__tests__/replay-divergence/session-replay-divergence-capture-policy.test.ts b/packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-capture-policy.test.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/session-replay-divergence-capture-policy.test.ts rename to packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-capture-policy.test.ts diff --git a/src/daemon/__tests__/replay-divergence/session-replay-divergence-chrome-filter.test.ts b/packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-chrome-filter.test.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/session-replay-divergence-chrome-filter.test.ts rename to packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-chrome-filter.test.ts diff --git a/src/daemon/__tests__/replay-divergence/session-replay-divergence-observation.test.ts b/packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-observation.test.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/session-replay-divergence-observation.test.ts rename to packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-observation.test.ts diff --git a/src/daemon/__tests__/replay-divergence/session-replay-divergence-overlay.test.ts b/packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-overlay.test.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/session-replay-divergence-overlay.test.ts rename to packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-overlay.test.ts diff --git a/src/daemon/__tests__/replay-divergence/session-replay-divergence-publication.test.ts b/packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-publication.test.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/session-replay-divergence-publication.test.ts rename to packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-publication.test.ts diff --git a/src/daemon/__tests__/replay-divergence/session-replay-divergence-suggestions.test.ts b/packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-suggestions.test.ts similarity index 100% rename from src/daemon/__tests__/replay-divergence/session-replay-divergence-suggestions.test.ts rename to packages/daemon/src/__tests__/replay-divergence/session-replay-divergence-suggestions.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-maestro-error-projection.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-error-projection.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-maestro-error-projection.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-error-projection.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-maestro-failure.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-failure.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-maestro-failure.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-failure.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-maestro-remote-evalscript.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-remote-evalscript.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-maestro-remote-evalscript.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-remote-evalscript.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-maestro-session-address.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-session-address.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-maestro-session-address.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-maestro-session-address.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-dispatch.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-dispatch.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-dispatch.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-dispatch.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-keyboard.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-keyboard.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-keyboard.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-keyboard.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-run-flow.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-run-flow.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-run-flow.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-run-flow.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-run-script.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-run-script.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-run-script.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-run-script.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-shell-artifacts.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-shell-artifacts.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-shell-artifacts.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-shell-artifacts.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-swipe.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-swipe.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-swipe.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-swipe.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-targeting.test.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-targeting.test.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro-targeting.test.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro-targeting.test.ts diff --git a/src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro.fixtures.ts b/packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro.fixtures.ts similarity index 100% rename from src/daemon/__tests__/replay-maestro/session-replay-runtime-maestro.fixtures.ts rename to packages/daemon/src/__tests__/replay-maestro/session-replay-runtime-maestro.fixtures.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-acceptance.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-acceptance.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-acceptance.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-acceptance.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-empty-tail.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-empty-tail.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-empty-tail.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-empty-tail.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-loop.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-loop.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-loop.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-loop.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-record-exclusion.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-record-exclusion.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-record-exclusion.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-record-exclusion.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-transaction-close-ordering.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction-close-ordering.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-transaction-close-ordering.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction-close-ordering.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-transaction-force.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction-force.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-transaction-force.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction-force.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-transaction.fixtures.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction.fixtures.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-transaction.fixtures.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction.fixtures.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair-transaction.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair-transaction.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair-transaction.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair.fixtures.test.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair.fixtures.test.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair.fixtures.test.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair.fixtures.test.ts diff --git a/src/daemon/__tests__/replay-repair/session-replay-repair.fixtures.ts b/packages/daemon/src/__tests__/replay-repair/session-replay-repair.fixtures.ts similarity index 100% rename from src/daemon/__tests__/replay-repair/session-replay-repair.fixtures.ts rename to packages/daemon/src/__tests__/replay-repair/session-replay-repair.fixtures.ts diff --git a/src/daemon/__tests__/replay-runtime/application.test.ts b/packages/daemon/src/__tests__/replay-runtime/application.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/application.test.ts rename to packages/daemon/src/__tests__/replay-runtime/application.test.ts diff --git a/src/daemon/__tests__/replay-runtime/replay-command-fixture.ts b/packages/daemon/src/__tests__/replay-runtime/replay-command-fixture.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/replay-command-fixture.ts rename to packages/daemon/src/__tests__/replay-runtime/replay-command-fixture.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-action-runtime.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-action-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-action-runtime.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-action-runtime.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-resume.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-resume.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-resume.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-resume.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime-artifact-ledger.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-artifact-ledger.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime-artifact-ledger.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-artifact-ledger.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime-binding.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-binding.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime-binding.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-binding.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime-failure-response.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-failure-response.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime-failure-response.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-failure-response.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime-failure.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-failure.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime-failure.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-failure.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime-keep-session.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-keep-session.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime-keep-session.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-keep-session.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime-plan.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-plan.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime-plan.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime-plan.test.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime.fixtures.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime.fixtures.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime.fixtures.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime.fixtures.ts diff --git a/src/daemon/__tests__/replay-runtime/session-replay-runtime.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime.test.ts similarity index 99% rename from src/daemon/__tests__/replay-runtime/session-replay-runtime.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-runtime.test.ts index efbfd81883..1bf016aab8 100644 --- a/src/daemon/__tests__/replay-runtime/session-replay-runtime.test.ts +++ b/packages/daemon/src/__tests__/replay-runtime/session-replay-runtime.test.ts @@ -453,7 +453,7 @@ test('replay rejects legacy JSON payload files', async () => { // `req.flags` — so the `parseReplayInput` check that used to reject an // unrecognized `--replay-backend` value (`parseReplayInput`) no // longer ran on this path. `buildReplayTargetDeviceResolution` -// (`src/daemon/replay-device-selection.ts`) still calls `parseReplayInput` +// (`packages/daemon/src/replay-device-selection.ts`) still calls `parseReplayInput` // for advisory device-lock binding, but its `catch` deliberately swallows // any thrown error ("Parsing and validation stay in the replay handler."), // so a raw `.ad` replay with `replayBackend: 'unknown'` executed instead of diff --git a/src/daemon/__tests__/replay-runtime/session-replay-script-source.test.ts b/packages/daemon/src/__tests__/replay-runtime/session-replay-script-source.test.ts similarity index 100% rename from src/daemon/__tests__/replay-runtime/session-replay-script-source.test.ts rename to packages/daemon/src/__tests__/replay-runtime/session-replay-script-source.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-command-trust.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-command-trust.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-command-trust.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-command-trust.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-fail-fast.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-fail-fast.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-fail-fast.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-fail-fast.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-runner.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-runner.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-runner.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-runner.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-source-discovery.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-source-discovery.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-source-discovery.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-source-discovery.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-suite-command-cancellation.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-suite-command-cancellation.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-suite-command-cancellation.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-suite-command-cancellation.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-suite-command-nested-flags.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-suite-command-nested-flags.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-suite-command-nested-flags.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-suite-command-nested-flags.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-suite-command-remote-artifacts.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-suite-command-remote-artifacts.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-suite-command-remote-artifacts.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-suite-command-remote-artifacts.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-suite-command-video.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-suite-command-video.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-suite-command-video.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-suite-command-video.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-suite-infrastructure.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-suite-infrastructure.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-suite-infrastructure.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-suite-infrastructure.test.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-suite.fixtures.ts b/packages/daemon/src/__tests__/replay-suite/session-test-suite.fixtures.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-suite.fixtures.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-suite.fixtures.ts diff --git a/src/daemon/__tests__/replay-suite/session-test-suite.test.ts b/packages/daemon/src/__tests__/replay-suite/session-test-suite.test.ts similarity index 100% rename from src/daemon/__tests__/replay-suite/session-test-suite.test.ts rename to packages/daemon/src/__tests__/replay-suite/session-test-suite.test.ts diff --git a/src/daemon/__tests__/replay-target/session-replay-dispatch-selector-miss.test.ts b/packages/daemon/src/__tests__/replay-target/session-replay-dispatch-selector-miss.test.ts similarity index 100% rename from src/daemon/__tests__/replay-target/session-replay-dispatch-selector-miss.test.ts rename to packages/daemon/src/__tests__/replay-target/session-replay-dispatch-selector-miss.test.ts diff --git a/src/daemon/__tests__/replay-target/session-replay-scenario.fixtures.ts b/packages/daemon/src/__tests__/replay-target/session-replay-scenario.fixtures.ts similarity index 100% rename from src/daemon/__tests__/replay-target/session-replay-scenario.fixtures.ts rename to packages/daemon/src/__tests__/replay-target/session-replay-scenario.fixtures.ts diff --git a/src/daemon/__tests__/replay-target/session-replay-selector-routes.test.ts b/packages/daemon/src/__tests__/replay-target/session-replay-selector-routes.test.ts similarity index 100% rename from src/daemon/__tests__/replay-target/session-replay-selector-routes.test.ts rename to packages/daemon/src/__tests__/replay-target/session-replay-selector-routes.test.ts diff --git a/src/daemon/__tests__/replay-target/session-replay-target-verification-runtime.test.ts b/packages/daemon/src/__tests__/replay-target/session-replay-target-verification-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/replay-target/session-replay-target-verification-runtime.test.ts rename to packages/daemon/src/__tests__/replay-target/session-replay-target-verification-runtime.test.ts diff --git a/src/daemon/__tests__/request-admission.test.ts b/packages/daemon/src/__tests__/request-admission.test.ts similarity index 100% rename from src/daemon/__tests__/request-admission.test.ts rename to packages/daemon/src/__tests__/request-admission.test.ts diff --git a/src/daemon/__tests__/request-diagnostics-http.test.ts b/packages/daemon/src/__tests__/request-diagnostics-http.test.ts similarity index 100% rename from src/daemon/__tests__/request-diagnostics-http.test.ts rename to packages/daemon/src/__tests__/request-diagnostics-http.test.ts diff --git a/src/daemon/__tests__/request-dispatch-ledger.test.ts b/packages/daemon/src/__tests__/request-dispatch-ledger.test.ts similarity index 100% rename from src/daemon/__tests__/request-dispatch-ledger.test.ts rename to packages/daemon/src/__tests__/request-dispatch-ledger.test.ts diff --git a/src/daemon/__tests__/request-execution-locks.test.ts b/packages/daemon/src/__tests__/request-execution-locks.test.ts similarity index 100% rename from src/daemon/__tests__/request-execution-locks.test.ts rename to packages/daemon/src/__tests__/request-execution-locks.test.ts diff --git a/src/daemon/__tests__/request-execution-scope-lease-expiry.test.ts b/packages/daemon/src/__tests__/request-execution-scope-lease-expiry.test.ts similarity index 100% rename from src/daemon/__tests__/request-execution-scope-lease-expiry.test.ts rename to packages/daemon/src/__tests__/request-execution-scope-lease-expiry.test.ts diff --git a/src/daemon/__tests__/request-execution-scope-macos-app-lease.test.ts b/packages/daemon/src/__tests__/request-execution-scope-macos-app-lease.test.ts similarity index 100% rename from src/daemon/__tests__/request-execution-scope-macos-app-lease.test.ts rename to packages/daemon/src/__tests__/request-execution-scope-macos-app-lease.test.ts diff --git a/src/daemon/__tests__/request-execution-scope-open-device-wait.test.ts b/packages/daemon/src/__tests__/request-execution-scope-open-device-wait.test.ts similarity index 100% rename from src/daemon/__tests__/request-execution-scope-open-device-wait.test.ts rename to packages/daemon/src/__tests__/request-execution-scope-open-device-wait.test.ts diff --git a/src/daemon/__tests__/request-execution-scope.test.ts b/packages/daemon/src/__tests__/request-execution-scope.test.ts similarity index 100% rename from src/daemon/__tests__/request-execution-scope.test.ts rename to packages/daemon/src/__tests__/request-execution-scope.test.ts diff --git a/src/daemon/__tests__/request-finalization.test.ts b/packages/daemon/src/__tests__/request-finalization.test.ts similarity index 100% rename from src/daemon/__tests__/request-finalization.test.ts rename to packages/daemon/src/__tests__/request-finalization.test.ts diff --git a/src/daemon/__tests__/request-handler-catalog.test.ts b/packages/daemon/src/__tests__/request-handler-catalog.test.ts similarity index 100% rename from src/daemon/__tests__/request-handler-catalog.test.ts rename to packages/daemon/src/__tests__/request-handler-catalog.test.ts diff --git a/src/daemon/__tests__/request-handler-chain-provider-scope.test.ts b/packages/daemon/src/__tests__/request-handler-chain-provider-scope.test.ts similarity index 100% rename from src/daemon/__tests__/request-handler-chain-provider-scope.test.ts rename to packages/daemon/src/__tests__/request-handler-chain-provider-scope.test.ts diff --git a/src/daemon/__tests__/request-lease-work.test.ts b/packages/daemon/src/__tests__/request-lease-work.test.ts similarity index 100% rename from src/daemon/__tests__/request-lease-work.test.ts rename to packages/daemon/src/__tests__/request-lease-work.test.ts diff --git a/src/daemon/__tests__/request-lock-identity-policy.test.ts b/packages/daemon/src/__tests__/request-lock-identity-policy.test.ts similarity index 100% rename from src/daemon/__tests__/request-lock-identity-policy.test.ts rename to packages/daemon/src/__tests__/request-lock-identity-policy.test.ts diff --git a/src/daemon/__tests__/request-lock-policy.test.ts b/packages/daemon/src/__tests__/request-lock-policy.test.ts similarity index 100% rename from src/daemon/__tests__/request-lock-policy.test.ts rename to packages/daemon/src/__tests__/request-lock-policy.test.ts diff --git a/src/daemon/__tests__/request-recording-health.test.ts b/packages/daemon/src/__tests__/request-recording-health.test.ts similarity index 100% rename from src/daemon/__tests__/request-recording-health.test.ts rename to packages/daemon/src/__tests__/request-recording-health.test.ts diff --git a/src/daemon/__tests__/request-router-apps-admission.test.ts b/packages/daemon/src/__tests__/request-router-apps-admission.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-apps-admission.test.ts rename to packages/daemon/src/__tests__/request-router-apps-admission.test.ts diff --git a/src/daemon/__tests__/request-router-artifacts-web.test.ts b/packages/daemon/src/__tests__/request-router-artifacts-web.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-artifacts-web.test.ts rename to packages/daemon/src/__tests__/request-router-artifacts-web.test.ts diff --git a/src/daemon/__tests__/request-router-cost.test.ts b/packages/daemon/src/__tests__/request-router-cost.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-cost.test.ts rename to packages/daemon/src/__tests__/request-router-cost.test.ts diff --git a/src/daemon/__tests__/request-router-custom-action-flags.test.ts b/packages/daemon/src/__tests__/request-router-custom-action-flags.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-custom-action-flags.test.ts rename to packages/daemon/src/__tests__/request-router-custom-action-flags.test.ts diff --git a/src/daemon/__tests__/request-router-developer-dir.test.ts b/packages/daemon/src/__tests__/request-router-developer-dir.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-developer-dir.test.ts rename to packages/daemon/src/__tests__/request-router-developer-dir.test.ts diff --git a/src/daemon/__tests__/request-router-dispatch-mocks.ts b/packages/daemon/src/__tests__/request-router-dispatch-mocks.ts similarity index 66% rename from src/daemon/__tests__/request-router-dispatch-mocks.ts rename to packages/daemon/src/__tests__/request-router-dispatch-mocks.ts index aff97cea5c..6f1e95bd18 100644 --- a/src/daemon/__tests__/request-router-dispatch-mocks.ts +++ b/packages/daemon/src/__tests__/request-router-dispatch-mocks.ts @@ -1,7 +1,10 @@ -import { vi } from 'vitest'; +import { vi, type Mock } from 'vitest'; +// The explicit Mock annotation is what lets the daemon package's composite project emit +// this fixture's declaration; the inferred vi.fn() type names @vitest/spy internals that +// are not importable from the emitted .d.ts (TS2883) — the capture-kit fixtures' pattern. const dispatchMocks = vi.hoisted(() => ({ - resolveTargetDevice: vi.fn(), + resolveTargetDevice: vi.fn() as Mock, })); vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal) => { diff --git a/src/daemon/__tests__/request-router-error-redaction.test.ts b/packages/daemon/src/__tests__/request-router-error-redaction.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-error-redaction.test.ts rename to packages/daemon/src/__tests__/request-router-error-redaction.test.ts diff --git a/src/daemon/__tests__/request-router-events.test.ts b/packages/daemon/src/__tests__/request-router-events.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-events.test.ts rename to packages/daemon/src/__tests__/request-router-events.test.ts diff --git a/src/daemon/__tests__/request-router-idle-expired.test.ts b/packages/daemon/src/__tests__/request-router-idle-expired.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-idle-expired.test.ts rename to packages/daemon/src/__tests__/request-router-idle-expired.test.ts diff --git a/src/daemon/__tests__/request-router-open-claim.test.ts b/packages/daemon/src/__tests__/request-router-open-claim.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-open-claim.test.ts rename to packages/daemon/src/__tests__/request-router-open-claim.test.ts diff --git a/src/daemon/__tests__/request-router-open-harness.ts b/packages/daemon/src/__tests__/request-router-open-harness.ts similarity index 100% rename from src/daemon/__tests__/request-router-open-harness.ts rename to packages/daemon/src/__tests__/request-router-open-harness.ts diff --git a/src/daemon/__tests__/request-router-open.test.ts b/packages/daemon/src/__tests__/request-router-open.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-open.test.ts rename to packages/daemon/src/__tests__/request-router-open.test.ts diff --git a/src/daemon/__tests__/request-router-record-flags.test.ts b/packages/daemon/src/__tests__/request-router-record-flags.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-record-flags.test.ts rename to packages/daemon/src/__tests__/request-router-record-flags.test.ts diff --git a/src/daemon/__tests__/request-router-repair-expired.test.ts b/packages/daemon/src/__tests__/request-router-repair-expired.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-repair-expired.test.ts rename to packages/daemon/src/__tests__/request-router-repair-expired.test.ts diff --git a/src/daemon/__tests__/request-router-replay-env.test.ts b/packages/daemon/src/__tests__/request-router-replay-env.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-replay-env.test.ts rename to packages/daemon/src/__tests__/request-router-replay-env.test.ts diff --git a/src/daemon/__tests__/request-router-response-level.test.ts b/packages/daemon/src/__tests__/request-router-response-level.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-response-level.test.ts rename to packages/daemon/src/__tests__/request-router-response-level.test.ts diff --git a/src/daemon/__tests__/request-router-session-address.test.ts b/packages/daemon/src/__tests__/request-router-session-address.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-session-address.test.ts rename to packages/daemon/src/__tests__/request-router-session-address.test.ts diff --git a/src/daemon/__tests__/request-router-typed-error.test.ts b/packages/daemon/src/__tests__/request-router-typed-error.test.ts similarity index 100% rename from src/daemon/__tests__/request-router-typed-error.test.ts rename to packages/daemon/src/__tests__/request-router-typed-error.test.ts diff --git a/src/daemon/__tests__/request-runtime-binding-router.test.ts b/packages/daemon/src/__tests__/request-runtime-binding-router.test.ts similarity index 100% rename from src/daemon/__tests__/request-runtime-binding-router.test.ts rename to packages/daemon/src/__tests__/request-runtime-binding-router.test.ts diff --git a/src/daemon/__tests__/request-runtime-binding.test.ts b/packages/daemon/src/__tests__/request-runtime-binding.test.ts similarity index 100% rename from src/daemon/__tests__/request-runtime-binding.test.ts rename to packages/daemon/src/__tests__/request-runtime-binding.test.ts diff --git a/src/daemon/__tests__/request-save-script-policy.test.ts b/packages/daemon/src/__tests__/request-save-script-policy.test.ts similarity index 100% rename from src/daemon/__tests__/request-save-script-policy.test.ts rename to packages/daemon/src/__tests__/request-save-script-policy.test.ts diff --git a/src/daemon/__tests__/request-save-script-transports.test.ts b/packages/daemon/src/__tests__/request-save-script-transports.test.ts similarity index 100% rename from src/daemon/__tests__/request-save-script-transports.test.ts rename to packages/daemon/src/__tests__/request-save-script-transports.test.ts diff --git a/src/daemon/__tests__/response-views.test.ts b/packages/daemon/src/__tests__/response-views.test.ts similarity index 100% rename from src/daemon/__tests__/response-views.test.ts rename to packages/daemon/src/__tests__/response-views.test.ts diff --git a/src/daemon/__tests__/resumable-upload-range.test.ts b/packages/daemon/src/__tests__/resumable-upload-range.test.ts similarity index 100% rename from src/daemon/__tests__/resumable-upload-range.test.ts rename to packages/daemon/src/__tests__/resumable-upload-range.test.ts diff --git a/src/daemon/__tests__/resumable-upload.test.ts b/packages/daemon/src/__tests__/resumable-upload.test.ts similarity index 100% rename from src/daemon/__tests__/resumable-upload.test.ts rename to packages/daemon/src/__tests__/resumable-upload.test.ts diff --git a/src/daemon/__tests__/runtime-binding-conformance-completeness.test.ts b/packages/daemon/src/__tests__/runtime-binding-conformance-completeness.test.ts similarity index 96% rename from src/daemon/__tests__/runtime-binding-conformance-completeness.test.ts rename to packages/daemon/src/__tests__/runtime-binding-conformance-completeness.test.ts index a996a6f9c5..8fb6bb67aa 100644 --- a/src/daemon/__tests__/runtime-binding-conformance-completeness.test.ts +++ b/packages/daemon/src/__tests__/runtime-binding-conformance-completeness.test.ts @@ -14,7 +14,7 @@ import { * The command registry's `platformExecution` declarations are the production enumeration of * daemon runtime bindings: every device-runtime descriptor names the uses its route admits, and * `admitRuntimeOperations` is one seam with no table of its own. The generic and interaction routes - * admit through per-command `src/daemon/-runtime.ts` resolvers, so every single-use + * admit through per-command `packages/daemon/src/-runtime.ts` resolvers, so every single-use * descriptor on those routes owes the family its conformance entry; the other direction holds any * entry to a cell its descriptor actually declares. */ diff --git a/src/daemon/__tests__/runtime-binding-conformance.ts b/packages/daemon/src/__tests__/runtime-binding-conformance.ts similarity index 100% rename from src/daemon/__tests__/runtime-binding-conformance.ts rename to packages/daemon/src/__tests__/runtime-binding-conformance.ts diff --git a/src/daemon/__tests__/runtime-operation-effects.test.ts b/packages/daemon/src/__tests__/runtime-operation-effects.test.ts similarity index 100% rename from src/daemon/__tests__/runtime-operation-effects.test.ts rename to packages/daemon/src/__tests__/runtime-operation-effects.test.ts diff --git a/src/daemon/__tests__/runtime-policy.test.ts b/packages/daemon/src/__tests__/runtime-policy.test.ts similarity index 100% rename from src/daemon/__tests__/runtime-policy.test.ts rename to packages/daemon/src/__tests__/runtime-policy.test.ts diff --git a/src/daemon/__tests__/runtime-session.test.ts b/packages/daemon/src/__tests__/runtime-session.test.ts similarity index 100% rename from src/daemon/__tests__/runtime-session.test.ts rename to packages/daemon/src/__tests__/runtime-session.test.ts diff --git a/src/daemon/__tests__/screen-recording-resource-recovery.test.ts b/packages/daemon/src/__tests__/screen-recording-resource-recovery.test.ts similarity index 100% rename from src/daemon/__tests__/screen-recording-resource-recovery.test.ts rename to packages/daemon/src/__tests__/screen-recording-resource-recovery.test.ts diff --git a/src/daemon/__tests__/screenshot-crop-target.test.ts b/packages/daemon/src/__tests__/screenshot-crop-target.test.ts similarity index 100% rename from src/daemon/__tests__/screenshot-crop-target.test.ts rename to packages/daemon/src/__tests__/screenshot-crop-target.test.ts diff --git a/src/daemon/__tests__/screenshot-crop.test.ts b/packages/daemon/src/__tests__/screenshot-crop.test.ts similarity index 100% rename from src/daemon/__tests__/screenshot-crop.test.ts rename to packages/daemon/src/__tests__/screenshot-crop.test.ts diff --git a/src/daemon/__tests__/screenshot-runtime-fixture.ts b/packages/daemon/src/__tests__/screenshot-runtime-fixture.ts similarity index 100% rename from src/daemon/__tests__/screenshot-runtime-fixture.ts rename to packages/daemon/src/__tests__/screenshot-runtime-fixture.ts diff --git a/src/daemon/__tests__/scroll-movement.test.ts b/packages/daemon/src/__tests__/scroll-movement.test.ts similarity index 100% rename from src/daemon/__tests__/scroll-movement.test.ts rename to packages/daemon/src/__tests__/scroll-movement.test.ts diff --git a/src/daemon/__tests__/scroll-runtime.test.ts b/packages/daemon/src/__tests__/scroll-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/scroll-runtime.test.ts rename to packages/daemon/src/__tests__/scroll-runtime.test.ts diff --git a/src/daemon/__tests__/selector-capture-binding.test.ts b/packages/daemon/src/__tests__/selector-capture-binding.test.ts similarity index 100% rename from src/daemon/__tests__/selector-capture-binding.test.ts rename to packages/daemon/src/__tests__/selector-capture-binding.test.ts diff --git a/src/daemon/__tests__/selector-capture-fixture.ts b/packages/daemon/src/__tests__/selector-capture-fixture.ts similarity index 100% rename from src/daemon/__tests__/selector-capture-fixture.ts rename to packages/daemon/src/__tests__/selector-capture-fixture.ts diff --git a/src/daemon/__tests__/selector-capture-runtime.test.ts b/packages/daemon/src/__tests__/selector-capture-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/selector-capture-runtime.test.ts rename to packages/daemon/src/__tests__/selector-capture-runtime.test.ts diff --git a/src/daemon/__tests__/selector-operation-binding.test.ts b/packages/daemon/src/__tests__/selector-operation-binding.test.ts similarity index 100% rename from src/daemon/__tests__/selector-operation-binding.test.ts rename to packages/daemon/src/__tests__/selector-operation-binding.test.ts diff --git a/src/daemon/__tests__/selector-recording-find-data.test.ts b/packages/daemon/src/__tests__/selector-recording-find-data.test.ts similarity index 100% rename from src/daemon/__tests__/selector-recording-find-data.test.ts rename to packages/daemon/src/__tests__/selector-recording-find-data.test.ts diff --git a/src/daemon/__tests__/selector-recording.test.ts b/packages/daemon/src/__tests__/selector-recording.test.ts similarity index 100% rename from src/daemon/__tests__/selector-recording.test.ts rename to packages/daemon/src/__tests__/selector-recording.test.ts diff --git a/src/daemon/__tests__/selector-text-runtime.test.ts b/packages/daemon/src/__tests__/selector-text-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/selector-text-runtime.test.ts rename to packages/daemon/src/__tests__/selector-text-runtime.test.ts diff --git a/src/daemon/__tests__/server-shutdown.test.ts b/packages/daemon/src/__tests__/server-shutdown.test.ts similarity index 100% rename from src/daemon/__tests__/server-shutdown.test.ts rename to packages/daemon/src/__tests__/server-shutdown.test.ts diff --git a/src/daemon/__tests__/session-action-recorder.test.ts b/packages/daemon/src/__tests__/session-action-recorder.test.ts similarity index 100% rename from src/daemon/__tests__/session-action-recorder.test.ts rename to packages/daemon/src/__tests__/session-action-recorder.test.ts diff --git a/src/daemon/__tests__/session-artifact-paths.test.ts b/packages/daemon/src/__tests__/session-artifact-paths.test.ts similarity index 100% rename from src/daemon/__tests__/session-artifact-paths.test.ts rename to packages/daemon/src/__tests__/session-artifact-paths.test.ts diff --git a/src/daemon/__tests__/session-capture-binding.test.ts b/packages/daemon/src/__tests__/session-capture-binding.test.ts similarity index 100% rename from src/daemon/__tests__/session-capture-binding.test.ts rename to packages/daemon/src/__tests__/session-capture-binding.test.ts diff --git a/src/daemon/__tests__/session-device-resolution.test.ts b/packages/daemon/src/__tests__/session-device-resolution.test.ts similarity index 100% rename from src/daemon/__tests__/session-device-resolution.test.ts rename to packages/daemon/src/__tests__/session-device-resolution.test.ts diff --git a/src/daemon/__tests__/session-idle-activity.test.ts b/packages/daemon/src/__tests__/session-idle-activity.test.ts similarity index 100% rename from src/daemon/__tests__/session-idle-activity.test.ts rename to packages/daemon/src/__tests__/session-idle-activity.test.ts diff --git a/src/daemon/__tests__/session-idle-expiry-harness.ts b/packages/daemon/src/__tests__/session-idle-expiry-harness.ts similarity index 100% rename from src/daemon/__tests__/session-idle-expiry-harness.ts rename to packages/daemon/src/__tests__/session-idle-expiry-harness.ts diff --git a/src/daemon/__tests__/session-idle-expiry.test.ts b/packages/daemon/src/__tests__/session-idle-expiry.test.ts similarity index 100% rename from src/daemon/__tests__/session-idle-expiry.test.ts rename to packages/daemon/src/__tests__/session-idle-expiry.test.ts diff --git a/src/daemon/__tests__/session-routing.test.ts b/packages/daemon/src/__tests__/session-routing.test.ts similarity index 100% rename from src/daemon/__tests__/session-routing.test.ts rename to packages/daemon/src/__tests__/session-routing.test.ts diff --git a/src/daemon/__tests__/session-runtime-admission.test.ts b/packages/daemon/src/__tests__/session-runtime-admission.test.ts similarity index 97% rename from src/daemon/__tests__/session-runtime-admission.test.ts rename to packages/daemon/src/__tests__/session-runtime-admission.test.ts index 69982f0566..f15fbba70f 100644 --- a/src/daemon/__tests__/session-runtime-admission.test.ts +++ b/packages/daemon/src/__tests__/session-runtime-admission.test.ts @@ -47,7 +47,7 @@ test('the admission cannot be written down or copied: only admitRuntimePlan mint // Planted reds for the seam itself: each directive below becomes unused — and tsc fails — if // the token loses its #private member (degrades to a plain shape). A route holds a token only // by having called admitRuntimePlan (or by a type assertion, which the cutover gate rejects in - // src/daemon/). The class value is not exported, so `new` is not even nameable from here. + // packages/daemon/src/). The class value is not exported, so `new` is not even nameable from here. // @ts-expect-error a literal is not an admission: it lacks the #private member const literal: AdmittedRuntimePlan = { admitted: true }; // @ts-expect-error a spread of a real admission is a plain object without the #private member diff --git a/src/daemon/__tests__/session-runtime.test.ts b/packages/daemon/src/__tests__/session-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/session-runtime.test.ts rename to packages/daemon/src/__tests__/session-runtime.test.ts diff --git a/src/daemon/__tests__/session-script-active-publication.test.ts b/packages/daemon/src/__tests__/session-script-active-publication.test.ts similarity index 100% rename from src/daemon/__tests__/session-script-active-publication.test.ts rename to packages/daemon/src/__tests__/session-script-active-publication.test.ts diff --git a/src/daemon/__tests__/session-script-publication-state.test.ts b/packages/daemon/src/__tests__/session-script-publication-state.test.ts similarity index 100% rename from src/daemon/__tests__/session-script-publication-state.test.ts rename to packages/daemon/src/__tests__/session-script-publication-state.test.ts diff --git a/src/daemon/__tests__/session-script-writer.test.ts b/packages/daemon/src/__tests__/session-script-writer.test.ts similarity index 100% rename from src/daemon/__tests__/session-script-writer.test.ts rename to packages/daemon/src/__tests__/session-script-writer.test.ts diff --git a/src/daemon/__tests__/session-selector.test.ts b/packages/daemon/src/__tests__/session-selector.test.ts similarity index 100% rename from src/daemon/__tests__/session-selector.test.ts rename to packages/daemon/src/__tests__/session-selector.test.ts diff --git a/src/daemon/__tests__/session-snapshot-freshness.test.ts b/packages/daemon/src/__tests__/session-snapshot-freshness.test.ts similarity index 100% rename from src/daemon/__tests__/session-snapshot-freshness.test.ts rename to packages/daemon/src/__tests__/session-snapshot-freshness.test.ts diff --git a/src/daemon/__tests__/session-snapshot.test.ts b/packages/daemon/src/__tests__/session-snapshot.test.ts similarity index 100% rename from src/daemon/__tests__/session-snapshot.test.ts rename to packages/daemon/src/__tests__/session-snapshot.test.ts diff --git a/src/daemon/__tests__/session-store-lifetime.test.ts b/packages/daemon/src/__tests__/session-store-lifetime.test.ts similarity index 100% rename from src/daemon/__tests__/session-store-lifetime.test.ts rename to packages/daemon/src/__tests__/session-store-lifetime.test.ts diff --git a/src/daemon/__tests__/session-store.test.ts b/packages/daemon/src/__tests__/session-store.test.ts similarity index 100% rename from src/daemon/__tests__/session-store.test.ts rename to packages/daemon/src/__tests__/session-store.test.ts diff --git a/src/daemon/__tests__/session-teardown-budget.test.ts b/packages/daemon/src/__tests__/session-teardown-budget.test.ts similarity index 100% rename from src/daemon/__tests__/session-teardown-budget.test.ts rename to packages/daemon/src/__tests__/session-teardown-budget.test.ts diff --git a/src/daemon/__tests__/session-teardown.fixtures.ts b/packages/daemon/src/__tests__/session-teardown.fixtures.ts similarity index 100% rename from src/daemon/__tests__/session-teardown.fixtures.ts rename to packages/daemon/src/__tests__/session-teardown.fixtures.ts diff --git a/src/daemon/__tests__/settle-observation-capture.test.ts b/packages/daemon/src/__tests__/settle-observation-capture.test.ts similarity index 100% rename from src/daemon/__tests__/settle-observation-capture.test.ts rename to packages/daemon/src/__tests__/settle-observation-capture.test.ts diff --git a/src/daemon/__tests__/snapshot-capture.test.ts b/packages/daemon/src/__tests__/snapshot-capture.test.ts similarity index 100% rename from src/daemon/__tests__/snapshot-capture.test.ts rename to packages/daemon/src/__tests__/snapshot-capture.test.ts diff --git a/src/daemon/__tests__/snapshot-custom-actions-platform-guard.test.ts b/packages/daemon/src/__tests__/snapshot-custom-actions-platform-guard.test.ts similarity index 100% rename from src/daemon/__tests__/snapshot-custom-actions-platform-guard.test.ts rename to packages/daemon/src/__tests__/snapshot-custom-actions-platform-guard.test.ts diff --git a/src/daemon/__tests__/snapshot-diff.test.ts b/packages/daemon/src/__tests__/snapshot-diff.test.ts similarity index 100% rename from src/daemon/__tests__/snapshot-diff.test.ts rename to packages/daemon/src/__tests__/snapshot-diff.test.ts diff --git a/src/daemon/__tests__/snapshot-interactor-capture.test.ts b/packages/daemon/src/__tests__/snapshot-interactor-capture.test.ts similarity index 100% rename from src/daemon/__tests__/snapshot-interactor-capture.test.ts rename to packages/daemon/src/__tests__/snapshot-interactor-capture.test.ts diff --git a/src/daemon/__tests__/snapshot-publication-membership.test.ts b/packages/daemon/src/__tests__/snapshot-publication-membership.test.ts similarity index 100% rename from src/daemon/__tests__/snapshot-publication-membership.test.ts rename to packages/daemon/src/__tests__/snapshot-publication-membership.test.ts diff --git a/src/daemon/__tests__/snapshot-runtime-binding.test.ts b/packages/daemon/src/__tests__/snapshot-runtime-binding.test.ts similarity index 100% rename from src/daemon/__tests__/snapshot-runtime-binding.test.ts rename to packages/daemon/src/__tests__/snapshot-runtime-binding.test.ts diff --git a/src/daemon/__tests__/snapshot-runtime-fixture.ts b/packages/daemon/src/__tests__/snapshot-runtime-fixture.ts similarity index 100% rename from src/daemon/__tests__/snapshot-runtime-fixture.ts rename to packages/daemon/src/__tests__/snapshot-runtime-fixture.ts diff --git a/src/daemon/__tests__/snapshot-scope-ref.test.ts b/packages/daemon/src/__tests__/snapshot-scope-ref.test.ts similarity index 100% rename from src/daemon/__tests__/snapshot-scope-ref.test.ts rename to packages/daemon/src/__tests__/snapshot-scope-ref.test.ts diff --git a/src/daemon/__tests__/support/command-surface-fake.ts b/packages/daemon/src/__tests__/support/command-surface-fake.ts similarity index 100% rename from src/daemon/__tests__/support/command-surface-fake.ts rename to packages/daemon/src/__tests__/support/command-surface-fake.ts diff --git a/src/daemon/__tests__/support/device-claim-store.ts b/packages/daemon/src/__tests__/support/device-claim-store.ts similarity index 100% rename from src/daemon/__tests__/support/device-claim-store.ts rename to packages/daemon/src/__tests__/support/device-claim-store.ts diff --git a/src/daemon/__tests__/support/host-diagnostics-fixture.ts b/packages/daemon/src/__tests__/support/host-diagnostics-fixture.ts similarity index 100% rename from src/daemon/__tests__/support/host-diagnostics-fixture.ts rename to packages/daemon/src/__tests__/support/host-diagnostics-fixture.ts diff --git a/src/daemon/__tests__/support/platform-resource-cleanup-fixture.ts b/packages/daemon/src/__tests__/support/platform-resource-cleanup-fixture.ts similarity index 100% rename from src/daemon/__tests__/support/platform-resource-cleanup-fixture.ts rename to packages/daemon/src/__tests__/support/platform-resource-cleanup-fixture.ts diff --git a/src/daemon/__tests__/support/provider-credentials-fixture.ts b/packages/daemon/src/__tests__/support/provider-credentials-fixture.ts similarity index 100% rename from src/daemon/__tests__/support/provider-credentials-fixture.ts rename to packages/daemon/src/__tests__/support/provider-credentials-fixture.ts diff --git a/src/daemon/__tests__/support/provider-device-admission-fixture.ts b/packages/daemon/src/__tests__/support/provider-device-admission-fixture.ts similarity index 100% rename from src/daemon/__tests__/support/provider-device-admission-fixture.ts rename to packages/daemon/src/__tests__/support/provider-device-admission-fixture.ts diff --git a/src/daemon/__tests__/support/screen-recording-live-handle.ts b/packages/daemon/src/__tests__/support/screen-recording-live-handle.ts similarity index 100% rename from src/daemon/__tests__/support/screen-recording-live-handle.ts rename to packages/daemon/src/__tests__/support/screen-recording-live-handle.ts diff --git a/src/daemon/__tests__/support/session-factories.ts b/packages/daemon/src/__tests__/support/session-factories.ts similarity index 100% rename from src/daemon/__tests__/support/session-factories.ts rename to packages/daemon/src/__tests__/support/session-factories.ts diff --git a/src/daemon/__tests__/support/store-factory.ts b/packages/daemon/src/__tests__/support/store-factory.ts similarity index 100% rename from src/daemon/__tests__/support/store-factory.ts rename to packages/daemon/src/__tests__/support/store-factory.ts diff --git a/src/daemon/__tests__/support/unavailable-device-runtime-gateway.ts b/packages/daemon/src/__tests__/support/unavailable-device-runtime-gateway.ts similarity index 100% rename from src/daemon/__tests__/support/unavailable-device-runtime-gateway.ts rename to packages/daemon/src/__tests__/support/unavailable-device-runtime-gateway.ts diff --git a/src/daemon/__tests__/system-button-runtime.test.ts b/packages/daemon/src/__tests__/system-button-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/system-button-runtime.test.ts rename to packages/daemon/src/__tests__/system-button-runtime.test.ts diff --git a/src/daemon/__tests__/tenant-owned-entry.test.ts b/packages/daemon/src/__tests__/tenant-owned-entry.test.ts similarity index 100% rename from src/daemon/__tests__/tenant-owned-entry.test.ts rename to packages/daemon/src/__tests__/tenant-owned-entry.test.ts diff --git a/src/daemon/__tests__/test-device-runtime-gateway.ts b/packages/daemon/src/__tests__/test-device-runtime-gateway.ts similarity index 100% rename from src/daemon/__tests__/test-device-runtime-gateway.ts rename to packages/daemon/src/__tests__/test-device-runtime-gateway.ts diff --git a/src/daemon/__tests__/tv-remote-runtime.test.ts b/packages/daemon/src/__tests__/tv-remote-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/tv-remote-runtime.test.ts rename to packages/daemon/src/__tests__/tv-remote-runtime.test.ts diff --git a/src/daemon/__tests__/type-text-runtime.test.ts b/packages/daemon/src/__tests__/type-text-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/type-text-runtime.test.ts rename to packages/daemon/src/__tests__/type-text-runtime.test.ts diff --git a/src/daemon/__tests__/upload.test.ts b/packages/daemon/src/__tests__/upload.test.ts similarity index 100% rename from src/daemon/__tests__/upload.test.ts rename to packages/daemon/src/__tests__/upload.test.ts diff --git a/src/daemon/__tests__/viewport-runtime.test.ts b/packages/daemon/src/__tests__/viewport-runtime.test.ts similarity index 100% rename from src/daemon/__tests__/viewport-runtime.test.ts rename to packages/daemon/src/__tests__/viewport-runtime.test.ts diff --git a/src/daemon/android-foreground-surface.ts b/packages/daemon/src/android-foreground-surface.ts similarity index 100% rename from src/daemon/android-foreground-surface.ts rename to packages/daemon/src/android-foreground-surface.ts diff --git a/src/daemon/android-snapshot-timeout-evidence.ts b/packages/daemon/src/android-snapshot-timeout-evidence.ts similarity index 98% rename from src/daemon/android-snapshot-timeout-evidence.ts rename to packages/daemon/src/android-snapshot-timeout-evidence.ts index 11b8b68197..acc02ae071 100644 --- a/src/daemon/android-snapshot-timeout-evidence.ts +++ b/packages/daemon/src/android-snapshot-timeout-evidence.ts @@ -28,7 +28,7 @@ import { * The two things that are not daemon assembly moved out: whether a failure is the * accessibility-timeout shape is a policy * (`packages/capture-kit/src/snapshot/snapshot-timeout-policy.ts`), and the published evidence shape is - * vocabulary (`src/daemon/snapshot-timeout-evidence.ts`, whose only consumer is this + * vocabulary (`packages/daemon/src/snapshot-timeout-evidence.ts`, whose only consumer is this * module). What remains here is the ordering that * genuinely needs the daemon: resolving a bound screenshot runtime, writing the artifact, * annotating it from the stored observation, and emitting the diagnostics. diff --git a/src/daemon/android-system-dialog.ts b/packages/daemon/src/android-system-dialog.ts similarity index 100% rename from src/daemon/android-system-dialog.ts rename to packages/daemon/src/android-system-dialog.ts diff --git a/src/daemon/app-event-runtime.ts b/packages/daemon/src/app-event-runtime.ts similarity index 100% rename from src/daemon/app-event-runtime.ts rename to packages/daemon/src/app-event-runtime.ts diff --git a/src/daemon/app-events.test.ts b/packages/daemon/src/app-events.test.ts similarity index 100% rename from src/daemon/app-events.test.ts rename to packages/daemon/src/app-events.test.ts diff --git a/src/daemon/app-events.ts b/packages/daemon/src/app-events.ts similarity index 100% rename from src/daemon/app-events.ts rename to packages/daemon/src/app-events.ts diff --git a/src/daemon/app-log-admission-ledger.ts b/packages/daemon/src/app-log-admission-ledger.ts similarity index 100% rename from src/daemon/app-log-admission-ledger.ts rename to packages/daemon/src/app-log-admission-ledger.ts diff --git a/src/daemon/app-log-files.ts b/packages/daemon/src/app-log-files.ts similarity index 100% rename from src/daemon/app-log-files.ts rename to packages/daemon/src/app-log-files.ts diff --git a/src/daemon/app-log-resource-recovery.ts b/packages/daemon/src/app-log-resource-recovery.ts similarity index 100% rename from src/daemon/app-log-resource-recovery.ts rename to packages/daemon/src/app-log-resource-recovery.ts diff --git a/src/daemon/app-log-resource-store.ts b/packages/daemon/src/app-log-resource-store.ts similarity index 100% rename from src/daemon/app-log-resource-store.ts rename to packages/daemon/src/app-log-resource-store.ts diff --git a/src/daemon/app-log-session-resource.ts b/packages/daemon/src/app-log-session-resource.ts similarity index 100% rename from src/daemon/app-log-session-resource.ts rename to packages/daemon/src/app-log-session-resource.ts diff --git a/src/daemon/app-log-start-preflight.ts b/packages/daemon/src/app-log-start-preflight.ts similarity index 100% rename from src/daemon/app-log-start-preflight.ts rename to packages/daemon/src/app-log-start-preflight.ts diff --git a/src/daemon/app-log.ts b/packages/daemon/src/app-log.ts similarity index 100% rename from src/daemon/app-log.ts rename to packages/daemon/src/app-log.ts diff --git a/src/daemon/application-lifecycle-execution.ts b/packages/daemon/src/application-lifecycle-execution.ts similarity index 100% rename from src/daemon/application-lifecycle-execution.ts rename to packages/daemon/src/application-lifecycle-execution.ts diff --git a/src/daemon/application-lifecycle-recovery.ts b/packages/daemon/src/application-lifecycle-recovery.ts similarity index 100% rename from src/daemon/application-lifecycle-recovery.ts rename to packages/daemon/src/application-lifecycle-recovery.ts diff --git a/src/daemon/apps-runtime.ts b/packages/daemon/src/apps-runtime.ts similarity index 100% rename from src/daemon/apps-runtime.ts rename to packages/daemon/src/apps-runtime.ts diff --git a/src/daemon/artifact-archive.ts b/packages/daemon/src/artifact-archive.ts similarity index 100% rename from src/daemon/artifact-archive.ts rename to packages/daemon/src/artifact-archive.ts diff --git a/src/daemon/artifact-download.ts b/packages/daemon/src/artifact-download.ts similarity index 100% rename from src/daemon/artifact-download.ts rename to packages/daemon/src/artifact-download.ts diff --git a/src/daemon/artifact-tracking.ts b/packages/daemon/src/artifact-tracking.ts similarity index 100% rename from src/daemon/artifact-tracking.ts rename to packages/daemon/src/artifact-tracking.ts diff --git a/src/daemon/back-runtime.ts b/packages/daemon/src/back-runtime.ts similarity index 100% rename from src/daemon/back-runtime.ts rename to packages/daemon/src/back-runtime.ts diff --git a/src/daemon/capture-disclosure.ts b/packages/daemon/src/capture-disclosure.ts similarity index 100% rename from src/daemon/capture-disclosure.ts rename to packages/daemon/src/capture-disclosure.ts diff --git a/src/daemon/config.ts b/packages/daemon/src/config.ts similarity index 100% rename from src/daemon/config.ts rename to packages/daemon/src/config.ts diff --git a/src/daemon/context.ts b/packages/daemon/src/context.ts similarity index 100% rename from src/daemon/context.ts rename to packages/daemon/src/context.ts diff --git a/src/daemon/daemon-command-registry.ts b/packages/daemon/src/daemon-command-registry.ts similarity index 100% rename from src/daemon/daemon-command-registry.ts rename to packages/daemon/src/daemon-command-registry.ts diff --git a/src/daemon/daemon-policy.ts b/packages/daemon/src/daemon-policy.ts similarity index 100% rename from src/daemon/daemon-policy.ts rename to packages/daemon/src/daemon-policy.ts diff --git a/src/daemon/daemon-request.ts b/packages/daemon/src/daemon-request.ts similarity index 100% rename from src/daemon/daemon-request.ts rename to packages/daemon/src/daemon-request.ts diff --git a/src/daemon/daemon-stop.ts b/packages/daemon/src/daemon-stop.ts similarity index 100% rename from src/daemon/daemon-stop.ts rename to packages/daemon/src/daemon-stop.ts diff --git a/src/daemon/deferred-interaction-outcome.ts b/packages/daemon/src/deferred-interaction-outcome.ts similarity index 100% rename from src/daemon/deferred-interaction-outcome.ts rename to packages/daemon/src/deferred-interaction-outcome.ts diff --git a/src/daemon/device/__tests__/device-claim-admission.test.ts b/packages/daemon/src/device/__tests__/device-claim-admission.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-admission.test.ts rename to packages/daemon/src/device/__tests__/device-claim-admission.test.ts diff --git a/src/daemon/device/__tests__/device-claim-conflict.test.ts b/packages/daemon/src/device/__tests__/device-claim-conflict.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-conflict.test.ts rename to packages/daemon/src/device/__tests__/device-claim-conflict.test.ts diff --git a/src/daemon/device/__tests__/device-claim-owner-recovery.test.ts b/packages/daemon/src/device/__tests__/device-claim-owner-recovery.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-owner-recovery.test.ts rename to packages/daemon/src/device/__tests__/device-claim-owner-recovery.test.ts diff --git a/src/daemon/device/__tests__/device-claim-prune.test.ts b/packages/daemon/src/device/__tests__/device-claim-prune.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-prune.test.ts rename to packages/daemon/src/device/__tests__/device-claim-prune.test.ts diff --git a/src/daemon/device/__tests__/device-claim-reboot.test.ts b/packages/daemon/src/device/__tests__/device-claim-reboot.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-reboot.test.ts rename to packages/daemon/src/device/__tests__/device-claim-reboot.test.ts diff --git a/src/daemon/device/__tests__/device-claim-reconciliation.test.ts b/packages/daemon/src/device/__tests__/device-claim-reconciliation.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-reconciliation.test.ts rename to packages/daemon/src/device/__tests__/device-claim-reconciliation.test.ts diff --git a/src/daemon/device/__tests__/device-claim-record.test.ts b/packages/daemon/src/device/__tests__/device-claim-record.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-record.test.ts rename to packages/daemon/src/device/__tests__/device-claim-record.test.ts diff --git a/src/daemon/device/__tests__/device-claim-rule.test.ts b/packages/daemon/src/device/__tests__/device-claim-rule.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-rule.test.ts rename to packages/daemon/src/device/__tests__/device-claim-rule.test.ts diff --git a/src/daemon/device/__tests__/device-claim-settlement.test.ts b/packages/daemon/src/device/__tests__/device-claim-settlement.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claim-settlement.test.ts rename to packages/daemon/src/device/__tests__/device-claim-settlement.test.ts diff --git a/src/daemon/device/__tests__/device-claims.test.ts b/packages/daemon/src/device/__tests__/device-claims.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-claims.test.ts rename to packages/daemon/src/device/__tests__/device-claims.test.ts diff --git a/src/daemon/device/__tests__/device-mutation-drain.test.ts b/packages/daemon/src/device/__tests__/device-mutation-drain.test.ts similarity index 100% rename from src/daemon/device/__tests__/device-mutation-drain.test.ts rename to packages/daemon/src/device/__tests__/device-mutation-drain.test.ts diff --git a/src/daemon/device/claim-recovery-gateway.ts b/packages/daemon/src/device/claim-recovery-gateway.ts similarity index 100% rename from src/daemon/device/claim-recovery-gateway.ts rename to packages/daemon/src/device/claim-recovery-gateway.ts diff --git a/src/daemon/device/device-claim-admission.ts b/packages/daemon/src/device/device-claim-admission.ts similarity index 100% rename from src/daemon/device/device-claim-admission.ts rename to packages/daemon/src/device/device-claim-admission.ts diff --git a/src/daemon/device/device-claim-conflict.ts b/packages/daemon/src/device/device-claim-conflict.ts similarity index 100% rename from src/daemon/device/device-claim-conflict.ts rename to packages/daemon/src/device/device-claim-conflict.ts diff --git a/src/daemon/device/device-claim-inspection.ts b/packages/daemon/src/device/device-claim-inspection.ts similarity index 100% rename from src/daemon/device/device-claim-inspection.ts rename to packages/daemon/src/device/device-claim-inspection.ts diff --git a/src/daemon/device/device-claim-owner-recovery.ts b/packages/daemon/src/device/device-claim-owner-recovery.ts similarity index 100% rename from src/daemon/device/device-claim-owner-recovery.ts rename to packages/daemon/src/device/device-claim-owner-recovery.ts diff --git a/src/daemon/device/device-claim-paths.ts b/packages/daemon/src/device/device-claim-paths.ts similarity index 100% rename from src/daemon/device/device-claim-paths.ts rename to packages/daemon/src/device/device-claim-paths.ts diff --git a/src/daemon/device/device-claim-reboot.ts b/packages/daemon/src/device/device-claim-reboot.ts similarity index 100% rename from src/daemon/device/device-claim-reboot.ts rename to packages/daemon/src/device/device-claim-reboot.ts diff --git a/src/daemon/device/device-claim-reconciliation.ts b/packages/daemon/src/device/device-claim-reconciliation.ts similarity index 100% rename from src/daemon/device/device-claim-reconciliation.ts rename to packages/daemon/src/device/device-claim-reconciliation.ts diff --git a/src/daemon/device/device-claim-record.ts b/packages/daemon/src/device/device-claim-record.ts similarity index 100% rename from src/daemon/device/device-claim-record.ts rename to packages/daemon/src/device/device-claim-record.ts diff --git a/src/daemon/device/device-claim-rule.ts b/packages/daemon/src/device/device-claim-rule.ts similarity index 100% rename from src/daemon/device/device-claim-rule.ts rename to packages/daemon/src/device/device-claim-rule.ts diff --git a/src/daemon/device/device-claim-settlement.ts b/packages/daemon/src/device/device-claim-settlement.ts similarity index 100% rename from src/daemon/device/device-claim-settlement.ts rename to packages/daemon/src/device/device-claim-settlement.ts diff --git a/src/daemon/device/device-claim-store.ts b/packages/daemon/src/device/device-claim-store.ts similarity index 100% rename from src/daemon/device/device-claim-store.ts rename to packages/daemon/src/device/device-claim-store.ts diff --git a/src/daemon/device/device-claims.ts b/packages/daemon/src/device/device-claims.ts similarity index 100% rename from src/daemon/device/device-claims.ts rename to packages/daemon/src/device/device-claims.ts diff --git a/src/daemon/device/device-mutation-drain.ts b/packages/daemon/src/device/device-mutation-drain.ts similarity index 100% rename from src/daemon/device/device-mutation-drain.ts rename to packages/daemon/src/device/device-mutation-drain.ts diff --git a/src/daemon/device/device-ready.ts b/packages/daemon/src/device/device-ready.ts similarity index 100% rename from src/daemon/device/device-ready.ts rename to packages/daemon/src/device/device-ready.ts diff --git a/src/daemon/device/device-selector-intent.ts b/packages/daemon/src/device/device-selector-intent.ts similarity index 100% rename from src/daemon/device/device-selector-intent.ts rename to packages/daemon/src/device/device-selector-intent.ts diff --git a/src/daemon/device/device-targets.ts b/packages/daemon/src/device/device-targets.ts similarity index 100% rename from src/daemon/device/device-targets.ts rename to packages/daemon/src/device/device-targets.ts diff --git a/src/daemon/direct-ios-selector.ts b/packages/daemon/src/direct-ios-selector.ts similarity index 100% rename from src/daemon/direct-ios-selector.ts rename to packages/daemon/src/direct-ios-selector.ts diff --git a/src/daemon/dispatch-context.ts b/packages/daemon/src/dispatch-context.ts similarity index 100% rename from src/daemon/dispatch-context.ts rename to packages/daemon/src/dispatch-context.ts diff --git a/src/daemon/dispatch-payload.test.ts b/packages/daemon/src/dispatch-payload.test.ts similarity index 100% rename from src/daemon/dispatch-payload.test.ts rename to packages/daemon/src/dispatch-payload.test.ts diff --git a/src/daemon/dispatch-payload.ts b/packages/daemon/src/dispatch-payload.ts similarity index 100% rename from src/daemon/dispatch-payload.ts rename to packages/daemon/src/dispatch-payload.ts diff --git a/src/daemon/downloadable-artifact-http.ts b/packages/daemon/src/downloadable-artifact-http.ts similarity index 100% rename from src/daemon/downloadable-artifact-http.ts rename to packages/daemon/src/downloadable-artifact-http.ts diff --git a/src/daemon/execution-plan.ts b/packages/daemon/src/execution-plan.ts similarity index 100% rename from src/daemon/execution-plan.ts rename to packages/daemon/src/execution-plan.ts diff --git a/src/daemon/fill-backend-result.test.ts b/packages/daemon/src/fill-backend-result.test.ts similarity index 100% rename from src/daemon/fill-backend-result.test.ts rename to packages/daemon/src/fill-backend-result.test.ts diff --git a/src/daemon/fill-backend-result.ts b/packages/daemon/src/fill-backend-result.ts similarity index 100% rename from src/daemon/fill-backend-result.ts rename to packages/daemon/src/fill-backend-result.ts diff --git a/src/daemon/focus-runtime.ts b/packages/daemon/src/focus-runtime.ts similarity index 100% rename from src/daemon/focus-runtime.ts rename to packages/daemon/src/focus-runtime.ts diff --git a/src/daemon/fold-runtime.ts b/packages/daemon/src/fold-runtime.ts similarity index 100% rename from src/daemon/fold-runtime.ts rename to packages/daemon/src/fold-runtime.ts diff --git a/src/daemon/generic-leaf-execution.ts b/packages/daemon/src/generic-leaf-execution.ts similarity index 100% rename from src/daemon/generic-leaf-execution.ts rename to packages/daemon/src/generic-leaf-execution.ts diff --git a/src/daemon/generic-runtime-execution.ts b/packages/daemon/src/generic-runtime-execution.ts similarity index 100% rename from src/daemon/generic-runtime-execution.ts rename to packages/daemon/src/generic-runtime-execution.ts diff --git a/src/daemon/generic-settle.ts b/packages/daemon/src/generic-settle.ts similarity index 100% rename from src/daemon/generic-settle.ts rename to packages/daemon/src/generic-settle.ts diff --git a/src/daemon/gesture-runtime.ts b/packages/daemon/src/gesture-runtime.ts similarity index 100% rename from src/daemon/gesture-runtime.ts rename to packages/daemon/src/gesture-runtime.ts diff --git a/src/daemon/handlers/__tests__/human-control.test.ts b/packages/daemon/src/handlers/__tests__/human-control.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/human-control.test.ts rename to packages/daemon/src/handlers/__tests__/human-control.test.ts diff --git a/src/daemon/handlers/__tests__/install-source.test.ts b/packages/daemon/src/handlers/__tests__/install-source.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/install-source.test.ts rename to packages/daemon/src/handlers/__tests__/install-source.test.ts diff --git a/src/daemon/handlers/__tests__/lease-artifacts.test.ts b/packages/daemon/src/handlers/__tests__/lease-artifacts.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/lease-artifacts.test.ts rename to packages/daemon/src/handlers/__tests__/lease-artifacts.test.ts diff --git a/src/daemon/handlers/__tests__/lease.test.ts b/packages/daemon/src/handlers/__tests__/lease.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/lease.test.ts rename to packages/daemon/src/handlers/__tests__/lease.test.ts diff --git a/src/daemon/handlers/__tests__/react-native.test.ts b/packages/daemon/src/handlers/__tests__/react-native.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/react-native.test.ts rename to packages/daemon/src/handlers/__tests__/react-native.test.ts diff --git a/src/daemon/handlers/__tests__/record-runtime-request.test.ts b/packages/daemon/src/handlers/__tests__/record-runtime-request.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/record-runtime-request.test.ts rename to packages/daemon/src/handlers/__tests__/record-runtime-request.test.ts diff --git a/src/daemon/handlers/__tests__/record-runtime-response.test.ts b/packages/daemon/src/handlers/__tests__/record-runtime-response.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/record-runtime-response.test.ts rename to packages/daemon/src/handlers/__tests__/record-runtime-response.test.ts diff --git a/src/daemon/handlers/__tests__/record-runtime-start.test.ts b/packages/daemon/src/handlers/__tests__/record-runtime-start.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/record-runtime-start.test.ts rename to packages/daemon/src/handlers/__tests__/record-runtime-start.test.ts diff --git a/src/daemon/handlers/__tests__/record-runtime-stop-recovery.test.ts b/packages/daemon/src/handlers/__tests__/record-runtime-stop-recovery.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/record-runtime-stop-recovery.test.ts rename to packages/daemon/src/handlers/__tests__/record-runtime-stop-recovery.test.ts diff --git a/src/daemon/handlers/__tests__/record-runtime.fixtures.ts b/packages/daemon/src/handlers/__tests__/record-runtime.fixtures.ts similarity index 98% rename from src/daemon/handlers/__tests__/record-runtime.fixtures.ts rename to packages/daemon/src/handlers/__tests__/record-runtime.fixtures.ts index 820a37364b..e3bb5a4399 100644 --- a/src/daemon/handlers/__tests__/record-runtime.fixtures.ts +++ b/packages/daemon/src/handlers/__tests__/record-runtime.fixtures.ts @@ -1,5 +1,5 @@ import { daemonPlatformServicesFixture } from '../../__tests__/platform-services-fixture.ts'; -import { expect, vi } from 'vitest'; +import { expect, vi, type Mock } from 'vitest'; import { applicationLifecycleOperationFacts } from '@agent-device/contracts/application-lifecycle-runtime'; import { PendingTransferGuard } from '@agent-device/contracts/async-lifecycle'; import type { CleanupOutcome } from '@agent-device/contracts/durable-resource'; @@ -225,7 +225,7 @@ function makeRuntime(session: SessionState, options: RuntimeOptions = {}) { [Symbol.asyncDispose]: async () => {}, }; const bindDevice: BindDeviceRuntime = async (_device, use) => narrowDeviceBinding(binding, use); - const bindExactDeviceCalls = vi.fn(); + const bindExactDeviceCalls = vi.fn() as Mock; const bindExactDevice: BindExactDeviceRuntime = async (device, ownerRef, fence, use, scope) => { bindExactDeviceCalls(device, ownerRef, fence, use, scope); return narrowDeviceBinding(binding, use); diff --git a/src/daemon/handlers/__tests__/session-appstate-device-runtime.test.ts b/packages/daemon/src/handlers/__tests__/session-appstate-device-runtime.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-appstate-device-runtime.test.ts rename to packages/daemon/src/handlers/__tests__/session-appstate-device-runtime.test.ts diff --git a/src/daemon/handlers/__tests__/session-appstate-input.test.ts b/packages/daemon/src/handlers/__tests__/session-appstate-input.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-appstate-input.test.ts rename to packages/daemon/src/handlers/__tests__/session-appstate-input.test.ts diff --git a/src/daemon/handlers/__tests__/session-appstate.test.ts b/packages/daemon/src/handlers/__tests__/session-appstate.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-appstate.test.ts rename to packages/daemon/src/handlers/__tests__/session-appstate.test.ts diff --git a/src/daemon/handlers/__tests__/session-boot-shutdown-device-claims.test.ts b/packages/daemon/src/handlers/__tests__/session-boot-shutdown-device-claims.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-boot-shutdown-device-claims.test.ts rename to packages/daemon/src/handlers/__tests__/session-boot-shutdown-device-claims.test.ts diff --git a/src/daemon/handlers/__tests__/session-boot-warmup.test.ts b/packages/daemon/src/handlers/__tests__/session-boot-warmup.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-boot-warmup.test.ts rename to packages/daemon/src/handlers/__tests__/session-boot-warmup.test.ts diff --git a/src/daemon/handlers/__tests__/session-boot.test.ts b/packages/daemon/src/handlers/__tests__/session-boot.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-boot.test.ts rename to packages/daemon/src/handlers/__tests__/session-boot.test.ts diff --git a/src/daemon/handlers/__tests__/session-clipboard.test.ts b/packages/daemon/src/handlers/__tests__/session-clipboard.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-clipboard.test.ts rename to packages/daemon/src/handlers/__tests__/session-clipboard.test.ts diff --git a/src/daemon/handlers/__tests__/session-command-harness.ts b/packages/daemon/src/handlers/__tests__/session-command-harness.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-command-harness.ts rename to packages/daemon/src/handlers/__tests__/session-command-harness.ts diff --git a/src/daemon/handlers/__tests__/session-command-replay.test.ts b/packages/daemon/src/handlers/__tests__/session-command-replay.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-command-replay.test.ts rename to packages/daemon/src/handlers/__tests__/session-command-replay.test.ts diff --git a/src/daemon/handlers/__tests__/session-device-claims.test.ts b/packages/daemon/src/handlers/__tests__/session-device-claims.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-device-claims.test.ts rename to packages/daemon/src/handlers/__tests__/session-device-claims.test.ts diff --git a/src/daemon/handlers/__tests__/session-device-status-response.test.ts b/packages/daemon/src/handlers/__tests__/session-device-status-response.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-device-status-response.test.ts rename to packages/daemon/src/handlers/__tests__/session-device-status-response.test.ts diff --git a/src/daemon/handlers/__tests__/session-doctor-app-runtime.test.ts b/packages/daemon/src/handlers/__tests__/session-doctor-app-runtime.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-doctor-app-runtime.test.ts rename to packages/daemon/src/handlers/__tests__/session-doctor-app-runtime.test.ts diff --git a/src/daemon/handlers/__tests__/session-doctor-device.test.ts b/packages/daemon/src/handlers/__tests__/session-doctor-device.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-doctor-device.test.ts rename to packages/daemon/src/handlers/__tests__/session-doctor-device.test.ts diff --git a/src/daemon/handlers/__tests__/session-doctor-metro.test.ts b/packages/daemon/src/handlers/__tests__/session-doctor-metro.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-doctor-metro.test.ts rename to packages/daemon/src/handlers/__tests__/session-doctor-metro.test.ts diff --git a/src/daemon/handlers/__tests__/session-doctor-options.test.ts b/packages/daemon/src/handlers/__tests__/session-doctor-options.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-doctor-options.test.ts rename to packages/daemon/src/handlers/__tests__/session-doctor-options.test.ts diff --git a/src/daemon/handlers/__tests__/session-install-source-ref-frame.test.ts b/packages/daemon/src/handlers/__tests__/session-install-source-ref-frame.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-install-source-ref-frame.test.ts rename to packages/daemon/src/handlers/__tests__/session-install-source-ref-frame.test.ts diff --git a/src/daemon/handlers/__tests__/session-prepare.test.ts b/packages/daemon/src/handlers/__tests__/session-prepare.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-prepare.test.ts rename to packages/daemon/src/handlers/__tests__/session-prepare.test.ts diff --git a/src/daemon/handlers/__tests__/session-push-ref-frame.test.ts b/packages/daemon/src/handlers/__tests__/session-push-ref-frame.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-push-ref-frame.test.ts rename to packages/daemon/src/handlers/__tests__/session-push-ref-frame.test.ts diff --git a/src/daemon/handlers/__tests__/session-push.test.ts b/packages/daemon/src/handlers/__tests__/session-push.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-push.test.ts rename to packages/daemon/src/handlers/__tests__/session-push.test.ts diff --git a/src/daemon/handlers/__tests__/session-reinstall.test.ts b/packages/daemon/src/handlers/__tests__/session-reinstall.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-reinstall.test.ts rename to packages/daemon/src/handlers/__tests__/session-reinstall.test.ts diff --git a/src/daemon/handlers/__tests__/session-relaunch-guards.test.ts b/packages/daemon/src/handlers/__tests__/session-relaunch-guards.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-relaunch-guards.test.ts rename to packages/daemon/src/handlers/__tests__/session-relaunch-guards.test.ts diff --git a/src/daemon/handlers/__tests__/session-replay-command.test.ts b/packages/daemon/src/handlers/__tests__/session-replay-command.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-replay-command.test.ts rename to packages/daemon/src/handlers/__tests__/session-replay-command.test.ts diff --git a/src/daemon/handlers/__tests__/session-runtime-command.test.ts b/packages/daemon/src/handlers/__tests__/session-runtime-command.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-runtime-command.test.ts rename to packages/daemon/src/handlers/__tests__/session-runtime-command.test.ts diff --git a/src/daemon/handlers/__tests__/session-runtime-port-reverse.test.ts b/packages/daemon/src/handlers/__tests__/session-runtime-port-reverse.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-runtime-port-reverse.test.ts rename to packages/daemon/src/handlers/__tests__/session-runtime-port-reverse.test.ts diff --git a/src/daemon/handlers/__tests__/session-script-publication.test.ts b/packages/daemon/src/handlers/__tests__/session-script-publication.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-script-publication.test.ts rename to packages/daemon/src/handlers/__tests__/session-script-publication.test.ts diff --git a/src/daemon/handlers/__tests__/session-selector-dispatch.test.ts b/packages/daemon/src/handlers/__tests__/session-selector-dispatch.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-selector-dispatch.test.ts rename to packages/daemon/src/handlers/__tests__/session-selector-dispatch.test.ts diff --git a/src/daemon/handlers/__tests__/session-shutdown.test.ts b/packages/daemon/src/handlers/__tests__/session-shutdown.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-shutdown.test.ts rename to packages/daemon/src/handlers/__tests__/session-shutdown.test.ts diff --git a/src/daemon/handlers/__tests__/session-test-harness.ts b/packages/daemon/src/handlers/__tests__/session-test-harness.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-test-harness.ts rename to packages/daemon/src/handlers/__tests__/session-test-harness.ts diff --git a/src/daemon/handlers/__tests__/session-trigger.test.ts b/packages/daemon/src/handlers/__tests__/session-trigger.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session-trigger.test.ts rename to packages/daemon/src/handlers/__tests__/session-trigger.test.ts diff --git a/src/daemon/handlers/__tests__/session.test.ts b/packages/daemon/src/handlers/__tests__/session.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/session.test.ts rename to packages/daemon/src/handlers/__tests__/session.test.ts diff --git a/src/daemon/handlers/__tests__/snapshot-alert.test.ts b/packages/daemon/src/handlers/__tests__/snapshot-alert.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/snapshot-alert.test.ts rename to packages/daemon/src/handlers/__tests__/snapshot-alert.test.ts diff --git a/src/daemon/handlers/__tests__/snapshot-handler.fixtures.ts b/packages/daemon/src/handlers/__tests__/snapshot-handler.fixtures.ts similarity index 100% rename from src/daemon/handlers/__tests__/snapshot-handler.fixtures.ts rename to packages/daemon/src/handlers/__tests__/snapshot-handler.fixtures.ts diff --git a/src/daemon/handlers/__tests__/snapshot-settings-handler.test.ts b/packages/daemon/src/handlers/__tests__/snapshot-settings-handler.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/snapshot-settings-handler.test.ts rename to packages/daemon/src/handlers/__tests__/snapshot-settings-handler.test.ts diff --git a/src/daemon/handlers/__tests__/snapshot.test.ts b/packages/daemon/src/handlers/__tests__/snapshot.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/snapshot.test.ts rename to packages/daemon/src/handlers/__tests__/snapshot.test.ts diff --git a/src/daemon/handlers/__tests__/trace-runtime.test.ts b/packages/daemon/src/handlers/__tests__/trace-runtime.test.ts similarity index 100% rename from src/daemon/handlers/__tests__/trace-runtime.test.ts rename to packages/daemon/src/handlers/__tests__/trace-runtime.test.ts diff --git a/src/daemon/handlers/human-control.ts b/packages/daemon/src/handlers/human-control.ts similarity index 100% rename from src/daemon/handlers/human-control.ts rename to packages/daemon/src/handlers/human-control.ts diff --git a/src/daemon/handlers/lease.ts b/packages/daemon/src/handlers/lease.ts similarity index 100% rename from src/daemon/handlers/lease.ts rename to packages/daemon/src/handlers/lease.ts diff --git a/src/daemon/handlers/react-native.ts b/packages/daemon/src/handlers/react-native.ts similarity index 100% rename from src/daemon/handlers/react-native.ts rename to packages/daemon/src/handlers/react-native.ts diff --git a/src/daemon/handlers/record-runtime-request.ts b/packages/daemon/src/handlers/record-runtime-request.ts similarity index 100% rename from src/daemon/handlers/record-runtime-request.ts rename to packages/daemon/src/handlers/record-runtime-request.ts diff --git a/src/daemon/handlers/record-runtime-response.ts b/packages/daemon/src/handlers/record-runtime-response.ts similarity index 100% rename from src/daemon/handlers/record-runtime-response.ts rename to packages/daemon/src/handlers/record-runtime-response.ts diff --git a/src/daemon/handlers/record-runtime.ts b/packages/daemon/src/handlers/record-runtime.ts similarity index 100% rename from src/daemon/handlers/record-runtime.ts rename to packages/daemon/src/handlers/record-runtime.ts diff --git a/src/daemon/handlers/record-trace.ts b/packages/daemon/src/handlers/record-trace.ts similarity index 100% rename from src/daemon/handlers/record-trace.ts rename to packages/daemon/src/handlers/record-trace.ts diff --git a/src/daemon/handlers/session-app-deployment-route.ts b/packages/daemon/src/handlers/session-app-deployment-route.ts similarity index 100% rename from src/daemon/handlers/session-app-deployment-route.ts rename to packages/daemon/src/handlers/session-app-deployment-route.ts diff --git a/src/daemon/handlers/session-app-deployment.ts b/packages/daemon/src/handlers/session-app-deployment.ts similarity index 100% rename from src/daemon/handlers/session-app-deployment.ts rename to packages/daemon/src/handlers/session-app-deployment.ts diff --git a/src/daemon/handlers/session-app-source-deployment.ts b/packages/daemon/src/handlers/session-app-source-deployment.ts similarity index 100% rename from src/daemon/handlers/session-app-source-deployment.ts rename to packages/daemon/src/handlers/session-app-source-deployment.ts diff --git a/src/daemon/handlers/session-appstate-apple-session.ts b/packages/daemon/src/handlers/session-appstate-apple-session.ts similarity index 100% rename from src/daemon/handlers/session-appstate-apple-session.ts rename to packages/daemon/src/handlers/session-appstate-apple-session.ts diff --git a/src/daemon/handlers/session-appstate-device-runtime.ts b/packages/daemon/src/handlers/session-appstate-device-runtime.ts similarity index 100% rename from src/daemon/handlers/session-appstate-device-runtime.ts rename to packages/daemon/src/handlers/session-appstate-device-runtime.ts diff --git a/src/daemon/handlers/session-appstate.ts b/packages/daemon/src/handlers/session-appstate.ts similarity index 100% rename from src/daemon/handlers/session-appstate.ts rename to packages/daemon/src/handlers/session-appstate.ts diff --git a/src/daemon/handlers/session-batch.ts b/packages/daemon/src/handlers/session-batch.ts similarity index 100% rename from src/daemon/handlers/session-batch.ts rename to packages/daemon/src/handlers/session-batch.ts diff --git a/src/daemon/handlers/session-boot.ts b/packages/daemon/src/handlers/session-boot.ts similarity index 100% rename from src/daemon/handlers/session-boot.ts rename to packages/daemon/src/handlers/session-boot.ts diff --git a/src/daemon/handlers/session-clipboard.ts b/packages/daemon/src/handlers/session-clipboard.ts similarity index 100% rename from src/daemon/handlers/session-clipboard.ts rename to packages/daemon/src/handlers/session-clipboard.ts diff --git a/src/daemon/handlers/session-command-input.ts b/packages/daemon/src/handlers/session-command-input.ts similarity index 100% rename from src/daemon/handlers/session-command-input.ts rename to packages/daemon/src/handlers/session-command-input.ts diff --git a/src/daemon/handlers/session-device-status-response.ts b/packages/daemon/src/handlers/session-device-status-response.ts similarity index 100% rename from src/daemon/handlers/session-device-status-response.ts rename to packages/daemon/src/handlers/session-device-status-response.ts diff --git a/src/daemon/handlers/session-doctor-app.ts b/packages/daemon/src/handlers/session-doctor-app.ts similarity index 100% rename from src/daemon/handlers/session-doctor-app.ts rename to packages/daemon/src/handlers/session-doctor-app.ts diff --git a/src/daemon/handlers/session-doctor-device.ts b/packages/daemon/src/handlers/session-doctor-device.ts similarity index 100% rename from src/daemon/handlers/session-doctor-device.ts rename to packages/daemon/src/handlers/session-doctor-device.ts diff --git a/src/daemon/handlers/session-doctor-metro.ts b/packages/daemon/src/handlers/session-doctor-metro.ts similarity index 100% rename from src/daemon/handlers/session-doctor-metro.ts rename to packages/daemon/src/handlers/session-doctor-metro.ts diff --git a/src/daemon/handlers/session-doctor-options.ts b/packages/daemon/src/handlers/session-doctor-options.ts similarity index 100% rename from src/daemon/handlers/session-doctor-options.ts rename to packages/daemon/src/handlers/session-doctor-options.ts diff --git a/src/daemon/handlers/session-doctor-output.ts b/packages/daemon/src/handlers/session-doctor-output.ts similarity index 100% rename from src/daemon/handlers/session-doctor-output.ts rename to packages/daemon/src/handlers/session-doctor-output.ts diff --git a/src/daemon/handlers/session-doctor-types.ts b/packages/daemon/src/handlers/session-doctor-types.ts similarity index 100% rename from src/daemon/handlers/session-doctor-types.ts rename to packages/daemon/src/handlers/session-doctor-types.ts diff --git a/src/daemon/handlers/session-doctor.ts b/packages/daemon/src/handlers/session-doctor.ts similarity index 100% rename from src/daemon/handlers/session-doctor.ts rename to packages/daemon/src/handlers/session-doctor.ts diff --git a/src/daemon/handlers/session-prepare.ts b/packages/daemon/src/handlers/session-prepare.ts similarity index 100% rename from src/daemon/handlers/session-prepare.ts rename to packages/daemon/src/handlers/session-prepare.ts diff --git a/src/daemon/handlers/session-replay-command.ts b/packages/daemon/src/handlers/session-replay-command.ts similarity index 100% rename from src/daemon/handlers/session-replay-command.ts rename to packages/daemon/src/handlers/session-replay-command.ts diff --git a/src/daemon/handlers/session-replay-video-owner.ts b/packages/daemon/src/handlers/session-replay-video-owner.ts similarity index 100% rename from src/daemon/handlers/session-replay-video-owner.ts rename to packages/daemon/src/handlers/session-replay-video-owner.ts diff --git a/src/daemon/handlers/session-runtime-command.ts b/packages/daemon/src/handlers/session-runtime-command.ts similarity index 100% rename from src/daemon/handlers/session-runtime-command.ts rename to packages/daemon/src/handlers/session-runtime-command.ts diff --git a/src/daemon/handlers/session-runtime-port-reverse.ts b/packages/daemon/src/handlers/session-runtime-port-reverse.ts similarity index 100% rename from src/daemon/handlers/session-runtime-port-reverse.ts rename to packages/daemon/src/handlers/session-runtime-port-reverse.ts diff --git a/src/daemon/handlers/session-script-publication.ts b/packages/daemon/src/handlers/session-script-publication.ts similarity index 100% rename from src/daemon/handlers/session-script-publication.ts rename to packages/daemon/src/handlers/session-script-publication.ts diff --git a/src/daemon/handlers/session-selector-dispatch.ts b/packages/daemon/src/handlers/session-selector-dispatch.ts similarity index 100% rename from src/daemon/handlers/session-selector-dispatch.ts rename to packages/daemon/src/handlers/session-selector-dispatch.ts diff --git a/src/daemon/handlers/session-shutdown.ts b/packages/daemon/src/handlers/session-shutdown.ts similarity index 100% rename from src/daemon/handlers/session-shutdown.ts rename to packages/daemon/src/handlers/session-shutdown.ts diff --git a/src/daemon/handlers/session.ts b/packages/daemon/src/handlers/session.ts similarity index 98% rename from src/daemon/handlers/session.ts rename to packages/daemon/src/handlers/session.ts index 13b0ce7e42..aa73b8f325 100644 --- a/src/daemon/handlers/session.ts +++ b/packages/daemon/src/handlers/session.ts @@ -91,7 +91,7 @@ const handleSessionObservabilityCommandGroup: SessionCommandHandler = async ({ /** * Descriptor-driven exhaustive dispatch table for the daemon's `session` * route (mirrors `DISPATCH_HANDLERS` in -device/device-selection/dispatch-resolve and - * `SNAPSHOT_COMMAND_HANDLER_IMPLS` in src/daemon/handlers/snapshot.ts). The + * `SNAPSHOT_COMMAND_HANDLER_IMPLS` in packages/daemon/src/handlers/snapshot.ts). The * `satisfies Record` check means a * session-routed descriptor added to the registry without a matching entry * here is a COMPILE error, not a runtime routing gap. Command-kind groupings diff --git a/src/daemon/handlers/snapshot-alert.ts b/packages/daemon/src/handlers/snapshot-alert.ts similarity index 100% rename from src/daemon/handlers/snapshot-alert.ts rename to packages/daemon/src/handlers/snapshot-alert.ts diff --git a/src/daemon/handlers/snapshot-runtime-route.test.ts b/packages/daemon/src/handlers/snapshot-runtime-route.test.ts similarity index 100% rename from src/daemon/handlers/snapshot-runtime-route.test.ts rename to packages/daemon/src/handlers/snapshot-runtime-route.test.ts diff --git a/src/daemon/handlers/snapshot-settings.ts b/packages/daemon/src/handlers/snapshot-settings.ts similarity index 100% rename from src/daemon/handlers/snapshot-settings.ts rename to packages/daemon/src/handlers/snapshot-settings.ts diff --git a/src/daemon/handlers/snapshot.ts b/packages/daemon/src/handlers/snapshot.ts similarity index 100% rename from src/daemon/handlers/snapshot.ts rename to packages/daemon/src/handlers/snapshot.ts diff --git a/src/daemon/handlers/trace-runtime.ts b/packages/daemon/src/handlers/trace-runtime.ts similarity index 100% rename from src/daemon/handlers/trace-runtime.ts rename to packages/daemon/src/handlers/trace-runtime.ts diff --git a/src/daemon/host-lease-http.ts b/packages/daemon/src/host-lease-http.ts similarity index 100% rename from src/daemon/host-lease-http.ts rename to packages/daemon/src/host-lease-http.ts diff --git a/src/daemon/http-errors.ts b/packages/daemon/src/http-errors.ts similarity index 100% rename from src/daemon/http-errors.ts rename to packages/daemon/src/http-errors.ts diff --git a/src/daemon/http-request-target.ts b/packages/daemon/src/http-request-target.ts similarity index 100% rename from src/daemon/http-request-target.ts rename to packages/daemon/src/http-request-target.ts diff --git a/src/daemon/human-control-contract.ts b/packages/daemon/src/human-control-contract.ts similarity index 100% rename from src/daemon/human-control-contract.ts rename to packages/daemon/src/human-control-contract.ts diff --git a/src/daemon/human-control-http.ts b/packages/daemon/src/human-control-http.ts similarity index 100% rename from src/daemon/human-control-http.ts rename to packages/daemon/src/human-control-http.ts diff --git a/src/daemon/install-source-resolution.ts b/packages/daemon/src/install-source-resolution.ts similarity index 100% rename from src/daemon/install-source-resolution.ts rename to packages/daemon/src/install-source-resolution.ts diff --git a/src/daemon/interaction-surface-signature.ts b/packages/daemon/src/interaction-surface-signature.ts similarity index 100% rename from src/daemon/interaction-surface-signature.ts rename to packages/daemon/src/interaction-surface-signature.ts diff --git a/src/daemon/interaction/index.ts b/packages/daemon/src/interaction/index.ts similarity index 100% rename from src/daemon/interaction/index.ts rename to packages/daemon/src/interaction/index.ts diff --git a/src/daemon/interaction/internal/__tests__/find-handler-fixture.ts b/packages/daemon/src/interaction/internal/__tests__/find-handler-fixture.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/find-handler-fixture.ts rename to packages/daemon/src/interaction/internal/__tests__/find-handler-fixture.ts diff --git a/src/daemon/interaction/internal/__tests__/find-match-ranking.test.ts b/packages/daemon/src/interaction/internal/__tests__/find-match-ranking.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/find-match-ranking.test.ts rename to packages/daemon/src/interaction/internal/__tests__/find-match-ranking.test.ts diff --git a/src/daemon/interaction/internal/__tests__/find-single-bind.test.ts b/packages/daemon/src/interaction/internal/__tests__/find-single-bind.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/find-single-bind.test.ts rename to packages/daemon/src/interaction/internal/__tests__/find-single-bind.test.ts diff --git a/src/daemon/interaction/internal/__tests__/find-target-activation-disclosure.test.ts b/packages/daemon/src/interaction/internal/__tests__/find-target-activation-disclosure.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/find-target-activation-disclosure.test.ts rename to packages/daemon/src/interaction/internal/__tests__/find-target-activation-disclosure.test.ts diff --git a/src/daemon/interaction/internal/__tests__/find-touch-runtime-fixture.ts b/packages/daemon/src/interaction/internal/__tests__/find-touch-runtime-fixture.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/find-touch-runtime-fixture.ts rename to packages/daemon/src/interaction/internal/__tests__/find-touch-runtime-fixture.ts diff --git a/src/daemon/interaction/internal/__tests__/find.test.ts b/packages/daemon/src/interaction/internal/__tests__/find.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/find.test.ts rename to packages/daemon/src/interaction/internal/__tests__/find.test.ts diff --git a/src/daemon/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts b/packages/daemon/src/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts similarity index 64% rename from src/daemon/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts rename to packages/daemon/src/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts index ebc033b318..e66c287994 100644 --- a/src/daemon/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts +++ b/packages/daemon/src/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts @@ -1,7 +1,15 @@ -import { vi } from 'vitest'; +import { vi, type Mock } from 'vitest'; import type { BoundDeviceRuntime, RuntimeFacts } from '@agent-device/contracts/platform-runtime'; import type { PlatformRuntimeOperations } from '@agent-device/contracts/platform-runtime-operations'; import type { Rect } from '@agent-device/kernel/snapshot'; +import type { + GesturePlanInput, + GestureViewportInput, +} from '@agent-device/contracts/gesture-runtime'; +import type { + CaptureSnapshotInput, + SnapshotResult, +} from '@agent-device/contracts/snapshot-runtime'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts, @@ -26,14 +34,25 @@ export function gestureRuntimeBindingsFixture( ? ({ available: false, reason: 'unsupported-platform-leaf' } as const) : available; const operationSpies = { - captureSnapshot: vi.fn(async () => ({ backend: 'xctest' as const, nodes: [] })), - performGesturePlan: vi.fn(async () => ({})), - performDirectionalFlingPlan: vi.fn(async () => ({})), - performMultiTouchGesturePlan: vi.fn(async () => ({})), - performTargetAuthoredDrag: vi.fn(async () => ({})), + captureSnapshot: vi.fn(async () => ({ + backend: 'xctest' as const, + nodes: [], + })) as unknown as Mock<(input: CaptureSnapshotInput) => Promise>, + performGesturePlan: vi.fn(async () => ({})) as Mock< + (input: GesturePlanInput) => Promise> + >, + performDirectionalFlingPlan: vi.fn(async () => ({})) as Mock< + (input: GesturePlanInput) => Promise> + >, + performMultiTouchGesturePlan: vi.fn(async () => ({})) as Mock< + (input: GesturePlanInput) => Promise> + >, + performTargetAuthoredDrag: vi.fn(async () => ({})) as Mock< + (input: GesturePlanInput) => Promise> + >, gestureViewport: vi.fn( - async () => options.viewport ?? ({ x: 0, y: 0, width: 400, height: 800 } as Rect), - ), + async () => options.viewport ?? { x: 0, y: 0, width: 400, height: 800 }, + ) as Mock<(input: GestureViewportInput) => Promise>, }; const facts = { device: { family: 'apple', kind: 'simulator', providerMode: 'local' }, @@ -48,7 +67,7 @@ export function gestureRuntimeBindingsFixture( }, } as unknown as RuntimeFacts; const inspectFacts = vi.fn(async () => facts) as unknown as InspectDeviceRuntimeFacts & - ReturnType; + Mock<() => Promise>>; const bindDevice = vi.fn( async () => ({ @@ -57,6 +76,6 @@ export function gestureRuntimeBindingsFixture( Object.entries(operationSpies).filter(([name]) => !unavailable.has(name)), ), }) as unknown as BoundDeviceRuntime, - ) as unknown as BindDeviceRuntime & ReturnType; + ) as unknown as BindDeviceRuntime & Mock<() => Promise>>; return { ...operationSpies, facts, inspectFacts, bindDevice }; } diff --git a/src/daemon/interaction/internal/__tests__/interaction-gesture-response.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-gesture-response.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-gesture-response.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-gesture-response.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-recorded-input.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-recorded-input.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-recorded-input.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-recorded-input.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-ref-policy.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-ref-policy.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-ref-policy.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-ref-policy.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-response-construction-guard.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-response-construction-guard.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-response-construction-guard.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-response-construction-guard.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-response-data-transform.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-response-data-transform.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-response-data-transform.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-response-data-transform.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-runtime.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-runtime.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-runtime.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-runtime.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-snapshot-scope.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-snapshot-scope.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-snapshot-scope.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-snapshot-scope.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-touch-fixtures.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-touch-fixtures.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-touch-reference-frame.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-touch-reference-frame.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-touch-reference-frame.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-touch-reference-frame.test.ts diff --git a/packages/daemon/src/interaction/internal/__tests__/interaction-touch-response.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-touch-response.test.ts new file mode 100644 index 0000000000..09b8672601 --- /dev/null +++ b/packages/daemon/src/interaction/internal/__tests__/interaction-touch-response.test.ts @@ -0,0 +1,308 @@ +import fs from 'node:fs'; +import path from 'node:path'; +import { + withDiagnosticsScope, + flushDiagnosticsToSessionFile, +} from '@agent-device/host-kit/diagnostics'; +import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; +import { test, expect, vi, beforeEach } from 'vitest'; +import { attachRefs } from '@agent-device/kernel/snapshot'; +import { makeSessionStore } from '../../../__tests__/support/store-factory.ts'; +import { + buildInteractionResponseData, + buildTargetedTouchResponsePayloads, + transformTouchResponseData, +} from '../interaction-touch-response.ts'; +import type { PressCommandResult } from '@agent-device/contracts/interaction'; +import { daemonPlatformServicesFixture } from '../../../__tests__/platform-services-fixture.ts'; +import { fakeCreateCommandSurface as testCreateCommandSurface } from '../../../__tests__/support/command-surface-fake.ts'; +import { + contextFromFlags, + installTestScreenRecording, + makeSession, +} from './interaction-touch-fixtures.ts'; + +// Pure response-builder suites: every case calls the daemon builders directly. The +// suites that drive `handleInteractionCommands` through the real root command surface +// (the --verify evidence branches) stayed root-side under +// `src/__tests__/daemon-composition/interaction/`, where the surface they exercise lives. + +const { mockRunAppleRunnerCommand } = vi.hoisted(() => ({ + mockRunAppleRunnerCommand: vi.fn(), +})); + +vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + getAndroidScreenSize: vi.fn(async () => ({ width: 1344, height: 2992 })), + getAndroidAppState: vi.fn(async () => ({})), + getAndroidBlockingDialogObservation: vi.fn(async () => ({ status: 'clear' }) as const), + }; +}); + +vi.mock('../../../snapshot-interactor-capture.ts', () => ({ + captureSnapshotWithInteractor: vi.fn(), +})); + +vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) => { + const actual = + await importOriginal(); + return { ...actual, runAppleRunnerCommand: mockRunAppleRunnerCommand }; +}); + +import { + getAndroidAppState, + getAndroidBlockingDialogObservation, + getAndroidScreenSize, +} from '@agent-device/platform-android/mechanics'; +import { captureSnapshotWithInteractor } from '../../../snapshot-interactor-capture.ts'; + +beforeEach(() => { + vi.mocked(getAndroidAppState).mockReset(); + vi.mocked(getAndroidAppState).mockResolvedValue({}); + vi.mocked(getAndroidBlockingDialogObservation).mockReset(); + vi.mocked(getAndroidBlockingDialogObservation).mockResolvedValue({ status: 'clear' }); + vi.mocked(getAndroidScreenSize).mockReset(); + vi.mocked(getAndroidScreenSize).mockResolvedValue({ width: 1344, height: 2992 }); + vi.mocked(captureSnapshotWithInteractor).mockReset(); + mockRunAppleRunnerCommand.mockReset(); + mockRunAppleRunnerCommand.mockResolvedValue({}); +}); + +test('commandless longpress response omits internal interaction diagnostics', () => { + expect( + transformTouchResponseData({ + flags: {}, + data: { + currentUptimeMs: 900, + gestureStartUptimeMs: 100, + gestureEndUptimeMs: 800, + sequenceResults: [{ index: 0, success: true }], + completedSteps: 1, + }, + }), + ).toEqual({ completedSteps: 1 }); +}); + +function selectorResult(readiness?: { polls: number; waitedMs: number }): PressCommandResult { + return { + kind: 'selector', + point: { x: 10, y: 20 }, + target: { kind: 'selector', selector: 'label=Continue' }, + node: { ref: 'e1', index: 0, type: 'Button', label: 'Continue' }, + selectorChain: ['label=Continue'], + warning: 'earlier warning', + ...(readiness ? { readiness } : {}), + }; +} + +const WAITED_SELECTOR_RESULT = selectorResult({ polls: 3, waitedMs: 400 }); + +test.each([false, true])('selector-touch observation after retirement=%s', async (retired) => { + const sessionStore = makeSessionStore(); + const address = 'cwd:selector-touch-response:default'; + const session = makeSession('default'); + session.snapshot = { + nodes: attachRefs([{ index: 0, type: 'Button', label: 'Continue' }]), + createdAt: Date.now(), + backend: 'xctest', + }; + session.snapshotGeneration = 3; + const ref = sessionStore.publish(address, session); + const result: PressCommandResult = { + ...selectorResult(), + settle: { + settled: true, + waitedMs: 25, + captures: 2, + quietMs: 25, + timeoutMs: 2000, + diff: { + summary: { additions: 1, removals: 0, unchanged: 0 }, + lines: [{ kind: 'added', text: 'Continue', ref: 'e1' }], + }, + }, + }; + let successor; + if (retired) { + sessionStore.retire(ref); + successor = sessionStore.publish(address, makeSession('default')); + } + const payloads = await buildTargetedTouchResponsePayloads({ + params: { + createCommandSurface: testCreateCommandSurface, + req: { token: 't', command: 'press', positionals: ['@e1'], session: 'default' }, + sessionName: address, + sessionRef: ref, + sessionStore, + contextFromFlags, + platformServices: daemonPlatformServicesFixture(), + captureSnapshotForSession: vi.fn(), + }, + result, + staleRefsWarning: undefined, + extra: {}, + }); + if (retired) { + expect(payloads.responseData.settle).toBeUndefined(); + expect(payloads.result.settle).toBeUndefined(); + expect(sessionStore.lookup(address)).toEqual(successor); + expect(successor?.session.snapshot).toBeUndefined(); + } else { + expect(payloads.responseData.settle).toMatchObject({ refsGeneration: 3, settled: true }); + } +}); + +test.each([ + [false, false], + [false, true], + [true, false], + [true, true], +])( + 'point-touch publication after a held frame probe, retired=%s, fails=%s', + async (retired, fails) => { + const sessionStore = makeSessionStore(); + const address = 'cwd:held-touch-response:default'; + const session = makeSession('default'); + session.snapshot = { + nodes: attachRefs([{ index: 0, type: 'Button', label: 'Continue' }]), + createdAt: Date.now(), + backend: 'xctest', + }; + session.snapshotGeneration = 3; + installTestScreenRecording(session); + const ref = sessionStore.publish(address, session); + let startProbe!: () => void; + let releaseProbe!: () => void; + const probing = new Promise((resolve) => { + startProbe = resolve; + }); + const released = new Promise((resolve) => { + releaseProbe = resolve; + }); + const result: PressCommandResult = { + kind: 'point', + point: { x: 10, y: 20 }, + settle: { + settled: true, + waitedMs: 25, + captures: 2, + quietMs: 25, + timeoutMs: 2000, + diff: { + summary: { additions: 1, removals: 0, unchanged: 0 }, + lines: [{ kind: 'added', text: 'Continue', ref: 'e1' }], + }, + }, + }; + const logPath = path.join(mkdtempForTestSync('held-point-'), 'request.log'); + const running = withDiagnosticsScope( + { command: 'press', session: address, logPath, debug: true }, + async () => { + const payloads = await buildTargetedTouchResponsePayloads({ + params: { + createCommandSurface: testCreateCommandSurface, + req: { + token: 't', + command: 'press', + positionals: ['10', '20'], + session: 'default', + flags: {}, + }, + sessionName: address, + sessionRef: ref, + sessionStore, + contextFromFlags, + platformServices: daemonPlatformServicesFixture(), + captureSnapshotForSession: async () => { + startProbe(); + await released; + if (fails) throw new Error('frame capture failed'); + return sessionStore.requireCurrent(ref).snapshot!; + }, + }, + result, + staleRefsWarning: undefined, + extra: {}, + }); + flushDiagnosticsToSessionFile({ force: true }); + return payloads; + }, + ); + await probing; + let successor; + if (retired) { + sessionStore.retire(ref); + successor = sessionStore.publish(address, makeSession('default')); + } + releaseProbe(); + const payloads = await running; + const diagnostics = fs.existsSync(logPath) ? fs.readFileSync(logPath, 'utf8') : ''; + expect(diagnostics.includes('touch_reference_frame_resolve_failed')).toBe(!retired && fails); + expect(payloads.responseData.x).toBe(10); + if (retired) { + expect(payloads.responseData.settle).toBeUndefined(); + expect(payloads.result.settle).toBeUndefined(); + expect(sessionStore.lookup(address)).toEqual(successor); + expect(successor?.session.snapshot).toBeUndefined(); + } else { + expect(payloads.responseData.settle).toMatchObject({ refsGeneration: 3, settled: true }); + } + }, +); + +test('the response builder reports the resolved wait and keeps the prior warning', () => { + const { responseData, result } = buildInteractionResponseData({ + source: { kind: 'runtime', result: WAITED_SELECTOR_RESULT }, + referenceFrame: undefined, + staleRefsWarning: 'stale refs', + }); + + expect(responseData.readiness).toEqual({ polls: 3, waitedMs: 400 }); + expect(responseData.warning).toBe('earlier warning stale refs'); + expect(result.readiness).toBeUndefined(); +}); + +test('the response builder omits readiness when nothing waited', () => { + const { responseData } = buildInteractionResponseData({ + source: { kind: 'runtime', result: selectorResult() }, + referenceFrame: undefined, + }); + + expect('readiness' in responseData).toBe(false); +}); + +test('an already retired coordinate touch skips its frame probe without a warning', async () => { + const sessionStore = makeSessionStore(); + const ref = sessionStore.publish('retired-point', makeSession('retired-point')); + sessionStore.retire(ref); + const capture = vi.fn(); + const logPath = path.join(mkdtempForTestSync('retired-point-'), 'request.log'); + await withDiagnosticsScope( + { command: 'click', session: ref.address, logPath, debug: true }, + async () => { + const payloads = await buildTargetedTouchResponsePayloads({ + params: { + createCommandSurface: testCreateCommandSurface, + req: { token: 't', command: 'click', positionals: ['1', '2'], session: ref.address }, + sessionName: ref.address, + sessionRef: ref, + sessionStore, + contextFromFlags, + platformServices: daemonPlatformServicesFixture(), + captureSnapshotForSession: capture, + }, + result: { kind: 'point', point: { x: 1, y: 2 } }, + staleRefsWarning: undefined, + extra: {}, + }); + expect(payloads.responseData).toMatchObject({ x: 1, y: 2 }); + flushDiagnosticsToSessionFile({ force: true }); + }, + ); + expect(capture).not.toHaveBeenCalled(); + expect(fs.existsSync(logPath) ? fs.readFileSync(logPath, 'utf8') : '').not.toContain( + 'touch_reference_frame_resolve_failed', + ); +}); diff --git a/src/daemon/interaction/internal/__tests__/interaction-touch-targets.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-touch-targets.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-touch-targets.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-touch-targets.test.ts diff --git a/src/daemon/interaction/internal/__tests__/interaction-type-android-readiness.test.ts b/packages/daemon/src/interaction/internal/__tests__/interaction-type-android-readiness.test.ts similarity index 100% rename from src/daemon/interaction/internal/__tests__/interaction-type-android-readiness.test.ts rename to packages/daemon/src/interaction/internal/__tests__/interaction-type-android-readiness.test.ts diff --git a/src/daemon/interaction/internal/find-match-ranking.ts b/packages/daemon/src/interaction/internal/find-match-ranking.ts similarity index 100% rename from src/daemon/interaction/internal/find-match-ranking.ts rename to packages/daemon/src/interaction/internal/find-match-ranking.ts diff --git a/src/daemon/interaction/internal/find-match-resolution.ts b/packages/daemon/src/interaction/internal/find-match-resolution.ts similarity index 100% rename from src/daemon/interaction/internal/find-match-resolution.ts rename to packages/daemon/src/interaction/internal/find-match-resolution.ts diff --git a/src/daemon/interaction/internal/find-target-capture.ts b/packages/daemon/src/interaction/internal/find-target-capture.ts similarity index 100% rename from src/daemon/interaction/internal/find-target-capture.ts rename to packages/daemon/src/interaction/internal/find-target-capture.ts diff --git a/src/daemon/interaction/internal/find.ts b/packages/daemon/src/interaction/internal/find.ts similarity index 100% rename from src/daemon/interaction/internal/find.ts rename to packages/daemon/src/interaction/internal/find.ts diff --git a/src/daemon/interaction/internal/interaction-android-escape.ts b/packages/daemon/src/interaction/internal/interaction-android-escape.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-android-escape.ts rename to packages/daemon/src/interaction/internal/interaction-android-escape.ts diff --git a/src/daemon/interaction/internal/interaction-common.ts b/packages/daemon/src/interaction/internal/interaction-common.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-common.ts rename to packages/daemon/src/interaction/internal/interaction-common.ts diff --git a/src/daemon/interaction/internal/interaction-flags.ts b/packages/daemon/src/interaction/internal/interaction-flags.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-flags.ts rename to packages/daemon/src/interaction/internal/interaction-flags.ts diff --git a/src/daemon/interaction/internal/interaction-gesture-response.ts b/packages/daemon/src/interaction/internal/interaction-gesture-response.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-gesture-response.ts rename to packages/daemon/src/interaction/internal/interaction-gesture-response.ts diff --git a/src/daemon/interaction/internal/interaction-gesture.ts b/packages/daemon/src/interaction/internal/interaction-gesture.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-gesture.ts rename to packages/daemon/src/interaction/internal/interaction-gesture.ts diff --git a/src/daemon/interaction/internal/interaction-ios-tap-outcome.ts b/packages/daemon/src/interaction/internal/interaction-ios-tap-outcome.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-ios-tap-outcome.ts rename to packages/daemon/src/interaction/internal/interaction-ios-tap-outcome.ts diff --git a/src/daemon/interaction/internal/interaction-recorded-input.ts b/packages/daemon/src/interaction/internal/interaction-recorded-input.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-recorded-input.ts rename to packages/daemon/src/interaction/internal/interaction-recorded-input.ts diff --git a/src/daemon/interaction/internal/interaction-ref-policy.ts b/packages/daemon/src/interaction/internal/interaction-ref-policy.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-ref-policy.ts rename to packages/daemon/src/interaction/internal/interaction-ref-policy.ts diff --git a/src/daemon/interaction/internal/interaction-response-data-transform.ts b/packages/daemon/src/interaction/internal/interaction-response-data-transform.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-response-data-transform.ts rename to packages/daemon/src/interaction/internal/interaction-response-data-transform.ts diff --git a/src/daemon/interaction/internal/interaction-response.ts b/packages/daemon/src/interaction/internal/interaction-response.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-response.ts rename to packages/daemon/src/interaction/internal/interaction-response.ts diff --git a/src/daemon/interaction/internal/interaction-runtime.ts b/packages/daemon/src/interaction/internal/interaction-runtime.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-runtime.ts rename to packages/daemon/src/interaction/internal/interaction-runtime.ts diff --git a/src/daemon/interaction/internal/interaction-session.ts b/packages/daemon/src/interaction/internal/interaction-session.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-session.ts rename to packages/daemon/src/interaction/internal/interaction-session.ts diff --git a/src/daemon/interaction/internal/interaction-snapshot.ts b/packages/daemon/src/interaction/internal/interaction-snapshot.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-snapshot.ts rename to packages/daemon/src/interaction/internal/interaction-snapshot.ts diff --git a/src/daemon/interaction/internal/interaction-targeting.ts b/packages/daemon/src/interaction/internal/interaction-targeting.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-targeting.ts rename to packages/daemon/src/interaction/internal/interaction-targeting.ts diff --git a/src/daemon/interaction/internal/interaction-touch-android-freshness.ts b/packages/daemon/src/interaction/internal/interaction-touch-android-freshness.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-android-freshness.ts rename to packages/daemon/src/interaction/internal/interaction-touch-android-freshness.ts diff --git a/src/daemon/interaction/internal/interaction-touch-android-readiness.ts b/packages/daemon/src/interaction/internal/interaction-touch-android-readiness.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-android-readiness.ts rename to packages/daemon/src/interaction/internal/interaction-touch-android-readiness.ts diff --git a/src/daemon/interaction/internal/interaction-touch-direct-ios-eligibility.ts b/packages/daemon/src/interaction/internal/interaction-touch-direct-ios-eligibility.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-direct-ios-eligibility.ts rename to packages/daemon/src/interaction/internal/interaction-touch-direct-ios-eligibility.ts diff --git a/src/daemon/interaction/internal/interaction-touch-direct-ios.ts b/packages/daemon/src/interaction/internal/interaction-touch-direct-ios.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-direct-ios.ts rename to packages/daemon/src/interaction/internal/interaction-touch-direct-ios.ts diff --git a/src/daemon/interaction/internal/interaction-touch-fill.ts b/packages/daemon/src/interaction/internal/interaction-touch-fill.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-fill.ts rename to packages/daemon/src/interaction/internal/interaction-touch-fill.ts diff --git a/src/daemon/interaction/internal/interaction-touch-payload.ts b/packages/daemon/src/interaction/internal/interaction-touch-payload.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-payload.ts rename to packages/daemon/src/interaction/internal/interaction-touch-payload.ts diff --git a/src/daemon/interaction/internal/interaction-touch-policy.ts b/packages/daemon/src/interaction/internal/interaction-touch-policy.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-policy.ts rename to packages/daemon/src/interaction/internal/interaction-touch-policy.ts diff --git a/src/daemon/interaction/internal/interaction-touch-prepare.ts b/packages/daemon/src/interaction/internal/interaction-touch-prepare.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-prepare.ts rename to packages/daemon/src/interaction/internal/interaction-touch-prepare.ts diff --git a/src/daemon/interaction/internal/interaction-touch-press-admission.ts b/packages/daemon/src/interaction/internal/interaction-touch-press-admission.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-press-admission.ts rename to packages/daemon/src/interaction/internal/interaction-touch-press-admission.ts diff --git a/src/daemon/interaction/internal/interaction-touch-press.ts b/packages/daemon/src/interaction/internal/interaction-touch-press.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-press.ts rename to packages/daemon/src/interaction/internal/interaction-touch-press.ts diff --git a/src/daemon/interaction/internal/interaction-touch-reference-frame.ts b/packages/daemon/src/interaction/internal/interaction-touch-reference-frame.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-reference-frame.ts rename to packages/daemon/src/interaction/internal/interaction-touch-reference-frame.ts diff --git a/src/daemon/interaction/internal/interaction-touch-response.ts b/packages/daemon/src/interaction/internal/interaction-touch-response.ts similarity index 99% rename from src/daemon/interaction/internal/interaction-touch-response.ts rename to packages/daemon/src/interaction/internal/interaction-touch-response.ts index 741da1b325..3ed955f893 100644 --- a/src/daemon/interaction/internal/interaction-touch-response.ts +++ b/packages/daemon/src/interaction/internal/interaction-touch-response.ts @@ -155,7 +155,7 @@ export function buildInteractionResponseData(params: { extra?: Record; /** * Staleness warning for the consumed `@ref` argument (ADR 0014), resolved by - * `resolveRefStalenessWarning` (src/daemon/session-snapshot.ts): the + * `resolveRefStalenessWarning` (packages/daemon/src/session-snapshot.ts): the * STALE_SNAPSHOT_REFS_WARNING for a plain ref once the frame has expired, or * the precise pinned-generation warning for a `@e12~s3` ref whose epoch no * longer matches the frame. Stale mutations are rejected before reaching this diff --git a/src/daemon/interaction/internal/interaction-touch-runtime.ts b/packages/daemon/src/interaction/internal/interaction-touch-runtime.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-runtime.ts rename to packages/daemon/src/interaction/internal/interaction-touch-runtime.ts diff --git a/src/daemon/interaction/internal/interaction-touch-targets.ts b/packages/daemon/src/interaction/internal/interaction-touch-targets.ts similarity index 100% rename from src/daemon/interaction/internal/interaction-touch-targets.ts rename to packages/daemon/src/interaction/internal/interaction-touch-targets.ts diff --git a/src/daemon/interaction/internal/interaction.ts b/packages/daemon/src/interaction/internal/interaction.ts similarity index 100% rename from src/daemon/interaction/internal/interaction.ts rename to packages/daemon/src/interaction/internal/interaction.ts diff --git a/src/daemon/interaction/internal/types.ts b/packages/daemon/src/interaction/internal/types.ts similarity index 100% rename from src/daemon/interaction/internal/types.ts rename to packages/daemon/src/interaction/internal/types.ts diff --git a/src/daemon/interactor-resolution.ts b/packages/daemon/src/interactor-resolution.ts similarity index 100% rename from src/daemon/interactor-resolution.ts rename to packages/daemon/src/interactor-resolution.ts diff --git a/src/daemon/internal-observation.ts b/packages/daemon/src/internal-observation.ts similarity index 100% rename from src/daemon/internal-observation.ts rename to packages/daemon/src/internal-observation.ts diff --git a/src/daemon/ios-app-session-hint.test.ts b/packages/daemon/src/ios-app-session-hint.test.ts similarity index 100% rename from src/daemon/ios-app-session-hint.test.ts rename to packages/daemon/src/ios-app-session-hint.test.ts diff --git a/src/daemon/ios-app-session-hint.ts b/packages/daemon/src/ios-app-session-hint.ts similarity index 100% rename from src/daemon/ios-app-session-hint.ts rename to packages/daemon/src/ios-app-session-hint.ts diff --git a/src/daemon/keyboard-runtime.ts b/packages/daemon/src/keyboard-runtime.ts similarity index 100% rename from src/daemon/keyboard-runtime.ts rename to packages/daemon/src/keyboard-runtime.ts diff --git a/src/daemon/lease-context.ts b/packages/daemon/src/lease-context.ts similarity index 100% rename from src/daemon/lease-context.ts rename to packages/daemon/src/lease-context.ts diff --git a/src/daemon/lease-in-flight-work.ts b/packages/daemon/src/lease-in-flight-work.ts similarity index 100% rename from src/daemon/lease-in-flight-work.ts rename to packages/daemon/src/lease-in-flight-work.ts diff --git a/src/daemon/lease-lifecycle.ts b/packages/daemon/src/lease-lifecycle.ts similarity index 100% rename from src/daemon/lease-lifecycle.ts rename to packages/daemon/src/lease-lifecycle.ts diff --git a/src/daemon/lease-registry-scope.ts b/packages/daemon/src/lease-registry-scope.ts similarity index 100% rename from src/daemon/lease-registry-scope.ts rename to packages/daemon/src/lease-registry-scope.ts diff --git a/src/daemon/lease-registry.ts b/packages/daemon/src/lease-registry.ts similarity index 100% rename from src/daemon/lease-registry.ts rename to packages/daemon/src/lease-registry.ts diff --git a/src/daemon/macos-app-lease.ts b/packages/daemon/src/macos-app-lease.ts similarity index 100% rename from src/daemon/macos-app-lease.ts rename to packages/daemon/src/macos-app-lease.ts diff --git a/src/daemon/managed-session-artifact-path.ts b/packages/daemon/src/managed-session-artifact-path.ts similarity index 100% rename from src/daemon/managed-session-artifact-path.ts rename to packages/daemon/src/managed-session-artifact-path.ts diff --git a/src/daemon/materialized-path-registry.ts b/packages/daemon/src/materialized-path-registry.ts similarity index 100% rename from src/daemon/materialized-path-registry.ts rename to packages/daemon/src/materialized-path-registry.ts diff --git a/src/daemon/offscreen-target-probe.ts b/packages/daemon/src/offscreen-target-probe.ts similarity index 100% rename from src/daemon/offscreen-target-probe.ts rename to packages/daemon/src/offscreen-target-probe.ts diff --git a/src/daemon/open-device-contention-wait.ts b/packages/daemon/src/open-device-contention-wait.ts similarity index 100% rename from src/daemon/open-device-contention-wait.ts rename to packages/daemon/src/open-device-contention-wait.ts diff --git a/src/daemon/orientation-runtime.ts b/packages/daemon/src/orientation-runtime.ts similarity index 100% rename from src/daemon/orientation-runtime.ts rename to packages/daemon/src/orientation-runtime.ts diff --git a/src/daemon/payload-input.ts b/packages/daemon/src/payload-input.ts similarity index 100% rename from src/daemon/payload-input.ts rename to packages/daemon/src/payload-input.ts diff --git a/src/daemon/platform-owner-lifecycle.ts b/packages/daemon/src/platform-owner-lifecycle.ts similarity index 100% rename from src/daemon/platform-owner-lifecycle.ts rename to packages/daemon/src/platform-owner-lifecycle.ts diff --git a/src/daemon/platform-request-scope.ts b/packages/daemon/src/platform-request-scope.ts similarity index 100% rename from src/daemon/platform-request-scope.ts rename to packages/daemon/src/platform-request-scope.ts diff --git a/src/daemon/platform-resource-cleanup.ts b/packages/daemon/src/platform-resource-cleanup.ts similarity index 100% rename from src/daemon/platform-resource-cleanup.ts rename to packages/daemon/src/platform-resource-cleanup.ts diff --git a/src/daemon/platform-services.ts b/packages/daemon/src/platform-services.ts similarity index 100% rename from src/daemon/platform-services.ts rename to packages/daemon/src/platform-services.ts diff --git a/src/daemon/provider-device-admission.ts b/packages/daemon/src/provider-device-admission.ts similarity index 100% rename from src/daemon/provider-device-admission.ts rename to packages/daemon/src/provider-device-admission.ts diff --git a/src/daemon/provider-lease-expiry.ts b/packages/daemon/src/provider-lease-expiry.ts similarity index 100% rename from src/daemon/provider-lease-expiry.ts rename to packages/daemon/src/provider-lease-expiry.ts diff --git a/src/daemon/provider-session-ownership.ts b/packages/daemon/src/provider-session-ownership.ts similarity index 100% rename from src/daemon/provider-session-ownership.ts rename to packages/daemon/src/provider-session-ownership.ts diff --git a/src/daemon/recording-gesture-events.ts b/packages/daemon/src/recording-gesture-events.ts similarity index 100% rename from src/daemon/recording-gesture-events.ts rename to packages/daemon/src/recording-gesture-events.ts diff --git a/src/daemon/recording-gestures.ts b/packages/daemon/src/recording-gestures.ts similarity index 100% rename from src/daemon/recording-gestures.ts rename to packages/daemon/src/recording-gestures.ts diff --git a/src/daemon/recording-timing.ts b/packages/daemon/src/recording-timing.ts similarity index 100% rename from src/daemon/recording-timing.ts rename to packages/daemon/src/recording-timing.ts diff --git a/src/daemon/recording-values.ts b/packages/daemon/src/recording-values.ts similarity index 100% rename from src/daemon/recording-values.ts rename to packages/daemon/src/recording-values.ts diff --git a/src/daemon/ref-frame-slot.ts b/packages/daemon/src/ref-frame-slot.ts similarity index 100% rename from src/daemon/ref-frame-slot.ts rename to packages/daemon/src/ref-frame-slot.ts diff --git a/src/daemon/ref-frame.ts b/packages/daemon/src/ref-frame.ts similarity index 100% rename from src/daemon/ref-frame.ts rename to packages/daemon/src/ref-frame.ts diff --git a/src/daemon/ref-positionals.ts b/packages/daemon/src/ref-positionals.ts similarity index 100% rename from src/daemon/ref-positionals.ts rename to packages/daemon/src/ref-positionals.ts diff --git a/src/daemon/ref-snapshot-flag-policy.ts b/packages/daemon/src/ref-snapshot-flag-policy.ts similarity index 100% rename from src/daemon/ref-snapshot-flag-policy.ts rename to packages/daemon/src/ref-snapshot-flag-policy.ts diff --git a/src/daemon/replay-device-selection.ts b/packages/daemon/src/replay-device-selection.ts similarity index 100% rename from src/daemon/replay-device-selection.ts rename to packages/daemon/src/replay-device-selection.ts diff --git a/src/daemon/request-admission.ts b/packages/daemon/src/request-admission.ts similarity index 100% rename from src/daemon/request-admission.ts rename to packages/daemon/src/request-admission.ts diff --git a/src/daemon/request-binding.ts b/packages/daemon/src/request-binding.ts similarity index 100% rename from src/daemon/request-binding.ts rename to packages/daemon/src/request-binding.ts diff --git a/src/daemon/request-diagnostics-http.ts b/packages/daemon/src/request-diagnostics-http.ts similarity index 100% rename from src/daemon/request-diagnostics-http.ts rename to packages/daemon/src/request-diagnostics-http.ts diff --git a/src/daemon/request-dispatch-disclosure.ts b/packages/daemon/src/request-dispatch-disclosure.ts similarity index 100% rename from src/daemon/request-dispatch-disclosure.ts rename to packages/daemon/src/request-dispatch-disclosure.ts diff --git a/src/daemon/request-dispatch-ledger.ts b/packages/daemon/src/request-dispatch-ledger.ts similarity index 100% rename from src/daemon/request-dispatch-ledger.ts rename to packages/daemon/src/request-dispatch-ledger.ts diff --git a/src/daemon/request-execution-locks.ts b/packages/daemon/src/request-execution-locks.ts similarity index 100% rename from src/daemon/request-execution-locks.ts rename to packages/daemon/src/request-execution-locks.ts diff --git a/src/daemon/request-execution-scope.ts b/packages/daemon/src/request-execution-scope.ts similarity index 100% rename from src/daemon/request-execution-scope.ts rename to packages/daemon/src/request-execution-scope.ts diff --git a/src/daemon/request-finalization.ts b/packages/daemon/src/request-finalization.ts similarity index 100% rename from src/daemon/request-finalization.ts rename to packages/daemon/src/request-finalization.ts diff --git a/src/daemon/request-generic-dispatch.ts b/packages/daemon/src/request-generic-dispatch.ts similarity index 100% rename from src/daemon/request-generic-dispatch.ts rename to packages/daemon/src/request-generic-dispatch.ts diff --git a/src/daemon/request-handler-chain.ts b/packages/daemon/src/request-handler-chain.ts similarity index 100% rename from src/daemon/request-handler-chain.ts rename to packages/daemon/src/request-handler-chain.ts diff --git a/src/daemon/request-lease-work.ts b/packages/daemon/src/request-lease-work.ts similarity index 100% rename from src/daemon/request-lease-work.ts rename to packages/daemon/src/request-lease-work.ts diff --git a/src/daemon/request-lock-policy.ts b/packages/daemon/src/request-lock-policy.ts similarity index 100% rename from src/daemon/request-lock-policy.ts rename to packages/daemon/src/request-lock-policy.ts diff --git a/src/daemon/request-platform-provider-context.ts b/packages/daemon/src/request-platform-provider-context.ts similarity index 100% rename from src/daemon/request-platform-provider-context.ts rename to packages/daemon/src/request-platform-provider-context.ts diff --git a/src/daemon/request-recording-health.ts b/packages/daemon/src/request-recording-health.ts similarity index 100% rename from src/daemon/request-recording-health.ts rename to packages/daemon/src/request-recording-health.ts diff --git a/src/daemon/request-router.ts b/packages/daemon/src/request-router.ts similarity index 100% rename from src/daemon/request-router.ts rename to packages/daemon/src/request-router.ts diff --git a/src/daemon/request-runtime-binding.ts b/packages/daemon/src/request-runtime-binding.ts similarity index 100% rename from src/daemon/request-runtime-binding.ts rename to packages/daemon/src/request-runtime-binding.ts diff --git a/src/daemon/request-save-script-policy.ts b/packages/daemon/src/request-save-script-policy.ts similarity index 100% rename from src/daemon/request-save-script-policy.ts rename to packages/daemon/src/request-save-script-policy.ts diff --git a/src/daemon/response-views.ts b/packages/daemon/src/response-views.ts similarity index 100% rename from src/daemon/response-views.ts rename to packages/daemon/src/response-views.ts diff --git a/src/daemon/resumable-upload-range.ts b/packages/daemon/src/resumable-upload-range.ts similarity index 100% rename from src/daemon/resumable-upload-range.ts rename to packages/daemon/src/resumable-upload-range.ts diff --git a/src/daemon/resumable-upload-transfer.ts b/packages/daemon/src/resumable-upload-transfer.ts similarity index 100% rename from src/daemon/resumable-upload-transfer.ts rename to packages/daemon/src/resumable-upload-transfer.ts diff --git a/src/daemon/resumable-upload.ts b/packages/daemon/src/resumable-upload.ts similarity index 100% rename from src/daemon/resumable-upload.ts rename to packages/daemon/src/resumable-upload.ts diff --git a/src/daemon/route-owner-files.ts b/packages/daemon/src/route-owner-files.ts similarity index 70% rename from src/daemon/route-owner-files.ts rename to packages/daemon/src/route-owner-files.ts index e8d7fc785d..f77f5fa1b3 100644 --- a/src/daemon/route-owner-files.ts +++ b/packages/daemon/src/route-owner-files.ts @@ -17,15 +17,15 @@ import type { DaemonCommandRoute } from './request-handler-chain.ts'; * each path still points at the module that route's loader imports. */ const DAEMON_ROUTE_OWNER_FILES = { - humanControl: 'src/daemon/handlers/human-control.ts', - lease: 'src/daemon/handlers/lease.ts', - session: 'src/daemon/handlers/session.ts', - snapshot: 'src/daemon/handlers/snapshot.ts', - reactNative: 'src/daemon/handlers/react-native.ts', - recordTrace: 'src/daemon/handlers/record-trace.ts', - find: 'src/daemon/interaction/index.ts', - interaction: 'src/daemon/interaction/index.ts', - generic: 'src/daemon/request-generic-dispatch.ts', + humanControl: 'packages/daemon/src/handlers/human-control.ts', + lease: 'packages/daemon/src/handlers/lease.ts', + session: 'packages/daemon/src/handlers/session.ts', + snapshot: 'packages/daemon/src/handlers/snapshot.ts', + reactNative: 'packages/daemon/src/handlers/react-native.ts', + recordTrace: 'packages/daemon/src/handlers/record-trace.ts', + find: 'packages/daemon/src/interaction/index.ts', + interaction: 'packages/daemon/src/interaction/index.ts', + generic: 'packages/daemon/src/request-generic-dispatch.ts', } as const satisfies Record; export function getDaemonRouteOwnerFiles(): Record { diff --git a/src/daemon/runtime-admission.ts b/packages/daemon/src/runtime-admission.ts similarity index 100% rename from src/daemon/runtime-admission.ts rename to packages/daemon/src/runtime-admission.ts diff --git a/src/daemon/runtime-artifacts.ts b/packages/daemon/src/runtime-artifacts.ts similarity index 100% rename from src/daemon/runtime-artifacts.ts rename to packages/daemon/src/runtime-artifacts.ts diff --git a/src/daemon/runtime-operation-effects.ts b/packages/daemon/src/runtime-operation-effects.ts similarity index 100% rename from src/daemon/runtime-operation-effects.ts rename to packages/daemon/src/runtime-operation-effects.ts diff --git a/src/daemon/runtime-policy.ts b/packages/daemon/src/runtime-policy.ts similarity index 100% rename from src/daemon/runtime-policy.ts rename to packages/daemon/src/runtime-policy.ts diff --git a/src/daemon/runtime-session.ts b/packages/daemon/src/runtime-session.ts similarity index 100% rename from src/daemon/runtime-session.ts rename to packages/daemon/src/runtime-session.ts diff --git a/src/daemon/screenshot-crop-target.ts b/packages/daemon/src/screenshot-crop-target.ts similarity index 100% rename from src/daemon/screenshot-crop-target.ts rename to packages/daemon/src/screenshot-crop-target.ts diff --git a/src/daemon/screenshot-crop.ts b/packages/daemon/src/screenshot-crop.ts similarity index 100% rename from src/daemon/screenshot-crop.ts rename to packages/daemon/src/screenshot-crop.ts diff --git a/src/daemon/screenshot-runtime-binding.ts b/packages/daemon/src/screenshot-runtime-binding.ts similarity index 100% rename from src/daemon/screenshot-runtime-binding.ts rename to packages/daemon/src/screenshot-runtime-binding.ts diff --git a/src/daemon/screenshot-runtime.ts b/packages/daemon/src/screenshot-runtime.ts similarity index 100% rename from src/daemon/screenshot-runtime.ts rename to packages/daemon/src/screenshot-runtime.ts diff --git a/src/daemon/scroll-movement.ts b/packages/daemon/src/scroll-movement.ts similarity index 100% rename from src/daemon/scroll-movement.ts rename to packages/daemon/src/scroll-movement.ts diff --git a/src/daemon/scroll-runtime.ts b/packages/daemon/src/scroll-runtime.ts similarity index 100% rename from src/daemon/scroll-runtime.ts rename to packages/daemon/src/scroll-runtime.ts diff --git a/src/daemon/scroll-until.test.ts b/packages/daemon/src/scroll-until.test.ts similarity index 100% rename from src/daemon/scroll-until.test.ts rename to packages/daemon/src/scroll-until.test.ts diff --git a/src/daemon/scroll-until.ts b/packages/daemon/src/scroll-until.ts similarity index 100% rename from src/daemon/scroll-until.ts rename to packages/daemon/src/scroll-until.ts diff --git a/src/daemon/selector-capture-binding.ts b/packages/daemon/src/selector-capture-binding.ts similarity index 100% rename from src/daemon/selector-capture-binding.ts rename to packages/daemon/src/selector-capture-binding.ts diff --git a/src/daemon/selector-capture-runtime.ts b/packages/daemon/src/selector-capture-runtime.ts similarity index 100% rename from src/daemon/selector-capture-runtime.ts rename to packages/daemon/src/selector-capture-runtime.ts diff --git a/src/daemon/selector-match-errors.ts b/packages/daemon/src/selector-match-errors.ts similarity index 100% rename from src/daemon/selector-match-errors.ts rename to packages/daemon/src/selector-match-errors.ts diff --git a/src/daemon/selector-operation-binding.ts b/packages/daemon/src/selector-operation-binding.ts similarity index 100% rename from src/daemon/selector-operation-binding.ts rename to packages/daemon/src/selector-operation-binding.ts diff --git a/src/daemon/selector-recording.ts b/packages/daemon/src/selector-recording.ts similarity index 100% rename from src/daemon/selector-recording.ts rename to packages/daemon/src/selector-recording.ts diff --git a/src/daemon/selector-runtime-backend.ts b/packages/daemon/src/selector-runtime-backend.ts similarity index 100% rename from src/daemon/selector-runtime-backend.ts rename to packages/daemon/src/selector-runtime-backend.ts diff --git a/src/daemon/selector-runtime.ts b/packages/daemon/src/selector-runtime.ts similarity index 100% rename from src/daemon/selector-runtime.ts rename to packages/daemon/src/selector-runtime.ts diff --git a/src/daemon/selector-text-runtime.ts b/packages/daemon/src/selector-text-runtime.ts similarity index 100% rename from src/daemon/selector-text-runtime.ts rename to packages/daemon/src/selector-text-runtime.ts diff --git a/src/daemon/server/daemon-idle-reap.test.ts b/packages/daemon/src/server/daemon-idle-reap.test.ts similarity index 100% rename from src/daemon/server/daemon-idle-reap.test.ts rename to packages/daemon/src/server/daemon-idle-reap.test.ts diff --git a/src/daemon/server/daemon-idle-reap.ts b/packages/daemon/src/server/daemon-idle-reap.ts similarity index 100% rename from src/daemon/server/daemon-idle-reap.ts rename to packages/daemon/src/server/daemon-idle-reap.ts diff --git a/src/daemon/server/daemon-lease-finalizer.test.ts b/packages/daemon/src/server/daemon-lease-finalizer.test.ts similarity index 100% rename from src/daemon/server/daemon-lease-finalizer.test.ts rename to packages/daemon/src/server/daemon-lease-finalizer.test.ts diff --git a/src/daemon/server/daemon-lease-finalizer.ts b/packages/daemon/src/server/daemon-lease-finalizer.ts similarity index 100% rename from src/daemon/server/daemon-lease-finalizer.ts rename to packages/daemon/src/server/daemon-lease-finalizer.ts diff --git a/src/daemon/server/daemon-metadata-loss.test.ts b/packages/daemon/src/server/daemon-metadata-loss.test.ts similarity index 100% rename from src/daemon/server/daemon-metadata-loss.test.ts rename to packages/daemon/src/server/daemon-metadata-loss.test.ts diff --git a/src/daemon/server/daemon-metadata-loss.ts b/packages/daemon/src/server/daemon-metadata-loss.ts similarity index 100% rename from src/daemon/server/daemon-metadata-loss.ts rename to packages/daemon/src/server/daemon-metadata-loss.ts diff --git a/src/daemon/server/daemon-runtime-device-claims.test.ts b/packages/daemon/src/server/daemon-runtime-device-claims.test.ts similarity index 100% rename from src/daemon/server/daemon-runtime-device-claims.test.ts rename to packages/daemon/src/server/daemon-runtime-device-claims.test.ts diff --git a/src/daemon/server/daemon-runtime.ts b/packages/daemon/src/server/daemon-runtime.ts similarity index 100% rename from src/daemon/server/daemon-runtime.ts rename to packages/daemon/src/server/daemon-runtime.ts diff --git a/src/daemon/server/daemon-session-idle-expiry-scheduling.test.ts b/packages/daemon/src/server/daemon-session-idle-expiry-scheduling.test.ts similarity index 100% rename from src/daemon/server/daemon-session-idle-expiry-scheduling.test.ts rename to packages/daemon/src/server/daemon-session-idle-expiry-scheduling.test.ts diff --git a/src/daemon/server/daemon-session-idle-expiry.test.ts b/packages/daemon/src/server/daemon-session-idle-expiry.test.ts similarity index 100% rename from src/daemon/server/daemon-session-idle-expiry.test.ts rename to packages/daemon/src/server/daemon-session-idle-expiry.test.ts diff --git a/src/daemon/server/daemon-session-idle-expiry.ts b/packages/daemon/src/server/daemon-session-idle-expiry.ts similarity index 100% rename from src/daemon/server/daemon-session-idle-expiry.ts rename to packages/daemon/src/server/daemon-session-idle-expiry.ts diff --git a/src/daemon/server/daemon-shutdown-claims.test.ts b/packages/daemon/src/server/daemon-shutdown-claims.test.ts similarity index 100% rename from src/daemon/server/daemon-shutdown-claims.test.ts rename to packages/daemon/src/server/daemon-shutdown-claims.test.ts diff --git a/src/daemon/server/daemon-shutdown-claims.ts b/packages/daemon/src/server/daemon-shutdown-claims.ts similarity index 100% rename from src/daemon/server/daemon-shutdown-claims.ts rename to packages/daemon/src/server/daemon-shutdown-claims.ts diff --git a/src/daemon/server/http-authorization.test.ts b/packages/daemon/src/server/http-authorization.test.ts similarity index 100% rename from src/daemon/server/http-authorization.test.ts rename to packages/daemon/src/server/http-authorization.test.ts diff --git a/src/daemon/server/http-authorization.ts b/packages/daemon/src/server/http-authorization.ts similarity index 100% rename from src/daemon/server/http-authorization.ts rename to packages/daemon/src/server/http-authorization.ts diff --git a/src/daemon/server/http-instance-precondition.test.ts b/packages/daemon/src/server/http-instance-precondition.test.ts similarity index 100% rename from src/daemon/server/http-instance-precondition.test.ts rename to packages/daemon/src/server/http-instance-precondition.test.ts diff --git a/src/daemon/server/http-instance-precondition.ts b/packages/daemon/src/server/http-instance-precondition.ts similarity index 100% rename from src/daemon/server/http-instance-precondition.ts rename to packages/daemon/src/server/http-instance-precondition.ts diff --git a/src/daemon/server/http-rpc-envelope.ts b/packages/daemon/src/server/http-rpc-envelope.ts similarity index 100% rename from src/daemon/server/http-rpc-envelope.ts rename to packages/daemon/src/server/http-rpc-envelope.ts diff --git a/src/daemon/server/http-rpc-methods.ts b/packages/daemon/src/server/http-rpc-methods.ts similarity index 100% rename from src/daemon/server/http-rpc-methods.ts rename to packages/daemon/src/server/http-rpc-methods.ts diff --git a/src/daemon/server/http-server.ts b/packages/daemon/src/server/http-server.ts similarity index 100% rename from src/daemon/server/http-server.ts rename to packages/daemon/src/server/http-server.ts diff --git a/src/daemon/server/server-lifecycle.ts b/packages/daemon/src/server/server-lifecycle.ts similarity index 100% rename from src/daemon/server/server-lifecycle.ts rename to packages/daemon/src/server/server-lifecycle.ts diff --git a/src/daemon/server/server-shutdown.ts b/packages/daemon/src/server/server-shutdown.ts similarity index 100% rename from src/daemon/server/server-shutdown.ts rename to packages/daemon/src/server/server-shutdown.ts diff --git a/src/daemon/server/tenant-trust.ts b/packages/daemon/src/server/tenant-trust.ts similarity index 100% rename from src/daemon/server/tenant-trust.ts rename to packages/daemon/src/server/tenant-trust.ts diff --git a/src/daemon/server/transport.ts b/packages/daemon/src/server/transport.ts similarity index 100% rename from src/daemon/server/transport.ts rename to packages/daemon/src/server/transport.ts diff --git a/src/daemon/session-action-recorder.ts b/packages/daemon/src/session-action-recorder.ts similarity index 100% rename from src/daemon/session-action-recorder.ts rename to packages/daemon/src/session-action-recorder.ts diff --git a/src/daemon/session-artifact-paths.ts b/packages/daemon/src/session-artifact-paths.ts similarity index 100% rename from src/daemon/session-artifact-paths.ts rename to packages/daemon/src/session-artifact-paths.ts diff --git a/src/daemon/session-capture-binding.ts b/packages/daemon/src/session-capture-binding.ts similarity index 100% rename from src/daemon/session-capture-binding.ts rename to packages/daemon/src/session-capture-binding.ts diff --git a/src/daemon/session-device-resolution.ts b/packages/daemon/src/session-device-resolution.ts similarity index 100% rename from src/daemon/session-device-resolution.ts rename to packages/daemon/src/session-device-resolution.ts diff --git a/src/daemon/session-idle-expiry.ts b/packages/daemon/src/session-idle-expiry.ts similarity index 100% rename from src/daemon/session-idle-expiry.ts rename to packages/daemon/src/session-idle-expiry.ts diff --git a/src/daemon/session-idle-tombstone.test.ts b/packages/daemon/src/session-idle-tombstone.test.ts similarity index 100% rename from src/daemon/session-idle-tombstone.test.ts rename to packages/daemon/src/session-idle-tombstone.test.ts diff --git a/src/daemon/session-idle-tombstone.ts b/packages/daemon/src/session-idle-tombstone.ts similarity index 100% rename from src/daemon/session-idle-tombstone.ts rename to packages/daemon/src/session-idle-tombstone.ts diff --git a/src/daemon/session-lifecycle/__tests__/application.test.ts b/packages/daemon/src/session-lifecycle/__tests__/application.test.ts similarity index 100% rename from src/daemon/session-lifecycle/__tests__/application.test.ts rename to packages/daemon/src/session-lifecycle/__tests__/application.test.ts diff --git a/src/daemon/session-lifecycle/index.ts b/packages/daemon/src/session-lifecycle/index.ts similarity index 100% rename from src/daemon/session-lifecycle/index.ts rename to packages/daemon/src/session-lifecycle/index.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-capabilities-install-projection.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities-install-projection.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-capabilities-install-projection.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities-install-projection.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-capabilities.fixtures.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities.fixtures.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-capabilities.fixtures.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities.fixtures.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-capabilities.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-capabilities.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-cwd-scoped-resources.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-cwd-scoped-resources.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-cwd-scoped-resources.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-cwd-scoped-resources.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-error-precedence.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-error-precedence.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-error-precedence.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-error-precedence.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-lifecycle-runtime.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-lifecycle-runtime.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-lifecycle-runtime.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-lifecycle-runtime.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-resource-cleanup.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-resource-cleanup.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-resource-cleanup.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-resource-cleanup.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-save-script.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-save-script.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-save-script.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-save-script.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-script.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-script.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-script.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-script.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown-platform.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-shutdown-platform.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown-platform.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-shutdown-platform.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-devices-batch-runtime.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-devices-batch-runtime.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-devices-batch-runtime.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-devices-batch-runtime.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-inventory-appleos.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-appleos.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-inventory-appleos.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-appleos.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-inventory-apps-runtime.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-apps-runtime.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-inventory-apps-runtime.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-apps-runtime.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-inventory-harmonyos.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-harmonyos.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-inventory-harmonyos.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-harmonyos.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-inventory-scoped-paths.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-scoped-paths.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-inventory-scoped-paths.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-inventory-scoped-paths.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-device-in-use.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-device-in-use.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-device-in-use.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-device-in-use.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-execution-runtime.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-execution-runtime.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-execution-runtime.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-execution-runtime.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-existing.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-existing.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-existing.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-existing.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-foreground.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-foreground.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-foreground.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-foreground.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-runtime.fixtures.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-runtime.fixtures.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-runtime.fixtures.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-runtime.fixtures.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-runtime.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-runtime.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-runtime.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-runtime.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-state.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-state.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-state.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-state.test.ts diff --git a/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-surface.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-surface.test.ts new file mode 100644 index 0000000000..dc1e065ec6 --- /dev/null +++ b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-surface.test.ts @@ -0,0 +1,78 @@ +import { test } from 'vitest'; +import { buildOpenResult } from '../session-open-surface.ts'; +import { IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; +import assert from 'node:assert/strict'; + +test('buildOpenResult exposes the Vega serial without leaking an internal platform alias', () => { + const result = buildOpenResult({ + sessionName: 'vega-tv', + sessionStateDir: '/tmp/state', + runnerLogPath: '/tmp/runner.log', + requestLogPath: '/tmp/request.ndjson', + eventLogPath: '/tmp/events.ndjson', + appName: 'com.example.app.main', + surface: 'app', + device: { + platform: 'vega', + id: 'amazon-vvd', + name: 'Vega Virtual Device', + kind: 'emulator', + target: 'tv', + booted: true, + }, + runtimeHintCount: () => 0, + sessionReused: false, + }); + + assert.equal(result.platform, 'vega'); + assert.equal(result.serial, 'amazon-vvd'); + assert.equal(result.target, 'tv'); +}); + +test('buildOpenResult exposes typed device-selection evidence once at response level', () => { + const result = buildOpenResult({ + sessionName: 'ios-selection', + sessionStateDir: '/tmp/state', + runnerLogPath: '/tmp/runner.log', + requestLogPath: '/tmp/request.ndjson', + eventLogPath: '/tmp/events.ndjson', + surface: 'app', + device: IOS_SIMULATOR, + runtimeHintCount: () => 0, + sessionReused: false, + selection: { + device: IOS_SIMULATOR, + reason: 'single-booted-local', + source: 'local', + candidateCount: 1, + bootOccurred: false, + }, + }); + + assert.deepEqual(result.selection, { + reason: 'single-booted-local', + source: 'local', + candidateCount: 1, + bootOccurred: false, + }); +}); + +test('buildOpenResult reports an answered launch confirmation and omits one that never appeared', () => { + const base = { + sessionName: 'ios-launch-url', + sessionStateDir: '/tmp/state', + runnerLogPath: '/tmp/runner.log', + requestLogPath: '/tmp/request.ndjson', + eventLogPath: '/tmp/events.ndjson', + surface: 'app' as const, + device: IOS_SIMULATOR, + runtimeHintCount: () => 0, + sessionReused: false, + }; + + assert.equal( + buildOpenResult({ ...base, launchConfirmation: 'accepted' }).launchConfirmation, + 'accepted', + ); + assert.equal('launchConfirmation' in buildOpenResult(base), false); +}); diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-open-warnings.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-open-warnings.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-open-warnings.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-open-warnings.test.ts diff --git a/src/daemon/session-lifecycle/internal/__tests__/session-teardown-resources.test.ts b/packages/daemon/src/session-lifecycle/internal/__tests__/session-teardown-resources.test.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/__tests__/session-teardown-resources.test.ts rename to packages/daemon/src/session-lifecycle/internal/__tests__/session-teardown-resources.test.ts diff --git a/src/daemon/session-lifecycle/internal/inventory.ts b/packages/daemon/src/session-lifecycle/internal/inventory.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/inventory.ts rename to packages/daemon/src/session-lifecycle/internal/inventory.ts diff --git a/src/daemon/session-lifecycle/internal/session-close-lifecycle-teardown.ts b/packages/daemon/src/session-lifecycle/internal/session-close-lifecycle-teardown.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-close-lifecycle-teardown.ts rename to packages/daemon/src/session-lifecycle/internal/session-close-lifecycle-teardown.ts diff --git a/src/daemon/session-lifecycle/internal/session-close-runtime-admission.ts b/packages/daemon/src/session-lifecycle/internal/session-close-runtime-admission.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-close-runtime-admission.ts rename to packages/daemon/src/session-lifecycle/internal/session-close-runtime-admission.ts diff --git a/src/daemon/session-lifecycle/internal/session-close-script.ts b/packages/daemon/src/session-lifecycle/internal/session-close-script.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-close-script.ts rename to packages/daemon/src/session-lifecycle/internal/session-close-script.ts diff --git a/src/daemon/session-lifecycle/internal/session-close.ts b/packages/daemon/src/session-lifecycle/internal/session-close.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-close.ts rename to packages/daemon/src/session-lifecycle/internal/session-close.ts diff --git a/src/daemon/session-lifecycle/internal/session-open-execution.ts b/packages/daemon/src/session-lifecycle/internal/session-open-execution.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-open-execution.ts rename to packages/daemon/src/session-lifecycle/internal/session-open-execution.ts diff --git a/src/daemon/session-lifecycle/internal/session-open-foreground.ts b/packages/daemon/src/session-lifecycle/internal/session-open-foreground.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-open-foreground.ts rename to packages/daemon/src/session-lifecycle/internal/session-open-foreground.ts diff --git a/src/daemon/session-lifecycle/internal/session-open-prepare.ts b/packages/daemon/src/session-lifecycle/internal/session-open-prepare.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-open-prepare.ts rename to packages/daemon/src/session-lifecycle/internal/session-open-prepare.ts diff --git a/src/daemon/session-lifecycle/internal/session-open-state.ts b/packages/daemon/src/session-lifecycle/internal/session-open-state.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-open-state.ts rename to packages/daemon/src/session-lifecycle/internal/session-open-state.ts diff --git a/src/daemon/session-lifecycle/internal/session-open-surface.ts b/packages/daemon/src/session-lifecycle/internal/session-open-surface.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-open-surface.ts rename to packages/daemon/src/session-lifecycle/internal/session-open-surface.ts diff --git a/src/daemon/session-lifecycle/internal/session-open-warnings.ts b/packages/daemon/src/session-lifecycle/internal/session-open-warnings.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-open-warnings.ts rename to packages/daemon/src/session-lifecycle/internal/session-open-warnings.ts diff --git a/src/daemon/session-lifecycle/internal/session-open.ts b/packages/daemon/src/session-lifecycle/internal/session-open.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-open.ts rename to packages/daemon/src/session-lifecycle/internal/session-open.ts diff --git a/src/daemon/session-lifecycle/internal/session-startup-metrics.ts b/packages/daemon/src/session-lifecycle/internal/session-startup-metrics.ts similarity index 100% rename from src/daemon/session-lifecycle/internal/session-startup-metrics.ts rename to packages/daemon/src/session-lifecycle/internal/session-startup-metrics.ts diff --git a/src/daemon/session-observability/__tests__/application.test.ts b/packages/daemon/src/session-observability/__tests__/application.test.ts similarity index 100% rename from src/daemon/session-observability/__tests__/application.test.ts rename to packages/daemon/src/session-observability/__tests__/application.test.ts diff --git a/src/daemon/session-observability/__tests__/session-audio.coverage.ts b/packages/daemon/src/session-observability/__tests__/session-audio.coverage.ts similarity index 100% rename from src/daemon/session-observability/__tests__/session-audio.coverage.ts rename to packages/daemon/src/session-observability/__tests__/session-audio.coverage.ts diff --git a/src/daemon/session-observability/index.ts b/packages/daemon/src/session-observability/index.ts similarity index 100% rename from src/daemon/session-observability/index.ts rename to packages/daemon/src/session-observability/index.ts diff --git a/src/daemon/session-observability/internal/__tests__/network-runtime-harness.ts b/packages/daemon/src/session-observability/internal/__tests__/network-runtime-harness.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/network-runtime-harness.ts rename to packages/daemon/src/session-observability/internal/__tests__/network-runtime-harness.ts diff --git a/src/daemon/session-observability/internal/__tests__/session-audio.test.ts b/packages/daemon/src/session-observability/internal/__tests__/session-audio.test.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/session-audio.test.ts rename to packages/daemon/src/session-observability/internal/__tests__/session-audio.test.ts diff --git a/src/daemon/session-observability/internal/__tests__/session-logs.test.ts b/packages/daemon/src/session-observability/internal/__tests__/session-logs.test.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/session-logs.test.ts rename to packages/daemon/src/session-observability/internal/__tests__/session-logs.test.ts diff --git a/src/daemon/session-observability/internal/__tests__/session-network-runtime-parity-fixtures.ts b/packages/daemon/src/session-observability/internal/__tests__/session-network-runtime-parity-fixtures.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/session-network-runtime-parity-fixtures.ts rename to packages/daemon/src/session-observability/internal/__tests__/session-network-runtime-parity-fixtures.ts diff --git a/src/daemon/session-observability/internal/__tests__/session-network-runtime-parity.test.ts b/packages/daemon/src/session-observability/internal/__tests__/session-network-runtime-parity.test.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/session-network-runtime-parity.test.ts rename to packages/daemon/src/session-observability/internal/__tests__/session-network-runtime-parity.test.ts diff --git a/src/daemon/session-observability/internal/__tests__/session-network.test.ts b/packages/daemon/src/session-observability/internal/__tests__/session-network.test.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/session-network.test.ts rename to packages/daemon/src/session-observability/internal/__tests__/session-network.test.ts diff --git a/src/daemon/session-observability/internal/__tests__/session-observability.test.ts b/packages/daemon/src/session-observability/internal/__tests__/session-observability.test.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/session-observability.test.ts rename to packages/daemon/src/session-observability/internal/__tests__/session-observability.test.ts diff --git a/src/daemon/session-observability/internal/__tests__/session-perf-runtime.test.ts b/packages/daemon/src/session-observability/internal/__tests__/session-perf-runtime.test.ts similarity index 100% rename from src/daemon/session-observability/internal/__tests__/session-perf-runtime.test.ts rename to packages/daemon/src/session-observability/internal/__tests__/session-perf-runtime.test.ts diff --git a/src/daemon/session-observability/internal/session-audio.ts b/packages/daemon/src/session-observability/internal/session-audio.ts similarity index 100% rename from src/daemon/session-observability/internal/session-audio.ts rename to packages/daemon/src/session-observability/internal/session-audio.ts diff --git a/src/daemon/session-observability/internal/session-network.ts b/packages/daemon/src/session-observability/internal/session-network.ts similarity index 100% rename from src/daemon/session-observability/internal/session-network.ts rename to packages/daemon/src/session-observability/internal/session-network.ts diff --git a/src/daemon/session-observability/internal/session-observability.ts b/packages/daemon/src/session-observability/internal/session-observability.ts similarity index 100% rename from src/daemon/session-observability/internal/session-observability.ts rename to packages/daemon/src/session-observability/internal/session-observability.ts diff --git a/src/daemon/session-observability/internal/session-perf-runtime.ts b/packages/daemon/src/session-observability/internal/session-perf-runtime.ts similarity index 100% rename from src/daemon/session-observability/internal/session-perf-runtime.ts rename to packages/daemon/src/session-observability/internal/session-perf-runtime.ts diff --git a/src/daemon/session-recovery-hints.test.ts b/packages/daemon/src/session-recovery-hints.test.ts similarity index 100% rename from src/daemon/session-recovery-hints.test.ts rename to packages/daemon/src/session-recovery-hints.test.ts diff --git a/src/daemon/session-recovery-hints.ts b/packages/daemon/src/session-recovery-hints.ts similarity index 100% rename from src/daemon/session-recovery-hints.ts rename to packages/daemon/src/session-recovery-hints.ts diff --git a/src/daemon/session-replay-coordinator.ts b/packages/daemon/src/session-replay-coordinator.ts similarity index 100% rename from src/daemon/session-replay-coordinator.ts rename to packages/daemon/src/session-replay-coordinator.ts diff --git a/src/daemon/session-replay-transaction.ts b/packages/daemon/src/session-replay-transaction.ts similarity index 100% rename from src/daemon/session-replay-transaction.ts rename to packages/daemon/src/session-replay-transaction.ts diff --git a/src/daemon/session-routing.ts b/packages/daemon/src/session-routing.ts similarity index 100% rename from src/daemon/session-routing.ts rename to packages/daemon/src/session-routing.ts diff --git a/src/daemon/session-runtime-admission.ts b/packages/daemon/src/session-runtime-admission.ts similarity index 99% rename from src/daemon/session-runtime-admission.ts rename to packages/daemon/src/session-runtime-admission.ts index 20e0aa48e1..2d8b84750c 100644 --- a/src/daemon/session-runtime-admission.ts +++ b/packages/daemon/src/session-runtime-admission.ts @@ -73,7 +73,7 @@ let mintAdmission: ( * WeakMap keyed by the token's identity. A binder gets at the device and plan only through * `unwrapAdmittedRuntimePlan`, which refuses any object that was not minted here — including a * Proxy around a real token, which types as the token but is a different identity. What remains - * is a type assertion, which the cutover gate's manufactured-proof column rejects in src/daemon/. + * is a type assertion, which the cutover gate's manufactured-proof column rejects in packages/daemon/src/. * A facts-first binder that requires the token therefore enforces "admit before bind" — for this * device, for this plan — at the seam. */ diff --git a/src/daemon/session-runtime.ts b/packages/daemon/src/session-runtime.ts similarity index 100% rename from src/daemon/session-runtime.ts rename to packages/daemon/src/session-runtime.ts diff --git a/src/daemon/session-script-active-publication.ts b/packages/daemon/src/session-script-active-publication.ts similarity index 100% rename from src/daemon/session-script-active-publication.ts rename to packages/daemon/src/session-script-active-publication.ts diff --git a/src/daemon/session-script-publication-capability.ts b/packages/daemon/src/session-script-publication-capability.ts similarity index 100% rename from src/daemon/session-script-publication-capability.ts rename to packages/daemon/src/session-script-publication-capability.ts diff --git a/src/daemon/session-script-publication-state.ts b/packages/daemon/src/session-script-publication-state.ts similarity index 100% rename from src/daemon/session-script-publication-state.ts rename to packages/daemon/src/session-script-publication-state.ts diff --git a/src/daemon/session-script-writer.ts b/packages/daemon/src/session-script-writer.ts similarity index 100% rename from src/daemon/session-script-writer.ts rename to packages/daemon/src/session-script-writer.ts diff --git a/src/daemon/session-selector.ts b/packages/daemon/src/session-selector.ts similarity index 100% rename from src/daemon/session-selector.ts rename to packages/daemon/src/session-selector.ts diff --git a/src/daemon/session-snapshot-freshness.ts b/packages/daemon/src/session-snapshot-freshness.ts similarity index 100% rename from src/daemon/session-snapshot-freshness.ts rename to packages/daemon/src/session-snapshot-freshness.ts diff --git a/src/daemon/session-snapshot.ts b/packages/daemon/src/session-snapshot.ts similarity index 99% rename from src/daemon/session-snapshot.ts rename to packages/daemon/src/session-snapshot.ts index 503d35c840..a5178babf6 100644 --- a/src/daemon/session-snapshot.ts +++ b/packages/daemon/src/session-snapshot.ts @@ -22,7 +22,7 @@ export const STALE_SNAPSHOT_REFS_WARNING = * does NOT touch the ref frame: replacing the latest observation is an * operational read, so it never expires, reactivates, or reindexes the * authorized frame (ADR 0014). Frame lifetime is owned solely by - * `src/daemon/ref-frame.ts`; the partial-issuance writer below decides WHETHER to issue + * `packages/daemon/src/ref-frame.ts`; the partial-issuance writer below decides WHETHER to issue * and hands the transition there. */ export function setSessionSnapshot(session: SessionState, snapshot: SnapshotState): void { diff --git a/src/daemon/session-state.ts b/packages/daemon/src/session-state.ts similarity index 98% rename from src/daemon/session-state.ts rename to packages/daemon/src/session-state.ts index 9444108349..c3a50070d6 100644 --- a/src/daemon/session-state.ts +++ b/packages/daemon/src/session-state.ts @@ -200,7 +200,7 @@ export type SessionState = { * resolution, settle observation, system-modal probes) can arm the runner-side penalty * without any user-facing render — when the latch is not held, the first public * deferred verdict re-renders the warning once. Managed only through - * `src/daemon/snapshot-quality-latch.ts`: a genuine recovered render sets it, a healthy + * `packages/daemon/src/snapshot-quality-latch.ts`: a genuine recovered render sets it, a healthy * public verdict clears it, and an app switch supersedes it. */ recoveredSnapshotWarningLatch?: { appBundleId?: string }; @@ -290,7 +290,7 @@ export type SessionState = { * app-rendered echo of an already-authored literal. In-memory only for * this session's lifetime: never read by the script writer, the event * log, or diagnostics, and dropped with the session. Owned by - * `src/daemon/session-action-recorder.ts`. + * `packages/daemon/src/session-action-recorder.ts`. */ recordedFillLiterals?: Map; /** diff --git a/src/daemon/session-store.ts b/packages/daemon/src/session-store.ts similarity index 100% rename from src/daemon/session-store.ts rename to packages/daemon/src/session-store.ts diff --git a/src/daemon/session-teardown-budget.ts b/packages/daemon/src/session-teardown-budget.ts similarity index 100% rename from src/daemon/session-teardown-budget.ts rename to packages/daemon/src/session-teardown-budget.ts diff --git a/src/daemon/session-teardown.ts b/packages/daemon/src/session-teardown.ts similarity index 100% rename from src/daemon/session-teardown.ts rename to packages/daemon/src/session-teardown.ts diff --git a/src/daemon/session-tenant-scope.ts b/packages/daemon/src/session-tenant-scope.ts similarity index 100% rename from src/daemon/session-tenant-scope.ts rename to packages/daemon/src/session-tenant-scope.ts diff --git a/src/daemon/settle-observation-capture.ts b/packages/daemon/src/settle-observation-capture.ts similarity index 100% rename from src/daemon/settle-observation-capture.ts rename to packages/daemon/src/settle-observation-capture.ts diff --git a/src/daemon/snapshot-capture.ts b/packages/daemon/src/snapshot-capture.ts similarity index 100% rename from src/daemon/snapshot-capture.ts rename to packages/daemon/src/snapshot-capture.ts diff --git a/src/daemon/snapshot-command-runtime.ts b/packages/daemon/src/snapshot-command-runtime.ts similarity index 100% rename from src/daemon/snapshot-command-runtime.ts rename to packages/daemon/src/snapshot-command-runtime.ts diff --git a/src/daemon/snapshot-diff-runtime.ts b/packages/daemon/src/snapshot-diff-runtime.ts similarity index 100% rename from src/daemon/snapshot-diff-runtime.ts rename to packages/daemon/src/snapshot-diff-runtime.ts diff --git a/src/daemon/snapshot-interactor-capture.ts b/packages/daemon/src/snapshot-interactor-capture.ts similarity index 100% rename from src/daemon/snapshot-interactor-capture.ts rename to packages/daemon/src/snapshot-interactor-capture.ts diff --git a/src/daemon/snapshot-quality-latch.ts b/packages/daemon/src/snapshot-quality-latch.ts similarity index 100% rename from src/daemon/snapshot-quality-latch.ts rename to packages/daemon/src/snapshot-quality-latch.ts diff --git a/src/daemon/snapshot-runtime-binding.ts b/packages/daemon/src/snapshot-runtime-binding.ts similarity index 100% rename from src/daemon/snapshot-runtime-binding.ts rename to packages/daemon/src/snapshot-runtime-binding.ts diff --git a/src/daemon/snapshot-runtime-capture-input.ts b/packages/daemon/src/snapshot-runtime-capture-input.ts similarity index 100% rename from src/daemon/snapshot-runtime-capture-input.ts rename to packages/daemon/src/snapshot-runtime-capture-input.ts diff --git a/src/daemon/snapshot-runtime.ts b/packages/daemon/src/snapshot-runtime.ts similarity index 100% rename from src/daemon/snapshot-runtime.ts rename to packages/daemon/src/snapshot-runtime.ts diff --git a/src/daemon/snapshot-session.ts b/packages/daemon/src/snapshot-session.ts similarity index 100% rename from src/daemon/snapshot-session.ts rename to packages/daemon/src/snapshot-session.ts diff --git a/src/daemon/snapshot-timeout-evidence.test.ts b/packages/daemon/src/snapshot-timeout-evidence.test.ts similarity index 100% rename from src/daemon/snapshot-timeout-evidence.test.ts rename to packages/daemon/src/snapshot-timeout-evidence.test.ts diff --git a/src/daemon/snapshot-timeout-evidence.ts b/packages/daemon/src/snapshot-timeout-evidence.ts similarity index 100% rename from src/daemon/snapshot-timeout-evidence.ts rename to packages/daemon/src/snapshot-timeout-evidence.ts diff --git a/src/daemon/sparse-fallback-screenshot.ts b/packages/daemon/src/sparse-fallback-screenshot.ts similarity index 100% rename from src/daemon/sparse-fallback-screenshot.ts rename to packages/daemon/src/sparse-fallback-screenshot.ts diff --git a/src/daemon/startup-deadline.ts b/packages/daemon/src/startup-deadline.ts similarity index 100% rename from src/daemon/startup-deadline.ts rename to packages/daemon/src/startup-deadline.ts diff --git a/src/daemon/system-button-runtime.ts b/packages/daemon/src/system-button-runtime.ts similarity index 100% rename from src/daemon/system-button-runtime.ts rename to packages/daemon/src/system-button-runtime.ts diff --git a/src/daemon/tenant-owned-entry.ts b/packages/daemon/src/tenant-owned-entry.ts similarity index 100% rename from src/daemon/tenant-owned-entry.ts rename to packages/daemon/src/tenant-owned-entry.ts diff --git a/src/daemon/touch-runtime.ts b/packages/daemon/src/touch-runtime.ts similarity index 100% rename from src/daemon/touch-runtime.ts rename to packages/daemon/src/touch-runtime.ts diff --git a/src/daemon/tv-remote-runtime.ts b/packages/daemon/src/tv-remote-runtime.ts similarity index 100% rename from src/daemon/tv-remote-runtime.ts rename to packages/daemon/src/tv-remote-runtime.ts diff --git a/src/daemon/type-target-warning.ts b/packages/daemon/src/type-target-warning.ts similarity index 100% rename from src/daemon/type-target-warning.ts rename to packages/daemon/src/type-target-warning.ts diff --git a/src/daemon/type-text-runtime.ts b/packages/daemon/src/type-text-runtime.ts similarity index 100% rename from src/daemon/type-text-runtime.ts rename to packages/daemon/src/type-text-runtime.ts diff --git a/src/daemon/upload-http.ts b/packages/daemon/src/upload-http.ts similarity index 100% rename from src/daemon/upload-http.ts rename to packages/daemon/src/upload-http.ts diff --git a/src/daemon/upload.ts b/packages/daemon/src/upload.ts similarity index 100% rename from src/daemon/upload.ts rename to packages/daemon/src/upload.ts diff --git a/src/daemon/viewport-runtime.ts b/packages/daemon/src/viewport-runtime.ts similarity index 100% rename from src/daemon/viewport-runtime.ts rename to packages/daemon/src/viewport-runtime.ts diff --git a/src/daemon/wait-current-surface.test.ts b/packages/daemon/src/wait-current-surface.test.ts similarity index 100% rename from src/daemon/wait-current-surface.test.ts rename to packages/daemon/src/wait-current-surface.test.ts diff --git a/src/daemon/wait-current-surface.ts b/packages/daemon/src/wait-current-surface.ts similarity index 100% rename from src/daemon/wait-current-surface.ts rename to packages/daemon/src/wait-current-surface.ts diff --git a/src/daemon/wait-runtime.ts b/packages/daemon/src/wait-runtime.ts similarity index 100% rename from src/daemon/wait-runtime.ts rename to packages/daemon/src/wait-runtime.ts diff --git a/src/daemon/web-session-names.ts b/packages/daemon/src/web-session-names.ts similarity index 100% rename from src/daemon/web-session-names.ts rename to packages/daemon/src/web-session-names.ts diff --git a/packages/daemon/tsconfig.json b/packages/daemon/tsconfig.json new file mode 100644 index 0000000000..71114553ab --- /dev/null +++ b/packages/daemon/tsconfig.json @@ -0,0 +1,69 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "noEmit": false, + "emitDeclarationOnly": true, + "declaration": true, + "declarationDir": "./dist-types", + "rootDir": "./src", + "tsBuildInfoFile": "./dist-types/index.tsbuildinfo" + }, + "include": ["src"], + "references": [ + { + "path": "../ad-replay" + }, + { + "path": "../ad-script" + }, + { + "path": "../capture-kit" + }, + { + "path": "../command-registry" + }, + { + "path": "../contracts" + }, + { + "path": "../daemon-contracts" + }, + { + "path": "../device-selection" + }, + { + "path": "../host-kit" + }, + { + "path": "../kernel" + }, + { + "path": "../maestro" + }, + { + "path": "../platform-android" + }, + { + "path": "../platform-apple" + }, + { + "path": "../platform-web" + }, + { + "path": "../replay-port" + }, + { + "path": "../replay-test" + }, + { + "path": "../selectors" + }, + { + "path": "../session-journal" + }, + { + "path": "../test-kit" + } + ] +} diff --git a/packages/host-kit/src/code-signature.ts b/packages/host-kit/src/code-signature.ts index edea9084ce..6af3f98ad4 100644 --- a/packages/host-kit/src/code-signature.ts +++ b/packages/host-kit/src/code-signature.ts @@ -69,7 +69,7 @@ export function resolveDaemonCodeSignature(): string { * first: two installed trees of one version hold the same artifact and have nothing to * compare (#2458), while a checkout's code moves under a version that does not move * with it. A running daemon publishes its own answer beside its signature - * (`src/daemon/server/server-lifecycle.ts`) because the question is about the code that + * (`packages/daemon/src/server/server-lifecycle.ts`) because the question is about the code that * is RUNNING, not only about the client asking it. */ export type DaemonCodeOrigin = 'installed' | 'checkout'; diff --git a/packages/maestro/test/conformance/differential/invariants.ts b/packages/maestro/test/conformance/differential/invariants.ts index 5d11103d3d..68bbc7da29 100644 --- a/packages/maestro/test/conformance/differential/invariants.ts +++ b/packages/maestro/test/conformance/differential/invariants.ts @@ -6,7 +6,7 @@ // loop has no reflectable upstream constant to cross-check in layer 2). // // These invariants read the `replay-timing.ndjson` written by the test runtime -// (src/daemon/handlers/session-test-runtime.ts) and assert engine-side facts — +// (packages/replay-test/src/internal/session-test-runtime.ts) and assert engine-side facts — // e.g. a tap's stability loop must latch rather than run out of settle budget. // // The evaluator is pure and unit-tested against synthetic traces; the device run diff --git a/packages/replay-port/src/daemon-port/test-command.ts b/packages/replay-port/src/daemon-port/test-command.ts index 4ab1e65bea..ad8906ad91 100644 --- a/packages/replay-port/src/daemon-port/test-command.ts +++ b/packages/replay-port/src/daemon-port/test-command.ts @@ -301,7 +301,7 @@ export async function runReplayTestCommand(command: ReplayTestCommand): Promise< * client-side *before* the suite runs, so it never contains the suite's own invocation id. * * `data.artifactsDir` (the daemon-local suite directory) is always `/`: `createDirectoryArchive` (`src/daemon/artifact-tracking.ts`) tars it as + * invocation id>`: `createDirectoryArchive` (`packages/daemon/src/artifact-tracking.ts`) tars it as * `-C dirname(daemonRoot) -- basename(daemonRoot)`, so extracting that archive under the * caller-local root reproduces the SAME invocation-id segment there. The caller-facing root is * therefore `path.join(clientRoot, basename(daemonRoot))`, not `clientRoot` itself — every path diff --git a/packages/replay-test/src/internal/__tests__/session-test-runtime.test.ts b/packages/replay-test/src/internal/__tests__/session-test-runtime.test.ts index 6bd8cb8fbd..5a976470fb 100644 --- a/packages/replay-test/src/internal/__tests__/session-test-runtime.test.ts +++ b/packages/replay-test/src/internal/__tests__/session-test-runtime.test.ts @@ -11,7 +11,7 @@ import { mkdtempForTestSync } from '../../tmp-dir.fixtures.ts'; // What the scheduler owes its host around cancellation (#1478 P3b): cancel exactly once when // an attempt times out, and always release when it settles. How the daemon then maps that onto // its request registry is the adapter's contract, pinned in -// `src/daemon/__tests__/replay-suite/session-test-suite-command-cancellation.test.ts`. +// `packages/daemon/src/__tests__/replay-suite/session-test-suite-command-cancellation.test.ts`. const cancellations: Array<{ attemptId: string; canceled: number; released: number }> = []; function trackCancellation() { diff --git a/packages/session-journal/src/__tests__/journal-request-input.test.ts b/packages/session-journal/src/__tests__/journal-request-input.test.ts index 742f69c174..dba6d2d15b 100644 --- a/packages/session-journal/src/__tests__/journal-request-input.test.ts +++ b/packages/session-journal/src/__tests__/journal-request-input.test.ts @@ -93,7 +93,7 @@ type ReachableTypes< : never; /** - * The structural minimum of `src/daemon/session-state.ts`'s `SessionState`. The package may not + * The structural minimum of `packages/daemon/src/session-state.ts`'s `SessionState`. The package may not * import that module (R11), so the live session record is named by the three required fields no * other shape in the public request vocabulary carries together. Anything typed as `SessionState` * is assignable to this, which is what `Extract` needs. diff --git a/packages/test-kit/src/boundary-fault-matrix.ts b/packages/test-kit/src/boundary-fault-matrix.ts index afdc2d6fcc..a97f541767 100644 --- a/packages/test-kit/src/boundary-fault-matrix.ts +++ b/packages/test-kit/src/boundary-fault-matrix.ts @@ -176,7 +176,7 @@ export const BOUNDARY_FAULT_MATRIX = { 'artifact-producing': { kind: 'covered', evidence: [ - 'src/daemon/__tests__/filesystem-boundary-faults.test.ts', + 'packages/daemon/src/__tests__/filesystem-boundary-faults.test.ts', 'packages/platform-apple/src/runner/__tests__/runner-lease-filesystem-boundary-faults.test.ts', ], invariants: ['atomic-publication', 'publication-residue-free'], @@ -184,7 +184,7 @@ export const BOUNDARY_FAULT_MATRIX = { 'session-lifecycle': { kind: 'covered', evidence: [ - 'src/daemon/__tests__/filesystem-boundary-faults.test.ts', + 'packages/daemon/src/__tests__/filesystem-boundary-faults.test.ts', 'packages/platform-apple/src/runner/__tests__/runner-lease-filesystem-boundary-faults.test.ts', ], invariants: ['atomic-publication', 'publication-residue-free', 'claim-or-lease-state'], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 62654b0d05..0d344c6697 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -34,6 +34,9 @@ importers: '@agent-device/contracts': specifier: workspace:* version: link:packages/contracts + '@agent-device/daemon': + specifier: workspace:* + version: link:packages/daemon '@agent-device/daemon-contracts': specifier: workspace:* version: link:packages/daemon-contracts @@ -280,6 +283,76 @@ importers: specifier: ^4.9.0 version: 4.9.0 + packages/daemon: + dependencies: + '@agent-device/ad-replay': + specifier: workspace:* + version: link:../ad-replay + '@agent-device/ad-script': + specifier: workspace:* + version: link:../ad-script + '@agent-device/capture-kit': + specifier: workspace:* + version: link:../capture-kit + '@agent-device/command-registry': + specifier: workspace:* + version: link:../command-registry + '@agent-device/contracts': + specifier: workspace:* + version: link:../contracts + '@agent-device/daemon-contracts': + specifier: workspace:* + version: link:../daemon-contracts + '@agent-device/device-selection': + specifier: workspace:* + version: link:../device-selection + '@agent-device/host-kit': + specifier: workspace:* + version: link:../host-kit + '@agent-device/kernel': + specifier: workspace:* + version: link:../kernel + '@agent-device/maestro': + specifier: workspace:* + version: link:../maestro + '@agent-device/platform-android': + specifier: workspace:* + version: link:../platform-android + '@agent-device/platform-apple': + specifier: workspace:* + version: link:../platform-apple + '@agent-device/platform-web': + specifier: workspace:* + version: link:../platform-web + '@agent-device/replay-port': + specifier: workspace:* + version: link:../replay-port + '@agent-device/replay-test': + specifier: workspace:* + version: link:../replay-test + '@agent-device/selectors': + specifier: workspace:* + version: link:../selectors + '@agent-device/session-journal': + specifier: workspace:* + version: link:../session-journal + '@agent-device/test-kit': + specifier: workspace:* + version: link:../test-kit + devDependencies: + fast-check: + specifier: ^4.9.0 + version: 4.9.0 + oxc-parser: + specifier: ^0.146.0 + version: 0.146.0 + vitest: + specifier: 5.0.4 + version: 5.0.4(@types/node@22.20.1)(@vitest/coverage-v8@5.0.4)(vite@8.2.1(@types/node@22.20.1)(yaml@2.9.0)) + yaml: + specifier: ^2.9.0 + version: 2.9.0 + packages/daemon-contracts: dependencies: '@agent-device/command-registry': diff --git a/scripts/__tests__/committed-source-tree.ts b/scripts/__tests__/committed-source-tree.ts index 2c61e4bee9..80e42cf0db 100644 --- a/scripts/__tests__/committed-source-tree.ts +++ b/scripts/__tests__/committed-source-tree.ts @@ -42,10 +42,29 @@ export function headCommit(repoRoot: string): string { return git(repoRoot, ['rev-parse', 'HEAD']).toString('utf8').trim(); } -/** Files renamed since `base`, current path -> path at `base`, so a rename is not a new entry. */ -export function renamedSince(repoRoot: string, base: string): ReadonlyMap { +/** + * Files renamed between `base` and `head` (the working tree unless a commit is given), + * head path -> base path, so a rename is not a new entry. The explicit rename limit keeps + * inexact detection on regardless of the clone's `diff.renameLimit` config — a bulk move + * with edits (the daemon extraction) is exactly the inexact case the ratchets must see. + */ +export function renamedSince( + repoRoot: string, + base: string, + head?: string, +): ReadonlyMap { const renamed = new Map(); - const status = git(repoRoot, ['diff', '--name-status', '-M', '--diff-filter=R', '-z', base]); + const status = git(repoRoot, [ + '-c', + 'diff.renameLimit=0', + 'diff', + '--name-status', + '-M', + '--diff-filter=R', + '-z', + base, + ...(head ? [head] : []), + ]); const fields = status.toString('utf8').split('\0'); for (let index = 0; index + 2 < fields.length; index += 3) { const [from, to] = [fields[index + 1], fields[index + 2]]; diff --git a/scripts/__tests__/eager-closure-budgets.test.ts b/scripts/__tests__/eager-closure-budgets.test.ts index c8ca29456f..50b32056c5 100644 --- a/scripts/__tests__/eager-closure-budgets.test.ts +++ b/scripts/__tests__/eager-closure-budgets.test.ts @@ -506,6 +506,56 @@ test('a renamed entry is followed to its path at the base, not treated as first- ).toBe(null); }); +test('rename detection survives a git mv with an edit and a hostile renameLimit', () => { + // The daemon move is the load-bearing case: `git mv` PLUS a per-file edit makes the rename + // inexact, and a clone-side `diff.renameLimit` below the file count silently disables the + // scan. `renamedSince` pins the limit off, so both must still pair. + const repo = mkGitFixtureRepo('renamed-since-inexact-'); + // git mv PLUS an edit: inexact rename detection has to score similarity to pair this one. + // The fixture files are one statement long, so an appended edit would be a rewrite git + // refuses to pair at all; pad in the base commit first, then move and touch a line the + // way the daemon files were touched. + for (const file of ['packages/demo/src/entry.ts', 'packages/demo/src/facades/top.ts']) + fs.appendFileSync( + path.join(repo, file), + Array.from({ length: 40 }, (_, i) => `export const pad${i} = ${i};`).join('\n') + '\n', + ); + execFileSync('git', ['commit', '-aqm', 'pad'], { cwd: repo }); + execFileSync('git', ['mv', 'packages/demo/src/entry.ts', 'packages/demo/src/moved.ts'], { + cwd: repo, + }); + fs.appendFileSync(path.join(repo, 'packages/demo/src/moved.ts'), '\nexport const touched = 1;\n'); + execFileSync( + 'git', + ['mv', 'packages/demo/src/facades/top.ts', 'packages/demo/src/facades/top2.ts'], + { + cwd: repo, + }, + ); + fs.appendFileSync( + path.join(repo, 'packages/demo/src/facades/top2.ts'), + '\nexport const t2 = 1;\n', + ); + execFileSync('git', ['add', '-A'], { cwd: repo }); + execFileSync('git', ['commit', '-qm', 'two moved edits'], { cwd: repo }); + const withEdits = renamedSince(repo, 'HEAD~1', 'HEAD'); + expect(withEdits.get('packages/demo/src/moved.ts')).toBe('packages/demo/src/entry.ts'); + expect(withEdits.get('packages/demo/src/facades/top2.ts')).toBe( + 'packages/demo/src/facades/top.ts', + ); + // A clone-side limit BELOW the two inexact renames must not disable detection: the helper + // passes its own `-c diff.renameLimit=0` (unlimited). + execFileSync('git', ['config', 'diff.renameLimit', '1'], { cwd: repo }); + const underLimit = renamedSince(repo, 'HEAD~1', 'HEAD'); + expect(underLimit.get('packages/demo/src/moved.ts')).toBe('packages/demo/src/entry.ts'); + expect(underLimit.get('packages/demo/src/facades/top2.ts')).toBe( + 'packages/demo/src/facades/top.ts', + ); + // The base -> head direction the wire-compat ledger canonicalizes with (#3546 review). + const baseToHead = new Map([...underLimit].map(([headPath, basePath]) => [basePath, headPath])); + expect(baseToHead.get('packages/demo/src/entry.ts')).toBe('packages/demo/src/moved.ts'); +}); + test('discovery is recursive and reads TRACKED files only', () => { // Two holes in one fixture, because both are about discovery seeing the wrong set of files. // diff --git a/scripts/__tests__/eager-closure-budgets.ts b/scripts/__tests__/eager-closure-budgets.ts index e17b81e142..87136f3203 100644 --- a/scripts/__tests__/eager-closure-budgets.ts +++ b/scripts/__tests__/eager-closure-budgets.ts @@ -109,7 +109,7 @@ export const HUB_ENTRY_FILES: readonly string[] = [ 'src/daemon.ts', 'src/platform-runtime.ts', 'src/core/interactors/register-builtins.ts', - 'src/daemon/session-teardown.ts', + 'packages/daemon/src/session-teardown.ts', ]; /** A platform façade evaluates exactly this many modules: itself. */ diff --git a/scripts/__tests__/eager-closure-gate-fixtures.ts b/scripts/__tests__/eager-closure-gate-fixtures.ts index 02e24f8c20..9276097384 100644 --- a/scripts/__tests__/eager-closure-gate-fixtures.ts +++ b/scripts/__tests__/eager-closure-gate-fixtures.ts @@ -36,11 +36,14 @@ export function mkGitFixtureRepo(prefix: string): string { fs.mkdirSync(path.join(repo, 'scripts')); fs.writeFileSync(path.join(repo, 'scripts/standalone.ts'), 'export const outside = 1;\n'); execFileSync('git', ['init', '-q'], { cwd: repo }); + // Pin identity and signing into the repo config rather than the run's `-c` flags or the + // runner's global config: callers commit more than the base (e.g. the pad commit in + // eager-closure-budgets.test.ts), and a CI runner without a global identity fails those + // later commits with "Author identity unknown". + execFileSync('git', ['config', 'user.name', 'Gate'], { cwd: repo }); + execFileSync('git', ['config', 'user.email', 'gate@example.test'], { cwd: repo }); + execFileSync('git', ['config', 'commit.gpgsign', 'false'], { cwd: repo }); execFileSync('git', ['add', '.'], { cwd: repo }); - execFileSync( - 'git', - ['-c', 'user.name=Gate', '-c', 'user.email=gate@example.test', 'commit', '-qm', 'base'], - { cwd: repo }, - ); + execFileSync('git', ['commit', '-qm', 'base'], { cwd: repo }); return repo; } diff --git a/scripts/__tests__/help-conformance-sample-producers.ts b/scripts/__tests__/help-conformance-sample-producers.ts index 025abbca5b..a453009400 100644 --- a/scripts/__tests__/help-conformance-sample-producers.ts +++ b/scripts/__tests__/help-conformance-sample-producers.ts @@ -20,13 +20,16 @@ import { interactionCliOutputFormatters } from '../../src/commands/interaction/o import { snapshotCliOutput } from '../../src/commands/capture/output.ts'; import { openCliOutput } from '../../src/commands/management/output.ts'; import { NEVER_SETTLED_HINT } from '../../src/commands/interaction/runtime/settle.ts'; -import { buildAmbiguousMatchError } from '../../src/daemon/selector-match-errors.ts'; -import { refMutationAdmissionResponse } from '../../src/daemon/interaction/index.ts'; -import { buildDeviceInUseBySessionError } from '../../src/daemon/session-recovery-hints.ts'; -import { buildDeviceClaimConflictError } from '../../src/daemon/device/device-claim-conflict.ts'; -import { activateCompleteRefFrame, readRefMutationFrame } from '../../src/daemon/ref-frame.ts'; -import { resolveRefStalenessWarning } from '../../src/daemon/session-snapshot.ts'; -import type { SessionState } from '../../src/daemon/session-state.ts'; +import { buildAmbiguousMatchError } from '@agent-device/daemon/testing/selector-match-errors'; +import { refMutationAdmissionResponse } from '@agent-device/daemon/testing/interaction/index'; +import { buildDeviceInUseBySessionError } from '@agent-device/daemon/testing/session-recovery-hints'; +import { buildDeviceClaimConflictError } from '@agent-device/daemon/testing/device/device-claim-conflict'; +import { + activateCompleteRefFrame, + readRefMutationFrame, +} from '@agent-device/daemon/testing/ref-frame'; +import { resolveRefStalenessWarning } from '@agent-device/daemon/testing/session-snapshot'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { buildAppNotInstalledError } from '@agent-device/platform-apple/app-resolution'; import { presentConnectReadiness, diff --git a/scripts/check-affected/device-lanes.test.ts b/scripts/check-affected/device-lanes.test.ts index b3f3eb388d..3d12a21bb0 100644 --- a/scripts/check-affected/device-lanes.test.ts +++ b/scripts/check-affected/device-lanes.test.ts @@ -71,9 +71,9 @@ test('the macOS coverage manifest selects its executable gate and macOS replay l test('shared runtime surface owns every device lane', () => { for (const file of [ - 'src/daemon/handlers/session.ts', + 'packages/daemon/src/handlers/session.ts', 'packages/kernel/src/errors.ts', - 'src/daemon/android-system-dialog.ts', // naming convention in a shared dir, not a boundary + 'packages/daemon/src/android-system-dialog.ts', // naming convention in a shared dir, not a boundary 'test/integration/smoke-daemon-clean.test.ts', 'packages/provision-kit/src/install-source.ts', ]) { @@ -127,7 +127,7 @@ test('the fixture app owns the mobile lanes whichever subtree changes', () => { test('unit tests under src/ and packages/*/src own no lane', () => { for (const file of [ - 'src/daemon/selectors.test.ts', + 'packages/daemon/src/handlers/snapshot-runtime-route.test.ts', 'src/__tests__/contracts/interaction-guarantees.test.ts', 'packages/platform-apple/src/core/__tests__/apps.test.ts', 'packages/platform-apple/src/runtime.test.ts', diff --git a/scripts/check-affected/device-lanes.ts b/scripts/check-affected/device-lanes.ts index 7ba9503c6d..47d954c3ff 100644 --- a/scripts/check-affected/device-lanes.ts +++ b/scripts/check-affected/device-lanes.ts @@ -8,7 +8,7 @@ // // What enumerates the surface. The import graph cannot: the daemon value-imports every // platform module (`src/platform-runtime.ts` composes all six families; `src/core/interactors/*` -// import each family's actions; `src/daemon/session-teardown.ts` calls Android cleanup on every +// import each family's actions; `packages/daemon/src/session-teardown.ts` calls Android cleanup on every // session close), so reachability from `src/bin.ts` is the whole tree, and the layering graph // does not resolve relative imports inside `packages/`. The repo's *enforced* platform partition // can: `CANONICAL_PLATFORM_FAMILIES` names the families, layering R13 pins each family's runtime @@ -77,7 +77,7 @@ function leafOfSegment(segment: string): Leaf | null { // Under test/integration/ the smoke files carry their lane in the leading tokens of the first // segment (`smoke-android-emulator.test.ts`, `ios-simulator-e2e/`, `android-emulator-e2e/`). -// Elsewhere only directory segments tag: `src/daemon/android-system-dialog.ts` is a naming +// Elsewhere only directory segments tag: `packages/daemon/src/android-system-dialog.ts` is a naming // convention in a shared directory, not an enforced boundary, so it stays shared. function tagSegments(file: string): string[] { const segments = file.split('/'); diff --git a/scripts/check-affected/model.test.ts b/scripts/check-affected/model.test.ts index 5036aca8dc..aa642d18b4 100644 --- a/scripts/check-affected/model.test.ts +++ b/scripts/check-affected/model.test.ts @@ -46,7 +46,7 @@ test('platform package source additionally selects provider-integration', () => }); test('unit test files delegate affected-test discovery to Vitest', () => { - const result = ids(['src/daemon/selectors.test.ts']); + const result = ids(['packages/daemon/src/selectors.test.ts']); assert.ok(result.includes('vitest-related')); assert.ok(!result.includes('unit')); assert.ok(!result.includes('provider-integration')); diff --git a/scripts/check-bundle-owner-files.ts b/scripts/check-bundle-owner-files.ts index eb8d8bfa29..1fceefb948 100644 --- a/scripts/check-bundle-owner-files.ts +++ b/scripts/check-bundle-owner-files.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { COMMAND_OWNER_FILES } from '@agent-device/command-registry/owner-files'; -import { getDaemonRouteOwnerFiles } from '../src/daemon/route-owner-files.ts'; +import { getDaemonRouteOwnerFiles } from '@agent-device/daemon/route-owner-files'; import { walkFiles } from './lib/walk-files.ts'; const repoRoot = path.resolve(import.meta.dirname, '..'); diff --git a/scripts/coverage-crap/fallow-health-report.fixture.json b/scripts/coverage-crap/fallow-health-report.fixture.json index e97f3449ba..2cdb32d6fb 100644 --- a/scripts/coverage-crap/fallow-health-report.fixture.json +++ b/scripts/coverage-crap/fallow-health-report.fixture.json @@ -38,7 +38,7 @@ "coverage_source": "istanbul" }, { - "path": "src/daemon/server/http-server.ts", + "path": "packages/daemon/src/server/http-server.ts", "name": "", "line": 188, "col": 18, diff --git a/scripts/coverage-crap/model.test.ts b/scripts/coverage-crap/model.test.ts index ceacd0004f..1647f2cad1 100644 --- a/scripts/coverage-crap/model.test.ts +++ b/scripts/coverage-crap/model.test.ts @@ -417,6 +417,8 @@ test('a captured fallow 3.32 report yields its measured findings past leading ou assert.deepEqual( findings.map((entry) => [entry.path, entry.name, entry.line, entry.crap]), [ + // The captured fixture keeps the historical capture path: it never existed + // at head (the module lives at the package root), so the sweep left it. ['src/daemon/handlers/session-state.ts', 'handleSessionStateCommands', 232, 34.1], ['src/daemon/handlers/session-state.ts', 'handleAppStateCommand', 112, 30.4], ], diff --git a/scripts/daemon-edge-residue-scan.mjs b/scripts/daemon-edge-residue-scan.mjs deleted file mode 100644 index fe96a27118..0000000000 --- a/scripts/daemon-edge-residue-scan.mjs +++ /dev/null @@ -1,90 +0,0 @@ -// Daemon residue scan (11a-4): every module specifier in a file under src/daemon/ that resolves -// to a non-package module outside src/daemon/. The rule: daemon files may import workspace -// packages, externals, and each other — nothing else. Once the daemon is its own package, R11 in -// the layering guard (#3546) enforces this permanently; until then this scan is the measurement. -// -// Why a naive regex reported zero edges while five mocks survived: a single alternation that -// starts at `import|export` and bridges to the next `from` with `[\s\S]*?` swallows everything in -// between — including a `vi.mock('../../../platform-runtime-….ts', …)` whose own specifier sits -// between an earlier `importOriginal` and the file's next static `from`. The -// mocked specifier is then attributed to the wrong (allowed) capture or skipped entirely. So each -// specifier form is matched independently, statement-anchored where the language is: -// -// - static `import`/`export … from '…'` and side-effect `import '…'`, anchored at a statement -// start (line start or `;`), never bridging statements; -// - `import type` / `export type` variants (same anchor); -// - dynamic `import('…')` / `require('…')` with a string or no-substitution template argument; -// - `vi.mock` / `vi.doMock` / `vi.unmock` / `vi.importMock` / `vi.importActual` / -// `vi.importOriginal` first argument, any position, string or template literal; -// - `importOriginal` type-position specifiers (the dynamic-import form). -// -// Known limits: computed specifiers (variables, string concatenation) are out of scope — none -// exist in the daemon tree, and a runtime resolver is the only tool that could see them. -// -// Usage: `node scripts/daemon-edge-residue-scan.mjs` from the repo root. Exit code 1 when any -// edge is found. -import fs from 'node:fs'; -import path from 'node:path'; - -const root = process.cwd(); - -function walk(dir, out) { - for (const ent of fs.readdirSync(dir, { withFileTypes: true })) { - const p = path.join(dir, ent.name); - if (ent.isDirectory()) walk(p, out); - else if (/\.(ts|tsx|mjs)$/.test(ent.name)) out.push(p); - } - return out; -} - -// A quoted string or no-substitution template literal as the specifier position. -const SPEC = '(?:\'([^\']*)\'|"([^"]*)"|`([^`]*)`)'; -const forms = [ - // Static import/export with a `from` clause; the keyword must start a statement. - new RegExp(`(?:^|[;\\n])\\s*(?:import|export)\\b[^'"()\`]*?\\bfrom\\s*${SPEC}`, 'gm'), - // Side-effect import. - new RegExp(`(?:^|[;\\n])\\s*import\\s+${SPEC}`, 'gm'), - // Dynamic import (also catches `typeof import('…')` in type positions) and require. - new RegExp(`\\bimport\\s*\\(\\s*${SPEC}`, 'g'), - new RegExp(`\\brequire\\s*\\(\\s*${SPEC}`, 'g'), - // Vitest module-factory hoists, any position in the file. - new RegExp( - `\\bvi\\.(?:mock|doMock|unmock|importMock|importActual|importOriginal)\\s*\\(\\s*${SPEC}`, - 'g', - ), -]; - -const files = walk(path.join(root, 'src/daemon'), []); -const edges = []; -for (const file of files) { - const rel = path.relative(root, file); - const source = fs.readFileSync(file, 'utf8'); - const seen = new Set(); - for (const form of forms) { - form.lastIndex = 0; - let match; - while ((match = form.exec(source))) { - const specifier = match[1] ?? match[2] ?? match[3]; - if (!specifier) continue; - if (!specifier.startsWith('.')) continue; // bare specifier: package or external, allowed - const resolved = path - .normalize(path.join(path.dirname(rel), specifier)) - .replace(/\.tsx?$/, ''); - // path.join yields backslashes on Windows, so compare against the native separator. - const daemonDir = path.join('src', 'daemon'); - if (resolved === daemonDir || resolved.startsWith(`${daemonDir}${path.sep}`)) continue; - if (seen.has(resolved)) continue; - seen.add(resolved); - // The static forms anchor at the preceding `;`/newline, so slice(0, match.index) - // counts lines only up to that separator and reports one early. Count to the - // keyword inside the match (position 0 for the unanchored forms). - const keywordAt = match[0].search(/import|export|require|vi\./); - const line = source.slice(0, match.index + keywordAt).split('\n').length; - edges.push(`${rel}:${line} -> ${resolved}`); - } - } -} -edges.sort(); -if (edges.length > 0) process.stdout.write(edges.join('\n') + '\n'); -process.stdout.write(`daemon residue edges: ${edges.length}\n`); -if (edges.length > 0) process.exit(1); diff --git a/scripts/depgraph/README.md b/scripts/depgraph/README.md index d0dc146f54..e1299c250a 100644 --- a/scripts/depgraph/README.md +++ b/scripts/depgraph/README.md @@ -14,7 +14,7 @@ productive artifact is the JSON, queried directly. ```sh pnpm depgraph affected packages/host-kit/src/command.ts # bounded text -pnpm depgraph affected src/daemon/ref-frame.ts --json --limit 25 +pnpm depgraph affected packages/daemon/src/ref-frame.ts --json --limit 25 ``` Reverse reachability over the value-edge graph, plus the three lookups that used to follow it: @@ -162,9 +162,9 @@ roots, exports, and named live-state symbols in `scripts/layering/architecture-o - `vocabulary` — the target is a declared contract facade root. - `capability` — the target is a declared capability root and the import names a declared export. -- `live-state-shape` — the edge names the exact `SessionState` type from `src/daemon/session-state.ts`. +- `live-state-shape` — the edge names the exact `SessionState` type from `packages/daemon/src/session-state.ts`. - `live-state-authority` — the edge names the exact `SessionStore` class from - `src/daemon/session-store.ts`. + `packages/daemon/src/session-store.ts`. - `executable-policy` — the source is under a declared executable-policy root. - `ordinary` — no declared authority evidence matches the edge. diff --git a/scripts/depgraph/affected-run.ts b/scripts/depgraph/affected-run.ts index 11479e729c..1df1ba6d7f 100644 --- a/scripts/depgraph/affected-run.ts +++ b/scripts/depgraph/affected-run.ts @@ -1,7 +1,7 @@ // `pnpm depgraph affected ` — the blast radius of one file in one query. // // pnpm depgraph affected packages/host-kit/src/command.ts -// pnpm depgraph affected src/daemon/ref-frame.ts --json --limit 20 +// pnpm depgraph affected packages/daemon/src/ref-frame.ts --json --limit 20 // // Answers, from the sources of truth rather than a second copy of them: // - dependents (direct / transitive, with a zone breakdown) — reverse reachability over the @@ -23,7 +23,7 @@ import { INTERACTION_DISPATCH_PATHS, type InteractionPathId, } from '@agent-device/contracts/interaction-guarantees'; -import { DAEMON_COMMAND_DESCRIPTORS } from '../../src/daemon/daemon-command-registry.ts'; +import { DAEMON_COMMAND_DESCRIPTORS } from '@agent-device/daemon/daemon-command-registry'; import { parseArgs } from 'node:util'; import { selectChecks, type CheckPlan } from '../check-affected/model.ts'; import { @@ -48,7 +48,7 @@ const USAGE = ' --json unbounded machine-readable output\n' + ' --limit entries per list in text output (default 10)\n'; -const HANDLER_CHAIN_FILE = 'src/daemon/request-handler-chain.ts'; +const HANDLER_CHAIN_FILE = 'packages/daemon/src/request-handler-chain.ts'; /** * The live iOS coverage manifest (#1408) is consumed through the narrowest shape this query diff --git a/scripts/depgraph/affected.test.ts b/scripts/depgraph/affected.test.ts index 48789de5c9..b551f3e6c1 100644 --- a/scripts/depgraph/affected.test.ts +++ b/scripts/depgraph/affected.test.ts @@ -69,11 +69,11 @@ test('collectDependents ignores type-only and dynamic dependents, which are coun test('zoneBreakdown and rankByFanIn order by weight, then name', () => { const nodes = nodesOf({ - 'src/daemon/a.ts': { zone: 'daemon-server', fanIn: 3 }, - 'src/daemon/b.ts': { zone: 'daemon-server', fanIn: 9 }, + 'packages/daemon/src/a.ts': { zone: 'daemon-server', fanIn: 3 }, + 'packages/daemon/src/b.ts': { zone: 'daemon-server', fanIn: 9 }, 'src/core/c.ts': { zone: 'core', fanIn: 9 }, }); - const files = ['src/daemon/a.ts', 'src/daemon/b.ts', 'src/core/c.ts']; + const files = ['packages/daemon/src/a.ts', 'packages/daemon/src/b.ts', 'src/core/c.ts']; assert.deepEqual(zoneBreakdown(files, nodes), [ { zone: 'daemon-server', count: 2 }, @@ -81,25 +81,25 @@ test('zoneBreakdown and rankByFanIn order by weight, then name', () => { ]); assert.deepEqual( rankByFanIn(files, nodes).map((entry) => entry.file), - ['src/core/c.ts', 'src/daemon/b.ts', 'src/daemon/a.ts'], + ['packages/daemon/src/b.ts', 'src/core/c.ts', 'packages/daemon/src/a.ts'], ); }); test('commandsReaching follows the dynamic import a route uses to load its handler', () => { // These are in-memory arbitrary paths for graph traversal, not repository ownership metadata. const edges = edgesOf({ - 'src/daemon/handlers/session.ts': - "import { helper } from '../../utils/helper.ts';\nexport const h = helper;", - 'src/daemon/interaction/index.ts': 'export const f = 1;', + 'packages/daemon/src/handlers/session.ts': + "import { helper } from '../../../../src/utils/helper.ts';\nexport const h = helper;", + 'packages/daemon/src/interaction/index.ts': 'export const f = 1;', 'src/utils/helper.ts': 'export const helper = 1;', - 'src/daemon/chain.ts': [ + 'packages/daemon/src/chain.ts': [ "export const routes = { session: () => import('./handlers/session.ts'),", " find: () => import('./interaction/index.ts') };", ].join('\n'), }); const chains = [ - { command: 'open', route: 'session', entry: 'src/daemon/handlers/session.ts' }, - { command: 'find', route: 'find', entry: 'src/daemon/interaction/index.ts' }, + { command: 'open', route: 'session', entry: 'packages/daemon/src/handlers/session.ts' }, + { command: 'find', route: 'find', entry: 'packages/daemon/src/interaction/index.ts' }, ]; assert.deepEqual( @@ -108,7 +108,7 @@ test('commandsReaching follows the dynamic import a route uses to load its handl ); // The entry module itself counts as part of its own chain. assert.deepEqual( - commandsReaching('src/daemon/interaction/index.ts', chains, edges).map( + commandsReaching('packages/daemon/src/interaction/index.ts', chains, edges).map( (chain) => chain.command, ), ['find'], @@ -153,14 +153,14 @@ test('bounded lists disclose what they hid', () => { }); test('every daemon route in the real route table resolves to a handler entry', () => { - const chainFile = 'src/daemon/request-handler-chain.ts'; + const chainFile = 'packages/daemon/src/request-handler-chain.ts'; const source = readFileSync(path.join(repoRoot, chainFile), 'utf8'); const entries = parseRouteEntries(source, chainFile); const declared = [...source.matchAll(/(\w+): defineDaemonRoute\(/g)].map((match) => match[1]!); assert.ok(declared.length > 0, 'route table shape changed: no defineDaemonRoute entries found'); assert.deepEqual([...entries.keys()].sort(), [...declared].sort()); - assert.equal(entries.get('generic'), 'src/daemon/request-generic-dispatch.ts'); + assert.equal(entries.get('generic'), 'packages/daemon/src/request-generic-dispatch.ts'); }); test('the real guarantee matrix contributes module-qualified rows', () => { @@ -209,7 +209,9 @@ test('text output bounds every list and says what it hid', () => { weakDirect: { type: 2, dynamic: 1 }, }, gates: { checks: ['lint', 'typecheck'], failOpen: false }, - commands: [{ command: 'click', route: 'interaction', entry: 'src/daemon/handlers/x.ts' }], + commands: [ + { command: 'click', route: 'interaction', entry: 'packages/daemon/src/handlers/x.ts' }, + ], liveOwners: { manifest: 'test/…/coverage-manifest.ts', present: false, owners: [] }, guaranteeRows: [], }, diff --git a/scripts/depgraph/affected.ts b/scripts/depgraph/affected.ts index 7dd5c77c71..42e48ae3fb 100644 --- a/scripts/depgraph/affected.ts +++ b/scripts/depgraph/affected.ts @@ -96,7 +96,7 @@ export function rankByFanIn( export type CommandChain = { command: string; - /** Daemon route that owns the command (`src/daemon/daemon-command-registry.ts`). */ + /** Daemon route that owns the command (`packages/daemon/src/daemon-command-registry.ts`). */ route: string; /** Handler entry module the route loads. */ entry: string; diff --git a/scripts/depgraph/import-graph.ts b/scripts/depgraph/import-graph.ts index e17a9ea826..8b585952a0 100644 --- a/scripts/depgraph/import-graph.ts +++ b/scripts/depgraph/import-graph.ts @@ -11,7 +11,7 @@ export const VALUE_EDGES: ReadonlySet = new Set(['value']); /** * What a module can actually run: value imports plus dynamic ones. The daemon loads every - * command handler through `import()` (`src/daemon/request-handler-chain.ts`), so dropping + * command handler through `import()` (`packages/daemon/src/request-handler-chain.ts`), so dropping * dynamic edges would cut every handler chain at its root. */ export const EXECUTABLE_EDGES: ReadonlySet = new Set(['value', 'dynamic']); diff --git a/scripts/depgraph/model.test.ts b/scripts/depgraph/model.test.ts index a9ca7deac4..9603242397 100644 --- a/scripts/depgraph/model.test.ts +++ b/scripts/depgraph/model.test.ts @@ -38,31 +38,33 @@ function authorityFixture(): Map { "import type { ReplayShape } from '@agent-device/contracts/replay';", "import type { ProgressShape } from '@agent-device/contracts/progress';", ].join('\n'), - 'src/daemon/capability-consumer.ts': [ + 'packages/daemon/src/capability-consumer.ts': [ "import { createRequestRuntimeBindings } from './request-runtime-binding.ts';", "import { isSessionRecording } from './session-script-publication-capability.ts';", ].join('\n'), - 'src/daemon/state-consumer.ts': [ + 'packages/daemon/src/state-consumer.ts': [ "import type { SessionState } from './session-state.ts';", "import { SessionStore } from './session-store.ts';", ].join('\n'), - 'src/daemon/type-consumer.ts': "import type { SessionStore } from './session-store.ts';\n", + 'packages/daemon/src/type-consumer.ts': + "import type { SessionStore } from './session-store.ts';\n", 'packages/capture-kit/src/snapshot/policy-consumer.ts': [ - "import type { SessionState } from '../../../../src/daemon/session-state.ts';", - "import type { SessionRef } from '../../../../src/daemon/session-state.ts';", + "import type { SessionState } from '../../../../packages/daemon/src/session-state.ts';", + "import type { SessionRef } from '../../../../packages/daemon/src/session-state.ts';", "import './ordinary-target.ts';", ].join('\n'), - 'src/daemon/ordinary-consumer.ts': [ + 'packages/daemon/src/ordinary-consumer.ts': [ "import { SessionState } from './session-state-store.ts';", "import { createRequestRuntimeBindingsExtra } from './request-runtime-binding.ts';", ].join('\n'), - 'src/daemon/session-state.ts': + 'packages/daemon/src/session-state.ts': 'export type SessionState = { name: string };\nexport type SessionRef = unknown;\n', - 'src/daemon/session-store.ts': 'export class SessionStore {}\n', - 'src/daemon/request-runtime-binding.ts': 'export function createRequestRuntimeBindings() {}\n', - 'src/daemon/session-script-publication-capability.ts': + 'packages/daemon/src/session-store.ts': 'export class SessionStore {}\n', + 'packages/daemon/src/request-runtime-binding.ts': + 'export function createRequestRuntimeBindings() {}\n', + 'packages/daemon/src/session-script-publication-capability.ts': 'export function isSessionRecording() {}\n', - 'src/daemon/session-state-store.ts': 'export const SessionState = 1;\n', + 'packages/daemon/src/session-state-store.ts': 'export const SessionState = 1;\n', 'packages/capture-kit/src/snapshot/ordinary-target.ts': 'export const ordinary = 1;\n', 'packages/contracts/src/facades/client.ts': 'export type ClientShape = string;\n', 'packages/contracts/src/facades/capture.ts': 'export type CaptureShape = string;\n', @@ -90,24 +92,43 @@ test('authority overlay uses declared roots and symbols, keeps kind separate, an { kind: 'type', labels: ['vocabulary'] }, ); assert.deepEqual( - graphEdge(graph, 'src/daemon/capability-consumer.ts', 'src/daemon/request-runtime-binding.ts'), + graphEdge( + graph, + 'packages/daemon/src/capability-consumer.ts', + 'packages/daemon/src/request-runtime-binding.ts', + ), { kind: 'value', labels: ['capability'] }, ); assert.deepEqual( - graphEdge(graph, 'src/daemon/state-consumer.ts', 'src/daemon/session-state.ts'), + graphEdge( + graph, + 'packages/daemon/src/state-consumer.ts', + 'packages/daemon/src/session-state.ts', + ), { kind: 'type', labels: ['live-state-shape'], }, ); assert.deepEqual( - graphEdge(graph, 'src/daemon/state-consumer.ts', 'src/daemon/session-store.ts'), + graphEdge( + graph, + 'packages/daemon/src/state-consumer.ts', + 'packages/daemon/src/session-store.ts', + ), { kind: 'value', labels: ['live-state-authority'] }, ); - assert.deepEqual(graphEdge(graph, 'src/daemon/type-consumer.ts', 'src/daemon/session-store.ts'), { - kind: 'type', - labels: ['live-state-authority'], - }); + assert.deepEqual( + graphEdge( + graph, + 'packages/daemon/src/type-consumer.ts', + 'packages/daemon/src/session-store.ts', + ), + { + kind: 'type', + labels: ['live-state-authority'], + }, + ); assert.deepEqual( graphEdge( graph, @@ -117,25 +138,33 @@ test('authority overlay uses declared roots and symbols, keeps kind separate, an { kind: 'value', labels: ['executable-policy'] }, ); assert.deepEqual( - graphEdge(graph, 'src/daemon/ordinary-consumer.ts', 'src/daemon/session-state-store.ts'), + graphEdge( + graph, + 'packages/daemon/src/ordinary-consumer.ts', + 'packages/daemon/src/session-state-store.ts', + ), { kind: 'value', labels: ['ordinary'] }, ); assert.deepEqual( - graphEdge(graph, 'src/daemon/ordinary-consumer.ts', 'src/daemon/request-runtime-binding.ts'), + graphEdge( + graph, + 'packages/daemon/src/ordinary-consumer.ts', + 'packages/daemon/src/request-runtime-binding.ts', + ), { kind: 'value', labels: ['ordinary'] }, ); const stateEdges = resolveImportEdges(files, authorityWorkspaceTargets()).filter( (edge) => edge.file === 'packages/capture-kit/src/snapshot/policy-consumer.ts' && - edge.target === 'src/daemon/session-state.ts', + edge.target === 'packages/daemon/src/session-state.ts', ); assert.equal(stateEdges.length, 2, 'the fixture must exercise raw same-pair imports'); assert.deepEqual( graphEdge( graph, 'packages/capture-kit/src/snapshot/policy-consumer.ts', - 'src/daemon/session-state.ts', + 'packages/daemon/src/session-state.ts', ), { kind: 'type', @@ -179,7 +208,7 @@ test('live-state labels follow shared declarations and reject lookalike targets' assert.deepEqual( authorityLabelsForEdge({ file: 'src/core/live-state-consumer.ts', - target: 'src/daemon/session-state-store.ts', + target: 'packages/daemon/src/session-state-store.ts', spec: './session-state-store.ts', dynamic: false, typeOnly: true, diff --git a/scripts/depgraph/structure-summary.test.ts b/scripts/depgraph/structure-summary.test.ts index ab2160daa7..e28be8cced 100644 --- a/scripts/depgraph/structure-summary.test.ts +++ b/scripts/depgraph/structure-summary.test.ts @@ -67,8 +67,8 @@ test('computeZoneSccSummary finds a zone-level cycle built from value edges acro // file than the first edge's source. const files = sources({ 'src/commands/x1.ts': "import { y } from '../core/y.ts';", - 'src/core/y.ts': "import { z } from '../daemon/z.ts';", - 'src/daemon/z.ts': "import { x2 } from '../commands/x2.ts';", + 'src/core/y.ts': "import { z } from '../../packages/daemon/src/z.ts';", + 'packages/daemon/src/z.ts': "import { x2 } from '../../../src/commands/x2.ts';", 'src/commands/x2.ts': 'export const x2 = 1;', }); const graph = buildGraph(files, resolveImportEdges(files)); diff --git a/scripts/di-seams/check.ts b/scripts/di-seams/check.ts index 916d9dd484..bd4f61df6f 100644 --- a/scripts/di-seams/check.ts +++ b/scripts/di-seams/check.ts @@ -15,7 +15,12 @@ const repoRoot = execFileSync('git', ['rev-parse', '--show-toplevel'], { }).trim(); function listProductionSourceFiles(): string[] { - const out = execFileSync('git', ['ls-files', '--', 'src'], { cwd: repoRoot, encoding: 'utf8' }); + // The daemon server moved to packages/daemon (#3352); its DI seams need the same guard. + // Other packages stay out of scope for this guard's current claim. + const out = execFileSync('git', ['ls-files', '--', 'src', 'packages/daemon'], { + cwd: repoRoot, + encoding: 'utf8', + }); return out .split('\n') .filter(Boolean) @@ -37,7 +42,7 @@ export function main(): number { if (violations.length === 0) { process.stdout.write( - `DI-seam guard: OK — ${files.length} production src/ files scanned, ` + + `DI-seam guard: OK — ${files.length} production src/ and daemon-package files scanned, ` + `${approved.length} approved seam(s) found, no unapproved seams.\n`, ); return 0; diff --git a/scripts/explain-command.ts b/scripts/explain-command.ts index e0d5a4e279..52e334e629 100644 --- a/scripts/explain-command.ts +++ b/scripts/explain-command.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { explainCommand, formatCommandExplanation } from '../src/cli/command-explain.ts'; -import { getDaemonRouteOwnerFiles } from '../src/daemon/route-owner-files.ts'; +import { getDaemonRouteOwnerFiles } from '@agent-device/daemon/route-owner-files'; const repoRoot = path.resolve(import.meta.dirname, '..'); export type ExplainCommandCliResult = { diff --git a/scripts/help-conformance-sample-outputs.mjs b/scripts/help-conformance-sample-outputs.mjs index db109ec6de..f808540979 100644 --- a/scripts/help-conformance-sample-outputs.mjs +++ b/scripts/help-conformance-sample-outputs.mjs @@ -83,7 +83,7 @@ Detected an overly complex or slow accessibility tree. Fell back to the private- }; // DEVICE_IN_USE from buildDeviceInUseBySessionError -// (src/daemon/session-recovery-hints.ts) — the parity test drives that exact producer. +// (packages/daemon/src/session-recovery-hints.ts) — the parity test drives that exact producer. export const DEVICE_IN_USE_SAMPLE = { command: `agent-device press 'label="Place order"' --settle`, output: `Error (DEVICE_IN_USE): Device is already in use by session "checkout". @@ -91,7 +91,7 @@ Hint: Run agent-device session list to inspect active sessions. To reuse this de }; // Enforced cross-daemon device claim conflict from -// src/daemon/device/device-claim-conflict.ts. This path is deliberately non-retriable: +// packages/daemon/src/device/device-claim-conflict.ts. This path is deliberately non-retriable: // the exact status command is the only safe next step while ownership is live. export const DEVICE_CLAIM_IN_USE_SAMPLE = { command: 'agent-device open Demo --platform android --serial emulator-5554', @@ -100,7 +100,7 @@ Hint: Inspect the owner with: agent-device device status --platform android --se }; // ADR 0014 mutation rejection from -// src/daemon/interaction/index.ts: a pinned ref minted from a +// packages/daemon/src/interaction/index.ts: a pinned ref minted from a // superseded generation is rejected before dispatch. The daemon strips the // `~s5` pin at the boundary (interaction-touch-targets.ts), so the message // names the plain ref; the hint is the precise resolveRefStalenessWarning. @@ -110,7 +110,7 @@ export const STALE_REF_SAMPLE = { Hint: Ref @e12 was minted from snapshot s5 but the session's ref frame is now s7 — re-run snapshot -i.`, }; -// AMBIGUOUS_MATCH from buildAmbiguousMatchError (src/daemon/selector-match-errors.ts) +// AMBIGUOUS_MATCH from buildAmbiguousMatchError (packages/daemon/src/selector-match-errors.ts) // — the parity test drives that exact producer. The by-design rejection // instead of silent disambiguation: #1597 made the candidate refs (ref, role, // label/identifier — the same compact rendering as snapshot -i) print diff --git a/scripts/integration-progress-model.ts b/scripts/integration-progress-model.ts index a40956f3b6..bd333954ba 100644 --- a/scripts/integration-progress-model.ts +++ b/scripts/integration-progress-model.ts @@ -10,7 +10,7 @@ const EMPTY_STATEMENT_COVERAGE = { covered: 0, pct: 0, total: 0 }; export function buildIntegrationProgressModel({ root = process.cwd() } = {}) { const coverageSummary = path.join(root, 'coverage/coverage-summary.json'); - const handlerTestDir = path.join(root, 'src/daemon/handlers/__tests__'); + const handlerTestDir = path.join(root, 'packages/daemon/src/handlers/__tests__'); const providerScenarioDir = path.join(root, 'test/integration/provider-scenarios'); const commandContractFiles = walkFiles(path.join(root, 'src/commands'), (file) => isCommandContractSource(file), diff --git a/scripts/layering/architecture-ownership.ts b/scripts/layering/architecture-ownership.ts index 42704c05c6..921d0665fb 100644 --- a/scripts/layering/architecture-ownership.ts +++ b/scripts/layering/architecture-ownership.ts @@ -1,3 +1,5 @@ +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; + type FacadeDeclaration = Readonly<{ root: string; exports: readonly string[]; @@ -12,7 +14,7 @@ export type LogicalModulePolicy = Readonly<{ }>; const DAEMON_SESSION_LIFECYCLE_FACADE = { - root: 'src/daemon/session-lifecycle/index.ts', + root: 'packages/daemon/src/session-lifecycle/index.ts', exports: [ 'SessionCloseCommandInput', 'SessionInventoryCommandInput', @@ -24,52 +26,52 @@ const DAEMON_SESSION_LIFECYCLE_FACADE = { } as const; const DAEMON_SESSION_OBSERVABILITY_FACADE = { - root: 'src/daemon/session-observability/index.ts', + root: 'packages/daemon/src/session-observability/index.ts', exports: ['SessionObservabilityCommandInput', 'handleSessionObservabilityCommands'], } as const; export const SESSION_LIFECYCLE_RETIRED_HANDLER_PATHS = [ - 'src/daemon/handlers/session-device-utils.ts', - 'src/daemon/handlers/session-runtime-admission.ts', - 'src/daemon/handlers/session-open.ts', - 'src/daemon/handlers/session-open-prepare.ts', - 'src/daemon/handlers/session-open-execution.ts', - 'src/daemon/handlers/session-open-foreground.ts', - 'src/daemon/handlers/session-open-surface.ts', - 'src/daemon/handlers/session-startup-metrics.ts', + 'packages/daemon/src/handlers/session-device-utils.ts', + 'packages/daemon/src/handlers/session-runtime-admission.ts', + 'packages/daemon/src/handlers/session-open.ts', + 'packages/daemon/src/handlers/session-open-prepare.ts', + 'packages/daemon/src/handlers/session-open-execution.ts', + 'packages/daemon/src/handlers/session-open-foreground.ts', + 'packages/daemon/src/handlers/session-open-surface.ts', + 'packages/daemon/src/handlers/session-startup-metrics.ts', ] as const; export const INTERACTION_RETIRED_HANDLER_PATHS = [ - 'src/daemon/handlers/find.ts', - 'src/daemon/handlers/find-match-ranking.ts', - 'src/daemon/handlers/find-match-resolution.ts', - 'src/daemon/handlers/find-target-capture.ts', - 'src/daemon/handlers/interaction.ts', - 'src/daemon/handlers/interaction-android-escape.ts', - 'src/daemon/handlers/interaction-gesture.ts', - 'src/daemon/handlers/interaction-gesture-response.ts', - 'src/daemon/handlers/interaction-ios-tap-outcome.ts', - 'src/daemon/handlers/interaction-targeting.ts', - 'src/daemon/handlers/interaction-touch.ts', - 'src/daemon/handlers/interaction-touch-android-freshness.ts', - 'src/daemon/handlers/interaction-touch-android-readiness.ts', - 'src/daemon/handlers/interaction-touch-direct-ios-eligibility.ts', - 'src/daemon/handlers/interaction-touch-direct-ios.ts', - 'src/daemon/handlers/interaction-touch-fill.ts', - 'src/daemon/handlers/interaction-touch-payload.ts', - 'src/daemon/handlers/interaction-touch-policy.ts', - 'src/daemon/handlers/interaction-touch-prepare.ts', - 'src/daemon/handlers/interaction-touch-press-admission.ts', - 'src/daemon/handlers/interaction-touch-press.ts', - 'src/daemon/handlers/interaction-touch-reference-frame.ts', - 'src/daemon/handlers/interaction-touch-response.ts', - 'src/daemon/handlers/interaction-touch-runtime.ts', - 'src/daemon/handlers/interaction-touch-targets.ts', - 'src/daemon/handlers/system-surface-disclosure.ts', + 'packages/daemon/src/handlers/find.ts', + 'packages/daemon/src/handlers/find-match-ranking.ts', + 'packages/daemon/src/handlers/find-match-resolution.ts', + 'packages/daemon/src/handlers/find-target-capture.ts', + 'packages/daemon/src/handlers/interaction.ts', + 'packages/daemon/src/handlers/interaction-android-escape.ts', + 'packages/daemon/src/handlers/interaction-gesture.ts', + 'packages/daemon/src/handlers/interaction-gesture-response.ts', + 'packages/daemon/src/handlers/interaction-ios-tap-outcome.ts', + 'packages/daemon/src/handlers/interaction-targeting.ts', + 'packages/daemon/src/handlers/interaction-touch.ts', + 'packages/daemon/src/handlers/interaction-touch-android-freshness.ts', + 'packages/daemon/src/handlers/interaction-touch-android-readiness.ts', + 'packages/daemon/src/handlers/interaction-touch-direct-ios-eligibility.ts', + 'packages/daemon/src/handlers/interaction-touch-direct-ios.ts', + 'packages/daemon/src/handlers/interaction-touch-fill.ts', + 'packages/daemon/src/handlers/interaction-touch-payload.ts', + 'packages/daemon/src/handlers/interaction-touch-policy.ts', + 'packages/daemon/src/handlers/interaction-touch-prepare.ts', + 'packages/daemon/src/handlers/interaction-touch-press-admission.ts', + 'packages/daemon/src/handlers/interaction-touch-press.ts', + 'packages/daemon/src/handlers/interaction-touch-reference-frame.ts', + 'packages/daemon/src/handlers/interaction-touch-response.ts', + 'packages/daemon/src/handlers/interaction-touch-runtime.ts', + 'packages/daemon/src/handlers/interaction-touch-targets.ts', + 'packages/daemon/src/handlers/system-surface-disclosure.ts', ] as const; const DAEMON_INTERACTION_FACADE = { - root: 'src/daemon/interaction/index.ts', + root: 'packages/daemon/src/interaction/index.ts', exports: [ 'FindRouteInput', 'InteractionRouteInput', @@ -86,16 +88,16 @@ const DAEMON_INTERACTION_FACADE = { } as const; export const SESSION_OBSERVABILITY_RETIRED_HANDLER_PATHS = [ - 'src/daemon/handlers/session-observability.ts', - 'src/daemon/handlers/session-perf-runtime.ts', - 'src/daemon/handlers/session-network.ts', - 'src/daemon/handlers/session-audio.ts', + 'packages/daemon/src/handlers/session-observability.ts', + 'packages/daemon/src/handlers/session-perf-runtime.ts', + 'packages/daemon/src/handlers/session-network.ts', + 'packages/daemon/src/handlers/session-audio.ts', ] as const; export const SNAPSHOT_EXECUTION_RETIRED_HANDLER_PATHS = [ - 'src/daemon/handlers/snapshot-capture.ts', - 'src/daemon/handlers/snapshot-interactor-capture.ts', - 'src/daemon/handlers/snapshot-session.ts', + 'packages/daemon/src/handlers/snapshot-capture.ts', + 'packages/daemon/src/handlers/snapshot-interactor-capture.ts', + 'packages/daemon/src/handlers/snapshot-session.ts', ] as const; export const LOGICAL_MODULE_POLICIES = [ @@ -103,7 +105,7 @@ export const LOGICAL_MODULE_POLICIES = [ name: 'ad-replay', roots: ['packages/ad-replay/src/'], forbiddenTargetRoots: [ - 'src/daemon/', + DAEMON_SOURCE_ROOT, 'src/providers/', 'src/compat/', 'packages/maestro/', @@ -114,7 +116,7 @@ export const LOGICAL_MODULE_POLICIES = [ name: 'maestro', roots: ['packages/maestro/src/'], forbiddenTargetRoots: [ - 'src/daemon/', + DAEMON_SOURCE_ROOT, 'src/providers/', 'packages/ad-replay/', 'packages/replay-port/', @@ -124,7 +126,7 @@ export const LOGICAL_MODULE_POLICIES = [ name: 'replay-test', roots: ['packages/replay-test/src/'], forbiddenTargetRoots: [ - 'src/daemon/', + DAEMON_SOURCE_ROOT, 'src/providers/', 'src/request/', 'src/compat/', @@ -136,25 +138,25 @@ export const LOGICAL_MODULE_POLICIES = [ { name: 'replay-port', roots: ['packages/replay-port/src/'], - forbiddenTargetRoots: ['src/daemon/', 'src/providers/', 'src/compat/'], + forbiddenTargetRoots: [DAEMON_SOURCE_ROOT, 'src/providers/', 'src/compat/'], }, { name: 'daemon-session-lifecycle', - roots: ['src/daemon/session-lifecycle/'], - forbiddenTargetRoots: ['src/daemon/handlers/'], + roots: ['packages/daemon/src/session-lifecycle/'], + forbiddenTargetRoots: ['packages/daemon/src/handlers/'], facade: DAEMON_SESSION_LIFECYCLE_FACADE, }, { name: 'daemon-interaction', - roots: ['src/daemon/interaction/'], + roots: ['packages/daemon/src/interaction/'], forbiddenTargetRoots: [], - internalForbiddenTargetRoots: ['src/daemon/handlers/'], + internalForbiddenTargetRoots: ['packages/daemon/src/handlers/'], facade: DAEMON_INTERACTION_FACADE, }, { name: 'daemon-session-observability', - roots: ['src/daemon/session-observability/'], - forbiddenTargetRoots: ['src/daemon/handlers/'], + roots: ['packages/daemon/src/session-observability/'], + forbiddenTargetRoots: ['packages/daemon/src/handlers/'], facade: DAEMON_SESSION_OBSERVABILITY_FACADE, }, ] as const satisfies readonly LogicalModulePolicy[]; @@ -190,7 +192,7 @@ export const ARCHITECTURE_OWNERSHIP = { { name: 'request-runtime-binding', kind: 'capability', - root: 'src/daemon/request-runtime-binding.ts', + root: 'packages/daemon/src/request-runtime-binding.ts', exports: [ 'BindDeviceRuntime', 'BindExactDeviceRuntime', @@ -205,7 +207,7 @@ export const ARCHITECTURE_OWNERSHIP = { { name: 'session-script-publication', kind: 'capability', - root: 'src/daemon/session-script-publication-capability.ts', + root: 'packages/daemon/src/session-script-publication-capability.ts', exports: [ 'abortAuthoringOnSecondOpen', 'applyRecordedSaveScriptFlags', @@ -224,13 +226,13 @@ export const ARCHITECTURE_OWNERSHIP = { { name: 'session-state-shape', kind: 'live-state-shape', - root: 'src/daemon/session-state.ts', + root: 'packages/daemon/src/session-state.ts', exports: ['SessionState'], }, { name: 'session-store-authority', kind: 'live-state-authority', - root: 'src/daemon/session-store.ts', + root: 'packages/daemon/src/session-store.ts', exports: ['SessionStore'], }, ], @@ -239,7 +241,7 @@ export const ARCHITECTURE_OWNERSHIP = { name: 'snapshot-policy', kind: 'executable-policy', roots: ['packages/capture-kit/src/snapshot/'], - forbiddenTargetRoots: ['src/daemon/'], + forbiddenTargetRoots: [DAEMON_SOURCE_ROOT], }, ], } as const; diff --git a/scripts/layering/check.ts b/scripts/layering/check.ts index d60ab64d9c..6e53134277 100644 --- a/scripts/layering/check.ts +++ b/scripts/layering/check.ts @@ -54,7 +54,7 @@ // brand casts inside those two modules, so a udid never runs outside the set that holds it. // - Over REQUEST-BOUND RUNTIME EXECUTION: facts remain the only admission authority and daemon // code cannot manufacture or repair a narrowed runtime proof (R66). -// - Over THE DAEMON'S INTERIOR: every production file under src/daemon/ is owned by exactly one +// - Over THE DAEMON'S INTERIOR: every production file under packages/daemon/src/ is owned by exactly one // layer of the manifest in scripts/layering/daemon-layers.ts, and no static edge reads up the // daemon-local order core < resources < execution < sessions < server (R81). The global spine // ranks all five layers at daemon-server's rank, so R5/R6/R80 are blind inside the zone. @@ -134,6 +134,7 @@ import { checkDaemonClientEntry } from './daemon-client-entry.ts'; import { checkDaemonLayers, readDaemonLayerManifest } from './daemon-layers.ts'; import { checkSessionAuthorityOverlay, handlerOwnedOverlay } from './session-authority-overlay.ts'; import { + DAEMON_SOURCE_ROOT, listTrackedPlatformZoneFiles, listTrackedProductionSources, listTrackedSrcUtilsFiles, @@ -281,7 +282,7 @@ function checkSessionStateOwnership(sources: ReadonlyMap): Layer return [ { rule: 'R7 session-state-ownership', - file: 'src/daemon/session-state.ts', + file: 'packages/daemon/src/session-state.ts', line: 1, message: 'no daemon module declares SessionState, so its ownership cannot be checked.', }, @@ -426,7 +427,8 @@ function report( `${ratchets.largestTypeCycle.length} files (R9); ${daemonModularitySummary(reference)}; ` + `${packageBoundariesSummary(repoRoot)}; ${platformPackagePolicySummary()}; ` + `runtime facts remain the only device-command admission authority and daemon code cannot ` + - `manufacture narrowed runtime proof (R66); R65 keeps production src/daemon free of ` + + `manufacture narrowed runtime proof (R66); R65 keeps production packages/daemon/src ` + + `free of ` + `concrete platform imports in every executable and type-only form; ` + `no production daemon file reaches the root platform-runtime family or a hub that ` + `does (R76); and the handler-owned SessionState/SessionStore ` + @@ -584,7 +586,7 @@ export const LAYERING_RULES: Readonly> = { ), 'daemon-layers': (context) => checkDaemonLayers( - context.sourceFiles.filter((file) => file.startsWith('src/daemon/')), + context.sourceFiles.filter((file) => file.startsWith(DAEMON_SOURCE_ROOT)), context.edges, readDaemonLayerManifest(repoRoot), ), diff --git a/scripts/layering/client-only-subpaths.test.ts b/scripts/layering/client-only-subpaths.test.ts index 6902090c87..6cc4903a96 100644 --- a/scripts/layering/client-only-subpaths.test.ts +++ b/scripts/layering/client-only-subpaths.test.ts @@ -36,7 +36,6 @@ test('the caller-side replay source subpaths are denied to daemon production cod : checkPackageInternalSites(daemon, sites(file), [], true); for (const file of [ 'src/commands/replay/index.ts', - 'src/daemon/__tests__/replay.test.ts', 'packages/daemon/src/__tests__/replay.test.ts', ]) { assert.deepEqual( @@ -46,7 +45,6 @@ test('the caller-side replay source subpaths are denied to daemon production cod ); } for (const file of [ - 'src/daemon/replay-runtime.ts', 'packages/daemon/src/replay-runtime.ts', 'src/daemon.ts', 'src/daemon-composition.ts', diff --git a/scripts/layering/daemon-client-entry.test.ts b/scripts/layering/daemon-client-entry.test.ts index 63bb752d0e..1ebca6d61a 100644 --- a/scripts/layering/daemon-client-entry.test.ts +++ b/scripts/layering/daemon-client-entry.test.ts @@ -49,18 +49,29 @@ test('a client import of a non-daemon module is not daemon-client entry surface' test('a planted runtime import of daemon internals by the client is red', () => { const violations = checkDaemonClientEntry([ ...recordedWireEdges(), - clientEdge('src/daemon-client/daemon-client-metadata.ts', 'src/daemon/config.ts', 'value'), + clientEdge( + 'src/daemon-client/daemon-client-metadata.ts', + 'packages/daemon/src/config.ts', + 'value', + ), ]); assert.equal(violations.length, 1); assert.equal(violations[0]!.rule, DAEMON_CLIENT_ENTRY_RULE); assert.match(violations[0]!.message, /value-imports daemon internals/); - assert.match(violations[0]!.message, /daemon-client-metadata\.ts -> src\/daemon\/config\.ts/); + assert.match( + violations[0]!.message, + /daemon-client-metadata\.ts -> packages\/daemon\/src\/config\.ts/, + ); }); test('a planted dynamic import of daemon internals by the client is red', () => { const violations = checkDaemonClientEntry([ ...recordedWireEdges(), - clientEdge('src/daemon-client/daemon-client-progress.ts', 'src/daemon/config.ts', 'dynamic'), + clientEdge( + 'src/daemon-client/daemon-client-progress.ts', + 'packages/daemon/src/config.ts', + 'dynamic', + ), ]); assert.equal(violations.length, 1); assert.match(violations[0]!.message, /dynamic-imports daemon internals/); @@ -69,7 +80,11 @@ test('a planted dynamic import of daemon internals by the client is red', () => test('a runtime import is red even when the same pair is a recorded type edge', () => { const violations = checkDaemonClientEntry([ ...recordedWireEdges(), - clientEdge('src/daemon-client/daemon-client-rpc.ts', 'src/daemon/daemon-request.ts', 'value'), + clientEdge( + 'src/daemon-client/daemon-client-rpc.ts', + 'packages/daemon/src/daemon-request.ts', + 'value', + ), ]); assert.equal(violations.length, 1); assert.match(violations[0]!.message, /value-imports daemon internals/); @@ -78,17 +93,20 @@ test('a runtime import is red even when the same pair is a recorded type edge', test('an unrecorded type import of daemon internals is red', () => { const violations = checkDaemonClientEntry([ ...recordedWireEdges(), - clientEdge('src/daemon-client/daemon-launch-spec.ts', 'src/daemon/daemon-request.ts'), + clientEdge('src/daemon-client/daemon-launch-spec.ts', 'packages/daemon/src/daemon-request.ts'), ]); assert.equal(violations.length, 1); assert.match(violations[0]!.message, /unclassified daemon-client import of daemon internals/); - assert.match(violations[0]!.message, /daemon-launch-spec\.ts -> src\/daemon\/daemon-request\.ts/); + assert.match( + violations[0]!.message, + /daemon-launch-spec\.ts -> packages\/daemon\/src\/daemon-request\.ts/, + ); }); test('a type import of a daemon module other than the recorded type is red', () => { const recorded = DAEMON_CLIENT_ENTRY_EDGES.map((edge) => edge.file === 'src/daemon-client/daemon-client.ts' - ? clientEdge(edge.file, 'src/daemon/session-state.ts', 'type') + ? clientEdge(edge.file, 'packages/daemon/src/session-state.ts', 'type') : clientEdge(edge.file, edge.target, 'type'), ); const violations = checkDaemonClientEntry(recorded); diff --git a/scripts/layering/daemon-client-entry.ts b/scripts/layering/daemon-client-entry.ts index 1b04c923e7..f1cf50ed4a 100644 --- a/scripts/layering/daemon-client-entry.ts +++ b/scripts/layering/daemon-client-entry.ts @@ -1,11 +1,12 @@ import type { LayeringViolation, ResolvedImportEdge } from './model.ts'; +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; // The declared daemon-entry surface for the client (#2559). `src/daemon-client/**` composes the // daemon over the network, not over its module graph, so it is NOT an entry point into daemon // internals: the process root composition is. Every on-disk or protocol contract the client shares // with the daemon (state-dir/transport resolution, pidfile liveness, the repair tombstone, the // progress framing) therefore lives below both sides — since the daemon-contracts extraction, in -// `packages/daemon-contracts` — not under `src/daemon/`, and the client +// `packages/daemon-contracts` — not under `packages/daemon/src/`, and the client // reaches it there. What remains is the client reading the daemon's request/response vocabulary — // the `DaemonRequest`/`DaemonResponse` types that anchor the ADR 0006 wire surface — recorded here, // per measured `file -> target` edge, and only as a type-only import. A runtime (value or dynamic) @@ -36,37 +37,37 @@ export type DaemonClientEntryEdge = Readonly<{ export const DAEMON_CLIENT_ENTRY_EDGES: readonly DaemonClientEntryEdge[] = [ { file: 'src/daemon-client/daemon-client.ts', - target: 'src/daemon/daemon-request.ts', + target: 'packages/daemon/src/daemon-request.ts', rationale: REQUEST_RATIONALE, }, { file: 'src/daemon-client/daemon-client-lifecycle.ts', - target: 'src/daemon/daemon-request.ts', + target: 'packages/daemon/src/daemon-request.ts', rationale: REQUEST_RATIONALE, }, { file: 'src/daemon-client/daemon-client-lease-beat.ts', - target: 'src/daemon/daemon-request.ts', + target: 'packages/daemon/src/daemon-request.ts', rationale: REQUEST_RATIONALE, }, { file: 'src/daemon-client/daemon-client-liveness-probe.ts', - target: 'src/daemon/daemon-request.ts', + target: 'packages/daemon/src/daemon-request.ts', rationale: REQUEST_RATIONALE, }, { file: 'src/daemon-client/daemon-client-progress.ts', - target: 'src/daemon/daemon-request.ts', + target: 'packages/daemon/src/daemon-request.ts', rationale: REQUEST_RATIONALE, }, { file: 'src/daemon-client/daemon-client-rpc.ts', - target: 'src/daemon/daemon-request.ts', + target: 'packages/daemon/src/daemon-request.ts', rationale: REQUEST_RATIONALE, }, { file: 'src/daemon-client/daemon-client-transport.ts', - target: 'src/daemon/daemon-request.ts', + target: 'packages/daemon/src/daemon-request.ts', rationale: REQUEST_RATIONALE, }, ] as const; @@ -94,7 +95,7 @@ export function checkDaemonClientEntry(edges: readonly ResolvedImportEdge[]): La const measured = new Map(); for (const edge of edges) { if (!edge.file.startsWith('src/daemon-client/')) continue; - if (!edge.target.startsWith('src/daemon/')) continue; + if (!edge.target.startsWith(DAEMON_SOURCE_ROOT)) continue; const key = keyOf(edge.file, edge.target); const entry = measured.get(key) ?? { file: edge.file, @@ -122,7 +123,7 @@ export function checkDaemonClientEntry(edges: readonly ResolvedImportEdge[]): La `the daemon client ${entry.runtimeKind} daemon internals: ${key}. The client composes the ` + `daemon over the network, not its module graph. Move the shared contract to ` + `packages/daemon-contracts (or read the DaemonRequest/DaemonResponse types in ` + - `src/daemon/daemon-request.ts as a type).`, + `packages/daemon/src/daemon-request.ts as a type).`, }); seen.add(key); continue; diff --git a/scripts/layering/daemon-layer-manifest.json b/scripts/layering/daemon-layer-manifest.json index 98971eb8cf..584f7f818d 100644 --- a/scripts/layering/daemon-layer-manifest.json +++ b/scripts/layering/daemon-layer-manifest.json @@ -1,305 +1,305 @@ { "daemon-core": [ - "src/daemon/capture-disclosure.ts", - "src/daemon/config.ts", - "src/daemon/context.ts", - "src/daemon/daemon-command-registry.ts", - "src/daemon/daemon-policy.ts", - "src/daemon/daemon-request.ts", - "src/daemon/deferred-interaction-outcome.ts", - "src/daemon/device/device-ready.ts", - "src/daemon/device/device-selector-intent.ts", - "src/daemon/direct-ios-selector.ts", - "src/daemon/dispatch-context.ts", - "src/daemon/execution-plan.ts", - "src/daemon/fill-backend-result.ts", - "src/daemon/generic-leaf-execution.ts", - "src/daemon/gesture-runtime.ts", - "src/daemon/interaction-surface-signature.ts", - "src/daemon/interaction/internal/interaction-touch-direct-ios-eligibility.ts", - "src/daemon/interaction/internal/types.ts", - "src/daemon/interactor-resolution.ts", - "src/daemon/ios-app-session-hint.ts", - "src/daemon/lease-context.ts", - "src/daemon/managed-session-artifact-path.ts", - "src/daemon/platform-owner-lifecycle.ts", - "src/daemon/platform-resource-cleanup.ts", - "src/daemon/platform-services.ts", - "src/daemon/provider-device-admission.ts", - "src/daemon/recording-gesture-events.ts", - "src/daemon/recording-gestures.ts", - "src/daemon/recording-timing.ts", - "src/daemon/recording-values.ts", - "src/daemon/ref-frame-slot.ts", - "src/daemon/ref-frame.ts", - "src/daemon/request-dispatch-ledger.ts", - "src/daemon/request-runtime-binding.ts", - "src/daemon/runtime-admission.ts", - "src/daemon/runtime-operation-effects.ts", - "src/daemon/runtime-session.ts", - "src/daemon/selector-operation-binding.ts", - "src/daemon/selector-recording.ts", - "src/daemon/session-action-recorder.ts", - "src/daemon/session-artifact-paths.ts", - "src/daemon/session-capture-binding.ts", - "src/daemon/session-idle-tombstone.ts", - "src/daemon/session-recovery-hints.ts", - "src/daemon/session-replay-transaction.ts", - "src/daemon/session-runtime-admission.ts", - "src/daemon/session-script-active-publication.ts", - "src/daemon/session-script-publication-capability.ts", - "src/daemon/session-script-publication-state.ts", - "src/daemon/session-script-writer.ts", - "src/daemon/session-selector.ts", - "src/daemon/session-snapshot-freshness.ts", - "src/daemon/session-state.ts", - "src/daemon/session-store.ts", - "src/daemon/session-tenant-scope.ts", - "src/daemon/settle-observation-capture.ts", - "src/daemon/snapshot-capture.ts", - "src/daemon/snapshot-interactor-capture.ts", - "src/daemon/snapshot-runtime-binding.ts", - "src/daemon/snapshot-runtime-capture-input.ts", - "src/daemon/snapshot-session.ts", - "src/daemon/tenant-owned-entry.ts", - "src/daemon/touch-runtime.ts" + "packages/daemon/src/capture-disclosure.ts", + "packages/daemon/src/config.ts", + "packages/daemon/src/context.ts", + "packages/daemon/src/daemon-command-registry.ts", + "packages/daemon/src/daemon-policy.ts", + "packages/daemon/src/daemon-request.ts", + "packages/daemon/src/deferred-interaction-outcome.ts", + "packages/daemon/src/device/device-ready.ts", + "packages/daemon/src/device/device-selector-intent.ts", + "packages/daemon/src/direct-ios-selector.ts", + "packages/daemon/src/dispatch-context.ts", + "packages/daemon/src/execution-plan.ts", + "packages/daemon/src/fill-backend-result.ts", + "packages/daemon/src/generic-leaf-execution.ts", + "packages/daemon/src/gesture-runtime.ts", + "packages/daemon/src/interaction-surface-signature.ts", + "packages/daemon/src/interaction/internal/interaction-touch-direct-ios-eligibility.ts", + "packages/daemon/src/interaction/internal/types.ts", + "packages/daemon/src/interactor-resolution.ts", + "packages/daemon/src/ios-app-session-hint.ts", + "packages/daemon/src/lease-context.ts", + "packages/daemon/src/managed-session-artifact-path.ts", + "packages/daemon/src/platform-owner-lifecycle.ts", + "packages/daemon/src/platform-resource-cleanup.ts", + "packages/daemon/src/platform-services.ts", + "packages/daemon/src/provider-device-admission.ts", + "packages/daemon/src/recording-gesture-events.ts", + "packages/daemon/src/recording-gestures.ts", + "packages/daemon/src/recording-timing.ts", + "packages/daemon/src/recording-values.ts", + "packages/daemon/src/ref-frame-slot.ts", + "packages/daemon/src/ref-frame.ts", + "packages/daemon/src/request-dispatch-ledger.ts", + "packages/daemon/src/request-runtime-binding.ts", + "packages/daemon/src/runtime-admission.ts", + "packages/daemon/src/runtime-operation-effects.ts", + "packages/daemon/src/runtime-session.ts", + "packages/daemon/src/selector-operation-binding.ts", + "packages/daemon/src/selector-recording.ts", + "packages/daemon/src/session-action-recorder.ts", + "packages/daemon/src/session-artifact-paths.ts", + "packages/daemon/src/session-capture-binding.ts", + "packages/daemon/src/session-idle-tombstone.ts", + "packages/daemon/src/session-recovery-hints.ts", + "packages/daemon/src/session-replay-transaction.ts", + "packages/daemon/src/session-runtime-admission.ts", + "packages/daemon/src/session-script-active-publication.ts", + "packages/daemon/src/session-script-publication-capability.ts", + "packages/daemon/src/session-script-publication-state.ts", + "packages/daemon/src/session-script-writer.ts", + "packages/daemon/src/session-selector.ts", + "packages/daemon/src/session-snapshot-freshness.ts", + "packages/daemon/src/session-state.ts", + "packages/daemon/src/session-store.ts", + "packages/daemon/src/session-tenant-scope.ts", + "packages/daemon/src/settle-observation-capture.ts", + "packages/daemon/src/snapshot-capture.ts", + "packages/daemon/src/snapshot-interactor-capture.ts", + "packages/daemon/src/snapshot-runtime-binding.ts", + "packages/daemon/src/snapshot-runtime-capture-input.ts", + "packages/daemon/src/snapshot-session.ts", + "packages/daemon/src/tenant-owned-entry.ts", + "packages/daemon/src/touch-runtime.ts" ], "daemon-resources": [ - "src/daemon/app-log-admission-ledger.ts", - "src/daemon/app-log-files.ts", - "src/daemon/app-log-resource-recovery.ts", - "src/daemon/app-log-resource-store.ts", - "src/daemon/app-log-session-resource.ts", - "src/daemon/app-log-start-preflight.ts", - "src/daemon/app-log.ts", - "src/daemon/artifact-tracking.ts", - "src/daemon/device/claim-recovery-gateway.ts", - "src/daemon/device/device-claim-admission.ts", - "src/daemon/device/device-claim-conflict.ts", - "src/daemon/device/device-claim-inspection.ts", - "src/daemon/device/device-claim-paths.ts", - "src/daemon/device/device-claim-reboot.ts", - "src/daemon/device/device-claim-record.ts", - "src/daemon/device/device-claim-rule.ts", - "src/daemon/device/device-claim-settlement.ts", - "src/daemon/device/device-claim-store.ts", - "src/daemon/device/device-claims.ts", - "src/daemon/device/device-mutation-drain.ts", - "src/daemon/human-control-contract.ts", - "src/daemon/lease-in-flight-work.ts", - "src/daemon/lease-registry-scope.ts", - "src/daemon/lease-registry.ts", - "src/daemon/macos-app-lease.ts", - "src/daemon/provider-session-ownership.ts", - "src/daemon/session-device-resolution.ts" + "packages/daemon/src/app-log-admission-ledger.ts", + "packages/daemon/src/app-log-files.ts", + "packages/daemon/src/app-log-resource-recovery.ts", + "packages/daemon/src/app-log-resource-store.ts", + "packages/daemon/src/app-log-session-resource.ts", + "packages/daemon/src/app-log-start-preflight.ts", + "packages/daemon/src/app-log.ts", + "packages/daemon/src/artifact-tracking.ts", + "packages/daemon/src/device/claim-recovery-gateway.ts", + "packages/daemon/src/device/device-claim-admission.ts", + "packages/daemon/src/device/device-claim-conflict.ts", + "packages/daemon/src/device/device-claim-inspection.ts", + "packages/daemon/src/device/device-claim-paths.ts", + "packages/daemon/src/device/device-claim-reboot.ts", + "packages/daemon/src/device/device-claim-record.ts", + "packages/daemon/src/device/device-claim-rule.ts", + "packages/daemon/src/device/device-claim-settlement.ts", + "packages/daemon/src/device/device-claim-store.ts", + "packages/daemon/src/device/device-claims.ts", + "packages/daemon/src/device/device-mutation-drain.ts", + "packages/daemon/src/human-control-contract.ts", + "packages/daemon/src/lease-in-flight-work.ts", + "packages/daemon/src/lease-registry-scope.ts", + "packages/daemon/src/lease-registry.ts", + "packages/daemon/src/macos-app-lease.ts", + "packages/daemon/src/provider-session-ownership.ts", + "packages/daemon/src/session-device-resolution.ts" ], "daemon-execution": [ - "src/daemon/android-foreground-surface.ts", - "src/daemon/android-snapshot-timeout-evidence.ts", - "src/daemon/android-system-dialog.ts", - "src/daemon/app-event-runtime.ts", - "src/daemon/app-events.ts", - "src/daemon/apps-runtime.ts", - "src/daemon/back-runtime.ts", - "src/daemon/focus-runtime.ts", - "src/daemon/fold-runtime.ts", - "src/daemon/generic-runtime-execution.ts", - "src/daemon/generic-settle.ts", - "src/daemon/handlers/react-native.ts", - "src/daemon/handlers/session-clipboard.ts", - "src/daemon/handlers/session-selector-dispatch.ts", - "src/daemon/handlers/snapshot-alert.ts", - "src/daemon/handlers/snapshot-settings.ts", - "src/daemon/interaction/index.ts", - "src/daemon/interaction/internal/find-match-ranking.ts", - "src/daemon/interaction/internal/find-match-resolution.ts", - "src/daemon/interaction/internal/find-target-capture.ts", - "src/daemon/interaction/internal/find.ts", - "src/daemon/interaction/internal/interaction-android-escape.ts", - "src/daemon/interaction/internal/interaction-common.ts", - "src/daemon/interaction/internal/interaction-flags.ts", - "src/daemon/interaction/internal/interaction-gesture-response.ts", - "src/daemon/interaction/internal/interaction-gesture.ts", - "src/daemon/interaction/internal/interaction-ios-tap-outcome.ts", - "src/daemon/interaction/internal/interaction-recorded-input.ts", - "src/daemon/interaction/internal/interaction-ref-policy.ts", - "src/daemon/interaction/internal/interaction-response-data-transform.ts", - "src/daemon/interaction/internal/interaction-response.ts", - "src/daemon/interaction/internal/interaction-runtime.ts", - "src/daemon/interaction/internal/interaction-session.ts", - "src/daemon/interaction/internal/interaction-snapshot.ts", - "src/daemon/interaction/internal/interaction-targeting.ts", - "src/daemon/interaction/internal/interaction-touch-android-freshness.ts", - "src/daemon/interaction/internal/interaction-touch-android-readiness.ts", - "src/daemon/interaction/internal/interaction-touch-direct-ios.ts", - "src/daemon/interaction/internal/interaction-touch-fill.ts", - "src/daemon/interaction/internal/interaction-touch-payload.ts", - "src/daemon/interaction/internal/interaction-touch-policy.ts", - "src/daemon/interaction/internal/interaction-touch-prepare.ts", - "src/daemon/interaction/internal/interaction-touch-press-admission.ts", - "src/daemon/interaction/internal/interaction-touch-press.ts", - "src/daemon/interaction/internal/interaction-touch-reference-frame.ts", - "src/daemon/interaction/internal/interaction-touch-response.ts", - "src/daemon/interaction/internal/interaction-touch-runtime.ts", - "src/daemon/interaction/internal/interaction-touch-targets.ts", - "src/daemon/interaction/internal/interaction.ts", - "src/daemon/internal-observation.ts", - "src/daemon/keyboard-runtime.ts", - "src/daemon/offscreen-target-probe.ts", - "src/daemon/orientation-runtime.ts", - "src/daemon/ref-positionals.ts", - "src/daemon/ref-snapshot-flag-policy.ts", - "src/daemon/request-dispatch-disclosure.ts", - "src/daemon/request-generic-dispatch.ts", - "src/daemon/runtime-artifacts.ts", - "src/daemon/runtime-policy.ts", - "src/daemon/screenshot-crop-target.ts", - "src/daemon/screenshot-crop.ts", - "src/daemon/screenshot-runtime-binding.ts", - "src/daemon/screenshot-runtime.ts", - "src/daemon/scroll-movement.ts", - "src/daemon/scroll-runtime.ts", - "src/daemon/scroll-until.ts", - "src/daemon/selector-capture-binding.ts", - "src/daemon/selector-capture-runtime.ts", - "src/daemon/selector-match-errors.ts", - "src/daemon/selector-runtime-backend.ts", - "src/daemon/selector-runtime.ts", - "src/daemon/selector-text-runtime.ts", - "src/daemon/session-snapshot.ts", - "src/daemon/snapshot-timeout-evidence.ts", - "src/daemon/sparse-fallback-screenshot.ts", - "src/daemon/system-button-runtime.ts", - "src/daemon/tv-remote-runtime.ts", - "src/daemon/type-target-warning.ts", - "src/daemon/type-text-runtime.ts", - "src/daemon/viewport-runtime.ts", - "src/daemon/wait-current-surface.ts", - "src/daemon/wait-runtime.ts" + "packages/daemon/src/android-foreground-surface.ts", + "packages/daemon/src/android-snapshot-timeout-evidence.ts", + "packages/daemon/src/android-system-dialog.ts", + "packages/daemon/src/app-event-runtime.ts", + "packages/daemon/src/app-events.ts", + "packages/daemon/src/apps-runtime.ts", + "packages/daemon/src/back-runtime.ts", + "packages/daemon/src/focus-runtime.ts", + "packages/daemon/src/fold-runtime.ts", + "packages/daemon/src/generic-runtime-execution.ts", + "packages/daemon/src/generic-settle.ts", + "packages/daemon/src/handlers/react-native.ts", + "packages/daemon/src/handlers/session-clipboard.ts", + "packages/daemon/src/handlers/session-selector-dispatch.ts", + "packages/daemon/src/handlers/snapshot-alert.ts", + "packages/daemon/src/handlers/snapshot-settings.ts", + "packages/daemon/src/interaction/index.ts", + "packages/daemon/src/interaction/internal/find-match-ranking.ts", + "packages/daemon/src/interaction/internal/find-match-resolution.ts", + "packages/daemon/src/interaction/internal/find-target-capture.ts", + "packages/daemon/src/interaction/internal/find.ts", + "packages/daemon/src/interaction/internal/interaction-android-escape.ts", + "packages/daemon/src/interaction/internal/interaction-common.ts", + "packages/daemon/src/interaction/internal/interaction-flags.ts", + "packages/daemon/src/interaction/internal/interaction-gesture-response.ts", + "packages/daemon/src/interaction/internal/interaction-gesture.ts", + "packages/daemon/src/interaction/internal/interaction-ios-tap-outcome.ts", + "packages/daemon/src/interaction/internal/interaction-recorded-input.ts", + "packages/daemon/src/interaction/internal/interaction-ref-policy.ts", + "packages/daemon/src/interaction/internal/interaction-response-data-transform.ts", + "packages/daemon/src/interaction/internal/interaction-response.ts", + "packages/daemon/src/interaction/internal/interaction-runtime.ts", + "packages/daemon/src/interaction/internal/interaction-session.ts", + "packages/daemon/src/interaction/internal/interaction-snapshot.ts", + "packages/daemon/src/interaction/internal/interaction-targeting.ts", + "packages/daemon/src/interaction/internal/interaction-touch-android-freshness.ts", + "packages/daemon/src/interaction/internal/interaction-touch-android-readiness.ts", + "packages/daemon/src/interaction/internal/interaction-touch-direct-ios.ts", + "packages/daemon/src/interaction/internal/interaction-touch-fill.ts", + "packages/daemon/src/interaction/internal/interaction-touch-payload.ts", + "packages/daemon/src/interaction/internal/interaction-touch-policy.ts", + "packages/daemon/src/interaction/internal/interaction-touch-prepare.ts", + "packages/daemon/src/interaction/internal/interaction-touch-press-admission.ts", + "packages/daemon/src/interaction/internal/interaction-touch-press.ts", + "packages/daemon/src/interaction/internal/interaction-touch-reference-frame.ts", + "packages/daemon/src/interaction/internal/interaction-touch-response.ts", + "packages/daemon/src/interaction/internal/interaction-touch-runtime.ts", + "packages/daemon/src/interaction/internal/interaction-touch-targets.ts", + "packages/daemon/src/interaction/internal/interaction.ts", + "packages/daemon/src/internal-observation.ts", + "packages/daemon/src/keyboard-runtime.ts", + "packages/daemon/src/offscreen-target-probe.ts", + "packages/daemon/src/orientation-runtime.ts", + "packages/daemon/src/ref-positionals.ts", + "packages/daemon/src/ref-snapshot-flag-policy.ts", + "packages/daemon/src/request-dispatch-disclosure.ts", + "packages/daemon/src/request-generic-dispatch.ts", + "packages/daemon/src/runtime-artifacts.ts", + "packages/daemon/src/runtime-policy.ts", + "packages/daemon/src/screenshot-crop-target.ts", + "packages/daemon/src/screenshot-crop.ts", + "packages/daemon/src/screenshot-runtime-binding.ts", + "packages/daemon/src/screenshot-runtime.ts", + "packages/daemon/src/scroll-movement.ts", + "packages/daemon/src/scroll-runtime.ts", + "packages/daemon/src/scroll-until.ts", + "packages/daemon/src/selector-capture-binding.ts", + "packages/daemon/src/selector-capture-runtime.ts", + "packages/daemon/src/selector-match-errors.ts", + "packages/daemon/src/selector-runtime-backend.ts", + "packages/daemon/src/selector-runtime.ts", + "packages/daemon/src/selector-text-runtime.ts", + "packages/daemon/src/session-snapshot.ts", + "packages/daemon/src/snapshot-timeout-evidence.ts", + "packages/daemon/src/sparse-fallback-screenshot.ts", + "packages/daemon/src/system-button-runtime.ts", + "packages/daemon/src/tv-remote-runtime.ts", + "packages/daemon/src/type-target-warning.ts", + "packages/daemon/src/type-text-runtime.ts", + "packages/daemon/src/viewport-runtime.ts", + "packages/daemon/src/wait-current-surface.ts", + "packages/daemon/src/wait-runtime.ts" ], "daemon-sessions": [ - "src/daemon/application-lifecycle-execution.ts", - "src/daemon/device/device-claim-reconciliation.ts", - "src/daemon/device/device-targets.ts", - "src/daemon/dispatch-payload.ts", - "src/daemon/handlers/human-control.ts", - "src/daemon/handlers/lease.ts", - "src/daemon/handlers/record-runtime-request.ts", - "src/daemon/handlers/record-runtime-response.ts", - "src/daemon/handlers/record-runtime.ts", - "src/daemon/handlers/record-trace.ts", - "src/daemon/handlers/session-app-deployment-route.ts", - "src/daemon/handlers/session-app-deployment.ts", - "src/daemon/handlers/session-app-source-deployment.ts", - "src/daemon/handlers/session-batch.ts", - "src/daemon/handlers/session-appstate-apple-session.ts", - "src/daemon/handlers/session-appstate-device-runtime.ts", - "src/daemon/handlers/session-appstate.ts", - "src/daemon/handlers/session-boot.ts", - "src/daemon/handlers/session-command-input.ts", - "src/daemon/handlers/session-device-status-response.ts", - "src/daemon/handlers/session-doctor-app.ts", - "src/daemon/handlers/session-doctor-device.ts", - "src/daemon/handlers/session-doctor-metro.ts", - "src/daemon/handlers/session-doctor-options.ts", - "src/daemon/handlers/session-doctor-output.ts", - "src/daemon/handlers/session-doctor-types.ts", - "src/daemon/handlers/session-doctor.ts", - "src/daemon/handlers/session-prepare.ts", - "src/daemon/handlers/session-replay-command.ts", - "src/daemon/handlers/session-replay-video-owner.ts", - "src/daemon/handlers/session-runtime-command.ts", - "src/daemon/handlers/session-runtime-port-reverse.ts", - "src/daemon/handlers/session-script-publication.ts", - "src/daemon/handlers/session-shutdown.ts", - "src/daemon/handlers/session.ts", - "src/daemon/handlers/snapshot.ts", - "src/daemon/handlers/trace-runtime.ts", - "src/daemon/install-source-resolution.ts", - "src/daemon/lease-lifecycle.ts", - "src/daemon/materialized-path-registry.ts", - "src/daemon/open-device-contention-wait.ts", - "src/daemon/payload-input.ts", - "src/daemon/request-admission.ts", - "src/daemon/request-handler-chain.ts", - "src/daemon/request-recording-health.ts", - "src/daemon/route-owner-files.ts", - "src/daemon/server/daemon-idle-reap.ts", - "src/daemon/session-lifecycle/index.ts", - "src/daemon/session-lifecycle/internal/inventory.ts", - "src/daemon/session-lifecycle/internal/session-close-lifecycle-teardown.ts", - "src/daemon/session-lifecycle/internal/session-close-runtime-admission.ts", - "src/daemon/session-lifecycle/internal/session-close-script.ts", - "src/daemon/session-lifecycle/internal/session-close.ts", - "src/daemon/session-lifecycle/internal/session-open-execution.ts", - "src/daemon/session-lifecycle/internal/session-open-foreground.ts", - "src/daemon/session-lifecycle/internal/session-open-prepare.ts", - "src/daemon/session-lifecycle/internal/session-open-state.ts", - "src/daemon/session-lifecycle/internal/session-open-surface.ts", - "src/daemon/session-lifecycle/internal/session-open-warnings.ts", - "src/daemon/session-lifecycle/internal/session-open.ts", - "src/daemon/session-lifecycle/internal/session-startup-metrics.ts", - "src/daemon/session-observability/index.ts", - "src/daemon/session-observability/internal/session-audio.ts", - "src/daemon/session-observability/internal/session-network.ts", - "src/daemon/session-observability/internal/session-observability.ts", - "src/daemon/session-observability/internal/session-perf-runtime.ts", - "src/daemon/session-replay-coordinator.ts", - "src/daemon/session-routing.ts", - "src/daemon/session-runtime.ts", - "src/daemon/session-teardown-budget.ts", - "src/daemon/session-teardown.ts", - "src/daemon/snapshot-command-runtime.ts", - "src/daemon/snapshot-diff-runtime.ts", - "src/daemon/snapshot-quality-latch.ts", - "src/daemon/snapshot-runtime.ts", - "src/daemon/startup-deadline.ts", - "src/daemon/web-session-names.ts" + "packages/daemon/src/application-lifecycle-execution.ts", + "packages/daemon/src/device/device-claim-reconciliation.ts", + "packages/daemon/src/device/device-targets.ts", + "packages/daemon/src/dispatch-payload.ts", + "packages/daemon/src/handlers/human-control.ts", + "packages/daemon/src/handlers/lease.ts", + "packages/daemon/src/handlers/record-runtime-request.ts", + "packages/daemon/src/handlers/record-runtime-response.ts", + "packages/daemon/src/handlers/record-runtime.ts", + "packages/daemon/src/handlers/record-trace.ts", + "packages/daemon/src/handlers/session-app-deployment-route.ts", + "packages/daemon/src/handlers/session-app-deployment.ts", + "packages/daemon/src/handlers/session-app-source-deployment.ts", + "packages/daemon/src/handlers/session-batch.ts", + "packages/daemon/src/handlers/session-appstate-apple-session.ts", + "packages/daemon/src/handlers/session-appstate-device-runtime.ts", + "packages/daemon/src/handlers/session-appstate.ts", + "packages/daemon/src/handlers/session-boot.ts", + "packages/daemon/src/handlers/session-command-input.ts", + "packages/daemon/src/handlers/session-device-status-response.ts", + "packages/daemon/src/handlers/session-doctor-app.ts", + "packages/daemon/src/handlers/session-doctor-device.ts", + "packages/daemon/src/handlers/session-doctor-metro.ts", + "packages/daemon/src/handlers/session-doctor-options.ts", + "packages/daemon/src/handlers/session-doctor-output.ts", + "packages/daemon/src/handlers/session-doctor-types.ts", + "packages/daemon/src/handlers/session-doctor.ts", + "packages/daemon/src/handlers/session-prepare.ts", + "packages/daemon/src/handlers/session-replay-command.ts", + "packages/daemon/src/handlers/session-replay-video-owner.ts", + "packages/daemon/src/handlers/session-runtime-command.ts", + "packages/daemon/src/handlers/session-runtime-port-reverse.ts", + "packages/daemon/src/handlers/session-script-publication.ts", + "packages/daemon/src/handlers/session-shutdown.ts", + "packages/daemon/src/handlers/session.ts", + "packages/daemon/src/handlers/snapshot.ts", + "packages/daemon/src/handlers/trace-runtime.ts", + "packages/daemon/src/install-source-resolution.ts", + "packages/daemon/src/lease-lifecycle.ts", + "packages/daemon/src/materialized-path-registry.ts", + "packages/daemon/src/open-device-contention-wait.ts", + "packages/daemon/src/payload-input.ts", + "packages/daemon/src/request-admission.ts", + "packages/daemon/src/request-handler-chain.ts", + "packages/daemon/src/request-recording-health.ts", + "packages/daemon/src/route-owner-files.ts", + "packages/daemon/src/server/daemon-idle-reap.ts", + "packages/daemon/src/session-lifecycle/index.ts", + "packages/daemon/src/session-lifecycle/internal/inventory.ts", + "packages/daemon/src/session-lifecycle/internal/session-close-lifecycle-teardown.ts", + "packages/daemon/src/session-lifecycle/internal/session-close-runtime-admission.ts", + "packages/daemon/src/session-lifecycle/internal/session-close-script.ts", + "packages/daemon/src/session-lifecycle/internal/session-close.ts", + "packages/daemon/src/session-lifecycle/internal/session-open-execution.ts", + "packages/daemon/src/session-lifecycle/internal/session-open-foreground.ts", + "packages/daemon/src/session-lifecycle/internal/session-open-prepare.ts", + "packages/daemon/src/session-lifecycle/internal/session-open-state.ts", + "packages/daemon/src/session-lifecycle/internal/session-open-surface.ts", + "packages/daemon/src/session-lifecycle/internal/session-open-warnings.ts", + "packages/daemon/src/session-lifecycle/internal/session-open.ts", + "packages/daemon/src/session-lifecycle/internal/session-startup-metrics.ts", + "packages/daemon/src/session-observability/index.ts", + "packages/daemon/src/session-observability/internal/session-audio.ts", + "packages/daemon/src/session-observability/internal/session-network.ts", + "packages/daemon/src/session-observability/internal/session-observability.ts", + "packages/daemon/src/session-observability/internal/session-perf-runtime.ts", + "packages/daemon/src/session-replay-coordinator.ts", + "packages/daemon/src/session-routing.ts", + "packages/daemon/src/session-runtime.ts", + "packages/daemon/src/session-teardown-budget.ts", + "packages/daemon/src/session-teardown.ts", + "packages/daemon/src/snapshot-command-runtime.ts", + "packages/daemon/src/snapshot-diff-runtime.ts", + "packages/daemon/src/snapshot-quality-latch.ts", + "packages/daemon/src/snapshot-runtime.ts", + "packages/daemon/src/startup-deadline.ts", + "packages/daemon/src/web-session-names.ts" ], "daemon-server": [ - "src/daemon/application-lifecycle-recovery.ts", - "src/daemon/artifact-archive.ts", - "src/daemon/artifact-download.ts", - "src/daemon/daemon-stop.ts", - "src/daemon/device/device-claim-owner-recovery.ts", - "src/daemon/downloadable-artifact-http.ts", - "src/daemon/host-lease-http.ts", - "src/daemon/http-errors.ts", - "src/daemon/http-request-target.ts", - "src/daemon/human-control-http.ts", - "src/daemon/platform-request-scope.ts", - "src/daemon/provider-lease-expiry.ts", - "src/daemon/replay-device-selection.ts", - "src/daemon/request-binding.ts", - "src/daemon/request-diagnostics-http.ts", - "src/daemon/request-execution-locks.ts", - "src/daemon/request-execution-scope.ts", - "src/daemon/request-finalization.ts", - "src/daemon/request-lease-work.ts", - "src/daemon/request-lock-policy.ts", - "src/daemon/request-platform-provider-context.ts", - "src/daemon/request-router.ts", - "src/daemon/request-save-script-policy.ts", - "src/daemon/response-views.ts", - "src/daemon/resumable-upload-range.ts", - "src/daemon/resumable-upload-transfer.ts", - "src/daemon/resumable-upload.ts", - "src/daemon/server/daemon-lease-finalizer.ts", - "src/daemon/server/daemon-metadata-loss.ts", - "src/daemon/server/daemon-runtime.ts", - "src/daemon/server/daemon-session-idle-expiry.ts", - "src/daemon/server/daemon-shutdown-claims.ts", - "src/daemon/server/http-authorization.ts", - "src/daemon/server/http-instance-precondition.ts", - "src/daemon/server/http-rpc-envelope.ts", - "src/daemon/server/http-rpc-methods.ts", - "src/daemon/server/http-server.ts", - "src/daemon/server/server-lifecycle.ts", - "src/daemon/server/server-shutdown.ts", - "src/daemon/server/tenant-trust.ts", - "src/daemon/server/transport.ts", - "src/daemon/session-idle-expiry.ts", - "src/daemon/upload-http.ts", - "src/daemon/upload.ts" + "packages/daemon/src/application-lifecycle-recovery.ts", + "packages/daemon/src/artifact-archive.ts", + "packages/daemon/src/artifact-download.ts", + "packages/daemon/src/daemon-stop.ts", + "packages/daemon/src/device/device-claim-owner-recovery.ts", + "packages/daemon/src/downloadable-artifact-http.ts", + "packages/daemon/src/host-lease-http.ts", + "packages/daemon/src/http-errors.ts", + "packages/daemon/src/http-request-target.ts", + "packages/daemon/src/human-control-http.ts", + "packages/daemon/src/platform-request-scope.ts", + "packages/daemon/src/provider-lease-expiry.ts", + "packages/daemon/src/replay-device-selection.ts", + "packages/daemon/src/request-binding.ts", + "packages/daemon/src/request-diagnostics-http.ts", + "packages/daemon/src/request-execution-locks.ts", + "packages/daemon/src/request-execution-scope.ts", + "packages/daemon/src/request-finalization.ts", + "packages/daemon/src/request-lease-work.ts", + "packages/daemon/src/request-lock-policy.ts", + "packages/daemon/src/request-platform-provider-context.ts", + "packages/daemon/src/request-router.ts", + "packages/daemon/src/request-save-script-policy.ts", + "packages/daemon/src/response-views.ts", + "packages/daemon/src/resumable-upload-range.ts", + "packages/daemon/src/resumable-upload-transfer.ts", + "packages/daemon/src/resumable-upload.ts", + "packages/daemon/src/server/daemon-lease-finalizer.ts", + "packages/daemon/src/server/daemon-metadata-loss.ts", + "packages/daemon/src/server/daemon-runtime.ts", + "packages/daemon/src/server/daemon-session-idle-expiry.ts", + "packages/daemon/src/server/daemon-shutdown-claims.ts", + "packages/daemon/src/server/http-authorization.ts", + "packages/daemon/src/server/http-instance-precondition.ts", + "packages/daemon/src/server/http-rpc-envelope.ts", + "packages/daemon/src/server/http-rpc-methods.ts", + "packages/daemon/src/server/http-server.ts", + "packages/daemon/src/server/server-lifecycle.ts", + "packages/daemon/src/server/server-shutdown.ts", + "packages/daemon/src/server/tenant-trust.ts", + "packages/daemon/src/server/transport.ts", + "packages/daemon/src/session-idle-expiry.ts", + "packages/daemon/src/upload-http.ts", + "packages/daemon/src/upload.ts" ] } diff --git a/scripts/layering/daemon-layers.test.ts b/scripts/layering/daemon-layers.test.ts index 2e27eca044..6c00d5d0a9 100644 --- a/scripts/layering/daemon-layers.test.ts +++ b/scripts/layering/daemon-layers.test.ts @@ -19,11 +19,11 @@ const repoRoot = execFileSync('git', ['rev-parse', '--show-toplevel'], { // Fixtures sit at the real daemon paths so the layer lookup treats them like production files; // `listSourceFiles()` keeps the manifest half honest against the tracked tree. const FIXTURE_MANIFEST = { - 'daemon-core': ['src/daemon/core.ts'], - 'daemon-resources': ['src/daemon/resources.ts'], - 'daemon-execution': ['src/daemon/execution.ts'], - 'daemon-sessions': ['src/daemon/sessions.ts'], - 'daemon-server': ['src/daemon/server.ts'], + 'daemon-core': ['packages/daemon/src/core.ts'], + 'daemon-resources': ['packages/daemon/src/resources.ts'], + 'daemon-execution': ['packages/daemon/src/execution.ts'], + 'daemon-sessions': ['packages/daemon/src/sessions.ts'], + 'daemon-server': ['packages/daemon/src/server.ts'], }; const FIXTURE_FILES = Object.values(FIXTURE_MANIFEST).flat(); @@ -40,7 +40,7 @@ function driftFor( } test('the manifest owns every tracked daemon file exactly once, and no static edge reads upward', () => { - const daemonFiles = listSourceFiles().filter((file) => file.startsWith('src/daemon/')); + const daemonFiles = listSourceFiles().filter((file) => file.startsWith('packages/daemon/src/')); assert.ok(daemonFiles.length > 0, 'expected daemon production files to scan'); const manifest = readDaemonLayerManifest(repoRoot); assert.deepEqual(Object.keys(manifest).sort(), [...DAEMON_LAYER_ORDER].sort()); @@ -63,13 +63,15 @@ test('the manifest owns every tracked daemon file exactly once, and no static ed test('an upward value import fails the layer order', () => { const violations = checkDaemonLayers( FIXTURE_FILES, - fixtureEdges(new Map([['src/daemon/core.ts', "import { thing } from './resources.ts';"]])), + fixtureEdges( + new Map([['packages/daemon/src/core.ts', "import { thing } from './resources.ts';"]]), + ), FIXTURE_MANIFEST, () => {}, ); assert.equal(violations.length, 1); assert.equal(violations[0]!.rule, 'R81 daemon-layers'); - assert.equal(violations[0]!.file, 'src/daemon/core.ts'); + assert.equal(violations[0]!.file, 'packages/daemon/src/core.ts'); assert.match(violations[0]!.message, /value import reads up the daemon layer order/); }); @@ -77,7 +79,9 @@ test('an upward type-only import fails the layer order too', () => { const violations = checkDaemonLayers( FIXTURE_FILES, fixtureEdges( - new Map([['src/daemon/resources.ts', "import type { Thing } from './sessions.ts';"]]), + new Map([ + ['packages/daemon/src/resources.ts', "import type { Thing } from './sessions.ts';"], + ]), ), FIXTURE_MANIFEST, () => {}, @@ -91,8 +95,8 @@ test('downward and same-layer static edges stay silent', () => { FIXTURE_FILES, fixtureEdges( new Map([ - ['src/daemon/server.ts', "import { thing } from './core.ts';"], - ['src/daemon/sessions.ts', "import type { CoreThing } from './core.ts';"], + ['packages/daemon/src/server.ts', "import { thing } from './core.ts';"], + ['packages/daemon/src/sessions.ts', "import type { CoreThing } from './core.ts';"], ]), ), FIXTURE_MANIFEST, @@ -105,7 +109,7 @@ test('a dynamic cross-layer edge is reported, not rejected', () => { const reported: string[] = []; const violations = checkDaemonLayers( FIXTURE_FILES, - fixtureEdges(new Map([['src/daemon/sessions.ts', "void import('./server.ts');"]])), + fixtureEdges(new Map([['packages/daemon/src/sessions.ts', "void import('./server.ts');"]])), FIXTURE_MANIFEST, (line) => reported.push(line), ); @@ -114,37 +118,43 @@ test('a dynamic cross-layer edge is reported, not rejected', () => { assert.match(reported.join(''), /1 dynamic cross-layer daemon edge/); assert.match( reported.join(''), - /src\/daemon\/sessions\.ts \(daemon-sessions\) -> src\/daemon\/server\.ts \(daemon-server\) \[upward, reported only\]/, + /packages\/daemon\/src\/sessions\.ts \(daemon-sessions\) -> packages\/daemon\/src\/server\.ts \(daemon-server\) \[upward, reported only\]/, ); }); test('a production daemon file missing from the manifest fails', () => { - const violations = driftFor(FIXTURE_MANIFEST, [...FIXTURE_FILES, 'src/daemon/server2.ts']); + const violations = driftFor(FIXTURE_MANIFEST, [ + ...FIXTURE_FILES, + 'packages/daemon/src/server2.ts', + ]); assert.equal(violations.length, 1); - assert.equal(violations[0]!.file, 'src/daemon/server2.ts'); + assert.equal(violations[0]!.file, 'packages/daemon/src/server2.ts'); assert.match(violations[0]!.message, /production daemon file is in no layer/); }); test('a file claimed by two layers fails', () => { const manifest = { ...FIXTURE_MANIFEST, - 'daemon-resources': ['src/daemon/resources.ts', 'src/daemon/core.ts'], + 'daemon-resources': ['packages/daemon/src/resources.ts', 'packages/daemon/src/core.ts'], }; const violations = driftFor(manifest); assert.equal(violations.length, 1); - assert.match(violations[0]!.message, /"src\/daemon\/core\.ts" is claimed by more than one layer/); + assert.match( + violations[0]!.message, + /"packages\/daemon\/src\/core\.ts" is claimed by more than one layer/, + ); }); test('a manifest entry that is not a tracked production file fails', () => { const manifest = { ...FIXTURE_MANIFEST, - 'daemon-core': ['src/daemon/core.ts', 'src/daemon/gone.ts'], + 'daemon-core': ['packages/daemon/src/core.ts', 'packages/daemon/src/gone.ts'], }; const violations = driftFor(manifest); assert.equal(violations.length, 1); assert.match( violations[0]!.message, - /"src\/daemon\/gone\.ts" is owned by "daemon-core" but is not a tracked production file/, + /"packages\/daemon\/src\/gone\.ts" is owned by "daemon-core" but is not a tracked production file/, ); }); @@ -152,15 +162,15 @@ test('a test, fixture, or foreign path in the manifest fails as a non-production const manifest = { ...FIXTURE_MANIFEST, 'daemon-core': [ - 'src/daemon/core.ts', - 'src/daemon/__tests__/core.test.ts', + 'packages/daemon/src/core.ts', + 'packages/daemon/src/__tests__/core.test.ts', 'src/core/helper.ts', ], }; const violations = driftFor(manifest); assert.equal(violations.length, 2); for (const violation of violations) { - assert.match(violation.message, /is not a production path under src\/daemon\/\./); + assert.match(violation.message, /is not a production path under packages\/daemon\/src\/\./); } }); @@ -178,7 +188,7 @@ test('a layer key missing from the manifest fails even when no file is orphaned' delete manifest['daemon-resources']; const violations = driftFor( manifest, - FIXTURE_FILES.filter((file) => file !== 'src/daemon/resources.ts'), + FIXTURE_FILES.filter((file) => file !== 'packages/daemon/src/resources.ts'), ); assert.equal(violations.length, 1); assert.match(violations[0]!.message, /layer "daemon-resources" is missing from the manifest/); @@ -187,7 +197,7 @@ test('a layer key missing from the manifest fails even when no file is orphaned' test('a declared layer whose array is empty fails, so it cannot linger after its last file moves', () => { const violations = driftFor( { ...FIXTURE_MANIFEST, 'daemon-resources': [] }, - FIXTURE_FILES.filter((file) => file !== 'src/daemon/resources.ts'), + FIXTURE_FILES.filter((file) => file !== 'packages/daemon/src/resources.ts'), ); assert.equal(violations.length, 1); assert.match(violations[0]!.message, /layer "daemon-resources" owns no files/); diff --git a/scripts/layering/daemon-layers.ts b/scripts/layering/daemon-layers.ts index cbd440c715..ffebedb2f8 100644 --- a/scripts/layering/daemon-layers.ts +++ b/scripts/layering/daemon-layers.ts @@ -1,4 +1,4 @@ -// Catches: the daemon's internal layering drifting silently — a production file under `src/daemon/` +// Catches: the daemon's internal layering drifting silently — a production file under `packages/daemon/src/` // that no layer owns, an owned file that moved or disappeared, a file claimed by two layers, or a // static import that reads UP the daemon-local order (core < resources < execution < sessions < // server). The global spine ranks all five at daemon-server's rank 4, so R5/R6 cannot see any @@ -17,7 +17,7 @@ import fs from 'node:fs'; import path from 'node:path'; import type { LayeringViolation, ResolvedImportEdge } from './model.ts'; -import { isProductionSourceFile } from './tracked-sources.ts'; +import { DAEMON_SOURCE_ROOT, isProductionSourceFile } from './tracked-sources.ts'; export const DAEMON_LAYER_RULE = 'R81 daemon-layers'; @@ -46,7 +46,7 @@ export function daemonLayerRank(layer: DaemonLayer): number { } /** - * The exhaustive `{layer: sourcePaths}` claim over every production file under `src/daemon/`, + * The exhaustive `{layer: sourcePaths}` claim over every production file under `packages/daemon/src/`, * committed next to this verifier so moving a file into its layer's folder carries its ownership * with it. */ @@ -56,9 +56,9 @@ export function readDaemonLayerManifest(repoRoot: string): DaemonLayerManifest { ) as DaemonLayerManifest; } -/** `src/daemon/<…>.ts` and not a test or fixture path — the only entries the manifest may name. */ +/** `packages/daemon/src/<…>.ts` and not a test or fixture path — the only entries the manifest may name. */ function isDaemonProductionPath(file: string): boolean { - return file.startsWith('src/daemon/') && isProductionSourceFile(file); + return file.startsWith(DAEMON_SOURCE_ROOT) && isProductionSourceFile(file); } /** The partition flattened to one lookup; a path in two layers keeps its first claim. */ @@ -122,7 +122,7 @@ export function daemonLayerManifestDrift( if (!isDaemonProductionPath(file)) { violations.push( manifestFileViolation( - `entry "${file}" is not a production path under src/daemon/. Test files, fixtures, and paths outside the daemon carry no layer.`, + `entry "${file}" is not a production path under packages/daemon/src/. Test files, fixtures, and paths outside the daemon carry no layer.`, ), ); continue; diff --git a/scripts/layering/daemon-modularity.test.ts b/scripts/layering/daemon-modularity.test.ts index 3767f369e8..51ef5359df 100644 --- a/scripts/layering/daemon-modularity.test.ts +++ b/scripts/layering/daemon-modularity.test.ts @@ -27,7 +27,7 @@ function importEdge(file: string, target: string): ResolvedImportEdge { function baselineDaemonTypesEdges(): ResolvedImportEdge[] { return DAEMON_MODULARITY_BASELINE.externalDaemonTypesImporters.map((file) => - importEdge(file, 'src/daemon/daemon-request.ts'), + importEdge(file, 'packages/daemon/src/daemon-request.ts'), ); } @@ -39,7 +39,7 @@ function baselineEdges(): ResolvedImportEdge[] { /** Where a member of `zone` lives, so a zone count can be turned back into file paths. */ const ZONE_DIRECTORY: Readonly> = { '(root)': 'src/', - 'daemon-server': 'src/daemon/', + 'daemon-server': 'packages/daemon/src/', 'ad-replay': 'packages/ad-replay/src/', 'provider-webdriver': 'packages/provider-webdriver/src/', }; @@ -110,9 +110,9 @@ test('external daemon request/session-state importer membership changes require new Map([ [ 'src/client/new-importer.ts', - "import type { SessionState } from '../daemon/session-state.ts';", + "import type { SessionState } from '../../packages/daemon/src/session-state.ts';", ], - ['src/daemon/session-state.ts', 'export type SessionState = { name: string };'], + ['packages/daemon/src/session-state.ts', 'export type SessionState = { name: string };'], ]), ); @@ -215,7 +215,10 @@ test('replay-test may still import its own files inside the package', () => { test('internal trees reject deep imports globally, including from daemon', () => { const edges = resolveImportEdges( new Map([ - ['src/daemon/adapter.ts', "import type { Plan } from '@agent-device/maestro/internal/plan';"], + [ + 'packages/daemon/src/adapter.ts', + "import type { Plan } from '@agent-device/maestro/internal/plan';", + ], ['packages/maestro/src/internal/plan.ts', 'export type Plan = { steps: number };'], ]), ); @@ -234,18 +237,21 @@ test('replay-port rejects daemon source imports and engine back edges', () => { new Map([ [ 'packages/replay-port/src/daemon-port/test-command.ts', - "import { handleSessionCloseCommands } from '../../../../src/daemon/session-lifecycle/index.ts';", + "import { handleSessionCloseCommands } from '../../../../packages/daemon/src/session-lifecycle/index.ts';", ], [ 'packages/replay-port/src/daemon-port/native-command.ts', - "import { SessionStore } from '../../../../src/daemon/session-store.ts';", + "import { SessionStore } from '../../../../packages/daemon/src/session-store.ts';", ], [ 'packages/ad-replay/src/internal/step-loop.ts', "import { runReplayCommand } from '../../../replay-port/src/daemon-port/native-command.ts';", ], - ['src/daemon/session-lifecycle/index.ts', 'export function handleSessionCloseCommands() {}'], - ['src/daemon/session-store.ts', 'export class SessionStore {}'], + [ + 'packages/daemon/src/session-lifecycle/index.ts', + 'export function handleSessionCloseCommands() {}', + ], + ['packages/daemon/src/session-store.ts', 'export class SessionStore {}'], ]), ); @@ -259,11 +265,11 @@ test('replay-port rejects daemon source imports and engine back edges', () => { [ { file: 'packages/replay-port/src/daemon-port/test-command.ts', - message: 'replay-port must not import src/daemon/session-lifecycle/index.ts', + message: 'replay-port must not import packages/daemon/src/session-lifecycle/index.ts', }, { file: 'packages/replay-port/src/daemon-port/native-command.ts', - message: 'replay-port must not import src/daemon/session-store.ts', + message: 'replay-port must not import packages/daemon/src/session-store.ts', }, { file: 'packages/ad-replay/src/internal/step-loop.ts', @@ -277,19 +283,19 @@ test('session lifecycle rejects handler deep imports in both directions', () => const edges = resolveImportEdges( new Map([ [ - 'src/daemon/handlers/session.ts', + 'packages/daemon/src/handlers/session.ts', "import { handleSessionInventoryCommands } from '../session-lifecycle/internal/inventory.ts';\nexport function handleSessionCommands() {}", ], [ - 'src/daemon/session-lifecycle/internal/inventory.ts', + 'packages/daemon/src/session-lifecycle/internal/inventory.ts', "import { handleSessionCommands } from '../../handlers/session.ts';\nexport function handleSessionInventoryCommands() {}", ], [ - 'src/daemon/session-lifecycle/internal/session-close.ts', + 'packages/daemon/src/session-lifecycle/internal/session-close.ts', "import { handleSessionCommands } from '../../handlers/session.ts';", ], [ - 'src/daemon/session-lifecycle/index.ts', + 'packages/daemon/src/session-lifecycle/index.ts', 'export function handleSessionInventoryCommands() {}', ], ]), @@ -308,20 +314,20 @@ test('session lifecycle rejects handler deep imports in both directions', () => })), [ { - file: 'src/daemon/handlers/session.ts', + file: 'packages/daemon/src/handlers/session.ts', line: 1, message: - "src/daemon/handlers/session.ts must not import daemon-session-lifecycle's internal tree (src/daemon/session-lifecycle/internal/inventory.ts)", + "packages/daemon/src/handlers/session.ts must not import daemon-session-lifecycle's internal tree (packages/daemon/src/session-lifecycle/internal/inventory.ts)", }, { - file: 'src/daemon/session-lifecycle/internal/inventory.ts', + file: 'packages/daemon/src/session-lifecycle/internal/inventory.ts', line: 1, - message: 'daemon-session-lifecycle must not import src/daemon/handlers/session.ts', + message: 'daemon-session-lifecycle must not import packages/daemon/src/handlers/session.ts', }, { - file: 'src/daemon/session-lifecycle/internal/session-close.ts', + file: 'packages/daemon/src/session-lifecycle/internal/session-close.ts', line: 1, - message: 'daemon-session-lifecycle must not import src/daemon/handlers/session.ts', + message: 'daemon-session-lifecycle must not import packages/daemon/src/handlers/session.ts', }, ], ); @@ -331,31 +337,31 @@ test('interaction rejects handler crossings and deep imports around its facade', const edges = resolveImportEdges( new Map([ [ - 'src/daemon/handlers/react-native.ts', + 'packages/daemon/src/handlers/react-native.ts', "import { refSnapshotFlagGuardResponse } from '../interaction/internal/interaction-flags.ts';\nexport function handleReactNativeCommands() {}", ], [ - 'src/daemon/interaction/internal/interaction-runtime.ts', + 'packages/daemon/src/interaction/internal/interaction-runtime.ts', "import { handleReactNativeCommands } from '../../handlers/react-native.ts';\nexport function createInteractionRuntime() {}", ], [ - 'src/daemon/generic-settle.ts', + 'packages/daemon/src/generic-settle.ts', "import { createInteractionRuntime } from './interaction/internal/interaction-runtime.ts';", ], [ - 'src/daemon/selector-runtime.ts', + 'packages/daemon/src/selector-runtime.ts', "import { refSnapshotFlagGuardResponse } from './interaction/internal/interaction-flags.ts';", ], [ - 'src/daemon/selector-runtime-backend.ts', + 'packages/daemon/src/selector-runtime-backend.ts', "import { readTextForNode } from './interaction/internal/interaction-ref-policy.ts';", ], [ - 'src/daemon/interaction/internal/interaction-flags.ts', + 'packages/daemon/src/interaction/internal/interaction-flags.ts', 'export function refSnapshotFlagGuardResponse() {}', ], [ - 'src/daemon/interaction/internal/interaction-ref-policy.ts', + 'packages/daemon/src/interaction/internal/interaction-ref-policy.ts', 'export function readTextForNode() {}', ], ]), @@ -370,14 +376,14 @@ test('interaction rejects handler crossings and deep imports around its facade', assert.ok( violations.some(({ message }) => message.includes( - "src/daemon/handlers/react-native.ts must not import daemon-interaction's internal tree", + "packages/daemon/src/handlers/react-native.ts must not import daemon-interaction's internal tree", ), ), ); assert.ok( violations.some(({ message }) => message.includes( - "src/daemon/interaction/internal/interaction-runtime.ts must not import src/daemon/handlers/react-native.ts from daemon-interaction's internal tree", + "packages/daemon/src/interaction/internal/interaction-runtime.ts must not import packages/daemon/src/handlers/react-native.ts from daemon-interaction's internal tree", ), ), ); @@ -393,15 +399,15 @@ test('session observability rejects handler deep imports in both directions', () const edges = resolveImportEdges( new Map([ [ - 'src/daemon/handlers/session.ts', + 'packages/daemon/src/handlers/session.ts', "import { handleSessionObservabilityCommands } from '../session-observability/internal/session-observability.ts';\nexport function handleSessionCommands() {}", ], [ - 'src/daemon/session-observability/internal/session-observability.ts', + 'packages/daemon/src/session-observability/internal/session-observability.ts', "import { handleSessionCommands } from '../../handlers/session.ts';\nexport function handleSessionObservabilityCommands() {}", ], [ - 'src/daemon/session-observability/index.ts', + 'packages/daemon/src/session-observability/index.ts', 'export function handleSessionObservabilityCommands() {}', ], ]), @@ -420,15 +426,16 @@ test('session observability rejects handler deep imports in both directions', () })), [ { - file: 'src/daemon/handlers/session.ts', + file: 'packages/daemon/src/handlers/session.ts', line: 1, message: - "src/daemon/handlers/session.ts must not import daemon-session-observability's internal tree (src/daemon/session-observability/internal/session-observability.ts)", + "packages/daemon/src/handlers/session.ts must not import daemon-session-observability's internal tree (packages/daemon/src/session-observability/internal/session-observability.ts)", }, { - file: 'src/daemon/session-observability/internal/session-observability.ts', + file: 'packages/daemon/src/session-observability/internal/session-observability.ts', line: 1, - message: 'daemon-session-observability must not import src/daemon/handlers/session.ts', + message: + 'daemon-session-observability must not import packages/daemon/src/handlers/session.ts', }, ], ); @@ -436,9 +443,9 @@ test('session observability rejects handler deep imports in both directions', () test('snapshot execution cannot return to handler-owned support paths', () => { const restored = [ - 'src/daemon/handlers/snapshot-capture.ts', - 'src/daemon/handlers/snapshot-interactor-capture.ts', - 'src/daemon/handlers/snapshot-session.ts', + 'packages/daemon/src/handlers/snapshot-capture.ts', + 'packages/daemon/src/handlers/snapshot-interactor-capture.ts', + 'packages/daemon/src/handlers/snapshot-session.ts', ]; assert.deepEqual( @@ -450,64 +457,67 @@ test('snapshot execution cannot return to handler-owned support paths', () => { 'Reuse the daemon-owned snapshot execution module instead of restoring shared mechanics beneath a route adapter.', })), ); - assert.deepEqual(checkRetiredSnapshotExecutionPaths(['src/daemon/handlers/snapshot.ts']), []); + assert.deepEqual( + checkRetiredSnapshotExecutionPaths(['packages/daemon/src/handlers/snapshot.ts']), + [], + ); }); test('session lifecycle rejects restored neutral helper paths', () => { const violations = checkRetiredSessionLifecyclePaths([ - 'src/daemon/session-device-resolution.ts', - 'src/daemon/handlers/session-device-utils.ts', - 'src/daemon/handlers/session-runtime-admission.ts', - 'src/daemon/handlers/session-close-script.ts', - 'src/daemon/handlers/session-close.ts', + 'packages/daemon/src/session-device-resolution.ts', + 'packages/daemon/src/handlers/session-device-utils.ts', + 'packages/daemon/src/handlers/session-runtime-admission.ts', + 'packages/daemon/src/handlers/session-close-script.ts', + 'packages/daemon/src/handlers/session-close.ts', ]); assert.deepEqual( violations.map(({ message }) => message), [ - 'retired session lifecycle path was restored: src/daemon/handlers/session-device-utils.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', - 'retired session lifecycle path was restored: src/daemon/handlers/session-runtime-admission.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', - 'retired session lifecycle path was restored: src/daemon/handlers/session-close-script.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', - 'retired session lifecycle path was restored: src/daemon/handlers/session-close.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', + 'retired session lifecycle path was restored: packages/daemon/src/handlers/session-device-utils.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', + 'retired session lifecycle path was restored: packages/daemon/src/handlers/session-runtime-admission.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', + 'retired session lifecycle path was restored: packages/daemon/src/handlers/session-close-script.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', + 'retired session lifecycle path was restored: packages/daemon/src/handlers/session-close.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', ], ); }); test('interaction rejects restored handler implementation paths', () => { const violations = checkRetiredInteractionPaths([ - 'src/daemon/interaction/internal/interaction.ts', - 'src/daemon/handlers/interaction-touch.ts', + 'packages/daemon/src/interaction/internal/interaction.ts', + 'packages/daemon/src/handlers/interaction-touch.ts', ]); assert.deepEqual(violations, [ { rule: 'R10 daemon-modularity', - file: 'src/daemon/handlers/interaction-touch.ts', + file: 'packages/daemon/src/handlers/interaction-touch.ts', line: 1, message: - 'retired interaction handler path was restored: src/daemon/handlers/interaction-touch.ts. Keep route implementations behind src/daemon/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', + 'retired interaction handler path was restored: packages/daemon/src/handlers/interaction-touch.ts. Keep route implementations behind packages/daemon/src/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', }, ]); }); test('interaction rejects renamed handler implementation paths', () => { const violations = checkRetiredInteractionPaths([ - 'src/daemon/handlers/interaction-touch-v2.ts', - 'src/daemon/handlers/find-next.ts', + 'packages/daemon/src/handlers/interaction-touch-v2.ts', + 'packages/daemon/src/handlers/find-next.ts', ]); assert.deepEqual( violations.map(({ file, message }) => ({ file, message })), [ { - file: 'src/daemon/handlers/interaction-touch-v2.ts', + file: 'packages/daemon/src/handlers/interaction-touch-v2.ts', message: - 'retired interaction handler path was restored: src/daemon/handlers/interaction-touch-v2.ts. Keep route implementations behind src/daemon/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', + 'retired interaction handler path was restored: packages/daemon/src/handlers/interaction-touch-v2.ts. Keep route implementations behind packages/daemon/src/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', }, { - file: 'src/daemon/handlers/find-next.ts', + file: 'packages/daemon/src/handlers/find-next.ts', message: - 'retired interaction handler path was restored: src/daemon/handlers/find-next.ts. Keep route implementations behind src/daemon/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', + 'retired interaction handler path was restored: packages/daemon/src/handlers/find-next.ts. Keep route implementations behind packages/daemon/src/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', }, ], ); @@ -515,8 +525,8 @@ test('interaction rejects renamed handler implementation paths', () => { test('session lifecycle rejects any restored open or close handler path', () => { const violations = checkRetiredSessionLifecyclePaths([ - 'src/daemon/handlers/session-open-regressed.ts', - 'src/daemon/handlers/session-close-regressed.ts', + 'packages/daemon/src/handlers/session-open-regressed.ts', + 'packages/daemon/src/handlers/session-close-regressed.ts', ]); assert.deepEqual( @@ -529,17 +539,17 @@ test('session lifecycle rejects any restored open or close handler path', () => [ { rule: 'R10 daemon-modularity', - file: 'src/daemon/handlers/session-open-regressed.ts', + file: 'packages/daemon/src/handlers/session-open-regressed.ts', line: 1, message: - 'retired session lifecycle path was restored: src/daemon/handlers/session-open-regressed.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', + 'retired session lifecycle path was restored: packages/daemon/src/handlers/session-open-regressed.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', }, { rule: 'R10 daemon-modularity', - file: 'src/daemon/handlers/session-close-regressed.ts', + file: 'packages/daemon/src/handlers/session-close-regressed.ts', line: 1, message: - 'retired session lifecycle path was restored: src/daemon/handlers/session-close-regressed.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', + 'retired session lifecycle path was restored: packages/daemon/src/handlers/session-close-regressed.ts. Keep the neutral seam at its daemon owner instead of rebuilding a handler grab-bag.', }, ], ); @@ -547,14 +557,14 @@ test('session lifecycle rejects any restored open or close handler path', () => test('session observability rejects restored handler paths', () => { const restoredPaths = [ - 'src/daemon/handlers/session-observability.ts', - 'src/daemon/handlers/session-perf-runtime.ts', - 'src/daemon/handlers/session-network.ts', - 'src/daemon/handlers/session-audio.ts', - 'src/daemon/handlers/session-network-regressed.ts', - 'src/daemon/handlers/session-perf.ts', - 'src/daemon/handlers/session-logs.ts', - 'src/daemon/handlers/session-events.ts', + 'packages/daemon/src/handlers/session-observability.ts', + 'packages/daemon/src/handlers/session-perf-runtime.ts', + 'packages/daemon/src/handlers/session-network.ts', + 'packages/daemon/src/handlers/session-audio.ts', + 'packages/daemon/src/handlers/session-network-regressed.ts', + 'packages/daemon/src/handlers/session-perf.ts', + 'packages/daemon/src/handlers/session-logs.ts', + 'packages/daemon/src/handlers/session-events.ts', ] as const; const violations = checkRetiredSessionObservabilityPaths(restoredPaths); @@ -595,7 +605,7 @@ test('R9 holds each zone to the merge-base and keeps engine files outside the co // The merge-base carries membership, so the message names exactly the files that joined. test('R10 zone overflow names the member that joined the cycle', () => { // Sorts after the provider-webdriver probes: a first-member pick could not name it by luck. - const joined = 'src/daemon/snapshot-interactor-capture.ts'; + const joined = 'packages/daemon/src/snapshot-interactor-capture.ts'; const members = [...typeCycleMembers({ 'provider-webdriver': 5 }), joined].sort(); const violations = checkDaemonModularityRatchets( diff --git a/scripts/layering/daemon-modularity.ts b/scripts/layering/daemon-modularity.ts index 37349b2b36..fc45977b54 100644 --- a/scripts/layering/daemon-modularity.ts +++ b/scripts/layering/daemon-modularity.ts @@ -1,4 +1,5 @@ import path from 'node:path'; +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; import { INTERACTION_RETIRED_HANDLER_PATHS, LOGICAL_MODULE_POLICIES, @@ -31,8 +32,8 @@ export const DAEMON_MODULARITY_BASELINE = { // `@agent-device/contracts/command` as `DaemonWireRequest`). Both are ratcheted // together, so moving a symbol between them cannot reopen the boundary to a new outside zone. const DAEMON_TYPE_MODULES: readonly string[] = [ - 'src/daemon/daemon-request.ts', - 'src/daemon/session-state.ts', + 'packages/daemon/src/daemon-request.ts', + 'packages/daemon/src/session-state.ts', ]; const ENGINE_FILE_PREFIXES = [ @@ -75,7 +76,7 @@ export function checkRetiredSessionLifecyclePaths( return checkRetiredHandlerPaths( sourceFiles, SESSION_LIFECYCLE_RETIRED_HANDLER_PATHS, - /^src\/daemon\/handlers\/session-(?:open|close)(?:-[^/]+)?\.ts$/, + /^packages\/daemon\/src\/handlers\/session-(?:open|close)(?:-[^/]+)?\.ts$/, 'session lifecycle', ); } @@ -86,7 +87,7 @@ export function checkRetiredSessionObservabilityPaths( return checkRetiredHandlerPaths( sourceFiles, SESSION_OBSERVABILITY_RETIRED_HANDLER_PATHS, - /^src\/daemon\/handlers\/session-(?:observability|perf|logs|events|network|audio)(?:-[^/]+)?\.ts$/, + /^packages\/daemon\/src\/handlers\/session-(?:observability|perf|logs|events|network|audio)(?:-[^/]+)?\.ts$/, 'session observability', ); } @@ -124,9 +125,9 @@ export function checkRetiredInteractionPaths(sourceFiles: readonly string[]): La return checkRetiredHandlerPaths( sourceFiles, INTERACTION_RETIRED_HANDLER_PATHS, - /^src\/daemon\/handlers\/(?:find|interaction)(?:-[^/]+)?\.ts$/, + /^packages\/daemon\/src\/handlers\/(?:find|interaction)(?:-[^/]+)?\.ts$/, 'interaction handler', - 'Keep route implementations behind src/daemon/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', + 'Keep route implementations behind packages/daemon/src/interaction/index.ts instead of rebuilding a handler-owned interaction surface.', ); } @@ -218,7 +219,8 @@ function checkDaemonTypesImporters(edges: readonly ResolvedImportEdge[]): Layeri const allowed = new Set(DAEMON_MODULARITY_BASELINE.externalDaemonTypesImporters); const importers = new Map(); for (const edge of edges) { - if (!DAEMON_TYPE_MODULES.includes(edge.target) || edge.file.startsWith('src/daemon/')) continue; + if (!DAEMON_TYPE_MODULES.includes(edge.target) || edge.file.startsWith(DAEMON_SOURCE_ROOT)) + continue; // #2559: the client's daemon-request/session-state reads are owned by the stricter // R78 `daemon-client-entry` gate, which also bans runtime imports and names each edge. if (edge.file.startsWith('src/daemon-client/')) continue; diff --git a/scripts/layering/daemon-platform-boundary.test.ts b/scripts/layering/daemon-platform-boundary.test.ts index f90c0836fa..480665822e 100644 --- a/scripts/layering/daemon-platform-boundary.test.ts +++ b/scripts/layering/daemon-platform-boundary.test.ts @@ -6,7 +6,7 @@ import { findDaemonPlatformDependencies, } from './daemon-platform-boundary.ts'; -const daemonFile = 'src/daemon/terminal-boundary-fixture.ts'; +const daemonFile = 'packages/daemon/src/terminal-boundary-fixture.ts'; function dependencies(source: string, file = daemonFile) { return findDaemonPlatformDependencies([{ path: file, source }]); @@ -18,11 +18,11 @@ function violations(source: string, file = daemonFile) { test('R65 rejects static, type-only, dynamic, type, and re-export dependencies with source lines', () => { const source = [ - "import { old } from '../platforms/android/old.ts';", - "import type { OldType } from '../platforms/android/types.ts';", - "const lazy = import('../platforms/android/lazy.ts');", - "type ImportedType = import('../platforms/android/type.ts').ImportedType;", - "export { old } from '../platforms/android/re-export.ts';", + "import { old } from '../../../src/platforms/android/old.ts';", + "import type { OldType } from '../../../src/platforms/android/types.ts';", + "const lazy = import('../../../src/platforms/android/lazy.ts');", + "type ImportedType = import('../../../src/platforms/android/type.ts').ImportedType;", + "export { old } from '../../../src/platforms/android/re-export.ts';", "export type { OldType } from '@agent-device/platform-android/types';", "export * from '@agent-device/platform-apple';", ].join('\n'); @@ -32,31 +32,31 @@ test('R65 rejects static, type-only, dynamic, type, and re-export dependencies w [ { kind: 'static import', - spec: '../platforms/android/old.ts', + spec: '../../../src/platforms/android/old.ts', line: 1, target: 'src/platforms/android/old.ts', }, { kind: 'type-only import', - spec: '../platforms/android/types.ts', + spec: '../../../src/platforms/android/types.ts', line: 2, target: 'src/platforms/android/types.ts', }, { kind: 'dynamic import', - spec: '../platforms/android/lazy.ts', + spec: '../../../src/platforms/android/lazy.ts', line: 3, target: 'src/platforms/android/lazy.ts', }, { kind: 'type import', - spec: '../platforms/android/type.ts', + spec: '../../../src/platforms/android/type.ts', line: 4, target: 'src/platforms/android/type.ts', }, { kind: 're-export', - spec: '../platforms/android/re-export.ts', + spec: '../../../src/platforms/android/re-export.ts', line: 5, target: 'src/platforms/android/re-export.ts', }, @@ -87,22 +87,24 @@ test('R65 rejects static, type-only, dynamic, type, and re-export dependencies w test('R65 recognizes side-effect and aliased imports, including nested daemon paths', () => { const source = [ - "import '../../platforms/web/runtime.ts';", + "import '../../../../src/platforms/web/runtime.ts';", "import { runtime as platformRuntime } from '@agent-device/platform-web/runtime';", ].join('\n'); assert.deepEqual( - dependencies(source, 'src/daemon/handlers/terminal-boundary-fixture.ts').map((found) => ({ - kind: found.kind, - line: found.line, - spec: found.spec, - target: found.target, - })), + dependencies(source, 'packages/daemon/src/handlers/terminal-boundary-fixture.ts').map( + (found) => ({ + kind: found.kind, + line: found.line, + spec: found.spec, + target: found.target, + }), + ), [ { kind: 'static import', line: 1, - spec: '../../platforms/web/runtime.ts', + spec: '../../../../src/platforms/web/runtime.ts', target: 'src/platforms/web/runtime.ts', }, { @@ -117,12 +119,12 @@ test('R65 recognizes side-effect and aliased imports, including nested daemon pa test('R65 ignores comments, ordinary strings, unresolved dynamic imports, and lookalike names', () => { const source = [ - 'const documentation = "import(\'../platforms/android/comment.ts\'); @agent-device/platform-android";', - "// import { ignored } from '../platforms/android/comment.ts';", + 'const documentation = "import(\'../../../src/platforms/android/comment.ts\'); @agent-device/platform-android";', + "// import { ignored } from '../../../src/platforms/android/comment.ts';", "const packageName = '@agent-device/platform-android';", - "const relativeName = '../platforms/android/not-an-import.ts';", + "const relativeName = '../../../src/platforms/android/not-an-import.ts';", 'const computed = import(platformSpecifier);', - "import '../platforms-sibling/not-platform.ts';", + "import '../../../src/platforms-sibling/not-platform.ts';", "import '@agent-device/platforms';", "import '@agent-device/platform';", ].join('\n'); @@ -133,20 +135,20 @@ test('R65 ignores comments, ordinary strings, unresolved dynamic imports, and lo test('R65 rejects require, import-equals, and template-literal type imports', () => { const source = [ "const android = require('@agent-device/platform-android');", - 'const runtime = require(`../platforms/android/runtime.ts`);', + 'const runtime = require(`../../../src/platforms/android/runtime.ts`);', "import web = require('@agent-device/platform-web');", 'type Apple = import(`@agent-device/platform-apple`).Apple;', - 'type Android = import(`../platforms/android/types.ts`).Android;', + 'type Android = import(`../../../src/platforms/android/types.ts`).Android;', ].join('\n'); assert.deepEqual( dependencies(source).map(({ kind, spec, line }) => ({ kind, spec, line })), [ { kind: 'require', spec: '@agent-device/platform-android', line: 1 }, - { kind: 'require', spec: '../platforms/android/runtime.ts', line: 2 }, + { kind: 'require', spec: '../../../src/platforms/android/runtime.ts', line: 2 }, { kind: 'import equals', spec: '@agent-device/platform-web', line: 3 }, { kind: 'type import', spec: '@agent-device/platform-apple', line: 4 }, - { kind: 'type import', spec: '../platforms/android/types.ts', line: 5 }, + { kind: 'type import', spec: '../../../src/platforms/android/types.ts', line: 5 }, ], ); }); @@ -154,7 +156,7 @@ test('R65 rejects require, import-equals, and template-literal type imports', () test('R65 folds statically constructed dynamic platform specifiers', () => { const source = [ "const apple = import('@agent-device/' + 'platform-apple');", - 'const android = import(`../platforms/${"android"}/runtime.ts`);', + 'const android = import(`../../../src/platforms/${"android"}/runtime.ts`);', "const wrapped = import((('@agent-device/' + 'platform-android')));", 'const required = require((`@agent-device/platform-web`));', ].join('\n'); @@ -163,7 +165,7 @@ test('R65 folds statically constructed dynamic platform specifiers', () => { dependencies(source).map(({ kind, spec, line }) => ({ kind, spec, line })), [ { kind: 'dynamic import', spec: '@agent-device/platform-apple', line: 1 }, - { kind: 'dynamic import', spec: '../platforms/android/runtime.ts', line: 2 }, + { kind: 'dynamic import', spec: '../../../src/platforms/android/runtime.ts', line: 2 }, { kind: 'dynamic import', spec: '@agent-device/platform-android', line: 3 }, { kind: 'require', spec: '@agent-device/platform-web', line: 4 }, ], @@ -174,7 +176,7 @@ test('R65 unwraps erased TypeScript expressions around executable specifiers', ( const source = [ "void import('@agent-device/platform-android' as string);", "require('@agent-device/platform-web' satisfies string);", - "void import('../platforms/apple/runtime.ts');", + "void import('../../../src/platforms/apple/runtime.ts');", ].join('\n'); assert.deepEqual( @@ -182,7 +184,7 @@ test('R65 unwraps erased TypeScript expressions around executable specifiers', ( [ { kind: 'dynamic import', spec: '@agent-device/platform-android', line: 1 }, { kind: 'require', spec: '@agent-device/platform-web', line: 2 }, - { kind: 'dynamic import', spec: '../platforms/apple/runtime.ts', line: 3 }, + { kind: 'dynamic import', spec: '../../../src/platforms/apple/runtime.ts', line: 3 }, ], ); }); @@ -195,7 +197,7 @@ test('R65 follows common createRequire and require aliases', () => { 'const load = makeRequire(import.meta.url);', 'const loadAgain = load;', "loadAgain('@agent-device/platform-android');", - "makeRequire(import.meta.url)('../platforms/web/runtime.ts');", + "makeRequire(import.meta.url)('../../../src/platforms/web/runtime.ts');", "moduleApi.createRequire(import.meta.url)('@agent-device/platform-apple');", "moduleDefault.createRequire(import.meta.url)('@agent-device/platform-web');", 'const loadAlias = require;', @@ -209,7 +211,7 @@ test('R65 follows common createRequire and require aliases', () => { dependencies(source).map(({ spec, line }) => ({ spec, line })), [ { spec: '@agent-device/platform-android', line: 6 }, - { spec: '../platforms/web/runtime.ts', line: 7 }, + { spec: '../../../src/platforms/web/runtime.ts', line: 7 }, { spec: '@agent-device/platform-apple', line: 8 }, { spec: '@agent-device/platform-web', line: 9 }, { spec: '@agent-device/platform-linux', line: 11 }, @@ -222,7 +224,7 @@ test('R65 follows common createRequire and require aliases', () => { test('R65 rejects triple-slash concrete-platform type references', () => { const source = [ '/// ', - '/// ', + '/// ', '/*', '/// ', '*/', @@ -232,7 +234,7 @@ test('R65 rejects triple-slash concrete-platform type references', () => { dependencies(source).map(({ kind, spec, line }) => ({ kind, spec, line })), [ { kind: 'type import', spec: '@agent-device/platform-android', line: 1 }, - { kind: 'type import', spec: '../platforms/apple/types.ts', line: 2 }, + { kind: 'type import', spec: '../../../src/platforms/apple/types.ts', line: 2 }, ], ); }); @@ -240,50 +242,56 @@ test('R65 rejects triple-slash concrete-platform type references', () => { test('R65 rejects platform selection inside cleanup orchestrators', () => { const direct = violations( "export const cleanup = (session: any) => session.device.platform === 'android';", - 'src/daemon/session-teardown.ts', + 'packages/daemon/src/session-teardown.ts', ); assert.match(direct[0]?.message ?? '', /may not select a concrete platform/); const predicate = violations( 'export const cleanup = (device: any) => isIosFamily(device);', - 'src/daemon/snapshot-session.ts', + 'packages/daemon/src/snapshot-session.ts', ); assert.match(predicate[0]?.message ?? '', /typed root-composed cleanup capability/); const destructured = violations( "export const cleanup = (session: any) => { const { platform } = session.device; return platform === 'android'; };", - 'src/daemon/session-lifecycle/internal/session-close-lifecycle-teardown.ts', + 'packages/daemon/src/session-lifecycle/internal/session-close-lifecycle-teardown.ts', ); assert.match(destructured[0]?.message ?? '', /may not select a concrete platform/); assert.deepEqual( violations( 'export const cleanup = (owner: any, device: any) => owner.cleanupSessionlessExecutionHost(device);', - 'src/daemon/snapshot-session.ts', + 'packages/daemon/src/snapshot-session.ts', ), [], ); }); test('R65 ignores non-daemon and test-shaped records even when their syntax is red', () => { - const source = "import { platform } from '../platforms/android/runtime.ts';"; + const source = "import { platform } from '../../../src/platforms/android/runtime.ts';"; assert.deepEqual(dependencies(source, 'src/core/terminal-boundary-fixture.ts'), []); - assert.deepEqual(dependencies(source, 'src/daemon/terminal-boundary-fixture.test.ts'), []); - assert.deepEqual(dependencies(source, 'src/daemon/__tests__/terminal-boundary-fixture.ts'), []); + assert.deepEqual( + dependencies(source, 'packages/daemon/src/terminal-boundary-fixture.test.ts'), + [], + ); + assert.deepEqual( + dependencies(source, 'packages/daemon/src/__tests__/terminal-boundary-fixture.ts'), + [], + ); }); test('R65 treats a relative specifier as legacy platform code only after path resolution', () => { const source = [ - "import { platform } from '../../platforms/android/runtime.ts';", - "import { sibling } from '../platforms-sibling/runtime.ts';", - "import { exact } from '../platforms';", + "import { platform } from '../../../../src/platforms/android/runtime.ts';", + "import { sibling } from '../../../src/platforms-sibling/runtime.ts';", + "import { exact } from '../../../src/platforms';", ].join('\n'); assert.deepEqual( dependencies(source).map(({ spec, target, line }) => ({ spec, target, line })), [ { - spec: '../platforms', + spec: '../../../src/platforms', target: 'src/platforms', line: 3, }, diff --git a/scripts/layering/daemon-platform-boundary.ts b/scripts/layering/daemon-platform-boundary.ts index 4220fda7c8..c1da006d05 100644 --- a/scripts/layering/daemon-platform-boundary.ts +++ b/scripts/layering/daemon-platform-boundary.ts @@ -1,6 +1,6 @@ import path from 'node:path'; import { parseSync } from 'oxc-parser'; -import { isProductionSourceFile } from './tracked-sources.ts'; +import { DAEMON_SOURCE_ROOT, isProductionSourceFile } from './tracked-sources.ts'; import type { LayeringViolation } from './model.ts'; /** @@ -330,12 +330,12 @@ function tripleSlashDependencies(file: string, source: string): DaemonPlatformDe function dependencyMessage(dependency: DaemonPlatformDependency): string { return ( `${dependency.kind} '${dependency.spec}' resolves to concrete platform code ` + - `(${dependency.target}); production src/daemon/ must use the request-bound runtime contract` + `(${dependency.target}); production packages/daemon/src/ must use the request-bound runtime contract` ); } /** - * Find every concrete platform dependency in tracked production `src/daemon/**` sources. + * Find every concrete platform dependency in tracked production `packages/daemon/src/**` sources. * * The input is intentionally source records rather than a filesystem walk. Callers use the * canonical tracked-production enumerator, while synthetic tests can plant one edge at a time @@ -345,7 +345,7 @@ export function findDaemonPlatformDependencies( sources: readonly ProductionSource[], ): DaemonPlatformDependency[] { return sources - .filter(({ path: file }) => file.startsWith('src/daemon/') && isProductionSourceFile(file)) + .filter(({ path: file }) => file.startsWith(DAEMON_SOURCE_ROOT) && isProductionSourceFile(file)) .flatMap(({ path: file, source }) => [ ...staticDependencies(file, source), ...dynamicDependencies(file, source), @@ -373,9 +373,9 @@ export function daemonPlatformBoundaryViolations( } const CLEANUP_ORCHESTRATORS = new Set([ - 'src/daemon/session-teardown.ts', - 'src/daemon/session-lifecycle/internal/session-close-lifecycle-teardown.ts', - 'src/daemon/snapshot-session.ts', + 'packages/daemon/src/session-teardown.ts', + 'packages/daemon/src/session-lifecycle/internal/session-close-lifecycle-teardown.ts', + 'packages/daemon/src/snapshot-session.ts', ]); function cleanupDispatchViolations(sources: readonly ProductionSource[]): LayeringViolation[] { diff --git a/scripts/layering/daemon-platform-runtime-inventory.test.ts b/scripts/layering/daemon-platform-runtime-inventory.test.ts index b0c04338dd..23cb5bbfd3 100644 --- a/scripts/layering/daemon-platform-runtime-inventory.test.ts +++ b/scripts/layering/daemon-platform-runtime-inventory.test.ts @@ -11,7 +11,7 @@ import { // inventory carried, retired by #3430. Under the ban it is a violation like any other. const RETIRED_TARGET = 'src/platform-runtime-apple-resources.ts'; const RETIRED_STUB = 'export const queryAppleRuntimeSelector = () => ({});\n'; -const RETIRED_IMPORTER = 'src/daemon/direct-ios-selector.ts'; +const RETIRED_IMPORTER = 'packages/daemon/src/direct-ios-selector.ts'; function violations(sources: Record): LayeringViolation[] { return checkDaemonPlatformRuntimeInventory(resolveImportEdges(new Map(Object.entries(sources)))); @@ -25,7 +25,7 @@ test('R76 rejects the direct-iOS selector edge the retired inventory classified' const sources = { [RETIRED_TARGET]: RETIRED_STUB, [RETIRED_IMPORTER]: - "import { queryAppleRuntimeSelector } from '../platform-runtime-apple-resources.ts';\n" + + "import { queryAppleRuntimeSelector } from '../../../src/platform-runtime-apple-resources.ts';\n" + 'void queryAppleRuntimeSelector;\n', }; const found = edgeViolations(sources, RETIRED_IMPORTER); @@ -34,7 +34,7 @@ test('R76 rejects the direct-iOS selector edge the retired inventory classified' assert.match(found[0]!.message, /daemon coupling to root platform mechanics is banned/); assert.match( found[0]!.message, - /src\/daemon\/direct-ios-selector\.ts -> src\/platform-runtime-apple-resources\.ts/, + /packages\/daemon\/src\/direct-ios-selector\.ts -> src\/platform-runtime-apple-resources\.ts/, ); }); @@ -44,10 +44,10 @@ for (const [file, target, symbol] of [ ['ios-app-session-hint', 'open-target', 'resolveSoleForegroundIosApp'], ]) { test(`R76 rejects retired observation mechanics in ${file}`, () => { - const importer = `src/daemon/${file}.ts`; + const importer = `packages/daemon/src/${file}.ts`; const sources = { [`src/platform-runtime-${target}.ts`]: `export function ${symbol}() {}\n`, - [importer]: `import { ${symbol} } from '../platform-runtime-${target}.ts';\nvoid ${symbol};\n`, + [importer]: `import { ${symbol} } from '../../../src/platform-runtime-${target}.ts';\nvoid ${symbol};\n`, }; const found = edgeViolations(sources, importer); assert.equal(found.length, 1); @@ -59,18 +59,18 @@ for (const [file, target, symbol] of [ test('R76 rejects an edge with the pair and its line', () => { const sources = { 'src/platform-runtime-android-tool-host.ts': 'export function createAndroidToolHost() {}\n', - 'src/daemon/fixture.ts': - "import { createAndroidToolHost } from '../platform-runtime-android-tool-host.ts';\n" + + 'packages/daemon/src/fixture.ts': + "import { createAndroidToolHost } from '../../../src/platform-runtime-android-tool-host.ts';\n" + 'void createAndroidToolHost;\n', }; - const found = edgeViolations(sources, 'src/daemon/fixture.ts'); + const found = edgeViolations(sources, 'packages/daemon/src/fixture.ts'); assert.equal(found.length, 1); assert.equal(found[0]!.rule, DAEMON_PLATFORM_RUNTIME_RULE); assert.equal(found[0]!.line, 1); assert.match(found[0]!.message, /daemon coupling to root platform mechanics is banned/); assert.match( found[0]!.message, - /src\/daemon\/fixture\.ts -> src\/platform-runtime-android-tool-host\.ts/, + /packages\/daemon\/src\/fixture\.ts -> src\/platform-runtime-android-tool-host\.ts/, ); }); @@ -78,8 +78,8 @@ test('R76 reports an import and re-export of one pair as a single violation', () const sources = { [RETIRED_TARGET]: RETIRED_STUB, [RETIRED_IMPORTER]: - "import { queryAppleRuntimeSelector } from '../platform-runtime-apple-resources.ts';\n" + - "export { queryAppleRuntimeSelector } from '../platform-runtime-apple-resources.ts';\n" + + "import { queryAppleRuntimeSelector } from '../../../src/platform-runtime-apple-resources.ts';\n" + + "export { queryAppleRuntimeSelector } from '../../../src/platform-runtime-apple-resources.ts';\n" + 'void queryAppleRuntimeSelector;\n', }; assert.equal(edgeViolations(sources, RETIRED_IMPORTER).length, 1); @@ -89,7 +89,7 @@ test('R76 rejects a destructured dynamic import of the root platform-runtime fam const sources = { [RETIRED_TARGET]: RETIRED_STUB, [RETIRED_IMPORTER]: - "const { queryAppleRuntimeSelector } = await import('../platform-runtime-apple-resources.ts');\n" + + "const { queryAppleRuntimeSelector } = await import('../../../src/platform-runtime-apple-resources.ts');\n" + 'void queryAppleRuntimeSelector;\n', }; assert.equal(edgeViolations(sources, RETIRED_IMPORTER).length, 1); @@ -99,7 +99,7 @@ test('R76 rejects a dynamic namespace import of a root platform-runtime module', const sources = { [RETIRED_TARGET]: RETIRED_STUB, [RETIRED_IMPORTER]: - "const appleResources = await import('../platform-runtime-apple-resources.ts');\n" + + "const appleResources = await import('../../../src/platform-runtime-apple-resources.ts');\n" + 'void appleResources;\n', }; const found = edgeViolations(sources, RETIRED_IMPORTER); @@ -107,15 +107,15 @@ test('R76 rejects a dynamic namespace import of a root platform-runtime module', assert.equal(found[0]!.rule, DAEMON_PLATFORM_RUNTIME_RULE); assert.match( found[0]!.message, - /src\/daemon\/direct-ios-selector\.ts -> src\/platform-runtime-apple-resources\.ts/, + /packages\/daemon\/src\/direct-ios-selector\.ts -> src\/platform-runtime-apple-resources\.ts/, ); }); test('R76 ignores test-shaped and non-daemon importers', () => { const sources = { 'src/platform-runtime-android-tool-host.ts': 'export function createAndroidToolHost() {}\n', - 'src/daemon/__tests__/fixture.test.ts': - "import { createAndroidToolHost } from '../platform-runtime-android-tool-host.ts';\n" + + 'packages/daemon/src/__tests__/fixture.test.ts': + "import { createAndroidToolHost } from '../../../src/platform-runtime-android-tool-host.ts';\n" + 'void createAndroidToolHost;\n', 'src/cli.ts': "import { createAndroidToolHost } from './platform-runtime-android-tool-host.ts';\n" + @@ -127,9 +127,10 @@ test('R76 ignores test-shaped and non-daemon importers', () => { test('R76 ignores retired-zone targets, which R65 owns', () => { const sources = { 'src/platforms/android.ts': 'export const legacy = 1;\n', - 'src/daemon/fixture.ts': 'import { legacy } from "../platforms/android.ts";\nvoid legacy;\n', + 'packages/daemon/src/fixture.ts': + 'import { legacy } from "../../../src/platforms/android.ts";\nvoid legacy;\n', }; - assert.deepEqual(edgeViolations(sources, 'src/daemon/fixture.ts'), []); + assert.deepEqual(edgeViolations(sources, 'packages/daemon/src/fixture.ts'), []); }); test('the root composition family is src/platform-runtime.ts plus src/platform-runtime-*.ts only', () => { @@ -139,7 +140,7 @@ test('the root composition family is src/platform-runtime.ts plus src/platform-r assert.equal(isRootPlatformRuntimeTarget('src/platform-runtime-android.tsx'), false); assert.equal(isRootPlatformRuntimeTarget('src/platform-runtime.ts.bak'), false); assert.equal(isRootPlatformRuntimeTarget('src/platforms/runtime.ts'), false); - assert.equal(isRootPlatformRuntimeTarget('src/daemon/platform-runtime.ts'), false); + assert.equal(isRootPlatformRuntimeTarget('packages/daemon/src/platform-runtime.ts'), false); }); const ROOT_PLATFORM_STUB = 'export const gateway = 1;\nvoid gateway;\n'; @@ -149,24 +150,26 @@ test('R76 catches a daemon import of a root hub that reaches the platform family 'src/hub-runtime.ts': "import { gateway } from './platform-runtime.ts';\nvoid gateway;\n" + 'export function hubFact() {}\n', - 'src/daemon/fixture.ts': "import { hubFact } from '../hub-runtime.ts';\nvoid hubFact;\n", + 'packages/daemon/src/fixture.ts': + "import { hubFact } from '../../../src/hub-runtime.ts';\nvoid hubFact;\n", }; - const found = edgeViolations(sources, 'src/daemon/fixture.ts'); + const found = edgeViolations(sources, 'packages/daemon/src/fixture.ts'); assert.equal(found.length, 1); assert.equal(found[0]!.rule, DAEMON_PLATFORM_RUNTIME_RULE); - assert.match(found[0]!.message, /src\/daemon\/fixture\.ts -> src\/hub-runtime\.ts/); + assert.match(found[0]!.message, /packages\/daemon\/src\/fixture\.ts -> src\/hub-runtime\.ts/); }); test('R76 does not turn an intra-daemon hop into a hub edge', () => { const sources = { 'src/platform-runtime.ts': ROOT_PLATFORM_STUB, - 'src/daemon/dispatch.ts': - "import { gateway } from '../platform-runtime.ts';\nvoid gateway;\nexport function dispatch() {}\n", - 'src/daemon/handler.ts': "import { dispatch } from './dispatch.ts';\nvoid dispatch;\n", + 'packages/daemon/src/dispatch.ts': + "import { gateway } from '../../../src/platform-runtime.ts';\nvoid gateway;\nexport function dispatch() {}\n", + 'packages/daemon/src/handler.ts': "import { dispatch } from './dispatch.ts';\nvoid dispatch;\n", }; - assert.deepEqual(edgeViolations(sources, 'src/daemon/handler.ts'), []); + assert.deepEqual(edgeViolations(sources, 'packages/daemon/src/handler.ts'), []); assert.equal( - violations(sources).filter((violation) => violation.file === 'src/daemon/dispatch.ts').length, + violations(sources).filter((violation) => violation.file === 'packages/daemon/src/dispatch.ts') + .length, 1, ); }); diff --git a/scripts/layering/daemon-platform-runtime-inventory.ts b/scripts/layering/daemon-platform-runtime-inventory.ts index 60a7e2d55e..2cba916f5e 100644 --- a/scripts/layering/daemon-platform-runtime-inventory.ts +++ b/scripts/layering/daemon-platform-runtime-inventory.ts @@ -1,5 +1,5 @@ import { genDFS } from '@statelyai/graph'; -import { isProductionSourceFile } from './tracked-sources.ts'; +import { DAEMON_SOURCE_ROOT, isProductionSourceFile } from './tracked-sources.ts'; import type { LayeringViolation, ResolvedImportEdge } from './model.ts'; import { ALL_EDGES, importGraphFromResolvedEdges } from '../depgraph/import-graph.ts'; @@ -33,7 +33,7 @@ export function computePlatformMechanicsHubs( const hubs = new Set(); const graph = importGraphFromResolvedEdges(edges, ALL_EDGES, roots); for (const { id: importer } of genDFS(graph, { from: roots, direction: 'incoming' })) { - if (!importer.startsWith('src/daemon/')) hubs.add(importer); + if (!importer.startsWith(DAEMON_SOURCE_ROOT)) hubs.add(importer); } return hubs; } @@ -60,7 +60,7 @@ export function checkDaemonPlatformRuntimeInventory( const violations: LayeringViolation[] = []; const reported = new Set(); for (const edge of edges) { - if (!edge.file.startsWith('src/daemon/')) continue; + if (!edge.file.startsWith(DAEMON_SOURCE_ROOT)) continue; if (!isProductionSourceFile(edge.file)) continue; if (!hubs.has(edge.target)) continue; const key = `${edge.file} -> ${edge.target}`; diff --git a/scripts/layering/model.test.ts b/scripts/layering/model.test.ts index d27f4e6542..04a6c16d4d 100644 --- a/scripts/layering/model.test.ts +++ b/scripts/layering/model.test.ts @@ -182,37 +182,37 @@ const RECORDED_IMPORT_TYPE_CASES = [ 'RunnerStartAdmission', ], [ - 'src/daemon/interaction/index.ts', - 'src/daemon/gesture-runtime.ts', + 'packages/daemon/src/interaction/index.ts', + 'packages/daemon/src/gesture-runtime.ts', '../gesture-runtime.ts', 'BoundGestureExecutor', ], [ - 'src/daemon/interaction/index.ts', - 'src/daemon/touch-runtime.ts', + 'packages/daemon/src/interaction/index.ts', + 'packages/daemon/src/touch-runtime.ts', '../touch-runtime.ts', 'BoundTouchExecutor', ], [ - 'src/daemon/interaction/internal/interaction.ts', + 'packages/daemon/src/interaction/internal/interaction.ts', 'packages/contracts/src/android-observation.ts', '@agent-device/contracts/android-observation', 'AndroidObservationAdapter', ], [ - 'src/daemon/snapshot-runtime-binding.ts', + 'packages/daemon/src/snapshot-runtime-binding.ts', 'packages/contracts/src/focus-runtime.ts', '@agent-device/contracts/focus-runtime', 'FocusPointInput', ], [ - 'src/daemon/snapshot-runtime-binding.ts', + 'packages/daemon/src/snapshot-runtime-binding.ts', 'packages/contracts/src/interactor-types.ts', '@agent-device/contracts/interactor-types', 'TypeTextBackendResult', ], [ - 'src/daemon/snapshot-runtime-binding.ts', + 'packages/daemon/src/snapshot-runtime-binding.ts', 'packages/contracts/src/type-text-runtime.ts', '@agent-device/contracts/type-text-runtime', 'TypeTextInput', @@ -574,27 +574,39 @@ test('SessionState field names come from the declaration, not a hand-kept list', test('session-state writes are found by field, and non-daemon or undeclared names are not', () => { const writes = findSessionStateWrites( new Map([ - ['src/daemon/ref-frame.ts', "session.refFrame = 'active';"], - ['src/daemon/session-snapshot.ts', 'session.snapshotGeneration += 1;'], + ['packages/daemon/src/ref-frame.ts', "session.refFrame = 'active';"], + ['packages/daemon/src/session-snapshot.ts', 'session.snapshotGeneration += 1;'], // the store owns the record and may write anything on it - ['src/daemon/session-store.ts', "session.refFrame = 'expired';"], + ['packages/daemon/src/session-store.ts', "session.refFrame = 'expired';"], // a runner session outside the daemon is a different type that happens to share a name ['src/platforms/apple/runner-session.ts', 'session.refFrame = 1;'], // a local that is not a declared SessionState field - ['src/daemon/session-observability/internal/session-audio.ts', 'session.somethingElse = 1;'], + [ + 'packages/daemon/src/session-observability/internal/session-audio.ts', + 'session.somethingElse = 1;', + ], // reads and comparisons are not writes - ['src/daemon/interaction/internal/find.ts', "if (session.refFrame === 'active') return;"], + [ + 'packages/daemon/src/interaction/internal/find.ts', + "if (session.refFrame === 'active') return;", + ], // a write into a sub-object is not a write to the field itself - ['src/daemon/handlers/session-probe.ts', 'session.refFrame.inner = 1;'], + ['packages/daemon/src/handlers/session-probe.ts', 'session.refFrame.inner = 1;'], // a different binding that happens to have a matching property - ['src/daemon/session-lifecycle/internal/session-close.ts', "other.refFrame = 'expired';"], + [ + 'packages/daemon/src/session-lifecycle/internal/session-close.ts', + "other.refFrame = 'expired';", + ], ]), ['refFrame', 'snapshotGeneration'], ); assert.deepEqual( writes.map(({ file, field }) => `${file}:${field}`), - ['src/daemon/ref-frame.ts:refFrame', 'src/daemon/session-snapshot.ts:snapshotGeneration'], + [ + 'packages/daemon/src/ref-frame.ts:refFrame', + 'packages/daemon/src/session-snapshot.ts:snapshotGeneration', + ], ); }); @@ -613,7 +625,9 @@ test('every assignment form is a write, including the ones a regex forgets', () 'session\n .refFrame = 1;', ]; for (const form of forms) { - const writes = findSessionStateWrites(new Map([['src/daemon/probe.ts', form]]), ['refFrame']); + const writes = findSessionStateWrites(new Map([['packages/daemon/src/probe.ts', form]]), [ + 'refFrame', + ]); assert.deepEqual( writes.map(({ field }) => field), ['refFrame'], @@ -624,7 +638,7 @@ test('every assignment form is a write, including the ones a regex forgets', () test('a computed session write is reported rather than silently unattributed', () => { const writes = findSessionStateWrites( - new Map([['src/daemon/probe.ts', 'session[key] = 1;\nsession[`refFrame`] = 2;']]), + new Map([['packages/daemon/src/probe.ts', 'session[key] = 1;\nsession[`refFrame`] = 2;']]), ['refFrame'], ); // `[computed]` has no entry in SESSION_STATE_FIELD_OWNERS, so R7 fails on it by @@ -636,13 +650,13 @@ test('a computed session write is reported rather than silently unattributed', ( assert.equal(SESSION_STATE_FIELD_OWNERS['[computed]'], undefined); }); -test('every declared session-state owner is a real file path under src/daemon', () => { +test('every declared session-state owner is a real file path under packages/daemon', () => { for (const [field, owners] of Object.entries(SESSION_STATE_FIELD_OWNERS)) { assert.ok(owners.length > 0, `${field} must name at least one owner`); for (const owner of owners) { assert.match( owner, - /^src\/daemon\/.+\.ts$/, + /^packages\/daemon\/src\/.+\.ts$/, `${field} owner ${owner} must be a daemon module`, ); } @@ -658,7 +672,7 @@ test('a session write counts through an aliased binding, not only one named `ses const writes = findSessionStateWrites( new Map([ [ - 'src/daemon/probe.ts', + 'packages/daemon/src/probe.ts', [ 'nextSession.snapshotGeneration = 3;', 'preEntrySession.refFrame = "active";', @@ -682,7 +696,10 @@ test('every SessionState field is classified exactly once', () => { // R7 by being invisible to the scan, and the rule would silently stop covering part of the // type it claims to cover. const fields = sessionStateFields( - readFileSync(path.resolve(import.meta.dirname, '../../src/daemon/session-state.ts'), 'utf8'), + readFileSync( + path.resolve(import.meta.dirname, '../../packages/daemon/src/session-state.ts'), + 'utf8', + ), ); assert.deepEqual(fieldClassificationDrift(fields), []); assert.equal( @@ -693,7 +710,10 @@ test('every SessionState field is classified exactly once', () => { test('classification drift is reported in all three directions', () => { const declared = sessionStateFields( - readFileSync(path.resolve(import.meta.dirname, '../../src/daemon/session-state.ts'), 'utf8'), + readFileSync( + path.resolve(import.meta.dirname, '../../packages/daemon/src/session-state.ts'), + 'utf8', + ), ); // Unclassified: a field added to SessionState and to neither table. This is the case the diff --git a/scripts/layering/model.ts b/scripts/layering/model.ts index 7208703bc5..61962c80e4 100644 --- a/scripts/layering/model.ts +++ b/scripts/layering/model.ts @@ -1,4 +1,5 @@ import path from 'node:path'; +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; import { PLATFORMS } from '@agent-device/kernel/device'; import { createGraph, genDFS, getStronglyConnectedComponents, getSubgraph } from '@statelyai/graph'; import { parseSync } from 'oxc-parser'; @@ -306,8 +307,8 @@ export function topFolder(file: string): string { export function targetDagZone(file: string): string { // #2342 relocated the daemon client to its own `src/daemon-client/` folder, so the - // client zone now falls out of the folder itself; `src/daemon/` is server-only. - if (file.startsWith('src/daemon/')) return 'daemon-server'; + // client zone now falls out of the folder itself; `packages/daemon/src/` is server-only. + if (file.startsWith(DAEMON_SOURCE_ROOT)) return 'daemon-server'; return declaredRootModuleZone(file) ?? topFolder(file); } @@ -330,6 +331,39 @@ export function unclassifiedZones(files: readonly string[]): string[] { // a sibling file — unresolved and invisible to the value-cycle and reverse-reachability graphs). const PACKAGE_SRC_PREFIX = /^packages\/[^/]+\/src\//; +/** + * Resolve a workspace specifier against an exports-derived targets map, mirroring + * Node's exports semantics: exact keys first, then `*` pattern entries with the + * longest matching prefix winning and the matched suffix filling the target's + * `*`. The map keeps a pattern entry as its literal key + * (`@agent-device/daemon/testing/handlers/__tests__/*`), so a plain `get` misses + * every concrete import of it — which is how the layering edges, the depgraph, + * mutation ownership, and R11's named-surface check each started resolving + * pattern-exported specifiers to nothing (#3546 review). This is the single + * semantics every in-repo consumer applies: `resolveTargetFile`, `namedByExports`, + * and — by ordering its Vite first-match list to this rule — `workspaceSourceAliases`. + */ +export function resolveWorkspaceSpecifier( + specifier: string, + targets: ReadonlyMap, +): string | undefined { + const exact = targets.get(specifier); + if (exact !== undefined) return exact; + let best: { prefix: string; target: string } | undefined; + for (const [key, target] of targets) { + if (!key.endsWith('*') || !target.includes('*')) continue; + const prefix = key.slice(0, -1); + if (!specifier.startsWith(prefix)) continue; + if (best && best.prefix.length >= prefix.length) continue; + best = { prefix, target }; + } + if (!best) return undefined; + const star = best.target.indexOf('*'); + return ( + best.target.slice(0, star) + specifier.slice(best.prefix.length) + best.target.slice(star + 1) + ); +} + function resolveTargetFile( fromFile: string, spec: string, @@ -339,11 +373,12 @@ function resolveTargetFile( if (spec.startsWith('@agent-device/')) { // Workspace specifier (#1490 W0). Real runs pass the exports-derived map // (workspaceSpecifierTargets), which is authoritative — it handles '.' - // facade exports and any source layout. The positional fallback exists - // only for map-less fixtures (the P0-pinned depgraph contract) and cannot - // resolve a bare facade specifier by construction. + // facade exports, `*` pattern entries, and any source layout. The + // positional fallback exists only for map-less fixtures (the P0-pinned + // depgraph contract) and cannot resolve a bare facade specifier by + // construction. if (workspaceExportTargets) { - const target = workspaceExportTargets.get(spec); + const target = resolveWorkspaceSpecifier(spec, workspaceExportTargets); return target !== undefined && sourceFiles.has(target) ? target : null; } const [name, ...subParts] = spec.slice('@agent-device/'.length).split('/'); diff --git a/scripts/layering/package-boundaries-facade.test.ts b/scripts/layering/package-boundaries-facade.test.ts new file mode 100644 index 0000000000..61e6edcca6 --- /dev/null +++ b/scripts/layering/package-boundaries-facade.test.ts @@ -0,0 +1,197 @@ +// R11's ./testing/ façade rule bites: test data stays behind the package's +// `./testing/` namespace — named `./testing/` entries and per-folder +// `./testing//*` patterns — that only test files may import (owner review +// #3546). Compact sibling of package-boundaries.test.ts, which sits at its size +// ratchet. + +import assert from 'node:assert/strict'; +import { test } from 'node:test'; +import { + checkPackageInternalSites, + checkRootSites, + isTestConsumerFile, + specifierSites, + workspacePackagesFromManifests, +} from './package-boundaries.ts'; + +const daemonManifest = JSON.stringify({ + name: '@agent-device/daemon', + private: true, + exports: { + './session-store': { types: './src/session-store.ts', default: './src/session-store.ts' }, + './testing/__tests__/store-factory': { + types: './src/__tests__/store-factory.ts', + default: './src/__tests__/store-factory.ts', + }, + './testing/handlers/__tests__/*': { + types: './src/handlers/__tests__/*.ts', + default: './src/handlers/__tests__/*.ts', + }, + }, +}); +const [daemon] = workspacePackagesFromManifests( + new Map([['packages/daemon/package.json', daemonManifest]]), +); + +function sites(file: string, specifier: string) { + return [{ file, line: 1, specifier }]; +} +const PROD = new Set(['@agent-device/daemon']); + +test('a production root file importing the ./testing/ namespace is refused', () => { + const violations = checkRootSites( + sites('src/commands/something.ts', '@agent-device/daemon/testing/__tests__/store-factory'), + [daemon], + PROD, + true, + ); + assert.equal(violations.length, 1); + assert.match(violations[0]!.message, /publishes test data to test files only/); +}); + +test('a test root file importing ./testing/ passes, and a named entry stays open to all', () => { + assert.deepEqual( + checkRootSites( + sites( + 'src/__tests__/daemon-composition/anything.test.ts', + '@agent-device/daemon/testing/__tests__/store-factory', + ), + [daemon], + PROD, + true, + ), + [], + ); + // The exact spelling the fixture manifest names. A compiled site skips + // resolution, so `[]` there would pass even for a specifier no entry exports; + // the uncompiled pass reports "not named" for exactly that, so asserting [] + // in both modes is what proves this specifier resolves through the named entry. + for (const compiled of [true, false]) { + assert.deepEqual( + checkRootSites( + sites('src/cli.ts', '@agent-device/daemon/session-store'), + [daemon], + PROD, + compiled, + ), + [], + ); + } +}); + +test('the ./testing/ refusal bites inside packages and through the vi.mock scan', () => { + const planted = "vi.mock('@agent-device/daemon/testing/__tests__/store-factory', () => ({}));"; + assert.deepEqual( + checkPackageInternalSites( + daemon, + sites( + 'packages/daemon/src/handlers/production.ts', + '@agent-device/daemon/testing/__tests__/store-factory', + ), + [daemon], + true, + ).length, + 1, + ); + assert.equal( + checkRootSites( + specifierSites('src/platform-runtime-something.ts', planted), + [daemon], + PROD, + true, + ).length, + 1, + ); +}); + +test('a package-local test/ tree is a test consumer, its src/ tree is not', () => { + // The file vocabulary TEST_ONLY_FIXTURE_SUBPATHS' predicate uses: a package's + // own harness tree (`packages//test/`) imports fixtures just like the + // root `test/` tree does; the same file under src/ does not (#3546 review). + const consumer = workspacePackagesFromManifests( + new Map([ + [ + 'packages/daemon-side/package.json', + JSON.stringify({ + name: '@agent-device/daemon-side', + private: true, + exports: { '.': './src/index.ts' }, + dependencies: { '@agent-device/daemon': 'workspace:*' }, + }), + ], + ]), + )[0]!; + const fixture = '@agent-device/daemon/testing/__tests__/store-factory'; + assert.deepEqual( + checkPackageInternalSites( + consumer, + sites('packages/daemon-side/test/harness.ts', fixture), + [daemon, consumer], + true, + ), + [], + ); + const denied = checkPackageInternalSites( + consumer, + sites('packages/daemon-side/src/harness.ts', fixture), + [daemon, consumer], + true, + ); + assert.equal(denied.length, 1); + assert.match(denied[0]!.message, /publishes test data to test files only/); +}); + +test('isTestConsumerFile accepts the test vocabulary and denies production files', () => { + // One spelling serves both test-data gates (the ./testing/ façade check and the + // TEST_ONLY_FIXTURE_SUBPATHS predicate), so the vocabulary itself is pinned here: + // every accepted shape forwards to both gates, and the shapes that once spelled + // differently across the two copies (.test.tsx, .mts, a root __tests__/ tree) are + // in the accepted set (#3546 review). + for (const file of [ + 'test/integration/consumer.ts', + 'packages/daemon-side/test/harness.ts', + 'src/daemon/__tests__/consumer.ts', + '__tests__/root-consumer.ts', + 'scripts/layering/daemon-layers.test.tsx', + 'src/daemon/session-store.test.mts', + 'src/foo.test.js', + 'src/foo.test.cjs', + ]) { + assert.equal(isTestConsumerFile(file), true, file); + } + for (const file of [ + 'src/commands/inventory.ts', + 'packages/kernel/src/errors.ts', + 'scripts/layering/package-boundaries.ts', + 'testbed/notes.ts', + 'docs/writing/tests.ts', + 'src/foo.ts', + ]) { + assert.equal(isTestConsumerFile(file), false, file); + } +}); + +test('a pattern entry matches deep specifiers, and an unnamed one is refused in scripts/', () => { + // uncompiled sites resolve through the pattern rather than report "not named", + // and a spelling no entry names still reports. + assert.deepEqual( + checkRootSites( + sites( + 'src/__tests__/x/y.test.ts', + '@agent-device/daemon/testing/handlers/__tests__/session-test-harness', + ), + [daemon], + PROD, + false, + ), + [], + ); + const unnamed = checkRootSites( + sites('src/__tests__/x/y.test.ts', '@agent-device/daemon/testing/support/whatever'), + [daemon], + PROD, + false, + ); + assert.equal(unnamed.length, 1); + assert.match(unnamed[0]!.message, /not named by/); +}); diff --git a/scripts/layering/package-boundaries.test.ts b/scripts/layering/package-boundaries.test.ts index 87ff27dfe7..7eaca8f078 100644 --- a/scripts/layering/package-boundaries.test.ts +++ b/scripts/layering/package-boundaries.test.ts @@ -236,6 +236,42 @@ test('double-quoted and re-export routes into packages are not invisible to R11' assert.equal(checkPackageInternalSites(kernel, packageEscape, ALL, false).length, 1); }); +test('a package vi.mock route into root src is an R11 escape, and a sibling route needs its declaration', () => { + // `vi.mock('./x')` is a call expression the AST import parser never visits, yet the loader + // resolves its specifier and instantiates that module — the same double-instance route the + // tunnels above name. Planted red: delete the scan in `specifierSites` and every assertion. + const kernelViolations = (compiled: boolean, source: string) => + checkPackageInternalSites( + kernel, + specifierSites('packages/kernel/src/internal/thing.test.ts', source), + ALL, + compiled, + ); + const rootMock = kernelViolations(true, "vi.mock('../../../../src/utils/exec.ts', () => ({}));"); + assert.equal(rootMock.length, 1); + assert.match(rootMock[0]!.message, /escapes packages\/kernel/); + assert.equal(kernelViolations(true, "vi.doMock('../../../../src/utils/exec.ts');").length, 1); + assert.equal( + kernelViolations(true, 'vi.importActual("../../../../src/utils/exec.ts")').length, + 1, + ); + + // Legitimate mock routes keep working: a declared sibling's exported subpath is not an + // escape, an undeclared sibling is still the undeclared-sibling branch, and a mock of the + // package's own module stays silent, so the scan cannot be read as flagging all mocks. + const declaredMock = specifierSites( + 'packages/contracts/src/internal/thing.test.ts', + "vi.mock('@agent-device/kernel/errors', () => ({}));", + ); + assert.deepEqual(checkPackageInternalSites(contracts, declaredMock, ALL, true), []); + const undeclaredMock = specifierSites( + 'packages/kernel/src/internal/thing.test.ts', + "vi.mock('@agent-device/contracts/interaction', () => ({}));", + ); + assert.equal(rules(checkPackageInternalSites(kernel, undeclaredMock, ALL, false)).length, 1); + assert.deepEqual(kernelViolations(true, "vi.mock('./exec.ts', () => ({}));"), []); +}); + // This `src/utils` path is another in-memory arbitrary parser fixture, not a live repository path. test('a package relative escape is R11-owned, compiled or not', () => { // #3289 maintainer review restored this branch after a planted `tsc -b` run showed the diff --git a/scripts/layering/package-boundaries.ts b/scripts/layering/package-boundaries.ts index b87590b17d..3f71bce35e 100644 --- a/scripts/layering/package-boundaries.ts +++ b/scripts/layering/package-boundaries.ts @@ -31,8 +31,12 @@ import fs from 'node:fs'; import path from 'node:path'; -import { parseImports } from './model.ts'; -import { listTrackedPackageManifests, listTrackedProductionSources } from './tracked-sources.ts'; +import { parseImports, resolveWorkspaceSpecifier } from './model.ts'; +import { + DAEMON_SOURCE_ROOT, + listTrackedPackageManifests, + listTrackedProductionSources, +} from './tracked-sources.ts'; export type PackageBoundaryViolation = { rule: string; @@ -66,9 +70,30 @@ export type SpecifierSite = { * layering model's own parser, so static/dynamic/side-effect/re-export sites * and both quote styles are covered by one scanner instead of a private regex * that silently missed double-quoted routes. + * + * `vi.mock`/`vi.doMock`/`vi.mockActual`/`vi.unmock`/`vi.importActual` join the sweep + * by literal scan: they are plain call expressions the AST import parser never + * visits, yet the loader resolves their specifier and instantiates that module under + * test — the same double-instance route a relative tunnel takes. `importOriginal + * ` needs no extra branch; the parser already sees it as a + * TSImportType. */ +const VI_MOCK_CALL_RE = + /\bvi\.(?:mock|doMock|mockActual|unmock|importActual)\(\s*(['"])([^'"\n]*)\1/g; + export function specifierSites(file: string, source: string): SpecifierSite[] { - return parseImports(source).map((edge) => ({ file, line: edge.line, specifier: edge.spec })); + const sites: SpecifierSite[] = parseImports(source).map((edge) => ({ + file, + line: edge.line, + specifier: edge.spec, + })); + for (const match of source.matchAll(VI_MOCK_CALL_RE)) { + const line = source.slice(0, match.index).split('\n').length; + const specifier = match[2]!; + if (!sites.some((site) => site.line === line && site.specifier === specifier)) + sites.push({ file, line, specifier }); + } + return sites.sort((a, b) => a.line - b.line); } /** @@ -143,6 +168,57 @@ function packageByName(packages: readonly WorkspacePackage[], name: string) { return packages.find((pkg) => pkg.name === name); } +/** + * A specifier is named by the exports map when it matches a named key or resolves + * through a `*` pattern entry. Delegates to `resolveWorkspaceSpecifier` so every + * consumer (this rule, the layering edges, the depgraph, mutation ownership, and + * the Stryker alias table) applies one Node-exports semantics, not a private scan. + */ +function namedByExports(target: WorkspacePackage, specifier: string): boolean { + return resolveWorkspaceSpecifier(specifier, target.exportTargets) !== undefined; +} + +const TEST_CONSUMER_RE = /(^|\/)__tests__\/|\.test\.[cm]?[jt]sx?$|(?:^|\/)test\//; + +/** + * The one file vocabulary for "this file consumes test data": the root `test/` tree, a + * package-local `test/` harness tree, `*.test.*` files, and `__tests__/` trees (root or + * nested). Both test-data gates call this — the `./testing/` façade check and the + * TEST_ONLY_FIXTURE_SUBPATHS predicate — so what counts as a test consumer is one rule, + * not two spellings that drift. Pinned by an accept/deny table in + * `package-boundaries-facade.test.ts`. + */ +export function isTestConsumerFile(file: string): boolean { + return TEST_CONSUMER_RE.test(file); +} + +/** + * Façade policy (ADR-0033 amendment): a package publishes test data only under its + * `./testing/` namespace — named `./testing/` entries and per-folder + * `./testing//*` patterns — and only test files may import it. The gate is the + * namespace, not a pattern entry: narrowing the surface to exact keys must not + * smuggle a fixture past the test-file rule. Production code that reaches a fixture + * through the package boundary is production code depending on a test double — it + * must inject the real port instead. + */ +function checkTestDataOnlySites( + site: SpecifierSite, + target: WorkspacePackage, +): PackageBoundaryViolation | undefined { + if (!site.specifier.startsWith(`${target.name}/testing/`)) return undefined; + if (!namedByExports(target, site.specifier)) return undefined; + if (isTestConsumerFile(site.file)) return undefined; + return { + rule: 'R11 package-boundaries', + file: site.file, + line: site.line, + message: + `'${site.specifier}' resolves through ${target.dir}/package.json#exports './testing/' ` + + `namespace, which publishes test data to test files only. '${site.file}' is not a test ` + + `file: import a production subpath or inject the port.`, + }; +} + function specifierPackageName(specifier: string): string | undefined { const match = /^(@[^/]+\/[^/]+)/.exec(specifier); return match?.[1]; @@ -182,12 +258,6 @@ export const TEST_ONLY_FIXTURE_SUBPATHS: ReadonlySet = new Set([ '@agent-device/replay-port/replay-script-source-fixtures', ]); -// Root `test/`, package-local `packages//test/`, *.test.ts, and __tests__ trees are test -// consumers; anything else is production. Mirrors R13's non-production predicate. -function isTestConsumerFile(file: string): boolean { - return /(?:^|\/)test\//.test(file) || file.endsWith('.test.ts') || file.includes('/__tests__/'); -} - /** Consumer side of `TEST_ONLY_FIXTURE_SUBPATHS`. */ function importsTestOnlyFixtureFromProduction(file: string, specifier: string): boolean { return TEST_ONLY_FIXTURE_SUBPATHS.has(specifier) && !isTestConsumerFile(file); @@ -203,8 +273,7 @@ export const CLIENT_ONLY_SUBPATHS: ReadonlySet = new Set([ '@agent-device/replay-port/source-discovery', ]); -const DAEMON_SOURCE_FILE = /^(?:src\/daemon|packages\/daemon\/src)\//; -// The daemon process also runs its root entry and composition root, outside the daemon tree. +// The daemon process also runs its root entry and composition root, outside the daemon package. const DAEMON_PROCESS_ROOT_FILES: ReadonlySet = new Set([ 'src/daemon.ts', 'src/daemon-composition.ts', @@ -213,7 +282,7 @@ const DAEMON_PROCESS_ROOT_FILES: ReadonlySet = new Set([ function importsClientOnlyFromDaemon(file: string, specifier: string): boolean { return ( CLIENT_ONLY_SUBPATHS.has(specifier) && - (DAEMON_SOURCE_FILE.test(file) || DAEMON_PROCESS_ROOT_FILES.has(file)) && + (file.startsWith(DAEMON_SOURCE_ROOT) || DAEMON_PROCESS_ROOT_FILES.has(file)) && !isTestConsumerFile(file) ); } @@ -308,7 +377,12 @@ export function checkPackageInternalSites( `in ${pkg.dir}/package.json ${pkg.workspaceDependencyField}.`, }); } - if (!compiled && !target.exportTargets.has(site.specifier)) { + const testDataOnly = checkTestDataOnlySites(site, target); + if (testDataOnly) { + violations.push(testDataOnly); + continue; + } + if (!compiled && !namedByExports(target, site.specifier)) { violations.push({ rule: 'R11 package-boundaries', file: site.file, @@ -399,7 +473,12 @@ export function checkRootSites( `package.json devDependencies.`, }); } - if (!compiled && !target.exportTargets.has(site.specifier)) { + const testDataOnly = checkTestDataOnlySites(site, target); + if (testDataOnly) { + violations.push(testDataOnly); + continue; + } + if (!compiled && !namedByExports(target, site.specifier)) { violations.push({ rule: 'R11 package-boundaries', file: site.file, diff --git a/scripts/layering/platform-package-policy.test.ts b/scripts/layering/platform-package-policy.test.ts index fb4c1270ee..9c348d1d40 100644 --- a/scripts/layering/platform-package-policy.test.ts +++ b/scripts/layering/platform-package-policy.test.ts @@ -171,7 +171,7 @@ test('composition policy does not pin local platform-module identifier spelling' test('external consumers use root facades with static imports only at the interactor seam', () => { const staticImport = validSources(); staticImport.set( - 'src/daemon/not-the-root.ts', + 'packages/daemon/src/not-the-root.ts', "import { applePlatformMetadata } from '@agent-device/platform-apple';", ); assert.match( @@ -184,7 +184,7 @@ test('external consumers use root facades with static imports only at the intera "void import('@agent-device/platform-apple');", ]) { const sources = validSources(); - sources.set('src/daemon/not-the-root.ts', statement); + sources.set('packages/daemon/src/not-the-root.ts', statement); assert.match( messages(sources).join('\n'), /production static imports of '@agent-device\/platform-apple' are limited to/, @@ -231,7 +231,7 @@ test('external consumers use root facades with static imports only at the intera const reExport = validSources(); reExport.set( - 'src/daemon/not-the-root.ts', + 'packages/daemon/src/not-the-root.ts', "export { applePlatformMetadata } from '@agent-device/platform-apple';", ); assert.match( @@ -241,7 +241,7 @@ test('external consumers use root facades with static imports only at the intera const deep = validSources(); deep.set( - 'src/daemon/not-the-root.ts', + 'packages/daemon/src/not-the-root.ts', "import { implementation } from '@agent-device/platform-apple/internal';", ); assert.match( @@ -267,8 +267,8 @@ test('only the canonical composition root may import the private provider compos assert.deepEqual(checkPlatformPackagePolicy(sources, declarations()), []); sources.set( - 'src/daemon/request-router.ts', - "import { providerScope } from '../platform-runtime/request-providers.ts';", + 'packages/daemon/src/request-router.ts', + "import { providerScope } from '../../../src/platform-runtime/request-providers.ts';", ); assert.match( messages(sources).join('\n'), @@ -280,7 +280,7 @@ test('the apple runner mechanics facet subpaths are the enumerated exception', ( // The façade subpath is the facet's consumer seam: root code may import it. const sources = validSources(); sources.set( - 'src/daemon/selector-runtime.ts', + 'packages/daemon/src/selector-runtime.ts', "import type { RunnerCommand } from '@agent-device/platform-apple/runner';", ); assert.deepEqual(checkPlatformPackagePolicy(sources, declarations()), []); @@ -392,7 +392,7 @@ test('the Android mechanics facet is the named consumer seam and adb host wiring const allowed = validSources(); allowed.set('src/core/interactors/android.ts', mechanicsImport); allowed.set('src/sdk/android-adb.ts', mechanicsImport); - allowed.set('src/daemon/handlers/session.test.ts', mechanicsImport); + allowed.set('packages/daemon/src/handlers/__tests__/session.test.ts', mechanicsImport); allowed.set('src/platform-runtime-android-adb-host.ts', hostImport); assert.deepEqual( messages(allowed).filter((message) => message.includes('may import')), @@ -400,14 +400,14 @@ test('the Android mechanics facet is the named consumer seam and adb host wiring ); const denied = validSources(); - denied.set('src/daemon/handlers/session.ts', mechanicsImport); + denied.set('packages/daemon/src/handlers/session.ts', mechanicsImport); assert.match( messages(denied).join('\n'), /only src\/platform-runtime\.ts or its governed request-provider composition submodule may import '@agent-device\/platform-android\/mechanics'/, ); const deniedHost = validSources(); - deniedHost.set('src/daemon/handlers/session.ts', hostImport); + deniedHost.set('packages/daemon/src/handlers/session.ts', hostImport); assert.match( messages(deniedHost).join('\n'), /only src\/platform-runtime\.ts or its governed request-provider composition submodule may import '@agent-device\/platform-android\/adb-host'/, @@ -435,7 +435,10 @@ test('the Android test-only fixture subpaths accept test consumers and deny prod "import { createAndroidSnapshotCapture } from '@agent-device/platform-android/snapshot-capture-fixtures';"; const allowed = validSources(); allowed.set('src/__tests__/android-ui-hierarchy.test.ts', fixtureImport); - allowed.set('src/daemon/__tests__/android-system-dialog-occlusion.test.ts', fixtureImport); + allowed.set( + 'packages/daemon/src/__tests__/android-system-dialog-occlusion.test.ts', + fixtureImport, + ); allowed.set('test/integration/provider-scenarios/android.test.ts', fixtureImport); assert.deepEqual( messages(allowed).filter((message) => message.includes('may import')), @@ -473,7 +476,10 @@ test('platform packages cannot escape to root, daemon, siblings, or raw process // spawning at runtime, so test files (which fake process primitives) and // type-only imports (the runner host port names ChildProcess) are exempt. const planted = [ - ["import type { DaemonRequest } from '../../../src/daemon/types.ts';", 'probe.test.ts'], + [ + "import type { DaemonRequest } from '../../../packages/daemon/src/types.ts';", + 'probe.test.ts', + ], ["export { x } from '../../../src/core/x.ts';", 'probe.test.ts'], ["void import('@agent-device/platform-android');", 'probe.test.ts'], ["import { spawn } from 'node:child_process';", 'probe.ts'], diff --git a/scripts/layering/platform-package-policy.ts b/scripts/layering/platform-package-policy.ts index ed5bbb27ca..fde579d321 100644 --- a/scripts/layering/platform-package-policy.ts +++ b/scripts/layering/platform-package-policy.ts @@ -15,6 +15,7 @@ // into a sibling's src still compiles; project references are a build cache, not a boundary. import path from 'node:path'; +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; import { PLATFORMS } from '@agent-device/kernel/device'; import { parseImports, type LayeringViolation } from './model.ts'; import { checkPlatformComposition } from './platform-composition-policy.ts'; @@ -113,7 +114,7 @@ function isAndroidFacetSubpathImport(file: string, specifier: string): boolean { // The named facets are the implementation seam for root/core/SDK consumers. Daemon production // code still reaches platform behavior through the request-bound runtime gateway; tests may // import a facet to exercise the package-owned mechanics directly. - return !file.startsWith('src/daemon/') || !isProductionSource(file); + return !file.startsWith(DAEMON_SOURCE_ROOT) || !isProductionSource(file); } function isAppleFacadeSubpathImport(specifier: string): boolean { diff --git a/scripts/layering/ratchet-reference.test.ts b/scripts/layering/ratchet-reference.test.ts index e27e79e53a..f2c98eba39 100644 --- a/scripts/layering/ratchet-reference.test.ts +++ b/scripts/layering/ratchet-reference.test.ts @@ -17,10 +17,13 @@ const SESSION_TYPES = [ function tree(extra: Record = {}) { return new Map([ - ['src/daemon/session-state.ts', SESSION_TYPES], - ['src/daemon/session-snapshot.ts', 'session.snapshot = "a"; nextSession.snapshot = "b";'], - ['src/daemon/ref-frame.ts', 'session.snapshot = undefined;'], - ['src/daemon/handlers/trace-runtime.ts', 'session.trace ??= "t";'], + ['packages/daemon/src/session-state.ts', SESSION_TYPES], + [ + 'packages/daemon/src/session-snapshot.ts', + 'session.snapshot = "a"; nextSession.snapshot = "b";', + ], + ['packages/daemon/src/ref-frame.ts', 'session.snapshot = undefined;'], + ['packages/daemon/src/handlers/trace-runtime.ts', 'session.trace ??= "t";'], ['src/client/client.ts', "import type { Loop } from '../commands/loop.ts';"], ['src/commands/loop.ts', "import type { Client } from '../client/client.ts';"], ...Object.entries(extra), @@ -37,7 +40,7 @@ test('sessionStateWritePressure counts written fields and (field, writer) claims ownerFileClaims: 3, }); assert.deepEqual( - sessionStateWritePressure(tree({ 'src/daemon/other.ts': 'session[key] = 1;' })), + sessionStateWritePressure(tree({ 'packages/daemon/src/other.ts': 'session[key] = 1;' })), { writerOwnedFields: 2, ownerFileClaims: 3, @@ -58,16 +61,16 @@ test('measureRatchets reports all ratchets from one tree', () => { sessionAuthority: { shapeFiles: [], authorityFiles: [] }, }); const withAuthority = tree({ - 'src/daemon/handlers/fixture.ts': + 'packages/daemon/src/handlers/fixture.ts': "import type { SessionState } from '../session-state.ts';\n" + "import { SessionStore } from '../session-store.ts';", - 'src/daemon/session-store.ts': 'export class SessionStore {}', + 'packages/daemon/src/session-store.ts': 'export class SessionStore {}', }); assert.deepEqual( measureRatchets(withAuthority, resolveImportEdges(withAuthority)).sessionAuthority, { - shapeFiles: ['src/daemon/handlers/fixture.ts'], - authorityFiles: ['src/daemon/handlers/fixture.ts'], + shapeFiles: ['packages/daemon/src/handlers/fixture.ts'], + authorityFiles: ['packages/daemon/src/handlers/fixture.ts'], }, ); }); diff --git a/scripts/layering/ratchet-reference.ts b/scripts/layering/ratchet-reference.ts index 2fcc409144..2a16c39d20 100644 --- a/scripts/layering/ratchet-reference.ts +++ b/scripts/layering/ratchet-reference.ts @@ -7,11 +7,16 @@ // The base tree is read through the shared committed-tree reader (one `git ls-tree`, one // `git cat-file --batch`), never a second checkout and never a read per file. -import { mergeBaseWithMain, readCommittedSources } from '../__tests__/committed-source-tree.ts'; +import { + mergeBaseWithMain, + readCommittedSources, + renamedSince, +} from '../__tests__/committed-source-tree.ts'; import { largestTypeCycleMembers, memoizedImportParser, resolveImportEdges, + targetDagZone, typeInversionCounts, type ImportParser, type ResolvedImportEdge, @@ -59,10 +64,28 @@ export function mergeBaseRatchets( ): MergeBaseRatchets { const ref = mergeBaseWithMain(repoRoot); const { sources, manifests } = readCommittedSources(repoRoot, ref); - const edges = resolveImportEdges( + // Measure the base tree in the working tree's coordinates: a `git mv` since the merge-base + // (the daemon's move to packages/daemon, 11b) would otherwise make rules keyed on current + // paths read the base as empty and accept any growth above a zero reference. Edges are + // resolved in base coordinates first — the base tree is internally consistent — and then + // the resolved endpoints are canonicalized base -> head, exactly like the eager-closure + // ratchet canonicalizes entries. + const baseToHead = new Map( + [...renamedSince(repoRoot, ref)].map(([headPath, basePath]) => [basePath, headPath]), + ); + const toHead = (file: string) => baseToHead.get(file) ?? file; + const baseEdges = resolveImportEdges( sources, workspaceSpecifierTargetsFromManifests(manifests), parse, ); - return { ref, ...measureRatchets(sources, edges) }; + const edges = baseEdges.map((edge) => { + const file = toHead(edge.file); + const target = toHead(edge.target); + return file === edge.file && target === edge.target + ? edge + : { ...edge, file, target, fromZone: targetDagZone(file), toZone: targetDagZone(target) }; + }); + const canonical = new Map([...sources].map(([file, text]) => [toHead(file), text])); + return { ref, ...measureRatchets(canonical, edges) }; } diff --git a/scripts/layering/record-runtime-mechanics-policy.test.ts b/scripts/layering/record-runtime-mechanics-policy.test.ts index 0e4bc2cd9a..501e6c5df3 100644 --- a/scripts/layering/record-runtime-mechanics-policy.test.ts +++ b/scripts/layering/record-runtime-mechanics-policy.test.ts @@ -5,7 +5,7 @@ import { recordRuntimeDaemonMechanicsViolations } from './record-runtime-mechani test('R16 rejects native mechanics in the daemon record owner without scanning prose', () => { const violations = recordRuntimeDaemonMechanicsViolations([ { - path: 'src/daemon/handlers/record-runtime.ts', + path: 'packages/daemon/src/handlers/record-runtime.ts', source: ` import fs from 'node:fs'; import { runCmdBackground } from '@agent-device/host-kit/command'; @@ -20,17 +20,17 @@ test('R16 rejects native mechanics in the daemon record owner without scanning p }, ]); assert.deepEqual(violations, [ - 'src/daemon/handlers/record-runtime.ts: daemon record owner imports native mechanic node:fs', - 'src/daemon/handlers/record-runtime.ts: daemon record owner imports native mechanic @agent-device/host-kit/command', - 'src/daemon/handlers/record-runtime.ts: daemon record owner calls native mechanic setTimeout', - 'src/daemon/handlers/record-runtime.ts: daemon record owner calls native mechanic runCmdBackground', + 'packages/daemon/src/handlers/record-runtime.ts: daemon record owner imports native mechanic node:fs', + 'packages/daemon/src/handlers/record-runtime.ts: daemon record owner imports native mechanic @agent-device/host-kit/command', + 'packages/daemon/src/handlers/record-runtime.ts: daemon record owner calls native mechanic setTimeout', + 'packages/daemon/src/handlers/record-runtime.ts: daemon record owner calls native mechanic runCmdBackground', ]); }); test('R16 rejects child termination and platform branching in daemon record owners', () => { const violations = recordRuntimeDaemonMechanicsViolations([ { - path: 'src/daemon/handlers/record-runtime.ts', + path: 'packages/daemon/src/handlers/record-runtime.ts', source: ` // child.kill(), process.kill(), and device.platform === 'apple' are prose. const prose = 'switch (device.platform)'; diff --git a/scripts/layering/record-runtime-mechanics-policy.ts b/scripts/layering/record-runtime-mechanics-policy.ts index cf80728d1a..11ad519fcd 100644 --- a/scripts/layering/record-runtime-mechanics-policy.ts +++ b/scripts/layering/record-runtime-mechanics-policy.ts @@ -69,7 +69,7 @@ export function recordRuntimeDaemonMechanicsViolations( } function isDaemonRecordOwner(filePath: string): boolean { - return /^src\/daemon\/handlers\/record-runtime(?:-[^/]+)?\.ts$/.test(filePath); + return /^packages\/daemon\/src\/handlers\/record-runtime(?:-[^/]+)?\.ts$/.test(filePath); } function isDaemonRecordMechanicImport(imported: string): boolean { diff --git a/scripts/layering/retired-paths-policy.test.ts b/scripts/layering/retired-paths-policy.test.ts index 67a1be18ea..b26442aa9f 100644 --- a/scripts/layering/retired-paths-policy.test.ts +++ b/scripts/layering/retired-paths-policy.test.ts @@ -97,7 +97,7 @@ test('R71 accepts the current replay owners and ignores the src/utils zone', () retiredPathRuleViolations('R71', [ 'packages/replay-port/src/script-source-bundle.ts', 'src/cli/replay-test/reporting.ts', - 'src/daemon/replay-script-source.ts', + 'packages/daemon/src/replay-script-source.ts', 'src/replay-next.ts', 'src/utils/regrown.ts', ]), diff --git a/scripts/layering/root-module-zones.ts b/scripts/layering/root-module-zones.ts index 032f4d448b..40e119875e 100644 --- a/scripts/layering/root-module-zones.ts +++ b/scripts/layering/root-module-zones.ts @@ -28,7 +28,7 @@ export const ROOT_MODULE_ZONES: Readonly> = { // The platform composition the daemon, CLI and SDK import eagerly. It shares the zone with its // private `src/platform-runtime/` submodule, and with the daemon runtime's dependency // construction, which names these same runtime families and keeps the same value-free direction - // toward `src/daemon/` (PR 6 of #3276's daemon extraction). + // toward `packages/daemon/src/` (PR 6 of #3276's daemon extraction). 'platform-runtime': [ 'src/daemon-composition.ts', 'src/platform-runtime-android-mechanics.ts', diff --git a/scripts/layering/runtime-execution-policy.test.ts b/scripts/layering/runtime-execution-policy.test.ts index d530a46fb4..fd30ad3f9a 100644 --- a/scripts/layering/runtime-execution-policy.test.ts +++ b/scripts/layering/runtime-execution-policy.test.ts @@ -3,7 +3,7 @@ import { test } from 'node:test'; import { runtimeExecutionIntegrityViolations } from './runtime-execution-policy.ts'; const REGISTRY = 'packages/command-registry/src/registry.ts'; -const ADMISSION = 'src/daemon/runtime-admission.ts'; +const ADMISSION = 'packages/daemon/src/runtime-admission.ts'; function sources(entries: readonly (readonly [string, string])[]): ReadonlyMap { return new Map(entries); @@ -36,7 +36,7 @@ test('the permanent runtime policy accepts facts-only admission and typed operat `), ], [ - 'src/daemon/handler.ts', + 'packages/daemon/src/handler.ts', `async function run(runtime) { return runtime.operations.focusPoint(input); }`, ], ]), @@ -56,7 +56,7 @@ test('a descriptor capability bucket and legacy admission call are rejected glob `requireFactsInspection(request.inspectFacts); requireDeviceBinding(request.bindDevice);`, ), ], - ['src/daemon/planted.ts', `requireCommandSupported('focus', device);`], + ['packages/daemon/src/planted.ts', `requireCommandSupported('focus', device);`], ]); assert.deepEqual(found, [ 'command descriptors may not restore capability-bucket admission', @@ -74,7 +74,7 @@ test('daemon code cannot cast, assert, or bracket its way around runtime narrowi ), ], [ - 'src/daemon/planted.ts', + 'packages/daemon/src/planted.ts', ` const forged = value as BoundDeviceRuntime; runtime.operations.focusPoint!; @@ -103,7 +103,7 @@ test('dynamic operation iteration used by admission remains legal', () => { `requireFactsInspection(request.inspectFacts); requireDeviceBinding(request.bindDevice);`, ), ], - ['src/daemon/planted.ts', `const fact = facts.operations[operation];`], + ['packages/daemon/src/planted.ts', `const fact = facts.operations[operation];`], ]), [], ); diff --git a/scripts/layering/runtime-execution-policy.ts b/scripts/layering/runtime-execution-policy.ts index 4c6573a384..06a9517626 100644 --- a/scripts/layering/runtime-execution-policy.ts +++ b/scripts/layering/runtime-execution-policy.ts @@ -11,6 +11,7 @@ // token is a type, so an `as` cast or narrowing to it type-checks from any module. import { parseSync } from 'oxc-parser'; +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; import { memberName, propertyName, visitAst } from './layering-ast.ts'; import type { LayeringViolation } from './model.ts'; @@ -19,7 +20,7 @@ type AstNode = Record; export const RUNTIME_EXECUTION_INTEGRITY_RULE = 'R66 runtime-execution-integrity'; const COMMAND_DESCRIPTOR_MODULE = 'packages/command-registry/src/registry.ts'; -const RUNTIME_ADMISSION_MODULE = 'src/daemon/runtime-admission.ts'; +const RUNTIME_ADMISSION_MODULE = 'packages/daemon/src/runtime-admission.ts'; const RUNTIME_PROOF_TYPES = new Set(['AdmittedRuntimePlan', 'BoundDeviceRuntime']); /** Facts are the only admission authority, and daemon code must consume narrowed runtime proofs. */ @@ -40,7 +41,7 @@ export function runtimeExecutionIntegrityViolations( at(file, source, node, 'runtime facts are the only device-command admission authority'), ); } - if (!file.startsWith('src/daemon/')) return; + if (!file.startsWith(DAEMON_SOURCE_ROOT)) return; if (isManufacturedRuntimeProof(node)) { violations.push( at(file, source, node, 'daemon code may not manufacture a narrowed runtime proof'), diff --git a/scripts/layering/selector-pipeline-ownership.test.ts b/scripts/layering/selector-pipeline-ownership.test.ts index f77e83c00d..a992f86aea 100644 --- a/scripts/layering/selector-pipeline-ownership.test.ts +++ b/scripts/layering/selector-pipeline-ownership.test.ts @@ -13,7 +13,7 @@ import { * `parseImports` the gate uses. That is the point of the shape: a bypass is * only refused in every import FORM if the check never looks at symbol names. */ -function violations(source: string, file = 'src/daemon/handlers/planted.ts'): string[] { +function violations(source: string, file = 'packages/daemon/src/handlers/planted.ts'): string[] { const edges: ResolvedImportEdge[] = parseImports(source).map((edge) => ({ ...edge, file, diff --git a/scripts/layering/session-authority-overlay.test.ts b/scripts/layering/session-authority-overlay.test.ts index 68af64910a..009a0f6bac 100644 --- a/scripts/layering/session-authority-overlay.test.ts +++ b/scripts/layering/session-authority-overlay.test.ts @@ -23,21 +23,22 @@ function overlayOf(sources: Record): SessionAuthorityOverlay { test('the overlay counts symbol-level production importers, not file-level importers', () => { const sources = { - 'src/daemon/session-state.ts': STATE_STUB, - 'src/daemon/session-store.ts': STORE_STUB, - 'src/daemon/handlers/fixture.ts': + 'packages/daemon/src/session-state.ts': STATE_STUB, + 'packages/daemon/src/session-store.ts': STORE_STUB, + 'packages/daemon/src/handlers/fixture.ts': "import type { SessionState } from '../session-state.ts';\n" + "import { SessionStore } from '../session-store.ts';\n", - 'src/daemon/handlers/request-only.ts': + 'packages/daemon/src/handlers/request-only.ts': "import type { DaemonRequest } from '../session-state.ts';\n" + "import { resolveDaemonStateDir } from '../session-store.ts';\n", - 'src/daemon/non-handler.ts': "import type { SessionState } from './session-state.ts';\n", - 'src/daemon/handlers/fixture.test.ts': + 'packages/daemon/src/non-handler.ts': + "import type { SessionState } from './session-state.ts';\n", + 'packages/daemon/src/handlers/fixture.test.ts': "import type { SessionState } from '../session-state.ts';\n", }; assert.deepEqual(overlayOf(sources), { - shapeFiles: ['src/daemon/handlers/fixture.ts', 'src/daemon/non-handler.ts'], - authorityFiles: ['src/daemon/handlers/fixture.ts'], + shapeFiles: ['packages/daemon/src/handlers/fixture.ts', 'packages/daemon/src/non-handler.ts'], + authorityFiles: ['packages/daemon/src/handlers/fixture.ts'], }); }); @@ -45,14 +46,16 @@ test('the overlay follows the SessionState declaration to a moved path, not a re // Planted-red against a hardcoded src/daemon/types.ts target: #2346 moved the declaration to // session-state.ts, so importers point there, and the overlay must still count them. const sources = { - 'src/daemon/types.ts': 'export type DaemonRequest = { x: number; };\n', - 'src/daemon/session-state.ts': STATE_STUB, - 'src/daemon/session-store.ts': STORE_STUB, - 'src/daemon/handlers/fixture.ts': "import type { SessionState } from '../session-state.ts';\n", - 'src/daemon/non-handler.ts': "import type { SessionState } from './session-state.ts';\n", + 'packages/daemon/src/types.ts': 'export type DaemonRequest = { x: number; };\n', + 'packages/daemon/src/session-state.ts': STATE_STUB, + 'packages/daemon/src/session-store.ts': STORE_STUB, + 'packages/daemon/src/handlers/fixture.ts': + "import type { SessionState } from '../session-state.ts';\n", + 'packages/daemon/src/non-handler.ts': + "import type { SessionState } from './session-state.ts';\n", }; assert.deepEqual(overlayOf(sources), { - shapeFiles: ['src/daemon/handlers/fixture.ts', 'src/daemon/non-handler.ts'], + shapeFiles: ['packages/daemon/src/handlers/fixture.ts', 'packages/daemon/src/non-handler.ts'], authorityFiles: [], }); }); @@ -60,34 +63,40 @@ test('the overlay follows the SessionState declaration to a moved path, not a re test('the handler-owned subset is the flat handlers surface only', () => { const overlay: SessionAuthorityOverlay = { shapeFiles: [ - 'src/daemon/handlers/fixture.ts', - 'src/daemon/non-handler.ts', - 'src/daemon/interaction/internal/interaction.ts', + 'packages/daemon/src/handlers/fixture.ts', + 'packages/daemon/src/non-handler.ts', + 'packages/daemon/src/interaction/internal/interaction.ts', + ], + authorityFiles: [ + 'packages/daemon/src/handlers/fixture.ts', + 'packages/daemon/src/request-router.ts', ], - authorityFiles: ['src/daemon/handlers/fixture.ts', 'src/daemon/request-router.ts'], }; assert.deepEqual(handlerOwnedOverlay(overlay), { - shapeFiles: ['src/daemon/handlers/fixture.ts'], - authorityFiles: ['src/daemon/handlers/fixture.ts'], + shapeFiles: ['packages/daemon/src/handlers/fixture.ts'], + authorityFiles: ['packages/daemon/src/handlers/fixture.ts'], }); }); test('R75 fails a handler file that gains a shape or authority edge beyond the merge-base', () => { const reference: SessionAuthorityOverlay = { - shapeFiles: ['src/daemon/handlers/kept.ts'], - authorityFiles: ['src/daemon/handlers/kept.ts'], + shapeFiles: ['packages/daemon/src/handlers/kept.ts'], + authorityFiles: ['packages/daemon/src/handlers/kept.ts'], }; const measured: SessionAuthorityOverlay = { - shapeFiles: ['src/daemon/handlers/kept.ts', 'src/daemon/handlers/new-shape.ts'], - authorityFiles: ['src/daemon/handlers/new-authority.ts'], + shapeFiles: [ + 'packages/daemon/src/handlers/kept.ts', + 'packages/daemon/src/handlers/new-shape.ts', + ], + authorityFiles: ['packages/daemon/src/handlers/new-authority.ts'], }; const violations = checkSessionAuthorityOverlay(measured, reference); assert.equal(violations.length, 2); const shape = violations.find( - (violation) => violation.file === 'src/daemon/handlers/new-shape.ts', + (violation) => violation.file === 'packages/daemon/src/handlers/new-shape.ts', )!; const authority = violations.find( - (violation) => violation.file === 'src/daemon/handlers/new-authority.ts', + (violation) => violation.file === 'packages/daemon/src/handlers/new-authority.ts', )!; assert.equal(shape.rule, SESSION_AUTHORITY_OVERLAY_RULE); assert.equal(authority.rule, SESSION_AUTHORITY_OVERLAY_RULE); @@ -97,11 +106,11 @@ test('R75 fails a handler file that gains a shape or authority edge beyond the m test('R75 passes when the handler-owned sets hold or shrink', () => { const reference: SessionAuthorityOverlay = { - shapeFiles: ['src/daemon/handlers/a.ts', 'src/daemon/handlers/b.ts'], - authorityFiles: ['src/daemon/handlers/a.ts'], + shapeFiles: ['packages/daemon/src/handlers/a.ts', 'packages/daemon/src/handlers/b.ts'], + authorityFiles: ['packages/daemon/src/handlers/a.ts'], }; const measured: SessionAuthorityOverlay = { - shapeFiles: ['src/daemon/handlers/a.ts'], + shapeFiles: ['packages/daemon/src/handlers/a.ts'], authorityFiles: [], }; assert.deepEqual(checkSessionAuthorityOverlay(measured, reference), []); @@ -109,8 +118,8 @@ test('R75 passes when the handler-owned sets hold or shrink', () => { test('R75 leaves new non-handler importers to the module declarations, not this ratchet', () => { const measured: SessionAuthorityOverlay = { - shapeFiles: ['src/daemon/new-module.ts'], - authorityFiles: ['src/daemon/server/new-module.ts'], + shapeFiles: ['packages/daemon/src/new-module.ts'], + authorityFiles: ['packages/daemon/src/server/new-module.ts'], }; assert.deepEqual( checkSessionAuthorityOverlay(measured, { shapeFiles: [], authorityFiles: [] }), @@ -120,38 +129,41 @@ test('R75 leaves new non-handler importers to the module declarations, not this test('the end-to-end measurement feeds the ratchet: a new handler importer is red, an existing one is not', () => { const base = { - 'src/daemon/session-state.ts': STATE_STUB, - 'src/daemon/session-store.ts': STORE_STUB, - 'src/daemon/handlers/kept.ts': "import type { SessionState } from '../session-state.ts';\n", + 'packages/daemon/src/session-state.ts': STATE_STUB, + 'packages/daemon/src/session-store.ts': STORE_STUB, + 'packages/daemon/src/handlers/kept.ts': + "import type { SessionState } from '../session-state.ts';\n", }; const reference = handlerOwnedOverlay(overlayOf(base)); const grown = { ...base, - 'src/daemon/handlers/new.ts': "import type { SessionState } from '../session-state.ts';\n", + 'packages/daemon/src/handlers/new.ts': + "import type { SessionState } from '../session-state.ts';\n", }; const measured = handlerOwnedOverlay(overlayOf(grown)); assert.deepEqual(checkSessionAuthorityOverlay(reference, reference), []); const violations = checkSessionAuthorityOverlay(measured, reference); assert.equal(violations.length, 1); - assert.equal(violations[0]!.file, 'src/daemon/handlers/new.ts'); + assert.equal(violations[0]!.file, 'packages/daemon/src/handlers/new.ts'); }); test('R75 catches a new handler shape edge expressed as an import type', () => { const base = { - 'src/daemon/session-state.ts': STATE_STUB, - 'src/daemon/session-store.ts': STORE_STUB, + 'packages/daemon/src/session-state.ts': STATE_STUB, + 'packages/daemon/src/session-store.ts': STORE_STUB, }; const reference = handlerOwnedOverlay(overlayOf(base)); const measured = handlerOwnedOverlay( overlayOf({ ...base, - 'src/daemon/handlers/new.ts': "type State = import('../session-state.ts').SessionState;\n", + 'packages/daemon/src/handlers/new.ts': + "type State = import('../session-state.ts').SessionState;\n", }), ); const violations = checkSessionAuthorityOverlay(measured, reference); assert.equal(violations.length, 1); assert.equal(violations[0]!.rule, SESSION_AUTHORITY_OVERLAY_RULE); - assert.equal(violations[0]!.file, 'src/daemon/handlers/new.ts'); + assert.equal(violations[0]!.file, 'packages/daemon/src/handlers/new.ts'); assert.match(violations[0]!.message, /new handler-owned SessionState shape edge/); }); diff --git a/scripts/layering/session-authority-overlay.ts b/scripts/layering/session-authority-overlay.ts index 3e4d3a78cc..4637d5ae1d 100644 --- a/scripts/layering/session-authority-overlay.ts +++ b/scripts/layering/session-authority-overlay.ts @@ -4,25 +4,25 @@ import { sessionStateDeclarationFile } from './session-state.ts'; // The SessionState/SessionStore authority overlay (#2278, ADR 0022): which production files // import the SessionState shape from the module that declares it and the SessionStore authority -// from src/daemon/session-store.ts, at symbol level so that a file importing only helper +// from packages/daemon/src/session-store.ts, at symbol level so that a file importing only helper // functions from session-store.ts is not an authority edge. R7 already owns the write side // (field ownership); this overlay owns the read side. The shape target is found by the // declaration, not a recorded path: a path constant would silently measure zero shape importers // the moment the declaration moves (#2346 moved it from types.ts to session-state.ts). The -// ratchet applies to the handler-owned subset — the flat src/daemon/handlers/ surface the +// ratchet applies to the handler-owned subset — the flat packages/daemon/src/handlers/ surface the // #2132 migration targeted — and is a membership ratchet against the merge-base: the set may // only shrink, so a handler file gaining state-shape or store authority fails instead of // silently regrowing the hotspot. export const SESSION_AUTHORITY_OVERLAY_RULE = 'R75 session-authority-overlay'; -const SESSION_STORE_AUTHORITY_TARGET = 'src/daemon/session-store.ts'; -const HANDLER_ROOT = 'src/daemon/handlers/'; +const SESSION_STORE_AUTHORITY_TARGET = 'packages/daemon/src/session-store.ts'; +const HANDLER_ROOT = 'packages/daemon/src/handlers/'; export type SessionAuthorityOverlay = Readonly<{ /** Production files importing the SessionState symbol from its declaring module, sorted. */ shapeFiles: readonly string[]; - /** Production files importing the SessionStore symbol from src/daemon/session-store.ts, sorted. */ + /** Production files importing the SessionStore symbol from packages/daemon/src/session-store.ts, sorted. */ authorityFiles: readonly string[]; }>; @@ -60,7 +60,7 @@ export function handlerOwnedOverlay(overlay: SessionAuthorityOverlay): SessionAu /** * Catches: the handler-owned SessionState-shape / SessionStore-authority surface regrowing — - * a file under src/daemon/handlers/ importing either symbol that the merge-base does not + * a file under packages/daemon/src/handlers/ importing either symbol that the merge-base does not * already import it, which is exactly the deep-import the #2132 migration paid to delete. * Both overlays are full-scope; the handler-owned subset is filtered here, at the single * place the ratchet applies it, so the message can never name a file outside its scope. diff --git a/scripts/layering/session-resource-ownership.test.ts b/scripts/layering/session-resource-ownership.test.ts index 9f29c09f99..1f351f93eb 100644 --- a/scripts/layering/session-resource-ownership.test.ts +++ b/scripts/layering/session-resource-ownership.test.ts @@ -12,7 +12,7 @@ test('session resources are constructed only by their durable domain owners', () assert.deepEqual( summaries([ [ - 'src/daemon/handlers/planted.ts', + 'packages/daemon/src/handlers/planted.ts', `sessionStore.set(name, { ...session, appLog: log, @@ -23,17 +23,17 @@ test('session resources are constructed only by their durable domain owners', () });`, ], [ - 'src/daemon/app-log-session-resource.ts', + 'packages/daemon/src/app-log-session-resource.ts', `sessionStore.update(ref, { appLog: log, appLogFailure: undefined });`, ], [ - 'src/daemon/session-capture-binding.ts', + 'packages/daemon/src/session-capture-binding.ts', `sessionStore.update(ref, { audioProbe: audio }); sessionStore.update(ref, { perfCapture: perf }); sessionStore.update(ref, { screenRecording: recording });`, ], [ - 'src/daemon/screen-recording-session-binding.ts', + 'packages/daemon/src/screen-recording-session-binding.ts', `sessionStore.publish(address, { ...draft, screenRecording });`, ], [ @@ -46,12 +46,12 @@ test('session resources are constructed only by their durable domain owners', () ], ]), [ - 'src/daemon/handlers/planted.ts: session appLog record constructed outside its owner', - 'src/daemon/handlers/planted.ts: session appLogFailure record constructed outside its owner', - 'src/daemon/handlers/planted.ts: session audioProbe record constructed outside its owner', - 'src/daemon/handlers/planted.ts: session perfCapture record constructed outside its owner', - 'src/daemon/handlers/planted.ts: session screenRecording record constructed outside its owner', - 'src/daemon/screen-recording-session-binding.ts: session screenRecording record constructed outside its owner', + 'packages/daemon/src/handlers/planted.ts: session appLog record constructed outside its owner', + 'packages/daemon/src/handlers/planted.ts: session appLogFailure record constructed outside its owner', + 'packages/daemon/src/handlers/planted.ts: session audioProbe record constructed outside its owner', + 'packages/daemon/src/handlers/planted.ts: session perfCapture record constructed outside its owner', + 'packages/daemon/src/handlers/planted.ts: session screenRecording record constructed outside its owner', + 'packages/daemon/src/screen-recording-session-binding.ts: session screenRecording record constructed outside its owner', 'packages/capture-kit/src/capture-admission/audio-probe-session-resource.ts: session audioProbe record constructed outside its owner', 'packages/capture-kit/src/capture-admission/perf-capture-session-resource.ts: session perfCapture record constructed outside its owner', ], @@ -76,12 +76,14 @@ test('teardown app-log discriminants are policy input rather than session constr assert.deepEqual( summaries([ [ - 'src/daemon/session-teardown.ts', + 'packages/daemon/src/session-teardown.ts', `teardownSessionResources({ appLog: 'run' }); teardownSessionResources({ appLog: 'already-settled' });`, ], - ['src/daemon/handlers/planted.ts', `teardownSessionResources({ appLog: 'skip' });`], + ['packages/daemon/src/handlers/planted.ts', `teardownSessionResources({ appLog: 'skip' });`], ]), - ['src/daemon/handlers/planted.ts: session appLog record constructed outside its owner'], + [ + 'packages/daemon/src/handlers/planted.ts: session appLog record constructed outside its owner', + ], ); }); diff --git a/scripts/layering/session-resource-ownership.ts b/scripts/layering/session-resource-ownership.ts index f9274f53e8..016af4ac94 100644 --- a/scripts/layering/session-resource-ownership.ts +++ b/scripts/layering/session-resource-ownership.ts @@ -10,6 +10,7 @@ // are plain mutable properties on the shared session record, so an outside write type-checks. import { parseSync } from 'oxc-parser'; +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; import { propertyName, visitAst } from './layering-ast.ts'; import type { LayeringViolation } from './model.ts'; @@ -22,17 +23,29 @@ export const SESSION_RESOURCE_OWNERSHIP_RULE = 'R68 session-resource-ownership'; * `@agent-device/capture-kit`, so the scan covers that directory alongside the daemon: the rule * guards the field, not the folder it happens to live in. */ -const SCANNED_ROOTS = ['src/daemon/', 'packages/capture-kit/src/capture-admission/'] as const; +const SCANNED_ROOTS = [DAEMON_SOURCE_ROOT, 'packages/capture-kit/src/capture-admission/'] as const; const RESOURCE_OWNERS: Readonly>> = { - appLog: new Set(['src/daemon/app-log-session-resource.ts', 'src/daemon/session-state.ts']), - appLogFailure: new Set(['src/daemon/app-log-session-resource.ts', 'src/daemon/session-state.ts']), - audioProbe: new Set(['src/daemon/session-capture-binding.ts', 'src/daemon/session-state.ts']), + appLog: new Set([ + 'packages/daemon/src/app-log-session-resource.ts', + 'packages/daemon/src/session-state.ts', + ]), + appLogFailure: new Set([ + 'packages/daemon/src/app-log-session-resource.ts', + 'packages/daemon/src/session-state.ts', + ]), + audioProbe: new Set([ + 'packages/daemon/src/session-capture-binding.ts', + 'packages/daemon/src/session-state.ts', + ]), screenRecording: new Set([ - 'src/daemon/session-capture-binding.ts', - 'src/daemon/session-state.ts', + 'packages/daemon/src/session-capture-binding.ts', + 'packages/daemon/src/session-state.ts', + ]), + perfCapture: new Set([ + 'packages/daemon/src/session-capture-binding.ts', + 'packages/daemon/src/session-state.ts', ]), - perfCapture: new Set(['src/daemon/session-capture-binding.ts', 'src/daemon/session-state.ts']), }; /** Durable session-resource records have one whole-record construction owner per domain. */ diff --git a/scripts/layering/session-state.test.ts b/scripts/layering/session-state.test.ts index c2c12bdb12..d24ec0552c 100644 --- a/scripts/layering/session-state.test.ts +++ b/scripts/layering/session-state.test.ts @@ -7,7 +7,7 @@ import { sessionStateWritePressure, } from './session-state.ts'; -const OWNER = 'src/daemon/app-log-session-resource.ts'; +const OWNER = 'packages/daemon/src/app-log-session-resource.ts'; const FIELDS = ['appLog', 'appLogFailure', 'lease', 'lastPerfProfile']; function scan(source: string, file = OWNER) { assert.deepEqual(parseSync(file, source).errors, [], `fixture must parse as a module: ${file}`); @@ -28,7 +28,7 @@ test('explicit owner patches name their writes and retain direct assignment chec assert.ok(SESSION_STATE_FIELD_OWNERS.appLogFailure!.includes(OWNER)); const foreign = scan( 'sessionStore.update(ref, { appLogFailure: error });', - 'src/daemon/handlers/probe.ts', + 'packages/daemon/src/handlers/probe.ts', )[0]!; assert.equal(foreign.field, 'appLogFailure'); assert.ok(!SESSION_STATE_FIELD_OWNERS[foreign.field]!.includes(foreign.file)); @@ -353,8 +353,8 @@ test('alias declarations and patch parameters are collected before checking writ test('draft exceptions cover only the declared constructors and fresh open publication', () => { for (const [file, constructor] of [ - ['src/daemon/snapshot-session.ts', 'createSnapshotSession'], - ['src/daemon/handlers/record-runtime.ts', 'createRecordOnlySession'], + ['packages/daemon/src/snapshot-session.ts', 'createSnapshotSession'], + ['packages/daemon/src/handlers/record-runtime.ts', 'createRecordOnlySession'], ]) { assert.deepEqual( scan( @@ -369,7 +369,7 @@ test('draft exceptions cover only the declared constructors and fresh open publi ), ); } - const open = 'src/daemon/session-lifecycle/internal/session-open-state.ts'; + const open = 'packages/daemon/src/session-lifecycle/internal/session-open-state.ts'; assert.deepEqual( scan( 'function publishOpenSession(session: SessionState) { return store.publish(address, { ...session }); }', @@ -395,7 +395,7 @@ test('the owning store can merge records, while unrelated updates and platform s assert.deepEqual( scan( 'sessionStore.update(ref, changes); session.appLogFailure = error;', - 'src/daemon/session-store.ts', + 'packages/daemon/src/session-store.ts', ), [], ); @@ -413,17 +413,17 @@ test('pressure counts capture-kit record replacement and daemon patches with the const declaration = 'export type SessionState = {\n appLogFailure?: Error;\n lease?: object;\n};'; const baseline = new Map([ - ['src/daemon/session-state.ts', declaration], - ['src/daemon/owner.ts', 'session.appLogFailure = error;'], + ['packages/daemon/src/session-state.ts', declaration], + ['packages/daemon/src/owner.ts', 'session.appLogFailure = error;'], [ 'packages/capture-kit/src/capture-admission/owner.ts', 'const next = { ...session, appLogFailure: error };', ], ]); const current = new Map([ - ['src/daemon/session-state.ts', declaration], + ['packages/daemon/src/session-state.ts', declaration], [OWNER, 'store.update(ref, { appLogFailure: error });'], - ['src/daemon/invalid.ts', 'store.update(ref, changes);'], + ['packages/daemon/src/invalid.ts', 'store.update(ref, changes);'], ]); assert.deepEqual(sessionStateWritePressure(baseline), { writerOwnedFields: 1, diff --git a/scripts/layering/session-state.ts b/scripts/layering/session-state.ts index e3d97159d9..f1801a3a0d 100644 --- a/scripts/layering/session-state.ts +++ b/scripts/layering/session-state.ts @@ -1,6 +1,7 @@ /** SessionState field ownership for assignments, named patches and record copies. */ import { parseSync } from 'oxc-parser'; +import { DAEMON_SOURCE_ROOT } from './tracked-sources.ts'; import { memberName, memberPath, propertyName, visitAst } from './layering-ast.ts'; import path from 'node:path'; @@ -21,17 +22,20 @@ export const SESSION_STATE_FIELD_OWNERS: Readonlyplaceholder registry is populated and consulted only at the // recorder's single choke point. - recordedFillLiterals: ['src/daemon/session-action-recorder.ts'], + recordedFillLiterals: ['packages/daemon/src/session-action-recorder.ts'], }; /** @@ -156,7 +160,7 @@ export function sessionStateDeclarationFile( sources: ReadonlyMap, ): string | undefined { for (const [file, source] of sources) { - if (file.startsWith('src/daemon/') && SESSION_STATE_DECLARATION.test(source)) return file; + if (file.startsWith(DAEMON_SOURCE_ROOT) && SESSION_STATE_DECLARATION.test(source)) return file; } return undefined; } @@ -407,11 +411,14 @@ function patchObjects(value: unknown): AstNode[] | undefined { return result?.type === 'ObjectExpression' ? [result] : undefined; } -const SESSION_STATE_SCAN_ROOTS = ['src/daemon/', 'packages/capture-kit/src/capture-admission/']; +const SESSION_STATE_SCAN_ROOTS = [ + DAEMON_SOURCE_ROOT, + 'packages/capture-kit/src/capture-admission/', +]; const SESSION_DRAFT_CONSTRUCTORS: Readonly> = { - 'src/daemon/session-lifecycle/internal/session-open-state.ts': 'publishOpenSession', - 'src/daemon/snapshot-session.ts': 'createSnapshotSession', - 'src/daemon/handlers/record-runtime.ts': 'createRecordOnlySession', + 'packages/daemon/src/session-lifecycle/internal/session-open-state.ts': 'publishOpenSession', + 'packages/daemon/src/snapshot-session.ts': 'createSnapshotSession', + 'packages/daemon/src/handlers/record-runtime.ts': 'createRecordOnlySession', }; /** Assignments, named update keys and whole-record copies at the session ownership seam. */ diff --git a/scripts/layering/snapshot-assembly-presentation-policy.ts b/scripts/layering/snapshot-assembly-presentation-policy.ts index b93f795933..f7676165b2 100644 --- a/scripts/layering/snapshot-assembly-presentation-policy.ts +++ b/scripts/layering/snapshot-assembly-presentation-policy.ts @@ -26,7 +26,7 @@ export const SNAPSHOT_ASSEMBLY_PRESENTATION_RULE = 'R74 snapshot-assembly-presen */ export const SNAPSHOT_ASSEMBLY_FILES: readonly string[] = [ 'packages/capture-kit/src/snapshot-state.ts', - 'src/daemon/snapshot-capture.ts', + 'packages/daemon/src/snapshot-capture.ts', ]; /** Producer adapters: they report acquisition facts and nothing else. */ diff --git a/scripts/layering/snapshot-presentation-boundary.test.ts b/scripts/layering/snapshot-presentation-boundary.test.ts index ac87036c95..ffd859ad1e 100644 --- a/scripts/layering/snapshot-presentation-boundary.test.ts +++ b/scripts/layering/snapshot-presentation-boundary.test.ts @@ -11,7 +11,7 @@ const repoRoot = path.resolve(import.meta.dirname, '../..'); /** * The `snapshot-policy` declaration owns presentation, freshness, timeout and overlay policy; - * `src/daemon/` owns the assembly that orders them (#1983, ADR 0004). The dependency runs one way + * `packages/daemon/src/` owns the assembly that orders them (#1983, ADR 0004). The dependency runs one way * only, so a policy stays testable without standing up a session. * * The real tree is clean, which is exactly why the positive control below exists: a filter that @@ -50,14 +50,14 @@ test('the snapshot facet cannot import daemon assembly', () => { test('the boundary reports a facet module that reaches back into the daemon', () => { const sources = new Map([ - ['src/daemon/types.ts', 'export type SessionState = { id: string };\n'], + ['packages/daemon/src/types.ts', 'export type SessionState = { id: string };\n'], [ 'packages/capture-kit/src/snapshot/snapshot-freshness/android.ts', - "import type { SessionState } from '../../../../../src/daemon/types.ts';\nexport type X = SessionState;\n", + "import type { SessionState } from '../../../../../packages/daemon/src/types.ts';\nexport type X = SessionState;\n", ], ]); assert.deepEqual(daemonImportsFromSnapshotFacet(sources), [ - 'packages/capture-kit/src/snapshot/snapshot-freshness/android.ts:1 -> src/daemon/types.ts', + 'packages/capture-kit/src/snapshot/snapshot-freshness/android.ts:1 -> packages/daemon/src/types.ts', ]); }); diff --git a/scripts/layering/tracked-sources.ts b/scripts/layering/tracked-sources.ts index ebe3e81c6f..f33447c058 100644 --- a/scripts/layering/tracked-sources.ts +++ b/scripts/layering/tracked-sources.ts @@ -69,6 +69,12 @@ function listTrackedFiles(repoRoot: string, pathspecs: readonly string[]): strin return out.split('\0').filter(Boolean); } +/** + * The daemon package's source root, as every layering filter sees it. One constant so a + * rule cannot filter on a stale path when the daemon moves again (#3546 review). + */ +export const DAEMON_SOURCE_ROOT = 'packages/daemon/src/'; + /** Production sources only: test files and `__tests__/` trees are not layering subjects. */ export function isProductionSourceFile(file: string): boolean { return file.endsWith('.ts') && !/(?:^|\/)__tests__\//.test(file) && !/\.test\.ts$/.test(file); diff --git a/scripts/layering/zone-value-dag.test.ts b/scripts/layering/zone-value-dag.test.ts index b39c876ecc..2da9d1096d 100644 --- a/scripts/layering/zone-value-dag.test.ts +++ b/scripts/layering/zone-value-dag.test.ts @@ -6,11 +6,20 @@ import { checkZoneValueDag, zoneValueCycles } from './zone-value-dag.ts'; test('two same-rank zones importing each other form a cycle no file-level or rank check sees', () => { const edges = resolveImportEdges( new Map([ - ['src/daemon/lease.ts', "import { isTempPath } from '../remote/temp-path.ts';"], - ['src/daemon/capture.ts', "import { isTempPath } from '../remote/temp-path.ts';"], + [ + 'packages/daemon/src/lease.ts', + "import { isTempPath } from '../../../src/remote/temp-path.ts';", + ], + [ + 'packages/daemon/src/capture.ts', + "import { isTempPath } from '../../../src/remote/temp-path.ts';", + ], ['src/remote/temp-path.ts', 'export const isTempPath = true;'], - ['src/remote/diagnostics.ts', "import { logPath } from '../daemon/paths.ts';"], - ['src/daemon/paths.ts', 'export const logPath = 1;'], + [ + 'src/remote/diagnostics.ts', + "import { logPath } from '../../packages/daemon/src/paths.ts';", + ], + ['packages/daemon/src/paths.ts', 'export const logPath = 1;'], ]), ); @@ -19,12 +28,12 @@ test('two same-rank zones importing each other form a cycle no file-level or ran assert.deepEqual(checkZoneValueDag(edges), [ { rule: 'R80 zone-value-dag', - file: 'src/daemon/capture.ts', + file: 'packages/daemon/src/capture.ts', line: 1, message: 'zone-level value-import cycle: daemon-server -> remote -> daemon-server ' + - '(daemon-server -> remote: src/daemon/capture.ts -> src/remote/temp-path.ts; ' + - 'remote -> daemon-server: src/remote/diagnostics.ts -> src/daemon/paths.ts). ' + + '(daemon-server -> remote: packages/daemon/src/capture.ts -> src/remote/temp-path.ts; ' + + 'remote -> daemon-server: src/remote/diagnostics.ts -> packages/daemon/src/paths.ts). ' + 'Move the contract both zones read below both of them.', }, ]); @@ -33,10 +42,16 @@ test('two same-rank zones importing each other form a cycle no file-level or ran test('type-only, dynamic and same-zone imports never close a zone cycle', () => { const edges = resolveImportEdges( new Map([ - ['src/remote/diagnostics.ts', "import { logPath } from '../daemon/paths.ts';"], - ['src/daemon/paths.ts', "import type { TempPath } from '../remote/temp-path.ts';"], - ['src/daemon/lease.ts', "void import('../remote/temp-path.ts');"], - ['src/daemon/capture.ts', "import { logPath } from './paths.ts';"], + [ + 'src/remote/diagnostics.ts', + "import { logPath } from '../../packages/daemon/src/paths.ts';", + ], + [ + 'packages/daemon/src/paths.ts', + "import type { TempPath } from '../../../src/remote/temp-path.ts';", + ], + ['packages/daemon/src/lease.ts', "void import('../../../src/remote/temp-path.ts');"], + ['packages/daemon/src/capture.ts', "import { logPath } from './paths.ts';"], ['src/remote/temp-path.ts', 'export type TempPath = string;'], ]), ); diff --git a/scripts/mutation/modules.test.ts b/scripts/mutation/modules.test.ts index 370296bd19..624b8e6a66 100644 --- a/scripts/mutation/modules.test.ts +++ b/scripts/mutation/modules.test.ts @@ -28,7 +28,7 @@ test('every enumerated kernel path exists', () => { test('changed sources map onto the module that owns them', () => { assert.equal(moduleForFile('packages/kernel/src/errors.ts'), 'kernel-errors'); - assert.equal(moduleForFile('./src/daemon/ref-frame.ts'), 'daemon-ref-frame'); + assert.equal(moduleForFile('./packages/daemon/src/ref-frame.ts'), 'daemon-ref-frame'); assert.equal(moduleForFile('packages/selectors/src/internal/parse.ts'), 'selectors'); // Selector tests live under the owned prefix; every other kernel's tests are // attributed by ownership.ts, not by this path match. @@ -89,12 +89,12 @@ test('a kernel test is reachable only under root or package src', () => { // `scripts/__tests__/` (explicitly included by `unit-core`) and this predicate keeps them out of // every mutation lane. Widening the pattern to scripts/ would silently pull them back in and // fail every dry run. - assert.ok(isKernelTestFile('src/daemon/__tests__/ref-frame.test.ts')); + assert.ok(isKernelTestFile('packages/daemon/src/__tests__/ref-frame.test.ts')); assert.ok(isKernelTestFile('packages/selectors/src/parse.test.ts')); assert.ok(!isKernelTestFile('scripts/__tests__/test-file-size-ratchet.test.ts')); assert.ok(!isKernelTestFile('scripts/__tests__/eager-closure-budgets.test.ts')); assert.ok(fs.existsSync(path.join(repoRoot, 'scripts/__tests__/eager-closure-budgets.test.ts'))); assert.ok(!fs.existsSync(path.join(repoRoot, 'src/__tests__/eager-closure-budgets.test.ts'))); assert.ok(!isKernelTestFile('test/integration/daemon.test.ts')); - assert.ok(!isKernelTestFile('src/daemon/ref-frame.ts')); + assert.ok(!isKernelTestFile('packages/daemon/src/ref-frame.ts')); }); diff --git a/scripts/mutation/modules.ts b/scripts/mutation/modules.ts index 62962325ef..dbe59b95db 100644 --- a/scripts/mutation/modules.ts +++ b/scripts/mutation/modules.ts @@ -50,8 +50,8 @@ export const KERNEL_MODULES: readonly KernelModule[] = [ { id: 'daemon-ref-frame', label: 'Ref-frame admission matrix (ADR 0014)', - mutate: ['src/daemon/ref-frame.ts'], - owns: ['src/daemon/ref-frame.ts'], + mutate: ['packages/daemon/src/ref-frame.ts'], + owns: ['packages/daemon/src/ref-frame.ts'], }, { id: 'interaction-settle', diff --git a/scripts/mutation/ownership.test.ts b/scripts/mutation/ownership.test.ts index 9d3299eb3b..36b64d94ba 100644 --- a/scripts/mutation/ownership.test.ts +++ b/scripts/mutation/ownership.test.ts @@ -20,7 +20,9 @@ test('a kernel is owned by the mirrored test that imports it directly', () => { 'kernel-errors', ]); assert.ok( - deriver.ownersOf('src/daemon/__tests__/ref-frame.test.ts').includes('daemon-ref-frame'), + deriver + .ownersOf('packages/daemon/src/__tests__/ref-frame.test.ts') + .includes('daemon-ref-frame'), ); assert.ok( deriver @@ -38,7 +40,9 @@ test('a kernel is owned by tests that reach it indirectly', () => { 'daemon-error.test.ts exercises normalizeError but does not own kernel-errors', ); assert.ok( - deriver.ownersOf('src/daemon/__tests__/back-runtime.test.ts').includes('scroll-edge-state'), + deriver + .ownersOf('packages/daemon/src/__tests__/back-runtime.test.ts') + .includes('scroll-edge-state'), 'back-runtime.test.ts exercises edge detection but does not own scroll-edge-state', ); }); @@ -90,7 +94,7 @@ test('derived selection unions source ownership with test reachability', () => { derivedAffectedModules( [ 'packages/selectors/src/internal/parse.ts', - 'src/daemon/__tests__/ref-frame.test.ts', + 'packages/daemon/src/__tests__/ref-frame.test.ts', 'docs/agents/testing.md', ], repoRoot, diff --git a/scripts/mutation/test-scope.test.ts b/scripts/mutation/test-scope.test.ts index 43d61ba3b8..09453053ae 100644 --- a/scripts/mutation/test-scope.test.ts +++ b/scripts/mutation/test-scope.test.ts @@ -31,7 +31,7 @@ test('the thread-hostile exclusion is derived from imports, not listed', () => { assert.ok(files.includes('src/__tests__/cli-help.test.ts')); assert.ok(files.includes('packages/capture-kit/src/png-worker.test.ts')); // A pure decision-kernel test is never excluded — that would hide survivors. - assert.ok(!files.includes('src/daemon/__tests__/ref-frame.test.ts')); + assert.ok(!files.includes('packages/daemon/src/__tests__/ref-frame.test.ts')); assert.ok(files.every((file) => file.endsWith('.test.ts'))); }); diff --git a/scripts/mutation/workspace-aliases.test.ts b/scripts/mutation/workspace-aliases.test.ts index 6940f4d3db..4daaf5889b 100644 --- a/scripts/mutation/workspace-aliases.test.ts +++ b/scripts/mutation/workspace-aliases.test.ts @@ -2,6 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test } from 'node:test'; +import { resolveWorkspaceSpecifier } from '../layering/model.ts'; import { workspaceSpecifierTargets } from '../layering/package-boundaries.ts'; import { workspaceSourceAliases } from './workspace-aliases.ts'; @@ -13,11 +14,24 @@ test('Stryker aliases every exported workspace subpath exactly', () => { for (const [specifier, target] of targets) { const matches = aliases.filter(({ find }) => find.test(specifier)); - assert.deepEqual( - matches.map(({ replacement }) => replacement), - [path.join(repoRoot, target)], - `${specifier} must resolve to its own export instead of a package-root prefix`, - ); + if (!specifier.endsWith('*')) { + assert.deepEqual( + matches.map(({ replacement }) => replacement), + [path.join(repoRoot, target)], + `${specifier} must resolve to its own export instead of a package-root prefix`, + ); + continue; + } + // A pattern entry aliases through a capture group filling its target's `*`, + // so concrete imports resolve in the sandbox to the same module id as the + // exports map gives them outside it (#3546 review). + const pattern = matches.find(({ replacement }) => replacement.includes('$1')); + assert.ok(pattern, `${specifier} must alias as a capture-group pattern`); + const suffix = 'probe/nested'; + const applied = `${specifier.slice(0, -1)}${suffix}`.replace(pattern.find, pattern.replacement); + const expected = path.join(repoRoot, target); + const star = expected.indexOf('*'); + assert.equal(applied, expected.slice(0, star) + suffix + expected.slice(star + 1)); } assert.equal( @@ -26,6 +40,118 @@ test('Stryker aliases every exported workspace subpath exactly', () => { ); }); +test('every exports map resolves through the alias table exactly as resolveWorkspaceSpecifier does', () => { + // One semantics, three consumers: the alias table Vite applies first-match, + // resolveWorkspaceSpecifier's longest-prefix rule, and Node's exports + // resolution must pick the same module id for every concrete specifier. + const targets = workspaceSpecifierTargets(repoRoot); + const aliases = workspaceSourceAliases(repoRoot, 'tracked-manifests'); + for (const key of targets.keys()) { + const probe = key.endsWith('*') ? `${key.slice(0, -1)}probe/nested` : key; + const expected = resolveWorkspaceSpecifier(probe, targets); + assert.ok(expected, `${probe} must resolve through the exports map`); + const alias = aliases.find(({ find }) => find.test(probe)); + assert.ok(alias, `${probe} must hit an alias`); + assert.equal( + probe.replace(alias.find, alias.replacement), + path.join(repoRoot, expected), + `${probe} must hit the alias for its longest-prefix export`, + ); + } +}); + +test('a named alias wins over a pattern alias that also matches it', () => { + // Vite applies the first matching alias, so exact entries are ordered first; + // a named `./testing/x` under a `./testing/*` pattern keeps its own export. + const aliases = workspaceSourceAliases(repoRoot, 'tracked-manifests'); + const firstExact = aliases.findIndex( + ({ find, replacement }) => !replacement.includes('$1') && find.source.includes('testing/'), + ); + const lastPattern = aliases.findLastIndex(({ replacement }) => replacement.includes('$1')); + assert.ok( + firstExact === -1 || lastPattern === -1 || firstExact < lastPattern, + 'every exact alias must precede every pattern alias', + ); +}); + +test('overlapping patterns alias in longest-prefix order regardless of declaration order', () => { + // The real manifests may happen to declare patterns in the order that hides a + // missing sort, so plant the hostile order: `./testing/*` declared BEFORE + // `./testing/handlers/*`. Vite applies the first matching alias, so the table + // must still hand `testing/handlers/x` to the longer pattern — the same target + // resolveWorkspaceSpecifier picks by Node's longest-prefix rule (#3546 review). + fs.mkdirSync(path.join(repoRoot, '.tmp'), { recursive: true }); + const sandboxRoot = fs.mkdtempSync(path.join(repoRoot, '.tmp', 'stryker-overlap-fixture-')); + try { + const packageDir = path.join(sandboxRoot, 'packages', 'demo'); + fs.mkdirSync(path.join(packageDir, 'src'), { recursive: true }); + fs.writeFileSync( + path.join(packageDir, 'package.json'), + JSON.stringify({ + name: '@agent-device/demo', + // The targets must differ per pattern or the suffix fill would land both + // on the same file and the probe could not tell which alias fired. + exports: { + './testing/*': { default: './src/shadow/*.ts' }, + './testing/handlers/*': { default: './src/handlers/*.ts' }, + }, + }), + ); + const diskAliases = workspaceSourceAliases(sandboxRoot, 'disk-manifests'); + const probe = '@agent-device/demo/testing/handlers/x'; + const alias = diskAliases.find(({ find }) => find.test(probe)); + assert.ok(alias, `${probe} must hit an alias`); + assert.equal( + probe.replace(alias.find, alias.replacement), + path.join(sandboxRoot, 'packages', 'demo', 'src', 'handlers', 'x.ts'), + `${probe} must alias through the longer pattern even though the shorter one was declared first`, + ); + const targets = new Map([ + ['@agent-device/demo/testing/*', 'packages/demo/src/shadow/*.ts'], + ['@agent-device/demo/testing/handlers/*', 'packages/demo/src/handlers/*.ts'], + ]); + assert.equal( + probe.replace(alias.find, alias.replacement), + path.join(sandboxRoot, resolveWorkspaceSpecifier(probe, targets)!), + 'the first-matched alias must agree with resolveWorkspaceSpecifier on hostile declaration order too', + ); + } finally { + fs.rmSync(sandboxRoot, { recursive: true, force: true }); + } +}); + +test('a repo root containing replacement patterns survives the alias round-trip', () => { + // A checkout under a path like `/build/$1/app` is rare but legal. The pattern + // alias applies with a STRING replacement, so every `$` in the repo path must + // arrive doubled: with a plain `$$` string replace, `$$` means one `$` and + // each `$` survives UNescaped, letting `$&`/`$1` in the path expand to the + // match or the capture when Vite applies the alias (#3546 review). + fs.mkdirSync(path.join(repoRoot, '.tmp'), { recursive: true }); + const sandboxRoot = fs.mkdtempSync(path.join(repoRoot, '.tmp', 'stryker-dollar-$&$1-fixture-')); + try { + const packageDir = path.join(sandboxRoot, 'packages', 'demo'); + fs.mkdirSync(path.join(packageDir, 'src'), { recursive: true }); + fs.writeFileSync( + path.join(packageDir, 'package.json'), + JSON.stringify({ + name: '@agent-device/demo', + exports: { './testing/*': { default: './src/testing/*.ts' } }, + }), + ); + const alias = workspaceSourceAliases(sandboxRoot, 'disk-manifests').find(({ find }) => + find.test('@agent-device/demo/testing/handlers/x'), + ); + assert.ok(alias, 'the pattern export must produce an alias'); + assert.equal( + '@agent-device/demo/testing/handlers/x'.replace(alias.find, alias.replacement), + path.join(sandboxRoot, 'packages', 'demo', 'src', 'testing', 'handlers', 'x.ts'), + 'the $-bearing root must round-trip through the alias to its literal path', + ); + } finally { + fs.rmSync(sandboxRoot, { recursive: true, force: true }); + } +}); + test('disk manifests alias an untracked sandbox copy the tracked reader cannot see', () => { fs.mkdirSync(path.join(repoRoot, '.tmp'), { recursive: true }); const sandboxRoot = fs.mkdtempSync(path.join(repoRoot, '.tmp', 'stryker-sandbox-fixture-')); diff --git a/scripts/mutation/workspace-aliases.ts b/scripts/mutation/workspace-aliases.ts index 31e0167366..45f56ca07e 100644 --- a/scripts/mutation/workspace-aliases.ts +++ b/scripts/mutation/workspace-aliases.ts @@ -9,8 +9,40 @@ export type WorkspaceSourceAlias = { export type ManifestSource = 'tracked-manifests' | 'disk-manifests'; +function escapeRegExp(literal: string): string { + return literal.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`); +} + function exactSpecifier(specifier: string): RegExp { - return new RegExp(`^${specifier.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`)}$`); + return new RegExp(`^${escapeRegExp(specifier)}$`); +} + +/** + * An alias pair for one exports entry: exact for a named subpath, and a capture- + * group pattern for a `*` pattern entry (ADR-0033's `./testing//*`). Emitting + * the pattern key as a literal matches nothing, so every concrete import of a + * pattern-exported module would load the UNaliased path in the Stryker sandbox — + * a different module id than its `vi.mock` registers, and the mock silently misses + * (#3546 review). Vite substitutes `$1` into the target template the way Node + * fills the exports target's `*`. + */ +function aliasFor(specifier: string, target: string, repoRoot: string): WorkspaceSourceAlias { + if (specifier.endsWith('*') && target.includes('*')) { + // Node requires exactly one `*` in the target, so it splices at a known + // index; `$` in the repo path is escaped so Vite sees only the `$1` fill. + const template = path.join(repoRoot, target); + const star = template.indexOf('*'); + // The callback form is load-bearing: in a string replacement `$$` IS one + // literal `$`, so a string '$$' would replace each `$` with itself and + // leave `$1`/`$&` in the repo path to be expanded when the alias applies. + const escapeDollar = (text: string) => text.replaceAll('$', () => '$$'); + return { + find: new RegExp(`^${escapeRegExp(specifier.slice(0, -1))}(.*)$`), + replacement: + escapeDollar(template.slice(0, star)) + '$1' + escapeDollar(template.slice(star + 1)), + }; + } + return { find: exactSpecifier(specifier), replacement: path.join(repoRoot, target) }; } function specifierTargets(repoRoot: string, source: ManifestSource): ReadonlyMap { @@ -50,13 +82,24 @@ function* manifestSpecifierTargets( } } -/** Exact exported workspace-package aliases for Vitest, from the declared manifest source. */ +/** + * Exported workspace-package aliases for Vitest, from the declared manifest source: + * one per exports entry, exact for named subpaths and capture-group patterns for + * `*` entries. Vite applies aliases in list order, so exact entries are emitted + * first — a named subpath under a pattern's prefix keeps its own export. + */ export function workspaceSourceAliases( repoRoot: string, source: ManifestSource, ): WorkspaceSourceAlias[] { - return [...specifierTargets(repoRoot, source)].map(([specifier, target]) => ({ - find: exactSpecifier(specifier), - replacement: path.join(repoRoot, target), - })); + const targets = [...specifierTargets(repoRoot, source)]; + const patterns = targets.filter(([specifier]) => specifier.endsWith('*')); + // Vite applies the first matching alias, so exact entries lead (Node's exact + // precedence) and patterns follow sorted by prefix length descending (Node's + // longest-prefix rule) — the same order resolveWorkspaceSpecifier resolves in, + // so the sandbox never picks a different module id than the exports semantics. + patterns.sort(([a], [b]) => b.length - a.length); + return [...targets.filter(([specifier]) => !specifier.endsWith('*')), ...patterns].map( + ([specifier, target]) => aliasFor(specifier, target, repoRoot), + ); } diff --git a/scripts/wire-compat/model.test.ts b/scripts/wire-compat/model.test.ts index eeb1a0a82f..8be69bf59e 100644 --- a/scripts/wire-compat/model.test.ts +++ b/scripts/wire-compat/model.test.ts @@ -117,7 +117,7 @@ test('a removed wire declaration passes with a bump', () => { // unchanged is a file move, not a removal: a released peer still parses it, // so it must not force a protocol bump. test('a declaration moved to a new file unchanged is a move, not a removal', () => { - const movedFrom = 'src/daemon/http-contract.ts#buildDaemonHttpUrl'; + const movedFrom = 'packages/daemon/src/http-contract.ts#buildDaemonHttpUrl'; const movedTo = 'packages/contracts/src/daemon-http.ts#buildDaemonHttpUrl'; const released = ledger({ declarations: { [movedFrom]: 'sha256:ddd', [META]: 'sha256:bbb' }, @@ -140,7 +140,7 @@ test('a declaration moved to a new file unchanged is a move, not a removal', () // CHANGE at the destination (ackable at the new digest) rather than the // bump-only removal the key-pair alone would suggest. test('a move that changes the shape is a change, acked at the path it moved to', () => { - const movedFrom = 'src/daemon/http-health.ts#buildDaemonHealthPayload'; + const movedFrom = 'packages/daemon/src/http-health.ts#buildDaemonHealthPayload'; const movedTo = 'packages/contracts/src/daemon-http.ts#buildDaemonHealthPayload'; const released = ledger({ declarations: { [movedFrom]: 'sha256:old' } }); const current = ledger({ @@ -171,8 +171,8 @@ test('a move that changes the shape is a change, acked at the path it moved to', // the name at its own path, a same-named declaration elsewhere cannot be // identified as a move of this one, so the baseline key stays a removal. test('a name still owned by the baseline is not a move, so it remains a removal', () => { - const serverSendJson = 'src/daemon/server/http-rpc-envelope.ts#sendJson'; - const uploadSendJson = 'src/daemon/upload-http.ts#sendJson'; + const serverSendJson = 'packages/daemon/src/server/http-rpc-envelope.ts#sendJson'; + const uploadSendJson = 'packages/daemon/src/upload-http.ts#sendJson'; const released = ledger({ declarations: { [serverSendJson]: 'sha256:old', [uploadSendJson]: 'sha256:eee' }, }); diff --git a/scripts/wire-compat/run.ts b/scripts/wire-compat/run.ts index 93adef726c..633f0fdfff 100644 --- a/scripts/wire-compat/run.ts +++ b/scripts/wire-compat/run.ts @@ -20,6 +20,7 @@ import path from 'node:path'; import { repoGit, requireUnshallowHistory } from '../lib/repo-git.ts'; +import { renamedSince } from '../__tests__/committed-source-tree.ts'; import { digestDeclaration } from '../../test/wire-compat/declaration-digest.ts'; import { digestWireSurface, @@ -71,9 +72,46 @@ if (!baseline) { process.exit(0); } +/** + * Rename pairs from the baseline tag to HEAD, as ` -> `. The ledger's + * move detection identifies a moved declaration by a sole same-name re-declaration; + * a bulk `git mv` of two files that share a declaration name (the daemon's two + * `sendJson` helpers) outruns that heuristic, because both destinations are claimed + * by candidates. Git's rename detection knows the truth for the whole tree at once, + * so the baseline's keys are canonicalized into HEAD coordinates before comparison. + * Digests travel unchanged: a pure move is not a wire change. + */ +function tagToHeadRenames(tag: string): Map { + // head -> base at [tag, HEAD]; flipped into the base -> head direction the ledger needs. + const flipped = new Map(); + for (const [headPath, basePath] of renamedSince(repoRoot, tag, 'HEAD')) + flipped.set(basePath, headPath); + return flipped; +} + +function canonicalizeLedgerRef(ref: string, renames: ReadonlyMap): string { + const hash = ref.lastIndexOf('#'); + const renamed = renames.get(ref.slice(0, hash)); + return renamed === undefined ? ref : `${renamed}#${ref.slice(hash + 1)}`; +} + +const releasedRenames = tagToHeadRenames(baseline.tag); +const released = parseWireLedger(baseline.raw, `${baseline.tag}:${WIRE_LEDGER_PATH}`); const result = compareWireLedgers({ baselineTag: baseline.tag, - released: parseWireLedger(baseline.raw, `${baseline.tag}:${WIRE_LEDGER_PATH}`), + released: { + ...released, + declarations: Object.fromEntries( + Object.entries(released.declarations).map(([ref, digest]) => [ + canonicalizeLedgerRef(ref, releasedRenames), + digest, + ]), + ), + compatibleChanges: released.compatibleChanges.map((change) => ({ + ...change, + declaration: canonicalizeLedgerRef(change.declaration, releasedRenames), + })), + }, current: readWireLedger(repoRoot), digests: digestWireSurface(repoRoot, WIRE_DECLARATIONS, digestDeclaration), }); diff --git a/src/__tests__/cli-device-release.test.ts b/src/__tests__/cli-device-release.test.ts index 40ea33d2ea..4391805f83 100644 --- a/src/__tests__/cli-device-release.test.ts +++ b/src/__tests__/cli-device-release.test.ts @@ -6,7 +6,7 @@ import { test, vi } from 'vitest'; import { readCurrentOwnerIdentity } from '@agent-device/host-kit/process'; import { createDurableResourceEnvelope } from '@agent-device/capture-kit'; import { localRuntimeOwner } from '@agent-device/contracts/platform-runtime'; -import { appLogResourceStore } from '../daemon/app-log-resource-store.ts'; +import { appLogResourceStore } from '@agent-device/daemon/testing/app-log-resource-store'; import { runStaleDeviceClaimRelease } from '../cli/commands/device-release.ts'; import { runCliCapture } from './cli-capture.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; diff --git a/src/__tests__/cli-remote-diagnostics.test.ts b/src/__tests__/cli-remote-diagnostics.test.ts index ef1712876b..155c35f7dc 100644 --- a/src/__tests__/cli-remote-diagnostics.test.ts +++ b/src/__tests__/cli-remote-diagnostics.test.ts @@ -10,10 +10,10 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { normalizeError, AppError } from '@agent-device/kernel/errors'; -import { createDaemonHttpServer } from '../daemon/server/http-server.ts'; -import { resolveSessionRequestLogPath } from '../daemon/session-artifact-paths.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import { resolveSessionRequestLogPath } from '@agent-device/daemon/session-artifact-paths'; import { safeSessionName } from '@agent-device/host-kit/session-paths'; -import type { DaemonRequest, DaemonResponse } from '../daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { runCliCapture, type CapturedCliRun } from './cli-capture.ts'; import { closeLoopbackServer, diff --git a/src/__tests__/command-descriptor-parity.test.ts b/src/__tests__/command-descriptor-parity.test.ts index 954ea5eb77..84728493ae 100644 --- a/src/__tests__/command-descriptor-parity.test.ts +++ b/src/__tests__/command-descriptor-parity.test.ts @@ -6,7 +6,7 @@ import { listCliCommandNames, PUBLIC_COMMANDS, } from '@agent-device/command-registry/catalog'; -import { canRunReplayScopedAction } from '../daemon/daemon-command-registry.ts'; +import { canRunReplayScopedAction } from '@agent-device/daemon/daemon-command-registry'; import { deriveDaemonCommandDescriptors, deriveStructuredBatchCommandNames, diff --git a/src/__tests__/command-descriptor-ref-frame-effect.test.ts b/src/__tests__/command-descriptor-ref-frame-effect.test.ts index 72ac075951..92a0bd56bf 100644 --- a/src/__tests__/command-descriptor-ref-frame-effect.test.ts +++ b/src/__tests__/command-descriptor-ref-frame-effect.test.ts @@ -5,8 +5,8 @@ import { PUBLIC_COMMANDS } from '@agent-device/command-registry/catalog'; import { DAEMON_COMMAND_DESCRIPTORS, resolveRefFrameEffect, -} from '../daemon/daemon-command-registry.ts'; -import type { DaemonRequest } from '../daemon/daemon-request.ts'; +} from '@agent-device/daemon/daemon-command-registry'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; // ADR 0014 migration step 2: the ref-frame-effect classification is an // honesty/completeness guard. Every command that reaches a session-owning daemon diff --git a/src/__tests__/command-descriptor-shutdown-runtime-execution.test.ts b/src/__tests__/command-descriptor-shutdown-runtime-execution.test.ts index 61f5e4975b..c2b626854b 100644 --- a/src/__tests__/command-descriptor-shutdown-runtime-execution.test.ts +++ b/src/__tests__/command-descriptor-shutdown-runtime-execution.test.ts @@ -4,11 +4,11 @@ import { shutdownTargetUse } from '@agent-device/contracts/platform-runtime-oper import { commandDescriptors } from '@agent-device/command-registry/registry'; const sessionShutdownSource = readFileSync( - new URL('../daemon/handlers/session-shutdown.ts', import.meta.url), + new URL('../../packages/daemon/src/handlers/session-shutdown.ts', import.meta.url), 'utf8', ); const sessionCloseSource = readFileSync( - new URL('../daemon/session-lifecycle/internal/session-close.ts', import.meta.url), + new URL('../../packages/daemon/src/session-lifecycle/internal/session-close.ts', import.meta.url), 'utf8', ); const appleLifecycleSource = readFileSync( diff --git a/src/__tests__/daemon-client-progress.test.ts b/src/__tests__/daemon-client-progress.test.ts index 212098b24e..6f14366a95 100644 --- a/src/__tests__/daemon-client-progress.test.ts +++ b/src/__tests__/daemon-client-progress.test.ts @@ -3,7 +3,7 @@ import assert from 'node:assert/strict'; import { EventEmitter } from 'node:events'; import type { Socket } from 'node:net'; import { test } from 'vitest'; -import type { DaemonRequest, DaemonResponse } from '../daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { readDaemonSocketProgressResponse } from '../daemon-client/daemon-client-progress.ts'; import { beginStderrCapture } from './test-utils/stream-capture.ts'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/__tests__/daemon-composition-assembly.test.ts b/src/__tests__/daemon-composition-assembly.test.ts index 2a0533f534..ba75e5eaa7 100644 --- a/src/__tests__/daemon-composition-assembly.test.ts +++ b/src/__tests__/daemon-composition-assembly.test.ts @@ -7,16 +7,17 @@ import { WEB_DESKTOP_DEVICE } from '@agent-device/test-kit/device-fixtures'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { createDaemonRuntimeDeps } from '../daemon-composition.ts'; import { startDaemonRuntimeFixture } from './daemon-composition/daemon-runtime-fixture.ts'; -import type { DaemonRuntimeDepsInput } from '../daemon/server/daemon-runtime.ts'; +import type { DaemonRuntimeDepsInput } from '@agent-device/daemon/server/daemon-runtime'; // The server builds its own store, so capture that instance the same way the shutdown tests do: // the proof is about the store the server hands to the composition callbacks, not one the test // fabricates. const storeProbe = vi.hoisted(() => ({ - store: undefined as import('../daemon/session-store.ts').SessionStore | undefined, + store: undefined as import('@agent-device/daemon/testing/session-store').SessionStore | undefined, })); -vi.mock('../daemon/session-store.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/session-store', async (importOriginal) => { + const actual = + await importOriginal(); return { ...actual, SessionStore: class extends actual.SessionStore { diff --git a/src/__tests__/daemon-composition-web-cleanup.test.ts b/src/__tests__/daemon-composition-web-cleanup.test.ts index 7186850bb4..cf0e8955c9 100644 --- a/src/__tests__/daemon-composition-web-cleanup.test.ts +++ b/src/__tests__/daemon-composition-web-cleanup.test.ts @@ -18,8 +18,8 @@ vi.mock('@agent-device/platform-web', async (importOriginal) => { }); import { WEB_DESKTOP_DEVICE } from '@agent-device/test-kit/device-fixtures'; -import { SessionStore } from '../daemon/session-store.ts'; -import { openWebSessionNames } from '../daemon/web-session-names.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import { openWebSessionNames } from '@agent-device/daemon/testing/web-session-names'; import { cleanupWebBrowserOrphansForDaemonStartup } from '../daemon-composition.ts'; const mockCleanupManagedAgentBrowserOrphans = vi.mocked(cleanupManagedAgentBrowserOrphansMock); diff --git a/src/__tests__/daemon-composition/android-dialog-readiness.test.ts b/src/__tests__/daemon-composition/android-dialog-readiness.test.ts index 124a46ef16..5a099cd3bd 100644 --- a/src/__tests__/daemon-composition/android-dialog-readiness.test.ts +++ b/src/__tests__/daemon-composition/android-dialog-readiness.test.ts @@ -32,13 +32,13 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -import { makeAndroidSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { makeAndroidSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { withFakeAdb, type FakeAdbScript } from '../test-utils/fake-adb.ts'; import { countDiagnosticEventsByPhase, withDiagnosticsScope, } from '@agent-device/host-kit/diagnostics'; -import { ensureAndroidBlockingSystemDialogReady as ensureOwnedAndroidBlockingSystemDialogReady } from '../../daemon/android-system-dialog.ts'; +import { ensureAndroidBlockingSystemDialogReady as ensureOwnedAndroidBlockingSystemDialogReady } from '@agent-device/daemon/testing/android-system-dialog'; import { androidObservation } from '../../platform-runtime.ts'; const ensureAndroidBlockingSystemDialogReady = ( diff --git a/src/__tests__/daemon-composition/app-event-delivery.test.ts b/src/__tests__/daemon-composition/app-event-delivery.test.ts index 9425fd4425..2ca5afa435 100644 --- a/src/__tests__/daemon-composition/app-event-delivery.test.ts +++ b/src/__tests__/daemon-composition/app-event-delivery.test.ts @@ -4,7 +4,10 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { bindAdmittedLocalInteractorOperations } from '@agent-device/contracts/interactor-operation-catalog'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { parseTriggerAppEventArgs, resolveAppEventUrl } from '../../daemon/app-events.ts'; +import { + parseTriggerAppEventArgs, + resolveAppEventUrl, +} from '@agent-device/daemon/testing/app-events'; import { getInteractor } from '../../core/interactors.ts'; import { AppError } from '@agent-device/kernel/errors'; import { ANDROID_EMULATOR, IOS_DEVICE, MACOS_DEVICE } from '@agent-device/test-kit/device-fixtures'; diff --git a/src/__tests__/daemon-composition/application-lifecycle-runtime-fixture.ts b/src/__tests__/daemon-composition/application-lifecycle-runtime-fixture.ts index a36337784c..19004b0634 100644 --- a/src/__tests__/daemon-composition/application-lifecycle-runtime-fixture.ts +++ b/src/__tests__/daemon-composition/application-lifecycle-runtime-fixture.ts @@ -15,11 +15,11 @@ import { vi } from 'vitest'; export { awaitFixtureReadiness, dispatchApplicationLifecycleEffect, -} from '../../daemon/__tests__/application-lifecycle-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/application-lifecycle-runtime-fixture'; import { applicationLifecycleFixtureInteractor, awaitFixtureReadiness, -} from '../../daemon/__tests__/application-lifecycle-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/application-lifecycle-runtime-fixture'; import type { Interactor, RunnerContext } from '@agent-device/contracts/interactor-types'; import { createAndroidApplicationTools } from '../../platform-runtime-android-application-tools.ts'; import { createAppleApplicationTools } from '../../platform-runtime-apple-application-tools.ts'; diff --git a/src/__tests__/daemon-composition/capture-disclosure.test.ts b/src/__tests__/daemon-composition/capture-disclosure.test.ts index e8972a9630..0bf36a4971 100644 --- a/src/__tests__/daemon-composition/capture-disclosure.test.ts +++ b/src/__tests__/daemon-composition/capture-disclosure.test.ts @@ -1,18 +1,18 @@ import { test, expect, vi, beforeEach } from 'vitest'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { handleFindCommands } from '../../daemon/interaction/index.ts'; -import { getRuntimeBindings } from '../../daemon/__tests__/interaction-get-runtime-fixture.ts'; -import { dispatchFindReadOnlyViaRuntime } from '../../daemon/selector-runtime.ts'; -import { dispatchWaitViaRuntime } from '../../daemon/wait-runtime.ts'; -import type { DaemonRequest, DaemonResponse } from '../../daemon/daemon-request.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { handleFindCommands } from '@agent-device/daemon/testing/interaction/index'; +import { getRuntimeBindings } from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; +import { dispatchFindReadOnlyViaRuntime } from '@agent-device/daemon/testing/selector-runtime'; +import { dispatchWaitViaRuntime } from '@agent-device/daemon/testing/wait-runtime'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { ANDROID_SYSTEM_SURFACE_DISCLOSURE } from '@agent-device/contracts/android-system-surface-disclosure'; import { iosSystemSurfaceDisclosure } from '@agent-device/contracts/ios-system-surface'; -import { snapshotRuntimeFixture } from '../../daemon/__tests__/snapshot-runtime-fixture.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { makeAndroidSession, makeIosSession, -} from '../../daemon/__tests__/support/session-factories.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { platformResourceCleanup } from '../../platform-runtime-resource-cleanup.ts'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; @@ -25,20 +25,21 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal }; }); -vi.mock('../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); -vi.mock('../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); import { resolveTargetDevice } from '@agent-device/device-selection/dispatch-resolve'; import { ANDROID_EMULATOR } from '@agent-device/test-kit/device-fixtures'; -import { withSystemSurfaceDisclosure } from '../../daemon/capture-disclosure.ts'; +import { withSystemSurfaceDisclosure } from '@agent-device/daemon/testing/capture-disclosure'; import { iosTargetActivationDisclosure } from '@agent-device/contracts/ios-target-activation'; -import { TARGET_ACTIVATION_FACT } from '../../daemon/__tests__/capture-disclosure-target-activation-fact.ts'; +import { TARGET_ACTIVATION_FACT } from '@agent-device/daemon/testing/__tests__/capture-disclosure-target-activation-fact'; // The occluding-shade capture every scenario below consumes: no application window content, one // active quick-settings surface. The Android capture route stamps systemSurfaceOnly on both the diff --git a/src/__tests__/daemon-composition/daemon-runtime-fixture.ts b/src/__tests__/daemon-composition/daemon-runtime-fixture.ts index 06b8c992c6..2c5770c56b 100644 --- a/src/__tests__/daemon-composition/daemon-runtime-fixture.ts +++ b/src/__tests__/daemon-composition/daemon-runtime-fixture.ts @@ -3,7 +3,7 @@ import { startDaemonRuntime, type ComposeDaemonRuntimeDeps, type DaemonRuntimeController, -} from '../../daemon/server/daemon-runtime.ts'; +} from '@agent-device/daemon/server/daemon-runtime'; type WritableOutput = { write: (chunk: string) => unknown }; diff --git a/src/__tests__/daemon-composition/device/device-ready.test.ts b/src/__tests__/daemon-composition/device/device-ready.test.ts index aaf2776f7c..9342e56114 100644 --- a/src/__tests__/daemon-composition/device/device-ready.test.ts +++ b/src/__tests__/daemon-composition/device/device-ready.test.ts @@ -31,7 +31,7 @@ import { import { DEVICE_READY_CACHE_TTL_MS, ensureDeviceReady, -} from '../../../daemon/device/device-ready.ts'; +} from '@agent-device/daemon/testing/device/device-ready'; const mockRunCmd = vi.mocked(runCmd); const mockEnsureBootedSimulator = vi.mocked(ensureBootedSimulator); diff --git a/src/__tests__/daemon-composition/generic-settle.test.ts b/src/__tests__/daemon-composition/generic-settle.test.ts index 1692f33de6..d7a3111ab3 100644 --- a/src/__tests__/daemon-composition/generic-settle.test.ts +++ b/src/__tests__/daemon-composition/generic-settle.test.ts @@ -8,15 +8,15 @@ import { iosSystemSurfaceTransitionDisclosure, type IosSystemSurfaceProvenance, } from '@agent-device/contracts/ios-system-surface'; -import { makeIosSession } from '../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { activateCompleteRefFrame, refFrameState } from '../../daemon/ref-frame.ts'; -import { setSessionSnapshot } from '../../daemon/session-snapshot.ts'; -import type { SessionStore } from '../../daemon/session-store.ts'; -import type { DaemonRequest, DaemonResponse } from '../../daemon/daemon-request.ts'; -import type { SessionRef, SessionState } from '../../daemon/session-state.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { activateCompleteRefFrame, refFrameState } from '@agent-device/daemon/testing/ref-frame'; +import { setSessionSnapshot } from '@agent-device/daemon/testing/session-snapshot'; +import type { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; +import type { SessionRef, SessionState } from '@agent-device/daemon/testing/session-state'; import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; -import { selectorCaptureFixture } from '../../daemon/__tests__/selector-capture-fixture.ts'; +import { selectorCaptureFixture } from '@agent-device/daemon/testing/__tests__/selector-capture-fixture'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; // #1638 `--settle` on the GENERIC daemon route (scroll/back): the settled diff, @@ -25,8 +25,9 @@ import { testCreateCommandSurface } from './command-surface-fixture.ts'; // a resolution, and the observation must run after the deferred-outcome // markers. Quiet windows are tuned down so no test waits real time. -vi.mock('../../daemon/interaction/index.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/interaction/index', async (importOriginal) => { + const actual = + await importOriginal(); return { ...actual, captureSnapshotForSession: vi.fn(async () => ({ @@ -38,9 +39,9 @@ vi.mock('../../daemon/interaction/index.ts', async (importOriginal) => { }; }); -import { captureSnapshotForSession } from '../../daemon/interaction/index.ts'; -import { dispatchGenericCommand } from '../../daemon/request-generic-dispatch.ts'; -import { pendingSurfaceStabilization } from '../../daemon/deferred-interaction-outcome.ts'; +import { captureSnapshotForSession } from '@agent-device/daemon/testing/interaction/index'; +import { dispatchGenericCommand } from '@agent-device/daemon/testing/request-generic-dispatch'; +import { pendingSurfaceStabilization } from '@agent-device/daemon/testing/deferred-interaction-outcome'; const mockCaptureSnapshotForSession = vi.mocked(captureSnapshotForSession); diff --git a/src/__tests__/daemon-composition/gesture-admission-parity.test.ts b/src/__tests__/daemon-composition/gesture-admission-parity.test.ts index 3b64ea4b55..40b45e79b0 100644 --- a/src/__tests__/daemon-composition/gesture-admission-parity.test.ts +++ b/src/__tests__/daemon-composition/gesture-admission-parity.test.ts @@ -10,9 +10,9 @@ import { } from '@agent-device/contracts/gesture-normalization'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { createPlatformRuntimeGateway } from '../../platform-runtime.ts'; -import { createRequestRuntimeBindings } from '../../daemon/request-runtime-binding.ts'; -import { createRequestDispatchLedger } from '../../daemon/request-dispatch-ledger.ts'; -import { resolveBoundGestureRuntime } from '../../daemon/gesture-runtime.ts'; +import { createRequestRuntimeBindings } from '@agent-device/daemon/testing/request-runtime-binding'; +import { createRequestDispatchLedger } from '@agent-device/daemon/testing/request-dispatch-ledger'; +import { resolveBoundGestureRuntime } from '@agent-device/daemon/testing/gesture-runtime'; /** * The parity artifact for R42/R44 (ADR 0019 §6). diff --git a/src/__tests__/daemon-composition/handlers/lease-provider-credentials.test.ts b/src/__tests__/daemon-composition/handlers/lease-provider-credentials.test.ts index c7ef858510..986be0065a 100644 --- a/src/__tests__/daemon-composition/handlers/lease-provider-credentials.test.ts +++ b/src/__tests__/daemon-composition/handlers/lease-provider-credentials.test.ts @@ -2,10 +2,10 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; -import { handleLeaseCommands } from '../../../daemon/handlers/lease.ts'; -import { LeaseRegistry } from '../../../daemon/lease-registry.ts'; -import type { DaemonRequest } from '../../../daemon/daemon-request.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { handleLeaseCommands } from '@agent-device/daemon/testing/handlers/lease'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { AppError } from '@agent-device/kernel/errors'; import { providerCredentialFingerprint, diff --git a/src/__tests__/daemon-composition/handlers/session-close-runner-retention.test.ts b/src/__tests__/daemon-composition/handlers/session-close-runner-retention.test.ts index 08ed51dd7b..58df3d58a6 100644 --- a/src/__tests__/daemon-composition/handlers/session-close-runner-retention.test.ts +++ b/src/__tests__/daemon-composition/handlers/session-close-runner-retention.test.ts @@ -1,12 +1,12 @@ import { test, expect, vi, beforeEach } from 'vitest'; import * as path from 'node:path'; -import { LeaseRegistry } from '../../../daemon/lease-registry.ts'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { makeSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { getResolveTargetDeviceMock } from '../../../daemon/__tests__/request-router-dispatch-mocks.ts'; -import type { DaemonRequest } from '../../../daemon/daemon-request.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { getResolveTargetDeviceMock } from '@agent-device/daemon/testing/__tests__/request-router-dispatch-mocks'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; // The runner-retention decision is the real `PlatformResourceCleanup` rule (a booted simulator @@ -17,7 +17,7 @@ vi.mock('node:timers/promises', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, setTimeout: vi.fn(async () => undefined) }; }); -vi.mock('../../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) => { @@ -51,7 +51,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { return { ...actual, resolveAndroidPackageForOpen: vi.fn(async () => undefined) }; }); -import { createRequestHandler } from '../../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { realLifecycleDeviceRuntimeGateway } from '../lifecycle-runtime-gateway.ts'; import { dispatchApplicationLifecycleEffect, diff --git a/src/__tests__/daemon-composition/handlers/session-device-claims-cancellation.test.ts b/src/__tests__/daemon-composition/handlers/session-device-claims-cancellation.test.ts index 5997af2372..a36ccd82dd 100644 --- a/src/__tests__/daemon-composition/handlers/session-device-claims-cancellation.test.ts +++ b/src/__tests__/daemon-composition/handlers/session-device-claims-cancellation.test.ts @@ -3,13 +3,13 @@ import assert from 'node:assert/strict'; import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal) => { const actual = await importOriginal(); const { selectionFromResolveTargetDevice } = - await import('../../../daemon/__tests__/device-selection-stub.ts'); + await import('@agent-device/daemon/testing/__tests__/device-selection-stub'); const resolveTargetDevice = vi.fn(); return { ...actual, @@ -17,7 +17,7 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal resolveTargetDeviceSelection: vi.fn(selectionFromResolveTargetDevice(resolveTargetDevice)), }; }); -vi.mock('../../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); vi.mock('@agent-device/platform-android/mechanics', () => ({ @@ -34,28 +34,28 @@ vi.mock('@agent-device/host-kit/process', async (importOriginal) => ); import { resolveTargetDevice } from '@agent-device/device-selection/dispatch-resolve'; -import { ensureDeviceReady } from '../../../daemon/device/device-ready.ts'; +import { ensureDeviceReady } from '@agent-device/daemon/testing/device/device-ready'; import { activateAndroidTestIme, resolveAndroidPackageForOpen, } from '@agent-device/platform-android/mechanics'; import { clearRequestCanceled, markRequestCanceled } from '@agent-device/host-kit/request'; -import { inspectDeviceClaims } from '../../../daemon/device/device-claim-inspection.ts'; +import { inspectDeviceClaims } from '@agent-device/daemon/device/device-claim-inspection'; import { localRuntimeOwner, narrowDeviceBinding, type DeviceBinding, } from '@agent-device/contracts/platform-runtime'; import type { PlatformRuntimeOperations } from '@agent-device/contracts/platform-runtime-operations'; -import type { BindDeviceRuntime } from '../../../daemon/request-runtime-binding.ts'; +import type { BindDeviceRuntime } from '@agent-device/daemon/testing/request-runtime-binding'; import { composedLifecycleRuntimeFixture, dispatchApplicationLifecycleEffect, } from '../application-lifecycle-runtime-fixture.ts'; -import { SessionStore } from '../../../daemon/session-store.ts'; -import { handleSessionOpenCommands as handleProductionOpenCommand } from '../../../daemon/session-lifecycle/index.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import { handleSessionOpenCommands as handleProductionOpenCommand } from '@agent-device/daemon/testing/session-lifecycle/index'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { inspectLifecycleRuntimeFacts } from '../../../daemon/__tests__/application-lifecycle-runtime-harness.ts'; +import { inspectLifecycleRuntimeFacts } from '@agent-device/daemon/testing/__tests__/application-lifecycle-runtime-harness'; const mockDispatch = vi.mocked(dispatchApplicationLifecycleEffect); const mockResolveTargetDevice = vi.mocked(resolveTargetDevice); diff --git a/src/__tests__/daemon-composition/handlers/session-doctor-warmup.test.ts b/src/__tests__/daemon-composition/handlers/session-doctor-warmup.test.ts index e40a30178a..0cef4c405d 100644 --- a/src/__tests__/daemon-composition/handlers/session-doctor-warmup.test.ts +++ b/src/__tests__/daemon-composition/handlers/session-doctor-warmup.test.ts @@ -1,11 +1,11 @@ import { beforeEach, expect, test, vi } from 'vitest'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { isActiveProviderDevice } from '../../../daemon/provider-device-admission.ts'; -import { handleDoctorCommand } from '../../../daemon/handlers/session-doctor.ts'; +import { isActiveProviderDevice } from '@agent-device/daemon/testing/provider-device-admission'; +import { handleDoctorCommand } from '@agent-device/daemon/testing/handlers/session-doctor'; import { createHostDiagnostics } from '../../../platform-runtime-host-diagnostics.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { withTestDeviceInventory } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import type { DaemonResponse } from '../../../daemon/daemon-request.ts'; +import type { DaemonResponse } from '@agent-device/daemon/daemon-request'; const { mockAppleRunnerWarmupCheck } = vi.hoisted(() => ({ mockAppleRunnerWarmupCheck: vi.fn(), @@ -15,13 +15,13 @@ vi.mock('@agent-device/platform-apple/doctor', async (importOriginal) => ({ ...(await importOriginal()), appleRunnerWarmupCheck: mockAppleRunnerWarmupCheck, })); -vi.mock('../../../daemon/handlers/session-doctor-app.ts', () => ({ +vi.mock('@agent-device/daemon/testing/handlers/session-doctor-app', () => ({ appendAppChecks: vi.fn(async () => {}), })); -vi.mock('../../../daemon/handlers/session-doctor-metro.ts', () => ({ +vi.mock('@agent-device/daemon/testing/handlers/session-doctor-metro', () => ({ probeMetro: vi.fn(async () => ({ id: 'metro', status: 'pass', summary: 'mocked' })), })); -vi.mock('../../../daemon/provider-device-admission.ts', () => ({ +vi.mock('@agent-device/daemon/testing/provider-device-admission', () => ({ isActiveProviderDevice: vi.fn(() => false), })); diff --git a/src/__tests__/daemon-composition/handlers/session-relaunch-close.test.ts b/src/__tests__/daemon-composition/handlers/session-relaunch-close.test.ts index 680a1d8dfb..fd2d0f9434 100644 --- a/src/__tests__/daemon-composition/handlers/session-relaunch-close.test.ts +++ b/src/__tests__/daemon-composition/handlers/session-relaunch-close.test.ts @@ -1,23 +1,23 @@ import { test, expect, vi, beforeEach } from 'vitest'; import * as path from 'node:path'; -import { LeaseRegistry } from '../../../daemon/lease-registry.ts'; -import { providerDeviceAdmissionFixture } from '../../../daemon/__tests__/support/provider-device-admission-fixture.ts'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { providerDeviceAdmissionFixture } from '@agent-device/daemon/testing/__tests__/support/provider-device-admission-fixture'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; // The daemon reads provider ownership through its own typed admission seam; these suites // install the seam over runtime fakes, the way root composition installs the real one. const providerAdmission = providerDeviceAdmissionFixture(); import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { makeSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { getResolveTargetDeviceMock } from '../../../daemon/__tests__/request-router-dispatch-mocks.ts'; -import type { DaemonRequest } from '../../../daemon/daemon-request.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { getResolveTargetDeviceMock } from '@agent-device/daemon/testing/__tests__/request-router-dispatch-mocks'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; vi.mock('node:timers/promises', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, setTimeout: vi.fn(async () => undefined) }; }); -vi.mock('../../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) => { @@ -57,7 +57,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { return { ...actual, resolveAndroidPackageForOpen: vi.fn(async () => undefined) }; }); -import { createRequestHandler } from '../../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { realLifecycleDeviceRuntimeGateway } from '../lifecycle-runtime-gateway.ts'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; import { @@ -65,7 +65,7 @@ import { awaitFixtureReadiness, discoverReadyAndroidEmulators, } from '../application-lifecycle-runtime-fixture.ts'; -import { ensureDeviceReady } from '../../../daemon/device/device-ready.ts'; +import { ensureDeviceReady } from '@agent-device/daemon/testing/device/device-ready'; import { prewarmIosRunnerSession, notifyIosRunnerAppRelaunched, @@ -73,7 +73,7 @@ import { releaseIosRunnerOnClose, } from '@agent-device/platform-apple/runner/operations'; import { runMacOsAlertAction } from '@agent-device/platform-apple/macos'; -import { refFrameState } from '../../../daemon/ref-frame.ts'; +import { refFrameState } from '@agent-device/daemon/testing/ref-frame'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; const mockResolveTargetDevice = vi.mocked(getResolveTargetDeviceMock()); diff --git a/src/__tests__/daemon-composition/handlers/session-relaunch-guards.test.ts b/src/__tests__/daemon-composition/handlers/session-relaunch-guards.test.ts index e1409d1c81..364cf50529 100644 --- a/src/__tests__/daemon-composition/handlers/session-relaunch-guards.test.ts +++ b/src/__tests__/daemon-composition/handlers/session-relaunch-guards.test.ts @@ -6,10 +6,10 @@ import { makeSession, noopInvoke, assertInvalidArgsMessage, -} from '../../../daemon/handlers/__tests__/session-test-harness.ts'; -import { handleSessionCommands } from '../../../daemon/handlers/__tests__/session-command-harness.ts'; +} from '@agent-device/daemon/testing/handlers/__tests__/session-test-harness'; +import { handleSessionCommands } from '@agent-device/daemon/testing/handlers/__tests__/session-command-harness'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; // These relaunch cases pin the REAL open-target validation rules (the URL-target refusal and the diff --git a/src/__tests__/daemon-composition/handlers/snapshot-handler-freshness.test.ts b/src/__tests__/daemon-composition/handlers/snapshot-handler-freshness.test.ts index ff80e7c5c0..4c0f166d30 100644 --- a/src/__tests__/daemon-composition/handlers/snapshot-handler-freshness.test.ts +++ b/src/__tests__/daemon-composition/handlers/snapshot-handler-freshness.test.ts @@ -1,15 +1,15 @@ import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; import { test, expect, vi, afterEach, beforeEach } from 'vitest'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { resetGetRuntimeFixture } from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { resetGetRuntimeFixture } from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import fs from 'node:fs'; -import { captureSnapshot } from '../../../daemon/snapshot-capture.ts'; -import { SessionStore } from '../../../daemon/session-store.ts'; +import { captureSnapshot } from '@agent-device/daemon/testing/snapshot-capture'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; import { isActiveProviderDevice, setActiveProviderDeviceRuntimes, } from '../../../provider-device-runtime.ts'; -import { installProviderDeviceAdmission } from '../../../daemon/provider-device-admission.ts'; +import { installProviderDeviceAdmission } from '@agent-device/daemon/testing/provider-device-admission'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // The daemon reads provider ownership through its own typed admission seam; production @@ -23,7 +23,7 @@ import { buildNodes } from '@agent-device/test-kit/snapshot-builders'; import { fixtureScreenshotCaptures, resetSnapshotRuntimeFixture, -} from '../../../daemon/__tests__/snapshot-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { androidCapture, androidDevice, @@ -36,10 +36,11 @@ import { makeSession, makeSessionStore, snapshotRequest, -} from '../../../daemon/handlers/__tests__/snapshot-handler.fixtures.ts'; +} from '@agent-device/daemon/testing/handlers/__tests__/snapshot-handler.fixtures'; -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) => { @@ -52,12 +53,12 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) // unambiguous environment; that live-probe logic is covered by // ios-app-session-hint.test.ts. Stubbed here so this suite stays hermetic and // fast — defaults to "no enrichment", matching the current-behavior fallback. -vi.mock('../../../daemon/ios-app-session-hint.ts', () => ({ +vi.mock('@agent-device/daemon/testing/ios-app-session-hint', () => ({ buildIosOpenCommandHint: vi.fn(async () => undefined), })); import { runAppleRunnerCommand } from '@agent-device/platform-apple/runner/operations'; -import { buildIosOpenCommandHint } from '../../../daemon/ios-app-session-hint.ts'; +import { buildIosOpenCommandHint } from '@agent-device/daemon/testing/ios-app-session-hint'; const mockRunnerCommand = vi.mocked(runAppleRunnerCommand); const mockBuildIosOpenCommandHint = vi.mocked(buildIosOpenCommandHint); diff --git a/src/__tests__/daemon-composition/handlers/snapshot-handler-wait.test.ts b/src/__tests__/daemon-composition/handlers/snapshot-handler-wait.test.ts index f8ac888679..3275a825bb 100644 --- a/src/__tests__/daemon-composition/handlers/snapshot-handler-wait.test.ts +++ b/src/__tests__/daemon-composition/handlers/snapshot-handler-wait.test.ts @@ -1,22 +1,22 @@ import { test, expect, vi, afterEach, beforeEach } from 'vitest'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { resetGetRuntimeFixture } from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { resetGetRuntimeFixture } from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { isActiveProviderDevice, setActiveProviderDeviceRuntimes, } from '../../../provider-device-runtime.ts'; -import { installProviderDeviceAdmission } from '../../../daemon/provider-device-admission.ts'; +import { installProviderDeviceAdmission } from '@agent-device/daemon/testing/provider-device-admission'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // The daemon reads provider ownership through its own typed admission seam; production // installs it from root composition, and these tests compose it the same way. installProviderDeviceAdmission({ isActive: isActiveProviderDevice }); -import type { SessionState } from '../../../daemon/session-state.ts'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { buildSnapshotPresentationKey } from '@agent-device/kernel/snapshot'; import { resetSnapshotRuntimeFixture, snapshotRuntimeFixture, -} from '../../../daemon/__tests__/snapshot-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { androidCapture, androidDevice, @@ -31,10 +31,11 @@ import { makeSession, makeSessionStore, snapshotRequest, -} from '../../../daemon/handlers/__tests__/snapshot-handler.fixtures.ts'; +} from '@agent-device/daemon/testing/handlers/__tests__/snapshot-handler.fixtures'; -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) => { @@ -47,12 +48,12 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) // unambiguous environment; that live-probe logic is covered by // ios-app-session-hint.test.ts. Stubbed here so this suite stays hermetic and // fast — defaults to "no enrichment", matching the current-behavior fallback. -vi.mock('../../../daemon/ios-app-session-hint.ts', () => ({ +vi.mock('@agent-device/daemon/testing/ios-app-session-hint', () => ({ buildIosOpenCommandHint: vi.fn(async () => undefined), })); import { runAppleRunnerCommand } from '@agent-device/platform-apple/runner/operations'; -import { buildIosOpenCommandHint } from '../../../daemon/ios-app-session-hint.ts'; +import { buildIosOpenCommandHint } from '@agent-device/daemon/testing/ios-app-session-hint'; const mockRunnerCommand = vi.mocked(runAppleRunnerCommand); const mockBuildIosOpenCommandHint = vi.mocked(buildIosOpenCommandHint); diff --git a/src/__tests__/daemon-composition/handlers/snapshot-handler.test.ts b/src/__tests__/daemon-composition/handlers/snapshot-handler.test.ts index 4cb1287762..19fb34d8fd 100644 --- a/src/__tests__/daemon-composition/handlers/snapshot-handler.test.ts +++ b/src/__tests__/daemon-composition/handlers/snapshot-handler.test.ts @@ -1,20 +1,20 @@ import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; import { test, expect, vi, afterEach, beforeEach } from 'vitest'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { resetGetRuntimeFixture } from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; -import { resetSnapshotRuntimeFixture } from '../../../daemon/__tests__/snapshot-runtime-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { resetGetRuntimeFixture } from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; +import { resetSnapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { isActiveProviderDevice, setActiveProviderDeviceRuntimes, } from '../../../provider-device-runtime.ts'; -import { installProviderDeviceAdmission } from '../../../daemon/provider-device-admission.ts'; +import { installProviderDeviceAdmission } from '@agent-device/daemon/testing/provider-device-admission'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // The daemon reads provider ownership through its own typed admission seam; production // installs it from root composition, and these tests compose it the same way. installProviderDeviceAdmission({ isActive: isActiveProviderDevice }); -import type { DaemonResponse } from '../../../daemon/daemon-request.ts'; -import type { SessionState } from '../../../daemon/session-state.ts'; +import type { DaemonResponse } from '@agent-device/daemon/daemon-request'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { androidCapture, androidDevice, @@ -26,10 +26,11 @@ import { makeSessionStore, providerIosDevice, snapshotRequest, -} from '../../../daemon/handlers/__tests__/snapshot-handler.fixtures.ts'; +} from '@agent-device/daemon/testing/handlers/__tests__/snapshot-handler.fixtures'; -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) => { @@ -42,18 +43,18 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) // unambiguous environment; that live-probe logic is covered by // ios-app-session-hint.test.ts. Stubbed here so this suite stays hermetic and // fast — defaults to "no enrichment", matching the current-behavior fallback. -vi.mock('../../../daemon/ios-app-session-hint.ts', () => ({ +vi.mock('@agent-device/daemon/testing/ios-app-session-hint', () => ({ buildIosOpenCommandHint: vi.fn(async () => undefined), })); import { runAppleRunnerCommand } from '@agent-device/platform-apple/runner/operations'; -import { buildIosOpenCommandHint } from '../../../daemon/ios-app-session-hint.ts'; +import { buildIosOpenCommandHint } from '@agent-device/daemon/testing/ios-app-session-hint'; import { expireRefFrame, refFrame, refFrameState, refFrameTree, -} from '../../../daemon/ref-frame.ts'; +} from '@agent-device/daemon/testing/ref-frame'; const mockRunnerCommand = vi.mocked(runAppleRunnerCommand); const mockBuildIosOpenCommandHint = vi.mocked(buildIosOpenCommandHint); diff --git a/src/__tests__/daemon-composition/handlers/snapshot-scoped-refs.test.ts b/src/__tests__/daemon-composition/handlers/snapshot-scoped-refs.test.ts index b8c02f6c65..996500da12 100644 --- a/src/__tests__/daemon-composition/handlers/snapshot-scoped-refs.test.ts +++ b/src/__tests__/daemon-composition/handlers/snapshot-scoped-refs.test.ts @@ -1,11 +1,11 @@ import { beforeEach, expect, test } from 'vitest'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { handleSnapshotCommands as handleProductionSnapshotCommands } from '../../../daemon/handlers/snapshot.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { handleSnapshotCommands as handleProductionSnapshotCommands } from '@agent-device/daemon/testing/handlers/snapshot'; import type { RawSnapshotNode, SnapshotState } from '@agent-device/kernel/snapshot'; -import { makeAndroidSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { expireRefFrame } from '../../../daemon/ref-frame.ts'; -import { snapshotRuntimeFixture } from '../../../daemon/__tests__/snapshot-runtime-fixture.ts'; +import { makeAndroidSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { expireRefFrame } from '@agent-device/daemon/testing/ref-frame'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; const ANDROID_SCRIPT_ERROR = 'Unable to load script. Make sure you are running Metro.'; diff --git a/src/__tests__/daemon-composition/handlers/snapshot-session-cleanup.test.ts b/src/__tests__/daemon-composition/handlers/snapshot-session-cleanup.test.ts index 230644271e..fb688700bc 100644 --- a/src/__tests__/daemon-composition/handlers/snapshot-session-cleanup.test.ts +++ b/src/__tests__/daemon-composition/handlers/snapshot-session-cleanup.test.ts @@ -9,7 +9,7 @@ vi.mock('@agent-device/platform-apple/app-lifecycle', async (importOriginal) => closeIosApp: vi.fn(async () => {}), })); -import { withSessionlessRunnerCleanup } from '../../../daemon/snapshot-session.ts'; +import { withSessionlessRunnerCleanup } from '@agent-device/daemon/testing/snapshot-session'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; import { closeIosApp } from '@agent-device/platform-apple/app-lifecycle'; import { stopIosRunnerSession } from '@agent-device/platform-apple/runner/operations'; @@ -18,7 +18,7 @@ import { isActiveProviderDevice, setActiveProviderDeviceRuntimes, } from '../../../provider-device-runtime.ts'; -import { installProviderDeviceAdmission } from '../../../daemon/provider-device-admission.ts'; +import { installProviderDeviceAdmission } from '@agent-device/daemon/testing/provider-device-admission'; // The daemon reads provider ownership through its own typed admission seam; production // installs it from root composition, and these tests compose it the same way. diff --git a/src/__tests__/daemon-composition/handlers/wait-landmark-recording.test.ts b/src/__tests__/daemon-composition/handlers/wait-landmark-recording.test.ts index 38e625ef8a..27ee6398c4 100644 --- a/src/__tests__/daemon-composition/handlers/wait-landmark-recording.test.ts +++ b/src/__tests__/daemon-composition/handlers/wait-landmark-recording.test.ts @@ -12,17 +12,17 @@ * `WAIT_LANDMARK_MISMATCH_REASON` refusal. */ import { test, expect, vi, beforeEach } from 'vitest'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { dispatchWaitViaRuntime } from '../../../daemon/wait-runtime.ts'; -import type { DaemonRequest } from '../../../daemon/daemon-request.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { dispatchWaitViaRuntime } from '@agent-device/daemon/testing/wait-runtime'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { WAIT_LANDMARK_MISMATCH_REASON } from '@agent-device/contracts/replay'; import type { TargetAnnotationV1 } from '@agent-device/contracts/replay'; -import { snapshotRuntimeFixture } from '../../../daemon/__tests__/snapshot-runtime-fixture.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { makeAndroidSession, authoringPublication, -} from '../../../daemon/__tests__/support/session-factories.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal) => { @@ -34,12 +34,13 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); -vi.mock('../../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); diff --git a/src/__tests__/daemon-composition/http-server-limrun-uploaded-apps.test.ts b/src/__tests__/daemon-composition/http-server-limrun-uploaded-apps.test.ts index 742de15b8a..d42f3b0e43 100644 --- a/src/__tests__/daemon-composition/http-server-limrun-uploaded-apps.test.ts +++ b/src/__tests__/daemon-composition/http-server-limrun-uploaded-apps.test.ts @@ -10,15 +10,15 @@ import { listenOnLoopback, skipWhenLoopbackUnavailable, } from '@agent-device/test-kit/loopback'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { limrunTestDependencies } from '../../platform-runtime-gateway.fixtures.ts'; import { DAEMON_HTTP_NETWORK_ACCESS_HEADER, DAEMON_HTTP_PUBLIC_NETWORK_ACCESS, } from '@agent-device/contracts/daemon-http'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { createDaemonHttpServer } from '../../daemon/server/http-server.ts'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; diff --git a/src/__tests__/daemon-composition/interaction-touch-android-readiness-spawns.test.ts b/src/__tests__/daemon-composition/interaction-touch-android-readiness-spawns.test.ts index daafe00e2b..4a01cdd4ca 100644 --- a/src/__tests__/daemon-composition/interaction-touch-android-readiness-spawns.test.ts +++ b/src/__tests__/daemon-composition/interaction-touch-android-readiness-spawns.test.ts @@ -1,9 +1,9 @@ import { expect, test } from 'vitest'; -import { makeAndroidSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { makeAndroidSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { withFakeAdb } from '../test-utils/fake-adb.ts'; -import { expireRefFrame } from '../../daemon/ref-frame.ts'; -import { runWithAndroidDialogReadinessCheck } from '../../daemon/interaction/internal/interaction-touch-android-readiness.ts'; -import { androidObservationPolicyFixture as androidObservation } from '../../daemon/__tests__/android-observation-fixture.ts'; +import { expireRefFrame } from '@agent-device/daemon/testing/ref-frame'; +import { runWithAndroidDialogReadinessCheck } from '@agent-device/daemon/testing/interaction/internal/interaction-touch-android-readiness'; +import { androidObservationPolicyFixture as androidObservation } from '@agent-device/daemon/testing/__tests__/android-observation-fixture'; // What blocking-dialog readiness costs a run of taps, end to end. Every one of these `dumpsys` // spawns is a device round trip on the critical path of an interaction, so the budget is pinned diff --git a/src/__tests__/daemon-composition/interaction/find-ambiguous-match.test.ts b/src/__tests__/daemon-composition/interaction/find-ambiguous-match.test.ts index 3344438a1c..0dd8a3d508 100644 --- a/src/__tests__/daemon-composition/interaction/find-ambiguous-match.test.ts +++ b/src/__tests__/daemon-composition/interaction/find-ambiguous-match.test.ts @@ -7,17 +7,18 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal resolveTargetDevice: actual.resolveTargetDevice, }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); import { resetFindTouchRuntimeFixture, runFindClickScenario, -} from '../../../daemon/interaction/internal/__tests__/find-touch-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/find-touch-runtime-fixture'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; -import { refFrameScope, refFrameState } from '../../../daemon/ref-frame.ts'; +import { refFrameScope, refFrameState } from '@agent-device/daemon/testing/ref-frame'; beforeEach(() => { resetFindTouchRuntimeFixture(); diff --git a/src/__tests__/daemon-composition/interaction/find-production-route.test.ts b/src/__tests__/daemon-composition/interaction/find-production-route.test.ts index c5352f6de8..a0c6ead9b8 100644 --- a/src/__tests__/daemon-composition/interaction/find-production-route.test.ts +++ b/src/__tests__/daemon-composition/interaction/find-production-route.test.ts @@ -1,9 +1,9 @@ import { test, expect, vi, beforeEach } from 'vitest'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import type { CommandFlags } from '@agent-device/contracts/command'; -import type { DaemonRequest, DaemonResponse } from '../../../daemon/daemon-request.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { makeIosSession as makeSession } from '../../../daemon/__tests__/support/session-factories.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeIosSession as makeSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal) => { @@ -13,8 +13,9 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal resolveTargetDevice: actual.resolveTargetDevice, }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); @@ -22,8 +23,8 @@ import { findTouchRuntimeBindings, mockDispatch, resetFindTouchRuntimeFixture, -} from '../../../daemon/interaction/internal/__tests__/find-touch-runtime-fixture.ts'; -import { invokeFindHandler } from '../../../daemon/interaction/internal/__tests__/find-handler-fixture.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/find-touch-runtime-fixture'; +import { invokeFindHandler } from '@agent-device/daemon/testing/interaction/internal/__tests__/find-handler-fixture'; beforeEach(() => { resetFindTouchRuntimeFixture(); diff --git a/src/__tests__/daemon-composition/interaction/find-read-only.test.ts b/src/__tests__/daemon-composition/interaction/find-read-only.test.ts index 80cb0ea335..e55d556c7f 100644 --- a/src/__tests__/daemon-composition/interaction/find-read-only.test.ts +++ b/src/__tests__/daemon-composition/interaction/find-read-only.test.ts @@ -1,11 +1,11 @@ import { test, expect, vi, beforeEach } from 'vitest'; -import type { SessionState } from '../../../daemon/session-state.ts'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { buildSnapshotSignatures } from '@agent-device/capture-kit/snapshot-freshness'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { makeAuthoringSession, makeIosSession as makeSession, -} from '../../../daemon/__tests__/support/session-factories.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal) => { const actual = (await importOriginal()) as Record; @@ -14,8 +14,9 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal resolveTargetDevice: actual.resolveTargetDevice, }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); @@ -23,9 +24,9 @@ import { mockDispatch, resetFindTouchRuntimeFixture, runFindClickScenario, -} from '../../../daemon/interaction/internal/__tests__/find-touch-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/find-touch-runtime-fixture'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; -import { invokeFindHandler } from '../../../daemon/interaction/internal/__tests__/find-handler-fixture.ts'; +import { invokeFindHandler } from '@agent-device/daemon/testing/interaction/internal/__tests__/find-handler-fixture'; beforeEach(() => { resetFindTouchRuntimeFixture(); diff --git a/src/__tests__/daemon-composition/interaction/interaction-capture-disclosure.test.ts b/src/__tests__/daemon-composition/interaction/interaction-capture-disclosure.test.ts index 3be6ee7bfc..4067928d7f 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-capture-disclosure.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-capture-disclosure.test.ts @@ -6,20 +6,21 @@ import { type SnapshotState, } from '@agent-device/kernel/snapshot'; import { iosTargetActivationDisclosure } from '@agent-device/contracts/ios-target-activation'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; -import { getRuntimeBindings } from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; +import { getRuntimeBindings } from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { markDeferredInteractionOutcome } from '../../../daemon/deferred-interaction-outcome.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { markDeferredInteractionOutcome } from '@agent-device/daemon/testing/deferred-interaction-outcome'; import { formatPostGestureOutcomeWarning } from '@agent-device/capture-kit/post-gesture-stability'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); diff --git a/src/__tests__/daemon-composition/interaction/interaction-common.test.ts b/src/__tests__/daemon-composition/interaction/interaction-common.test.ts index 4aea4698bf..f659e60046 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-common.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-common.test.ts @@ -1,23 +1,23 @@ import type { CommandFlags } from '@agent-device/contracts/command'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { beforeEach, expect, test } from 'vitest'; import { makeIosSession, makeAuthoringSession, authoringPublication, -} from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { attachRefs, type RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { finalizeTouchInteraction, handleInteractionCommands, -} from '../../../daemon/interaction/index.ts'; +} from '@agent-device/daemon/testing/interaction/index'; import { IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; import { getRuntimeBindings, mockFillPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; const contextFromFlags = (_flags: CommandFlags | undefined) => ({}); diff --git a/src/__tests__/daemon-composition/interaction/interaction-dispatch-disclosure.test.ts b/src/__tests__/daemon-composition/interaction/interaction-dispatch-disclosure.test.ts index 4f116db6e0..038cf9a770 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-dispatch-disclosure.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-dispatch-disclosure.test.ts @@ -10,39 +10,39 @@ import { DISPATCH_DISCLOSURE_TABLE_PATH, dispatchDisclosureRowsOwnedBy, } from '@agent-device/contracts/dispatch-disclosure-fixtures'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { makeAndroidSession } from '../../../daemon/__tests__/support/session-factories.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeAndroidSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { getRuntimeBindings, mockFillPoint, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; -import { discloseRequestDispatch } from '../../../daemon/request-dispatch-disclosure.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; +import { discloseRequestDispatch } from '@agent-device/daemon/testing/request-dispatch-disclosure'; import { createRequestDispatchLedger, recordBoundMutations, -} from '../../../daemon/request-dispatch-ledger.ts'; -import type { BindDeviceRuntime } from '../../../daemon/request-runtime-binding.ts'; -import { clearAndroidObservationFixture } from '../../../daemon/__tests__/android-observation-fixture.ts'; -import { activateCompleteRefFrame, expireRefFrame } from '../../../daemon/ref-frame.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; -import type { InteractionRouteInput } from '../../../daemon/interaction/internal/types.ts'; -import { assertAndroidPressStayedInApp } from '../../../daemon/interaction/internal/interaction-android-escape.ts'; -import { gestureRuntimeBindingsFixture } from '../../../daemon/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts'; +} from '@agent-device/daemon/testing/request-dispatch-ledger'; +import type { BindDeviceRuntime } from '@agent-device/daemon/testing/request-runtime-binding'; +import { clearAndroidObservationFixture } from '@agent-device/daemon/testing/__tests__/android-observation-fixture'; +import { activateCompleteRefFrame, expireRefFrame } from '@agent-device/daemon/testing/ref-frame'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; +import type { InteractionRouteInput } from '@agent-device/daemon/testing/interaction/internal/types'; +import { assertAndroidPressStayedInApp } from '@agent-device/daemon/testing/interaction/internal/interaction-android-escape'; +import { gestureRuntimeBindingsFixture } from '@agent-device/daemon/testing/interaction/internal/__tests__/gesture-runtime-bindings.fixtures'; import { contextFromFlags, makeSession, makeStaleRefSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // contracts/fixtures/dispatch-disclosure.json, daemon and post-action guard rows: the daemon rows // drive a real `press` through the daemon interaction handler, inside the router's dispatch seam, // with only the device touch mocked; the guard row drives the guard itself. -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); diff --git a/src/__tests__/daemon-composition/interaction/interaction-gesture-drag.test.ts b/src/__tests__/daemon-composition/interaction/interaction-gesture-drag.test.ts index 28812a6fa0..e9b4d7a1be 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-gesture-drag.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-gesture-drag.test.ts @@ -4,18 +4,18 @@ import { attachRefs } from '@agent-device/kernel/snapshot'; import { makeIosSession, authoringPublication, -} from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { activateCompleteRefFrame, refFrameState } from '../../../daemon/ref-frame.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { activateCompleteRefFrame, refFrameState } from '@agent-device/daemon/testing/ref-frame'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; -import { gestureRuntimeBindingsFixture } from '../../../daemon/interaction/internal/__tests__/gesture-runtime-bindings.fixtures.ts'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; +import { gestureRuntimeBindingsFixture } from '@agent-device/daemon/testing/interaction/internal/__tests__/gesture-runtime-bindings.fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; const contextFromFlags = () => ({}); const captureSnapshotForSession = async ({ session, -}: import('../../../daemon/session-state.ts').SessionRef) => session.snapshot!; +}: import('@agent-device/daemon/testing/session-state').SessionRef) => session.snapshot!; let gestures = gestureRuntimeBindingsFixture(); beforeEach(() => { diff --git a/src/__tests__/daemon-composition/interaction/interaction-get.test.ts b/src/__tests__/daemon-composition/interaction/interaction-get.test.ts index fce694bd3d..0694700b81 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-get.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-get.test.ts @@ -1,25 +1,25 @@ import { test, expect, vi, beforeEach } from 'vitest'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { attachRefs } from '@agent-device/kernel/snapshot'; import { WEB_DESKTOP_DEVICE } from '@agent-device/test-kit/device-fixtures'; import { makeAndroidSession as makeBaseAndroidSession, makeIosSession, -} from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { expireRefFrame } from '../../../daemon/ref-frame.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { expireRefFrame } from '@agent-device/daemon/testing/ref-frame'; import { setSessionSnapshot, STALE_SNAPSHOT_REFS_WARNING, -} from '../../../daemon/session-snapshot.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +} from '@agent-device/daemon/testing/session-snapshot'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; import { contextFromFlags, makeSession, makeStaleRefSession, makeVisibleButtonSnapshot, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { runInteraction } from './interaction-touch-runner.ts'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; @@ -30,8 +30,9 @@ const { mockRunAppleRunnerCommand } = vi.hoisted(() => ({ mockRunAppleRunnerCommand: vi.fn(), })); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); @@ -59,7 +60,7 @@ import { getRuntimeBindings, mockReadTextAtPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { getAndroidAppState, getAndroidBlockingDialogObservation, diff --git a/src/__tests__/daemon-composition/interaction/interaction-ios-tap-outcome.test.ts b/src/__tests__/daemon-composition/interaction/interaction-ios-tap-outcome.test.ts index 2695a56e01..c960608bf2 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-ios-tap-outcome.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-ios-tap-outcome.test.ts @@ -1,5 +1,5 @@ import type { CommandFlags } from '@agent-device/contracts/command'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { beforeEach, expect, test, vi } from 'vitest'; import fs from 'node:fs'; @@ -7,40 +7,41 @@ import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import { buildSnapshotPresentationKey } from '@agent-device/kernel/snapshot'; import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { makeIosSession, authoringPublication, -} from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { SessionScriptWriter } from '../../../daemon/session-script-writer.ts'; -import { runReplayForTest } from '../../../daemon/__tests__/replay-runtime/replay-command-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { SessionScriptWriter } from '@agent-device/daemon/testing/session-script-writer'; +import { runReplayForTest } from '@agent-device/daemon/testing/__tests__/replay-runtime/replay-command-fixture'; import { replayScriptSourceBundleFor } from '@agent-device/replay-port/replay-script-source-fixtures'; import { imageViewerNodes, profileNodes, snapshot, snapshotPayload, -} from '../../../daemon/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-ios-tap-outcome-fixtures'; import { appCaptureComparisonIdentity, appCaptureComparisonKey, systemSurfaceCaptureComparisonKey, -} from '../../../daemon/__tests__/ios-comparison-key-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/ios-comparison-key-fixture'; import { IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; import { getRuntimeBindings, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; -import { corroborateIosTapFailure } from '../../../daemon/interaction/internal/interaction-ios-tap-outcome.ts'; -import { movingTargetBaseline } from '../../../daemon/deferred-interaction-outcome.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; +import { corroborateIosTapFailure } from '@agent-device/daemon/testing/interaction/internal/interaction-ios-tap-outcome'; +import { movingTargetBaseline } from '@agent-device/daemon/testing/deferred-interaction-outcome'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: vi.fn(fixture.captureSnapshotThroughLegacyDispatchFixture), }; diff --git a/src/__tests__/daemon-composition/interaction/interaction-settle-private-ax-route.test.ts b/src/__tests__/daemon-composition/interaction/interaction-settle-private-ax-route.test.ts index 9171418dda..8a7b0ca9af 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-settle-private-ax-route.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-settle-private-ax-route.test.ts @@ -1,13 +1,13 @@ import { beforeEach, expect, test, vi } from 'vitest'; import { makeSnapshotState } from '@agent-device/selectors/snapshot-geometry-fixtures'; -import { makeIosSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { withAppleRunnerProvider } from '@agent-device/platform-apple/runner'; -import { contextFromFlags as buildDaemonContext } from '../../../daemon/context.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; -import { getRuntimeBindings } from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +import { contextFromFlags as buildDaemonContext } from '@agent-device/daemon/testing/context'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; +import { getRuntimeBindings } from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { getInteractor } from '../../../core/interactors.ts'; -import { installInteractorResolution } from '../../../daemon/interactor-resolution.ts'; +import { installInteractorResolution } from '@agent-device/daemon/testing/interactor-resolution'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // Root composition hands the daemon its interactor resolution; this test drives the real diff --git a/src/__tests__/daemon-composition/interaction/interaction-settle.test.ts b/src/__tests__/daemon-composition/interaction/interaction-settle.test.ts index 494bec2804..70433c07a0 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-settle.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-settle.test.ts @@ -1,24 +1,24 @@ import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; import type { CommandFlags } from '@agent-device/contracts/command'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { test, expect, vi, beforeEach } from 'vitest'; import { createInteractionRuntime, handleInteractionCommands, -} from '../../../daemon/interaction/index.ts'; -import type { SessionStore } from '../../../daemon/session-store.ts'; -import type { SessionRef, SessionState } from '../../../daemon/session-state.ts'; +} from '@agent-device/daemon/testing/interaction/index'; +import type { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { SessionRef, SessionState } from '@agent-device/daemon/testing/session-state'; import { buildSnapshotState } from '@agent-device/capture-kit/snapshot-state'; -import { setSessionSnapshot } from '../../../daemon/session-snapshot.ts'; +import { setSessionSnapshot } from '@agent-device/daemon/testing/session-snapshot'; import { activateCompleteRefFrame, expireRefFrame, refFrameState, refFrameTree, -} from '../../../daemon/ref-frame.ts'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { makeIosSession } from '../../../daemon/__tests__/support/session-factories.ts'; +} from '@agent-device/daemon/testing/ref-frame'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { clearRequestAbortRegistration, registerRequestAbort, @@ -29,7 +29,7 @@ import { mockFillPoint, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // #1101 --settle daemon response shape: the settle payload (diff + settled + @@ -39,7 +39,7 @@ import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // beyond a few poll ticks. const mockCaptureSnapshotForSession = vi.hoisted(() => vi.fn()); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); const nativeCapture = vi.mocked(captureSnapshotWithInteractor); diff --git a/src/__tests__/daemon-composition/interaction/interaction-target-evidence.test.ts b/src/__tests__/daemon-composition/interaction/interaction-target-evidence.test.ts index 9f58f7a4a7..57104a230b 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-target-evidence.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-target-evidence.test.ts @@ -1,18 +1,18 @@ import type { CommandFlags } from '@agent-device/contracts/command'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { test, expect, vi, beforeEach } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { attachRefs, type RawSnapshotNode } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { makeIosSession, makeAuthoringSession, authoringPublication, -} from '../../../daemon/__tests__/support/session-factories.ts'; -import { SessionScriptWriter } from '../../../daemon/session-script-writer.ts'; -import type { SessionState } from '../../../daemon/session-state.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { SessionScriptWriter } from '@agent-device/daemon/testing/session-script-writer'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; @@ -27,8 +27,9 @@ const { mockRunAppleRunnerCommand } = vi.hoisted(() => ({ mockRunAppleRunnerCommand: vi.fn(), })); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); @@ -44,7 +45,7 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) import { getRuntimeBindings, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; const contextFromFlags = (_flags: CommandFlags | undefined) => ({}); beforeEach(() => { diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-android-freshness.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-android-freshness.test.ts index 298e4d9e12..c9329f67b1 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-android-freshness.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-android-freshness.test.ts @@ -1,16 +1,16 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeAndroidSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // The Android ref-refresh capture a @ref mutation takes before dispatch: when @@ -31,7 +31,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -46,8 +46,8 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; -import { activateCompleteRefFrame } from '../../../daemon/ref-frame.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; +import { activateCompleteRefFrame } from '@agent-device/daemon/testing/ref-frame'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-android-readiness.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-android-readiness.test.ts index 951b4d0cc9..e6a5fba15b 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-android-readiness.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-android-readiness.test.ts @@ -1,17 +1,17 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { expireRefFrame } from '../../../daemon/ref-frame.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { expireRefFrame } from '@agent-device/daemon/testing/ref-frame'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeAndroidSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // The Android device state a dispatch has to survive: an escape to launcher or @@ -19,7 +19,7 @@ import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // blocking-dialog recovery aborts an admitted @ref rather than retargeting it. type EnsureAndroidBlockingSystemDialogReady = - typeof import('../../../daemon/android-system-dialog.ts').ensureAndroidBlockingSystemDialogReady; + typeof import('@agent-device/daemon/testing/android-system-dialog').ensureAndroidBlockingSystemDialogReady; const { androidDialogReadiness } = vi.hoisted(() => ({ androidDialogReadiness: { @@ -42,7 +42,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -54,8 +54,9 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) // The blocking-dialog readiness check runs for real (its focus probe is mocked // above); the recovery regression below swaps in a recovering implementation. -vi.mock('../../../daemon/android-system-dialog.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/android-system-dialog', async (importOriginal) => { + const actual = + await importOriginal(); androidDialogReadiness.actual = actual.ensureAndroidBlockingSystemDialogReady; return { ...actual, ensureAndroidBlockingSystemDialogReady: androidDialogReadiness.spy }; }); @@ -65,7 +66,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios-eligibility.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios-eligibility.test.ts index f8c812eccc..37c14bb245 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios-eligibility.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios-eligibility.test.ts @@ -1,16 +1,16 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeIosSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockFillPoint, mockTapElementSelector, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; -import { contextFromFlags } from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; +import { contextFromFlags } from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // Ordinary selectors stay capture-backed. Only the explicit Maestro @@ -30,7 +30,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -45,7 +45,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios.test.ts index 084cfd589d..49f4c5f381 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-direct-ios.test.ts @@ -7,23 +7,23 @@ import { dispatchDisclosureRowsOwnedBy, } from '@agent-device/contracts/dispatch-disclosure-fixtures'; import { beforeEach, expect, test, vi } from 'vitest'; -import { makeIosSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockTapElementSelector, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeStaleRefSession, makeTwoButtonNodes, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { runInteraction } from './interaction-touch-runner.ts'; -import { refFrameState } from '../../../daemon/ref-frame.ts'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { refFrameState } from '@agent-device/daemon/testing/ref-frame'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { @@ -36,7 +36,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-fill.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-fill.test.ts index ef4c38ff12..b9b3db30c5 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-fill.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-fill.test.ts @@ -1,20 +1,20 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; import { withAppleRunnerProvider } from '@agent-device/platform-apple/runner'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { activateCompleteRefFrame, expireRefFrame } from '../../../daemon/ref-frame.ts'; -import { STALE_SNAPSHOT_REFS_WARNING } from '../../../daemon/session-snapshot.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { activateCompleteRefFrame, expireRefFrame } from '@agent-device/daemon/testing/ref-frame'; +import { STALE_SNAPSHOT_REFS_WARNING } from '@agent-device/daemon/testing/session-snapshot'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockFillPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeSession, makeStaleRefSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { runInteraction } from './interaction-touch-runner.ts'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; @@ -39,7 +39,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -54,7 +54,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-payload.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-payload.test.ts index 83458c6226..ffbd8b9a8f 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-payload.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-payload.test.ts @@ -1,18 +1,18 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, installTestScreenRecording, makeAndroidSession, makeSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // What a built touch payload carries: the recorded action entry and touch @@ -33,7 +33,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -48,7 +48,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-prepare.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-prepare.test.ts index 9c0a16c89c..7c0fb0f86a 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-prepare.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-prepare.test.ts @@ -16,16 +16,16 @@ import { import { attachRefs, type RawSnapshotNode } from '@agent-device/kernel/snapshot'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { createUnavailableRuntimeFactsForTest } from '@agent-device/test-kit/runtime-operation-facts'; -import { makeIosAppSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { makeIosAppSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts, -} from '../../../daemon/request-runtime-binding.ts'; +} from '@agent-device/daemon/testing/request-runtime-binding'; import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; -import type { SessionStore } from '../../../daemon/session-store.ts'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; +import type { SessionStore } from '@agent-device/daemon/testing/session-store'; // #3510: the capture an interaction's post-action observation polls. A coordinate-targeted press or // fill acts through a use that declares no capture, so before this its settle loop read the screen @@ -56,7 +56,7 @@ const BRIDGE_PRODUCED = Object.freeze({ }); const mockInteractorCapture = vi.hoisted(() => vi.fn()); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: mockInteractorCapture, })); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-press-admission.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-press-admission.test.ts index 52eeb5b0ae..db81737659 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-press-admission.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-press-admission.test.ts @@ -1,17 +1,17 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { activateCompleteRefFrame, refFrameState } from '../../../daemon/ref-frame.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { activateCompleteRefFrame, refFrameState } from '@agent-device/daemon/testing/ref-frame'; import { setSessionSnapshot, STALE_SNAPSHOT_REFS_WARNING, -} from '../../../daemon/session-snapshot.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +} from '@agent-device/daemon/testing/session-snapshot'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, findResolvedTarget, @@ -20,7 +20,7 @@ import { makeStaleRefSession, makeTwoButtonNodes, readPressPoint, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { runFindInternalClick, runInteraction } from './interaction-touch-runner.ts'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; @@ -42,7 +42,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -57,7 +57,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-press.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-press.test.ts index ae57d07403..73666b524b 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-press.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-press.test.ts @@ -1,13 +1,13 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeIosSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, findResolvedTarget, @@ -16,7 +16,7 @@ import { makeSession, makeStaleRefSession, readPressPoint, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { runFindInternalClick } from './interaction-touch-runner.ts'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; @@ -38,7 +38,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -53,7 +53,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-response.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-response.test.ts index aa04e9235c..55b01f4330 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-response.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-response.test.ts @@ -1,32 +1,18 @@ -import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; -import fs from 'node:fs'; -import path from 'node:path'; -import { - withDiagnosticsScope, - flushDiagnosticsToSessionFile, -} from '@agent-device/host-kit/diagnostics'; -import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; -import { - buildInteractionResponseData, - buildTargetedTouchResponsePayloads, - transformTouchResponseData, -} from '../../../daemon/interaction/internal/interaction-touch-response.ts'; -import type { PressCommandResult } from '@agent-device/contracts/interaction'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockFillPoint, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, installTestScreenRecording, makeSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // The identity extras the one response site composes: --verify evidence rides @@ -47,7 +33,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -62,7 +48,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); @@ -81,209 +67,6 @@ beforeEach(() => { mockRunAppleRunnerCommand.mockResolvedValue({}); }); -test('commandless longpress response omits internal interaction diagnostics', () => { - expect( - transformTouchResponseData({ - flags: {}, - data: { - currentUptimeMs: 900, - gestureStartUptimeMs: 100, - gestureEndUptimeMs: 800, - sequenceResults: [{ index: 0, success: true }], - completedSteps: 1, - }, - }), - ).toEqual({ completedSteps: 1 }); -}); - -function selectorResult(readiness?: { polls: number; waitedMs: number }): PressCommandResult { - return { - kind: 'selector', - point: { x: 10, y: 20 }, - target: { kind: 'selector', selector: 'label=Continue' }, - node: { ref: 'e1', index: 0, type: 'Button', label: 'Continue' }, - selectorChain: ['label=Continue'], - warning: 'earlier warning', - ...(readiness ? { readiness } : {}), - }; -} - -const WAITED_SELECTOR_RESULT = selectorResult({ polls: 3, waitedMs: 400 }); - -test.each([false, true])('selector-touch observation after retirement=%s', async (retired) => { - const sessionStore = makeSessionStore(); - const address = 'cwd:selector-touch-response:default'; - const session = makeSession('default'); - session.snapshot = { - nodes: attachRefs([{ index: 0, type: 'Button', label: 'Continue' }]), - createdAt: Date.now(), - backend: 'xctest', - }; - session.snapshotGeneration = 3; - const ref = sessionStore.publish(address, session); - const result: PressCommandResult = { - ...selectorResult(), - settle: { - settled: true, - waitedMs: 25, - captures: 2, - quietMs: 25, - timeoutMs: 2000, - diff: { - summary: { additions: 1, removals: 0, unchanged: 0 }, - lines: [{ kind: 'added', text: 'Continue', ref: 'e1' }], - }, - }, - }; - let successor; - if (retired) { - sessionStore.retire(ref); - successor = sessionStore.publish(address, makeSession('default')); - } - const payloads = await buildTargetedTouchResponsePayloads({ - params: { - createCommandSurface: testCreateCommandSurface, - req: { token: 't', command: 'press', positionals: ['@e1'], session: 'default' }, - sessionName: address, - sessionRef: ref, - sessionStore, - contextFromFlags, - platformServices: composedPlatformServicesFixture(), - captureSnapshotForSession: vi.fn(), - }, - result, - staleRefsWarning: undefined, - extra: {}, - }); - if (retired) { - expect(payloads.responseData.settle).toBeUndefined(); - expect(payloads.result.settle).toBeUndefined(); - expect(sessionStore.lookup(address)).toEqual(successor); - expect(successor?.session.snapshot).toBeUndefined(); - } else { - expect(payloads.responseData.settle).toMatchObject({ refsGeneration: 3, settled: true }); - } -}); - -test.each([ - [false, false], - [false, true], - [true, false], - [true, true], -])( - 'point-touch publication after a held frame probe, retired=%s, fails=%s', - async (retired, fails) => { - const sessionStore = makeSessionStore(); - const address = 'cwd:held-touch-response:default'; - const session = makeSession('default'); - session.snapshot = { - nodes: attachRefs([{ index: 0, type: 'Button', label: 'Continue' }]), - createdAt: Date.now(), - backend: 'xctest', - }; - session.snapshotGeneration = 3; - installTestScreenRecording(session); - const ref = sessionStore.publish(address, session); - let startProbe!: () => void; - let releaseProbe!: () => void; - const probing = new Promise((resolve) => { - startProbe = resolve; - }); - const released = new Promise((resolve) => { - releaseProbe = resolve; - }); - const result: PressCommandResult = { - kind: 'point', - point: { x: 10, y: 20 }, - settle: { - settled: true, - waitedMs: 25, - captures: 2, - quietMs: 25, - timeoutMs: 2000, - diff: { - summary: { additions: 1, removals: 0, unchanged: 0 }, - lines: [{ kind: 'added', text: 'Continue', ref: 'e1' }], - }, - }, - }; - const logPath = path.join(mkdtempForTestSync('held-point-'), 'request.log'); - const running = withDiagnosticsScope( - { command: 'press', session: address, logPath, debug: true }, - async () => { - const payloads = await buildTargetedTouchResponsePayloads({ - params: { - createCommandSurface: testCreateCommandSurface, - req: { - token: 't', - command: 'press', - positionals: ['10', '20'], - session: 'default', - flags: {}, - }, - sessionName: address, - sessionRef: ref, - sessionStore, - contextFromFlags, - platformServices: composedPlatformServicesFixture(), - captureSnapshotForSession: async () => { - startProbe(); - await released; - if (fails) throw new Error('frame capture failed'); - return sessionStore.requireCurrent(ref).snapshot!; - }, - }, - result, - staleRefsWarning: undefined, - extra: {}, - }); - flushDiagnosticsToSessionFile({ force: true }); - return payloads; - }, - ); - await probing; - let successor; - if (retired) { - sessionStore.retire(ref); - successor = sessionStore.publish(address, makeSession('default')); - } - releaseProbe(); - const payloads = await running; - const diagnostics = fs.existsSync(logPath) ? fs.readFileSync(logPath, 'utf8') : ''; - expect(diagnostics.includes('touch_reference_frame_resolve_failed')).toBe(!retired && fails); - expect(payloads.responseData.x).toBe(10); - if (retired) { - expect(payloads.responseData.settle).toBeUndefined(); - expect(payloads.result.settle).toBeUndefined(); - expect(sessionStore.lookup(address)).toEqual(successor); - expect(successor?.session.snapshot).toBeUndefined(); - } else { - expect(payloads.responseData.settle).toMatchObject({ refsGeneration: 3, settled: true }); - } - }, -); - -test('the response builder reports the resolved wait and keeps the prior warning', () => { - const { responseData, result } = buildInteractionResponseData({ - source: { kind: 'runtime', result: WAITED_SELECTOR_RESULT }, - referenceFrame: undefined, - staleRefsWarning: 'stale refs', - }); - - expect(responseData.readiness).toEqual({ polls: 3, waitedMs: 400 }); - expect(responseData.warning).toBe('earlier warning stale refs'); - expect(result.readiness).toBeUndefined(); -}); - -test('the response builder omits readiness when nothing waited', () => { - const { responseData } = buildInteractionResponseData({ - source: { kind: 'runtime', result: selectorResult() }, - referenceFrame: undefined, - }); - - expect('readiness' in responseData).toBe(false); -}); - test('press @ref --verify surfaces evidence through the interactionResultExtra allowlist', async () => { const sessionStore = makeSessionStore(); const sessionName = 'verify-press'; @@ -647,37 +430,3 @@ test('fill @ref preserves fallback coordinates for recording when platform resul expect(event?.x).toBe(60); expect(event?.y).toBe(40); }); - -test('an already retired coordinate touch skips its frame probe without a warning', async () => { - const sessionStore = makeSessionStore(); - const ref = sessionStore.publish('retired-point', makeSession('retired-point')); - sessionStore.retire(ref); - const capture = vi.fn(); - const logPath = path.join(mkdtempForTestSync('retired-point-'), 'request.log'); - await withDiagnosticsScope( - { command: 'click', session: ref.address, logPath, debug: true }, - async () => { - const payloads = await buildTargetedTouchResponsePayloads({ - params: { - createCommandSurface: testCreateCommandSurface, - req: { token: 't', command: 'click', positionals: ['1', '2'], session: ref.address }, - sessionName: ref.address, - sessionRef: ref, - sessionStore, - contextFromFlags, - platformServices: composedPlatformServicesFixture(), - captureSnapshotForSession: capture, - }, - result: { kind: 'point', point: { x: 1, y: 2 } }, - staleRefsWarning: undefined, - extra: {}, - }); - expect(payloads.responseData).toMatchObject({ x: 1, y: 2 }); - flushDiagnosticsToSessionFile({ force: true }); - }, - ); - expect(capture).not.toHaveBeenCalled(); - expect(fs.existsSync(logPath) ? fs.readFileSync(logPath, 'utf8') : '').not.toContain( - 'touch_reference_frame_resolve_failed', - ); -}); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-runner.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-runner.ts index 2d36b3ab22..c540cc58ba 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-runner.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-runner.ts @@ -1,8 +1,8 @@ -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; -import { getRuntimeBindings } from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; -import { contextFromFlags } from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; +import { getRuntimeBindings } from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; +import { contextFromFlags } from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; -import type { SessionStore } from '../../../daemon/session-store.ts'; +import type { SessionStore } from '@agent-device/daemon/testing/session-store'; /** * The real command-surface legs the relocated interaction suites drive through the handler. diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch-runtime.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch-runtime.test.ts index 33073b078d..839ada4962 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch-runtime.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch-runtime.test.ts @@ -1,19 +1,19 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; import { withAppleRunnerProvider } from '@agent-device/platform-apple/runner'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { elementReadFixtureState, getRuntimeBindings, mockQuerySelector, mockTapPoint, resetGetRuntimeFixture, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // What the shared runtime dispatch does with the resolved target: refuse @@ -38,7 +38,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -53,7 +53,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/interaction/interaction-touch.test.ts b/src/__tests__/daemon-composition/interaction/interaction-touch.test.ts index 2503449eda..8139f29792 100644 --- a/src/__tests__/daemon-composition/interaction/interaction-touch.test.ts +++ b/src/__tests__/daemon-composition/interaction/interaction-touch.test.ts @@ -1,8 +1,8 @@ import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { WEB_DESKTOP_DEVICE } from '@agent-device/test-kit/device-fixtures'; -import { handleInteractionCommands } from '../../../daemon/interaction/index.ts'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { getRuntimeBindings, mockHoverPoint, @@ -11,13 +11,13 @@ import { mockTapPoint, resetGetRuntimeFixture, runtimeBindingSpies, -} from '../../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeMacOsDesktopSession, makeMacOsMenubarSession, makeSession, -} from '../../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; // Router ownership: one representative per touch command proves @@ -37,7 +37,7 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(), })); @@ -52,7 +52,7 @@ import { getAndroidBlockingDialogObservation, getAndroidScreenSize, } from '@agent-device/platform-android/mechanics'; -import { captureSnapshotWithInteractor } from '../../../daemon/snapshot-interactor-capture.ts'; +import { captureSnapshotWithInteractor } from '@agent-device/daemon/testing/snapshot-interactor-capture'; const mockGetAndroidAppState = vi.mocked(getAndroidAppState); const mockGetAndroidBlockingDialogObservation = vi.mocked(getAndroidBlockingDialogObservation); const mockGetAndroidScreenSize = vi.mocked(getAndroidScreenSize); diff --git a/src/__tests__/daemon-composition/is-runtime.test.ts b/src/__tests__/daemon-composition/is-runtime.test.ts index 46a5e41211..9d8e126599 100644 --- a/src/__tests__/daemon-composition/is-runtime.test.ts +++ b/src/__tests__/daemon-composition/is-runtime.test.ts @@ -7,14 +7,14 @@ import { makeAndroidSession, makeIosAppSession, makeIosSession, -} from '../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { withTestDeviceInventory } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { makeSnapshotState } from '@agent-device/selectors/snapshot-geometry-fixtures'; import type { PostGestureOutcome } from '@agent-device/kernel/snapshot'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; -import { selectorCaptureFixture } from '../../daemon/__tests__/selector-capture-fixture.ts'; -import { markDeferredInteractionOutcome } from '../../daemon/deferred-interaction-outcome.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import { selectorCaptureFixture } from '@agent-device/daemon/testing/__tests__/selector-capture-fixture'; +import { markDeferredInteractionOutcome } from '@agent-device/daemon/testing/deferred-interaction-outcome'; import { formatPostGestureOutcomeWarning } from '@agent-device/capture-kit/post-gesture-stability'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; @@ -26,7 +26,7 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) return { ...actual, runAppleRunnerCommand: mockRunAppleRunnerCommand }; }); -import { dispatchIsViaRuntime } from '../../daemon/selector-runtime.ts'; +import { dispatchIsViaRuntime } from '@agent-device/daemon/testing/selector-runtime'; beforeEach(() => { mockRunAppleRunnerCommand.mockReset(); diff --git a/src/__tests__/daemon-composition/lifecycle-runtime-gateway.ts b/src/__tests__/daemon-composition/lifecycle-runtime-gateway.ts index 97446176cd..4a9a00e115 100644 --- a/src/__tests__/daemon-composition/lifecycle-runtime-gateway.ts +++ b/src/__tests__/daemon-composition/lifecycle-runtime-gateway.ts @@ -1,7 +1,7 @@ import { createLifecycleDeviceRuntimeGateway, createLifecycleDeviceRuntimeGatewaySpies, -} from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +} from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { composedLifecycleRuntimeFixture } from './application-lifecycle-runtime-fixture.ts'; /** diff --git a/src/__tests__/daemon-composition/perf-capture-session-resource.test.ts b/src/__tests__/daemon-composition/perf-capture-session-resource.test.ts index 8c8cf0f8b0..6107ebb24e 100644 --- a/src/__tests__/daemon-composition/perf-capture-session-resource.test.ts +++ b/src/__tests__/daemon-composition/perf-capture-session-resource.test.ts @@ -1,9 +1,9 @@ -import { bindSessionPerfCapture } from '../../daemon/session-capture-binding.ts'; +import { bindSessionPerfCapture } from '@agent-device/daemon/testing/session-capture-binding'; import { beforeEach, expect, test, vi } from 'vitest'; import { localRuntimeOwner } from '@agent-device/contracts/platform-runtime'; import { AppError } from '@agent-device/kernel/errors'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { createPerfCaptureAdmissionLedger } from '@agent-device/capture-kit/perf-capture-admission-ledger'; import { perfCaptureResourceStore } from '@agent-device/capture-kit/perf-capture-resource-store'; import { @@ -11,7 +11,7 @@ import { finishLivePerfCapture, } from '@agent-device/capture-kit/perf-capture-session-resource'; import { startAndroidPerfCapture } from '../../platform-runtime-perf-capture-host.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; const androidNative = vi.hoisted(() => ({ startAndroidSimpleperfProfile: vi.fn(), diff --git a/src/__tests__/daemon-composition/platform-services-fixture.ts b/src/__tests__/daemon-composition/platform-services-fixture.ts index 5cf9783a8a..19ac33979d 100644 --- a/src/__tests__/daemon-composition/platform-services-fixture.ts +++ b/src/__tests__/daemon-composition/platform-services-fixture.ts @@ -1,7 +1,7 @@ import { createDaemonPlatformServices } from '../../platform-runtime-daemon-services.ts'; import { createClaimRecoveryGateway } from '../../platform-runtime-claim-recovery.ts'; -import type { DaemonPlatformServices } from '../../daemon/platform-services.ts'; -import type { ClaimRecoveryGatewayFactory } from '../../daemon/device/claim-recovery-gateway.ts'; +import type { DaemonPlatformServices } from '@agent-device/daemon/platform-services'; +import type { ClaimRecoveryGatewayFactory } from '@agent-device/daemon/device/claim-recovery-gateway'; /** * The port the production composition root builds, handed to a test the same way the shared router diff --git a/src/__tests__/daemon-composition/providers-plugin-routing-parity.test.ts b/src/__tests__/daemon-composition/providers-plugin-routing-parity.test.ts index d7186bf522..c6dba82ab4 100644 --- a/src/__tests__/daemon-composition/providers-plugin-routing-parity.test.ts +++ b/src/__tests__/daemon-composition/providers-plugin-routing-parity.test.ts @@ -25,15 +25,15 @@ import { VISIONOS_SIMULATOR, WEB_DESKTOP_DEVICE, } from '@agent-device/test-kit/device-fixtures'; -import { makeSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { makeSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { getPlugin, tryGetPlugin } from '../../core/platform-plugin-registry.ts'; import { registerBuiltinPlatformPlugins } from '../../core/interactors/register-builtins.ts'; import { createRequestPlatformProviders, type PlatformProviderResolvers, } from '../../platform-runtime.ts'; -import { resolvePlatformProviderRequestContext } from '../../daemon/request-platform-provider-context.ts'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; +import { resolvePlatformProviderRequestContext } from '@agent-device/daemon/testing/request-platform-provider-context'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; // Phase 3 step b.3 (issue #974) parity gate for the request-scope provider // facet. The per-platform GATE that each descriptor in the root-owned provider composition diff --git a/src/__tests__/daemon-composition/replay-coordinator-ownership.test.ts b/src/__tests__/daemon-composition/replay-coordinator-ownership.test.ts index 21bd581a4c..c4d2f35682 100644 --- a/src/__tests__/daemon-composition/replay-coordinator-ownership.test.ts +++ b/src/__tests__/daemon-composition/replay-coordinator-ownership.test.ts @@ -24,11 +24,11 @@ import { parseSync } from 'oxc-parser'; */ const REPO_ROOT = fileURLToPath(new URL('../../../', import.meta.url)); -const COORDINATOR_MODULE = 'src/daemon/session-replay-coordinator.ts'; -const TRANSACTION_MODULE = 'src/daemon/session-replay-transaction.ts'; -const SESSION_STORE_MODULE = 'src/daemon/session-store.ts'; +const COORDINATOR_MODULE = 'packages/daemon/src/session-replay-coordinator.ts'; +const TRANSACTION_MODULE = 'packages/daemon/src/session-replay-transaction.ts'; +const SESSION_STORE_MODULE = 'packages/daemon/src/session-store.ts'; -const RUNTIME_FILE = 'src/daemon/handlers/session-replay-command.ts'; +const RUNTIME_FILE = 'packages/daemon/src/handlers/session-replay-command.ts'; /** The divergence-report chain: never a second `ReplayCoordinator`, never a bare `SessionStore`. */ const DIVERGENCE_CHAIN_FILES = [ @@ -50,7 +50,7 @@ type ImportSite = { declarationTypeOnly: boolean; }; -const PRODUCTION_ROOTS = ['src', 'packages/replay-port/src'] as const; +const PRODUCTION_ROOTS = ['src', 'packages/daemon/src', 'packages/replay-port/src'] as const; function listProductionSourceFiles(): string[] { const out: string[] = []; @@ -367,7 +367,7 @@ test('createReplayCoordinator has exactly one production call site', () => { }); test('coordinator ownership scanning catches re-exports and unresolved dynamic imports', () => { - const probe = 'src/daemon/replay/internal/probe.ts'; + const probe = 'packages/daemon/src/replay/internal/probe.ts'; const source = ` export { createReplayCoordinator } from '../../session-replay-coordinator.ts'; export * from '../../session-replay-coordinator.ts'; @@ -395,7 +395,7 @@ test('coordinator ownership scanning catches aliases, namespaces, and dynamic im void import('../../session-replay-coordinator.ts'); `; assert.deepEqual( - coordinatorConstructionSites('src/daemon/replay/internal/probe.ts', source).map( + coordinatorConstructionSites('packages/daemon/src/replay/internal/probe.ts', source).map( ({ kind }) => kind, ), ['call', 'call', 'dynamic-import'], @@ -464,7 +464,7 @@ test('the divergence-report chain rejects unresolved dynamic imports', () => { test('SessionStore ownership scanning catches dynamic imports and re-exports', () => { const sites = collectImportSites( - 'src/daemon/replay/internal/probe.ts', + 'packages/daemon/src/replay/internal/probe.ts', [ "void import('../../session-store.ts');", "export { SessionStore } from '../../session-store.ts';", diff --git a/src/__tests__/daemon-composition/replay-suite/session-test-suite-command-flag-policy.test.ts b/src/__tests__/daemon-composition/replay-suite/session-test-suite-command-flag-policy.test.ts index 68c7b3cd58..06c44ce728 100644 --- a/src/__tests__/daemon-composition/replay-suite/session-test-suite-command-flag-policy.test.ts +++ b/src/__tests__/daemon-composition/replay-suite/session-test-suite-command-flag-policy.test.ts @@ -8,11 +8,11 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test, vi } from 'vitest'; -import { SessionStore } from '../../../daemon/session-store.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; import { createReplaySession, replayDaemonDependencies, -} from '../../../daemon/handlers/session-replay-command.ts'; +} from '@agent-device/daemon/testing/handlers/session-replay-command'; import { runReplayTestCommand } from '@agent-device/replay-port/test-command'; import { replayInvokeOverDispatch, @@ -22,7 +22,7 @@ import type { ReplayTestCommand } from '@agent-device/replay-port/command-types' import { REPLAY_ONLY_TEST_FLAG_REJECTIONS } from '@agent-device/replay-port/session-replay-test-policy'; import { replayCommandFamily } from '../../../commands/replay/index.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import type { DaemonInvokeFn, DaemonRequest } from '../../../daemon/daemon-request.ts'; +import type { DaemonInvokeFn, DaemonRequest } from '@agent-device/daemon/daemon-request'; // --- ADR 0012 decision 4 / migration step 5: `--from` is replay-only --- diff --git a/src/__tests__/daemon-composition/request-dispatch-disclosure.test.ts b/src/__tests__/daemon-composition/request-dispatch-disclosure.test.ts index 47e143a0a9..0fe5e2f30d 100644 --- a/src/__tests__/daemon-composition/request-dispatch-disclosure.test.ts +++ b/src/__tests__/daemon-composition/request-dispatch-disclosure.test.ts @@ -10,7 +10,7 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) return { ...actual, stopIosRunnerSession: vi.fn(async () => {}) }; }); -vi.mock('../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); @@ -29,20 +29,20 @@ import { makeAndroidSession, makeIosAppSession, makeSession, -} from '../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; -import { discloseRequestDispatch } from '../../daemon/request-dispatch-disclosure.ts'; -import { createRequestDispatchLedger } from '../../daemon/request-dispatch-ledger.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; -import { clearAndroidObservationFixture } from '../../daemon/__tests__/android-observation-fixture.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import { discloseRequestDispatch } from '@agent-device/daemon/testing/request-dispatch-disclosure'; +import { createRequestDispatchLedger } from '@agent-device/daemon/testing/request-dispatch-ledger'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { clearAndroidObservationFixture } from '@agent-device/daemon/testing/__tests__/android-observation-fixture'; import { createRequestHandler, gestureRuntimeSpies, lifecycleDeviceRuntimeGateway, -} from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +} from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; // contracts/fixtures/dispatch-disclosure.json, daemon.route rows: each drives one request through // the real request router, with only the bound device operations faked. diff --git a/src/__tests__/daemon-composition/request-handler-chain.test.ts b/src/__tests__/daemon-composition/request-handler-chain.test.ts index 1fb425fa73..2dc9419c6e 100644 --- a/src/__tests__/daemon-composition/request-handler-chain.test.ts +++ b/src/__tests__/daemon-composition/request-handler-chain.test.ts @@ -4,25 +4,28 @@ import fs from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; import { INTERNAL_COMMANDS } from '@agent-device/command-registry/catalog'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { runRequestHandlerChain } from '../../daemon/request-handler-chain.ts'; -import { getDaemonRouteOwnerFiles } from '../../daemon/route-owner-files.ts'; -import type { DaemonRequest, DaemonResponse } from '../../daemon/daemon-request.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { runRequestHandlerChain } from '@agent-device/daemon/testing/request-handler-chain'; +import { getDaemonRouteOwnerFiles } from '@agent-device/daemon/route-owner-files'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { LINUX_DEVICE } from '@agent-device/test-kit/device-fixtures'; -import { makeIosSession, makeSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { + makeIosSession, + makeSession, +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { makeSnapshotState } from '@agent-device/selectors/snapshot-geometry-fixtures'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { handleInteractionCommands } from '../../daemon/interaction/index.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { createPlatformRuntimeGateway } from '../../platform-runtime.ts'; -import { createRequestRuntimeBindings } from '../../daemon/request-runtime-binding.ts'; -import { createRequestDispatchLedger } from '../../daemon/request-dispatch-ledger.ts'; +import { createRequestRuntimeBindings } from '@agent-device/daemon/testing/request-runtime-binding'; +import { createRequestDispatchLedger } from '@agent-device/daemon/testing/request-dispatch-ledger'; import { createLocalLinuxToolProvider, withLinuxToolProvider } from '@agent-device/platform-linux'; import { unavailableBindDevice, unavailableBindExactDevice, unavailableDeviceRuntimeGateway, unavailableInspectFacts, -} from '../../daemon/__tests__/support/unavailable-device-runtime-gateway.ts'; +} from '@agent-device/daemon/testing/__tests__/support/unavailable-device-runtime-gateway'; import { createAudioProbeAdmissionLedger } from '@agent-device/capture-kit/audio-probe-admission-ledger'; import { createPerfCaptureAdmissionLedger } from '@agent-device/capture-kit/perf-capture-admission-ledger'; import { createScreenRecordingAdmissionLedger } from '@agent-device/capture-kit/screen-recording-admission-ledger'; @@ -76,7 +79,7 @@ function makeChainParams(req: DaemonRequest) { test('route owner files match the production module loaders', () => { const source = fs.readFileSync( - new URL('../../daemon/request-handler-chain.ts', import.meta.url), + new URL('../../../packages/daemon/src/request-handler-chain.ts', import.meta.url), 'utf8', ); const definitions = [ @@ -94,10 +97,13 @@ test('route owner files match the production module loaders', () => { assert.equal(definitions.length + 1, Object.keys(ownerFiles).length); for (const [, route, modulePath] of definitions) { assert.ok(route && modulePath); - assert.equal(ownerFiles[route as keyof typeof ownerFiles], `src/daemon/${modulePath.slice(2)}`); + assert.equal( + ownerFiles[route as keyof typeof ownerFiles], + `packages/daemon/src/${modulePath.slice(2)}`, + ); } assert.ok(genericModulePath && genericRouteMatches); - assert.equal(ownerFiles.generic, `src/daemon/${genericModulePath.slice(2)}`); + assert.equal(ownerFiles.generic, `packages/daemon/src/${genericModulePath.slice(2)}`); assert.ok( !/ownerFile/.test(source), @@ -106,23 +112,31 @@ test('route owner files match the production module loaders', () => { }); test('request handler chain keeps interaction routes out of its eager import closure', () => { - const chainFile = path.resolve(import.meta.dirname, '../../daemon/request-handler-chain.ts'); + const chainFile = path.resolve( + import.meta.dirname, + '../../../packages/daemon/src/request-handler-chain.ts', + ); const closure = eagerClosureOf(chainFile); assert.ok(closure.length > 20, 'eager closure walk must reach the request chain'); assert.equal( - closure.includes(path.resolve(import.meta.dirname, '../../daemon/interaction/index.ts')), + closure.includes( + path.resolve(import.meta.dirname, '../../../packages/daemon/src/interaction/index.ts'), + ), false, 'interaction routes must stay behind the request chain lazy import', ); }); test('interaction facade keeps route implementations out of its eager import closure', () => { - const facadeFile = path.resolve(import.meta.dirname, '../../daemon/interaction/index.ts'); + const facadeFile = path.resolve( + import.meta.dirname, + '../../../packages/daemon/src/interaction/index.ts', + ); const closure = eagerClosureOf(facadeFile); const snapshotComposition = path.resolve( import.meta.dirname, - '../../daemon/snapshot-runtime-capture-input.ts', + '../../../packages/daemon/src/snapshot-runtime-capture-input.ts', ); assert.ok( @@ -133,7 +147,7 @@ test('interaction facade keeps route implementations out of its eager import clo for (const routeModule of ['find.ts', 'interaction.ts']) { const routePath = path.resolve( import.meta.dirname, - `../../daemon/interaction/internal/${routeModule}`, + `../../../packages/daemon/src/interaction/internal/${routeModule}`, ); assert.equal( fs.existsSync(routePath), diff --git a/src/__tests__/daemon-composition/request-platform-providers.test.ts b/src/__tests__/daemon-composition/request-platform-providers.test.ts index 72043c1ce2..ee51de6a8a 100644 --- a/src/__tests__/daemon-composition/request-platform-providers.test.ts +++ b/src/__tests__/daemon-composition/request-platform-providers.test.ts @@ -11,7 +11,7 @@ import { makeIosSession, makeMacOsSession, makeSession, -} from '../../daemon/__tests__/support/session-factories.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { withTestDeviceInventoryProvider as withTargetDeviceResolutionScope } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { createLocalAppleToolProvider, runXcrun } from '@agent-device/platform-apple/tool-provider'; import { buildSimctlArgsForDevice } from '@agent-device/platform-apple/simctl'; @@ -30,8 +30,8 @@ import type { RequestPlatformProviderScope, PlatformProviderRequestContext, } from '@agent-device/contracts/platform-providers'; -import { resolvePlatformProviderRequestContext } from '../../daemon/request-platform-provider-context.ts'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; +import { resolvePlatformProviderRequestContext } from '@agent-device/daemon/testing/request-platform-provider-context'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; const OTHER_IOS_SIMULATOR: DeviceInfo = { platform: 'apple', diff --git a/src/__tests__/daemon-composition/request-router-android-modal.test.ts b/src/__tests__/daemon-composition/request-router-android-modal.test.ts index 3acd1fa2b6..a5941a99b6 100644 --- a/src/__tests__/daemon-composition/request-router-android-modal.test.ts +++ b/src/__tests__/daemon-composition/request-router-android-modal.test.ts @@ -13,21 +13,21 @@ import { createRequestHandler, gestureDeviceRuntimeGateway, gestureRuntimeSpies, -} from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +} from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { createProviderDeviceRuntimeRequestProviders, isActiveProviderDevice, } from '../../provider-device-runtime.ts'; -import { installProviderDeviceAdmission } from '../../daemon/provider-device-admission.ts'; +import { installProviderDeviceAdmission } from '@agent-device/daemon/testing/provider-device-admission'; // Root composition installs the daemon's provider-device admission; this test composes the // request providers the same way, so it installs the fact the same way. installProviderDeviceAdmission({ isActive: isActiveProviderDevice }); import type { ProviderDeviceRuntime } from '@agent-device/contracts/device'; -import { makeTestScreenRecordingResource } from '../../daemon/__tests__/support/screen-recording-live-handle.ts'; +import { makeTestScreenRecordingResource } from '@agent-device/daemon/testing/__tests__/support/screen-recording-live-handle'; import { androidObservation } from '../../platform-runtime.ts'; import type { AndroidObservationAdapter } from '@agent-device/contracts/android-observation'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; diff --git a/src/__tests__/daemon-composition/request-router-android-perf.test.ts b/src/__tests__/daemon-composition/request-router-android-perf.test.ts index 30a52c1dc1..08ff3cf155 100644 --- a/src/__tests__/daemon-composition/request-router-android-perf.test.ts +++ b/src/__tests__/daemon-composition/request-router-android-perf.test.ts @@ -1,8 +1,8 @@ import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { expect, test } from 'vitest'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { SessionStore } from '../../daemon/session-store.ts'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; import { AppError } from '@agent-device/kernel/errors'; import type { AndroidAdbExecutor, diff --git a/src/__tests__/daemon-composition/request-router-android-snapshot-helper.test.ts b/src/__tests__/daemon-composition/request-router-android-snapshot-helper.test.ts index 7c6cc38fb4..be50b47ea0 100644 --- a/src/__tests__/daemon-composition/request-router-android-snapshot-helper.test.ts +++ b/src/__tests__/daemon-composition/request-router-android-snapshot-helper.test.ts @@ -1,8 +1,8 @@ import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { beforeEach, expect, test } from 'vitest'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { SessionStore } from '../../daemon/session-store.ts'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; import { AppError } from '@agent-device/kernel/errors'; import { resetAndroidSnapshotHelperInstallCache } from '@agent-device/platform-android/mechanics'; import { ANDROID_SNAPSHOT_HELPER_FIXTURE_ARTIFACT } from '../test-utils/android-snapshot-helper.ts'; diff --git a/src/__tests__/daemon-composition/request-router-fill-text-stdin.test.ts b/src/__tests__/daemon-composition/request-router-fill-text-stdin.test.ts index 629b4e880f..6a611a10b7 100644 --- a/src/__tests__/daemon-composition/request-router-fill-text-stdin.test.ts +++ b/src/__tests__/daemon-composition/request-router-fill-text-stdin.test.ts @@ -9,15 +9,15 @@ import fs from 'node:fs'; import path from 'node:path'; import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; import type { WebProvider } from '@agent-device/platform-web'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { makeAuthoringSession, makeSession, -} from '../../daemon/__tests__/support/session-factories.ts'; +} from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { WEB_DESKTOP_DEVICE } from '@agent-device/test-kit/device-fixtures'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; diff --git a/src/__tests__/daemon-composition/request-router-lock-policy.test.ts b/src/__tests__/daemon-composition/request-router-lock-policy.test.ts index 1c67eb48fb..338155f05a 100644 --- a/src/__tests__/daemon-composition/request-router-lock-policy.test.ts +++ b/src/__tests__/daemon-composition/request-router-lock-policy.test.ts @@ -3,7 +3,7 @@ import { createTestDeviceInventoryGatewaysFromProvider, } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { test, expect, vi, beforeEach } from 'vitest'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import path from 'node:path'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; @@ -13,7 +13,7 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) return { ...actual, stopIosRunnerSession: vi.fn(async () => {}) }; }); -vi.mock('../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); @@ -21,11 +21,11 @@ import { createRequestHandler, lifecycleDeviceRuntimeGateway, systemRuntimeSpies, -} from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import { snapshotRuntimeFixture } from '../../daemon/__tests__/snapshot-runtime-fixture.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +} from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import type { DeviceRuntimeGateway } from '@agent-device/contracts/platform-runtime'; import { type PlatformRuntimeOperations, diff --git a/src/__tests__/daemon-composition/request-router-macos-app-lease.test.ts b/src/__tests__/daemon-composition/request-router-macos-app-lease.test.ts index 02604ce4ff..feefc65631 100644 --- a/src/__tests__/daemon-composition/request-router-macos-app-lease.test.ts +++ b/src/__tests__/daemon-composition/request-router-macos-app-lease.test.ts @@ -2,13 +2,13 @@ import { afterEach, beforeEach, expect, test, vi } from 'vitest'; import path from 'node:path'; import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { MACOS_DEVICE } from '@agent-device/test-kit/device-fixtures'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { makeMacOsSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeMacOsSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import type { DaemonRequest, DaemonResponse } from '../../daemon/daemon-request.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import { screenshotRuntimeFixture } from '../../daemon/__tests__/screenshot-runtime-fixture.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import { screenshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/screenshot-runtime-fixture'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; const BUNDLE_ID = 'com.example.leased'; diff --git a/src/__tests__/daemon-composition/request-router-open-claim-recovery.test.ts b/src/__tests__/daemon-composition/request-router-open-claim-recovery.test.ts index 85b6f72c5e..25028a974f 100644 --- a/src/__tests__/daemon-composition/request-router-open-claim-recovery.test.ts +++ b/src/__tests__/daemon-composition/request-router-open-claim-recovery.test.ts @@ -3,21 +3,21 @@ import fs from 'node:fs'; import path from 'node:path'; import crypto from 'node:crypto'; import { spawn } from 'node:child_process'; -import { fakeCreateCommandSurface } from '../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { composedClaimRecoveryGatewayFixture, composedPlatformServicesFixture, } from './platform-services-fixture.ts'; -import { getResolveTargetDeviceMock } from '../../daemon/__tests__/request-router-dispatch-mocks.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; +import { getResolveTargetDeviceMock } from '@agent-device/daemon/testing/__tests__/request-router-dispatch-mocks'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; import type { DeviceInfo } from '@agent-device/kernel/device'; // Open-time claim reconciliation runs on the root-composed claim-recovery gateway: the router // must hand the acquire path the OWNER-scoped reconciler, so a foreign dead owner's recording // recovery executes against that owner's state dir, never the daemon's own store (#2168). -vi.mock('../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); vi.mock('@agent-device/host-kit/process', async (importOriginal) => { @@ -71,14 +71,14 @@ vi.mock('@agent-device/platform-apple/app-resolution', async (importOriginal) => import { createRequestHandler, lifecycleDeviceRuntimeGateway, -} from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +} from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { awaitFixtureReadiness, dispatchApplicationLifecycleEffect, -} from '../../daemon/__tests__/application-lifecycle-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/application-lifecycle-runtime-fixture'; import { discoverReadyAndroidEmulators } from './application-lifecycle-runtime-fixture.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { inspectDeviceClaims } from '../../daemon/device/device-claim-inspection.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { inspectDeviceClaims } from '@agent-device/daemon/device/device-claim-inspection'; import { createOwnedProcessRecordStore, isProcessAlive, @@ -88,7 +88,10 @@ import { import { createDurableResourceEnvelope } from '@agent-device/capture-kit'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; import { screenRecordingDurableResource } from '@agent-device/capture-kit/screen-recording-session-resource'; -import { makeIosDevice, openRequest } from '../../daemon/__tests__/request-router-open-harness.ts'; +import { + makeIosDevice, + openRequest, +} from '@agent-device/daemon/testing/__tests__/request-router-open-harness'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; const mockResolveTargetDevice = vi.mocked(getResolveTargetDeviceMock()); diff --git a/src/__tests__/daemon-composition/request-router-provider-credentials.test.ts b/src/__tests__/daemon-composition/request-router-provider-credentials.test.ts index fe5f0d00af..4c7bc35aef 100644 --- a/src/__tests__/daemon-composition/request-router-provider-credentials.test.ts +++ b/src/__tests__/daemon-composition/request-router-provider-credentials.test.ts @@ -1,14 +1,14 @@ import path from 'node:path'; import { expect, test } from 'vitest'; import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { providerCredentialFingerprint, readDaemonProviderCredentials, } from '../../provider-credential-fingerprint.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; const DAEMON_ENV = { LIMRUN_API_KEY: 'lim-key' }; diff --git a/src/__tests__/daemon-composition/request-router-record-runtime-lock.test.ts b/src/__tests__/daemon-composition/request-router-record-runtime-lock.test.ts index 96433041cd..faaade6e03 100644 --- a/src/__tests__/daemon-composition/request-router-record-runtime-lock.test.ts +++ b/src/__tests__/daemon-composition/request-router-record-runtime-lock.test.ts @@ -12,11 +12,11 @@ import { createDurableResourceEnvelope } from '@agent-device/capture-kit'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { unavailableDeploymentSnapshotAndShutdownOperationFacts } from '@agent-device/test-kit/runtime-operation-facts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; import { createPlatformRuntimeGateway } from '../../platform-runtime.ts'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; const DEVICE: DeviceInfo = { @@ -32,7 +32,7 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal return { ...actual, resolveTargetDevice: vi.fn(async () => DEVICE) }; }); -vi.mock('../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); diff --git a/src/__tests__/daemon-composition/request-router-recording-health.test.ts b/src/__tests__/daemon-composition/request-router-recording-health.test.ts index c5bc86db5f..7b519ef1fb 100644 --- a/src/__tests__/daemon-composition/request-router-recording-health.test.ts +++ b/src/__tests__/daemon-composition/request-router-recording-health.test.ts @@ -1,5 +1,5 @@ import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { test, expect, vi, beforeEach } from 'vitest'; import path from 'node:path'; @@ -10,11 +10,11 @@ import { createRequestHandler, gestureDeviceRuntimeGateway, gestureRuntimeSpies, -} from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { makeTestScreenRecordingResource } from '../../daemon/__tests__/support/screen-recording-live-handle.ts'; +} from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeTestScreenRecordingResource } from '@agent-device/daemon/testing/__tests__/support/screen-recording-live-handle'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; // The observation spy hangs off the port the router composes with (ADR 0019 section 11), not off diff --git a/src/__tests__/daemon-composition/request-router-replay-scope.test.ts b/src/__tests__/daemon-composition/request-router-replay-scope.test.ts index 20ed0e0ee3..7e2b7e1d84 100644 --- a/src/__tests__/daemon-composition/request-router-replay-scope.test.ts +++ b/src/__tests__/daemon-composition/request-router-replay-scope.test.ts @@ -1,13 +1,13 @@ import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { beforeEach, expect, test, vi } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; -import { getResolveTargetDeviceMock } from '../../daemon/__tests__/request-router-dispatch-mocks.ts'; +import { getResolveTargetDeviceMock } from '@agent-device/daemon/testing/__tests__/request-router-dispatch-mocks'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; -vi.mock('../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); @@ -33,18 +33,18 @@ vi.mock('@agent-device/platform-apple/app-resolution', async (importOriginal) => }); import { IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; -import { makeIosSession } from '../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; import { createRequestHandler, gestureRuntimeSpies, lifecycleDeviceRuntimeGateway, systemRuntimeSpies, -} from '../../daemon/__tests__/test-device-runtime-gateway.ts'; -import { ensureDeviceReady } from '../../daemon/device/device-ready.ts'; +} from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; +import { ensureDeviceReady } from '@agent-device/daemon/testing/device/device-ready'; // Readiness is package-owned; hold the open at the fixture's platform-neutral readiness gate. -import { awaitFixtureReadiness } from '../../daemon/__tests__/application-lifecycle-runtime-fixture.ts'; +import { awaitFixtureReadiness } from '@agent-device/daemon/testing/__tests__/application-lifecycle-runtime-fixture'; import { createRequestPlatformProviders } from '../../platform-runtime.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; diff --git a/src/__tests__/daemon-composition/request-router-replay-test-ime.test.ts b/src/__tests__/daemon-composition/request-router-replay-test-ime.test.ts index f967106802..ea1019362b 100644 --- a/src/__tests__/daemon-composition/request-router-replay-test-ime.test.ts +++ b/src/__tests__/daemon-composition/request-router-replay-test-ime.test.ts @@ -10,10 +10,10 @@ import { beforeEach, expect, test, vi } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; -import { getResolveTargetDeviceMock } from '../../daemon/__tests__/request-router-dispatch-mocks.ts'; +import { getResolveTargetDeviceMock } from '@agent-device/daemon/testing/__tests__/request-router-dispatch-mocks'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; -vi.mock('../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); @@ -37,10 +37,10 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }); import { ANDROID_DEVICE } from '@agent-device/test-kit/device-fixtures'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { replayScriptSourceBundleFor } from '@agent-device/replay-port/replay-script-source-fixtures'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { realLifecycleDeviceRuntimeGateway } from './lifecycle-runtime-gateway.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; diff --git a/src/__tests__/daemon-composition/request-router-screenshot.test.ts b/src/__tests__/daemon-composition/request-router-screenshot.test.ts index 636187e1ca..56e14858db 100644 --- a/src/__tests__/daemon-composition/request-router-screenshot.test.ts +++ b/src/__tests__/daemon-composition/request-router-screenshot.test.ts @@ -1,5 +1,5 @@ import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; import { test, expect, vi, beforeEach } from 'vitest'; import fs from 'node:fs'; @@ -16,21 +16,21 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -import { createRequestHandler } from '../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { screenshotRuntimeFixture, writeSolidPng, type ScreenshotRuntimeFixture, type ScreenshotRuntimeFixtureOptions, -} from '../../daemon/__tests__/screenshot-runtime-fixture.ts'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; -import { LeaseRegistry } from '../../daemon/lease-registry.ts'; +} from '@agent-device/daemon/testing/__tests__/screenshot-runtime-fixture'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; import { attachRefs } from '@agent-device/kernel/snapshot'; import { PNG } from '@agent-device/capture-kit/png'; import { ANDROID_EMULATOR, IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { makeSession as makeBaseSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeSession as makeBaseSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; function makeSession(name: string): SessionState { diff --git a/src/__tests__/daemon-composition/screenshot-runtime.test.ts b/src/__tests__/daemon-composition/screenshot-runtime.test.ts index 3ebbdf86a8..3fd95cf7c3 100644 --- a/src/__tests__/daemon-composition/screenshot-runtime.test.ts +++ b/src/__tests__/daemon-composition/screenshot-runtime.test.ts @@ -6,15 +6,15 @@ import { expect, test } from 'vitest'; import { SCREENSHOT_CROP_REASONS } from '@agent-device/contracts/capture'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { ANDROID_EMULATOR, IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; -import { makeSession } from '../../daemon/__tests__/support/session-factories.ts'; -import type { GenericPlatformExecutionParams } from '../../daemon/generic-leaf-execution.ts'; -import { resolveScreenshotGenericExecution } from '../../daemon/screenshot-runtime.ts'; +import { makeSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import type { GenericPlatformExecutionParams } from '@agent-device/daemon/testing/generic-leaf-execution'; +import { resolveScreenshotGenericExecution } from '@agent-device/daemon/testing/screenshot-runtime'; import { screenshotRuntimeFixture, writeSolidPng, -} from '../../daemon/__tests__/screenshot-runtime-fixture.ts'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; +} from '@agent-device/daemon/testing/__tests__/screenshot-runtime-fixture'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; diff --git a/src/__tests__/daemon-composition/selector-runtime-ambiguity-issuance.test.ts b/src/__tests__/daemon-composition/selector-runtime-ambiguity-issuance.test.ts index 8c11023046..9d7a63b01b 100644 --- a/src/__tests__/daemon-composition/selector-runtime-ambiguity-issuance.test.ts +++ b/src/__tests__/daemon-composition/selector-runtime-ambiguity-issuance.test.ts @@ -1,23 +1,23 @@ import { composedPlatformServicesFixture } from './platform-services-fixture.ts'; import { test, expect, vi, beforeEach } from 'vitest'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { selectorCaptureFixture } from '../../daemon/__tests__/selector-capture-fixture.ts'; -import { refFrameScope, refFrameState } from '../../daemon/ref-frame.ts'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; -import { dispatchIsViaRuntime } from '../../daemon/selector-runtime.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { selectorCaptureFixture } from '@agent-device/daemon/testing/__tests__/selector-capture-fixture'; +import { refFrameScope, refFrameState } from '@agent-device/daemon/testing/ref-frame'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import { dispatchIsViaRuntime } from '@agent-device/daemon/testing/selector-runtime'; import { IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; import { getRuntimeBindings, mockTapPoint, resetGetRuntimeFixture, -} from '../../daemon/__tests__/interaction-get-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/interaction-get-runtime-fixture'; import { contextFromFlags, makeStaleRefSession, readPressPoint, -} from '../../daemon/interaction/internal/__tests__/interaction-touch-fixtures.ts'; -import { handleInteractionCommands } from '../../daemon/interaction/index.ts'; +} from '@agent-device/daemon/testing/interaction/internal/__tests__/interaction-touch-fixtures'; +import { handleInteractionCommands } from '@agent-device/daemon/testing/interaction/index'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; // #2870 review, the reviewer's pinned invariant: a response that prints @@ -43,9 +43,11 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { }; }); -vi.mock('../../daemon/snapshot-interactor-capture.ts', async (importOriginal) => { +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async (importOriginal) => { const actual = - await importOriginal(); + await importOriginal< + typeof import('@agent-device/daemon/testing/snapshot-interactor-capture') + >(); return { ...actual, captureSnapshotWithInteractor: mockCaptureSnapshotWithInteractor }; }); diff --git a/src/__tests__/daemon-composition/selector-runtime-backend.test.ts b/src/__tests__/daemon-composition/selector-runtime-backend.test.ts index 7fcd66ce65..1d9b592f4d 100644 --- a/src/__tests__/daemon-composition/selector-runtime-backend.test.ts +++ b/src/__tests__/daemon-composition/selector-runtime-backend.test.ts @@ -5,9 +5,9 @@ import type { CaptureSnapshotInput, SnapshotResult, } from '@agent-device/contracts/snapshot-runtime'; -import { createSelectorRuntimeForDevice } from '../../daemon/selector-runtime-backend.ts'; -import { SessionStore } from '../../daemon/session-store.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; +import { createSelectorRuntimeForDevice } from '@agent-device/daemon/testing/selector-runtime-backend'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { makeSnapshotState } from '@agent-device/selectors/snapshot-geometry-fixtures'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; diff --git a/src/__tests__/daemon-composition/selector-runtime.test.ts b/src/__tests__/daemon-composition/selector-runtime.test.ts index 2b22923d76..6f02ef2487 100644 --- a/src/__tests__/daemon-composition/selector-runtime.test.ts +++ b/src/__tests__/daemon-composition/selector-runtime.test.ts @@ -11,9 +11,9 @@ import { type SnapshotResult, } from '@agent-device/contracts/snapshot-runtime'; import { createUnavailableRuntimeFactsForTest } from '@agent-device/test-kit/runtime-operation-facts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; -import { makeSession as makeStoredSession } from '../../daemon/__tests__/support/session-factories.ts'; -import { dispatchGetViaRuntime } from '../../daemon/selector-runtime.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeSession as makeStoredSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { dispatchGetViaRuntime } from '@agent-device/daemon/testing/selector-runtime'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; test.each(['rebuild', 'retire'] as const)( diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-idle-reap.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-idle-reap.test.ts index 5e34891198..30444447e7 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-idle-reap.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-idle-reap.test.ts @@ -3,10 +3,11 @@ import fs from 'node:fs'; import { afterEach, test, vi } from 'vitest'; const leaseProbe = vi.hoisted(() => ({ - registries: [] as import('../../../daemon/lease-registry.ts').LeaseRegistry[], + registries: [] as import('@agent-device/daemon/testing/lease-registry').LeaseRegistry[], })); -vi.mock('../../../daemon/lease-registry.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/lease-registry', async (importOriginal) => { + const actual = + await importOriginal(); class RecordedLeaseRegistry extends actual.LeaseRegistry { constructor(...args: ConstructorParameters) { super(...args); diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-interactor-composition.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-interactor-composition.test.ts index 4ecef4000d..3682e93845 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-interactor-composition.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-interactor-composition.test.ts @@ -12,7 +12,7 @@ import { tryAcquireDaemonRegistration, } from '@agent-device/daemon-contracts/daemon-registration-owner'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; -import { interactorResolution } from '../../../daemon/interactor-resolution.ts'; +import { interactorResolution } from '@agent-device/daemon/testing/interactor-resolution'; vi.mock('../../../platform-runtime.ts', () => ({ androidObservation: {}, diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-lifecycle-shutdown.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-lifecycle-shutdown.test.ts index 1e9afab92a..3f8e342072 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-lifecycle-shutdown.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-lifecycle-shutdown.test.ts @@ -48,14 +48,15 @@ vi.mock('../../../provider-device-runtimes.ts', () => ({ })); const shutdownProbe = vi.hoisted(() => ({ - store: undefined as import('../../../daemon/session-store.ts').SessionStore | undefined, + store: undefined as import('@agent-device/daemon/testing/session-store').SessionStore | undefined, drain: undefined as (() => Promise) | undefined, finalize: vi.fn(async () => {}), - dispatch: undefined as import('../../../daemon/daemon-request.ts').DaemonInvokeFn | undefined, + dispatch: undefined as import('@agent-device/daemon/daemon-request').DaemonInvokeFn | undefined, closeTimeout: undefined as number | undefined, })); -vi.mock('../../../daemon/session-store.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/session-store', async (importOriginal) => { + const actual = + await importOriginal(); return { ...actual, SessionStore: class extends actual.SessionStore { @@ -66,8 +67,9 @@ vi.mock('../../../daemon/session-store.ts', async (importOriginal) => { }, }; }); -vi.mock('../../../daemon/server/server-shutdown.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/server/server-shutdown', async (importOriginal) => { + const actual = + await importOriginal(); return { ...actual, closeDaemonServers: async (...args: Parameters) => { @@ -76,8 +78,9 @@ vi.mock('../../../daemon/server/server-shutdown.ts', async (importOriginal) => { }, }; }); -vi.mock('../../../daemon/request-router.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/request-router', async (importOriginal) => { + const actual = + await importOriginal(); return { ...actual, createRequestHandler: (...args: Parameters) => { @@ -87,17 +90,20 @@ vi.mock('../../../daemon/request-router.ts', async (importOriginal) => { }, }; }); -vi.mock('../../../daemon/application-lifecycle-recovery.ts', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/daemon/testing/application-lifecycle-recovery', async (importOriginal) => ({ + ...(await importOriginal< + typeof import('@agent-device/daemon/testing/application-lifecycle-recovery') + >()), finalizeDaemonSessionApplicationLifecycle: shutdownProbe.finalize, })); const leaseProbe = vi.hoisted(() => ({ - registries: [] as import('../../../daemon/lease-registry.ts').LeaseRegistry[], + registries: [] as import('@agent-device/daemon/testing/lease-registry').LeaseRegistry[], released: [] as import('@agent-device/contracts/device').DeviceLease[], })); -vi.mock('../../../daemon/lease-registry.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/lease-registry', async (importOriginal) => { + const actual = + await importOriginal(); class RecordedLeaseRegistry extends actual.LeaseRegistry { constructor(...args: ConstructorParameters) { super(...args); @@ -107,8 +113,9 @@ vi.mock('../../../daemon/lease-registry.ts', async (importOriginal) => { return { ...actual, LeaseRegistry: RecordedLeaseRegistry }; }); -vi.mock('../../../daemon/provider-lease-expiry.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/provider-lease-expiry', async (importOriginal) => { + const actual = + await importOriginal(); return { ...actual, createExpiredProviderLeaseReleaser: ( @@ -126,19 +133,19 @@ vi.mock('../../../daemon/provider-lease-expiry.ts', async (importOriginal) => { }; }); -import { acquireDeviceClaim } from '../../../daemon/device/device-claims.ts'; -import { resolveDeviceClaimPath } from '../../../daemon/device/device-claim-paths.ts'; +import { acquireDeviceClaim } from '@agent-device/daemon/device/device-claims'; +import { resolveDeviceClaimPath } from '@agent-device/daemon/testing/device/device-claim-paths'; import { ANDROID_EMULATOR } from '@agent-device/test-kit/device-fixtures'; import { isolatedDeviceClaimStores, retainOrphanedDeviceClaims, -} from '../../../daemon/__tests__/support/device-claim-store.ts'; +} from '@agent-device/daemon/testing/__tests__/support/device-claim-store'; import { sendRequest } from '../../../daemon-client/daemon-client-transport.ts'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; -import { teardownDaemonSessionForShutdown } from '../../../daemon/server/daemon-runtime.ts'; +import { teardownDaemonSessionForShutdown } from '@agent-device/daemon/server/daemon-runtime'; import { startDaemonRuntimeFixture } from '../daemon-runtime-fixture.ts'; -import { makeIosSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; afterEach(() => { lifecycleEvents.length = 0; diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-metadata-ownership.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-metadata-ownership.test.ts index 84318a1fba..9b192299d5 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-metadata-ownership.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-metadata-ownership.test.ts @@ -256,7 +256,7 @@ test('the loss watch is armed only after this daemon publishes its own record', // Arming before publication would report a predecessor's record as a takeover of something this // daemon never owned. Ordering is the invariant, the same way the startup-ordering guards read it. const source = fs.readFileSync( - new URL('../../../daemon/server/daemon-runtime.ts', import.meta.url), + new URL('../../../../packages/daemon/src/server/daemon-runtime.ts', import.meta.url), 'utf8', ); const published = source.indexOf('publishDaemonInfo(socketPort, httpPort);'); @@ -272,7 +272,7 @@ test('both exits tear the watch down before they touch daemon.json', () => { // publication needs a real toolchain — so the invariant is read off the source, the same way the // arming order above is. const source = fs.readFileSync( - new URL('../../../daemon/server/daemon-runtime.ts', import.meta.url), + new URL('../../../../packages/daemon/src/server/daemon-runtime.ts', import.meta.url), 'utf8', ); const stops = [...source.matchAll(/stopMetadataLossWatch\(\);/g)].map((m) => m.index); diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-recording-teardown.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-recording-teardown.test.ts index 1dd9cf1d2b..6ef487f6a2 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-recording-teardown.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-recording-teardown.test.ts @@ -3,9 +3,9 @@ import { afterEach, expect, test, vi } from 'vitest'; import type { ScreenRecordingCompletion } from '@agent-device/contracts/screen-recording-runtime'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; -import { SessionStore } from '../../../daemon/session-store.ts'; -import { makeRecordingSession } from '../../../daemon/__tests__/session-teardown.fixtures.ts'; -import { teardownDaemonSessionForShutdown } from '../../../daemon/server/daemon-runtime.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import { makeRecordingSession } from '@agent-device/daemon/testing/__tests__/session-teardown.fixtures'; +import { teardownDaemonSessionForShutdown } from '@agent-device/daemon/server/daemon-runtime'; afterEach(() => { vi.useRealTimers(); diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-rpc-flow-failure.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-rpc-flow-failure.test.ts index 67d4dbf112..8b55069f65 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-rpc-flow-failure.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-rpc-flow-failure.test.ts @@ -14,8 +14,9 @@ const requestProbe = vi.hoisted(() => ({ failuresRemaining: 0, })); -vi.mock('../../../daemon/request-router.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/daemon/testing/request-router', async (importOriginal) => { + const actual = + await importOriginal(); return { ...actual, createRequestHandler: (...args: Parameters) => { diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-snapshot-shutdown.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-snapshot-shutdown.test.ts index 7e986a20f6..ba2b4a45ab 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-snapshot-shutdown.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-snapshot-shutdown.test.ts @@ -5,20 +5,20 @@ import { registerRequestAbort, } from '@agent-device/host-kit/request'; import { ANDROID_EMULATOR } from '@agent-device/test-kit/device-fixtures'; -import { makeAndroidSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { legacyDispatchCapture } from '../../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { snapshotRuntimeFixture } from '../../../daemon/__tests__/snapshot-runtime-fixture.ts'; +import { makeAndroidSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; -import { DAEMON_SESSION_TEARDOWN_TIMEOUT_MS } from '../../../daemon/session-teardown-budget.ts'; -import { dispatchSnapshotViaRuntime } from '../../../daemon/snapshot-runtime.ts'; -import { teardownDaemonSessionForShutdown } from '../../../daemon/server/daemon-runtime.ts'; +import { DAEMON_SESSION_TEARDOWN_TIMEOUT_MS } from '@agent-device/daemon/testing/session-teardown-budget'; +import { dispatchSnapshotViaRuntime } from '@agent-device/daemon/testing/snapshot-runtime'; +import { teardownDaemonSessionForShutdown } from '@agent-device/daemon/server/daemon-runtime'; import { testCreateCommandSurface } from '../command-surface-fixture.ts'; vi.mock('@agent-device/device-selection/dispatch-resolve', () => ({ resolveTargetDevice: vi.fn(async () => ANDROID_EMULATOR), })); -vi.mock('../../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); vi.mock('../../../platform-runtime-resource-cleanup.ts', () => ({ diff --git a/src/__tests__/daemon-composition/server/daemon-runtime-web-close-teardown.test.ts b/src/__tests__/daemon-composition/server/daemon-runtime-web-close-teardown.test.ts index 1119913108..fafe5c7661 100644 --- a/src/__tests__/daemon-composition/server/daemon-runtime-web-close-teardown.test.ts +++ b/src/__tests__/daemon-composition/server/daemon-runtime-web-close-teardown.test.ts @@ -10,9 +10,9 @@ import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { installFakeManagedAgentBrowser } from '@agent-device/test-kit/web-managed-agent-browser'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; import { runCmd } from '@agent-device/host-kit/command'; -import { SessionStore } from '../../../daemon/session-store.ts'; -import { makeWebSession } from '../../../daemon/__tests__/session-teardown.fixtures.ts'; -import { teardownDaemonSessionForShutdown } from '../../../daemon/server/daemon-runtime.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import { makeWebSession } from '@agent-device/daemon/testing/__tests__/session-teardown.fixtures'; +import { teardownDaemonSessionForShutdown } from '@agent-device/daemon/server/daemon-runtime'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-close-error-precedence.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-close-error-precedence.test.ts index 62d6d9799c..02d54e0695 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-close-error-precedence.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-close-error-precedence.test.ts @@ -3,8 +3,8 @@ import { composedPlatformServicesFixture } from '../platform-services-fixture.ts import { sessionCloseShutdownFixture, type SessionState, -} from '../../../daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +} from '@agent-device/daemon/testing/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { composedLifecycleRuntimeFixture } from '../application-lifecycle-runtime-fixture.ts'; const { diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-close-runtime-hints.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-close-runtime-hints.test.ts index 471f63c789..b8fcbbf956 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-close-runtime-hints.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-close-runtime-hints.test.ts @@ -1,9 +1,9 @@ import { beforeEach, expect, test, vi } from 'vitest'; import path from 'node:path'; -import { SessionStore } from '../../../daemon/session-store.ts'; -import type { DaemonRequest, DaemonResponse } from '../../../daemon/daemon-request.ts'; -import type { SessionState } from '../../../daemon/session-state.ts'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; // These close cases pin when the REAL composed lifecycle reaches the root runtime-hints module // (lazy evaluation: only an admitted hint mutation loads it), so they run in the composition lane @@ -23,8 +23,8 @@ import { handleSessionCommands as handleHarnessSessionCommands, mockBindDeviceRuntime, mockInspectDeviceRuntimeFacts, -} from '../../../daemon/handlers/__tests__/session-command-harness.ts'; -import { lifecycleRuntimeFacts } from '../../../daemon/__tests__/application-lifecycle-runtime-harness.ts'; +} from '@agent-device/daemon/testing/handlers/__tests__/session-command-harness'; +import { lifecycleRuntimeFacts } from '@agent-device/daemon/testing/__tests__/application-lifecycle-runtime-harness'; import { composedLifecycleRuntimeFixture, dispatchApplicationLifecycleEffect, diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-close-save-script.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-close-save-script.test.ts index 55d57300c2..f98f24d17b 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-close-save-script.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-close-save-script.test.ts @@ -1,9 +1,9 @@ import { beforeEach, expect, test } from 'vitest'; import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { composedLifecycleRuntimeFixture } from '../application-lifecycle-runtime-fixture.ts'; -import { sessionCloseShutdownFixture } from '../../../daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts'; +import { sessionCloseShutdownFixture } from '@agent-device/daemon/testing/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures'; const { handleSessionCommands: handleHarnessSessionCommands, diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-close-shutdown-platform.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-close-shutdown-platform.test.ts index bf1519341f..b4f24eca59 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-close-shutdown-platform.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-close-shutdown-platform.test.ts @@ -1,9 +1,9 @@ import { beforeEach, expect, test } from 'vitest'; import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { composedLifecycleRuntimeFixture } from '../application-lifecycle-runtime-fixture.ts'; -import { sessionCloseShutdownFixture } from '../../../daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts'; +import { sessionCloseShutdownFixture } from '@agent-device/daemon/testing/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures'; const { handleSessionCommands: handleHarnessSessionCommands, diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-open-existing.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-open-existing.test.ts index e378d16267..42af124701 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-open-existing.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-open-existing.test.ts @@ -9,11 +9,11 @@ import { makeSession, noopInvoke, assertInvalidArgsMessage, -} from '../../../daemon/handlers/__tests__/session-test-harness.ts'; -import { handleSessionCommands as handleHarnessSessionCommands } from '../../../daemon/handlers/__tests__/session-command-harness.ts'; +} from '@agent-device/daemon/testing/handlers/__tests__/session-test-harness'; +import { handleSessionCommands as handleHarnessSessionCommands } from '@agent-device/daemon/testing/handlers/__tests__/session-command-harness'; import { composedLifecycleRuntimeFixture } from '../application-lifecycle-runtime-fixture.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; // These open cases pin what the REAL composed open-target and surface rules answer through the diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-open-post-open-observation.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-open-post-open-observation.test.ts index 4f7c77248e..7a39354558 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-open-post-open-observation.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-open-post-open-observation.test.ts @@ -15,14 +15,14 @@ vi.mock('@agent-device/device-selection/dispatch-resolve', async (importOriginal const actual = await importOriginal(); const { selectionFromResolveTargetDevice } = - await import('../../../daemon/__tests__/device-selection-stub.ts'); + await import('@agent-device/daemon/testing/__tests__/device-selection-stub'); return { ...actual, resolveTargetDevice: mockResolveTargetDevice, resolveTargetDeviceSelection: vi.fn(selectionFromResolveTargetDevice(mockResolveTargetDevice)), }; }); -vi.mock('../../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); vi.mock('../../../platform-runtime-apple-application-tools.ts', async (importOriginal) => { @@ -55,16 +55,16 @@ vi.mock('@agent-device/host-kit/process', async (importOriginal) => { }); import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { handleSessionCommands as handleHarnessSessionCommands, mockBindDeviceRuntime, -} from '../../../daemon/handlers/__tests__/session-command-harness.ts'; +} from '@agent-device/daemon/testing/handlers/__tests__/session-command-harness'; import { composedLifecycleRuntimeFixture, dispatchApplicationLifecycleEffect, } from '../application-lifecycle-runtime-fixture.ts'; -import { pendingSurfaceStabilization } from '../../../daemon/deferred-interaction-outcome.ts'; +import { pendingSurfaceStabilization } from '@agent-device/daemon/testing/deferred-interaction-outcome'; // The harness takes the lifecycle-operations loader per call, exactly like the gateway factories: // these composition cases pass the REAL composed fixture instead of the daemon's canned default. @@ -77,7 +77,7 @@ import { makeAppleSimulator, makeSessionStore, noopInvoke, -} from '../../../daemon/session-lifecycle/internal/__tests__/session-open-runtime.fixtures.ts'; +} from '@agent-device/daemon/testing/session-lifecycle/internal/__tests__/session-open-runtime.fixtures'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; const mockDispatch = vi.mocked(dispatchApplicationLifecycleEffect); diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-open-surface.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-open-surface.test.ts index ee6cf19bb0..2c44185891 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-open-surface.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-open-surface.test.ts @@ -1,9 +1,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; -import { buildOpenResult } from '../../../daemon/session-lifecycle/internal/session-open-surface.ts'; import { resolveRequestedOpenSurface } from '../../../platform-runtime-open-target.ts'; -import { IOS_SIMULATOR } from '@agent-device/test-kit/device-fixtures'; test('resolveRequestedOpenSurface rejects surface flag on iOS', () => { assert.throws( @@ -24,77 +22,3 @@ test('resolveRequestedOpenSurface rejects surface flag on iOS', () => { /surface is only supported on macOS/i.test(error.message), ); }); - -test('buildOpenResult exposes the Vega serial without leaking an internal platform alias', () => { - const result = buildOpenResult({ - sessionName: 'vega-tv', - sessionStateDir: '/tmp/state', - runnerLogPath: '/tmp/runner.log', - requestLogPath: '/tmp/request.ndjson', - eventLogPath: '/tmp/events.ndjson', - appName: 'com.example.app.main', - surface: 'app', - device: { - platform: 'vega', - id: 'amazon-vvd', - name: 'Vega Virtual Device', - kind: 'emulator', - target: 'tv', - booted: true, - }, - runtimeHintCount: () => 0, - sessionReused: false, - }); - - assert.equal(result.platform, 'vega'); - assert.equal(result.serial, 'amazon-vvd'); - assert.equal(result.target, 'tv'); -}); - -test('buildOpenResult exposes typed device-selection evidence once at response level', () => { - const result = buildOpenResult({ - sessionName: 'ios-selection', - sessionStateDir: '/tmp/state', - runnerLogPath: '/tmp/runner.log', - requestLogPath: '/tmp/request.ndjson', - eventLogPath: '/tmp/events.ndjson', - surface: 'app', - device: IOS_SIMULATOR, - runtimeHintCount: () => 0, - sessionReused: false, - selection: { - device: IOS_SIMULATOR, - reason: 'single-booted-local', - source: 'local', - candidateCount: 1, - bootOccurred: false, - }, - }); - - assert.deepEqual(result.selection, { - reason: 'single-booted-local', - source: 'local', - candidateCount: 1, - bootOccurred: false, - }); -}); - -test('buildOpenResult reports an answered launch confirmation and omits one that never appeared', () => { - const base = { - sessionName: 'ios-launch-url', - sessionStateDir: '/tmp/state', - runnerLogPath: '/tmp/runner.log', - requestLogPath: '/tmp/request.ndjson', - eventLogPath: '/tmp/events.ndjson', - surface: 'app' as const, - device: IOS_SIMULATOR, - runtimeHintCount: () => 0, - sessionReused: false, - }; - - assert.equal( - buildOpenResult({ ...base, launchConfirmation: 'accepted' }).launchConfirmation, - 'accepted', - ); - assert.equal('launchConfirmation' in buildOpenResult(base), false); -}); diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-open-url-prewarm.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-open-url-prewarm.test.ts index 180cfe4486..3ebd57cafe 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-open-url-prewarm.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-open-url-prewarm.test.ts @@ -1,13 +1,13 @@ import { test, expect, vi, beforeEach } from 'vitest'; import * as path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; vi.mock('node:timers/promises', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, setTimeout: vi.fn(async () => undefined) }; }); -vi.mock('../../../daemon/device/device-ready.ts', () => ({ +vi.mock('@agent-device/daemon/testing/device/device-ready', () => ({ ensureDeviceReady: vi.fn(async () => {}), })); vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) => { @@ -44,19 +44,19 @@ vi.mock('@agent-device/platform-android/mechanics', async (importOriginal) => { return { ...actual, resolveAndroidPackageForOpen: vi.fn(async () => undefined) }; }); -import { createRequestHandler } from '../../../daemon/__tests__/test-device-runtime-gateway.ts'; +import { createRequestHandler } from '@agent-device/daemon/testing/__tests__/test-device-runtime-gateway'; import { createRealLifecycleDeviceRuntimeGatewaySpies, realLifecycleDeviceRuntimeGateway, } from '../lifecycle-runtime-gateway.ts'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; import { dispatchApplicationLifecycleEffect } from '../application-lifecycle-runtime-fixture.ts'; -import { getResolveTargetDeviceMock } from '../../../daemon/__tests__/request-router-dispatch-mocks.ts'; +import { getResolveTargetDeviceMock } from '@agent-device/daemon/testing/__tests__/request-router-dispatch-mocks'; import { createTestDeviceInventoryGateways } from '@agent-device/device-selection/inventory-gateways-fixtures'; -import { makeSessionStore } from '../../../daemon/__tests__/support/store-factory.ts'; -import { makeSession } from '../../../daemon/__tests__/support/session-factories.ts'; -import { LeaseRegistry } from '../../../daemon/lease-registry.ts'; -import type { DaemonRequest } from '../../../daemon/daemon-request.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; +import { makeSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { prepareIosRunner, prewarmAppleRunnerCache, diff --git a/src/__tests__/daemon-composition/session-lifecycle/session-teardown-resources.test.ts b/src/__tests__/daemon-composition/session-lifecycle/session-teardown-resources.test.ts index 094abf91f1..99ce9888c4 100644 --- a/src/__tests__/daemon-composition/session-lifecycle/session-teardown-resources.test.ts +++ b/src/__tests__/daemon-composition/session-lifecycle/session-teardown-resources.test.ts @@ -2,9 +2,9 @@ import { beforeEach, expect, test } from 'vitest'; import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; import { composedPlatformServicesFixture } from '../platform-services-fixture.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { fakeCreateCommandSurface } from '../../../daemon/__tests__/support/command-surface-fake.ts'; +import { fakeCreateCommandSurface } from '@agent-device/daemon/testing/__tests__/support/command-surface-fake'; import { composedLifecycleRuntimeFixture } from '../application-lifecycle-runtime-fixture.ts'; -import { sessionCloseShutdownFixture } from '../../../daemon/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures.ts'; +import { sessionCloseShutdownFixture } from '@agent-device/daemon/testing/session-lifecycle/internal/__tests__/session-close-shutdown.fixtures'; const { handleSessionCommands: handleHarnessSessionCommands, diff --git a/src/__tests__/daemon-composition/session-teardown-import-closure.test.ts b/src/__tests__/daemon-composition/session-teardown-import-closure.test.ts index 505308ac0b..b59045f388 100644 --- a/src/__tests__/daemon-composition/session-teardown-import-closure.test.ts +++ b/src/__tests__/daemon-composition/session-teardown-import-closure.test.ts @@ -1,5 +1,6 @@ import { expect, test } from 'vitest'; import path from 'node:path'; +import { DAEMON_SOURCE_ROOT } from '../../../scripts/layering/tracked-sources.ts'; import { eagerClosureOf } from '../eager-import-closure.fixtures.ts'; /** @@ -15,8 +16,11 @@ import { eagerClosureOf } from '../eager-import-closure.fixtures.ts'; * eager closure and fails here. */ -const srcRoot = path.resolve(import.meta.dirname, '../..'); -const teardownFile = path.resolve(srcRoot, 'daemon/session-teardown.ts'); +const repoRoot = path.resolve(import.meta.dirname, '../../..'); +// Derived from the layering constant rather than a fresh literal: the daemon moved to +// packages/daemon/src and a hand-written `daemon/...` under src/ silently ENOENTs (#3546 CI). +const daemonRoot = path.join(repoRoot, DAEMON_SOURCE_ROOT); +const teardownFile = path.join(daemonRoot, 'session-teardown.ts'); const LAZY_ANDROID_HELPERS = [ /platforms[/\\]android[/\\]perf\.ts$/, /platforms[/\\]android[/\\]snapshot-helper\.ts$/, @@ -29,7 +33,7 @@ test('the session teardown eager import closure never evaluates the android clea ); expect( - offenders.map((file) => path.relative(srcRoot, file)), + offenders.map((file) => path.relative(daemonRoot, file)), 'Load the android perf/snapshot-helper cleanup helpers on demand instead: teardown is shared ' + 'by every platform, and eagerly evaluating these drags their whole subtree into sessions ' + 'that never ran an android capture.', @@ -42,7 +46,7 @@ test('the session teardown eager import closure never evaluates the web managed- ); expect( - offenders.map((file) => path.relative(srcRoot, file)), + offenders.map((file) => path.relative(daemonRoot, file)), 'Load the agent-browser web provider on demand instead: teardown is shared by every ' + 'platform, and eagerly evaluating it drags its whole subtree (agent-browser tool ' + 'resolution, selectors, snapshot/network normalization) into sessions that never opened a ' + @@ -55,5 +59,5 @@ test('the teardown closure walk is reachable and the dynamic seam exists', () => // guard above pass while proving nothing, so pin a real lower bound… const closure = eagerClosureOf(teardownFile); expect(closure.length).toBeGreaterThan(20); - expect(closure).toContain(path.resolve(srcRoot, 'daemon/materialized-path-registry.ts')); + expect(closure).toContain(path.join(daemonRoot, 'materialized-path-registry.ts')); }); diff --git a/src/__tests__/daemon-composition/snapshot-command-runtime.test.ts b/src/__tests__/daemon-composition/snapshot-command-runtime.test.ts index 4b4c58396f..4442446d63 100644 --- a/src/__tests__/daemon-composition/snapshot-command-runtime.test.ts +++ b/src/__tests__/daemon-composition/snapshot-command-runtime.test.ts @@ -1,16 +1,16 @@ import { composedPlatformServicesFixture } from './platform-services-fixture.ts'; import { afterEach, expect, test } from 'vitest'; -import { makeAndroidSession } from '../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeAndroidSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { clearRequestAbortRegistration, markRequestCanceled, registerRequestAbort, } from '@agent-device/host-kit/request'; -import { dispatchSnapshotDiffViaRuntime } from '../../daemon/snapshot-diff-runtime.ts'; -import { dispatchSnapshotViaRuntime } from '../../daemon/snapshot-runtime.ts'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { snapshotRuntimeFixture } from '../../daemon/__tests__/snapshot-runtime-fixture.ts'; +import { dispatchSnapshotDiffViaRuntime } from '@agent-device/daemon/testing/snapshot-diff-runtime'; +import { dispatchSnapshotViaRuntime } from '@agent-device/daemon/testing/snapshot-runtime'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; /** diff --git a/src/__tests__/daemon-composition/snapshot-diff-runtime.test.ts b/src/__tests__/daemon-composition/snapshot-diff-runtime.test.ts index 088f5dfe59..7f54de517d 100644 --- a/src/__tests__/daemon-composition/snapshot-diff-runtime.test.ts +++ b/src/__tests__/daemon-composition/snapshot-diff-runtime.test.ts @@ -13,15 +13,15 @@ import { snapshotRuntimeOperationFacts, } from '@agent-device/contracts/snapshot-runtime'; import { deviceShape } from '@agent-device/kernel/device'; -import { makeAndroidSession } from '../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeAndroidSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts, -} from '../../daemon/request-runtime-binding.ts'; -import { dispatchSnapshotDiffViaRuntime } from '../../daemon/snapshot-diff-runtime.ts'; -import { expectRefusesUnavailableExactOwnerFact } from '../../daemon/__tests__/runtime-binding-conformance.ts'; -import { unavailableDeviceRuntimeGateway } from '../../daemon/__tests__/support/unavailable-device-runtime-gateway.ts'; +} from '@agent-device/daemon/testing/request-runtime-binding'; +import { dispatchSnapshotDiffViaRuntime } from '@agent-device/daemon/testing/snapshot-diff-runtime'; +import { expectRefusesUnavailableExactOwnerFact } from '@agent-device/daemon/testing/__tests__/runtime-binding-conformance'; +import { unavailableDeviceRuntimeGateway } from '@agent-device/daemon/testing/__tests__/support/unavailable-device-runtime-gateway'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; const available = Object.freeze({ available: true } as const); diff --git a/src/__tests__/daemon-composition/snapshot-quality-latch.test.ts b/src/__tests__/daemon-composition/snapshot-quality-latch.test.ts index d765e4bf75..65e2cf663f 100644 --- a/src/__tests__/daemon-composition/snapshot-quality-latch.test.ts +++ b/src/__tests__/daemon-composition/snapshot-quality-latch.test.ts @@ -1,7 +1,7 @@ import path from 'node:path'; import { expect, test, vi } from 'vitest'; import type { SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; -import { makeIosSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { recoveredSnapshotQualityWarning, renderSnapshotQualityWarnings, @@ -9,18 +9,19 @@ import { import { applyRecoveredWarningLatch, resolveRecoveredWarningLatch, -} from '../../daemon/snapshot-quality-latch.ts'; -import { dispatchSnapshotDiffViaRuntime } from '../../daemon/snapshot-diff-runtime.ts'; -import { dispatchSnapshotViaRuntime } from '../../daemon/snapshot-runtime.ts'; -import { SessionStore } from '../../daemon/session-store.ts'; -import type { SessionState } from '../../daemon/session-state.ts'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { snapshotRuntimeFixture } from '../../daemon/__tests__/snapshot-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/snapshot-quality-latch'; +import { dispatchSnapshotDiffViaRuntime } from '@agent-device/daemon/testing/snapshot-diff-runtime'; +import { dispatchSnapshotViaRuntime } from '@agent-device/daemon/testing/snapshot-runtime'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; -vi.mock('../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); diff --git a/src/__tests__/daemon-composition/snapshot-runtime-disclosure.test.ts b/src/__tests__/daemon-composition/snapshot-runtime-disclosure.test.ts index cd2aef5532..b8543f4b8d 100644 --- a/src/__tests__/daemon-composition/snapshot-runtime-disclosure.test.ts +++ b/src/__tests__/daemon-composition/snapshot-runtime-disclosure.test.ts @@ -4,17 +4,18 @@ import { iosTargetActivationDisclosure } from '@agent-device/contracts/ios-targe import type { IosTargetActivation, PostGestureOutcome } from '@agent-device/kernel/snapshot'; import { formatPostGestureOutcomeWarning } from '@agent-device/capture-kit/post-gesture-stability'; import { makeSnapshotState } from '@agent-device/selectors/snapshot-geometry-fixtures'; -import { markDeferredInteractionOutcome } from '../../daemon/deferred-interaction-outcome.ts'; -import { makeIosSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { markDeferredInteractionOutcome } from '@agent-device/daemon/testing/deferred-interaction-outcome'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; -import { SessionStore } from '../../daemon/session-store.ts'; -import { handleSnapshotCommands } from '../../daemon/handlers/snapshot.ts'; -import { legacyDispatchCapture } from '../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'; -import { snapshotRuntimeFixture } from '../../daemon/__tests__/snapshot-runtime-fixture.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import { handleSnapshotCommands } from '@agent-device/daemon/testing/handlers/snapshot'; +import { legacyDispatchCapture } from '@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'; +import { snapshotRuntimeFixture } from '@agent-device/daemon/testing/__tests__/snapshot-runtime-fixture'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; -vi.mock('../../daemon/snapshot-interactor-capture.ts', async () => { - const fixture = await import('../../daemon/__tests__/legacy-snapshot-capture-fixture.ts'); +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', async () => { + const fixture = + await import('@agent-device/daemon/testing/__tests__/legacy-snapshot-capture-fixture'); return { captureSnapshotWithInteractor: fixture.captureSnapshotThroughLegacyDispatchFixture }; }); diff --git a/src/__tests__/daemon-composition/sparse-fallback-screenshot.test.ts b/src/__tests__/daemon-composition/sparse-fallback-screenshot.test.ts index 7572fde6bb..dba0f71d14 100644 --- a/src/__tests__/daemon-composition/sparse-fallback-screenshot.test.ts +++ b/src/__tests__/daemon-composition/sparse-fallback-screenshot.test.ts @@ -2,18 +2,18 @@ import { composedPlatformServicesFixture } from './platform-services-fixture.ts' import path from 'node:path'; import { expect, test } from 'vitest'; import type { SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; -import { makeIosSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { mkdtempForTest } from '@agent-device/test-kit/tmp-dir'; -import { SessionStore } from '../../daemon/session-store.ts'; -import { dispatchSnapshotViaRuntime } from '../../daemon/snapshot-runtime.ts'; -import type { DownloadableArtifactRegistration } from '../../daemon/artifact-tracking.ts'; -import { finalizeDaemonResponse } from '../../daemon/request-finalization.ts'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import { dispatchSnapshotViaRuntime } from '@agent-device/daemon/testing/snapshot-runtime'; +import type { DownloadableArtifactRegistration } from '@agent-device/daemon/testing/artifact-tracking'; +import { finalizeDaemonResponse } from '@agent-device/daemon/testing/request-finalization'; import { screenshotRuntimeFixture, writeSolidPng, type ScreenshotRuntimeFixture, type ScreenshotRuntimeFixtureOptions, -} from '../../daemon/__tests__/screenshot-runtime-fixture.ts'; +} from '@agent-device/daemon/testing/__tests__/screenshot-runtime-fixture'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; const SPARSE: SnapshotQualityVerdict = { diff --git a/src/__tests__/daemon-composition/wait-runtime.test.ts b/src/__tests__/daemon-composition/wait-runtime.test.ts index d79b494f67..02e006972a 100644 --- a/src/__tests__/daemon-composition/wait-runtime.test.ts +++ b/src/__tests__/daemon-composition/wait-runtime.test.ts @@ -21,17 +21,17 @@ import { snapshotRuntimeOperationFacts, } from '@agent-device/contracts/snapshot-runtime'; import { deviceShape, type DeviceInfo } from '@agent-device/kernel/device'; -import { makeSession } from '../../daemon/__tests__/support/session-factories.ts'; -import { makeSessionStore } from '../../daemon/__tests__/support/store-factory.ts'; +import { makeSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { unavailableDeploymentSnapshotAndShutdownOperationFacts } from '@agent-device/test-kit/runtime-operation-facts'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts, -} from '../../daemon/request-runtime-binding.ts'; -import { handleSnapshotCommands } from '../../daemon/handlers/snapshot.ts'; -import { resolveBoundSelectorCapture } from '../../daemon/selector-capture-binding.ts'; -import { dispatchGetViaRuntime } from '../../daemon/selector-runtime.ts'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; +} from '@agent-device/daemon/testing/request-runtime-binding'; +import { handleSnapshotCommands } from '@agent-device/daemon/testing/handlers/snapshot'; +import { resolveBoundSelectorCapture } from '@agent-device/daemon/testing/selector-capture-binding'; +import { dispatchGetViaRuntime } from '@agent-device/daemon/testing/selector-runtime'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { testCreateCommandSurface } from './command-surface-fixture.ts'; const webDevice = { diff --git a/src/__tests__/daemon-entrypoint.test.ts b/src/__tests__/daemon-entrypoint.test.ts index c656cdc1f4..5da1ba2721 100644 --- a/src/__tests__/daemon-entrypoint.test.ts +++ b/src/__tests__/daemon-entrypoint.test.ts @@ -7,11 +7,11 @@ import path from 'node:path'; import { test } from 'vitest'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; import { startDaemonRuntimeFixture } from './daemon-composition/daemon-runtime-fixture.ts'; -import type { DaemonRuntimeController } from '../daemon/server/daemon-runtime.ts'; +import type { DaemonRuntimeController } from '@agent-device/daemon/server/daemon-runtime'; import { cleanupDownloadableArtifact, trackDownloadableArtifact, -} from '../daemon/artifact-tracking.ts'; +} from '@agent-device/daemon/testing/artifact-tracking'; import { runCmdBackground } from '@agent-device/host-kit/command'; import { createOwnedProcessRecordStore, diff --git a/src/__tests__/daemon-proxy.test.ts b/src/__tests__/daemon-proxy.test.ts index dca0f0e6df..5410d77b04 100644 --- a/src/__tests__/daemon-proxy.test.ts +++ b/src/__tests__/daemon-proxy.test.ts @@ -3,7 +3,7 @@ import assert from 'node:assert/strict'; import crypto from 'node:crypto'; import http from 'node:http'; import { createDaemonProxyServer } from '@agent-device/proxy'; -import { createDaemonHttpServer } from '../daemon/server/http-server.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { getRequestSignal } from '@agent-device/host-kit/request'; import { readHostCpuArch } from '@agent-device/host-kit/process'; import { executeRunScriptHttpRequest } from '@agent-device/maestro/run-script-http'; diff --git a/src/__tests__/daemon-registration-owner.test.ts b/src/__tests__/daemon-registration-owner.test.ts index b3b792cb24..fed23def09 100644 --- a/src/__tests__/daemon-registration-owner.test.ts +++ b/src/__tests__/daemon-registration-owner.test.ts @@ -32,7 +32,7 @@ import { inspectProcessLock } from '@agent-device/host-kit/file'; import { AppError } from '@agent-device/kernel/errors'; import { sleep } from '@agent-device/host-kit/retry'; import { stopDaemonProcess } from '@agent-device/daemon-contracts/daemon-process'; -import { stopDaemon } from '../daemon/daemon-stop.ts'; +import { stopDaemon } from '@agent-device/daemon/daemon-stop'; const fields = { socketPort: 4210, diff --git a/src/__tests__/kernel/errors-code-policy.test.ts b/src/__tests__/kernel/errors-code-policy.test.ts index 4845dd0295..e7ef9d42d4 100644 --- a/src/__tests__/kernel/errors-code-policy.test.ts +++ b/src/__tests__/kernel/errors-code-policy.test.ts @@ -42,7 +42,7 @@ test('AppError leaves details and cause undefined when the constructor omits the // --- asAppError: identity, wrapping, and duck-typing contract --- // // Every catch site that normalizes a thrown value (src/cli.ts, src/daemon.ts, -// src/daemon/server/daemon-runtime.ts, the platform runners) funnels through +// packages/daemon/src/server/daemon-runtime.ts, the platform runners) funnels through // `asAppError`, so its branch selection is load-bearing: get it wrong and a // caller silently loses a real error's message/stack. diff --git a/src/__tests__/kernel/errors-metadata.test.ts b/src/__tests__/kernel/errors-metadata.test.ts index c6702e483b..6c3aff3ecb 100644 --- a/src/__tests__/kernel/errors-metadata.test.ts +++ b/src/__tests__/kernel/errors-metadata.test.ts @@ -129,7 +129,7 @@ test('normalizeError omits details entirely once stripping diagnostic-meta keys }); // --- Cross-cutting contract: normalizeError composes retriableForErrorCode and -// defaultHintForCode exactly the way src/daemon/request-router.ts's +// defaultHintForCode exactly the way packages/daemon/src/request-router.ts's // enrichDaemonError (`error.retriable ?? retriableForErrorCode(error.code)`) // and the CLI's printHumanError expect, for every registered code. Per-code // hint/retriability policy itself is pinned in errors-code-policy.test.ts. --- diff --git a/src/__tests__/lease-provider-profile-fields.test.ts b/src/__tests__/lease-provider-profile-fields.test.ts index 67c3e09ea0..93877912d0 100644 --- a/src/__tests__/lease-provider-profile-fields.test.ts +++ b/src/__tests__/lease-provider-profile-fields.test.ts @@ -10,8 +10,8 @@ import { } from '@agent-device/kernel/contracts'; import { LimrunRuntime } from '../sdk/limrun.ts'; import { createAgentDeviceClient } from '../agent-device-client.ts'; -import { handleLeaseCommands } from '../daemon/handlers/lease.ts'; -import { LeaseRegistry } from '../daemon/lease-registry.ts'; +import { handleLeaseCommands } from '@agent-device/daemon/testing/handlers/lease'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; import { createProviderDeviceRuntimeRequestProviders } from '../provider-device-runtime.ts'; import { hashRemoteConfigFile, @@ -20,7 +20,7 @@ import { import { createTransport } from './client-transport-fixture.ts'; import { runCliCapture } from './cli-capture.ts'; import { makeTempWorkspace } from './cli-config-fixtures.ts'; -import { makeSessionStore } from '../daemon/__tests__/support/store-factory.ts'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; const limrunInstances = vi.hoisted(() => ({ iosCreate: vi.fn(async () => { diff --git a/src/__tests__/limrun-runtime.test.ts b/src/__tests__/limrun-runtime.test.ts index f33ab96e4b..a125382405 100644 --- a/src/__tests__/limrun-runtime.test.ts +++ b/src/__tests__/limrun-runtime.test.ts @@ -5,7 +5,7 @@ import { afterEach, test, vi } from 'vitest'; import { createInstanceClient as createAndroidInstanceClient } from '@limrun/api/instance-client'; import { createInstanceClient as createIosInstanceClient } from '@limrun/api/ios-client'; import { LimrunRuntime } from '../sdk/limrun.ts'; -import { createExpiredProviderLeaseReleaser } from '../daemon/provider-lease-expiry.ts'; +import { createExpiredProviderLeaseReleaser } from '@agent-device/daemon/testing/provider-lease-expiry'; import type { DeviceLease } from '@agent-device/contracts/device'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/__tests__/platform-runtime-runtime-hints.test.ts b/src/__tests__/platform-runtime-runtime-hints.test.ts index b0d9de7a60..eef4bc3083 100644 --- a/src/__tests__/platform-runtime-runtime-hints.test.ts +++ b/src/__tests__/platform-runtime-runtime-hints.test.ts @@ -6,7 +6,10 @@ import { applyRuntimeHintValues, clearRuntimeHintValues, } from '../platform-runtime-runtime-hints.ts'; -import { applyDeviceDefaultMetroHost, runtimeHintValues } from '../daemon/session-runtime.ts'; +import { + applyDeviceDefaultMetroHost, + runtimeHintValues, +} from '@agent-device/daemon/testing/session-runtime'; import { resolveRuntimeTransportHints } from '@agent-device/host-kit/runtime-transport-hints'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { diff --git a/src/__tests__/remote-connection-harmonyos.test.ts b/src/__tests__/remote-connection-harmonyos.test.ts index 3ecfc8e8bb..3c0f811458 100644 --- a/src/__tests__/remote-connection-harmonyos.test.ts +++ b/src/__tests__/remote-connection-harmonyos.test.ts @@ -12,7 +12,7 @@ import { } from '../cli/commands/connection-runtime.ts'; import { disconnectCommand } from '../cli/commands/connection.ts'; import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; -import { LeaseRegistry } from '../daemon/lease-registry.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; test('HarmonyOS platform resolves to its proxy lease backend', () => { expect( diff --git a/src/__tests__/remote-connection-macos-app.test.ts b/src/__tests__/remote-connection-macos-app.test.ts index 4f235d1d8d..8f08910ade 100644 --- a/src/__tests__/remote-connection-macos-app.test.ts +++ b/src/__tests__/remote-connection-macos-app.test.ts @@ -7,7 +7,7 @@ import { connectCommand, disconnectCommand } from '../cli/commands/connection.ts import { materializeRemoteConnectionForCommand } from '../cli/commands/connection-runtime.ts'; import { beginStdoutCapture } from './test-utils/stream-capture.ts'; import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; -import { LeaseRegistry } from '../daemon/lease-registry.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; const LEASE_ID = 'a1b2c3d4e5f60718293a4b5c6d7e8f90'; diff --git a/src/__tests__/takeover-command.test.ts b/src/__tests__/takeover-command.test.ts index b52830a176..717442517f 100644 --- a/src/__tests__/takeover-command.test.ts +++ b/src/__tests__/takeover-command.test.ts @@ -9,7 +9,7 @@ import { import { HUMAN_CONTROL_HOLD, createControlLatch, -} from '../daemon/__tests__/human-control-fixtures.ts'; +} from '@agent-device/daemon/testing/__tests__/human-control-fixtures'; import type { DaemonRequest } from '@agent-device/kernel/contracts'; import { TAKEOVER_CLI_FLAGS } from './test-utils/client-lease-fixtures.ts'; diff --git a/src/cli.ts b/src/cli.ts index 3fb705fe68..3dfb3fc23d 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -7,7 +7,7 @@ import { throwDaemonError, type NormalizedError, } from '@agent-device/kernel/errors'; -import { resolveRemoteRequestDiagnosticsPath } from './daemon/session-artifact-paths.ts'; +import { resolveRemoteRequestDiagnosticsPath } from '@agent-device/daemon/session-artifact-paths'; import { exitAfterFlush } from './cli/process-exit.ts'; import { readVersion } from '@agent-device/host-kit/version'; import { pathToFileURL } from 'node:url'; diff --git a/src/cli/__tests__/command-explain.test.ts b/src/cli/__tests__/command-explain.test.ts index 408c910412..0d7ff8b76e 100644 --- a/src/cli/__tests__/command-explain.test.ts +++ b/src/cli/__tests__/command-explain.test.ts @@ -5,7 +5,7 @@ import { describe, expect, test } from 'vitest'; import { runExplainCommandCli } from '../../../scripts/explain-command.ts'; import { commandDescriptors } from '@agent-device/command-registry/registry'; import { ownerFilesForCommand } from '@agent-device/command-registry/owner-files'; -import { getDaemonRouteOwnerFiles } from '../../daemon/route-owner-files.ts'; +import { getDaemonRouteOwnerFiles } from '@agent-device/daemon/route-owner-files'; import { explainCommand as explainCommandFromMetadata, formatCommandExplanation, @@ -80,7 +80,7 @@ describe('explainCommand', () => { if (!result.found) return; expect(result.explanation.cli?.commandFlags.map((flag) => flag.key)).toContain('settle'); expect(result.explanation.files).toContain('src/commands/interaction/index.ts'); - expect(result.explanation.files).toContain('src/daemon/interaction/index.ts'); + expect(result.explanation.files).toContain('packages/daemon/src/interaction/index.ts'); expect(result.explanation.files.every(fileExists)).toBe(true); }); @@ -146,15 +146,18 @@ describe('explainCommand table-driven coverage', () => { }); test.each([ - ['press', ['src/commands/interaction/index.ts', 'src/daemon/interaction/index.ts']], + ['press', ['src/commands/interaction/index.ts', 'packages/daemon/src/interaction/index.ts']], ['apps', ['src/commands/management/app.ts']], // R39: screenshot has no dispatch projection left, so its platform work is named directly. - ['screenshot', ['src/commands/capture/screenshot.ts', 'src/daemon/screenshot-runtime.ts']], - ['react-native', ['src/daemon/handlers/react-native.ts']], - ['record', ['src/daemon/handlers/record-trace.ts']], - ['trace', ['src/daemon/handlers/record-trace.ts']], - ['back', ['src/daemon/request-generic-dispatch.ts']], - ['home', ['src/daemon/request-generic-dispatch.ts']], + [ + 'screenshot', + ['src/commands/capture/screenshot.ts', 'packages/daemon/src/screenshot-runtime.ts'], + ], + ['react-native', ['packages/daemon/src/handlers/react-native.ts']], + ['record', ['packages/daemon/src/handlers/record-trace.ts']], + ['trace', ['packages/daemon/src/handlers/record-trace.ts']], + ['back', ['packages/daemon/src/request-generic-dispatch.ts']], + ['home', ['packages/daemon/src/request-generic-dispatch.ts']], ])('derives owner files for %s (split family / route variant / dispatch)', (command, owners) => { const result = explainCommand(command as string, { fileExists }); expect(result.found).toBe(true); diff --git a/src/cli/command-explain.ts b/src/cli/command-explain.ts index a22cb9338b..569ba29a8a 100644 --- a/src/cli/command-explain.ts +++ b/src/cli/command-explain.ts @@ -4,7 +4,7 @@ import { normalizeCliCommandAlias, } from '@agent-device/command-registry/cli-command-aliases'; import { buildCommandUsage } from '../commands/schema/usage.ts'; -import type { DaemonCommandRoute } from '../daemon/daemon-command-registry.ts'; +import type { DaemonCommandRoute } from '@agent-device/daemon/daemon-command-registry'; import { commandDescriptors, type Command } from '@agent-device/command-registry/registry'; import { ownerFilesForCommand } from '@agent-device/command-registry/owner-files'; import type { CommandTimeoutPolicy } from '@agent-device/command-registry/types'; diff --git a/src/cli/commands/__tests__/daemon.test.ts b/src/cli/commands/__tests__/daemon.test.ts index c7a2de231d..0de3ad7158 100644 --- a/src/cli/commands/__tests__/daemon.test.ts +++ b/src/cli/commands/__tests__/daemon.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import { afterEach, expect, test, vi } from 'vitest'; -import type { DaemonStopResult } from '../../../daemon/daemon-stop.ts'; +import type { DaemonStopResult } from '@agent-device/daemon/daemon-stop'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; const mocks = vi.hoisted(() => ({ @@ -12,7 +12,10 @@ const mocks = vi.hoisted(() => ({ writeCommandOutput: vi.fn(), })); -vi.mock('../../../daemon/daemon-stop.ts', () => ({ +// The mock specifier must be the SUT's exact `@agent-device/daemon/daemon-stop`: the +// mutation lane aliases only the manifest's exact entries, so the `./testing/*` pattern +// form resolved outside the Stryker sandbox and the mock silently missed (#3546 CI). +vi.mock('@agent-device/daemon/daemon-stop', () => ({ readDaemonStopIdentity: mocks.readDaemonStopIdentity, stopDaemon: mocks.stopDaemon, })); diff --git a/src/cli/commands/daemon.ts b/src/cli/commands/daemon.ts index fd9c1d301f..c8fa927af0 100644 --- a/src/cli/commands/daemon.ts +++ b/src/cli/commands/daemon.ts @@ -3,7 +3,7 @@ import { readDaemonStopIdentity, stopDaemon, type DaemonStopResult, -} from '../../daemon/daemon-stop.ts'; +} from '@agent-device/daemon/daemon-stop'; import { readDaemonShutdownReport } from '@agent-device/daemon-contracts/daemon-shutdown-report'; import { AppError } from '@agent-device/kernel/errors'; import { writeCommandOutput } from './shared.ts'; diff --git a/src/cli/commands/device-release.ts b/src/cli/commands/device-release.ts index 2efc5fd702..5259ea26d1 100644 --- a/src/cli/commands/device-release.ts +++ b/src/cli/commands/device-release.ts @@ -1,14 +1,14 @@ import { createOwnerScopedDeviceClaimReconciler, type OwnerScopedClaimRecoveryComposer, -} from '../../daemon/device/device-claim-owner-recovery.ts'; +} from '@agent-device/daemon/device/device-claim-owner-recovery'; import { createClaimRecoveryGateway } from '../../platform-runtime-claim-recovery.ts'; -import { createDaemonRecoveryPlatformScope } from '../../daemon/platform-request-scope.ts'; +import { createDaemonRecoveryPlatformScope } from '@agent-device/daemon/platform-request-scope'; import { releaseProvenStaleDeviceClaims, type DeviceClaimStaleReleaseOutcome, -} from '../../daemon/device/device-claims.ts'; -import type { DeviceClaimSelectors } from '../../daemon/device/device-claim-inspection.ts'; +} from '@agent-device/daemon/device/device-claims'; +import type { DeviceClaimSelectors } from '@agent-device/daemon/device/device-claim-inspection'; /** * Daemonless `device release --stale`: settles each provably dead owner diff --git a/src/cli/commands/device.ts b/src/cli/commands/device.ts index 2381c75721..de6c307eaf 100644 --- a/src/cli/commands/device.ts +++ b/src/cli/commands/device.ts @@ -5,8 +5,8 @@ import { deviceClaimRequiresStaleInspection, inspectDeviceClaims, type InspectedDeviceClaim, -} from '../../daemon/device/device-claim-inspection.ts'; -import type { DeviceClaimStaleReleaseOutcome } from '../../daemon/device/device-claims.ts'; +} from '@agent-device/daemon/device/device-claim-inspection'; +import type { DeviceClaimStaleReleaseOutcome } from '@agent-device/daemon/device/device-claims'; import { shellQuoteIfNeeded } from '@agent-device/kernel/device-shell'; import { writeCommandOutput } from './shared.ts'; import type { CliFlags } from '@agent-device/contracts/command'; diff --git a/src/cli/replay-test/__tests__/session-test-reporter-values-maestro.test.ts b/src/cli/replay-test/__tests__/session-test-reporter-values-maestro.test.ts index b178ada491..b45523f2e6 100644 --- a/src/cli/replay-test/__tests__/session-test-reporter-values-maestro.test.ts +++ b/src/cli/replay-test/__tests__/session-test-reporter-values-maestro.test.ts @@ -1,4 +1,4 @@ -import { daemonPlatformServicesFixture } from '../../../daemon/__tests__/platform-services-fixture.ts'; +import { daemonPlatformServicesFixture } from '@agent-device/daemon/testing/__tests__/platform-services-fixture'; // Characterization of the shipped reporter contract for the MAESTRO adapter (#1478 P3). // // The sibling session-test-reporter-values.test.ts covers the same contract for native `.ad`. @@ -41,9 +41,9 @@ import fs from 'node:fs'; import path from 'node:path'; import type { ReplaySuiteResult } from '@agent-device/contracts/replay'; -import { handleSessionCommands } from '../../../daemon/handlers/__tests__/session-command-harness.ts'; -import { SessionStore } from '../../../daemon/session-store.ts'; -import type { DaemonRequest, DaemonResponse } from '../../../daemon/daemon-request.ts'; +import { handleSessionCommands } from '@agent-device/daemon/testing/handlers/__tests__/session-command-harness'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { withRequestProgressSink } from '@agent-device/host-kit/request'; import { getReplayTestReporterExitCode, diff --git a/src/cli/replay-test/__tests__/session-test-reporter-values.test.ts b/src/cli/replay-test/__tests__/session-test-reporter-values.test.ts index 02b2d2ca17..4713fbd261 100644 --- a/src/cli/replay-test/__tests__/session-test-reporter-values.test.ts +++ b/src/cli/replay-test/__tests__/session-test-reporter-values.test.ts @@ -1,4 +1,4 @@ -import { daemonPlatformServicesFixture } from '../../../daemon/__tests__/platform-services-fixture.ts'; +import { daemonPlatformServicesFixture } from '@agent-device/daemon/testing/__tests__/platform-services-fixture'; // Characterization of the shipped reporter contract across the scheduler seam (#1478 P3). // // P3 moves the scheduler into `packages/replay-test` and makes attempt identity @@ -14,7 +14,7 @@ import { daemonPlatformServicesFixture } from '../../../daemon/__tests__/platfor import { expect, test, vi } from 'vitest'; import { testCreateCommandSurface } from '../../../__tests__/daemon-composition/command-surface-fixture.ts'; -vi.mock('../../../daemon/snapshot-interactor-capture.ts', () => ({ +vi.mock('@agent-device/daemon/testing/snapshot-interactor-capture', () => ({ captureSnapshotWithInteractor: vi.fn(async () => { throw new Error('no device runner available in this test'); }), @@ -24,9 +24,9 @@ import fs from 'node:fs'; import path from 'node:path'; import type { ReplaySuiteResult } from '@agent-device/contracts/replay'; -import { handleSessionCommands } from '../../../daemon/handlers/__tests__/session-command-harness.ts'; -import { SessionStore } from '../../../daemon/session-store.ts'; -import type { DaemonRequest, DaemonResponse } from '../../../daemon/daemon-request.ts'; +import { handleSessionCommands } from '@agent-device/daemon/testing/handlers/__tests__/session-command-harness'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { withRequestProgressSink } from '@agent-device/host-kit/request'; import { withTestDeviceInventoryProvider as withDeviceInventoryProvider } from '@agent-device/device-selection/inventory-gateways-fixtures'; import type { DeviceInfo } from '@agent-device/kernel/device'; diff --git a/src/client/client-normalizers.ts b/src/client/client-normalizers.ts index ccd0a3d29c..73edc29077 100644 --- a/src/client/client-normalizers.ts +++ b/src/client/client-normalizers.ts @@ -25,7 +25,7 @@ import { leaseScopeFromOptions, leaseScopeToRequestMeta, } from '@agent-device/contracts/lease-scope'; -import type { DaemonRequest } from '../daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { asRecord, isRecord, diff --git a/src/client/lease-client.test.ts b/src/client/lease-client.test.ts index 3738bdb0ae..5ba5fff9ea 100644 --- a/src/client/lease-client.test.ts +++ b/src/client/lease-client.test.ts @@ -5,7 +5,7 @@ import { createAgentDeviceClient } from '../agent-device-client.ts'; import { HUMAN_CONTROL_HOLD, HUMAN_CONTROL_SCOPE, -} from '../daemon/__tests__/human-control-fixtures.ts'; +} from '@agent-device/daemon/testing/__tests__/human-control-fixtures'; import type { DaemonRequest } from '@agent-device/kernel/contracts'; test('human-control client carries normal remote authentication and full lease metadata', async () => { diff --git a/src/commands/__tests__/command-surface-metadata.test.ts b/src/commands/__tests__/command-surface-metadata.test.ts index 3f250e558b..4784c99cdc 100644 --- a/src/commands/__tests__/command-surface-metadata.test.ts +++ b/src/commands/__tests__/command-surface-metadata.test.ts @@ -22,7 +22,7 @@ import { import { listExecutableCommandNames } from '../command-surface.ts'; import { helpBody, mcpBody } from '@agent-device/command-registry/command-text'; import { explainCommand } from '../../cli/command-explain.ts'; -import { getDaemonRouteOwnerFiles } from '../../daemon/route-owner-files.ts'; +import { getDaemonRouteOwnerFiles } from '@agent-device/daemon/route-owner-files'; test('MCP exposed command names have metadata and executable command definitions', () => { const mcpExposedNames = listMcpExposedCommandNames().sort(); diff --git a/src/commands/cli-grammar/flag-declaration-admission.test.ts b/src/commands/cli-grammar/flag-declaration-admission.test.ts index 55912e3f15..7ad93591de 100644 --- a/src/commands/cli-grammar/flag-declaration-admission.test.ts +++ b/src/commands/cli-grammar/flag-declaration-admission.test.ts @@ -6,8 +6,8 @@ import type { CliFlags } from '@agent-device/contracts/command'; import { getFlagDefinitionsForKey } from '@agent-device/command-registry/flag-registry'; import type { FlagDefinition } from '@agent-device/command-registry/flag-types'; import { resolveConfigBackedFlagDefaults } from '../schema/cli-config.ts'; -import { recordActionEntry } from '../../daemon/session-action-recorder.ts'; -import { makeIosSession } from '../../daemon/__tests__/support/session-factories.ts'; +import { recordActionEntry } from '@agent-device/daemon/testing/session-action-recorder'; +import { makeIosSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { makeTempWorkspace } from '../../__tests__/cli-config-fixtures.ts'; /** @@ -99,7 +99,7 @@ test('recorder sanitization follows the declaration: an undeclared key is droppe const planted = getInRegistry(registry, 'overlayRefs'); Object.assign(planted, { recorded: true }); const { recordActionEntry: recordPlanted } = - await import('../../daemon/session-action-recorder.ts'); + await import('@agent-device/daemon/testing/session-action-recorder'); const recorded = recordPlanted(makeIosSession('default'), { command: 'screenshot', positionals: [], diff --git a/src/commands/interaction/runtime/offscreen-double-check.test.ts b/src/commands/interaction/runtime/offscreen-double-check.test.ts index 8eac66fb29..1dee9edd1a 100644 --- a/src/commands/interaction/runtime/offscreen-double-check.test.ts +++ b/src/commands/interaction/runtime/offscreen-double-check.test.ts @@ -11,7 +11,7 @@ import { createInteractionDevice } from './__tests__/test-utils/index.ts'; // resolution.test.ts uses (createInteractionDevice), mocking // `confirmOffscreenTargetVisible` directly rather than the local XCTest // runner — the runner-level probe I/O is covered separately in -// src/daemon/__tests__/offscreen-target-probe.test.ts. +// packages/daemon/src/__tests__/offscreen-target-probe.test.ts. // The bulk tree's ScrollView ancestor is corrupted (squeezed to a sliver), // so the target's rect doesn't overlap it — the guard rejects even though diff --git a/src/daemon-client/__tests__/boundary-fault-acceptance.test.ts b/src/daemon-client/__tests__/boundary-fault-acceptance.test.ts index ea65579978..01ef1d94d7 100644 --- a/src/daemon-client/__tests__/boundary-fault-acceptance.test.ts +++ b/src/daemon-client/__tests__/boundary-fault-acceptance.test.ts @@ -6,7 +6,7 @@ import { AppError } from '@agent-device/kernel/errors'; import { assertRejectsAppError } from '@agent-device/test-kit/app-error'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import type { DaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { sendRequest } from '../daemon-client-transport.ts'; type ProcessDeathCommand = 'press' | 'fill' | 'snapshot' | 'screenshot' | 'open' | 'close'; diff --git a/src/daemon-client/__tests__/boundary-fault-transport.test.ts b/src/daemon-client/__tests__/boundary-fault-transport.test.ts index 19518ca95c..a8e266f213 100644 --- a/src/daemon-client/__tests__/boundary-fault-transport.test.ts +++ b/src/daemon-client/__tests__/boundary-fault-transport.test.ts @@ -12,7 +12,7 @@ import { } from '@agent-device/test-kit/loopback'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import type { DaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { sendRequest } from '../daemon-client-transport.ts'; const { mockRunCmdSync } = vi.hoisted(() => ({ mockRunCmdSync: vi.fn() })); diff --git a/src/daemon-client/__tests__/daemon-client-abort-default-transport.test.ts b/src/daemon-client/__tests__/daemon-client-abort-default-transport.test.ts index c0a533cf96..caf8ed643b 100644 --- a/src/daemon-client/__tests__/daemon-client-abort-default-transport.test.ts +++ b/src/daemon-client/__tests__/daemon-client-abort-default-transport.test.ts @@ -22,9 +22,13 @@ import { isRequestCanceledError } from '@agent-device/kernel/errors'; import { getRequestSignal, isRequestCanceled } from '@agent-device/host-kit/request'; import { readProcessStartTime } from '@agent-device/host-kit/process'; import { readVersion } from '@agent-device/host-kit/version'; -import type { DaemonInvokeFn, DaemonRequest, DaemonResponse } from '../../daemon/daemon-request.ts'; -import { createDaemonHttpServer } from '../../daemon/server/http-server.ts'; -import { createSocketServer, listenNetServer } from '../../daemon/server/transport.ts'; +import type { + DaemonInvokeFn, + DaemonRequest, + DaemonResponse, +} from '@agent-device/daemon/daemon-request'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import { createSocketServer, listenNetServer } from '@agent-device/daemon/testing/server/transport'; import { createAgentDeviceClient } from '../../agent-device-client.ts'; import { currentDaemonCodeSignature } from '../../__tests__/test-utils/daemon-http-fixture.ts'; import { diff --git a/src/daemon-client/__tests__/daemon-client-abort-timeout.test.ts b/src/daemon-client/__tests__/daemon-client-abort-timeout.test.ts index 837ea57bc0..cdb98ef8fb 100644 --- a/src/daemon-client/__tests__/daemon-client-abort-timeout.test.ts +++ b/src/daemon-client/__tests__/daemon-client-abort-timeout.test.ts @@ -16,8 +16,12 @@ import { DAEMON_HTTP_INSTANCE_MISMATCH_HEADER } from '@agent-device/contracts/da import { test, vi } from 'vitest'; import { AppError, isRequestCanceledError } from '@agent-device/kernel/errors'; import { getRequestSignal } from '@agent-device/host-kit/request'; -import type { DaemonInvokeFn, DaemonRequest, DaemonResponse } from '../../daemon/daemon-request.ts'; -import { createSocketServer, listenNetServer } from '../../daemon/server/transport.ts'; +import type { + DaemonInvokeFn, + DaemonRequest, + DaemonResponse, +} from '@agent-device/daemon/daemon-request'; +import { createSocketServer, listenNetServer } from '@agent-device/daemon/testing/server/transport'; import { sendRequest } from '../daemon-client-transport.ts'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; import { diff --git a/src/daemon-client/__tests__/daemon-client-abort.test.ts b/src/daemon-client/__tests__/daemon-client-abort.test.ts index 674b3cd004..8cd014e46f 100644 --- a/src/daemon-client/__tests__/daemon-client-abort.test.ts +++ b/src/daemon-client/__tests__/daemon-client-abort.test.ts @@ -12,9 +12,13 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import { isRequestCanceledError } from '@agent-device/kernel/errors'; import { getRequestSignal, isRequestCanceled } from '@agent-device/host-kit/request'; -import type { DaemonInvokeFn, DaemonRequest, DaemonResponse } from '../../daemon/daemon-request.ts'; -import { createDaemonHttpServer } from '../../daemon/server/http-server.ts'; -import { createSocketServer, listenNetServer } from '../../daemon/server/transport.ts'; +import type { + DaemonInvokeFn, + DaemonRequest, + DaemonResponse, +} from '@agent-device/daemon/daemon-request'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import { createSocketServer, listenNetServer } from '@agent-device/daemon/testing/server/transport'; import { sendRequest } from '../daemon-client-transport.ts'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; import { diff --git a/src/daemon-client/__tests__/daemon-client-address-hints.test.ts b/src/daemon-client/__tests__/daemon-client-address-hints.test.ts index 22cd5c004b..0a3b5f8145 100644 --- a/src/daemon-client/__tests__/daemon-client-address-hints.test.ts +++ b/src/daemon-client/__tests__/daemon-client-address-hints.test.ts @@ -1,4 +1,4 @@ -import type { DaemonResponse } from '../../daemon/daemon-request.ts'; +import type { DaemonResponse } from '@agent-device/daemon/daemon-request'; import { shellQuoteIfNeeded } from '@agent-device/kernel/device-shell'; import assert from 'node:assert/strict'; import { test } from 'vitest'; diff --git a/src/daemon-client/__tests__/daemon-client-lease-beat.test.ts b/src/daemon-client/__tests__/daemon-client-lease-beat.test.ts index 73164ed10a..c100855bae 100644 --- a/src/daemon-client/__tests__/daemon-client-lease-beat.test.ts +++ b/src/daemon-client/__tests__/daemon-client-lease-beat.test.ts @@ -10,7 +10,7 @@ import { runProtectedLeaseWork, } from '../daemon-client-lease-beat.ts'; import { leaseScopeFromRequest } from '@agent-device/contracts/lease-scope'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; function lostLeaseError(reason: string): AppError { return new AppError('UNAUTHORIZED', 'Lease is not active', { reason }); diff --git a/src/daemon-client/__tests__/daemon-client-timeout-route.test.ts b/src/daemon-client/__tests__/daemon-client-timeout-route.test.ts index 0b306eb40a..bdd5f6133c 100644 --- a/src/daemon-client/__tests__/daemon-client-timeout-route.test.ts +++ b/src/daemon-client/__tests__/daemon-client-timeout-route.test.ts @@ -38,7 +38,7 @@ vi.mock('@agent-device/host-kit/command', async () => { import { AppError } from '@agent-device/kernel/errors'; import { PUBLIC_COMMANDS } from '@agent-device/command-registry/catalog'; import { sendRequest } from '../daemon-client-transport.ts'; -import type { DaemonRequest } from '../../daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import type { DaemonInfo } from '../daemon-client-metadata.ts'; import type { DaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; diff --git a/src/daemon-client/daemon-client-lease-beat.ts b/src/daemon-client/daemon-client-lease-beat.ts index dcce3011e5..d000720491 100644 --- a/src/daemon-client/daemon-client-lease-beat.ts +++ b/src/daemon-client/daemon-client-lease-beat.ts @@ -1,4 +1,4 @@ -import type { DaemonRequest } from '../daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { AppError } from '@agent-device/kernel/errors'; import { createRequestId, emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { INTERNAL_COMMANDS } from '@agent-device/command-registry/catalog'; diff --git a/src/daemon-client/daemon-client-lifecycle.ts b/src/daemon-client/daemon-client-lifecycle.ts index 002e3e09da..8af7232888 100644 --- a/src/daemon-client/daemon-client-lifecycle.ts +++ b/src/daemon-client/daemon-client-lifecycle.ts @@ -4,7 +4,7 @@ import { processLockHoldsDaemonIdentity } from '@agent-device/daemon-contracts/d import net from 'node:net'; import { AppError, normalizeError, type NormalizedError } from '@agent-device/kernel/errors'; import { readReplayDivergenceResume } from '@agent-device/ad-replay/divergence'; -import type { DaemonRequest, DaemonResponse } from '../daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { type ExecDetachedExit } from '@agent-device/host-kit/command'; import { shellQuoteIfNeeded } from '@agent-device/kernel/device-shell'; import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; diff --git a/src/daemon-client/daemon-client-liveness-probe.ts b/src/daemon-client/daemon-client-liveness-probe.ts index 66a3605ece..ac12e1e9e1 100644 --- a/src/daemon-client/daemon-client-liveness-probe.ts +++ b/src/daemon-client/daemon-client-liveness-probe.ts @@ -2,7 +2,7 @@ import net from 'node:net'; import { INTERNAL_COMMANDS } from '@agent-device/command-registry/catalog'; import { createRequestId } from '@agent-device/host-kit/diagnostics'; import { loadNodeHttpRequester, consumeTextLines } from '@agent-device/host-kit/transport'; -import type { DaemonRequest } from '../daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import type { DaemonInfo } from './daemon-client-metadata.ts'; // The post-timeout liveness probe (#3177): the question a daemon reset may no longer assume. The diff --git a/src/daemon-client/daemon-client-progress.ts b/src/daemon-client/daemon-client-progress.ts index 1e15ab9b2a..016b255281 100644 --- a/src/daemon-client/daemon-client-progress.ts +++ b/src/daemon-client/daemon-client-progress.ts @@ -4,7 +4,7 @@ import type { RequestProgressSink } from '@agent-device/contracts/progress'; import type http from 'node:http'; import type { Socket } from 'node:net'; import { AppError } from '@agent-device/kernel/errors'; -import type { DaemonRequest, DaemonResponse } from '../daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { consumeTextLines } from '@agent-device/host-kit/transport'; import { isDaemonProgressEnvelope, diff --git a/src/daemon-client/daemon-client-rpc.ts b/src/daemon-client/daemon-client-rpc.ts index 8da929e319..b6b0698a76 100644 --- a/src/daemon-client/daemon-client-rpc.ts +++ b/src/daemon-client/daemon-client-rpc.ts @@ -6,7 +6,7 @@ import { } from '@agent-device/kernel/errors'; import { sanitizeErrorCause } from '@agent-device/kernel/redaction'; import { createRequestId } from '@agent-device/host-kit/diagnostics'; -import type { DaemonRequest, DaemonResponse } from '../daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { materializeRemoteArtifacts } from '../remote/daemon-artifacts.ts'; import { localizeRemoteDaemonError } from '../remote/remote-request-diagnostics.ts'; import type { DaemonInfo } from './daemon-client-metadata.ts'; diff --git a/src/daemon-client/daemon-client-transport.ts b/src/daemon-client/daemon-client-transport.ts index f291b3e118..26bf8695ac 100644 --- a/src/daemon-client/daemon-client-transport.ts +++ b/src/daemon-client/daemon-client-transport.ts @@ -2,7 +2,7 @@ import type { RequestProgressSink } from '@agent-device/contracts/progress'; import net from 'node:net'; import { AppError, createRequestCanceledError } from '@agent-device/kernel/errors'; import { loadNodeHttpRequester, readNodeHttpResponseBody } from '@agent-device/host-kit/transport'; -import type { DaemonRequest, DaemonResponse } from '../daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { DaemonPaths, diff --git a/src/daemon-client/daemon-client.ts b/src/daemon-client/daemon-client.ts index 5285b8f52c..6c8aa52418 100644 --- a/src/daemon-client/daemon-client.ts +++ b/src/daemon-client/daemon-client.ts @@ -2,7 +2,7 @@ import type { RequestProgressSink } from '@agent-device/contracts/progress'; import type { DaemonRequest as SharedDaemonRequest, DaemonResponse as SharedDaemonResponse, -} from '../daemon/daemon-request.ts'; +} from '@agent-device/daemon/daemon-request'; import type { AgentDeviceDaemonTransportContext } from '@agent-device/contracts/client'; import { AppError } from '@agent-device/kernel/errors'; import { diff --git a/src/daemon-composition.ts b/src/daemon-composition.ts index 41f0c1a13a..c8ced064f0 100644 --- a/src/daemon-composition.ts +++ b/src/daemon-composition.ts @@ -1,4 +1,4 @@ -// The daemon runtime's dependency construction, extracted from `src/daemon/server/daemon-runtime.ts` +// The daemon runtime's dependency construction, extracted from `packages/daemon/src/server/daemon-runtime.ts` // so the operational server owns sequencing and this module owns naming runtimes (ADR 0019). // Everything here that names a platform runtime, a provider runtime, an interactor, host // diagnostics, credential fingerprinting, resource cleanup, the platform lifecycle owners, the @@ -10,7 +10,7 @@ // entry reaches this module through a function-scoped `await import`, so the daemon entry's eager // closure does not grow; the platform-services and claim-recovery // compositions stay behind function-scoped `await import`, and the command surface loads on first -// request use. Nothing here value-imports `src/daemon/`: the daemon's session data enters through +// request use. Nothing here value-imports `packages/daemon/src/`: the daemon's session data enters through // plain callbacks, so the platform-runtime zone keeps its value-free direction toward the daemon. import { @@ -42,7 +42,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { ComposeDaemonRuntimeDeps, DaemonRuntimeDeps, -} from './daemon/server/daemon-runtime.ts'; +} from '@agent-device/daemon/server/daemon-runtime'; /** * Best-effort startup cleanup of managed-agent-browser orphans left by a previous daemon. It runs diff --git a/src/daemon.ts b/src/daemon.ts index d331ae5d49..c7ca9eef94 100644 --- a/src/daemon.ts +++ b/src/daemon.ts @@ -1,5 +1,5 @@ import { asAppError } from '@agent-device/kernel/errors'; -import { startDaemonRuntime } from './daemon/server/daemon-runtime.ts'; +import { startDaemonRuntime } from '@agent-device/daemon/server/daemon-runtime'; // The root's composition enters as a factory behind a function-scoped `await import`: the server // calls it before it acquires the registration, so startup order is unchanged, and the eager diff --git a/src/platform-runtime-app-log-output.ts b/src/platform-runtime-app-log-output.ts index 0befd67ebf..1c8845211e 100644 --- a/src/platform-runtime-app-log-output.ts +++ b/src/platform-runtime-app-log-output.ts @@ -1,8 +1,8 @@ import type { AppLogOutputSink } from '@agent-device/contracts/app-log-runtime'; import fs from 'node:fs'; import { openVerifiedFileForAppend, openVerifiedFileForRead } from '@agent-device/host-kit/file'; -import { ensureAppLogPath } from './daemon/app-log-files.ts'; -import { requireManagedSessionArtifactPath } from './daemon/managed-session-artifact-path.ts'; +import { ensureAppLogPath } from '@agent-device/daemon/app-log-files'; +import { requireManagedSessionArtifactPath } from '@agent-device/daemon/managed-session-artifact-path'; export async function openAppLogOutput( sessionsDir: string, diff --git a/src/platform-runtime-app-log-process.ts b/src/platform-runtime-app-log-process.ts index 9c1a326630..508e65aff3 100644 --- a/src/platform-runtime-app-log-process.ts +++ b/src/platform-runtime-app-log-process.ts @@ -23,7 +23,7 @@ import { waitForProcessExit, } from '@agent-device/host-kit/process'; -import { requireManagedSessionArtifactPath } from './daemon/managed-session-artifact-path.ts'; +import { requireManagedSessionArtifactPath } from '@agent-device/daemon/managed-session-artifact-path'; const APP_LOG_PID_FILENAME = 'app-log.pid'; diff --git a/src/platform-runtime-claim-recovery.ts b/src/platform-runtime-claim-recovery.ts index b1f3b53a17..fbda2fe726 100644 --- a/src/platform-runtime-claim-recovery.ts +++ b/src/platform-runtime-claim-recovery.ts @@ -1,5 +1,5 @@ import { createPlatformRuntimeGateway } from './platform-runtime.ts'; -import type { ClaimRecoveryGatewayFactory } from './daemon/device/claim-recovery-gateway.ts'; +import type { ClaimRecoveryGatewayFactory } from '@agent-device/daemon/device/claim-recovery-gateway'; /** * Root composition for owner-scoped claim recovery (ADR 0019 section 1): the daemon owns the diff --git a/src/platform-runtime-daemon-lifecycle.ts b/src/platform-runtime-daemon-lifecycle.ts index 8526e96620..7a6433aef6 100644 --- a/src/platform-runtime-daemon-lifecycle.ts +++ b/src/platform-runtime-daemon-lifecycle.ts @@ -1,4 +1,4 @@ -import type { PlatformOwnerLifecycle } from './daemon/platform-owner-lifecycle.ts'; +import type { PlatformOwnerLifecycle } from '@agent-device/daemon/platform-owner-lifecycle'; import { configureAppleRunnerDeviceClaimAuthorityProbe, configureAppleRunnerLeaseOwnerStateDir, diff --git a/src/platform-runtime-daemon-services.ts b/src/platform-runtime-daemon-services.ts index 916aab5574..ad29bbcee2 100644 --- a/src/platform-runtime-daemon-services.ts +++ b/src/platform-runtime-daemon-services.ts @@ -6,7 +6,7 @@ import { resolveSessionAppBundleIdForTarget, validateOpenRelaunchTarget, } from './platform-runtime-open-target.ts'; -import type { DaemonPlatformServices } from './daemon/platform-services.ts'; +import type { DaemonPlatformServices } from '@agent-device/daemon/platform-services'; /** * Root composition of the daemon's platform-services port (ADR 0019 section 11). Each member is diff --git a/src/platform-runtime-device-inventory.test.ts b/src/platform-runtime-device-inventory.test.ts index 040fc1c51c..28cf1a54b6 100644 --- a/src/platform-runtime-device-inventory.test.ts +++ b/src/platform-runtime-device-inventory.test.ts @@ -16,18 +16,6 @@ const simctl = vi.hoisted(() => ({ calls: [] as string[], })); -vi.mock('../packages/platform-apple/src/core/tool-provider.ts', async (importOriginal) => ({ - ...(await importOriginal()), - runXcrun: async (args: string[]) => { - const idx = args.indexOf('listapps'); - const deviceId = idx >= 0 ? args[idx + 1] : undefined; - if (deviceId) simctl.calls.push(deviceId); - const entry = simctl.listapps.find((l) => l.deviceId === deviceId); - return { stdout: entry ? JSON.stringify(entry.apps) : '{}', stderr: '', exitCode: 0 }; - }, - runAppleToolCommand: async () => ({ stdout: '', stderr: '', exitCode: 1 }), -})); - const scope: PlatformRequestScope = Object.freeze({ signal: new AbortController().signal, diagnostics: Object.freeze({ emit: () => {} }), @@ -71,13 +59,34 @@ describe('production device inventory composition', () => { loadHost: async () => testInventoryHost, }); - const selection = await withDeviceInventoryContext({ ...gateways, requestScope: scope }, () => - resolveTargetDeviceSelection( - { platform: 'ios' }, - { - appleSimulatorAppTarget: 'com.example.demo', + // The fake answers through the production tool-provider scope — the same seam the + // package's own tests install with — so no module mock has to guess which loader + // identity the probe's dynamic import will land on. + const { withAppleToolProvider, createLocalAppleToolProvider } = + await import('@agent-device/platform-apple/tool-provider'); + const selection = await withAppleToolProvider( + createLocalAppleToolProvider({ + runCommand: async () => ({ stdout: '', stderr: '', exitCode: 1 }), + simctl: { + run: async (args) => { + const [command, deviceId] = args as readonly string[]; + if (command !== 'listapps') return { stdout: '{}', stderr: '', exitCode: 0 }; + simctl.calls.push(deviceId!); + const entry = simctl.listapps.find((l) => l.deviceId === deviceId); + return { stdout: entry ? JSON.stringify(entry.apps) : '{}', stderr: '', exitCode: 0 }; + }, }, - ), + devicectl: { run: async () => ({ stdout: '', stderr: '', exitCode: 1 }) }, + }), + () => + withDeviceInventoryContext({ ...gateways, requestScope: scope }, () => + resolveTargetDeviceSelection( + { platform: 'ios' }, + { + appleSimulatorAppTarget: 'com.example.demo', + }, + ), + ), ); expect(selection.device.id).toBe('sim-b'); diff --git a/src/platform-runtime-gateway.test.ts b/src/platform-runtime-gateway.test.ts index 96b1739359..07ef62a04a 100644 --- a/src/platform-runtime-gateway.test.ts +++ b/src/platform-runtime-gateway.test.ts @@ -1,4 +1,4 @@ -import { daemonPlatformServicesFixture } from './daemon/__tests__/platform-services-fixture.ts'; +import { daemonPlatformServicesFixture } from '@agent-device/daemon/testing/__tests__/platform-services-fixture'; import { type DeviceBinding, localRuntimeOwner, @@ -16,10 +16,10 @@ import { viewportRuntimeOperationFacts } from '@agent-device/contracts/viewport- import type { DeviceInfo } from '@agent-device/kernel/device'; import { createLimrunRuntime } from '@agent-device/provider-limrun'; import { describe, expect, test, vi } from 'vitest'; -import { handleAppStateCommand } from './daemon/handlers/session-appstate.ts'; -import { createRequestRuntimeBindings } from './daemon/request-runtime-binding.ts'; -import { createRequestDispatchLedger } from './daemon/request-dispatch-ledger.ts'; -import { makeSessionStore } from './daemon/__tests__/support/store-factory.ts'; +import { handleAppStateCommand } from '@agent-device/daemon/testing/handlers/session-appstate'; +import { createRequestRuntimeBindings } from '@agent-device/daemon/testing/request-runtime-binding'; +import { createRequestDispatchLedger } from '@agent-device/daemon/testing/request-dispatch-ledger'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { withTestDeviceInventory } from '@agent-device/device-selection/inventory-gateways-fixtures'; import { createComposedPlatformRuntimeGateway } from './platform-runtime-gateway.ts'; import { diff --git a/src/platform-runtime-resource-cleanup.ts b/src/platform-runtime-resource-cleanup.ts index 689c02af6e..0a83a827a7 100644 --- a/src/platform-runtime-resource-cleanup.ts +++ b/src/platform-runtime-resource-cleanup.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { isIosFamily } from '@agent-device/kernel/device'; -import type { PlatformResourceCleanup } from './daemon/platform-resource-cleanup.ts'; +import type { PlatformResourceCleanup } from '@agent-device/daemon/platform-resource-cleanup'; import { emitDiagnostic, type ResourceDiagnostic } from '@agent-device/host-kit/diagnostics'; import { type OwnedProcessRecordStore } from '@agent-device/host-kit/process'; import { loadAndroidMechanics } from './platform-runtime-android-mechanics.ts'; diff --git a/src/remote/daemon-artifacts.ts b/src/remote/daemon-artifacts.ts index ad9f0f5fbe..052d359529 100644 --- a/src/remote/daemon-artifacts.ts +++ b/src/remote/daemon-artifacts.ts @@ -5,7 +5,11 @@ import { buildRemoteTempArtifactPath, } from '@agent-device/contracts/daemon-http'; import { AppError } from '@agent-device/kernel/errors'; -import type { DaemonArtifact, DaemonRequest, DaemonResponse } from '../daemon/daemon-request.ts'; +import type { + DaemonArtifact, + DaemonRequest, + DaemonResponse, +} from '@agent-device/daemon/daemon-request'; import { appendRecordingExtensionWhenMissing, recordingExtensionForPlatform, diff --git a/src/remote/remote-request-diagnostics.ts b/src/remote/remote-request-diagnostics.ts index e257b9f89f..6db7802ddf 100644 --- a/src/remote/remote-request-diagnostics.ts +++ b/src/remote/remote-request-diagnostics.ts @@ -26,7 +26,7 @@ import { buildDaemonHttpTenantHeaders, buildDaemonHttpUrl, } from '@agent-device/contracts/daemon-http'; -import { resolveRemoteRequestDiagnosticsPath } from '../daemon/session-artifact-paths.ts'; +import { resolveRemoteRequestDiagnosticsPath } from '@agent-device/daemon/session-artifact-paths'; const REMOTE_DIAGNOSTICS_FETCH_TIMEOUT_MS = 10_000; const REMOTE_DIAGNOSTICS_MAX_BYTES = 8 * 1024 * 1024; diff --git a/stryker.config.json b/stryker.config.json index e019504f93..c59c33c128 100644 --- a/stryker.config.json +++ b/stryker.config.json @@ -34,7 +34,7 @@ }, "mutate": [ "packages/kernel/src/errors.ts", - "src/daemon/ref-frame.ts", + "packages/daemon/src/ref-frame.ts", "src/commands/interaction/runtime/settle.ts", "packages/capture-kit/src/snapshot/scroll-edge-state.ts", "packages/capture-kit/src/snapshot/scroll-edge-state/**/*.ts", diff --git a/test/integration/command-coverage/declarations.ts b/test/integration/command-coverage/declarations.ts index 0e63314d3f..f500eb9406 100644 --- a/test/integration/command-coverage/declarations.ts +++ b/test/integration/command-coverage/declarations.ts @@ -1,5 +1,5 @@ import { PUBLIC_COMMANDS } from '@agent-device/command-registry/catalog'; -import { ANDROID_AUDIO_CONTRACT_EVIDENCE } from '../../../src/daemon/session-observability/__tests__/session-audio.coverage.ts'; +import { ANDROID_AUDIO_CONTRACT_EVIDENCE } from '@agent-device/daemon/testing/session-observability/__tests__/session-audio.coverage'; import { ANDROID_INSTALL_SOURCE_CONTRACT_EVIDENCE } from '../../../src/__tests__/install-source.coverage.ts'; import { ANDROID_LIFECYCLE_CONTRACT_EVIDENCE } from '../provider-scenarios/android-lifecycle.coverage.ts'; import { @@ -53,18 +53,18 @@ const COMMAND_COVERAGE_DECLARATIONS = { 'inventory exposes generated recording and trace artifacts and one download consumes its entry', ), iosSimulator: iosSimulator.contract( - 'src/daemon/__tests__/http-server-artifacts.test.ts', + 'packages/daemon/src/__tests__/http-server-artifacts.test.ts', 'daemon artifact inventory lists artifacts and downloads consume them', 'daemon inventory exposes a typed non-empty artifact and its downloadable bytes', ), macos: macos.contract( - 'src/daemon/__tests__/http-server-artifacts.test.ts', + 'packages/daemon/src/__tests__/http-server-artifacts.test.ts', 'daemon artifact inventory lists artifacts and downloads consume them', 'daemon artifact inventory exposes downloadable files for the macOS session tooling', ), tvos: tvos.gap('No tvOS-specific artifact inventory command evidence exists yet'), web: web.contract( - 'src/daemon/__tests__/request-router-artifacts-web.test.ts', + 'packages/daemon/src/__tests__/request-router-artifacts-web.test.ts', 'artifacts lists a daemon-tracked artifact produced during a web session', 'daemon artifact listing round-trips a tracked artifact for a web-backed session', ), @@ -112,13 +112,13 @@ const COMMAND_COVERAGE_DECLARATIONS = { 'typed capability response includes fixture-driving commands', ), macos: macos.contract( - 'src/daemon/session-lifecycle/internal/__tests__/session-capabilities.test.ts', + 'packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities.test.ts', 'capabilities preserves session-owned appstate for an active %s session', 'the capabilities response projects exact runtime facts plus active macOS session state', ), tvos: tvos.gap('No tvOS-specific capabilities command evidence exists yet'), web: web.contract( - 'src/daemon/session-lifecycle/internal/__tests__/session-capabilities.test.ts', + 'packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities.test.ts', 'capabilities omits apps when $label runtime facts deny the operation', 'web capability projection reflects runtime-owned unsupported operations', ), @@ -159,7 +159,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { ), tvos: tvos.gap('No tvOS-specific app inventory command evidence exists yet'), web: web.contract( - 'src/daemon/session-lifecycle/internal/__tests__/session-capabilities.test.ts', + 'packages/daemon/src/session-lifecycle/internal/__tests__/session-capabilities.test.ts', 'capabilities omits apps when $label runtime facts deny the operation', 'web runtime facts keep native app inventory unavailable', ), @@ -179,7 +179,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { 'shutdown simulator boots again and inventory confirms it', ), macos: macos.contract( - 'src/daemon/handlers/__tests__/session-boot.test.ts', + 'packages/daemon/src/handlers/__tests__/session-boot.test.ts', 'boot rejects the macOS host boot cell after one facts inspection and before binding', 'macOS boot is refused by the runtime fact before dispatch', ), @@ -294,7 +294,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { macos: macos.gap('No command-specific macOS event timeline evidence exists yet'), tvos: tvos.gap('No tvOS-specific session-event command evidence exists yet'), web: web.contract( - 'src/daemon/__tests__/request-router-events.test.ts', + 'packages/daemon/src/__tests__/request-router-events.test.ts', 'events reads the daemon-owned session timeline for a web-backed session', 'the session-owned event timeline works the same for a web-backed session as any other platform', ), @@ -331,12 +331,12 @@ const COMMAND_COVERAGE_DECLARATIONS = { 'host audio probing has an Android-emulator session contract', ), iosSimulator: iosSimulator.contract( - 'src/daemon/session-observability/internal/__tests__/session-audio.test.ts', + 'packages/daemon/src/session-observability/internal/__tests__/session-audio.test.ts', 'audio probe starts host helper for iOS simulator audio', 'host audio permission and probe lifecycle; ScreenCaptureKit is not available on hosted CI', ), macos: macos.contract( - 'src/daemon/session-observability/internal/__tests__/session-audio.test.ts', + 'packages/daemon/src/session-observability/internal/__tests__/session-audio.test.ts', 'audio probe start binds once, adopts the durable handle, and answers from it', 'macOS audio probe starts the ScreenCaptureKit helper and reports its backend', ), @@ -347,7 +347,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { 'host-dependent', ), web: web.contract( - 'src/daemon/session-observability/internal/__tests__/session-audio.test.ts', + 'packages/daemon/src/session-observability/internal/__tests__/session-audio.test.ts', 'audio probe forwards daemon millisecond timing to the web query operation', 'web audio probe forwards typed duration and bucket values', ), @@ -369,7 +369,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { macos: macos.gap('No command-specific macOS replay evidence exists beyond the suite runner'), tvos: tvos.gap('No tvOS-specific replay command evidence exists yet'), web: web.contract( - 'src/daemon/handlers/__tests__/session-command-replay.test.ts', + 'packages/daemon/src/handlers/__tests__/session-command-replay.test.ts', 'replay inherits the parent web platform selector for each invoked step', 'replay re-invokes each recorded step with no platform branch, so a web selector threads through unchanged', ), @@ -614,7 +614,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { macos: macos.gap('No command-specific macOS batch evidence exists yet'), tvos: tvos.gap('No tvOS-specific batch command evidence exists yet'), web: web.contract( - 'src/daemon/session-lifecycle/internal/__tests__/session-devices-batch-runtime.test.ts', + 'packages/daemon/src/session-lifecycle/internal/__tests__/session-devices-batch-runtime.test.ts', 'batch step forwards the parent web platform selector to each invoked step', 'batch re-invokes each step through the normal dispatcher with no platform branch, so a web selector threads through unchanged', ), @@ -814,7 +814,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { macos: macos.gap('No command-specific macOS trace evidence exists yet'), tvos: tvos.gap('No tvOS-specific trace command evidence exists yet'), web: web.contract( - 'src/daemon/handlers/__tests__/trace-runtime.test.ts', + 'packages/daemon/src/handlers/__tests__/trace-runtime.test.ts', 'starts and stops one trace through the session-owned trace slot on a web session', 'session-scoped trace start/stop bookkeeping works the same for a web session as any other platform', ), @@ -1256,7 +1256,7 @@ const COMMAND_COVERAGE_DECLARATIONS = { 'Android viewport fails closed through its unavailable exact-owner runtime fact', ), iosSimulator: iosSimulator.contract( - 'src/daemon/__tests__/viewport-runtime.test.ts', + 'packages/daemon/src/__tests__/viewport-runtime.test.ts', 'rejects an unavailable exact-owner fact before binding', 'iOS viewport fails closed through its unavailable exact-owner runtime fact', ), diff --git a/test/integration/command-coverage/evidence.ts b/test/integration/command-coverage/evidence.ts index ccd78dc1e5..0b824d8114 100644 --- a/test/integration/command-coverage/evidence.ts +++ b/test/integration/command-coverage/evidence.ts @@ -52,7 +52,7 @@ export const ANDROID_FOLD_RUNTIME_CONTRACT_EVIDENCE: AndroidContractEvidence = ); export const ANDROID_VIEWPORT_RUNTIME_CONTRACT_EVIDENCE: AndroidContractEvidence = defineAndroidContractEvidence( - 'src/daemon/__tests__/viewport-runtime.test.ts', + 'packages/daemon/src/__tests__/viewport-runtime.test.ts', [C.viewport], 'rejects an unavailable exact-owner fact before binding', ); diff --git a/test/integration/interaction-contract/native-ref.contract.test.ts b/test/integration/interaction-contract/native-ref.contract.test.ts index a002969777..036167ca75 100644 --- a/test/integration/interaction-contract/native-ref.contract.test.ts +++ b/test/integration/interaction-contract/native-ref.contract.test.ts @@ -4,7 +4,7 @@ import type { InteractionGuarantee } from '@agent-device/contracts/interaction-g import type { SnapshotState } from '@agent-device/kernel/snapshot'; import { ref } from '../../../src/commands/interaction/runtime/selector-read-utils.ts'; import { scenarioName } from './coverage-manifest.ts'; -import { buildInteractionResponseData } from '../../../src/daemon/interaction/internal/interaction-touch-response.ts'; +import { buildInteractionResponseData } from '@agent-device/daemon/testing/interaction/internal/interaction-touch-response'; import { NATIVE_REF_COVERAGE } from './native-ref.coverage.ts'; import { closedDrawerSnapshot, diff --git a/test/integration/nightly/concurrency-torture/bindings.ts b/test/integration/nightly/concurrency-torture/bindings.ts index 319815c18a..e523996370 100644 --- a/test/integration/nightly/concurrency-torture/bindings.ts +++ b/test/integration/nightly/concurrency-torture/bindings.ts @@ -2,7 +2,7 @@ // // The lane does NOT hand-write which locks an operation takes. It derives the // plan from the REAL router primitive `resolveRequestExecutionLockPlan` -// (src/daemon/request-binding.ts), driven with a fake in-memory device +// (packages/daemon/src/request-binding.ts), driven with a fake in-memory device // inventory via the production `withDeviceInventoryProvider` seam. This is what // makes the same-device serialization invariant revert-sensitive: if production // stops returning a `device:` key (e.g. the router's same-device open @@ -20,11 +20,11 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { CommandFlags } from '@agent-device/contracts/command'; -import type { DaemonRequest } from '../../../../src/daemon/daemon-request.ts'; -import type { SessionRef } from '../../../../src/daemon/session-state.ts'; -import type { SessionStore } from '../../../../src/daemon/session-store.ts'; -import { resolveRequestExecutionLockPlan } from '../../../../src/daemon/request-binding.ts'; -import { shouldLockSessionExecution } from '../../../../src/daemon/daemon-command-registry.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import type { SessionRef } from '@agent-device/daemon/testing/session-state'; +import type { SessionStore } from '@agent-device/daemon/testing/session-store'; +import { resolveRequestExecutionLockPlan } from '@agent-device/daemon/testing/request-binding'; +import { shouldLockSessionExecution } from '@agent-device/daemon/daemon-command-registry'; import { PUBLIC_COMMANDS } from '@agent-device/command-registry/catalog'; import { withTestDeviceInventoryProvider as withDeviceInventoryProvider } from '@agent-device/device-selection/inventory-gateways-fixtures'; diff --git a/test/integration/nightly/concurrency-torture/claim-registry.ts b/test/integration/nightly/concurrency-torture/claim-registry.ts index 001db632f7..279dffa588 100644 --- a/test/integration/nightly/concurrency-torture/claim-registry.ts +++ b/test/integration/nightly/concurrency-torture/claim-registry.ts @@ -1,4 +1,4 @@ -// In-memory model of the enforced host-global device claim (`src/daemon/device/device-claims.ts`). +// In-memory model of the enforced host-global device claim (`packages/daemon/src/device/device-claims.ts`). // // The production claim is a filesystem lock file guarded by a process lock, keyed // by `canonicalLocalDeviceKey`. That is real I/O and a real OS lock — neither is diff --git a/test/integration/nightly/concurrency-torture/harness.ts b/test/integration/nightly/concurrency-torture/harness.ts index 6cabd1ab17..13d7718bdc 100644 --- a/test/integration/nightly/concurrency-torture/harness.ts +++ b/test/integration/nightly/concurrency-torture/harness.ts @@ -26,9 +26,9 @@ import os from 'node:os'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { LeaseRegistry } from '../../../../src/daemon/lease-registry.ts'; -import { SessionStore } from '../../../../src/daemon/session-store.ts'; -import type { SessionState } from '../../../../src/daemon/session-state.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { AppError } from '@agent-device/kernel/errors'; import { makePrng, type Prng } from './prng.ts'; diff --git a/test/integration/nightly/concurrency-torture/invariants.ts b/test/integration/nightly/concurrency-torture/invariants.ts index 06afe30a05..610c8c6863 100644 --- a/test/integration/nightly/concurrency-torture/invariants.ts +++ b/test/integration/nightly/concurrency-torture/invariants.ts @@ -10,8 +10,8 @@ // - no cross-session bleed: each stored session carries exactly its own // lease/claim/device, never a concurrent session's -import type { LeaseRegistry } from '../../../../src/daemon/lease-registry.ts'; -import type { SessionStore } from '../../../../src/daemon/session-store.ts'; +import type { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import type { SessionStore } from '@agent-device/daemon/testing/session-store'; import type { SessionInstance } from './bindings.ts'; diff --git a/test/integration/nightly/concurrency-torture/real-scope-serialization.ts b/test/integration/nightly/concurrency-torture/real-scope-serialization.ts index 1bea3c7f24..6d4e46606f 100644 --- a/test/integration/nightly/concurrency-torture/real-scope-serialization.ts +++ b/test/integration/nightly/concurrency-torture/real-scope-serialization.ts @@ -19,12 +19,12 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { createRequestExecutionScope } from '../../../../src/daemon/request-execution-scope.ts'; -import { LeaseRegistry } from '../../../../src/daemon/lease-registry.ts'; -import { SessionStore } from '../../../../src/daemon/session-store.ts'; +import { createRequestExecutionScope } from '@agent-device/daemon/testing/request-execution-scope'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; import { withTestDeviceInventoryProvider as withDeviceInventoryProvider } from '@agent-device/device-selection/inventory-gateways-fixtures'; import type { CommandFlags } from '@agent-device/contracts/command'; -import type { DaemonRequest } from '../../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { DEVICE_POOL } from './bindings.ts'; diff --git a/test/integration/provider-scenarios/cloud-webdriver-ios-text-entry.test.ts b/test/integration/provider-scenarios/cloud-webdriver-ios-text-entry.test.ts index 249bc050c7..8fac543a64 100644 --- a/test/integration/provider-scenarios/cloud-webdriver-ios-text-entry.test.ts +++ b/test/integration/provider-scenarios/cloud-webdriver-ios-text-entry.test.ts @@ -3,7 +3,7 @@ import { test } from 'vitest'; import { createBundledCloudWebDriverRuntimes } from '@agent-device/provider-webdriver'; import type { DeviceLease } from '@agent-device/contracts/device'; import { createProviderDeviceRuntimeRequestProviders } from '../../../src/provider-device-runtime.ts'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { assertRpcOk } from './assertions.ts'; import { createProviderScenarioHarness, diff --git a/test/integration/provider-scenarios/cloud-webdriver-lease-http.test.ts b/test/integration/provider-scenarios/cloud-webdriver-lease-http.test.ts index 88934a33b1..cd97ece723 100644 --- a/test/integration/provider-scenarios/cloud-webdriver-lease-http.test.ts +++ b/test/integration/provider-scenarios/cloud-webdriver-lease-http.test.ts @@ -3,7 +3,7 @@ import http from 'node:http'; import { test } from 'vitest'; import { createBundledCloudWebDriverRuntimes } from '@agent-device/provider-webdriver'; import { createProviderDeviceRuntimeRequestProviders } from '../../../src/provider-device-runtime.ts'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { buildHttpRpcPayload } from '../../../src/daemon-client/daemon-client-rpc.ts'; import { closeLoopbackServer, diff --git a/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts b/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts index b4ba80efe5..61e9d4810e 100644 --- a/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts +++ b/test/integration/provider-scenarios/cloud-webdriver-provider-regressions.test.ts @@ -10,7 +10,7 @@ import type { CaptureSnapshotResult } from '@agent-device/contracts/client'; import type { DeviceLease } from '@agent-device/contracts/device'; import type { PlatformRuntimeHost } from '@agent-device/contracts/platform-runtime-operations'; import { createProviderDeviceRuntimeRequestProviders } from '../../../src/provider-device-runtime.ts'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import * as iosSnapshotRuntime from '@agent-device/capture-kit/ios-snapshot-runtime'; import { createProviderScenarioHarness, diff --git a/test/integration/provider-scenarios/cloud-webdriver-runtime.test.ts b/test/integration/provider-scenarios/cloud-webdriver-runtime.test.ts index f9fcbd5424..24ba1fe073 100644 --- a/test/integration/provider-scenarios/cloud-webdriver-runtime.test.ts +++ b/test/integration/provider-scenarios/cloud-webdriver-runtime.test.ts @@ -11,8 +11,8 @@ import { createBundledCloudWebDriverRuntimes } from '@agent-device/provider-webd import type { CloudArtifact } from '@agent-device/contracts/observability'; import type { DeviceLease } from '@agent-device/contracts/device'; import { createProviderDeviceRuntimeRequestProviders } from '../../../src/provider-device-runtime.ts'; -import { createExpiredProviderLeaseReleaser } from '../../../src/daemon/provider-lease-expiry.ts'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import { createExpiredProviderLeaseReleaser } from '@agent-device/daemon/testing/provider-lease-expiry'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { assertRpcOk } from './assertions.ts'; import { createProviderScenarioHarness, diff --git a/test/integration/provider-scenarios/daemon-http-boundary-cancellation.test.ts b/test/integration/provider-scenarios/daemon-http-boundary-cancellation.test.ts index b05a9f3aab..7e592b0c65 100644 --- a/test/integration/provider-scenarios/daemon-http-boundary-cancellation.test.ts +++ b/test/integration/provider-scenarios/daemon-http-boundary-cancellation.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import http from 'node:http'; import { test } from 'vitest'; import { getRequestSignal } from '@agent-device/host-kit/request'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; -import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/provider-scenarios/daemon-http-disconnect.test.ts b/test/integration/provider-scenarios/daemon-http-disconnect.test.ts index 49db2c678d..968d33495a 100644 --- a/test/integration/provider-scenarios/daemon-http-disconnect.test.ts +++ b/test/integration/provider-scenarios/daemon-http-disconnect.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import http from 'node:http'; import { test } from 'vitest'; import { getRequestSignal } from '@agent-device/host-kit/request'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; -import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/provider-scenarios/daemon-http-lease-allocate.test.ts b/test/integration/provider-scenarios/daemon-http-lease-allocate.test.ts index d72cd7631b..36fa67e882 100644 --- a/test/integration/provider-scenarios/daemon-http-lease-allocate.test.ts +++ b/test/integration/provider-scenarios/daemon-http-lease-allocate.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; -import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/provider-scenarios/daemon-http-resumable-upload.test.ts b/test/integration/provider-scenarios/daemon-http-resumable-upload.test.ts index 44f5707019..0e07866b00 100644 --- a/test/integration/provider-scenarios/daemon-http-resumable-upload.test.ts +++ b/test/integration/provider-scenarios/daemon-http-resumable-upload.test.ts @@ -6,9 +6,9 @@ import { test } from 'vitest'; import { cleanupUploadedArtifact, prepareUploadedArtifact, -} from '../../../src/daemon/artifact-tracking.ts'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; -import type { DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +} from '@agent-device/daemon/testing/artifact-tracking'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import type { DaemonResponse } from '@agent-device/daemon/daemon-request'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/provider-scenarios/daemon-http-server.test.ts b/test/integration/provider-scenarios/daemon-http-server.test.ts index 36e69e625c..e367be1049 100644 --- a/test/integration/provider-scenarios/daemon-http-server.test.ts +++ b/test/integration/provider-scenarios/daemon-http-server.test.ts @@ -10,16 +10,16 @@ import { cleanupUploadedArtifact, prepareUploadedArtifact, trackDownloadableArtifact, -} from '../../../src/daemon/artifact-tracking.ts'; +} from '@agent-device/daemon/testing/artifact-tracking'; import { DAEMON_RPC_PROTOCOL_VERSION } from '@agent-device/contracts/daemon-http'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { emitRequestProgress, getRequestSignal, isRequestCanceled, } from '@agent-device/host-kit/request'; -import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/provider-scenarios/daemon-lifecycle.test.ts b/test/integration/provider-scenarios/daemon-lifecycle.test.ts index 52490603b7..2abbfff01f 100644 --- a/test/integration/provider-scenarios/daemon-lifecycle.test.ts +++ b/test/integration/provider-scenarios/daemon-lifecycle.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; -import { parseIntegerEnv } from '../../../src/daemon/server/server-lifecycle.ts'; +import { parseIntegerEnv } from '@agent-device/daemon/testing/server/server-lifecycle'; import { tryAcquireDaemonRegistration } from '@agent-device/daemon-contracts/daemon-registration-owner'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; diff --git a/test/integration/provider-scenarios/daemon-transport.test.ts b/test/integration/provider-scenarios/daemon-transport.test.ts index 47d2ee702f..633a0bf877 100644 --- a/test/integration/provider-scenarios/daemon-transport.test.ts +++ b/test/integration/provider-scenarios/daemon-transport.test.ts @@ -2,12 +2,12 @@ import assert from 'node:assert/strict'; import http from 'node:http'; import net from 'node:net'; import { test } from 'vitest'; -import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { createSocketServer, listenHttpServer, listenNetServer, -} from '../../../src/daemon/server/transport.ts'; +} from '@agent-device/daemon/testing/server/transport'; import { getRequestSignal } from '@agent-device/host-kit/request'; import { closeLoopbackServer, skipWhenLoopbackUnavailable } from '@agent-device/test-kit/loopback'; diff --git a/test/integration/provider-scenarios/harness.ts b/test/integration/provider-scenarios/harness.ts index 90e8b310f3..4ff1df5c2c 100644 --- a/test/integration/provider-scenarios/harness.ts +++ b/test/integration/provider-scenarios/harness.ts @@ -9,7 +9,7 @@ import type { AgentDeviceClient } from '../../../src/client/client-types.ts'; import { createRequestHandler, type RequestRouterDeps, -} from '../../../src/daemon/request-router.ts'; +} from '@agent-device/daemon/testing/request-router'; import { createPlatformRuntimeGateway, createRequestPlatformProviders, @@ -21,15 +21,15 @@ import { createDaemonPlatformServices } from '../../../src/platform-runtime-daem import { platformResourceCleanup } from '../../../src/platform-runtime-resource-cleanup.ts'; import { readDaemonProviderCredentials } from '../../../src/provider-credential-fingerprint.ts'; import type { AppleSimulatorScreenRecordingProcess } from '../../../src/platform-runtime-screen-recording-apple-transport.ts'; -import { trackDownloadableArtifact } from '../../../src/daemon/artifact-tracking.ts'; -import { LeaseRegistry } from '../../../src/daemon/lease-registry.ts'; -import { SessionStore } from '../../../src/daemon/session-store.ts'; +import { trackDownloadableArtifact } from '@agent-device/daemon/testing/artifact-tracking'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { SessionStore } from '@agent-device/daemon/testing/session-store'; import type { DaemonInvokeFn, DaemonRequest, DaemonResponse, -} from '../../../src/daemon/daemon-request.ts'; -import type { SessionState } from '../../../src/daemon/session-state.ts'; +} from '@agent-device/daemon/daemon-request'; +import type { SessionState } from '@agent-device/daemon/testing/session-state'; import { runCmdBackground } from '@agent-device/host-kit/command'; import { createOwnedProcessRecordStore } from '@agent-device/host-kit/process'; import { withClientReplayScriptSources } from '@agent-device/replay-port/replay-script-source-fixtures'; @@ -46,12 +46,12 @@ import { createHostDiagnostics } from '../../../src/platform-runtime-host-diagno import type { PlatformRuntimeProviderRegistration } from '../../../src/platform-runtime-gateway.ts'; import { createProviderPlatformRuntimeRegistrations } from '../../../src/provider-device-runtimes.ts'; import { isActiveProviderDevice } from '../../../src/provider-device-runtime.ts'; -import { installProviderDeviceAdmission } from '../../../src/daemon/provider-device-admission.ts'; -import { installInteractorResolution } from '../../../src/daemon/interactor-resolution.ts'; +import { installProviderDeviceAdmission } from '@agent-device/daemon/testing/provider-device-admission'; +import { installInteractorResolution } from '@agent-device/daemon/testing/interactor-resolution'; import { getInteractor } from '../../../src/core/interactors.ts'; -import { unavailableDeviceRuntimeGateway } from '../../../src/daemon/__tests__/support/unavailable-device-runtime-gateway.ts'; +import { unavailableDeviceRuntimeGateway } from '@agent-device/daemon/testing/__tests__/support/unavailable-device-runtime-gateway'; -import { openWebSessionNames } from '../../../src/daemon/web-session-names.ts'; +import { openWebSessionNames } from '@agent-device/daemon/testing/web-session-names'; import { testCreateCommandSurface } from '../../../src/__tests__/daemon-composition/command-surface-fixture.ts'; // Match daemon composition (src/daemon-composition.ts): the daemon decides on provider diff --git a/test/integration/provider-scenarios/ios-fold.test.ts b/test/integration/provider-scenarios/ios-fold.test.ts index 79ab5b40d2..9cc2c082d8 100644 --- a/test/integration/provider-scenarios/ios-fold.test.ts +++ b/test/integration/provider-scenarios/ios-fold.test.ts @@ -4,9 +4,9 @@ import { resolveCommandRequestTimeoutMs } from '@agent-device/command-registry/t import { MAX_FOLD_DURATION_MS } from '@agent-device/contracts/device'; import type { AppleToolProvider } from '@agent-device/platform-apple/tool-provider'; import type { ExecResult } from '@agent-device/host-kit/command'; -import { recordActionEntry } from '../../../src/daemon/session-action-recorder.ts'; +import { recordActionEntry } from '@agent-device/daemon/testing/session-action-recorder'; import { assertRpcError, assertRpcOk } from './assertions.ts'; -import { makeIosAppSession } from '../../../src/daemon/__tests__/support/session-factories.ts'; +import { makeIosAppSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; diff --git a/test/integration/provider-scenarios/ios-wait-selector.test.ts b/test/integration/provider-scenarios/ios-wait-selector.test.ts index b804a51c78..3ba5fb188a 100644 --- a/test/integration/provider-scenarios/ios-wait-selector.test.ts +++ b/test/integration/provider-scenarios/ios-wait-selector.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; -import { makeIosAppSession } from '../../../src/daemon/__tests__/support/session-factories.ts'; +import { makeIosAppSession } from '@agent-device/daemon/testing/__tests__/support/session-factories'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { PROVIDER_SCENARIO_IOS_SIMULATOR } from './fixtures.ts'; import { assertRpcOk } from './assertions.ts'; diff --git a/test/integration/provider-scenarios/limrun-ios-snapshot-owner.test.ts b/test/integration/provider-scenarios/limrun-ios-snapshot-owner.test.ts index c629c4690d..8b8a75059d 100644 --- a/test/integration/provider-scenarios/limrun-ios-snapshot-owner.test.ts +++ b/test/integration/provider-scenarios/limrun-ios-snapshot-owner.test.ts @@ -64,7 +64,7 @@ vi.mock('@agent-device/platform-apple/runner/operations', async (importOriginal) return { ...actual, runAppleRunnerCommand: vi.fn(async () => ({})) }; }); -vi.mock('../../../src/daemon/ios-app-session-hint.ts', () => ({ +vi.mock('@agent-device/daemon/testing/ios-app-session-hint', () => ({ buildIosOpenCommandHint: vi.fn(async () => undefined), })); diff --git a/test/integration/provider-scenarios/provider-device-runtime.fixtures.ts b/test/integration/provider-scenarios/provider-device-runtime.fixtures.ts index 1d391fdbc0..5380f4b8bf 100644 --- a/test/integration/provider-scenarios/provider-device-runtime.fixtures.ts +++ b/test/integration/provider-scenarios/provider-device-runtime.fixtures.ts @@ -45,7 +45,7 @@ import type { } from '@agent-device/contracts/platform-runtime-operations'; import { bindAdmittedProviderInteractorOperations } from '@agent-device/contracts/interactor-operation-catalog'; import { unavailableDeploymentSnapshotAndShutdownOperationFacts } from '@agent-device/test-kit/runtime-operation-facts'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { deviceShape, hasAppleActionButton, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import { createProviderScenarioHarness } from './harness.ts'; diff --git a/test/integration/provider-scenarios/provider-ios-runner-transport.test.ts b/test/integration/provider-scenarios/provider-ios-runner-transport.test.ts index d8619d861d..cf72fc577b 100644 --- a/test/integration/provider-scenarios/provider-ios-runner-transport.test.ts +++ b/test/integration/provider-scenarios/provider-ios-runner-transport.test.ts @@ -8,7 +8,7 @@ import type { ProviderDeviceRuntime, } from '@agent-device/contracts/device'; import type { Interactor, RunnerContext } from '@agent-device/contracts/interactor-types'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { applePlugin } from '@agent-device/platform-apple'; import type { diff --git a/test/integration/provider-scenarios/provider-ios-selector-runtime.test.ts b/test/integration/provider-scenarios/provider-ios-selector-runtime.test.ts index 9bc06ab5cd..c4a3d03052 100644 --- a/test/integration/provider-scenarios/provider-ios-selector-runtime.test.ts +++ b/test/integration/provider-scenarios/provider-ios-selector-runtime.test.ts @@ -9,7 +9,7 @@ import type { } from '@agent-device/contracts/device'; import type { Interactor, SnapshotResult } from '@agent-device/contracts/interactor-types'; import { providerRuntimeOwner } from '@agent-device/contracts/platform-runtime'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { assertRpcOk } from './assertions.ts'; import { createProviderScenarioHarness, withProviderScenarioResource } from './harness.ts'; diff --git a/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts b/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts index a980bbaf48..ed58ea6a56 100644 --- a/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts +++ b/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts @@ -7,9 +7,9 @@ import { createAgentDeviceClient } from '../../../src/agent-device-client.ts'; import { cleanupDownloadableArtifact, trackDownloadableArtifact, -} from '../../../src/daemon/artifact-tracking.ts'; -import { finalizeDaemonResponse } from '../../../src/daemon/request-finalization.ts'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; +} from '@agent-device/daemon/testing/artifact-tracking'; +import { finalizeDaemonResponse } from '@agent-device/daemon/testing/request-finalization'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { normalizeAgentDeviceError } from '@agent-device/kernel/errors'; import { downloadRemoteArtifact } from '../../../src/remote/daemon-artifacts.ts'; import { createDaemonProxyServer } from '@agent-device/proxy'; diff --git a/test/integration/provider-scenarios/remote-proxy-parity.test.ts b/test/integration/provider-scenarios/remote-proxy-parity.test.ts index f2ca7b4951..edefdab9e3 100644 --- a/test/integration/provider-scenarios/remote-proxy-parity.test.ts +++ b/test/integration/provider-scenarios/remote-proxy-parity.test.ts @@ -5,10 +5,10 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'vitest'; import { sendToDaemon } from '../../../src/daemon-client/daemon-client.ts'; -import { LeaseRegistry } from '../../../src/daemon/lease-registry.ts'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; -import { resolveSessionRequestLogPath } from '../../../src/daemon/session-artifact-paths.ts'; -import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; +import { resolveSessionRequestLogPath } from '@agent-device/daemon/session-artifact-paths'; +import type { DaemonRequest, DaemonResponse } from '@agent-device/daemon/daemon-request'; import { createDaemonProxyServer } from '@agent-device/proxy'; import { AppError, type DaemonError } from '@agent-device/kernel/errors'; import { diff --git a/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts b/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts index 6988d578e2..778eb854c2 100644 --- a/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts +++ b/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts @@ -15,13 +15,13 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { createDaemonProxyServer } from '@agent-device/proxy'; import { localizeRemoteDaemonError } from '../../../src/remote/remote-request-diagnostics.ts'; -import { resolveSessionRequestLogPath } from '../../../src/daemon/session-artifact-paths.ts'; +import { resolveSessionRequestLogPath } from '@agent-device/daemon/session-artifact-paths'; import { safeSessionName } from '@agent-device/host-kit/session-paths'; import type { DaemonError } from '@agent-device/kernel/errors'; -import type { DaemonResponse } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonResponse } from '@agent-device/daemon/daemon-request'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts b/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts index 8b8c27d94a..f6997bd234 100644 --- a/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts +++ b/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts @@ -15,8 +15,8 @@ import { AppError } from '@agent-device/kernel/errors'; import { cleanupDownloadableArtifact, trackDownloadableArtifact, -} from '../../../src/daemon/artifact-tracking.ts'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; +} from '@agent-device/daemon/testing/artifact-tracking'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { downloadRemoteArtifact } from '../../../src/remote/daemon-artifacts.ts'; import { closeLoopbackServer, diff --git a/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts b/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts index 3d6e5d7d3a..12acdc0ee1 100644 --- a/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts +++ b/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts @@ -8,9 +8,9 @@ import type { ReplaySuiteResult } from '@agent-device/contracts/replay'; import { cleanupDownloadableArtifact, trackDownloadableArtifact, -} from '../../../src/daemon/artifact-tracking.ts'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; -import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; +} from '@agent-device/daemon/testing/artifact-tracking'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; +import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { attachRemoteReplayTestArtifacts } from '@agent-device/replay-port/test-command'; import { downloadRemoteArtifact, diff --git a/test/integration/provider-scenarios/remote-upload-lease-beat.test.ts b/test/integration/provider-scenarios/remote-upload-lease-beat.test.ts index 113aab3bca..5b29cc0ab9 100644 --- a/test/integration/provider-scenarios/remote-upload-lease-beat.test.ts +++ b/test/integration/provider-scenarios/remote-upload-lease-beat.test.ts @@ -11,7 +11,7 @@ import { withDiagnosticsScope, } from '@agent-device/host-kit/diagnostics'; import { sendToDaemon } from '../../../src/daemon-client/daemon-client.ts'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import { listenOnLoopback, skipWhenLoopbackUnavailable } from '@agent-device/test-kit/loopback'; import { PARALLEL_PROVIDER_SCENARIO_TIMEOUT_MS } from './test-timeouts.ts'; diff --git a/test/integration/provider-scenarios/scenario.ts b/test/integration/provider-scenarios/scenario.ts index 63c4f4626c..9da2bfc031 100644 --- a/test/integration/provider-scenarios/scenario.ts +++ b/test/integration/provider-scenarios/scenario.ts @@ -1,5 +1,5 @@ import assert from 'node:assert/strict'; -import type { DaemonRequest } from '../../../src/daemon/daemon-request.ts'; +import type { DaemonRequest } from '@agent-device/daemon/daemon-request'; import type { ProviderScenarioHarness, ProviderScenarioRpcResult } from './harness.ts'; export type ProviderScenarioState = { diff --git a/test/integration/provider-scenarios/scroll-movement-observation.test.ts b/test/integration/provider-scenarios/scroll-movement-observation.test.ts index 7e059935f1..92972b25eb 100644 --- a/test/integration/provider-scenarios/scroll-movement-observation.test.ts +++ b/test/integration/provider-scenarios/scroll-movement-observation.test.ts @@ -36,7 +36,7 @@ const DEVICE_ID = PROVIDER_SCENARIO_IOS_SIMULATOR.id; // Directional-scroll observation on `observeUntil` (packages/capture-kit/src/observe-until.ts): // `scroll down` gates its own `movement` claim on the tree it held before the gesture against one // (or more, while the surface still looks untouched) post-gesture capture. The unit-level coverage -// in src/daemon/__tests__/scroll-movement.test.ts pins the verdict against a scripted capture +// in packages/daemon/src/__tests__/scroll-movement.test.ts pins the verdict against a scripted capture // function directly; these two scenarios drive the SAME loop end to end through the daemon's real // command routing and a scripted Apple runner, the way `settle-observation.test.ts` drives `--settle`. @@ -97,7 +97,7 @@ function repeatSnapshotEntry(nodes: readonly unknown[]): ProviderScenarioProvide } // Midpoint (201, 437) sits inside CONTAINER, matching the swipe fixture -// `src/daemon/__tests__/scroll-movement.test.ts` uses for the same geometry. +// `packages/daemon/src/__tests__/scroll-movement.test.ts` uses for the same geometry. function scrollEntry(): ProviderScenarioProviderEntry { return { command: 'ios.runner.scroll', diff --git a/test/integration/provider-scenarios/scroll-until.test.ts b/test/integration/provider-scenarios/scroll-until.test.ts index b951518c6a..4054ca5f2b 100644 --- a/test/integration/provider-scenarios/scroll-until.test.ts +++ b/test/integration/provider-scenarios/scroll-until.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; -import { SCROLL_UNTIL_PASS_LIMIT } from '../../../src/daemon/scroll-until.ts'; +import { SCROLL_UNTIL_PASS_LIMIT } from '@agent-device/daemon/testing/scroll-until'; import { createAndroidSettingsWorld } from './android-world.ts'; import { withProviderScenarioResource } from './harness.ts'; diff --git a/test/integration/provider-scenarios/stale-provider-runtime-admission.fixtures.ts b/test/integration/provider-scenarios/stale-provider-runtime-admission.fixtures.ts index 6231d558dd..e89731b810 100644 --- a/test/integration/provider-scenarios/stale-provider-runtime-admission.fixtures.ts +++ b/test/integration/provider-scenarios/stale-provider-runtime-admission.fixtures.ts @@ -10,10 +10,10 @@ import type { PlatformRuntimeProviderModule, } from '@agent-device/contracts/platform-runtime-operations'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { handleAppDeploymentCommand } from '../../../src/daemon/handlers/session-app-deployment.ts'; -import { createRequestRuntimeBindings } from '../../../src/daemon/request-runtime-binding.ts'; -import { createRequestDispatchLedger } from '../../../src/daemon/request-dispatch-ledger.ts'; -import { makeSessionStore } from '../../../src/daemon/__tests__/support/store-factory.ts'; +import { handleAppDeploymentCommand } from '@agent-device/daemon/testing/handlers/session-app-deployment'; +import { createRequestRuntimeBindings } from '@agent-device/daemon/testing/request-runtime-binding'; +import { createRequestDispatchLedger } from '@agent-device/daemon/testing/request-dispatch-ledger'; +import { makeSessionStore } from '@agent-device/daemon/testing/__tests__/support/store-factory'; import { mkdtempForTestSync } from '@agent-device/test-kit/tmp-dir'; import { createComposedPlatformRuntimeGateway } from '../../../src/platform-runtime-gateway.ts'; diff --git a/test/output-economy/fixtures.ts b/test/output-economy/fixtures.ts index 3972d2fc2f..fd52759964 100644 --- a/test/output-economy/fixtures.ts +++ b/test/output-economy/fixtures.ts @@ -1,7 +1,7 @@ import type { CaptureSnapshotResult, CommandRequestResult } from '@agent-device/contracts/client'; import { AppError } from '@agent-device/kernel/errors'; import { attachRefs, type RawSnapshotNode } from '@agent-device/kernel/snapshot'; -import type { DaemonResponseData } from '../../src/daemon/daemon-request.ts'; +import type { DaemonResponseData } from '@agent-device/daemon/daemon-request'; const SNAPSHOT_NODES: RawSnapshotNode[] = [ { diff --git a/test/output-economy/owner-files-no-leak.test.ts b/test/output-economy/owner-files-no-leak.test.ts index d98a6fc43f..415e954c35 100644 --- a/test/output-economy/owner-files-no-leak.test.ts +++ b/test/output-economy/owner-files-no-leak.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { runCmdSync } from '@agent-device/host-kit/command'; import { COMMAND_OWNER_FILES } from '@agent-device/command-registry/owner-files'; -import { getDaemonRouteOwnerFiles } from '../../src/daemon/route-owner-files.ts'; +import { getDaemonRouteOwnerFiles } from '@agent-device/daemon/route-owner-files'; const repoRoot = path.resolve(import.meta.dirname, '../..'); const distPath = path.join(repoRoot, 'dist/src'); diff --git a/test/output-economy/render-fixtures.ts b/test/output-economy/render-fixtures.ts index 1f1b0b1ee9..64b33d93c4 100644 --- a/test/output-economy/render-fixtures.ts +++ b/test/output-economy/render-fixtures.ts @@ -1,7 +1,7 @@ import { snapshotCliOutput } from '../../src/commands/capture/output.ts'; import { interactionCliOutputFormatters } from '../../src/commands/interaction/output.ts'; import type { AgentDeviceClient } from '../../src/client/client-types.ts'; -import { RESPONSE_VIEWS } from '../../src/daemon/response-views.ts'; +import { RESPONSE_VIEWS } from '@agent-device/daemon/testing/response-views'; import { normalizeError } from '@agent-device/kernel/errors'; import { createCommandToolExecutor } from '../../src/mcp/command-tools.ts'; import type { EconomySample } from './economy-metrics.ts'; diff --git a/test/output-economy/selection-fixtures.ts b/test/output-economy/selection-fixtures.ts index d45c1dce61..b67c019849 100644 --- a/test/output-economy/selection-fixtures.ts +++ b/test/output-economy/selection-fixtures.ts @@ -1,5 +1,5 @@ import type { DebugSymbolsResult } from '@agent-device/contracts/observability'; -import type { DaemonResponseData } from '../../src/daemon/daemon-request.ts'; +import type { DaemonResponseData } from '@agent-device/daemon/daemon-request'; const requestBody = JSON.stringify({ cartId: 'cart-economy-fixture', diff --git a/test/wire-compat/closure-policy.ts b/test/wire-compat/closure-policy.ts index 64d3dc521e..bea9e4788f 100644 --- a/test/wire-compat/closure-policy.ts +++ b/test/wire-compat/closure-policy.ts @@ -43,11 +43,11 @@ export const WIRE_CLOSURE_WAIVERS: Readonly> = { 'Local detail bag behind AppError; the wire form is DaemonError.details, typed as Record and listed.', 'src/daemon-client/daemon-client-metadata.ts#DaemonInfo': 'Client-side record of where a daemon is listening (pid, ports, state dir). Never serialized into a request or response.', - 'src/daemon/daemon-request.ts#DaemonRequest': + 'packages/daemon/src/daemon-request.ts#DaemonRequest': 'Server-side narrowing of the listed kernel DaemonRequest; the declaration that fixes the shape is packages/kernel/src/contracts.ts#DaemonRequest.', - 'src/daemon/daemon-request.ts#DaemonResponse': + 'packages/daemon/src/daemon-request.ts#DaemonResponse': 'Re-export alias of the listed kernel DaemonResponse; the shape is fixed by packages/kernel/src/contracts.ts#DaemonResponse.', - 'src/daemon/daemon-request.ts#DaemonArtifact': + 'packages/daemon/src/daemon-request.ts#DaemonArtifact': 'Re-export alias of the listed kernel DaemonArtifact; the shape is fixed by packages/kernel/src/contracts.ts#DaemonArtifact.', 'src/remote/upload-stream.ts#UploadStreamProgressOptions': 'Byte-progress callback options for local upload rendering. The bytes counted are digested through the request/response declarations; these options never cross the wire.', diff --git a/test/wire-compat/ledger.json b/test/wire-compat/ledger.json index 8e8077de80..d9a2eb8700 100644 --- a/test/wire-compat/ledger.json +++ b/test/wire-compat/ledger.json @@ -71,23 +71,23 @@ "src/daemon-client/daemon-client-transport.ts#readHealthLink": "sha256:f56404b94d73da57de7248719c9136b760d2be8b4a53cde5315a2311b088425b", "src/daemon-client/daemon-client-transport.ts#readHealthPayload": "sha256:4e85ffc3e35e02379c393e9312344757e003cf1f0ad9eb8d1f77d90c81c861f1", "src/daemon-client/daemon-client-transport.ts#readRemoteDaemonHealth": "sha256:df174d1ccf73851ca58bd75533fb4660424003b98bd9e41fe942cf3ab3698e5f", - "src/daemon/downloadable-artifact-http.ts#DownloadableArtifactHttpAuthorizer": "sha256:1b2702a929ca9170db2ca97c08e3ab67e17edb3ee75325a576c4c1b9cdbebb44", - "src/daemon/downloadable-artifact-http.ts#DownloadableArtifactHttpRoute": "sha256:e63c4581ccde668913914149c9092d16ecf8a5cbd7ab33c6eb8617e77fc1015e", - "src/daemon/downloadable-artifact-http.ts#handleArtifactDownload": "sha256:7f96d17b7c605230fb3cc21ceaa5b2e515d7445653ff95b2b0f6f15fa6214d4e", - "src/daemon/downloadable-artifact-http.ts#handleArtifactInventory": "sha256:24f071c082af80f2c50fb4f390bd8949f0f2c91e0bb58e67518b6cdcf6108aff", - "src/daemon/downloadable-artifact-http.ts#readArtifactId": "sha256:3472ee52d951fdf7ef00ee500298602c68f0e1e3b8c44ff51b09981efabf348c", - "src/daemon/downloadable-artifact-http.ts#readRequestPathname": "sha256:6b3a49c72365cf7da4552abef59862c073461f746025e28d409048815dd586f2", - "src/daemon/downloadable-artifact-http.ts#resolveDownloadableArtifactHttpRoute": "sha256:9fcdc9619e8d378e8f04ef7b3584863af446e855702ddce83a16ec194a6d98af", - "src/daemon/http-errors.ts#NormalizedHttpError": "sha256:2c2111802fe5f193acbeacc454de9cfab82bc8e4274b896f485e19a14f5518cf", - "src/daemon/http-errors.ts#failStreamedHttpResponse": "sha256:7199933eca7244bc801e0601b17cc1aed584bc2353879830fd0686e99f1200c4", - "src/daemon/http-errors.ts#sendRestJsonError": "sha256:981abb859649419604d555601b5c4bd6616e78215327e055e5f8023c6c15f556", - "src/daemon/http-errors.ts#statusCodeForNormalizedError": "sha256:20ad272162e28425920bd2dcb4da5ec104bd7e8be2028b902b05bfa4da3df966", - "src/daemon/http-request-target.ts#decodeUriSegment": "sha256:b37622771ea4e61d1a9820169dbdc5809b5c38889bfad79277d7b22f3c3f1ef1", - "src/daemon/request-diagnostics-http.ts#REQUEST_DIAGNOSTICS_CONTENT_TYPE": "sha256:16bbd9ae7eaeaaa8c8cbd6e65c4ce786a6c5230c5351288228bbf1a6f11bdcdc", - "src/daemon/request-diagnostics-http.ts#RequestDiagnosticsHttpAuthorizer": "sha256:24b0fa6b1d965e5cf6503a4665148dc6360c56bf5a0ae710eeaa76a73a62c52a", - "src/daemon/request-diagnostics-http.ts#RequestDiagnosticsHttpOptions": "sha256:cd2c0dda77d2bc434857aea07206a5491ce5f0b82cb86628569f607d6c2cebcf", - "src/daemon/request-diagnostics-http.ts#handleRequestDiagnostics": "sha256:32c3d100176dd99ecbb61f8050d05b1cda64b7be1944a2cd16633e83fa78660b", - "src/daemon/request-diagnostics-http.ts#resolveRequestDiagnosticsHttpRoute": "sha256:4ff07623b27a6f7461e1addb87aabd149904da63f7462149ae4114d14336cde0", + "packages/daemon/src/downloadable-artifact-http.ts#DownloadableArtifactHttpAuthorizer": "sha256:1b2702a929ca9170db2ca97c08e3ab67e17edb3ee75325a576c4c1b9cdbebb44", + "packages/daemon/src/downloadable-artifact-http.ts#DownloadableArtifactHttpRoute": "sha256:e63c4581ccde668913914149c9092d16ecf8a5cbd7ab33c6eb8617e77fc1015e", + "packages/daemon/src/downloadable-artifact-http.ts#handleArtifactDownload": "sha256:7f96d17b7c605230fb3cc21ceaa5b2e515d7445653ff95b2b0f6f15fa6214d4e", + "packages/daemon/src/downloadable-artifact-http.ts#handleArtifactInventory": "sha256:24f071c082af80f2c50fb4f390bd8949f0f2c91e0bb58e67518b6cdcf6108aff", + "packages/daemon/src/downloadable-artifact-http.ts#readArtifactId": "sha256:3472ee52d951fdf7ef00ee500298602c68f0e1e3b8c44ff51b09981efabf348c", + "packages/daemon/src/downloadable-artifact-http.ts#readRequestPathname": "sha256:6b3a49c72365cf7da4552abef59862c073461f746025e28d409048815dd586f2", + "packages/daemon/src/downloadable-artifact-http.ts#resolveDownloadableArtifactHttpRoute": "sha256:9fcdc9619e8d378e8f04ef7b3584863af446e855702ddce83a16ec194a6d98af", + "packages/daemon/src/http-errors.ts#NormalizedHttpError": "sha256:2c2111802fe5f193acbeacc454de9cfab82bc8e4274b896f485e19a14f5518cf", + "packages/daemon/src/http-errors.ts#failStreamedHttpResponse": "sha256:7199933eca7244bc801e0601b17cc1aed584bc2353879830fd0686e99f1200c4", + "packages/daemon/src/http-errors.ts#sendRestJsonError": "sha256:981abb859649419604d555601b5c4bd6616e78215327e055e5f8023c6c15f556", + "packages/daemon/src/http-errors.ts#statusCodeForNormalizedError": "sha256:20ad272162e28425920bd2dcb4da5ec104bd7e8be2028b902b05bfa4da3df966", + "packages/daemon/src/http-request-target.ts#decodeUriSegment": "sha256:b37622771ea4e61d1a9820169dbdc5809b5c38889bfad79277d7b22f3c3f1ef1", + "packages/daemon/src/request-diagnostics-http.ts#REQUEST_DIAGNOSTICS_CONTENT_TYPE": "sha256:16bbd9ae7eaeaaa8c8cbd6e65c4ce786a6c5230c5351288228bbf1a6f11bdcdc", + "packages/daemon/src/request-diagnostics-http.ts#RequestDiagnosticsHttpAuthorizer": "sha256:24b0fa6b1d965e5cf6503a4665148dc6360c56bf5a0ae710eeaa76a73a62c52a", + "packages/daemon/src/request-diagnostics-http.ts#RequestDiagnosticsHttpOptions": "sha256:cd2c0dda77d2bc434857aea07206a5491ce5f0b82cb86628569f607d6c2cebcf", + "packages/daemon/src/request-diagnostics-http.ts#handleRequestDiagnostics": "sha256:32c3d100176dd99ecbb61f8050d05b1cda64b7be1944a2cd16633e83fa78660b", + "packages/daemon/src/request-diagnostics-http.ts#resolveRequestDiagnosticsHttpRoute": "sha256:4ff07623b27a6f7461e1addb87aabd149904da63f7462149ae4114d14336cde0", "packages/daemon-contracts/src/request-progress-protocol.ts#DaemonProgressEnvelope": "sha256:16162d01cfc43fc6a0198dbba3358981c1a278a70f7494ebe70d051f517cfb22", "packages/daemon-contracts/src/request-progress-protocol.ts#DaemonResponseEnvelope": "sha256:202ae64836af890549a1d95963903f9a506294b80bd0862c1b708e72d7f286d0", "packages/daemon-contracts/src/request-progress-protocol.ts#isDaemonProgressEnvelope": "sha256:e38ec26b64d20e257ff00860548e9c12ac22faf5a6308749d4715129814b381f", @@ -96,54 +96,54 @@ "packages/daemon-contracts/src/request-progress-protocol.ts#serializeDaemonResponseEnvelope": "sha256:bc2b651df28446c51d8b92b7fd47a3bced9fade9ae50e2cd73e453ba89fd33b5", "packages/daemon-contracts/src/request-progress-protocol.ts#serializeDaemonRpcResponseEnvelope": "sha256:e244291bef44cedfb59ad07c45337bb8e5fdde00b712ebdf5ca9627f6355f111", "packages/daemon-contracts/src/request-progress-protocol.ts#shouldStreamRequestProgress": "sha256:cf7b26ccea9cd5c33c93477f783a3bdb9a1b0ce629da8b77fef0d49d6c6f4112", - "src/daemon/resumable-upload.ts#BeginResumableUploadOptions": "sha256:ef804e321b8cd1f23a51566919fc0cda79c1b0ef82aeceed54ce3f2a398d8457", - "src/daemon/server/http-rpc-methods.ts#COMMAND_RPC_METHODS": "sha256:4b675a84ef475c2fe0e864457c254c2e888de942e4ae428d5b3e1fa72101e97b", - "src/daemon/server/http-authorization.ts#HttpAuthDecision": "sha256:a7fc2a91f998ce62b107b14dd9b6fcf1f4ca5abe2e30d4df5a0896d56a0a52f8", - "src/daemon/server/http-authorization.ts#HttpAuthHook": "sha256:1ed0ba84708f040787d81d7f546c8b6e0cb8c319625d6c654ece3819be2de8e6", - "src/daemon/server/http-authorization.ts#HttpAuthHookContext": "sha256:c555532dcc31c106d893445d2cff01ad6c5e5b3390b86fad982385059ec69663", - "src/daemon/server/http-authorization.ts#HttpAuthHookResult": "sha256:d52c3f14ff05da925a8efc53b9eac4538826ba615ab9fc073eeed4f3df678086", - "src/daemon/server/http-rpc-methods.ts#INSTALL_FROM_SOURCE_RPC_METHODS": "sha256:d0dc3f3d872e7384343e28aaaf2b57e0da822e654a2e345fb108d160f520c16d", - "src/daemon/server/http-rpc-envelope.ts#JsonRpcRequest": "sha256:7c299fe17818993a0bacbb48e12dcd1fd28b3595cf8efcae3484acbec383ce22", - "src/daemon/server/http-rpc-envelope.ts#JsonRpcResponse": "sha256:13b36c1e2b9eae9437fdac982efde142fd4abba947e11011fa22191675b6e4ba", - "src/daemon/server/http-rpc-methods.ts#LEASE_RPC_METHOD_TO_COMMAND": "sha256:ff52d6c6040080973d51c572ea09b0e23eaa07c7f7b813061599d404dfc811ca", - "src/daemon/server/http-server.ts#MAX_HTTP_RPC_BODY_BYTES": "sha256:3cb06e12b3110fa27e390d5c6473578b3f13c93b9f2b571e0e8e42d7ce29d48a", - "src/daemon/server/http-rpc-methods.ts#RELEASE_MATERIALIZED_PATHS_RPC_METHODS": "sha256:75a18d3496894309dd6042b16c4dcc241c16ec6336783e6310eddd6db7437ccb", - "src/daemon/server/http-rpc-methods.ts#SUPPORTED_RPC_METHODS": "sha256:4d5ed730dcb669b0dacca3bb4977f35686bab9b7fb464c0590fd50f838e6c243", - "src/daemon/server/http-authorization.ts#authorizeAuxiliaryHttpRequest": "sha256:1c323f97c3cefec8f95633b6abd127342bf75494bfb109d1cc6eadf3ceacaeae", - "src/daemon/server/http-rpc-envelope.ts#createRpcError": "sha256:1921762129636afc7772937d48e8afb8f09047b343e3a27d18b49c1c4385bbe8", - "src/daemon/server/http-authorization.ts#enforceDaemonToken": "sha256:60036cffc34388b33fc0dad39c905d9cb3fc18c9ed0cf24255bb7105f5d444c7", - "src/daemon/server/http-rpc-methods.ts#isCommandRpcMethod": "sha256:9922102ba9c72c3032f205717d772ab7c3506c6f3012f55b8e7e5636b672ed7e", - "src/daemon/server/http-rpc-envelope.ts#jsonRpcCodeForNormalizedError": "sha256:27f397cf1a36254602d1df2ae2c0edcb45bb210d595a76890816c841bf152458", - "src/daemon/server/http-rpc-methods.ts#methodToDaemonRequest": "sha256:9c0ef19695f1a4aabf355565925a5deb3fbd832997c089f11918b8c4750bb03f", - "src/daemon/server/http-rpc-methods.ts#parseCommandRpcParams": "sha256:303b9b596c6c5fff13bc8e16dfa32ea816f41e0988832ce795157937cb38ae79", - "src/daemon/server/http-authorization.ts#readHeaderValue": "sha256:0ec16993e5d9b460ba02deb4a43bbc4c248f9697eaed9aa64003eec7d5dce6bf", - "src/daemon/server/http-authorization.ts#resolveToken": "sha256:3abcb019e1325317618045b7138e41845990af10953dd937571997cd6ec35981", - "src/daemon/server/http-rpc-envelope.ts#sendJson": "sha256:a1de00da3f1db8c98e69a85dfe2e11b626a4d2ce472840e3b8f519aa8a207a8f", - "src/daemon/server/http-rpc-methods.ts#toDaemonRequest": "sha256:f3861d2d4f67f66e83800616926f6bbb0595de4ecbb0072b5b78971ebeb0705b", - "src/daemon/server/http-rpc-methods.ts#toInstallFromSourceDaemonRequest": "sha256:dff093758b433043816dfc1e2e9658078875e46b887fdc530fb9380158d629f5", - "src/daemon/server/http-rpc-methods.ts#toLeaseDaemonRequest": "sha256:3018984aeace4054767875f5eb6e6ad5d38bfcb71c15d1a56ccf9b53e0a419ec", - "src/daemon/server/http-rpc-methods.ts#toReleaseMaterializedPathsDaemonRequest": "sha256:708736ca03d6a3fc449bb408382dbd509e490de1f84ecc8771fd77d4adda0154", - "src/daemon/server/http-rpc-envelope.ts#writeProgressEnvelope": "sha256:7be778b3902c72d7aa6282c16dc7106fdd64e99c0b5daf9f413ff5dd3fb044f1", - "src/daemon/server/http-rpc-envelope.ts#writeRpcResponseEnvelope": "sha256:7a8155e9fcbb53485489728250a85109b5dab0d96cdd4aa8b7e7eb87a4898ddb", - "src/daemon/session-tenant-scope.ts#TenantSessionNamespace": "sha256:a6613d22933caa053e479f05b7f016664f6be8d0afdbbf81e578ff497fc1b13d", - "src/daemon/session-tenant-scope.ts#isTenantAddressableSessionName": "sha256:cc8ae18094b7f57d4bb694678f84ba767637b1087fd28058ffd6a3c92c79f05d", - "src/daemon/session-tenant-scope.ts#isTenantOwnedSessionName": "sha256:c3cff883507d462548846554b89779cb815ceb265714575e57bee022b57c4bd1", - "src/daemon/upload-http.ts#AuxiliaryHttpAuthorizer": "sha256:6521ffa355c57af97bfc8095699f2a2b38745a6ef8d61a34c8cfc80ee690b6b5", - "src/daemon/upload-http.ts#DIRECT_UPLOAD_PATH_PREFIX": "sha256:6fe7d42a65baceb595d96b6aa83fe9aa84527d9aa2e448d7ef47882d31a03276", - "src/daemon/upload-http.ts#UploadFinalizeBody": "sha256:c358aea9b3c341f51f3fa263032dfda8a3fbbf729396fcf7f2d8aa051b231b8b", - "src/daemon/upload-http.ts#UploadHttpRoute": "sha256:3fee66976292bedc9587e266f7f584ff27574e939329bb3ecb98f100c4c54b2e", - "src/daemon/upload-http.ts#UploadPreflightBody": "sha256:05b5e8bd75887f821c44cd54b027f09de1ea08c6e41c44d4dc9ec7cf09fc1ea5", - "src/daemon/upload-http.ts#buildUploadTicketAuthHeaders": "sha256:04d65207c440424257ea04a86fa50fd27f5e6b62e8cede884d9af1db4fb86475", - "src/daemon/upload-http.ts#handleResumableUpload": "sha256:b1e1cfd79f13470a1111a377b87975ed5c721500d99f3160a8b631194af37ce5", - "src/daemon/upload-http.ts#handleUpload": "sha256:bba7347a32f53b265cded1c7d73f943431ba3b5a0c8b347d621266ea20c10cd6", - "src/daemon/upload-http.ts#handleUploadFinalize": "sha256:f6879ce6b62d916265d98f6b6aa5f99650c82a9d391a7d5873015036d9289a24", - "src/daemon/upload-http.ts#handleUploadPreflight": "sha256:6d850c477241295d0e8d7e9da3c0dd6abc6f8ea436d52674c3e2ebd77b43f711", - "src/daemon/upload-http.ts#readUploadFinalizeBody": "sha256:076298afa73d7e498a964b6c48d823de1cc8b15e9e971d0a22b7e6c3fd98d685", - "src/daemon/upload-http.ts#readUploadPreflightBody": "sha256:2e56302178b75d9a6f5424f01dfc46551dca2056ba06a43e48ae09ec528956b6", - "src/daemon/upload-http.ts#resolveHttpRequestBaseUrl": "sha256:0d06968c7577c421573281bc574485dc964e98f484afd1dc022fbba24d1face3", - "src/daemon/upload-http.ts#resolveUploadHttpRoute": "sha256:8837e62933cf57111a8070454877c5859aed65b4dcdba755f145346e30f82835", - "src/daemon/upload-http.ts#sendJson": "sha256:c2317b4b14a10731684c9160038005965856150f05f8923765a3fa833d2ecae9", - "src/daemon/upload-http.ts#sendUploadedArtifactResponse": "sha256:9e418403448d58a96284fed605762fa71f9349bf2c70ad79df69b2b3e27487d6", + "packages/daemon/src/resumable-upload.ts#BeginResumableUploadOptions": "sha256:ef804e321b8cd1f23a51566919fc0cda79c1b0ef82aeceed54ce3f2a398d8457", + "packages/daemon/src/server/http-rpc-methods.ts#COMMAND_RPC_METHODS": "sha256:4b675a84ef475c2fe0e864457c254c2e888de942e4ae428d5b3e1fa72101e97b", + "packages/daemon/src/server/http-authorization.ts#HttpAuthDecision": "sha256:a7fc2a91f998ce62b107b14dd9b6fcf1f4ca5abe2e30d4df5a0896d56a0a52f8", + "packages/daemon/src/server/http-authorization.ts#HttpAuthHook": "sha256:1ed0ba84708f040787d81d7f546c8b6e0cb8c319625d6c654ece3819be2de8e6", + "packages/daemon/src/server/http-authorization.ts#HttpAuthHookContext": "sha256:c555532dcc31c106d893445d2cff01ad6c5e5b3390b86fad982385059ec69663", + "packages/daemon/src/server/http-authorization.ts#HttpAuthHookResult": "sha256:d52c3f14ff05da925a8efc53b9eac4538826ba615ab9fc073eeed4f3df678086", + "packages/daemon/src/server/http-rpc-methods.ts#INSTALL_FROM_SOURCE_RPC_METHODS": "sha256:d0dc3f3d872e7384343e28aaaf2b57e0da822e654a2e345fb108d160f520c16d", + "packages/daemon/src/server/http-rpc-envelope.ts#JsonRpcRequest": "sha256:7c299fe17818993a0bacbb48e12dcd1fd28b3595cf8efcae3484acbec383ce22", + "packages/daemon/src/server/http-rpc-envelope.ts#JsonRpcResponse": "sha256:13b36c1e2b9eae9437fdac982efde142fd4abba947e11011fa22191675b6e4ba", + "packages/daemon/src/server/http-rpc-methods.ts#LEASE_RPC_METHOD_TO_COMMAND": "sha256:ff52d6c6040080973d51c572ea09b0e23eaa07c7f7b813061599d404dfc811ca", + "packages/daemon/src/server/http-server.ts#MAX_HTTP_RPC_BODY_BYTES": "sha256:3cb06e12b3110fa27e390d5c6473578b3f13c93b9f2b571e0e8e42d7ce29d48a", + "packages/daemon/src/server/http-rpc-methods.ts#RELEASE_MATERIALIZED_PATHS_RPC_METHODS": "sha256:75a18d3496894309dd6042b16c4dcc241c16ec6336783e6310eddd6db7437ccb", + "packages/daemon/src/server/http-rpc-methods.ts#SUPPORTED_RPC_METHODS": "sha256:4d5ed730dcb669b0dacca3bb4977f35686bab9b7fb464c0590fd50f838e6c243", + "packages/daemon/src/server/http-authorization.ts#authorizeAuxiliaryHttpRequest": "sha256:1c323f97c3cefec8f95633b6abd127342bf75494bfb109d1cc6eadf3ceacaeae", + "packages/daemon/src/server/http-rpc-envelope.ts#createRpcError": "sha256:1921762129636afc7772937d48e8afb8f09047b343e3a27d18b49c1c4385bbe8", + "packages/daemon/src/server/http-authorization.ts#enforceDaemonToken": "sha256:60036cffc34388b33fc0dad39c905d9cb3fc18c9ed0cf24255bb7105f5d444c7", + "packages/daemon/src/server/http-rpc-methods.ts#isCommandRpcMethod": "sha256:9922102ba9c72c3032f205717d772ab7c3506c6f3012f55b8e7e5636b672ed7e", + "packages/daemon/src/server/http-rpc-envelope.ts#jsonRpcCodeForNormalizedError": "sha256:27f397cf1a36254602d1df2ae2c0edcb45bb210d595a76890816c841bf152458", + "packages/daemon/src/server/http-rpc-methods.ts#methodToDaemonRequest": "sha256:9c0ef19695f1a4aabf355565925a5deb3fbd832997c089f11918b8c4750bb03f", + "packages/daemon/src/server/http-rpc-methods.ts#parseCommandRpcParams": "sha256:303b9b596c6c5fff13bc8e16dfa32ea816f41e0988832ce795157937cb38ae79", + "packages/daemon/src/server/http-authorization.ts#readHeaderValue": "sha256:0ec16993e5d9b460ba02deb4a43bbc4c248f9697eaed9aa64003eec7d5dce6bf", + "packages/daemon/src/server/http-authorization.ts#resolveToken": "sha256:3abcb019e1325317618045b7138e41845990af10953dd937571997cd6ec35981", + "packages/daemon/src/server/http-rpc-envelope.ts#sendJson": "sha256:a1de00da3f1db8c98e69a85dfe2e11b626a4d2ce472840e3b8f519aa8a207a8f", + "packages/daemon/src/server/http-rpc-methods.ts#toDaemonRequest": "sha256:f3861d2d4f67f66e83800616926f6bbb0595de4ecbb0072b5b78971ebeb0705b", + "packages/daemon/src/server/http-rpc-methods.ts#toInstallFromSourceDaemonRequest": "sha256:dff093758b433043816dfc1e2e9658078875e46b887fdc530fb9380158d629f5", + "packages/daemon/src/server/http-rpc-methods.ts#toLeaseDaemonRequest": "sha256:3018984aeace4054767875f5eb6e6ad5d38bfcb71c15d1a56ccf9b53e0a419ec", + "packages/daemon/src/server/http-rpc-methods.ts#toReleaseMaterializedPathsDaemonRequest": "sha256:708736ca03d6a3fc449bb408382dbd509e490de1f84ecc8771fd77d4adda0154", + "packages/daemon/src/server/http-rpc-envelope.ts#writeProgressEnvelope": "sha256:7be778b3902c72d7aa6282c16dc7106fdd64e99c0b5daf9f413ff5dd3fb044f1", + "packages/daemon/src/server/http-rpc-envelope.ts#writeRpcResponseEnvelope": "sha256:7a8155e9fcbb53485489728250a85109b5dab0d96cdd4aa8b7e7eb87a4898ddb", + "packages/daemon/src/session-tenant-scope.ts#TenantSessionNamespace": "sha256:a6613d22933caa053e479f05b7f016664f6be8d0afdbbf81e578ff497fc1b13d", + "packages/daemon/src/session-tenant-scope.ts#isTenantAddressableSessionName": "sha256:cc8ae18094b7f57d4bb694678f84ba767637b1087fd28058ffd6a3c92c79f05d", + "packages/daemon/src/session-tenant-scope.ts#isTenantOwnedSessionName": "sha256:c3cff883507d462548846554b89779cb815ceb265714575e57bee022b57c4bd1", + "packages/daemon/src/upload-http.ts#AuxiliaryHttpAuthorizer": "sha256:6521ffa355c57af97bfc8095699f2a2b38745a6ef8d61a34c8cfc80ee690b6b5", + "packages/daemon/src/upload-http.ts#DIRECT_UPLOAD_PATH_PREFIX": "sha256:6fe7d42a65baceb595d96b6aa83fe9aa84527d9aa2e448d7ef47882d31a03276", + "packages/daemon/src/upload-http.ts#UploadFinalizeBody": "sha256:c358aea9b3c341f51f3fa263032dfda8a3fbbf729396fcf7f2d8aa051b231b8b", + "packages/daemon/src/upload-http.ts#UploadHttpRoute": "sha256:3fee66976292bedc9587e266f7f584ff27574e939329bb3ecb98f100c4c54b2e", + "packages/daemon/src/upload-http.ts#UploadPreflightBody": "sha256:05b5e8bd75887f821c44cd54b027f09de1ea08c6e41c44d4dc9ec7cf09fc1ea5", + "packages/daemon/src/upload-http.ts#buildUploadTicketAuthHeaders": "sha256:04d65207c440424257ea04a86fa50fd27f5e6b62e8cede884d9af1db4fb86475", + "packages/daemon/src/upload-http.ts#handleResumableUpload": "sha256:b1e1cfd79f13470a1111a377b87975ed5c721500d99f3160a8b631194af37ce5", + "packages/daemon/src/upload-http.ts#handleUpload": "sha256:bba7347a32f53b265cded1c7d73f943431ba3b5a0c8b347d621266ea20c10cd6", + "packages/daemon/src/upload-http.ts#handleUploadFinalize": "sha256:f6879ce6b62d916265d98f6b6aa5f99650c82a9d391a7d5873015036d9289a24", + "packages/daemon/src/upload-http.ts#handleUploadPreflight": "sha256:6d850c477241295d0e8d7e9da3c0dd6abc6f8ea436d52674c3e2ebd77b43f711", + "packages/daemon/src/upload-http.ts#readUploadFinalizeBody": "sha256:076298afa73d7e498a964b6c48d823de1cc8b15e9e971d0a22b7e6c3fd98d685", + "packages/daemon/src/upload-http.ts#readUploadPreflightBody": "sha256:2e56302178b75d9a6f5424f01dfc46551dca2056ba06a43e48ae09ec528956b6", + "packages/daemon/src/upload-http.ts#resolveHttpRequestBaseUrl": "sha256:0d06968c7577c421573281bc574485dc964e98f484afd1dc022fbba24d1face3", + "packages/daemon/src/upload-http.ts#resolveUploadHttpRoute": "sha256:8837e62933cf57111a8070454877c5859aed65b4dcdba755f145346e30f82835", + "packages/daemon/src/upload-http.ts#sendJson": "sha256:c2317b4b14a10731684c9160038005965856150f05f8923765a3fa833d2ecae9", + "packages/daemon/src/upload-http.ts#sendUploadedArtifactResponse": "sha256:9e418403448d58a96284fed605762fa71f9349bf2c70ad79df69b2b3e27487d6", "src/remote/artifact-download.ts#RemoteArtifactDownload": "sha256:f73a888f4f8c9d603701c505bb342787b1ca6559a13b15da2385e60349ecea8e", "src/remote/artifact-download.ts#downloadRemoteArtifactFromUrl": "sha256:5176697267907e3f5e4383a881969721e4ea3f6776128d28c313bdc210128834", "src/remote/daemon-artifacts.ts#DaemonArtifactEndpoint": "sha256:45226717ac52c0af2a62f74e91549582d95f4a4abc49be87989e026291a88c82", @@ -184,7 +184,7 @@ "packages/contracts/src/daemon-http.ts#DAEMON_HTTP_INSTANCE_HEADER": "sha256:d2bb3f4846470188a0fc1724271da0f0bcbdf2337bd6bf331508142cadcb65d8", "packages/contracts/src/daemon-http.ts#DAEMON_HTTP_UPSTREAM_INSTANCE_HEADER": "sha256:4564c2ce437d30d7a823e3326f4375c0750ba8d42bec22b4d02e8eb7f7db2973", "packages/contracts/src/daemon-http.ts#DAEMON_HTTP_INSTANCE_MISMATCH_HEADER": "sha256:a197edaf7f9fa94a6aab269856aa852da3204cc586f5fd23198689eb11908b61", - "src/daemon/server/http-instance-precondition.ts#refuseStaleDaemonInstance": "sha256:cf9b6f9dd95bb2593e4810c5b5939936b6d6358bf2614c7c234266cab1922d29", + "packages/daemon/src/server/http-instance-precondition.ts#refuseStaleDaemonInstance": "sha256:cf9b6f9dd95bb2593e4810c5b5939936b6d6358bf2614c7c234266cab1922d29", "packages/proxy/src/daemon-proxy.ts#refuseStaleProxyInstance": "sha256:a5d802a666fd04a5c41a40bf3c96cbb4d05d6b449e950cf52098836df01df6ea", "packages/proxy/src/daemon-proxy.ts#sendInstanceMismatch": "sha256:7d0a889f8c7a8151a5ac7a37f52620a269b707144303cae7304825fca49e2a0d", "packages/contracts/src/daemon-http.ts#buildDaemonInstanceMismatchRpcResponse": "sha256:24e50130bbd0c4a21dfc51005cabf118525b9121f918719a2c16f73fcfcfbcf9", @@ -225,7 +225,7 @@ "rationale": "Adds the optional providerCredentialFingerprint parameter to agent_device.lease.allocate, forwarded only when the request meta carries one, which the client sets only for a local daemon. A released protocol-2 daemon ignores unknown JSON-RPC parameters, and a request without a fingerprint keeps the previous payload byte-for-byte." }, { - "declaration": "src/daemon/server/http-rpc-methods.ts#toLeaseDaemonRequest", + "declaration": "packages/daemon/src/server/http-rpc-methods.ts#toLeaseDaemonRequest", "digest": "sha256:3018984aeace4054767875f5eb6e6ad5d38bfcb71c15d1a56ccf9b53e0a419ec", "rationale": "#2110 read the optional providerApp lease-allocation parameter into the existing flags bag; #2494 reads the full provider-allocation flag set into that same bag through the shared readLeaseAllocateProviderFlags projection, so the reconstructed req.flags handed to prepareSession match what the line transport forwards for free. Released protocol-2 clients omit these and follow the unchanged allocation path; no existing field is required or reinterpreted. The optional retainOnClose boolean parameter is read into meta.leaseRetainOnClose; a released daemon ignores it and keeps releasing on session close. Reads the optional providerCredentialFingerprint lease-allocation parameter into request meta, so a local caller over HTTP gets the same credential check as over the socket. A daemon with an auth hook treats every HTTP caller as remote and strips it, as it does developerDir. Released protocol-2 clients omit it and follow the unchanged allocation path; no existing field is required or reinterpreted." }, @@ -250,12 +250,12 @@ "rationale": "#1801 and #1862 client-side only: this reads optional daemon error metadata, most recently the structured `cause`. Parsing of every previously read field is unchanged, so a released daemon's error payload is accepted exactly as before." }, { - "declaration": "src/daemon/downloadable-artifact-http.ts#readArtifactId", + "declaration": "packages/daemon/src/downloadable-artifact-http.ts#readArtifactId", "digest": "sha256:3472ee52d951fdf7ef00ee500298602c68f0e1e3b8c44ff51b09981efabf348c", - "rationale": "Inlined `decodeURIComponent`+catch replaced by the shared `decodeUriSegment` (src/daemon/http-request-target.ts), which is listed and byte-identical in behaviour: the same artifact ids decode, and an undecodable id still resolves to the empty id the route rejects." + "rationale": "Inlined `decodeURIComponent`+catch replaced by the shared `decodeUriSegment` (packages/daemon/src/http-request-target.ts), which is listed and byte-identical in behaviour: the same artifact ids decode, and an undecodable id still resolves to the empty id the route rejects." }, { - "declaration": "src/daemon/downloadable-artifact-http.ts#handleArtifactDownload", + "declaration": "packages/daemon/src/downloadable-artifact-http.ts#handleArtifactDownload", "digest": "sha256:7f96d17b7c605230fb3cc21ceaa5b2e515d7445653ff95b2b0f6f15fa6214d4e", "rationale": "The mid-stream error branch moved verbatim into the shared `failStreamedHttpResponse` (listed): same status codes before headers, same destroy after. Response framing on the success path is untouched." }, @@ -280,17 +280,17 @@ "rationale": "#2198 checks every link a command RPC crosses for protocol skew. #2650 caps a retry health probe at the request's remaining deadline. Health payload parsing and protocol mismatch refusal are unchanged; released peers still receive the same RPCs. #3178 threads the caller's optional AbortSignal through so a canceled call cuts a probe already in flight instead of waiting it out: the signal is client-local, never serialized, and the GET /health request and payload are unchanged." }, { - "declaration": "src/daemon/server/http-authorization.ts#authorizeAuxiliaryHttpRequest", + "declaration": "packages/daemon/src/server/http-authorization.ts#authorizeAuxiliaryHttpRequest", "digest": "sha256:1c323f97c3cefec8f95633b6abd127342bf75494bfb109d1cc6eadf3ceacaeae", "rationale": "#2198 context: adds one optional field to the value this DAEMON-INTERNAL gate hands its own route handlers — sessionNamespace, the caller's tenant plus whether the daemon partitioned that caller's session names. Nothing about it is serialized: no request header is read that was not read before, no response field is added, and a refusal keeps the same 401 {ok:false,error,code} REST body sendRestJsonError already sent. What it enables is a refusal DROPPED, never one added — an unattested (client-declared) tenant no longer has the : prefix rule applied to it, because scopeRequestSession never applied that prefix to its sessions either. A released peer that now gets 200 where it got 401 is getting the ndjson record it asked for and already parses." }, { - "declaration": "src/daemon/request-diagnostics-http.ts#RequestDiagnosticsHttpAuthorizer", + "declaration": "packages/daemon/src/request-diagnostics-http.ts#RequestDiagnosticsHttpAuthorizer", "digest": "sha256:24b0fa6b1d965e5cf6503a4665148dc6360c56bf5a0ae710eeaa76a73a62c52a", "rationale": "#2198 context: widens the authorizer callback's result by the same optional sessionNamespace field, so the route can put its tenant question to session-tenant-scope instead of re-deriving the rule locally. The callback is supplied by createDaemonHttpServer inside this process and never crosses the wire; a caller of the route sends and parses exactly the bytes it did before." }, { - "declaration": "src/daemon/request-diagnostics-http.ts#handleRequestDiagnostics", + "declaration": "packages/daemon/src/request-diagnostics-http.ts#handleRequestDiagnostics", "digest": "sha256:32c3d100176dd99ecbb61f8050d05b1cda64b7be1944a2cd16633e83fa78660b", "rationale": "#2198 context: asks isTenantAddressableSessionName instead of applying the prefix rule locally. Same UNAUTHORIZED code, same 'Session is outside this tenant' message and same 401 body for the attested-tenant case the rule still refuses; the only difference a peer can observe is that an unattested tenant now gets the 200 + ndjson record it already knows how to read instead of a 401 it could not act on." }, @@ -310,7 +310,7 @@ "rationale": "#2266 broadens runtime-hint validation to accept the additive HarmonyOS platform value; existing protocol-2 runtime hints remain valid and unchanged." }, { - "declaration": "src/daemon/server/http-rpc-envelope.ts#writeProgressEnvelope", + "declaration": "packages/daemon/src/server/http-rpc-envelope.ts#writeProgressEnvelope", "digest": "sha256:7be778b3902c72d7aa6282c16dc7106fdd64e99c0b5daf9f413ff5dd3fb044f1", "rationale": "#2894 lets an iOS runner start outlive the caller whose deadline gave up on it, so a progress event can arrive after the response ended. The sink now also skips a response whose writable side has ended, next to the destroyed check it already had. No byte written to a live response changes: the envelope framing and payload are untouched, and a released client never sees an event it could not have received before." }, @@ -395,7 +395,7 @@ "rationale": "#2650 shares the existing conditional 409 JSON-RPC error envelope between daemon and proxy. Its status, header, error code, and normalized reason are unchanged; released peers omit the instance precondition and never receive this response." }, { - "declaration": "src/daemon/server/http-instance-precondition.ts#refuseStaleDaemonInstance", + "declaration": "packages/daemon/src/server/http-instance-precondition.ts#refuseStaleDaemonInstance", "digest": "sha256:cf9b6f9dd95bb2593e4810c5b5939936b6d6358bf2614c7c234266cab1922d29", "rationale": "#2650 adds conditional RPC refusal and retry only for peers that advertise complete instance IDs. Released peers advertise none, so new clients keep per-command health probes and send their unchanged RPC; older clients omit the new request precondition and parse existing responses as before." }, diff --git a/test/wire-compat/surface.ts b/test/wire-compat/surface.ts index 62aeab19a3..026fd8e094 100644 --- a/test/wire-compat/surface.ts +++ b/test/wire-compat/surface.ts @@ -43,17 +43,17 @@ const KERNEL_ERRORS = 'packages/kernel/src/errors.ts'; const KERNEL_DEVICE = 'packages/kernel/src/device.ts'; const REQUEST_PROGRESS = 'packages/contracts/src/request-progress.ts'; const DAEMON_HTTP = 'packages/contracts/src/daemon-http.ts'; -const HTTP_ERRORS = 'src/daemon/http-errors.ts'; -const HTTP_SERVER = 'src/daemon/server/http-server.ts'; -const HTTP_RPC_ENVELOPE = 'src/daemon/server/http-rpc-envelope.ts'; -const HTTP_RPC_METHODS = 'src/daemon/server/http-rpc-methods.ts'; -const HTTP_AUTHORIZATION = 'src/daemon/server/http-authorization.ts'; -const HTTP_INSTANCE_PRECONDITION = 'src/daemon/server/http-instance-precondition.ts'; -const UPLOAD_HTTP = 'src/daemon/upload-http.ts'; -const ARTIFACT_HTTP = 'src/daemon/downloadable-artifact-http.ts'; -const REQUEST_DIAGNOSTICS_HTTP = 'src/daemon/request-diagnostics-http.ts'; -const SESSION_TENANT_SCOPE = 'src/daemon/session-tenant-scope.ts'; -const HTTP_REQUEST_TARGET = 'src/daemon/http-request-target.ts'; +const HTTP_ERRORS = 'packages/daemon/src/http-errors.ts'; +const HTTP_SERVER = 'packages/daemon/src/server/http-server.ts'; +const HTTP_RPC_ENVELOPE = 'packages/daemon/src/server/http-rpc-envelope.ts'; +const HTTP_RPC_METHODS = 'packages/daemon/src/server/http-rpc-methods.ts'; +const HTTP_AUTHORIZATION = 'packages/daemon/src/server/http-authorization.ts'; +const HTTP_INSTANCE_PRECONDITION = 'packages/daemon/src/server/http-instance-precondition.ts'; +const UPLOAD_HTTP = 'packages/daemon/src/upload-http.ts'; +const ARTIFACT_HTTP = 'packages/daemon/src/downloadable-artifact-http.ts'; +const REQUEST_DIAGNOSTICS_HTTP = 'packages/daemon/src/request-diagnostics-http.ts'; +const SESSION_TENANT_SCOPE = 'packages/daemon/src/session-tenant-scope.ts'; +const HTTP_REQUEST_TARGET = 'packages/daemon/src/http-request-target.ts'; const REMOTE_REQUEST_DIAGNOSTICS = 'src/remote/remote-request-diagnostics.ts'; const PROGRESS_PROTOCOL = 'packages/daemon-contracts/src/request-progress-protocol.ts'; const CLIENT_RPC = 'src/daemon-client/daemon-client-rpc.ts'; @@ -325,7 +325,7 @@ export const WIRE_SURFACE: readonly WireSurfaceGroup[] = [ 'sendUploadedArtifactResponse', ), // The resumable-upload ticket the preflight response hands back. - ...from('src/daemon/resumable-upload.ts', 'BeginResumableUploadOptions'), + ...from('packages/daemon/src/resumable-upload.ts', 'BeginResumableUploadOptions'), // `NormalizedHttpError` is `ReturnType`, so the // function and its return type — not a type alias — are what fix the // REST error payload a released client parses. diff --git a/test/wire-compat/wire-mutations.test.ts b/test/wire-compat/wire-mutations.test.ts index c3513637e1..b348eddcba 100644 --- a/test/wire-compat/wire-mutations.test.ts +++ b/test/wire-compat/wire-mutations.test.ts @@ -51,7 +51,7 @@ type WireMutation = { const MUTATIONS: readonly WireMutation[] = [ { breakClass: 'instance refusal: the daemon drops the mismatch response header', - file: 'src/daemon/server/http-instance-precondition.ts', + file: 'packages/daemon/src/server/http-instance-precondition.ts', name: 'refuseStaleDaemonInstance', from: "res.setHeader(DAEMON_HTTP_INSTANCE_MISMATCH_HEADER, 'true');", to: '', @@ -72,14 +72,14 @@ const MUTATIONS: readonly WireMutation[] = [ }, { breakClass: 'method naming: a released client keeps sending the old method name', - file: 'src/daemon/server/http-rpc-methods.ts', + file: 'packages/daemon/src/server/http-rpc-methods.ts', name: 'COMMAND_RPC_METHODS', from: "'agent-device.command'", to: "'agent-device.cmd'", }, { breakClass: 'method naming: the lease method table drops a released alias', - file: 'src/daemon/server/http-rpc-methods.ts', + file: 'packages/daemon/src/server/http-rpc-methods.ts', name: 'LEASE_RPC_METHOD_TO_COMMAND', from: "'agent-device.lease.allocate': 'lease_allocate',", to: '', @@ -100,7 +100,7 @@ const MUTATIONS: readonly WireMutation[] = [ }, { breakClass: 'auth projection: the header a released client authenticates with is dropped', - file: 'src/daemon/server/http-authorization.ts', + file: 'packages/daemon/src/server/http-authorization.ts', name: 'resolveToken', from: "typeof headers['x-agent-device-token'] === 'string'", to: 'false', @@ -114,42 +114,42 @@ const MUTATIONS: readonly WireMutation[] = [ }, { breakClass: 'upload ticket shape: a required preflight field is renamed', - file: 'src/daemon/resumable-upload.ts', + file: 'packages/daemon/src/resumable-upload.ts', name: 'BeginResumableUploadOptions', from: 'sha256: string;', to: 'checksum: string;', }, { breakClass: 'upload ticket shape: the preflight body parser requires a new field', - file: 'src/daemon/upload-http.ts', + file: 'packages/daemon/src/upload-http.ts', name: 'readUploadPreflightBody', from: "readRequiredText(record, 'uploadAttemptId')", to: "readRequiredText(record, 'attemptId')", }, { breakClass: '308 framing: resumable upload stops signalling continuation', - file: 'src/daemon/upload-http.ts', + file: 'packages/daemon/src/upload-http.ts', name: 'handleResumableUpload', from: 'res.statusCode = 308;', to: 'res.statusCode = 200;', }, { breakClass: 'artifact framing: the direct-upload route prefix moves', - file: 'src/daemon/upload-http.ts', + file: 'packages/daemon/src/upload-http.ts', name: 'DIRECT_UPLOAD_PATH_PREFIX', from: "'/upload/direct/'", to: "'/uploads/direct/'", }, { breakClass: 'artifact framing: the artifact inventory route stops answering its released path', - file: 'src/daemon/downloadable-artifact-http.ts', + file: 'packages/daemon/src/downloadable-artifact-http.ts', name: 'resolveDownloadableArtifactHttpRoute', from: "pathname === '/artifacts' || pathname === '/artifacts/'", to: "pathname === '/artifacts'", }, { breakClass: 'REST error framing: a released status mapping changes', - file: 'src/daemon/http-errors.ts', + file: 'packages/daemon/src/http-errors.ts', name: 'statusCodeForNormalizedError', from: 'INVALID_ARGS', to: 'BAD_ARGS', diff --git a/tsconfig.json b/tsconfig.json index 6af9b4e3ac..e0a9e4aefe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -34,6 +34,7 @@ { "path": "packages/capture-kit" }, { "path": "packages/command-registry" }, { "path": "packages/contracts" }, + { "path": "packages/daemon" }, { "path": "packages/daemon-contracts" }, { "path": "packages/device-selection" }, { "path": "packages/host-kit" },