From 56039fea74e753bc90dfdfb044c29ba171981b27 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 18:27:07 +0000 Subject: [PATCH 1/8] refactor: split generic host mechanics into @agent-device/host-kit (#2082 W1) The shared src/utils closure that blocked the platform-family moves lands on declared owners: generic host mechanics form a new private @agent-device/host-kit package between kernel and capture-kit, and capture-kit keeps capture, snapshot, and recording behavior, depending on host-kit for the mechanics it needs. tar-stream and yauzl move with the archive code. Every seam's exported subpaths are pinned in package-boundaries.test.ts, the layering model ranks the new zone, R13's allow-list names it, and each seam carries an exact eager-closure row. ADR-0019's substrate amendment describes the layout. Tests that mocked two of the moved modules separately became duplicate same-seam vi.mock factories, where the second silently replaced the first; those are merged, and the mocks that production code reaches past are pinned at their injection points instead. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- .fallowrc.json | 12 +++ .oxlintrc.json | 11 ++- AGENTS.md | 9 +- .../RunnerTapPointPolicy.swift | 2 +- .../0019-request-bound-platform-runtime.md | 28 ++++++ docs/agents/testing.md | 2 +- package.json | 3 +- .../ad-replay/src/internal/canonical-json.ts | 14 --- .../ad-replay/src/internal/plan-digest.ts | 2 +- packages/capture-kit/package.json | 51 +++++++++- .../capture-kit/src}/internal-entry.ts | 0 .../src}/mobile-snapshot-semantics.test.ts | 2 +- .../src}/mobile-snapshot-semantics.ts | 4 +- .../capture-kit/src}/png-resize.test.ts | 8 +- .../capture-kit/src}/png-resize.ts | 0 .../capture-kit/src}/png-rgb-difference.ts | 0 .../capture-kit/src}/png-size.test.ts | 6 +- .../capture-kit/src}/png-size.ts | 0 .../src}/png-worker-client.test.ts | 6 +- .../capture-kit/src}/png-worker-client.ts | 2 +- .../capture-kit/src}/png-worker-contract.ts | 0 .../capture-kit/src}/png-worker.test.ts | 2 +- .../capture-kit/src}/png-worker.ts | 0 .../utils => packages/capture-kit/src}/png.ts | 0 .../capture-kit/src}/screenshot-density.ts | 0 .../src}/screenshot-diff-pixels.ts | 0 .../src}/snapshot-occlusion.test.ts | 2 +- .../capture-kit/src}/snapshot-occlusion.ts | 2 +- ...pshot-quality-backend-capabilities.test.ts | 3 +- .../snapshot-quality-backend-capabilities.ts | 0 .../src/snapshot-quality-verdict.test.ts | 2 +- .../src/snapshot-quality-verdict.ts | 2 +- packages/capture-kit/src/tmp-dir.fixtures.ts | 20 ++++ packages/contracts/package.json | 96 +++++++++---------- packages/host-kit/package.json | 35 +++++++ packages/host-kit/src/exec.ts | 77 +++++++++++++++ packages/host-kit/src/fs.ts | 22 +++++ .../internal}/archive-extraction-tar.test.ts | 4 +- .../src/internal}/archive-extraction-tar.ts | 0 .../internal}/archive-extraction-zip.test.ts | 4 +- .../src/internal}/archive-extraction-zip.ts | 0 .../internal}/archive-extraction.fixtures.ts | 2 +- .../src/internal}/archive-extraction.ts | 0 .../src/internal}/archive-safety.test.ts | 2 +- .../host-kit/src/internal}/archive-safety.ts | 0 .../host-kit/src/internal}/artifact-limits.ts | 0 .../host-kit/src/internal}/atomic-file.ts | 0 .../src/internal}/byte-limit-stream.test.ts | 2 +- .../src/internal}/byte-limit-stream.ts | 0 .../src/internal}/device-isolation.ts | 0 .../src/internal}/diagnostics.test.ts | 4 +- .../host-kit/src/internal}/diagnostics.ts | 0 .../host-kit/src/internal}/env-map.ts | 1 - .../src/internal}/exec-windows-hide.test.ts | 2 +- .../host-kit/src/internal}/exec.test.ts | 6 +- .../host-kit/src/internal}/exec.ts | 1 + .../internal}/host-process-liveness.test.ts | 6 +- .../src/internal}/host-process.test.ts | 2 +- .../host-kit/src/internal}/host-process.ts | 0 .../src/internal}/location-coordinates.ts | 0 .../host-kit/src/internal}/method-scope.ts | 0 .../src/internal}/owned-process-reaper.ts | 0 .../internal}/owned-process-record.test.ts | 2 +- .../src/internal}/owned-process-record.ts | 0 .../internal}/owner-identity-liveness.test.ts | 4 +- .../src/internal}/owner-identity.test.ts | 4 +- .../host-kit/src/internal}/owner-identity.ts | 0 .../host-kit/src/internal}/parsing.ts | 0 .../src/internal}/path-resolution.test.ts | 2 +- .../host-kit/src/internal}/path-resolution.ts | 0 .../src/internal}/process-lock.test.ts | 10 +- .../host-kit/src/internal}/process-lock.ts | 0 .../host-kit/src/internal/project-root.ts | 22 +++++ .../src/internal/request-cancel.test.ts | 2 +- .../host-kit/src/internal/request-cancel.ts | 0 .../host-kit/src/internal/request-progress.ts | 0 .../host-kit/src/internal}/retry.test.ts | 6 +- .../host-kit/src/internal}/retry.ts | 1 + .../host-kit/src/internal}/scoped-provider.ts | 0 .../src/internal}/shell-quote.test.ts | 2 +- .../host-kit/src/internal}/shell-quote.ts | 0 .../host-kit/src/internal}/source-value.ts | 2 + .../host-kit/src/internal}/success-text.ts | 0 .../host-kit/src/internal}/timeouts.ts | 0 .../host-kit/src/internal/tmp-dir.fixtures.ts | 21 ++++ .../host-kit/src/internal}/ttl-memo.test.ts | 2 +- .../host-kit/src/internal}/ttl-memo.ts | 0 .../host-kit/src/internal}/version.test.ts | 62 ++++++++++-- .../host-kit/src/internal}/version.ts | 21 +--- packages/host-kit/src/request.ts | 12 +++ packages/host-kit/src/values.ts | 39 ++++++++ packages/host-kit/tsconfig.json | 12 +++ packages/kernel/package.json | 46 +++++---- packages/kernel/src/collections.ts | 28 ++++++ .../kernel/src}/keyed-lock.test.ts | 2 +- .../kernel/src}/rect-center.test.ts | 2 +- .../kernel/src}/rect-center.ts | 0 .../kernel/src}/scroll-indicator.ts | 0 packages/maestro/src/internal/shared.ts | 32 +------ .../__tests__/session-test-discovery.test.ts | 3 +- .../src/internal/session-test-artifacts.ts | 14 +-- .../src/internal/session-test-discovery.ts | 2 +- pnpm-lock.yaml | 35 +++++++ .../__tests__/fallow-fixture-policy.test.ts | 2 +- .../__tests__/test-file-size-ratchet.test.ts | 2 +- scripts/check-affected/run.test.ts | 2 +- scripts/check-affected/run.ts | 2 +- scripts/check-replay-compat-provenance.ts | 14 +-- scripts/check-tmpdir-leaks-model.ts | 2 +- scripts/check-xctest-selection.ts | 2 +- scripts/coverage-changed/run.ts | 2 +- scripts/depgraph/affected.test.ts | 2 +- scripts/fuzz/envelope.ts | 2 +- scripts/gate/check.ts | 2 +- scripts/gate/run.ts | 2 +- scripts/layering/model.ts | 1 + scripts/layering/package-boundaries.test.ts | 38 +++++++- .../layering/platform-package-policy.test.ts | 2 +- scripts/layering/platform-package-policy.ts | 3 +- scripts/lib/repo-git.ts | 15 +++ scripts/mutation/envelope.test.ts | 2 +- scripts/mutation/modules.ts | 4 +- scripts/mutation/run.ts | 2 +- scripts/mutation/selection.test.ts | 2 +- scripts/mutation/test-scope.test.ts | 2 +- scripts/mutation/test-scope.ts | 2 +- scripts/mutation/workspace-aliases.test.ts | 43 ++++++++- scripts/mutation/workspace-aliases.ts | 49 +++++++++- scripts/node-test-tmpdir.test.ts | 4 +- scripts/node-test-tmpdir.ts | 2 +- scripts/perf/cli.ts | 2 +- scripts/swift-toolchain-tmpdir.test.ts | 2 +- scripts/swift-toolchain-tmpdir.ts | 2 +- scripts/vitest-tmpdir-global-setup.test.ts | 2 +- scripts/wire-compat/run.ts | 13 +-- .../apple-runner-package-source.test.ts | 2 +- src/__tests__/cli-agent-cdp.test.ts | 4 +- src/__tests__/cli-auth-diagnostics.test.ts | 2 +- src/__tests__/cli-client-commands.test.ts | 2 +- src/__tests__/cli-debug-symbols.test.ts | 2 +- src/__tests__/cli-device-status.test.ts | 4 +- src/__tests__/cli-diff.test.ts | 2 +- src/__tests__/cli-react-devtools.test.ts | 4 +- src/__tests__/cli-web.test.ts | 2 +- src/__tests__/client-metro-companion.test.ts | 11 +-- .../client-metro-startup-cleanup.test.ts | 10 +- src/__tests__/client-metro.test.ts | 2 +- src/__tests__/daemon-entrypoint.test.ts | 4 +- src/__tests__/eager-closure-budgets.ts | 33 ++++++- src/__tests__/limrun-runtime.test.ts | 8 +- src/__tests__/process-memo-setup.ts | 2 +- .../test-utils/device-claim-store.ts | 2 +- src/__tests__/test-utils/exec-faults.ts | 2 +- src/__tests__/test-utils/fake-apple-tool.ts | 2 +- .../test-utils/filesystem-boundary-faults.ts | 2 +- src/__tests__/test-utils/host-process-mock.ts | 12 ++- src/__tests__/update-check.test.ts | 4 +- src/__tests__/upload-client.test.ts | 2 +- src/agent-device-client.ts | 2 +- src/bin.ts | 2 +- src/cli-schema/cli-config.ts | 4 +- src/cli-schema/cli-help-examples.test.ts | 2 +- src/cli-schema/cli-help.ts | 2 +- src/cli-schema/option-schema.ts | 2 +- src/cli.ts | 4 +- src/cli/auth-session.ts | 4 +- src/cli/commands/agent-cdp.ts | 2 +- src/cli/commands/connection-presentation.ts | 2 +- src/cli/commands/connection.ts | 2 +- src/cli/commands/device.ts | 2 +- src/cli/commands/generic.ts | 2 +- src/cli/commands/react-devtools.ts | 2 +- src/cli/commands/replay.ts | 2 +- src/cli/commands/screenshot.ts | 2 +- src/cli/connection/cloud-profile.ts | 2 +- src/cli/connection/cloud-webdriver-profile.ts | 2 +- .../connection/connect-provider-adapters.ts | 4 +- src/cli/connection/generated-config.ts | 2 +- src/cli/connection/limrun-profile.ts | 2 +- src/cli/connection/proxy-profile.ts | 2 +- src/cli/resolve-cli-options.ts | 2 +- src/client/client-companion-tunnel.ts | 4 +- src/client/client-normalizers.ts | 4 +- src/commands/batch/output.ts | 2 +- .../capture/runtime/diff-screenshot.test.ts | 2 +- src/commands/capture/runtime/screenshot.ts | 4 +- src/commands/capture/settings.ts | 2 +- src/commands/capture/snapshot.ts | 2 +- src/commands/command-flags.ts | 2 +- src/commands/input-audience.ts | 2 +- src/commands/interaction/output.ts | 2 +- .../interaction/runtime/gesture-command.ts | 2 +- src/commands/interaction/runtime/gestures.ts | 2 +- .../interaction/runtime/resolution.ts | 4 +- .../runtime/selector-read-shared.ts | 2 +- .../interaction/runtime/selector-read.ts | 2 +- .../interaction/runtime/settle.test.ts | 2 +- src/commands/interaction/runtime/settle.ts | 2 +- .../interaction/runtime/stable-capture.ts | 2 +- src/commands/management/output.ts | 2 +- src/commands/management/runtime/admin.ts | 2 +- src/commands/management/runtime/apps.ts | 2 +- src/commands/output-common.ts | 2 +- src/commands/perf/output.ts | 2 +- src/commands/recording/runtime/recording.ts | 2 +- src/commands/system/runtime/system.ts | 2 +- src/core/batch.ts | 2 +- src/core/dispatch-resolve.ts | 4 +- src/core/interaction-targeting.ts | 4 +- src/core/interaction-touch-point.ts | 2 +- src/core/interactors/android.ts | 4 +- src/core/interactors/harmonyos.ts | 2 +- src/core/interactors/linux.ts | 2 +- src/core/interactors/web.ts | 2 +- src/core/lease-scope.ts | 2 +- src/core/press-retarget.ts | 2 +- src/core/selector-pipeline.ts | 2 +- src/core/snapshot-state.ts | 2 +- .../android-dialog-readiness.test.ts | 2 +- src/daemon/__tests__/daemon-exit-wait.test.ts | 4 +- .../__tests__/daemon-process-takeover.test.ts | 2 +- src/daemon/__tests__/daemon-stop.test.ts | 5 +- .../deferred-interaction-outcome.test.ts | 2 +- .../__tests__/device-claim-prune.test.ts | 6 +- src/daemon/__tests__/device-claims.test.ts | 4 +- src/daemon/__tests__/device-ready.test.ts | 4 +- ...rable-capture-resource-transitions.test.ts | 2 +- .../filesystem-boundary-faults.test.ts | 2 +- .../__tests__/http-server-artifacts.test.ts | 2 +- .../post-gesture-no-effect-claim.test.ts | 2 +- .../post-gesture-stabilization.test.ts | 2 +- .../__tests__/request-execution-scope.test.ts | 4 +- .../__tests__/request-handler-catalog.test.ts | 2 +- .../request-router-android-modal.test.ts | 4 +- .../__tests__/request-router-cost.test.ts | 2 +- .../__tests__/request-router-open.test.ts | 4 +- .../request-router-screenshot.test.ts | 2 +- .../request-router-session-address.test.ts | 4 +- src/daemon/__tests__/resumable-upload.test.ts | 2 +- src/daemon/__tests__/runtime-session.test.ts | 2 +- .../screen-recording-boundary-faults.test.ts | 2 +- .../__tests__/screenshot-overlay.test.ts | 2 +- .../__tests__/screenshot-runtime-fixture.ts | 2 +- .../snapshot-command-runtime.test.ts | 2 +- .../__tests__/snapshot-runtime-fixture.ts | 2 +- src/daemon/__tests__/upload.test.ts | 2 +- .../daemon-runtime-port-targets.test.ts | 2 +- .../__tests__/daemon-runtime-port.test.ts | 4 +- .../wait-for-animation-to-end.test.ts | 2 +- .../maestro/daemon-runtime-port-support.ts | 2 +- .../adapters/maestro/daemon-runtime-port.ts | 4 +- .../adapters/maestro/daemon-runtime-tap.ts | 4 +- .../maestro/maestro-screenshot-comparison.ts | 6 +- .../adapters/maestro/run-script-execution.ts | 4 +- .../android-snapshot-timeout-evidence.ts | 2 +- src/daemon/android-system-dialog.ts | 6 +- src/daemon/app-event-runtime.ts | 2 +- src/daemon/app-switcher-runtime.ts | 2 +- src/daemon/artifact-archive.ts | 3 +- src/daemon/artifact-download.ts | 3 +- src/daemon/artifact-tracking.ts | 2 +- src/daemon/back-runtime.ts | 2 +- .../boundary-fault-transport.test.ts | 7 +- .../daemon-client-timeout-route.test.ts | 7 +- .../__tests__/daemon-launch-spec.test.ts | 2 +- src/daemon/client/daemon-client-lifecycle.ts | 15 ++- src/daemon/client/daemon-client-metadata.ts | 4 +- src/daemon/client/daemon-client-rpc.ts | 2 +- src/daemon/client/daemon-client-timeout.ts | 4 +- src/daemon/client/daemon-client-transport.ts | 4 +- src/daemon/client/daemon-client.ts | 2 +- src/daemon/client/daemon-launch-spec.ts | 4 +- src/daemon/code-signature-cache.ts | 2 +- src/daemon/code-signature.ts | 2 +- src/daemon/config.ts | 5 +- src/daemon/context.ts | 2 +- src/daemon/daemon-process.ts | 4 +- src/daemon/daemon-registration.ts | 2 +- src/daemon/daemon-shutdown-report.ts | 2 +- src/daemon/daemon-stop.ts | 4 +- src/daemon/deferred-interaction-outcome.ts | 2 +- src/daemon/device-claim-admission.ts | 2 +- src/daemon/device-claim-conflict.ts | 2 +- src/daemon/device-claim-inspection.ts | 5 +- src/daemon/device-claim-reconciliation.ts | 2 +- src/daemon/device-claims.ts | 11 ++- src/daemon/device-ready.ts | 2 +- .../durable-capture-resource-adoption.ts | 2 +- .../durable-capture-resource-recovery.ts | 2 +- src/daemon/durable-capture-resource-store.ts | 2 +- .../durable-capture-resource-transitions.ts | 2 +- src/daemon/focus-runtime.ts | 2 +- .../__tests__/interaction-settle.test.ts | 5 +- .../session-close-shutdown.fixtures.ts | 12 ++- .../__tests__/session-device-claims.test.ts | 4 +- .../session-open-execution-runtime.test.ts | 4 +- .../__tests__/session-open-runtime.test.ts | 4 +- .../session-replay-divergence.test.ts | 4 +- ...ion-replay-repair-record-exclusion.test.ts | 4 +- .../session-replay-repair-transaction.test.ts | 4 +- .../session-replay-runtime-maestro.test.ts | 2 +- ...replay-target-verification-runtime.test.ts | 4 +- .../__tests__/session-test-harness.ts | 11 +-- ...ssion-test-reporter-values-maestro.test.ts | 2 +- .../session-test-reporter-values.test.ts | 2 +- .../__tests__/session-test-runner.test.ts | 2 +- ...on-test-suite-command-cancellation.test.ts | 2 +- .../__tests__/session-test-suite.test.ts | 5 +- src/daemon/handlers/find.ts | 4 +- src/daemon/handlers/interaction-gesture.ts | 2 +- .../handlers/interaction-ios-tap-outcome.ts | 6 +- src/daemon/handlers/interaction-read.ts | 2 +- src/daemon/handlers/interaction-runtime.ts | 2 +- src/daemon/handlers/interaction-snapshot.ts | 2 +- src/daemon/handlers/interaction-targeting.ts | 2 +- .../interaction-touch-android-freshness.ts | 2 +- .../handlers/interaction-touch-direct-ios.ts | 2 +- .../handlers/interaction-touch-payload.ts | 2 +- .../interaction-touch-reference-frame.ts | 2 +- src/daemon/handlers/lease.ts | 2 +- src/daemon/handlers/react-native.ts | 6 +- src/daemon/handlers/session-app-deployment.ts | 2 +- .../handlers/session-app-source-deployment.ts | 2 +- src/daemon/handlers/session-clipboard.ts | 2 +- src/daemon/handlers/session-close-script.ts | 2 +- src/daemon/handlers/session-close.ts | 4 +- src/daemon/handlers/session-doctor-metro.ts | 2 +- src/daemon/handlers/session-doctor-output.ts | 2 +- src/daemon/handlers/session-doctor.ts | 6 +- src/daemon/handlers/session-inventory.ts | 2 +- src/daemon/handlers/session-open-execution.ts | 4 +- src/daemon/handlers/session-open-surface.ts | 2 +- src/daemon/handlers/session-open.ts | 2 +- .../handlers/session-replay-divergence.ts | 4 +- .../session-replay-maestro-failure.ts | 2 +- .../session-replay-maestro-observer.ts | 2 +- .../session-replay-maestro-runtime.ts | 4 +- .../session-replay-runtime-failure.ts | 2 +- src/daemon/handlers/session-replay-runtime.ts | 2 +- src/daemon/handlers/session-replay-trace.ts | 2 +- .../session-replay-video-recording.ts | 4 +- .../handlers/session-script-publication.ts | 2 +- src/daemon/handlers/session-state.ts | 2 +- .../handlers/session-test-shard-devices.ts | 2 +- .../handlers/session-test-suite-command.ts | 7 +- src/daemon/handlers/snapshot-settings.ts | 10 +- src/daemon/home-runtime.ts | 2 +- src/daemon/http-health.ts | 2 +- src/daemon/interaction-outcome-policy.ts | 2 +- src/daemon/ios-app-session-hint.ts | 2 +- src/daemon/keyboard-runtime.ts | 2 +- src/daemon/lease-context.ts | 2 +- src/daemon/lease-lifecycle.ts | 2 +- src/daemon/offscreen-target-probe.ts | 2 +- src/daemon/orientation-runtime.ts | 2 +- src/daemon/platform-request-scope.ts | 6 +- src/daemon/post-gesture-stability.ts | 3 +- src/daemon/provider-lease-expiry.ts | 5 +- src/daemon/recording-gestures.ts | 2 +- src/daemon/request-execution-locks.ts | 2 +- src/daemon/request-execution-scope.ts | 4 +- src/daemon/request-finalization.ts | 2 +- src/daemon/request-lock-policy.ts | 2 +- src/daemon/request-router.ts | 2 +- src/daemon/request-save-script-policy.ts | 2 +- src/daemon/resumable-upload-transfer.ts | 2 +- src/daemon/runtime-session.ts | 2 +- src/daemon/screenshot-overlay-draw.ts | 2 +- src/daemon/screenshot-overlay.ts | 2 +- src/daemon/screenshot-runtime.ts | 2 +- src/daemon/scroll-runtime.ts | 2 +- src/daemon/selector-capture-runtime.ts | 2 +- src/daemon/selector-runtime-backend.ts | 2 +- src/daemon/server/daemon-idle-reap.ts | 2 +- .../daemon-runtime-web-close-teardown.test.ts | 6 +- src/daemon/server/daemon-runtime.ts | 18 ++-- .../server/daemon-session-lease-finalizer.ts | 2 +- src/daemon/server/daemon-shutdown-claims.ts | 2 +- src/daemon/server/http-server.ts | 7 +- src/daemon/server/server-lifecycle.ts | 4 +- src/daemon/server/transport.ts | 7 +- src/daemon/session-action-recorder.ts | 2 +- src/daemon/session-event-log-window.ts | 2 +- src/daemon/session-event-log.ts | 4 +- src/daemon/session-event-request.ts | 2 +- src/daemon/session-paths.ts | 2 +- src/daemon/session-recovery-hints.ts | 2 +- src/daemon/session-script-writer.ts | 4 +- src/daemon/session-selector.ts | 2 +- src/daemon/session-store.ts | 4 +- src/daemon/session-target-evidence.ts | 2 +- src/daemon/session-teardown.ts | 2 +- src/daemon/snapshot-command-runtime.ts | 2 +- src/daemon/sparse-fallback-screenshot.ts | 2 +- src/daemon/touch-runtime.ts | 2 +- src/daemon/tv-remote-runtime.ts | 2 +- src/daemon/type-text-runtime.ts | 2 +- src/daemon/wait-conditional-selector.ts | 2 +- src/mcp/command-tools.ts | 2 +- src/mcp/protocol-era.ts | 2 +- src/mcp/tool-ref-pins.ts | 2 +- src/metro/client-metro.ts | 8 +- ...tform-runtime-android-application-tools.ts | 2 +- src/platform-runtime-android-emulator-host.ts | 3 +- src/platform-runtime-app-log-process.test.ts | 5 +- src/platform-runtime-app-log-process.ts | 5 +- ...latform-runtime-apple-application-tools.ts | 2 +- src/platform-runtime-host.ts | 2 +- src/platform-runtime-operation-host.ts | 2 +- src/platform-runtime-resource-cleanup.ts | 3 +- src/platform-runtime-runtime-hints.ts | 2 +- ...m-runtime-screen-recording-android-host.ts | 2 +- ...screen-recording-apple-runner-transport.ts | 4 +- ...een-recording-apple-simulator-host.test.ts | 4 +- ...untime-screen-recording-apple-transport.ts | 6 +- ...time-screen-recording-process-host.test.ts | 4 +- ...m-runtime-screen-recording-process-host.ts | 2 +- src/platform-runtime/request-providers.ts | 2 +- .../__tests__/install-source.test.ts | 2 +- .../android/__tests__/adb-executor.test.ts | 6 +- .../__tests__/adb-provider-scope.test.ts | 2 +- .../__tests__/device-input-state.test.ts | 2 +- .../__tests__/emulator-lifecycle.test.ts | 6 +- .../__tests__/ime-helper-security.test.ts | 2 +- .../snapshot-capture-failure-reason.test.ts | 4 +- .../__tests__/snapshot-clickability.test.ts | 4 +- .../__tests__/snapshot-helper-session.test.ts | 2 +- .../snapshot-occlusion-context.test.ts | 4 +- .../android/__tests__/snapshot.test.ts | 20 ++-- .../__tests__/text-input-test-ime.test.ts | 2 +- src/platforms/android/adb-host-binding.ts | 5 +- src/platforms/android/adb.ts | 2 +- src/platforms/android/alert-detection.ts | 2 +- src/platforms/android/alert.ts | 6 +- src/platforms/android/app-deployment.ts | 2 +- src/platforms/android/app-lifecycle.ts | 4 +- src/platforms/android/device-input-state.ts | 4 +- src/platforms/android/emulator-lifecycle.ts | 14 ++- src/platforms/android/fill-verification.ts | 2 +- .../android/helper-package-install.ts | 2 +- src/platforms/android/ime-recovery-marker.ts | 2 +- src/platforms/android/manifest.ts | 2 +- .../android/perf-native-artifacts.ts | 2 +- src/platforms/android/perf-native-report.ts | 2 +- src/platforms/android/perf.ts | 2 +- src/platforms/android/settings.ts | 2 +- .../android/snapshot-helper-capture.ts | 2 +- .../android/snapshot-helper-runtime.ts | 2 +- .../snapshot-helper-session-lifecycle.ts | 2 +- .../android/snapshot-helper-session.ts | 2 +- src/platforms/android/snapshot.ts | 6 +- src/platforms/android/text-input.ts | 4 +- src/platforms/android/touch-helper.ts | 8 +- src/platforms/apple/alert.ts | 2 +- .../core/__tests__/app-launch-url.test.ts | 6 +- .../apple/core/__tests__/apps.test.ts | 28 +++--- .../core/__tests__/debug-symbols.test.ts | 2 +- .../__tests__/install-artifact.fixtures.ts | 2 +- .../apple/core/__tests__/perf.test.ts | 6 +- .../apple/core/__tests__/plist.test.ts | 6 +- .../core/__tests__/screenshot-density.test.ts | 2 +- .../apple/core/__tests__/screenshot.test.ts | 27 +++--- .../apple/core/__tests__/simulator.test.ts | 10 +- src/platforms/apple/core/app-device-io.ts | 2 +- src/platforms/apple/core/app-launch.ts | 11 ++- src/platforms/apple/core/app-resolution.ts | 2 +- src/platforms/apple/core/app-settings.ts | 6 +- .../core/debug-symbols/crash-artifact.ts | 2 +- .../apple/core/debug-symbols/dsym.ts | 2 +- .../apple/core/debug-symbols/report.ts | 2 +- .../apple/core/debug-symbols/symbolication.ts | 2 +- .../apple/core/debug-symbols/utils.ts | 2 +- src/platforms/apple/core/devicectl.ts | 2 +- src/platforms/apple/core/install-artifact.ts | 4 +- src/platforms/apple/core/perf-xctrace.ts | 2 +- src/platforms/apple/core/perf.ts | 12 ++- .../apple/core/physical-device-control.ts | 2 +- .../apple/core/physical-device-coredevice.ts | 2 +- .../apple/core/physical-device-files.ts | 2 +- .../apple/core/physical-device-screenshot.ts | 2 +- src/platforms/apple/core/runner-host.ts | 46 +++++---- .../apple/core/screenshot-status-bar.ts | 4 +- src/platforms/apple/core/screenshot.ts | 16 ++-- src/platforms/apple/core/simctl.ts | 4 +- src/platforms/apple/core/simulator.ts | 26 +++-- .../apple/core/tool-provider-types.ts | 2 +- src/platforms/apple/core/tool-provider.ts | 4 +- src/platforms/apple/interactor.ts | 6 +- src/platforms/apple/os/macos/helper.ts | 2 +- src/platforms/apple/os/macos/host-provider.ts | 2 +- .../harmonyos/__tests__/app-lifecycle.test.ts | 6 +- .../harmonyos/__tests__/doctor.test.ts | 6 +- src/platforms/harmonyos/__tests__/hdc.test.ts | 6 +- .../harmonyos/__tests__/input-actions.test.ts | 2 +- src/platforms/harmonyos/app-lifecycle.ts | 2 +- src/platforms/harmonyos/hdc.ts | 2 +- src/platforms/harmonyos/input-actions.ts | 2 +- src/platforms/harmonyos/snapshot.ts | 2 +- .../install-artifact-archive-context.ts | 2 +- src/platforms/install-source-archive.ts | 7 +- src/platforms/install-source-download.ts | 4 +- src/platforms/install-source.ts | 4 +- .../linux/__tests__/atspi-bridge.test.ts | 6 +- .../linux/__tests__/clipboard.test.ts | 6 +- .../linux/__tests__/input-actions.test.ts | 6 +- src/platforms/linux/input-actions.ts | 2 +- src/platforms/linux/snapshot.ts | 2 +- src/platforms/linux/tool-provider.ts | 15 ++- src/platforms/toolchain-probe.ts | 2 +- src/platforms/vega/app-lifecycle.ts | 2 +- src/platforms/vega/input-actions.ts | 2 +- src/platforms/vega/tool-provider.ts | 4 +- .../agent-browser-boundary-faults.test.ts | 2 +- src/platforms/web/agent-browser-install.ts | 2 +- .../web/agent-browser-lifecycle.test.ts | 16 ++-- src/platforms/web/agent-browser-lifecycle.ts | 9 +- src/platforms/web/agent-browser-network.ts | 2 +- .../web/agent-browser-process-record.ts | 7 +- .../web/agent-browser-provider.test.ts | 7 +- src/platforms/web/agent-browser-provider.ts | 11 ++- src/platforms/web/agent-browser-tool.test.ts | 2 +- src/platforms/web/agent-browser-tool.ts | 6 +- src/platforms/web/provider.ts | 2 +- src/provider-webdriver.ts | 4 +- src/recording/__tests__/overlay.test.ts | 5 +- .../__tests__/recording-scripts.test.ts | 2 +- src/recording/output-path.ts | 2 +- src/recording/overlay.ts | 4 +- src/remote/remote-config-core.ts | 4 +- src/remote/remote-config-schema.ts | 2 +- src/remote/remote-connection-state.ts | 4 +- src/remote/upload-client-artifact.ts | 2 +- src/replay/script-source-bundle.ts | 2 +- src/replay/source-discovery.ts | 2 +- .../__tests__/screenshot-diff.test.ts | 10 +- .../screenshot-diff-region-overlay.ts | 2 +- .../screenshot-diff-region-split.ts | 2 +- .../screenshot-diff-regions.ts | 2 +- src/screenshot-diff/screenshot-diff.ts | 4 +- src/sdk/limrun-runtime-dependencies.ts | 4 +- .../__tests__/warnings.test.ts | 2 +- src/snapshot/snapshot-freshness/recovery.ts | 2 +- src/snapshot/snapshot-lines.ts | 2 +- .../snapshot-presentation/ios/rows.ts | 2 +- .../snapshot-presentation/ios/scroll.ts | 2 +- src/snapshot/snapshot-presentation/tree.ts | 2 +- src/snapshot/snapshot-visibility.ts | 2 +- .../atomic-publish-ownership.test.ts | 2 +- .../__tests__/daemon-client-lifecycle.test.ts | 24 ++--- src/utils/__tests__/daemon-client.test.ts | 20 ++-- .../__tests__/exec-boundary-faults.test.ts | 2 +- src/utils/__tests__/process-exit.test.ts | 6 +- src/utils/__tests__/swift-cache.test.ts | 5 +- src/utils/keyed-lock.ts | 1 - src/utils/output.ts | 2 +- src/utils/process-exit.ts | 2 +- src/utils/result-serialization.ts | 2 +- src/utils/screenshot-result.ts | 2 +- src/utils/scroll-edge-state.ts | 2 +- src/utils/source-value.test.ts | 7 +- src/utils/swift-cache.ts | 19 +--- src/utils/update-check.ts | 2 +- src/utils/video.ts | 4 +- stryker.config.json | 3 +- .../live-form-scenario.ts | 2 +- test/integration/cli-exit-flush.test.ts | 2 +- test/integration/cli-json.ts | 2 +- .../client-api-doc-snippets.test.ts | 2 +- .../daemon-leak-oracle-cli.test.ts | 3 +- .../daemon-replace-exit-flush.test.ts | 2 +- .../installed-package-metro.test.ts | 2 +- .../snapshot-backend-conformance.ts | 2 +- test/integration/limrun-public-types.test.ts | 2 +- .../active-session-script-publication.test.ts | 2 +- .../provider-scenarios/android-world.ts | 2 +- .../provider-scenarios/assertions.ts | 2 +- .../daemon-http-boundary-cancellation.test.ts | 2 +- .../daemon-http-disconnect.test.ts | 2 +- .../daemon-http-server.test.ts | 8 +- .../daemon-transport.test.ts | 2 +- .../integration/provider-scenarios/harness.ts | 4 +- .../provider-scenarios/providers.ts | 2 +- .../smoke-clean-xcuitest-derived.test.ts | 2 +- test/integration/smoke-cli.test.ts | 2 +- test/integration/smoke-daemon-clean.test.ts | 4 +- test/integration/smoke-web-platform.test.ts | 2 +- test/integration/support/daemon-leak-model.ts | 2 +- .../integration/support/daemon-leak-oracle.ts | 5 +- test/integration/test-helpers.ts | 4 +- .../output-economy.baseline.test.ts | 2 +- .../owner-files-no-leak.test.ts | 2 +- tsdown.config.ts | 2 +- vitest.mutation.config.ts | 8 +- 593 files changed, 1711 insertions(+), 1080 deletions(-) delete mode 100644 packages/ad-replay/src/internal/canonical-json.ts rename {src/utils => packages/capture-kit/src}/internal-entry.ts (100%) rename {src/utils/__tests__ => packages/capture-kit/src}/mobile-snapshot-semantics.test.ts (99%) rename {src/snapshot => packages/capture-kit/src}/mobile-snapshot-semantics.ts (98%) rename {src/utils/__tests__ => packages/capture-kit/src}/png-resize.test.ts (86%) rename {src/utils => packages/capture-kit/src}/png-resize.ts (100%) rename {src/utils => packages/capture-kit/src}/png-rgb-difference.ts (100%) rename {src/utils/__tests__ => packages/capture-kit/src}/png-size.test.ts (85%) rename {src/utils => packages/capture-kit/src}/png-size.ts (100%) rename {src/utils/__tests__ => packages/capture-kit/src}/png-worker-client.test.ts (96%) rename {src/utils => packages/capture-kit/src}/png-worker-client.ts (99%) rename {src/utils => packages/capture-kit/src}/png-worker-contract.ts (100%) rename {src/utils/__tests__ => packages/capture-kit/src}/png-worker.test.ts (96%) rename {src/utils => packages/capture-kit/src}/png-worker.ts (100%) rename {src/utils => packages/capture-kit/src}/png.ts (100%) rename {src/utils => packages/capture-kit/src}/screenshot-density.ts (100%) rename {src/utils => packages/capture-kit/src}/screenshot-diff-pixels.ts (100%) rename {src/snapshot/__tests__ => packages/capture-kit/src}/snapshot-occlusion.test.ts (99%) rename {src/snapshot => packages/capture-kit/src}/snapshot-occlusion.ts (99%) rename src/snapshot-quality/backend-capabilities.test.ts => packages/capture-kit/src/snapshot-quality-backend-capabilities.test.ts (99%) rename src/snapshot-quality/backend-capabilities.ts => packages/capture-kit/src/snapshot-quality-backend-capabilities.ts (100%) rename src/snapshot-quality/__tests__/verdict.test.ts => packages/capture-kit/src/snapshot-quality-verdict.test.ts (98%) rename src/snapshot-quality/verdict.ts => packages/capture-kit/src/snapshot-quality-verdict.ts (97%) create mode 100644 packages/capture-kit/src/tmp-dir.fixtures.ts create mode 100644 packages/host-kit/package.json create mode 100644 packages/host-kit/src/exec.ts create mode 100644 packages/host-kit/src/fs.ts rename {src/utils/__tests__ => packages/host-kit/src/internal}/archive-extraction-tar.test.ts (90%) rename {src/utils => packages/host-kit/src/internal}/archive-extraction-tar.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/archive-extraction-zip.test.ts (90%) rename {src/utils => packages/host-kit/src/internal}/archive-extraction-zip.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/archive-extraction.fixtures.ts (97%) rename {src/utils => packages/host-kit/src/internal}/archive-extraction.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/archive-safety.test.ts (98%) rename {src/utils => packages/host-kit/src/internal}/archive-safety.ts (100%) rename {src/utils => packages/host-kit/src/internal}/artifact-limits.ts (100%) rename {src/utils => packages/host-kit/src/internal}/atomic-file.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/byte-limit-stream.test.ts (96%) rename {src/utils => packages/host-kit/src/internal}/byte-limit-stream.ts (100%) rename {src/utils => packages/host-kit/src/internal}/device-isolation.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/diagnostics.test.ts (98%) rename {src/utils => packages/host-kit/src/internal}/diagnostics.ts (100%) rename {src/utils => packages/host-kit/src/internal}/env-map.ts (52%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/exec-windows-hide.test.ts (98%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/exec.test.ts (99%) rename {src/utils => packages/host-kit/src/internal}/exec.ts (99%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/host-process-liveness.test.ts (92%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/host-process.test.ts (99%) rename {src/utils => packages/host-kit/src/internal}/host-process.ts (100%) rename {src/utils => packages/host-kit/src/internal}/location-coordinates.ts (100%) rename {src/utils => packages/host-kit/src/internal}/method-scope.ts (100%) rename {src/utils => packages/host-kit/src/internal}/owned-process-reaper.ts (100%) rename {src/utils => packages/host-kit/src/internal}/owned-process-record.test.ts (99%) rename {src/utils => packages/host-kit/src/internal}/owned-process-record.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/owner-identity-liveness.test.ts (96%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/owner-identity.test.ts (96%) rename {src/utils => packages/host-kit/src/internal}/owner-identity.ts (100%) rename {src/utils => packages/host-kit/src/internal}/parsing.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/path-resolution.test.ts (91%) rename {src/utils => packages/host-kit/src/internal}/path-resolution.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/process-lock.test.ts (92%) rename {src/utils => packages/host-kit/src/internal}/process-lock.ts (100%) create mode 100644 packages/host-kit/src/internal/project-root.ts rename src/request/cancel.test.ts => packages/host-kit/src/internal/request-cancel.test.ts (99%) rename src/request/cancel.ts => packages/host-kit/src/internal/request-cancel.ts (100%) rename src/request/progress.ts => packages/host-kit/src/internal/request-progress.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/retry.test.ts (96%) rename {src/utils => packages/host-kit/src/internal}/retry.ts (99%) rename {src/utils => packages/host-kit/src/internal}/scoped-provider.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/shell-quote.test.ts (92%) rename {src/utils => packages/host-kit/src/internal}/shell-quote.ts (100%) rename {src/utils => packages/host-kit/src/internal}/source-value.ts (98%) rename {src/utils => packages/host-kit/src/internal}/success-text.ts (100%) rename {src/utils => packages/host-kit/src/internal}/timeouts.ts (100%) create mode 100644 packages/host-kit/src/internal/tmp-dir.fixtures.ts rename {src/utils/__tests__ => packages/host-kit/src/internal}/ttl-memo.test.ts (96%) rename {src/utils => packages/host-kit/src/internal}/ttl-memo.ts (100%) rename {src/utils/__tests__ => packages/host-kit/src/internal}/version.test.ts (56%) rename {src/utils => packages/host-kit/src/internal}/version.ts (63%) create mode 100644 packages/host-kit/src/request.ts create mode 100644 packages/host-kit/src/values.ts create mode 100644 packages/host-kit/tsconfig.json rename {src/utils/__tests__ => packages/kernel/src}/keyed-lock.test.ts (97%) rename {src/utils/__tests__ => packages/kernel/src}/rect-center.test.ts (82%) rename {src/utils => packages/kernel/src}/rect-center.ts (100%) rename {src/utils => packages/kernel/src}/scroll-indicator.ts (100%) create mode 100644 scripts/lib/repo-git.ts delete mode 100644 src/utils/keyed-lock.ts diff --git a/.fallowrc.json b/.fallowrc.json index 121bc33f18..66eb67b5b7 100644 --- a/.fallowrc.json +++ b/.fallowrc.json @@ -65,6 +65,11 @@ "file": "src/platforms/android/perf.ts", "exports": ["sampleAndroidMemoryPerf"] }, + { + "comment": "Apple perf sampling metadata is selected through the same lazy platform host; Fallow cannot follow the dynamic property read in src/platform-runtime-perf-host.ts.", + "file": "src/platforms/apple/core/perf.ts", + "exports": ["buildAppleFrameSamplingMetadata", "buildAppleMemorySamplingMetadata"] + }, { "comment": "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/{lease,session,snapshot,react-native,record-trace,find,interaction}.ts", @@ -212,6 +217,13 @@ "rules": { "unused-types": "off" } + }, + { + "comment": "Host-kit seam façades: same false-positive shape as the contracts façades above — each seam names every type its re-exported functions put in a public signature, and callers use those types structurally without importing the name. unused-exports (the VALUE check) stays on.", + "files": ["packages/host-kit/src/*.ts"], + "rules": { + "unused-types": "off" + } } ], "production": { diff --git a/.oxlintrc.json b/.oxlintrc.json index ba1f3d3a0a..c88ec9613b 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -37,7 +37,7 @@ }, "overrides": [ { - "files": ["src/**/*.ts"], + "files": ["src/**/*.ts", "packages/capture-kit/src/**/*.ts"], "rules": { "eslint/no-restricted-imports": [ "error", @@ -45,7 +45,7 @@ "paths": [ { "name": "node:child_process", - "message": "Use process helpers from src/utils/exec.ts instead of importing node:child_process directly." + "message": "Use process helpers from @agent-device/capture-kit/exec instead of importing node:child_process directly." } ] } @@ -53,7 +53,12 @@ } }, { - "files": ["src/utils/exec.ts", "src/**/*.test.ts", "src/**/__tests__/**/*.ts"], + "files": [ + "packages/capture-kit/src/exec.ts", + "packages/capture-kit/src/*.test.ts", + "src/**/*.test.ts", + "src/**/__tests__/**/*.ts" + ], "rules": { "eslint/no-restricted-imports": ["error", { "paths": [] }] } diff --git a/AGENTS.md b/AGENTS.md index 5ec92172d5..45daae9698 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -61,9 +61,10 @@ Read the declaration rather than maintaining a prose copy: - 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` -Shared selector parsing and matching belongs in `@agent-device/selectors`; request cancellation and -progress in `src/request`; cross-layer contracts in `src/contracts`; CLI flags in -`src/commands/cli-grammar`; cross-surface schema composition in `src/cli-schema`. +Shared selector parsing and matching belongs in `@agent-device/selectors`; request cancellation +and progress in `@agent-device/capture-kit` (`request-cancel`, `request-progress`); cross-layer +contracts in `src/contracts`; CLI flags in `src/commands/cli-grammar`; cross-surface schema +composition in `src/cli-schema`. The enforced registries are self-declaring. A failing completeness, parity, coverage, timeout, layering, or construction gate means the new cell or path is unclassified; do not suppress or @@ -123,7 +124,7 @@ The OS-neutral Apple runner lives under `packages/platform-apple/src/runner/`. F retry policy, or command typing, start at `runner-contract.ts`; transport stays below session/client behavior, and xctestrun build/cache logic stays outside request execution. -Diagnostics use `src/utils/diagnostics.ts`. Request diagnostics belong in the session request log; +Diagnostics use `@agent-device/capture-kit/diagnostics`. Request diagnostics belong in the session request log; session artifact paths come from `src/daemon/session-store.ts`. App/device logs remain in `app.log`; Apple runner and xcodebuild output remains in `runner.log`. diff --git a/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift b/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift index aeec438aa9..8571450abb 100644 --- a/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +++ b/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift @@ -11,7 +11,7 @@ import XCTest // This is pure geometry on purpose — no XCUIElement — so the exact decision // can be proven against the golden fixture table shared with the TS twin: // table: contracts/fixtures/tap-point-policy.json -// TS twin: src/snapshot/mobile-snapshot-semantics.ts#isTapPointInsideViewport +// TS twin: packages/contracts/src/mobile-snapshot-semantics.ts#isTapPointInsideViewport // TS test: src/snapshot/__tests__/tap-point-policy-parity.test.ts // Drift on either side turns CI red without needing a simulator. enum TapPointPolicy { diff --git a/docs/adr/0019-request-bound-platform-runtime.md b/docs/adr/0019-request-bound-platform-runtime.md index ce74f03674..f901f8d149 100644 --- a/docs/adr/0019-request-bound-platform-runtime.md +++ b/docs/adr/0019-request-bound-platform-runtime.md @@ -132,6 +132,34 @@ platform-common package, and it preserves the package façades' implementation-l Its introduction carries the normal workspace-package compliance surface: `check:affected` selection, R11/R13 package enumeration, and the composite typecheck project list. +> **Amendment (#2082): the substrate below the platform families.** Retiring the shared +> `src/utils` and `src/platforms` root surfaces (so the family trees can move behind their +> exports maps) forces every shared file onto a declared domain owner, and the paragraph above +> is amended to name that layout rather than let capture-kit absorb it: +> +> - `@agent-device/host-kit` owns generic host mechanics — process execution, supervision, and +> diagnostics; archives, streams, atomic files, locks, and path/device isolation; small host +> value helpers; request-scoped plumbing — behind a small deep surface of exactly four seams: +> `exec`, `fs`, `values`, `request`. Modules under `src/internal/` are reachable only through +> those seams; consumers import a seam, never an internal module. +> - `@agent-device/capture-kit` owns capture, snapshot, and recording behavior — PNG tooling, +> screenshot density and pixel diffing, snapshot occlusion, mobile snapshot semantics, +> quality verdicts and backend capability tables. Snapshot *behavior* is capture domain, not +> contracts vocabulary, and host mechanics are host-kit's, not capture-kit's. +> - `@agent-device/provision-kit` owns provisioning mechanics — install-artifact acquisition +> (local paths, archives, guarded network downloads) and host toolchain probing. +> - The enforced direction is `kernel < contracts < host-kit < capture-kit < provision-kit < +> platform/provider/daemon`. +> - Contracts stays vocabulary, plan models, and pure classification with no process, +> filesystem, or timer mechanics (the existing planted-red gate); platform-specific parsing +> stays with its family package and reaches legacy callers through composition, never by a +> family importing another owner's internals. +> +> Enforcement: each substrate package's exported subpaths are pinned in +> `package-boundaries.test.ts` (widening fails the gate), the contracts mechanics gate stays +> planted red, and the `platforms-root-shape` rule rejects any new shared file or directory +> appearing directly under `src/platforms`. + The Apple XCUITest runner client is a durable platform-owned implementation facet colocated inside `packages/platform-apple` as the `src/runner/` subtree (#2040) — Apple mechanics belong to the Apple package. R13 models the facet by enumeration rather than by exception sprawl: the family diff --git a/docs/agents/testing.md b/docs/agents/testing.md index b32c346d24..2d5c266759 100644 --- a/docs/agents/testing.md +++ b/docs/agents/testing.md @@ -129,7 +129,7 @@ whether tests distinguish changed decision logic. Do not infer redundancy from l Run `pnpm depgraph affected` before touching a high-fan-in module: ```sh -pnpm depgraph affected src/utils/exec.ts +pnpm depgraph affected packages/capture-kit/src/exec.ts pnpm depgraph affected src/daemon/ref-frame.ts --json --limit 25 ``` diff --git a/package.json b/package.json index 3bfa2f704b..ebaa46113b 100644 --- a/package.json +++ b/package.json @@ -161,7 +161,7 @@ "check:unit": "pnpm test:unit && pnpm check:tmpdir-leaks && pnpm test:smoke", "check": "pnpm check:tooling && pnpm check:fallow && pnpm check:unit", "prepack": "pnpm check:mcp-metadata && pnpm package:npm", - "typecheck": "tsc -b packages/xml packages/kernel packages/contracts packages/capture-kit packages/platform-apple packages/platform-android packages/platform-harmonyos packages/platform-vega packages/platform-linux packages/platform-web packages/ad-script packages/selectors packages/ad-replay packages/maestro packages/replay-test packages/provider-webdriver packages/provider-limrun && tsc -p tsconfig.json && tsc -p examples/sdk/tsconfig.json", + "typecheck": "tsc -b packages/xml packages/kernel packages/contracts packages/host-kit packages/capture-kit packages/platform-apple packages/platform-android packages/platform-harmonyos packages/platform-vega packages/platform-linux packages/platform-web packages/ad-script packages/selectors packages/ad-replay packages/maestro packages/replay-test packages/provider-webdriver packages/provider-limrun && tsc -p tsconfig.json && tsc -p examples/sdk/tsconfig.json", "test-app:install": "pnpm install --dir examples/test-app", "test-app:start": "pnpm --dir examples/test-app start", "test-app:ios": "pnpm --dir examples/test-app ios", @@ -278,6 +278,7 @@ "@agent-device/ad-script": "workspace:*", "@agent-device/capture-kit": "workspace:*", "@agent-device/contracts": "workspace:*", + "@agent-device/host-kit": "workspace:*", "@agent-device/kernel": "workspace:*", "@agent-device/maestro": "workspace:*", "@agent-device/platform-android": "workspace:*", diff --git a/packages/ad-replay/src/internal/canonical-json.ts b/packages/ad-replay/src/internal/canonical-json.ts deleted file mode 100644 index 14a0f40397..0000000000 --- a/packages/ad-replay/src/internal/canonical-json.ts +++ /dev/null @@ -1,14 +0,0 @@ -export function canonicalJson(value: unknown): string { - return JSON.stringify(sortKeysDeep(value)); -} - -function sortKeysDeep(value: unknown): unknown { - if (Array.isArray(value)) return value.map(sortKeysDeep); - if (!value || typeof value !== 'object') return value; - const record = value as Record; - return Object.fromEntries( - Object.keys(record) - .sort() - .map((key) => [key, sortKeysDeep(record[key])]), - ); -} diff --git a/packages/ad-replay/src/internal/plan-digest.ts b/packages/ad-replay/src/internal/plan-digest.ts index 1eafd390b3..58b0ff31d0 100644 --- a/packages/ad-replay/src/internal/plan-digest.ts +++ b/packages/ad-replay/src/internal/plan-digest.ts @@ -1,6 +1,6 @@ import { createHash } from 'node:crypto'; import type { SessionAction } from '@agent-device/contracts/session'; -import { canonicalJson } from './canonical-json.ts'; +import { canonicalJson } from '@agent-device/kernel/collections'; /** * ADR 0012 decision 4 / migration step 5: `planDigest` is SHA-256 over the diff --git a/packages/capture-kit/package.json b/packages/capture-kit/package.json index 002b5a0b1d..0b2ba0e64e 100644 --- a/packages/capture-kit/package.json +++ b/packages/capture-kit/package.json @@ -3,15 +3,64 @@ "version": "0.0.0", "private": true, "type": "module", - "description": "Private durable-capture mechanics shared by platform runtimes, providers, and daemon orchestration.", + "description": "Private host and durable-capture mechanics shared by platform runtimes, providers, and daemon orchestration: process execution, diagnostics, archives, PNG tooling, and request-scoped plumbing.", "dependencies": { "@agent-device/contracts": "workspace:*", + "@agent-device/host-kit": "workspace:*", "@agent-device/kernel": "workspace:*" }, "exports": { ".": { "types": "./src/index.ts", "default": "./src/index.ts" + }, + "./mobile-snapshot-semantics": { + "types": "./src/mobile-snapshot-semantics.ts", + "default": "./src/mobile-snapshot-semantics.ts" + }, + "./png": { + "types": "./src/png.ts", + "default": "./src/png.ts" + }, + "./png-resize": { + "types": "./src/png-resize.ts", + "default": "./src/png-resize.ts" + }, + "./png-rgb-difference": { + "types": "./src/png-rgb-difference.ts", + "default": "./src/png-rgb-difference.ts" + }, + "./png-size": { + "types": "./src/png-size.ts", + "default": "./src/png-size.ts" + }, + "./png-worker-client": { + "types": "./src/png-worker-client.ts", + "default": "./src/png-worker-client.ts" + }, + "./screenshot-density": { + "types": "./src/screenshot-density.ts", + "default": "./src/screenshot-density.ts" + }, + "./screenshot-diff-pixels": { + "types": "./src/screenshot-diff-pixels.ts", + "default": "./src/screenshot-diff-pixels.ts" + }, + "./snapshot-occlusion": { + "types": "./src/snapshot-occlusion.ts", + "default": "./src/snapshot-occlusion.ts" + }, + "./snapshot-quality-backend-capabilities": { + "types": "./src/snapshot-quality-backend-capabilities.ts", + "default": "./src/snapshot-quality-backend-capabilities.ts" + }, + "./snapshot-quality-verdict": { + "types": "./src/snapshot-quality-verdict.ts", + "default": "./src/snapshot-quality-verdict.ts" } + }, + "devDependencies": { + "@types/pngjs": "^6.0.5", + "pngjs": "^7.0.0" } } diff --git a/src/utils/internal-entry.ts b/packages/capture-kit/src/internal-entry.ts similarity index 100% rename from src/utils/internal-entry.ts rename to packages/capture-kit/src/internal-entry.ts diff --git a/src/utils/__tests__/mobile-snapshot-semantics.test.ts b/packages/capture-kit/src/mobile-snapshot-semantics.test.ts similarity index 99% rename from src/utils/__tests__/mobile-snapshot-semantics.test.ts rename to packages/capture-kit/src/mobile-snapshot-semantics.test.ts index fd452be447..bd87f817fe 100644 --- a/src/utils/__tests__/mobile-snapshot-semantics.test.ts +++ b/packages/capture-kit/src/mobile-snapshot-semantics.test.ts @@ -4,7 +4,7 @@ import { buildMobileSnapshotPresentation, classifyOffscreenScrollDirection, isConfirmedOnScreenProbe, -} from '../../snapshot/mobile-snapshot-semantics.ts'; +} from './mobile-snapshot-semantics.ts'; import { isNodeVisibleInEffectiveViewport } from '@agent-device/contracts/snapshot'; import type { Rect, SnapshotNode } from '@agent-device/kernel/snapshot'; diff --git a/src/snapshot/mobile-snapshot-semantics.ts b/packages/capture-kit/src/mobile-snapshot-semantics.ts similarity index 98% rename from src/snapshot/mobile-snapshot-semantics.ts rename to packages/capture-kit/src/mobile-snapshot-semantics.ts index 8e0c80bde9..bf6d0dc0ec 100644 --- a/src/snapshot/mobile-snapshot-semantics.ts +++ b/packages/capture-kit/src/mobile-snapshot-semantics.ts @@ -8,7 +8,7 @@ import { resolveEffectiveViewportRect, resolveViewportRect, } from '@agent-device/contracts/snapshot'; -import { inferVerticalScrollIndicatorDirections } from '../utils/scroll-indicator.ts'; +import { inferVerticalScrollIndicatorDirections } from '@agent-device/kernel/scroll-indicator'; import type { HiddenContentHint, Rect, SnapshotNode } from '@agent-device/kernel/snapshot'; type Direction = 'above' | 'below'; @@ -320,6 +320,7 @@ function classifyVerticalDirection(targetRect: Rect, viewportRect: Rect): Direct return null; } +// fallow-ignore-next-line complexity function isDiscoverableOffscreenNode(node: SnapshotNode): boolean { if (node.hittable === true) { return true; @@ -378,6 +379,7 @@ function findNearestVisibleScrollableAncestor( ); } +// fallow-ignore-next-line complexity function mergeScrollIndicatorDirections( nodes: SnapshotNode[], visibleNodeIndexes: Set, diff --git a/src/utils/__tests__/png-resize.test.ts b/packages/capture-kit/src/png-resize.test.ts similarity index 86% rename from src/utils/__tests__/png-resize.test.ts rename to packages/capture-kit/src/png-resize.test.ts index af8bc248c1..f9bc207e44 100644 --- a/src/utils/__tests__/png-resize.test.ts +++ b/packages/capture-kit/src/png-resize.test.ts @@ -2,10 +2,10 @@ import { afterAll, test } from 'vitest'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; -import { PNG } from '../png.ts'; -import { resizePngFileToScale } from '../png-resize.ts'; -import { terminatePngWorker } from '../png-worker-client.ts'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; +import { PNG } from './png.ts'; +import { resizePngFileToScale } from './png-resize.ts'; +import { terminatePngWorker } from './png-worker-client.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; afterAll(async () => { await terminatePngWorker(); diff --git a/src/utils/png-resize.ts b/packages/capture-kit/src/png-resize.ts similarity index 100% rename from src/utils/png-resize.ts rename to packages/capture-kit/src/png-resize.ts diff --git a/src/utils/png-rgb-difference.ts b/packages/capture-kit/src/png-rgb-difference.ts similarity index 100% rename from src/utils/png-rgb-difference.ts rename to packages/capture-kit/src/png-rgb-difference.ts diff --git a/src/utils/__tests__/png-size.test.ts b/packages/capture-kit/src/png-size.test.ts similarity index 85% rename from src/utils/__tests__/png-size.test.ts rename to packages/capture-kit/src/png-size.test.ts index e8ab097bad..a0bb63c35d 100644 --- a/src/utils/__tests__/png-size.test.ts +++ b/packages/capture-kit/src/png-size.test.ts @@ -3,9 +3,9 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { PNG } from '../png.ts'; -import { readPngSize } from '../png-size.ts'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; +import { PNG } from './png.ts'; +import { readPngSize } from './png-size.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; test('readPngSize reads PNG dimensions from the file header', async () => { const filePath = tmpPngPath('size'); diff --git a/src/utils/png-size.ts b/packages/capture-kit/src/png-size.ts similarity index 100% rename from src/utils/png-size.ts rename to packages/capture-kit/src/png-size.ts diff --git a/src/utils/__tests__/png-worker-client.test.ts b/packages/capture-kit/src/png-worker-client.test.ts similarity index 96% rename from src/utils/__tests__/png-worker-client.test.ts rename to packages/capture-kit/src/png-worker-client.test.ts index 4244e304f3..52a00cccb5 100644 --- a/src/utils/__tests__/png-worker-client.test.ts +++ b/packages/capture-kit/src/png-worker-client.test.ts @@ -1,15 +1,15 @@ import { afterAll, test } from 'vitest'; import assert from 'node:assert/strict'; import { AppError } from '@agent-device/kernel/errors'; -import { PNG } from '../png.ts'; +import { PNG } from './png.ts'; import { computePngRgbDifferenceAsync, computeScreenshotDiffPixelsAsync, decodePngAsync, encodePngAsync, terminatePngWorker, -} from '../png-worker-client.ts'; -import { computeScreenshotDiffPixels } from '../screenshot-diff-pixels.ts'; +} from './png-worker-client.ts'; +import { computeScreenshotDiffPixels } from './screenshot-diff-pixels.ts'; afterAll(async () => { await terminatePngWorker(); diff --git a/src/utils/png-worker-client.ts b/packages/capture-kit/src/png-worker-client.ts similarity index 99% rename from src/utils/png-worker-client.ts rename to packages/capture-kit/src/png-worker-client.ts index 932d4b6bb4..60f630547a 100644 --- a/src/utils/png-worker-client.ts +++ b/packages/capture-kit/src/png-worker-client.ts @@ -1,5 +1,5 @@ import { Worker } from 'node:worker_threads'; -import { emitDiagnostic } from './diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { AppError, toAppErrorCode } from '@agent-device/kernel/errors'; import { resolveInternalEntryModulePath } from './internal-entry.ts'; import { decodePng, PNG } from './png.ts'; diff --git a/src/utils/png-worker-contract.ts b/packages/capture-kit/src/png-worker-contract.ts similarity index 100% rename from src/utils/png-worker-contract.ts rename to packages/capture-kit/src/png-worker-contract.ts diff --git a/src/utils/__tests__/png-worker.test.ts b/packages/capture-kit/src/png-worker.test.ts similarity index 96% rename from src/utils/__tests__/png-worker.test.ts rename to packages/capture-kit/src/png-worker.test.ts index eb154f60e8..e4a2d9b140 100644 --- a/src/utils/__tests__/png-worker.test.ts +++ b/packages/capture-kit/src/png-worker.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; -import { resultTransferList } from '../png-worker.ts'; +import { resultTransferList } from './png-worker.ts'; test('resultTransferList transfers a buffer that fully owns its ArrayBuffer', () => { const owned = new Uint8Array(8).fill(1); diff --git a/src/utils/png-worker.ts b/packages/capture-kit/src/png-worker.ts similarity index 100% rename from src/utils/png-worker.ts rename to packages/capture-kit/src/png-worker.ts diff --git a/src/utils/png.ts b/packages/capture-kit/src/png.ts similarity index 100% rename from src/utils/png.ts rename to packages/capture-kit/src/png.ts diff --git a/src/utils/screenshot-density.ts b/packages/capture-kit/src/screenshot-density.ts similarity index 100% rename from src/utils/screenshot-density.ts rename to packages/capture-kit/src/screenshot-density.ts diff --git a/src/utils/screenshot-diff-pixels.ts b/packages/capture-kit/src/screenshot-diff-pixels.ts similarity index 100% rename from src/utils/screenshot-diff-pixels.ts rename to packages/capture-kit/src/screenshot-diff-pixels.ts diff --git a/src/snapshot/__tests__/snapshot-occlusion.test.ts b/packages/capture-kit/src/snapshot-occlusion.test.ts similarity index 99% rename from src/snapshot/__tests__/snapshot-occlusion.test.ts rename to packages/capture-kit/src/snapshot-occlusion.test.ts index f2548df449..1137058544 100644 --- a/src/snapshot/__tests__/snapshot-occlusion.test.ts +++ b/packages/capture-kit/src/snapshot-occlusion.test.ts @@ -1,7 +1,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; -import { annotateCoveredSnapshotNodes } from '../snapshot-occlusion.ts'; +import { annotateCoveredSnapshotNodes } from './snapshot-occlusion.ts'; // #1478 P5 codec-extraction regression: `annotateCoveredSnapshotNodes` marks // a touch candidate `interactionBlocked: 'covered'` when a later, floating diff --git a/src/snapshot/snapshot-occlusion.ts b/packages/capture-kit/src/snapshot-occlusion.ts similarity index 99% rename from src/snapshot/snapshot-occlusion.ts rename to packages/capture-kit/src/snapshot-occlusion.ts index 8a1c074211..ae26367e4e 100644 --- a/src/snapshot/snapshot-occlusion.ts +++ b/packages/capture-kit/src/snapshot-occlusion.ts @@ -1,6 +1,6 @@ import type { RawSnapshotNode, Rect } from '@agent-device/kernel/snapshot'; import { centerOfRect } from '@agent-device/kernel/snapshot'; -import { areRectsApproximatelyEqual, normalizeRect } from '../utils/rect-center.ts'; +import { areRectsApproximatelyEqual, normalizeRect } from '@agent-device/kernel/rect-center'; import { containsPoint } from '@agent-device/kernel/rect'; import { normalizeType, isViewportRootNode } from '@agent-device/contracts/snapshot'; diff --git a/src/snapshot-quality/backend-capabilities.test.ts b/packages/capture-kit/src/snapshot-quality-backend-capabilities.test.ts similarity index 99% rename from src/snapshot-quality/backend-capabilities.test.ts rename to packages/capture-kit/src/snapshot-quality-backend-capabilities.test.ts index 6ae1523df9..4cf2b012e6 100644 --- a/src/snapshot-quality/backend-capabilities.test.ts +++ b/packages/capture-kit/src/snapshot-quality-backend-capabilities.test.ts @@ -6,7 +6,7 @@ import { expect, test } from 'vitest'; import { ANDROID_SNAPSHOT_BACKEND_CAPABILITIES, SNAPSHOT_BACKEND_CAPABILITIES, -} from './backend-capabilities.ts'; +} from './snapshot-quality-backend-capabilities.ts'; type SnapshotBackendParityFixture = { backends: Array<{ @@ -33,6 +33,7 @@ const SNAPSHOT_BACKEND_PARITY_FIXTURE_PATH = path.resolve( import.meta.dirname, '..', '..', + '..', 'contracts', 'fixtures', 'ios-snapshot-backends.json', diff --git a/src/snapshot-quality/backend-capabilities.ts b/packages/capture-kit/src/snapshot-quality-backend-capabilities.ts similarity index 100% rename from src/snapshot-quality/backend-capabilities.ts rename to packages/capture-kit/src/snapshot-quality-backend-capabilities.ts diff --git a/src/snapshot-quality/__tests__/verdict.test.ts b/packages/capture-kit/src/snapshot-quality-verdict.test.ts similarity index 98% rename from src/snapshot-quality/__tests__/verdict.test.ts rename to packages/capture-kit/src/snapshot-quality-verdict.test.ts index d3c3796e43..ea8afbc157 100644 --- a/src/snapshot-quality/__tests__/verdict.test.ts +++ b/packages/capture-kit/src/snapshot-quality-verdict.test.ts @@ -5,7 +5,7 @@ import { isSparseSnapshotQualityVerdict, preferredSnapshotBackendForVerdict, readSnapshotQualityVerdict, -} from '../verdict.ts'; +} from './snapshot-quality-verdict.ts'; test('readSnapshotQualityVerdict accepts a well-formed verdict', () => { const verdict = readSnapshotQualityVerdict({ diff --git a/src/snapshot-quality/verdict.ts b/packages/capture-kit/src/snapshot-quality-verdict.ts similarity index 97% rename from src/snapshot-quality/verdict.ts rename to packages/capture-kit/src/snapshot-quality-verdict.ts index 623bd95949..2913abe32f 100644 --- a/src/snapshot-quality/verdict.ts +++ b/packages/capture-kit/src/snapshot-quality-verdict.ts @@ -1,5 +1,5 @@ import type { SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; -import { SNAPSHOT_QUALITY_BACKEND_CAPABILITIES } from './backend-capabilities.ts'; +import { SNAPSHOT_QUALITY_BACKEND_CAPABILITIES } from './snapshot-quality-backend-capabilities.ts'; const SNAPSHOT_QUALITY_STATES = new Set([ 'healthy', diff --git a/packages/capture-kit/src/tmp-dir.fixtures.ts b/packages/capture-kit/src/tmp-dir.fixtures.ts new file mode 100644 index 0000000000..f562d3030a --- /dev/null +++ b/packages/capture-kit/src/tmp-dir.fixtures.ts @@ -0,0 +1,20 @@ +// Package tests cannot reach root test helpers (R11); fixture copy of tmp-dir.ts. +import fs from 'node:fs'; +import fsPromises from 'node:fs/promises'; +import os from 'node:os'; +import path from 'node:path'; + +/** + * Creates a fresh scratch directory for one test. Cleanup is automatic: the + * unit suite redirects TMPDIR to a per-run directory (scripts/vitest-tmpdir-global-setup.ts) + * that gets removed in one recursive rm after every worker finishes, so + * individual tests never need their own afterEach/afterAll for this. + */ +export async function mkdtempForTest(prefix: string): Promise { + return fsPromises.mkdtemp(path.join(os.tmpdir(), prefix)); +} + +/** Sync counterpart of {@link mkdtempForTest}, for setup code that can't await. */ +export function mkdtempForTestSync(prefix: string): string { + return fs.mkdtempSync(path.join(os.tmpdir(), prefix)); +} diff --git a/packages/contracts/package.json b/packages/contracts/package.json index 0f93cfc8bd..5df12899ff 100644 --- a/packages/contracts/package.json +++ b/packages/contracts/package.json @@ -23,6 +23,10 @@ "types": "./src/android-clipboard-support.ts", "default": "./src/android-clipboard-support.ts" }, + "./android-helper-artifacts": { + "types": "./src/android-helper-artifacts.ts", + "default": "./src/android-helper-artifacts.ts" + }, "./android-input-ownership": { "types": "./src/android-input-ownership.ts", "default": "./src/android-input-ownership.ts" @@ -39,6 +43,10 @@ "types": "./src/android-system-chrome.ts", "default": "./src/android-system-chrome.ts" }, + "./android-touch-plan": { + "types": "./src/android-touch-plan.ts", + "default": "./src/android-touch-plan.ts" + }, "./app-deployment-runtime": { "types": "./src/app-deployment-runtime.ts", "default": "./src/app-deployment-runtime.ts" @@ -151,6 +159,10 @@ "types": "./src/command-platform-execution.ts", "default": "./src/command-platform-execution.ts" }, + "./daemon-owner-cleanup": { + "types": "./src/daemon-owner-cleanup.ts", + "default": "./src/daemon-owner-cleanup.ts" + }, "./device": { "types": "./src/facades/device.ts", "default": "./src/facades/device.ts" @@ -199,18 +211,6 @@ "types": "./src/gesture-plan.ts", "default": "./src/gesture-plan.ts" }, - "./host-diagnostics": { - "types": "./src/host-diagnostics.ts", - "default": "./src/host-diagnostics.ts" - }, - "./daemon-owner-cleanup": { - "types": "./src/daemon-owner-cleanup.ts", - "default": "./src/daemon-owner-cleanup.ts" - }, - "./managed-web-backend": { - "types": "./src/managed-web-backend.ts", - "default": "./src/managed-web-backend.ts" - }, "./gesture-plan-types": { "types": "./src/gesture-plan-types.ts", "default": "./src/gesture-plan-types.ts" @@ -223,6 +223,10 @@ "types": "./src/home-runtime.ts", "default": "./src/home-runtime.ts" }, + "./host-diagnostics": { + "types": "./src/host-diagnostics.ts", + "default": "./src/host-diagnostics.ts" + }, "./interaction": { "types": "./src/interaction.ts", "default": "./src/interaction.ts" @@ -259,6 +263,10 @@ "types": "./src/logs-runtime-plan.ts", "default": "./src/logs-runtime-plan.ts" }, + "./managed-web-backend": { + "types": "./src/managed-web-backend.ts", + "default": "./src/managed-web-backend.ts" + }, "./navigation": { "types": "./src/navigation.ts", "default": "./src/navigation.ts" @@ -283,6 +291,22 @@ "types": "./src/orientation-runtime.ts", "default": "./src/orientation-runtime.ts" }, + "./perf-runtime": { + "types": "./src/perf-runtime.ts", + "default": "./src/perf-runtime.ts" + }, + "./perf-runtime-host": { + "types": "./src/perf-runtime-host.ts", + "default": "./src/perf-runtime-host.ts" + }, + "./perf-runtime-operation-builder": { + "types": "./src/perf-runtime-operation-builder.ts", + "default": "./src/perf-runtime-operation-builder.ts" + }, + "./perf-runtime-plan": { + "types": "./src/perf-runtime-plan.ts", + "default": "./src/perf-runtime-plan.ts" + }, "./platform-module": { "types": "./src/platform-module.ts", "default": "./src/platform-module.ts" @@ -295,6 +319,10 @@ "types": "./src/platform-providers.ts", "default": "./src/platform-providers.ts" }, + "./platform-resource-cleanup": { + "types": "./src/platform-resource-cleanup.ts", + "default": "./src/platform-resource-cleanup.ts" + }, "./platform-runtime": { "types": "./src/platform-runtime.ts", "default": "./src/platform-runtime.ts" @@ -307,34 +335,18 @@ "types": "./src/platform-runtime-operations.ts", "default": "./src/platform-runtime-operations.ts" }, - "./platform-resource-cleanup": { - "types": "./src/platform-resource-cleanup.ts", - "default": "./src/platform-resource-cleanup.ts" - }, "./platform-runtime-unavailable": { "types": "./src/platform-runtime-unavailable.ts", "default": "./src/platform-runtime-unavailable.ts" }, - "./perf-runtime": { - "types": "./src/perf-runtime.ts", - "default": "./src/perf-runtime.ts" - }, - "./perf-runtime-host": { - "types": "./src/perf-runtime-host.ts", - "default": "./src/perf-runtime-host.ts" - }, - "./perf-runtime-operation-builder": { - "types": "./src/perf-runtime-operation-builder.ts", - "default": "./src/perf-runtime-operation-builder.ts" - }, - "./perf-runtime-plan": { - "types": "./src/perf-runtime-plan.ts", - "default": "./src/perf-runtime-plan.ts" - }, "./progress": { "types": "./src/facades/progress.ts", "default": "./src/facades/progress.ts" }, + "./react-native-overlay": { + "types": "./src/react-native-overlay.ts", + "default": "./src/react-native-overlay.ts" + }, "./record-runtime-execution": { "types": "./src/record-runtime-execution.ts", "default": "./src/record-runtime-execution.ts" @@ -351,10 +363,6 @@ "types": "./src/facades/replay.ts", "default": "./src/facades/replay.ts" }, - "./react-native-overlay": { - "types": "./src/react-native-overlay.ts", - "default": "./src/react-native-overlay.ts" - }, "./runner-lease-context": { "types": "./src/runner-lease-context.ts", "default": "./src/runner-lease-context.ts" @@ -423,6 +431,10 @@ "types": "./src/startup-recovery-fence.ts", "default": "./src/startup-recovery-fence.ts" }, + "./touch-runtime": { + "types": "./src/touch-runtime.ts", + "default": "./src/touch-runtime.ts" + }, "./tv-remote": { "types": "./src/tv-remote.ts", "default": "./src/tv-remote.ts" @@ -435,10 +447,6 @@ "types": "./src/type-text-runtime.ts", "default": "./src/type-text-runtime.ts" }, - "./touch-runtime": { - "types": "./src/touch-runtime.ts", - "default": "./src/touch-runtime.ts" - }, "./viewport-runtime": { "types": "./src/viewport-runtime.ts", "default": "./src/viewport-runtime.ts" @@ -450,14 +458,6 @@ "./wait-runtime-plan": { "types": "./src/wait-runtime-plan.ts", "default": "./src/wait-runtime-plan.ts" - }, - "./android-helper-artifacts": { - "types": "./src/android-helper-artifacts.ts", - "default": "./src/android-helper-artifacts.ts" - }, - "./android-touch-plan": { - "types": "./src/android-touch-plan.ts", - "default": "./src/android-touch-plan.ts" } } } diff --git a/packages/host-kit/package.json b/packages/host-kit/package.json new file mode 100644 index 0000000000..248a870493 --- /dev/null +++ b/packages/host-kit/package.json @@ -0,0 +1,35 @@ +{ + "name": "@agent-device/host-kit", + "version": "0.0.0", + "private": true, + "type": "module", + "description": "Private generic host mechanics behind four deep seams: process execution and supervision (exec), filesystem and archive guards (fs), pure value helpers (values), and request-scoped plumbing (request). Internal workspace package bundled into the published agent-device artifact.", + "dependencies": { + "@agent-device/contracts": "workspace:*", + "@agent-device/kernel": "workspace:*", + "tar-stream": "^3.2.0", + "yauzl": "^3.4.0" + }, + "devDependencies": { + "@types/tar-stream": "^3.1.4", + "@types/yauzl": "^3.4.0" + }, + "exports": { + "./exec": { + "types": "./src/exec.ts", + "default": "./src/exec.ts" + }, + "./fs": { + "types": "./src/fs.ts", + "default": "./src/fs.ts" + }, + "./request": { + "types": "./src/request.ts", + "default": "./src/request.ts" + }, + "./values": { + "types": "./src/values.ts", + "default": "./src/values.ts" + } + } +} diff --git a/packages/host-kit/src/exec.ts b/packages/host-kit/src/exec.ts new file mode 100644 index 0000000000..e5ca9f8a97 --- /dev/null +++ b/packages/host-kit/src/exec.ts @@ -0,0 +1,77 @@ +export { + coerceExecResult, + execFailureDetails, + isExecutablePath, + requireExecSuccess, + resolveExecutableOverridePath, + resolveFileOverridePath, + runCmd, + runCmdBackground, + runCmdDetached, + runCmdDetachedMonitored, + runCmdStreaming, + runCmdSync, + whichCmd, + withCommandExecutorOverride, + withoutCommandExecutorOverride, + type CommandExecutorOverride, + type ExecBackgroundOptions, + type ExecBackgroundResult, + type ExecDetachedExit, + type ExecDetachedProcess, + type ExecOptions, + type ExecResult, +} from './internal/exec.ts'; +export { + countDiagnosticEventsByPhase, + createRequestId, + emitDiagnostic, + flushDiagnosticsToSessionFile, + getDiagnosticsMeta, + registerDiagnosticSensitiveValue, + updateDiagnosticsScope, + withDiagnosticTimer, + withDiagnosticsScope, + type FlushedDiagnosticsRecord, +} from './internal/diagnostics.ts'; +export { + expandProcessTree, + isProcessAlive, + isProcessGroupAlive, + isProcessZombie, + listHostProcesses, + readHostProcessIdentityObservations, + readProcessCommand, + readProcessStartTime, + signalPidsBestEffort, + signalProcessGroupBestEffort, + stopPidsWithEscalation, + uniquePositivePids, + waitForProcessExit, + type HostProcessIdentityObservation, + type HostProcessInfo, + type ListHostProcessesOptions, + type StopPidsWithEscalationOptions, +} from './internal/host-process.ts'; +export { + reapOwnedProcessRecordsAtStartup, + type OwnedProcessReapSummary, +} from './internal/owned-process-reaper.ts'; +export { + createOwnedProcessRecordStore, + readOwnedProcessRecordFile, + type OwnedProcessRecordRead, + type OwnedProcessRecordStore, +} from './internal/owned-process-record.ts'; +export { + classifyOwnerLiveness, + classifyOwnerLivenessFromObservation, + ownerIdentityDiffers, + ownerIdentityMatches, + readCurrentOwnerIdentity, + type OwnerIdentity, + type OwnerLiveness, +} from './internal/owner-identity.ts'; +export { shellQuote, shellQuoteIfNeeded } from './internal/shell-quote.ts'; +export { sleep } from './internal/timeouts.ts'; +export { Deadline, isEnvTruthy, retryWithPolicy } from './internal/retry.ts'; diff --git a/packages/host-kit/src/fs.ts b/packages/host-kit/src/fs.ts new file mode 100644 index 0000000000..b6965b7d48 --- /dev/null +++ b/packages/host-kit/src/fs.ts @@ -0,0 +1,22 @@ +export { + archiveTypeFromPath, + extractArchiveSafely, + type ExtractArchiveOptions, + type SupportedArchiveType, +} from './internal/archive-extraction.ts'; +export { ArchiveBudget, type ArchiveManifestEntry } from './internal/archive-safety.ts'; +export { MAX_ARTIFACT_COMPRESSED_BYTES } from './internal/artifact-limits.ts'; +export { + isAtomicPublishTemporaryPath, + publishFileSync, + withAtomicPublishTempPathSync, + type AtomicPublishMode, +} from './internal/atomic-file.ts'; +export { createByteLimitStream, type ByteLimitStream } from './internal/byte-limit-stream.ts'; +export { + parseSerialAllowlist, + resolveAndroidSerialAllowlist, + resolveIosSimulatorDeviceSetPath, +} from './internal/device-isolation.ts'; +export { expandUserHomePath, resolveUserPath } from './internal/path-resolution.ts'; +export { acquireProcessLock, type ProcessLockOwner } from './internal/process-lock.ts'; diff --git a/src/utils/__tests__/archive-extraction-tar.test.ts b/packages/host-kit/src/internal/archive-extraction-tar.test.ts similarity index 90% rename from src/utils/__tests__/archive-extraction-tar.test.ts rename to packages/host-kit/src/internal/archive-extraction-tar.test.ts index 05333db87e..54bb3b9e89 100644 --- a/src/utils/__tests__/archive-extraction-tar.test.ts +++ b/packages/host-kit/src/internal/archive-extraction-tar.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import { promises as fs } from 'node:fs'; import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; -import { extractTarArchive } from '../archive-extraction-tar.ts'; -import { ArchiveBudget } from '../archive-safety.ts'; +import { extractTarArchive } from './archive-extraction-tar.ts'; +import { ArchiveBudget } from './archive-safety.ts'; import { createArchiveWorkspace, createTruncatedTgz } from './archive-extraction.fixtures.ts'; test('tar inspection rejects declared bytes before draining an over-budget entry', async () => { diff --git a/src/utils/archive-extraction-tar.ts b/packages/host-kit/src/internal/archive-extraction-tar.ts similarity index 100% rename from src/utils/archive-extraction-tar.ts rename to packages/host-kit/src/internal/archive-extraction-tar.ts diff --git a/src/utils/__tests__/archive-extraction-zip.test.ts b/packages/host-kit/src/internal/archive-extraction-zip.test.ts similarity index 90% rename from src/utils/__tests__/archive-extraction-zip.test.ts rename to packages/host-kit/src/internal/archive-extraction-zip.test.ts index 40a5e26699..9ad4aa0116 100644 --- a/src/utils/__tests__/archive-extraction-zip.test.ts +++ b/packages/host-kit/src/internal/archive-extraction-zip.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import { promises as fs } from 'node:fs'; import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; -import { extractZipArchive } from '../archive-extraction-zip.ts'; -import { ArchiveBudget } from '../archive-safety.ts'; +import { extractZipArchive } from './archive-extraction-zip.ts'; +import { ArchiveBudget } from './archive-safety.ts'; import { createArchiveWorkspace, createZipWithEncryptedSecondEntry, diff --git a/src/utils/archive-extraction-zip.ts b/packages/host-kit/src/internal/archive-extraction-zip.ts similarity index 100% rename from src/utils/archive-extraction-zip.ts rename to packages/host-kit/src/internal/archive-extraction-zip.ts diff --git a/src/utils/__tests__/archive-extraction.fixtures.ts b/packages/host-kit/src/internal/archive-extraction.fixtures.ts similarity index 97% rename from src/utils/__tests__/archive-extraction.fixtures.ts rename to packages/host-kit/src/internal/archive-extraction.fixtures.ts index 694ea53dfc..1471882fca 100644 --- a/src/utils/__tests__/archive-extraction.fixtures.ts +++ b/packages/host-kit/src/internal/archive-extraction.fixtures.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import { gzipSync } from 'node:zlib'; import * as tar from 'tar-stream'; -import { runCmdSync } from '../exec.ts'; +import { runCmdSync } from './exec.ts'; export async function createArchiveWorkspace(): Promise<{ archivePath: string; diff --git a/src/utils/archive-extraction.ts b/packages/host-kit/src/internal/archive-extraction.ts similarity index 100% rename from src/utils/archive-extraction.ts rename to packages/host-kit/src/internal/archive-extraction.ts diff --git a/src/utils/__tests__/archive-safety.test.ts b/packages/host-kit/src/internal/archive-safety.test.ts similarity index 98% rename from src/utils/__tests__/archive-safety.test.ts rename to packages/host-kit/src/internal/archive-safety.test.ts index 701d6a3432..9b0f4f8ae8 100644 --- a/src/utils/__tests__/archive-safety.test.ts +++ b/packages/host-kit/src/internal/archive-safety.test.ts @@ -5,7 +5,7 @@ import { ArchiveBudget, normalizeArchiveEntryName, resolveArchiveOutputPath, -} from '../archive-safety.ts'; +} from './archive-safety.ts'; function reason(error: unknown): string | undefined { return error instanceof AppError ? (error.details?.reason as string | undefined) : undefined; diff --git a/src/utils/archive-safety.ts b/packages/host-kit/src/internal/archive-safety.ts similarity index 100% rename from src/utils/archive-safety.ts rename to packages/host-kit/src/internal/archive-safety.ts diff --git a/src/utils/artifact-limits.ts b/packages/host-kit/src/internal/artifact-limits.ts similarity index 100% rename from src/utils/artifact-limits.ts rename to packages/host-kit/src/internal/artifact-limits.ts diff --git a/src/utils/atomic-file.ts b/packages/host-kit/src/internal/atomic-file.ts similarity index 100% rename from src/utils/atomic-file.ts rename to packages/host-kit/src/internal/atomic-file.ts diff --git a/src/utils/__tests__/byte-limit-stream.test.ts b/packages/host-kit/src/internal/byte-limit-stream.test.ts similarity index 96% rename from src/utils/__tests__/byte-limit-stream.test.ts rename to packages/host-kit/src/internal/byte-limit-stream.test.ts index cf070a52dd..d050c6b653 100644 --- a/src/utils/__tests__/byte-limit-stream.test.ts +++ b/packages/host-kit/src/internal/byte-limit-stream.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { Readable, Writable } from 'node:stream'; import { pipeline } from 'node:stream/promises'; import { test } from 'vitest'; -import { createByteLimitStream } from '../byte-limit-stream.ts'; +import { createByteLimitStream } from './byte-limit-stream.ts'; test('byte limit rejects before forwarding overflow and reports accepted bytes only', async () => { const limitError = new Error('limit exceeded'); diff --git a/src/utils/byte-limit-stream.ts b/packages/host-kit/src/internal/byte-limit-stream.ts similarity index 100% rename from src/utils/byte-limit-stream.ts rename to packages/host-kit/src/internal/byte-limit-stream.ts diff --git a/src/utils/device-isolation.ts b/packages/host-kit/src/internal/device-isolation.ts similarity index 100% rename from src/utils/device-isolation.ts rename to packages/host-kit/src/internal/device-isolation.ts diff --git a/src/utils/__tests__/diagnostics.test.ts b/packages/host-kit/src/internal/diagnostics.test.ts similarity index 98% rename from src/utils/__tests__/diagnostics.test.ts rename to packages/host-kit/src/internal/diagnostics.test.ts index 966aae9c05..088c9e23db 100644 --- a/src/utils/__tests__/diagnostics.test.ts +++ b/packages/host-kit/src/internal/diagnostics.test.ts @@ -7,8 +7,8 @@ import { flushDiagnosticsToSessionFile, registerDiagnosticSensitiveValue, withDiagnosticsScope, -} from '../diagnostics.ts'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; +} from './diagnostics.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; test('diagnostics redacts sensitive fields', async () => { const previousHome = process.env.HOME; diff --git a/src/utils/diagnostics.ts b/packages/host-kit/src/internal/diagnostics.ts similarity index 100% rename from src/utils/diagnostics.ts rename to packages/host-kit/src/internal/diagnostics.ts diff --git a/src/utils/env-map.ts b/packages/host-kit/src/internal/env-map.ts similarity index 52% rename from src/utils/env-map.ts rename to packages/host-kit/src/internal/env-map.ts index 43fd717aa4..f203e11695 100644 --- a/src/utils/env-map.ts +++ b/packages/host-kit/src/internal/env-map.ts @@ -1,2 +1 @@ export type EnvMap = Record; -export type DefinedEnvMap = Record; diff --git a/src/utils/__tests__/exec-windows-hide.test.ts b/packages/host-kit/src/internal/exec-windows-hide.test.ts similarity index 98% rename from src/utils/__tests__/exec-windows-hide.test.ts rename to packages/host-kit/src/internal/exec-windows-hide.test.ts index 0cbff61fe5..0f1e4e74f1 100644 --- a/src/utils/__tests__/exec-windows-hide.test.ts +++ b/packages/host-kit/src/internal/exec-windows-hide.test.ts @@ -21,7 +21,7 @@ vi.mock('node:child_process', () => ({ spawnSync: spawnSyncMock, })); -import { runCmd, runCmdBackground, runCmdDetached, runCmdSync } from '../exec.ts'; +import { runCmd, runCmdBackground, runCmdDetached, runCmdSync } from './exec.ts'; beforeEach(() => { spawnMock.mockReset(); diff --git a/src/utils/__tests__/exec.test.ts b/packages/host-kit/src/internal/exec.test.ts similarity index 99% rename from src/utils/__tests__/exec.test.ts rename to packages/host-kit/src/internal/exec.test.ts index d4d89fef9b..dfd8dc0af4 100644 --- a/src/utils/__tests__/exec.test.ts +++ b/packages/host-kit/src/internal/exec.test.ts @@ -2,7 +2,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '../diagnostics.ts'; +import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from './diagnostics.ts'; import { coerceExecResult, requireExecSuccess, @@ -13,9 +13,9 @@ import { runCmdSync, whichCmd, type ExecResult, -} from '../exec.ts'; +} from './exec.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; test('runCmd enforces timeoutMs and rejects with COMMAND_FAILED', async () => { await assert.rejects( diff --git a/src/utils/exec.ts b/packages/host-kit/src/internal/exec.ts similarity index 99% rename from src/utils/exec.ts rename to packages/host-kit/src/internal/exec.ts index 3bf80eb7d7..7fb5764bb2 100644 --- a/src/utils/exec.ts +++ b/packages/host-kit/src/internal/exec.ts @@ -282,6 +282,7 @@ export async function resolveFileOverridePath( return candidate; } +// fallow-ignore-next-line complexity export function runCmdSync(cmd: string, args: string[], options: ExecOptions = {}): ExecResult { const executable = normalizeExecutableCommand(cmd); const result = spawnSync(executable, args, { diff --git a/src/utils/__tests__/host-process-liveness.test.ts b/packages/host-kit/src/internal/host-process-liveness.test.ts similarity index 92% rename from src/utils/__tests__/host-process-liveness.test.ts rename to packages/host-kit/src/internal/host-process-liveness.test.ts index 5b7f6d108f..fab9d2173c 100644 --- a/src/utils/__tests__/host-process-liveness.test.ts +++ b/packages/host-kit/src/internal/host-process-liveness.test.ts @@ -3,12 +3,12 @@ import { beforeEach, test, vi } from 'vitest'; const { mockRunCmdSync } = vi.hoisted(() => ({ mockRunCmdSync: vi.fn() })); -vi.mock('../exec.ts', async () => { - const actual = await vi.importActual('../exec.ts'); +vi.mock('./exec.ts', async () => { + const actual = await vi.importActual('./exec.ts'); return { ...actual, runCmdSync: mockRunCmdSync }; }); -import { isProcessZombie, readHostProcessIdentityObservations } from '../host-process.ts'; +import { isProcessZombie, readHostProcessIdentityObservations } from './host-process.ts'; function psReturns(stdout: string, exitCode = 0): void { mockRunCmdSync.mockReturnValue({ stdout, stderr: '', exitCode }); diff --git a/src/utils/__tests__/host-process.test.ts b/packages/host-kit/src/internal/host-process.test.ts similarity index 99% rename from src/utils/__tests__/host-process.test.ts rename to packages/host-kit/src/internal/host-process.test.ts index 3ced0c86bf..6236d74b4d 100644 --- a/src/utils/__tests__/host-process.test.ts +++ b/packages/host-kit/src/internal/host-process.test.ts @@ -12,7 +12,7 @@ import { signalProcessGroupBestEffort, stopPidsWithEscalation, uniquePositivePids, -} from '../host-process.ts'; +} from './host-process.ts'; test('isProcessAlive returns false for invalid pid', () => { assert.equal(isProcessAlive(-1), false); diff --git a/src/utils/host-process.ts b/packages/host-kit/src/internal/host-process.ts similarity index 100% rename from src/utils/host-process.ts rename to packages/host-kit/src/internal/host-process.ts diff --git a/src/utils/location-coordinates.ts b/packages/host-kit/src/internal/location-coordinates.ts similarity index 100% rename from src/utils/location-coordinates.ts rename to packages/host-kit/src/internal/location-coordinates.ts diff --git a/src/utils/method-scope.ts b/packages/host-kit/src/internal/method-scope.ts similarity index 100% rename from src/utils/method-scope.ts rename to packages/host-kit/src/internal/method-scope.ts diff --git a/src/utils/owned-process-reaper.ts b/packages/host-kit/src/internal/owned-process-reaper.ts similarity index 100% rename from src/utils/owned-process-reaper.ts rename to packages/host-kit/src/internal/owned-process-reaper.ts diff --git a/src/utils/owned-process-record.test.ts b/packages/host-kit/src/internal/owned-process-record.test.ts similarity index 99% rename from src/utils/owned-process-record.test.ts rename to packages/host-kit/src/internal/owned-process-record.test.ts index 8daf342750..38b651b5d6 100644 --- a/src/utils/owned-process-record.test.ts +++ b/packages/host-kit/src/internal/owned-process-record.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { afterEach, beforeEach, test, vi } from 'vitest'; -import { mkdtempForTestSync } from '../__tests__/test-utils/tmp-dir.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; const processState = vi.hoisted(() => ({ alive: new Set(), diff --git a/src/utils/owned-process-record.ts b/packages/host-kit/src/internal/owned-process-record.ts similarity index 100% rename from src/utils/owned-process-record.ts rename to packages/host-kit/src/internal/owned-process-record.ts diff --git a/src/utils/__tests__/owner-identity-liveness.test.ts b/packages/host-kit/src/internal/owner-identity-liveness.test.ts similarity index 96% rename from src/utils/__tests__/owner-identity-liveness.test.ts rename to packages/host-kit/src/internal/owner-identity-liveness.test.ts index 4f103062a6..fd5278afa8 100644 --- a/src/utils/__tests__/owner-identity-liveness.test.ts +++ b/packages/host-kit/src/internal/owner-identity-liveness.test.ts @@ -7,13 +7,13 @@ const { mockIsProcessAlive, mockIsProcessZombie, mockReadProcessStartTime } = vi mockReadProcessStartTime: vi.fn(), })); -vi.mock('../host-process.ts', () => ({ +vi.mock('./host-process.ts', () => ({ isProcessAlive: mockIsProcessAlive, isProcessZombie: mockIsProcessZombie, readProcessStartTime: mockReadProcessStartTime, })); -import { classifyOwnerLiveness, classifyOwnerLivenessFromObservation } from '../owner-identity.ts'; +import { classifyOwnerLiveness, classifyOwnerLivenessFromObservation } from './owner-identity.ts'; const OWNER_PID = 4242; diff --git a/src/utils/__tests__/owner-identity.test.ts b/packages/host-kit/src/internal/owner-identity.test.ts similarity index 96% rename from src/utils/__tests__/owner-identity.test.ts rename to packages/host-kit/src/internal/owner-identity.test.ts index 53b9b1a645..6b6c867d8d 100644 --- a/src/utils/__tests__/owner-identity.test.ts +++ b/packages/host-kit/src/internal/owner-identity.test.ts @@ -8,8 +8,8 @@ import { ownerIdentityDiffers, ownerIdentityMatches, type OwnerIdentity, -} from '../owner-identity.ts'; -import { readProcessStartTime } from '../host-process.ts'; +} from './owner-identity.ts'; +import { readProcessStartTime } from './host-process.ts'; afterEach(() => { vi.restoreAllMocks(); diff --git a/src/utils/owner-identity.ts b/packages/host-kit/src/internal/owner-identity.ts similarity index 100% rename from src/utils/owner-identity.ts rename to packages/host-kit/src/internal/owner-identity.ts diff --git a/src/utils/parsing.ts b/packages/host-kit/src/internal/parsing.ts similarity index 100% rename from src/utils/parsing.ts rename to packages/host-kit/src/internal/parsing.ts diff --git a/src/utils/__tests__/path-resolution.test.ts b/packages/host-kit/src/internal/path-resolution.test.ts similarity index 91% rename from src/utils/__tests__/path-resolution.test.ts rename to packages/host-kit/src/internal/path-resolution.test.ts index a691be3d66..f76a503041 100644 --- a/src/utils/__tests__/path-resolution.test.ts +++ b/packages/host-kit/src/internal/path-resolution.test.ts @@ -1,7 +1,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import path from 'node:path'; -import { expandUserHomePath, resolveUserPath } from '../path-resolution.ts'; +import { expandUserHomePath, resolveUserPath } from './path-resolution.ts'; test('expandUserHomePath expands the current user home prefix', () => { const env = { HOME: '/tmp/agent-device-home' }; diff --git a/src/utils/path-resolution.ts b/packages/host-kit/src/internal/path-resolution.ts similarity index 100% rename from src/utils/path-resolution.ts rename to packages/host-kit/src/internal/path-resolution.ts diff --git a/src/utils/__tests__/process-lock.test.ts b/packages/host-kit/src/internal/process-lock.test.ts similarity index 92% rename from src/utils/__tests__/process-lock.test.ts rename to packages/host-kit/src/internal/process-lock.test.ts index af3399fad7..5e1d393147 100644 --- a/src/utils/__tests__/process-lock.test.ts +++ b/packages/host-kit/src/internal/process-lock.test.ts @@ -6,14 +6,14 @@ import { AppError } from '@agent-device/kernel/errors'; const { zombiePids } = vi.hoisted(() => ({ zombiePids: new Set() })); -vi.mock('../host-process.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('./host-process.ts', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, isProcessZombie: (pid: number) => zombiePids.has(pid) }; }); -import { acquireProcessLock, type ProcessLockOwner } from '../process-lock.ts'; -import { readProcessStartTime } from '../host-process.ts'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; +import { acquireProcessLock, type ProcessLockOwner } from './process-lock.ts'; +import { readProcessStartTime } from './host-process.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; let tmpDir: string; diff --git a/src/utils/process-lock.ts b/packages/host-kit/src/internal/process-lock.ts similarity index 100% rename from src/utils/process-lock.ts rename to packages/host-kit/src/internal/process-lock.ts diff --git a/packages/host-kit/src/internal/project-root.ts b/packages/host-kit/src/internal/project-root.ts new file mode 100644 index 0000000000..d41846d5a2 --- /dev/null +++ b/packages/host-kit/src/internal/project-root.ts @@ -0,0 +1,22 @@ +import fs from 'node:fs'; +import path from 'node:path'; + +/** Walks up from `startDirectory` to the manifest named `agent-device`; the first manifest found is the fallback for renamed or vendored installs. */ +export function resolveAgentDeviceProjectRoot(startDirectory: string): string { + let current = startDirectory; + let nearest: string | null = null; + for (let i = 0; i < 8; i += 1) { + const pkgPath = path.join(current, 'package.json'); + if (fs.existsSync(pkgPath)) { + nearest ??= current; + try { + const name = (JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as { name?: unknown }).name; + if (name === 'agent-device') return current; + } catch { + // an unreadable manifest is not the root; keep walking + } + } + current = path.dirname(current); + } + return nearest ?? startDirectory; +} diff --git a/src/request/cancel.test.ts b/packages/host-kit/src/internal/request-cancel.test.ts similarity index 99% rename from src/request/cancel.test.ts rename to packages/host-kit/src/internal/request-cancel.test.ts index 0104b58a89..915a9d0087 100644 --- a/src/request/cancel.test.ts +++ b/packages/host-kit/src/internal/request-cancel.test.ts @@ -10,7 +10,7 @@ import { markRequestCanceled, registerRequestAbort, resolveRequestTrackingId, -} from './cancel.ts'; +} from './request-cancel.ts'; test('resolveRequestTrackingId generates unique ids for fallback seeds', () => { const first = resolveRequestTrackingId(undefined, 42); diff --git a/src/request/cancel.ts b/packages/host-kit/src/internal/request-cancel.ts similarity index 100% rename from src/request/cancel.ts rename to packages/host-kit/src/internal/request-cancel.ts diff --git a/src/request/progress.ts b/packages/host-kit/src/internal/request-progress.ts similarity index 100% rename from src/request/progress.ts rename to packages/host-kit/src/internal/request-progress.ts diff --git a/src/utils/__tests__/retry.test.ts b/packages/host-kit/src/internal/retry.test.ts similarity index 96% rename from src/utils/__tests__/retry.test.ts rename to packages/host-kit/src/internal/retry.test.ts index 91c60077aa..c5cfdfb2f3 100644 --- a/src/utils/__tests__/retry.test.ts +++ b/packages/host-kit/src/internal/retry.test.ts @@ -2,9 +2,9 @@ import { test, vi } from 'vitest'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import { AppError } from '@agent-device/kernel/errors'; -import { retryWithPolicy } from '../retry.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '../diagnostics.ts'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; +import { retryWithPolicy } from './retry.ts'; +import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from './diagnostics.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; test('retryWithPolicy retries until success', async () => { let attempts = 0; diff --git a/src/utils/retry.ts b/packages/host-kit/src/internal/retry.ts similarity index 99% rename from src/utils/retry.ts rename to packages/host-kit/src/internal/retry.ts index fe10078ac7..46d17b7b21 100644 --- a/src/utils/retry.ts +++ b/packages/host-kit/src/internal/retry.ts @@ -77,6 +77,7 @@ export class Deadline { } } +// fallow-ignore-next-line complexity export async function retryWithPolicy( fn: (context: RetryAttemptContext) => Promise, policy: Partial = {}, diff --git a/src/utils/scoped-provider.ts b/packages/host-kit/src/internal/scoped-provider.ts similarity index 100% rename from src/utils/scoped-provider.ts rename to packages/host-kit/src/internal/scoped-provider.ts diff --git a/src/utils/__tests__/shell-quote.test.ts b/packages/host-kit/src/internal/shell-quote.test.ts similarity index 92% rename from src/utils/__tests__/shell-quote.test.ts rename to packages/host-kit/src/internal/shell-quote.test.ts index ed0cfd1aa7..17094de555 100644 --- a/src/utils/__tests__/shell-quote.test.ts +++ b/packages/host-kit/src/internal/shell-quote.test.ts @@ -1,6 +1,6 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; -import { shellQuote, shellQuoteIfNeeded } from '../shell-quote.ts'; +import { shellQuote, shellQuoteIfNeeded } from './shell-quote.ts'; test('shellQuote single-quotes and escapes POSIX shell arguments', () => { assert.equal(shellQuote('plain'), "'plain'"); diff --git a/src/utils/shell-quote.ts b/packages/host-kit/src/internal/shell-quote.ts similarity index 100% rename from src/utils/shell-quote.ts rename to packages/host-kit/src/internal/shell-quote.ts diff --git a/src/utils/source-value.ts b/packages/host-kit/src/internal/source-value.ts similarity index 98% rename from src/utils/source-value.ts rename to packages/host-kit/src/internal/source-value.ts index 64d1f22a27..1886e07a19 100644 --- a/src/utils/source-value.ts +++ b/packages/host-kit/src/internal/source-value.ts @@ -19,6 +19,7 @@ export function buildPrimaryEnvVarName(key: string): string { .toUpperCase()}`; } +// fallow-ignore-next-line complexity export function parseSourceValue( definition: SourceValueDefinition, value: unknown, @@ -115,6 +116,7 @@ export function parseBooleanLiteral(value: string): boolean | undefined { return undefined; } +// fallow-ignore-next-line complexity function parseEnumSetValue( definition: SourceValueDefinition, value: unknown, diff --git a/src/utils/success-text.ts b/packages/host-kit/src/internal/success-text.ts similarity index 100% rename from src/utils/success-text.ts rename to packages/host-kit/src/internal/success-text.ts diff --git a/src/utils/timeouts.ts b/packages/host-kit/src/internal/timeouts.ts similarity index 100% rename from src/utils/timeouts.ts rename to packages/host-kit/src/internal/timeouts.ts diff --git a/packages/host-kit/src/internal/tmp-dir.fixtures.ts b/packages/host-kit/src/internal/tmp-dir.fixtures.ts new file mode 100644 index 0000000000..edf03d27a4 --- /dev/null +++ b/packages/host-kit/src/internal/tmp-dir.fixtures.ts @@ -0,0 +1,21 @@ +// Package tests cannot reach root test helpers (R11); fixture copy of tmp-dir.ts. +import fs from 'node:fs'; +import fsPromises from 'node:fs/promises'; +import os from 'node:os'; +import path from 'node:path'; + +/** + * Creates a fresh scratch directory for one test. Cleanup is automatic: the + * unit suite redirects TMPDIR to a per-run directory (scripts/vitest-tmpdir-global-setup.ts) + * that gets removed in one recursive rm after every worker finishes, so + * individual tests never need their own afterEach/afterAll for this. + */ +// fallow-ignore-next-line code-duplication +export async function mkdtempForTest(prefix: string): Promise { + return fsPromises.mkdtemp(path.join(os.tmpdir(), prefix)); +} + +/** Sync counterpart of {@link mkdtempForTest}, for setup code that can't await. */ +export function mkdtempForTestSync(prefix: string): string { + return fs.mkdtempSync(path.join(os.tmpdir(), prefix)); +} diff --git a/src/utils/__tests__/ttl-memo.test.ts b/packages/host-kit/src/internal/ttl-memo.test.ts similarity index 96% rename from src/utils/__tests__/ttl-memo.test.ts rename to packages/host-kit/src/internal/ttl-memo.test.ts index 5e81380d9c..8b889676c8 100644 --- a/src/utils/__tests__/ttl-memo.test.ts +++ b/packages/host-kit/src/internal/ttl-memo.test.ts @@ -1,6 +1,6 @@ import { expect, test, vi } from 'vitest'; -import { createTtlMemo } from '../ttl-memo.ts'; +import { createTtlMemo } from './ttl-memo.ts'; const crossTestMemo = createTtlMemo({ ttlMs: 60_000 }); diff --git a/src/utils/ttl-memo.ts b/packages/host-kit/src/internal/ttl-memo.ts similarity index 100% rename from src/utils/ttl-memo.ts rename to packages/host-kit/src/internal/ttl-memo.ts diff --git a/src/utils/__tests__/version.test.ts b/packages/host-kit/src/internal/version.test.ts similarity index 56% rename from src/utils/__tests__/version.test.ts rename to packages/host-kit/src/internal/version.test.ts index 7f041213e4..ee185b235b 100644 --- a/src/utils/__tests__/version.test.ts +++ b/packages/host-kit/src/internal/version.test.ts @@ -2,9 +2,10 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; -import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -import { resetAllProcessMemosForTests } from '../ttl-memo.ts'; -import { findProjectRoot, readVersion } from '../version.ts'; +import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; +import { resetAllProcessMemosForTests } from './ttl-memo.ts'; +import { resolveAgentDeviceProjectRoot } from './project-root.ts'; +import { findProjectRoot, readVersion } from './version.ts'; afterEach(() => { vi.restoreAllMocks(); @@ -19,12 +20,6 @@ function countPackageJsonReads(): () => number { ).length; } -// The package version and the project root are immutable for the life of a -// process: nothing can rewrite the running code's own package.json in a way -// the process is allowed to observe. Every CLI invocation reads both several -// times (daemon reuse check, transport client version, help header), so they -// are computed once per process and reset between tests. - test('readVersion parses each root package.json once per process', () => { const root = mkdtempForTestSync('agent-device-version-memo-'); try { @@ -84,3 +79,52 @@ test('findProjectRoot walks the ancestor chain once per process', () => { assert.equal(findProjectRoot(), root); assert.equal(existsSpy.mock.calls.length, walkCalls); }); + +test('the resolver walks past a workspace-package manifest to the agent-device root', () => { + const root = mkdtempForTestSync('agent-device-project-root-'); + try { + fs.writeFileSync( + path.join(root, 'package.json'), + JSON.stringify({ name: 'agent-device', version: '9.9.9' }), + ); + const moduleDir = path.join(root, 'packages', 'capture-kit', 'src'); + fs.mkdirSync(moduleDir, { recursive: true }); + fs.writeFileSync( + path.join(root, 'packages', 'capture-kit', 'package.json'), + JSON.stringify({ name: '@agent-device/capture-kit', version: '0.0.0' }), + ); + + assert.equal(resolveAgentDeviceProjectRoot(moduleDir), root); + assert.equal(readVersion(resolveAgentDeviceProjectRoot(moduleDir)), '9.9.9'); + } finally { + resetAllProcessMemosForTests(); + fs.rmSync(root, { recursive: true, force: true }); + } +}); + +test('the resolver falls back to the nearest manifest when none names agent-device', () => { + const root = mkdtempForTestSync('agent-device-project-root-fallback-'); + try { + fs.writeFileSync( + path.join(root, 'package.json'), + JSON.stringify({ name: 'vendored-fork', version: '1.0.0' }), + ); + const nested = path.join(root, 'lib', 'deep'); + fs.mkdirSync(nested, { recursive: true }); + + assert.equal(resolveAgentDeviceProjectRoot(nested), root); + } finally { + resetAllProcessMemosForTests(); + fs.rmSync(root, { recursive: true, force: true }); + } +}); + +test('from this source tree, the project root is the agent-device manifest, not this package', () => { + const resolved = findProjectRoot(); + const manifest = JSON.parse(fs.readFileSync(path.join(resolved, 'package.json'), 'utf8')) as { + name?: string; + version?: string; + }; + assert.equal(manifest.name, 'agent-device'); + assert.equal(readVersion(), manifest.version); +}); diff --git a/src/utils/version.ts b/packages/host-kit/src/internal/version.ts similarity index 63% rename from src/utils/version.ts rename to packages/host-kit/src/internal/version.ts index 27c0cefed5..6a3e77e3d4 100644 --- a/src/utils/version.ts +++ b/packages/host-kit/src/internal/version.ts @@ -1,12 +1,10 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { resolveAgentDeviceProjectRoot } from './project-root.ts'; import { createTtlMemo } from './ttl-memo.ts'; -// A running process cannot observe its own package version or its own project -// root changing, and both are read several times per CLI invocation (daemon -// reuse check, transport client version, help header, runner cache key), so -// each is resolved once and cleared between tests by the process-memo reset. +// Immutable for a process's lifetime, so resolved once; the process-memo reset clears them between tests. const versionMemo = createTtlMemo(); const projectRootMemo = createTtlMemo<'self', string>(); @@ -33,16 +31,7 @@ export function readVersion(root: string = findProjectRoot()): string { export function findProjectRoot(): string { const memoized = projectRootMemo.get('self'); if (memoized !== undefined) return memoized; - - const start = path.dirname(fileURLToPath(import.meta.url)); - let current = start; - for (let i = 0; i < 6; i += 1) { - const pkgPath = path.join(current, 'package.json'); - if (fs.existsSync(pkgPath)) { - projectRootMemo.set('self', current); - return current; - } - current = path.dirname(current); - } - return start; + const resolved = resolveAgentDeviceProjectRoot(path.dirname(fileURLToPath(import.meta.url))); + projectRootMemo.set('self', resolved); + return resolved; } diff --git a/packages/host-kit/src/request.ts b/packages/host-kit/src/request.ts new file mode 100644 index 0000000000..934f0ab380 --- /dev/null +++ b/packages/host-kit/src/request.ts @@ -0,0 +1,12 @@ +export { + clearRequestAbortRegistration, + clearRequestCanceled, + getRequestSignal, + isRequestCanceled, + markRequestCanceled, + registerRequestAbort, + resolveRequestTrackingId, + throwIfRequestCanceled, + type RequestAbortRegistration, +} from './internal/request-cancel.ts'; +export { emitRequestProgress, withRequestProgressSink } from './internal/request-progress.ts'; diff --git a/packages/host-kit/src/values.ts b/packages/host-kit/src/values.ts new file mode 100644 index 0000000000..846d6c24a2 --- /dev/null +++ b/packages/host-kit/src/values.ts @@ -0,0 +1,39 @@ +export { type EnvMap } from './internal/env-map.ts'; +export { + readLocationCoordinate, + requireLocationCoordinates, + type LocationCoordinateLabel, + type LocationCoordinates, +} from './internal/location-coordinates.ts'; +export { withMethodScope } from './internal/method-scope.ts'; +export { + asOptionalRecord, + asRecord, + isRecord, + parsePoint, + parseRect, + readDeviceTarget, + readNullableString, + readOptionalString, + readRequiredDeviceKind, + readRequiredNumber, + readRequiredPlatform, + readRequiredString, + splitNonEmptyTrimmedLines, + stripUndefined, +} from './internal/parsing.ts'; +export { createScopedProvider, type ScopedProvider } from './internal/scoped-provider.ts'; +export { + buildPrimaryEnvVarName, + parseBooleanLiteral, + parseSourceValue, + type SourceValueDefinition, +} from './internal/source-value.ts'; +export { readCommandMessage, successText, withSuccessText } from './internal/success-text.ts'; +export { + createTtlMemo, + resetAllProcessMemosForTests, + type TtlMemo, + type TtlMemoOptions, +} from './internal/ttl-memo.ts'; +export { findProjectRoot, readVersion } from './internal/version.ts'; diff --git a/packages/host-kit/tsconfig.json b/packages/host-kit/tsconfig.json new file mode 100644 index 0000000000..935c871a4d --- /dev/null +++ b/packages/host-kit/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "noEmit": false, + "emitDeclarationOnly": true, + "declaration": true, + "declarationDir": "./dist-types", + "rootDir": "./src" + }, + "include": ["src"] +} diff --git a/packages/kernel/package.json b/packages/kernel/package.json index c4b0dee2ac..9399792803 100644 --- a/packages/kernel/package.json +++ b/packages/kernel/package.json @@ -5,41 +5,49 @@ "type": "module", "description": "Foundational vocabulary for agent-device: errors, device identity, snapshot model, shared contracts. Internal workspace package bundled into the published agent-device artifact.", "exports": { - "./errors": { - "types": "./src/errors.ts", - "default": "./src/errors.ts" - }, - "./device": { - "types": "./src/device.ts", - "default": "./src/device.ts" + "./bounds": { + "types": "./src/bounds.ts", + "default": "./src/bounds.ts" }, - "./snapshot": { - "types": "./src/snapshot.ts", - "default": "./src/snapshot.ts" + "./collections": { + "types": "./src/collections.ts", + "default": "./src/collections.ts" }, "./contracts": { "types": "./src/contracts.ts", "default": "./src/contracts.ts" }, - "./collections": { - "types": "./src/collections.ts", - "default": "./src/collections.ts" + "./device": { + "types": "./src/device.ts", + "default": "./src/device.ts" + }, + "./errors": { + "types": "./src/errors.ts", + "default": "./src/errors.ts" + }, + "./keyed-lock": { + "types": "./src/keyed-lock.ts", + "default": "./src/keyed-lock.ts" }, "./rect": { "types": "./src/rect.ts", "default": "./src/rect.ts" }, + "./rect-center": { + "types": "./src/rect-center.ts", + "default": "./src/rect-center.ts" + }, "./redaction": { "types": "./src/redaction.ts", "default": "./src/redaction.ts" }, - "./bounds": { - "types": "./src/bounds.ts", - "default": "./src/bounds.ts" + "./scroll-indicator": { + "types": "./src/scroll-indicator.ts", + "default": "./src/scroll-indicator.ts" }, - "./keyed-lock": { - "types": "./src/keyed-lock.ts", - "default": "./src/keyed-lock.ts" + "./snapshot": { + "types": "./src/snapshot.ts", + "default": "./src/snapshot.ts" } } } diff --git a/packages/kernel/src/collections.ts b/packages/kernel/src/collections.ts index 64538f193a..c0d38c735c 100644 --- a/packages/kernel/src/collections.ts +++ b/packages/kernel/src/collections.ts @@ -1,3 +1,31 @@ export function uniqueStrings(values: readonly string[]): string[] { return Array.from(new Set(values)); } + +export function canonicalJson(value: unknown): string { + return JSON.stringify(sortKeysDeep(value)); +} + +function sortKeysDeep(value: unknown): unknown { + if (Array.isArray(value)) return value.map(sortKeysDeep); + if (!value || typeof value !== 'object') return value; + const record = value as Record; + return Object.fromEntries( + Object.keys(record) + .sort() + .map((key) => [key, sortKeysDeep(record[key])]), + ); +} + +/** + * Linear-time edge trim. The regex form (`/^-+|-+$/g`) backtracks polynomially + * on long dash runs (CodeQL js/polynomial-redos), and callers build their + * inputs from caller-supplied strings such as file paths and cache names. + */ +export function trimEdgeDashes(value: string): string { + let start = 0; + let end = value.length; + while (start < end && value[start] === '-') start += 1; + while (end > start && value[end - 1] === '-') end -= 1; + return value.slice(start, end); +} diff --git a/src/utils/__tests__/keyed-lock.test.ts b/packages/kernel/src/keyed-lock.test.ts similarity index 97% rename from src/utils/__tests__/keyed-lock.test.ts rename to packages/kernel/src/keyed-lock.test.ts index d5941d138a..5fc2bf8259 100644 --- a/src/utils/__tests__/keyed-lock.test.ts +++ b/packages/kernel/src/keyed-lock.test.ts @@ -1,6 +1,6 @@ import { test, expect, vi } from 'vitest'; import assert from 'node:assert/strict'; -import { withKeyedLock } from '../keyed-lock.ts'; +import { withKeyedLock } from './keyed-lock.ts'; test('withKeyedLock serializes work per key', async () => { const locks = new Map>(); diff --git a/src/utils/__tests__/rect-center.test.ts b/packages/kernel/src/rect-center.test.ts similarity index 82% rename from src/utils/__tests__/rect-center.test.ts rename to packages/kernel/src/rect-center.test.ts index be5004466c..a6e025c825 100644 --- a/src/utils/__tests__/rect-center.test.ts +++ b/packages/kernel/src/rect-center.test.ts @@ -1,5 +1,5 @@ import { expect, test } from 'vitest'; -import { interiorCoordinate, pointInsideRect } from '../rect-center.ts'; +import { interiorCoordinate, pointInsideRect } from './rect-center.ts'; test('interiorCoordinate preserves one-pixel edge controls', () => { expect(interiorCoordinate(0, 1)).toBe(0); diff --git a/src/utils/rect-center.ts b/packages/kernel/src/rect-center.ts similarity index 100% rename from src/utils/rect-center.ts rename to packages/kernel/src/rect-center.ts diff --git a/src/utils/scroll-indicator.ts b/packages/kernel/src/scroll-indicator.ts similarity index 100% rename from src/utils/scroll-indicator.ts rename to packages/kernel/src/scroll-indicator.ts diff --git a/packages/maestro/src/internal/shared.ts b/packages/maestro/src/internal/shared.ts index 1b9b0d841c..fa9dd74c66 100644 --- a/packages/maestro/src/internal/shared.ts +++ b/packages/maestro/src/internal/shared.ts @@ -1,37 +1,11 @@ -import type { Point, Rect, SnapshotNode } from '@agent-device/kernel/snapshot'; +import type { SnapshotNode } from '@agent-device/kernel/snapshot'; export function stripUndefined>(value: T): T { return Object.fromEntries(Object.entries(value).filter(([, entry]) => entry !== undefined)) as T; } -export function canonicalJson(value: unknown): string { - return JSON.stringify(sortKeysDeep(value)); -} - -function sortKeysDeep(value: unknown): unknown { - if (Array.isArray(value)) return value.map(sortKeysDeep); - if (!value || typeof value !== 'object') return value; - const record = value as Record; - return Object.fromEntries( - Object.keys(record) - .sort() - .map((key) => [key, sortKeysDeep(record[key])]), - ); -} - -export function pointInsideRect(rect: Rect): Point { - return { - x: interiorCoordinate(rect.x, rect.width), - y: interiorCoordinate(rect.y, rect.height), - }; -} - -function interiorCoordinate(origin: number, size: number): number { - if (size <= 1) return Math.floor(origin); - const min = Math.ceil(origin); - const max = Math.floor(origin + size - 1); - return Math.round(Math.min(max, Math.max(min, origin + size / 2))); -} +export { canonicalJson } from '@agent-device/kernel/collections'; +export { pointInsideRect } from '@agent-device/kernel/rect-center'; export function normalizeText(value: string): string { return value.trim().toLowerCase().replace(/\s+/g, ' '); diff --git a/packages/replay-test/src/internal/__tests__/session-test-discovery.test.ts b/packages/replay-test/src/internal/__tests__/session-test-discovery.test.ts index 4d26cc6801..9abad17d51 100644 --- a/packages/replay-test/src/internal/__tests__/session-test-discovery.test.ts +++ b/packages/replay-test/src/internal/__tests__/session-test-discovery.test.ts @@ -6,7 +6,8 @@ import { buildReplayTestSessionName, discoverReplayTestEntries, } from '../session-test-discovery.ts'; -import { buildReplayTestArtifactSlug, trimEdgeDashes } from '../session-test-artifacts.ts'; +import { trimEdgeDashes } from '@agent-device/kernel/collections'; +import { buildReplayTestArtifactSlug } from '../session-test-artifacts.ts'; import type { ReplayTestManifest, ReplayTestSource } from '../session-test-types.ts'; // Scheduler-owned discovery policy (#1478 P3b): which sources a --platform filter runs, which diff --git a/packages/replay-test/src/internal/session-test-artifacts.ts b/packages/replay-test/src/internal/session-test-artifacts.ts index 1c65e4c9dc..90dbc459c4 100644 --- a/packages/replay-test/src/internal/session-test-artifacts.ts +++ b/packages/replay-test/src/internal/session-test-artifacts.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; +import { trimEdgeDashes } from '@agent-device/kernel/collections'; import type { ReplayTestAttemptOutcome } from '@agent-device/replay-test'; const DEFAULT_TEST_ARTIFACTS_ROOT = '.agent-device/test-artifacts'; @@ -136,16 +137,3 @@ function isExistingFile(filePath: string): boolean { return false; } } - -/** - * Linear-time edge trim. The regex form (`/^-+|-+$/g`) backtracks - * polynomially on long dash runs (CodeQL js/polynomial-redos #27/#28), and - * these slugs are built from caller-supplied file paths. - */ -export function trimEdgeDashes(value: string): string { - let start = 0; - let end = value.length; - while (start < end && value[start] === '-') start += 1; - while (end > start && value[end - 1] === '-') end -= 1; - return value.slice(start, end); -} diff --git a/packages/replay-test/src/internal/session-test-discovery.ts b/packages/replay-test/src/internal/session-test-discovery.ts index 3dc97a766f..2e7cebb520 100644 --- a/packages/replay-test/src/internal/session-test-discovery.ts +++ b/packages/replay-test/src/internal/session-test-discovery.ts @@ -1,5 +1,5 @@ import path from 'node:path'; -import { trimEdgeDashes } from './session-test-artifacts.ts'; +import { trimEdgeDashes } from '@agent-device/kernel/collections'; import { AppError } from '@agent-device/kernel/errors'; import { isApplePlatform, type PlatformSelector } from '@agent-device/kernel/device'; import type { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 26478f568f..711fd4d7d1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -48,6 +48,9 @@ importers: '@agent-device/contracts': specifier: workspace:* version: link:packages/contracts + '@agent-device/host-kit': + specifier: workspace:* + version: link:packages/host-kit '@agent-device/kernel': specifier: workspace:* version: link:packages/kernel @@ -183,9 +186,19 @@ importers: '@agent-device/contracts': specifier: workspace:* version: link:../contracts + '@agent-device/host-kit': + specifier: workspace:* + version: link:../host-kit '@agent-device/kernel': specifier: workspace:* version: link:../kernel + devDependencies: + '@types/pngjs': + specifier: ^6.0.5 + version: 6.0.5 + pngjs: + specifier: ^7.0.0 + version: 7.0.0 packages/contracts: dependencies: @@ -197,6 +210,28 @@ importers: specifier: ^4.9.0 version: 4.9.0 + packages/host-kit: + dependencies: + '@agent-device/contracts': + specifier: workspace:* + version: link:../contracts + '@agent-device/kernel': + specifier: workspace:* + version: link:../kernel + tar-stream: + specifier: ^3.2.0 + version: 3.2.0 + yauzl: + specifier: ^3.4.0 + version: 3.4.0 + devDependencies: + '@types/tar-stream': + specifier: ^3.1.4 + version: 3.1.4 + '@types/yauzl': + specifier: ^3.4.0 + version: 3.4.0 + packages/kernel: {} packages/maestro: diff --git a/scripts/__tests__/fallow-fixture-policy.test.ts b/scripts/__tests__/fallow-fixture-policy.test.ts index 00f2c000e8..bc551d925b 100644 --- a/scripts/__tests__/fallow-fixture-policy.test.ts +++ b/scripts/__tests__/fallow-fixture-policy.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { test } from 'vitest'; import { mkdtempForTest } from '../../src/__tests__/test-utils/tmp-dir.ts'; -import { runCmd } from '../../src/utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); const FALLOW_CLI = path.join(REPOSITORY_ROOT, 'node_modules', 'fallow', 'bin', 'fallow'); diff --git a/scripts/__tests__/test-file-size-ratchet.test.ts b/scripts/__tests__/test-file-size-ratchet.test.ts index 2f65584834..6d515b1417 100644 --- a/scripts/__tests__/test-file-size-ratchet.test.ts +++ b/scripts/__tests__/test-file-size-ratchet.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { expect, test } from 'vitest'; import { walkFiles } from '../lib/walk-files.ts'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; /** * Test-file size ratchet (AGENTS.md "Scope & shape": past 1,000 lines is architecture debt, diff --git a/scripts/check-affected/run.test.ts b/scripts/check-affected/run.test.ts index 58402cb696..902a60d65b 100644 --- a/scripts/check-affected/run.test.ts +++ b/scripts/check-affected/run.test.ts @@ -8,7 +8,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { STALE_NODE_MODULES_MESSAGE } from './lockfile-install-sync.ts'; import { CHECK_CATALOG } from './checks.ts'; import { DEFAULT_VITEST_MAX_WORKERS } from '../lib/vitest-concurrency.ts'; diff --git a/scripts/check-affected/run.ts b/scripts/check-affected/run.ts index 7c4d3a2759..da02fe1a63 100644 --- a/scripts/check-affected/run.ts +++ b/scripts/check-affected/run.ts @@ -8,7 +8,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdStreaming, runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/exec'; import { checkLockfileInstallSync, STALE_NODE_MODULES_MESSAGE, diff --git a/scripts/check-replay-compat-provenance.ts b/scripts/check-replay-compat-provenance.ts index df4dcd8fda..c9e1712153 100644 --- a/scripts/check-replay-compat-provenance.ts +++ b/scripts/check-replay-compat-provenance.ts @@ -16,20 +16,14 @@ import { REPLAY_COMPAT_RELEASED_TAGS, } from '../test/replay-compat/manifest.ts'; import { findProvenanceKindViolations } from '../test/replay-compat/provenance-rules.ts'; -import { runCmdSync } from '../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; +import { repoGit, requireUnshallowHistory } from './lib/repo-git.ts'; const repoRoot = path.resolve(import.meta.dirname, '..'); const corpusRoot = path.join(repoRoot, 'test', 'replay-compat'); -function git(args: string[]): string { - return runCmdSync('git', args, { cwd: repoRoot, allowFailure: true }).stdout.trim(); -} - -if (git(['rev-parse', '--is-shallow-repository']) === 'true') { - throw new Error( - 'Corpus provenance needs full history and tags. Run `git fetch --unshallow --tags` first.', - ); -} +const git = repoGit(repoRoot); +requireUnshallowHistory(git, 'Corpus provenance'); // An entry that escaped `mined` would also escape the history check below, so // the area rule is enforced here as well as in the unit lane. diff --git a/scripts/check-tmpdir-leaks-model.ts b/scripts/check-tmpdir-leaks-model.ts index 9d4ecfbfad..d6a60723b8 100644 --- a/scripts/check-tmpdir-leaks-model.ts +++ b/scripts/check-tmpdir-leaks-model.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; // Every test run (Vitest via scripts/vitest-tmpdir-global-setup.ts, node --test // via scripts/node-test-tmpdir.ts) redirects TMPDIR into one disposable, diff --git a/scripts/check-xctest-selection.ts b/scripts/check-xctest-selection.ts index 7d6977d301..b3e177463c 100644 --- a/scripts/check-xctest-selection.ts +++ b/scripts/check-xctest-selection.ts @@ -35,7 +35,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdSync } from '../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import type { Platform } from './swift-conditional-compilation.ts'; import { parseDeclaredTestsByPlatform, diff --git a/scripts/coverage-changed/run.ts b/scripts/coverage-changed/run.ts index 0802d63cc3..1196b1a717 100644 --- a/scripts/coverage-changed/run.ts +++ b/scripts/coverage-changed/run.ts @@ -12,7 +12,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { parseScriptArgs } from '../lib/cli-args.ts'; import { computeChangedCoverage, diff --git a/scripts/depgraph/affected.test.ts b/scripts/depgraph/affected.test.ts index 1a4737b17c..9b751b2627 100644 --- a/scripts/depgraph/affected.test.ts +++ b/scripts/depgraph/affected.test.ts @@ -218,7 +218,7 @@ test('text output bounds every list and says what it hid', () => { }); test('blast radius over the real tree agrees with check:affected and stays under 10s', async () => { - const file = 'src/utils/exec.ts'; + const file = 'packages/host-kit/src/internal/exec.ts'; const started = Date.now(); const radius = await computeBlastRadius(repoRoot, file); const elapsed = Date.now() - started; diff --git a/scripts/fuzz/envelope.ts b/scripts/fuzz/envelope.ts index 3df2744773..a60fc6a157 100644 --- a/scripts/fuzz/envelope.ts +++ b/scripts/fuzz/envelope.ts @@ -14,7 +14,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { laneEnvelope } from '../lib/lane-envelope.ts'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import type { FuzzFailure } from './invariant.ts'; const FILENAME = 'run-envelope.json'; diff --git a/scripts/gate/check.ts b/scripts/gate/check.ts index 91a460da95..fd6baca3ad 100644 --- a/scripts/gate/check.ts +++ b/scripts/gate/check.ts @@ -8,7 +8,7 @@ // launder a new step past review by regenerating it. import { pathToFileURL } from 'node:url'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { audit, formatFailures } from './audit.ts'; import { MANUAL_ONLY_OWNERS, UNPROVABLE_OWNERS } from './declarations.ts'; import { loadModel } from './model.ts'; diff --git a/scripts/gate/run.ts b/scripts/gate/run.ts index 9710dc4847..b2d928779b 100644 --- a/scripts/gate/run.ts +++ b/scripts/gate/run.ts @@ -10,7 +10,7 @@ import { pathToFileURL } from 'node:url'; import fs from 'node:fs'; import path from 'node:path'; -import { runCmdStreaming, runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/exec'; import { runEntrypoint } from '../lib/cli-entrypoint.ts'; import { CHECK_CATALOG, resolveCommand } from '../check-affected/checks.ts'; diff --git a/scripts/layering/model.ts b/scripts/layering/model.ts index 2dc99f55f0..4ca1aadc91 100644 --- a/scripts/layering/model.ts +++ b/scripts/layering/model.ts @@ -89,6 +89,7 @@ export const UNRANKED_ZONES: ReadonlySet = new Set([ // importer and concrete-platform authority; giving them a spine rank would duplicate that seam. 'platform-runtime', 'kernel', + 'host-kit', 'capture-kit', 'platform-apple', 'platform-android', diff --git a/scripts/layering/package-boundaries.test.ts b/scripts/layering/package-boundaries.test.ts index a48580d7fb..3ef3a07dd0 100644 --- a/scripts/layering/package-boundaries.test.ts +++ b/scripts/layering/package-boundaries.test.ts @@ -453,8 +453,44 @@ test('the real tree parses, declares, and passes R11', () => { true, 'capture-kit stays a private implementation package', ); - assert.deepEqual([...captureKitPackage.exportTargets.keys()], ['@agent-device/capture-kit']); + // #2082 W1 host-mechanics subpaths; any further subpath widens this key list + // and fails the assertion, same as the platform-apple pin below. + assert.deepEqual([...captureKitPackage.exportTargets.keys()].sort(), [ + '@agent-device/capture-kit', + '@agent-device/capture-kit/mobile-snapshot-semantics', + '@agent-device/capture-kit/png', + '@agent-device/capture-kit/png-resize', + '@agent-device/capture-kit/png-rgb-difference', + '@agent-device/capture-kit/png-size', + '@agent-device/capture-kit/png-worker-client', + '@agent-device/capture-kit/screenshot-density', + '@agent-device/capture-kit/screenshot-diff-pixels', + '@agent-device/capture-kit/snapshot-occlusion', + '@agent-device/capture-kit/snapshot-quality-backend-capabilities', + '@agent-device/capture-kit/snapshot-quality-verdict', + ]); assert.deepEqual([...captureKitPackage.workspaceDependencies].sort(), [ + '@agent-device/contracts', + '@agent-device/host-kit', + '@agent-device/kernel', + ]); + const hostKitPackage = packages.find((pkg) => pkg.name === '@agent-device/host-kit'); + assert.ok(hostKitPackage, 'host-kit package must exist'); + assert.equal( + JSON.parse(fs.readFileSync(path.join(repoRoot, 'packages/host-kit/package.json'), 'utf8')) + .private, + true, + 'host-kit stays a private implementation package', + ); + // The four deep host-mechanics seams; any further subpath widens this key + // list and fails the assertion, same as the capture-kit pin above. + assert.deepEqual([...hostKitPackage.exportTargets.keys()].sort(), [ + '@agent-device/host-kit/exec', + '@agent-device/host-kit/fs', + '@agent-device/host-kit/request', + '@agent-device/host-kit/values', + ]); + assert.deepEqual([...hostKitPackage.workspaceDependencies].sort(), [ '@agent-device/contracts', '@agent-device/kernel', ]); diff --git a/scripts/layering/platform-package-policy.test.ts b/scripts/layering/platform-package-policy.test.ts index 307ad1f5ca..8dcf85ad18 100644 --- a/scripts/layering/platform-package-policy.test.ts +++ b/scripts/layering/platform-package-policy.test.ts @@ -385,7 +385,7 @@ test('platform packages may use capture-kit but no unrelated workspace implement ); assert.match( messages(sources).join('\n'), - /may import workspace code only from capture-kit, contracts, kernel, or xml/, + /may import workspace code only from capture-kit, host-kit, contracts, kernel, or xml/, ); } }); diff --git a/scripts/layering/platform-package-policy.ts b/scripts/layering/platform-package-policy.ts index 249dc02029..dca542aef8 100644 --- a/scripts/layering/platform-package-policy.ts +++ b/scripts/layering/platform-package-policy.ts @@ -263,6 +263,7 @@ function checkSource(file: string, source: string): LayeringViolation[] { !site.spec.startsWith('@agent-device/contracts/') && site.spec !== '@agent-device/capture-kit' && !site.spec.startsWith('@agent-device/capture-kit/') && + !site.spec.startsWith('@agent-device/host-kit/') && !site.spec.startsWith('@agent-device/kernel/') && site.spec !== '@agent-device/xml' && !isPackageOwnedFacadeTest(file, ownerFamily, site.spec) @@ -271,7 +272,7 @@ function checkSource(file: string, source: string): LayeringViolation[] { violation( file, site.line, - `platform-${ownerFamily} may import workspace code only from capture-kit, contracts, kernel, or xml; found '${site.spec}'`, + `platform-${ownerFamily} may import workspace code only from capture-kit, host-kit, contracts, kernel, or xml; found '${site.spec}'`, ), ); } diff --git a/scripts/lib/repo-git.ts b/scripts/lib/repo-git.ts new file mode 100644 index 0000000000..310175e6c4 --- /dev/null +++ b/scripts/lib/repo-git.ts @@ -0,0 +1,15 @@ +import { runCmdSync } from '@agent-device/host-kit/exec'; + +export type RepoGit = (args: string[]) => string; + +export function repoGit(repoRoot: string): RepoGit { + return (args) => runCmdSync('git', args, { cwd: repoRoot, allowFailure: true }).stdout.trim(); +} + +/** History-derivation checks cannot run against a shallow CI clone. */ +export function requireUnshallowHistory(git: RepoGit, subject: string): void { + if (git(['rev-parse', '--is-shallow-repository']) !== 'true') return; + throw new Error( + `${subject} needs full history and tags. Run \`git fetch --unshallow --tags\` first.`, + ); +} diff --git a/scripts/mutation/envelope.test.ts b/scripts/mutation/envelope.test.ts index ea026942d5..b6b2ba592e 100644 --- a/scripts/mutation/envelope.test.ts +++ b/scripts/mutation/envelope.test.ts @@ -7,7 +7,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test } from 'node:test'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { laneEnvelope, LANE_ENVELOPE_SCHEMA_VERSION } from '../lib/lane-envelope.ts'; const repoRoot = path.resolve(import.meta.dirname, '../..'); diff --git a/scripts/mutation/modules.ts b/scripts/mutation/modules.ts index e337fa33ce..81e321e31e 100644 --- a/scripts/mutation/modules.ts +++ b/scripts/mutation/modules.ts @@ -87,8 +87,8 @@ export const KERNEL_MODULES: readonly KernelModule[] = [ { id: 'snapshot-occlusion', label: 'Snapshot occlusion (covered/not-covered) decisions', - mutate: ['src/snapshot/snapshot-occlusion.ts'], - owns: ['src/snapshot/snapshot-occlusion.ts'], + mutate: ['packages/capture-kit/src/snapshot-occlusion.ts'], + owns: ['packages/capture-kit/src/snapshot-occlusion.ts'], }, ]; diff --git a/scripts/mutation/run.ts b/scripts/mutation/run.ts index a4888dfcb0..64a87eeb47 100644 --- a/scripts/mutation/run.ts +++ b/scripts/mutation/run.ts @@ -15,7 +15,7 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdStreaming, runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/exec'; import { parseScriptArgs } from '../lib/cli-args.ts'; import { laneEnvelope } from '../lib/lane-envelope.ts'; import { diff --git a/scripts/mutation/selection.test.ts b/scripts/mutation/selection.test.ts index 137b102528..d8737e9231 100644 --- a/scripts/mutation/selection.test.ts +++ b/scripts/mutation/selection.test.ts @@ -8,7 +8,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { after, test } from 'node:test'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { LANE_CANARY, shardMatrix, type ShardSpec } from './modules.ts'; import { affectedMatrixFor } from './run.ts'; diff --git a/scripts/mutation/test-scope.test.ts b/scripts/mutation/test-scope.test.ts index 9dc565738a..c29145b6af 100644 --- a/scripts/mutation/test-scope.test.ts +++ b/scripts/mutation/test-scope.test.ts @@ -21,7 +21,7 @@ test('the thread-hostile exclusion is derived from imports, not listed', () => { // Both reasons are represented: process.chdir (CLI capture harness) and a // worker inside a worker (the node:worker_threads PNG pipeline). assert.ok(files.includes('src/__tests__/cli-help.test.ts')); - assert.ok(files.includes('src/utils/__tests__/png-worker.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.every((file) => file.endsWith('.test.ts'))); diff --git a/scripts/mutation/test-scope.ts b/scripts/mutation/test-scope.ts index 9127825d9b..0961f37f4d 100644 --- a/scripts/mutation/test-scope.ts +++ b/scripts/mutation/test-scope.ts @@ -27,7 +27,7 @@ import fs from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { readWorkspacePackages } from '../layering/package-boundaries.ts'; import { walkFiles } from '../lib/walk-files.ts'; import { isKernelTestFile, normalizePath } from './modules.ts'; diff --git a/scripts/mutation/workspace-aliases.test.ts b/scripts/mutation/workspace-aliases.test.ts index f8f0671493..f8e5eeaaa7 100644 --- a/scripts/mutation/workspace-aliases.test.ts +++ b/scripts/mutation/workspace-aliases.test.ts @@ -1,4 +1,5 @@ import assert from 'node:assert/strict'; +import fs from 'node:fs'; import path from 'node:path'; import { test } from 'node:test'; import { workspaceSpecifierTargets } from '../layering/package-boundaries.ts'; @@ -8,7 +9,7 @@ const repoRoot = path.resolve(import.meta.dirname, '../..'); test('Stryker aliases every exported workspace subpath exactly', () => { const targets = workspaceSpecifierTargets(repoRoot); - const aliases = workspaceSourceAliases(repoRoot); + const aliases = workspaceSourceAliases(repoRoot, 'tracked-manifests'); for (const [specifier, target] of targets) { const matches = aliases.filter(({ find }) => find.test(specifier)); @@ -24,3 +25,43 @@ test('Stryker aliases every exported workspace subpath exactly', () => { false, ); }); + +test('disk manifests alias an untracked sandbox copy the tracked reader cannot see', () => { + // Inside the repository tree, like the real sandbox under .tmp/stryker: + // `git ls-files` runs but lists nothing, which is the exact blindness the + // disk reader exists for. + fs.mkdirSync(path.join(repoRoot, '.tmp'), { recursive: true }); + const sandboxRoot = fs.mkdtempSync(path.join(repoRoot, '.tmp', 'stryker-sandbox-fixture-')); + try { + const packageDir = path.join(sandboxRoot, 'packages', 'kernel'); + fs.mkdirSync(path.join(packageDir, 'src'), { recursive: true }); + fs.writeFileSync( + path.join(packageDir, 'package.json'), + JSON.stringify({ + name: '@agent-device/kernel', + exports: { './errors': { default: './src/errors.ts' } }, + }), + ); + fs.writeFileSync(path.join(packageDir, 'src', 'errors.ts'), 'export const mutated = true;\n'); + + assert.deepEqual( + workspaceSourceAliases(sandboxRoot, 'tracked-manifests'), + [], + 'the git-backed reader must see nothing in an untracked copy', + ); + + const diskAliases = workspaceSourceAliases(sandboxRoot, 'disk-manifests'); + const match = diskAliases.filter(({ find }) => find.test('@agent-device/kernel/errors')); + assert.deepEqual( + match.map(({ replacement }) => replacement), + [path.join(sandboxRoot, 'packages', 'kernel', 'src', 'errors.ts')], + 'the disk reader must resolve the specifier inside the sandbox copy', + ); + assert.equal( + diskAliases.some(({ find }) => find.test('@agent-device/kernel/not-exported')), + false, + ); + } finally { + fs.rmSync(sandboxRoot, { recursive: true, force: true }); + } +}); diff --git a/scripts/mutation/workspace-aliases.ts b/scripts/mutation/workspace-aliases.ts index 05b50eaee8..0261dec36d 100644 --- a/scripts/mutation/workspace-aliases.ts +++ b/scripts/mutation/workspace-aliases.ts @@ -1,3 +1,4 @@ +import fs from 'node:fs'; import path from 'node:path'; import { workspaceSpecifierTargets } from '../layering/package-boundaries.ts'; @@ -6,13 +7,55 @@ export type WorkspaceSourceAlias = { replacement: string; }; +export type ManifestSource = 'tracked-manifests' | 'disk-manifests'; + function exactSpecifier(specifier: string): RegExp { return new RegExp(`^${specifier.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')}$`); } -/** Exact exported workspace-package aliases for Vitest inside Stryker's sandbox. */ -export function workspaceSourceAliases(repoRoot: string): WorkspaceSourceAlias[] { - return [...workspaceSpecifierTargets(repoRoot)].map(([specifier, target]) => ({ +function specifierTargets(repoRoot: string, source: ManifestSource): ReadonlyMap { + return source === 'tracked-manifests' + ? workspaceSpecifierTargets(repoRoot) + : diskSpecifierTargets(repoRoot); +} + +function diskSpecifierTargets(repoRoot: string): ReadonlyMap { + const targets = new Map(); + const packagesDir = path.join(repoRoot, 'packages'); + if (!fs.existsSync(packagesDir)) return targets; + for (const entry of fs.readdirSync(packagesDir)) { + for (const [specifier, target] of manifestSpecifierTargets(packagesDir, entry)) { + targets.set(specifier, target); + } + } + return targets; +} + +function* manifestSpecifierTargets( + packagesDir: string, + entry: string, +): Generator<[string, string]> { + const manifestPath = path.join(packagesDir, entry, 'package.json'); + if (!fs.existsSync(manifestPath)) return; + const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8')) as { + name?: string; + exports?: Record; + }; + if (!manifest.name?.startsWith('@agent-device/')) return; + for (const [subpath, targetEntry] of Object.entries(manifest.exports ?? {})) { + const target = targetEntry?.default; + if (!target) continue; + const specifier = subpath === '.' ? manifest.name : `${manifest.name}/${subpath.slice(2)}`; + yield [specifier, path.join('packages', entry, target)]; + } +} + +/** Exact exported workspace-package aliases for Vitest, from the declared manifest source. */ +export function workspaceSourceAliases( + repoRoot: string, + source: ManifestSource, +): WorkspaceSourceAlias[] { + return [...specifierTargets(repoRoot, source)].map(([specifier, target]) => ({ find: exactSpecifier(specifier), replacement: path.join(repoRoot, target), })); diff --git a/scripts/node-test-tmpdir.test.ts b/scripts/node-test-tmpdir.test.ts index 22b44ccab8..0a1c54793d 100644 --- a/scripts/node-test-tmpdir.test.ts +++ b/scripts/node-test-tmpdir.test.ts @@ -5,7 +5,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmd, runCmdBackground } from '../src/utils/exec.ts'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; import { liveRunDirectoryConsumers, pruneAbandonedRunDirectories, @@ -318,7 +318,7 @@ test('a run whose owner alone was killed keeps its directory while a child still `import fs from 'node:fs'; import os from 'node:os'; import { test } from 'node:test'; -import { runCmdDetached } from '../src/utils/exec.ts'; +import { runCmdDetached } from '@agent-device/host-kit/exec'; test('probe starts a long-lived detached child that inherits TMPDIR, then waits to be killed', async () => { const childPid = runCmdDetached(process.execPath, ['-e', 'setTimeout(() => {}, 60_000)']); diff --git a/scripts/node-test-tmpdir.ts b/scripts/node-test-tmpdir.ts index bb1af509bc..921daf7746 100644 --- a/scripts/node-test-tmpdir.ts +++ b/scripts/node-test-tmpdir.ts @@ -27,7 +27,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { runCmdBackground } from '../src/utils/exec.ts'; +import { runCmdBackground } from '@agent-device/host-kit/exec'; import { TEST_RUN_TMP_PREFIX, TEST_RUN_TMP_ROOT, diff --git a/scripts/perf/cli.ts b/scripts/perf/cli.ts index 486cc5eb83..437b1283ec 100644 --- a/scripts/perf/cli.ts +++ b/scripts/perf/cli.ts @@ -1,5 +1,5 @@ import { performance } from 'node:perf_hooks'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { resolveCliArgv, REPO_ROOT } from './config.ts'; import type { BatchStepSpec } from './scenario.ts'; import type { CliResult } from './types.ts'; diff --git a/scripts/swift-toolchain-tmpdir.test.ts b/scripts/swift-toolchain-tmpdir.test.ts index edc5d3f8a3..a6791263e8 100644 --- a/scripts/swift-toolchain-tmpdir.test.ts +++ b/scripts/swift-toolchain-tmpdir.test.ts @@ -4,7 +4,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmd, runCmdBackground } from '../src/utils/exec.ts'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const WRAPPER = path.join(REPOSITORY_ROOT, 'scripts', 'swift-toolchain-tmpdir.ts'); diff --git a/scripts/swift-toolchain-tmpdir.ts b/scripts/swift-toolchain-tmpdir.ts index 23fec43a5a..a8e34b10b2 100644 --- a/scripts/swift-toolchain-tmpdir.ts +++ b/scripts/swift-toolchain-tmpdir.ts @@ -5,7 +5,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { runCmdBackground } from '../src/utils/exec.ts'; +import { runCmdBackground } from '@agent-device/host-kit/exec'; const [command, ...args] = process.argv.slice(2); if (!command) { diff --git a/scripts/vitest-tmpdir-global-setup.test.ts b/scripts/vitest-tmpdir-global-setup.test.ts index f151107845..8317751d50 100644 --- a/scripts/vitest-tmpdir-global-setup.test.ts +++ b/scripts/vitest-tmpdir-global-setup.test.ts @@ -5,7 +5,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmd } from '../src/utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { TEST_RUN_TMP_PREFIX, TEST_RUN_TMP_ROOT } from './check-tmpdir-leaks-model.ts'; const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); diff --git a/scripts/wire-compat/run.ts b/scripts/wire-compat/run.ts index b7b38b1f6b..ff5f86112e 100644 --- a/scripts/wire-compat/run.ts +++ b/scripts/wire-compat/run.ts @@ -19,7 +19,7 @@ */ import path from 'node:path'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { repoGit, requireUnshallowHistory } from '../lib/repo-git.ts'; import { digestDeclaration } from '../../test/wire-compat/declaration-digest.ts'; import { digestWireSurface, @@ -32,15 +32,8 @@ import { compareWireLedgers } from './model.ts'; const repoRoot = path.resolve(import.meta.dirname, '..', '..'); -function git(args: string[]): string { - return runCmdSync('git', args, { cwd: repoRoot, allowFailure: true }).stdout.trim(); -} - -if (git(['rev-parse', '--is-shallow-repository']) === 'true') { - throw new Error( - 'Daemon wire compatibility needs full history and tags. Run `git fetch --unshallow --tags` first.', - ); -} +const git = repoGit(repoRoot); +requireUnshallowHistory(git, 'Daemon wire compatibility'); /** Released tags newest-first by semver, not by tag-creation order. */ function releasedTagsNewestFirst(): string[] { diff --git a/src/__tests__/apple-runner-package-source.test.ts b/src/__tests__/apple-runner-package-source.test.ts index 64bd5d972e..16faac4553 100644 --- a/src/__tests__/apple-runner-package-source.test.ts +++ b/src/__tests__/apple-runner-package-source.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { onTestFinished, test } from 'vitest'; -import { runCmd } from '../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); diff --git a/src/__tests__/cli-agent-cdp.test.ts b/src/__tests__/cli-agent-cdp.test.ts index 45cc29fa86..2a61c7d88f 100644 --- a/src/__tests__/cli-agent-cdp.test.ts +++ b/src/__tests__/cli-agent-cdp.test.ts @@ -2,11 +2,11 @@ import fs from 'node:fs'; import assert from 'node:assert/strict'; import { afterEach, test, vi } from 'vitest'; -vi.mock('../utils/exec.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', () => ({ runCmdStreaming: vi.fn(), })); -import { runCmdStreaming } from '../utils/exec.ts'; +import { runCmdStreaming } from '@agent-device/host-kit/exec'; import { AGENT_CDP_PACKAGE, buildAgentCdpNpmExecArgs, diff --git a/src/__tests__/cli-auth-diagnostics.test.ts b/src/__tests__/cli-auth-diagnostics.test.ts index d8f6eed3b1..1d9fedf610 100644 --- a/src/__tests__/cli-auth-diagnostics.test.ts +++ b/src/__tests__/cli-auth-diagnostics.test.ts @@ -1,7 +1,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import fs from 'node:fs'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { runCliCapture } from './cli-capture.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; diff --git a/src/__tests__/cli-client-commands.test.ts b/src/__tests__/cli-client-commands.test.ts index 6f267346db..42866b11bd 100644 --- a/src/__tests__/cli-client-commands.test.ts +++ b/src/__tests__/cli-client-commands.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; import assert from 'node:assert/strict'; -import { PNG } from '../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { tryRunClientBackedCommand } from '../cli/commands/router.ts'; import { runCliCapture } from './cli-capture.ts'; import type { diff --git a/src/__tests__/cli-debug-symbols.test.ts b/src/__tests__/cli-debug-symbols.test.ts index 4f6d6fd738..713b217bc1 100644 --- a/src/__tests__/cli-debug-symbols.test.ts +++ b/src/__tests__/cli-debug-symbols.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import path from 'node:path'; import { test } from 'vitest'; -import { withCommandExecutorOverride } from '../utils/exec.ts'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { runCliCapture } from './cli-capture.ts'; import { mkdtempForTest } from './test-utils/tmp-dir.ts'; diff --git a/src/__tests__/cli-device-status.test.ts b/src/__tests__/cli-device-status.test.ts index 59c1b7adcd..617467e2db 100644 --- a/src/__tests__/cli-device-status.test.ts +++ b/src/__tests__/cli-device-status.test.ts @@ -2,12 +2,12 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test, vi } from 'vitest'; -import { readCurrentOwnerIdentity } from '../utils/owner-identity.ts'; +import { readCurrentOwnerIdentity } from '@agent-device/host-kit/exec'; import { runCliCapture } from './cli-capture.ts'; import { publishDaemonRegistration } from './test-utils/device-claim-store.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('../utils/host-process.ts', async (importOriginal) => +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => (await import('./test-utils/host-process-mock.ts')).pinOwnProcessStartTime(importOriginal), ); diff --git a/src/__tests__/cli-diff.test.ts b/src/__tests__/cli-diff.test.ts index 6dfe82de65..8a26b992d6 100644 --- a/src/__tests__/cli-diff.test.ts +++ b/src/__tests__/cli-diff.test.ts @@ -3,7 +3,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { PNG } from '../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import type { DaemonResponse } from '../daemon/client/daemon-client.ts'; import { runCliCapture as captureCli, diff --git a/src/__tests__/cli-react-devtools.test.ts b/src/__tests__/cli-react-devtools.test.ts index f9896250fa..f67e9bfb0c 100644 --- a/src/__tests__/cli-react-devtools.test.ts +++ b/src/__tests__/cli-react-devtools.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import { afterEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('../utils/exec.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', () => ({ runCmdStreaming: vi.fn(), })); @@ -11,7 +11,7 @@ vi.mock('../client/client-react-devtools-companion.ts', () => ({ stopReactDevtoolsCompanion: vi.fn(), })); -import { runCmdStreaming } from '../utils/exec.ts'; +import { runCmdStreaming } from '@agent-device/host-kit/exec'; import { ensureReactDevtoolsCompanion, stopReactDevtoolsCompanion, diff --git a/src/__tests__/cli-web.test.ts b/src/__tests__/cli-web.test.ts index 9f74552a03..c62a3fab8a 100644 --- a/src/__tests__/cli-web.test.ts +++ b/src/__tests__/cli-web.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import { test } from 'vitest'; import { runCliCapture } from './cli-capture.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -import { withCommandExecutorOverride } from '../utils/exec.ts'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { installFakeManagedAgentBrowser, withNodeRuntime, diff --git a/src/__tests__/client-metro-companion.test.ts b/src/__tests__/client-metro-companion.test.ts index 15e221d820..04eb4cf40d 100644 --- a/src/__tests__/client-metro-companion.test.ts +++ b/src/__tests__/client-metro-companion.test.ts @@ -4,24 +4,23 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('../utils/exec.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), runCmdDetached: vi.fn(), -})); - -vi.mock('../utils/host-process.ts', () => ({ isProcessAlive: vi.fn(), readProcessCommand: vi.fn(), readProcessStartTime: vi.fn(), waitForProcessExit: vi.fn(), })); -import { runCmdDetached } from '../utils/exec.ts'; import { + runCmdDetached, isProcessAlive, readProcessCommand, readProcessStartTime, waitForProcessExit, -} from '../utils/host-process.ts'; +} from '@agent-device/host-kit/exec'; + import { ensureMetroCompanion, stopMetroCompanion } from '../metro/client-metro-companion.ts'; import { ensureReactDevtoolsCompanion } from '../client/client-react-devtools-companion.ts'; diff --git a/src/__tests__/client-metro-startup-cleanup.test.ts b/src/__tests__/client-metro-startup-cleanup.test.ts index cd25a945da..900b90fbe2 100644 --- a/src/__tests__/client-metro-startup-cleanup.test.ts +++ b/src/__tests__/client-metro-startup-cleanup.test.ts @@ -4,17 +4,15 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('../utils/exec.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), runCmdDetached: vi.fn(), runCmdSync: vi.fn(), -})); - -vi.mock('../utils/host-process.ts', () => ({ waitForProcessExit: vi.fn(), })); -import { runCmdDetached } from '../utils/exec.ts'; -import { waitForProcessExit } from '../utils/host-process.ts'; +import { runCmdDetached, waitForProcessExit } from '@agent-device/host-kit/exec'; + import { prepareMetroRuntime } from '../metro/client-metro.ts'; afterEach(() => { diff --git a/src/__tests__/client-metro.test.ts b/src/__tests__/client-metro.test.ts index 0c57ef6dc9..ca228be85f 100644 --- a/src/__tests__/client-metro.test.ts +++ b/src/__tests__/client-metro.test.ts @@ -14,7 +14,7 @@ import { createAgentDeviceClient } from '../agent-device-client.ts'; import { readMetroSessionHints } from '../metro/metro-session-hints.ts'; import { resolveDaemonPaths } from '../daemon/config.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { isProcessAlive, waitForProcessExit } from '../utils/host-process.ts'; +import { isProcessAlive, waitForProcessExit } from '@agent-device/host-kit/exec'; const TEST_TOKEN = 'agent-device-proxy-test-token'; diff --git a/src/__tests__/daemon-entrypoint.test.ts b/src/__tests__/daemon-entrypoint.test.ts index 87e8de8f4b..e75a2cca1d 100644 --- a/src/__tests__/daemon-entrypoint.test.ts +++ b/src/__tests__/daemon-entrypoint.test.ts @@ -10,8 +10,8 @@ import { cleanupDownloadableArtifact, trackDownloadableArtifact, } from '../daemon/artifact-tracking.ts'; -import { runCmdBackground } from '../utils/exec.ts'; -import { isProcessAlive, waitForProcessExit } from '../utils/host-process.ts'; +import { runCmdBackground, isProcessAlive, waitForProcessExit } from '@agent-device/host-kit/exec'; + import { closeLoopbackServer, listenOnLoopback, waitForHttpOk } from './test-utils/loopback.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; diff --git a/src/__tests__/eager-closure-budgets.ts b/src/__tests__/eager-closure-budgets.ts index b3108d9f6f..e97902c05a 100644 --- a/src/__tests__/eager-closure-budgets.ts +++ b/src/__tests__/eager-closure-budgets.ts @@ -106,7 +106,7 @@ export function discoverFacadeEntryFiles(repoRoot: string): string[] { */ export const FACADE_BUDGETS: Readonly> = Object.freeze({ // --- @agent-device/ad-replay --- - 'packages/ad-replay/src/index.ts': 58, + 'packages/ad-replay/src/index.ts': 57, // --- @agent-device/ad-script --- 'packages/ad-script/src/index.ts': 37, @@ -122,6 +122,24 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ // --- @agent-device/capture-kit --- // R60 review: audio-probe split into descriptor/status/recovery/live-process modules (+3 files). 'packages/capture-kit/src/index.ts': 32, + 'packages/capture-kit/src/png-resize.ts': 28, + 'packages/capture-kit/src/png-rgb-difference.ts': 1, + 'packages/capture-kit/src/png-size.ts': 3, + 'packages/capture-kit/src/png-worker-client.ts': 20, + 'packages/capture-kit/src/png.ts': 3, + 'packages/capture-kit/src/screenshot-density.ts': 6, + 'packages/capture-kit/src/screenshot-diff-pixels.ts': 1, + 'packages/capture-kit/src/mobile-snapshot-semantics.ts': 10, + 'packages/capture-kit/src/snapshot-occlusion.ts': 10, + 'packages/capture-kit/src/snapshot-quality-backend-capabilities.ts': 1, + 'packages/capture-kit/src/snapshot-quality-verdict.ts': 2, + + // --- @agent-device/host-kit --- + // Deep seams: each façade eagerly closes over the internal modules it names. + 'packages/host-kit/src/exec.ts': 14, + 'packages/host-kit/src/fs.ts': 19, + 'packages/host-kit/src/request.ts': 5, + 'packages/host-kit/src/values.ts': 12, // --- @agent-device/contracts --- 'packages/contracts/src/alert-contract.ts': 1, @@ -188,6 +206,7 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/contracts/src/keyboard.ts': 1, 'packages/contracts/src/logs-runtime-plan.ts': 5, 'packages/contracts/src/managed-web-backend.ts': 1, + // #2082 W1: snapshot semantics moved out of root src. 'packages/contracts/src/navigation.ts': 1, 'packages/contracts/src/network-runtime-plan.ts': 5, 'packages/contracts/src/network-runtime.ts': 1, @@ -235,12 +254,16 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/kernel/src/errors.ts': 2, // Added by #2041: keyed async lock moved from src/utils for the extracted IME lifecycle. 'packages/kernel/src/keyed-lock.ts': 1, + // #2082 W1: geometry/vocabulary sunk below contracts. + 'packages/kernel/src/rect-center.ts': 2, 'packages/kernel/src/rect.ts': 1, 'packages/kernel/src/redaction.ts': 1, + 'packages/kernel/src/scroll-indicator.ts': 1, 'packages/kernel/src/snapshot.ts': 1, // --- @agent-device/maestro --- - 'packages/maestro/src/index.ts': 105, + // +1 in #2082 W1: internal/shared.ts reuses @agent-device/kernel/rect-center. + 'packages/maestro/src/index.ts': 106, // --- @agent-device/platform-*: ADR-0019's metadata-eager/implementation-lazy façades. Each // evaluates only itself; every implementation sits behind a function-scoped `await import`. @@ -276,7 +299,7 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/provider-webdriver/src/index.ts': 49, // --- @agent-device/replay-test --- - 'packages/replay-test/src/index.ts': 19, + 'packages/replay-test/src/index.ts': 20, // --- @agent-device/selectors --- 'packages/selectors/src/ast.ts': 16, @@ -337,7 +360,7 @@ export const HUB_BUDGETS: Readonly> = Object.freeze({ // readers), `input-audience.ts` (who may write a key), and `common-input-fields.ts` (the table // itself). Every command schema already evaluated all three concerns; the growth is three more // module records for the same code, with no new subtree behind any of them. - 'src/cli.ts': 368, + 'src/cli.ts': 386, 'src/platform-runtime.ts': 47, 'src/core/command-descriptor/registry.ts': 67, 'src/core/command-descriptor/platform-execution-entry.ts': 3, @@ -345,7 +368,7 @@ export const HUB_BUDGETS: Readonly> = Object.freeze({ // R64 removes the perf plugin facet and keeps collector binding behind the selected runtime // operation. Teardown now owns only neutral durable-resource cleanup; platform collectors load // through the perf host when an admitted operation actually runs. - 'src/daemon/session-teardown.ts': 60, + 'src/daemon/session-teardown.ts': 79, }); /** diff --git a/src/__tests__/limrun-runtime.test.ts b/src/__tests__/limrun-runtime.test.ts index 83d77d4ed0..a751f5954e 100644 --- a/src/__tests__/limrun-runtime.test.ts +++ b/src/__tests__/limrun-runtime.test.ts @@ -6,8 +6,8 @@ import { LimrunRuntime } from '../sdk/limrun.ts'; import { createExpiredProviderLeaseReleaser } from '../daemon/provider-lease-expiry.ts'; import type { SimulatorLease } from '../daemon/lease-registry.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { runCmd } from '../utils/exec.ts'; -import { readVersion } from '../utils/version.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; +import { readVersion } from '@agent-device/host-kit/values'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; type LimrunInstancePage = { @@ -114,8 +114,8 @@ vi.mock('@limrun/api/instance-client', () => ({ })), })); -vi.mock('../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async () => ({ stdout: '', stderr: '', exitCode: 0 })), diff --git a/src/__tests__/process-memo-setup.ts b/src/__tests__/process-memo-setup.ts index 12319b1287..34a46875b3 100644 --- a/src/__tests__/process-memo-setup.ts +++ b/src/__tests__/process-memo-setup.ts @@ -1,6 +1,6 @@ import { afterEach } from 'vitest'; -import { resetAllProcessMemosForTests } from '../utils/ttl-memo.ts'; +import { resetAllProcessMemosForTests } from '@agent-device/host-kit/values'; afterEach(() => { resetAllProcessMemosForTests(); diff --git a/src/__tests__/test-utils/device-claim-store.ts b/src/__tests__/test-utils/device-claim-store.ts index 84bcfe2736..a503b0d6da 100644 --- a/src/__tests__/test-utils/device-claim-store.ts +++ b/src/__tests__/test-utils/device-claim-store.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { afterEach } from 'vitest'; import { mkdtempForTestSync } from './tmp-dir.ts'; import type { DeviceClaimReconciler } from '../../daemon/device-claims.ts'; -import type { OwnerIdentity } from '../../utils/owner-identity.ts'; +import type { OwnerIdentity } from '@agent-device/host-kit/exec'; export type IsolatedDeviceClaimStore = { /** Temporary root holding both the claim store and the daemon state dir. */ diff --git a/src/__tests__/test-utils/exec-faults.ts b/src/__tests__/test-utils/exec-faults.ts index 7ab4ac762b..6b0cad89c1 100644 --- a/src/__tests__/test-utils/exec-faults.ts +++ b/src/__tests__/test-utils/exec-faults.ts @@ -1,4 +1,4 @@ -import type { CommandExecutorOverride, ExecOptions, ExecResult } from '../../utils/exec.ts'; +import type { CommandExecutorOverride, ExecOptions, ExecResult } from '@agent-device/host-kit/exec'; export type RecordedCommand = Readonly<{ command: string; diff --git a/src/__tests__/test-utils/fake-apple-tool.ts b/src/__tests__/test-utils/fake-apple-tool.ts index 613dec75e2..afdaba7906 100644 --- a/src/__tests__/test-utils/fake-apple-tool.ts +++ b/src/__tests__/test-utils/fake-apple-tool.ts @@ -2,7 +2,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import type { AppleToolProvider } from '../../platforms/apple/core/tool-provider.ts'; import { withAppleToolProvider } from '../../platforms/apple/core/tool-provider.ts'; -import { execFailureDetails, type ExecResult } from '../../utils/exec.ts'; +import { execFailureDetails, type ExecResult } from '@agent-device/host-kit/exec'; import { IOS_DEVICE } from './device-fixtures.ts'; /** diff --git a/src/__tests__/test-utils/filesystem-boundary-faults.ts b/src/__tests__/test-utils/filesystem-boundary-faults.ts index 029f029bfc..3e173fdd60 100644 --- a/src/__tests__/test-utils/filesystem-boundary-faults.ts +++ b/src/__tests__/test-utils/filesystem-boundary-faults.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test, vi } from 'vitest'; -import { isAtomicPublishTemporaryPath } from '../../utils/atomic-file.ts'; +import { isAtomicPublishTemporaryPath } from '@agent-device/host-kit/fs'; import { mkdtempForTestSync } from './tmp-dir.ts'; export type FilesystemErrno = 'EIO' | 'ENOSPC' | 'EMFILE'; diff --git a/src/__tests__/test-utils/host-process-mock.ts b/src/__tests__/test-utils/host-process-mock.ts index f40a5b0b1e..57bd3ab756 100644 --- a/src/__tests__/test-utils/host-process-mock.ts +++ b/src/__tests__/test-utils/host-process-mock.ts @@ -1,9 +1,9 @@ -type HostProcessModule = typeof import('../../utils/host-process.ts'); +type HostProcessModule = typeof import('@agent-device/host-kit/exec'); type HostProcessIdentityObservation = - import('../../utils/host-process.ts').HostProcessIdentityObservation; + import('@agent-device/host-kit/exec').HostProcessIdentityObservation; /** - * `vi.mock` factory for `utils/host-process.ts` in tests that seed a "live" + * `vi.mock` factory for the host-kit `exec` seam in tests that seed a "live" * owner from the test process's own identity (readCurrentOwnerIdentity and * friends) and later have production code re-read it during classification. * @@ -16,13 +16,12 @@ type HostProcessIdentityObservation = * syscall, not a subprocess), so fabricated dead-pid fixtures still classify * as dead through that non-flaky check. * - * Usage: `vi.mock('/utils/host-process.ts', async (importOriginal) => + * Usage: `vi.mock('@agent-device/host-kit/exec', async (importOriginal) => * (await import('/test-utils/host-process-mock.ts')).pinOwnProcessStartTime(importOriginal))` */ // Consumed by three suites, but only through `(await import(...)).pinOwnProcessStartTime` // inside `vi.mock` factories — vitest hoists those above static imports, so the dynamic // form is required and fallow cannot trace the consumers statically. -// fallow-ignore-next-line unused-export export async function pinOwnProcessStartTime( importOriginal: () => Promise, ): Promise { @@ -30,6 +29,9 @@ export async function pinOwnProcessStartTime( const ownStartTime = 'test-process-start-time'; return { ...actual, + // The seam mock cannot reach readCurrentOwnerIdentity's internal + // readProcessStartTime call, so the recorded identity is pinned here too. + readCurrentOwnerIdentity: () => ({ pid: process.pid, startTime: ownStartTime }), readProcessStartTime: (pid: number) => { if (pid !== process.pid) return null; return ownStartTime; diff --git a/src/__tests__/update-check.test.ts b/src/__tests__/update-check.test.ts index 247bfed833..f687616a9b 100644 --- a/src/__tests__/update-check.test.ts +++ b/src/__tests__/update-check.test.ts @@ -4,11 +4,11 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('../utils/exec.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', () => ({ runCmdDetached: vi.fn(), })); -import { runCmdDetached } from '../utils/exec.ts'; +import { runCmdDetached } from '@agent-device/host-kit/exec'; import { maybeRunUpgradeNotifier, runUpdateCheckWorker } from '../utils/update-check.ts'; function makeTempStateDir(): string { diff --git a/src/__tests__/upload-client.test.ts b/src/__tests__/upload-client.test.ts index 4633e381d1..50776087b6 100644 --- a/src/__tests__/upload-client.test.ts +++ b/src/__tests__/upload-client.test.ts @@ -7,7 +7,7 @@ import path from 'node:path'; import { once } from 'node:events'; import { uploadArtifact } from '../remote/upload-client.ts'; import type { UploadProgressEvent } from '../remote/upload-progress.ts'; -import { runCmdSync, withCommandExecutorOverride } from '../utils/exec.ts'; +import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; const TEST_TOKEN = 'agent-device-upload-test-token'; diff --git a/src/agent-device-client.ts b/src/agent-device-client.ts index 124222f541..df7c485b74 100644 --- a/src/agent-device-client.ts +++ b/src/agent-device-client.ts @@ -78,7 +78,7 @@ import { writeMetroSessionHints, type MetroSessionHints, } from './metro/metro-session-hints.ts'; -import { isRecord } from './utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import { readScreenshotResultData } from './utils/screenshot-result.ts'; type ProjectedSystemCommandClient = ProjectedNavigationCommandClient & diff --git a/src/bin.ts b/src/bin.ts index 7797305bab..17bdf8d5c3 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -24,7 +24,7 @@ function runVersionFastPath(argv: string[]): boolean { process.stdout.write(`${__AGENT_DEVICE_VERSION__}\n`); return true; } - import('./utils/version.ts') + import('@agent-device/host-kit/values') .then(({ readVersion }) => { process.stdout.write(`${readVersion()}\n`); }) diff --git a/src/cli-schema/cli-config.ts b/src/cli-schema/cli-config.ts index 31358ebe6b..2bc94379a8 100644 --- a/src/cli-schema/cli-config.ts +++ b/src/cli-schema/cli-config.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import { mergeDefinedFlags } from '../utils/merge-flags.ts'; import { type FlagKey } from '../commands/cli-grammar/flag-types.ts'; -import { expandUserHomePath, resolveUserPath } from '../utils/path-resolution.ts'; +import { expandUserHomePath, resolveUserPath } from '@agent-device/host-kit/fs'; import { getConfigurableOptionSpecs, getOptionSpec, @@ -12,7 +12,7 @@ import { } from './option-schema.ts'; import { parseInstallSourceConfig } from '../utils/install-source-config.ts'; import { RETIRED_SCREENSHOT_MAX_SIZE } from '@agent-device/contracts/capture'; -import type { EnvMap } from '../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; export function resolveConfigBackedFlagDefaults(options: { command: string | null; diff --git a/src/cli-schema/cli-help-examples.test.ts b/src/cli-schema/cli-help-examples.test.ts index 5a00507393..d34f14eaab 100644 --- a/src/cli-schema/cli-help-examples.test.ts +++ b/src/cli-schema/cli-help-examples.test.ts @@ -7,7 +7,7 @@ import { buildCommandUsageText, buildUsageText, helpTopicIds } from './cli-help. import { listCliCommandNames } from '../command-catalog.ts'; import { readInputFromCli } from '../commands/cli-grammar.ts'; import { findCommandMetadata, isCommandName } from '../commands/command-metadata.ts'; -import { readVersion } from '../utils/version.ts'; +import { readVersion } from '@agent-device/host-kit/values'; // Help is the agent-facing contract, and agents copy its example lines verbatim, so an example the // CLI schema rejects is a broken command surface — not a docs nit (#1765: `help react-native` diff --git a/src/cli-schema/cli-help.ts b/src/cli-schema/cli-help.ts index 83647f9ec5..bad1b0f1d0 100644 --- a/src/cli-schema/cli-help.ts +++ b/src/cli-schema/cli-help.ts @@ -16,7 +16,7 @@ import { type FlagKey, } from './command-schema.ts'; import { buildCommandUsage } from './usage.ts'; -import { readVersion } from '../utils/version.ts'; +import { readVersion } from '@agent-device/host-kit/values'; import { renderCliHelpOverview } from './cli-help-overview.ts'; const CONFIGURATION_LINES = [ diff --git a/src/cli-schema/option-schema.ts b/src/cli-schema/option-schema.ts index 9a00797148..0e2fbdd7b6 100644 --- a/src/cli-schema/option-schema.ts +++ b/src/cli-schema/option-schema.ts @@ -1,4 +1,4 @@ -import { buildPrimaryEnvVarName, parseSourceValue } from '../utils/source-value.ts'; +import { buildPrimaryEnvVarName, parseSourceValue } from '@agent-device/host-kit/values'; import { listCliCommandNames } from '../command-catalog.ts'; import { getCliCommandSchema, diff --git a/src/cli.ts b/src/cli.ts index dfa39cff55..2abb766098 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,7 +10,7 @@ import { import { resolveRemoteRequestDiagnosticsPath } from './daemon/session-store.ts'; import { printHumanError, printJson } from './utils/output.ts'; import { exitAfterFlush } from './utils/process-exit.ts'; -import { readVersion } from './utils/version.ts'; +import { readVersion } from '@agent-device/host-kit/values'; import { pathToFileURL } from 'node:url'; import { sendToDaemon } from './daemon/client/daemon-client.ts'; import fs from 'node:fs'; @@ -34,7 +34,7 @@ import { getDiagnosticsMeta, registerDiagnosticSensitiveValue, withDiagnosticsScope, -} from './utils/diagnostics.ts'; +} from '@agent-device/host-kit/exec'; import { resolveDaemonPaths } from './daemon/config.ts'; import { applyDefaultPlatformBinding, resolveBindingSettings } from './utils/session-binding.ts'; import { resolveCliOptions } from './cli/resolve-cli-options.ts'; diff --git a/src/cli/auth-session.ts b/src/cli/auth-session.ts index 725a7162c8..fd5a5e0234 100644 --- a/src/cli/auth-session.ts +++ b/src/cli/auth-session.ts @@ -1,9 +1,9 @@ import fs from 'node:fs'; import path from 'node:path'; -import { runCmd } from '../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; import { readCloudJsonResponse } from './cloud-response.ts'; const DEFAULT_CLOUD_BASE_URL = 'https://cloud.agent-device.dev'; diff --git a/src/cli/commands/agent-cdp.ts b/src/cli/commands/agent-cdp.ts index b651da22f5..4e98f79147 100644 --- a/src/cli/commands/agent-cdp.ts +++ b/src/cli/commands/agent-cdp.ts @@ -1,4 +1,4 @@ -import { runCmdStreaming } from '../../utils/exec.ts'; +import { runCmdStreaming } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; import { isRemoteBridgeBackend } from './remote-bridge.ts'; import type { SessionRuntimeHints } from '@agent-device/kernel/contracts'; diff --git a/src/cli/commands/connection-presentation.ts b/src/cli/commands/connection-presentation.ts index 34e83478cc..748816ddd3 100644 --- a/src/cli/commands/connection-presentation.ts +++ b/src/cli/commands/connection-presentation.ts @@ -1,7 +1,7 @@ import { fingerprint, type RemoteConnectionState } from '../../remote/remote-connection-state.ts'; import type { ConnectVerification } from '../connection/connect-provider-adapters.ts'; import { connectionProviderLeaseKind } from '../connection/provider-policy.ts'; -import { shellQuoteIfNeeded } from '../../utils/shell-quote.ts'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; export type ConnectReadiness = ConnectVerification & { preparationMessage: string; diff --git a/src/cli/commands/connection.ts b/src/cli/commands/connection.ts index 102f039655..e9110b6276 100644 --- a/src/cli/commands/connection.ts +++ b/src/cli/commands/connection.ts @@ -32,7 +32,7 @@ import { stopReactDevtoolsCleanup, } from './connection-runtime.ts'; import { writeCommandOutput } from './shared.ts'; -import { shellQuoteIfNeeded } from '../../utils/shell-quote.ts'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; import type { LeaseBackend } from '@agent-device/kernel/contracts'; import type { CliFlags } from '@agent-device/contracts/command'; import type { ClientCommandHandler } from './router-types.ts'; diff --git a/src/cli/commands/device.ts b/src/cli/commands/device.ts index a928c6c363..5285491a93 100644 --- a/src/cli/commands/device.ts +++ b/src/cli/commands/device.ts @@ -5,7 +5,7 @@ import { inspectDeviceClaims, type InspectedDeviceClaim, } from '../../daemon/device-claim-inspection.ts'; -import { shellQuoteIfNeeded } from '../../utils/shell-quote.ts'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; import { writeCommandOutput } from './shared.ts'; import type { ClientCommandHandler } from './router-types.ts'; diff --git a/src/cli/commands/generic.ts b/src/cli/commands/generic.ts index ea5aeafaa4..114c9ab24c 100644 --- a/src/cli/commands/generic.ts +++ b/src/cli/commands/generic.ts @@ -4,7 +4,7 @@ import type { CommandName } from '../../commands/command-metadata.ts'; import type { CliOutput } from '../../commands/command-contract.ts'; import type { ReplaySuiteResult } from '@agent-device/contracts/replay'; import type { CliFlags } from '@agent-device/contracts/command'; -import { readCommandMessage } from '../../utils/success-text.ts'; +import { readCommandMessage } from '@agent-device/host-kit/values'; import { isNonDefaultResponseLevel } from '@agent-device/kernel/contracts'; import { writeCommandOutput } from './shared.ts'; import type { ClientBackedCliCommandName } from './client-backed.ts'; diff --git a/src/cli/commands/react-devtools.ts b/src/cli/commands/react-devtools.ts index 1b0dcfd6d3..03d4fefd17 100644 --- a/src/cli/commands/react-devtools.ts +++ b/src/cli/commands/react-devtools.ts @@ -1,4 +1,4 @@ -import { runCmdStreaming } from '../../utils/exec.ts'; +import { runCmdStreaming } from '@agent-device/host-kit/exec'; import { ensureReactDevtoolsCompanion, stopReactDevtoolsCompanion, diff --git a/src/cli/commands/replay.ts b/src/cli/commands/replay.ts index 1773f4d6e0..8c70287820 100644 --- a/src/cli/commands/replay.ts +++ b/src/cli/commands/replay.ts @@ -4,7 +4,7 @@ import { exportReplayActionsToMaestro, MAESTRO_SELECTOR_PROJECTION } from '@agen import { AppError } from '@agent-device/kernel/errors'; import { parseReplayScriptDetailed, readReplayScriptMetadata } from '@agent-device/ad-script'; import { projectSelectorExpression } from '@agent-device/selectors'; -import { resolveUserPath } from '../../utils/path-resolution.ts'; +import { resolveUserPath } from '@agent-device/host-kit/fs'; import { writeCommandOutput } from './shared.ts'; import type { ClientCommandHandler } from './router-types.ts'; diff --git a/src/cli/commands/screenshot.ts b/src/cli/commands/screenshot.ts index 02ca0ffc54..06df3d2121 100644 --- a/src/cli/commands/screenshot.ts +++ b/src/cli/commands/screenshot.ts @@ -2,7 +2,7 @@ import { formatScreenshotDiffText, formatSnapshotDiffText } from '../../utils/ou import type { ScreenshotDiffResult } from '../../screenshot-diff/screenshot-diff.ts'; import { AppError } from '@agent-device/kernel/errors'; import { isNonDefaultResponseLevel } from '@agent-device/kernel/contracts'; -import { resolveUserPath } from '../../utils/path-resolution.ts'; +import { resolveUserPath } from '@agent-device/host-kit/fs'; import type { AgentDeviceBackend } from '../../backend.ts'; import type { AgentDeviceClient, CaptureScreenshotResult } from '../../agent-device-client.ts'; import { runCliCommand } from '../../commands/cli-runner.ts'; diff --git a/src/cli/connection/cloud-profile.ts b/src/cli/connection/cloud-profile.ts index 7028dd3400..3fd03910ea 100644 --- a/src/cli/connection/cloud-profile.ts +++ b/src/cli/connection/cloud-profile.ts @@ -1,7 +1,7 @@ import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '../../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; import { resolveCloudAccessForConnect } from '../auth-session.ts'; import { readCloudJsonResponse } from '../cloud-response.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; diff --git a/src/cli/connection/cloud-webdriver-profile.ts b/src/cli/connection/cloud-webdriver-profile.ts index c7fec3b9d4..e28927e15d 100644 --- a/src/cli/connection/cloud-webdriver-profile.ts +++ b/src/cli/connection/cloud-webdriver-profile.ts @@ -10,7 +10,7 @@ import type { PlatformSelector } from '@agent-device/kernel/device'; import type { CliFlags } from '@agent-device/contracts/command'; import fs from 'node:fs'; import path from 'node:path'; -import type { EnvMap } from '../../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; import { readCloudDeviceFeatureProfileFields, readMetroProfileFields } from './profile-fields.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; import { resolveRequestedLeaseBackend } from '../commands/connection-runtime.ts'; diff --git a/src/cli/connection/connect-provider-adapters.ts b/src/cli/connection/connect-provider-adapters.ts index f65bfd742c..330bfd958e 100644 --- a/src/cli/connection/connect-provider-adapters.ts +++ b/src/cli/connection/connect-provider-adapters.ts @@ -4,8 +4,8 @@ import { verifyLimrunConnection } from '@agent-device/provider-limrun'; import { AppError } from '@agent-device/kernel/errors'; import { providerWebDriver } from '../../provider-webdriver.ts'; import { resolveRemoteConfigProfile } from '../../remote/remote-config.ts'; -import type { EnvMap } from '../../utils/env-map.ts'; -import { readVersion } from '../../utils/version.ts'; +import { type EnvMap, readVersion } from '@agent-device/host-kit/values'; + import { resolveCloudConnectProfile } from './cloud-profile.ts'; import { resolveCloudWebDriverConnectProfile } from './cloud-webdriver-profile.ts'; import { resolveLimrunConnectProfile } from './limrun-profile.ts'; diff --git a/src/cli/connection/generated-config.ts b/src/cli/connection/generated-config.ts index c3127914c2..09247586b4 100644 --- a/src/cli/connection/generated-config.ts +++ b/src/cli/connection/generated-config.ts @@ -7,7 +7,7 @@ import type { ResolvedRemoteConfigProfile, } from '../../remote/remote-config-schema.ts'; import { AppError, asAppError } from '@agent-device/kernel/errors'; -import type { EnvMap } from '../../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; import type { CliFlags } from '@agent-device/contracts/command'; import { profileToCliFlags } from '../remote-config-flags.ts'; diff --git a/src/cli/connection/limrun-profile.ts b/src/cli/connection/limrun-profile.ts index 9a50fe7d7b..bb65ca5d69 100644 --- a/src/cli/connection/limrun-profile.ts +++ b/src/cli/connection/limrun-profile.ts @@ -2,7 +2,7 @@ import { resolveDaemonPaths } from '../../daemon/config.ts'; import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '../../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; import { readMetroProfileFields } from './profile-fields.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; import { resolveRequestedLeaseBackend } from '../commands/connection-runtime.ts'; diff --git a/src/cli/connection/proxy-profile.ts b/src/cli/connection/proxy-profile.ts index d8d4a22890..79d1f38ad0 100644 --- a/src/cli/connection/proxy-profile.ts +++ b/src/cli/connection/proxy-profile.ts @@ -1,7 +1,7 @@ import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '../../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; import { readMetroProfileFields } from './profile-fields.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; import { resolveRequestedLeaseBackend } from '../commands/connection-runtime.ts'; diff --git a/src/cli/resolve-cli-options.ts b/src/cli/resolve-cli-options.ts index 9f75f5dd2c..f2e82d39b5 100644 --- a/src/cli/resolve-cli-options.ts +++ b/src/cli/resolve-cli-options.ts @@ -3,7 +3,7 @@ import { mergeDefinedFlags } from '../utils/merge-flags.ts'; import { finalizeParsedArgs, parseRawArgs } from './parser/args.ts'; import { resolveConfigBackedFlagDefaults } from '../cli-schema/cli-config.ts'; import { resolveRemoteConfigDefaults } from './remote-config-flags.ts'; -import type { EnvMap } from '../utils/env-map.ts'; +import type { EnvMap } from '@agent-device/host-kit/values'; export function resolveCliOptions( argv: string[], diff --git a/src/client/client-companion-tunnel.ts b/src/client/client-companion-tunnel.ts index b3098385b3..216ff4548e 100644 --- a/src/client/client-companion-tunnel.ts +++ b/src/client/client-companion-tunnel.ts @@ -18,13 +18,13 @@ import { ENV_COMPANION_TUNNEL_UNREGISTER_PATH, } from './client-companion-tunnel-contract.ts'; import { normalizeBaseUrl } from '../utils/url.ts'; -import { runCmdDetached } from '../utils/exec.ts'; import { + runCmdDetached, isProcessAlive, readProcessCommand, readProcessStartTime, waitForProcessExit, -} from '../utils/host-process.ts'; +} from '@agent-device/host-kit/exec'; const COMPANION_TUNNEL_TERM_TIMEOUT_MS = 1_000; const COMPANION_TUNNEL_KILL_TIMEOUT_MS = 1_000; diff --git a/src/client/client-normalizers.ts b/src/client/client-normalizers.ts index ea5494fad1..417ba49146 100644 --- a/src/client/client-normalizers.ts +++ b/src/client/client-normalizers.ts @@ -33,10 +33,10 @@ import { readRequiredPlatform, readRequiredString, stripUndefined, -} from '../utils/parsing.ts'; +} from '@agent-device/host-kit/values'; import { buildAppIdentifiers, buildDeviceIdentifiers } from '../utils/result-serialization.ts'; -export { readOptionalString, readRequiredString } from '../utils/parsing.ts'; +export { readOptionalString, readRequiredString } from '@agent-device/host-kit/values'; const DEFAULT_SESSION_NAME = 'default'; diff --git a/src/commands/batch/output.ts b/src/commands/batch/output.ts index f6b9448ae2..80a470ca98 100644 --- a/src/commands/batch/output.ts +++ b/src/commands/batch/output.ts @@ -1,5 +1,5 @@ import type { BatchRunResult, BatchStepResult } from '../../core/batch.ts'; -import { readCommandMessage } from '../../utils/success-text.ts'; +import { readCommandMessage } from '@agent-device/host-kit/values'; import type { CliOutput } from '../command-contract.ts'; import { resultOutput, type CliOutputFormatter } from '../output-common.ts'; diff --git a/src/commands/capture/runtime/diff-screenshot.test.ts b/src/commands/capture/runtime/diff-screenshot.test.ts index bdf8204ef7..0c8a329319 100644 --- a/src/commands/capture/runtime/diff-screenshot.test.ts +++ b/src/commands/capture/runtime/diff-screenshot.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; -import { PNG } from '../../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { test } from 'vitest'; import type { AgentDeviceBackend, diff --git a/src/commands/capture/runtime/screenshot.ts b/src/commands/capture/runtime/screenshot.ts index 250c42cb95..900cb51c08 100644 --- a/src/commands/capture/runtime/screenshot.ts +++ b/src/commands/capture/runtime/screenshot.ts @@ -1,7 +1,7 @@ import { AppError } from '@agent-device/kernel/errors'; import { validateScreenshotScale } from '@agent-device/contracts/capture'; -import { successText } from '../../../utils/success-text.ts'; -import { resizePngFileToScale } from '../../../utils/png-resize.ts'; +import { successText } from '@agent-device/host-kit/values'; +import { resizePngFileToScale } from '@agent-device/capture-kit/png-resize'; import type { ArtifactDescriptor } from '../../../io.ts'; import type { RuntimeCommand, ScreenshotCommandOptions } from '../../runtime-types.ts'; import { reserveCommandOutput } from '../../io-policy.ts'; diff --git a/src/commands/capture/settings.ts b/src/commands/capture/settings.ts index 6d7b077b13..6d81a31b7d 100644 --- a/src/commands/capture/settings.ts +++ b/src/commands/capture/settings.ts @@ -4,7 +4,7 @@ import { SETTINGS_USAGE_OVERRIDE } from '@agent-device/contracts/settings'; import type { CommandSchemaOverride } from '../../cli-schema/types.ts'; import type { CliFlags } from '@agent-device/contracts/command'; import { AppError } from '@agent-device/kernel/errors'; -import { readLocationCoordinate } from '../../utils/location-coordinates.ts'; +import { readLocationCoordinate } from '@agent-device/host-kit/values'; import { defineExecutableCommand } from '../command-contract.ts'; import { enumField, numberField, requiredField, stringField } from '../command-input.ts'; import { diff --git a/src/commands/capture/snapshot.ts b/src/commands/capture/snapshot.ts index 30505c8385..9c4a19adb6 100644 --- a/src/commands/capture/snapshot.ts +++ b/src/commands/capture/snapshot.ts @@ -1,5 +1,5 @@ import { PUBLIC_COMMANDS } from '../../command-catalog.ts'; -import { SNAPSHOT_BACKEND_CAPABILITIES } from '../../snapshot-quality/backend-capabilities.ts'; +import { SNAPSHOT_BACKEND_CAPABILITIES } from '@agent-device/capture-kit/snapshot-quality-backend-capabilities'; import { SNAPSHOT_FLAGS } from '../cli-grammar/flag-groups.ts'; import { booleanField, integerField, stringField } from '../command-input.ts'; import { defineExecutableCommand } from '../command-contract.ts'; diff --git a/src/commands/command-flags.ts b/src/commands/command-flags.ts index 8fa88063d9..61ab560c6b 100644 --- a/src/commands/command-flags.ts +++ b/src/commands/command-flags.ts @@ -1,7 +1,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import { screenshotFlagsFromOptions } from '@agent-device/contracts/capture'; import { leaseScopeFromOptions, leaseScopeToCommandFlags } from '../core/lease-scope.ts'; -import { stripUndefined } from '../utils/parsing.ts'; +import { stripUndefined } from '@agent-device/host-kit/values'; import { getFlagDefinitions } from './cli-grammar/flag-registry.ts'; import type { InternalRequestOptions } from '@agent-device/contracts/client'; import type { CommandMetadata } from './command-contract.ts'; diff --git a/src/commands/input-audience.ts b/src/commands/input-audience.ts index 67e9200434..8ae1e6fcf7 100644 --- a/src/commands/input-audience.ts +++ b/src/commands/input-audience.ts @@ -1,4 +1,4 @@ -import { buildPrimaryEnvVarName } from '../utils/source-value.ts'; +import { buildPrimaryEnvVarName } from '@agent-device/host-kit/values'; /** * Where an operator supplies a value that no model-facing surface may accept as diff --git a/src/commands/interaction/output.ts b/src/commands/interaction/output.ts index 81f584aeac..9af4682c03 100644 --- a/src/commands/interaction/output.ts +++ b/src/commands/interaction/output.ts @@ -2,7 +2,7 @@ import type { CommandRequestResult } from '@agent-device/contracts/client'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import type { CliOutput } from '../command-contract.ts'; import { displayLabel, formatRole } from '../../snapshot/snapshot-lines.ts'; -import { readCommandMessage } from '../../utils/success-text.ts'; +import { readCommandMessage } from '@agent-device/host-kit/values'; import { messageCliOutput, messageOutput, diff --git a/src/commands/interaction/runtime/gesture-command.ts b/src/commands/interaction/runtime/gesture-command.ts index c6d0d1dc2b..a30ad151aa 100644 --- a/src/commands/interaction/runtime/gesture-command.ts +++ b/src/commands/interaction/runtime/gesture-command.ts @@ -7,7 +7,7 @@ import type { import { buildGesturePlan } from '@agent-device/contracts/gesture-plan'; import type { Point } from '@agent-device/kernel/snapshot'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '../../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { toBackendContext } from '../../runtime-common.ts'; import { toBackendResult, diff --git a/src/commands/interaction/runtime/gestures.ts b/src/commands/interaction/runtime/gestures.ts index 363d6bba89..3d622b055d 100644 --- a/src/commands/interaction/runtime/gestures.ts +++ b/src/commands/interaction/runtime/gestures.ts @@ -27,7 +27,7 @@ import { type ScrollEdgeState, type ScrollEdgeTarget, } from '../../../utils/scroll-edge-state.ts'; -import { successText } from '../../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { requireIntInRange } from '../../../utils/validation.ts'; import { toBackendContext } from '../../runtime-common.ts'; import { diff --git a/src/commands/interaction/runtime/resolution.ts b/src/commands/interaction/runtime/resolution.ts index 741a7d145c..8d07266ee2 100644 --- a/src/commands/interaction/runtime/resolution.ts +++ b/src/commands/interaction/runtime/resolution.ts @@ -1,7 +1,7 @@ import { AppError } from '@agent-device/kernel/errors'; import type { Point, SnapshotNode, SnapshotState } from '@agent-device/kernel/snapshot'; import { findNodeByRef, normalizeRef } from '@agent-device/kernel/snapshot'; -import { resolveRectCenter } from '../../../utils/rect-center.ts'; +import { resolveRectCenter } from '@agent-device/kernel/rect-center'; import type { AgentDeviceRuntime, CommandContext, @@ -37,7 +37,7 @@ import { import { classifyOffscreenScrollDirection, type OffscreenScrollDirection, -} from '../../../snapshot/mobile-snapshot-semantics.ts'; +} from '@agent-device/capture-kit/mobile-snapshot-semantics'; import { truncateUtf8 } from '../../../utils/truncate-utf8.ts'; import type { InteractionTarget, diff --git a/src/commands/interaction/runtime/selector-read-shared.ts b/src/commands/interaction/runtime/selector-read-shared.ts index 79cd6e6808..d50cfa68b5 100644 --- a/src/commands/interaction/runtime/selector-read-shared.ts +++ b/src/commands/interaction/runtime/selector-read-shared.ts @@ -10,7 +10,7 @@ import type { SnapshotState, } from '@agent-device/kernel/snapshot'; import { findNodeByRef, normalizeRef } from '@agent-device/kernel/snapshot'; -import { isSparseSnapshotQualityVerdict } from '../../../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { extractReadableText } from '../../../utils/text-surface.ts'; import { now, toBackendContext } from '../../runtime-common.ts'; import { findNodeByLabel } from './selector-read-utils.ts'; diff --git a/src/commands/interaction/runtime/selector-read.ts b/src/commands/interaction/runtime/selector-read.ts index a074724c6b..ebd79dc34a 100644 --- a/src/commands/interaction/runtime/selector-read.ts +++ b/src/commands/interaction/runtime/selector-read.ts @@ -19,7 +19,7 @@ import { } from '../../../core/selector-pipeline.ts'; import { SELECTOR_PIPELINE_POLICIES } from '../../../core/selector-pipeline-policy.ts'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; -import { isSparseSnapshotQualityVerdict } from '../../../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import type { AgentDeviceRuntime, CommandContext } from '../../../runtime-contract.ts'; import { AppError } from '@agent-device/kernel/errors'; import type { diff --git a/src/commands/interaction/runtime/settle.test.ts b/src/commands/interaction/runtime/settle.test.ts index eae5f1e9a4..cc8fd86e17 100644 --- a/src/commands/interaction/runtime/settle.test.ts +++ b/src/commands/interaction/runtime/settle.test.ts @@ -11,7 +11,7 @@ import { import { makeSnapshotState } from '../../../__tests__/test-utils/snapshot-builders.ts'; import { ref, selector } from './selector-read-utils.ts'; import { buildSettleTailEntries, NEVER_SETTLED_HINT } from './settle.ts'; -import { readSnapshotQualityVerdict } from '../../../snapshot-quality/verdict.ts'; +import { readSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; // #1101 --settle: quiet-window settle loop composition on the interaction // commands. Budgets are injected (fake clock) — no real waiting. diff --git a/src/commands/interaction/runtime/settle.ts b/src/commands/interaction/runtime/settle.ts index b90327edc6..849f2cc8dc 100644 --- a/src/commands/interaction/runtime/settle.ts +++ b/src/commands/interaction/runtime/settle.ts @@ -4,7 +4,7 @@ import type { CommandContext, CommandSessionRecord, } from '../../../runtime-contract.ts'; -import { isSparseSnapshotQualityVerdict } from '../../../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { buildSnapshotDiff } from '../../../snapshot/snapshot-diff.ts'; import { displayLabel, formatRole } from '../../../snapshot/snapshot-lines.ts'; import { collectSettleChromeRefs, withoutSettleChrome } from '../../../core/snapshot-chrome.ts'; diff --git a/src/commands/interaction/runtime/stable-capture.ts b/src/commands/interaction/runtime/stable-capture.ts index ddf61130f2..1e7fcb5415 100644 --- a/src/commands/interaction/runtime/stable-capture.ts +++ b/src/commands/interaction/runtime/stable-capture.ts @@ -18,7 +18,7 @@ import { stableCaptureSignalsEqual, type StableCaptureSignal, } from './stable-capture-signal.ts'; -import { preferredSnapshotBackendForVerdict } from '../../../snapshot-quality/verdict.ts'; +import { preferredSnapshotBackendForVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; /** * The quiet-window stable-capture loop shared by `wait stable` and the diff --git a/src/commands/management/output.ts b/src/commands/management/output.ts index 74296c102d..db9f84b58c 100644 --- a/src/commands/management/output.ts +++ b/src/commands/management/output.ts @@ -28,7 +28,7 @@ import { serializeOpenResult, serializeSessionListEntry, } from '../../utils/result-serialization.ts'; -import { readCommandMessage } from '../../utils/success-text.ts'; +import { readCommandMessage } from '@agent-device/host-kit/values'; import { snapshotCliOutput } from '../capture/output.ts'; import type { CliOutput } from '../command-contract.ts'; import { diff --git a/src/commands/management/runtime/admin.ts b/src/commands/management/runtime/admin.ts index 625e74f6be..37b2263e48 100644 --- a/src/commands/management/runtime/admin.ts +++ b/src/commands/management/runtime/admin.ts @@ -8,7 +8,7 @@ import type { } from '../../../backend.ts'; import type { AgentDeviceRuntime, CommandContext } from '../../../runtime-contract.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '../../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { toBackendResult, type BackendResultEnvelope, diff --git a/src/commands/management/runtime/apps.ts b/src/commands/management/runtime/apps.ts index a8e324ae17..4951a8b2bf 100644 --- a/src/commands/management/runtime/apps.ts +++ b/src/commands/management/runtime/apps.ts @@ -11,7 +11,7 @@ import type { FileInputRef } from '../../../io.ts'; import type { AgentDeviceRuntime, CommandContext } from '../../../runtime-contract.ts'; import { assertResolvedAppsFilter } from '../app-inventory-contract.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '../../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { resolveCommandInput } from '../../io-policy.ts'; import { toBackendResult, diff --git a/src/commands/output-common.ts b/src/commands/output-common.ts index 53125ae608..a8a07ee372 100644 --- a/src/commands/output-common.ts +++ b/src/commands/output-common.ts @@ -1,4 +1,4 @@ -import { readCommandMessage } from '../utils/success-text.ts'; +import { readCommandMessage } from '@agent-device/host-kit/values'; import type { CliOutput } from './command-contract.ts'; export type CliOutputFormatter = (params: { diff --git a/src/commands/perf/output.ts b/src/commands/perf/output.ts index 94badeb4a7..6d980fe5fc 100644 --- a/src/commands/perf/output.ts +++ b/src/commands/perf/output.ts @@ -1,5 +1,5 @@ import type { CommandRequestResult } from '@agent-device/contracts/client'; -import { isRecord } from '../../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import type { CliOutput } from '../command-contract.ts'; import { resultOutput, type CliOutputFormatter } from '../output-common.ts'; diff --git a/src/commands/recording/runtime/recording.ts b/src/commands/recording/runtime/recording.ts index 67388355a6..5fecb62865 100644 --- a/src/commands/recording/runtime/recording.ts +++ b/src/commands/recording/runtime/recording.ts @@ -7,7 +7,7 @@ import type { import type { ArtifactDescriptor, FileOutputRef } from '../../../io.ts'; import type { CommandContext } from '../../../runtime-contract.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '../../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { requireIntInRange } from '../../../utils/validation.ts'; import { recordingQualityInputToExportQuality, diff --git a/src/commands/system/runtime/system.ts b/src/commands/system/runtime/system.ts index 6ed4799ebe..9e9840b083 100644 --- a/src/commands/system/runtime/system.ts +++ b/src/commands/system/runtime/system.ts @@ -10,7 +10,7 @@ import type { CommandContext } from '../../../runtime-contract.ts'; import type { BackMode } from '@agent-device/contracts/back-mode'; import { parseTvRemoteButton } from '@agent-device/contracts/tv-remote'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '../../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { requireIntInRange } from '../../../utils/validation.ts'; import { isKeyboardAction } from '../../../utils/keyboard-actions.ts'; import { diff --git a/src/core/batch.ts b/src/core/batch.ts index 7ec94e73f2..e9abd9881f 100644 --- a/src/core/batch.ts +++ b/src/core/batch.ts @@ -8,7 +8,7 @@ import { isNonDefaultResponseLevel, } from '@agent-device/kernel/contracts'; import { AppError, asAppError, type DaemonError } from '@agent-device/kernel/errors'; -import { isRecord } from '../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import { DEFAULT_BATCH_MAX_STEPS, assertBatchStepCount, diff --git a/src/core/dispatch-resolve.ts b/src/core/dispatch-resolve.ts index 6859057f2a..e45a8a5d06 100644 --- a/src/core/dispatch-resolve.ts +++ b/src/core/dispatch-resolve.ts @@ -12,8 +12,8 @@ import { AsyncLocalStorage } from 'node:async_hooks'; import { resolveAndroidSerialAllowlist, resolveIosSimulatorDeviceSetPath, -} from '../utils/device-isolation.ts'; -import { withDiagnosticTimer } from '../utils/diagnostics.ts'; +} from '@agent-device/host-kit/fs'; +import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; import { listLocalDeviceInventory, readDeviceInventory, diff --git a/src/core/interaction-targeting.ts b/src/core/interaction-targeting.ts index 9004df0706..2ebcb4853a 100644 --- a/src/core/interaction-targeting.ts +++ b/src/core/interaction-targeting.ts @@ -7,12 +7,12 @@ import { normalizeType, isViewportRootNode, } from '@agent-device/contracts/snapshot'; -import { isSnapshotNodeInteractionBlocked } from '../snapshot/snapshot-occlusion.ts'; +import { isSnapshotNodeInteractionBlocked } from '@agent-device/capture-kit/snapshot-occlusion'; import { areRectsApproximatelyEqual, normalizeRect, resolveRectCenter, -} from '../utils/rect-center.ts'; +} from '@agent-device/kernel/rect-center'; import { intersectArea } from '../utils/screenshot-geometry.ts'; import { isSemanticTouchTarget } from './touch-semantics.ts'; diff --git a/src/core/interaction-touch-point.ts b/src/core/interaction-touch-point.ts index f2751a4c30..6c23d2ec12 100644 --- a/src/core/interaction-touch-point.ts +++ b/src/core/interaction-touch-point.ts @@ -4,7 +4,7 @@ import { areRectsApproximatelyEqual, normalizeRect, resolveRectCenter, -} from '../utils/rect-center.ts'; +} from '@agent-device/kernel/rect-center'; import { isSemanticTouchTarget } from './touch-semantics.ts'; export type InteractionTouchPointResolution = diff --git a/src/core/interactors/android.ts b/src/core/interactors/android.ts index 6fba4e7f58..68a1e777bc 100644 --- a/src/core/interactors/android.ts +++ b/src/core/interactors/android.ts @@ -34,8 +34,8 @@ import { setAndroidSetting } from '../../platforms/android/settings.ts'; import { snapshotAndroid } from '../../platforms/android/snapshot.ts'; import type { AndroidHelperSessionScope } from '../../platforms/android/snapshot-helper-types.ts'; import { screenshotAndroid } from '../../platforms/android/screenshot.ts'; -import { withDiagnosticTimer } from '../../utils/diagnostics.ts'; -import { withMethodScope } from '../../utils/method-scope.ts'; +import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; +import { withMethodScope } from '@agent-device/host-kit/values'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Interactor, RunnerContext } from '@agent-device/contracts/interactor-types'; import { androidSnapshotPublicationInput } from '../../platforms/android/snapshot-capture.ts'; diff --git a/src/core/interactors/harmonyos.ts b/src/core/interactors/harmonyos.ts index 96f30915bb..85b2938e51 100644 --- a/src/core/interactors/harmonyos.ts +++ b/src/core/interactors/harmonyos.ts @@ -1,7 +1,7 @@ import { AppError } from '@agent-device/kernel/errors'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Interactor, RunnerContext } from '@agent-device/contracts/interactor-types'; -import { withDiagnosticTimer } from '../../utils/diagnostics.ts'; +import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; import { closeHarmonyApp, openHarmonyApp } from '../../platforms/harmonyos/app-lifecycle.ts'; import { appSwitcherHarmony, diff --git a/src/core/interactors/linux.ts b/src/core/interactors/linux.ts index 50be016efd..052fff6e8b 100644 --- a/src/core/interactors/linux.ts +++ b/src/core/interactors/linux.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { withDiagnosticTimer } from '../../utils/diagnostics.ts'; +import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; import { backLinux, closeLinuxApp, diff --git a/src/core/interactors/web.ts b/src/core/interactors/web.ts index e9462d94dd..fc4abee93e 100644 --- a/src/core/interactors/web.ts +++ b/src/core/interactors/web.ts @@ -1,7 +1,7 @@ import type { Interactor } from '@agent-device/contracts/interactor-types'; import { AppError } from '@agent-device/kernel/errors'; import { stripAtPrefix } from '../interaction-positionals.ts'; -import { withDiagnosticTimer } from '../../utils/diagnostics.ts'; +import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; import { resolveWebProvider, type WebProvider } from '../../platforms/web/provider.ts'; import { createUnsupportedInteractor } from '../../platforms/unsupported-interactor.ts'; diff --git a/src/core/lease-scope.ts b/src/core/lease-scope.ts index 36ba9212f7..8370c21bbb 100644 --- a/src/core/lease-scope.ts +++ b/src/core/lease-scope.ts @@ -1,5 +1,5 @@ import type { LeaseBackend } from '@agent-device/kernel/contracts'; -import { stripUndefined } from '../utils/parsing.ts'; +import { stripUndefined } from '@agent-device/host-kit/values'; const PROXY_LEASE_PROVIDER = 'proxy'; export const DEFAULT_PROXY_LEASE_TTL_MS = 300_000; diff --git a/src/core/press-retarget.ts b/src/core/press-retarget.ts index b062fb77e2..29c145e435 100644 --- a/src/core/press-retarget.ts +++ b/src/core/press-retarget.ts @@ -14,7 +14,7 @@ */ import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import { containsPoint } from '@agent-device/kernel/rect'; -import { resolveRectCenter } from '../utils/rect-center.ts'; +import { resolveRectCenter } from '@agent-device/kernel/rect-center'; import { demoteNonUniqueLocalIdentity, readNodeLocalIdentity } from '@agent-device/ad-script'; import { buildIndexMap } from '../replay/target-evidence-tree.ts'; import { normalizeSelectorText } from '@agent-device/selectors'; diff --git a/src/core/selector-pipeline.ts b/src/core/selector-pipeline.ts index 7b596a265f..39e5ab3ace 100644 --- a/src/core/selector-pipeline.ts +++ b/src/core/selector-pipeline.ts @@ -4,7 +4,7 @@ import { listSelectorChainMatches, resolveSelectorChainWithPolicy, } from '@agent-device/selectors/engine'; -import { isSnapshotNodeInteractionBlocked } from '../snapshot/snapshot-occlusion.ts'; +import { isSnapshotNodeInteractionBlocked } from '@agent-device/capture-kit/snapshot-occlusion'; import { isRootInteractionContainer, resolveActionableTouchResolution, diff --git a/src/core/snapshot-state.ts b/src/core/snapshot-state.ts index 1285b85539..b90f78fcf1 100644 --- a/src/core/snapshot-state.ts +++ b/src/core/snapshot-state.ts @@ -17,7 +17,7 @@ import { import { annotateCoveredSnapshotNodes, annotateSnapshotNodesCoveredByPolicy, -} from '../snapshot/snapshot-occlusion.ts'; +} from '@agent-device/capture-kit/snapshot-occlusion'; import { coveredAndroidReplacementNodeIndexes } from '../snapshot/android-replacement-surface-occlusion.ts'; import { scopeSnapshotNodes } from '../snapshot/snapshot-desktop-surface.ts'; import { normalizeSnapshotTree, pruneGroupNodes } from '../core/snapshot-tree-ingestion.ts'; diff --git a/src/daemon/__tests__/android-dialog-readiness.test.ts b/src/daemon/__tests__/android-dialog-readiness.test.ts index d88cea570c..a8df0b80eb 100644 --- a/src/daemon/__tests__/android-dialog-readiness.test.ts +++ b/src/daemon/__tests__/android-dialog-readiness.test.ts @@ -24,7 +24,7 @@ vi.mock('../../platforms/android/app-lifecycle.ts', async (importOriginal) => { import { makeAndroidSession } from '../../__tests__/test-utils/session-factories.ts'; import { withFakeAdb, type FakeAdbScript } from '../../__tests__/test-utils/fake-adb.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '../../utils/diagnostics.ts'; +import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { ensureAndroidBlockingSystemDialogReady as ensureOwnedAndroidBlockingSystemDialogReady } from '../android-system-dialog.ts'; import { androidObservation } from '../../platform-runtime.ts'; diff --git a/src/daemon/__tests__/daemon-exit-wait.test.ts b/src/daemon/__tests__/daemon-exit-wait.test.ts index 47a1e5f8bd..09faaf7aca 100644 --- a/src/daemon/__tests__/daemon-exit-wait.test.ts +++ b/src/daemon/__tests__/daemon-exit-wait.test.ts @@ -15,8 +15,8 @@ const state = vi.hoisted(() => ({ commands: new Map(), })); -vi.mock('../../utils/host-process.ts', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: (pid: number) => state.alive.get(pid) ?? false, readProcessStartTime: (pid: number) => state.starts.get(pid) ?? null, readProcessCommand: (pid: number) => state.commands.get(pid) ?? null, diff --git a/src/daemon/__tests__/daemon-process-takeover.test.ts b/src/daemon/__tests__/daemon-process-takeover.test.ts index e513119336..839dd19603 100644 --- a/src/daemon/__tests__/daemon-process-takeover.test.ts +++ b/src/daemon/__tests__/daemon-process-takeover.test.ts @@ -4,7 +4,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { afterEach, test } from 'vitest'; -import { isProcessAlive, readProcessStartTime } from '../../utils/host-process.ts'; +import { isProcessAlive, readProcessStartTime } from '@agent-device/host-kit/exec'; import { isAgentDeviceDaemonProcess, stopProcessForTakeover } from '../daemon-process.ts'; const TAKEOVER_TIMEOUTS = { termTimeoutMs: 5_000, killTimeoutMs: 2_000 }; diff --git a/src/daemon/__tests__/daemon-stop.test.ts b/src/daemon/__tests__/daemon-stop.test.ts index cceec7ebd1..ddff0e94bd 100644 --- a/src/daemon/__tests__/daemon-stop.test.ts +++ b/src/daemon/__tests__/daemon-stop.test.ts @@ -16,10 +16,11 @@ vi.mock('../daemon-process.ts', () => ({ trySignalProcess: mocks.trySignalProcess, waitForDaemonExit: mocks.waitForDaemonExit, })); -vi.mock('../../utils/host-process.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: mocks.isProcessAlive, + sleep: mocks.sleep, })); -vi.mock('../../utils/timeouts.ts', () => ({ sleep: mocks.sleep })); import { resolveDaemonPaths } from '../config.ts'; import { stopDaemon } from '../daemon-stop.ts'; diff --git a/src/daemon/__tests__/deferred-interaction-outcome.test.ts b/src/daemon/__tests__/deferred-interaction-outcome.test.ts index e588f52f04..f3b9c80d21 100644 --- a/src/daemon/__tests__/deferred-interaction-outcome.test.ts +++ b/src/daemon/__tests__/deferred-interaction-outcome.test.ts @@ -7,7 +7,7 @@ import { type DeferredOutcomeSnapshotAttempt, } from '../deferred-interaction-outcome.ts'; import type { InteractionRetryTap } from '../interaction-outcome-policy.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '../../utils/diagnostics.ts'; +import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import type { SessionState } from '../types.ts'; import { deliverySnapshot, diff --git a/src/daemon/__tests__/device-claim-prune.test.ts b/src/daemon/__tests__/device-claim-prune.test.ts index 95c4a12e2e..c2a0b17c60 100644 --- a/src/daemon/__tests__/device-claim-prune.test.ts +++ b/src/daemon/__tests__/device-claim-prune.test.ts @@ -5,12 +5,12 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { reconcileOrphanedDeviceClaims } from '../device-claims.ts'; import { resolveDeviceClaimPath } from '../device-claim-paths.ts'; -import { acquireProcessLock } from '../../utils/process-lock.ts'; -import { readCurrentOwnerIdentity } from '../../utils/owner-identity.ts'; +import { acquireProcessLock } from '@agent-device/host-kit/fs'; +import { readCurrentOwnerIdentity } from '@agent-device/host-kit/exec'; import { publishDaemonRegistration } from '../../__tests__/test-utils/device-claim-store.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../utils/host-process.ts', async (importOriginal) => +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => (await import('../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), diff --git a/src/daemon/__tests__/device-claims.test.ts b/src/daemon/__tests__/device-claims.test.ts index 956673f2f1..6da2db6798 100644 --- a/src/daemon/__tests__/device-claims.test.ts +++ b/src/daemon/__tests__/device-claims.test.ts @@ -12,9 +12,9 @@ import { inspectDeviceClaims } from '../device-claim-inspection.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; import { publishDaemonRegistration } from '../../__tests__/test-utils/device-claim-store.ts'; -import { readCurrentOwnerIdentity } from '../../utils/owner-identity.ts'; +import { readCurrentOwnerIdentity } from '@agent-device/host-kit/exec'; -vi.mock('../../utils/host-process.ts', async (importOriginal) => +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => (await import('../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), diff --git a/src/daemon/__tests__/device-ready.test.ts b/src/daemon/__tests__/device-ready.test.ts index 650bd48d5c..b0ec5d8a79 100644 --- a/src/daemon/__tests__/device-ready.test.ts +++ b/src/daemon/__tests__/device-ready.test.ts @@ -2,7 +2,7 @@ import { afterEach, beforeEach, expect, test, vi } from 'vitest'; import { promises as fs } from 'node:fs'; import type { DeviceInfo } from '@agent-device/kernel/device'; -vi.mock('../../utils/exec.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', () => ({ runCmd: vi.fn(), runCmdSync: vi.fn(), whichCmd: vi.fn(async () => true), @@ -14,7 +14,7 @@ vi.mock('../../platforms/android/emulator-lifecycle.ts', () => ({ waitForAndroidBoot: vi.fn(async () => {}), })); -import { runCmd } from '../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { waitForAndroidBoot } from '../../platforms/android/emulator-lifecycle.ts'; import { ensureBootedSimulator } from '../../platforms/apple/core/simulator.ts'; import { diff --git a/src/daemon/__tests__/durable-capture-resource-transitions.test.ts b/src/daemon/__tests__/durable-capture-resource-transitions.test.ts index 9516ec779d..24df906c4b 100644 --- a/src/daemon/__tests__/durable-capture-resource-transitions.test.ts +++ b/src/daemon/__tests__/durable-capture-resource-transitions.test.ts @@ -1,5 +1,5 @@ import { expect, test } from 'vitest'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '../../utils/diagnostics.ts'; +import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { createTestCaptureResource, makeDurableCaptureContext, diff --git a/src/daemon/__tests__/filesystem-boundary-faults.test.ts b/src/daemon/__tests__/filesystem-boundary-faults.test.ts index f8a7a852b4..54543d7504 100644 --- a/src/daemon/__tests__/filesystem-boundary-faults.test.ts +++ b/src/daemon/__tests__/filesystem-boundary-faults.test.ts @@ -21,7 +21,7 @@ import { type FilesystemBoundaryFixture, } from '../../__tests__/test-utils/filesystem-boundary-faults.ts'; -vi.mock('../../utils/host-process.ts', async (importOriginal) => +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => (await import('../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), diff --git a/src/daemon/__tests__/http-server-artifacts.test.ts b/src/daemon/__tests__/http-server-artifacts.test.ts index 91fbfc9fa5..34cad18a08 100644 --- a/src/daemon/__tests__/http-server-artifacts.test.ts +++ b/src/daemon/__tests__/http-server-artifacts.test.ts @@ -9,7 +9,7 @@ import { trackDownloadableArtifact, } from '../artifact-tracking.ts'; import type { DaemonResponse } from '../types.ts'; -import { runCmdSync, withCommandExecutorOverride } from '../../utils/exec.ts'; +import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { closeLoopbackServer, listenOnLoopback, diff --git a/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts b/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts index a936c82005..93e6578bec 100644 --- a/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts +++ b/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '../../utils/diagnostics.ts'; +import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { buildInteractionSurfaceSignature, summarizeDiscriminatingSurfaceDivergence, diff --git a/src/daemon/__tests__/post-gesture-stabilization.test.ts b/src/daemon/__tests__/post-gesture-stabilization.test.ts index 680bbb4a2d..4d87e2d6fc 100644 --- a/src/daemon/__tests__/post-gesture-stabilization.test.ts +++ b/src/daemon/__tests__/post-gesture-stabilization.test.ts @@ -2,7 +2,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import assert from 'node:assert/strict'; import { afterEach, test, vi } from 'vitest'; import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '../../utils/diagnostics.ts'; +import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { buildInteractionSurfaceSignature } from '../interaction-outcome-policy.ts'; import { capturePostGestureStabilizedResult, diff --git a/src/daemon/__tests__/request-execution-scope.test.ts b/src/daemon/__tests__/request-execution-scope.test.ts index f24360b052..18badcc570 100644 --- a/src/daemon/__tests__/request-execution-scope.test.ts +++ b/src/daemon/__tests__/request-execution-scope.test.ts @@ -5,7 +5,7 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, withDiagnosticsScope, -} from '../../utils/diagnostics.ts'; +} from '@agent-device/host-kit/exec'; import { makeAndroidSession, makeIosSession, @@ -14,7 +14,7 @@ import { import { LINUX_DEVICE } from '../../__tests__/test-utils/device-fixtures.ts'; import { makeSessionStore } from '../../__tests__/test-utils/store-factory.ts'; import { LeaseRegistry } from '../lease-registry.ts'; -import { clearRequestCanceled, markRequestCanceled } from '../../request/cancel.ts'; +import { clearRequestCanceled, markRequestCanceled } from '@agent-device/host-kit/request'; import { createRequestExecutionScope, prepareLockedRequestScope, diff --git a/src/daemon/__tests__/request-handler-catalog.test.ts b/src/daemon/__tests__/request-handler-catalog.test.ts index 0c875fefd0..e58c966fb6 100644 --- a/src/daemon/__tests__/request-handler-catalog.test.ts +++ b/src/daemon/__tests__/request-handler-catalog.test.ts @@ -16,7 +16,7 @@ import { clearRequestAbortRegistration, markRequestCanceled, registerRequestAbort, -} from '../../request/cancel.ts'; +} from '@agent-device/host-kit/request'; import { unavailableBindDevice, unavailableBindExactDevice, diff --git a/src/daemon/__tests__/request-router-android-modal.test.ts b/src/daemon/__tests__/request-router-android-modal.test.ts index 8ccfc2da12..0ce8c2df81 100644 --- a/src/daemon/__tests__/request-router-android-modal.test.ts +++ b/src/daemon/__tests__/request-router-android-modal.test.ts @@ -113,8 +113,8 @@ const modalObservation: AndroidObservationAdapter = { }, }; -vi.mock('../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async (_cmd: string, args: string[]) => { diff --git a/src/daemon/__tests__/request-router-cost.test.ts b/src/daemon/__tests__/request-router-cost.test.ts index 29c4113b68..d96826c3df 100644 --- a/src/daemon/__tests__/request-router-cost.test.ts +++ b/src/daemon/__tests__/request-router-cost.test.ts @@ -16,7 +16,7 @@ import { gestureDeviceRuntimeGateway, gestureRuntimeSpies, } from './test-device-runtime-gateway.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { DaemonRequest, SessionState } from '../types.ts'; import { LeaseRegistry } from '../lease-registry.ts'; import { makeSessionStore } from '../../__tests__/test-utils/store-factory.ts'; diff --git a/src/daemon/__tests__/request-router-open.test.ts b/src/daemon/__tests__/request-router-open.test.ts index 862ba4bb14..798b6560dc 100644 --- a/src/daemon/__tests__/request-router-open.test.ts +++ b/src/daemon/__tests__/request-router-open.test.ts @@ -9,8 +9,8 @@ import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; import { replayScriptSourceBundleFor } from '../../__tests__/test-utils/replay-script-source.ts'; vi.mock('../device-ready.ts', () => ({ ensureDeviceReady: vi.fn(async () => {}) })); -vi.mock('../../utils/host-process.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); // Opening a session runs the owned-lease cleanup, which pattern-kills stale diff --git a/src/daemon/__tests__/request-router-screenshot.test.ts b/src/daemon/__tests__/request-router-screenshot.test.ts index 6a1803bc77..55f5f63d2d 100644 --- a/src/daemon/__tests__/request-router-screenshot.test.ts +++ b/src/daemon/__tests__/request-router-screenshot.test.ts @@ -26,7 +26,7 @@ import { import type { DaemonRequest, SessionState } from '../types.ts'; import { LeaseRegistry } from '../lease-registry.ts'; import { attachRefs } from '@agent-device/kernel/snapshot'; -import { PNG } from '../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { ANDROID_EMULATOR, IOS_SIMULATOR } from '../../__tests__/test-utils/device-fixtures.ts'; import { makeSessionStore } from '../../__tests__/test-utils/store-factory.ts'; import { makeSession as makeBaseSession } from '../../__tests__/test-utils/session-factories.ts'; diff --git a/src/daemon/__tests__/request-router-session-address.test.ts b/src/daemon/__tests__/request-router-session-address.test.ts index 0dc88a5370..9e38917320 100644 --- a/src/daemon/__tests__/request-router-session-address.test.ts +++ b/src/daemon/__tests__/request-router-session-address.test.ts @@ -7,8 +7,8 @@ import { getResolveTargetDeviceMock } from './request-router-dispatch-mocks.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; vi.mock('../device-ready.ts', () => ({ ensureDeviceReady: vi.fn(async () => {}) })); -vi.mock('../../utils/host-process.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); // Opening a session runs owned-lease cleanup, which pattern-kills stale xcodebuild runners with a diff --git a/src/daemon/__tests__/resumable-upload.test.ts b/src/daemon/__tests__/resumable-upload.test.ts index fbc4774946..12aad11c6a 100644 --- a/src/daemon/__tests__/resumable-upload.test.ts +++ b/src/daemon/__tests__/resumable-upload.test.ts @@ -12,7 +12,7 @@ import { receiveResumableUploadChunk, } from '../resumable-upload.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -import { runCmdSync } from '../../utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; test('finalizing an unknown upload reports expiry with a recovery hint', async () => { const error = await finalizeResumableUpload('missing-upload-id').then( diff --git a/src/daemon/__tests__/runtime-session.test.ts b/src/daemon/__tests__/runtime-session.test.ts index c0ed07bacd..e1af977216 100644 --- a/src/daemon/__tests__/runtime-session.test.ts +++ b/src/daemon/__tests__/runtime-session.test.ts @@ -1,7 +1,7 @@ import { test, expect } from 'vitest'; import fs from 'node:fs'; import { makeIosSession } from '../../__tests__/test-utils/session-factories.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '../../utils/diagnostics.ts'; +import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { createDaemonRuntimeSessionStore } from '../runtime-session.ts'; import type { CommandSessionRecord } from '../../runtime-contract.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/daemon/__tests__/screen-recording-boundary-faults.test.ts b/src/daemon/__tests__/screen-recording-boundary-faults.test.ts index c02f489880..074d6a4e3a 100644 --- a/src/daemon/__tests__/screen-recording-boundary-faults.test.ts +++ b/src/daemon/__tests__/screen-recording-boundary-faults.test.ts @@ -14,7 +14,7 @@ import type { import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import { makeSessionStore } from '../../__tests__/test-utils/store-factory.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '../../utils/diagnostics.ts'; +import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { createDurableCaptureAdmissionLedger } from '../durable-capture-admission-ledger.ts'; import { createDurableCaptureResource } from '../durable-capture-resource.ts'; import type { DurableCaptureResourceStore } from '../durable-capture-resource-store.ts'; diff --git a/src/daemon/__tests__/screenshot-overlay.test.ts b/src/daemon/__tests__/screenshot-overlay.test.ts index a4d821e590..7d75724691 100644 --- a/src/daemon/__tests__/screenshot-overlay.test.ts +++ b/src/daemon/__tests__/screenshot-overlay.test.ts @@ -2,7 +2,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; -import { PNG } from '../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { annotateScreenshotWithRefs, buildScreenshotOverlayRefs } from '../screenshot-overlay.ts'; import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/daemon/__tests__/screenshot-runtime-fixture.ts b/src/daemon/__tests__/screenshot-runtime-fixture.ts index 694587de70..ecb462ba49 100644 --- a/src/daemon/__tests__/screenshot-runtime-fixture.ts +++ b/src/daemon/__tests__/screenshot-runtime-fixture.ts @@ -18,7 +18,7 @@ import { import { deviceShape, type DeviceInfo } from '@agent-device/kernel/device'; import fs from 'node:fs'; import { vi, type Mock } from 'vitest'; -import { PNG } from '../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-runtime-binding.ts'; import { unavailableDeviceRuntimeGateway } from './test-device-runtime-gateway.ts'; import { diff --git a/src/daemon/__tests__/snapshot-command-runtime.test.ts b/src/daemon/__tests__/snapshot-command-runtime.test.ts index 4715550341..b43dafba60 100644 --- a/src/daemon/__tests__/snapshot-command-runtime.test.ts +++ b/src/daemon/__tests__/snapshot-command-runtime.test.ts @@ -5,7 +5,7 @@ import { clearRequestAbortRegistration, markRequestCanceled, registerRequestAbort, -} from '../../request/cancel.ts'; +} from '@agent-device/host-kit/request'; import { dispatchSnapshotDiffViaRuntime } from '../snapshot-diff-runtime.ts'; import { dispatchSnapshotViaRuntime } from '../snapshot-runtime.ts'; import { legacyDispatchCapture } from './legacy-snapshot-capture-fixture.ts'; diff --git a/src/daemon/__tests__/snapshot-runtime-fixture.ts b/src/daemon/__tests__/snapshot-runtime-fixture.ts index 1ac41f3d90..eab84d6cca 100644 --- a/src/daemon/__tests__/snapshot-runtime-fixture.ts +++ b/src/daemon/__tests__/snapshot-runtime-fixture.ts @@ -32,7 +32,7 @@ import { } from '@agent-device/kernel/device'; import { actOnAppleAlert, awaitAppleAlert, readAppleAlert } from '../../platforms/apple/alert.ts'; import { type DispatchContext } from '../../core/dispatch-context.ts'; -import { getRequestSignal } from '../../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { isActiveProviderDevice } from '../../provider-device-runtime.ts'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-runtime-binding.ts'; import { unavailableDeviceRuntimeGateway } from './test-device-runtime-gateway.ts'; diff --git a/src/daemon/__tests__/upload.test.ts b/src/daemon/__tests__/upload.test.ts index 4676e32e09..b5c692075d 100644 --- a/src/daemon/__tests__/upload.test.ts +++ b/src/daemon/__tests__/upload.test.ts @@ -6,7 +6,7 @@ import { Readable } from 'node:stream'; import type { IncomingMessage } from 'node:http'; import { receiveUpload } from '../upload.ts'; import { streamReadableToFile, validateArtifactContentLength } from '../artifact-download.ts'; -import { runCmdSync } from '../../utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; function makeUploadRequest(body: Buffer, headers: Record): IncomingMessage { diff --git a/src/daemon/adapters/maestro/__tests__/daemon-runtime-port-targets.test.ts b/src/daemon/adapters/maestro/__tests__/daemon-runtime-port-targets.test.ts index 6d2de1f11a..7c4649064e 100644 --- a/src/daemon/adapters/maestro/__tests__/daemon-runtime-port-targets.test.ts +++ b/src/daemon/adapters/maestro/__tests__/daemon-runtime-port-targets.test.ts @@ -1,6 +1,6 @@ import { expect, test } from 'vitest'; import { promises as fs } from 'node:fs'; -import { PNG } from '../../../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import type { DaemonInvokeFn, DaemonRequest } from '../../../types.ts'; import { createDaemonMaestroRuntimePort } from '../daemon-runtime-port.ts'; import { makeBaseRequest, makeDependencies } from './daemon-runtime-port-fixtures.ts'; diff --git a/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts b/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts index f902ea14f2..a1182f144c 100644 --- a/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts +++ b/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts @@ -4,12 +4,12 @@ import { expect, test } from 'vitest'; import { noMaestroIncludeSources } from '../../../../__tests__/test-utils/replay-script-source.ts'; import { executeMaestroFlow, inspectMaestroFlow } from '@agent-device/maestro'; import type { DaemonInvokeFn, DaemonRequest } from '../../../types.ts'; -import { PNG } from '../../../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { emitDiagnostic, flushDiagnosticsToSessionFile, withDiagnosticsScope, -} from '../../../../utils/diagnostics.ts'; +} from '@agent-device/host-kit/exec'; import { createDaemonMaestroRuntimePort } from '../daemon-runtime-port.ts'; import { MAESTRO_OBSERVATION_POLL_MS } from '../daemon-runtime-port-observation.ts'; import { makeBaseRequest, makeDependencies, makeSnapshot } from './daemon-runtime-port-fixtures.ts'; diff --git a/src/daemon/adapters/maestro/__tests__/wait-for-animation-to-end.test.ts b/src/daemon/adapters/maestro/__tests__/wait-for-animation-to-end.test.ts index f1d1a5d345..4741c9b43a 100644 --- a/src/daemon/adapters/maestro/__tests__/wait-for-animation-to-end.test.ts +++ b/src/daemon/adapters/maestro/__tests__/wait-for-animation-to-end.test.ts @@ -1,7 +1,7 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { expect, test } from 'vitest'; -import { PNG } from '../../../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { waitForMaestroAnimationToEnd } from '../wait-for-animation-to-end.ts'; test('captures an explicit zero-timeout pair and accepts exactly 0.005% RGB difference', async () => { diff --git a/src/daemon/adapters/maestro/daemon-runtime-port-support.ts b/src/daemon/adapters/maestro/daemon-runtime-port-support.ts index bd2dfc6e72..033b511865 100644 --- a/src/daemon/adapters/maestro/daemon-runtime-port-support.ts +++ b/src/daemon/adapters/maestro/daemon-runtime-port-support.ts @@ -16,7 +16,7 @@ import type { import { AppError } from '@agent-device/kernel/errors'; import type { Rect } from '@agent-device/kernel/snapshot'; import type { DaemonMaestroRuntimeDependencies } from './daemon-runtime-port-observation.ts'; -import { stripUndefined } from '../../../utils/parsing.ts'; +import { stripUndefined } from '@agent-device/host-kit/values'; import { projectMaestroPublicOperation, type MaestroPublicOperation, diff --git a/src/daemon/adapters/maestro/daemon-runtime-port.ts b/src/daemon/adapters/maestro/daemon-runtime-port.ts index c8c702eaee..57ef80ad2b 100644 --- a/src/daemon/adapters/maestro/daemon-runtime-port.ts +++ b/src/daemon/adapters/maestro/daemon-runtime-port.ts @@ -8,8 +8,8 @@ import { type MaestroRuntimeOperations, type MaestroRuntimePort, } from '@agent-device/maestro'; -import { registerDiagnosticSensitiveValue } from '../../../utils/diagnostics.ts'; -import { stripUndefined } from '../../../utils/parsing.ts'; +import { registerDiagnosticSensitiveValue } from '@agent-device/host-kit/exec'; +import { stripUndefined } from '@agent-device/host-kit/values'; import { executeRunScriptFile } from './run-script-execution.ts'; import { waitForMaestroAnimationToEnd } from './wait-for-animation-to-end.ts'; import { diff --git a/src/daemon/adapters/maestro/daemon-runtime-tap.ts b/src/daemon/adapters/maestro/daemon-runtime-tap.ts index 2220521584..50734d7050 100644 --- a/src/daemon/adapters/maestro/daemon-runtime-tap.ts +++ b/src/daemon/adapters/maestro/daemon-runtime-tap.ts @@ -10,8 +10,8 @@ import { type MaestroTargetMatch, type MaestroTargetQuery, } from '@agent-device/maestro'; -import { emitDiagnostic } from '../../../utils/diagnostics.ts'; -import { pointInsideRect } from '../../../utils/rect-center.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { pointInsideRect } from '@agent-device/kernel/rect-center'; import { withMaestroScreenshotBaseline, type MaestroScreenshotBaseline, diff --git a/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts b/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts index adb1535e14..7b3e4285ec 100644 --- a/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts +++ b/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts @@ -3,9 +3,9 @@ import os from 'node:os'; import path from 'node:path'; import { MAESTRO_RUNTIME_ADAPTER_POLICY } from '@agent-device/maestro'; import { createRequestCanceledError, isRequestCanceledError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../../utils/diagnostics.ts'; -import { computePngRgbDifferenceAsync } from '../../../utils/png-worker-client.ts'; -import type { PngRgbDifferenceResult } from '../../../utils/png-rgb-difference.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { computePngRgbDifferenceAsync } from '@agent-device/capture-kit/png-worker-client'; +import type { PngRgbDifferenceResult } from '@agent-device/capture-kit/png-rgb-difference'; export type MaestroScreenshotBaseline = { readonly matchesCurrent: () => Promise; diff --git a/src/daemon/adapters/maestro/run-script-execution.ts b/src/daemon/adapters/maestro/run-script-execution.ts index 618bd21dde..d72d6296fe 100644 --- a/src/daemon/adapters/maestro/run-script-execution.ts +++ b/src/daemon/adapters/maestro/run-script-execution.ts @@ -1,8 +1,8 @@ import fs from 'node:fs'; import vm from 'node:vm'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { runCmdSync } from '../../../utils/exec.ts'; -import { stripUndefined } from '../../../utils/parsing.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; +import { stripUndefined } from '@agent-device/host-kit/values'; const RUN_SCRIPT_TIMEOUT_MS = 30_000; const RUN_SCRIPT_DIAGNOSTIC_PREVIEW_CHARS = 1_000; diff --git a/src/daemon/android-snapshot-timeout-evidence.ts b/src/daemon/android-snapshot-timeout-evidence.ts index f2c57249f3..0550fc8fdd 100644 --- a/src/daemon/android-snapshot-timeout-evidence.ts +++ b/src/daemon/android-snapshot-timeout-evidence.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import type { DaemonResponse, SessionState } from './types.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import { snapshotTimeoutCaptureFailed, diff --git a/src/daemon/android-system-dialog.ts b/src/daemon/android-system-dialog.ts index 18b0addc85..85afc3312b 100644 --- a/src/daemon/android-system-dialog.ts +++ b/src/daemon/android-system-dialog.ts @@ -2,11 +2,11 @@ import type { AndroidBlockingDialogFocus, AndroidObservationAdapter, } from '@agent-device/contracts/android-observation'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; import { AppError, normalizeError, type NormalizedError } from '@agent-device/kernel/errors'; import { centerOfRect, type SnapshotNode } from '@agent-device/kernel/snapshot'; -import { sleep } from '../utils/timeouts.ts'; -import { isSnapshotNodeInteractionBlocked } from '../snapshot/snapshot-occlusion.ts'; + +import { isSnapshotNodeInteractionBlocked } from '@agent-device/capture-kit/snapshot-occlusion'; import { expireRefFrame } from './ref-frame.ts'; import type { SessionState } from './types.ts'; import { isActiveProviderDevice } from '../provider-device-runtime.ts'; diff --git a/src/daemon/app-event-runtime.ts b/src/daemon/app-event-runtime.ts index 0f5cd3ee1f..a9462e1af5 100644 --- a/src/daemon/app-event-runtime.ts +++ b/src/daemon/app-event-runtime.ts @@ -3,7 +3,7 @@ import { appEventRuntimeUse } from '@agent-device/contracts/platform-runtime-ope import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { parseTriggerAppEventArgs, resolveAppEventUrl } from '../core/app-events.ts'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { DaemonCommandContext } from './context.ts'; import { admitRuntimeUse, type RuntimeAdmissionBindings } from './runtime-admission.ts'; import { runtimeExecutionFromContext } from './snapshot-runtime-capture-input.ts'; diff --git a/src/daemon/app-switcher-runtime.ts b/src/daemon/app-switcher-runtime.ts index f678bc43a2..5001fd37da 100644 --- a/src/daemon/app-switcher-runtime.ts +++ b/src/daemon/app-switcher-runtime.ts @@ -2,7 +2,7 @@ import type { AppSwitcherInput } from '@agent-device/contracts/app-switcher-runt import { appSwitcherRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/artifact-archive.ts b/src/daemon/artifact-archive.ts index 32774b7cba..f0dab6dd28 100644 --- a/src/daemon/artifact-archive.ts +++ b/src/daemon/artifact-archive.ts @@ -1,8 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { extractArchiveSafely } from '../utils/archive-extraction.ts'; -import type { ArchiveManifestEntry } from '../utils/archive-safety.ts'; +import { extractArchiveSafely, type ArchiveManifestEntry } from '@agent-device/host-kit/fs'; export async function extractTarInstallableArtifact(params: { archivePath: string; diff --git a/src/daemon/artifact-download.ts b/src/daemon/artifact-download.ts index b9d507f30e..797124bc91 100644 --- a/src/daemon/artifact-download.ts +++ b/src/daemon/artifact-download.ts @@ -4,8 +4,7 @@ import path from 'node:path'; import { once } from 'node:events'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { MAX_ARTIFACT_COMPRESSED_BYTES } from '../utils/artifact-limits.ts'; -import { createByteLimitStream } from '../utils/byte-limit-stream.ts'; +import { MAX_ARTIFACT_COMPRESSED_BYTES, createByteLimitStream } from '@agent-device/host-kit/fs'; const TEMP_PREFIX = 'agent-device-artifact-'; const REQUEST_IDLE_TIMEOUT_MS = 60_000; diff --git a/src/daemon/artifact-tracking.ts b/src/daemon/artifact-tracking.ts index df40440031..f383f7a966 100644 --- a/src/daemon/artifact-tracking.ts +++ b/src/daemon/artifact-tracking.ts @@ -4,7 +4,7 @@ import os from 'node:os'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import type { DaemonArtifactType } from '@agent-device/kernel/contracts'; -import { runCmd } from '../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { expiredTenantOwnedEntryError, requireTenantOwnedEntry, diff --git a/src/daemon/back-runtime.ts b/src/daemon/back-runtime.ts index a57802f6ec..0d7f6c9580 100644 --- a/src/daemon/back-runtime.ts +++ b/src/daemon/back-runtime.ts @@ -3,7 +3,7 @@ import type { BackMode } from '@agent-device/contracts/back-mode'; import { backRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/client/__tests__/boundary-fault-transport.test.ts b/src/daemon/client/__tests__/boundary-fault-transport.test.ts index 4d2c9bf273..92674b441d 100644 --- a/src/daemon/client/__tests__/boundary-fault-transport.test.ts +++ b/src/daemon/client/__tests__/boundary-fault-transport.test.ts @@ -17,9 +17,10 @@ import { sendRequest } from '../daemon-client-transport.ts'; const { mockRunCmdSync } = vi.hoisted(() => ({ mockRunCmdSync: vi.fn() })); -vi.mock('../../../utils/exec.ts', async () => { - const actual = - await vi.importActual('../../../utils/exec.ts'); +vi.mock('@agent-device/host-kit/exec', async () => { + const actual = await vi.importActual( + '@agent-device/host-kit/exec', + ); return { ...actual, runCmdSync: mockRunCmdSync }; }); 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 a19d430698..0d78d6972e 100644 --- a/src/daemon/client/__tests__/daemon-client-timeout-route.test.ts +++ b/src/daemon/client/__tests__/daemon-client-timeout-route.test.ts @@ -31,9 +31,10 @@ import { beforeEach, test, vi } from 'vitest'; const { mockRunCmdSync } = vi.hoisted(() => ({ mockRunCmdSync: vi.fn() })); -vi.mock('../../../utils/exec.ts', async () => { - const actual = - await vi.importActual('../../../utils/exec.ts'); +vi.mock('@agent-device/host-kit/exec', async () => { + const actual = await vi.importActual( + '@agent-device/host-kit/exec', + ); return { ...actual, runCmdSync: mockRunCmdSync }; }); diff --git a/src/daemon/client/__tests__/daemon-launch-spec.test.ts b/src/daemon/client/__tests__/daemon-launch-spec.test.ts index dae6bf6f9a..f20caf0d58 100644 --- a/src/daemon/client/__tests__/daemon-launch-spec.test.ts +++ b/src/daemon/client/__tests__/daemon-launch-spec.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { computeDaemonCodeSignature } from '../../code-signature.ts'; import { resolveDaemonLaunchSpec, resolveLocalDaemonCodeSignature } from '../daemon-launch-spec.ts'; -import { resetAllProcessMemosForTests } from '../../../utils/ttl-memo.ts'; +import { resetAllProcessMemosForTests } from '@agent-device/host-kit/values'; afterEach(() => { vi.restoreAllMocks(); diff --git a/src/daemon/client/daemon-client-lifecycle.ts b/src/daemon/client/daemon-client-lifecycle.ts index ce4f9965ea..d70ba27146 100644 --- a/src/daemon/client/daemon-client-lifecycle.ts +++ b/src/daemon/client/daemon-client-lifecycle.ts @@ -5,9 +5,15 @@ import path from 'node:path'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import { readReplayDivergenceResume } from '@agent-device/contracts/divergence'; import type { DaemonRequest, DaemonResponse } from '../types.ts'; -import { runCmdDetachedMonitored, type ExecDetachedExit } from '../../utils/exec.ts'; -import { readVersion } from '../../utils/version.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { + runCmdDetachedMonitored, + type ExecDetachedExit, + emitDiagnostic, + shellQuoteIfNeeded, + sleep, +} from '@agent-device/host-kit/exec'; +import { readVersion } from '@agent-device/host-kit/values'; + import { findUnrecoveredRepairCommitFailure } from '../session-store.ts'; import { resolveDaemonPaths, @@ -19,8 +25,7 @@ import { } from '../config.ts'; import { resolveDaemonLaunchSpec, resolveLocalDaemonCodeSignature } from './daemon-launch-spec.ts'; import { PUBLIC_COMMANDS } from '../../command-catalog.ts'; -import { shellQuoteIfNeeded } from '../../utils/shell-quote.ts'; -import { sleep } from '../../utils/timeouts.ts'; + import { cleanupFailedDaemonStartupMetadata, cleanupStaleDaemonLockIfSafe, diff --git a/src/daemon/client/daemon-client-metadata.ts b/src/daemon/client/daemon-client-metadata.ts index 1c67f8bb83..78c954d762 100644 --- a/src/daemon/client/daemon-client-metadata.ts +++ b/src/daemon/client/daemon-client-metadata.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic, shellQuote } from '@agent-device/host-kit/exec'; import { isAgentDeviceDaemonProcess, stopProcessForTakeover } from '../daemon-process.ts'; -import { shellQuote } from '../../utils/shell-quote.ts'; + import { resolveDaemonPaths, type DaemonPaths, type DaemonServerMode } from '../config.ts'; export type DaemonInfo = { diff --git a/src/daemon/client/daemon-client-rpc.ts b/src/daemon/client/daemon-client-rpc.ts index 36092c526c..2f24a7e7ff 100644 --- a/src/daemon/client/daemon-client-rpc.ts +++ b/src/daemon/client/daemon-client-rpc.ts @@ -5,7 +5,7 @@ import { type DaemonError, } from '@agent-device/kernel/errors'; import { sanitizeErrorCause } from '@agent-device/kernel/redaction'; -import { createRequestId } from '../../utils/diagnostics.ts'; +import { createRequestId } from '@agent-device/host-kit/exec'; import type { DaemonRequest, DaemonResponse } from '../types.ts'; import { materializeRemoteArtifacts } from '../../remote/daemon-artifacts.ts'; import { localizeRemoteDaemonError } from '../../remote/remote-request-diagnostics.ts'; diff --git a/src/daemon/client/daemon-client-timeout.ts b/src/daemon/client/daemon-client-timeout.ts index 0f5a7b6ac6..b0c9e0d5d0 100644 --- a/src/daemon/client/daemon-client-timeout.ts +++ b/src/daemon/client/daemon-client-timeout.ts @@ -1,6 +1,6 @@ import { AppError } from '@agent-device/kernel/errors'; -import { runCmdSync } from '../../utils/exec.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { runCmdSync, emitDiagnostic } from '@agent-device/host-kit/exec'; + import { isAgentDeviceDaemonProcess } from '../daemon-process.ts'; import { PUBLIC_COMMANDS } from '../../command-catalog.ts'; import { resolveCommandTimeoutPolicy } from '../../core/command-descriptor/registry.ts'; diff --git a/src/daemon/client/daemon-client-transport.ts b/src/daemon/client/daemon-client-transport.ts index 3305fc552d..09cbeafd12 100644 --- a/src/daemon/client/daemon-client-transport.ts +++ b/src/daemon/client/daemon-client-transport.ts @@ -3,7 +3,7 @@ import net from 'node:net'; import { AppError } from '@agent-device/kernel/errors'; import { loadNodeHttpRequester, readNodeHttpResponseBody } from '../../utils/node-http.ts'; import type { DaemonRequest, DaemonResponse } from '../types.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { DaemonPaths, DaemonTransportPreference } from '../config.ts'; import { readDaemonHttpProgressResponse, @@ -15,7 +15,7 @@ import { buildHttpRpcPayload, handleDaemonHttpResponseBody } from './daemon-clie import { handleRequestTimeout } from './daemon-client-timeout.ts'; import { isRemoteDaemon, type DaemonInfo } from './daemon-client-metadata.ts'; import { DAEMON_RPC_PROTOCOL_VERSION } from '../http-health.ts'; -import { readVersion } from '../../utils/version.ts'; +import { readVersion } from '@agent-device/host-kit/values'; type ResolvedDaemonTransport = 'socket' | 'http'; type SendRequestOptions = { diff --git a/src/daemon/client/daemon-client.ts b/src/daemon/client/daemon-client.ts index 8379d5dbc0..bc4a8909c6 100644 --- a/src/daemon/client/daemon-client.ts +++ b/src/daemon/client/daemon-client.ts @@ -5,7 +5,7 @@ import type { } from '../types.ts'; import type { AgentDeviceDaemonTransportContext } from '@agent-device/contracts/client'; import { AppError } from '@agent-device/kernel/errors'; -import { createRequestId, emitDiagnostic, withDiagnosticTimer } from '../../utils/diagnostics.ts'; +import { createRequestId, emitDiagnostic, withDiagnosticTimer } from '@agent-device/host-kit/exec'; import { INTERNAL_COMMANDS, PUBLIC_COMMANDS } from '../../command-catalog.ts'; import { prepareRemoteRequestArtifacts } from '../../remote/daemon-artifacts.ts'; import { diff --git a/src/daemon/client/daemon-launch-spec.ts b/src/daemon/client/daemon-launch-spec.ts index aad6289fb0..ca61c8d917 100644 --- a/src/daemon/client/daemon-launch-spec.ts +++ b/src/daemon/client/daemon-launch-spec.ts @@ -1,8 +1,8 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { createTtlMemo } from '../../utils/ttl-memo.ts'; -import { findProjectRoot } from '../../utils/version.ts'; +import { createTtlMemo, findProjectRoot } from '@agent-device/host-kit/values'; + import { computeDaemonCodeSignature } from '../code-signature.ts'; export type DaemonLaunchSpec = { diff --git a/src/daemon/code-signature-cache.ts b/src/daemon/code-signature-cache.ts index 8763de7035..56225a079a 100644 --- a/src/daemon/code-signature-cache.ts +++ b/src/daemon/code-signature-cache.ts @@ -2,7 +2,7 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { publishFileSync } from '../utils/atomic-file.ts'; +import { publishFileSync } from '@agent-device/host-kit/fs'; import { buildDaemonCodeFileLabel, formatDaemonCodeSignature, diff --git a/src/daemon/code-signature.ts b/src/daemon/code-signature.ts index 8702f86aa7..2e93254e8f 100644 --- a/src/daemon/code-signature.ts +++ b/src/daemon/code-signature.ts @@ -1,7 +1,7 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; -import { findProjectRoot } from '../utils/version.ts'; +import { findProjectRoot } from '@agent-device/host-kit/values'; // Any quoted, relative-path-shaped string literal is treated as a module // specifier, rather than matching the `import`/`export`/`from` grammar diff --git a/src/daemon/config.ts b/src/daemon/config.ts index 53ed43842e..16dbb9c7af 100644 --- a/src/daemon/config.ts +++ b/src/daemon/config.ts @@ -1,9 +1,8 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; -import { expandUserHomePath, resolveUserPath } from '../utils/path-resolution.ts'; -import { findProjectRoot } from '../utils/version.ts'; -import type { EnvMap } from '../utils/env-map.ts'; +import { expandUserHomePath, resolveUserPath } from '@agent-device/host-kit/fs'; +import { findProjectRoot, type EnvMap } from '@agent-device/host-kit/values'; import type { DaemonServerMode, diff --git a/src/daemon/context.ts b/src/daemon/context.ts index b10991c290..4bc1029c7d 100644 --- a/src/daemon/context.ts +++ b/src/daemon/context.ts @@ -5,7 +5,7 @@ import { screenshotFlagsFromOptions, type ScreenshotRuntimeFlags, } from '@agent-device/contracts/capture'; -import { getDiagnosticsMeta } from '../utils/diagnostics.ts'; +import { getDiagnosticsMeta } from '@agent-device/host-kit/exec'; import { resolveRunnerLogicalLeaseContext } from './lease-context.ts'; import type { DaemonRequest } from './types.ts'; diff --git a/src/daemon/daemon-process.ts b/src/daemon/daemon-process.ts index 0aea115baf..d4dec3db9b 100644 --- a/src/daemon/daemon-process.ts +++ b/src/daemon/daemon-process.ts @@ -3,8 +3,8 @@ import { readHostProcessIdentityObservations, readProcessCommand, readProcessStartTime, -} from '../utils/host-process.ts'; -import { sleep } from '../utils/timeouts.ts'; + sleep, +} from '@agent-device/host-kit/exec'; const DAEMON_COMMAND_PATTERNS = [ /\/dist\/src\/daemon\.js($|[\s"'])/, diff --git a/src/daemon/daemon-registration.ts b/src/daemon/daemon-registration.ts index b34fe64f7a..63179f11cb 100644 --- a/src/daemon/daemon-registration.ts +++ b/src/daemon/daemon-registration.ts @@ -1,5 +1,5 @@ import fs from 'node:fs'; -import { ownerIdentityDiffers, type OwnerIdentity } from '../utils/owner-identity.ts'; +import { ownerIdentityDiffers, type OwnerIdentity } from '@agent-device/host-kit/exec'; import { resolveDaemonPaths } from './config.ts'; /** diff --git a/src/daemon/daemon-shutdown-report.ts b/src/daemon/daemon-shutdown-report.ts index 5e4fe81c7f..5b6862fcec 100644 --- a/src/daemon/daemon-shutdown-report.ts +++ b/src/daemon/daemon-shutdown-report.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import type { DeviceLease } from '@agent-device/contracts/device'; -import { publishFileSync } from '../utils/atomic-file.ts'; +import { publishFileSync } from '@agent-device/host-kit/fs'; const SHUTDOWN_REPORT_FILE = 'daemon-shutdown.json'; diff --git a/src/daemon/daemon-stop.ts b/src/daemon/daemon-stop.ts index ac9667bc51..acb0658d0b 100644 --- a/src/daemon/daemon-stop.ts +++ b/src/daemon/daemon-stop.ts @@ -6,8 +6,8 @@ import { waitForDaemonExit, type DaemonProcessIdentity, } from './daemon-process.ts'; -import { isProcessAlive } from '../utils/host-process.ts'; -import { sleep } from '../utils/timeouts.ts'; +import { isProcessAlive, sleep } from '@agent-device/host-kit/exec'; + import type { DaemonPaths } from './config.ts'; import { readRegisteredDaemonIdentity } from './daemon-registration.ts'; import type { DeviceClaimRecord, ProviderReleaseRecord } from './daemon-shutdown-report.ts'; diff --git a/src/daemon/deferred-interaction-outcome.ts b/src/daemon/deferred-interaction-outcome.ts index 61886382f5..15c2bb466a 100644 --- a/src/daemon/deferred-interaction-outcome.ts +++ b/src/daemon/deferred-interaction-outcome.ts @@ -2,7 +2,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import type { SnapshotCaptureAnnotations } from '@agent-device/contracts/capture'; import { isApplePlatform, isMobilePlatform } from '@agent-device/kernel/device'; import type { SnapshotState } from '@agent-device/kernel/snapshot'; -import { sleep } from '../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import { captureAndroidFreshnessRecoveredAttempt, clearAndroidSnapshotFreshness, diff --git a/src/daemon/device-claim-admission.ts b/src/daemon/device-claim-admission.ts index da444e4cee..529e88147f 100644 --- a/src/daemon/device-claim-admission.ts +++ b/src/daemon/device-claim-admission.ts @@ -1,7 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { RuntimeOwnerRef } from '@agent-device/contracts/platform-runtime'; import type { DeviceClaimPolicy } from '../core/command-descriptor/types.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { deviceClaimConflictError } from './device-claim-conflict.ts'; import { acquireTransientDeviceClaim, diff --git a/src/daemon/device-claim-conflict.ts b/src/daemon/device-claim-conflict.ts index d7bb719ff6..f30dc4df7f 100644 --- a/src/daemon/device-claim-conflict.ts +++ b/src/daemon/device-claim-conflict.ts @@ -4,7 +4,7 @@ import { type DeviceInfo, } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { shellQuoteIfNeeded } from '../utils/shell-quote.ts'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; import { deviceClaimRequiresStaleInspection, type DeviceClaimClassification, diff --git a/src/daemon/device-claim-inspection.ts b/src/daemon/device-claim-inspection.ts index be2e2b4247..553c14e5c2 100644 --- a/src/daemon/device-claim-inspection.ts +++ b/src/daemon/device-claim-inspection.ts @@ -11,8 +11,9 @@ import { decodeDeviceIdentity } from '@agent-device/capture-kit'; import { classifyOwnerLivenessFromObservation, type OwnerLiveness, -} from '../utils/owner-identity.ts'; -import { readHostProcessIdentityObservations } from '../utils/host-process.ts'; + readHostProcessIdentityObservations, +} from '@agent-device/host-kit/exec'; + import { isSupersededDaemonOwner } from './daemon-registration.ts'; import { canonicalLocalDeviceKey, resolveDeviceClaimRoot } from './device-claim-paths.ts'; import type { DeviceClaim } from './device-claims.ts'; diff --git a/src/daemon/device-claim-reconciliation.ts b/src/daemon/device-claim-reconciliation.ts index b63f9fa10b..4e6cc2ee99 100644 --- a/src/daemon/device-claim-reconciliation.ts +++ b/src/daemon/device-claim-reconciliation.ts @@ -3,7 +3,7 @@ import type { DeviceRuntimeGateway } from '@agent-device/contracts/platform-runt import type { PlatformRequestScope } from '@agent-device/contracts/platform-runtime-host'; import type { PlatformRuntimeOperations } from '@agent-device/contracts/platform-runtime-operations'; import { sameDeviceIdentity } from '@agent-device/kernel/device'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { resolveDaemonPaths } from './config.ts'; import { appLogDurableResource } from './app-log-session-resource.ts'; import { recoverAppLogResourceAfterDaemonLock } from './app-log-resource-recovery.ts'; diff --git a/src/daemon/device-claims.ts b/src/daemon/device-claims.ts index e7c3588518..7b771e6978 100644 --- a/src/daemon/device-claims.ts +++ b/src/daemon/device-claims.ts @@ -8,11 +8,14 @@ import { type DeviceIdentity, type DeviceInfo, } from '@agent-device/kernel/device'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { + emitDiagnostic, + ownerIdentityMatches, + readCurrentOwnerIdentity, +} from '@agent-device/host-kit/exec'; import type { RuntimeOwnerRef } from '@agent-device/contracts/platform-runtime'; -import { publishFileSync } from '../utils/atomic-file.ts'; -import { acquireProcessLock } from '../utils/process-lock.ts'; -import { ownerIdentityMatches, readCurrentOwnerIdentity } from '../utils/owner-identity.ts'; +import { publishFileSync, acquireProcessLock } from '@agent-device/host-kit/fs'; + import { deviceClaimOwnerCannotRelease, inspectDeviceClaimFile, diff --git a/src/daemon/device-ready.ts b/src/daemon/device-ready.ts index 2137c227cb..e7008ec980 100644 --- a/src/daemon/device-ready.ts +++ b/src/daemon/device-ready.ts @@ -1,7 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { ensureLocalPlatformDeviceReady } from '../platform-runtime-device-ready.ts'; import { isActiveProviderDevice } from '../provider-device-runtime.ts'; -import { createTtlMemo } from '../utils/ttl-memo.ts'; +import { createTtlMemo } from '@agent-device/host-kit/values'; // Exported so unit tests can assert TTL behavior without duplicating the value. export const DEVICE_READY_CACHE_TTL_MS = 5_000; diff --git a/src/daemon/durable-capture-resource-adoption.ts b/src/daemon/durable-capture-resource-adoption.ts index 1d84f77752..afd7bad03f 100644 --- a/src/daemon/durable-capture-resource-adoption.ts +++ b/src/daemon/durable-capture-resource-adoption.ts @@ -11,7 +11,7 @@ import { } from '@agent-device/capture-kit'; import { deviceIdentity, sameDeviceIdentity, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { AdoptStartedDurableCaptureParams, DurableCaptureResourceDefinition, diff --git a/src/daemon/durable-capture-resource-recovery.ts b/src/daemon/durable-capture-resource-recovery.ts index fad77edaf3..3f8cf82f3e 100644 --- a/src/daemon/durable-capture-resource-recovery.ts +++ b/src/daemon/durable-capture-resource-recovery.ts @@ -6,7 +6,7 @@ import { isConfirmedCleanup, } from '@agent-device/contracts/durable-resource'; import type { PlatformRequestScope } from '@agent-device/contracts/platform-runtime-host'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { acquireDurableCaptureRecoveryAuthorityBeforeDeadline, DurableCaptureRecoveryDeadlineError, diff --git a/src/daemon/durable-capture-resource-store.ts b/src/daemon/durable-capture-resource-store.ts index 354703f80b..73875ac0d2 100644 --- a/src/daemon/durable-capture-resource-store.ts +++ b/src/daemon/durable-capture-resource-store.ts @@ -5,7 +5,7 @@ import type { DurableResourceEnvelope, } from '@agent-device/contracts/durable-resource-envelope'; import { decodeDurableResourceEnvelope } from '@agent-device/capture-kit'; -import { withAtomicPublishTempPathSync } from '../utils/atomic-file.ts'; +import { withAtomicPublishTempPathSync } from '@agent-device/host-kit/fs'; import { openVerifiedFileForRead } from '../utils/verified-file.ts'; export type DurableCaptureResourceRecord = diff --git a/src/daemon/durable-capture-resource-transitions.ts b/src/daemon/durable-capture-resource-transitions.ts index 6e6368de92..48d5973282 100644 --- a/src/daemon/durable-capture-resource-transitions.ts +++ b/src/daemon/durable-capture-resource-transitions.ts @@ -5,7 +5,7 @@ import { isConfirmedCleanup, } from '@agent-device/contracts/durable-resource'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { withDurableCaptureResourceFence, type DurableCaptureResourceFenceLease, diff --git a/src/daemon/focus-runtime.ts b/src/daemon/focus-runtime.ts index e9790fd175..482c910767 100644 --- a/src/daemon/focus-runtime.ts +++ b/src/daemon/focus-runtime.ts @@ -2,7 +2,7 @@ import type { FocusPointInput } from '@agent-device/contracts/focus-runtime'; import { focusRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Point } from '@agent-device/kernel/snapshot'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { readPointPositionals } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; diff --git a/src/daemon/handlers/__tests__/interaction-settle.test.ts b/src/daemon/handlers/__tests__/interaction-settle.test.ts index d547a9d70e..21939cbb92 100644 --- a/src/daemon/handlers/__tests__/interaction-settle.test.ts +++ b/src/daemon/handlers/__tests__/interaction-settle.test.ts @@ -11,7 +11,10 @@ import { activateCompleteRefFrame } from '../../ref-frame.ts'; import { makeSessionStore } from '../../../__tests__/test-utils/store-factory.ts'; import { makeIosSession } from '../../../__tests__/test-utils/session-factories.ts'; import { createInteractionRuntime } from '../interaction-runtime.ts'; -import { clearRequestAbortRegistration, registerRequestAbort } from '../../../request/cancel.ts'; +import { + clearRequestAbortRegistration, + registerRequestAbort, +} from '@agent-device/host-kit/request'; import { IOS_SIMULATOR } from '../../../__tests__/test-utils/device-fixtures.ts'; import { getRuntimeBindings, diff --git a/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts b/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts index e8871a54c6..b845ebda03 100644 --- a/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts +++ b/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts @@ -12,8 +12,8 @@ vi.mock('../../../platforms/apple/core/simulator.ts', async (importOriginal) => await importOriginal(); return { ...actual, shutdownSimulator: vi.fn() }; }); -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../../../platforms/apple/core/runner-client.ts', async (importOriginal) => { @@ -54,7 +54,11 @@ import { teardownSessionResources as teardownProductionSessionResources } from ' import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; import { LeaseRegistry } from '../../lease-registry.ts'; import { shutdownSimulator } from '../../../platforms/apple/core/simulator.ts'; -import { runCmd } from '../../../utils/exec.ts'; +import { + runCmd, + flushDiagnosticsToSessionFile, + withDiagnosticsScope, +} from '@agent-device/host-kit/exec'; import { cleanupAppleXctracePerfCapture } from '../../../platforms/apple/core/perf-xctrace.ts'; import { cleanupAndroidNativePerfSession } from '../../../platforms/android/perf-native.ts'; import { stopAndroidSnapshotHelperSessionForDevice } from '../../../platforms/android/snapshot-helper.ts'; @@ -62,7 +66,7 @@ import { stopIosRunnerSession } from '../../../platforms/apple/core/runner-clien import { WEB_DESKTOP_DEVICE } from '../../../__tests__/test-utils/device-fixtures.ts'; import { acquireDeviceClaim } from '../../device-claims.ts'; import { inspectDeviceClaims } from '../../device-claim-inspection.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '../../../utils/diagnostics.ts'; + import { type DeviceBinding, localRuntimeOwner, diff --git a/src/daemon/handlers/__tests__/session-device-claims.test.ts b/src/daemon/handlers/__tests__/session-device-claims.test.ts index 6cecb29d07..bba8f7fa0a 100644 --- a/src/daemon/handlers/__tests__/session-device-claims.test.ts +++ b/src/daemon/handlers/__tests__/session-device-claims.test.ts @@ -29,7 +29,7 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', () => ({ activateAndroidTestIme: vi.fn(async () => ({ activated: false })), restoreAndroidTestIme: vi.fn(async () => ({ restored: false, reason: 'no-record' })), })); -vi.mock('../../../utils/host-process.ts', async (importOriginal) => +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => (await import('../../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), @@ -44,7 +44,7 @@ import { discoverReadyAndroidEmulators, dispatchApplicationLifecycleEffect, } from '../../__tests__/application-lifecycle-runtime-fixture.ts'; -import { clearRequestCanceled, markRequestCanceled } from '../../../request/cancel.ts'; +import { clearRequestCanceled, markRequestCanceled } from '@agent-device/host-kit/request'; import { acquireDeviceClaim as acquireProductionDeviceClaim } from '../../device-claims.ts'; import { inspectDeviceClaims } from '../../device-claim-inspection.ts'; import { LeaseRegistry } from '../../lease-registry.ts'; diff --git a/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts b/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts index 590ef27037..1bcf015c06 100644 --- a/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts +++ b/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts @@ -51,8 +51,8 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', async (importOriginal) => await importOriginal(); return { ...actual, activateAndroidTestIme: vi.fn(async () => ({ activated: false })) }; }); -vi.mock('../../../utils/host-process.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); diff --git a/src/daemon/handlers/__tests__/session-open-runtime.test.ts b/src/daemon/handlers/__tests__/session-open-runtime.test.ts index 02ce130ea2..774b162ad7 100644 --- a/src/daemon/handlers/__tests__/session-open-runtime.test.ts +++ b/src/daemon/handlers/__tests__/session-open-runtime.test.ts @@ -49,8 +49,8 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', async (importOriginal) => await importOriginal(); return { ...actual, activateAndroidTestIme: vi.fn(async () => ({ activated: false })) }; }); -vi.mock('../../../utils/host-process.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); diff --git a/src/daemon/handlers/__tests__/session-replay-divergence.test.ts b/src/daemon/handlers/__tests__/session-replay-divergence.test.ts index 692824a1a4..c67db44b06 100644 --- a/src/daemon/handlers/__tests__/session-replay-divergence.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-divergence.test.ts @@ -18,8 +18,8 @@ vi.mock('../snapshot-interactor-capture.ts', () => ({ // re-captures — so the test still proves two dispatches and use of the retried // tree. The #1385 `retryLaunchRace` retry loop (`captureDivergenceObservation`) // awaits this SAME `sleep`, further down in this file. -vi.mock('../../../utils/timeouts.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, sleep: vi.fn(async () => {}) }; }); diff --git a/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts b/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts index a56b62ca64..b3f1455277 100644 --- a/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts @@ -25,8 +25,8 @@ vi.mock('../../../platforms/apple/core/simulator.ts', async (importOriginal) => await importOriginal(); return { ...actual, shutdownSimulator: vi.fn() }; }); -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../../../platforms/apple/core/runner-client.ts', async (importOriginal) => { diff --git a/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts b/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts index c3c4b07117..a9cad9f81a 100644 --- a/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts @@ -25,8 +25,8 @@ vi.mock('../../../platforms/apple/core/simulator.ts', async (importOriginal) => await importOriginal(); return { ...actual, shutdownSimulator: vi.fn() }; }); -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../../../platforms/apple/core/runner-client.ts', async (importOriginal) => { diff --git a/src/daemon/handlers/__tests__/session-replay-runtime-maestro.test.ts b/src/daemon/handlers/__tests__/session-replay-runtime-maestro.test.ts index 34be07eded..7c18c5b73b 100644 --- a/src/daemon/handlers/__tests__/session-replay-runtime-maestro.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-runtime-maestro.test.ts @@ -51,7 +51,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { Worker } from 'node:worker_threads'; -import { PNG } from '../../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import type { DaemonInvokeFn, DaemonRequest, DaemonResponse } from '../../types.ts'; import { SessionStore } from '../../session-store.ts'; import { runReplayScriptSource } from '../session-replay-runtime.ts'; diff --git a/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts b/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts index e0aee3fb42..dc0a0cc685 100644 --- a/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts @@ -23,8 +23,8 @@ vi.mock('../snapshot-interactor-capture.ts', () => ({ // no-op so the retry tests below exercise the retry BRANCH (still runs each // mocked capture attempt) without a real wall-clock wait (repo guidance: unit // tests must not wait real time). -vi.mock('../../../utils/timeouts.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, sleep: vi.fn(async () => {}) }; }); diff --git a/src/daemon/handlers/__tests__/session-test-harness.ts b/src/daemon/handlers/__tests__/session-test-harness.ts index 7b6ab0e0d2..b46cccfa22 100644 --- a/src/daemon/handlers/__tests__/session-test-harness.ts +++ b/src/daemon/handlers/__tests__/session-test-harness.ts @@ -69,13 +69,8 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', async (importOriginal) => restoreAndroidTestIme: vi.fn(async () => ({ restored: false, reason: 'no-record' })), }; }); -vi.mock('../../../platforms/apple/core/simulator.ts', async (importOriginal) => { - const actual = - await importOriginal(); - return { ...actual, getSimulatorState: vi.fn(async () => null) }; -}); -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async () => ({ stdout: '', stderr: '', exitCode: 0 })) }; }); vi.mock('../../materialized-path-registry.ts', async (importOriginal) => { @@ -111,7 +106,7 @@ import { } from '../../../platforms/apple/core/runner-client.ts'; import { runMacOsAlertAction } from '../../../platforms/apple/os/macos/helper.ts'; import { resolveAndroidPackageForOpen } from '../../../platform-runtime-open-target.ts'; -import { runCmd } from '../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { resolveIosApp, resolveIosSimulatorDeepLinkBundleId, diff --git a/src/daemon/handlers/__tests__/session-test-reporter-values-maestro.test.ts b/src/daemon/handlers/__tests__/session-test-reporter-values-maestro.test.ts index 1944637632..4fe8a68ff6 100644 --- a/src/daemon/handlers/__tests__/session-test-reporter-values-maestro.test.ts +++ b/src/daemon/handlers/__tests__/session-test-reporter-values-maestro.test.ts @@ -42,7 +42,7 @@ import type { ReplaySuiteResult } from '@agent-device/contracts/replay'; import { handleSessionCommands } from './session-command-harness.ts'; import { SessionStore } from '../../session-store.ts'; import type { DaemonRequest, DaemonResponse } from '../../types.ts'; -import { withRequestProgressSink } from '../../../request/progress.ts'; +import { withRequestProgressSink } from '@agent-device/host-kit/request'; import { getReplayTestReporterExitCode, runReplayTestReporterProgress, diff --git a/src/daemon/handlers/__tests__/session-test-reporter-values.test.ts b/src/daemon/handlers/__tests__/session-test-reporter-values.test.ts index 63db1e878f..43cb366f20 100644 --- a/src/daemon/handlers/__tests__/session-test-reporter-values.test.ts +++ b/src/daemon/handlers/__tests__/session-test-reporter-values.test.ts @@ -26,7 +26,7 @@ import type { ReplaySuiteResult } from '@agent-device/contracts/replay'; import { handleSessionCommands } from './session-command-harness.ts'; import { SessionStore } from '../../session-store.ts'; import type { DaemonRequest, DaemonResponse } from '../../types.ts'; -import { withRequestProgressSink } from '../../../request/progress.ts'; +import { withRequestProgressSink } from '@agent-device/host-kit/request'; import { withTestDeviceInventoryProvider as withDeviceInventoryProvider } from '../../../__tests__/test-utils/device-inventory-gateways.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { diff --git a/src/daemon/handlers/__tests__/session-test-runner.test.ts b/src/daemon/handlers/__tests__/session-test-runner.test.ts index cf9b78c0a8..7378b99c61 100644 --- a/src/daemon/handlers/__tests__/session-test-runner.test.ts +++ b/src/daemon/handlers/__tests__/session-test-runner.test.ts @@ -2,7 +2,7 @@ import { test, expect, vi } from 'vitest'; import fs from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; -import { clearRequestCanceled, markRequestCanceled } from '../../../request/cancel.ts'; +import { clearRequestCanceled, markRequestCanceled } from '@agent-device/host-kit/request'; import { mockResolveTargetDevice, makeSessionStore, diff --git a/src/daemon/handlers/__tests__/session-test-suite-command-cancellation.test.ts b/src/daemon/handlers/__tests__/session-test-suite-command-cancellation.test.ts index d6c6173cc7..ae94c81c46 100644 --- a/src/daemon/handlers/__tests__/session-test-suite-command-cancellation.test.ts +++ b/src/daemon/handlers/__tests__/session-test-suite-command-cancellation.test.ts @@ -5,7 +5,7 @@ import { isRequestCanceled, markRequestCanceled, registerRequestAbort, -} from '../../../request/cancel.ts'; +} from '@agent-device/host-kit/request'; import { bindReplayTestAttemptCancellation } from '../session-test-suite-command.ts'; // The daemon half of the replay-test cancellation seam (#1478 P3b). The scheduler only says diff --git a/src/daemon/handlers/__tests__/session-test-suite.test.ts b/src/daemon/handlers/__tests__/session-test-suite.test.ts index b3150faf3d..e9d59dc1c4 100644 --- a/src/daemon/handlers/__tests__/session-test-suite.test.ts +++ b/src/daemon/handlers/__tests__/session-test-suite.test.ts @@ -20,13 +20,14 @@ import path from 'node:path'; import { handleSessionCommands, mockInspectDeviceRuntimeFacts } from './session-command-harness.ts'; import type { DaemonRequest } from '../../types.ts'; import { expectOkData, makeSessionStore } from './session-test-suite.fixtures.ts'; -import { withRequestProgressSink } from '../../../request/progress.ts'; import { + withRequestProgressSink, clearRequestCanceled, getRequestSignal, markRequestCanceled, registerRequestAbort, -} from '../../../request/cancel.ts'; +} from '@agent-device/host-kit/request'; + import { withTestDeviceInventoryProvider as withDeviceInventoryProvider } from '../../../__tests__/test-utils/device-inventory-gateways.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { diff --git a/src/daemon/handlers/find.ts b/src/daemon/handlers/find.ts index 76fe61c91c..97bb1f4c55 100644 --- a/src/daemon/handlers/find.ts +++ b/src/daemon/handlers/find.ts @@ -12,7 +12,7 @@ import { expireRefFrame } from '../ref-frame.ts'; import type { DaemonInvokeFn, DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { SessionStore } from '../session-store.ts'; import { contextFromFlags } from '../context.ts'; -import { readCommandMessage, successText } from '../../utils/success-text.ts'; +import { readCommandMessage, successText } from '@agent-device/host-kit/values'; import { errorResponse, noActiveSessionError } from './response.ts'; import { withSystemSurfaceDisclosure } from './system-surface-disclosure.ts'; import { recordSessionAction } from './handler-utils.ts'; @@ -27,7 +27,7 @@ import { resolveSelectorCaptureRuntimePlan } from '@agent-device/contracts/platf import type { TypeTextRuntimeOperations } from '@agent-device/contracts/type-text-runtime'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-runtime-binding.ts'; import { createFindTargetCapture, sparseFindSnapshotResponse } from './find-target-capture.ts'; -import { isSparseSnapshotQualityVerdict } from '../../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; type FindContext = { req: DaemonRequest; diff --git a/src/daemon/handlers/interaction-gesture.ts b/src/daemon/handlers/interaction-gesture.ts index dfb26f53ef..f47437685f 100644 --- a/src/daemon/handlers/interaction-gesture.ts +++ b/src/daemon/handlers/interaction-gesture.ts @@ -25,7 +25,7 @@ import { } from '@agent-device/kernel/snapshot'; import { resolveBoundGestureRuntime, type BoundGestureExecutor } from '../gesture-runtime.ts'; import { isActiveProviderDevice } from '../../provider-device-runtime.ts'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import { ensureAndroidBlockingSystemDialogReady } from '../android-system-dialog.ts'; import type { DaemonResponse, SessionState } from '../types.ts'; import type { InteractionHandlerParams } from './interaction-common.ts'; diff --git a/src/daemon/handlers/interaction-ios-tap-outcome.ts b/src/daemon/handlers/interaction-ios-tap-outcome.ts index fff6677b05..b6ccccacd3 100644 --- a/src/daemon/handlers/interaction-ios-tap-outcome.ts +++ b/src/daemon/handlers/interaction-ios-tap-outcome.ts @@ -5,11 +5,11 @@ import { asAppError } from '@agent-device/kernel/errors'; import { isSparseSnapshotQualityVerdict, preferredSnapshotBackendForVerdict, -} from '../../snapshot-quality/verdict.ts'; +} from '@agent-device/capture-kit/snapshot-quality-verdict'; import { summarizeAxEvidence } from '../../utils/ax-digest.ts'; -import { getRequestSignal } from '../../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { isLocalIosRunnerSession } from '../direct-ios-selector.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { SessionStore } from '../session-store.ts'; import type { SessionState } from '../types.ts'; import type { ContextFromFlags } from './interaction-common.ts'; diff --git a/src/daemon/handlers/interaction-read.ts b/src/daemon/handlers/interaction-read.ts index 65746105b7..3ca4db3901 100644 --- a/src/daemon/handlers/interaction-read.ts +++ b/src/daemon/handlers/interaction-read.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/element-text-runtime'; import { isIosFamily } from '@agent-device/kernel/device'; import { runtimeExecutionFromContext } from '../snapshot-runtime-capture-input.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { SessionState } from '../types.ts'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import { extractReadableText, prefersValueForReadableText } from '../../utils/text-surface.ts'; diff --git a/src/daemon/handlers/interaction-runtime.ts b/src/daemon/handlers/interaction-runtime.ts index 6e9bbe4882..f178968066 100644 --- a/src/daemon/handlers/interaction-runtime.ts +++ b/src/daemon/handlers/interaction-runtime.ts @@ -15,7 +15,7 @@ import { createDaemonRuntimePolicy } from '../runtime-policy.ts'; import { createDaemonRuntimeSessionStore } from '../runtime-session.ts'; import { NO_ACTIVE_SESSION_MESSAGE } from './response.ts'; import type { Rect, SnapshotNode } from '@agent-device/kernel/snapshot'; -import { getRequestSignal } from '../../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { buildAppleRunnerRequestOptions } from '../apple-runner-options.ts'; import { isLocalIosRunnerSession } from '../direct-ios-selector.ts'; import { confirmIosOffscreenTargetVisible } from '../offscreen-target-probe.ts'; diff --git a/src/daemon/handlers/interaction-snapshot.ts b/src/daemon/handlers/interaction-snapshot.ts index fd0ff44cc3..49ab5ed061 100644 --- a/src/daemon/handlers/interaction-snapshot.ts +++ b/src/daemon/handlers/interaction-snapshot.ts @@ -5,7 +5,7 @@ import type { SnapshotPreferredBackend, SnapshotState } from '@agent-device/kern import type { ContextFromFlags } from './interaction-common.ts'; import { captureSnapshot } from './snapshot-capture.ts'; import { setSessionSnapshot } from '../session-snapshot.ts'; -import { isSparseSnapshotQualityVerdict } from '../../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { snapshotOptionsToFlags } from '../../backend-snapshot-options.ts'; import type { CaptureSnapshotInput, diff --git a/src/daemon/handlers/interaction-targeting.ts b/src/daemon/handlers/interaction-targeting.ts index ec8c8d8c8e..88987e9820 100644 --- a/src/daemon/handlers/interaction-targeting.ts +++ b/src/daemon/handlers/interaction-targeting.ts @@ -1,4 +1,4 @@ -import { resolveRectCenter } from '../../utils/rect-center.ts'; +import { resolveRectCenter } from '@agent-device/kernel/rect-center'; export function parseCoordinateTarget(positionals: string[]): { x: number; y: number } | null { if (positionals.length < 2) return null; diff --git a/src/daemon/handlers/interaction-touch-android-freshness.ts b/src/daemon/handlers/interaction-touch-android-freshness.ts index 42cbe175ea..287aa6cfb1 100644 --- a/src/daemon/handlers/interaction-touch-android-freshness.ts +++ b/src/daemon/handlers/interaction-touch-android-freshness.ts @@ -1,4 +1,4 @@ -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { getActiveAndroidSnapshotFreshness } from '../session-snapshot-freshness.ts'; import type { SessionState } from '../types.ts'; import type { InteractionHandlerParams } from './interaction-common.ts'; diff --git a/src/daemon/handlers/interaction-touch-direct-ios.ts b/src/daemon/handlers/interaction-touch-direct-ios.ts index c4a0faea26..114cd903ea 100644 --- a/src/daemon/handlers/interaction-touch-direct-ios.ts +++ b/src/daemon/handlers/interaction-touch-direct-ios.ts @@ -1,6 +1,6 @@ import type { GestureReferenceFrame } from '@agent-device/contracts/scroll-gesture'; import { normalizeError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { isDirectIosSelectorFallbackError, type DirectIosSelectorTarget, diff --git a/src/daemon/handlers/interaction-touch-payload.ts b/src/daemon/handlers/interaction-touch-payload.ts index 971b97879f..3997feb4a4 100644 --- a/src/daemon/handlers/interaction-touch-payload.ts +++ b/src/daemon/handlers/interaction-touch-payload.ts @@ -1,5 +1,5 @@ import type { GestureReferenceFrame } from '@agent-device/contracts/scroll-gesture'; -import { successText } from '../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; /** * What a built touch payload looks like: the field merge (backend data, point, diff --git a/src/daemon/handlers/interaction-touch-reference-frame.ts b/src/daemon/handlers/interaction-touch-reference-frame.ts index 79e573233a..77ddbc44e7 100644 --- a/src/daemon/handlers/interaction-touch-reference-frame.ts +++ b/src/daemon/handlers/interaction-touch-reference-frame.ts @@ -2,7 +2,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import type { AndroidObservationAdapter } from '@agent-device/contracts/android-observation'; import type { GestureReferenceFrame } from '@agent-device/contracts/scroll-gesture'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { SessionStore } from '../session-store.ts'; import { getSnapshotReferenceFrame } from '../touch-reference-frame.ts'; import type { SessionState } from '../types.ts'; diff --git a/src/daemon/handlers/lease.ts b/src/daemon/handlers/lease.ts index 9b235d878b..fa7293f831 100644 --- a/src/daemon/handlers/lease.ts +++ b/src/daemon/handlers/lease.ts @@ -23,7 +23,7 @@ import { } from '../../core/lease-scope.ts'; import { AppError, createRequestCanceledError, errorMessage } from '@agent-device/kernel/errors'; import { LEASE_ALLOCATION_BUDGET_MS } from '../../core/command-descriptor/timeout-policy.ts'; -import { getRequestSignal, isRequestCanceled } from '../../request/cancel.ts'; +import { getRequestSignal, isRequestCanceled } from '@agent-device/host-kit/request'; import { listDownloadableArtifacts } from '../artifact-tracking.ts'; type LeaseHandlerArgs = { diff --git a/src/daemon/handlers/react-native.ts b/src/daemon/handlers/react-native.ts index e02ab5c0e4..1bbb9eab9f 100644 --- a/src/daemon/handlers/react-native.ts +++ b/src/daemon/handlers/react-native.ts @@ -9,10 +9,10 @@ import { type ReactNativeOverlayDismissTarget, } from '../../core/react-native-overlay.ts'; import { normalizeError } from '@agent-device/kernel/errors'; -import { stripUndefined } from '../../utils/parsing.ts'; -import { successText } from '../../utils/success-text.ts'; +import { stripUndefined, successText } from '@agent-device/host-kit/values'; + import type { SnapshotQualityVerdict, SnapshotState } from '@agent-device/kernel/snapshot'; -import { isSparseSnapshotQualityVerdict } from '../../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import type { DaemonResponse, SessionState } from '../types.ts'; import { errorResponse, noActiveSessionError } from './response.ts'; import { captureSnapshotForSession } from './interaction-snapshot.ts'; diff --git a/src/daemon/handlers/session-app-deployment.ts b/src/daemon/handlers/session-app-deployment.ts index adde3e6aed..87339b41ab 100644 --- a/src/daemon/handlers/session-app-deployment.ts +++ b/src/daemon/handlers/session-app-deployment.ts @@ -13,7 +13,7 @@ import { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { resolvePayloadInput } from '../../utils/payload-input.ts'; import { resolveDeployResultTarget } from '../../utils/result-serialization.ts'; -import { withSuccessText } from '../../utils/success-text.ts'; +import { withSuccessText } from '@agent-device/host-kit/values'; import { recordSessionAction } from './handler-utils.ts'; import { errorResponse } from './response.ts'; import { requireSessionOrExplicitSelector, resolveCommandDevice } from './session-device-utils.ts'; diff --git a/src/daemon/handlers/session-app-source-deployment.ts b/src/daemon/handlers/session-app-source-deployment.ts index d6952970ec..3e0955f7ad 100644 --- a/src/daemon/handlers/session-app-source-deployment.ts +++ b/src/daemon/handlers/session-app-source-deployment.ts @@ -17,7 +17,7 @@ import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-ru import { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { resolveInstallFromSourceResultTarget } from '../../utils/result-serialization.ts'; -import { withSuccessText } from '../../utils/success-text.ts'; +import { withSuccessText } from '@agent-device/host-kit/values'; import { recordSessionAction } from './handler-utils.ts'; import { resolveCommandDevice } from './session-device-utils.ts'; import { diff --git a/src/daemon/handlers/session-clipboard.ts b/src/daemon/handlers/session-clipboard.ts index e275295ae2..f65a8d471a 100644 --- a/src/daemon/handlers/session-clipboard.ts +++ b/src/daemon/handlers/session-clipboard.ts @@ -16,7 +16,7 @@ import type { SessionStore } from '../session-store.ts'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-runtime-binding.ts'; import { admitRuntimeUse, type RuntimeAdmissionBindings } from '../runtime-admission.ts'; import { runtimeExecutionFromContext } from '../snapshot-runtime-capture-input.ts'; -import { successText } from '../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { errorResponse, type DaemonFailureResponse } from './response.ts'; import { recordSessionAction } from './handler-utils.ts'; import { requireSessionOrExplicitSelector, resolveCommandDevice } from './session-device-utils.ts'; diff --git a/src/daemon/handlers/session-close-script.ts b/src/daemon/handlers/session-close-script.ts index ce51ce715d..f16094e1b2 100644 --- a/src/daemon/handlers/session-close-script.ts +++ b/src/daemon/handlers/session-close-script.ts @@ -1,5 +1,5 @@ import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { successText } from '../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { recordSessionAction } from './handler-utils.ts'; diff --git a/src/daemon/handlers/session-close.ts b/src/daemon/handlers/session-close.ts index 0acbc6a867..6a8b408279 100644 --- a/src/daemon/handlers/session-close.ts +++ b/src/daemon/handlers/session-close.ts @@ -1,9 +1,9 @@ -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import type { LeaseLifecycleProvider, TargetShutdownResult } from '@agent-device/contracts/device'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { SessionStore } from '../session-store.ts'; -import { successText, withSuccessText } from '../../utils/success-text.ts'; +import { successText, withSuccessText } from '@agent-device/host-kit/values'; import { resolveCommandDevice } from './session-device-utils.ts'; import { errorResponse } from './response.ts'; import { expireRefFrame } from '../ref-frame.ts'; diff --git a/src/daemon/handlers/session-doctor-metro.ts b/src/daemon/handlers/session-doctor-metro.ts index cf8240441c..0abf6d10c0 100644 --- a/src/daemon/handlers/session-doctor-metro.ts +++ b/src/daemon/handlers/session-doctor-metro.ts @@ -1,5 +1,5 @@ import type { DoctorCheck, DoctorKind } from '@agent-device/contracts/observability'; -import { runCmd } from '../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; const METRO_PROBE_TIMEOUT_MS = 1500; const METRO_PROCESS_LOOKUP_TIMEOUT_MS = 1500; diff --git a/src/daemon/handlers/session-doctor-output.ts b/src/daemon/handlers/session-doctor-output.ts index 191e8f4e29..3b7d54fa7c 100644 --- a/src/daemon/handlers/session-doctor-output.ts +++ b/src/daemon/handlers/session-doctor-output.ts @@ -1,4 +1,4 @@ -import { emitRequestProgress } from '../../request/progress.ts'; +import { emitRequestProgress } from '@agent-device/host-kit/request'; import { formatDoctorCheckDetailLines, formatDoctorCheckSummaryLine, diff --git a/src/daemon/handlers/session-doctor.ts b/src/daemon/handlers/session-doctor.ts index ec40668ef8..a9f3d84bc2 100644 --- a/src/daemon/handlers/session-doctor.ts +++ b/src/daemon/handlers/session-doctor.ts @@ -2,13 +2,13 @@ import path from 'node:path'; import { PUBLIC_COMMANDS } from '../../command-catalog.ts'; import { isIosFamily, publicPlatformString, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitRequestProgress } from '../../request/progress.ts'; +import { emitRequestProgress } from '@agent-device/host-kit/request'; import { isActiveProviderDevice } from '../../provider-device-runtime.ts'; import { listLocalDeviceInventory, shouldPropagateDeviceInventoryProbeError, } from '../../request/device-inventory-context.ts'; -import { readVersion } from '../../utils/version.ts'; +import { readVersion } from '@agent-device/host-kit/values'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { SessionStore } from '../session-store.ts'; import { appendAppChecks, type DoctorAppInventory } from './session-doctor-app.ts'; @@ -36,7 +36,7 @@ import type { HostDiagnostics, HostDiagnosticsContext, } from '@agent-device/contracts/host-diagnostics'; -import { resolveAndroidSerialAllowlist } from '../../utils/device-isolation.ts'; +import { resolveAndroidSerialAllowlist } from '@agent-device/host-kit/fs'; import type { InstalledAppInfo } from '@agent-device/contracts/app-inventory-runtime'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import { appsRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; diff --git a/src/daemon/handlers/session-inventory.ts b/src/daemon/handlers/session-inventory.ts index 6def4d9682..167cc3aaf1 100644 --- a/src/daemon/handlers/session-inventory.ts +++ b/src/daemon/handlers/session-inventory.ts @@ -18,7 +18,7 @@ import { import { resolveAndroidSerialAllowlist, resolveIosSimulatorDeviceSetPath, -} from '../../utils/device-isolation.ts'; +} from '@agent-device/host-kit/fs'; import type { DaemonRequest, DaemonResponse, SessionRef } from '../types.ts'; import { resolveSessionRunnerLogPath, SessionStore } from '../session-store.ts'; import { diff --git a/src/daemon/handlers/session-open-execution.ts b/src/daemon/handlers/session-open-execution.ts index 74d65b2ecd..fc6e1b0243 100644 --- a/src/daemon/handlers/session-open-execution.ts +++ b/src/daemon/handlers/session-open-execution.ts @@ -16,7 +16,7 @@ import { armAuthoringOnOpen, isAuthoringArmedSession, } from '../session-script-publication-capability.ts'; -import { isRequestCanceled } from '../../request/cancel.ts'; +import { isRequestCanceled } from '@agent-device/host-kit/request'; import { createRequestCanceledError } from '@agent-device/kernel/errors'; import { resolveSessionRequestLogPath, @@ -31,7 +31,7 @@ import { import { STARTUP_SAMPLE_METHOD, type StartupPerfSample } from './session-startup-metrics.ts'; import { buildNextOpenSession, buildOpenResult } from './session-open-surface.ts'; import { markDeferredInteractionOutcome } from '../deferred-interaction-outcome.ts'; -import { emitDiagnostic, getDiagnosticsMeta } from '../../utils/diagnostics.ts'; +import { emitDiagnostic, getDiagnosticsMeta } from '@agent-device/host-kit/exec'; import { prepareOpenCommandDetails, type ResolvedOpenRuntimeHintPlan, diff --git a/src/daemon/handlers/session-open-surface.ts b/src/daemon/handlers/session-open-surface.ts index d990241727..cdac5eeae5 100644 --- a/src/daemon/handlers/session-open-surface.ts +++ b/src/daemon/handlers/session-open-surface.ts @@ -6,7 +6,7 @@ import { type DeviceInfo, } from '@agent-device/kernel/device'; import type { SessionRuntimeHints, SessionState } from '../types.ts'; -import { successText } from '../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { StartupPerfSample } from './session-startup-metrics.ts'; import type { DeviceSelectionResult } from '../../core/device-selection-resolver.ts'; diff --git a/src/daemon/handlers/session-open.ts b/src/daemon/handlers/session-open.ts index 27c06b0289..1f4dd5d883 100644 --- a/src/daemon/handlers/session-open.ts +++ b/src/daemon/handlers/session-open.ts @@ -10,7 +10,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { SessionStore } from '../session-store.ts'; import { refreshSessionDeviceIfNeeded } from './session-device-utils.ts'; -import { withKeyedLock } from '../../utils/keyed-lock.ts'; +import { withKeyedLock } from '@agent-device/kernel/keyed-lock'; import { buildOpenTargetDeviceResolutionOptions } from '../open-device-selection.ts'; import { invalidOpenArgs, diff --git a/src/daemon/handlers/session-replay-divergence.ts b/src/daemon/handlers/session-replay-divergence.ts index f760eba2ce..eae54deb10 100644 --- a/src/daemon/handlers/session-replay-divergence.ts +++ b/src/daemon/handlers/session-replay-divergence.ts @@ -1,8 +1,8 @@ import type { SessionAction } from '@agent-device/contracts/session'; import type { CommandFlags } from '@agent-device/contracts/command'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import { isUnreadableCaptureContentError } from '@agent-device/contracts/android-snapshot-quality'; -import { isSparseSnapshotQualityVerdict } from '../../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { displayLabel, formatRole } from '../../snapshot/snapshot-lines.ts'; import type { ResponseLevel } from '@agent-device/kernel/contracts'; import type { DaemonError } from '@agent-device/kernel/errors'; diff --git a/src/daemon/handlers/session-replay-maestro-failure.ts b/src/daemon/handlers/session-replay-maestro-failure.ts index 399be8d215..ed550dbd29 100644 --- a/src/daemon/handlers/session-replay-maestro-failure.ts +++ b/src/daemon/handlers/session-replay-maestro-failure.ts @@ -9,7 +9,7 @@ import { type ReplayVarScrubEntry, } from '@agent-device/contracts/divergence'; import { formatScriptArg } from '@agent-device/ad-script'; -import { getRequestSignal } from '../../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import type { ReplayReportAction } from './session-replay-report-action.ts'; diff --git a/src/daemon/handlers/session-replay-maestro-observer.ts b/src/daemon/handlers/session-replay-maestro-observer.ts index 92658549e9..79841a3f1e 100644 --- a/src/daemon/handlers/session-replay-maestro-observer.ts +++ b/src/daemon/handlers/session-replay-maestro-observer.ts @@ -6,7 +6,7 @@ import type { } from '@agent-device/maestro'; import { AppError } from '@agent-device/kernel/errors'; import type { ReplayTestAttemptStepSink } from '@agent-device/replay-test'; -import { stripUndefined } from '../../utils/parsing.ts'; +import { stripUndefined } from '@agent-device/host-kit/values'; import { appendReplayTraceEvent } from './session-replay-trace.ts'; export function createMaestroReplayObserver(params: { diff --git a/src/daemon/handlers/session-replay-maestro-runtime.ts b/src/daemon/handlers/session-replay-maestro-runtime.ts index a64cd17490..1c3793c93f 100644 --- a/src/daemon/handlers/session-replay-maestro-runtime.ts +++ b/src/daemon/handlers/session-replay-maestro-runtime.ts @@ -8,8 +8,8 @@ import { } from '@agent-device/maestro'; import { AppError } from '@agent-device/kernel/errors'; import { resolveTargetDevice } from '../../core/dispatch-resolve.ts'; -import { getRequestSignal } from '../../request/cancel.ts'; -import { stripUndefined } from '../../utils/parsing.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; +import { stripUndefined } from '@agent-device/host-kit/values'; import { collectReplayShellEnv, parseReplayCliEnvEntries, diff --git a/src/daemon/handlers/session-replay-runtime-failure.ts b/src/daemon/handlers/session-replay-runtime-failure.ts index c02ddb9e6d..ef4e02abca 100644 --- a/src/daemon/handlers/session-replay-runtime-failure.ts +++ b/src/daemon/handlers/session-replay-runtime-failure.ts @@ -13,7 +13,7 @@ import { buildReplayDivergenceFailureResponse, hoistReplayFailureCauseDiagnosticMeta, } from './session-replay-runtime-failure-response.ts'; -import { getRequestSignal } from '../../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; export async function withReplayFailureDiagnostics(params: { response: DaemonResponse; diff --git a/src/daemon/handlers/session-replay-runtime.ts b/src/daemon/handlers/session-replay-runtime.ts index 425e4d1e5f..2aec107346 100644 --- a/src/daemon/handlers/session-replay-runtime.ts +++ b/src/daemon/handlers/session-replay-runtime.ts @@ -7,7 +7,7 @@ import type { SnapshotTimingSample } from '@agent-device/contracts/capture'; import { summarizeSnapshotTimingSamples } from '@agent-device/contracts/capture'; import type { ReplayCommandResult } from '@agent-device/contracts/replay'; import { isMaestroYamlPath, maestroBackendRequiredMessage } from '../../replay/format.ts'; -import { getRequestSignal } from '../../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { createReplayCoordinator, type ReplayCoordinator } from '../session-replay-coordinator.ts'; import { createAdReplayStepRuntime, diff --git a/src/daemon/handlers/session-replay-trace.ts b/src/daemon/handlers/session-replay-trace.ts index 2feb38db96..cb4b53306a 100644 --- a/src/daemon/handlers/session-replay-trace.ts +++ b/src/daemon/handlers/session-replay-trace.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; import { redactDiagnosticData } from '@agent-device/kernel/redaction'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; export function appendReplayTraceEvent( tracePath: string | undefined, diff --git a/src/daemon/handlers/session-replay-video-recording.ts b/src/daemon/handlers/session-replay-video-recording.ts index be79ccf90b..f701976a4b 100644 --- a/src/daemon/handlers/session-replay-video-recording.ts +++ b/src/daemon/handlers/session-replay-video-recording.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import type { DaemonOpenLifecycle, DaemonRequest, DaemonResponse } from '../types.ts'; import type { SessionStore } from '../session-store.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; -import { sleep } from '../../utils/timeouts.ts'; +import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; + import { handleRecordCommand } from './record-runtime.ts'; import type { BindDeviceRuntime, BindExactDeviceRuntime } from '../request-runtime-binding.ts'; import type { ScreenRecordingAdmissionLedger } from '../screen-recording-admission-ledger.ts'; diff --git a/src/daemon/handlers/session-script-publication.ts b/src/daemon/handlers/session-script-publication.ts index 585713354d..1b54c51fe7 100644 --- a/src/daemon/handlers/session-script-publication.ts +++ b/src/daemon/handlers/session-script-publication.ts @@ -1,6 +1,6 @@ import { INTERNAL_COMMANDS } from '../../command-catalog.ts'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { successText } from '../../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { effectiveWriteForce, isAuthoringArmedSession, diff --git a/src/daemon/handlers/session-state.ts b/src/daemon/handlers/session-state.ts index 7fa1eff83e..f8808f1e70 100644 --- a/src/daemon/handlers/session-state.ts +++ b/src/daemon/handlers/session-state.ts @@ -15,7 +15,7 @@ import { } from '@agent-device/kernel/device'; import type { DaemonRequest, DaemonResponse } from '../types.ts'; import { SessionStore } from '../session-store.ts'; -import { resolveAndroidSerialAllowlist } from '../../utils/device-isolation.ts'; +import { resolveAndroidSerialAllowlist } from '@agent-device/host-kit/fs'; import { hasExplicitSessionFlag, requireSessionOrExplicitSelector, diff --git a/src/daemon/handlers/session-test-shard-devices.ts b/src/daemon/handlers/session-test-shard-devices.ts index 6cd3d46511..540f2e943f 100644 --- a/src/daemon/handlers/session-test-shard-devices.ts +++ b/src/daemon/handlers/session-test-shard-devices.ts @@ -4,7 +4,7 @@ import { listDeviceInventory } from '../../request/device-inventory-context.ts'; import { resolveAndroidSerialAllowlist, resolveIosSimulatorDeviceSetPath, -} from '../../utils/device-isolation.ts'; +} from '@agent-device/host-kit/fs'; import { isMobilePlatform, matchesPlatformSelector, diff --git a/src/daemon/handlers/session-test-suite-command.ts b/src/daemon/handlers/session-test-suite-command.ts index bde0219012..9360d546ff 100644 --- a/src/daemon/handlers/session-test-suite-command.ts +++ b/src/daemon/handlers/session-test-suite-command.ts @@ -23,15 +23,16 @@ import { runReplayScriptSource } from './session-replay-runtime.ts'; import { collectReplayActionArtifactPaths } from './session-replay-runtime-artifacts.ts'; import { errorResponse } from './response.ts'; import { AppError, asAppError } from '@agent-device/kernel/errors'; -import { emitRequestProgress } from '../../request/progress.ts'; import { + emitRequestProgress, clearRequestCanceled, getRequestSignal, isRequestCanceled, markRequestCanceled, registerRequestAbort, -} from '../../request/cancel.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +} from '@agent-device/host-kit/request'; + +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { buildReplayTestSourceDiscovery } from './session-test-source-discovery.ts'; import { buildReplayTestShardFlags, diff --git a/src/daemon/handlers/snapshot-settings.ts b/src/daemon/handlers/snapshot-settings.ts index ae9ba1f8cd..b35a69e48b 100644 --- a/src/daemon/handlers/snapshot-settings.ts +++ b/src/daemon/handlers/snapshot-settings.ts @@ -14,9 +14,13 @@ import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { recordIfSession } from './snapshot-session.ts'; import { errorResponse, type DaemonFailureResponse } from './response.ts'; import { expireRefFrame } from '../ref-frame.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; -import { readLocationCoordinate } from '../../utils/location-coordinates.ts'; -import { successText, withSuccessText } from '../../utils/success-text.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { + readLocationCoordinate, + successText, + withSuccessText, +} from '@agent-device/host-kit/values'; + import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-runtime-binding.ts'; import { admitRuntimeUse } from '../runtime-admission.ts'; import { runtimeExecutionFromContext } from '../snapshot-runtime-capture-input.ts'; diff --git a/src/daemon/home-runtime.ts b/src/daemon/home-runtime.ts index 8006010429..9acd6856b5 100644 --- a/src/daemon/home-runtime.ts +++ b/src/daemon/home-runtime.ts @@ -2,7 +2,7 @@ import type { HomeInput } from '@agent-device/contracts/home-runtime'; import { homeRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/http-health.ts b/src/daemon/http-health.ts index a7932df40c..9a648f8dcf 100644 --- a/src/daemon/http-health.ts +++ b/src/daemon/http-health.ts @@ -1,4 +1,4 @@ -import { readVersion } from '../utils/version.ts'; +import { readVersion } from '@agent-device/host-kit/values'; // See docs/adr/0006-daemon-rpc-protocol-version.md before changing this value. // Enforced, not just documented: `test/wire-compat/` digests the declarations diff --git a/src/daemon/interaction-outcome-policy.ts b/src/daemon/interaction-outcome-policy.ts index 020b2c65d9..a003be0965 100644 --- a/src/daemon/interaction-outcome-policy.ts +++ b/src/daemon/interaction-outcome-policy.ts @@ -2,7 +2,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import { isMobilePlatform } from '@agent-device/kernel/device'; import type { SnapshotNode, SnapshotState } from '@agent-device/kernel/snapshot'; import { collectKeyboardChromeRefs } from '../core/snapshot-chrome.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { isViewportRootNode } from '@agent-device/contracts/snapshot'; import { contextFromFlags, type DaemonCommandContext } from './context.ts'; import type { SessionState } from './types.ts'; diff --git a/src/daemon/ios-app-session-hint.ts b/src/daemon/ios-app-session-hint.ts index 91697f4c87..961757d894 100644 --- a/src/daemon/ios-app-session-hint.ts +++ b/src/daemon/ios-app-session-hint.ts @@ -1,6 +1,6 @@ import { isIosFamily, type DeviceInfo } from '@agent-device/kernel/device'; import { resolveSoleForegroundIosApp } from '../platform-runtime-open-target.ts'; -import { shellQuoteIfNeeded } from '../utils/shell-quote.ts'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; export { resolveSoleForegroundIosApp } from '../platform-runtime-open-target.ts'; diff --git a/src/daemon/keyboard-runtime.ts b/src/daemon/keyboard-runtime.ts index c3a43d26ba..10a2f5cc05 100644 --- a/src/daemon/keyboard-runtime.ts +++ b/src/daemon/keyboard-runtime.ts @@ -18,7 +18,7 @@ import type { import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import { isKeyboardAction, type KeyboardAction } from '../utils/keyboard-actions.ts'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { DaemonCommandContext } from './context.ts'; import { admitRuntimeUse, diff --git a/src/daemon/lease-context.ts b/src/daemon/lease-context.ts index 1cfd9c044e..d49a0bdc1c 100644 --- a/src/daemon/lease-context.ts +++ b/src/daemon/lease-context.ts @@ -2,7 +2,7 @@ import type { DaemonRequest } from './types.ts'; import type { LeaseBackend } from '@agent-device/kernel/contracts'; import type { DeviceLease } from '@agent-device/contracts/device'; import type { RunnerLogicalLeaseContext } from '@agent-device/contracts/runner-lease-context'; -import { stripUndefined } from '../utils/parsing.ts'; +import { stripUndefined } from '@agent-device/host-kit/values'; import { DEFAULT_PROXY_LEASE_TTL_MS, findMissingProxyLeaseFields, diff --git a/src/daemon/lease-lifecycle.ts b/src/daemon/lease-lifecycle.ts index 695bcb4be1..9fbf1ad7ba 100644 --- a/src/daemon/lease-lifecycle.ts +++ b/src/daemon/lease-lifecycle.ts @@ -1,4 +1,4 @@ -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { leaseScopeToReleaseRequest } from '../core/lease-scope.ts'; import { clearDeviceClaim } from './device-claims.ts'; import type { LeaseRegistry } from './lease-registry.ts'; diff --git a/src/daemon/offscreen-target-probe.ts b/src/daemon/offscreen-target-probe.ts index fe2132b573..eddebc5ec3 100644 --- a/src/daemon/offscreen-target-probe.ts +++ b/src/daemon/offscreen-target-probe.ts @@ -1,5 +1,5 @@ import type { Rect, SnapshotNode } from '@agent-device/kernel/snapshot'; -import { isConfirmedOnScreenProbe } from '../snapshot/mobile-snapshot-semantics.ts'; +import { isConfirmedOnScreenProbe } from '@agent-device/capture-kit/mobile-snapshot-semantics'; import { deriveDirectIosNodeSelector } from './direct-ios-selector.ts'; import { queryDirectIosSelector } from './selector-runtime.ts'; import type { AppleRunnerRequestOptions } from './apple-runner-options.ts'; diff --git a/src/daemon/orientation-runtime.ts b/src/daemon/orientation-runtime.ts index 071dd0451a..b6135d97ad 100644 --- a/src/daemon/orientation-runtime.ts +++ b/src/daemon/orientation-runtime.ts @@ -3,7 +3,7 @@ import { parseDeviceRotation, type DeviceRotation } from '@agent-device/contract import { orientationRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/platform-request-scope.ts b/src/daemon/platform-request-scope.ts index bf280477a7..d07d03715b 100644 --- a/src/daemon/platform-request-scope.ts +++ b/src/daemon/platform-request-scope.ts @@ -3,9 +3,9 @@ import type { PlatformProgressUpdate, PlatformRequestScope, } from '@agent-device/contracts/platform-runtime-host'; -import { getRequestSignal } from '../request/cancel.ts'; -import { emitRequestProgress } from '../request/progress.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { getRequestSignal, emitRequestProgress } from '@agent-device/host-kit/request'; + +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { DaemonRequest } from './types.ts'; const processLifetimeSignal = new AbortController().signal; diff --git a/src/daemon/post-gesture-stability.ts b/src/daemon/post-gesture-stability.ts index 60d6216f41..f390db34f4 100644 --- a/src/daemon/post-gesture-stability.ts +++ b/src/daemon/post-gesture-stability.ts @@ -1,5 +1,4 @@ -import { emitDiagnostic } from '../utils/diagnostics.ts'; -import { sleep } from '../utils/timeouts.ts'; +import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; /** * Pure post-gesture stability mechanics: the quiet-window polling loop and the diff --git a/src/daemon/provider-lease-expiry.ts b/src/daemon/provider-lease-expiry.ts index 3fadb6780a..1ddc2f354e 100644 --- a/src/daemon/provider-lease-expiry.ts +++ b/src/daemon/provider-lease-expiry.ts @@ -5,10 +5,9 @@ import type { LeaseLifecycleProvider, ProviderExpiredLeaseRecovery, } from '@agent-device/contracts/device'; -import { publishFileSync } from '../utils/atomic-file.ts'; +import { publishFileSync } from '@agent-device/host-kit/fs'; import { releaseExpiredProviderLease } from './lease-lifecycle.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; -import { sleep } from '../utils/timeouts.ts'; +import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; const DEFAULT_RETRY_DELAY_MS = 1_000; const PENDING_RELEASES_FILE = 'expired-provider-leases.json'; diff --git a/src/daemon/recording-gestures.ts b/src/daemon/recording-gestures.ts index f3a150cb69..e5965f0b86 100644 --- a/src/daemon/recording-gestures.ts +++ b/src/daemon/recording-gestures.ts @@ -7,7 +7,7 @@ import { resolveGestureOffsetMs, resolveTapVisualizationOffsetMs, } from './recording-timing.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { DEFAULT_MOBILE_SCROLL_DURATION_MS } from '@agent-device/contracts/scroll-command'; import { type ScrollDirection, diff --git a/src/daemon/request-execution-locks.ts b/src/daemon/request-execution-locks.ts index 99f8c1e46b..b91c3b39a8 100644 --- a/src/daemon/request-execution-locks.ts +++ b/src/daemon/request-execution-locks.ts @@ -1,4 +1,4 @@ -import { withKeyedLock } from '../utils/keyed-lock.ts'; +import { withKeyedLock } from '@agent-device/kernel/keyed-lock'; import type { RequestExecutionLockKey } from './request-binding.ts'; type RetainedExecutionLock = { diff --git a/src/daemon/request-execution-scope.ts b/src/daemon/request-execution-scope.ts index a04a90e4c4..daffa3feb8 100644 --- a/src/daemon/request-execution-scope.ts +++ b/src/daemon/request-execution-scope.ts @@ -4,7 +4,7 @@ import { emitDiagnostic, getDiagnosticsMeta, updateDiagnosticsScope, -} from '../utils/diagnostics.ts'; +} from '@agent-device/host-kit/exec'; import { applyCommandDefaults } from '../cli-schema/command-schema.ts'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import { @@ -21,7 +21,7 @@ import { } from './lease-lifecycle.ts'; import { prepareLockedRequestBinding, resolveRequestExecutionLockKeys } from './request-binding.ts'; import { createRequestExecutionLocks } from './request-execution-locks.ts'; -import { throwIfRequestCanceled } from '../request/cancel.ts'; +import { throwIfRequestCanceled } from '@agent-device/host-kit/request'; import { finalizeDaemonResponse } from './request-finalization.ts'; import { refreshRecordingHealth } from './request-recording-health.ts'; import { diff --git a/src/daemon/request-finalization.ts b/src/daemon/request-finalization.ts index 962d6b904c..759fcb19ab 100644 --- a/src/daemon/request-finalization.ts +++ b/src/daemon/request-finalization.ts @@ -4,7 +4,7 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, getDiagnosticsMeta, -} from '../utils/diagnostics.ts'; +} from '@agent-device/host-kit/exec'; import type { DaemonRequest, DaemonResponse, DaemonResponseData } from './types.ts'; import type { DaemonArtifact, DaemonArtifactType } from '@agent-device/kernel/contracts'; diff --git a/src/daemon/request-lock-policy.ts b/src/daemon/request-lock-policy.ts index 093d5a9160..a1780895fd 100644 --- a/src/daemon/request-lock-policy.ts +++ b/src/daemon/request-lock-policy.ts @@ -13,7 +13,7 @@ import { type PlatformSelector, } from '@agent-device/kernel/device'; import { buildSessionRecoveryHint, describeSessionDevice } from './session-recovery-hints.ts'; -import { shellQuoteIfNeeded } from '../utils/shell-quote.ts'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; import { hasLockableDeviceSelector, hasSelectorValue } from './device-selector-intent.ts'; import { canOverrideLockPolicySelector } from './daemon-command-registry.ts'; diff --git a/src/daemon/request-router.ts b/src/daemon/request-router.ts index dc6f832216..8ab4107a16 100644 --- a/src/daemon/request-router.ts +++ b/src/daemon/request-router.ts @@ -29,7 +29,7 @@ import { getDiagnosticsMeta, registerDiagnosticSensitiveValue, withDiagnosticsScope, -} from '../utils/diagnostics.ts'; +} from '@agent-device/host-kit/exec'; import type { LeaseRegistry } from './lease-registry.ts'; import { loadGenericRequestHandlerModule, diff --git a/src/daemon/request-save-script-policy.ts b/src/daemon/request-save-script-policy.ts index 4f04cf2d77..f753e48e89 100644 --- a/src/daemon/request-save-script-policy.ts +++ b/src/daemon/request-save-script-policy.ts @@ -3,7 +3,7 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, getDiagnosticsMeta, -} from '../utils/diagnostics.ts'; +} from '@agent-device/host-kit/exec'; import { listSaveScriptFlagOwnerCommands, ownsSaveScriptFlag } from './daemon-command-registry.ts'; import type { DaemonRequest, DaemonResponse } from './types.ts'; diff --git a/src/daemon/resumable-upload-transfer.ts b/src/daemon/resumable-upload-transfer.ts index 37cd30eaa6..89cf12a95a 100644 --- a/src/daemon/resumable-upload-transfer.ts +++ b/src/daemon/resumable-upload-transfer.ts @@ -3,7 +3,7 @@ import crypto from 'node:crypto'; import type { IncomingMessage } from 'node:http'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { createByteLimitStream } from '../utils/byte-limit-stream.ts'; +import { createByteLimitStream } from '@agent-device/host-kit/fs'; import { parseUploadContentLength, parseUploadContentRange } from './resumable-upload-range.ts'; export type ResumableTransferEntry = { diff --git a/src/daemon/runtime-session.ts b/src/daemon/runtime-session.ts index 32591e984b..3a5ed184b6 100644 --- a/src/daemon/runtime-session.ts +++ b/src/daemon/runtime-session.ts @@ -1,5 +1,5 @@ import type { CommandSessionRecord, CommandSessionStore } from '../runtime-contract.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { SessionState } from './types.ts'; export type RuntimeSessionRecordOptions = { diff --git a/src/daemon/screenshot-overlay-draw.ts b/src/daemon/screenshot-overlay-draw.ts index 0d0b0ee115..1b01d56fc5 100644 --- a/src/daemon/screenshot-overlay-draw.ts +++ b/src/daemon/screenshot-overlay-draw.ts @@ -1,5 +1,5 @@ import type { Rect, ScreenshotOverlayRef } from '@agent-device/kernel/snapshot'; -import type { PNG } from '../utils/png.ts'; +import type { PNG } from '@agent-device/capture-kit/png'; import { clamp } from '../snapshot/screenshot-overlay/rects.ts'; /** diff --git a/src/daemon/screenshot-overlay.ts b/src/daemon/screenshot-overlay.ts index 1c835721b8..d3bf634722 100644 --- a/src/daemon/screenshot-overlay.ts +++ b/src/daemon/screenshot-overlay.ts @@ -6,7 +6,7 @@ import { type SnapshotNode, type SnapshotState, } from '@agent-device/kernel/snapshot'; -import { decodePngAsync, encodePngAsync } from '../utils/png-worker-client.ts'; +import { decodePngAsync, encodePngAsync } from '@agent-device/capture-kit/png-worker-client'; import { analyzeReactNativeOverlay } from '../core/react-native-overlay.ts'; import { findNearestAncestor, diff --git a/src/daemon/screenshot-runtime.ts b/src/daemon/screenshot-runtime.ts index 9d0ddee20e..0e05453eb5 100644 --- a/src/daemon/screenshot-runtime.ts +++ b/src/daemon/screenshot-runtime.ts @@ -17,7 +17,7 @@ import { createAgentDevice, localCommandPolicy } from '../runtime.ts'; import { assertSupportedScreenshotPixelDensity, readScreenshotResultMetadata, -} from '../utils/screenshot-density.ts'; +} from '@agent-device/capture-kit/screenshot-density'; import { runtimeExecutionFromContext } from './snapshot-runtime-capture-input.ts'; import type { DaemonCommandContext } from './context.ts'; import { captureSnapshotData } from './handlers/snapshot-capture.ts'; diff --git a/src/daemon/scroll-runtime.ts b/src/daemon/scroll-runtime.ts index ea83085513..c07c448417 100644 --- a/src/daemon/scroll-runtime.ts +++ b/src/daemon/scroll-runtime.ts @@ -22,7 +22,7 @@ import { type ScrollEdge, type ScrollEdgeState, } from '../utils/scroll-edge-state.ts'; -import { withSuccessText } from '../utils/success-text.ts'; +import { withSuccessText } from '@agent-device/host-kit/values'; import type { DaemonCommandContext } from './context.ts'; import { errorResponse } from './handlers/response.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; diff --git a/src/daemon/selector-capture-runtime.ts b/src/daemon/selector-capture-runtime.ts index 5f78cb2e70..f06747679d 100644 --- a/src/daemon/selector-capture-runtime.ts +++ b/src/daemon/selector-capture-runtime.ts @@ -5,7 +5,7 @@ import { snapshotPresentationOptionsFromFlags, type SnapshotState, } from '@agent-device/kernel/snapshot'; -import { isSparseSnapshotQualityVerdict } from '../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import type { DaemonRequest, SessionState } from './types.ts'; import { SessionStore } from './session-store.ts'; import { captureSnapshot } from './handlers/snapshot-capture.ts'; diff --git a/src/daemon/selector-runtime-backend.ts b/src/daemon/selector-runtime-backend.ts index 627c9f75bf..ced8d7fda6 100644 --- a/src/daemon/selector-runtime-backend.ts +++ b/src/daemon/selector-runtime-backend.ts @@ -27,7 +27,7 @@ import { import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from './request-runtime-binding.ts'; import type { AndroidObservationAdapter } from '@agent-device/contracts/android-observation'; import type { PlatformResourceCleanup } from '@agent-device/contracts/platform-resource-cleanup'; -import { getRequestSignal } from '../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { snapshotOptionsToFlags } from '../backend-snapshot-options.ts'; export type SelectorRuntimeParams = { diff --git a/src/daemon/server/daemon-idle-reap.ts b/src/daemon/server/daemon-idle-reap.ts index de7313badb..5f10fa03aa 100644 --- a/src/daemon/server/daemon-idle-reap.ts +++ b/src/daemon/server/daemon-idle-reap.ts @@ -1,4 +1,4 @@ -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { SessionStore } from '../session-store.ts'; import type { SessionState } from '../types.ts'; import { isUncommittedRepairSession } from '../session-replay-transaction.ts'; diff --git a/src/daemon/server/daemon-runtime-web-close-teardown.test.ts b/src/daemon/server/daemon-runtime-web-close-teardown.test.ts index 84f390a100..ac5bc02919 100644 --- a/src/daemon/server/daemon-runtime-web-close-teardown.test.ts +++ b/src/daemon/server/daemon-runtime-web-close-teardown.test.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import { afterEach, expect, test, vi } from 'vitest'; -vi.mock('../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); @@ -10,7 +10,7 @@ import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; import { WEB_DESKTOP_DEVICE } from '../../__tests__/test-utils/device-fixtures.ts'; import { AGENT_BROWSER_TIMEOUT_MS } from '../../platforms/web/agent-browser-provider.ts'; import { installFakeManagedAgentBrowser } from '../../platforms/web/__tests__/test-utils.ts'; -import { runCmd } from '../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { SessionStore } from '../session-store.ts'; import type { SessionState } from '../types.ts'; import { diff --git a/src/daemon/server/daemon-runtime.ts b/src/daemon/server/daemon-runtime.ts index c28c38fe1d..40e3ada5b6 100644 --- a/src/daemon/server/daemon-runtime.ts +++ b/src/daemon/server/daemon-runtime.ts @@ -35,8 +35,13 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, withDiagnosticsScope, -} from '../../utils/diagnostics.ts'; -import { isEnvTruthy } from '../../utils/retry.ts'; + isEnvTruthy, + sleep, + createOwnedProcessRecordStore, + type OwnedProcessRecordStore, + reapOwnedProcessRecordsAtStartup, +} from '@agent-device/host-kit/exec'; + import { acquireDaemonLock, parseIntegerEnv, @@ -53,8 +58,8 @@ import { listenNetServer, type DaemonServer, } from './transport.ts'; -import { prewarmPngWorker, terminatePngWorker } from '../../utils/png-worker-client.ts'; -import { sleep } from '../../utils/timeouts.ts'; +import { prewarmPngWorker, terminatePngWorker } from '@agent-device/capture-kit/png-worker-client'; + import { configureAppleRunnerLeaseOwnerStateDir } from '../../platform-runtime-apple-runner-owner.ts'; import { cleanupManagedWebRuntimeOrphans, @@ -70,11 +75,6 @@ import { createDaemonRecoveryPlatformScope } from '../platform-request-scope.ts' import { createAppLogAdmissionLedger } from '../app-log-admission-ledger.ts'; import { createAudioProbeAdmissionLedger } from '../audio-probe-admission-ledger.ts'; import { createScreenRecordingAdmissionLedger } from '../screen-recording-admission-ledger.ts'; -import { - createOwnedProcessRecordStore, - type OwnedProcessRecordStore, -} from '../../utils/owned-process-record.ts'; -import { reapOwnedProcessRecordsAtStartup } from '../../utils/owned-process-reaper.ts'; const DAEMON_SESSION_TEARDOWN_TIMEOUT_MS = 5_000; export const SCREEN_RECORDING_SESSION_TEARDOWN_BUDGET_MS = 11_000; diff --git a/src/daemon/server/daemon-session-lease-finalizer.ts b/src/daemon/server/daemon-session-lease-finalizer.ts index 4e48b10292..6aaca1937d 100644 --- a/src/daemon/server/daemon-session-lease-finalizer.ts +++ b/src/daemon/server/daemon-session-lease-finalizer.ts @@ -1,5 +1,5 @@ import { leaseScopeToReleaseRequest } from '../../core/lease-scope.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { ExpiredProviderLeaseReleaser } from '../provider-lease-expiry.ts'; import type { LeaseRegistry } from '../lease-registry.ts'; import type { SessionState } from '../types.ts'; diff --git a/src/daemon/server/daemon-shutdown-claims.ts b/src/daemon/server/daemon-shutdown-claims.ts index ffa7cb260f..ef6b0553a5 100644 --- a/src/daemon/server/daemon-shutdown-claims.ts +++ b/src/daemon/server/daemon-shutdown-claims.ts @@ -1,5 +1,5 @@ import { publicPlatformString } from '@agent-device/kernel/device'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { clearDeviceClaim, type DeviceClaimClearOutcome } from '../device-claims.ts'; import type { DeviceClaimRecord } from '../daemon-shutdown-report.ts'; import type { SessionState } from '../types.ts'; diff --git a/src/daemon/server/http-server.ts b/src/daemon/server/http-server.ts index cbac9a2056..4d35b9461d 100644 --- a/src/daemon/server/http-server.ts +++ b/src/daemon/server/http-server.ts @@ -6,7 +6,7 @@ import { toAppErrorCode, type DiagnosticsRecordRef, } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { timingSafeStringEqual } from '../../utils/timing-safe-equal.ts'; import type { CommandRpcParams, @@ -22,10 +22,11 @@ import { markRequestCanceled, registerRequestAbort, resolveRequestTrackingId, -} from '../../request/cancel.ts'; + withRequestProgressSink, +} from '@agent-device/host-kit/request'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { withRequestProgressSink } from '../../request/progress.ts'; + import { serializeDaemonProgressEnvelope, serializeDaemonRpcResponseEnvelope, diff --git a/src/daemon/server/server-lifecycle.ts b/src/daemon/server/server-lifecycle.ts index 911b0fc7ec..ba86f52321 100644 --- a/src/daemon/server/server-lifecycle.ts +++ b/src/daemon/server/server-lifecycle.ts @@ -1,8 +1,8 @@ import fs from 'node:fs'; import { isAgentDeviceDaemonProcess } from '../daemon-process.ts'; -export { readVersion } from '../../utils/version.ts'; -export { readProcessStartTime } from '../../utils/host-process.ts'; +export { readVersion } from '@agent-device/host-kit/values'; +export { readProcessStartTime } from '@agent-device/host-kit/exec'; export { resolveDaemonCodeSignature } from '../code-signature.ts'; export type DaemonLockInfo = { diff --git a/src/daemon/server/transport.ts b/src/daemon/server/transport.ts index d5cbe7595a..118a7cc4ae 100644 --- a/src/daemon/server/transport.ts +++ b/src/daemon/server/transport.ts @@ -8,10 +8,11 @@ import { markRequestCanceled, registerRequestAbort, resolveRequestTrackingId, -} from '../../request/cancel.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; + withRequestProgressSink, +} from '@agent-device/host-kit/request'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { consumeTextLines } from '../../utils/line-stream.ts'; -import { withRequestProgressSink } from '../../request/progress.ts'; + import { serializeDaemonProgressEnvelope, serializeDaemonResponseEnvelope, diff --git a/src/daemon/session-action-recorder.ts b/src/daemon/session-action-recorder.ts index 89f31ce4aa..20f2fdcfd6 100644 --- a/src/daemon/session-action-recorder.ts +++ b/src/daemon/session-action-recorder.ts @@ -1,7 +1,7 @@ import type { SessionAction } from '@agent-device/contracts/session'; import type { CommandFlags } from '@agent-device/contracts/command'; import { SCREENSHOT_ACTION_FLAG_KEYS } from '@agent-device/contracts/capture'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { DaemonRequest, SessionRuntimeHints, SessionState } from './types.ts'; import { applyRecordedSaveScriptFlags } from './session-script-publication-capability.ts'; import { repairSessionBoundary } from './session-replay-transaction.ts'; diff --git a/src/daemon/session-event-log-window.ts b/src/daemon/session-event-log-window.ts index 5ba5e73e86..b2f3e0acba 100644 --- a/src/daemon/session-event-log-window.ts +++ b/src/daemon/session-event-log-window.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; import { AppError } from '@agent-device/kernel/errors'; -import { isRecord } from '../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import { measureEventLogFile, readFirstLineDigest, diff --git a/src/daemon/session-event-log.ts b/src/daemon/session-event-log.ts index 09719b5e30..c33e74fe3d 100644 --- a/src/daemon/session-event-log.ts +++ b/src/daemon/session-event-log.ts @@ -4,8 +4,8 @@ import path from 'node:path'; import { PUBLIC_COMMANDS } from '../command-catalog.ts'; import { AppError } from '@agent-device/kernel/errors'; import { redactDiagnosticData } from '@agent-device/kernel/redaction'; -import { emitDiagnostic, getDiagnosticsMeta } from '../utils/diagnostics.ts'; -import { isRecord } from '../utils/parsing.ts'; +import { emitDiagnostic, getDiagnosticsMeta } from '@agent-device/host-kit/exec'; +import { isRecord } from '@agent-device/host-kit/values'; import type { DaemonRequest, DaemonResponse } from './types.ts'; import { buildActionDetails, buildActionSummary } from './session-event-action.ts'; import { buildRequestSuccessEventPresentation } from './session-event-request.ts'; diff --git a/src/daemon/session-event-request.ts b/src/daemon/session-event-request.ts index 55a0198d14..bd67cc98f8 100644 --- a/src/daemon/session-event-request.ts +++ b/src/daemon/session-event-request.ts @@ -1,5 +1,5 @@ import { PUBLIC_COMMANDS } from '../command-catalog.ts'; -import { isRecord } from '../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import type { DaemonRequest, DaemonResponseData } from './types.ts'; const EVENT_LIST_PREVIEW_LIMIT = 5; diff --git a/src/daemon/session-paths.ts b/src/daemon/session-paths.ts index 4ac0f3a765..3457272ba1 100644 --- a/src/daemon/session-paths.ts +++ b/src/daemon/session-paths.ts @@ -1,4 +1,4 @@ -import { resolveUserPath } from '../utils/path-resolution.ts'; +import { resolveUserPath } from '@agent-device/host-kit/fs'; export function safeSessionName(name: string): string { return name.replace(/[^a-zA-Z0-9._-]/g, '_'); diff --git a/src/daemon/session-recovery-hints.ts b/src/daemon/session-recovery-hints.ts index a0e7892780..63ba03fe04 100644 --- a/src/daemon/session-recovery-hints.ts +++ b/src/daemon/session-recovery-hints.ts @@ -1,5 +1,5 @@ import type { SessionRef, SessionState } from './types.ts'; -import { shellQuoteIfNeeded } from '../utils/shell-quote.ts'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; export type SessionRecoveryContext = 'device-in-use' | 'selector-conflict'; diff --git a/src/daemon/session-script-writer.ts b/src/daemon/session-script-writer.ts index 1eb5bbbf3f..46b8578e6d 100644 --- a/src/daemon/session-script-writer.ts +++ b/src/daemon/session-script-writer.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { publicPlatformString } from '@agent-device/kernel/device'; import { dragGesturePayloadFromPositionals } from '@agent-device/contracts/gesture-normalization'; import { inferFillText } from './action-utils.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; import { appendScriptSeriesFlags, @@ -17,7 +17,7 @@ import { stripRecordedRefGeneration, } from '@agent-device/ad-script'; import { expandSessionPath, safeSessionName } from './session-paths.ts'; -import { publishFileSync } from '../utils/atomic-file.ts'; +import { publishFileSync } from '@agent-device/host-kit/fs'; import type { SessionState } from './types.ts'; import { NO_SCRIPT_PUBLICATION, diff --git a/src/daemon/session-selector.ts b/src/daemon/session-selector.ts index cf646e439b..afae1916db 100644 --- a/src/daemon/session-selector.ts +++ b/src/daemon/session-selector.ts @@ -6,7 +6,7 @@ import { isSerialAddressablePlatform, matchesPlatformSelector, } from '@agent-device/kernel/device'; -import { parseSerialAllowlist } from '../utils/device-isolation.ts'; +import { parseSerialAllowlist } from '@agent-device/host-kit/fs'; import { buildSessionRecoveryHint, describeSessionDevice } from './session-recovery-hints.ts'; export type SessionSelectorConflictKey = diff --git a/src/daemon/session-store.ts b/src/daemon/session-store.ts index 24779e6c46..85df06b1a5 100644 --- a/src/daemon/session-store.ts +++ b/src/daemon/session-store.ts @@ -1,7 +1,7 @@ import path from 'node:path'; import fs from 'node:fs'; import { AppError, type DiagnosticsRecordRef } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { SessionRef, SessionRuntimeHints, SessionState } from './types.ts'; import { recordActionEntry, type RecordActionEntry } from './session-action-recorder.ts'; import { expandSessionPath, isSafeSessionSegment, safeSessionName } from './session-paths.ts'; @@ -16,7 +16,7 @@ import { type SessionScriptWriteOptions, type SessionScriptWriteResult, } from './session-script-writer.ts'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { appendActionEvent, appendSessionEvent, diff --git a/src/daemon/session-target-evidence.ts b/src/daemon/session-target-evidence.ts index c816216779..d7f1b5b638 100644 --- a/src/daemon/session-target-evidence.ts +++ b/src/daemon/session-target-evidence.ts @@ -21,7 +21,7 @@ */ import type { SnapshotNode } from '@agent-device/kernel/snapshot'; -import { resolveRectCenter } from '../utils/rect-center.ts'; +import { resolveRectCenter } from '@agent-device/kernel/rect-center'; import { findNearestScrollableContainer } from '../snapshot/snapshot-presentation/tree.ts'; import { classifyTargetBindingMatch, diff --git a/src/daemon/session-teardown.ts b/src/daemon/session-teardown.ts index 43a981608b..ca44e8baf1 100644 --- a/src/daemon/session-teardown.ts +++ b/src/daemon/session-teardown.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { cleanupRetainedMaterializedPathsForSession } from './materialized-path-registry.ts'; import type { SessionState } from './types.ts'; import type { SessionStore } from './session-store.ts'; diff --git a/src/daemon/snapshot-command-runtime.ts b/src/daemon/snapshot-command-runtime.ts index e8fd3007db..4f767e65e0 100644 --- a/src/daemon/snapshot-command-runtime.ts +++ b/src/daemon/snapshot-command-runtime.ts @@ -9,7 +9,7 @@ import { publicPlatformString } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import type { AgentDeviceBackend, BackendSnapshotResult } from '../backend.ts'; import { type CommandSessionRecord, createAgentDevice } from '../runtime.ts'; -import { getRequestSignal } from '../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import type { RuntimeAdmissionBindings } from './request-runtime-binding.ts'; import { maybeBuildAndroidSnapshotTimeoutFailure } from './android-snapshot-timeout-evidence.ts'; import { captureSnapshot } from './handlers/snapshot-capture.ts'; diff --git a/src/daemon/sparse-fallback-screenshot.ts b/src/daemon/sparse-fallback-screenshot.ts index e1f4effd45..b6a1bde400 100644 --- a/src/daemon/sparse-fallback-screenshot.ts +++ b/src/daemon/sparse-fallback-screenshot.ts @@ -1,5 +1,5 @@ import type { SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; -import { isSparseSnapshotQualityVerdict } from '../snapshot-quality/verdict.ts'; +import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { contextFromFlags } from './context.ts'; import { captureScreenshotArtifact } from './screenshot-runtime.ts'; import { diff --git a/src/daemon/touch-runtime.ts b/src/daemon/touch-runtime.ts index 02a9675802..c328f231f1 100644 --- a/src/daemon/touch-runtime.ts +++ b/src/daemon/touch-runtime.ts @@ -20,7 +20,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import type { Point } from '@agent-device/kernel/snapshot'; import { readFillBackendResult } from '../core/fill-backend-result.ts'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { requireIntInRange } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; import type { DirectIosSelectorTarget } from './direct-ios-selector.ts'; diff --git a/src/daemon/tv-remote-runtime.ts b/src/daemon/tv-remote-runtime.ts index 7f807f8e54..b0a74224a6 100644 --- a/src/daemon/tv-remote-runtime.ts +++ b/src/daemon/tv-remote-runtime.ts @@ -4,7 +4,7 @@ import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtim import { parseTvRemoteButton, type TvRemoteButton } from '@agent-device/contracts/tv-remote'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { requireIntInRange } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; diff --git a/src/daemon/type-text-runtime.ts b/src/daemon/type-text-runtime.ts index d1caf430ff..fcc68c566c 100644 --- a/src/daemon/type-text-runtime.ts +++ b/src/daemon/type-text-runtime.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/type-text-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '../utils/success-text.ts'; +import { successText } from '@agent-device/host-kit/values'; import { findMistargetedTypeRefToken } from '../utils/type-target-warning.ts'; import { requireIntInRange } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; diff --git a/src/daemon/wait-conditional-selector.ts b/src/daemon/wait-conditional-selector.ts index 2f1373a6a6..4381951a43 100644 --- a/src/daemon/wait-conditional-selector.ts +++ b/src/daemon/wait-conditional-selector.ts @@ -1,7 +1,7 @@ import type { FindSelectorRuntimeOperations } from '@agent-device/contracts/selector-observation-runtime'; import type { TargetAnnotationV1 } from '@agent-device/contracts/replay'; import { readSimpleSelectorTarget } from '@agent-device/selectors'; -import { getRequestSignal } from '../request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { buildRuntimeCaptureInput } from './snapshot-runtime-capture-input.ts'; import { recordIfSession, stripSelectorChain } from './selector-recording.ts'; import { isSessionRecording } from './session-script-publication-capability.ts'; diff --git a/src/mcp/command-tools.ts b/src/mcp/command-tools.ts index 130640d043..707abf2f4d 100644 --- a/src/mcp/command-tools.ts +++ b/src/mcp/command-tools.ts @@ -30,7 +30,7 @@ import { mcpToolConfigProperties, } from './tool-control-fields.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { isRecord } from '../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import { formatToolErrorText, normalizeToolError } from './tool-error.ts'; import { resolveMcpConfigDefaults } from './tool-input-config.ts'; import { projectStructuredContent } from './tool-result.ts'; diff --git a/src/mcp/protocol-era.ts b/src/mcp/protocol-era.ts index f21fa6d703..de01e534d2 100644 --- a/src/mcp/protocol-era.ts +++ b/src/mcp/protocol-era.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { readVersion } from '../utils/version.ts'; +import { readVersion } from '@agent-device/host-kit/values'; /** * MCP has two protocol eras, and agent-device serves both from one stdio process diff --git a/src/mcp/tool-ref-pins.ts b/src/mcp/tool-ref-pins.ts index e32d86fce2..9d54e947ce 100644 --- a/src/mcp/tool-ref-pins.ts +++ b/src/mcp/tool-ref-pins.ts @@ -6,7 +6,7 @@ import { commandDescriptors, commandSupportsSettleObservation, } from '../core/command-descriptor/registry.ts'; -import { asOptionalRecord } from '../utils/parsing.ts'; +import { asOptionalRecord } from '@agent-device/host-kit/values'; import { readElementMatchCandidateRefs } from '../utils/error-candidates.ts'; export type ToolRefPinStore = { diff --git a/src/metro/client-metro.ts b/src/metro/client-metro.ts index 9138e71f17..1c654d4290 100644 --- a/src/metro/client-metro.ts +++ b/src/metro/client-metro.ts @@ -10,7 +10,7 @@ import type { } from '@agent-device/contracts/remote'; import fs from 'node:fs'; import path from 'node:path'; -import { sleep } from '../utils/timeouts.ts'; +import { sleep, runCmdSync, runCmdDetached, waitForProcessExit } from '@agent-device/host-kit/exec'; import { ensureMetroCompanion } from './client-metro-companion.ts'; import type { MetroBridgeDescriptor, @@ -19,9 +19,9 @@ import type { MetroRuntimeHints, } from './metro-types.ts'; import { AppError, asAppError } from '@agent-device/kernel/errors'; -import { runCmdSync, runCmdDetached } from '../utils/exec.ts'; -import { resolveUserPath } from '../utils/path-resolution.ts'; -import { waitForProcessExit } from '../utils/host-process.ts'; + +import { resolveUserPath } from '@agent-device/host-kit/fs'; + import { detectProjectRuntimeKindFromPackageJson, readProjectPackageJson, diff --git a/src/platform-runtime-android-application-tools.ts b/src/platform-runtime-android-application-tools.ts index 83b34d19f7..279d8bb94a 100644 --- a/src/platform-runtime-android-application-tools.ts +++ b/src/platform-runtime-android-application-tools.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/application-lifecycle-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from './utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; /** Lazy Android tools; the Android package owns lifecycle sequencing and durable IME policy. */ export function createAndroidApplicationTools(): AndroidApplicationTools { diff --git a/src/platform-runtime-android-emulator-host.ts b/src/platform-runtime-android-emulator-host.ts index bb2cefc8de..651c62ba0b 100644 --- a/src/platform-runtime-android-emulator-host.ts +++ b/src/platform-runtime-android-emulator-host.ts @@ -1,7 +1,6 @@ import type { DeviceReadinessRuntimeHost } from '@agent-device/contracts/device-readiness-runtime'; import { listLocalDeviceInventory } from './request/device-inventory-context.ts'; -import { runCmdDetached } from './utils/exec.ts'; -import { stopPidsWithEscalation } from './utils/host-process.ts'; +import { runCmdDetached, stopPidsWithEscalation } from '@agent-device/host-kit/exec'; export function createAndroidEmulatorHost(): DeviceReadinessRuntimeHost['androidEmulator'] { return Object.freeze({ diff --git a/src/platform-runtime-app-log-process.test.ts b/src/platform-runtime-app-log-process.test.ts index e3754d8335..164eb6837f 100644 --- a/src/platform-runtime-app-log-process.test.ts +++ b/src/platform-runtime-app-log-process.test.ts @@ -12,8 +12,9 @@ const processIdentity = vi.hoisted(() => ({ startTime: 'Sun Aug 9 22:00:00 2026' as string | null, })); -vi.mock('./utils/exec.ts', () => ({ runCmdBackground: exec.run })); -vi.mock('./utils/host-process.ts', () => ({ +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), + runCmdBackground: exec.run, isProcessAlive: () => processIdentity.alive, readProcessCommand: () => processIdentity.command, readProcessStartTime: () => processIdentity.startTime, diff --git a/src/platform-runtime-app-log-process.ts b/src/platform-runtime-app-log-process.ts index 4731b2125e..96f73cc835 100644 --- a/src/platform-runtime-app-log-process.ts +++ b/src/platform-runtime-app-log-process.ts @@ -14,13 +14,14 @@ import { decodeAppLogProcessMarker } from '@agent-device/capture-kit'; import type { DeviceIdentity } from '@agent-device/kernel/device'; import fs from 'node:fs'; import path from 'node:path'; -import { runCmdBackground } from './utils/exec.ts'; import { + runCmdBackground, isProcessAlive, readProcessCommand, readProcessStartTime, waitForProcessExit, -} from './utils/host-process.ts'; +} from '@agent-device/host-kit/exec'; + import { requireManagedSessionArtifactPath } from './utils/managed-session-artifact-path.ts'; import { openVerifiedFileForRead } from './utils/verified-file.ts'; diff --git a/src/platform-runtime-apple-application-tools.ts b/src/platform-runtime-apple-application-tools.ts index 5fb90af790..422bd0b01b 100644 --- a/src/platform-runtime-apple-application-tools.ts +++ b/src/platform-runtime-apple-application-tools.ts @@ -38,7 +38,7 @@ export function createAppleApplicationTools(): AppleApplicationTools { ); }, prepareRunner: async (device, input, signal) => { - const { Deadline } = await import('./utils/retry.ts'); + const { Deadline } = await import('@agent-device/host-kit/exec'); const { prepareIosRunner } = await import('./platforms/apple/core/runner-client.ts'); const startedAtMs = Date.now(); return await prepareIosRunner(device, { diff --git a/src/platform-runtime-host.ts b/src/platform-runtime-host.ts index 80013fd0fb..4d69db41c9 100644 --- a/src/platform-runtime-host.ts +++ b/src/platform-runtime-host.ts @@ -11,7 +11,7 @@ import os from 'node:os'; import path from 'node:path'; import { createAppleToolHost } from './platform-runtime-apple-tool-host.ts'; import { createHostToolchainPreparer } from './platform-runtime-toolchain-host.ts'; -import { runCmd, whichCmd } from './utils/exec.ts'; +import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; export function createDeviceInventoryHost(): DeviceInventoryHost { return Object.freeze({ diff --git a/src/platform-runtime-operation-host.ts b/src/platform-runtime-operation-host.ts index 4941e8191b..088ed95845 100644 --- a/src/platform-runtime-operation-host.ts +++ b/src/platform-runtime-operation-host.ts @@ -9,7 +9,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { setTimeout as sleep } from 'node:timers/promises'; import { createAppleToolHost } from './platform-runtime-apple-tool-host.ts'; import { createHostToolchainPreparer } from './platform-runtime-toolchain-host.ts'; -import { runCmd, whichCmd } from './utils/exec.ts'; +import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; import { openAppLogOutput, readAppLogOutputTail } from './platform-runtime-app-log-output.ts'; import { createManagedAppLogProcesses } from './platform-runtime-app-log-process.ts'; import { createNetworkRuntimeHost } from './platform-runtime-network-host.ts'; diff --git a/src/platform-runtime-resource-cleanup.ts b/src/platform-runtime-resource-cleanup.ts index 9ab506936d..5b424ff5d1 100644 --- a/src/platform-runtime-resource-cleanup.ts +++ b/src/platform-runtime-resource-cleanup.ts @@ -1,8 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { isIosFamily } from '@agent-device/kernel/device'; import type { PlatformResourceCleanup } from '@agent-device/contracts/platform-resource-cleanup'; -import { emitDiagnostic } from './utils/diagnostics.ts'; -import type { OwnedProcessRecordStore } from './utils/owned-process-record.ts'; +import { emitDiagnostic, type OwnedProcessRecordStore } from '@agent-device/host-kit/exec'; /** Focused durable-resource cleanup composed above daemon policy and concrete platforms. */ export async function resetAndroidSnapshotHelperRuntime(): Promise { diff --git a/src/platform-runtime-runtime-hints.ts b/src/platform-runtime-runtime-hints.ts index 5f7a4b96eb..5bde522d02 100644 --- a/src/platform-runtime-runtime-hints.ts +++ b/src/platform-runtime-runtime-hints.ts @@ -2,7 +2,7 @@ import { isIosFamily, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError, asAppError } from '@agent-device/kernel/errors'; import { escapeXmlTextAndAttribute } from '@agent-device/xml'; import type { RuntimeHintValues } from '@agent-device/contracts/application-lifecycle-runtime'; -import { execFailureDetails, type ExecResult } from './utils/exec.ts'; +import { execFailureDetails, type ExecResult } from '@agent-device/host-kit/exec'; import { type ResolvedRuntimeTransport } from './utils/runtime-transport.ts'; // React Native's PackagerConnectionSettings/DevInternalSettings read debug_http_host via diff --git a/src/platform-runtime-screen-recording-android-host.ts b/src/platform-runtime-screen-recording-android-host.ts index 101b9ee2c2..301088dd5a 100644 --- a/src/platform-runtime-screen-recording-android-host.ts +++ b/src/platform-runtime-screen-recording-android-host.ts @@ -4,7 +4,7 @@ import type { AndroidScreenRecordingTransport, } from '@agent-device/contracts/screen-recording-runtime-host'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { shellQuote } from './utils/shell-quote.ts'; +import { shellQuote } from '@agent-device/host-kit/exec'; import { isPlayableVideo } from './utils/video.ts'; const ANDROID_MANIFEST_NAME = 'agent-device-recording-active.json'; diff --git a/src/platform-runtime-screen-recording-apple-runner-transport.ts b/src/platform-runtime-screen-recording-apple-runner-transport.ts index 9f3ffd8efc..fadb4e26ef 100644 --- a/src/platform-runtime-screen-recording-apple-runner-transport.ts +++ b/src/platform-runtime-screen-recording-apple-runner-transport.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import type { ManagedProcessOwnership } from '@agent-device/contracts/platform-runtime-host'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { createScopedProvider } from './utils/scoped-provider.ts'; -import { isProcessAlive } from './utils/host-process.ts'; +import { createScopedProvider } from '@agent-device/host-kit/values'; +import { isProcessAlive } from '@agent-device/host-kit/exec'; type AppleRunnerScreenRecordingStartRequest = Readonly<{ device: DeviceInfo; diff --git a/src/platform-runtime-screen-recording-apple-simulator-host.test.ts b/src/platform-runtime-screen-recording-apple-simulator-host.test.ts index bc27e916df..647e62dd25 100644 --- a/src/platform-runtime-screen-recording-apple-simulator-host.test.ts +++ b/src/platform-runtime-screen-recording-apple-simulator-host.test.ts @@ -12,8 +12,8 @@ const processes = vi.hoisted(() => ({ commands: new Map(), })); -vi.mock('./utils/host-process.ts', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: (pid: number) => processes.alive.get(pid) ?? false, isProcessZombie: () => false, readProcessStartTime: (pid: number) => processes.starts.get(pid) ?? null, diff --git a/src/platform-runtime-screen-recording-apple-transport.ts b/src/platform-runtime-screen-recording-apple-transport.ts index 391adad738..35e3b88fcd 100644 --- a/src/platform-runtime-screen-recording-apple-transport.ts +++ b/src/platform-runtime-screen-recording-apple-transport.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; -import type { ExecBackgroundResult, ExecResult } from './utils/exec.ts'; -import { createScopedProvider } from './utils/scoped-provider.ts'; +import type { ExecBackgroundResult, ExecResult } from '@agent-device/host-kit/exec'; +import { createScopedProvider } from '@agent-device/host-kit/values'; export type AppleSimulatorScreenRecordingProcess = Readonly<{ child: Pick; @@ -27,7 +27,7 @@ const localTransport: AppleSimulatorScreenRecordingTransport = Object.freeze({ async start({ device, outputPath, signal }) { const [{ buildSimctlArgsForDevice }, { runCmdBackground }] = await Promise.all([ import('./platforms/apple/core/simctl.ts'), - import('./utils/exec.ts'), + import('@agent-device/host-kit/exec'), ]); signal?.throwIfAborted(); return runCmdBackground( diff --git a/src/platform-runtime-screen-recording-process-host.test.ts b/src/platform-runtime-screen-recording-process-host.test.ts index 323bafff52..28b39282b0 100644 --- a/src/platform-runtime-screen-recording-process-host.test.ts +++ b/src/platform-runtime-screen-recording-process-host.test.ts @@ -11,8 +11,8 @@ const state = vi.hoisted(() => ({ signaled: [] as Array<{ pids: readonly number[]; signal: NodeJS.Signals }>, })); -vi.mock('./utils/host-process.ts', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: (pid: number) => state.alive.get(pid) ?? false, isProcessZombie: () => false, readProcessStartTime: (pid: number) => state.starts.get(pid) ?? null, diff --git a/src/platform-runtime-screen-recording-process-host.ts b/src/platform-runtime-screen-recording-process-host.ts index caf76d2b9e..265c8ac520 100644 --- a/src/platform-runtime-screen-recording-process-host.ts +++ b/src/platform-runtime-screen-recording-process-host.ts @@ -12,7 +12,7 @@ import { readProcessStartTime, signalPidsBestEffort, waitForProcessExit, -} from './utils/host-process.ts'; +} from '@agent-device/host-kit/exec'; const STOP_TIMEOUT_MS = 5_000; const FORCE_STOP_TIMEOUT_MS = 2_000; diff --git a/src/platform-runtime/request-providers.ts b/src/platform-runtime/request-providers.ts index c4c43b6f3e..27370725fd 100644 --- a/src/platform-runtime/request-providers.ts +++ b/src/platform-runtime/request-providers.ts @@ -16,7 +16,7 @@ import type { VegaToolProvider } from '../platforms/vega/tool-provider.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { AppleSimulatorScreenRecordingTransport } from '../platform-runtime-screen-recording-apple-transport.ts'; import type { AppleRunnerScreenRecordingTransport } from '../platform-runtime-screen-recording-apple-runner-transport.ts'; -import type { OwnedProcessRecordStore } from '../utils/owned-process-record.ts'; +import type { OwnedProcessRecordStore } from '@agent-device/host-kit/exec'; import { tryGetPlugin } from '../core/platform-plugin-registry.ts'; import { registerBuiltinPlatformPlugins } from '../core/interactors/register-builtins.ts'; diff --git a/src/platforms/__tests__/install-source.test.ts b/src/platforms/__tests__/install-source.test.ts index b439d9693c..bfcf0684a3 100644 --- a/src/platforms/__tests__/install-source.test.ts +++ b/src/platforms/__tests__/install-source.test.ts @@ -6,7 +6,7 @@ import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { Readable } from 'node:stream'; -import { runCmdSync, withCommandExecutorOverride } from '../../utils/exec.ts'; +import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { ARCHIVE_EXTENSIONS, isTrustedInstallSourceUrl, diff --git a/src/platforms/android/__tests__/adb-executor.test.ts b/src/platforms/android/__tests__/adb-executor.test.ts index 2b5b2cbda7..c3ea20ef07 100644 --- a/src/platforms/android/__tests__/adb-executor.test.ts +++ b/src/platforms/android/__tests__/adb-executor.test.ts @@ -8,8 +8,8 @@ const { runCmdBackgroundMock } = vi.hoisted(() => ({ })), })); -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async () => ({ stdout: 'ok', stderr: '', exitCode: 0 })), @@ -32,7 +32,7 @@ import { withAndroidAdbProvider, type AndroidAdbProvider, } from '../adb-executor.ts'; -import { runCmd, runCmdBackground } from '../../../utils/exec.ts'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/android/__tests__/adb-provider-scope.test.ts b/src/platforms/android/__tests__/adb-provider-scope.test.ts index ffe7b31fa2..ad619d25cf 100644 --- a/src/platforms/android/__tests__/adb-provider-scope.test.ts +++ b/src/platforms/android/__tests__/adb-provider-scope.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 { runCmd } from '../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { withAndroidAdbProvider } from '../adb-executor.ts'; import { mkdtempForTestSync } from '../../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/platforms/android/__tests__/device-input-state.test.ts b/src/platforms/android/__tests__/device-input-state.test.ts index 8f47d0aa3c..42fa3f8191 100644 --- a/src/platforms/android/__tests__/device-input-state.test.ts +++ b/src/platforms/android/__tests__/device-input-state.test.ts @@ -10,7 +10,7 @@ import { readAndroidClipboardWithAdb, writeAndroidClipboardWithAdb, } from '../device-input-state.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '../../../utils/diagnostics.ts'; +import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { assertRejectsAppError } from '../../../__tests__/test-utils/app-error.ts'; import { withFakeAdb } from '../../../__tests__/test-utils/fake-adb.ts'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/platforms/android/__tests__/emulator-lifecycle.test.ts b/src/platforms/android/__tests__/emulator-lifecycle.test.ts index 9777495438..156e253761 100644 --- a/src/platforms/android/__tests__/emulator-lifecycle.test.ts +++ b/src/platforms/android/__tests__/emulator-lifecycle.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import { beforeEach, test, vi } from 'vitest'; import type { DeviceInfo } from '@agent-device/kernel/device'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), @@ -13,7 +13,7 @@ vi.mock('../../../utils/exec.ts', async (importOriginal) => { }); vi.mock('../sdk.ts', () => ({ ensureAndroidSdkPathConfigured: vi.fn(async () => {}) })); -import { runCmd, runCmdDetached, whichCmd } from '../../../utils/exec.ts'; +import { runCmd, runCmdDetached, whichCmd } from '@agent-device/host-kit/exec'; import { ensureAndroidEmulatorBooted } from '../emulator-lifecycle.ts'; const stopped: DeviceInfo = { diff --git a/src/platforms/android/__tests__/ime-helper-security.test.ts b/src/platforms/android/__tests__/ime-helper-security.test.ts index d5ee182e38..94986f1cc9 100644 --- a/src/platforms/android/__tests__/ime-helper-security.test.ts +++ b/src/platforms/android/__tests__/ime-helper-security.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; -import { findProjectRoot } from '../../../utils/version.ts'; +import { findProjectRoot } from '@agent-device/host-kit/values'; // Security guard for #1201: the text-injection broadcast receiver must require a sender permission // that only adb shell / privileged callers hold, so a co-installed third-party app cannot inject diff --git a/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts b/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts index c861d4244d..8eb91cd8aa 100644 --- a/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts +++ b/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts @@ -24,8 +24,8 @@ import { isAndroidSnapshotTimeoutError } from '../../../snapshot/snapshot-timeou * value it publishes. Split out of `snapshot.test.ts`, which is over the file-size tripwire. */ -vi.mock('../../../utils/exec.ts', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ + ...(await importOriginal()), runCmd: vi.fn(), })); diff --git a/src/platforms/android/__tests__/snapshot-clickability.test.ts b/src/platforms/android/__tests__/snapshot-clickability.test.ts index 1086ac69eb..598497a69e 100644 --- a/src/platforms/android/__tests__/snapshot-clickability.test.ts +++ b/src/platforms/android/__tests__/snapshot-clickability.test.ts @@ -15,8 +15,8 @@ import { resetAndroidSnapshotHelperInstallCache } from '../snapshot-helper-insta import { resetAndroidSnapshotHelperSessions } from '../snapshot-helper-session-lifecycle.ts'; import { androidSnapshotPublicationInput } from '../snapshot-capture.ts'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../adb.ts', async (importOriginal) => { diff --git a/src/platforms/android/__tests__/snapshot-helper-session.test.ts b/src/platforms/android/__tests__/snapshot-helper-session.test.ts index abde725aa7..39ea7a456a 100644 --- a/src/platforms/android/__tests__/snapshot-helper-session.test.ts +++ b/src/platforms/android/__tests__/snapshot-helper-session.test.ts @@ -10,7 +10,7 @@ import { import path from 'node:path'; import { promises as fs } from 'node:fs'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; -import { withDiagnosticsScope } from '../../../utils/diagnostics.ts'; +import { withDiagnosticsScope } from '@agent-device/host-kit/exec'; beforeEach(async () => { await resetAndroidSnapshotHelperSessions(); diff --git a/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts b/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts index af5ab174e3..89e0cc5d20 100644 --- a/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts +++ b/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts @@ -16,8 +16,8 @@ import { isAndroidHelperRuntimeForceStop, } from './snapshot-helper-session.fixtures.ts'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../adb.ts', async (importOriginal) => { diff --git a/src/platforms/android/__tests__/snapshot.test.ts b/src/platforms/android/__tests__/snapshot.test.ts index 04f8557627..07c41243a7 100644 --- a/src/platforms/android/__tests__/snapshot.test.ts +++ b/src/platforms/android/__tests__/snapshot.test.ts @@ -5,8 +5,8 @@ import os from 'node:os'; import path from 'node:path'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../adb.ts', async (importOriginal) => { @@ -19,9 +19,9 @@ import { snapshotAndroid } from '../snapshot.ts'; import { readAndroidGestureViewport } from '../touch-executor.ts'; import { buildUiHierarchySnapshot, parseUiHierarchyTree } from '../ui-hierarchy.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '../../../utils/diagnostics.ts'; +import * as diagnosticsModule from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { sleep } from '../adb.ts'; import { resetAndroidSnapshotHelperInstallCache } from '../snapshot-helper-install.ts'; import { resetAndroidSnapshotHelperSessions } from '../snapshot-helper-session-lifecycle.ts'; @@ -282,13 +282,13 @@ function isAndroidSdkVersionCommand(args: string[]): boolean { } async function captureDiagnostics( - scope: Parameters[0], + scope: Parameters[0], callback: () => Promise, ): Promise { const previousHome = process.env.HOME; process.env.HOME = await mkdtempForTest('agent-device-android-diag-'); try { - const diagnosticsPath = await withDiagnosticsScope(scope, callback); + const diagnosticsPath = await diagnosticsModule.withDiagnosticsScope(scope, callback); assert.ok(diagnosticsPath); return await fs.readFile(diagnosticsPath, 'utf8'); } finally { @@ -412,7 +412,7 @@ test('snapshotAndroid emits helper phase diagnostics', async () => { helperAdb, helperArtifact, }); - return flushDiagnosticsToSessionFile({ force: true })?.path ?? null; + return diagnosticsModule.flushDiagnosticsToSessionFile({ force: true })?.path ?? null; }, ); @@ -938,7 +938,7 @@ test('snapshotAndroid emits helper failure diagnostics', async () => { return true; }, ); - return flushDiagnosticsToSessionFile({ force: true })?.path ?? null; + return diagnosticsModule.flushDiagnosticsToSessionFile({ force: true })?.path ?? null; }, ); @@ -962,7 +962,7 @@ test('snapshotAndroid emits unavailable diagnostics when helper artifact is miss () => snapshotAndroid(device), /Android snapshot helper is unavailable/, ); - return flushDiagnosticsToSessionFile({ force: true })?.path ?? null; + return diagnosticsModule.flushDiagnosticsToSessionFile({ force: true })?.path ?? null; }, ); @@ -1066,7 +1066,7 @@ test('snapshotAndroid emits timeout diagnostics when helper capture times out', () => snapshotAndroidWithHelper(helperAdb), /Android snapshot helper failed: helper capture timed out/, ); - return flushDiagnosticsToSessionFile({ force: true })?.path ?? null; + return diagnosticsModule.flushDiagnosticsToSessionFile({ force: true })?.path ?? null; }, ); diff --git a/src/platforms/android/__tests__/text-input-test-ime.test.ts b/src/platforms/android/__tests__/text-input-test-ime.test.ts index c3a5da9a4d..b0ae70551f 100644 --- a/src/platforms/android/__tests__/text-input-test-ime.test.ts +++ b/src/platforms/android/__tests__/text-input-test-ime.test.ts @@ -32,7 +32,7 @@ vi.mock('@agent-device/platform-android/ime-helper', async (importOriginal) => { import fs from 'node:fs/promises'; import { ANDROID_EMULATOR } from '../../../__tests__/test-utils/device-fixtures.ts'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '../../../utils/diagnostics.ts'; +import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '@agent-device/host-kit/exec'; import { ANDROID_SNAPSHOT_HELPER_FIXTURE_ARTIFACT, createAndroidSnapshotHelperExecutor, diff --git a/src/platforms/android/adb-host-binding.ts b/src/platforms/android/adb-host-binding.ts index ca03424fc9..019a992498 100644 --- a/src/platforms/android/adb-host-binding.ts +++ b/src/platforms/android/adb-host-binding.ts @@ -6,8 +6,9 @@ import { runCmdBackground, withCommandExecutorOverride, withoutCommandExecutorOverride, -} from '../../utils/exec.ts'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; + emitDiagnostic, +} from '@agent-device/host-kit/exec'; + import { clearAndroidTestImeRecoveryMarker, readAndroidTestImeRecoveryMarkers, diff --git a/src/platforms/android/adb.ts b/src/platforms/android/adb.ts index fac14c2097..272273c3c6 100644 --- a/src/platforms/android/adb.ts +++ b/src/platforms/android/adb.ts @@ -5,7 +5,7 @@ import { type AndroidAdbExecutorResult, } from './adb-executor.ts'; -export { sleep } from '../../utils/timeouts.ts'; +export { sleep } from '@agent-device/host-kit/exec'; export async function runAndroidAdb( device: DeviceInfo, diff --git a/src/platforms/android/alert-detection.ts b/src/platforms/android/alert-detection.ts index 053c106e30..23b70429a4 100644 --- a/src/platforms/android/alert-detection.ts +++ b/src/platforms/android/alert-detection.ts @@ -1,6 +1,6 @@ import { centerOfRect, type RawSnapshotNode } from '@agent-device/kernel/snapshot'; import type { AlertInfo, AlertSource } from '@agent-device/contracts/alert-contract'; -import { isSnapshotNodeInteractionBlocked } from '../../snapshot/snapshot-occlusion.ts'; +import { isSnapshotNodeInteractionBlocked } from '@agent-device/capture-kit/snapshot-occlusion'; type AndroidAlertButtonRole = 'accept' | 'dismiss' | 'neutral'; diff --git a/src/platforms/android/alert.ts b/src/platforms/android/alert.ts index 56f7249cd5..cba84ceb3b 100644 --- a/src/platforms/android/alert.ts +++ b/src/platforms/android/alert.ts @@ -5,9 +5,9 @@ import { DEFAULT_ALERT_TIMEOUT_MS, } from '@agent-device/contracts/alert-contract'; import { AppError } from '@agent-device/kernel/errors'; -import { withDiagnosticTimer } from '../../utils/diagnostics.ts'; -import { successText } from '../../utils/success-text.ts'; -import { sleep } from '../../utils/timeouts.ts'; +import { withDiagnosticTimer, sleep } from '@agent-device/host-kit/exec'; +import { successText } from '@agent-device/host-kit/values'; + import type { DeviceInfo } from '@agent-device/kernel/device'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { diff --git a/src/platforms/android/app-deployment.ts b/src/platforms/android/app-deployment.ts index 47f5233181..01c342d30f 100644 --- a/src/platforms/android/app-deployment.ts +++ b/src/platforms/android/app-deployment.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { resolveFileOverridePath, runCmd, whichCmd } from '../../utils/exec.ts'; +import { resolveFileOverridePath, runCmd, whichCmd } from '@agent-device/host-kit/exec'; import { waitForAndroidBoot } from './emulator-lifecycle.ts'; import { installAndroidAdbPackage, resolveAndroidAdbProvider } from './adb-executor.ts'; import { withAndroidAppResolutionCacheInvalidated } from './app-deployment-resolution.ts'; diff --git a/src/platforms/android/app-lifecycle.ts b/src/platforms/android/app-lifecycle.ts index d0265d23d5..6e32045bc8 100644 --- a/src/platforms/android/app-lifecycle.ts +++ b/src/platforms/android/app-lifecycle.ts @@ -1,10 +1,10 @@ import { AppError } from '@agent-device/kernel/errors'; import type { AppStateRuntimeResult } from '@agent-device/contracts/app-state-runtime'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep, shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; import type { AppsFilter } from '@agent-device/contracts/device'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { isDeepLinkTarget } from '@agent-device/contracts/command'; -import { shellQuoteIfNeeded } from '../../utils/shell-quote.ts'; + import { waitForAndroidBoot } from './emulator-lifecycle.ts'; import { runAndroidAdb } from './adb.ts'; import { diff --git a/src/platforms/android/device-input-state.ts b/src/platforms/android/device-input-state.ts index 45bade05a3..09551fae5a 100644 --- a/src/platforms/android/device-input-state.ts +++ b/src/platforms/android/device-input-state.ts @@ -1,7 +1,7 @@ -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic, shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { shellQuoteIfNeeded } from '../../utils/shell-quote.ts'; + import { isClipboardShellUnsupported, sleep } from './adb.ts'; import { androidAdbResultError, diff --git a/src/platforms/android/emulator-lifecycle.ts b/src/platforms/android/emulator-lifecycle.ts index 4499fce026..d848cc4287 100644 --- a/src/platforms/android/emulator-lifecycle.ts +++ b/src/platforms/android/emulator-lifecycle.ts @@ -1,11 +1,17 @@ import type { DeviceInventoryRequest } from '@agent-device/contracts/device'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError, asAppError } from '@agent-device/kernel/errors'; -import type { ExecResult } from '../../utils/exec.ts'; -import { runCmdDetached, whichCmd } from '../../utils/exec.ts'; +import { + type ExecResult, + runCmdDetached, + whichCmd, + Deadline, + retryWithPolicy, + sleep, +} from '@agent-device/host-kit/exec'; + import { runAndroidHostAdb } from './adb-executor.ts'; -import { Deadline, retryWithPolicy } from '../../utils/retry.ts'; -import { sleep } from '../../utils/timeouts.ts'; + import { bootFailureHint, classifyBootFailure } from '../boot-diagnostics.ts'; import { ensureAndroidSdkPathConfigured } from './sdk.ts'; diff --git a/src/platforms/android/fill-verification.ts b/src/platforms/android/fill-verification.ts index d452aa0974..7267f22d9d 100644 --- a/src/platforms/android/fill-verification.ts +++ b/src/platforms/android/fill-verification.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { containsPoint } from '@agent-device/kernel/rect'; import { buildFillFailureDetails, diff --git a/src/platforms/android/helper-package-install.ts b/src/platforms/android/helper-package-install.ts index a16a6f3fce..3c82b06aec 100644 --- a/src/platforms/android/helper-package-install.ts +++ b/src/platforms/android/helper-package-install.ts @@ -3,7 +3,7 @@ import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { findProjectRoot, readVersion } from '../../utils/version.ts'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; // The package subpath (not the root shim) breaks the module cycle the shim route would create: // the adb-host binding reaches this file for the helper port facets, and the shim imports that // binding. Allowed by the transitional #2041 R13 table. diff --git a/src/platforms/android/ime-recovery-marker.ts b/src/platforms/android/ime-recovery-marker.ts index fea7bcd558..b021bb578d 100644 --- a/src/platforms/android/ime-recovery-marker.ts +++ b/src/platforms/android/ime-recovery-marker.ts @@ -2,7 +2,7 @@ import fs from 'node:fs/promises'; import { randomUUID } from 'node:crypto'; import path from 'node:path'; import { normalizeError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; // Device-scoped pending-recovery markers, one file per switched device, in the daemon state dir. // The marker is separate from IME mechanics so startup can establish evidence before it loads the diff --git a/src/platforms/android/manifest.ts b/src/platforms/android/manifest.ts index 650f22c7e1..f040a92355 100644 --- a/src/platforms/android/manifest.ts +++ b/src/platforms/android/manifest.ts @@ -1,7 +1,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import { TextDecoder } from 'node:util'; -import { isExecutablePath, runCmd } from '../../utils/exec.ts'; +import { isExecutablePath, runCmd } from '@agent-device/host-kit/exec'; import { resolveAndroidSdkRoots } from './sdk.ts'; const RES_XML_TYPE = 0x0003; diff --git a/src/platforms/android/perf-native-artifacts.ts b/src/platforms/android/perf-native-artifacts.ts index 831edc3f11..c9eb89d7fe 100644 --- a/src/platforms/android/perf-native-artifacts.ts +++ b/src/platforms/android/perf-native-artifacts.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import { resolveAndroidAdbExecutor, type AndroidAdbExecutor } from './adb-executor.ts'; import { annotateAndroidNativePerfError } from './perf-native-errors.ts'; import { buildAndroidNativePerfStopSummary } from './perf-native-summary.ts'; diff --git a/src/platforms/android/perf-native-report.ts b/src/platforms/android/perf-native-report.ts index 20ee674245..476378819f 100644 --- a/src/platforms/android/perf-native-report.ts +++ b/src/platforms/android/perf-native-report.ts @@ -1,4 +1,4 @@ -import { splitNonEmptyTrimmedLines } from '../../utils/parsing.ts'; +import { splitNonEmptyTrimmedLines } from '@agent-device/host-kit/values'; import { roundPercent } from '../perf-utils.ts'; const SIMPLEPERF_REPORT_ARTIFACT_ENTRY_LIMIT = 50; diff --git a/src/platforms/android/perf.ts b/src/platforms/android/perf.ts index ec46f81867..2d008833bf 100644 --- a/src/platforms/android/perf.ts +++ b/src/platforms/android/perf.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { requireExecSuccess } from '../../utils/exec.ts'; +import { requireExecSuccess } from '@agent-device/host-kit/exec'; import { androidAdbResultError, resolveAndroidAdbExecutor, diff --git a/src/platforms/android/settings.ts b/src/platforms/android/settings.ts index b4b7825ccf..803565a155 100644 --- a/src/platforms/android/settings.ts +++ b/src/platforms/android/settings.ts @@ -1,6 +1,6 @@ import { AppError } from '@agent-device/kernel/errors'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { requireLocationCoordinates } from '../../utils/location-coordinates.ts'; +import { requireLocationCoordinates } from '@agent-device/host-kit/values'; import { summarizeCommandAttemptFailures, type CommandAttemptFailure, diff --git a/src/platforms/android/snapshot-helper-capture.ts b/src/platforms/android/snapshot-helper-capture.ts index 7c7eef446c..6a8464082d 100644 --- a/src/platforms/android/snapshot-helper-capture.ts +++ b/src/platforms/android/snapshot-helper-capture.ts @@ -4,7 +4,7 @@ import { androidCaptureFailureReasonFromExitCode, androidCaptureFailureReasonFromHelperResult, } from './snapshot-capture-failure-reason.ts'; -import { execFailureDetails } from '../../utils/exec.ts'; +import { execFailureDetails } from '@agent-device/host-kit/exec'; import { parseInstrumentationRecords, readInstrumentationResultBoolean, diff --git a/src/platforms/android/snapshot-helper-runtime.ts b/src/platforms/android/snapshot-helper-runtime.ts index 3a7bf1397b..58127637c7 100644 --- a/src/platforms/android/snapshot-helper-runtime.ts +++ b/src/platforms/android/snapshot-helper-runtime.ts @@ -1,5 +1,5 @@ import { normalizeError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { sleep } from './adb.ts'; import type { AndroidAdbExecutor } from './adb-executor.ts'; import { stopAndroidSnapshotHelperSession } from './snapshot-helper-session-lifecycle.ts'; diff --git a/src/platforms/android/snapshot-helper-session-lifecycle.ts b/src/platforms/android/snapshot-helper-session-lifecycle.ts index f01b6d6040..5bd48edd0b 100644 --- a/src/platforms/android/snapshot-helper-session-lifecycle.ts +++ b/src/platforms/android/snapshot-helper-session-lifecycle.ts @@ -9,7 +9,7 @@ import type { AndroidAdbProcess } from './adb-executor.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { androidAdbForwardsDeviceExitStatus, resetAndroidAdbShellProtocolProbes, diff --git a/src/platforms/android/snapshot-helper-session.ts b/src/platforms/android/snapshot-helper-session.ts index 4718a61203..960277f722 100644 --- a/src/platforms/android/snapshot-helper-session.ts +++ b/src/platforms/android/snapshot-helper-session.ts @@ -4,7 +4,7 @@ * `snapshot-helper-session-lifecycle.ts`, which this module acquires through. */ import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { readAndroidCaptureFailureReason } from '@agent-device/contracts/android-snapshot-quality'; import type { AndroidSnapshotHelperCaptureOptions, diff --git a/src/platforms/android/snapshot.ts b/src/platforms/android/snapshot.ts index b4a875616f..2b2e99610e 100644 --- a/src/platforms/android/snapshot.ts +++ b/src/platforms/android/snapshot.ts @@ -6,16 +6,16 @@ import { toAppErrorCode, type NormalizedError, } from '@agent-device/kernel/errors'; -import { emitDiagnostic, withDiagnosticTimer } from '../../utils/diagnostics.ts'; +import { emitDiagnostic, withDiagnosticTimer } from '@agent-device/host-kit/exec'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { findProjectRoot, readVersion } from '../../utils/version.ts'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; import { attachRefs, type HiddenContentHint, type RawSnapshotNode, type SnapshotOptions, } from '@agent-device/kernel/snapshot'; -import { deriveMobileSnapshotHiddenContentHints } from '../../snapshot/mobile-snapshot-semantics.ts'; +import { deriveMobileSnapshotHiddenContentHints } from '@agent-device/capture-kit/mobile-snapshot-semantics'; import { buildUiHierarchySnapshot, parseUiHierarchyTree, diff --git a/src/platforms/android/text-input.ts b/src/platforms/android/text-input.ts index 9c26ec6ce3..11a3e115c9 100644 --- a/src/platforms/android/text-input.ts +++ b/src/platforms/android/text-input.ts @@ -7,8 +7,8 @@ import type { FillUnconfirmedVerification } from '@agent-device/contracts/interactor-types'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; -import { shellQuoteIfNeeded } from '../../utils/shell-quote.ts'; +import { emitDiagnostic, shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; + import { resolveAndroidAdbExecutor, resolveAndroidAdbProvider, diff --git a/src/platforms/android/touch-helper.ts b/src/platforms/android/touch-helper.ts index 9bd1ac8272..8cb7e1695c 100644 --- a/src/platforms/android/touch-helper.ts +++ b/src/platforms/android/touch-helper.ts @@ -2,8 +2,12 @@ import type { PointerTrajectory } from '@agent-device/contracts/gesture-plan-typ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Rect } from '@agent-device/kernel/snapshot'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails } from '../../utils/exec.ts'; -import { emitDiagnostic, withDiagnosticTimer } from '../../utils/diagnostics.ts'; +import { + execFailureDetails, + emitDiagnostic, + withDiagnosticTimer, +} from '@agent-device/host-kit/exec'; + import { resolveAndroidAdbProvider, type AndroidAdbExecutor, diff --git a/src/platforms/apple/alert.ts b/src/platforms/apple/alert.ts index 2d2adec8d4..e8a9bbc26c 100644 --- a/src/platforms/apple/alert.ts +++ b/src/platforms/apple/alert.ts @@ -11,7 +11,7 @@ import type { } from '@agent-device/contracts/interactor-types'; import { isIosFamily, isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import { runAppleRunnerCommand } from './core/runner-client.ts'; import { runMacOsAlertAction } from './os/macos/helper.ts'; diff --git a/src/platforms/apple/core/__tests__/app-launch-url.test.ts b/src/platforms/apple/core/__tests__/app-launch-url.test.ts index a94e3c586a..3f58a07838 100644 --- a/src/platforms/apple/core/__tests__/app-launch-url.test.ts +++ b/src/platforms/apple/core/__tests__/app-launch-url.test.ts @@ -3,8 +3,8 @@ import assert from 'node:assert/strict'; import { IOS_TEST_SIMULATOR } from './apple-core-stub-helpers.ts'; import { IOS_SIMULATOR_TERMINATE_TIMEOUT_MS } from '../config.ts'; -vi.mock('../../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd) }; }); vi.mock('../simulator.ts', async (importOriginal) => { @@ -12,7 +12,7 @@ vi.mock('../simulator.ts', async (importOriginal) => { return { ...actual, ensureBootedSimulator: vi.fn(actual.ensureBootedSimulator) }; }); -import { runCmd } from '../../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { ensureBootedSimulator } from '../simulator.ts'; import { openIosApp } from '../app-launch.ts'; diff --git a/src/platforms/apple/core/__tests__/apps.test.ts b/src/platforms/apple/core/__tests__/apps.test.ts index 30a00fe675..10c2cbd371 100644 --- a/src/platforms/apple/core/__tests__/apps.test.ts +++ b/src/platforms/apple/core/__tests__/apps.test.ts @@ -4,24 +4,24 @@ import { promises as fs, readFileSync, writeFileSync } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); - return { ...actual, runCmd: vi.fn(actual.runCmd) }; -}); -vi.mock('../../../../utils/retry.ts', async (importOriginal) => { - const actual = await importOriginal(); - return { ...actual, retryWithPolicy: vi.fn(actual.retryWithPolicy) }; +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + runCmd: vi.fn(actual.runCmd), + retryWithPolicy: vi.fn(actual.retryWithPolicy), + }; }); vi.mock('../simulator.ts', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, ensureBootedSimulator: vi.fn(actual.ensureBootedSimulator) }; }); -const execActual = await vi.importActual( - '../../../../utils/exec.ts', +const execActual = await vi.importActual( + '@agent-device/host-kit/exec', ); -const retryActual = await vi.importActual( - '../../../../utils/retry.ts', +const retryActual = await vi.importActual( + '@agent-device/host-kit/exec', ); const simulatorActual = await vi.importActual('../simulator.ts'); @@ -42,9 +42,9 @@ import { ensureBootedSimulator } from '../simulator.ts'; import { IOS_DEVICE_INSTALL_TIMEOUT_MS, IOS_SIMULATOR_TERMINATE_TIMEOUT_MS } from '../config.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../../../../utils/exec.ts'; -import { retryWithPolicy } from '../../../../utils/retry.ts'; -import { PNG } from '../../../../utils/png.ts'; +import { runCmd, retryWithPolicy } from '@agent-device/host-kit/exec'; + +import { PNG } from '@agent-device/capture-kit/png'; import { assertRejectsAppError } from '../../../../__tests__/test-utils/app-error.ts'; import { withFakeAppleTool, diff --git a/src/platforms/apple/core/__tests__/debug-symbols.test.ts b/src/platforms/apple/core/__tests__/debug-symbols.test.ts index 18d07fc6f3..33c153cd77 100644 --- a/src/platforms/apple/core/__tests__/debug-symbols.test.ts +++ b/src/platforms/apple/core/__tests__/debug-symbols.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { test } from 'vitest'; import { symbolicateCrashArtifact } from '../debug-symbols.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { withCommandExecutorOverride } from '../../../../utils/exec.ts'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; const UUID = 'ABCDEFAB-CDEF-ABCD-EFAB-CDEFABCDEFAB'; diff --git a/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts b/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts index b33d6f1ed1..58b2f71933 100644 --- a/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts +++ b/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts @@ -1,6 +1,6 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '../../../../utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; export async function createZipFixture( archivePath: string, diff --git a/src/platforms/apple/core/__tests__/perf.test.ts b/src/platforms/apple/core/__tests__/perf.test.ts index 069bce8920..b0ed3dc6e3 100644 --- a/src/platforms/apple/core/__tests__/perf.test.ts +++ b/src/platforms/apple/core/__tests__/perf.test.ts @@ -4,8 +4,8 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd), @@ -27,7 +27,7 @@ import { type AppleXctracePerfCapture, } from '../perf-xctrace.ts'; import { parseAppleFramePerfSample } from '../perf-frame.ts'; -import { runCmd, runCmdBackground } from '../../../../utils/exec.ts'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/platforms/apple/core/__tests__/plist.test.ts b/src/platforms/apple/core/__tests__/plist.test.ts index 7b808332d6..df9bfee358 100644 --- a/src/platforms/apple/core/__tests__/plist.test.ts +++ b/src/platforms/apple/core/__tests__/plist.test.ts @@ -4,12 +4,12 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd) }; }); -import { runCmd } from '../../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { readInfoPlistString } from '../plist.ts'; import { createLocalAppleToolProvider, withAppleToolProvider } from '../tool-provider.ts'; diff --git a/src/platforms/apple/core/__tests__/screenshot-density.test.ts b/src/platforms/apple/core/__tests__/screenshot-density.test.ts index 7857bf923a..7b77d40d24 100644 --- a/src/platforms/apple/core/__tests__/screenshot-density.test.ts +++ b/src/platforms/apple/core/__tests__/screenshot-density.test.ts @@ -3,7 +3,7 @@ import assert from 'node:assert/strict'; import { promises as fs } from 'node:fs'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { PNG } from '../../../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { screenshotIos } from '../screenshot.ts'; import { createLocalAppleToolProvider, withAppleToolProvider } from '../tool-provider.ts'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/platforms/apple/core/__tests__/screenshot.test.ts b/src/platforms/apple/core/__tests__/screenshot.test.ts index 0cebc6ed50..fd2d38f9d6 100644 --- a/src/platforms/apple/core/__tests__/screenshot.test.ts +++ b/src/platforms/apple/core/__tests__/screenshot.test.ts @@ -4,13 +4,13 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); - return { ...actual, runCmd: vi.fn(actual.runCmd) }; -}); -vi.mock('../../../../utils/retry.ts', async (importOriginal) => { - const actual = await importOriginal(); - return { ...actual, retryWithPolicy: vi.fn(actual.retryWithPolicy) }; +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); + return { + ...actual, + runCmd: vi.fn(actual.runCmd), + retryWithPolicy: vi.fn(actual.retryWithPolicy), + }; }); vi.mock('../runner-client.ts', async (importOriginal) => { const actual = await importOriginal(); @@ -32,11 +32,11 @@ vi.mock('../screenshot-status-bar.ts', async (importOriginal) => { }; }); -const execActual = await vi.importActual( - '../../../../utils/exec.ts', +const execActual = await vi.importActual( + '@agent-device/host-kit/exec', ); -const retryActual = await vi.importActual( - '../../../../utils/retry.ts', +const retryActual = await vi.importActual( + '@agent-device/host-kit/exec', ); const runnerActual = await vi.importActual('../runner-client.ts'); @@ -55,10 +55,9 @@ import { import { ensureBootedSimulator, openIosSimulatorApp } from '../simulator.ts'; import { prepareSimulatorStatusBarForScreenshot } from '../screenshot-status-bar.ts'; import { runAppleRunnerCommand } from '../runner-client.ts'; -import { withDiagnosticsScope } from '../../../../utils/diagnostics.ts'; +import { withDiagnosticsScope, runCmd, retryWithPolicy } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../../../../utils/exec.ts'; -import { retryWithPolicy } from '../../../../utils/retry.ts'; + import { IOS_TEST_SIMULATOR, MACOS_TEST_DEVICE } from './apple-core-stub-helpers.ts'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/apple/core/__tests__/simulator.test.ts b/src/platforms/apple/core/__tests__/simulator.test.ts index 719589d6df..596e90f9bf 100644 --- a/src/platforms/apple/core/__tests__/simulator.test.ts +++ b/src/platforms/apple/core/__tests__/simulator.test.ts @@ -3,16 +3,16 @@ import assert from 'node:assert/strict'; import { ensureBootedSimulator, openIosSimulatorApp } from '../simulator.ts'; import { IOS_SIMULATOR_FOCUS_TIMEOUT_MS } from '../config.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { IOS_TEST_SIMULATOR } from './apple-core-stub-helpers.ts'; -vi.mock('../../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd) }; }); -const execActual = await vi.importActual( - '../../../../utils/exec.ts', +const execActual = await vi.importActual( + '@agent-device/host-kit/exec', ); const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/apple/core/app-device-io.ts b/src/platforms/apple/core/app-device-io.ts index 531bea8ea6..e3c6283b5e 100644 --- a/src/platforms/apple/core/app-device-io.ts +++ b/src/platforms/apple/core/app-device-io.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; -import { requireExecSuccess } from '../../../utils/exec.ts'; +import { requireExecSuccess } from '@agent-device/host-kit/exec'; import { ensureBootedSimulator, requireSimulatorDevice } from './simulator.ts'; import { readMacOsClipboardText, writeMacOsClipboardText } from '../os/macos/apps.ts'; import { runSimctl } from './apps-simctl.ts'; diff --git a/src/platforms/apple/core/app-launch.ts b/src/platforms/apple/core/app-launch.ts index f41b49493e..9708aeefdc 100644 --- a/src/platforms/apple/core/app-launch.ts +++ b/src/platforms/apple/core/app-launch.ts @@ -2,13 +2,18 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { isIosFamily, isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../../utils/diagnostics.ts'; -import { execFailureDetails } from '../../../utils/exec.ts'; +import { + emitDiagnostic, + execFailureDetails, + Deadline, + retryWithPolicy, +} from '@agent-device/host-kit/exec'; + import { LAUNCH_CONSOLE_DIRECT_APP_ONLY_MESSAGE, LAUNCH_CONSOLE_IOS_SIMULATOR_ONLY_MESSAGE, } from '@agent-device/contracts/observability'; -import { Deadline, retryWithPolicy } from '../../../utils/retry.ts'; + import { isDeepLinkTarget, isWebUrl, diff --git a/src/platforms/apple/core/app-resolution.ts b/src/platforms/apple/core/app-resolution.ts index 2d90abd294..103fa1ea22 100644 --- a/src/platforms/apple/core/app-resolution.ts +++ b/src/platforms/apple/core/app-resolution.ts @@ -14,7 +14,7 @@ import { listMacApps, resolveMacOsApp } from '../os/macos/apps.ts'; import { runAppleToolCommand } from './tool-provider.ts'; import { runSimctl } from './apps-simctl.ts'; import { resolveIosPhysicalDeviceControl } from './physical-device-control.ts'; -import { createTtlMemo } from '../../../utils/ttl-memo.ts'; +import { createTtlMemo } from '@agent-device/host-kit/values'; const ALIASES: Record = { settings: 'com.apple.Preferences', diff --git a/src/platforms/apple/core/app-settings.ts b/src/platforms/apple/core/app-settings.ts index f0da0d061e..232afd0db5 100644 --- a/src/platforms/apple/core/app-settings.ts +++ b/src/platforms/apple/core/app-settings.ts @@ -8,9 +8,9 @@ import { isIosFamily, isMacOs, type DeviceInfo } from '@agent-device/kernel/devi import { AppError } from '@agent-device/kernel/errors'; import { promises as fs } from 'node:fs'; import path from 'node:path'; -import { resolveIosSimulatorDeviceSetPath } from '../../../utils/device-isolation.ts'; -import { requireExecSuccess } from '../../../utils/exec.ts'; -import { requireLocationCoordinates } from '../../../utils/location-coordinates.ts'; +import { resolveIosSimulatorDeviceSetPath } from '@agent-device/host-kit/fs'; +import { requireExecSuccess } from '@agent-device/host-kit/exec'; +import { requireLocationCoordinates } from '@agent-device/host-kit/values'; import { parseAppearanceAction } from '../../appearance.ts'; import { summarizeCommandAttemptFailures, diff --git a/src/platforms/apple/core/debug-symbols/crash-artifact.ts b/src/platforms/apple/core/debug-symbols/crash-artifact.ts index a22c4d3785..2d78d6133c 100644 --- a/src/platforms/apple/core/debug-symbols/crash-artifact.ts +++ b/src/platforms/apple/core/debug-symbols/crash-artifact.ts @@ -1,5 +1,5 @@ import path from 'node:path'; -import { isRecord } from '../../../../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import type { AppleImage, CrashArtifact, diff --git a/src/platforms/apple/core/debug-symbols/dsym.ts b/src/platforms/apple/core/debug-symbols/dsym.ts index 331727ace8..dae648b66d 100644 --- a/src/platforms/apple/core/debug-symbols/dsym.ts +++ b/src/platforms/apple/core/debug-symbols/dsym.ts @@ -2,7 +2,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import type { AppleImage, DsymMatch, DsymSlice } from './types.ts'; import { normalizeUuid, unique } from './utils.ts'; -import { requireExecSuccess, runCmd } from '../../../../utils/exec.ts'; +import { requireExecSuccess, runCmd } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; const MAX_SEARCH_ENTRIES = 10_000; diff --git a/src/platforms/apple/core/debug-symbols/report.ts b/src/platforms/apple/core/debug-symbols/report.ts index cee0016b2b..69c22aaef0 100644 --- a/src/platforms/apple/core/debug-symbols/report.ts +++ b/src/platforms/apple/core/debug-symbols/report.ts @@ -9,7 +9,7 @@ import type { DebugSymbolsCrashFrame, DebugSymbolsCrashSummary, } from '@agent-device/contracts/observability'; -import { isRecord } from '../../../../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; import { addressKey, compactJoin, diff --git a/src/platforms/apple/core/debug-symbols/symbolication.ts b/src/platforms/apple/core/debug-symbols/symbolication.ts index 1045b703b1..e97eb9aa84 100644 --- a/src/platforms/apple/core/debug-symbols/symbolication.ts +++ b/src/platforms/apple/core/debug-symbols/symbolication.ts @@ -1,6 +1,6 @@ import type { DsymMatch, SymbolicatedAddress, SymbolicationGroup } from './types.ts'; import { addressKey, hex, unique } from './utils.ts'; -import { requireExecSuccess, runCmd } from '../../../../utils/exec.ts'; +import { requireExecSuccess, runCmd } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; export async function symbolicateAddresses( diff --git a/src/platforms/apple/core/debug-symbols/utils.ts b/src/platforms/apple/core/debug-symbols/utils.ts index bba3ab3eda..90aa18e289 100644 --- a/src/platforms/apple/core/debug-symbols/utils.ts +++ b/src/platforms/apple/core/debug-symbols/utils.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { isRecord } from '../../../../utils/parsing.ts'; +import { isRecord } from '@agent-device/host-kit/values'; const UUID_RE = /^[0-9a-fA-F-]{32,36}$/; diff --git a/src/platforms/apple/core/devicectl.ts b/src/platforms/apple/core/devicectl.ts index 729ecea93a..3beb31afaa 100644 --- a/src/platforms/apple/core/devicectl.ts +++ b/src/platforms/apple/core/devicectl.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails } from '../../../utils/exec.ts'; +import { execFailureDetails } from '@agent-device/host-kit/exec'; import { IOS_DEVICECTL_TIMEOUT_MS } from './config.ts'; import { runXcrun } from './tool-provider.ts'; diff --git a/src/platforms/apple/core/install-artifact.ts b/src/platforms/apple/core/install-artifact.ts index db3caa9d5d..3c78f1057e 100644 --- a/src/platforms/apple/core/install-artifact.ts +++ b/src/platforms/apple/core/install-artifact.ts @@ -4,8 +4,8 @@ import path from 'node:path'; import type { LocalInstallSource } from '@agent-device/kernel/contracts'; import { readInfoPlistString } from './plist.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { extractArchiveSafely } from '../../../utils/archive-extraction.ts'; -import { ArchiveBudget } from '../../../utils/archive-safety.ts'; +import { extractArchiveSafely, ArchiveBudget } from '@agent-device/host-kit/fs'; + import { installArtifactArchiveBudget, installArtifactArchiveDepth, diff --git a/src/platforms/apple/core/perf-xctrace.ts b/src/platforms/apple/core/perf-xctrace.ts index 69ed0ee081..1fac412d50 100644 --- a/src/platforms/apple/core/perf-xctrace.ts +++ b/src/platforms/apple/core/perf-xctrace.ts @@ -17,7 +17,7 @@ import { runCmdBackground, type ExecBackgroundResult, type ExecResult, -} from '../../../utils/exec.ts'; +} from '@agent-device/host-kit/exec'; import { uniqueStrings } from '@agent-device/kernel/collections'; import { findAllXmlNodes } from './perf-xml.ts'; import { diff --git a/src/platforms/apple/core/perf.ts b/src/platforms/apple/core/perf.ts index 5d9d4ccf0f..56a045dd90 100644 --- a/src/platforms/apple/core/perf.ts +++ b/src/platforms/apple/core/perf.ts @@ -11,8 +11,12 @@ import { } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import { parseXmlDocumentSync, type XmlNode } from '@agent-device/xml'; -import { execFailureDetails, requireExecSuccess, type ExecResult } from '../../../utils/exec.ts'; -import { splitNonEmptyTrimmedLines } from '../../../utils/parsing.ts'; +import { + execFailureDetails, + requireExecSuccess, + type ExecResult, +} from '@agent-device/host-kit/exec'; +import { splitNonEmptyTrimmedLines } from '@agent-device/host-kit/values'; import { uniqueStrings } from '@agent-device/kernel/collections'; import { IOS_DEVICECTL_DEFAULT_HINT, resolveIosDevicectlHint } from './devicectl.ts'; import type { IosDeviceProcessInfo } from './app-info.ts'; @@ -36,9 +40,7 @@ import { const APPLE_MEMORY_SAMPLE_METHOD = 'ps-process-snapshot'; const IOS_DEVICE_MEMORY_SAMPLE_METHOD = 'xctrace-activity-monitor'; -export const APPLE_MEMGRAPH_SNAPSHOT_METHOD = 'leaks-output-graph'; -export const APPLE_MEMGRAPH_SNAPSHOT_DESCRIPTION = - 'Memory graph captured with leaks --outputGraph for host-visible Apple app processes.'; +const APPLE_MEMGRAPH_SNAPSHOT_METHOD = 'leaks-output-graph'; const APPLE_PERF_TIMEOUT_MS = 15_000; const APPLE_MEMORY_SNAPSHOT_TIMEOUT_MS = 120_000; diff --git a/src/platforms/apple/core/physical-device-control.ts b/src/platforms/apple/core/physical-device-control.ts index c96492d045..ecf59dc6e3 100644 --- a/src/platforms/apple/core/physical-device-control.ts +++ b/src/platforms/apple/core/physical-device-control.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails } from '../../../utils/exec.ts'; +import { execFailureDetails } from '@agent-device/host-kit/exec'; import type { AppsFilter } from '@agent-device/contracts/device'; import type { IosAppInfo, IosDeviceAppProcesses } from './app-info.ts'; import { diff --git a/src/platforms/apple/core/physical-device-coredevice.ts b/src/platforms/apple/core/physical-device-coredevice.ts index 1051f3ea8a..849051a5ec 100644 --- a/src/platforms/apple/core/physical-device-coredevice.ts +++ b/src/platforms/apple/core/physical-device-coredevice.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails } from '../../../utils/exec.ts'; +import { execFailureDetails } from '@agent-device/host-kit/exec'; import { IOS_DEVICECTL_DEFAULT_HINT, resolveIosDevicectlHint, diff --git a/src/platforms/apple/core/physical-device-files.ts b/src/platforms/apple/core/physical-device-files.ts index af9d93bdff..1397ec2be4 100644 --- a/src/platforms/apple/core/physical-device-files.ts +++ b/src/platforms/apple/core/physical-device-files.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { Deadline } from '../../../utils/retry.ts'; +import { Deadline } from '@agent-device/host-kit/exec'; import { IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS } from './config.ts'; import { IOS_RUNNER_CONTAINER_BUNDLE_IDS } from '@agent-device/platform-apple/runner'; import { runXcrun } from './tool-provider.ts'; diff --git a/src/platforms/apple/core/physical-device-screenshot.ts b/src/platforms/apple/core/physical-device-screenshot.ts index 7d3aef96d6..03bc5fd831 100644 --- a/src/platforms/apple/core/physical-device-screenshot.ts +++ b/src/platforms/apple/core/physical-device-screenshot.ts @@ -1,7 +1,7 @@ import { promises as fs } from 'node:fs'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { runIosDevicectl } from './devicectl.ts'; import { copyCoreDeviceRunnerFile } from './physical-device-files.ts'; import type { diff --git a/src/platforms/apple/core/runner-host.ts b/src/platforms/apple/core/runner-host.ts index 30e6560e87..6025a6e016 100644 --- a/src/platforms/apple/core/runner-host.ts +++ b/src/platforms/apple/core/runner-host.ts @@ -1,31 +1,45 @@ import type { AppleRunnerHost } from '@agent-device/platform-apple/runner'; -import { publishFileSync } from '../../../utils/atomic-file.ts'; -import { resolveIosSimulatorDeviceSetPath } from '../../../utils/device-isolation.ts'; -import { emitDiagnostic, withDiagnosticTimer } from '../../../utils/diagnostics.ts'; import { + publishFileSync, + resolveIosSimulatorDeviceSetPath, + acquireProcessLock, +} from '@agent-device/host-kit/fs'; + +import { + emitDiagnostic, + withDiagnosticTimer, requireExecSuccess, runCmdBackground, runCmdStreaming, runCmdSync, -} from '../../../utils/exec.ts'; -import { isProcessAlive, isProcessGroupAlive, readProcessCommand, readProcessStartTime, signalPidsBestEffort, signalProcessGroupBestEffort, -} from '../../../utils/host-process.ts'; -import { withKeyedLock } from '../../../utils/keyed-lock.ts'; -import { classifyOwnerLiveness } from '../../../utils/owner-identity.ts'; -import { isRecord } from '../../../utils/parsing.ts'; -import { acquireProcessLock } from '../../../utils/process-lock.ts'; -import { Deadline, isEnvTruthy, retryWithPolicy } from '../../../utils/retry.ts'; -import { parseBooleanLiteral } from '../../../utils/source-value.ts'; -import { createTtlMemo } from '../../../utils/ttl-memo.ts'; -import { findProjectRoot, readVersion } from '../../../utils/version.ts'; -import { getRequestSignal, isRequestCanceled } from '../../../request/cancel.ts'; -import { emitRequestProgress } from '../../../request/progress.ts'; + classifyOwnerLiveness, + Deadline, + isEnvTruthy, + retryWithPolicy, +} from '@agent-device/host-kit/exec'; + +import { withKeyedLock } from '@agent-device/kernel/keyed-lock'; + +import { + isRecord, + parseBooleanLiteral, + createTtlMemo, + findProjectRoot, + readVersion, +} from '@agent-device/host-kit/values'; + +import { + getRequestSignal, + isRequestCanceled, + emitRequestProgress, +} from '@agent-device/host-kit/request'; + import { bootFailureHint, classifyBootFailure } from '../../boot-diagnostics.ts'; import { resolveIosPhysicalDeviceControl } from './physical-device-control.ts'; import { visitXmlPlistEntries } from './plist-xml.ts'; diff --git a/src/platforms/apple/core/screenshot-status-bar.ts b/src/platforms/apple/core/screenshot-status-bar.ts index 096a0de42f..5805d1792f 100644 --- a/src/platforms/apple/core/screenshot-status-bar.ts +++ b/src/platforms/apple/core/screenshot-status-bar.ts @@ -1,7 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; -import { emitDiagnostic } from '../../../utils/diagnostics.ts'; +import { emitDiagnostic, requireExecSuccess, type ExecOptions } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; -import { requireExecSuccess, type ExecOptions } from '../../../utils/exec.ts'; + import { runSimctlForDevice } from './simctl.ts'; import { extractAppleToolErrorMeta } from './tool-diagnostics.ts'; diff --git a/src/platforms/apple/core/screenshot.ts b/src/platforms/apple/core/screenshot.ts index e749ebf8f6..115f03cf14 100644 --- a/src/platforms/apple/core/screenshot.ts +++ b/src/platforms/apple/core/screenshot.ts @@ -1,13 +1,17 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; -import { emitDiagnostic } from '../../../utils/diagnostics.ts'; +import { + emitDiagnostic, + type ExecOptions, + Deadline, + retryWithPolicy, +} from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; -import type { ExecOptions } from '../../../utils/exec.ts'; -import { resizePngFile } from '../../../utils/png-resize.ts'; -import { readPngSize } from '../../../utils/png-size.ts'; -import { computeDensityScaledScreenshotSize } from '../../../utils/screenshot-density.ts'; -import { Deadline, retryWithPolicy } from '../../../utils/retry.ts'; + +import { resizePngFile } from '@agent-device/capture-kit/png-resize'; +import { readPngSize } from '@agent-device/capture-kit/png-size'; +import { computeDensityScaledScreenshotSize } from '@agent-device/capture-kit/screenshot-density'; import { IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS, diff --git a/src/platforms/apple/core/simctl.ts b/src/platforms/apple/core/simctl.ts index 91c2052f49..3dcf9ac425 100644 --- a/src/platforms/apple/core/simctl.ts +++ b/src/platforms/apple/core/simctl.ts @@ -1,6 +1,6 @@ import { isIosFamily, type DeviceInfo } from '@agent-device/kernel/device'; -import type { ExecOptions, ExecResult } from '../../../utils/exec.ts'; -import { resolveIosSimulatorDeviceSetPath } from '../../../utils/device-isolation.ts'; +import type { ExecOptions, ExecResult } from '@agent-device/host-kit/exec'; +import { resolveIosSimulatorDeviceSetPath } from '@agent-device/host-kit/fs'; import { runXcrun } from './tool-provider.ts'; type SimctlArgsOptions = { diff --git a/src/platforms/apple/core/simulator.ts b/src/platforms/apple/core/simulator.ts index 1f5d1170c7..610f0ca3c2 100644 --- a/src/platforms/apple/core/simulator.ts +++ b/src/platforms/apple/core/simulator.ts @@ -1,8 +1,13 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails, requireExecSuccess } from '../../../utils/exec.ts'; -import { Deadline, retryWithPolicy } from '../../../utils/retry.ts'; -import { createTtlMemo } from '../../../utils/ttl-memo.ts'; +import { + execFailureDetails, + requireExecSuccess, + Deadline, + retryWithPolicy, +} from '@agent-device/host-kit/exec'; + +import { createTtlMemo } from '@agent-device/host-kit/values'; import { bootFailureHint, classifyBootFailure } from '../../boot-diagnostics.ts'; import { @@ -10,7 +15,7 @@ import { IOS_SIMCTL_LIST_TIMEOUT_MS, IOS_SIMULATOR_FOCUS_TIMEOUT_MS, } from './config.ts'; -import { buildSimctlArgs, buildSimctlArgsForDevice } from './simctl.ts'; +import { buildSimctlArgsForDevice } from './simctl.ts'; import { runAppleToolCommand, runXcrun } from './tool-provider.ts'; const IOS_SIMULATOR_HOST_APPS = ['Simulator'] as const; @@ -235,15 +240,8 @@ export async function shutdownSimulator( }; } -export async function getSimulatorState( - deviceOrUdid: DeviceInfo | string, - signal?: AbortSignal, -): Promise { - const udid = typeof deviceOrUdid === 'string' ? deviceOrUdid : deviceOrUdid.id; - const simctlArgs = - typeof deviceOrUdid === 'string' - ? buildSimctlArgs(['list', 'devices', '-j']) - : buildSimctlArgsForDevice(deviceOrUdid, ['list', 'devices', '-j']); +async function getSimulatorState(device: DeviceInfo, signal?: AbortSignal): Promise { + const simctlArgs = buildSimctlArgsForDevice(device, ['list', 'devices', '-j']); const result = await runXcrun(simctlArgs, { allowFailure: true, signal, @@ -257,7 +255,7 @@ export async function getSimulatorState( }; for (const runtime of Object.values(payload.devices ?? {})) { - const match = runtime.find((entry) => entry.udid === udid); + const match = runtime.find((entry) => entry.udid === device.id); if (match) return match.state; } return null; diff --git a/src/platforms/apple/core/tool-provider-types.ts b/src/platforms/apple/core/tool-provider-types.ts index 7c4b499ddb..f1ed6d095a 100644 --- a/src/platforms/apple/core/tool-provider-types.ts +++ b/src/platforms/apple/core/tool-provider-types.ts @@ -1,5 +1,5 @@ import type { AppsFilter } from '@agent-device/contracts/device'; -import type { ExecOptions, ExecResult } from '../../../utils/exec.ts'; +import type { ExecOptions, ExecResult } from '@agent-device/host-kit/exec'; import type { IosAppInfo } from './app-info.ts'; export type AppleToolCommandExecutor = ( diff --git a/src/platforms/apple/core/tool-provider.ts b/src/platforms/apple/core/tool-provider.ts index e98bbc8315..96b97b4eda 100644 --- a/src/platforms/apple/core/tool-provider.ts +++ b/src/platforms/apple/core/tool-provider.ts @@ -4,8 +4,8 @@ import { whichCmd, type ExecOptions, type ExecResult, -} from '../../../utils/exec.ts'; -import { createScopedProvider } from '../../../utils/scoped-provider.ts'; +} from '@agent-device/host-kit/exec'; +import { createScopedProvider } from '@agent-device/host-kit/values'; import { createLocalAppleMacOsHostProvider } from '../os/macos/host-provider.ts'; import type { AppleMacOsHelperProvider, diff --git a/src/platforms/apple/interactor.ts b/src/platforms/apple/interactor.ts index f47d7d5ee2..38617ebb96 100644 --- a/src/platforms/apple/interactor.ts +++ b/src/platforms/apple/interactor.ts @@ -23,10 +23,10 @@ import { toAppleTvRemoteButton } from '@agent-device/contracts/tv-remote'; import type { SessionSurface } from '@agent-device/contracts/session'; import { DEVICE_ROTATIONS, type DeviceRotation } from '@agent-device/contracts/device'; import { normalizeSnapshotScope } from '@agent-device/contracts/snapshot'; -import { withDiagnosticTimer } from '../../utils/diagnostics.ts'; +import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; import { isMacOs, isTvOsDevice, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { withMethodScope } from '../../utils/method-scope.ts'; +import { withMethodScope } from '@agent-device/host-kit/values'; import type { Point, RawSnapshotNode, SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; import type { Interactor, @@ -35,7 +35,7 @@ import type { ScreenshotOptions, SnapshotOptions, } from '@agent-device/contracts/interactor-types'; -import { readSnapshotQualityVerdict } from '../../snapshot-quality/verdict.ts'; +import { readSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { captureMacOsSurfaceSnapshot } from '../../snapshot/snapshot-desktop-surface.ts'; export function createAppleInteractor( diff --git a/src/platforms/apple/os/macos/helper.ts b/src/platforms/apple/os/macos/helper.ts index 15f1c7ea18..4e432d93e1 100644 --- a/src/platforms/apple/os/macos/helper.ts +++ b/src/platforms/apple/os/macos/helper.ts @@ -8,7 +8,7 @@ import { resolveExecutableOverridePath, runCmdBackground, type ExecBackgroundResult, -} from '../../../../utils/exec.ts'; +} from '@agent-device/host-kit/exec'; import type { SessionSurface } from '@agent-device/contracts/session'; import { hasScopedAppleToolProvider, diff --git a/src/platforms/apple/os/macos/host-provider.ts b/src/platforms/apple/os/macos/host-provider.ts index 7c7e1f9aef..1b43680f8f 100644 --- a/src/platforms/apple/os/macos/host-provider.ts +++ b/src/platforms/apple/os/macos/host-provider.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import type { AppsFilter } from '@agent-device/contracts/device'; import { AppError } from '@agent-device/kernel/errors'; -import { requireExecSuccess } from '../../../../utils/exec.ts'; +import { requireExecSuccess } from '@agent-device/host-kit/exec'; import { filterAppleAppsByBundlePrefix } from '../../core/app-filter.ts'; import type { IosAppInfo } from '../../core/app-info.ts'; import type { diff --git a/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts b/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts index 3db05e85e0..0729a8b489 100644 --- a/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts +++ b/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import { AppError } from '@agent-device/kernel/errors'; import { afterEach, beforeEach, test, vi } from 'vitest'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); @@ -25,7 +25,7 @@ import { parseHarmonyLaunchTarget, resolveHarmonyArchiveBundleName, } from '../app-lifecycle.ts'; -import { runCmd } from '../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/harmonyos/__tests__/doctor.test.ts b/src/platforms/harmonyos/__tests__/doctor.test.ts index becc9124bf..ba0e7360be 100644 --- a/src/platforms/harmonyos/__tests__/doctor.test.ts +++ b/src/platforms/harmonyos/__tests__/doctor.test.ts @@ -2,12 +2,12 @@ import assert from 'node:assert/strict'; import { beforeEach, test, vi } from 'vitest'; import type { DoctorCheck } from '@agent-device/contracts/observability'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); -import { runCmd } from '../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { harmonyToolchainCheck } from '../doctor.ts'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/harmonyos/__tests__/hdc.test.ts b/src/platforms/harmonyos/__tests__/hdc.test.ts index a10b81b05b..5133731e05 100644 --- a/src/platforms/harmonyos/__tests__/hdc.test.ts +++ b/src/platforms/harmonyos/__tests__/hdc.test.ts @@ -1,12 +1,12 @@ import assert from 'node:assert/strict'; import { beforeEach, test, vi } from 'vitest'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); -import { runCmd } from '../../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { DEFAULT_HARMONY_HDC_TIMEOUT_MS, runHarmonyHdc } from '../hdc.ts'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/harmonyos/__tests__/input-actions.test.ts b/src/platforms/harmonyos/__tests__/input-actions.test.ts index e1210b4435..613ef9a650 100644 --- a/src/platforms/harmonyos/__tests__/input-actions.test.ts +++ b/src/platforms/harmonyos/__tests__/input-actions.test.ts @@ -12,7 +12,7 @@ const { runHarmonyHdc, sleep, readHarmonyGestureViewport, invalidateHarmonyGestu })); vi.mock('../hdc.ts', () => ({ runHarmonyHdc })); -vi.mock('../../../utils/timeouts.ts', () => ({ sleep })); +vi.mock('@agent-device/host-kit/exec', () => ({ sleep })); vi.mock('../snapshot.ts', () => ({ readHarmonyGestureViewport, invalidateHarmonyGestureViewport, diff --git a/src/platforms/harmonyos/app-lifecycle.ts b/src/platforms/harmonyos/app-lifecycle.ts index 41e07f741c..2db7a9abac 100644 --- a/src/platforms/harmonyos/app-lifecycle.ts +++ b/src/platforms/harmonyos/app-lifecycle.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { runHarmonyHdc } from './hdc.ts'; import { invalidateHarmonyGestureViewport } from './snapshot.ts'; diff --git a/src/platforms/harmonyos/hdc.ts b/src/platforms/harmonyos/hdc.ts index 4afd5c451a..91c7a33205 100644 --- a/src/platforms/harmonyos/hdc.ts +++ b/src/platforms/harmonyos/hdc.ts @@ -1,7 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { promises as fs } from 'node:fs'; import path from 'node:path'; -import { runCmd, type ExecOptions, type ExecResult } from '../../utils/exec.ts'; +import { runCmd, type ExecOptions, type ExecResult } from '@agent-device/host-kit/exec'; export type HarmonyHdcOptions = Pick< ExecOptions, diff --git a/src/platforms/harmonyos/input-actions.ts b/src/platforms/harmonyos/input-actions.ts index abe9799b5c..62b34f639f 100644 --- a/src/platforms/harmonyos/input-actions.ts +++ b/src/platforms/harmonyos/input-actions.ts @@ -7,7 +7,7 @@ import { } from '@agent-device/contracts/scroll-gesture'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import { runHarmonyHdc } from './hdc.ts'; import { invalidateHarmonyGestureViewport, readHarmonyGestureViewport } from './snapshot.ts'; diff --git a/src/platforms/harmonyos/snapshot.ts b/src/platforms/harmonyos/snapshot.ts index 50ba5ccd62..d848affa23 100644 --- a/src/platforms/harmonyos/snapshot.ts +++ b/src/platforms/harmonyos/snapshot.ts @@ -6,7 +6,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { RawSnapshotNode, Rect } from '@agent-device/kernel/snapshot'; import { AppError } from '@agent-device/kernel/errors'; import type { SnapshotOptions } from '@agent-device/contracts/interactor-types'; -import { createTtlMemo } from '../../utils/ttl-memo.ts'; +import { createTtlMemo } from '@agent-device/host-kit/values'; import { runHarmonyHdc } from './hdc.ts'; const MAX_NODES = 5_000; diff --git a/src/platforms/install-artifact-archive-context.ts b/src/platforms/install-artifact-archive-context.ts index 23cb74c873..e0a7488c51 100644 --- a/src/platforms/install-artifact-archive-context.ts +++ b/src/platforms/install-artifact-archive-context.ts @@ -1,5 +1,5 @@ import { AsyncLocalStorage } from 'node:async_hooks'; -import { ArchiveBudget } from '../utils/archive-safety.ts'; +import { ArchiveBudget } from '@agent-device/host-kit/fs'; type ArchiveState = { budget: ArchiveBudget; depth: number }; const ARCHIVE_STATE = new AsyncLocalStorage(); diff --git a/src/platforms/install-source-archive.ts b/src/platforms/install-source-archive.ts index 6a093d73d5..511688cb8e 100644 --- a/src/platforms/install-source-archive.ts +++ b/src/platforms/install-source-archive.ts @@ -2,8 +2,11 @@ import { promises as fs } from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { extractArchiveSafely, archiveTypeFromPath } from '../utils/archive-extraction.ts'; -import { ArchiveBudget } from '../utils/archive-safety.ts'; +import { + extractArchiveSafely, + archiveTypeFromPath, + ArchiveBudget, +} from '@agent-device/host-kit/fs'; const MAX_INSTALL_SOURCE_SEARCH_DEPTH = 5; diff --git a/src/platforms/install-source-download.ts b/src/platforms/install-source-download.ts index bf2514370f..b1c8995ffb 100644 --- a/src/platforms/install-source-download.ts +++ b/src/platforms/install-source-download.ts @@ -2,8 +2,8 @@ import { createWriteStream, promises as fs } from 'node:fs'; import path from 'node:path'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { MAX_ARTIFACT_COMPRESSED_BYTES } from '../utils/artifact-limits.ts'; -import { createByteLimitStream } from '../utils/byte-limit-stream.ts'; +import { MAX_ARTIFACT_COMPRESSED_BYTES, createByteLimitStream } from '@agent-device/host-kit/fs'; + import { approveDownloadSourceUrl } from './install-source-network.ts'; import * as networkTransport from './install-source-network-transport.ts'; diff --git a/src/platforms/install-source.ts b/src/platforms/install-source.ts index 53fd4c930e..37274de00b 100644 --- a/src/platforms/install-source.ts +++ b/src/platforms/install-source.ts @@ -3,8 +3,8 @@ import os from 'node:os'; import path from 'node:path'; import type { LocalInstallSource } from '@agent-device/kernel/contracts'; import { AppError, createRequestCanceledError } from '@agent-device/kernel/errors'; -import { expandUserHomePath } from '../utils/path-resolution.ts'; -import { ArchiveBudget } from '../utils/archive-safety.ts'; +import { expandUserHomePath, ArchiveBudget } from '@agent-device/host-kit/fs'; + import { resolveInstallableCandidate } from './install-source-archive.ts'; import { installArtifactArchiveBudget, diff --git a/src/platforms/linux/__tests__/atspi-bridge.test.ts b/src/platforms/linux/__tests__/atspi-bridge.test.ts index c993ad3785..8f7c6eeef1 100644 --- a/src/platforms/linux/__tests__/atspi-bridge.test.ts +++ b/src/platforms/linux/__tests__/atspi-bridge.test.ts @@ -1,13 +1,13 @@ import { afterAll, beforeEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), whichCmd: vi.fn() }; }); import { captureAccessibilityTree } from '../atspi-bridge.ts'; -import { runCmd, whichCmd } from '../../../utils/exec.ts'; +import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/linux/__tests__/clipboard.test.ts b/src/platforms/linux/__tests__/clipboard.test.ts index 2712c1c9a4..0abf4a737d 100644 --- a/src/platforms/linux/__tests__/clipboard.test.ts +++ b/src/platforms/linux/__tests__/clipboard.test.ts @@ -1,12 +1,12 @@ import { afterAll, beforeEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), whichCmd: vi.fn() }; }); -import { runCmd, whichCmd } from '../../../utils/exec.ts'; +import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; import { readLinuxClipboard, writeLinuxClipboard } from '../clipboard.ts'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/platforms/linux/__tests__/input-actions.test.ts b/src/platforms/linux/__tests__/input-actions.test.ts index e1732d1c15..3100f704dc 100644 --- a/src/platforms/linux/__tests__/input-actions.test.ts +++ b/src/platforms/linux/__tests__/input-actions.test.ts @@ -1,12 +1,12 @@ import { afterAll, beforeEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('../../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), whichCmd: vi.fn() }; }); -import { runCmd, whichCmd } from '../../../utils/exec.ts'; +import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; import { resetInputToolCache } from '../linux-env.ts'; import { fillLinux, pressLinux, scrollLinux, typeLinux, sendKey } from '../input-actions.ts'; diff --git a/src/platforms/linux/input-actions.ts b/src/platforms/linux/input-actions.ts index 114a9bee21..47f279ebdb 100644 --- a/src/platforms/linux/input-actions.ts +++ b/src/platforms/linux/input-actions.ts @@ -1,6 +1,6 @@ import { ensureInputTool } from './linux-env.ts'; import { resolveLinuxToolProvider, type LinuxPointerButton } from './tool-provider.ts'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import type { ScrollDirection } from '@agent-device/contracts/scroll-gesture'; // ── Low-level wrappers ───────────────────────────────────────────────── diff --git a/src/platforms/linux/snapshot.ts b/src/platforms/linux/snapshot.ts index 91ea2ff8c9..a87c0b60b2 100644 --- a/src/platforms/linux/snapshot.ts +++ b/src/platforms/linux/snapshot.ts @@ -1,7 +1,7 @@ import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { captureAccessibilityTree, type SnapshotSurface } from './atspi-bridge.ts'; import type { SessionSurface } from '@agent-device/contracts/session'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; /** * Map the session-level surface to an AT-SPI2 surface. diff --git a/src/platforms/linux/tool-provider.ts b/src/platforms/linux/tool-provider.ts index 8cc9bc4d45..bf637fc34f 100644 --- a/src/platforms/linux/tool-provider.ts +++ b/src/platforms/linux/tool-provider.ts @@ -1,10 +1,17 @@ import type { ClickButton } from '@agent-device/contracts/click-button'; import type { ScrollDirection } from '@agent-device/contracts/scroll-gesture'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; -import { runCmd, whichCmd, type ExecOptions, type ExecResult } from '../../utils/exec.ts'; -import { createScopedProvider } from '../../utils/scoped-provider.ts'; -import { sleep } from '../../utils/timeouts.ts'; +import { + emitDiagnostic, + runCmd, + whichCmd, + type ExecOptions, + type ExecResult, + sleep, +} from '@agent-device/host-kit/exec'; + +import { createScopedProvider } from '@agent-device/host-kit/values'; + import type { LinuxAccessibilityTree, LinuxSnapshotSurface, diff --git a/src/platforms/toolchain-probe.ts b/src/platforms/toolchain-probe.ts index 4bbdfe8b5a..e74f5f8981 100644 --- a/src/platforms/toolchain-probe.ts +++ b/src/platforms/toolchain-probe.ts @@ -1,4 +1,4 @@ -import { runCmd } from '../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; export const TOOLCHAIN_TIMEOUT_MS = 3_000; diff --git a/src/platforms/vega/app-lifecycle.ts b/src/platforms/vega/app-lifecycle.ts index 67d734bff3..264c70dfe8 100644 --- a/src/platforms/vega/app-lifecycle.ts +++ b/src/platforms/vega/app-lifecycle.ts @@ -1,5 +1,5 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; -import { requireExecSuccess, type ExecOptions } from '../../utils/exec.ts'; +import { requireExecSuccess, type ExecOptions } from '@agent-device/host-kit/exec'; import { resolveVegaToolProvider } from './tool-provider.ts'; const VEGA_APP_COMMAND_TIMEOUT_MS = 30_000; diff --git a/src/platforms/vega/input-actions.ts b/src/platforms/vega/input-actions.ts index 92937f2829..be0319f247 100644 --- a/src/platforms/vega/input-actions.ts +++ b/src/platforms/vega/input-actions.ts @@ -1,6 +1,6 @@ import { type TvRemoteButton, toVegaTvRemoteKey } from '@agent-device/contracts/tv-remote'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { requireExecSuccess } from '../../utils/exec.ts'; +import { requireExecSuccess } from '@agent-device/host-kit/exec'; import { resolveVegaToolProvider } from './tool-provider.ts'; const VEGA_INPUT_TRANSPORT_OVERHEAD_MS = 10_000; diff --git a/src/platforms/vega/tool-provider.ts b/src/platforms/vega/tool-provider.ts index 84d26dd720..ec01c44bc7 100644 --- a/src/platforms/vega/tool-provider.ts +++ b/src/platforms/vega/tool-provider.ts @@ -3,8 +3,8 @@ import { access } from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import type { VegaTvRemoteKey } from '@agent-device/contracts/tv-remote'; -import { runCmd, whichCmd, type ExecOptions, type ExecResult } from '../../utils/exec.ts'; -import { createScopedProvider } from '../../utils/scoped-provider.ts'; +import { runCmd, whichCmd, type ExecOptions, type ExecResult } from '@agent-device/host-kit/exec'; +import { createScopedProvider } from '@agent-device/host-kit/values'; export type VegaToolProvider = { isAvailable(): Promise; diff --git a/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts b/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts index 86729d3e66..36025e8429 100644 --- a/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts +++ b/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts @@ -4,7 +4,7 @@ import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; import { mkdtempForTestSync } from '../../../__tests__/test-utils/tmp-dir.ts'; import { createFailNthCommandExecutor } from '../../../__tests__/test-utils/exec-faults.ts'; -import { withCommandExecutorOverride } from '../../../utils/exec.ts'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { createAgentBrowserWebProvider } from '../agent-browser-provider.ts'; import { installFakeManagedAgentBrowser } from './test-utils.ts'; diff --git a/src/platforms/web/agent-browser-install.ts b/src/platforms/web/agent-browser-install.ts index 0d41e710bf..3a51958648 100644 --- a/src/platforms/web/agent-browser-install.ts +++ b/src/platforms/web/agent-browser-install.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; /** * How the managed backend gets onto disk. Kept apart from the tool module, diff --git a/src/platforms/web/agent-browser-lifecycle.test.ts b/src/platforms/web/agent-browser-lifecycle.test.ts index 762d822b7e..ecbb099d8e 100644 --- a/src/platforms/web/agent-browser-lifecycle.test.ts +++ b/src/platforms/web/agent-browser-lifecycle.test.ts @@ -8,21 +8,21 @@ const { runCmdMock } = vi.hoisted(() => ({ runCmdMock: vi.fn(), })); -vi.mock('../../utils/exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: runCmdMock, + // The seam mock cannot reach listHostProcesses' internal runCmd call, so + // the ps read is routed through its runCommand injection point instead. + listHostProcesses: async (options: Parameters[0]) => + await actual.listHostProcesses({ ...options, runCommand: runCmdMock }), withoutCommandExecutorOverride: async (fn: () => Promise) => await fn(), + readProcessStartTime: (pid: number) => `start-${pid}`, + readProcessCommand: (pid: number) => `command-${pid}`, }; }); -vi.mock('../../utils/host-process.ts', async (importOriginal) => ({ - ...(await importOriginal()), - readProcessStartTime: (pid: number) => `start-${pid}`, - readProcessCommand: (pid: number) => `command-${pid}`, -})); - import { DEFAULT_AGENT_BROWSER_IDLE_TIMEOUT_MS, agentBrowserChromeLaunchMarker, diff --git a/src/platforms/web/agent-browser-lifecycle.ts b/src/platforms/web/agent-browser-lifecycle.ts index b75fdb336d..ce2e0d088b 100644 --- a/src/platforms/web/agent-browser-lifecycle.ts +++ b/src/platforms/web/agent-browser-lifecycle.ts @@ -1,9 +1,12 @@ import fs from 'node:fs'; import path from 'node:path'; import { uniqueStrings } from '@agent-device/kernel/collections'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; -import type { OwnedProcessRecordStore } from '../../utils/owned-process-record.ts'; -import { reapOwnedProcessRecordsAtStartup } from '../../utils/owned-process-reaper.ts'; +import { + emitDiagnostic, + type OwnedProcessRecordStore, + reapOwnedProcessRecordsAtStartup, +} from '@agent-device/host-kit/exec'; + import type { AgentBrowserToolStatus } from './agent-browser-tool.ts'; import type { AgentBrowserProcessSummary } from './agent-browser-process-record.ts'; export { diff --git a/src/platforms/web/agent-browser-network.ts b/src/platforms/web/agent-browser-network.ts index 4ae37c7564..e5e9360291 100644 --- a/src/platforms/web/agent-browser-network.ts +++ b/src/platforms/web/agent-browser-network.ts @@ -3,7 +3,7 @@ import type { BackendDumpNetworkResult, BackendNetworkEntry, } from '../../backend.ts'; -import { stripUndefined } from '../../utils/parsing.ts'; +import { stripUndefined } from '@agent-device/host-kit/values'; import { isJsonObject, readNumberProperty, readStringProperty } from './json-utils.ts'; type AgentBrowserNetworkRequest = { diff --git a/src/platforms/web/agent-browser-process-record.ts b/src/platforms/web/agent-browser-process-record.ts index f60b33ab40..75b07327d5 100644 --- a/src/platforms/web/agent-browser-process-record.ts +++ b/src/platforms/web/agent-browser-process-record.ts @@ -2,15 +2,16 @@ import crypto from 'node:crypto'; import path from 'node:path'; import type { OwnedProcessRecord } from '@agent-device/contracts/platform-runtime-host'; import { uniqueStrings } from '@agent-device/kernel/collections'; -import { withoutCommandExecutorOverride } from '../../utils/exec.ts'; import { + withoutCommandExecutorOverride, expandProcessTree, listHostProcesses, readProcessCommand, readProcessStartTime, type HostProcessInfo, -} from '../../utils/host-process.ts'; -import type { OwnedProcessRecordStore } from '../../utils/owned-process-record.ts'; + type OwnedProcessRecordStore, +} from '@agent-device/host-kit/exec'; + import type { AgentBrowserToolStatus } from './agent-browser-tool.ts'; const HOST_PROCESS_LIST_TIMEOUT_MS = 1_500; diff --git a/src/platforms/web/agent-browser-provider.test.ts b/src/platforms/web/agent-browser-provider.test.ts index cc490cd9be..d2c1fde454 100644 --- a/src/platforms/web/agent-browser-provider.test.ts +++ b/src/platforms/web/agent-browser-provider.test.ts @@ -17,12 +17,15 @@ vi.mock('./agent-browser-lifecycle.ts', async (importOriginal) => { import { createAgentBrowserWebProvider } from './agent-browser-provider.ts'; import type { WebSnapshotResult } from './provider.ts'; -import { withCommandExecutorOverride, type ExecResult } from '../../utils/exec.ts'; +import { + withCommandExecutorOverride, + type ExecResult, + type OwnedProcessRecordStore, +} from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; import { buildSelectorChainForNode, resolveRecordedTarget } from '@agent-device/selectors'; import { attachRefs } from '@agent-device/kernel/snapshot'; import { installFakeManagedAgentBrowser, withNodeRuntime } from './__tests__/test-utils.ts'; -import type { OwnedProcessRecordStore } from '../../utils/owned-process-record.ts'; type AgentBrowserCall = { cmd: string; diff --git a/src/platforms/web/agent-browser-provider.ts b/src/platforms/web/agent-browser-provider.ts index d62bc44ce2..439289ce87 100644 --- a/src/platforms/web/agent-browser-provider.ts +++ b/src/platforms/web/agent-browser-provider.ts @@ -1,7 +1,11 @@ -import { execFailureDetails } from '../../utils/exec.ts'; +import { + execFailureDetails, + emitDiagnostic, + sleep, + type OwnedProcessRecordStore, +} from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '../../utils/diagnostics.ts'; -import { sleep } from '../../utils/timeouts.ts'; + import type { Rect } from '@agent-device/kernel/snapshot'; import { buildAudioProbeEvalScript, @@ -25,7 +29,6 @@ import { cleanupManagedAgentBrowserOrphansForProviderStartup, recordManagedAgentBrowserProcesses, } from './agent-browser-lifecycle.ts'; -import type { OwnedProcessRecordStore } from '../../utils/owned-process-record.ts'; const AGENT_BROWSER = 'agent-browser'; // Exported so daemon shutdown can pin its web-close budget to the ceiling enforced for one diff --git a/src/platforms/web/agent-browser-tool.test.ts b/src/platforms/web/agent-browser-tool.test.ts index 0e1b88e3de..f4950308b2 100644 --- a/src/platforms/web/agent-browser-tool.test.ts +++ b/src/platforms/web/agent-browser-tool.test.ts @@ -14,7 +14,7 @@ import { writeFakeNpmCliScript, } from './__tests__/test-utils.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { withCommandExecutorOverride } from '../../utils/exec.ts'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; type SpawnedCommand = { cmd: string; args: string[] }; diff --git a/src/platforms/web/agent-browser-tool.ts b/src/platforms/web/agent-browser-tool.ts index f11d1ede97..e086d4a3a4 100644 --- a/src/platforms/web/agent-browser-tool.ts +++ b/src/platforms/web/agent-browser-tool.ts @@ -2,15 +2,15 @@ import fs from 'node:fs'; import crypto from 'node:crypto'; import os from 'node:os'; import path from 'node:path'; -import { runCmd, type ExecResult } from '../../utils/exec.ts'; +import { runCmd, type ExecResult, readProcessStartTime } from '@agent-device/host-kit/exec'; import { AppError, asAppError } from '@agent-device/kernel/errors'; import type { ManagedWebBackendStatus } from '@agent-device/contracts/managed-web-backend'; import { installManagedAgentBrowserPackage, writeManagedAgentBrowserManifest, } from './agent-browser-install.ts'; -import { acquireProcessLock } from '../../utils/process-lock.ts'; -import { readProcessStartTime } from '../../utils/host-process.ts'; +import { acquireProcessLock } from '@agent-device/host-kit/fs'; + import { appendAgentDeviceChromeArgs, resolveAgentBrowserIdleTimeoutMs, diff --git a/src/platforms/web/provider.ts b/src/platforms/web/provider.ts index 081382180e..849550b370 100644 --- a/src/platforms/web/provider.ts +++ b/src/platforms/web/provider.ts @@ -1,6 +1,6 @@ import type { ScrollDirection } from '@agent-device/contracts/scroll-gesture'; import type { SessionSurface } from '@agent-device/contracts/session'; -import { createScopedProvider } from '../../utils/scoped-provider.ts'; +import { createScopedProvider } from '@agent-device/host-kit/values'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import type { BackendDumpNetworkOptions, BackendDumpNetworkResult } from '../../backend.ts'; import type { AudioProbeResult } from '@agent-device/contracts/audio-probe-result'; diff --git a/src/provider-webdriver.ts b/src/provider-webdriver.ts index dcbe0e5808..1ee7e4a537 100644 --- a/src/provider-webdriver.ts +++ b/src/provider-webdriver.ts @@ -1,6 +1,6 @@ import { createProviderWebDriver } from '@agent-device/provider-webdriver'; -import { runCmd } from './utils/exec.ts'; -import { readVersion } from './utils/version.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; +import { readVersion } from '@agent-device/host-kit/values'; export const providerWebDriver = createProviderWebDriver({ clientVersion: readVersion(), diff --git a/src/recording/__tests__/overlay.test.ts b/src/recording/__tests__/overlay.test.ts index 6f86d3b7a0..bd5fd9d022 100644 --- a/src/recording/__tests__/overlay.test.ts +++ b/src/recording/__tests__/overlay.test.ts @@ -3,10 +3,11 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../utils/exec.ts', async () => { +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { const fs = await import('node:fs'); const path = await import('node:path'); return { + ...(await importOriginal()), runCmd: vi.fn(async (cmd: string, args: string[]) => { if (cmd === 'xcrun') { const outputPath = args[args.indexOf('-o') + 1]!; @@ -29,7 +30,7 @@ vi.mock('../../utils/video.ts', () => ({ import { buildRecordingScriptPathCandidates, overlayRecordingTouches } from '../overlay.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; function helperScriptArgs(): string[] { const helperCall = mockRunCmd.mock.calls.find(([cmd]) => cmd !== 'xcrun'); diff --git a/src/recording/__tests__/recording-scripts.test.ts b/src/recording/__tests__/recording-scripts.test.ts index d8650d60df..6de4ebb332 100644 --- a/src/recording/__tests__/recording-scripts.test.ts +++ b/src/recording/__tests__/recording-scripts.test.ts @@ -2,7 +2,7 @@ import { beforeAll, test } from 'vitest'; import assert from 'node:assert/strict'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmd } from '../../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { getRecordingOverlaySupportWarning } from '../overlay.ts'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); diff --git a/src/recording/output-path.ts b/src/recording/output-path.ts index 81813d5f65..9d5da6ab9a 100644 --- a/src/recording/output-path.ts +++ b/src/recording/output-path.ts @@ -1,6 +1,6 @@ import path from 'node:path'; import type { Platform, PlatformSelector } from '@agent-device/kernel/device'; -import { resolveUserPath } from '../utils/path-resolution.ts'; +import { resolveUserPath } from '@agent-device/host-kit/fs'; const DEFAULT_RECORDING_EXTENSION = '.mp4'; const WEB_RECORDING_EXTENSION = '.webm'; diff --git a/src/recording/overlay.ts b/src/recording/overlay.ts index 40e0acc373..b4d173729b 100644 --- a/src/recording/overlay.ts +++ b/src/recording/overlay.ts @@ -1,10 +1,10 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmd } from '../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { AppError } from '@agent-device/kernel/errors'; import { buildSwiftToolEnv, compileSwiftSourceFile } from '../utils/swift-cache.ts'; -import { findProjectRoot } from '../utils/version.ts'; +import { findProjectRoot } from '@agent-device/host-kit/values'; import { waitForPlayableVideo, waitForStableFile } from '../utils/video.ts'; import { DEFAULT_RECORDING_EXPORT_QUALITY, diff --git a/src/remote/remote-config-core.ts b/src/remote/remote-config-core.ts index 1a768065ad..3f550e675e 100644 --- a/src/remote/remote-config-core.ts +++ b/src/remote/remote-config-core.ts @@ -9,8 +9,8 @@ import { type ResolvedRemoteConfigProfile, } from './remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { resolveUserPath } from '../utils/path-resolution.ts'; -import { parseSourceValue } from '../utils/source-value.ts'; +import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { parseSourceValue } from '@agent-device/host-kit/values'; // Deliberately narrower than `resolveRemoteConfigProfile`: this reads only // what the config *file itself* declares, with no ambient environment diff --git a/src/remote/remote-config-schema.ts b/src/remote/remote-config-schema.ts index b2cd81ac16..489f9e8175 100644 --- a/src/remote/remote-config-schema.ts +++ b/src/remote/remote-config-schema.ts @@ -7,7 +7,7 @@ import { // Declared in contracts/ so zones below remote/ can be stated in terms of the field vocabulary; // re-exported here because this module is where consumers already import it from. export type { RemoteConnectionProfileFields } from '@agent-device/contracts/remote'; -import { buildPrimaryEnvVarName } from '../utils/source-value.ts'; +import { buildPrimaryEnvVarName } from '@agent-device/host-kit/values'; import { PLATFORM_SELECTORS, type DeviceTarget, diff --git a/src/remote/remote-connection-state.ts b/src/remote/remote-connection-state.ts index deb877db96..a1cbda3830 100644 --- a/src/remote/remote-connection-state.ts +++ b/src/remote/remote-connection-state.ts @@ -3,8 +3,8 @@ import fs from 'node:fs'; import path from 'node:path'; import { resolveRemoteConfigPath, resolveRemoteConfigProfile } from './remote-config-core.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { publishFileSync } from '../utils/atomic-file.ts'; -import { emitDiagnostic } from '../utils/diagnostics.ts'; +import { publishFileSync } from '@agent-device/host-kit/fs'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import type { CliFlags } from '@agent-device/contracts/command'; import type { LeaseBackend, SessionRuntimeHints } from '@agent-device/kernel/contracts'; import { diff --git a/src/remote/upload-client-artifact.ts b/src/remote/upload-client-artifact.ts index c0d6dfd102..e11388b7a7 100644 --- a/src/remote/upload-client-artifact.ts +++ b/src/remote/upload-client-artifact.ts @@ -5,7 +5,7 @@ import path from 'node:path'; import { Writable } from 'node:stream'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '../utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; const ARTIFACT_HASH_ALGORITHM = 'sha256'; const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; diff --git a/src/replay/script-source-bundle.ts b/src/replay/script-source-bundle.ts index 07ba00bfe3..a6061ab715 100644 --- a/src/replay/script-source-bundle.ts +++ b/src/replay/script-source-bundle.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import { AppError } from '@agent-device/kernel/errors'; import type { ReplayScriptSourceBundle } from '@agent-device/contracts/replay'; -import { resolveUserPath } from '../utils/path-resolution.ts'; +import { resolveUserPath } from '@agent-device/host-kit/fs'; import { resolveReplayFormat } from './format.ts'; /** diff --git a/src/replay/source-discovery.ts b/src/replay/source-discovery.ts index fbcafd673f..29c6170182 100644 --- a/src/replay/source-discovery.ts +++ b/src/replay/source-discovery.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { resolveUserPath } from '../utils/path-resolution.ts'; +import { resolveUserPath } from '@agent-device/host-kit/fs'; import { isMaestroYamlPath, maestroBackendRequiredMessage } from './format.ts'; const GLOB_PATTERN_CHARS = /[*?[\]{}]/; diff --git a/src/screenshot-diff/__tests__/screenshot-diff.test.ts b/src/screenshot-diff/__tests__/screenshot-diff.test.ts index b90899da95..f5fbb90c9f 100644 --- a/src/screenshot-diff/__tests__/screenshot-diff.test.ts +++ b/src/screenshot-diff/__tests__/screenshot-diff.test.ts @@ -4,11 +4,11 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../../utils/png-worker-client.ts', async () => { +vi.mock('@agent-device/capture-kit/png-worker-client', async () => { const [{ PNG }, { decodePng }, { computeScreenshotDiffPixels }] = await Promise.all([ - import('../../utils/png.ts'), - import('../../utils/png.ts'), - import('../../utils/screenshot-diff-pixels.ts'), + import('@agent-device/capture-kit/png'), + import('@agent-device/capture-kit/png'), + import('@agent-device/capture-kit/screenshot-diff-pixels'), ]); return { decodePngAsync: async (buffer: Buffer, label: string) => decodePng(buffer, label), @@ -19,7 +19,7 @@ vi.mock('../../utils/png-worker-client.ts', async () => { }; }); -import { PNG } from '../../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { compareScreenshots } from '../screenshot-diff.ts'; function tmpDir(): string { diff --git a/src/screenshot-diff/screenshot-diff-region-overlay.ts b/src/screenshot-diff/screenshot-diff-region-overlay.ts index 22b74fcb8f..66d7c0cafa 100644 --- a/src/screenshot-diff/screenshot-diff-region-overlay.ts +++ b/src/screenshot-diff/screenshot-diff-region-overlay.ts @@ -1,4 +1,4 @@ -import type { PNG } from '../utils/png.ts'; +import type { PNG } from '@agent-device/capture-kit/png'; import type { ScreenshotDiffRegion } from './screenshot-diff-regions.ts'; const REGION_BORDER_COLOR = [0, 187, 255, 255] as const; diff --git a/src/screenshot-diff/screenshot-diff-region-split.ts b/src/screenshot-diff/screenshot-diff-region-split.ts index bb537b37de..ace6cbbd97 100644 --- a/src/screenshot-diff/screenshot-diff-region-split.ts +++ b/src/screenshot-diff/screenshot-diff-region-split.ts @@ -1,4 +1,4 @@ -import type { PNG } from '../utils/png.ts'; +import type { PNG } from '@agent-device/capture-kit/png'; import type { MutableDiffRegion } from './screenshot-diff-region-types.ts'; // Region splitting is based on screen-relative heights so it works on phone, diff --git a/src/screenshot-diff/screenshot-diff-regions.ts b/src/screenshot-diff/screenshot-diff-regions.ts index ee464b9465..39d5f87be8 100644 --- a/src/screenshot-diff/screenshot-diff-regions.ts +++ b/src/screenshot-diff/screenshot-diff-regions.ts @@ -1,5 +1,5 @@ import type { Rect } from '@agent-device/kernel/snapshot'; -import type { PNG } from '../utils/png.ts'; +import type { PNG } from '@agent-device/capture-kit/png'; import { normalizedRect, type NormalizedRect } from '../utils/screenshot-geometry.ts'; import { findConnectedMaskComponents } from './screenshot-diff-components.ts'; import { splitLargeDiffRegions } from './screenshot-diff-region-split.ts'; diff --git a/src/screenshot-diff/screenshot-diff.ts b/src/screenshot-diff/screenshot-diff.ts index 269389cf96..2aaf0b02cc 100644 --- a/src/screenshot-diff/screenshot-diff.ts +++ b/src/screenshot-diff/screenshot-diff.ts @@ -2,12 +2,12 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import type { Rect } from '@agent-device/kernel/snapshot'; -import { PNG } from '../utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import { computeScreenshotDiffPixelsAsync, decodePngAsync, encodePngAsync, -} from '../utils/png-worker-client.ts'; +} from '@agent-device/capture-kit/png-worker-client'; import { annotateDiffRegions } from './screenshot-diff-region-overlay.ts'; import { summarizeDiffRegions, type ScreenshotDiffRegion } from './screenshot-diff-regions.ts'; import type { ImageDimensions } from '../utils/screenshot-geometry.ts'; diff --git a/src/sdk/limrun-runtime-dependencies.ts b/src/sdk/limrun-runtime-dependencies.ts index ca9ab2c1b0..4cb518713c 100644 --- a/src/sdk/limrun-runtime-dependencies.ts +++ b/src/sdk/limrun-runtime-dependencies.ts @@ -4,8 +4,8 @@ import type { LimrunRuntimeDependencies } from '@agent-device/provider-limrun'; // deliberate static edge; making it lazy would require a proxy interactor rather than this seam. import { createAndroidInteractor } from '../core/interactors/android.ts'; import { runAndroidHostAdb } from '../platforms/android/adb-executor.ts'; -import { execFailureDetails, runCmd } from '../utils/exec.ts'; -import { readVersion } from '../utils/version.ts'; +import { execFailureDetails, runCmd } from '@agent-device/host-kit/exec'; +import { readVersion } from '@agent-device/host-kit/values'; export function createLimrunRuntimeDependencies(): LimrunRuntimeDependencies { return { diff --git a/src/snapshot-quality/__tests__/warnings.test.ts b/src/snapshot-quality/__tests__/warnings.test.ts index 43e0aa1f11..024586435a 100644 --- a/src/snapshot-quality/__tests__/warnings.test.ts +++ b/src/snapshot-quality/__tests__/warnings.test.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; -import { readSnapshotQualityVerdict } from '../verdict.ts'; +import { readSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { renderSnapshotQualityWarnings } from '../warnings.ts'; const sharedRecoveryReason = diff --git a/src/snapshot/snapshot-freshness/recovery.ts b/src/snapshot/snapshot-freshness/recovery.ts index 9e8414c632..8072879325 100644 --- a/src/snapshot/snapshot-freshness/recovery.ts +++ b/src/snapshot/snapshot-freshness/recovery.ts @@ -3,7 +3,7 @@ import { type SnapshotCaptureAnnotations, } from '@agent-device/contracts/capture'; import type { SnapshotState } from '@agent-device/kernel/snapshot'; -import { sleep } from '../../utils/timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; import type { SnapshotFreshnessReason, SnapshotFreshnessWindow } from './types.ts'; /** diff --git a/src/snapshot/snapshot-lines.ts b/src/snapshot/snapshot-lines.ts index 1553120579..fe7677fca0 100644 --- a/src/snapshot/snapshot-lines.ts +++ b/src/snapshot/snapshot-lines.ts @@ -1,4 +1,4 @@ -import { isSystemScrollIndicatorLabel } from '../utils/scroll-indicator.ts'; +import { isSystemScrollIndicatorLabel } from '@agent-device/kernel/scroll-indicator'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import { buildTextPreview, describeTextSurface, trimText } from '../utils/text-surface.ts'; diff --git a/src/snapshot/snapshot-presentation/ios/rows.ts b/src/snapshot/snapshot-presentation/ios/rows.ts index b3cbd83a31..06613ba7a0 100644 --- a/src/snapshot/snapshot-presentation/ios/rows.ts +++ b/src/snapshot/snapshot-presentation/ios/rows.ts @@ -1,6 +1,6 @@ import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { normalizeType } from '@agent-device/contracts/snapshot'; -import { isSystemScrollIndicatorLabel } from '../../../utils/scroll-indicator.ts'; +import { isSystemScrollIndicatorLabel } from '@agent-device/kernel/scroll-indicator'; import { areRectsApproximatelyEqual, collectDescendants, diff --git a/src/snapshot/snapshot-presentation/ios/scroll.ts b/src/snapshot/snapshot-presentation/ios/scroll.ts index d41eaff147..09ede96247 100644 --- a/src/snapshot/snapshot-presentation/ios/scroll.ts +++ b/src/snapshot/snapshot-presentation/ios/scroll.ts @@ -2,7 +2,7 @@ import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { inferVerticalScrollIndicatorDirections, isSystemScrollIndicatorLabel, -} from '../../../utils/scroll-indicator.ts'; +} from '@agent-device/kernel/scroll-indicator'; import { findNearestScrollableContainer, isScrollableSnapshotType, diff --git a/src/snapshot/snapshot-presentation/tree.ts b/src/snapshot/snapshot-presentation/tree.ts index ac9bce796a..25350a941a 100644 --- a/src/snapshot/snapshot-presentation/tree.ts +++ b/src/snapshot/snapshot-presentation/tree.ts @@ -1,6 +1,6 @@ import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { normalizeType } from '@agent-device/contracts/snapshot'; -export { areRectsApproximatelyEqual } from '../../utils/rect-center.ts'; +export { areRectsApproximatelyEqual } from '@agent-device/kernel/rect-center'; export type SnapshotTreeRuleContext = { replacements: Map; diff --git a/src/snapshot/snapshot-visibility.ts b/src/snapshot/snapshot-visibility.ts index b9dc1dc477..6e96565d62 100644 --- a/src/snapshot/snapshot-visibility.ts +++ b/src/snapshot/snapshot-visibility.ts @@ -1,4 +1,4 @@ -import { buildMobileSnapshotPresentation } from './mobile-snapshot-semantics.ts'; +import { buildMobileSnapshotPresentation } from '@agent-device/capture-kit/mobile-snapshot-semantics'; import { usesMobileSnapshotPresentation, type SnapshotState, diff --git a/src/utils/__tests__/atomic-publish-ownership.test.ts b/src/utils/__tests__/atomic-publish-ownership.test.ts index f5e082c162..5c17a53fa7 100644 --- a/src/utils/__tests__/atomic-publish-ownership.test.ts +++ b/src/utils/__tests__/atomic-publish-ownership.test.ts @@ -9,7 +9,7 @@ const SIMPLE_PUBLISHERS = [ new URL('../../daemon/session-script-writer.ts', import.meta.url), new URL('../../../packages/platform-apple/src/runner/runner-lease.ts', import.meta.url), new URL('../../remote/remote-connection-state.ts', import.meta.url), - new URL('../process-lock.ts', import.meta.url), + new URL('../../../packages/host-kit/src/internal/process-lock.ts', import.meta.url), ] as const; test('simple same-directory publishers use the shared atomic publish owner', () => { diff --git a/src/utils/__tests__/daemon-client-lifecycle.test.ts b/src/utils/__tests__/daemon-client-lifecycle.test.ts index d8af0aa30c..1cd2476566 100644 --- a/src/utils/__tests__/daemon-client-lifecycle.test.ts +++ b/src/utils/__tests__/daemon-client-lifecycle.test.ts @@ -7,21 +7,17 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../exec.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmdDetached: vi.fn(), runCmdDetachedMonitored: vi.fn(), runCmdSync: vi.fn(() => ({ exitCode: 1, stdout: '', stderr: '' })), + sleep: vi.fn(async () => {}), }; }); -vi.mock('../timeouts.ts', async (importOriginal) => { - const actual = await importOriginal(); - return { ...actual, sleep: vi.fn(async () => {}) }; -}); - import { resolveDaemonPaths, type DaemonPaths } from '../../daemon/config.ts'; import { sendToDaemon, @@ -37,11 +33,15 @@ import { supportsLoopbackBind, } from '../../__tests__/test-utils/loopback.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmdDetachedMonitored, runCmdSync } from '../exec.ts'; -import { readProcessStartTime } from '../host-process.ts'; -import { shellQuoteIfNeeded } from '../shell-quote.ts'; -import { sleep } from '../timeouts.ts'; -import { findProjectRoot, readVersion } from '../version.ts'; +import { + runCmdDetachedMonitored, + runCmdSync, + readProcessStartTime, + shellQuoteIfNeeded, + sleep, +} from '@agent-device/host-kit/exec'; + +import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; type DaemonInfoFixture = { port?: number; diff --git a/src/utils/__tests__/daemon-client.test.ts b/src/utils/__tests__/daemon-client.test.ts index 0fed780f1c..a25af4b20d 100644 --- a/src/utils/__tests__/daemon-client.test.ts +++ b/src/utils/__tests__/daemon-client.test.ts @@ -11,7 +11,13 @@ import { listenOnLoopback, supportsLoopbackBind, } from '../../__tests__/test-utils/loopback.ts'; -import { runCmdBackground } from '../exec.ts'; +import { + runCmdBackground, + isProcessAlive, + readProcessCommand, + readProcessStartTime, + waitForProcessExit, +} from '@agent-device/host-kit/exec'; import { sendToDaemon } from '../../daemon/client/daemon-client.ts'; import { computeDaemonCodeSignature } from '../../daemon/code-signature.ts'; import { downloadRemoteArtifact } from '../../remote/daemon-artifacts.ts'; @@ -27,14 +33,8 @@ import { shouldResetDaemonAfterRequestTimeout, } from '../../daemon/client/daemon-client-timeout.ts'; import { resolveDaemonPaths } from '../../daemon/config.ts'; -import { - isProcessAlive, - readProcessCommand, - readProcessStartTime, - waitForProcessExit, -} from '../host-process.ts'; import { stopProcessForTakeover } from '../../daemon/daemon-process.ts'; -import { findProjectRoot, readVersion } from '../version.ts'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; // readProcessStartTime/readProcessCommand shell out to `ps` with a 1s @@ -52,8 +52,8 @@ const { mockReadProcessStartTime, mockReadProcessCommand } = vi.hoisted(() => ({ mockReadProcessCommand: vi.fn<(pid: number) => string | null | undefined>(), })); -vi.mock('../host-process.ts', async () => { - const actual = await vi.importActual('../host-process.ts'); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: (pid: number) => { diff --git a/src/utils/__tests__/exec-boundary-faults.test.ts b/src/utils/__tests__/exec-boundary-faults.test.ts index 552d69f5e5..6d20af36ad 100644 --- a/src/utils/__tests__/exec-boundary-faults.test.ts +++ b/src/utils/__tests__/exec-boundary-faults.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; import { createFailNthCommandExecutor } from '../../__tests__/test-utils/exec-faults.ts'; -import { runCmd, withCommandExecutorOverride } from '../exec.ts'; +import { runCmd, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; test('fail-Nth executor drives one deterministic command failure without hiding later calls', async () => { const failure = new AppError('COMMAND_FAILED', 'injected command failure', { diff --git a/src/utils/__tests__/process-exit.test.ts b/src/utils/__tests__/process-exit.test.ts index ff9d4c575a..7966e76dd5 100644 --- a/src/utils/__tests__/process-exit.test.ts +++ b/src/utils/__tests__/process-exit.test.ts @@ -1,13 +1,13 @@ import assert from 'node:assert/strict'; import { afterEach, test, vi } from 'vitest'; -vi.mock('../timeouts.ts', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, sleep: vi.fn(async () => {}) }; }); import { exitAfterFlush } from '../process-exit.ts'; -import { sleep } from '../timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; type FakeWriteStream = { writableLength: number; diff --git a/src/utils/__tests__/swift-cache.test.ts b/src/utils/__tests__/swift-cache.test.ts index a0f691acc7..ce43c22cd4 100644 --- a/src/utils/__tests__/swift-cache.test.ts +++ b/src/utils/__tests__/swift-cache.test.ts @@ -3,7 +3,8 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('../exec.ts', () => ({ +vi.mock(import('@agent-device/host-kit/exec'), async (importOriginal) => ({ + ...(await importOriginal()), runCmd: vi.fn(async (_cmd: string, args: string[]) => { const outputPath = args[args.indexOf('-o') + 1]!; fs.writeFileSync(outputPath, 'compiled'); @@ -12,7 +13,7 @@ vi.mock('../exec.ts', () => ({ }), })); -import { runCmd } from '../exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { compileSwiftSourceFile, compileSwiftSourceText } from '../swift-cache.ts'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/utils/keyed-lock.ts b/src/utils/keyed-lock.ts deleted file mode 100644 index e5eef7881a..0000000000 --- a/src/utils/keyed-lock.ts +++ /dev/null @@ -1 +0,0 @@ -export { withKeyedLock } from '@agent-device/kernel/keyed-lock'; diff --git a/src/utils/output.ts b/src/utils/output.ts index 0bea051959..c43e874a2e 100644 --- a/src/utils/output.ts +++ b/src/utils/output.ts @@ -18,7 +18,7 @@ import { import type { ScreenshotDiffResult } from '../screenshot-diff/screenshot-diff.ts'; import type { ScreenshotDiffRegion } from '../screenshot-diff/screenshot-diff-regions.ts'; import { styleText } from 'node:util'; -import { buildMobileSnapshotPresentation } from '../snapshot/mobile-snapshot-semantics.ts'; +import { buildMobileSnapshotPresentation } from '@agent-device/capture-kit/mobile-snapshot-semantics'; type JsonResult = | { success: true; data?: unknown } diff --git a/src/utils/process-exit.ts b/src/utils/process-exit.ts index 97f47b971b..82a2799723 100644 --- a/src/utils/process-exit.ts +++ b/src/utils/process-exit.ts @@ -1,4 +1,4 @@ -import { sleep } from './timeouts.ts'; +import { sleep } from '@agent-device/host-kit/exec'; const FLUSH_TIMEOUT_MS = 2000; diff --git a/src/utils/result-serialization.ts b/src/utils/result-serialization.ts index 575827c396..f34cf97649 100644 --- a/src/utils/result-serialization.ts +++ b/src/utils/result-serialization.ts @@ -15,7 +15,7 @@ import type { SessionCloseResult, } from '@agent-device/contracts/client'; import { isSerialAddressablePlatform, type PublicPlatform } from '@agent-device/kernel/device'; -import { successText, withSuccessText } from './success-text.ts'; +import { successText, withSuccessText } from '@agent-device/host-kit/values'; export function buildAppIdentifiers(params: { session?: string; diff --git a/src/utils/screenshot-result.ts b/src/utils/screenshot-result.ts index 491dfa0169..09507e019e 100644 --- a/src/utils/screenshot-result.ts +++ b/src/utils/screenshot-result.ts @@ -1,6 +1,6 @@ import type { ScreenshotResultData } from '@agent-device/contracts/capture'; import type { ScreenshotOverlayRef } from '@agent-device/kernel/snapshot'; -import { isRecord, parsePoint, parseRect } from './parsing.ts'; +import { isRecord, parsePoint, parseRect } from '@agent-device/host-kit/values'; export function pickScreenshotResultData(value: ScreenshotResultData): ScreenshotResultData { return { diff --git a/src/utils/scroll-edge-state.ts b/src/utils/scroll-edge-state.ts index b5deaaae09..1695eea582 100644 --- a/src/utils/scroll-edge-state.ts +++ b/src/utils/scroll-edge-state.ts @@ -1,4 +1,4 @@ -import { deriveMobileSnapshotHiddenContentHints } from '../snapshot/mobile-snapshot-semantics.ts'; +import { deriveMobileSnapshotHiddenContentHints } from '@agent-device/capture-kit/mobile-snapshot-semantics'; import { isNodeVisibleInEffectiveViewport, isScrollableNodeLike, diff --git a/src/utils/source-value.test.ts b/src/utils/source-value.test.ts index 5f4d5cb4e6..167f05bc41 100644 --- a/src/utils/source-value.test.ts +++ b/src/utils/source-value.test.ts @@ -1,6 +1,9 @@ import { describe, expect, test } from 'vitest'; -import { buildPrimaryEnvVarName, parseSourceValue } from './source-value.ts'; -import type { SourceValueDefinition } from './source-value.ts'; +import { + buildPrimaryEnvVarName, + parseSourceValue, + type SourceValueDefinition, +} from '@agent-device/host-kit/values'; const LABEL = 'config file'; diff --git a/src/utils/swift-cache.ts b/src/utils/swift-cache.ts index 0b89e321c7..196d3afb4d 100644 --- a/src/utils/swift-cache.ts +++ b/src/utils/swift-cache.ts @@ -2,10 +2,10 @@ import { createHash } from 'node:crypto'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import { trimEdgeDashes } from '@agent-device/kernel/collections'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from './exec.ts'; -import { acquireProcessLock } from './process-lock.ts'; -import { readProcessStartTime } from './host-process.ts'; +import { runCmd, readProcessStartTime } from '@agent-device/host-kit/exec'; +import { acquireProcessLock } from '@agent-device/host-kit/fs'; const SWIFT_CACHE_VERSION = '2'; const LOCK_RETRY_DELAY_MS = 25; @@ -181,19 +181,6 @@ function sanitizeCacheName(value: string): string { return trimEdgeDashes(value.replaceAll(/[^A-Za-z0-9._-]/g, '-')) || 'swift-helper'; } -/** - * Linear-time edge trim. The regex form (`/^-+|-+$/g`) backtracks - * polynomially on long dash runs (CodeQL js/polynomial-redos), and cache - * names are derived from caller-supplied strings. - */ -function trimEdgeDashes(value: string): string { - let start = 0; - let end = value.length; - while (start < end && value[start] === '-') start += 1; - while (end > start && value[end - 1] === '-') end -= 1; - return value.slice(start, end); -} - function hashParts(parts: Array): string { const hash = createHash('sha256'); for (const part of parts) { diff --git a/src/utils/update-check.ts b/src/utils/update-check.ts index e4b828f092..f3f4df0762 100644 --- a/src/utils/update-check.ts +++ b/src/utils/update-check.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmdDetached } from './exec.ts'; +import { runCmdDetached } from '@agent-device/host-kit/exec'; const PACKAGE_NAME = 'agent-device'; const UPDATE_CHECK_INTERVAL_MS = 14 * 24 * 60 * 60 * 1000; diff --git a/src/utils/video.ts b/src/utils/video.ts index afd7c76344..d5cda8ac22 100644 --- a/src/utils/video.ts +++ b/src/utils/video.ts @@ -1,8 +1,8 @@ import fs from 'node:fs'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from './exec.ts'; +import { runCmd, sleep } from '@agent-device/host-kit/exec'; import { buildSwiftToolEnv, compileSwiftSourceText } from './swift-cache.ts'; -import { sleep } from './timeouts.ts'; + import { hasPlayableWebmStructure } from './video-webm.ts'; // Duration zero must pass: a recording of a fully static screen legitimately contains a single diff --git a/stryker.config.json b/stryker.config.json index 1ab0498448..35a3443c6a 100644 --- a/stryker.config.json +++ b/stryker.config.json @@ -22,6 +22,7 @@ "ignoreStatic": true, "tempDirName": ".tmp/stryker", "cleanTempDir": true, + "dryRunTimeoutMinutes": 15, "timeoutMS": 20000, "timeoutFactor": 2, "thresholds": { @@ -38,6 +39,6 @@ "!packages/selectors/src/**/*.test.ts", "!packages/selectors/src/internal/__tests__/**", "packages/ad-script/src/internal/target-annotation-serde.ts", - "src/snapshot/snapshot-occlusion.ts" + "packages/capture-kit/src/snapshot-occlusion.ts" ] } diff --git a/test/integration/android-emulator-e2e/live-form-scenario.ts b/test/integration/android-emulator-e2e/live-form-scenario.ts index 267160fc11..c99fe2abbf 100644 --- a/test/integration/android-emulator-e2e/live-form-scenario.ts +++ b/test/integration/android-emulator-e2e/live-form-scenario.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import path from 'node:path'; import { PUBLIC_COMMANDS } from '../../../src/command-catalog.ts'; -import { parseRect } from '../../../src/utils/parsing.ts'; +import { parseRect } from '@agent-device/host-kit/values'; import type { CliJsonResult } from '../cli-json.ts'; import { assertElementText, diff --git a/test/integration/cli-exit-flush.test.ts b/test/integration/cli-exit-flush.test.ts index fdc9fa3452..f1de1d70aa 100644 --- a/test/integration/cli-exit-flush.test.ts +++ b/test/integration/cli-exit-flush.test.ts @@ -2,7 +2,7 @@ import test from 'node:test'; import assert from 'node:assert/strict'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmd } from '../../src/utils/exec.ts'; +import { runCmd } from '@agent-device/host-kit/exec'; import { PAYLOAD_MARKER } from './support/exit-payload.ts'; const SUPPORT_DIR = path.join(import.meta.dirname, 'support'); diff --git a/test/integration/cli-json.ts b/test/integration/cli-json.ts index 707469f166..3845dbf3ed 100644 --- a/test/integration/cli-json.ts +++ b/test/integration/cli-json.ts @@ -1,4 +1,4 @@ -import { runCmd, runCmdSync, type ExecResult } from '../../src/utils/exec.ts'; +import { runCmd, runCmdSync, type ExecResult } from '@agent-device/host-kit/exec'; const CLI_TIMEOUT_MS = 120_000; diff --git a/test/integration/client-api-doc-snippets.test.ts b/test/integration/client-api-doc-snippets.test.ts index 1fd046c4a9..37868cbfc0 100644 --- a/test/integration/client-api-doc-snippets.test.ts +++ b/test/integration/client-api-doc-snippets.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import assert from 'node:assert/strict'; import test from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; // Compiles every fenced ```ts snippet in website/docs/docs/client-api.md against // agent-device's real `agent-device/*` subpath sources, so a doc snippet that no diff --git a/test/integration/daemon-leak-oracle-cli.test.ts b/test/integration/daemon-leak-oracle-cli.test.ts index b150925f0f..d68fdf12b4 100644 --- a/test/integration/daemon-leak-oracle-cli.test.ts +++ b/test/integration/daemon-leak-oracle-cli.test.ts @@ -3,8 +3,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { runCmdSync } from '../../src/utils/exec.ts'; -import { readProcessCommand, readProcessStartTime } from '../../src/utils/host-process.ts'; +import { runCmdSync, readProcessCommand, readProcessStartTime } from '@agent-device/host-kit/exec'; // #1781 B1: the oracle's `after-close` checkpoint is only meaningful when it can // name the sessions that closed — without them it would accept every unfinalized diff --git a/test/integration/daemon-replace-exit-flush.test.ts b/test/integration/daemon-replace-exit-flush.test.ts index b3009a4085..6331d51972 100644 --- a/test/integration/daemon-replace-exit-flush.test.ts +++ b/test/integration/daemon-replace-exit-flush.test.ts @@ -5,7 +5,7 @@ import os from 'node:os'; import path from 'node:path'; import { skipWhenLoopbackUnavailable } from '../../src/__tests__/test-utils/loopback.ts'; import { stopProcessForTakeover } from '../../src/daemon/daemon-process.ts'; -import { isProcessAlive } from '../../src/utils/host-process.ts'; +import { isProcessAlive } from '@agent-device/host-kit/exec'; import { assertNoDaemonLeaks } from './support/daemon-leak-oracle.ts'; import { runCliJson } from './test-helpers.ts'; diff --git a/test/integration/installed-package-metro.test.ts b/test/integration/installed-package-metro.test.ts index 38b7eca89d..d1d8ba0ece 100644 --- a/test/integration/installed-package-metro.test.ts +++ b/test/integration/installed-package-metro.test.ts @@ -8,7 +8,7 @@ import path from 'node:path'; import type { Duplex } from 'node:stream'; import { fileURLToPath } from 'node:url'; import { closeLoopbackServer, listenOnLoopback } from '../../src/__tests__/test-utils/loopback.ts'; -import { runCmd, runCmdSync } from '../../src/utils/exec.ts'; +import { runCmd, runCmdSync } from '@agent-device/host-kit/exec'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..'); const SUBPROCESS_TIMEOUT_MS = 120_000; diff --git a/test/integration/ios-simulator-e2e/snapshot-backend-conformance.ts b/test/integration/ios-simulator-e2e/snapshot-backend-conformance.ts index 57234dc68d..964145a20f 100644 --- a/test/integration/ios-simulator-e2e/snapshot-backend-conformance.ts +++ b/test/integration/ios-simulator-e2e/snapshot-backend-conformance.ts @@ -11,7 +11,7 @@ import { type SnapshotCaptureBackend, type SnapshotPreferredBackend, } from '@agent-device/kernel/snapshot'; -import { SNAPSHOT_BACKEND_CAPABILITIES } from '../../../src/snapshot-quality/backend-capabilities.ts'; +import { SNAPSHOT_BACKEND_CAPABILITIES } from '@agent-device/capture-kit/snapshot-quality-backend-capabilities'; import { isSemanticTouchTarget } from '../../../src/core/touch-semantics.ts'; export type SnapshotBackendConformanceFixture = { diff --git a/test/integration/limrun-public-types.test.ts b/test/integration/limrun-public-types.test.ts index 58de67d275..c91d55b68e 100644 --- a/test/integration/limrun-public-types.test.ts +++ b/test/integration/limrun-public-types.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import test from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..'); const TSC_BIN = path.join(repoRoot, 'node_modules/.bin/tsc'); diff --git a/test/integration/provider-scenarios/active-session-script-publication.test.ts b/test/integration/provider-scenarios/active-session-script-publication.test.ts index 412de427b4..7af4418f83 100644 --- a/test/integration/provider-scenarios/active-session-script-publication.test.ts +++ b/test/integration/provider-scenarios/active-session-script-publication.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { emitDiagnostic } from '../../../src/utils/diagnostics.ts'; +import { emitDiagnostic } from '@agent-device/host-kit/exec'; import { INTERNAL_COMMANDS } from '../../../src/command-catalog.ts'; import { test } from 'vitest'; import { assertRpcError, assertRpcOk } from './assertions.ts'; diff --git a/test/integration/provider-scenarios/android-world.ts b/test/integration/provider-scenarios/android-world.ts index fe14a0347a..bc88ad9858 100644 --- a/test/integration/provider-scenarios/android-world.ts +++ b/test/integration/provider-scenarios/android-world.ts @@ -14,7 +14,7 @@ import { ANDROID_SNAPSHOT_HELPER_FIXTURE_ARTIFACT, androidSnapshotHelperOutput, } from '../../../src/__tests__/test-utils/android-snapshot-helper.ts'; -import { runCmd, runCmdBackground } from '../../../src/utils/exec.ts'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; import { validPng } from './assertions.ts'; import { PROVIDER_SCENARIO_ANDROID } from './fixtures.ts'; import { diff --git a/test/integration/provider-scenarios/assertions.ts b/test/integration/provider-scenarios/assertions.ts index 0557d16983..a1f023a1b3 100644 --- a/test/integration/provider-scenarios/assertions.ts +++ b/test/integration/provider-scenarios/assertions.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; -import { PNG } from '../../../src/utils/png.ts'; +import { PNG } from '@agent-device/capture-kit/png'; import type { ProviderScenarioRpcResult } from './harness.ts'; export function assertCommandCall(calls: readonly string[][], expected: readonly string[]): void { 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 b579981fac..5f1a600156 100644 --- a/test/integration/provider-scenarios/daemon-http-boundary-cancellation.test.ts +++ b/test/integration/provider-scenarios/daemon-http-boundary-cancellation.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import http from 'node:http'; import { test } from 'vitest'; -import { getRequestSignal } from '../../../src/request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/types.ts'; import { diff --git a/test/integration/provider-scenarios/daemon-http-disconnect.test.ts b/test/integration/provider-scenarios/daemon-http-disconnect.test.ts index 1809626df2..75ac7346bd 100644 --- a/test/integration/provider-scenarios/daemon-http-disconnect.test.ts +++ b/test/integration/provider-scenarios/daemon-http-disconnect.test.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import http from 'node:http'; import { test } from 'vitest'; -import { getRequestSignal } from '../../../src/request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/types.ts'; import { diff --git a/test/integration/provider-scenarios/daemon-http-server.test.ts b/test/integration/provider-scenarios/daemon-http-server.test.ts index 572e7c3762..576432d81f 100644 --- a/test/integration/provider-scenarios/daemon-http-server.test.ts +++ b/test/integration/provider-scenarios/daemon-http-server.test.ts @@ -13,8 +13,12 @@ import { } from '../../../src/daemon/artifact-tracking.ts'; import { DAEMON_RPC_PROTOCOL_VERSION } from '../../../src/daemon/http-health.ts'; import { createDaemonHttpServer } from '../../../src/daemon/server/http-server.ts'; -import { emitRequestProgress } from '../../../src/request/progress.ts'; -import { getRequestSignal, isRequestCanceled } from '../../../src/request/cancel.ts'; +import { + emitRequestProgress, + getRequestSignal, + isRequestCanceled, +} from '@agent-device/host-kit/request'; + import type { DaemonRequest, DaemonResponse } from '../../../src/daemon/types.ts'; import { closeLoopbackServer, diff --git a/test/integration/provider-scenarios/daemon-transport.test.ts b/test/integration/provider-scenarios/daemon-transport.test.ts index 76609be106..2520764e56 100644 --- a/test/integration/provider-scenarios/daemon-transport.test.ts +++ b/test/integration/provider-scenarios/daemon-transport.test.ts @@ -8,7 +8,7 @@ import { listenHttpServer, listenNetServer, } from '../../../src/daemon/server/transport.ts'; -import { getRequestSignal } from '../../../src/request/cancel.ts'; +import { getRequestSignal } from '@agent-device/host-kit/request'; import { closeLoopbackServer, skipWhenLoopbackUnavailable, diff --git a/test/integration/provider-scenarios/harness.ts b/test/integration/provider-scenarios/harness.ts index 4365446f3f..b8a0e99433 100644 --- a/test/integration/provider-scenarios/harness.ts +++ b/test/integration/provider-scenarios/harness.ts @@ -22,7 +22,7 @@ import { trackDownloadableArtifact } from '../../../src/daemon/artifact-tracking import { LeaseRegistry } from '../../../src/daemon/lease-registry.ts'; import { SessionStore } from '../../../src/daemon/session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../../../src/daemon/types.ts'; -import { runCmdBackground } from '../../../src/utils/exec.ts'; +import { runCmdBackground, createOwnedProcessRecordStore } from '@agent-device/host-kit/exec'; import { withClientReplayScriptSources } from '../../../src/__tests__/test-utils/replay-script-source.ts'; import type { DeviceInventoryProvider, @@ -37,7 +37,7 @@ 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 { unavailableDeviceRuntimeGateway } from '../../../src/daemon/__tests__/test-device-runtime-gateway.ts'; -import { createOwnedProcessRecordStore } from '../../../src/utils/owned-process-record.ts'; + import { openWebSessionNames } from '../../../src/daemon/web-session-names.ts'; const PROVIDER_SCENARIO_TOKEN = 'provider-scenario-token'; diff --git a/test/integration/provider-scenarios/providers.ts b/test/integration/provider-scenarios/providers.ts index ddac165f6a..c858c16236 100644 --- a/test/integration/provider-scenarios/providers.ts +++ b/test/integration/provider-scenarios/providers.ts @@ -6,7 +6,7 @@ import type { AppleToolProvider, AppleToolSubcommandExecutor, } from '../../../src/platforms/apple/core/tool-provider.ts'; -import type { ExecResult } from '../../../src/utils/exec.ts'; +import type { ExecResult } from '@agent-device/host-kit/exec'; import type { ProviderScenarioTranscript } from './transcript.ts'; export type FlatToolCall = [string, ...string[]]; diff --git a/test/integration/smoke-clean-xcuitest-derived.test.ts b/test/integration/smoke-clean-xcuitest-derived.test.ts index d989d601d7..9114f95bad 100644 --- a/test/integration/smoke-clean-xcuitest-derived.test.ts +++ b/test/integration/smoke-clean-xcuitest-derived.test.ts @@ -4,7 +4,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..'); const scriptPath = path.join(repoRoot, 'scripts', 'clean-xcuitest-derived.mjs'); diff --git a/test/integration/smoke-cli.test.ts b/test/integration/smoke-cli.test.ts index 2ab1a7d188..b0055d21a1 100644 --- a/test/integration/smoke-cli.test.ts +++ b/test/integration/smoke-cli.test.ts @@ -1,6 +1,6 @@ import test from 'node:test'; import assert from 'node:assert/strict'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; function runCli(args: string[]): { status: number; stdout: string; stderr: string } { const result = runCmdSync( diff --git a/test/integration/smoke-daemon-clean.test.ts b/test/integration/smoke-daemon-clean.test.ts index 2d39ff29b1..7a861eb6f2 100644 --- a/test/integration/smoke-daemon-clean.test.ts +++ b/test/integration/smoke-daemon-clean.test.ts @@ -4,9 +4,9 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { skipWhenLoopbackUnavailable } from '../../src/__tests__/test-utils/loopback.ts'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync, isProcessAlive } from '@agent-device/host-kit/exec'; import { stopProcessForTakeover } from '../../src/daemon/daemon-process.ts'; -import { isProcessAlive } from '../../src/utils/host-process.ts'; + import { assertNoDaemonLeaks } from './support/daemon-leak-oracle.ts'; import { runCliJson } from './test-helpers.ts'; diff --git a/test/integration/smoke-web-platform.test.ts b/test/integration/smoke-web-platform.test.ts index 29a054f239..191dd1fea6 100644 --- a/test/integration/smoke-web-platform.test.ts +++ b/test/integration/smoke-web-platform.test.ts @@ -28,7 +28,7 @@ import { listHostProcesses, readProcessStartTime, stopPidsWithEscalation, -} from '../../src/utils/host-process.ts'; +} from '@agent-device/host-kit/exec'; const TEST_NAME = 'live web platform e2e smoke'; const SHUTDOWN_TEST_NAME = 'live web platform e2e daemon-shutdown browser cleanup'; diff --git a/test/integration/support/daemon-leak-model.ts b/test/integration/support/daemon-leak-model.ts index 14684e2e93..fcfced1cd3 100644 --- a/test/integration/support/daemon-leak-model.ts +++ b/test/integration/support/daemon-leak-model.ts @@ -27,7 +27,7 @@ // still live, or no longer matches and therefore cannot be // proved dead. The latter fails closed rather than allowing // pid reuse to turn unknown evidence into a green checkpoint. -import { uniquePositivePids } from '../../../src/utils/host-process.ts'; +import { uniquePositivePids } from '@agent-device/host-kit/exec'; import type { OwnedProcessRecord } from '@agent-device/contracts/platform-runtime-host'; export type DaemonLeakPhase = 'after-close' | 'after-shutdown'; diff --git a/test/integration/support/daemon-leak-oracle.ts b/test/integration/support/daemon-leak-oracle.ts index baf6084b38..7439ed93b6 100644 --- a/test/integration/support/daemon-leak-oracle.ts +++ b/test/integration/support/daemon-leak-oracle.ts @@ -8,8 +8,9 @@ import { isProcessAlive, readHostProcessIdentityObservations, readProcessCommand, -} from '../../../src/utils/host-process.ts'; -import { readOwnedProcessRecordFile } from '../../../src/utils/owned-process-record.ts'; + readOwnedProcessRecordFile, +} from '@agent-device/host-kit/exec'; + import { AppError } from '@agent-device/kernel/errors'; import type { OwnedProcessRecord } from '@agent-device/contracts/platform-runtime-host'; import { diff --git a/test/integration/test-helpers.ts b/test/integration/test-helpers.ts index 73418354e9..d7affeea05 100644 --- a/test/integration/test-helpers.ts +++ b/test/integration/test-helpers.ts @@ -1,8 +1,8 @@ import assert from 'node:assert/strict'; import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'; import path from 'node:path'; -import { PNG } from '../../src/utils/png.ts'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { PNG } from '@agent-device/capture-kit/png'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { type CliJsonResult, formatResultDebug, runSourceCliJsonSync } from './cli-json.ts'; const RECORDING_INSPECT_TIMEOUT_MS = 60_000; diff --git a/test/output-economy/output-economy.baseline.test.ts b/test/output-economy/output-economy.baseline.test.ts index a798739a93..c5c1eabf53 100644 --- a/test/output-economy/output-economy.baseline.test.ts +++ b/test/output-economy/output-economy.baseline.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { describe, expect, test } from 'vitest'; import { defaultHintForCode, retriableForErrorCode } from '@agent-device/kernel/errors'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { findEconomyBudgetIncreases, formatEconomyBudgetIncreases, diff --git a/test/output-economy/owner-files-no-leak.test.ts b/test/output-economy/owner-files-no-leak.test.ts index a87e47208b..7c4d33e39c 100644 --- a/test/output-economy/owner-files-no-leak.test.ts +++ b/test/output-economy/owner-files-no-leak.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '../../src/utils/exec.ts'; +import { runCmdSync } from '@agent-device/host-kit/exec'; import { COMMAND_OWNER_FILES } from '../../src/core/command-descriptor/owner-files.ts'; import { getDaemonRouteOwnerFiles } from '../../src/daemon/route-owner-files.ts'; diff --git a/tsdown.config.ts b/tsdown.config.ts index a94ac7dc19..1277f297d8 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -71,7 +71,7 @@ export default defineConfig({ 'internal/bin': 'src/bin.ts', 'internal/companion-tunnel': 'src/client/companion-tunnel.ts', 'internal/daemon': 'src/daemon.ts', - 'internal/png-worker': 'src/utils/png-worker.ts', + 'internal/png-worker': 'packages/capture-kit/src/png-worker.ts', 'internal/update-check-entry': 'src/utils/update-check-entry.ts', }, deps: { diff --git a/vitest.mutation.config.ts b/vitest.mutation.config.ts index 9b73834fa7..9491794ad8 100644 --- a/vitest.mutation.config.ts +++ b/vitest.mutation.config.ts @@ -8,7 +8,7 @@ import { SERIALIZED_TESTS, SETUP_FILES } from './vitest.config.ts'; const repoRoot = path.dirname(fileURLToPath(import.meta.url)); // Workspace-package aliases for the Stryker sandbox (#1490 W0). Stryker copies -// the tree into .stryker-tmp and symlinks node_modules back to the real repo, +// the tree into .tmp/stryker and symlinks node_modules back to the real repo, // so a `@agent-device/*` specifier resolved through pnpm's link escapes the // sandbox: mutants written into the sandbox copy never load, and // `vitest related` finds no tests for a mutated package file. Aliasing each @@ -16,7 +16,11 @@ const repoRoot = path.dirname(fileURLToPath(import.meta.url)); // which Stryker copies into the sandbox — keeps resolution inside the mutated // tree. Entries come from the shared exports-map reader, never a wildcard, so // this cannot resolve package internals the boundary forbids (R11). -const workspaceAliases = workspaceSourceAliases(repoRoot); +const inStrykerSandbox = repoRoot.includes(path.join('.tmp', 'stryker')); +const workspaceAliases = workspaceSourceAliases( + repoRoot, + inStrykerSandbox ? 'disk-manifests' : 'tracked-manifests', +); // Test scope for the decision-kernel mutation lane (issue #1415). // From 794fe4bb5ab6348257481413be0407389b7f4070 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 18:55:43 +0000 Subject: [PATCH 2/8] refactor(host-kit): one narrow capability port per export The four technical barrels (exec/fs/values/request) grouped by category rather than by capability, so a consumer needing one mechanic evaluated unrelated ones. Each export is now a single capability over the host machine: command, process, diagnostics, retry, archive, file, request, version. A port re-exports only what a consumer of that capability uses, and every port carries its own eager-closure row. Most of the old values barrel was never host mechanics. Pure record readers, config-source values, result text, memoization, async scoping, coordinate validation, and device-scope parsing touch no process, file, or environment, so they join kernel's other primitives instead. Closures fall accordingly: capture-kit's png-worker-client from 20 to 10, png-resize from 28 to 18, session-teardown from 79 to 68, and the CLI from 386 to 380. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- .../0019-request-bound-platform-runtime.md | 17 +- packages/capture-kit/src/png-worker-client.ts | 2 +- packages/host-kit/package.json | 36 +++- packages/host-kit/src/archive.ts | 4 + packages/host-kit/src/command.ts | 24 +++ packages/host-kit/src/diagnostics.ts | 11 + packages/host-kit/src/exec.ts | 77 ------- packages/host-kit/src/file.ts | 7 + packages/host-kit/src/fs.ts | 22 -- packages/host-kit/src/internal/env-map.ts | 1 - packages/host-kit/src/internal/exec.ts | 2 +- .../host-kit/src/internal/method-scope.ts | 18 -- .../host-kit/src/internal/path-resolution.ts | 2 +- .../host-kit/src/internal/version.test.ts | 2 +- packages/host-kit/src/internal/version.ts | 2 +- packages/host-kit/src/process.ts | 32 +++ packages/host-kit/src/request.ts | 1 - packages/host-kit/src/retry.ts | 2 + packages/host-kit/src/values.ts | 39 ---- packages/host-kit/src/version.ts | 1 + packages/kernel/package.json | 28 +++ .../src}/device-isolation.ts | 0 .../src}/location-coordinates.ts | 0 .../parsing.ts => kernel/src/record.ts} | 0 .../src}/scoped-provider.ts | 19 ++ .../internal => kernel/src}/source-value.ts | 2 + .../internal => kernel/src}/success-text.ts | 0 .../internal => kernel/src}/ttl-memo.test.ts | 0 .../src/internal => kernel/src}/ttl-memo.ts | 0 scratch-exports.json | 198 ++++++++++++++++++ scratch-symbol-map.json | 148 +++++++++++++ .../__tests__/fallow-fixture-policy.test.ts | 2 +- .../__tests__/test-file-size-ratchet.test.ts | 4 +- scripts/check-affected/run.test.ts | 2 +- scripts/check-affected/run.ts | 2 +- scripts/check-replay-compat-provenance.ts | 2 +- scripts/check-tmpdir-leaks-model.ts | 2 +- scripts/check-xctest-selection.ts | 2 +- scripts/coverage-changed/run.ts | 2 +- scripts/fuzz/envelope.ts | 2 +- scripts/gate/check.ts | 2 +- scripts/gate/run.ts | 2 +- scripts/layering/package-boundaries.test.ts | 15 +- scripts/lib/repo-git.ts | 2 +- scripts/mutation/envelope.test.ts | 2 +- scripts/mutation/run.ts | 2 +- scripts/mutation/selection.test.ts | 2 +- scripts/mutation/test-scope.ts | 2 +- scripts/node-test-tmpdir.test.ts | 4 +- scripts/node-test-tmpdir.ts | 2 +- scripts/perf/cli.ts | 2 +- scripts/swift-toolchain-tmpdir.test.ts | 2 +- scripts/swift-toolchain-tmpdir.ts | 2 +- scripts/vitest-tmpdir-global-setup.test.ts | 2 +- .../apple-runner-package-source.test.ts | 2 +- src/__tests__/cli-agent-cdp.test.ts | 4 +- src/__tests__/cli-auth-diagnostics.test.ts | 2 +- src/__tests__/cli-debug-symbols.test.ts | 2 +- src/__tests__/cli-device-status.test.ts | 4 +- src/__tests__/cli-react-devtools.test.ts | 4 +- src/__tests__/cli-web.test.ts | 2 +- src/__tests__/client-metro-companion.test.ts | 11 +- .../client-metro-startup-cleanup.test.ts | 10 +- src/__tests__/client-metro.test.ts | 2 +- src/__tests__/daemon-entrypoint.test.ts | 3 +- src/__tests__/eager-closure-budgets.ts | 29 ++- src/__tests__/limrun-runtime.test.ts | 8 +- src/__tests__/process-memo-setup.ts | 2 +- .../test-utils/device-claim-store.ts | 2 +- src/__tests__/test-utils/exec-faults.ts | 6 +- src/__tests__/test-utils/fake-apple-tool.ts | 2 +- .../test-utils/filesystem-boundary-faults.ts | 2 +- src/__tests__/test-utils/host-process-mock.ts | 6 +- src/__tests__/update-check.test.ts | 4 +- src/__tests__/upload-client.test.ts | 2 +- src/agent-device-client.ts | 2 +- src/bin.ts | 2 +- src/cli-schema/cli-config.ts | 4 +- src/cli-schema/cli-help-examples.test.ts | 2 +- src/cli-schema/cli-help.ts | 2 +- src/cli-schema/option-schema.ts | 2 +- src/cli.ts | 4 +- src/cli/auth-session.ts | 4 +- src/cli/commands/agent-cdp.ts | 2 +- src/cli/commands/connection-presentation.ts | 2 +- src/cli/commands/connection.ts | 2 +- src/cli/commands/device.ts | 2 +- src/cli/commands/generic.ts | 2 +- src/cli/commands/react-devtools.ts | 2 +- src/cli/commands/replay.ts | 2 +- src/cli/commands/screenshot.ts | 2 +- src/cli/connection/cloud-profile.ts | 2 +- src/cli/connection/cloud-webdriver-profile.ts | 2 +- .../connection/connect-provider-adapters.ts | 3 +- src/cli/connection/generated-config.ts | 2 +- src/cli/connection/limrun-profile.ts | 2 +- src/cli/connection/proxy-profile.ts | 2 +- src/cli/resolve-cli-options.ts | 2 +- src/client/client-companion-tunnel.ts | 4 +- src/client/client-normalizers.ts | 4 +- src/commands/batch/output.ts | 2 +- src/commands/capture/runtime/screenshot.ts | 2 +- src/commands/capture/settings.ts | 2 +- src/commands/command-flags.ts | 2 +- src/commands/input-audience.ts | 2 +- src/commands/interaction/output.ts | 2 +- .../interaction/runtime/gesture-command.ts | 2 +- src/commands/interaction/runtime/gestures.ts | 2 +- src/commands/management/output.ts | 2 +- src/commands/management/runtime/admin.ts | 2 +- src/commands/management/runtime/apps.ts | 2 +- src/commands/output-common.ts | 2 +- src/commands/perf/output.ts | 2 +- src/commands/recording/runtime/recording.ts | 2 +- src/commands/system/runtime/system.ts | 2 +- src/core/batch.ts | 2 +- src/core/dispatch-resolve.ts | 4 +- src/core/interactors/android.ts | 4 +- src/core/interactors/harmonyos.ts | 2 +- src/core/interactors/linux.ts | 2 +- src/core/interactors/web.ts | 2 +- src/core/lease-scope.ts | 2 +- .../android-dialog-readiness.test.ts | 5 +- src/daemon/__tests__/daemon-exit-wait.test.ts | 4 +- .../__tests__/daemon-process-takeover.test.ts | 2 +- src/daemon/__tests__/daemon-stop.test.ts | 7 +- .../deferred-interaction-outcome.test.ts | 5 +- .../__tests__/device-claim-prune.test.ts | 6 +- src/daemon/__tests__/device-claims.test.ts | 4 +- src/daemon/__tests__/device-ready.test.ts | 4 +- ...rable-capture-resource-transitions.test.ts | 5 +- .../filesystem-boundary-faults.test.ts | 2 +- .../__tests__/http-server-artifacts.test.ts | 2 +- .../post-gesture-no-effect-claim.test.ts | 5 +- .../post-gesture-stabilization.test.ts | 5 +- .../__tests__/request-execution-scope.test.ts | 2 +- .../request-router-android-modal.test.ts | 4 +- .../__tests__/request-router-cost.test.ts | 2 +- .../__tests__/request-router-open.test.ts | 4 +- .../request-router-session-address.test.ts | 4 +- src/daemon/__tests__/resumable-upload.test.ts | 2 +- src/daemon/__tests__/runtime-session.test.ts | 5 +- .../screen-recording-boundary-faults.test.ts | 5 +- src/daemon/__tests__/upload.test.ts | 2 +- .../__tests__/daemon-runtime-port.test.ts | 2 +- .../maestro/daemon-runtime-port-support.ts | 2 +- .../adapters/maestro/daemon-runtime-port.ts | 4 +- .../adapters/maestro/daemon-runtime-tap.ts | 2 +- .../maestro/maestro-screenshot-comparison.ts | 2 +- .../adapters/maestro/run-script-execution.ts | 4 +- .../android-snapshot-timeout-evidence.ts | 2 +- src/daemon/android-system-dialog.ts | 3 +- src/daemon/app-event-runtime.ts | 2 +- src/daemon/app-switcher-runtime.ts | 2 +- src/daemon/artifact-archive.ts | 2 +- src/daemon/artifact-download.ts | 5 +- src/daemon/artifact-tracking.ts | 2 +- src/daemon/back-runtime.ts | 2 +- .../boundary-fault-transport.test.ts | 6 +- .../daemon-client-timeout-route.test.ts | 6 +- .../__tests__/daemon-launch-spec.test.ts | 2 +- src/daemon/client/daemon-client-lifecycle.ts | 8 +- src/daemon/client/daemon-client-metadata.ts | 3 +- src/daemon/client/daemon-client-rpc.ts | 2 +- src/daemon/client/daemon-client-timeout.ts | 3 +- src/daemon/client/daemon-client-transport.ts | 4 +- src/daemon/client/daemon-client.ts | 6 +- src/daemon/client/daemon-launch-spec.ts | 3 +- src/daemon/code-signature-cache.ts | 2 +- src/daemon/code-signature.ts | 2 +- src/daemon/config.ts | 5 +- src/daemon/context.ts | 2 +- src/daemon/daemon-process.ts | 4 +- src/daemon/daemon-registration.ts | 2 +- src/daemon/daemon-shutdown-report.ts | 2 +- src/daemon/daemon-stop.ts | 3 +- src/daemon/deferred-interaction-outcome.ts | 2 +- src/daemon/device-claim-admission.ts | 2 +- src/daemon/device-claim-conflict.ts | 2 +- src/daemon/device-claim-inspection.ts | 2 +- src/daemon/device-claim-reconciliation.ts | 2 +- src/daemon/device-claims.ts | 9 +- src/daemon/device-ready.ts | 2 +- .../durable-capture-resource-adoption.ts | 2 +- .../durable-capture-resource-recovery.ts | 2 +- src/daemon/durable-capture-resource-store.ts | 2 +- .../durable-capture-resource-transitions.ts | 2 +- src/daemon/focus-runtime.ts | 2 +- .../session-close-shutdown.fixtures.ts | 8 +- .../__tests__/session-device-claims.test.ts | 2 +- .../session-open-execution-runtime.test.ts | 4 +- .../__tests__/session-open-runtime.test.ts | 4 +- .../session-replay-divergence.test.ts | 4 +- ...ion-replay-repair-record-exclusion.test.ts | 4 +- .../session-replay-repair-transaction.test.ts | 4 +- ...replay-target-verification-runtime.test.ts | 4 +- .../__tests__/session-test-harness.ts | 6 +- src/daemon/handlers/find.ts | 2 +- src/daemon/handlers/interaction-gesture.ts | 2 +- .../handlers/interaction-ios-tap-outcome.ts | 2 +- src/daemon/handlers/interaction-read.ts | 2 +- .../interaction-touch-android-freshness.ts | 2 +- .../handlers/interaction-touch-direct-ios.ts | 2 +- .../handlers/interaction-touch-payload.ts | 2 +- .../interaction-touch-reference-frame.ts | 2 +- src/daemon/handlers/react-native.ts | 3 +- src/daemon/handlers/session-app-deployment.ts | 2 +- .../handlers/session-app-source-deployment.ts | 2 +- src/daemon/handlers/session-clipboard.ts | 2 +- src/daemon/handlers/session-close-script.ts | 2 +- src/daemon/handlers/session-close.ts | 4 +- src/daemon/handlers/session-doctor-metro.ts | 2 +- src/daemon/handlers/session-doctor.ts | 4 +- src/daemon/handlers/session-inventory.ts | 2 +- src/daemon/handlers/session-open-execution.ts | 2 +- src/daemon/handlers/session-open-surface.ts | 2 +- .../handlers/session-replay-divergence.ts | 2 +- .../session-replay-maestro-observer.ts | 2 +- .../session-replay-maestro-runtime.ts | 2 +- src/daemon/handlers/session-replay-trace.ts | 2 +- .../session-replay-video-recording.ts | 3 +- .../handlers/session-script-publication.ts | 2 +- src/daemon/handlers/session-state.ts | 2 +- .../handlers/session-test-shard-devices.ts | 2 +- .../handlers/session-test-suite-command.ts | 2 +- src/daemon/handlers/snapshot-settings.ts | 9 +- src/daemon/home-runtime.ts | 2 +- src/daemon/http-health.ts | 2 +- src/daemon/interaction-outcome-policy.ts | 2 +- src/daemon/ios-app-session-hint.ts | 2 +- src/daemon/keyboard-runtime.ts | 2 +- src/daemon/lease-context.ts | 2 +- src/daemon/lease-lifecycle.ts | 2 +- src/daemon/orientation-runtime.ts | 2 +- src/daemon/platform-request-scope.ts | 2 +- src/daemon/post-gesture-stability.ts | 3 +- src/daemon/provider-lease-expiry.ts | 5 +- src/daemon/recording-gestures.ts | 2 +- src/daemon/request-execution-scope.ts | 2 +- src/daemon/request-finalization.ts | 2 +- src/daemon/request-lock-policy.ts | 2 +- src/daemon/request-router.ts | 2 +- src/daemon/request-save-script-policy.ts | 2 +- src/daemon/resumable-upload-transfer.ts | 2 +- src/daemon/runtime-session.ts | 2 +- src/daemon/scroll-runtime.ts | 2 +- src/daemon/server/daemon-idle-reap.ts | 2 +- .../daemon-runtime-web-close-teardown.test.ts | 6 +- src/daemon/server/daemon-runtime.ts | 7 +- .../server/daemon-session-lease-finalizer.ts | 2 +- src/daemon/server/daemon-shutdown-claims.ts | 2 +- src/daemon/server/http-server.ts | 2 +- src/daemon/server/server-lifecycle.ts | 4 +- src/daemon/server/transport.ts | 2 +- src/daemon/session-action-recorder.ts | 2 +- src/daemon/session-event-log-window.ts | 2 +- src/daemon/session-event-log.ts | 4 +- src/daemon/session-event-request.ts | 2 +- src/daemon/session-paths.ts | 2 +- src/daemon/session-recovery-hints.ts | 2 +- src/daemon/session-script-writer.ts | 4 +- src/daemon/session-selector.ts | 2 +- src/daemon/session-store.ts | 4 +- src/daemon/session-teardown.ts | 2 +- src/daemon/touch-runtime.ts | 2 +- src/daemon/tv-remote-runtime.ts | 2 +- src/daemon/type-text-runtime.ts | 2 +- src/mcp/command-tools.ts | 2 +- src/mcp/protocol-era.ts | 2 +- src/mcp/tool-ref-pins.ts | 2 +- src/metro/client-metro.ts | 6 +- ...tform-runtime-android-application-tools.ts | 2 +- src/platform-runtime-android-emulator-host.ts | 3 +- src/platform-runtime-app-log-process.test.ts | 7 +- src/platform-runtime-app-log-process.ts | 4 +- ...latform-runtime-apple-application-tools.ts | 2 +- src/platform-runtime-host.ts | 2 +- src/platform-runtime-operation-host.ts | 2 +- src/platform-runtime-resource-cleanup.ts | 3 +- src/platform-runtime-runtime-hints.ts | 2 +- ...m-runtime-screen-recording-android-host.ts | 2 +- ...screen-recording-apple-runner-transport.ts | 4 +- ...een-recording-apple-simulator-host.test.ts | 4 +- ...untime-screen-recording-apple-transport.ts | 6 +- ...time-screen-recording-process-host.test.ts | 4 +- ...m-runtime-screen-recording-process-host.ts | 2 +- src/platform-runtime/request-providers.ts | 2 +- .../__tests__/install-source.test.ts | 2 +- .../android/__tests__/adb-executor.test.ts | 6 +- .../__tests__/adb-provider-scope.test.ts | 2 +- .../__tests__/device-input-state.test.ts | 5 +- .../__tests__/emulator-lifecycle.test.ts | 6 +- .../__tests__/ime-helper-security.test.ts | 2 +- .../snapshot-capture-failure-reason.test.ts | 4 +- .../__tests__/snapshot-clickability.test.ts | 4 +- .../__tests__/snapshot-helper-session.test.ts | 2 +- .../snapshot-occlusion-context.test.ts | 4 +- .../android/__tests__/snapshot.test.ts | 8 +- .../__tests__/text-input-test-ime.test.ts | 5 +- src/platforms/android/adb-host-binding.ts | 4 +- src/platforms/android/adb.ts | 2 +- src/platforms/android/alert.ts | 5 +- src/platforms/android/app-deployment.ts | 2 +- src/platforms/android/app-lifecycle.ts | 3 +- src/platforms/android/device-input-state.ts | 3 +- src/platforms/android/emulator-lifecycle.ts | 10 +- src/platforms/android/fill-verification.ts | 2 +- .../android/helper-package-install.ts | 2 +- src/platforms/android/ime-recovery-marker.ts | 2 +- src/platforms/android/manifest.ts | 2 +- .../android/perf-native-artifacts.ts | 2 +- src/platforms/android/perf-native-report.ts | 2 +- src/platforms/android/perf.ts | 2 +- src/platforms/android/settings.ts | 2 +- .../android/snapshot-helper-capture.ts | 2 +- .../android/snapshot-helper-runtime.ts | 2 +- .../snapshot-helper-session-lifecycle.ts | 2 +- .../android/snapshot-helper-session.ts | 2 +- src/platforms/android/snapshot.ts | 4 +- src/platforms/android/text-input.ts | 3 +- src/platforms/android/touch-helper.ts | 7 +- src/platforms/apple/alert.ts | 2 +- .../core/__tests__/app-launch-url.test.ts | 6 +- .../apple/core/__tests__/apps.test.ts | 26 +-- .../core/__tests__/debug-symbols.test.ts | 2 +- .../__tests__/install-artifact.fixtures.ts | 2 +- .../apple/core/__tests__/perf.test.ts | 6 +- .../apple/core/__tests__/plist.test.ts | 6 +- .../apple/core/__tests__/screenshot.test.ts | 26 +-- .../apple/core/__tests__/simulator.test.ts | 10 +- src/platforms/apple/core/app-device-io.ts | 2 +- src/platforms/apple/core/app-launch.ts | 9 +- src/platforms/apple/core/app-resolution.ts | 2 +- src/platforms/apple/core/app-settings.ts | 6 +- .../core/debug-symbols/crash-artifact.ts | 2 +- .../apple/core/debug-symbols/dsym.ts | 2 +- .../apple/core/debug-symbols/report.ts | 2 +- .../apple/core/debug-symbols/symbolication.ts | 2 +- .../apple/core/debug-symbols/utils.ts | 2 +- src/platforms/apple/core/devicectl.ts | 2 +- src/platforms/apple/core/install-artifact.ts | 2 +- src/platforms/apple/core/perf-xctrace.ts | 2 +- src/platforms/apple/core/perf.ts | 4 +- .../apple/core/physical-device-control.ts | 2 +- .../apple/core/physical-device-coredevice.ts | 2 +- .../apple/core/physical-device-files.ts | 2 +- .../apple/core/physical-device-screenshot.ts | 2 +- src/platforms/apple/core/runner-host.ts | 29 +-- .../apple/core/screenshot-status-bar.ts | 3 +- src/platforms/apple/core/screenshot.ts | 9 +- src/platforms/apple/core/simctl.ts | 4 +- src/platforms/apple/core/simulator.ts | 10 +- .../apple/core/tool-provider-types.ts | 2 +- src/platforms/apple/core/tool-provider.ts | 4 +- src/platforms/apple/interactor.ts | 4 +- src/platforms/apple/os/macos/helper.ts | 2 +- src/platforms/apple/os/macos/host-provider.ts | 2 +- .../harmonyos/__tests__/app-lifecycle.test.ts | 6 +- .../harmonyos/__tests__/doctor.test.ts | 6 +- src/platforms/harmonyos/__tests__/hdc.test.ts | 6 +- .../harmonyos/__tests__/input-actions.test.ts | 2 +- src/platforms/harmonyos/app-lifecycle.ts | 2 +- src/platforms/harmonyos/hdc.ts | 2 +- src/platforms/harmonyos/input-actions.ts | 2 +- src/platforms/harmonyos/snapshot.ts | 2 +- .../install-artifact-archive-context.ts | 2 +- src/platforms/install-source-archive.ts | 2 +- src/platforms/install-source-download.ts | 5 +- src/platforms/install-source.ts | 3 +- .../linux/__tests__/atspi-bridge.test.ts | 6 +- .../linux/__tests__/clipboard.test.ts | 6 +- .../linux/__tests__/input-actions.test.ts | 6 +- src/platforms/linux/input-actions.ts | 2 +- src/platforms/linux/snapshot.ts | 2 +- src/platforms/linux/tool-provider.ts | 8 +- src/platforms/toolchain-probe.ts | 2 +- src/platforms/vega/app-lifecycle.ts | 2 +- src/platforms/vega/input-actions.ts | 2 +- src/platforms/vega/tool-provider.ts | 9 +- .../agent-browser-boundary-faults.test.ts | 2 +- src/platforms/web/agent-browser-install.ts | 2 +- .../web/agent-browser-lifecycle.test.ts | 14 +- src/platforms/web/agent-browser-lifecycle.ts | 4 +- src/platforms/web/agent-browser-network.ts | 2 +- .../web/agent-browser-process-record.ts | 4 +- .../web/agent-browser-provider.test.ts | 7 +- src/platforms/web/agent-browser-provider.ts | 10 +- src/platforms/web/agent-browser-tool.test.ts | 2 +- src/platforms/web/agent-browser-tool.ts | 5 +- src/platforms/web/provider.ts | 2 +- src/provider-webdriver.ts | 4 +- src/recording/__tests__/overlay.test.ts | 6 +- .../__tests__/recording-scripts.test.ts | 2 +- src/recording/output-path.ts | 2 +- src/recording/overlay.ts | 4 +- src/remote/remote-config-core.ts | 4 +- src/remote/remote-config-schema.ts | 2 +- src/remote/remote-connection-state.ts | 4 +- src/remote/upload-client-artifact.ts | 2 +- src/replay/script-source-bundle.ts | 2 +- src/replay/source-discovery.ts | 2 +- src/sdk/limrun-runtime-dependencies.ts | 4 +- src/snapshot/snapshot-freshness/recovery.ts | 2 +- .../__tests__/daemon-client-lifecycle.test.ts | 29 ++- src/utils/__tests__/daemon-client.test.ts | 10 +- .../__tests__/exec-boundary-faults.test.ts | 2 +- src/utils/__tests__/process-exit.test.ts | 6 +- src/utils/__tests__/swift-cache.test.ts | 4 +- src/utils/process-exit.ts | 2 +- src/utils/result-serialization.ts | 2 +- src/utils/screenshot-result.ts | 2 +- src/utils/source-value.test.ts | 2 +- src/utils/swift-cache.ts | 5 +- src/utils/update-check.ts | 2 +- src/utils/video.ts | 3 +- .../live-form-scenario.ts | 2 +- test/integration/cli-exit-flush.test.ts | 2 +- test/integration/cli-json.ts | 2 +- .../client-api-doc-snippets.test.ts | 2 +- .../daemon-leak-oracle-cli.test.ts | 3 +- .../daemon-replace-exit-flush.test.ts | 2 +- .../installed-package-metro.test.ts | 2 +- test/integration/limrun-public-types.test.ts | 2 +- .../active-session-script-publication.test.ts | 2 +- .../provider-scenarios/android-world.ts | 2 +- .../integration/provider-scenarios/harness.ts | 3 +- .../provider-scenarios/providers.ts | 2 +- .../smoke-clean-xcuitest-derived.test.ts | 2 +- test/integration/smoke-cli.test.ts | 2 +- test/integration/smoke-daemon-clean.test.ts | 3 +- test/integration/smoke-web-platform.test.ts | 2 +- test/integration/support/daemon-leak-model.ts | 2 +- .../integration/support/daemon-leak-oracle.ts | 2 +- test/integration/test-helpers.ts | 2 +- .../output-economy.baseline.test.ts | 2 +- .../owner-files-no-leak.test.ts | 2 +- 436 files changed, 1250 insertions(+), 835 deletions(-) create mode 100644 packages/host-kit/src/archive.ts create mode 100644 packages/host-kit/src/command.ts create mode 100644 packages/host-kit/src/diagnostics.ts delete mode 100644 packages/host-kit/src/exec.ts create mode 100644 packages/host-kit/src/file.ts delete mode 100644 packages/host-kit/src/fs.ts delete mode 100644 packages/host-kit/src/internal/env-map.ts delete mode 100644 packages/host-kit/src/internal/method-scope.ts create mode 100644 packages/host-kit/src/process.ts create mode 100644 packages/host-kit/src/retry.ts delete mode 100644 packages/host-kit/src/values.ts create mode 100644 packages/host-kit/src/version.ts rename packages/{host-kit/src/internal => kernel/src}/device-isolation.ts (100%) rename packages/{host-kit/src/internal => kernel/src}/location-coordinates.ts (100%) rename packages/{host-kit/src/internal/parsing.ts => kernel/src/record.ts} (100%) rename packages/{host-kit/src/internal => kernel/src}/scoped-provider.ts (55%) rename packages/{host-kit/src/internal => kernel/src}/source-value.ts (98%) rename packages/{host-kit/src/internal => kernel/src}/success-text.ts (100%) rename packages/{host-kit/src/internal => kernel/src}/ttl-memo.test.ts (100%) rename packages/{host-kit/src/internal => kernel/src}/ttl-memo.ts (100%) create mode 100644 scratch-exports.json create mode 100644 scratch-symbol-map.json diff --git a/docs/adr/0019-request-bound-platform-runtime.md b/docs/adr/0019-request-bound-platform-runtime.md index f901f8d149..5f128c7bd8 100644 --- a/docs/adr/0019-request-bound-platform-runtime.md +++ b/docs/adr/0019-request-bound-platform-runtime.md @@ -137,11 +137,18 @@ selection, R11/R13 package enumeration, and the composite typecheck project list > exports maps) forces every shared file onto a declared domain owner, and the paragraph above > is amended to name that layout rather than let capture-kit absorb it: > -> - `@agent-device/host-kit` owns generic host mechanics — process execution, supervision, and -> diagnostics; archives, streams, atomic files, locks, and path/device isolation; small host -> value helpers; request-scoped plumbing — behind a small deep surface of exactly four seams: -> `exec`, `fs`, `values`, `request`. Modules under `src/internal/` are reachable only through -> those seams; consumers import a seam, never an internal module. +> - `@agent-device/host-kit` owns mechanics that act on the host machine, and nothing else. Each +> export is one narrow capability port, not a category barrel: `command` (running host +> commands), `process` (observing and owning host processes), `diagnostics`, `retry` +> (deadline/backoff/sleep), `archive` (bounded extraction and byte limits), `file` (atomic +> publishes, locks, path resolution), `request` (request-scoped cancellation and progress), +> and `version` (the installed version off disk). Modules under `src/internal/` are reachable +> only through a port, and a port may only hold mechanics a consumer of that capability +> needs — the eager-closure row per port is what keeps that honest. +> - A helper that touches no process, file, or environment is not host mechanics and does not +> belong here: pure record readers, config-source values, result text, memoization, async +> scoping, coordinate validation, and device-scope parsing live in `@agent-device/kernel` +> beside its other primitives. > - `@agent-device/capture-kit` owns capture, snapshot, and recording behavior — PNG tooling, > screenshot density and pixel diffing, snapshot occlusion, mobile snapshot semantics, > quality verdicts and backend capability tables. Snapshot *behavior* is capture domain, not diff --git a/packages/capture-kit/src/png-worker-client.ts b/packages/capture-kit/src/png-worker-client.ts index 60f630547a..9208ba1d38 100644 --- a/packages/capture-kit/src/png-worker-client.ts +++ b/packages/capture-kit/src/png-worker-client.ts @@ -1,5 +1,5 @@ import { Worker } from 'node:worker_threads'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { AppError, toAppErrorCode } from '@agent-device/kernel/errors'; import { resolveInternalEntryModulePath } from './internal-entry.ts'; import { decodePng, PNG } from './png.ts'; diff --git a/packages/host-kit/package.json b/packages/host-kit/package.json index 248a870493..07666e7b80 100644 --- a/packages/host-kit/package.json +++ b/packages/host-kit/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "type": "module", - "description": "Private generic host mechanics behind four deep seams: process execution and supervision (exec), filesystem and archive guards (fs), pure value helpers (values), and request-scoped plumbing (request). Internal workspace package bundled into the published agent-device artifact.", + "description": "Private host-mechanics package: each export is one narrow capability port over the host machine \u2014 running commands, observing and owning processes, diagnostics, retry/deadline, archive extraction, durable files and locks, request-scoped plumbing, and the installed version.", "dependencies": { "@agent-device/contracts": "workspace:*", "@agent-device/kernel": "workspace:*", @@ -15,21 +15,37 @@ "@types/yauzl": "^3.4.0" }, "exports": { - "./exec": { - "types": "./src/exec.ts", - "default": "./src/exec.ts" + "./archive": { + "types": "./src/archive.ts", + "default": "./src/archive.ts" }, - "./fs": { - "types": "./src/fs.ts", - "default": "./src/fs.ts" + "./command": { + "types": "./src/command.ts", + "default": "./src/command.ts" + }, + "./diagnostics": { + "types": "./src/diagnostics.ts", + "default": "./src/diagnostics.ts" + }, + "./file": { + "types": "./src/file.ts", + "default": "./src/file.ts" + }, + "./process": { + "types": "./src/process.ts", + "default": "./src/process.ts" }, "./request": { "types": "./src/request.ts", "default": "./src/request.ts" }, - "./values": { - "types": "./src/values.ts", - "default": "./src/values.ts" + "./retry": { + "types": "./src/retry.ts", + "default": "./src/retry.ts" + }, + "./version": { + "types": "./src/version.ts", + "default": "./src/version.ts" } } } diff --git a/packages/host-kit/src/archive.ts b/packages/host-kit/src/archive.ts new file mode 100644 index 0000000000..3300b1f413 --- /dev/null +++ b/packages/host-kit/src/archive.ts @@ -0,0 +1,4 @@ +export { archiveTypeFromPath, extractArchiveSafely } from './internal/archive-extraction.ts'; +export { ArchiveBudget, type ArchiveManifestEntry } from './internal/archive-safety.ts'; +export { MAX_ARTIFACT_COMPRESSED_BYTES } from './internal/artifact-limits.ts'; +export { createByteLimitStream } from './internal/byte-limit-stream.ts'; diff --git a/packages/host-kit/src/command.ts b/packages/host-kit/src/command.ts new file mode 100644 index 0000000000..8c56f2d0ed --- /dev/null +++ b/packages/host-kit/src/command.ts @@ -0,0 +1,24 @@ +export { + coerceExecResult, + type CommandExecutorOverride, + type ExecBackgroundOptions, + type ExecBackgroundResult, + type ExecDetachedExit, + execFailureDetails, + type ExecOptions, + type ExecResult, + isExecutablePath, + requireExecSuccess, + resolveExecutableOverridePath, + resolveFileOverridePath, + runCmd, + runCmdBackground, + runCmdDetached, + runCmdDetachedMonitored, + runCmdStreaming, + runCmdSync, + whichCmd, + withCommandExecutorOverride, + withoutCommandExecutorOverride, +} from './internal/exec.ts'; +export { shellQuote, shellQuoteIfNeeded } from './internal/shell-quote.ts'; diff --git a/packages/host-kit/src/diagnostics.ts b/packages/host-kit/src/diagnostics.ts new file mode 100644 index 0000000000..2b0d0e5247 --- /dev/null +++ b/packages/host-kit/src/diagnostics.ts @@ -0,0 +1,11 @@ +export { + countDiagnosticEventsByPhase, + createRequestId, + emitDiagnostic, + flushDiagnosticsToSessionFile, + getDiagnosticsMeta, + registerDiagnosticSensitiveValue, + updateDiagnosticsScope, + withDiagnosticsScope, + withDiagnosticTimer, +} from './internal/diagnostics.ts'; diff --git a/packages/host-kit/src/exec.ts b/packages/host-kit/src/exec.ts deleted file mode 100644 index e5ca9f8a97..0000000000 --- a/packages/host-kit/src/exec.ts +++ /dev/null @@ -1,77 +0,0 @@ -export { - coerceExecResult, - execFailureDetails, - isExecutablePath, - requireExecSuccess, - resolveExecutableOverridePath, - resolveFileOverridePath, - runCmd, - runCmdBackground, - runCmdDetached, - runCmdDetachedMonitored, - runCmdStreaming, - runCmdSync, - whichCmd, - withCommandExecutorOverride, - withoutCommandExecutorOverride, - type CommandExecutorOverride, - type ExecBackgroundOptions, - type ExecBackgroundResult, - type ExecDetachedExit, - type ExecDetachedProcess, - type ExecOptions, - type ExecResult, -} from './internal/exec.ts'; -export { - countDiagnosticEventsByPhase, - createRequestId, - emitDiagnostic, - flushDiagnosticsToSessionFile, - getDiagnosticsMeta, - registerDiagnosticSensitiveValue, - updateDiagnosticsScope, - withDiagnosticTimer, - withDiagnosticsScope, - type FlushedDiagnosticsRecord, -} from './internal/diagnostics.ts'; -export { - expandProcessTree, - isProcessAlive, - isProcessGroupAlive, - isProcessZombie, - listHostProcesses, - readHostProcessIdentityObservations, - readProcessCommand, - readProcessStartTime, - signalPidsBestEffort, - signalProcessGroupBestEffort, - stopPidsWithEscalation, - uniquePositivePids, - waitForProcessExit, - type HostProcessIdentityObservation, - type HostProcessInfo, - type ListHostProcessesOptions, - type StopPidsWithEscalationOptions, -} from './internal/host-process.ts'; -export { - reapOwnedProcessRecordsAtStartup, - type OwnedProcessReapSummary, -} from './internal/owned-process-reaper.ts'; -export { - createOwnedProcessRecordStore, - readOwnedProcessRecordFile, - type OwnedProcessRecordRead, - type OwnedProcessRecordStore, -} from './internal/owned-process-record.ts'; -export { - classifyOwnerLiveness, - classifyOwnerLivenessFromObservation, - ownerIdentityDiffers, - ownerIdentityMatches, - readCurrentOwnerIdentity, - type OwnerIdentity, - type OwnerLiveness, -} from './internal/owner-identity.ts'; -export { shellQuote, shellQuoteIfNeeded } from './internal/shell-quote.ts'; -export { sleep } from './internal/timeouts.ts'; -export { Deadline, isEnvTruthy, retryWithPolicy } from './internal/retry.ts'; diff --git a/packages/host-kit/src/file.ts b/packages/host-kit/src/file.ts new file mode 100644 index 0000000000..fe8c310555 --- /dev/null +++ b/packages/host-kit/src/file.ts @@ -0,0 +1,7 @@ +export { + isAtomicPublishTemporaryPath, + publishFileSync, + withAtomicPublishTempPathSync, +} from './internal/atomic-file.ts'; +export { expandUserHomePath, resolveUserPath } from './internal/path-resolution.ts'; +export { acquireProcessLock, type ProcessLockOwner } from './internal/process-lock.ts'; diff --git a/packages/host-kit/src/fs.ts b/packages/host-kit/src/fs.ts deleted file mode 100644 index b6965b7d48..0000000000 --- a/packages/host-kit/src/fs.ts +++ /dev/null @@ -1,22 +0,0 @@ -export { - archiveTypeFromPath, - extractArchiveSafely, - type ExtractArchiveOptions, - type SupportedArchiveType, -} from './internal/archive-extraction.ts'; -export { ArchiveBudget, type ArchiveManifestEntry } from './internal/archive-safety.ts'; -export { MAX_ARTIFACT_COMPRESSED_BYTES } from './internal/artifact-limits.ts'; -export { - isAtomicPublishTemporaryPath, - publishFileSync, - withAtomicPublishTempPathSync, - type AtomicPublishMode, -} from './internal/atomic-file.ts'; -export { createByteLimitStream, type ByteLimitStream } from './internal/byte-limit-stream.ts'; -export { - parseSerialAllowlist, - resolveAndroidSerialAllowlist, - resolveIosSimulatorDeviceSetPath, -} from './internal/device-isolation.ts'; -export { expandUserHomePath, resolveUserPath } from './internal/path-resolution.ts'; -export { acquireProcessLock, type ProcessLockOwner } from './internal/process-lock.ts'; diff --git a/packages/host-kit/src/internal/env-map.ts b/packages/host-kit/src/internal/env-map.ts deleted file mode 100644 index f203e11695..0000000000 --- a/packages/host-kit/src/internal/env-map.ts +++ /dev/null @@ -1 +0,0 @@ -export type EnvMap = Record; diff --git a/packages/host-kit/src/internal/exec.ts b/packages/host-kit/src/internal/exec.ts index 7fb5764bb2..166853c7b9 100644 --- a/packages/host-kit/src/internal/exec.ts +++ b/packages/host-kit/src/internal/exec.ts @@ -7,7 +7,7 @@ import { Readable } from 'node:stream'; import { pipeline } from 'node:stream/promises'; import { AppError, createRequestCanceledError } from '@agent-device/kernel/errors'; import { emitDiagnostic, getDiagnosticsMeta, updateDiagnosticsScope } from './diagnostics.ts'; -import { parseBooleanLiteral } from './source-value.ts'; +import { parseBooleanLiteral } from '@agent-device/kernel/source-value'; export type ExecResult = { stdout: string; diff --git a/packages/host-kit/src/internal/method-scope.ts b/packages/host-kit/src/internal/method-scope.ts deleted file mode 100644 index 1d56831def..0000000000 --- a/packages/host-kit/src/internal/method-scope.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * Wraps every method call on `target` in `runScope`, so leaf code below the - * method resolves scope-injected state (AsyncLocalStorage transports) instead - * of the local default. Shared by the Android adb-provider and Apple - * runner-provider interactor seams. - */ -export function withMethodScope( - target: T, - runScope: (task: () => Promise) => Promise, -): T { - return new Proxy(target, { - get(proxyTarget, property, receiver) { - const value = Reflect.get(proxyTarget, property, receiver); - if (typeof value !== 'function') return value; - return (...args: unknown[]) => runScope(async () => await value.apply(proxyTarget, args)); - }, - }); -} diff --git a/packages/host-kit/src/internal/path-resolution.ts b/packages/host-kit/src/internal/path-resolution.ts index 0cedadc1f8..8ce8bd143d 100644 --- a/packages/host-kit/src/internal/path-resolution.ts +++ b/packages/host-kit/src/internal/path-resolution.ts @@ -1,6 +1,6 @@ import os from 'node:os'; import path from 'node:path'; -import type { EnvMap } from './env-map.ts'; +import type { EnvMap } from '@agent-device/kernel/source-value'; type PathResolutionOptions = { cwd?: string; diff --git a/packages/host-kit/src/internal/version.test.ts b/packages/host-kit/src/internal/version.test.ts index ee185b235b..6e7e164f59 100644 --- a/packages/host-kit/src/internal/version.test.ts +++ b/packages/host-kit/src/internal/version.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { mkdtempForTestSync } from './tmp-dir.fixtures.ts'; -import { resetAllProcessMemosForTests } from './ttl-memo.ts'; +import { resetAllProcessMemosForTests } from '@agent-device/kernel/ttl-memo'; import { resolveAgentDeviceProjectRoot } from './project-root.ts'; import { findProjectRoot, readVersion } from './version.ts'; diff --git a/packages/host-kit/src/internal/version.ts b/packages/host-kit/src/internal/version.ts index 6a3e77e3d4..76bffe9cf1 100644 --- a/packages/host-kit/src/internal/version.ts +++ b/packages/host-kit/src/internal/version.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { resolveAgentDeviceProjectRoot } from './project-root.ts'; -import { createTtlMemo } from './ttl-memo.ts'; +import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; // Immutable for a process's lifetime, so resolved once; the process-memo reset clears them between tests. const versionMemo = createTtlMemo(); diff --git a/packages/host-kit/src/process.ts b/packages/host-kit/src/process.ts new file mode 100644 index 0000000000..e4e77c1e99 --- /dev/null +++ b/packages/host-kit/src/process.ts @@ -0,0 +1,32 @@ +export { + expandProcessTree, + type HostProcessIdentityObservation, + type HostProcessInfo, + isProcessAlive, + isProcessGroupAlive, + isProcessZombie, + listHostProcesses, + readHostProcessIdentityObservations, + readProcessCommand, + readProcessStartTime, + signalPidsBestEffort, + signalProcessGroupBestEffort, + stopPidsWithEscalation, + uniquePositivePids, + waitForProcessExit, +} from './internal/host-process.ts'; +export { reapOwnedProcessRecordsAtStartup } from './internal/owned-process-reaper.ts'; +export { + createOwnedProcessRecordStore, + type OwnedProcessRecordStore, + readOwnedProcessRecordFile, +} from './internal/owned-process-record.ts'; +export { + classifyOwnerLiveness, + classifyOwnerLivenessFromObservation, + type OwnerIdentity, + ownerIdentityDiffers, + ownerIdentityMatches, + type OwnerLiveness, + readCurrentOwnerIdentity, +} from './internal/owner-identity.ts'; diff --git a/packages/host-kit/src/request.ts b/packages/host-kit/src/request.ts index 934f0ab380..ee98a01e7b 100644 --- a/packages/host-kit/src/request.ts +++ b/packages/host-kit/src/request.ts @@ -7,6 +7,5 @@ export { registerRequestAbort, resolveRequestTrackingId, throwIfRequestCanceled, - type RequestAbortRegistration, } from './internal/request-cancel.ts'; export { emitRequestProgress, withRequestProgressSink } from './internal/request-progress.ts'; diff --git a/packages/host-kit/src/retry.ts b/packages/host-kit/src/retry.ts new file mode 100644 index 0000000000..a4aee8ade6 --- /dev/null +++ b/packages/host-kit/src/retry.ts @@ -0,0 +1,2 @@ +export { Deadline, isEnvTruthy, retryWithPolicy } from './internal/retry.ts'; +export { sleep } from './internal/timeouts.ts'; diff --git a/packages/host-kit/src/values.ts b/packages/host-kit/src/values.ts deleted file mode 100644 index 846d6c24a2..0000000000 --- a/packages/host-kit/src/values.ts +++ /dev/null @@ -1,39 +0,0 @@ -export { type EnvMap } from './internal/env-map.ts'; -export { - readLocationCoordinate, - requireLocationCoordinates, - type LocationCoordinateLabel, - type LocationCoordinates, -} from './internal/location-coordinates.ts'; -export { withMethodScope } from './internal/method-scope.ts'; -export { - asOptionalRecord, - asRecord, - isRecord, - parsePoint, - parseRect, - readDeviceTarget, - readNullableString, - readOptionalString, - readRequiredDeviceKind, - readRequiredNumber, - readRequiredPlatform, - readRequiredString, - splitNonEmptyTrimmedLines, - stripUndefined, -} from './internal/parsing.ts'; -export { createScopedProvider, type ScopedProvider } from './internal/scoped-provider.ts'; -export { - buildPrimaryEnvVarName, - parseBooleanLiteral, - parseSourceValue, - type SourceValueDefinition, -} from './internal/source-value.ts'; -export { readCommandMessage, successText, withSuccessText } from './internal/success-text.ts'; -export { - createTtlMemo, - resetAllProcessMemosForTests, - type TtlMemo, - type TtlMemoOptions, -} from './internal/ttl-memo.ts'; -export { findProjectRoot, readVersion } from './internal/version.ts'; diff --git a/packages/host-kit/src/version.ts b/packages/host-kit/src/version.ts new file mode 100644 index 0000000000..ca16de62bf --- /dev/null +++ b/packages/host-kit/src/version.ts @@ -0,0 +1 @@ +export { findProjectRoot, readVersion } from './internal/version.ts'; diff --git a/packages/kernel/package.json b/packages/kernel/package.json index 9399792803..a3b741b2a3 100644 --- a/packages/kernel/package.json +++ b/packages/kernel/package.json @@ -21,6 +21,10 @@ "types": "./src/device.ts", "default": "./src/device.ts" }, + "./device-isolation": { + "types": "./src/device-isolation.ts", + "default": "./src/device-isolation.ts" + }, "./errors": { "types": "./src/errors.ts", "default": "./src/errors.ts" @@ -29,6 +33,14 @@ "types": "./src/keyed-lock.ts", "default": "./src/keyed-lock.ts" }, + "./location-coordinates": { + "types": "./src/location-coordinates.ts", + "default": "./src/location-coordinates.ts" + }, + "./record": { + "types": "./src/record.ts", + "default": "./src/record.ts" + }, "./rect": { "types": "./src/rect.ts", "default": "./src/rect.ts" @@ -41,6 +53,10 @@ "types": "./src/redaction.ts", "default": "./src/redaction.ts" }, + "./scoped-provider": { + "types": "./src/scoped-provider.ts", + "default": "./src/scoped-provider.ts" + }, "./scroll-indicator": { "types": "./src/scroll-indicator.ts", "default": "./src/scroll-indicator.ts" @@ -48,6 +64,18 @@ "./snapshot": { "types": "./src/snapshot.ts", "default": "./src/snapshot.ts" + }, + "./source-value": { + "types": "./src/source-value.ts", + "default": "./src/source-value.ts" + }, + "./success-text": { + "types": "./src/success-text.ts", + "default": "./src/success-text.ts" + }, + "./ttl-memo": { + "types": "./src/ttl-memo.ts", + "default": "./src/ttl-memo.ts" } } } diff --git a/packages/host-kit/src/internal/device-isolation.ts b/packages/kernel/src/device-isolation.ts similarity index 100% rename from packages/host-kit/src/internal/device-isolation.ts rename to packages/kernel/src/device-isolation.ts diff --git a/packages/host-kit/src/internal/location-coordinates.ts b/packages/kernel/src/location-coordinates.ts similarity index 100% rename from packages/host-kit/src/internal/location-coordinates.ts rename to packages/kernel/src/location-coordinates.ts diff --git a/packages/host-kit/src/internal/parsing.ts b/packages/kernel/src/record.ts similarity index 100% rename from packages/host-kit/src/internal/parsing.ts rename to packages/kernel/src/record.ts diff --git a/packages/host-kit/src/internal/scoped-provider.ts b/packages/kernel/src/scoped-provider.ts similarity index 55% rename from packages/host-kit/src/internal/scoped-provider.ts rename to packages/kernel/src/scoped-provider.ts index ba4b2a7d33..40bb59086c 100644 --- a/packages/host-kit/src/internal/scoped-provider.ts +++ b/packages/kernel/src/scoped-provider.ts @@ -25,3 +25,22 @@ export function createScopedProvider( }, }; } + +/** + * Wraps every method call on `target` in `runScope`, so leaf code below the + * method resolves scope-injected state (AsyncLocalStorage transports) instead + * of the local default. Shared by the Android adb-provider and Apple + * runner-provider interactor seams. + */ +export function withMethodScope( + target: T, + runScope: (task: () => Promise) => Promise, +): T { + return new Proxy(target, { + get(proxyTarget, property, receiver) { + const value = Reflect.get(proxyTarget, property, receiver); + if (typeof value !== 'function') return value; + return (...args: unknown[]) => runScope(async () => await value.apply(proxyTarget, args)); + }, + }); +} diff --git a/packages/host-kit/src/internal/source-value.ts b/packages/kernel/src/source-value.ts similarity index 98% rename from packages/host-kit/src/internal/source-value.ts rename to packages/kernel/src/source-value.ts index 1886e07a19..0020cc7084 100644 --- a/packages/host-kit/src/internal/source-value.ts +++ b/packages/kernel/src/source-value.ts @@ -137,3 +137,5 @@ function parseEnumSetValue( `Invalid value for "${rawKey}" in ${sourceLabel}. Expected boolean-like value for enum flag.`, ); } + +export type EnvMap = Record; diff --git a/packages/host-kit/src/internal/success-text.ts b/packages/kernel/src/success-text.ts similarity index 100% rename from packages/host-kit/src/internal/success-text.ts rename to packages/kernel/src/success-text.ts diff --git a/packages/host-kit/src/internal/ttl-memo.test.ts b/packages/kernel/src/ttl-memo.test.ts similarity index 100% rename from packages/host-kit/src/internal/ttl-memo.test.ts rename to packages/kernel/src/ttl-memo.test.ts diff --git a/packages/host-kit/src/internal/ttl-memo.ts b/packages/kernel/src/ttl-memo.ts similarity index 100% rename from packages/host-kit/src/internal/ttl-memo.ts rename to packages/kernel/src/ttl-memo.ts diff --git a/scratch-exports.json b/scratch-exports.json new file mode 100644 index 0000000000..bbba4dbb14 --- /dev/null +++ b/scratch-exports.json @@ -0,0 +1,198 @@ +{ + "archive-extraction-tar": [["extractTarArchive", "value"]], + "archive-extraction-zip": [["extractZipArchive", "value"]], + "archive-extraction": [ + ["SupportedArchiveType", "type"], + ["ExtractArchiveOptions", "type"], + ["extractArchiveSafely", "value"], + ["archiveTypeFromPath", "value"] + ], + "archive-safety": [ + ["ArchiveManifestEntry", "type"], + ["ArchiveBudget", "value"], + ["reserveArchiveManifest", "value"], + ["sameArchiveManifestEntry", "value"], + ["normalizeArchiveEntryName", "value"], + ["resolveArchiveOutputPath", "value"], + ["archiveError", "value"] + ], + "artifact-limits": [ + ["MAX_ARTIFACT_COMPRESSED_BYTES", "value"], + ["MAX_ARCHIVE_EXPANDED_BYTES", "value"], + ["MAX_ARCHIVE_ENTRIES", "value"], + ["MAX_ARCHIVE_NESTING_DEPTH", "value"] + ], + "atomic-file": [ + ["AtomicPublishMode", "type"], + ["publishFileSync", "value"], + ["withAtomicPublishTempPathSync", "value"], + ["isAtomicPublishTemporaryPath", "value"] + ], + "byte-limit-stream": [ + ["ByteLimitStream", "type"], + ["createByteLimitStream", "value"] + ], + "device-isolation": [ + ["resolveIosSimulatorDeviceSetPath", "value"], + ["parseSerialAllowlist", "value"], + ["resolveAndroidSerialAllowlist", "value"] + ], + "diagnostics": [ + ["createRequestId", "value"], + ["withDiagnosticsScope", "value"], + ["updateDiagnosticsScope", "value"], + ["getDiagnosticsMeta", "value"], + ["registerDiagnosticSensitiveValue", "value"], + ["countDiagnosticEventsByPhase", "value"], + ["emitDiagnostic", "value"], + ["withDiagnosticTimer", "value"], + ["FlushedDiagnosticsRecord", "type"], + ["flushDiagnosticsToSessionFile", "value"] + ], + "env-map": [["EnvMap", "type"]], + "exec": [ + ["ExecResult", "type"], + ["ExecOptions", "type"], + ["ExecBackgroundResult", "type"], + ["ExecDetachedExit", "type"], + ["ExecDetachedProcess", "type"], + ["ExecBackgroundOptions", "type"], + ["CommandExecutorOverride", "type"], + ["withCommandExecutorOverride", "value"], + ["withoutCommandExecutorOverride", "value"], + ["runCmd", "value"], + ["runCmdStreaming", "value"], + ["coerceExecResult", "value"], + ["whichCmd", "value"], + ["resolveExecutableOverridePath", "value"], + ["resolveFileOverridePath", "value"], + ["runCmdSync", "value"], + ["runCmdDetached", "value"], + ["runCmdDetachedMonitored", "value"], + ["runCmdBackground", "value"], + ["requireExecSuccess", "value"], + ["execFailureDetails", "value"], + ["isExecutablePath", "value"] + ], + "host-process": [ + ["HostProcessInfo", "type"], + ["HostProcessIdentityObservation", "type"], + ["ListHostProcessesOptions", "type"], + ["StopPidsWithEscalationOptions", "type"], + ["isProcessAlive", "value"], + ["isProcessGroupAlive", "value"], + ["readProcessStartTime", "value"], + ["readProcessCommand", "value"], + ["isProcessZombie", "value"], + ["readHostProcessIdentityObservations", "value"], + ["parseHostProcessList", "value"], + ["listHostProcesses", "value"], + ["expandProcessTree", "value"], + ["uniquePositivePids", "value"], + ["signalPidsBestEffort", "value"], + ["signalProcessGroupBestEffort", "value"], + ["waitForProcessExit", "value"], + ["stopPidsWithEscalation", "value"] + ], + "location-coordinates": [ + ["LocationCoordinateLabel", "type"], + ["LocationCoordinates", "type"], + ["readLocationCoordinate", "value"], + ["requireLocationCoordinates", "value"] + ], + "method-scope": [["withMethodScope", "value"]], + "owned-process-reaper": [ + ["OwnedProcessReapSummary", "type"], + ["reapOwnedProcessRecordsAtStartup", "value"] + ], + "owned-process-record": [ + ["OwnedProcessRecordRead", "type"], + ["OwnedProcessRecordStore", "type"], + ["createOwnedProcessRecordStore", "value"], + ["readOwnedProcessRecordFile", "value"] + ], + "owner-identity": [ + ["OwnerIdentity", "type"], + ["OwnerLiveness", "type"], + ["readCurrentOwnerIdentity", "value"], + ["ownerIdentityMatches", "value"], + ["ownerIdentityDiffers", "value"], + ["classifyOwnerLiveness", "value"], + ["classifyOwnerLivenessFromObservation", "value"] + ], + "parsing": [ + ["readRequiredString", "value"], + ["readOptionalString", "value"], + ["readNullableString", "value"], + ["readRequiredNumber", "value"], + ["readRequiredPlatform", "value"], + ["readRequiredDeviceKind", "value"], + ["readDeviceTarget", "value"], + ["parseRect", "value"], + ["parsePoint", "value"], + ["asRecord", "value"], + ["isRecord", "value"], + ["asOptionalRecord", "value"], + ["stripUndefined", "value"], + ["splitNonEmptyTrimmedLines", "value"] + ], + "path-resolution": [ + ["expandUserHomePath", "value"], + ["resolveUserPath", "value"] + ], + "process-lock": [ + ["ProcessLockOwner", "type"], + ["acquireProcessLock", "value"] + ], + "project-root": [["resolveAgentDeviceProjectRoot", "value"]], + "request-cancel": [ + ["RequestAbortRegistration", "type"], + ["resolveRequestTrackingId", "value"], + ["registerRequestAbort", "value"], + ["markRequestCanceled", "value"], + ["clearRequestCanceled", "value"], + ["clearRequestAbortRegistration", "value"], + ["isRequestCanceled", "value"], + ["getRequestSignal", "value"], + ["throwIfRequestCanceled", "value"] + ], + "request-progress": [ + ["withRequestProgressSink", "value"], + ["emitRequestProgress", "value"] + ], + "retry": [ + ["isEnvTruthy", "value"], + ["Deadline", "value"], + ["retryWithPolicy", "value"] + ], + "scoped-provider": [ + ["ScopedProvider", "type"], + ["createScopedProvider", "value"] + ], + "shell-quote": [ + ["shellQuote", "value"], + ["shellQuoteIfNeeded", "value"] + ], + "source-value": [ + ["SourceValueDefinition", "type"], + ["buildPrimaryEnvVarName", "value"], + ["parseSourceValue", "value"], + ["parseBooleanLiteral", "value"] + ], + "success-text": [ + ["successText", "value"], + ["withSuccessText", "value"], + ["readCommandMessage", "value"] + ], + "timeouts": [["sleep", "value"]], + "ttl-memo": [ + ["TtlMemo", "type"], + ["TtlMemoOptions", "type"], + ["createTtlMemo", "value"], + ["resetAllProcessMemosForTests", "value"] + ], + "version": [ + ["readVersion", "value"], + ["findProjectRoot", "value"] + ] +} diff --git a/scratch-symbol-map.json b/scratch-symbol-map.json new file mode 100644 index 0000000000..2329c52aec --- /dev/null +++ b/scratch-symbol-map.json @@ -0,0 +1,148 @@ +{ + "ExecResult": "@agent-device/host-kit/command", + "ExecOptions": "@agent-device/host-kit/command", + "ExecBackgroundResult": "@agent-device/host-kit/command", + "ExecDetachedExit": "@agent-device/host-kit/command", + "ExecDetachedProcess": "@agent-device/host-kit/command", + "ExecBackgroundOptions": "@agent-device/host-kit/command", + "CommandExecutorOverride": "@agent-device/host-kit/command", + "withCommandExecutorOverride": "@agent-device/host-kit/command", + "withoutCommandExecutorOverride": "@agent-device/host-kit/command", + "runCmd": "@agent-device/host-kit/command", + "runCmdStreaming": "@agent-device/host-kit/command", + "coerceExecResult": "@agent-device/host-kit/command", + "whichCmd": "@agent-device/host-kit/command", + "resolveExecutableOverridePath": "@agent-device/host-kit/command", + "resolveFileOverridePath": "@agent-device/host-kit/command", + "runCmdSync": "@agent-device/host-kit/command", + "runCmdDetached": "@agent-device/host-kit/command", + "runCmdDetachedMonitored": "@agent-device/host-kit/command", + "runCmdBackground": "@agent-device/host-kit/command", + "requireExecSuccess": "@agent-device/host-kit/command", + "execFailureDetails": "@agent-device/host-kit/command", + "isExecutablePath": "@agent-device/host-kit/command", + "shellQuote": "@agent-device/host-kit/command", + "shellQuoteIfNeeded": "@agent-device/host-kit/command", + "HostProcessInfo": "@agent-device/host-kit/process", + "HostProcessIdentityObservation": "@agent-device/host-kit/process", + "ListHostProcessesOptions": "@agent-device/host-kit/process", + "StopPidsWithEscalationOptions": "@agent-device/host-kit/process", + "isProcessAlive": "@agent-device/host-kit/process", + "isProcessGroupAlive": "@agent-device/host-kit/process", + "readProcessStartTime": "@agent-device/host-kit/process", + "readProcessCommand": "@agent-device/host-kit/process", + "isProcessZombie": "@agent-device/host-kit/process", + "readHostProcessIdentityObservations": "@agent-device/host-kit/process", + "parseHostProcessList": "@agent-device/host-kit/process", + "listHostProcesses": "@agent-device/host-kit/process", + "expandProcessTree": "@agent-device/host-kit/process", + "uniquePositivePids": "@agent-device/host-kit/process", + "signalPidsBestEffort": "@agent-device/host-kit/process", + "signalProcessGroupBestEffort": "@agent-device/host-kit/process", + "waitForProcessExit": "@agent-device/host-kit/process", + "stopPidsWithEscalation": "@agent-device/host-kit/process", + "OwnerIdentity": "@agent-device/host-kit/process", + "OwnerLiveness": "@agent-device/host-kit/process", + "readCurrentOwnerIdentity": "@agent-device/host-kit/process", + "ownerIdentityMatches": "@agent-device/host-kit/process", + "ownerIdentityDiffers": "@agent-device/host-kit/process", + "classifyOwnerLiveness": "@agent-device/host-kit/process", + "classifyOwnerLivenessFromObservation": "@agent-device/host-kit/process", + "OwnedProcessRecordRead": "@agent-device/host-kit/process", + "OwnedProcessRecordStore": "@agent-device/host-kit/process", + "createOwnedProcessRecordStore": "@agent-device/host-kit/process", + "readOwnedProcessRecordFile": "@agent-device/host-kit/process", + "OwnedProcessReapSummary": "@agent-device/host-kit/process", + "reapOwnedProcessRecordsAtStartup": "@agent-device/host-kit/process", + "createRequestId": "@agent-device/host-kit/diagnostics", + "withDiagnosticsScope": "@agent-device/host-kit/diagnostics", + "updateDiagnosticsScope": "@agent-device/host-kit/diagnostics", + "getDiagnosticsMeta": "@agent-device/host-kit/diagnostics", + "registerDiagnosticSensitiveValue": "@agent-device/host-kit/diagnostics", + "countDiagnosticEventsByPhase": "@agent-device/host-kit/diagnostics", + "emitDiagnostic": "@agent-device/host-kit/diagnostics", + "withDiagnosticTimer": "@agent-device/host-kit/diagnostics", + "FlushedDiagnosticsRecord": "@agent-device/host-kit/diagnostics", + "flushDiagnosticsToSessionFile": "@agent-device/host-kit/diagnostics", + "isEnvTruthy": "@agent-device/host-kit/retry", + "Deadline": "@agent-device/host-kit/retry", + "retryWithPolicy": "@agent-device/host-kit/retry", + "sleep": "@agent-device/host-kit/retry", + "SupportedArchiveType": "@agent-device/host-kit/archive", + "ExtractArchiveOptions": "@agent-device/host-kit/archive", + "extractArchiveSafely": "@agent-device/host-kit/archive", + "archiveTypeFromPath": "@agent-device/host-kit/archive", + "extractTarArchive": "@agent-device/host-kit/archive", + "extractZipArchive": "@agent-device/host-kit/archive", + "ArchiveManifestEntry": "@agent-device/host-kit/archive", + "ArchiveBudget": "@agent-device/host-kit/archive", + "reserveArchiveManifest": "@agent-device/host-kit/archive", + "sameArchiveManifestEntry": "@agent-device/host-kit/archive", + "normalizeArchiveEntryName": "@agent-device/host-kit/archive", + "resolveArchiveOutputPath": "@agent-device/host-kit/archive", + "archiveError": "@agent-device/host-kit/archive", + "MAX_ARTIFACT_COMPRESSED_BYTES": "@agent-device/host-kit/archive", + "MAX_ARCHIVE_EXPANDED_BYTES": "@agent-device/host-kit/archive", + "MAX_ARCHIVE_ENTRIES": "@agent-device/host-kit/archive", + "MAX_ARCHIVE_NESTING_DEPTH": "@agent-device/host-kit/archive", + "ByteLimitStream": "@agent-device/host-kit/archive", + "createByteLimitStream": "@agent-device/host-kit/archive", + "AtomicPublishMode": "@agent-device/host-kit/file", + "publishFileSync": "@agent-device/host-kit/file", + "withAtomicPublishTempPathSync": "@agent-device/host-kit/file", + "isAtomicPublishTemporaryPath": "@agent-device/host-kit/file", + "ProcessLockOwner": "@agent-device/host-kit/file", + "acquireProcessLock": "@agent-device/host-kit/file", + "expandUserHomePath": "@agent-device/host-kit/file", + "resolveUserPath": "@agent-device/host-kit/file", + "readVersion": "@agent-device/host-kit/version", + "findProjectRoot": "@agent-device/host-kit/version", + "resolveAgentDeviceProjectRoot": "@agent-device/host-kit/version", + "RequestAbortRegistration": "@agent-device/host-kit/request", + "resolveRequestTrackingId": "@agent-device/host-kit/request", + "registerRequestAbort": "@agent-device/host-kit/request", + "markRequestCanceled": "@agent-device/host-kit/request", + "clearRequestCanceled": "@agent-device/host-kit/request", + "clearRequestAbortRegistration": "@agent-device/host-kit/request", + "isRequestCanceled": "@agent-device/host-kit/request", + "getRequestSignal": "@agent-device/host-kit/request", + "throwIfRequestCanceled": "@agent-device/host-kit/request", + "withRequestProgressSink": "@agent-device/host-kit/request", + "emitRequestProgress": "@agent-device/host-kit/request", + "readRequiredString": "@agent-device/kernel/record", + "readOptionalString": "@agent-device/kernel/record", + "readNullableString": "@agent-device/kernel/record", + "readRequiredNumber": "@agent-device/kernel/record", + "readRequiredPlatform": "@agent-device/kernel/record", + "readRequiredDeviceKind": "@agent-device/kernel/record", + "readDeviceTarget": "@agent-device/kernel/record", + "parseRect": "@agent-device/kernel/record", + "parsePoint": "@agent-device/kernel/record", + "asRecord": "@agent-device/kernel/record", + "isRecord": "@agent-device/kernel/record", + "asOptionalRecord": "@agent-device/kernel/record", + "stripUndefined": "@agent-device/kernel/record", + "splitNonEmptyTrimmedLines": "@agent-device/kernel/record", + "SourceValueDefinition": "@agent-device/kernel/source-value", + "buildPrimaryEnvVarName": "@agent-device/kernel/source-value", + "parseSourceValue": "@agent-device/kernel/source-value", + "parseBooleanLiteral": "@agent-device/kernel/source-value", + "EnvMap": "@agent-device/kernel/source-value", + "successText": "@agent-device/kernel/success-text", + "withSuccessText": "@agent-device/kernel/success-text", + "readCommandMessage": "@agent-device/kernel/success-text", + "TtlMemo": "@agent-device/kernel/ttl-memo", + "TtlMemoOptions": "@agent-device/kernel/ttl-memo", + "createTtlMemo": "@agent-device/kernel/ttl-memo", + "resetAllProcessMemosForTests": "@agent-device/kernel/ttl-memo", + "ScopedProvider": "@agent-device/kernel/scoped-provider", + "createScopedProvider": "@agent-device/kernel/scoped-provider", + "withMethodScope": "@agent-device/kernel/scoped-provider", + "LocationCoordinateLabel": "@agent-device/kernel/location-coordinates", + "LocationCoordinates": "@agent-device/kernel/location-coordinates", + "readLocationCoordinate": "@agent-device/kernel/location-coordinates", + "requireLocationCoordinates": "@agent-device/kernel/location-coordinates", + "resolveIosSimulatorDeviceSetPath": "@agent-device/kernel/device-isolation", + "parseSerialAllowlist": "@agent-device/kernel/device-isolation", + "resolveAndroidSerialAllowlist": "@agent-device/kernel/device-isolation" +} diff --git a/scripts/__tests__/fallow-fixture-policy.test.ts b/scripts/__tests__/fallow-fixture-policy.test.ts index bc551d925b..1b798de120 100644 --- a/scripts/__tests__/fallow-fixture-policy.test.ts +++ b/scripts/__tests__/fallow-fixture-policy.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { test } from 'vitest'; import { mkdtempForTest } from '../../src/__tests__/test-utils/tmp-dir.ts'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); const FALLOW_CLI = path.join(REPOSITORY_ROOT, 'node_modules', 'fallow', 'bin', 'fallow'); diff --git a/scripts/__tests__/test-file-size-ratchet.test.ts b/scripts/__tests__/test-file-size-ratchet.test.ts index 6d515b1417..7e23d3c3d9 100644 --- a/scripts/__tests__/test-file-size-ratchet.test.ts +++ b/scripts/__tests__/test-file-size-ratchet.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { expect, test } from 'vitest'; import { walkFiles } from '../lib/walk-files.ts'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; /** * Test-file size ratchet (AGENTS.md "Scope & shape": past 1,000 lines is architecture debt, @@ -44,7 +44,7 @@ const PINNED_TEST_FILE_LINES: Readonly> = Object.freeze({ 'packages/platform-apple/src/runner/__tests__/runner-client.test.ts': 1577, 'src/__tests__/client.test.ts': 1592, 'test/integration/provider-scenarios/android-lifecycle.test.ts': 1556, - 'src/utils/__tests__/daemon-client-lifecycle.test.ts': 1414, + 'src/utils/__tests__/daemon-client-lifecycle.test.ts': 1413, 'packages/platform-apple/src/runner/__tests__/runner-command-retry.test.ts': 1325, 'src/__tests__/cli-client-commands.test.ts': 1317, 'src/__tests__/cli-config.test.ts': 1282, diff --git a/scripts/check-affected/run.test.ts b/scripts/check-affected/run.test.ts index 902a60d65b..4aecec7e59 100644 --- a/scripts/check-affected/run.test.ts +++ b/scripts/check-affected/run.test.ts @@ -8,7 +8,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { STALE_NODE_MODULES_MESSAGE } from './lockfile-install-sync.ts'; import { CHECK_CATALOG } from './checks.ts'; import { DEFAULT_VITEST_MAX_WORKERS } from '../lib/vitest-concurrency.ts'; diff --git a/scripts/check-affected/run.ts b/scripts/check-affected/run.ts index da02fe1a63..6387d4535e 100644 --- a/scripts/check-affected/run.ts +++ b/scripts/check-affected/run.ts @@ -8,7 +8,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/command'; import { checkLockfileInstallSync, STALE_NODE_MODULES_MESSAGE, diff --git a/scripts/check-replay-compat-provenance.ts b/scripts/check-replay-compat-provenance.ts index c9e1712153..ef0b52048a 100644 --- a/scripts/check-replay-compat-provenance.ts +++ b/scripts/check-replay-compat-provenance.ts @@ -16,7 +16,7 @@ import { REPLAY_COMPAT_RELEASED_TAGS, } from '../test/replay-compat/manifest.ts'; import { findProvenanceKindViolations } from '../test/replay-compat/provenance-rules.ts'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { repoGit, requireUnshallowHistory } from './lib/repo-git.ts'; const repoRoot = path.resolve(import.meta.dirname, '..'); diff --git a/scripts/check-tmpdir-leaks-model.ts b/scripts/check-tmpdir-leaks-model.ts index d6a60723b8..541c6fc1fb 100644 --- a/scripts/check-tmpdir-leaks-model.ts +++ b/scripts/check-tmpdir-leaks-model.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; // Every test run (Vitest via scripts/vitest-tmpdir-global-setup.ts, node --test // via scripts/node-test-tmpdir.ts) redirects TMPDIR into one disposable, diff --git a/scripts/check-xctest-selection.ts b/scripts/check-xctest-selection.ts index b3e177463c..6b8c36bbd1 100644 --- a/scripts/check-xctest-selection.ts +++ b/scripts/check-xctest-selection.ts @@ -35,7 +35,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import type { Platform } from './swift-conditional-compilation.ts'; import { parseDeclaredTestsByPlatform, diff --git a/scripts/coverage-changed/run.ts b/scripts/coverage-changed/run.ts index 1196b1a717..8d7644b07c 100644 --- a/scripts/coverage-changed/run.ts +++ b/scripts/coverage-changed/run.ts @@ -12,7 +12,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { parseScriptArgs } from '../lib/cli-args.ts'; import { computeChangedCoverage, diff --git a/scripts/fuzz/envelope.ts b/scripts/fuzz/envelope.ts index a60fc6a157..1dd928dfd0 100644 --- a/scripts/fuzz/envelope.ts +++ b/scripts/fuzz/envelope.ts @@ -14,7 +14,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { laneEnvelope } from '../lib/lane-envelope.ts'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import type { FuzzFailure } from './invariant.ts'; const FILENAME = 'run-envelope.json'; diff --git a/scripts/gate/check.ts b/scripts/gate/check.ts index fd6baca3ad..a9fe4c20ee 100644 --- a/scripts/gate/check.ts +++ b/scripts/gate/check.ts @@ -8,7 +8,7 @@ // launder a new step past review by regenerating it. import { pathToFileURL } from 'node:url'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { audit, formatFailures } from './audit.ts'; import { MANUAL_ONLY_OWNERS, UNPROVABLE_OWNERS } from './declarations.ts'; import { loadModel } from './model.ts'; diff --git a/scripts/gate/run.ts b/scripts/gate/run.ts index b2d928779b..b7122b4418 100644 --- a/scripts/gate/run.ts +++ b/scripts/gate/run.ts @@ -10,7 +10,7 @@ import { pathToFileURL } from 'node:url'; import fs from 'node:fs'; import path from 'node:path'; -import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/command'; import { runEntrypoint } from '../lib/cli-entrypoint.ts'; import { CHECK_CATALOG, resolveCommand } from '../check-affected/checks.ts'; diff --git a/scripts/layering/package-boundaries.test.ts b/scripts/layering/package-boundaries.test.ts index 3ef3a07dd0..99c8ec13f8 100644 --- a/scripts/layering/package-boundaries.test.ts +++ b/scripts/layering/package-boundaries.test.ts @@ -482,13 +482,18 @@ test('the real tree parses, declares, and passes R11', () => { true, 'host-kit stays a private implementation package', ); - // The four deep host-mechanics seams; any further subpath widens this key - // list and fails the assertion, same as the capture-kit pin above. + // One narrow capability port over the host machine per export; any further + // subpath widens this key list and fails the assertion, same as the + // capture-kit pin above. assert.deepEqual([...hostKitPackage.exportTargets.keys()].sort(), [ - '@agent-device/host-kit/exec', - '@agent-device/host-kit/fs', + '@agent-device/host-kit/archive', + '@agent-device/host-kit/command', + '@agent-device/host-kit/diagnostics', + '@agent-device/host-kit/file', + '@agent-device/host-kit/process', '@agent-device/host-kit/request', - '@agent-device/host-kit/values', + '@agent-device/host-kit/retry', + '@agent-device/host-kit/version', ]); assert.deepEqual([...hostKitPackage.workspaceDependencies].sort(), [ '@agent-device/contracts', diff --git a/scripts/lib/repo-git.ts b/scripts/lib/repo-git.ts index 310175e6c4..f7ea03ebb5 100644 --- a/scripts/lib/repo-git.ts +++ b/scripts/lib/repo-git.ts @@ -1,4 +1,4 @@ -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; export type RepoGit = (args: string[]) => string; diff --git a/scripts/mutation/envelope.test.ts b/scripts/mutation/envelope.test.ts index b6b2ba592e..f088c5146e 100644 --- a/scripts/mutation/envelope.test.ts +++ b/scripts/mutation/envelope.test.ts @@ -7,7 +7,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test } from 'node:test'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { laneEnvelope, LANE_ENVELOPE_SCHEMA_VERSION } from '../lib/lane-envelope.ts'; const repoRoot = path.resolve(import.meta.dirname, '../..'); diff --git a/scripts/mutation/run.ts b/scripts/mutation/run.ts index 64a87eeb47..a54bf59f03 100644 --- a/scripts/mutation/run.ts +++ b/scripts/mutation/run.ts @@ -15,7 +15,7 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdStreaming, runCmdSync } from '@agent-device/host-kit/command'; import { parseScriptArgs } from '../lib/cli-args.ts'; import { laneEnvelope } from '../lib/lane-envelope.ts'; import { diff --git a/scripts/mutation/selection.test.ts b/scripts/mutation/selection.test.ts index d8737e9231..da2766e614 100644 --- a/scripts/mutation/selection.test.ts +++ b/scripts/mutation/selection.test.ts @@ -8,7 +8,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { after, test } from 'node:test'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { LANE_CANARY, shardMatrix, type ShardSpec } from './modules.ts'; import { affectedMatrixFor } from './run.ts'; diff --git a/scripts/mutation/test-scope.ts b/scripts/mutation/test-scope.ts index 0961f37f4d..138ab0c8f9 100644 --- a/scripts/mutation/test-scope.ts +++ b/scripts/mutation/test-scope.ts @@ -27,7 +27,7 @@ import fs from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { readWorkspacePackages } from '../layering/package-boundaries.ts'; import { walkFiles } from '../lib/walk-files.ts'; import { isKernelTestFile, normalizePath } from './modules.ts'; diff --git a/scripts/node-test-tmpdir.test.ts b/scripts/node-test-tmpdir.test.ts index 0a1c54793d..cd490d2207 100644 --- a/scripts/node-test-tmpdir.test.ts +++ b/scripts/node-test-tmpdir.test.ts @@ -5,7 +5,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/command'; import { liveRunDirectoryConsumers, pruneAbandonedRunDirectories, @@ -318,7 +318,7 @@ test('a run whose owner alone was killed keeps its directory while a child still `import fs from 'node:fs'; import os from 'node:os'; import { test } from 'node:test'; -import { runCmdDetached } from '@agent-device/host-kit/exec'; +import { runCmdDetached } from '@agent-device/host-kit/command'; test('probe starts a long-lived detached child that inherits TMPDIR, then waits to be killed', async () => { const childPid = runCmdDetached(process.execPath, ['-e', 'setTimeout(() => {}, 60_000)']); diff --git a/scripts/node-test-tmpdir.ts b/scripts/node-test-tmpdir.ts index 921daf7746..35cfb89dac 100644 --- a/scripts/node-test-tmpdir.ts +++ b/scripts/node-test-tmpdir.ts @@ -27,7 +27,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { runCmdBackground } from '@agent-device/host-kit/exec'; +import { runCmdBackground } from '@agent-device/host-kit/command'; import { TEST_RUN_TMP_PREFIX, TEST_RUN_TMP_ROOT, diff --git a/scripts/perf/cli.ts b/scripts/perf/cli.ts index 437b1283ec..57ee22c56a 100644 --- a/scripts/perf/cli.ts +++ b/scripts/perf/cli.ts @@ -1,5 +1,5 @@ import { performance } from 'node:perf_hooks'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { resolveCliArgv, REPO_ROOT } from './config.ts'; import type { BatchStepSpec } from './scenario.ts'; import type { CliResult } from './types.ts'; diff --git a/scripts/swift-toolchain-tmpdir.test.ts b/scripts/swift-toolchain-tmpdir.test.ts index a6791263e8..22926193c5 100644 --- a/scripts/swift-toolchain-tmpdir.test.ts +++ b/scripts/swift-toolchain-tmpdir.test.ts @@ -4,7 +4,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/command'; const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const WRAPPER = path.join(REPOSITORY_ROOT, 'scripts', 'swift-toolchain-tmpdir.ts'); diff --git a/scripts/swift-toolchain-tmpdir.ts b/scripts/swift-toolchain-tmpdir.ts index a8e34b10b2..b4ce23e768 100644 --- a/scripts/swift-toolchain-tmpdir.ts +++ b/scripts/swift-toolchain-tmpdir.ts @@ -5,7 +5,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { runCmdBackground } from '@agent-device/host-kit/exec'; +import { runCmdBackground } from '@agent-device/host-kit/command'; const [command, ...args] = process.argv.slice(2); if (!command) { diff --git a/scripts/vitest-tmpdir-global-setup.test.ts b/scripts/vitest-tmpdir-global-setup.test.ts index 8317751d50..0154ae7328 100644 --- a/scripts/vitest-tmpdir-global-setup.test.ts +++ b/scripts/vitest-tmpdir-global-setup.test.ts @@ -5,7 +5,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { TEST_RUN_TMP_PREFIX, TEST_RUN_TMP_ROOT } from './check-tmpdir-leaks-model.ts'; const REPOSITORY_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); diff --git a/src/__tests__/apple-runner-package-source.test.ts b/src/__tests__/apple-runner-package-source.test.ts index 16faac4553..b9d86012db 100644 --- a/src/__tests__/apple-runner-package-source.test.ts +++ b/src/__tests__/apple-runner-package-source.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { onTestFinished, test } from 'vitest'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); diff --git a/src/__tests__/cli-agent-cdp.test.ts b/src/__tests__/cli-agent-cdp.test.ts index 2a61c7d88f..d9a5f6d952 100644 --- a/src/__tests__/cli-agent-cdp.test.ts +++ b/src/__tests__/cli-agent-cdp.test.ts @@ -2,11 +2,11 @@ import fs from 'node:fs'; import assert from 'node:assert/strict'; import { afterEach, test, vi } from 'vitest'; -vi.mock('@agent-device/host-kit/exec', () => ({ +vi.mock('@agent-device/host-kit/command', () => ({ runCmdStreaming: vi.fn(), })); -import { runCmdStreaming } from '@agent-device/host-kit/exec'; +import { runCmdStreaming } from '@agent-device/host-kit/command'; import { AGENT_CDP_PACKAGE, buildAgentCdpNpmExecArgs, diff --git a/src/__tests__/cli-auth-diagnostics.test.ts b/src/__tests__/cli-auth-diagnostics.test.ts index 1d9fedf610..0df3a38443 100644 --- a/src/__tests__/cli-auth-diagnostics.test.ts +++ b/src/__tests__/cli-auth-diagnostics.test.ts @@ -1,7 +1,7 @@ import { test } from 'vitest'; import assert from 'node:assert/strict'; import fs from 'node:fs'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { runCliCapture } from './cli-capture.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; diff --git a/src/__tests__/cli-debug-symbols.test.ts b/src/__tests__/cli-debug-symbols.test.ts index 713b217bc1..8803040b58 100644 --- a/src/__tests__/cli-debug-symbols.test.ts +++ b/src/__tests__/cli-debug-symbols.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs/promises'; import path from 'node:path'; import { test } from 'vitest'; -import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { runCliCapture } from './cli-capture.ts'; import { mkdtempForTest } from './test-utils/tmp-dir.ts'; diff --git a/src/__tests__/cli-device-status.test.ts b/src/__tests__/cli-device-status.test.ts index 617467e2db..34ac4f1221 100644 --- a/src/__tests__/cli-device-status.test.ts +++ b/src/__tests__/cli-device-status.test.ts @@ -2,12 +2,12 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test, vi } from 'vitest'; -import { readCurrentOwnerIdentity } from '@agent-device/host-kit/exec'; +import { readCurrentOwnerIdentity } from '@agent-device/host-kit/process'; import { runCliCapture } from './cli-capture.ts'; import { publishDaemonRegistration } from './test-utils/device-claim-store.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => +vi.mock('@agent-device/host-kit/process', async (importOriginal) => (await import('./test-utils/host-process-mock.ts')).pinOwnProcessStartTime(importOriginal), ); diff --git a/src/__tests__/cli-react-devtools.test.ts b/src/__tests__/cli-react-devtools.test.ts index f67e9bfb0c..76b21cd51c 100644 --- a/src/__tests__/cli-react-devtools.test.ts +++ b/src/__tests__/cli-react-devtools.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import { afterEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('@agent-device/host-kit/exec', () => ({ +vi.mock('@agent-device/host-kit/command', () => ({ runCmdStreaming: vi.fn(), })); @@ -11,7 +11,7 @@ vi.mock('../client/client-react-devtools-companion.ts', () => ({ stopReactDevtoolsCompanion: vi.fn(), })); -import { runCmdStreaming } from '@agent-device/host-kit/exec'; +import { runCmdStreaming } from '@agent-device/host-kit/command'; import { ensureReactDevtoolsCompanion, stopReactDevtoolsCompanion, diff --git a/src/__tests__/cli-web.test.ts b/src/__tests__/cli-web.test.ts index c62a3fab8a..66f34010d6 100644 --- a/src/__tests__/cli-web.test.ts +++ b/src/__tests__/cli-web.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import { test } from 'vitest'; import { runCliCapture } from './cli-capture.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { installFakeManagedAgentBrowser, withNodeRuntime, diff --git a/src/__tests__/client-metro-companion.test.ts b/src/__tests__/client-metro-companion.test.ts index 04eb4cf40d..cc3485029c 100644 --- a/src/__tests__/client-metro-companion.test.ts +++ b/src/__tests__/client-metro-companion.test.ts @@ -4,22 +4,25 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/command', async (importOriginal) => ({ + ...(await importOriginal()), runCmdDetached: vi.fn(), +})); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: vi.fn(), readProcessCommand: vi.fn(), readProcessStartTime: vi.fn(), waitForProcessExit: vi.fn(), })); +import { runCmdDetached } from '@agent-device/host-kit/command'; import { - runCmdDetached, isProcessAlive, readProcessCommand, readProcessStartTime, waitForProcessExit, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; import { ensureMetroCompanion, stopMetroCompanion } from '../metro/client-metro-companion.ts'; import { ensureReactDevtoolsCompanion } from '../client/client-react-devtools-companion.ts'; diff --git a/src/__tests__/client-metro-startup-cleanup.test.ts b/src/__tests__/client-metro-startup-cleanup.test.ts index 900b90fbe2..b2adc994f9 100644 --- a/src/__tests__/client-metro-startup-cleanup.test.ts +++ b/src/__tests__/client-metro-startup-cleanup.test.ts @@ -4,14 +4,18 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/command', async (importOriginal) => ({ + ...(await importOriginal()), runCmdDetached: vi.fn(), runCmdSync: vi.fn(), +})); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => ({ + ...(await importOriginal()), waitForProcessExit: vi.fn(), })); -import { runCmdDetached, waitForProcessExit } from '@agent-device/host-kit/exec'; +import { runCmdDetached } from '@agent-device/host-kit/command'; +import { waitForProcessExit } from '@agent-device/host-kit/process'; import { prepareMetroRuntime } from '../metro/client-metro.ts'; diff --git a/src/__tests__/client-metro.test.ts b/src/__tests__/client-metro.test.ts index ca228be85f..97b404851d 100644 --- a/src/__tests__/client-metro.test.ts +++ b/src/__tests__/client-metro.test.ts @@ -14,7 +14,7 @@ import { createAgentDeviceClient } from '../agent-device-client.ts'; import { readMetroSessionHints } from '../metro/metro-session-hints.ts'; import { resolveDaemonPaths } from '../daemon/config.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { isProcessAlive, waitForProcessExit } from '@agent-device/host-kit/exec'; +import { isProcessAlive, waitForProcessExit } from '@agent-device/host-kit/process'; const TEST_TOKEN = 'agent-device-proxy-test-token'; diff --git a/src/__tests__/daemon-entrypoint.test.ts b/src/__tests__/daemon-entrypoint.test.ts index e75a2cca1d..d88c62a617 100644 --- a/src/__tests__/daemon-entrypoint.test.ts +++ b/src/__tests__/daemon-entrypoint.test.ts @@ -10,7 +10,8 @@ import { cleanupDownloadableArtifact, trackDownloadableArtifact, } from '../daemon/artifact-tracking.ts'; -import { runCmdBackground, isProcessAlive, waitForProcessExit } from '@agent-device/host-kit/exec'; +import { runCmdBackground } from '@agent-device/host-kit/command'; +import { isProcessAlive, waitForProcessExit } from '@agent-device/host-kit/process'; import { closeLoopbackServer, listenOnLoopback, waitForHttpOk } from './test-utils/loopback.ts'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; diff --git a/src/__tests__/eager-closure-budgets.ts b/src/__tests__/eager-closure-budgets.ts index e97902c05a..da0bbf96ae 100644 --- a/src/__tests__/eager-closure-budgets.ts +++ b/src/__tests__/eager-closure-budgets.ts @@ -122,10 +122,10 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ // --- @agent-device/capture-kit --- // R60 review: audio-probe split into descriptor/status/recovery/live-process modules (+3 files). 'packages/capture-kit/src/index.ts': 32, - 'packages/capture-kit/src/png-resize.ts': 28, + 'packages/capture-kit/src/png-resize.ts': 18, 'packages/capture-kit/src/png-rgb-difference.ts': 1, 'packages/capture-kit/src/png-size.ts': 3, - 'packages/capture-kit/src/png-worker-client.ts': 20, + 'packages/capture-kit/src/png-worker-client.ts': 10, 'packages/capture-kit/src/png.ts': 3, 'packages/capture-kit/src/screenshot-density.ts': 6, 'packages/capture-kit/src/screenshot-diff-pixels.ts': 1, @@ -135,11 +135,16 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/capture-kit/src/snapshot-quality-verdict.ts': 2, // --- @agent-device/host-kit --- - // Deep seams: each façade eagerly closes over the internal modules it names. - 'packages/host-kit/src/exec.ts': 14, - 'packages/host-kit/src/fs.ts': 19, + // One capability port per export: the row is what a consumer of that + // capability evaluates, so a port that grew unrelated mechanics shows here. + 'packages/host-kit/src/archive.ts': 9, + 'packages/host-kit/src/command.ts': 7, + 'packages/host-kit/src/diagnostics.ts': 3, + 'packages/host-kit/src/file.ts': 12, + 'packages/host-kit/src/process.ts': 12, 'packages/host-kit/src/request.ts': 5, - 'packages/host-kit/src/values.ts': 12, + 'packages/host-kit/src/retry.ts': 6, + 'packages/host-kit/src/version.ts': 4, // --- @agent-device/contracts --- 'packages/contracts/src/alert-contract.ts': 1, @@ -257,6 +262,14 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ // #2082 W1: geometry/vocabulary sunk below contracts. 'packages/kernel/src/rect-center.ts': 2, 'packages/kernel/src/rect.ts': 1, + // #2082 W1: pure primitives that were never host mechanics. + 'packages/kernel/src/device-isolation.ts': 1, + 'packages/kernel/src/location-coordinates.ts': 3, + 'packages/kernel/src/record.ts': 3, + 'packages/kernel/src/scoped-provider.ts': 1, + 'packages/kernel/src/source-value.ts': 3, + 'packages/kernel/src/success-text.ts': 1, + 'packages/kernel/src/ttl-memo.ts': 1, 'packages/kernel/src/redaction.ts': 1, 'packages/kernel/src/scroll-indicator.ts': 1, 'packages/kernel/src/snapshot.ts': 1, @@ -360,7 +373,7 @@ export const HUB_BUDGETS: Readonly> = Object.freeze({ // readers), `input-audience.ts` (who may write a key), and `common-input-fields.ts` (the table // itself). Every command schema already evaluated all three concerns; the growth is three more // module records for the same code, with no new subtree behind any of them. - 'src/cli.ts': 386, + 'src/cli.ts': 380, 'src/platform-runtime.ts': 47, 'src/core/command-descriptor/registry.ts': 67, 'src/core/command-descriptor/platform-execution-entry.ts': 3, @@ -368,7 +381,7 @@ export const HUB_BUDGETS: Readonly> = Object.freeze({ // R64 removes the perf plugin facet and keeps collector binding behind the selected runtime // operation. Teardown now owns only neutral durable-resource cleanup; platform collectors load // through the perf host when an admitted operation actually runs. - 'src/daemon/session-teardown.ts': 79, + 'src/daemon/session-teardown.ts': 68, }); /** diff --git a/src/__tests__/limrun-runtime.test.ts b/src/__tests__/limrun-runtime.test.ts index a751f5954e..dd3446fbeb 100644 --- a/src/__tests__/limrun-runtime.test.ts +++ b/src/__tests__/limrun-runtime.test.ts @@ -6,8 +6,8 @@ import { LimrunRuntime } from '../sdk/limrun.ts'; import { createExpiredProviderLeaseReleaser } from '../daemon/provider-lease-expiry.ts'; import type { SimulatorLease } from '../daemon/lease-registry.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { runCmd } from '@agent-device/host-kit/exec'; -import { readVersion } from '@agent-device/host-kit/values'; +import { runCmd } from '@agent-device/host-kit/command'; +import { readVersion } from '@agent-device/host-kit/version'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; type LimrunInstancePage = { @@ -114,8 +114,8 @@ vi.mock('@limrun/api/instance-client', () => ({ })), })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async () => ({ stdout: '', stderr: '', exitCode: 0 })), diff --git a/src/__tests__/process-memo-setup.ts b/src/__tests__/process-memo-setup.ts index 34a46875b3..10f9a6f807 100644 --- a/src/__tests__/process-memo-setup.ts +++ b/src/__tests__/process-memo-setup.ts @@ -1,6 +1,6 @@ import { afterEach } from 'vitest'; -import { resetAllProcessMemosForTests } from '@agent-device/host-kit/values'; +import { resetAllProcessMemosForTests } from '@agent-device/kernel/ttl-memo'; afterEach(() => { resetAllProcessMemosForTests(); diff --git a/src/__tests__/test-utils/device-claim-store.ts b/src/__tests__/test-utils/device-claim-store.ts index a503b0d6da..f1acf204cb 100644 --- a/src/__tests__/test-utils/device-claim-store.ts +++ b/src/__tests__/test-utils/device-claim-store.ts @@ -3,7 +3,7 @@ import path from 'node:path'; import { afterEach } from 'vitest'; import { mkdtempForTestSync } from './tmp-dir.ts'; import type { DeviceClaimReconciler } from '../../daemon/device-claims.ts'; -import type { OwnerIdentity } from '@agent-device/host-kit/exec'; +import { type OwnerIdentity } from '@agent-device/host-kit/process'; export type IsolatedDeviceClaimStore = { /** Temporary root holding both the claim store and the daemon state dir. */ diff --git a/src/__tests__/test-utils/exec-faults.ts b/src/__tests__/test-utils/exec-faults.ts index 6b0cad89c1..102ed552c3 100644 --- a/src/__tests__/test-utils/exec-faults.ts +++ b/src/__tests__/test-utils/exec-faults.ts @@ -1,4 +1,8 @@ -import type { CommandExecutorOverride, ExecOptions, ExecResult } from '@agent-device/host-kit/exec'; +import { + type CommandExecutorOverride, + type ExecOptions, + type ExecResult, +} from '@agent-device/host-kit/command'; export type RecordedCommand = Readonly<{ command: string; diff --git a/src/__tests__/test-utils/fake-apple-tool.ts b/src/__tests__/test-utils/fake-apple-tool.ts index afdaba7906..384d65313b 100644 --- a/src/__tests__/test-utils/fake-apple-tool.ts +++ b/src/__tests__/test-utils/fake-apple-tool.ts @@ -2,7 +2,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import type { AppleToolProvider } from '../../platforms/apple/core/tool-provider.ts'; import { withAppleToolProvider } from '../../platforms/apple/core/tool-provider.ts'; -import { execFailureDetails, type ExecResult } from '@agent-device/host-kit/exec'; +import { execFailureDetails, type ExecResult } from '@agent-device/host-kit/command'; import { IOS_DEVICE } from './device-fixtures.ts'; /** diff --git a/src/__tests__/test-utils/filesystem-boundary-faults.ts b/src/__tests__/test-utils/filesystem-boundary-faults.ts index 3e173fdd60..fb8dcf8833 100644 --- a/src/__tests__/test-utils/filesystem-boundary-faults.ts +++ b/src/__tests__/test-utils/filesystem-boundary-faults.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { test, vi } from 'vitest'; -import { isAtomicPublishTemporaryPath } from '@agent-device/host-kit/fs'; +import { isAtomicPublishTemporaryPath } from '@agent-device/host-kit/file'; import { mkdtempForTestSync } from './tmp-dir.ts'; export type FilesystemErrno = 'EIO' | 'ENOSPC' | 'EMFILE'; diff --git a/src/__tests__/test-utils/host-process-mock.ts b/src/__tests__/test-utils/host-process-mock.ts index 57bd3ab756..4b33394cf2 100644 --- a/src/__tests__/test-utils/host-process-mock.ts +++ b/src/__tests__/test-utils/host-process-mock.ts @@ -1,6 +1,6 @@ -type HostProcessModule = typeof import('@agent-device/host-kit/exec'); +type HostProcessModule = typeof import('@agent-device/host-kit/process'); type HostProcessIdentityObservation = - import('@agent-device/host-kit/exec').HostProcessIdentityObservation; + import('@agent-device/host-kit/process').HostProcessIdentityObservation; /** * `vi.mock` factory for the host-kit `exec` seam in tests that seed a "live" @@ -16,7 +16,7 @@ type HostProcessIdentityObservation = * syscall, not a subprocess), so fabricated dead-pid fixtures still classify * as dead through that non-flaky check. * - * Usage: `vi.mock('@agent-device/host-kit/exec', async (importOriginal) => + * Usage: `vi.mock('@agent-device/host-kit/process', async (importOriginal) => * (await import('/test-utils/host-process-mock.ts')).pinOwnProcessStartTime(importOriginal))` */ // Consumed by three suites, but only through `(await import(...)).pinOwnProcessStartTime` diff --git a/src/__tests__/update-check.test.ts b/src/__tests__/update-check.test.ts index f687616a9b..19744d5b42 100644 --- a/src/__tests__/update-check.test.ts +++ b/src/__tests__/update-check.test.ts @@ -4,11 +4,11 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', () => ({ +vi.mock('@agent-device/host-kit/command', () => ({ runCmdDetached: vi.fn(), })); -import { runCmdDetached } from '@agent-device/host-kit/exec'; +import { runCmdDetached } from '@agent-device/host-kit/command'; import { maybeRunUpgradeNotifier, runUpdateCheckWorker } from '../utils/update-check.ts'; function makeTempStateDir(): string { diff --git a/src/__tests__/upload-client.test.ts b/src/__tests__/upload-client.test.ts index 50776087b6..f9de9991dc 100644 --- a/src/__tests__/upload-client.test.ts +++ b/src/__tests__/upload-client.test.ts @@ -7,7 +7,7 @@ import path from 'node:path'; import { once } from 'node:events'; import { uploadArtifact } from '../remote/upload-client.ts'; import type { UploadProgressEvent } from '../remote/upload-progress.ts'; -import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { mkdtempForTestSync } from './test-utils/tmp-dir.ts'; const TEST_TOKEN = 'agent-device-upload-test-token'; diff --git a/src/agent-device-client.ts b/src/agent-device-client.ts index df7c485b74..1793da8209 100644 --- a/src/agent-device-client.ts +++ b/src/agent-device-client.ts @@ -78,7 +78,7 @@ import { writeMetroSessionHints, type MetroSessionHints, } from './metro/metro-session-hints.ts'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import { readScreenshotResultData } from './utils/screenshot-result.ts'; type ProjectedSystemCommandClient = ProjectedNavigationCommandClient & diff --git a/src/bin.ts b/src/bin.ts index 17bdf8d5c3..beef52ef75 100644 --- a/src/bin.ts +++ b/src/bin.ts @@ -24,7 +24,7 @@ function runVersionFastPath(argv: string[]): boolean { process.stdout.write(`${__AGENT_DEVICE_VERSION__}\n`); return true; } - import('@agent-device/host-kit/values') + import('@agent-device/host-kit/version') .then(({ readVersion }) => { process.stdout.write(`${readVersion()}\n`); }) diff --git a/src/cli-schema/cli-config.ts b/src/cli-schema/cli-config.ts index 2bc94379a8..4d6d4027c8 100644 --- a/src/cli-schema/cli-config.ts +++ b/src/cli-schema/cli-config.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import { mergeDefinedFlags } from '../utils/merge-flags.ts'; import { type FlagKey } from '../commands/cli-grammar/flag-types.ts'; -import { expandUserHomePath, resolveUserPath } from '@agent-device/host-kit/fs'; +import { expandUserHomePath, resolveUserPath } from '@agent-device/host-kit/file'; import { getConfigurableOptionSpecs, getOptionSpec, @@ -12,7 +12,7 @@ import { } from './option-schema.ts'; import { parseInstallSourceConfig } from '../utils/install-source-config.ts'; import { RETIRED_SCREENSHOT_MAX_SIZE } from '@agent-device/contracts/capture'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; export function resolveConfigBackedFlagDefaults(options: { command: string | null; diff --git a/src/cli-schema/cli-help-examples.test.ts b/src/cli-schema/cli-help-examples.test.ts index d34f14eaab..7dc67824a1 100644 --- a/src/cli-schema/cli-help-examples.test.ts +++ b/src/cli-schema/cli-help-examples.test.ts @@ -7,7 +7,7 @@ import { buildCommandUsageText, buildUsageText, helpTopicIds } from './cli-help. import { listCliCommandNames } from '../command-catalog.ts'; import { readInputFromCli } from '../commands/cli-grammar.ts'; import { findCommandMetadata, isCommandName } from '../commands/command-metadata.ts'; -import { readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; // Help is the agent-facing contract, and agents copy its example lines verbatim, so an example the // CLI schema rejects is a broken command surface — not a docs nit (#1765: `help react-native` diff --git a/src/cli-schema/cli-help.ts b/src/cli-schema/cli-help.ts index bad1b0f1d0..36bbc4ca97 100644 --- a/src/cli-schema/cli-help.ts +++ b/src/cli-schema/cli-help.ts @@ -16,7 +16,7 @@ import { type FlagKey, } from './command-schema.ts'; import { buildCommandUsage } from './usage.ts'; -import { readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; import { renderCliHelpOverview } from './cli-help-overview.ts'; const CONFIGURATION_LINES = [ diff --git a/src/cli-schema/option-schema.ts b/src/cli-schema/option-schema.ts index 0e2fbdd7b6..9f92cddb72 100644 --- a/src/cli-schema/option-schema.ts +++ b/src/cli-schema/option-schema.ts @@ -1,4 +1,4 @@ -import { buildPrimaryEnvVarName, parseSourceValue } from '@agent-device/host-kit/values'; +import { buildPrimaryEnvVarName, parseSourceValue } from '@agent-device/kernel/source-value'; import { listCliCommandNames } from '../command-catalog.ts'; import { getCliCommandSchema, diff --git a/src/cli.ts b/src/cli.ts index 2abb766098..ca639e69d7 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -10,7 +10,7 @@ import { import { resolveRemoteRequestDiagnosticsPath } from './daemon/session-store.ts'; import { printHumanError, printJson } from './utils/output.ts'; import { exitAfterFlush } from './utils/process-exit.ts'; -import { readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; import { pathToFileURL } from 'node:url'; import { sendToDaemon } from './daemon/client/daemon-client.ts'; import fs from 'node:fs'; @@ -34,7 +34,7 @@ import { getDiagnosticsMeta, registerDiagnosticSensitiveValue, withDiagnosticsScope, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import { resolveDaemonPaths } from './daemon/config.ts'; import { applyDefaultPlatformBinding, resolveBindingSettings } from './utils/session-binding.ts'; import { resolveCliOptions } from './cli/resolve-cli-options.ts'; diff --git a/src/cli/auth-session.ts b/src/cli/auth-session.ts index fd5a5e0234..a58becae2d 100644 --- a/src/cli/auth-session.ts +++ b/src/cli/auth-session.ts @@ -1,9 +1,9 @@ import fs from 'node:fs'; import path from 'node:path'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import { readCloudJsonResponse } from './cloud-response.ts'; const DEFAULT_CLOUD_BASE_URL = 'https://cloud.agent-device.dev'; diff --git a/src/cli/commands/agent-cdp.ts b/src/cli/commands/agent-cdp.ts index 4e98f79147..092d8c2cbc 100644 --- a/src/cli/commands/agent-cdp.ts +++ b/src/cli/commands/agent-cdp.ts @@ -1,4 +1,4 @@ -import { runCmdStreaming } from '@agent-device/host-kit/exec'; +import { runCmdStreaming } from '@agent-device/host-kit/command'; import { AppError } from '@agent-device/kernel/errors'; import { isRemoteBridgeBackend } from './remote-bridge.ts'; import type { SessionRuntimeHints } from '@agent-device/kernel/contracts'; diff --git a/src/cli/commands/connection-presentation.ts b/src/cli/commands/connection-presentation.ts index 748816ddd3..7257a8f184 100644 --- a/src/cli/commands/connection-presentation.ts +++ b/src/cli/commands/connection-presentation.ts @@ -1,7 +1,7 @@ import { fingerprint, type RemoteConnectionState } from '../../remote/remote-connection-state.ts'; import type { ConnectVerification } from '../connection/connect-provider-adapters.ts'; import { connectionProviderLeaseKind } from '../connection/provider-policy.ts'; -import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; export type ConnectReadiness = ConnectVerification & { preparationMessage: string; diff --git a/src/cli/commands/connection.ts b/src/cli/commands/connection.ts index e9110b6276..2efdff6ca2 100644 --- a/src/cli/commands/connection.ts +++ b/src/cli/commands/connection.ts @@ -32,7 +32,7 @@ import { stopReactDevtoolsCleanup, } from './connection-runtime.ts'; import { writeCommandOutput } from './shared.ts'; -import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; import type { LeaseBackend } from '@agent-device/kernel/contracts'; import type { CliFlags } from '@agent-device/contracts/command'; import type { ClientCommandHandler } from './router-types.ts'; diff --git a/src/cli/commands/device.ts b/src/cli/commands/device.ts index 5285491a93..92b261c99f 100644 --- a/src/cli/commands/device.ts +++ b/src/cli/commands/device.ts @@ -5,7 +5,7 @@ import { inspectDeviceClaims, type InspectedDeviceClaim, } from '../../daemon/device-claim-inspection.ts'; -import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; import { writeCommandOutput } from './shared.ts'; import type { ClientCommandHandler } from './router-types.ts'; diff --git a/src/cli/commands/generic.ts b/src/cli/commands/generic.ts index 114c9ab24c..25bc7f7c9a 100644 --- a/src/cli/commands/generic.ts +++ b/src/cli/commands/generic.ts @@ -4,7 +4,7 @@ import type { CommandName } from '../../commands/command-metadata.ts'; import type { CliOutput } from '../../commands/command-contract.ts'; import type { ReplaySuiteResult } from '@agent-device/contracts/replay'; import type { CliFlags } from '@agent-device/contracts/command'; -import { readCommandMessage } from '@agent-device/host-kit/values'; +import { readCommandMessage } from '@agent-device/kernel/success-text'; import { isNonDefaultResponseLevel } from '@agent-device/kernel/contracts'; import { writeCommandOutput } from './shared.ts'; import type { ClientBackedCliCommandName } from './client-backed.ts'; diff --git a/src/cli/commands/react-devtools.ts b/src/cli/commands/react-devtools.ts index 03d4fefd17..c0ce8ba032 100644 --- a/src/cli/commands/react-devtools.ts +++ b/src/cli/commands/react-devtools.ts @@ -1,4 +1,4 @@ -import { runCmdStreaming } from '@agent-device/host-kit/exec'; +import { runCmdStreaming } from '@agent-device/host-kit/command'; import { ensureReactDevtoolsCompanion, stopReactDevtoolsCompanion, diff --git a/src/cli/commands/replay.ts b/src/cli/commands/replay.ts index 8c70287820..933596ff60 100644 --- a/src/cli/commands/replay.ts +++ b/src/cli/commands/replay.ts @@ -4,7 +4,7 @@ import { exportReplayActionsToMaestro, MAESTRO_SELECTOR_PROJECTION } from '@agen import { AppError } from '@agent-device/kernel/errors'; import { parseReplayScriptDetailed, readReplayScriptMetadata } from '@agent-device/ad-script'; import { projectSelectorExpression } from '@agent-device/selectors'; -import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { resolveUserPath } from '@agent-device/host-kit/file'; import { writeCommandOutput } from './shared.ts'; import type { ClientCommandHandler } from './router-types.ts'; diff --git a/src/cli/commands/screenshot.ts b/src/cli/commands/screenshot.ts index 06df3d2121..554f232322 100644 --- a/src/cli/commands/screenshot.ts +++ b/src/cli/commands/screenshot.ts @@ -2,7 +2,7 @@ import { formatScreenshotDiffText, formatSnapshotDiffText } from '../../utils/ou import type { ScreenshotDiffResult } from '../../screenshot-diff/screenshot-diff.ts'; import { AppError } from '@agent-device/kernel/errors'; import { isNonDefaultResponseLevel } from '@agent-device/kernel/contracts'; -import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { resolveUserPath } from '@agent-device/host-kit/file'; import type { AgentDeviceBackend } from '../../backend.ts'; import type { AgentDeviceClient, CaptureScreenshotResult } from '../../agent-device-client.ts'; import { runCliCommand } from '../../commands/cli-runner.ts'; diff --git a/src/cli/connection/cloud-profile.ts b/src/cli/connection/cloud-profile.ts index 3fd03910ea..37a8017b3a 100644 --- a/src/cli/connection/cloud-profile.ts +++ b/src/cli/connection/cloud-profile.ts @@ -1,7 +1,7 @@ import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import { resolveCloudAccessForConnect } from '../auth-session.ts'; import { readCloudJsonResponse } from '../cloud-response.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; diff --git a/src/cli/connection/cloud-webdriver-profile.ts b/src/cli/connection/cloud-webdriver-profile.ts index e28927e15d..ffa64093af 100644 --- a/src/cli/connection/cloud-webdriver-profile.ts +++ b/src/cli/connection/cloud-webdriver-profile.ts @@ -10,7 +10,7 @@ import type { PlatformSelector } from '@agent-device/kernel/device'; import type { CliFlags } from '@agent-device/contracts/command'; import fs from 'node:fs'; import path from 'node:path'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import { readCloudDeviceFeatureProfileFields, readMetroProfileFields } from './profile-fields.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; import { resolveRequestedLeaseBackend } from '../commands/connection-runtime.ts'; diff --git a/src/cli/connection/connect-provider-adapters.ts b/src/cli/connection/connect-provider-adapters.ts index 330bfd958e..572fbf5b63 100644 --- a/src/cli/connection/connect-provider-adapters.ts +++ b/src/cli/connection/connect-provider-adapters.ts @@ -4,7 +4,8 @@ import { verifyLimrunConnection } from '@agent-device/provider-limrun'; import { AppError } from '@agent-device/kernel/errors'; import { providerWebDriver } from '../../provider-webdriver.ts'; import { resolveRemoteConfigProfile } from '../../remote/remote-config.ts'; -import { type EnvMap, readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import { resolveCloudConnectProfile } from './cloud-profile.ts'; import { resolveCloudWebDriverConnectProfile } from './cloud-webdriver-profile.ts'; diff --git a/src/cli/connection/generated-config.ts b/src/cli/connection/generated-config.ts index 09247586b4..aebdf467aa 100644 --- a/src/cli/connection/generated-config.ts +++ b/src/cli/connection/generated-config.ts @@ -7,7 +7,7 @@ import type { ResolvedRemoteConfigProfile, } from '../../remote/remote-config-schema.ts'; import { AppError, asAppError } from '@agent-device/kernel/errors'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import type { CliFlags } from '@agent-device/contracts/command'; import { profileToCliFlags } from '../remote-config-flags.ts'; diff --git a/src/cli/connection/limrun-profile.ts b/src/cli/connection/limrun-profile.ts index bb65ca5d69..20ad38b56d 100644 --- a/src/cli/connection/limrun-profile.ts +++ b/src/cli/connection/limrun-profile.ts @@ -2,7 +2,7 @@ import { resolveDaemonPaths } from '../../daemon/config.ts'; import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import { readMetroProfileFields } from './profile-fields.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; import { resolveRequestedLeaseBackend } from '../commands/connection-runtime.ts'; diff --git a/src/cli/connection/proxy-profile.ts b/src/cli/connection/proxy-profile.ts index 79d1f38ad0..22f2658e9c 100644 --- a/src/cli/connection/proxy-profile.ts +++ b/src/cli/connection/proxy-profile.ts @@ -1,7 +1,7 @@ import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import { readMetroProfileFields } from './profile-fields.ts'; import { persistAndResolveGeneratedProfile } from './generated-config.ts'; import { resolveRequestedLeaseBackend } from '../commands/connection-runtime.ts'; diff --git a/src/cli/resolve-cli-options.ts b/src/cli/resolve-cli-options.ts index f2e82d39b5..e1fe640039 100644 --- a/src/cli/resolve-cli-options.ts +++ b/src/cli/resolve-cli-options.ts @@ -3,7 +3,7 @@ import { mergeDefinedFlags } from '../utils/merge-flags.ts'; import { finalizeParsedArgs, parseRawArgs } from './parser/args.ts'; import { resolveConfigBackedFlagDefaults } from '../cli-schema/cli-config.ts'; import { resolveRemoteConfigDefaults } from './remote-config-flags.ts'; -import type { EnvMap } from '@agent-device/host-kit/values'; +import { type EnvMap } from '@agent-device/kernel/source-value'; export function resolveCliOptions( argv: string[], diff --git a/src/client/client-companion-tunnel.ts b/src/client/client-companion-tunnel.ts index 216ff4548e..f19427d0ee 100644 --- a/src/client/client-companion-tunnel.ts +++ b/src/client/client-companion-tunnel.ts @@ -18,13 +18,13 @@ import { ENV_COMPANION_TUNNEL_UNREGISTER_PATH, } from './client-companion-tunnel-contract.ts'; import { normalizeBaseUrl } from '../utils/url.ts'; +import { runCmdDetached } from '@agent-device/host-kit/command'; import { - runCmdDetached, isProcessAlive, readProcessCommand, readProcessStartTime, waitForProcessExit, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; const COMPANION_TUNNEL_TERM_TIMEOUT_MS = 1_000; const COMPANION_TUNNEL_KILL_TIMEOUT_MS = 1_000; diff --git a/src/client/client-normalizers.ts b/src/client/client-normalizers.ts index 417ba49146..d0962c89f4 100644 --- a/src/client/client-normalizers.ts +++ b/src/client/client-normalizers.ts @@ -33,10 +33,10 @@ import { readRequiredPlatform, readRequiredString, stripUndefined, -} from '@agent-device/host-kit/values'; +} from '@agent-device/kernel/record'; import { buildAppIdentifiers, buildDeviceIdentifiers } from '../utils/result-serialization.ts'; -export { readOptionalString, readRequiredString } from '@agent-device/host-kit/values'; +export { readOptionalString, readRequiredString } from '@agent-device/kernel/record'; const DEFAULT_SESSION_NAME = 'default'; diff --git a/src/commands/batch/output.ts b/src/commands/batch/output.ts index 80a470ca98..4dc6da9461 100644 --- a/src/commands/batch/output.ts +++ b/src/commands/batch/output.ts @@ -1,5 +1,5 @@ import type { BatchRunResult, BatchStepResult } from '../../core/batch.ts'; -import { readCommandMessage } from '@agent-device/host-kit/values'; +import { readCommandMessage } from '@agent-device/kernel/success-text'; import type { CliOutput } from '../command-contract.ts'; import { resultOutput, type CliOutputFormatter } from '../output-common.ts'; diff --git a/src/commands/capture/runtime/screenshot.ts b/src/commands/capture/runtime/screenshot.ts index 900cb51c08..b71f62d8d8 100644 --- a/src/commands/capture/runtime/screenshot.ts +++ b/src/commands/capture/runtime/screenshot.ts @@ -1,6 +1,6 @@ import { AppError } from '@agent-device/kernel/errors'; import { validateScreenshotScale } from '@agent-device/contracts/capture'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { resizePngFileToScale } from '@agent-device/capture-kit/png-resize'; import type { ArtifactDescriptor } from '../../../io.ts'; import type { RuntimeCommand, ScreenshotCommandOptions } from '../../runtime-types.ts'; diff --git a/src/commands/capture/settings.ts b/src/commands/capture/settings.ts index 6d81a31b7d..9e2673b013 100644 --- a/src/commands/capture/settings.ts +++ b/src/commands/capture/settings.ts @@ -4,7 +4,7 @@ import { SETTINGS_USAGE_OVERRIDE } from '@agent-device/contracts/settings'; import type { CommandSchemaOverride } from '../../cli-schema/types.ts'; import type { CliFlags } from '@agent-device/contracts/command'; import { AppError } from '@agent-device/kernel/errors'; -import { readLocationCoordinate } from '@agent-device/host-kit/values'; +import { readLocationCoordinate } from '@agent-device/kernel/location-coordinates'; import { defineExecutableCommand } from '../command-contract.ts'; import { enumField, numberField, requiredField, stringField } from '../command-input.ts'; import { diff --git a/src/commands/command-flags.ts b/src/commands/command-flags.ts index 61ab560c6b..21f3d9b8ea 100644 --- a/src/commands/command-flags.ts +++ b/src/commands/command-flags.ts @@ -1,7 +1,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import { screenshotFlagsFromOptions } from '@agent-device/contracts/capture'; import { leaseScopeFromOptions, leaseScopeToCommandFlags } from '../core/lease-scope.ts'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; import { getFlagDefinitions } from './cli-grammar/flag-registry.ts'; import type { InternalRequestOptions } from '@agent-device/contracts/client'; import type { CommandMetadata } from './command-contract.ts'; diff --git a/src/commands/input-audience.ts b/src/commands/input-audience.ts index 8ae1e6fcf7..17edee193f 100644 --- a/src/commands/input-audience.ts +++ b/src/commands/input-audience.ts @@ -1,4 +1,4 @@ -import { buildPrimaryEnvVarName } from '@agent-device/host-kit/values'; +import { buildPrimaryEnvVarName } from '@agent-device/kernel/source-value'; /** * Where an operator supplies a value that no model-facing surface may accept as diff --git a/src/commands/interaction/output.ts b/src/commands/interaction/output.ts index 9af4682c03..2e19675669 100644 --- a/src/commands/interaction/output.ts +++ b/src/commands/interaction/output.ts @@ -2,7 +2,7 @@ import type { CommandRequestResult } from '@agent-device/contracts/client'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import type { CliOutput } from '../command-contract.ts'; import { displayLabel, formatRole } from '../../snapshot/snapshot-lines.ts'; -import { readCommandMessage } from '@agent-device/host-kit/values'; +import { readCommandMessage } from '@agent-device/kernel/success-text'; import { messageCliOutput, messageOutput, diff --git a/src/commands/interaction/runtime/gesture-command.ts b/src/commands/interaction/runtime/gesture-command.ts index a30ad151aa..abfef1120a 100644 --- a/src/commands/interaction/runtime/gesture-command.ts +++ b/src/commands/interaction/runtime/gesture-command.ts @@ -7,7 +7,7 @@ import type { import { buildGesturePlan } from '@agent-device/contracts/gesture-plan'; import type { Point } from '@agent-device/kernel/snapshot'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { toBackendContext } from '../../runtime-common.ts'; import { toBackendResult, diff --git a/src/commands/interaction/runtime/gestures.ts b/src/commands/interaction/runtime/gestures.ts index 3d622b055d..d643a73f90 100644 --- a/src/commands/interaction/runtime/gestures.ts +++ b/src/commands/interaction/runtime/gestures.ts @@ -27,7 +27,7 @@ import { type ScrollEdgeState, type ScrollEdgeTarget, } from '../../../utils/scroll-edge-state.ts'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { requireIntInRange } from '../../../utils/validation.ts'; import { toBackendContext } from '../../runtime-common.ts'; import { diff --git a/src/commands/management/output.ts b/src/commands/management/output.ts index db9f84b58c..79eb03c3a2 100644 --- a/src/commands/management/output.ts +++ b/src/commands/management/output.ts @@ -28,7 +28,7 @@ import { serializeOpenResult, serializeSessionListEntry, } from '../../utils/result-serialization.ts'; -import { readCommandMessage } from '@agent-device/host-kit/values'; +import { readCommandMessage } from '@agent-device/kernel/success-text'; import { snapshotCliOutput } from '../capture/output.ts'; import type { CliOutput } from '../command-contract.ts'; import { diff --git a/src/commands/management/runtime/admin.ts b/src/commands/management/runtime/admin.ts index 37b2263e48..0613b7ba72 100644 --- a/src/commands/management/runtime/admin.ts +++ b/src/commands/management/runtime/admin.ts @@ -8,7 +8,7 @@ import type { } from '../../../backend.ts'; import type { AgentDeviceRuntime, CommandContext } from '../../../runtime-contract.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { toBackendResult, type BackendResultEnvelope, diff --git a/src/commands/management/runtime/apps.ts b/src/commands/management/runtime/apps.ts index 4951a8b2bf..c131a2e5fa 100644 --- a/src/commands/management/runtime/apps.ts +++ b/src/commands/management/runtime/apps.ts @@ -11,7 +11,7 @@ import type { FileInputRef } from '../../../io.ts'; import type { AgentDeviceRuntime, CommandContext } from '../../../runtime-contract.ts'; import { assertResolvedAppsFilter } from '../app-inventory-contract.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { resolveCommandInput } from '../../io-policy.ts'; import { toBackendResult, diff --git a/src/commands/output-common.ts b/src/commands/output-common.ts index a8a07ee372..e6802326d7 100644 --- a/src/commands/output-common.ts +++ b/src/commands/output-common.ts @@ -1,4 +1,4 @@ -import { readCommandMessage } from '@agent-device/host-kit/values'; +import { readCommandMessage } from '@agent-device/kernel/success-text'; import type { CliOutput } from './command-contract.ts'; export type CliOutputFormatter = (params: { diff --git a/src/commands/perf/output.ts b/src/commands/perf/output.ts index 6d980fe5fc..9ec488cd90 100644 --- a/src/commands/perf/output.ts +++ b/src/commands/perf/output.ts @@ -1,5 +1,5 @@ import type { CommandRequestResult } from '@agent-device/contracts/client'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import type { CliOutput } from '../command-contract.ts'; import { resultOutput, type CliOutputFormatter } from '../output-common.ts'; diff --git a/src/commands/recording/runtime/recording.ts b/src/commands/recording/runtime/recording.ts index 5fecb62865..d184da2129 100644 --- a/src/commands/recording/runtime/recording.ts +++ b/src/commands/recording/runtime/recording.ts @@ -7,7 +7,7 @@ import type { import type { ArtifactDescriptor, FileOutputRef } from '../../../io.ts'; import type { CommandContext } from '../../../runtime-contract.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { requireIntInRange } from '../../../utils/validation.ts'; import { recordingQualityInputToExportQuality, diff --git a/src/commands/system/runtime/system.ts b/src/commands/system/runtime/system.ts index 9e9840b083..38f2c5058a 100644 --- a/src/commands/system/runtime/system.ts +++ b/src/commands/system/runtime/system.ts @@ -10,7 +10,7 @@ import type { CommandContext } from '../../../runtime-contract.ts'; import type { BackMode } from '@agent-device/contracts/back-mode'; import { parseTvRemoteButton } from '@agent-device/contracts/tv-remote'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { requireIntInRange } from '../../../utils/validation.ts'; import { isKeyboardAction } from '../../../utils/keyboard-actions.ts'; import { diff --git a/src/core/batch.ts b/src/core/batch.ts index e9abd9881f..c66fe805c8 100644 --- a/src/core/batch.ts +++ b/src/core/batch.ts @@ -8,7 +8,7 @@ import { isNonDefaultResponseLevel, } from '@agent-device/kernel/contracts'; import { AppError, asAppError, type DaemonError } from '@agent-device/kernel/errors'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import { DEFAULT_BATCH_MAX_STEPS, assertBatchStepCount, diff --git a/src/core/dispatch-resolve.ts b/src/core/dispatch-resolve.ts index e45a8a5d06..f0d8553a4d 100644 --- a/src/core/dispatch-resolve.ts +++ b/src/core/dispatch-resolve.ts @@ -12,8 +12,8 @@ import { AsyncLocalStorage } from 'node:async_hooks'; import { resolveAndroidSerialAllowlist, resolveIosSimulatorDeviceSetPath, -} from '@agent-device/host-kit/fs'; -import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; +} from '@agent-device/kernel/device-isolation'; +import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import { listLocalDeviceInventory, readDeviceInventory, diff --git a/src/core/interactors/android.ts b/src/core/interactors/android.ts index 68a1e777bc..b59529f765 100644 --- a/src/core/interactors/android.ts +++ b/src/core/interactors/android.ts @@ -34,8 +34,8 @@ import { setAndroidSetting } from '../../platforms/android/settings.ts'; import { snapshotAndroid } from '../../platforms/android/snapshot.ts'; import type { AndroidHelperSessionScope } from '../../platforms/android/snapshot-helper-types.ts'; import { screenshotAndroid } from '../../platforms/android/screenshot.ts'; -import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; -import { withMethodScope } from '@agent-device/host-kit/values'; +import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; +import { withMethodScope } from '@agent-device/kernel/scoped-provider'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Interactor, RunnerContext } from '@agent-device/contracts/interactor-types'; import { androidSnapshotPublicationInput } from '../../platforms/android/snapshot-capture.ts'; diff --git a/src/core/interactors/harmonyos.ts b/src/core/interactors/harmonyos.ts index 85b2938e51..2b966425c7 100644 --- a/src/core/interactors/harmonyos.ts +++ b/src/core/interactors/harmonyos.ts @@ -1,7 +1,7 @@ import { AppError } from '@agent-device/kernel/errors'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Interactor, RunnerContext } from '@agent-device/contracts/interactor-types'; -import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; +import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import { closeHarmonyApp, openHarmonyApp } from '../../platforms/harmonyos/app-lifecycle.ts'; import { appSwitcherHarmony, diff --git a/src/core/interactors/linux.ts b/src/core/interactors/linux.ts index 052fff6e8b..cd8eac4fa7 100644 --- a/src/core/interactors/linux.ts +++ b/src/core/interactors/linux.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; +import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import { backLinux, closeLinuxApp, diff --git a/src/core/interactors/web.ts b/src/core/interactors/web.ts index fc4abee93e..914da409e0 100644 --- a/src/core/interactors/web.ts +++ b/src/core/interactors/web.ts @@ -1,7 +1,7 @@ import type { Interactor } from '@agent-device/contracts/interactor-types'; import { AppError } from '@agent-device/kernel/errors'; import { stripAtPrefix } from '../interaction-positionals.ts'; -import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; +import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import { resolveWebProvider, type WebProvider } from '../../platforms/web/provider.ts'; import { createUnsupportedInteractor } from '../../platforms/unsupported-interactor.ts'; diff --git a/src/core/lease-scope.ts b/src/core/lease-scope.ts index 8370c21bbb..530fa97c10 100644 --- a/src/core/lease-scope.ts +++ b/src/core/lease-scope.ts @@ -1,5 +1,5 @@ import type { LeaseBackend } from '@agent-device/kernel/contracts'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; const PROXY_LEASE_PROVIDER = 'proxy'; export const DEFAULT_PROXY_LEASE_TTL_MS = 300_000; diff --git a/src/daemon/__tests__/android-dialog-readiness.test.ts b/src/daemon/__tests__/android-dialog-readiness.test.ts index a8df0b80eb..8697c139a5 100644 --- a/src/daemon/__tests__/android-dialog-readiness.test.ts +++ b/src/daemon/__tests__/android-dialog-readiness.test.ts @@ -24,7 +24,10 @@ vi.mock('../../platforms/android/app-lifecycle.ts', async (importOriginal) => { import { makeAndroidSession } from '../../__tests__/test-utils/session-factories.ts'; import { withFakeAdb, type FakeAdbScript } from '../../__tests__/test-utils/fake-adb.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + countDiagnosticEventsByPhase, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { ensureAndroidBlockingSystemDialogReady as ensureOwnedAndroidBlockingSystemDialogReady } from '../android-system-dialog.ts'; import { androidObservation } from '../../platform-runtime.ts'; diff --git a/src/daemon/__tests__/daemon-exit-wait.test.ts b/src/daemon/__tests__/daemon-exit-wait.test.ts index 09faaf7aca..b6c65943d6 100644 --- a/src/daemon/__tests__/daemon-exit-wait.test.ts +++ b/src/daemon/__tests__/daemon-exit-wait.test.ts @@ -15,8 +15,8 @@ const state = vi.hoisted(() => ({ commands: new Map(), })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/process', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: (pid: number) => state.alive.get(pid) ?? false, readProcessStartTime: (pid: number) => state.starts.get(pid) ?? null, readProcessCommand: (pid: number) => state.commands.get(pid) ?? null, diff --git a/src/daemon/__tests__/daemon-process-takeover.test.ts b/src/daemon/__tests__/daemon-process-takeover.test.ts index 839dd19603..f82bd9382e 100644 --- a/src/daemon/__tests__/daemon-process-takeover.test.ts +++ b/src/daemon/__tests__/daemon-process-takeover.test.ts @@ -4,7 +4,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { afterEach, test } from 'vitest'; -import { isProcessAlive, readProcessStartTime } from '@agent-device/host-kit/exec'; +import { isProcessAlive, readProcessStartTime } from '@agent-device/host-kit/process'; import { isAgentDeviceDaemonProcess, stopProcessForTakeover } from '../daemon-process.ts'; const TAKEOVER_TIMEOUTS = { termTimeoutMs: 5_000, killTimeoutMs: 2_000 }; diff --git a/src/daemon/__tests__/daemon-stop.test.ts b/src/daemon/__tests__/daemon-stop.test.ts index ddff0e94bd..e9f258852a 100644 --- a/src/daemon/__tests__/daemon-stop.test.ts +++ b/src/daemon/__tests__/daemon-stop.test.ts @@ -16,9 +16,12 @@ vi.mock('../daemon-process.ts', () => ({ trySignalProcess: mocks.trySignalProcess, waitForDaemonExit: mocks.waitForDaemonExit, })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/process', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: mocks.isProcessAlive, +})); +vi.mock('@agent-device/host-kit/retry', async (importOriginal) => ({ + ...(await importOriginal()), sleep: mocks.sleep, })); diff --git a/src/daemon/__tests__/deferred-interaction-outcome.test.ts b/src/daemon/__tests__/deferred-interaction-outcome.test.ts index f3b9c80d21..56a2689ac1 100644 --- a/src/daemon/__tests__/deferred-interaction-outcome.test.ts +++ b/src/daemon/__tests__/deferred-interaction-outcome.test.ts @@ -7,7 +7,10 @@ import { type DeferredOutcomeSnapshotAttempt, } from '../deferred-interaction-outcome.ts'; import type { InteractionRetryTap } from '../interaction-outcome-policy.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + countDiagnosticEventsByPhase, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import type { SessionState } from '../types.ts'; import { deliverySnapshot, diff --git a/src/daemon/__tests__/device-claim-prune.test.ts b/src/daemon/__tests__/device-claim-prune.test.ts index c2a0b17c60..7598915174 100644 --- a/src/daemon/__tests__/device-claim-prune.test.ts +++ b/src/daemon/__tests__/device-claim-prune.test.ts @@ -5,12 +5,12 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { reconcileOrphanedDeviceClaims } from '../device-claims.ts'; import { resolveDeviceClaimPath } from '../device-claim-paths.ts'; -import { acquireProcessLock } from '@agent-device/host-kit/fs'; -import { readCurrentOwnerIdentity } from '@agent-device/host-kit/exec'; +import { acquireProcessLock } from '@agent-device/host-kit/file'; +import { readCurrentOwnerIdentity } from '@agent-device/host-kit/process'; import { publishDaemonRegistration } from '../../__tests__/test-utils/device-claim-store.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => +vi.mock('@agent-device/host-kit/process', async (importOriginal) => (await import('../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), diff --git a/src/daemon/__tests__/device-claims.test.ts b/src/daemon/__tests__/device-claims.test.ts index 6da2db6798..995964636a 100644 --- a/src/daemon/__tests__/device-claims.test.ts +++ b/src/daemon/__tests__/device-claims.test.ts @@ -12,9 +12,9 @@ import { inspectDeviceClaims } from '../device-claim-inspection.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; import { publishDaemonRegistration } from '../../__tests__/test-utils/device-claim-store.ts'; -import { readCurrentOwnerIdentity } from '@agent-device/host-kit/exec'; +import { readCurrentOwnerIdentity } from '@agent-device/host-kit/process'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => +vi.mock('@agent-device/host-kit/process', async (importOriginal) => (await import('../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), diff --git a/src/daemon/__tests__/device-ready.test.ts b/src/daemon/__tests__/device-ready.test.ts index b0ec5d8a79..a332b7b8d4 100644 --- a/src/daemon/__tests__/device-ready.test.ts +++ b/src/daemon/__tests__/device-ready.test.ts @@ -2,7 +2,7 @@ import { afterEach, beforeEach, expect, test, vi } from 'vitest'; import { promises as fs } from 'node:fs'; import type { DeviceInfo } from '@agent-device/kernel/device'; -vi.mock('@agent-device/host-kit/exec', () => ({ +vi.mock('@agent-device/host-kit/command', () => ({ runCmd: vi.fn(), runCmdSync: vi.fn(), whichCmd: vi.fn(async () => true), @@ -14,7 +14,7 @@ vi.mock('../../platforms/android/emulator-lifecycle.ts', () => ({ waitForAndroidBoot: vi.fn(async () => {}), })); -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { waitForAndroidBoot } from '../../platforms/android/emulator-lifecycle.ts'; import { ensureBootedSimulator } from '../../platforms/apple/core/simulator.ts'; import { diff --git a/src/daemon/__tests__/durable-capture-resource-transitions.test.ts b/src/daemon/__tests__/durable-capture-resource-transitions.test.ts index 24df906c4b..be300cbe33 100644 --- a/src/daemon/__tests__/durable-capture-resource-transitions.test.ts +++ b/src/daemon/__tests__/durable-capture-resource-transitions.test.ts @@ -1,5 +1,8 @@ import { expect, test } from 'vitest'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + countDiagnosticEventsByPhase, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { createTestCaptureResource, makeDurableCaptureContext, diff --git a/src/daemon/__tests__/filesystem-boundary-faults.test.ts b/src/daemon/__tests__/filesystem-boundary-faults.test.ts index 54543d7504..e91acf8f05 100644 --- a/src/daemon/__tests__/filesystem-boundary-faults.test.ts +++ b/src/daemon/__tests__/filesystem-boundary-faults.test.ts @@ -21,7 +21,7 @@ import { type FilesystemBoundaryFixture, } from '../../__tests__/test-utils/filesystem-boundary-faults.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => +vi.mock('@agent-device/host-kit/process', async (importOriginal) => (await import('../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), diff --git a/src/daemon/__tests__/http-server-artifacts.test.ts b/src/daemon/__tests__/http-server-artifacts.test.ts index 34cad18a08..52adf08048 100644 --- a/src/daemon/__tests__/http-server-artifacts.test.ts +++ b/src/daemon/__tests__/http-server-artifacts.test.ts @@ -9,7 +9,7 @@ import { trackDownloadableArtifact, } from '../artifact-tracking.ts'; import type { DaemonResponse } from '../types.ts'; -import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { closeLoopbackServer, listenOnLoopback, diff --git a/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts b/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts index 93e6578bec..258bb9fefe 100644 --- a/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts +++ b/src/daemon/__tests__/post-gesture-no-effect-claim.test.ts @@ -4,7 +4,10 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + countDiagnosticEventsByPhase, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { buildInteractionSurfaceSignature, summarizeDiscriminatingSurfaceDivergence, diff --git a/src/daemon/__tests__/post-gesture-stabilization.test.ts b/src/daemon/__tests__/post-gesture-stabilization.test.ts index 4d87e2d6fc..3cdc90d20f 100644 --- a/src/daemon/__tests__/post-gesture-stabilization.test.ts +++ b/src/daemon/__tests__/post-gesture-stabilization.test.ts @@ -2,7 +2,10 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import assert from 'node:assert/strict'; import { afterEach, test, vi } from 'vitest'; import { makeSnapshotState } from '../../__tests__/test-utils/snapshot-builders.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + countDiagnosticEventsByPhase, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { buildInteractionSurfaceSignature } from '../interaction-outcome-policy.ts'; import { capturePostGestureStabilizedResult, diff --git a/src/daemon/__tests__/request-execution-scope.test.ts b/src/daemon/__tests__/request-execution-scope.test.ts index 18badcc570..86870102ff 100644 --- a/src/daemon/__tests__/request-execution-scope.test.ts +++ b/src/daemon/__tests__/request-execution-scope.test.ts @@ -5,7 +5,7 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, withDiagnosticsScope, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import { makeAndroidSession, makeIosSession, diff --git a/src/daemon/__tests__/request-router-android-modal.test.ts b/src/daemon/__tests__/request-router-android-modal.test.ts index 0ce8c2df81..985b8fc5b2 100644 --- a/src/daemon/__tests__/request-router-android-modal.test.ts +++ b/src/daemon/__tests__/request-router-android-modal.test.ts @@ -113,8 +113,8 @@ const modalObservation: AndroidObservationAdapter = { }, }; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async (_cmd: string, args: string[]) => { diff --git a/src/daemon/__tests__/request-router-cost.test.ts b/src/daemon/__tests__/request-router-cost.test.ts index d96826c3df..5d917a76a2 100644 --- a/src/daemon/__tests__/request-router-cost.test.ts +++ b/src/daemon/__tests__/request-router-cost.test.ts @@ -16,7 +16,7 @@ import { gestureDeviceRuntimeGateway, gestureRuntimeSpies, } from './test-device-runtime-gateway.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { DaemonRequest, SessionState } from '../types.ts'; import { LeaseRegistry } from '../lease-registry.ts'; import { makeSessionStore } from '../../__tests__/test-utils/store-factory.ts'; diff --git a/src/daemon/__tests__/request-router-open.test.ts b/src/daemon/__tests__/request-router-open.test.ts index 798b6560dc..4793489df4 100644 --- a/src/daemon/__tests__/request-router-open.test.ts +++ b/src/daemon/__tests__/request-router-open.test.ts @@ -9,8 +9,8 @@ import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; import { replayScriptSourceBundleFor } from '../../__tests__/test-utils/replay-script-source.ts'; vi.mock('../device-ready.ts', () => ({ ensureDeviceReady: vi.fn(async () => {}) })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); // Opening a session runs the owned-lease cleanup, which pattern-kills stale diff --git a/src/daemon/__tests__/request-router-session-address.test.ts b/src/daemon/__tests__/request-router-session-address.test.ts index 9e38917320..a46a90dcdb 100644 --- a/src/daemon/__tests__/request-router-session-address.test.ts +++ b/src/daemon/__tests__/request-router-session-address.test.ts @@ -7,8 +7,8 @@ import { getResolveTargetDeviceMock } from './request-router-dispatch-mocks.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; vi.mock('../device-ready.ts', () => ({ ensureDeviceReady: vi.fn(async () => {}) })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); // Opening a session runs owned-lease cleanup, which pattern-kills stale xcodebuild runners with a diff --git a/src/daemon/__tests__/resumable-upload.test.ts b/src/daemon/__tests__/resumable-upload.test.ts index 12aad11c6a..818566f989 100644 --- a/src/daemon/__tests__/resumable-upload.test.ts +++ b/src/daemon/__tests__/resumable-upload.test.ts @@ -12,7 +12,7 @@ import { receiveResumableUploadChunk, } from '../resumable-upload.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; test('finalizing an unknown upload reports expiry with a recovery hint', async () => { const error = await finalizeResumableUpload('missing-upload-id').then( diff --git a/src/daemon/__tests__/runtime-session.test.ts b/src/daemon/__tests__/runtime-session.test.ts index e1af977216..60426909d6 100644 --- a/src/daemon/__tests__/runtime-session.test.ts +++ b/src/daemon/__tests__/runtime-session.test.ts @@ -1,7 +1,10 @@ import { test, expect } from 'vitest'; import fs from 'node:fs'; import { makeIosSession } from '../../__tests__/test-utils/session-factories.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + flushDiagnosticsToSessionFile, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { createDaemonRuntimeSessionStore } from '../runtime-session.ts'; import type { CommandSessionRecord } from '../../runtime-contract.ts'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/daemon/__tests__/screen-recording-boundary-faults.test.ts b/src/daemon/__tests__/screen-recording-boundary-faults.test.ts index 074d6a4e3a..6cb8155755 100644 --- a/src/daemon/__tests__/screen-recording-boundary-faults.test.ts +++ b/src/daemon/__tests__/screen-recording-boundary-faults.test.ts @@ -14,7 +14,10 @@ import type { import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import { makeSessionStore } from '../../__tests__/test-utils/store-factory.ts'; -import { countDiagnosticEventsByPhase, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + countDiagnosticEventsByPhase, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { createDurableCaptureAdmissionLedger } from '../durable-capture-admission-ledger.ts'; import { createDurableCaptureResource } from '../durable-capture-resource.ts'; import type { DurableCaptureResourceStore } from '../durable-capture-resource-store.ts'; diff --git a/src/daemon/__tests__/upload.test.ts b/src/daemon/__tests__/upload.test.ts index b5c692075d..4ed7f60836 100644 --- a/src/daemon/__tests__/upload.test.ts +++ b/src/daemon/__tests__/upload.test.ts @@ -6,7 +6,7 @@ import { Readable } from 'node:stream'; import type { IncomingMessage } from 'node:http'; import { receiveUpload } from '../upload.ts'; import { streamReadableToFile, validateArtifactContentLength } from '../artifact-download.ts'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; function makeUploadRequest(body: Buffer, headers: Record): IncomingMessage { diff --git a/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts b/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts index a1182f144c..4d9cac2e75 100644 --- a/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts +++ b/src/daemon/adapters/maestro/__tests__/daemon-runtime-port.test.ts @@ -9,7 +9,7 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, withDiagnosticsScope, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import { createDaemonMaestroRuntimePort } from '../daemon-runtime-port.ts'; import { MAESTRO_OBSERVATION_POLL_MS } from '../daemon-runtime-port-observation.ts'; import { makeBaseRequest, makeDependencies, makeSnapshot } from './daemon-runtime-port-fixtures.ts'; diff --git a/src/daemon/adapters/maestro/daemon-runtime-port-support.ts b/src/daemon/adapters/maestro/daemon-runtime-port-support.ts index 033b511865..87bb3720d8 100644 --- a/src/daemon/adapters/maestro/daemon-runtime-port-support.ts +++ b/src/daemon/adapters/maestro/daemon-runtime-port-support.ts @@ -16,7 +16,7 @@ import type { import { AppError } from '@agent-device/kernel/errors'; import type { Rect } from '@agent-device/kernel/snapshot'; import type { DaemonMaestroRuntimeDependencies } from './daemon-runtime-port-observation.ts'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; import { projectMaestroPublicOperation, type MaestroPublicOperation, diff --git a/src/daemon/adapters/maestro/daemon-runtime-port.ts b/src/daemon/adapters/maestro/daemon-runtime-port.ts index 57ef80ad2b..b3ed9b8c3f 100644 --- a/src/daemon/adapters/maestro/daemon-runtime-port.ts +++ b/src/daemon/adapters/maestro/daemon-runtime-port.ts @@ -8,8 +8,8 @@ import { type MaestroRuntimeOperations, type MaestroRuntimePort, } from '@agent-device/maestro'; -import { registerDiagnosticSensitiveValue } from '@agent-device/host-kit/exec'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { registerDiagnosticSensitiveValue } from '@agent-device/host-kit/diagnostics'; +import { stripUndefined } from '@agent-device/kernel/record'; import { executeRunScriptFile } from './run-script-execution.ts'; import { waitForMaestroAnimationToEnd } from './wait-for-animation-to-end.ts'; import { diff --git a/src/daemon/adapters/maestro/daemon-runtime-tap.ts b/src/daemon/adapters/maestro/daemon-runtime-tap.ts index 50734d7050..c08d0c9243 100644 --- a/src/daemon/adapters/maestro/daemon-runtime-tap.ts +++ b/src/daemon/adapters/maestro/daemon-runtime-tap.ts @@ -10,7 +10,7 @@ import { type MaestroTargetMatch, type MaestroTargetQuery, } from '@agent-device/maestro'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { pointInsideRect } from '@agent-device/kernel/rect-center'; import { withMaestroScreenshotBaseline, diff --git a/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts b/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts index 7b3e4285ec..167b03b4bc 100644 --- a/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts +++ b/src/daemon/adapters/maestro/maestro-screenshot-comparison.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import { MAESTRO_RUNTIME_ADAPTER_POLICY } from '@agent-device/maestro'; import { createRequestCanceledError, isRequestCanceledError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { computePngRgbDifferenceAsync } from '@agent-device/capture-kit/png-worker-client'; import type { PngRgbDifferenceResult } from '@agent-device/capture-kit/png-rgb-difference'; diff --git a/src/daemon/adapters/maestro/run-script-execution.ts b/src/daemon/adapters/maestro/run-script-execution.ts index d72d6296fe..15427f56b3 100644 --- a/src/daemon/adapters/maestro/run-script-execution.ts +++ b/src/daemon/adapters/maestro/run-script-execution.ts @@ -1,8 +1,8 @@ import fs from 'node:fs'; import vm from 'node:vm'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { runCmdSync } from '@agent-device/host-kit/exec'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { runCmdSync } from '@agent-device/host-kit/command'; +import { stripUndefined } from '@agent-device/kernel/record'; const RUN_SCRIPT_TIMEOUT_MS = 30_000; const RUN_SCRIPT_DIAGNOSTIC_PREVIEW_CHARS = 1_000; diff --git a/src/daemon/android-snapshot-timeout-evidence.ts b/src/daemon/android-snapshot-timeout-evidence.ts index 0550fc8fdd..d08bb336d3 100644 --- a/src/daemon/android-snapshot-timeout-evidence.ts +++ b/src/daemon/android-snapshot-timeout-evidence.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import type { DaemonResponse, SessionState } from './types.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import { snapshotTimeoutCaptureFailed, diff --git a/src/daemon/android-system-dialog.ts b/src/daemon/android-system-dialog.ts index 85afc3312b..daaa45b5e2 100644 --- a/src/daemon/android-system-dialog.ts +++ b/src/daemon/android-system-dialog.ts @@ -2,7 +2,8 @@ import type { AndroidBlockingDialogFocus, AndroidObservationAdapter, } from '@agent-device/contracts/android-observation'; -import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { sleep } from '@agent-device/host-kit/retry'; import { AppError, normalizeError, type NormalizedError } from '@agent-device/kernel/errors'; import { centerOfRect, type SnapshotNode } from '@agent-device/kernel/snapshot'; diff --git a/src/daemon/app-event-runtime.ts b/src/daemon/app-event-runtime.ts index a9462e1af5..6b83ed980a 100644 --- a/src/daemon/app-event-runtime.ts +++ b/src/daemon/app-event-runtime.ts @@ -3,7 +3,7 @@ import { appEventRuntimeUse } from '@agent-device/contracts/platform-runtime-ope import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { parseTriggerAppEventArgs, resolveAppEventUrl } from '../core/app-events.ts'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import { admitRuntimeUse, type RuntimeAdmissionBindings } from './runtime-admission.ts'; import { runtimeExecutionFromContext } from './snapshot-runtime-capture-input.ts'; diff --git a/src/daemon/app-switcher-runtime.ts b/src/daemon/app-switcher-runtime.ts index 5001fd37da..127bb882b8 100644 --- a/src/daemon/app-switcher-runtime.ts +++ b/src/daemon/app-switcher-runtime.ts @@ -2,7 +2,7 @@ import type { AppSwitcherInput } from '@agent-device/contracts/app-switcher-runt import { appSwitcherRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/artifact-archive.ts b/src/daemon/artifact-archive.ts index f0dab6dd28..41492d3185 100644 --- a/src/daemon/artifact-archive.ts +++ b/src/daemon/artifact-archive.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { extractArchiveSafely, type ArchiveManifestEntry } from '@agent-device/host-kit/fs'; +import { extractArchiveSafely, type ArchiveManifestEntry } from '@agent-device/host-kit/archive'; export async function extractTarInstallableArtifact(params: { archivePath: string; diff --git a/src/daemon/artifact-download.ts b/src/daemon/artifact-download.ts index 797124bc91..2506d195f8 100644 --- a/src/daemon/artifact-download.ts +++ b/src/daemon/artifact-download.ts @@ -4,7 +4,10 @@ import path from 'node:path'; import { once } from 'node:events'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { MAX_ARTIFACT_COMPRESSED_BYTES, createByteLimitStream } from '@agent-device/host-kit/fs'; +import { + MAX_ARTIFACT_COMPRESSED_BYTES, + createByteLimitStream, +} from '@agent-device/host-kit/archive'; const TEMP_PREFIX = 'agent-device-artifact-'; const REQUEST_IDLE_TIMEOUT_MS = 60_000; diff --git a/src/daemon/artifact-tracking.ts b/src/daemon/artifact-tracking.ts index f383f7a966..4a8fff31ea 100644 --- a/src/daemon/artifact-tracking.ts +++ b/src/daemon/artifact-tracking.ts @@ -4,7 +4,7 @@ import os from 'node:os'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import type { DaemonArtifactType } from '@agent-device/kernel/contracts'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { expiredTenantOwnedEntryError, requireTenantOwnedEntry, diff --git a/src/daemon/back-runtime.ts b/src/daemon/back-runtime.ts index 0d7f6c9580..b3eedeca78 100644 --- a/src/daemon/back-runtime.ts +++ b/src/daemon/back-runtime.ts @@ -3,7 +3,7 @@ import type { BackMode } from '@agent-device/contracts/back-mode'; import { backRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/client/__tests__/boundary-fault-transport.test.ts b/src/daemon/client/__tests__/boundary-fault-transport.test.ts index 92674b441d..a0db14ad4c 100644 --- a/src/daemon/client/__tests__/boundary-fault-transport.test.ts +++ b/src/daemon/client/__tests__/boundary-fault-transport.test.ts @@ -17,9 +17,9 @@ import { sendRequest } from '../daemon-client-transport.ts'; const { mockRunCmdSync } = vi.hoisted(() => ({ mockRunCmdSync: vi.fn() })); -vi.mock('@agent-device/host-kit/exec', async () => { - const actual = await vi.importActual( - '@agent-device/host-kit/exec', +vi.mock('@agent-device/host-kit/command', async () => { + const actual = await vi.importActual( + '@agent-device/host-kit/command', ); return { ...actual, runCmdSync: mockRunCmdSync }; }); 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 0d78d6972e..c626662b51 100644 --- a/src/daemon/client/__tests__/daemon-client-timeout-route.test.ts +++ b/src/daemon/client/__tests__/daemon-client-timeout-route.test.ts @@ -31,9 +31,9 @@ import { beforeEach, test, vi } from 'vitest'; const { mockRunCmdSync } = vi.hoisted(() => ({ mockRunCmdSync: vi.fn() })); -vi.mock('@agent-device/host-kit/exec', async () => { - const actual = await vi.importActual( - '@agent-device/host-kit/exec', +vi.mock('@agent-device/host-kit/command', async () => { + const actual = await vi.importActual( + '@agent-device/host-kit/command', ); return { ...actual, runCmdSync: mockRunCmdSync }; }); diff --git a/src/daemon/client/__tests__/daemon-launch-spec.test.ts b/src/daemon/client/__tests__/daemon-launch-spec.test.ts index f20caf0d58..91644541a6 100644 --- a/src/daemon/client/__tests__/daemon-launch-spec.test.ts +++ b/src/daemon/client/__tests__/daemon-launch-spec.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { computeDaemonCodeSignature } from '../../code-signature.ts'; import { resolveDaemonLaunchSpec, resolveLocalDaemonCodeSignature } from '../daemon-launch-spec.ts'; -import { resetAllProcessMemosForTests } from '@agent-device/host-kit/values'; +import { resetAllProcessMemosForTests } from '@agent-device/kernel/ttl-memo'; afterEach(() => { vi.restoreAllMocks(); diff --git a/src/daemon/client/daemon-client-lifecycle.ts b/src/daemon/client/daemon-client-lifecycle.ts index d70ba27146..e57a1aa0d8 100644 --- a/src/daemon/client/daemon-client-lifecycle.ts +++ b/src/daemon/client/daemon-client-lifecycle.ts @@ -8,11 +8,11 @@ import type { DaemonRequest, DaemonResponse } from '../types.ts'; import { runCmdDetachedMonitored, type ExecDetachedExit, - emitDiagnostic, shellQuoteIfNeeded, - sleep, -} from '@agent-device/host-kit/exec'; -import { readVersion } from '@agent-device/host-kit/values'; +} from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { sleep } from '@agent-device/host-kit/retry'; +import { readVersion } from '@agent-device/host-kit/version'; import { findUnrecoveredRepairCommitFailure } from '../session-store.ts'; import { diff --git a/src/daemon/client/daemon-client-metadata.ts b/src/daemon/client/daemon-client-metadata.ts index 78c954d762..9c1549d4f8 100644 --- a/src/daemon/client/daemon-client-metadata.ts +++ b/src/daemon/client/daemon-client-metadata.ts @@ -1,5 +1,6 @@ import fs from 'node:fs'; -import { emitDiagnostic, shellQuote } from '@agent-device/host-kit/exec'; +import { shellQuote } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { isAgentDeviceDaemonProcess, stopProcessForTakeover } from '../daemon-process.ts'; import { resolveDaemonPaths, type DaemonPaths, type DaemonServerMode } from '../config.ts'; diff --git a/src/daemon/client/daemon-client-rpc.ts b/src/daemon/client/daemon-client-rpc.ts index 2f24a7e7ff..3ccc05adbe 100644 --- a/src/daemon/client/daemon-client-rpc.ts +++ b/src/daemon/client/daemon-client-rpc.ts @@ -5,7 +5,7 @@ import { type DaemonError, } from '@agent-device/kernel/errors'; import { sanitizeErrorCause } from '@agent-device/kernel/redaction'; -import { createRequestId } from '@agent-device/host-kit/exec'; +import { createRequestId } from '@agent-device/host-kit/diagnostics'; import type { DaemonRequest, DaemonResponse } from '../types.ts'; import { materializeRemoteArtifacts } from '../../remote/daemon-artifacts.ts'; import { localizeRemoteDaemonError } from '../../remote/remote-request-diagnostics.ts'; diff --git a/src/daemon/client/daemon-client-timeout.ts b/src/daemon/client/daemon-client-timeout.ts index b0c9e0d5d0..e7e1359113 100644 --- a/src/daemon/client/daemon-client-timeout.ts +++ b/src/daemon/client/daemon-client-timeout.ts @@ -1,5 +1,6 @@ import { AppError } from '@agent-device/kernel/errors'; -import { runCmdSync, emitDiagnostic } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { isAgentDeviceDaemonProcess } from '../daemon-process.ts'; import { PUBLIC_COMMANDS } from '../../command-catalog.ts'; diff --git a/src/daemon/client/daemon-client-transport.ts b/src/daemon/client/daemon-client-transport.ts index 09cbeafd12..93f95dd0ae 100644 --- a/src/daemon/client/daemon-client-transport.ts +++ b/src/daemon/client/daemon-client-transport.ts @@ -3,7 +3,7 @@ import net from 'node:net'; import { AppError } from '@agent-device/kernel/errors'; import { loadNodeHttpRequester, readNodeHttpResponseBody } from '../../utils/node-http.ts'; import type { DaemonRequest, DaemonResponse } from '../types.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { DaemonPaths, DaemonTransportPreference } from '../config.ts'; import { readDaemonHttpProgressResponse, @@ -15,7 +15,7 @@ import { buildHttpRpcPayload, handleDaemonHttpResponseBody } from './daemon-clie import { handleRequestTimeout } from './daemon-client-timeout.ts'; import { isRemoteDaemon, type DaemonInfo } from './daemon-client-metadata.ts'; import { DAEMON_RPC_PROTOCOL_VERSION } from '../http-health.ts'; -import { readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; type ResolvedDaemonTransport = 'socket' | 'http'; type SendRequestOptions = { diff --git a/src/daemon/client/daemon-client.ts b/src/daemon/client/daemon-client.ts index bc4a8909c6..a3d8f85259 100644 --- a/src/daemon/client/daemon-client.ts +++ b/src/daemon/client/daemon-client.ts @@ -5,7 +5,11 @@ import type { } from '../types.ts'; import type { AgentDeviceDaemonTransportContext } from '@agent-device/contracts/client'; import { AppError } from '@agent-device/kernel/errors'; -import { createRequestId, emitDiagnostic, withDiagnosticTimer } from '@agent-device/host-kit/exec'; +import { + createRequestId, + emitDiagnostic, + withDiagnosticTimer, +} from '@agent-device/host-kit/diagnostics'; import { INTERNAL_COMMANDS, PUBLIC_COMMANDS } from '../../command-catalog.ts'; import { prepareRemoteRequestArtifacts } from '../../remote/daemon-artifacts.ts'; import { diff --git a/src/daemon/client/daemon-launch-spec.ts b/src/daemon/client/daemon-launch-spec.ts index ca61c8d917..1159aa9eea 100644 --- a/src/daemon/client/daemon-launch-spec.ts +++ b/src/daemon/client/daemon-launch-spec.ts @@ -1,7 +1,8 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { createTtlMemo, findProjectRoot } from '@agent-device/host-kit/values'; +import { findProjectRoot } from '@agent-device/host-kit/version'; +import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; import { computeDaemonCodeSignature } from '../code-signature.ts'; diff --git a/src/daemon/code-signature-cache.ts b/src/daemon/code-signature-cache.ts index 56225a079a..a361f3f7a4 100644 --- a/src/daemon/code-signature-cache.ts +++ b/src/daemon/code-signature-cache.ts @@ -2,7 +2,7 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { publishFileSync } from '@agent-device/host-kit/fs'; +import { publishFileSync } from '@agent-device/host-kit/file'; import { buildDaemonCodeFileLabel, formatDaemonCodeSignature, diff --git a/src/daemon/code-signature.ts b/src/daemon/code-signature.ts index 2e93254e8f..823f72e601 100644 --- a/src/daemon/code-signature.ts +++ b/src/daemon/code-signature.ts @@ -1,7 +1,7 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; -import { findProjectRoot } from '@agent-device/host-kit/values'; +import { findProjectRoot } from '@agent-device/host-kit/version'; // Any quoted, relative-path-shaped string literal is treated as a module // specifier, rather than matching the `import`/`export`/`from` grammar diff --git a/src/daemon/config.ts b/src/daemon/config.ts index 16dbb9c7af..63a1ceb32a 100644 --- a/src/daemon/config.ts +++ b/src/daemon/config.ts @@ -1,8 +1,9 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; -import { expandUserHomePath, resolveUserPath } from '@agent-device/host-kit/fs'; -import { findProjectRoot, type EnvMap } from '@agent-device/host-kit/values'; +import { expandUserHomePath, resolveUserPath } from '@agent-device/host-kit/file'; +import { findProjectRoot } from '@agent-device/host-kit/version'; +import { type EnvMap } from '@agent-device/kernel/source-value'; import type { DaemonServerMode, diff --git a/src/daemon/context.ts b/src/daemon/context.ts index 4bc1029c7d..e022854df4 100644 --- a/src/daemon/context.ts +++ b/src/daemon/context.ts @@ -5,7 +5,7 @@ import { screenshotFlagsFromOptions, type ScreenshotRuntimeFlags, } from '@agent-device/contracts/capture'; -import { getDiagnosticsMeta } from '@agent-device/host-kit/exec'; +import { getDiagnosticsMeta } from '@agent-device/host-kit/diagnostics'; import { resolveRunnerLogicalLeaseContext } from './lease-context.ts'; import type { DaemonRequest } from './types.ts'; diff --git a/src/daemon/daemon-process.ts b/src/daemon/daemon-process.ts index d4dec3db9b..3f0fd19c80 100644 --- a/src/daemon/daemon-process.ts +++ b/src/daemon/daemon-process.ts @@ -3,8 +3,8 @@ import { readHostProcessIdentityObservations, readProcessCommand, readProcessStartTime, - sleep, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; +import { sleep } from '@agent-device/host-kit/retry'; const DAEMON_COMMAND_PATTERNS = [ /\/dist\/src\/daemon\.js($|[\s"'])/, diff --git a/src/daemon/daemon-registration.ts b/src/daemon/daemon-registration.ts index 63179f11cb..d0c2dcbbcd 100644 --- a/src/daemon/daemon-registration.ts +++ b/src/daemon/daemon-registration.ts @@ -1,5 +1,5 @@ import fs from 'node:fs'; -import { ownerIdentityDiffers, type OwnerIdentity } from '@agent-device/host-kit/exec'; +import { ownerIdentityDiffers, type OwnerIdentity } from '@agent-device/host-kit/process'; import { resolveDaemonPaths } from './config.ts'; /** diff --git a/src/daemon/daemon-shutdown-report.ts b/src/daemon/daemon-shutdown-report.ts index 5b6862fcec..2ec19ce684 100644 --- a/src/daemon/daemon-shutdown-report.ts +++ b/src/daemon/daemon-shutdown-report.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import type { DeviceLease } from '@agent-device/contracts/device'; -import { publishFileSync } from '@agent-device/host-kit/fs'; +import { publishFileSync } from '@agent-device/host-kit/file'; const SHUTDOWN_REPORT_FILE = 'daemon-shutdown.json'; diff --git a/src/daemon/daemon-stop.ts b/src/daemon/daemon-stop.ts index acb0658d0b..79ca7bd6d5 100644 --- a/src/daemon/daemon-stop.ts +++ b/src/daemon/daemon-stop.ts @@ -6,7 +6,8 @@ import { waitForDaemonExit, type DaemonProcessIdentity, } from './daemon-process.ts'; -import { isProcessAlive, sleep } from '@agent-device/host-kit/exec'; +import { isProcessAlive } from '@agent-device/host-kit/process'; +import { sleep } from '@agent-device/host-kit/retry'; import type { DaemonPaths } from './config.ts'; import { readRegisteredDaemonIdentity } from './daemon-registration.ts'; diff --git a/src/daemon/deferred-interaction-outcome.ts b/src/daemon/deferred-interaction-outcome.ts index 15c2bb466a..575b741af6 100644 --- a/src/daemon/deferred-interaction-outcome.ts +++ b/src/daemon/deferred-interaction-outcome.ts @@ -2,7 +2,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import type { SnapshotCaptureAnnotations } from '@agent-device/contracts/capture'; import { isApplePlatform, isMobilePlatform } from '@agent-device/kernel/device'; import type { SnapshotState } from '@agent-device/kernel/snapshot'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import { captureAndroidFreshnessRecoveredAttempt, clearAndroidSnapshotFreshness, diff --git a/src/daemon/device-claim-admission.ts b/src/daemon/device-claim-admission.ts index 529e88147f..69a256182c 100644 --- a/src/daemon/device-claim-admission.ts +++ b/src/daemon/device-claim-admission.ts @@ -1,7 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { RuntimeOwnerRef } from '@agent-device/contracts/platform-runtime'; import type { DeviceClaimPolicy } from '../core/command-descriptor/types.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { deviceClaimConflictError } from './device-claim-conflict.ts'; import { acquireTransientDeviceClaim, diff --git a/src/daemon/device-claim-conflict.ts b/src/daemon/device-claim-conflict.ts index f30dc4df7f..95d62953dc 100644 --- a/src/daemon/device-claim-conflict.ts +++ b/src/daemon/device-claim-conflict.ts @@ -4,7 +4,7 @@ import { type DeviceInfo, } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; import { deviceClaimRequiresStaleInspection, type DeviceClaimClassification, diff --git a/src/daemon/device-claim-inspection.ts b/src/daemon/device-claim-inspection.ts index 553c14e5c2..0b5d94107b 100644 --- a/src/daemon/device-claim-inspection.ts +++ b/src/daemon/device-claim-inspection.ts @@ -12,7 +12,7 @@ import { classifyOwnerLivenessFromObservation, type OwnerLiveness, readHostProcessIdentityObservations, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; import { isSupersededDaemonOwner } from './daemon-registration.ts'; import { canonicalLocalDeviceKey, resolveDeviceClaimRoot } from './device-claim-paths.ts'; diff --git a/src/daemon/device-claim-reconciliation.ts b/src/daemon/device-claim-reconciliation.ts index 4e6cc2ee99..0bd3bd6bd3 100644 --- a/src/daemon/device-claim-reconciliation.ts +++ b/src/daemon/device-claim-reconciliation.ts @@ -3,7 +3,7 @@ import type { DeviceRuntimeGateway } from '@agent-device/contracts/platform-runt import type { PlatformRequestScope } from '@agent-device/contracts/platform-runtime-host'; import type { PlatformRuntimeOperations } from '@agent-device/contracts/platform-runtime-operations'; import { sameDeviceIdentity } from '@agent-device/kernel/device'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { resolveDaemonPaths } from './config.ts'; import { appLogDurableResource } from './app-log-session-resource.ts'; import { recoverAppLogResourceAfterDaemonLock } from './app-log-resource-recovery.ts'; diff --git a/src/daemon/device-claims.ts b/src/daemon/device-claims.ts index 7b771e6978..c84d3fa0fc 100644 --- a/src/daemon/device-claims.ts +++ b/src/daemon/device-claims.ts @@ -8,13 +8,10 @@ import { type DeviceIdentity, type DeviceInfo, } from '@agent-device/kernel/device'; -import { - emitDiagnostic, - ownerIdentityMatches, - readCurrentOwnerIdentity, -} from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { ownerIdentityMatches, readCurrentOwnerIdentity } from '@agent-device/host-kit/process'; import type { RuntimeOwnerRef } from '@agent-device/contracts/platform-runtime'; -import { publishFileSync, acquireProcessLock } from '@agent-device/host-kit/fs'; +import { publishFileSync, acquireProcessLock } from '@agent-device/host-kit/file'; import { deviceClaimOwnerCannotRelease, diff --git a/src/daemon/device-ready.ts b/src/daemon/device-ready.ts index e7008ec980..15338570e9 100644 --- a/src/daemon/device-ready.ts +++ b/src/daemon/device-ready.ts @@ -1,7 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { ensureLocalPlatformDeviceReady } from '../platform-runtime-device-ready.ts'; import { isActiveProviderDevice } from '../provider-device-runtime.ts'; -import { createTtlMemo } from '@agent-device/host-kit/values'; +import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; // Exported so unit tests can assert TTL behavior without duplicating the value. export const DEVICE_READY_CACHE_TTL_MS = 5_000; diff --git a/src/daemon/durable-capture-resource-adoption.ts b/src/daemon/durable-capture-resource-adoption.ts index afd7bad03f..a190a6fbb7 100644 --- a/src/daemon/durable-capture-resource-adoption.ts +++ b/src/daemon/durable-capture-resource-adoption.ts @@ -11,7 +11,7 @@ import { } from '@agent-device/capture-kit'; import { deviceIdentity, sameDeviceIdentity, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { AdoptStartedDurableCaptureParams, DurableCaptureResourceDefinition, diff --git a/src/daemon/durable-capture-resource-recovery.ts b/src/daemon/durable-capture-resource-recovery.ts index 3f8cf82f3e..0e3e58070b 100644 --- a/src/daemon/durable-capture-resource-recovery.ts +++ b/src/daemon/durable-capture-resource-recovery.ts @@ -6,7 +6,7 @@ import { isConfirmedCleanup, } from '@agent-device/contracts/durable-resource'; import type { PlatformRequestScope } from '@agent-device/contracts/platform-runtime-host'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { acquireDurableCaptureRecoveryAuthorityBeforeDeadline, DurableCaptureRecoveryDeadlineError, diff --git a/src/daemon/durable-capture-resource-store.ts b/src/daemon/durable-capture-resource-store.ts index 73875ac0d2..8f7ac301e6 100644 --- a/src/daemon/durable-capture-resource-store.ts +++ b/src/daemon/durable-capture-resource-store.ts @@ -5,7 +5,7 @@ import type { DurableResourceEnvelope, } from '@agent-device/contracts/durable-resource-envelope'; import { decodeDurableResourceEnvelope } from '@agent-device/capture-kit'; -import { withAtomicPublishTempPathSync } from '@agent-device/host-kit/fs'; +import { withAtomicPublishTempPathSync } from '@agent-device/host-kit/file'; import { openVerifiedFileForRead } from '../utils/verified-file.ts'; export type DurableCaptureResourceRecord = diff --git a/src/daemon/durable-capture-resource-transitions.ts b/src/daemon/durable-capture-resource-transitions.ts index 48d5973282..6e46c2ba54 100644 --- a/src/daemon/durable-capture-resource-transitions.ts +++ b/src/daemon/durable-capture-resource-transitions.ts @@ -5,7 +5,7 @@ import { isConfirmedCleanup, } from '@agent-device/contracts/durable-resource'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { withDurableCaptureResourceFence, type DurableCaptureResourceFenceLease, diff --git a/src/daemon/focus-runtime.ts b/src/daemon/focus-runtime.ts index 482c910767..f9701487f4 100644 --- a/src/daemon/focus-runtime.ts +++ b/src/daemon/focus-runtime.ts @@ -2,7 +2,7 @@ import type { FocusPointInput } from '@agent-device/contracts/focus-runtime'; import { focusRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Point } from '@agent-device/kernel/snapshot'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { readPointPositionals } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; diff --git a/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts b/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts index b845ebda03..17c3f8173a 100644 --- a/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts +++ b/src/daemon/handlers/__tests__/session-close-shutdown.fixtures.ts @@ -12,8 +12,8 @@ vi.mock('../../../platforms/apple/core/simulator.ts', async (importOriginal) => await importOriginal(); return { ...actual, shutdownSimulator: vi.fn() }; }); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../../../platforms/apple/core/runner-client.ts', async (importOriginal) => { @@ -54,11 +54,11 @@ import { teardownSessionResources as teardownProductionSessionResources } from ' import { platformResourceCleanup } from '../../../platform-runtime-resource-cleanup.ts'; import { LeaseRegistry } from '../../lease-registry.ts'; import { shutdownSimulator } from '../../../platforms/apple/core/simulator.ts'; +import { runCmd } from '@agent-device/host-kit/command'; import { - runCmd, flushDiagnosticsToSessionFile, withDiagnosticsScope, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import { cleanupAppleXctracePerfCapture } from '../../../platforms/apple/core/perf-xctrace.ts'; import { cleanupAndroidNativePerfSession } from '../../../platforms/android/perf-native.ts'; import { stopAndroidSnapshotHelperSessionForDevice } from '../../../platforms/android/snapshot-helper.ts'; diff --git a/src/daemon/handlers/__tests__/session-device-claims.test.ts b/src/daemon/handlers/__tests__/session-device-claims.test.ts index bba8f7fa0a..b6ddcea2df 100644 --- a/src/daemon/handlers/__tests__/session-device-claims.test.ts +++ b/src/daemon/handlers/__tests__/session-device-claims.test.ts @@ -29,7 +29,7 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', () => ({ activateAndroidTestIme: vi.fn(async () => ({ activated: false })), restoreAndroidTestIme: vi.fn(async () => ({ restored: false, reason: 'no-record' })), })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => +vi.mock('@agent-device/host-kit/process', async (importOriginal) => (await import('../../../__tests__/test-utils/host-process-mock.ts')).pinOwnProcessStartTime( importOriginal, ), diff --git a/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts b/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts index 1bcf015c06..aad33d91c3 100644 --- a/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts +++ b/src/daemon/handlers/__tests__/session-open-execution-runtime.test.ts @@ -51,8 +51,8 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', async (importOriginal) => await importOriginal(); return { ...actual, activateAndroidTestIme: vi.fn(async () => ({ activated: false })) }; }); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); diff --git a/src/daemon/handlers/__tests__/session-open-runtime.test.ts b/src/daemon/handlers/__tests__/session-open-runtime.test.ts index 774b162ad7..8c65c99cbe 100644 --- a/src/daemon/handlers/__tests__/session-open-runtime.test.ts +++ b/src/daemon/handlers/__tests__/session-open-runtime.test.ts @@ -49,8 +49,8 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', async (importOriginal) => await importOriginal(); return { ...actual, activateAndroidTestIme: vi.fn(async () => ({ activated: false })) }; }); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: vi.fn(() => 'test-process-start') }; }); diff --git a/src/daemon/handlers/__tests__/session-replay-divergence.test.ts b/src/daemon/handlers/__tests__/session-replay-divergence.test.ts index c67db44b06..ccdce4e7e0 100644 --- a/src/daemon/handlers/__tests__/session-replay-divergence.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-divergence.test.ts @@ -18,8 +18,8 @@ vi.mock('../snapshot-interactor-capture.ts', () => ({ // re-captures — so the test still proves two dispatches and use of the retried // tree. The #1385 `retryLaunchRace` retry loop (`captureDivergenceObservation`) // awaits this SAME `sleep`, further down in this file. -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/retry', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, sleep: vi.fn(async () => {}) }; }); diff --git a/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts b/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts index b3f1455277..60cc9f6982 100644 --- a/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-repair-record-exclusion.test.ts @@ -25,8 +25,8 @@ vi.mock('../../../platforms/apple/core/simulator.ts', async (importOriginal) => await importOriginal(); return { ...actual, shutdownSimulator: vi.fn() }; }); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../../../platforms/apple/core/runner-client.ts', async (importOriginal) => { diff --git a/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts b/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts index a9cad9f81a..06d4bd6b1d 100644 --- a/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-repair-transaction.test.ts @@ -25,8 +25,8 @@ vi.mock('../../../platforms/apple/core/simulator.ts', async (importOriginal) => await importOriginal(); return { ...actual, shutdownSimulator: vi.fn() }; }); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../../../platforms/apple/core/runner-client.ts', async (importOriginal) => { diff --git a/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts b/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts index dc0a0cc685..b630f50f8b 100644 --- a/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts +++ b/src/daemon/handlers/__tests__/session-replay-target-verification-runtime.test.ts @@ -23,8 +23,8 @@ vi.mock('../snapshot-interactor-capture.ts', () => ({ // no-op so the retry tests below exercise the retry BRANCH (still runs each // mocked capture attempt) without a real wall-clock wait (repo guidance: unit // tests must not wait real time). -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/retry', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, sleep: vi.fn(async () => {}) }; }); diff --git a/src/daemon/handlers/__tests__/session-test-harness.ts b/src/daemon/handlers/__tests__/session-test-harness.ts index b46cccfa22..7811f95aca 100644 --- a/src/daemon/handlers/__tests__/session-test-harness.ts +++ b/src/daemon/handlers/__tests__/session-test-harness.ts @@ -69,8 +69,8 @@ vi.mock('../../../platforms/android/ime-lifecycle.ts', async (importOriginal) => restoreAndroidTestIme: vi.fn(async () => ({ restored: false, reason: 'no-record' })), }; }); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async () => ({ stdout: '', stderr: '', exitCode: 0 })) }; }); vi.mock('../../materialized-path-registry.ts', async (importOriginal) => { @@ -106,7 +106,7 @@ import { } from '../../../platforms/apple/core/runner-client.ts'; import { runMacOsAlertAction } from '../../../platforms/apple/os/macos/helper.ts'; import { resolveAndroidPackageForOpen } from '../../../platform-runtime-open-target.ts'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { resolveIosApp, resolveIosSimulatorDeepLinkBundleId, diff --git a/src/daemon/handlers/find.ts b/src/daemon/handlers/find.ts index 97bb1f4c55..2d7412b70d 100644 --- a/src/daemon/handlers/find.ts +++ b/src/daemon/handlers/find.ts @@ -12,7 +12,7 @@ import { expireRefFrame } from '../ref-frame.ts'; import type { DaemonInvokeFn, DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { SessionStore } from '../session-store.ts'; import { contextFromFlags } from '../context.ts'; -import { readCommandMessage, successText } from '@agent-device/host-kit/values'; +import { readCommandMessage, successText } from '@agent-device/kernel/success-text'; import { errorResponse, noActiveSessionError } from './response.ts'; import { withSystemSurfaceDisclosure } from './system-surface-disclosure.ts'; import { recordSessionAction } from './handler-utils.ts'; diff --git a/src/daemon/handlers/interaction-gesture.ts b/src/daemon/handlers/interaction-gesture.ts index f47437685f..1fc84f2eb9 100644 --- a/src/daemon/handlers/interaction-gesture.ts +++ b/src/daemon/handlers/interaction-gesture.ts @@ -25,7 +25,7 @@ import { } from '@agent-device/kernel/snapshot'; import { resolveBoundGestureRuntime, type BoundGestureExecutor } from '../gesture-runtime.ts'; import { isActiveProviderDevice } from '../../provider-device-runtime.ts'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import { ensureAndroidBlockingSystemDialogReady } from '../android-system-dialog.ts'; import type { DaemonResponse, SessionState } from '../types.ts'; import type { InteractionHandlerParams } from './interaction-common.ts'; diff --git a/src/daemon/handlers/interaction-ios-tap-outcome.ts b/src/daemon/handlers/interaction-ios-tap-outcome.ts index b6ccccacd3..19a787ef8a 100644 --- a/src/daemon/handlers/interaction-ios-tap-outcome.ts +++ b/src/daemon/handlers/interaction-ios-tap-outcome.ts @@ -9,7 +9,7 @@ import { import { summarizeAxEvidence } from '../../utils/ax-digest.ts'; import { getRequestSignal } from '@agent-device/host-kit/request'; import { isLocalIosRunnerSession } from '../direct-ios-selector.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { SessionStore } from '../session-store.ts'; import type { SessionState } from '../types.ts'; import type { ContextFromFlags } from './interaction-common.ts'; diff --git a/src/daemon/handlers/interaction-read.ts b/src/daemon/handlers/interaction-read.ts index 3ca4db3901..eda77362cb 100644 --- a/src/daemon/handlers/interaction-read.ts +++ b/src/daemon/handlers/interaction-read.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/element-text-runtime'; import { isIosFamily } from '@agent-device/kernel/device'; import { runtimeExecutionFromContext } from '../snapshot-runtime-capture-input.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { SessionState } from '../types.ts'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; import { extractReadableText, prefersValueForReadableText } from '../../utils/text-surface.ts'; diff --git a/src/daemon/handlers/interaction-touch-android-freshness.ts b/src/daemon/handlers/interaction-touch-android-freshness.ts index 287aa6cfb1..64ccb128cc 100644 --- a/src/daemon/handlers/interaction-touch-android-freshness.ts +++ b/src/daemon/handlers/interaction-touch-android-freshness.ts @@ -1,4 +1,4 @@ -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { getActiveAndroidSnapshotFreshness } from '../session-snapshot-freshness.ts'; import type { SessionState } from '../types.ts'; import type { InteractionHandlerParams } from './interaction-common.ts'; diff --git a/src/daemon/handlers/interaction-touch-direct-ios.ts b/src/daemon/handlers/interaction-touch-direct-ios.ts index 114cd903ea..bf9aff71c2 100644 --- a/src/daemon/handlers/interaction-touch-direct-ios.ts +++ b/src/daemon/handlers/interaction-touch-direct-ios.ts @@ -1,6 +1,6 @@ import type { GestureReferenceFrame } from '@agent-device/contracts/scroll-gesture'; import { normalizeError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { isDirectIosSelectorFallbackError, type DirectIosSelectorTarget, diff --git a/src/daemon/handlers/interaction-touch-payload.ts b/src/daemon/handlers/interaction-touch-payload.ts index 3997feb4a4..d1e55b0191 100644 --- a/src/daemon/handlers/interaction-touch-payload.ts +++ b/src/daemon/handlers/interaction-touch-payload.ts @@ -1,5 +1,5 @@ import type { GestureReferenceFrame } from '@agent-device/contracts/scroll-gesture'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; /** * What a built touch payload looks like: the field merge (backend data, point, diff --git a/src/daemon/handlers/interaction-touch-reference-frame.ts b/src/daemon/handlers/interaction-touch-reference-frame.ts index 77ddbc44e7..eb9e523139 100644 --- a/src/daemon/handlers/interaction-touch-reference-frame.ts +++ b/src/daemon/handlers/interaction-touch-reference-frame.ts @@ -2,7 +2,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import type { AndroidObservationAdapter } from '@agent-device/contracts/android-observation'; import type { GestureReferenceFrame } from '@agent-device/contracts/scroll-gesture'; import type { SnapshotNode } from '@agent-device/kernel/snapshot'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { SessionStore } from '../session-store.ts'; import { getSnapshotReferenceFrame } from '../touch-reference-frame.ts'; import type { SessionState } from '../types.ts'; diff --git a/src/daemon/handlers/react-native.ts b/src/daemon/handlers/react-native.ts index 1bbb9eab9f..4c6111f128 100644 --- a/src/daemon/handlers/react-native.ts +++ b/src/daemon/handlers/react-native.ts @@ -9,7 +9,8 @@ import { type ReactNativeOverlayDismissTarget, } from '../../core/react-native-overlay.ts'; import { normalizeError } from '@agent-device/kernel/errors'; -import { stripUndefined, successText } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; +import { successText } from '@agent-device/kernel/success-text'; import type { SnapshotQualityVerdict, SnapshotState } from '@agent-device/kernel/snapshot'; import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; diff --git a/src/daemon/handlers/session-app-deployment.ts b/src/daemon/handlers/session-app-deployment.ts index 87339b41ab..11830fa46b 100644 --- a/src/daemon/handlers/session-app-deployment.ts +++ b/src/daemon/handlers/session-app-deployment.ts @@ -13,7 +13,7 @@ import { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { resolvePayloadInput } from '../../utils/payload-input.ts'; import { resolveDeployResultTarget } from '../../utils/result-serialization.ts'; -import { withSuccessText } from '@agent-device/host-kit/values'; +import { withSuccessText } from '@agent-device/kernel/success-text'; import { recordSessionAction } from './handler-utils.ts'; import { errorResponse } from './response.ts'; import { requireSessionOrExplicitSelector, resolveCommandDevice } from './session-device-utils.ts'; diff --git a/src/daemon/handlers/session-app-source-deployment.ts b/src/daemon/handlers/session-app-source-deployment.ts index 3e0955f7ad..0f00dabb5c 100644 --- a/src/daemon/handlers/session-app-source-deployment.ts +++ b/src/daemon/handlers/session-app-source-deployment.ts @@ -17,7 +17,7 @@ import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-ru import { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { resolveInstallFromSourceResultTarget } from '../../utils/result-serialization.ts'; -import { withSuccessText } from '@agent-device/host-kit/values'; +import { withSuccessText } from '@agent-device/kernel/success-text'; import { recordSessionAction } from './handler-utils.ts'; import { resolveCommandDevice } from './session-device-utils.ts'; import { diff --git a/src/daemon/handlers/session-clipboard.ts b/src/daemon/handlers/session-clipboard.ts index f65a8d471a..d44e6462d5 100644 --- a/src/daemon/handlers/session-clipboard.ts +++ b/src/daemon/handlers/session-clipboard.ts @@ -16,7 +16,7 @@ import type { SessionStore } from '../session-store.ts'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-runtime-binding.ts'; import { admitRuntimeUse, type RuntimeAdmissionBindings } from '../runtime-admission.ts'; import { runtimeExecutionFromContext } from '../snapshot-runtime-capture-input.ts'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { errorResponse, type DaemonFailureResponse } from './response.ts'; import { recordSessionAction } from './handler-utils.ts'; import { requireSessionOrExplicitSelector, resolveCommandDevice } from './session-device-utils.ts'; diff --git a/src/daemon/handlers/session-close-script.ts b/src/daemon/handlers/session-close-script.ts index f16094e1b2..9e051e9c36 100644 --- a/src/daemon/handlers/session-close-script.ts +++ b/src/daemon/handlers/session-close-script.ts @@ -1,5 +1,5 @@ import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { SessionStore } from '../session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { recordSessionAction } from './handler-utils.ts'; diff --git a/src/daemon/handlers/session-close.ts b/src/daemon/handlers/session-close.ts index 6a8b408279..9d6ca0adda 100644 --- a/src/daemon/handlers/session-close.ts +++ b/src/daemon/handlers/session-close.ts @@ -1,9 +1,9 @@ -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import type { LeaseLifecycleProvider, TargetShutdownResult } from '@agent-device/contracts/device'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { SessionStore } from '../session-store.ts'; -import { successText, withSuccessText } from '@agent-device/host-kit/values'; +import { successText, withSuccessText } from '@agent-device/kernel/success-text'; import { resolveCommandDevice } from './session-device-utils.ts'; import { errorResponse } from './response.ts'; import { expireRefFrame } from '../ref-frame.ts'; diff --git a/src/daemon/handlers/session-doctor-metro.ts b/src/daemon/handlers/session-doctor-metro.ts index 0abf6d10c0..ed4d8578f4 100644 --- a/src/daemon/handlers/session-doctor-metro.ts +++ b/src/daemon/handlers/session-doctor-metro.ts @@ -1,5 +1,5 @@ import type { DoctorCheck, DoctorKind } from '@agent-device/contracts/observability'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; const METRO_PROBE_TIMEOUT_MS = 1500; const METRO_PROCESS_LOOKUP_TIMEOUT_MS = 1500; diff --git a/src/daemon/handlers/session-doctor.ts b/src/daemon/handlers/session-doctor.ts index a9f3d84bc2..f14019e5af 100644 --- a/src/daemon/handlers/session-doctor.ts +++ b/src/daemon/handlers/session-doctor.ts @@ -8,7 +8,7 @@ import { listLocalDeviceInventory, shouldPropagateDeviceInventoryProbeError, } from '../../request/device-inventory-context.ts'; -import { readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { SessionStore } from '../session-store.ts'; import { appendAppChecks, type DoctorAppInventory } from './session-doctor-app.ts'; @@ -36,7 +36,7 @@ import type { HostDiagnostics, HostDiagnosticsContext, } from '@agent-device/contracts/host-diagnostics'; -import { resolveAndroidSerialAllowlist } from '@agent-device/host-kit/fs'; +import { resolveAndroidSerialAllowlist } from '@agent-device/kernel/device-isolation'; import type { InstalledAppInfo } from '@agent-device/contracts/app-inventory-runtime'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import { appsRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; diff --git a/src/daemon/handlers/session-inventory.ts b/src/daemon/handlers/session-inventory.ts index 167cc3aaf1..ab14ffea8e 100644 --- a/src/daemon/handlers/session-inventory.ts +++ b/src/daemon/handlers/session-inventory.ts @@ -18,7 +18,7 @@ import { import { resolveAndroidSerialAllowlist, resolveIosSimulatorDeviceSetPath, -} from '@agent-device/host-kit/fs'; +} from '@agent-device/kernel/device-isolation'; import type { DaemonRequest, DaemonResponse, SessionRef } from '../types.ts'; import { resolveSessionRunnerLogPath, SessionStore } from '../session-store.ts'; import { diff --git a/src/daemon/handlers/session-open-execution.ts b/src/daemon/handlers/session-open-execution.ts index fc6e1b0243..0144926d84 100644 --- a/src/daemon/handlers/session-open-execution.ts +++ b/src/daemon/handlers/session-open-execution.ts @@ -31,7 +31,7 @@ import { import { STARTUP_SAMPLE_METHOD, type StartupPerfSample } from './session-startup-metrics.ts'; import { buildNextOpenSession, buildOpenResult } from './session-open-surface.ts'; import { markDeferredInteractionOutcome } from '../deferred-interaction-outcome.ts'; -import { emitDiagnostic, getDiagnosticsMeta } from '@agent-device/host-kit/exec'; +import { emitDiagnostic, getDiagnosticsMeta } from '@agent-device/host-kit/diagnostics'; import { prepareOpenCommandDetails, type ResolvedOpenRuntimeHintPlan, diff --git a/src/daemon/handlers/session-open-surface.ts b/src/daemon/handlers/session-open-surface.ts index cdac5eeae5..fc7262a300 100644 --- a/src/daemon/handlers/session-open-surface.ts +++ b/src/daemon/handlers/session-open-surface.ts @@ -6,7 +6,7 @@ import { type DeviceInfo, } from '@agent-device/kernel/device'; import type { SessionRuntimeHints, SessionState } from '../types.ts'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { StartupPerfSample } from './session-startup-metrics.ts'; import type { DeviceSelectionResult } from '../../core/device-selection-resolver.ts'; diff --git a/src/daemon/handlers/session-replay-divergence.ts b/src/daemon/handlers/session-replay-divergence.ts index eae54deb10..3b71272194 100644 --- a/src/daemon/handlers/session-replay-divergence.ts +++ b/src/daemon/handlers/session-replay-divergence.ts @@ -1,6 +1,6 @@ import type { SessionAction } from '@agent-device/contracts/session'; import type { CommandFlags } from '@agent-device/contracts/command'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import { isUnreadableCaptureContentError } from '@agent-device/contracts/android-snapshot-quality'; import { isSparseSnapshotQualityVerdict } from '@agent-device/capture-kit/snapshot-quality-verdict'; import { displayLabel, formatRole } from '../../snapshot/snapshot-lines.ts'; diff --git a/src/daemon/handlers/session-replay-maestro-observer.ts b/src/daemon/handlers/session-replay-maestro-observer.ts index 79841a3f1e..89b7dded01 100644 --- a/src/daemon/handlers/session-replay-maestro-observer.ts +++ b/src/daemon/handlers/session-replay-maestro-observer.ts @@ -6,7 +6,7 @@ import type { } from '@agent-device/maestro'; import { AppError } from '@agent-device/kernel/errors'; import type { ReplayTestAttemptStepSink } from '@agent-device/replay-test'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; import { appendReplayTraceEvent } from './session-replay-trace.ts'; export function createMaestroReplayObserver(params: { diff --git a/src/daemon/handlers/session-replay-maestro-runtime.ts b/src/daemon/handlers/session-replay-maestro-runtime.ts index 1c3793c93f..90ac983e33 100644 --- a/src/daemon/handlers/session-replay-maestro-runtime.ts +++ b/src/daemon/handlers/session-replay-maestro-runtime.ts @@ -9,7 +9,7 @@ import { import { AppError } from '@agent-device/kernel/errors'; import { resolveTargetDevice } from '../../core/dispatch-resolve.ts'; import { getRequestSignal } from '@agent-device/host-kit/request'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; import { collectReplayShellEnv, parseReplayCliEnvEntries, diff --git a/src/daemon/handlers/session-replay-trace.ts b/src/daemon/handlers/session-replay-trace.ts index cb4b53306a..2f314bfaee 100644 --- a/src/daemon/handlers/session-replay-trace.ts +++ b/src/daemon/handlers/session-replay-trace.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; import { redactDiagnosticData } from '@agent-device/kernel/redaction'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; export function appendReplayTraceEvent( tracePath: string | undefined, diff --git a/src/daemon/handlers/session-replay-video-recording.ts b/src/daemon/handlers/session-replay-video-recording.ts index f701976a4b..0084bb0903 100644 --- a/src/daemon/handlers/session-replay-video-recording.ts +++ b/src/daemon/handlers/session-replay-video-recording.ts @@ -1,7 +1,8 @@ import path from 'node:path'; import type { DaemonOpenLifecycle, DaemonRequest, DaemonResponse } from '../types.ts'; import type { SessionStore } from '../session-store.ts'; -import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { sleep } from '@agent-device/host-kit/retry'; import { handleRecordCommand } from './record-runtime.ts'; import type { BindDeviceRuntime, BindExactDeviceRuntime } from '../request-runtime-binding.ts'; diff --git a/src/daemon/handlers/session-script-publication.ts b/src/daemon/handlers/session-script-publication.ts index 1b54c51fe7..fea4d2549f 100644 --- a/src/daemon/handlers/session-script-publication.ts +++ b/src/daemon/handlers/session-script-publication.ts @@ -1,6 +1,6 @@ import { INTERNAL_COMMANDS } from '../../command-catalog.ts'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { effectiveWriteForce, isAuthoringArmedSession, diff --git a/src/daemon/handlers/session-state.ts b/src/daemon/handlers/session-state.ts index f8808f1e70..5bda3acb1a 100644 --- a/src/daemon/handlers/session-state.ts +++ b/src/daemon/handlers/session-state.ts @@ -15,7 +15,7 @@ import { } from '@agent-device/kernel/device'; import type { DaemonRequest, DaemonResponse } from '../types.ts'; import { SessionStore } from '../session-store.ts'; -import { resolveAndroidSerialAllowlist } from '@agent-device/host-kit/fs'; +import { resolveAndroidSerialAllowlist } from '@agent-device/kernel/device-isolation'; import { hasExplicitSessionFlag, requireSessionOrExplicitSelector, diff --git a/src/daemon/handlers/session-test-shard-devices.ts b/src/daemon/handlers/session-test-shard-devices.ts index 540f2e943f..03ef5adc3d 100644 --- a/src/daemon/handlers/session-test-shard-devices.ts +++ b/src/daemon/handlers/session-test-shard-devices.ts @@ -4,7 +4,7 @@ import { listDeviceInventory } from '../../request/device-inventory-context.ts'; import { resolveAndroidSerialAllowlist, resolveIosSimulatorDeviceSetPath, -} from '@agent-device/host-kit/fs'; +} from '@agent-device/kernel/device-isolation'; import { isMobilePlatform, matchesPlatformSelector, diff --git a/src/daemon/handlers/session-test-suite-command.ts b/src/daemon/handlers/session-test-suite-command.ts index 9360d546ff..94b4147e00 100644 --- a/src/daemon/handlers/session-test-suite-command.ts +++ b/src/daemon/handlers/session-test-suite-command.ts @@ -32,7 +32,7 @@ import { registerRequestAbort, } from '@agent-device/host-kit/request'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { buildReplayTestSourceDiscovery } from './session-test-source-discovery.ts'; import { buildReplayTestShardFlags, diff --git a/src/daemon/handlers/snapshot-settings.ts b/src/daemon/handlers/snapshot-settings.ts index b35a69e48b..47f270544d 100644 --- a/src/daemon/handlers/snapshot-settings.ts +++ b/src/daemon/handlers/snapshot-settings.ts @@ -14,12 +14,9 @@ import type { DaemonRequest, DaemonResponse, SessionState } from '../types.ts'; import { recordIfSession } from './snapshot-session.ts'; import { errorResponse, type DaemonFailureResponse } from './response.ts'; import { expireRefFrame } from '../ref-frame.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; -import { - readLocationCoordinate, - successText, - withSuccessText, -} from '@agent-device/host-kit/values'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { readLocationCoordinate } from '@agent-device/kernel/location-coordinates'; +import { successText, withSuccessText } from '@agent-device/kernel/success-text'; import type { BindDeviceRuntime, InspectDeviceRuntimeFacts } from '../request-runtime-binding.ts'; import { admitRuntimeUse } from '../runtime-admission.ts'; diff --git a/src/daemon/home-runtime.ts b/src/daemon/home-runtime.ts index 9acd6856b5..b20b2fe9e0 100644 --- a/src/daemon/home-runtime.ts +++ b/src/daemon/home-runtime.ts @@ -2,7 +2,7 @@ import type { HomeInput } from '@agent-device/contracts/home-runtime'; import { homeRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/http-health.ts b/src/daemon/http-health.ts index 9a648f8dcf..7c07183695 100644 --- a/src/daemon/http-health.ts +++ b/src/daemon/http-health.ts @@ -1,4 +1,4 @@ -import { readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; // See docs/adr/0006-daemon-rpc-protocol-version.md before changing this value. // Enforced, not just documented: `test/wire-compat/` digests the declarations diff --git a/src/daemon/interaction-outcome-policy.ts b/src/daemon/interaction-outcome-policy.ts index a003be0965..693e6211bf 100644 --- a/src/daemon/interaction-outcome-policy.ts +++ b/src/daemon/interaction-outcome-policy.ts @@ -2,7 +2,7 @@ import type { CommandFlags } from '@agent-device/contracts/command'; import { isMobilePlatform } from '@agent-device/kernel/device'; import type { SnapshotNode, SnapshotState } from '@agent-device/kernel/snapshot'; import { collectKeyboardChromeRefs } from '../core/snapshot-chrome.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { isViewportRootNode } from '@agent-device/contracts/snapshot'; import { contextFromFlags, type DaemonCommandContext } from './context.ts'; import type { SessionState } from './types.ts'; diff --git a/src/daemon/ios-app-session-hint.ts b/src/daemon/ios-app-session-hint.ts index 961757d894..8afa0d63d7 100644 --- a/src/daemon/ios-app-session-hint.ts +++ b/src/daemon/ios-app-session-hint.ts @@ -1,6 +1,6 @@ import { isIosFamily, type DeviceInfo } from '@agent-device/kernel/device'; import { resolveSoleForegroundIosApp } from '../platform-runtime-open-target.ts'; -import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; export { resolveSoleForegroundIosApp } from '../platform-runtime-open-target.ts'; diff --git a/src/daemon/keyboard-runtime.ts b/src/daemon/keyboard-runtime.ts index 10a2f5cc05..ab33d1d522 100644 --- a/src/daemon/keyboard-runtime.ts +++ b/src/daemon/keyboard-runtime.ts @@ -18,7 +18,7 @@ import type { import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import { isKeyboardAction, type KeyboardAction } from '../utils/keyboard-actions.ts'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import { admitRuntimeUse, diff --git a/src/daemon/lease-context.ts b/src/daemon/lease-context.ts index d49a0bdc1c..f96af5a390 100644 --- a/src/daemon/lease-context.ts +++ b/src/daemon/lease-context.ts @@ -2,7 +2,7 @@ import type { DaemonRequest } from './types.ts'; import type { LeaseBackend } from '@agent-device/kernel/contracts'; import type { DeviceLease } from '@agent-device/contracts/device'; import type { RunnerLogicalLeaseContext } from '@agent-device/contracts/runner-lease-context'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; import { DEFAULT_PROXY_LEASE_TTL_MS, findMissingProxyLeaseFields, diff --git a/src/daemon/lease-lifecycle.ts b/src/daemon/lease-lifecycle.ts index 9fbf1ad7ba..daba39eaab 100644 --- a/src/daemon/lease-lifecycle.ts +++ b/src/daemon/lease-lifecycle.ts @@ -1,4 +1,4 @@ -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { leaseScopeToReleaseRequest } from '../core/lease-scope.ts'; import { clearDeviceClaim } from './device-claims.ts'; import type { LeaseRegistry } from './lease-registry.ts'; diff --git a/src/daemon/orientation-runtime.ts b/src/daemon/orientation-runtime.ts index b6135d97ad..0d409c9fcd 100644 --- a/src/daemon/orientation-runtime.ts +++ b/src/daemon/orientation-runtime.ts @@ -3,7 +3,7 @@ import { parseDeviceRotation, type DeviceRotation } from '@agent-device/contract import { orientationRuntimeUse } from '@agent-device/contracts/platform-runtime-operations'; import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; import { resolveBoundGenericRuntime, type RuntimeAdmissionBindings } from './runtime-admission.ts'; diff --git a/src/daemon/platform-request-scope.ts b/src/daemon/platform-request-scope.ts index d07d03715b..201a92e9c6 100644 --- a/src/daemon/platform-request-scope.ts +++ b/src/daemon/platform-request-scope.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/platform-runtime-host'; import { getRequestSignal, emitRequestProgress } from '@agent-device/host-kit/request'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { DaemonRequest } from './types.ts'; const processLifetimeSignal = new AbortController().signal; diff --git a/src/daemon/post-gesture-stability.ts b/src/daemon/post-gesture-stability.ts index f390db34f4..cad874f7c8 100644 --- a/src/daemon/post-gesture-stability.ts +++ b/src/daemon/post-gesture-stability.ts @@ -1,4 +1,5 @@ -import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { sleep } from '@agent-device/host-kit/retry'; /** * Pure post-gesture stability mechanics: the quiet-window polling loop and the diff --git a/src/daemon/provider-lease-expiry.ts b/src/daemon/provider-lease-expiry.ts index 1ddc2f354e..ded6cb40e3 100644 --- a/src/daemon/provider-lease-expiry.ts +++ b/src/daemon/provider-lease-expiry.ts @@ -5,9 +5,10 @@ import type { LeaseLifecycleProvider, ProviderExpiredLeaseRecovery, } from '@agent-device/contracts/device'; -import { publishFileSync } from '@agent-device/host-kit/fs'; +import { publishFileSync } from '@agent-device/host-kit/file'; import { releaseExpiredProviderLease } from './lease-lifecycle.ts'; -import { emitDiagnostic, sleep } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { sleep } from '@agent-device/host-kit/retry'; const DEFAULT_RETRY_DELAY_MS = 1_000; const PENDING_RELEASES_FILE = 'expired-provider-leases.json'; diff --git a/src/daemon/recording-gestures.ts b/src/daemon/recording-gestures.ts index e5965f0b86..313f2ecd3e 100644 --- a/src/daemon/recording-gestures.ts +++ b/src/daemon/recording-gestures.ts @@ -7,7 +7,7 @@ import { resolveGestureOffsetMs, resolveTapVisualizationOffsetMs, } from './recording-timing.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { DEFAULT_MOBILE_SCROLL_DURATION_MS } from '@agent-device/contracts/scroll-command'; import { type ScrollDirection, diff --git a/src/daemon/request-execution-scope.ts b/src/daemon/request-execution-scope.ts index daffa3feb8..b66fe746e4 100644 --- a/src/daemon/request-execution-scope.ts +++ b/src/daemon/request-execution-scope.ts @@ -4,7 +4,7 @@ import { emitDiagnostic, getDiagnosticsMeta, updateDiagnosticsScope, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import { applyCommandDefaults } from '../cli-schema/command-schema.ts'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import { diff --git a/src/daemon/request-finalization.ts b/src/daemon/request-finalization.ts index 759fcb19ab..d2bad90c89 100644 --- a/src/daemon/request-finalization.ts +++ b/src/daemon/request-finalization.ts @@ -4,7 +4,7 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, getDiagnosticsMeta, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import type { DaemonRequest, DaemonResponse, DaemonResponseData } from './types.ts'; import type { DaemonArtifact, DaemonArtifactType } from '@agent-device/kernel/contracts'; diff --git a/src/daemon/request-lock-policy.ts b/src/daemon/request-lock-policy.ts index a1780895fd..512be48c10 100644 --- a/src/daemon/request-lock-policy.ts +++ b/src/daemon/request-lock-policy.ts @@ -13,7 +13,7 @@ import { type PlatformSelector, } from '@agent-device/kernel/device'; import { buildSessionRecoveryHint, describeSessionDevice } from './session-recovery-hints.ts'; -import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; import { hasLockableDeviceSelector, hasSelectorValue } from './device-selector-intent.ts'; import { canOverrideLockPolicySelector } from './daemon-command-registry.ts'; diff --git a/src/daemon/request-router.ts b/src/daemon/request-router.ts index 8ab4107a16..4228a4b80e 100644 --- a/src/daemon/request-router.ts +++ b/src/daemon/request-router.ts @@ -29,7 +29,7 @@ import { getDiagnosticsMeta, registerDiagnosticSensitiveValue, withDiagnosticsScope, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import type { LeaseRegistry } from './lease-registry.ts'; import { loadGenericRequestHandlerModule, diff --git a/src/daemon/request-save-script-policy.ts b/src/daemon/request-save-script-policy.ts index f753e48e89..a5d133d060 100644 --- a/src/daemon/request-save-script-policy.ts +++ b/src/daemon/request-save-script-policy.ts @@ -3,7 +3,7 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, getDiagnosticsMeta, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/diagnostics'; import { listSaveScriptFlagOwnerCommands, ownsSaveScriptFlag } from './daemon-command-registry.ts'; import type { DaemonRequest, DaemonResponse } from './types.ts'; diff --git a/src/daemon/resumable-upload-transfer.ts b/src/daemon/resumable-upload-transfer.ts index 89cf12a95a..7106c53efe 100644 --- a/src/daemon/resumable-upload-transfer.ts +++ b/src/daemon/resumable-upload-transfer.ts @@ -3,7 +3,7 @@ import crypto from 'node:crypto'; import type { IncomingMessage } from 'node:http'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { createByteLimitStream } from '@agent-device/host-kit/fs'; +import { createByteLimitStream } from '@agent-device/host-kit/archive'; import { parseUploadContentLength, parseUploadContentRange } from './resumable-upload-range.ts'; export type ResumableTransferEntry = { diff --git a/src/daemon/runtime-session.ts b/src/daemon/runtime-session.ts index 3a5ed184b6..80ab3fbcd9 100644 --- a/src/daemon/runtime-session.ts +++ b/src/daemon/runtime-session.ts @@ -1,5 +1,5 @@ import type { CommandSessionRecord, CommandSessionStore } from '../runtime-contract.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { SessionState } from './types.ts'; export type RuntimeSessionRecordOptions = { diff --git a/src/daemon/scroll-runtime.ts b/src/daemon/scroll-runtime.ts index c07c448417..5e0d987acf 100644 --- a/src/daemon/scroll-runtime.ts +++ b/src/daemon/scroll-runtime.ts @@ -22,7 +22,7 @@ import { type ScrollEdge, type ScrollEdgeState, } from '../utils/scroll-edge-state.ts'; -import { withSuccessText } from '@agent-device/host-kit/values'; +import { withSuccessText } from '@agent-device/kernel/success-text'; import type { DaemonCommandContext } from './context.ts'; import { errorResponse } from './handlers/response.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; diff --git a/src/daemon/server/daemon-idle-reap.ts b/src/daemon/server/daemon-idle-reap.ts index 5f10fa03aa..8cf63cfb62 100644 --- a/src/daemon/server/daemon-idle-reap.ts +++ b/src/daemon/server/daemon-idle-reap.ts @@ -1,4 +1,4 @@ -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { SessionStore } from '../session-store.ts'; import type { SessionState } from '../types.ts'; import { isUncommittedRepairSession } from '../session-replay-transaction.ts'; diff --git a/src/daemon/server/daemon-runtime-web-close-teardown.test.ts b/src/daemon/server/daemon-runtime-web-close-teardown.test.ts index ac5bc02919..53286eee5b 100644 --- a/src/daemon/server/daemon-runtime-web-close-teardown.test.ts +++ b/src/daemon/server/daemon-runtime-web-close-teardown.test.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import { afterEach, expect, test, vi } from 'vitest'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); @@ -10,7 +10,7 @@ import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; import { WEB_DESKTOP_DEVICE } from '../../__tests__/test-utils/device-fixtures.ts'; import { AGENT_BROWSER_TIMEOUT_MS } from '../../platforms/web/agent-browser-provider.ts'; import { installFakeManagedAgentBrowser } from '../../platforms/web/__tests__/test-utils.ts'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { SessionStore } from '../session-store.ts'; import type { SessionState } from '../types.ts'; import { diff --git a/src/daemon/server/daemon-runtime.ts b/src/daemon/server/daemon-runtime.ts index 40e3ada5b6..aa22576195 100644 --- a/src/daemon/server/daemon-runtime.ts +++ b/src/daemon/server/daemon-runtime.ts @@ -35,12 +35,13 @@ import { emitDiagnostic, flushDiagnosticsToSessionFile, withDiagnosticsScope, - isEnvTruthy, - sleep, +} from '@agent-device/host-kit/diagnostics'; +import { createOwnedProcessRecordStore, type OwnedProcessRecordStore, reapOwnedProcessRecordsAtStartup, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; +import { isEnvTruthy, sleep } from '@agent-device/host-kit/retry'; import { acquireDaemonLock, diff --git a/src/daemon/server/daemon-session-lease-finalizer.ts b/src/daemon/server/daemon-session-lease-finalizer.ts index 6aaca1937d..ee01e540ce 100644 --- a/src/daemon/server/daemon-session-lease-finalizer.ts +++ b/src/daemon/server/daemon-session-lease-finalizer.ts @@ -1,5 +1,5 @@ import { leaseScopeToReleaseRequest } from '../../core/lease-scope.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { ExpiredProviderLeaseReleaser } from '../provider-lease-expiry.ts'; import type { LeaseRegistry } from '../lease-registry.ts'; import type { SessionState } from '../types.ts'; diff --git a/src/daemon/server/daemon-shutdown-claims.ts b/src/daemon/server/daemon-shutdown-claims.ts index ef6b0553a5..126aab4b1a 100644 --- a/src/daemon/server/daemon-shutdown-claims.ts +++ b/src/daemon/server/daemon-shutdown-claims.ts @@ -1,5 +1,5 @@ import { publicPlatformString } from '@agent-device/kernel/device'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { clearDeviceClaim, type DeviceClaimClearOutcome } from '../device-claims.ts'; import type { DeviceClaimRecord } from '../daemon-shutdown-report.ts'; import type { SessionState } from '../types.ts'; diff --git a/src/daemon/server/http-server.ts b/src/daemon/server/http-server.ts index 4d35b9461d..6bd7317b6e 100644 --- a/src/daemon/server/http-server.ts +++ b/src/daemon/server/http-server.ts @@ -6,7 +6,7 @@ import { toAppErrorCode, type DiagnosticsRecordRef, } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { timingSafeStringEqual } from '../../utils/timing-safe-equal.ts'; import type { CommandRpcParams, diff --git a/src/daemon/server/server-lifecycle.ts b/src/daemon/server/server-lifecycle.ts index ba86f52321..77adf71657 100644 --- a/src/daemon/server/server-lifecycle.ts +++ b/src/daemon/server/server-lifecycle.ts @@ -1,8 +1,8 @@ import fs from 'node:fs'; import { isAgentDeviceDaemonProcess } from '../daemon-process.ts'; -export { readVersion } from '@agent-device/host-kit/values'; -export { readProcessStartTime } from '@agent-device/host-kit/exec'; +export { readVersion } from '@agent-device/host-kit/version'; +export { readProcessStartTime } from '@agent-device/host-kit/process'; export { resolveDaemonCodeSignature } from '../code-signature.ts'; export type DaemonLockInfo = { diff --git a/src/daemon/server/transport.ts b/src/daemon/server/transport.ts index 118a7cc4ae..49fd036389 100644 --- a/src/daemon/server/transport.ts +++ b/src/daemon/server/transport.ts @@ -10,7 +10,7 @@ import { resolveRequestTrackingId, withRequestProgressSink, } from '@agent-device/host-kit/request'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { consumeTextLines } from '../../utils/line-stream.ts'; import { diff --git a/src/daemon/session-action-recorder.ts b/src/daemon/session-action-recorder.ts index 20f2fdcfd6..1627815a33 100644 --- a/src/daemon/session-action-recorder.ts +++ b/src/daemon/session-action-recorder.ts @@ -1,7 +1,7 @@ import type { SessionAction } from '@agent-device/contracts/session'; import type { CommandFlags } from '@agent-device/contracts/command'; import { SCREENSHOT_ACTION_FLAG_KEYS } from '@agent-device/contracts/capture'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { DaemonRequest, SessionRuntimeHints, SessionState } from './types.ts'; import { applyRecordedSaveScriptFlags } from './session-script-publication-capability.ts'; import { repairSessionBoundary } from './session-replay-transaction.ts'; diff --git a/src/daemon/session-event-log-window.ts b/src/daemon/session-event-log-window.ts index b2f3e0acba..d0960044b1 100644 --- a/src/daemon/session-event-log-window.ts +++ b/src/daemon/session-event-log-window.ts @@ -1,6 +1,6 @@ import fs from 'node:fs'; import { AppError } from '@agent-device/kernel/errors'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import { measureEventLogFile, readFirstLineDigest, diff --git a/src/daemon/session-event-log.ts b/src/daemon/session-event-log.ts index c33e74fe3d..d81793c5d7 100644 --- a/src/daemon/session-event-log.ts +++ b/src/daemon/session-event-log.ts @@ -4,8 +4,8 @@ import path from 'node:path'; import { PUBLIC_COMMANDS } from '../command-catalog.ts'; import { AppError } from '@agent-device/kernel/errors'; import { redactDiagnosticData } from '@agent-device/kernel/redaction'; -import { emitDiagnostic, getDiagnosticsMeta } from '@agent-device/host-kit/exec'; -import { isRecord } from '@agent-device/host-kit/values'; +import { emitDiagnostic, getDiagnosticsMeta } from '@agent-device/host-kit/diagnostics'; +import { isRecord } from '@agent-device/kernel/record'; import type { DaemonRequest, DaemonResponse } from './types.ts'; import { buildActionDetails, buildActionSummary } from './session-event-action.ts'; import { buildRequestSuccessEventPresentation } from './session-event-request.ts'; diff --git a/src/daemon/session-event-request.ts b/src/daemon/session-event-request.ts index bd67cc98f8..f3c5b8be3c 100644 --- a/src/daemon/session-event-request.ts +++ b/src/daemon/session-event-request.ts @@ -1,5 +1,5 @@ import { PUBLIC_COMMANDS } from '../command-catalog.ts'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import type { DaemonRequest, DaemonResponseData } from './types.ts'; const EVENT_LIST_PREVIEW_LIMIT = 5; diff --git a/src/daemon/session-paths.ts b/src/daemon/session-paths.ts index 3457272ba1..544f9dd3ac 100644 --- a/src/daemon/session-paths.ts +++ b/src/daemon/session-paths.ts @@ -1,4 +1,4 @@ -import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { resolveUserPath } from '@agent-device/host-kit/file'; export function safeSessionName(name: string): string { return name.replace(/[^a-zA-Z0-9._-]/g, '_'); diff --git a/src/daemon/session-recovery-hints.ts b/src/daemon/session-recovery-hints.ts index 63ba03fe04..353caa63db 100644 --- a/src/daemon/session-recovery-hints.ts +++ b/src/daemon/session-recovery-hints.ts @@ -1,5 +1,5 @@ import type { SessionRef, SessionState } from './types.ts'; -import { shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; export type SessionRecoveryContext = 'device-in-use' | 'selector-conflict'; diff --git a/src/daemon/session-script-writer.ts b/src/daemon/session-script-writer.ts index 46b8578e6d..acf914850c 100644 --- a/src/daemon/session-script-writer.ts +++ b/src/daemon/session-script-writer.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { publicPlatformString } from '@agent-device/kernel/device'; import { dragGesturePayloadFromPositionals } from '@agent-device/contracts/gesture-normalization'; import { inferFillText } from './action-utils.ts'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { AppError } from '@agent-device/kernel/errors'; import { appendScriptSeriesFlags, @@ -17,7 +17,7 @@ import { stripRecordedRefGeneration, } from '@agent-device/ad-script'; import { expandSessionPath, safeSessionName } from './session-paths.ts'; -import { publishFileSync } from '@agent-device/host-kit/fs'; +import { publishFileSync } from '@agent-device/host-kit/file'; import type { SessionState } from './types.ts'; import { NO_SCRIPT_PUBLICATION, diff --git a/src/daemon/session-selector.ts b/src/daemon/session-selector.ts index afae1916db..4018b1df57 100644 --- a/src/daemon/session-selector.ts +++ b/src/daemon/session-selector.ts @@ -6,7 +6,7 @@ import { isSerialAddressablePlatform, matchesPlatformSelector, } from '@agent-device/kernel/device'; -import { parseSerialAllowlist } from '@agent-device/host-kit/fs'; +import { parseSerialAllowlist } from '@agent-device/kernel/device-isolation'; import { buildSessionRecoveryHint, describeSessionDevice } from './session-recovery-hints.ts'; export type SessionSelectorConflictKey = diff --git a/src/daemon/session-store.ts b/src/daemon/session-store.ts index 85df06b1a5..e848b2e20d 100644 --- a/src/daemon/session-store.ts +++ b/src/daemon/session-store.ts @@ -1,7 +1,7 @@ import path from 'node:path'; import fs from 'node:fs'; import { AppError, type DiagnosticsRecordRef } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { SessionRef, SessionRuntimeHints, SessionState } from './types.ts'; import { recordActionEntry, type RecordActionEntry } from './session-action-recorder.ts'; import { expandSessionPath, isSafeSessionSegment, safeSessionName } from './session-paths.ts'; @@ -16,7 +16,7 @@ import { type SessionScriptWriteOptions, type SessionScriptWriteResult, } from './session-script-writer.ts'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { appendActionEvent, appendSessionEvent, diff --git a/src/daemon/session-teardown.ts b/src/daemon/session-teardown.ts index ca44e8baf1..e461918fad 100644 --- a/src/daemon/session-teardown.ts +++ b/src/daemon/session-teardown.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { cleanupRetainedMaterializedPathsForSession } from './materialized-path-registry.ts'; import type { SessionState } from './types.ts'; import type { SessionStore } from './session-store.ts'; diff --git a/src/daemon/touch-runtime.ts b/src/daemon/touch-runtime.ts index c328f231f1..7a3fbc66be 100644 --- a/src/daemon/touch-runtime.ts +++ b/src/daemon/touch-runtime.ts @@ -20,7 +20,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; import type { Point } from '@agent-device/kernel/snapshot'; import { readFillBackendResult } from '../core/fill-backend-result.ts'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { requireIntInRange } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; import type { DirectIosSelectorTarget } from './direct-ios-selector.ts'; diff --git a/src/daemon/tv-remote-runtime.ts b/src/daemon/tv-remote-runtime.ts index b0a74224a6..cea981bba2 100644 --- a/src/daemon/tv-remote-runtime.ts +++ b/src/daemon/tv-remote-runtime.ts @@ -4,7 +4,7 @@ import type { BoundDeviceRuntime } from '@agent-device/contracts/platform-runtim import { parseTvRemoteButton, type TvRemoteButton } from '@agent-device/contracts/tv-remote'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { requireIntInRange } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; import type { ResolvedGenericExecution } from './request-generic-dispatch.ts'; diff --git a/src/daemon/type-text-runtime.ts b/src/daemon/type-text-runtime.ts index fcc68c566c..74d4360241 100644 --- a/src/daemon/type-text-runtime.ts +++ b/src/daemon/type-text-runtime.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/type-text-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { successText } from '@agent-device/host-kit/values'; +import { successText } from '@agent-device/kernel/success-text'; import { findMistargetedTypeRefToken } from '../utils/type-target-warning.ts'; import { requireIntInRange } from '../utils/validation.ts'; import type { DaemonCommandContext } from './context.ts'; diff --git a/src/mcp/command-tools.ts b/src/mcp/command-tools.ts index 707abf2f4d..81b85c78a3 100644 --- a/src/mcp/command-tools.ts +++ b/src/mcp/command-tools.ts @@ -30,7 +30,7 @@ import { mcpToolConfigProperties, } from './tool-control-fields.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import { formatToolErrorText, normalizeToolError } from './tool-error.ts'; import { resolveMcpConfigDefaults } from './tool-input-config.ts'; import { projectStructuredContent } from './tool-result.ts'; diff --git a/src/mcp/protocol-era.ts b/src/mcp/protocol-era.ts index de01e534d2..9991016f70 100644 --- a/src/mcp/protocol-era.ts +++ b/src/mcp/protocol-era.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { readVersion } from '@agent-device/host-kit/values'; +import { readVersion } from '@agent-device/host-kit/version'; /** * MCP has two protocol eras, and agent-device serves both from one stdio process diff --git a/src/mcp/tool-ref-pins.ts b/src/mcp/tool-ref-pins.ts index 9d54e947ce..21d12248f1 100644 --- a/src/mcp/tool-ref-pins.ts +++ b/src/mcp/tool-ref-pins.ts @@ -6,7 +6,7 @@ import { commandDescriptors, commandSupportsSettleObservation, } from '../core/command-descriptor/registry.ts'; -import { asOptionalRecord } from '@agent-device/host-kit/values'; +import { asOptionalRecord } from '@agent-device/kernel/record'; import { readElementMatchCandidateRefs } from '../utils/error-candidates.ts'; export type ToolRefPinStore = { diff --git a/src/metro/client-metro.ts b/src/metro/client-metro.ts index 1c654d4290..648a5eac62 100644 --- a/src/metro/client-metro.ts +++ b/src/metro/client-metro.ts @@ -10,7 +10,9 @@ import type { } from '@agent-device/contracts/remote'; import fs from 'node:fs'; import path from 'node:path'; -import { sleep, runCmdSync, runCmdDetached, waitForProcessExit } from '@agent-device/host-kit/exec'; +import { runCmdSync, runCmdDetached } from '@agent-device/host-kit/command'; +import { waitForProcessExit } from '@agent-device/host-kit/process'; +import { sleep } from '@agent-device/host-kit/retry'; import { ensureMetroCompanion } from './client-metro-companion.ts'; import type { MetroBridgeDescriptor, @@ -20,7 +22,7 @@ import type { } from './metro-types.ts'; import { AppError, asAppError } from '@agent-device/kernel/errors'; -import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { resolveUserPath } from '@agent-device/host-kit/file'; import { detectProjectRuntimeKindFromPackageJson, diff --git a/src/platform-runtime-android-application-tools.ts b/src/platform-runtime-android-application-tools.ts index 279d8bb94a..fd7d68cb26 100644 --- a/src/platform-runtime-android-application-tools.ts +++ b/src/platform-runtime-android-application-tools.ts @@ -5,7 +5,7 @@ import type { } from '@agent-device/contracts/application-lifecycle-runtime'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; /** Lazy Android tools; the Android package owns lifecycle sequencing and durable IME policy. */ export function createAndroidApplicationTools(): AndroidApplicationTools { diff --git a/src/platform-runtime-android-emulator-host.ts b/src/platform-runtime-android-emulator-host.ts index 651c62ba0b..5670e44190 100644 --- a/src/platform-runtime-android-emulator-host.ts +++ b/src/platform-runtime-android-emulator-host.ts @@ -1,6 +1,7 @@ import type { DeviceReadinessRuntimeHost } from '@agent-device/contracts/device-readiness-runtime'; import { listLocalDeviceInventory } from './request/device-inventory-context.ts'; -import { runCmdDetached, stopPidsWithEscalation } from '@agent-device/host-kit/exec'; +import { runCmdDetached } from '@agent-device/host-kit/command'; +import { stopPidsWithEscalation } from '@agent-device/host-kit/process'; export function createAndroidEmulatorHost(): DeviceReadinessRuntimeHost['androidEmulator'] { return Object.freeze({ diff --git a/src/platform-runtime-app-log-process.test.ts b/src/platform-runtime-app-log-process.test.ts index 164eb6837f..6393440532 100644 --- a/src/platform-runtime-app-log-process.test.ts +++ b/src/platform-runtime-app-log-process.test.ts @@ -12,9 +12,12 @@ const processIdentity = vi.hoisted(() => ({ startTime: 'Sun Aug 9 22:00:00 2026' as string | null, })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/command', async (importOriginal) => ({ + ...(await importOriginal()), runCmdBackground: exec.run, +})); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: () => processIdentity.alive, readProcessCommand: () => processIdentity.command, readProcessStartTime: () => processIdentity.startTime, diff --git a/src/platform-runtime-app-log-process.ts b/src/platform-runtime-app-log-process.ts index 96f73cc835..9f8b6eda37 100644 --- a/src/platform-runtime-app-log-process.ts +++ b/src/platform-runtime-app-log-process.ts @@ -14,13 +14,13 @@ import { decodeAppLogProcessMarker } from '@agent-device/capture-kit'; import type { DeviceIdentity } from '@agent-device/kernel/device'; import fs from 'node:fs'; import path from 'node:path'; +import { runCmdBackground } from '@agent-device/host-kit/command'; import { - runCmdBackground, isProcessAlive, readProcessCommand, readProcessStartTime, waitForProcessExit, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; import { requireManagedSessionArtifactPath } from './utils/managed-session-artifact-path.ts'; import { openVerifiedFileForRead } from './utils/verified-file.ts'; diff --git a/src/platform-runtime-apple-application-tools.ts b/src/platform-runtime-apple-application-tools.ts index 422bd0b01b..57dd1087dd 100644 --- a/src/platform-runtime-apple-application-tools.ts +++ b/src/platform-runtime-apple-application-tools.ts @@ -38,7 +38,7 @@ export function createAppleApplicationTools(): AppleApplicationTools { ); }, prepareRunner: async (device, input, signal) => { - const { Deadline } = await import('@agent-device/host-kit/exec'); + const { Deadline } = await import('@agent-device/host-kit/retry'); const { prepareIosRunner } = await import('./platforms/apple/core/runner-client.ts'); const startedAtMs = Date.now(); return await prepareIosRunner(device, { diff --git a/src/platform-runtime-host.ts b/src/platform-runtime-host.ts index 4d69db41c9..812167b24f 100644 --- a/src/platform-runtime-host.ts +++ b/src/platform-runtime-host.ts @@ -11,7 +11,7 @@ import os from 'node:os'; import path from 'node:path'; import { createAppleToolHost } from './platform-runtime-apple-tool-host.ts'; import { createHostToolchainPreparer } from './platform-runtime-toolchain-host.ts'; -import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; +import { runCmd, whichCmd } from '@agent-device/host-kit/command'; export function createDeviceInventoryHost(): DeviceInventoryHost { return Object.freeze({ diff --git a/src/platform-runtime-operation-host.ts b/src/platform-runtime-operation-host.ts index 088ed95845..6f4c7d04c1 100644 --- a/src/platform-runtime-operation-host.ts +++ b/src/platform-runtime-operation-host.ts @@ -9,7 +9,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { setTimeout as sleep } from 'node:timers/promises'; import { createAppleToolHost } from './platform-runtime-apple-tool-host.ts'; import { createHostToolchainPreparer } from './platform-runtime-toolchain-host.ts'; -import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; +import { runCmd, whichCmd } from '@agent-device/host-kit/command'; import { openAppLogOutput, readAppLogOutputTail } from './platform-runtime-app-log-output.ts'; import { createManagedAppLogProcesses } from './platform-runtime-app-log-process.ts'; import { createNetworkRuntimeHost } from './platform-runtime-network-host.ts'; diff --git a/src/platform-runtime-resource-cleanup.ts b/src/platform-runtime-resource-cleanup.ts index 5b424ff5d1..fee44beaac 100644 --- a/src/platform-runtime-resource-cleanup.ts +++ b/src/platform-runtime-resource-cleanup.ts @@ -1,7 +1,8 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { isIosFamily } from '@agent-device/kernel/device'; import type { PlatformResourceCleanup } from '@agent-device/contracts/platform-resource-cleanup'; -import { emitDiagnostic, type OwnedProcessRecordStore } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { type OwnedProcessRecordStore } from '@agent-device/host-kit/process'; /** Focused durable-resource cleanup composed above daemon policy and concrete platforms. */ export async function resetAndroidSnapshotHelperRuntime(): Promise { diff --git a/src/platform-runtime-runtime-hints.ts b/src/platform-runtime-runtime-hints.ts index 5bde522d02..04954f2dbd 100644 --- a/src/platform-runtime-runtime-hints.ts +++ b/src/platform-runtime-runtime-hints.ts @@ -2,7 +2,7 @@ import { isIosFamily, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError, asAppError } from '@agent-device/kernel/errors'; import { escapeXmlTextAndAttribute } from '@agent-device/xml'; import type { RuntimeHintValues } from '@agent-device/contracts/application-lifecycle-runtime'; -import { execFailureDetails, type ExecResult } from '@agent-device/host-kit/exec'; +import { execFailureDetails, type ExecResult } from '@agent-device/host-kit/command'; import { type ResolvedRuntimeTransport } from './utils/runtime-transport.ts'; // React Native's PackagerConnectionSettings/DevInternalSettings read debug_http_host via diff --git a/src/platform-runtime-screen-recording-android-host.ts b/src/platform-runtime-screen-recording-android-host.ts index 301088dd5a..a7370f64f2 100644 --- a/src/platform-runtime-screen-recording-android-host.ts +++ b/src/platform-runtime-screen-recording-android-host.ts @@ -4,7 +4,7 @@ import type { AndroidScreenRecordingTransport, } from '@agent-device/contracts/screen-recording-runtime-host'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { shellQuote } from '@agent-device/host-kit/exec'; +import { shellQuote } from '@agent-device/host-kit/command'; import { isPlayableVideo } from './utils/video.ts'; const ANDROID_MANIFEST_NAME = 'agent-device-recording-active.json'; diff --git a/src/platform-runtime-screen-recording-apple-runner-transport.ts b/src/platform-runtime-screen-recording-apple-runner-transport.ts index fadb4e26ef..22cfe768da 100644 --- a/src/platform-runtime-screen-recording-apple-runner-transport.ts +++ b/src/platform-runtime-screen-recording-apple-runner-transport.ts @@ -1,8 +1,8 @@ import path from 'node:path'; import type { ManagedProcessOwnership } from '@agent-device/contracts/platform-runtime-host'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { createScopedProvider } from '@agent-device/host-kit/values'; -import { isProcessAlive } from '@agent-device/host-kit/exec'; +import { createScopedProvider } from '@agent-device/kernel/scoped-provider'; +import { isProcessAlive } from '@agent-device/host-kit/process'; type AppleRunnerScreenRecordingStartRequest = Readonly<{ device: DeviceInfo; diff --git a/src/platform-runtime-screen-recording-apple-simulator-host.test.ts b/src/platform-runtime-screen-recording-apple-simulator-host.test.ts index 647e62dd25..ac23f76565 100644 --- a/src/platform-runtime-screen-recording-apple-simulator-host.test.ts +++ b/src/platform-runtime-screen-recording-apple-simulator-host.test.ts @@ -12,8 +12,8 @@ const processes = vi.hoisted(() => ({ commands: new Map(), })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/process', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: (pid: number) => processes.alive.get(pid) ?? false, isProcessZombie: () => false, readProcessStartTime: (pid: number) => processes.starts.get(pid) ?? null, diff --git a/src/platform-runtime-screen-recording-apple-transport.ts b/src/platform-runtime-screen-recording-apple-transport.ts index 35e3b88fcd..4ef8f91c32 100644 --- a/src/platform-runtime-screen-recording-apple-transport.ts +++ b/src/platform-runtime-screen-recording-apple-transport.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; -import type { ExecBackgroundResult, ExecResult } from '@agent-device/host-kit/exec'; -import { createScopedProvider } from '@agent-device/host-kit/values'; +import { type ExecBackgroundResult, type ExecResult } from '@agent-device/host-kit/command'; +import { createScopedProvider } from '@agent-device/kernel/scoped-provider'; export type AppleSimulatorScreenRecordingProcess = Readonly<{ child: Pick; @@ -27,7 +27,7 @@ const localTransport: AppleSimulatorScreenRecordingTransport = Object.freeze({ async start({ device, outputPath, signal }) { const [{ buildSimctlArgsForDevice }, { runCmdBackground }] = await Promise.all([ import('./platforms/apple/core/simctl.ts'), - import('@agent-device/host-kit/exec'), + import('@agent-device/host-kit/command'), ]); signal?.throwIfAborted(); return runCmdBackground( diff --git a/src/platform-runtime-screen-recording-process-host.test.ts b/src/platform-runtime-screen-recording-process-host.test.ts index 28b39282b0..9174cf4b51 100644 --- a/src/platform-runtime-screen-recording-process-host.test.ts +++ b/src/platform-runtime-screen-recording-process-host.test.ts @@ -11,8 +11,8 @@ const state = vi.hoisted(() => ({ signaled: [] as Array<{ pids: readonly number[]; signal: NodeJS.Signals }>, })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/process', async (importOriginal) => ({ + ...(await importOriginal()), isProcessAlive: (pid: number) => state.alive.get(pid) ?? false, isProcessZombie: () => false, readProcessStartTime: (pid: number) => state.starts.get(pid) ?? null, diff --git a/src/platform-runtime-screen-recording-process-host.ts b/src/platform-runtime-screen-recording-process-host.ts index 265c8ac520..41ec9f6f81 100644 --- a/src/platform-runtime-screen-recording-process-host.ts +++ b/src/platform-runtime-screen-recording-process-host.ts @@ -12,7 +12,7 @@ import { readProcessStartTime, signalPidsBestEffort, waitForProcessExit, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; const STOP_TIMEOUT_MS = 5_000; const FORCE_STOP_TIMEOUT_MS = 2_000; diff --git a/src/platform-runtime/request-providers.ts b/src/platform-runtime/request-providers.ts index 27370725fd..ba9fbc306b 100644 --- a/src/platform-runtime/request-providers.ts +++ b/src/platform-runtime/request-providers.ts @@ -16,7 +16,7 @@ import type { VegaToolProvider } from '../platforms/vega/tool-provider.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { AppleSimulatorScreenRecordingTransport } from '../platform-runtime-screen-recording-apple-transport.ts'; import type { AppleRunnerScreenRecordingTransport } from '../platform-runtime-screen-recording-apple-runner-transport.ts'; -import type { OwnedProcessRecordStore } from '@agent-device/host-kit/exec'; +import { type OwnedProcessRecordStore } from '@agent-device/host-kit/process'; import { tryGetPlugin } from '../core/platform-plugin-registry.ts'; import { registerBuiltinPlatformPlugins } from '../core/interactors/register-builtins.ts'; diff --git a/src/platforms/__tests__/install-source.test.ts b/src/platforms/__tests__/install-source.test.ts index bfcf0684a3..2ed07aad6c 100644 --- a/src/platforms/__tests__/install-source.test.ts +++ b/src/platforms/__tests__/install-source.test.ts @@ -6,7 +6,7 @@ import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { Readable } from 'node:stream'; -import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { runCmdSync, withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { ARCHIVE_EXTENSIONS, isTrustedInstallSourceUrl, diff --git a/src/platforms/android/__tests__/adb-executor.test.ts b/src/platforms/android/__tests__/adb-executor.test.ts index c3ea20ef07..9322ef7671 100644 --- a/src/platforms/android/__tests__/adb-executor.test.ts +++ b/src/platforms/android/__tests__/adb-executor.test.ts @@ -8,8 +8,8 @@ const { runCmdBackgroundMock } = vi.hoisted(() => ({ })), })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(async () => ({ stdout: 'ok', stderr: '', exitCode: 0 })), @@ -32,7 +32,7 @@ import { withAndroidAdbProvider, type AndroidAdbProvider, } from '../adb-executor.ts'; -import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/command'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/android/__tests__/adb-provider-scope.test.ts b/src/platforms/android/__tests__/adb-provider-scope.test.ts index ad619d25cf..9b81110997 100644 --- a/src/platforms/android/__tests__/adb-provider-scope.test.ts +++ b/src/platforms/android/__tests__/adb-provider-scope.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 { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { withAndroidAdbProvider } from '../adb-executor.ts'; import { mkdtempForTestSync } from '../../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/platforms/android/__tests__/device-input-state.test.ts b/src/platforms/android/__tests__/device-input-state.test.ts index 42fa3f8191..eabb3fae25 100644 --- a/src/platforms/android/__tests__/device-input-state.test.ts +++ b/src/platforms/android/__tests__/device-input-state.test.ts @@ -10,7 +10,10 @@ import { readAndroidClipboardWithAdb, writeAndroidClipboardWithAdb, } from '../device-input-state.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + flushDiagnosticsToSessionFile, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { assertRejectsAppError } from '../../../__tests__/test-utils/app-error.ts'; import { withFakeAdb } from '../../../__tests__/test-utils/fake-adb.ts'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; diff --git a/src/platforms/android/__tests__/emulator-lifecycle.test.ts b/src/platforms/android/__tests__/emulator-lifecycle.test.ts index 156e253761..59bf6272f4 100644 --- a/src/platforms/android/__tests__/emulator-lifecycle.test.ts +++ b/src/platforms/android/__tests__/emulator-lifecycle.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import { beforeEach, test, vi } from 'vitest'; import type { DeviceInfo } from '@agent-device/kernel/device'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), @@ -13,7 +13,7 @@ vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { }); vi.mock('../sdk.ts', () => ({ ensureAndroidSdkPathConfigured: vi.fn(async () => {}) })); -import { runCmd, runCmdDetached, whichCmd } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdDetached, whichCmd } from '@agent-device/host-kit/command'; import { ensureAndroidEmulatorBooted } from '../emulator-lifecycle.ts'; const stopped: DeviceInfo = { diff --git a/src/platforms/android/__tests__/ime-helper-security.test.ts b/src/platforms/android/__tests__/ime-helper-security.test.ts index 94986f1cc9..dab148ce99 100644 --- a/src/platforms/android/__tests__/ime-helper-security.test.ts +++ b/src/platforms/android/__tests__/ime-helper-security.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import path from 'node:path'; import { test } from 'vitest'; -import { findProjectRoot } from '@agent-device/host-kit/values'; +import { findProjectRoot } from '@agent-device/host-kit/version'; // Security guard for #1201: the text-injection broadcast receiver must require a sender permission // that only adb shell / privileged callers hold, so a co-installed third-party app cannot inject diff --git a/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts b/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts index 8eb91cd8aa..3b2e3197d1 100644 --- a/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts +++ b/src/platforms/android/__tests__/snapshot-capture-failure-reason.test.ts @@ -24,8 +24,8 @@ import { isAndroidSnapshotTimeoutError } from '../../../snapshot/snapshot-timeou * value it publishes. Split out of `snapshot.test.ts`, which is over the file-size tripwire. */ -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => ({ - ...(await importOriginal()), +vi.mock('@agent-device/host-kit/command', async (importOriginal) => ({ + ...(await importOriginal()), runCmd: vi.fn(), })); diff --git a/src/platforms/android/__tests__/snapshot-clickability.test.ts b/src/platforms/android/__tests__/snapshot-clickability.test.ts index 598497a69e..ae090c659f 100644 --- a/src/platforms/android/__tests__/snapshot-clickability.test.ts +++ b/src/platforms/android/__tests__/snapshot-clickability.test.ts @@ -15,8 +15,8 @@ import { resetAndroidSnapshotHelperInstallCache } from '../snapshot-helper-insta import { resetAndroidSnapshotHelperSessions } from '../snapshot-helper-session-lifecycle.ts'; import { androidSnapshotPublicationInput } from '../snapshot-capture.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../adb.ts', async (importOriginal) => { diff --git a/src/platforms/android/__tests__/snapshot-helper-session.test.ts b/src/platforms/android/__tests__/snapshot-helper-session.test.ts index 39ea7a456a..4250d3cc5c 100644 --- a/src/platforms/android/__tests__/snapshot-helper-session.test.ts +++ b/src/platforms/android/__tests__/snapshot-helper-session.test.ts @@ -10,7 +10,7 @@ import { import path from 'node:path'; import { promises as fs } from 'node:fs'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; -import { withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { withDiagnosticsScope } from '@agent-device/host-kit/diagnostics'; beforeEach(async () => { await resetAndroidSnapshotHelperSessions(); diff --git a/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts b/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts index 89e0cc5d20..276956a84e 100644 --- a/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts +++ b/src/platforms/android/__tests__/snapshot-occlusion-context.test.ts @@ -16,8 +16,8 @@ import { isAndroidHelperRuntimeForceStop, } from './snapshot-helper-session.fixtures.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../adb.ts', async (importOriginal) => { diff --git a/src/platforms/android/__tests__/snapshot.test.ts b/src/platforms/android/__tests__/snapshot.test.ts index 07c41243a7..70a108ce59 100644 --- a/src/platforms/android/__tests__/snapshot.test.ts +++ b/src/platforms/android/__tests__/snapshot.test.ts @@ -5,8 +5,8 @@ import os from 'node:os'; import path from 'node:path'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); vi.mock('../adb.ts', async (importOriginal) => { @@ -19,9 +19,9 @@ import { snapshotAndroid } from '../snapshot.ts'; import { readAndroidGestureViewport } from '../touch-executor.ts'; import { buildUiHierarchySnapshot, parseUiHierarchyTree } from '../ui-hierarchy.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import * as diagnosticsModule from '@agent-device/host-kit/exec'; +import * as diagnosticsModule from '@agent-device/host-kit/diagnostics'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { sleep } from '../adb.ts'; import { resetAndroidSnapshotHelperInstallCache } from '../snapshot-helper-install.ts'; import { resetAndroidSnapshotHelperSessions } from '../snapshot-helper-session-lifecycle.ts'; diff --git a/src/platforms/android/__tests__/text-input-test-ime.test.ts b/src/platforms/android/__tests__/text-input-test-ime.test.ts index b0ae70551f..e461281985 100644 --- a/src/platforms/android/__tests__/text-input-test-ime.test.ts +++ b/src/platforms/android/__tests__/text-input-test-ime.test.ts @@ -32,7 +32,10 @@ vi.mock('@agent-device/platform-android/ime-helper', async (importOriginal) => { import fs from 'node:fs/promises'; import { ANDROID_EMULATOR } from '../../../__tests__/test-utils/device-fixtures.ts'; import { mkdtempForTest } from '../../../__tests__/test-utils/tmp-dir.ts'; -import { flushDiagnosticsToSessionFile, withDiagnosticsScope } from '@agent-device/host-kit/exec'; +import { + flushDiagnosticsToSessionFile, + withDiagnosticsScope, +} from '@agent-device/host-kit/diagnostics'; import { ANDROID_SNAPSHOT_HELPER_FIXTURE_ARTIFACT, createAndroidSnapshotHelperExecutor, diff --git a/src/platforms/android/adb-host-binding.ts b/src/platforms/android/adb-host-binding.ts index 019a992498..ea1cdb97b6 100644 --- a/src/platforms/android/adb-host-binding.ts +++ b/src/platforms/android/adb-host-binding.ts @@ -6,8 +6,8 @@ import { runCmdBackground, withCommandExecutorOverride, withoutCommandExecutorOverride, - emitDiagnostic, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { clearAndroidTestImeRecoveryMarker, diff --git a/src/platforms/android/adb.ts b/src/platforms/android/adb.ts index 272273c3c6..6d00630bb2 100644 --- a/src/platforms/android/adb.ts +++ b/src/platforms/android/adb.ts @@ -5,7 +5,7 @@ import { type AndroidAdbExecutorResult, } from './adb-executor.ts'; -export { sleep } from '@agent-device/host-kit/exec'; +export { sleep } from '@agent-device/host-kit/retry'; export async function runAndroidAdb( device: DeviceInfo, diff --git a/src/platforms/android/alert.ts b/src/platforms/android/alert.ts index cba84ceb3b..9c406ea12e 100644 --- a/src/platforms/android/alert.ts +++ b/src/platforms/android/alert.ts @@ -5,8 +5,9 @@ import { DEFAULT_ALERT_TIMEOUT_MS, } from '@agent-device/contracts/alert-contract'; import { AppError } from '@agent-device/kernel/errors'; -import { withDiagnosticTimer, sleep } from '@agent-device/host-kit/exec'; -import { successText } from '@agent-device/host-kit/values'; +import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; +import { sleep } from '@agent-device/host-kit/retry'; +import { successText } from '@agent-device/kernel/success-text'; import type { DeviceInfo } from '@agent-device/kernel/device'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; diff --git a/src/platforms/android/app-deployment.ts b/src/platforms/android/app-deployment.ts index 01c342d30f..34ce75139e 100644 --- a/src/platforms/android/app-deployment.ts +++ b/src/platforms/android/app-deployment.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { resolveFileOverridePath, runCmd, whichCmd } from '@agent-device/host-kit/exec'; +import { resolveFileOverridePath, runCmd, whichCmd } from '@agent-device/host-kit/command'; import { waitForAndroidBoot } from './emulator-lifecycle.ts'; import { installAndroidAdbPackage, resolveAndroidAdbProvider } from './adb-executor.ts'; import { withAndroidAppResolutionCacheInvalidated } from './app-deployment-resolution.ts'; diff --git a/src/platforms/android/app-lifecycle.ts b/src/platforms/android/app-lifecycle.ts index 6e32045bc8..cdf0694b37 100644 --- a/src/platforms/android/app-lifecycle.ts +++ b/src/platforms/android/app-lifecycle.ts @@ -1,6 +1,7 @@ import { AppError } from '@agent-device/kernel/errors'; import type { AppStateRuntimeResult } from '@agent-device/contracts/app-state-runtime'; -import { sleep, shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; +import { sleep } from '@agent-device/host-kit/retry'; import type { AppsFilter } from '@agent-device/contracts/device'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { isDeepLinkTarget } from '@agent-device/contracts/command'; diff --git a/src/platforms/android/device-input-state.ts b/src/platforms/android/device-input-state.ts index 09551fae5a..722b01ba10 100644 --- a/src/platforms/android/device-input-state.ts +++ b/src/platforms/android/device-input-state.ts @@ -1,4 +1,5 @@ -import { emitDiagnostic, shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/platforms/android/emulator-lifecycle.ts b/src/platforms/android/emulator-lifecycle.ts index d848cc4287..cb31c71a9d 100644 --- a/src/platforms/android/emulator-lifecycle.ts +++ b/src/platforms/android/emulator-lifecycle.ts @@ -1,14 +1,8 @@ import type { DeviceInventoryRequest } from '@agent-device/contracts/device'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError, asAppError } from '@agent-device/kernel/errors'; -import { - type ExecResult, - runCmdDetached, - whichCmd, - Deadline, - retryWithPolicy, - sleep, -} from '@agent-device/host-kit/exec'; +import { type ExecResult, runCmdDetached, whichCmd } from '@agent-device/host-kit/command'; +import { Deadline, retryWithPolicy, sleep } from '@agent-device/host-kit/retry'; import { runAndroidHostAdb } from './adb-executor.ts'; diff --git a/src/platforms/android/fill-verification.ts b/src/platforms/android/fill-verification.ts index 7267f22d9d..145eef7b55 100644 --- a/src/platforms/android/fill-verification.ts +++ b/src/platforms/android/fill-verification.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { containsPoint } from '@agent-device/kernel/rect'; import { buildFillFailureDetails, diff --git a/src/platforms/android/helper-package-install.ts b/src/platforms/android/helper-package-install.ts index 3c82b06aec..4a5a06c416 100644 --- a/src/platforms/android/helper-package-install.ts +++ b/src/platforms/android/helper-package-install.ts @@ -3,7 +3,7 @@ import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; -import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/version'; // The package subpath (not the root shim) breaks the module cycle the shim route would create: // the adb-host binding reaches this file for the helper port facets, and the shim imports that // binding. Allowed by the transitional #2041 R13 table. diff --git a/src/platforms/android/ime-recovery-marker.ts b/src/platforms/android/ime-recovery-marker.ts index b021bb578d..b645300aec 100644 --- a/src/platforms/android/ime-recovery-marker.ts +++ b/src/platforms/android/ime-recovery-marker.ts @@ -2,7 +2,7 @@ import fs from 'node:fs/promises'; import { randomUUID } from 'node:crypto'; import path from 'node:path'; import { normalizeError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; // Device-scoped pending-recovery markers, one file per switched device, in the daemon state dir. // The marker is separate from IME mechanics so startup can establish evidence before it loads the diff --git a/src/platforms/android/manifest.ts b/src/platforms/android/manifest.ts index f040a92355..3587723b78 100644 --- a/src/platforms/android/manifest.ts +++ b/src/platforms/android/manifest.ts @@ -1,7 +1,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import { TextDecoder } from 'node:util'; -import { isExecutablePath, runCmd } from '@agent-device/host-kit/exec'; +import { isExecutablePath, runCmd } from '@agent-device/host-kit/command'; import { resolveAndroidSdkRoots } from './sdk.ts'; const RES_XML_TYPE = 0x0003; diff --git a/src/platforms/android/perf-native-artifacts.ts b/src/platforms/android/perf-native-artifacts.ts index c9eb89d7fe..b019350469 100644 --- a/src/platforms/android/perf-native-artifacts.ts +++ b/src/platforms/android/perf-native-artifacts.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import { resolveAndroidAdbExecutor, type AndroidAdbExecutor } from './adb-executor.ts'; import { annotateAndroidNativePerfError } from './perf-native-errors.ts'; import { buildAndroidNativePerfStopSummary } from './perf-native-summary.ts'; diff --git a/src/platforms/android/perf-native-report.ts b/src/platforms/android/perf-native-report.ts index 476378819f..580f0a5431 100644 --- a/src/platforms/android/perf-native-report.ts +++ b/src/platforms/android/perf-native-report.ts @@ -1,4 +1,4 @@ -import { splitNonEmptyTrimmedLines } from '@agent-device/host-kit/values'; +import { splitNonEmptyTrimmedLines } from '@agent-device/kernel/record'; import { roundPercent } from '../perf-utils.ts'; const SIMPLEPERF_REPORT_ARTIFACT_ENTRY_LIMIT = 50; diff --git a/src/platforms/android/perf.ts b/src/platforms/android/perf.ts index 2d008833bf..4e4c06f038 100644 --- a/src/platforms/android/perf.ts +++ b/src/platforms/android/perf.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { requireExecSuccess } from '@agent-device/host-kit/exec'; +import { requireExecSuccess } from '@agent-device/host-kit/command'; import { androidAdbResultError, resolveAndroidAdbExecutor, diff --git a/src/platforms/android/settings.ts b/src/platforms/android/settings.ts index 803565a155..e62e63e9b1 100644 --- a/src/platforms/android/settings.ts +++ b/src/platforms/android/settings.ts @@ -1,6 +1,6 @@ import { AppError } from '@agent-device/kernel/errors'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { requireLocationCoordinates } from '@agent-device/host-kit/values'; +import { requireLocationCoordinates } from '@agent-device/kernel/location-coordinates'; import { summarizeCommandAttemptFailures, type CommandAttemptFailure, diff --git a/src/platforms/android/snapshot-helper-capture.ts b/src/platforms/android/snapshot-helper-capture.ts index 6a8464082d..f92fdc7e21 100644 --- a/src/platforms/android/snapshot-helper-capture.ts +++ b/src/platforms/android/snapshot-helper-capture.ts @@ -4,7 +4,7 @@ import { androidCaptureFailureReasonFromExitCode, androidCaptureFailureReasonFromHelperResult, } from './snapshot-capture-failure-reason.ts'; -import { execFailureDetails } from '@agent-device/host-kit/exec'; +import { execFailureDetails } from '@agent-device/host-kit/command'; import { parseInstrumentationRecords, readInstrumentationResultBoolean, diff --git a/src/platforms/android/snapshot-helper-runtime.ts b/src/platforms/android/snapshot-helper-runtime.ts index 58127637c7..e34e47f506 100644 --- a/src/platforms/android/snapshot-helper-runtime.ts +++ b/src/platforms/android/snapshot-helper-runtime.ts @@ -1,5 +1,5 @@ import { normalizeError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { sleep } from './adb.ts'; import type { AndroidAdbExecutor } from './adb-executor.ts'; import { stopAndroidSnapshotHelperSession } from './snapshot-helper-session-lifecycle.ts'; diff --git a/src/platforms/android/snapshot-helper-session-lifecycle.ts b/src/platforms/android/snapshot-helper-session-lifecycle.ts index 5bd48edd0b..a9f2d7b1e1 100644 --- a/src/platforms/android/snapshot-helper-session-lifecycle.ts +++ b/src/platforms/android/snapshot-helper-session-lifecycle.ts @@ -9,7 +9,7 @@ import type { AndroidAdbProcess } from './adb-executor.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { androidAdbForwardsDeviceExitStatus, resetAndroidAdbShellProtocolProbes, diff --git a/src/platforms/android/snapshot-helper-session.ts b/src/platforms/android/snapshot-helper-session.ts index 960277f722..4014835d5d 100644 --- a/src/platforms/android/snapshot-helper-session.ts +++ b/src/platforms/android/snapshot-helper-session.ts @@ -4,7 +4,7 @@ * `snapshot-helper-session-lifecycle.ts`, which this module acquires through. */ import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { readAndroidCaptureFailureReason } from '@agent-device/contracts/android-snapshot-quality'; import type { AndroidSnapshotHelperCaptureOptions, diff --git a/src/platforms/android/snapshot.ts b/src/platforms/android/snapshot.ts index 2b2e99610e..37c84c6eb8 100644 --- a/src/platforms/android/snapshot.ts +++ b/src/platforms/android/snapshot.ts @@ -6,9 +6,9 @@ import { toAppErrorCode, type NormalizedError, } from '@agent-device/kernel/errors'; -import { emitDiagnostic, withDiagnosticTimer } from '@agent-device/host-kit/exec'; +import { emitDiagnostic, withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/version'; import { attachRefs, type HiddenContentHint, diff --git a/src/platforms/android/text-input.ts b/src/platforms/android/text-input.ts index 11a3e115c9..3502f4f976 100644 --- a/src/platforms/android/text-input.ts +++ b/src/platforms/android/text-input.ts @@ -7,7 +7,8 @@ import type { FillUnconfirmedVerification } from '@agent-device/contracts/interactor-types'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic, shellQuoteIfNeeded } from '@agent-device/host-kit/exec'; +import { shellQuoteIfNeeded } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { resolveAndroidAdbExecutor, diff --git a/src/platforms/android/touch-helper.ts b/src/platforms/android/touch-helper.ts index 8cb7e1695c..89052de745 100644 --- a/src/platforms/android/touch-helper.ts +++ b/src/platforms/android/touch-helper.ts @@ -2,11 +2,8 @@ import type { PointerTrajectory } from '@agent-device/contracts/gesture-plan-typ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { Rect } from '@agent-device/kernel/snapshot'; import { AppError } from '@agent-device/kernel/errors'; -import { - execFailureDetails, - emitDiagnostic, - withDiagnosticTimer, -} from '@agent-device/host-kit/exec'; +import { execFailureDetails } from '@agent-device/host-kit/command'; +import { emitDiagnostic, withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import { resolveAndroidAdbProvider, diff --git a/src/platforms/apple/alert.ts b/src/platforms/apple/alert.ts index e8a9bbc26c..d72a4399ca 100644 --- a/src/platforms/apple/alert.ts +++ b/src/platforms/apple/alert.ts @@ -11,7 +11,7 @@ import type { } from '@agent-device/contracts/interactor-types'; import { isIosFamily, isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import { runAppleRunnerCommand } from './core/runner-client.ts'; import { runMacOsAlertAction } from './os/macos/helper.ts'; diff --git a/src/platforms/apple/core/__tests__/app-launch-url.test.ts b/src/platforms/apple/core/__tests__/app-launch-url.test.ts index 3f58a07838..7d560f9db6 100644 --- a/src/platforms/apple/core/__tests__/app-launch-url.test.ts +++ b/src/platforms/apple/core/__tests__/app-launch-url.test.ts @@ -3,8 +3,8 @@ import assert from 'node:assert/strict'; import { IOS_TEST_SIMULATOR } from './apple-core-stub-helpers.ts'; import { IOS_SIMULATOR_TERMINATE_TIMEOUT_MS } from '../config.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd) }; }); vi.mock('../simulator.ts', async (importOriginal) => { @@ -12,7 +12,7 @@ vi.mock('../simulator.ts', async (importOriginal) => { return { ...actual, ensureBootedSimulator: vi.fn(actual.ensureBootedSimulator) }; }); -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { ensureBootedSimulator } from '../simulator.ts'; import { openIosApp } from '../app-launch.ts'; diff --git a/src/platforms/apple/core/__tests__/apps.test.ts b/src/platforms/apple/core/__tests__/apps.test.ts index 10c2cbd371..5d9b531947 100644 --- a/src/platforms/apple/core/__tests__/apps.test.ts +++ b/src/platforms/apple/core/__tests__/apps.test.ts @@ -4,24 +4,24 @@ import { promises as fs, readFileSync, writeFileSync } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - runCmd: vi.fn(actual.runCmd), - retryWithPolicy: vi.fn(actual.retryWithPolicy), - }; +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); + return { ...actual, runCmd: vi.fn(actual.runCmd) }; +}); +vi.mock('@agent-device/host-kit/retry', async (importOriginal) => { + const actual = await importOriginal(); + return { ...actual, retryWithPolicy: vi.fn(actual.retryWithPolicy) }; }); vi.mock('../simulator.ts', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, ensureBootedSimulator: vi.fn(actual.ensureBootedSimulator) }; }); -const execActual = await vi.importActual( - '@agent-device/host-kit/exec', +const execActual = await vi.importActual( + '@agent-device/host-kit/command', ); -const retryActual = await vi.importActual( - '@agent-device/host-kit/exec', +const retryActual = await vi.importActual( + '@agent-device/host-kit/retry', ); const simulatorActual = await vi.importActual('../simulator.ts'); @@ -42,8 +42,8 @@ import { ensureBootedSimulator } from '../simulator.ts'; import { IOS_DEVICE_INSTALL_TIMEOUT_MS, IOS_SIMULATOR_TERMINATE_TIMEOUT_MS } from '../config.ts'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd, retryWithPolicy } from '@agent-device/host-kit/exec'; - +import { runCmd } from '@agent-device/host-kit/command'; +import { retryWithPolicy } from '@agent-device/host-kit/retry'; import { PNG } from '@agent-device/capture-kit/png'; import { assertRejectsAppError } from '../../../../__tests__/test-utils/app-error.ts'; import { diff --git a/src/platforms/apple/core/__tests__/debug-symbols.test.ts b/src/platforms/apple/core/__tests__/debug-symbols.test.ts index 33c153cd77..19f7ec6821 100644 --- a/src/platforms/apple/core/__tests__/debug-symbols.test.ts +++ b/src/platforms/apple/core/__tests__/debug-symbols.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import { test } from 'vitest'; import { symbolicateCrashArtifact } from '../debug-symbols.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; const UUID = 'ABCDEFAB-CDEF-ABCD-EFAB-CDEFABCDEFAB'; diff --git a/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts b/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts index 58b2f71933..93577bd1a6 100644 --- a/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts +++ b/src/platforms/apple/core/__tests__/install-artifact.fixtures.ts @@ -1,6 +1,6 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; export async function createZipFixture( archivePath: string, diff --git a/src/platforms/apple/core/__tests__/perf.test.ts b/src/platforms/apple/core/__tests__/perf.test.ts index b0ed3dc6e3..939040f4ce 100644 --- a/src/platforms/apple/core/__tests__/perf.test.ts +++ b/src/platforms/apple/core/__tests__/perf.test.ts @@ -4,8 +4,8 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd), @@ -27,7 +27,7 @@ import { type AppleXctracePerfCapture, } from '../perf-xctrace.ts'; import { parseAppleFramePerfSample } from '../perf-frame.ts'; -import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/command'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/platforms/apple/core/__tests__/plist.test.ts b/src/platforms/apple/core/__tests__/plist.test.ts index df9bfee358..a31dd608d0 100644 --- a/src/platforms/apple/core/__tests__/plist.test.ts +++ b/src/platforms/apple/core/__tests__/plist.test.ts @@ -4,12 +4,12 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd) }; }); -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { readInfoPlistString } from '../plist.ts'; import { createLocalAppleToolProvider, withAppleToolProvider } from '../tool-provider.ts'; diff --git a/src/platforms/apple/core/__tests__/screenshot.test.ts b/src/platforms/apple/core/__tests__/screenshot.test.ts index fd2d38f9d6..1110e0c622 100644 --- a/src/platforms/apple/core/__tests__/screenshot.test.ts +++ b/src/platforms/apple/core/__tests__/screenshot.test.ts @@ -4,13 +4,13 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { mkdtempForTest } from '../../../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - runCmd: vi.fn(actual.runCmd), - retryWithPolicy: vi.fn(actual.retryWithPolicy), - }; +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); + return { ...actual, runCmd: vi.fn(actual.runCmd) }; +}); +vi.mock('@agent-device/host-kit/retry', async (importOriginal) => { + const actual = await importOriginal(); + return { ...actual, retryWithPolicy: vi.fn(actual.retryWithPolicy) }; }); vi.mock('../runner-client.ts', async (importOriginal) => { const actual = await importOriginal(); @@ -32,11 +32,11 @@ vi.mock('../screenshot-status-bar.ts', async (importOriginal) => { }; }); -const execActual = await vi.importActual( - '@agent-device/host-kit/exec', +const execActual = await vi.importActual( + '@agent-device/host-kit/command', ); -const retryActual = await vi.importActual( - '@agent-device/host-kit/exec', +const retryActual = await vi.importActual( + '@agent-device/host-kit/retry', ); const runnerActual = await vi.importActual('../runner-client.ts'); @@ -55,7 +55,9 @@ import { import { ensureBootedSimulator, openIosSimulatorApp } from '../simulator.ts'; import { prepareSimulatorStatusBarForScreenshot } from '../screenshot-status-bar.ts'; import { runAppleRunnerCommand } from '../runner-client.ts'; -import { withDiagnosticsScope, runCmd, retryWithPolicy } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; +import { withDiagnosticsScope } from '@agent-device/host-kit/diagnostics'; +import { retryWithPolicy } from '@agent-device/host-kit/retry'; import { AppError } from '@agent-device/kernel/errors'; import { IOS_TEST_SIMULATOR, MACOS_TEST_DEVICE } from './apple-core-stub-helpers.ts'; diff --git a/src/platforms/apple/core/__tests__/simulator.test.ts b/src/platforms/apple/core/__tests__/simulator.test.ts index 596e90f9bf..91315c81ae 100644 --- a/src/platforms/apple/core/__tests__/simulator.test.ts +++ b/src/platforms/apple/core/__tests__/simulator.test.ts @@ -3,16 +3,16 @@ import assert from 'node:assert/strict'; import { ensureBootedSimulator, openIosSimulatorApp } from '../simulator.ts'; import { IOS_SIMULATOR_FOCUS_TIMEOUT_MS } from '../config.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { IOS_TEST_SIMULATOR } from './apple-core-stub-helpers.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(actual.runCmd) }; }); -const execActual = await vi.importActual( - '@agent-device/host-kit/exec', +const execActual = await vi.importActual( + '@agent-device/host-kit/command', ); const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/apple/core/app-device-io.ts b/src/platforms/apple/core/app-device-io.ts index e3c6283b5e..912a53a6d3 100644 --- a/src/platforms/apple/core/app-device-io.ts +++ b/src/platforms/apple/core/app-device-io.ts @@ -2,7 +2,7 @@ import { promises as fs } from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; -import { requireExecSuccess } from '@agent-device/host-kit/exec'; +import { requireExecSuccess } from '@agent-device/host-kit/command'; import { ensureBootedSimulator, requireSimulatorDevice } from './simulator.ts'; import { readMacOsClipboardText, writeMacOsClipboardText } from '../os/macos/apps.ts'; import { runSimctl } from './apps-simctl.ts'; diff --git a/src/platforms/apple/core/app-launch.ts b/src/platforms/apple/core/app-launch.ts index 9708aeefdc..da5d8f6838 100644 --- a/src/platforms/apple/core/app-launch.ts +++ b/src/platforms/apple/core/app-launch.ts @@ -2,12 +2,9 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { isIosFamily, isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { - emitDiagnostic, - execFailureDetails, - Deadline, - retryWithPolicy, -} from '@agent-device/host-kit/exec'; +import { execFailureDetails } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { Deadline, retryWithPolicy } from '@agent-device/host-kit/retry'; import { LAUNCH_CONSOLE_DIRECT_APP_ONLY_MESSAGE, diff --git a/src/platforms/apple/core/app-resolution.ts b/src/platforms/apple/core/app-resolution.ts index 103fa1ea22..88f283eacf 100644 --- a/src/platforms/apple/core/app-resolution.ts +++ b/src/platforms/apple/core/app-resolution.ts @@ -14,7 +14,7 @@ import { listMacApps, resolveMacOsApp } from '../os/macos/apps.ts'; import { runAppleToolCommand } from './tool-provider.ts'; import { runSimctl } from './apps-simctl.ts'; import { resolveIosPhysicalDeviceControl } from './physical-device-control.ts'; -import { createTtlMemo } from '@agent-device/host-kit/values'; +import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; const ALIASES: Record = { settings: 'com.apple.Preferences', diff --git a/src/platforms/apple/core/app-settings.ts b/src/platforms/apple/core/app-settings.ts index 232afd0db5..246c8ced70 100644 --- a/src/platforms/apple/core/app-settings.ts +++ b/src/platforms/apple/core/app-settings.ts @@ -8,9 +8,9 @@ import { isIosFamily, isMacOs, type DeviceInfo } from '@agent-device/kernel/devi import { AppError } from '@agent-device/kernel/errors'; import { promises as fs } from 'node:fs'; import path from 'node:path'; -import { resolveIosSimulatorDeviceSetPath } from '@agent-device/host-kit/fs'; -import { requireExecSuccess } from '@agent-device/host-kit/exec'; -import { requireLocationCoordinates } from '@agent-device/host-kit/values'; +import { resolveIosSimulatorDeviceSetPath } from '@agent-device/kernel/device-isolation'; +import { requireExecSuccess } from '@agent-device/host-kit/command'; +import { requireLocationCoordinates } from '@agent-device/kernel/location-coordinates'; import { parseAppearanceAction } from '../../appearance.ts'; import { summarizeCommandAttemptFailures, diff --git a/src/platforms/apple/core/debug-symbols/crash-artifact.ts b/src/platforms/apple/core/debug-symbols/crash-artifact.ts index 2d78d6133c..d897bddc44 100644 --- a/src/platforms/apple/core/debug-symbols/crash-artifact.ts +++ b/src/platforms/apple/core/debug-symbols/crash-artifact.ts @@ -1,5 +1,5 @@ import path from 'node:path'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import type { AppleImage, CrashArtifact, diff --git a/src/platforms/apple/core/debug-symbols/dsym.ts b/src/platforms/apple/core/debug-symbols/dsym.ts index dae648b66d..cbf835cb91 100644 --- a/src/platforms/apple/core/debug-symbols/dsym.ts +++ b/src/platforms/apple/core/debug-symbols/dsym.ts @@ -2,7 +2,7 @@ import fs from 'node:fs/promises'; import path from 'node:path'; import type { AppleImage, DsymMatch, DsymSlice } from './types.ts'; import { normalizeUuid, unique } from './utils.ts'; -import { requireExecSuccess, runCmd } from '@agent-device/host-kit/exec'; +import { requireExecSuccess, runCmd } from '@agent-device/host-kit/command'; import { AppError } from '@agent-device/kernel/errors'; const MAX_SEARCH_ENTRIES = 10_000; diff --git a/src/platforms/apple/core/debug-symbols/report.ts b/src/platforms/apple/core/debug-symbols/report.ts index 69c22aaef0..e4809d97c7 100644 --- a/src/platforms/apple/core/debug-symbols/report.ts +++ b/src/platforms/apple/core/debug-symbols/report.ts @@ -9,7 +9,7 @@ import type { DebugSymbolsCrashFrame, DebugSymbolsCrashSummary, } from '@agent-device/contracts/observability'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; import { addressKey, compactJoin, diff --git a/src/platforms/apple/core/debug-symbols/symbolication.ts b/src/platforms/apple/core/debug-symbols/symbolication.ts index e97eb9aa84..20c482fe05 100644 --- a/src/platforms/apple/core/debug-symbols/symbolication.ts +++ b/src/platforms/apple/core/debug-symbols/symbolication.ts @@ -1,6 +1,6 @@ import type { DsymMatch, SymbolicatedAddress, SymbolicationGroup } from './types.ts'; import { addressKey, hex, unique } from './utils.ts'; -import { requireExecSuccess, runCmd } from '@agent-device/host-kit/exec'; +import { requireExecSuccess, runCmd } from '@agent-device/host-kit/command'; import { AppError } from '@agent-device/kernel/errors'; export async function symbolicateAddresses( diff --git a/src/platforms/apple/core/debug-symbols/utils.ts b/src/platforms/apple/core/debug-symbols/utils.ts index 90aa18e289..1e3afb4886 100644 --- a/src/platforms/apple/core/debug-symbols/utils.ts +++ b/src/platforms/apple/core/debug-symbols/utils.ts @@ -1,5 +1,5 @@ import { AppError } from '@agent-device/kernel/errors'; -import { isRecord } from '@agent-device/host-kit/values'; +import { isRecord } from '@agent-device/kernel/record'; const UUID_RE = /^[0-9a-fA-F-]{32,36}$/; diff --git a/src/platforms/apple/core/devicectl.ts b/src/platforms/apple/core/devicectl.ts index 3beb31afaa..e0c80933eb 100644 --- a/src/platforms/apple/core/devicectl.ts +++ b/src/platforms/apple/core/devicectl.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails } from '@agent-device/host-kit/exec'; +import { execFailureDetails } from '@agent-device/host-kit/command'; import { IOS_DEVICECTL_TIMEOUT_MS } from './config.ts'; import { runXcrun } from './tool-provider.ts'; diff --git a/src/platforms/apple/core/install-artifact.ts b/src/platforms/apple/core/install-artifact.ts index 3c78f1057e..8380db8b46 100644 --- a/src/platforms/apple/core/install-artifact.ts +++ b/src/platforms/apple/core/install-artifact.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import type { LocalInstallSource } from '@agent-device/kernel/contracts'; import { readInfoPlistString } from './plist.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { extractArchiveSafely, ArchiveBudget } from '@agent-device/host-kit/fs'; +import { extractArchiveSafely, ArchiveBudget } from '@agent-device/host-kit/archive'; import { installArtifactArchiveBudget, diff --git a/src/platforms/apple/core/perf-xctrace.ts b/src/platforms/apple/core/perf-xctrace.ts index 1fac412d50..b1a4fe0037 100644 --- a/src/platforms/apple/core/perf-xctrace.ts +++ b/src/platforms/apple/core/perf-xctrace.ts @@ -17,7 +17,7 @@ import { runCmdBackground, type ExecBackgroundResult, type ExecResult, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/command'; import { uniqueStrings } from '@agent-device/kernel/collections'; import { findAllXmlNodes } from './perf-xml.ts'; import { diff --git a/src/platforms/apple/core/perf.ts b/src/platforms/apple/core/perf.ts index 56a045dd90..175de0d322 100644 --- a/src/platforms/apple/core/perf.ts +++ b/src/platforms/apple/core/perf.ts @@ -15,8 +15,8 @@ import { execFailureDetails, requireExecSuccess, type ExecResult, -} from '@agent-device/host-kit/exec'; -import { splitNonEmptyTrimmedLines } from '@agent-device/host-kit/values'; +} from '@agent-device/host-kit/command'; +import { splitNonEmptyTrimmedLines } from '@agent-device/kernel/record'; import { uniqueStrings } from '@agent-device/kernel/collections'; import { IOS_DEVICECTL_DEFAULT_HINT, resolveIosDevicectlHint } from './devicectl.ts'; import type { IosDeviceProcessInfo } from './app-info.ts'; diff --git a/src/platforms/apple/core/physical-device-control.ts b/src/platforms/apple/core/physical-device-control.ts index ecf59dc6e3..5cab541eaa 100644 --- a/src/platforms/apple/core/physical-device-control.ts +++ b/src/platforms/apple/core/physical-device-control.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails } from '@agent-device/host-kit/exec'; +import { execFailureDetails } from '@agent-device/host-kit/command'; import type { AppsFilter } from '@agent-device/contracts/device'; import type { IosAppInfo, IosDeviceAppProcesses } from './app-info.ts'; import { diff --git a/src/platforms/apple/core/physical-device-coredevice.ts b/src/platforms/apple/core/physical-device-coredevice.ts index 849051a5ec..0dfebfa587 100644 --- a/src/platforms/apple/core/physical-device-coredevice.ts +++ b/src/platforms/apple/core/physical-device-coredevice.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { execFailureDetails } from '@agent-device/host-kit/exec'; +import { execFailureDetails } from '@agent-device/host-kit/command'; import { IOS_DEVICECTL_DEFAULT_HINT, resolveIosDevicectlHint, diff --git a/src/platforms/apple/core/physical-device-files.ts b/src/platforms/apple/core/physical-device-files.ts index 1397ec2be4..2ccb3c49a9 100644 --- a/src/platforms/apple/core/physical-device-files.ts +++ b/src/platforms/apple/core/physical-device-files.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { Deadline } from '@agent-device/host-kit/exec'; +import { Deadline } from '@agent-device/host-kit/retry'; import { IOS_RUNNER_SCREENSHOT_COPY_TIMEOUT_MS } from './config.ts'; import { IOS_RUNNER_CONTAINER_BUNDLE_IDS } from '@agent-device/platform-apple/runner'; import { runXcrun } from './tool-provider.ts'; diff --git a/src/platforms/apple/core/physical-device-screenshot.ts b/src/platforms/apple/core/physical-device-screenshot.ts index 03bc5fd831..44f3d79b04 100644 --- a/src/platforms/apple/core/physical-device-screenshot.ts +++ b/src/platforms/apple/core/physical-device-screenshot.ts @@ -1,7 +1,7 @@ import { promises as fs } from 'node:fs'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { runIosDevicectl } from './devicectl.ts'; import { copyCoreDeviceRunnerFile } from './physical-device-files.ts'; import type { diff --git a/src/platforms/apple/core/runner-host.ts b/src/platforms/apple/core/runner-host.ts index 6025a6e016..4cdc30b32f 100644 --- a/src/platforms/apple/core/runner-host.ts +++ b/src/platforms/apple/core/runner-host.ts @@ -1,17 +1,15 @@ import type { AppleRunnerHost } from '@agent-device/platform-apple/runner'; -import { - publishFileSync, - resolveIosSimulatorDeviceSetPath, - acquireProcessLock, -} from '@agent-device/host-kit/fs'; +import { publishFileSync, acquireProcessLock } from '@agent-device/host-kit/file'; +import { resolveIosSimulatorDeviceSetPath } from '@agent-device/kernel/device-isolation'; import { - emitDiagnostic, - withDiagnosticTimer, requireExecSuccess, runCmdBackground, runCmdStreaming, runCmdSync, +} from '@agent-device/host-kit/command'; +import { emitDiagnostic, withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; +import { isProcessAlive, isProcessGroupAlive, readProcessCommand, @@ -19,20 +17,15 @@ import { signalPidsBestEffort, signalProcessGroupBestEffort, classifyOwnerLiveness, - Deadline, - isEnvTruthy, - retryWithPolicy, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; +import { Deadline, isEnvTruthy, retryWithPolicy } from '@agent-device/host-kit/retry'; import { withKeyedLock } from '@agent-device/kernel/keyed-lock'; -import { - isRecord, - parseBooleanLiteral, - createTtlMemo, - findProjectRoot, - readVersion, -} from '@agent-device/host-kit/values'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/version'; +import { isRecord } from '@agent-device/kernel/record'; +import { parseBooleanLiteral } from '@agent-device/kernel/source-value'; +import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; import { getRequestSignal, diff --git a/src/platforms/apple/core/screenshot-status-bar.ts b/src/platforms/apple/core/screenshot-status-bar.ts index 5805d1792f..0ba2eb5a82 100644 --- a/src/platforms/apple/core/screenshot-status-bar.ts +++ b/src/platforms/apple/core/screenshot-status-bar.ts @@ -1,5 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; -import { emitDiagnostic, requireExecSuccess, type ExecOptions } from '@agent-device/host-kit/exec'; +import { requireExecSuccess, type ExecOptions } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { AppError } from '@agent-device/kernel/errors'; import { runSimctlForDevice } from './simctl.ts'; diff --git a/src/platforms/apple/core/screenshot.ts b/src/platforms/apple/core/screenshot.ts index 115f03cf14..5a5845e336 100644 --- a/src/platforms/apple/core/screenshot.ts +++ b/src/platforms/apple/core/screenshot.ts @@ -1,12 +1,9 @@ import { promises as fs } from 'node:fs'; import path from 'node:path'; import { isMacOs, type DeviceInfo } from '@agent-device/kernel/device'; -import { - emitDiagnostic, - type ExecOptions, - Deadline, - retryWithPolicy, -} from '@agent-device/host-kit/exec'; +import { type ExecOptions } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { Deadline, retryWithPolicy } from '@agent-device/host-kit/retry'; import { AppError } from '@agent-device/kernel/errors'; import { resizePngFile } from '@agent-device/capture-kit/png-resize'; diff --git a/src/platforms/apple/core/simctl.ts b/src/platforms/apple/core/simctl.ts index 3dcf9ac425..3997a6f4f1 100644 --- a/src/platforms/apple/core/simctl.ts +++ b/src/platforms/apple/core/simctl.ts @@ -1,6 +1,6 @@ import { isIosFamily, type DeviceInfo } from '@agent-device/kernel/device'; -import type { ExecOptions, ExecResult } from '@agent-device/host-kit/exec'; -import { resolveIosSimulatorDeviceSetPath } from '@agent-device/host-kit/fs'; +import { type ExecOptions, type ExecResult } from '@agent-device/host-kit/command'; +import { resolveIosSimulatorDeviceSetPath } from '@agent-device/kernel/device-isolation'; import { runXcrun } from './tool-provider.ts'; type SimctlArgsOptions = { diff --git a/src/platforms/apple/core/simulator.ts b/src/platforms/apple/core/simulator.ts index 610f0ca3c2..7a98e508ef 100644 --- a/src/platforms/apple/core/simulator.ts +++ b/src/platforms/apple/core/simulator.ts @@ -1,13 +1,9 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { - execFailureDetails, - requireExecSuccess, - Deadline, - retryWithPolicy, -} from '@agent-device/host-kit/exec'; +import { execFailureDetails, requireExecSuccess } from '@agent-device/host-kit/command'; +import { Deadline, retryWithPolicy } from '@agent-device/host-kit/retry'; -import { createTtlMemo } from '@agent-device/host-kit/values'; +import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; import { bootFailureHint, classifyBootFailure } from '../../boot-diagnostics.ts'; import { diff --git a/src/platforms/apple/core/tool-provider-types.ts b/src/platforms/apple/core/tool-provider-types.ts index f1ed6d095a..51892efa5e 100644 --- a/src/platforms/apple/core/tool-provider-types.ts +++ b/src/platforms/apple/core/tool-provider-types.ts @@ -1,5 +1,5 @@ import type { AppsFilter } from '@agent-device/contracts/device'; -import type { ExecOptions, ExecResult } from '@agent-device/host-kit/exec'; +import { type ExecOptions, type ExecResult } from '@agent-device/host-kit/command'; import type { IosAppInfo } from './app-info.ts'; export type AppleToolCommandExecutor = ( diff --git a/src/platforms/apple/core/tool-provider.ts b/src/platforms/apple/core/tool-provider.ts index 96b97b4eda..0f6f0bd7cc 100644 --- a/src/platforms/apple/core/tool-provider.ts +++ b/src/platforms/apple/core/tool-provider.ts @@ -4,8 +4,8 @@ import { whichCmd, type ExecOptions, type ExecResult, -} from '@agent-device/host-kit/exec'; -import { createScopedProvider } from '@agent-device/host-kit/values'; +} from '@agent-device/host-kit/command'; +import { createScopedProvider } from '@agent-device/kernel/scoped-provider'; import { createLocalAppleMacOsHostProvider } from '../os/macos/host-provider.ts'; import type { AppleMacOsHelperProvider, diff --git a/src/platforms/apple/interactor.ts b/src/platforms/apple/interactor.ts index 38617ebb96..5e19b22ae9 100644 --- a/src/platforms/apple/interactor.ts +++ b/src/platforms/apple/interactor.ts @@ -23,10 +23,10 @@ import { toAppleTvRemoteButton } from '@agent-device/contracts/tv-remote'; import type { SessionSurface } from '@agent-device/contracts/session'; import { DEVICE_ROTATIONS, type DeviceRotation } from '@agent-device/contracts/device'; import { normalizeSnapshotScope } from '@agent-device/contracts/snapshot'; -import { withDiagnosticTimer } from '@agent-device/host-kit/exec'; +import { withDiagnosticTimer } from '@agent-device/host-kit/diagnostics'; import { isMacOs, isTvOsDevice, type DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { withMethodScope } from '@agent-device/host-kit/values'; +import { withMethodScope } from '@agent-device/kernel/scoped-provider'; import type { Point, RawSnapshotNode, SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; import type { Interactor, diff --git a/src/platforms/apple/os/macos/helper.ts b/src/platforms/apple/os/macos/helper.ts index 4e432d93e1..f1143c8450 100644 --- a/src/platforms/apple/os/macos/helper.ts +++ b/src/platforms/apple/os/macos/helper.ts @@ -8,7 +8,7 @@ import { resolveExecutableOverridePath, runCmdBackground, type ExecBackgroundResult, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/command'; import type { SessionSurface } from '@agent-device/contracts/session'; import { hasScopedAppleToolProvider, diff --git a/src/platforms/apple/os/macos/host-provider.ts b/src/platforms/apple/os/macos/host-provider.ts index 1b43680f8f..dce442825c 100644 --- a/src/platforms/apple/os/macos/host-provider.ts +++ b/src/platforms/apple/os/macos/host-provider.ts @@ -3,7 +3,7 @@ import os from 'node:os'; import path from 'node:path'; import type { AppsFilter } from '@agent-device/contracts/device'; import { AppError } from '@agent-device/kernel/errors'; -import { requireExecSuccess } from '@agent-device/host-kit/exec'; +import { requireExecSuccess } from '@agent-device/host-kit/command'; import { filterAppleAppsByBundlePrefix } from '../../core/app-filter.ts'; import type { IosAppInfo } from '../../core/app-info.ts'; import type { diff --git a/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts b/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts index 0729a8b489..698d7bb803 100644 --- a/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts +++ b/src/platforms/harmonyos/__tests__/app-lifecycle.test.ts @@ -2,8 +2,8 @@ import assert from 'node:assert/strict'; import { AppError } from '@agent-device/kernel/errors'; import { afterEach, beforeEach, test, vi } from 'vitest'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); @@ -25,7 +25,7 @@ import { parseHarmonyLaunchTarget, resolveHarmonyArchiveBundleName, } from '../app-lifecycle.ts'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/harmonyos/__tests__/doctor.test.ts b/src/platforms/harmonyos/__tests__/doctor.test.ts index ba0e7360be..132c5aa575 100644 --- a/src/platforms/harmonyos/__tests__/doctor.test.ts +++ b/src/platforms/harmonyos/__tests__/doctor.test.ts @@ -2,12 +2,12 @@ import assert from 'node:assert/strict'; import { beforeEach, test, vi } from 'vitest'; import type { DoctorCheck } from '@agent-device/contracts/observability'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { harmonyToolchainCheck } from '../doctor.ts'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/harmonyos/__tests__/hdc.test.ts b/src/platforms/harmonyos/__tests__/hdc.test.ts index 5133731e05..a180f24a1d 100644 --- a/src/platforms/harmonyos/__tests__/hdc.test.ts +++ b/src/platforms/harmonyos/__tests__/hdc.test.ts @@ -1,12 +1,12 @@ import assert from 'node:assert/strict'; import { beforeEach, test, vi } from 'vitest'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn() }; }); -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { DEFAULT_HARMONY_HDC_TIMEOUT_MS, runHarmonyHdc } from '../hdc.ts'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/harmonyos/__tests__/input-actions.test.ts b/src/platforms/harmonyos/__tests__/input-actions.test.ts index 613ef9a650..df1b1b4182 100644 --- a/src/platforms/harmonyos/__tests__/input-actions.test.ts +++ b/src/platforms/harmonyos/__tests__/input-actions.test.ts @@ -12,7 +12,7 @@ const { runHarmonyHdc, sleep, readHarmonyGestureViewport, invalidateHarmonyGestu })); vi.mock('../hdc.ts', () => ({ runHarmonyHdc })); -vi.mock('@agent-device/host-kit/exec', () => ({ sleep })); +vi.mock('@agent-device/host-kit/retry', () => ({ sleep })); vi.mock('../snapshot.ts', () => ({ readHarmonyGestureViewport, invalidateHarmonyGestureViewport, diff --git a/src/platforms/harmonyos/app-lifecycle.ts b/src/platforms/harmonyos/app-lifecycle.ts index 2db7a9abac..4727d4b27a 100644 --- a/src/platforms/harmonyos/app-lifecycle.ts +++ b/src/platforms/harmonyos/app-lifecycle.ts @@ -1,6 +1,6 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { runHarmonyHdc } from './hdc.ts'; import { invalidateHarmonyGestureViewport } from './snapshot.ts'; diff --git a/src/platforms/harmonyos/hdc.ts b/src/platforms/harmonyos/hdc.ts index 91c7a33205..de62b2c521 100644 --- a/src/platforms/harmonyos/hdc.ts +++ b/src/platforms/harmonyos/hdc.ts @@ -1,7 +1,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import { promises as fs } from 'node:fs'; import path from 'node:path'; -import { runCmd, type ExecOptions, type ExecResult } from '@agent-device/host-kit/exec'; +import { runCmd, type ExecOptions, type ExecResult } from '@agent-device/host-kit/command'; export type HarmonyHdcOptions = Pick< ExecOptions, diff --git a/src/platforms/harmonyos/input-actions.ts b/src/platforms/harmonyos/input-actions.ts index 62b34f639f..d811800dae 100644 --- a/src/platforms/harmonyos/input-actions.ts +++ b/src/platforms/harmonyos/input-actions.ts @@ -7,7 +7,7 @@ import { } from '@agent-device/contracts/scroll-gesture'; import type { DeviceInfo } from '@agent-device/kernel/device'; import { AppError } from '@agent-device/kernel/errors'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import { runHarmonyHdc } from './hdc.ts'; import { invalidateHarmonyGestureViewport, readHarmonyGestureViewport } from './snapshot.ts'; diff --git a/src/platforms/harmonyos/snapshot.ts b/src/platforms/harmonyos/snapshot.ts index d848affa23..514ce8a7a8 100644 --- a/src/platforms/harmonyos/snapshot.ts +++ b/src/platforms/harmonyos/snapshot.ts @@ -6,7 +6,7 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; import type { RawSnapshotNode, Rect } from '@agent-device/kernel/snapshot'; import { AppError } from '@agent-device/kernel/errors'; import type { SnapshotOptions } from '@agent-device/contracts/interactor-types'; -import { createTtlMemo } from '@agent-device/host-kit/values'; +import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; import { runHarmonyHdc } from './hdc.ts'; const MAX_NODES = 5_000; diff --git a/src/platforms/install-artifact-archive-context.ts b/src/platforms/install-artifact-archive-context.ts index e0a7488c51..f254846737 100644 --- a/src/platforms/install-artifact-archive-context.ts +++ b/src/platforms/install-artifact-archive-context.ts @@ -1,5 +1,5 @@ import { AsyncLocalStorage } from 'node:async_hooks'; -import { ArchiveBudget } from '@agent-device/host-kit/fs'; +import { ArchiveBudget } from '@agent-device/host-kit/archive'; type ArchiveState = { budget: ArchiveBudget; depth: number }; const ARCHIVE_STATE = new AsyncLocalStorage(); diff --git a/src/platforms/install-source-archive.ts b/src/platforms/install-source-archive.ts index 511688cb8e..7449c3d480 100644 --- a/src/platforms/install-source-archive.ts +++ b/src/platforms/install-source-archive.ts @@ -6,7 +6,7 @@ import { extractArchiveSafely, archiveTypeFromPath, ArchiveBudget, -} from '@agent-device/host-kit/fs'; +} from '@agent-device/host-kit/archive'; const MAX_INSTALL_SOURCE_SEARCH_DEPTH = 5; diff --git a/src/platforms/install-source-download.ts b/src/platforms/install-source-download.ts index b1c8995ffb..25277c9ad5 100644 --- a/src/platforms/install-source-download.ts +++ b/src/platforms/install-source-download.ts @@ -2,7 +2,10 @@ import { createWriteStream, promises as fs } from 'node:fs'; import path from 'node:path'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { MAX_ARTIFACT_COMPRESSED_BYTES, createByteLimitStream } from '@agent-device/host-kit/fs'; +import { + MAX_ARTIFACT_COMPRESSED_BYTES, + createByteLimitStream, +} from '@agent-device/host-kit/archive'; import { approveDownloadSourceUrl } from './install-source-network.ts'; import * as networkTransport from './install-source-network-transport.ts'; diff --git a/src/platforms/install-source.ts b/src/platforms/install-source.ts index 37274de00b..e73c4aafdb 100644 --- a/src/platforms/install-source.ts +++ b/src/platforms/install-source.ts @@ -3,7 +3,8 @@ import os from 'node:os'; import path from 'node:path'; import type { LocalInstallSource } from '@agent-device/kernel/contracts'; import { AppError, createRequestCanceledError } from '@agent-device/kernel/errors'; -import { expandUserHomePath, ArchiveBudget } from '@agent-device/host-kit/fs'; +import { ArchiveBudget } from '@agent-device/host-kit/archive'; +import { expandUserHomePath } from '@agent-device/host-kit/file'; import { resolveInstallableCandidate } from './install-source-archive.ts'; import { diff --git a/src/platforms/linux/__tests__/atspi-bridge.test.ts b/src/platforms/linux/__tests__/atspi-bridge.test.ts index 8f7c6eeef1..49745ccd3a 100644 --- a/src/platforms/linux/__tests__/atspi-bridge.test.ts +++ b/src/platforms/linux/__tests__/atspi-bridge.test.ts @@ -1,13 +1,13 @@ import { afterAll, beforeEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), whichCmd: vi.fn() }; }); import { captureAccessibilityTree } from '../atspi-bridge.ts'; -import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; +import { runCmd, whichCmd } from '@agent-device/host-kit/command'; import { AppError } from '@agent-device/kernel/errors'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/platforms/linux/__tests__/clipboard.test.ts b/src/platforms/linux/__tests__/clipboard.test.ts index 0abf4a737d..3d41659b87 100644 --- a/src/platforms/linux/__tests__/clipboard.test.ts +++ b/src/platforms/linux/__tests__/clipboard.test.ts @@ -1,12 +1,12 @@ import { afterAll, beforeEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), whichCmd: vi.fn() }; }); -import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; +import { runCmd, whichCmd } from '@agent-device/host-kit/command'; import { readLinuxClipboard, writeLinuxClipboard } from '../clipboard.ts'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/platforms/linux/__tests__/input-actions.test.ts b/src/platforms/linux/__tests__/input-actions.test.ts index 3100f704dc..43c53c9dc8 100644 --- a/src/platforms/linux/__tests__/input-actions.test.ts +++ b/src/platforms/linux/__tests__/input-actions.test.ts @@ -1,12 +1,12 @@ import { afterAll, beforeEach, test, vi } from 'vitest'; import assert from 'node:assert/strict'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, runCmd: vi.fn(), whichCmd: vi.fn() }; }); -import { runCmd, whichCmd } from '@agent-device/host-kit/exec'; +import { runCmd, whichCmd } from '@agent-device/host-kit/command'; import { resetInputToolCache } from '../linux-env.ts'; import { fillLinux, pressLinux, scrollLinux, typeLinux, sendKey } from '../input-actions.ts'; diff --git a/src/platforms/linux/input-actions.ts b/src/platforms/linux/input-actions.ts index 47f279ebdb..1fb14402d4 100644 --- a/src/platforms/linux/input-actions.ts +++ b/src/platforms/linux/input-actions.ts @@ -1,6 +1,6 @@ import { ensureInputTool } from './linux-env.ts'; import { resolveLinuxToolProvider, type LinuxPointerButton } from './tool-provider.ts'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import type { ScrollDirection } from '@agent-device/contracts/scroll-gesture'; // ── Low-level wrappers ───────────────────────────────────────────────── diff --git a/src/platforms/linux/snapshot.ts b/src/platforms/linux/snapshot.ts index a87c0b60b2..80b7bfe39f 100644 --- a/src/platforms/linux/snapshot.ts +++ b/src/platforms/linux/snapshot.ts @@ -1,7 +1,7 @@ import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import { captureAccessibilityTree, type SnapshotSurface } from './atspi-bridge.ts'; import type { SessionSurface } from '@agent-device/contracts/session'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; /** * Map the session-level surface to an AT-SPI2 surface. diff --git a/src/platforms/linux/tool-provider.ts b/src/platforms/linux/tool-provider.ts index bf637fc34f..540e30088b 100644 --- a/src/platforms/linux/tool-provider.ts +++ b/src/platforms/linux/tool-provider.ts @@ -2,15 +2,15 @@ import type { ClickButton } from '@agent-device/contracts/click-button'; import type { ScrollDirection } from '@agent-device/contracts/scroll-gesture'; import { AppError } from '@agent-device/kernel/errors'; import { - emitDiagnostic, runCmd, whichCmd, type ExecOptions, type ExecResult, - sleep, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { sleep } from '@agent-device/host-kit/retry'; -import { createScopedProvider } from '@agent-device/host-kit/values'; +import { createScopedProvider } from '@agent-device/kernel/scoped-provider'; import type { LinuxAccessibilityTree, diff --git a/src/platforms/toolchain-probe.ts b/src/platforms/toolchain-probe.ts index e74f5f8981..8359d7173a 100644 --- a/src/platforms/toolchain-probe.ts +++ b/src/platforms/toolchain-probe.ts @@ -1,4 +1,4 @@ -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; export const TOOLCHAIN_TIMEOUT_MS = 3_000; diff --git a/src/platforms/vega/app-lifecycle.ts b/src/platforms/vega/app-lifecycle.ts index 264c70dfe8..1b8595260d 100644 --- a/src/platforms/vega/app-lifecycle.ts +++ b/src/platforms/vega/app-lifecycle.ts @@ -1,5 +1,5 @@ import type { DeviceInfo } from '@agent-device/kernel/device'; -import { requireExecSuccess, type ExecOptions } from '@agent-device/host-kit/exec'; +import { requireExecSuccess, type ExecOptions } from '@agent-device/host-kit/command'; import { resolveVegaToolProvider } from './tool-provider.ts'; const VEGA_APP_COMMAND_TIMEOUT_MS = 30_000; diff --git a/src/platforms/vega/input-actions.ts b/src/platforms/vega/input-actions.ts index be0319f247..dcae051927 100644 --- a/src/platforms/vega/input-actions.ts +++ b/src/platforms/vega/input-actions.ts @@ -1,6 +1,6 @@ import { type TvRemoteButton, toVegaTvRemoteKey } from '@agent-device/contracts/tv-remote'; import type { DeviceInfo } from '@agent-device/kernel/device'; -import { requireExecSuccess } from '@agent-device/host-kit/exec'; +import { requireExecSuccess } from '@agent-device/host-kit/command'; import { resolveVegaToolProvider } from './tool-provider.ts'; const VEGA_INPUT_TRANSPORT_OVERHEAD_MS = 10_000; diff --git a/src/platforms/vega/tool-provider.ts b/src/platforms/vega/tool-provider.ts index ec01c44bc7..78b080986f 100644 --- a/src/platforms/vega/tool-provider.ts +++ b/src/platforms/vega/tool-provider.ts @@ -3,8 +3,13 @@ import { access } from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import type { VegaTvRemoteKey } from '@agent-device/contracts/tv-remote'; -import { runCmd, whichCmd, type ExecOptions, type ExecResult } from '@agent-device/host-kit/exec'; -import { createScopedProvider } from '@agent-device/host-kit/values'; +import { + runCmd, + whichCmd, + type ExecOptions, + type ExecResult, +} from '@agent-device/host-kit/command'; +import { createScopedProvider } from '@agent-device/kernel/scoped-provider'; export type VegaToolProvider = { isAvailable(): Promise; diff --git a/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts b/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts index 36025e8429..799c271bc2 100644 --- a/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts +++ b/src/platforms/web/__tests__/agent-browser-boundary-faults.test.ts @@ -4,7 +4,7 @@ import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; import { mkdtempForTestSync } from '../../../__tests__/test-utils/tmp-dir.ts'; import { createFailNthCommandExecutor } from '../../../__tests__/test-utils/exec-faults.ts'; -import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { createAgentBrowserWebProvider } from '../agent-browser-provider.ts'; import { installFakeManagedAgentBrowser } from './test-utils.ts'; diff --git a/src/platforms/web/agent-browser-install.ts b/src/platforms/web/agent-browser-install.ts index 3a51958648..29ee09a0da 100644 --- a/src/platforms/web/agent-browser-install.ts +++ b/src/platforms/web/agent-browser-install.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; /** * How the managed backend gets onto disk. Kept apart from the tool module, diff --git a/src/platforms/web/agent-browser-lifecycle.test.ts b/src/platforms/web/agent-browser-lifecycle.test.ts index ecbb099d8e..6901a98bb8 100644 --- a/src/platforms/web/agent-browser-lifecycle.test.ts +++ b/src/platforms/web/agent-browser-lifecycle.test.ts @@ -8,16 +8,20 @@ const { runCmdMock } = vi.hoisted(() => ({ runCmdMock: vi.fn(), })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => ({ + ...(await importOriginal()), + runCmd: runCmdMock, + withoutCommandExecutorOverride: async (fn: () => Promise) => await fn(), +})); + +vi.mock('@agent-device/host-kit/process', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, - runCmd: runCmdMock, - // The seam mock cannot reach listHostProcesses' internal runCmd call, so + // The port mock cannot reach listHostProcesses' internal runCmd call, so // the ps read is routed through its runCommand injection point instead. listHostProcesses: async (options: Parameters[0]) => await actual.listHostProcesses({ ...options, runCommand: runCmdMock }), - withoutCommandExecutorOverride: async (fn: () => Promise) => await fn(), readProcessStartTime: (pid: number) => `start-${pid}`, readProcessCommand: (pid: number) => `command-${pid}`, }; diff --git a/src/platforms/web/agent-browser-lifecycle.ts b/src/platforms/web/agent-browser-lifecycle.ts index ce2e0d088b..60aa08cca5 100644 --- a/src/platforms/web/agent-browser-lifecycle.ts +++ b/src/platforms/web/agent-browser-lifecycle.ts @@ -1,11 +1,11 @@ import fs from 'node:fs'; import path from 'node:path'; import { uniqueStrings } from '@agent-device/kernel/collections'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { - emitDiagnostic, type OwnedProcessRecordStore, reapOwnedProcessRecordsAtStartup, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; import type { AgentBrowserToolStatus } from './agent-browser-tool.ts'; import type { AgentBrowserProcessSummary } from './agent-browser-process-record.ts'; diff --git a/src/platforms/web/agent-browser-network.ts b/src/platforms/web/agent-browser-network.ts index e5e9360291..7991c3d0a9 100644 --- a/src/platforms/web/agent-browser-network.ts +++ b/src/platforms/web/agent-browser-network.ts @@ -3,7 +3,7 @@ import type { BackendDumpNetworkResult, BackendNetworkEntry, } from '../../backend.ts'; -import { stripUndefined } from '@agent-device/host-kit/values'; +import { stripUndefined } from '@agent-device/kernel/record'; import { isJsonObject, readNumberProperty, readStringProperty } from './json-utils.ts'; type AgentBrowserNetworkRequest = { diff --git a/src/platforms/web/agent-browser-process-record.ts b/src/platforms/web/agent-browser-process-record.ts index 75b07327d5..448ec570bf 100644 --- a/src/platforms/web/agent-browser-process-record.ts +++ b/src/platforms/web/agent-browser-process-record.ts @@ -2,15 +2,15 @@ import crypto from 'node:crypto'; import path from 'node:path'; import type { OwnedProcessRecord } from '@agent-device/contracts/platform-runtime-host'; import { uniqueStrings } from '@agent-device/kernel/collections'; +import { withoutCommandExecutorOverride } from '@agent-device/host-kit/command'; import { - withoutCommandExecutorOverride, expandProcessTree, listHostProcesses, readProcessCommand, readProcessStartTime, type HostProcessInfo, type OwnedProcessRecordStore, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; import type { AgentBrowserToolStatus } from './agent-browser-tool.ts'; diff --git a/src/platforms/web/agent-browser-provider.test.ts b/src/platforms/web/agent-browser-provider.test.ts index d2c1fde454..b0bc4275ae 100644 --- a/src/platforms/web/agent-browser-provider.test.ts +++ b/src/platforms/web/agent-browser-provider.test.ts @@ -17,11 +17,8 @@ vi.mock('./agent-browser-lifecycle.ts', async (importOriginal) => { import { createAgentBrowserWebProvider } from './agent-browser-provider.ts'; import type { WebSnapshotResult } from './provider.ts'; -import { - withCommandExecutorOverride, - type ExecResult, - type OwnedProcessRecordStore, -} from '@agent-device/host-kit/exec'; +import { withCommandExecutorOverride, type ExecResult } from '@agent-device/host-kit/command'; +import { type OwnedProcessRecordStore } from '@agent-device/host-kit/process'; import { AppError } from '@agent-device/kernel/errors'; import { buildSelectorChainForNode, resolveRecordedTarget } from '@agent-device/selectors'; import { attachRefs } from '@agent-device/kernel/snapshot'; diff --git a/src/platforms/web/agent-browser-provider.ts b/src/platforms/web/agent-browser-provider.ts index 439289ce87..dd0359cd5d 100644 --- a/src/platforms/web/agent-browser-provider.ts +++ b/src/platforms/web/agent-browser-provider.ts @@ -1,9 +1,7 @@ -import { - execFailureDetails, - emitDiagnostic, - sleep, - type OwnedProcessRecordStore, -} from '@agent-device/host-kit/exec'; +import { execFailureDetails } from '@agent-device/host-kit/command'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; +import { type OwnedProcessRecordStore } from '@agent-device/host-kit/process'; +import { sleep } from '@agent-device/host-kit/retry'; import { AppError } from '@agent-device/kernel/errors'; import type { Rect } from '@agent-device/kernel/snapshot'; diff --git a/src/platforms/web/agent-browser-tool.test.ts b/src/platforms/web/agent-browser-tool.test.ts index f4950308b2..8dcf8d5c21 100644 --- a/src/platforms/web/agent-browser-tool.test.ts +++ b/src/platforms/web/agent-browser-tool.test.ts @@ -14,7 +14,7 @@ import { writeFakeNpmCliScript, } from './__tests__/test-utils.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { withCommandExecutorOverride } from '@agent-device/host-kit/command'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; type SpawnedCommand = { cmd: string; args: string[] }; diff --git a/src/platforms/web/agent-browser-tool.ts b/src/platforms/web/agent-browser-tool.ts index e086d4a3a4..a3abd74b0d 100644 --- a/src/platforms/web/agent-browser-tool.ts +++ b/src/platforms/web/agent-browser-tool.ts @@ -2,14 +2,15 @@ import fs from 'node:fs'; import crypto from 'node:crypto'; import os from 'node:os'; import path from 'node:path'; -import { runCmd, type ExecResult, readProcessStartTime } from '@agent-device/host-kit/exec'; +import { runCmd, type ExecResult } from '@agent-device/host-kit/command'; +import { readProcessStartTime } from '@agent-device/host-kit/process'; import { AppError, asAppError } from '@agent-device/kernel/errors'; import type { ManagedWebBackendStatus } from '@agent-device/contracts/managed-web-backend'; import { installManagedAgentBrowserPackage, writeManagedAgentBrowserManifest, } from './agent-browser-install.ts'; -import { acquireProcessLock } from '@agent-device/host-kit/fs'; +import { acquireProcessLock } from '@agent-device/host-kit/file'; import { appendAgentDeviceChromeArgs, diff --git a/src/platforms/web/provider.ts b/src/platforms/web/provider.ts index 849550b370..43a1d19f6e 100644 --- a/src/platforms/web/provider.ts +++ b/src/platforms/web/provider.ts @@ -1,6 +1,6 @@ import type { ScrollDirection } from '@agent-device/contracts/scroll-gesture'; import type { SessionSurface } from '@agent-device/contracts/session'; -import { createScopedProvider } from '@agent-device/host-kit/values'; +import { createScopedProvider } from '@agent-device/kernel/scoped-provider'; import type { RawSnapshotNode } from '@agent-device/kernel/snapshot'; import type { BackendDumpNetworkOptions, BackendDumpNetworkResult } from '../../backend.ts'; import type { AudioProbeResult } from '@agent-device/contracts/audio-probe-result'; diff --git a/src/provider-webdriver.ts b/src/provider-webdriver.ts index 1ee7e4a537..389292a1b0 100644 --- a/src/provider-webdriver.ts +++ b/src/provider-webdriver.ts @@ -1,6 +1,6 @@ import { createProviderWebDriver } from '@agent-device/provider-webdriver'; -import { runCmd } from '@agent-device/host-kit/exec'; -import { readVersion } from '@agent-device/host-kit/values'; +import { runCmd } from '@agent-device/host-kit/command'; +import { readVersion } from '@agent-device/host-kit/version'; export const providerWebDriver = createProviderWebDriver({ clientVersion: readVersion(), diff --git a/src/recording/__tests__/overlay.test.ts b/src/recording/__tests__/overlay.test.ts index bd5fd9d022..f2034040f6 100644 --- a/src/recording/__tests__/overlay.test.ts +++ b/src/recording/__tests__/overlay.test.ts @@ -3,11 +3,11 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { const fs = await import('node:fs'); const path = await import('node:path'); return { - ...(await importOriginal()), + ...(await importOriginal()), runCmd: vi.fn(async (cmd: string, args: string[]) => { if (cmd === 'xcrun') { const outputPath = args[args.indexOf('-o') + 1]!; @@ -30,7 +30,7 @@ vi.mock('../../utils/video.ts', () => ({ import { buildRecordingScriptPathCandidates, overlayRecordingTouches } from '../overlay.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; function helperScriptArgs(): string[] { const helperCall = mockRunCmd.mock.calls.find(([cmd]) => cmd !== 'xcrun'); diff --git a/src/recording/__tests__/recording-scripts.test.ts b/src/recording/__tests__/recording-scripts.test.ts index 6de4ebb332..5f230feff1 100644 --- a/src/recording/__tests__/recording-scripts.test.ts +++ b/src/recording/__tests__/recording-scripts.test.ts @@ -2,7 +2,7 @@ import { beforeAll, test } from 'vitest'; import assert from 'node:assert/strict'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { getRecordingOverlaySupportWarning } from '../overlay.ts'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); diff --git a/src/recording/output-path.ts b/src/recording/output-path.ts index 9d5da6ab9a..d8c5964f69 100644 --- a/src/recording/output-path.ts +++ b/src/recording/output-path.ts @@ -1,6 +1,6 @@ import path from 'node:path'; import type { Platform, PlatformSelector } from '@agent-device/kernel/device'; -import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { resolveUserPath } from '@agent-device/host-kit/file'; const DEFAULT_RECORDING_EXTENSION = '.mp4'; const WEB_RECORDING_EXTENSION = '.webm'; diff --git a/src/recording/overlay.ts b/src/recording/overlay.ts index b4d173729b..3bb0983f12 100644 --- a/src/recording/overlay.ts +++ b/src/recording/overlay.ts @@ -1,10 +1,10 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { AppError } from '@agent-device/kernel/errors'; import { buildSwiftToolEnv, compileSwiftSourceFile } from '../utils/swift-cache.ts'; -import { findProjectRoot } from '@agent-device/host-kit/values'; +import { findProjectRoot } from '@agent-device/host-kit/version'; import { waitForPlayableVideo, waitForStableFile } from '../utils/video.ts'; import { DEFAULT_RECORDING_EXPORT_QUALITY, diff --git a/src/remote/remote-config-core.ts b/src/remote/remote-config-core.ts index 3f550e675e..063e8527eb 100644 --- a/src/remote/remote-config-core.ts +++ b/src/remote/remote-config-core.ts @@ -9,8 +9,8 @@ import { type ResolvedRemoteConfigProfile, } from './remote-config-schema.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { resolveUserPath } from '@agent-device/host-kit/fs'; -import { parseSourceValue } from '@agent-device/host-kit/values'; +import { resolveUserPath } from '@agent-device/host-kit/file'; +import { parseSourceValue } from '@agent-device/kernel/source-value'; // Deliberately narrower than `resolveRemoteConfigProfile`: this reads only // what the config *file itself* declares, with no ambient environment diff --git a/src/remote/remote-config-schema.ts b/src/remote/remote-config-schema.ts index 489f9e8175..6c33f206dd 100644 --- a/src/remote/remote-config-schema.ts +++ b/src/remote/remote-config-schema.ts @@ -7,7 +7,7 @@ import { // Declared in contracts/ so zones below remote/ can be stated in terms of the field vocabulary; // re-exported here because this module is where consumers already import it from. export type { RemoteConnectionProfileFields } from '@agent-device/contracts/remote'; -import { buildPrimaryEnvVarName } from '@agent-device/host-kit/values'; +import { buildPrimaryEnvVarName } from '@agent-device/kernel/source-value'; import { PLATFORM_SELECTORS, type DeviceTarget, diff --git a/src/remote/remote-connection-state.ts b/src/remote/remote-connection-state.ts index a1cbda3830..f24d6f17de 100644 --- a/src/remote/remote-connection-state.ts +++ b/src/remote/remote-connection-state.ts @@ -3,8 +3,8 @@ import fs from 'node:fs'; import path from 'node:path'; import { resolveRemoteConfigPath, resolveRemoteConfigProfile } from './remote-config-core.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { publishFileSync } from '@agent-device/host-kit/fs'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { publishFileSync } from '@agent-device/host-kit/file'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import type { CliFlags } from '@agent-device/contracts/command'; import type { LeaseBackend, SessionRuntimeHints } from '@agent-device/kernel/contracts'; import { diff --git a/src/remote/upload-client-artifact.ts b/src/remote/upload-client-artifact.ts index e11388b7a7..f0d241ead8 100644 --- a/src/remote/upload-client-artifact.ts +++ b/src/remote/upload-client-artifact.ts @@ -5,7 +5,7 @@ import path from 'node:path'; import { Writable } from 'node:stream'; import { pipeline } from 'node:stream/promises'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; const ARTIFACT_HASH_ALGORITHM = 'sha256'; const DEFAULT_CONTENT_TYPE = 'application/octet-stream'; diff --git a/src/replay/script-source-bundle.ts b/src/replay/script-source-bundle.ts index a6061ab715..ee42516ba1 100644 --- a/src/replay/script-source-bundle.ts +++ b/src/replay/script-source-bundle.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import { AppError } from '@agent-device/kernel/errors'; import type { ReplayScriptSourceBundle } from '@agent-device/contracts/replay'; -import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { resolveUserPath } from '@agent-device/host-kit/file'; import { resolveReplayFormat } from './format.ts'; /** diff --git a/src/replay/source-discovery.ts b/src/replay/source-discovery.ts index 29c6170182..2fdbd56d0b 100644 --- a/src/replay/source-discovery.ts +++ b/src/replay/source-discovery.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { AppError } from '@agent-device/kernel/errors'; -import { resolveUserPath } from '@agent-device/host-kit/fs'; +import { resolveUserPath } from '@agent-device/host-kit/file'; import { isMaestroYamlPath, maestroBackendRequiredMessage } from './format.ts'; const GLOB_PATTERN_CHARS = /[*?[\]{}]/; diff --git a/src/sdk/limrun-runtime-dependencies.ts b/src/sdk/limrun-runtime-dependencies.ts index 4cb518713c..45009300b7 100644 --- a/src/sdk/limrun-runtime-dependencies.ts +++ b/src/sdk/limrun-runtime-dependencies.ts @@ -4,8 +4,8 @@ import type { LimrunRuntimeDependencies } from '@agent-device/provider-limrun'; // deliberate static edge; making it lazy would require a proxy interactor rather than this seam. import { createAndroidInteractor } from '../core/interactors/android.ts'; import { runAndroidHostAdb } from '../platforms/android/adb-executor.ts'; -import { execFailureDetails, runCmd } from '@agent-device/host-kit/exec'; -import { readVersion } from '@agent-device/host-kit/values'; +import { execFailureDetails, runCmd } from '@agent-device/host-kit/command'; +import { readVersion } from '@agent-device/host-kit/version'; export function createLimrunRuntimeDependencies(): LimrunRuntimeDependencies { return { diff --git a/src/snapshot/snapshot-freshness/recovery.ts b/src/snapshot/snapshot-freshness/recovery.ts index 8072879325..f6fb607fd4 100644 --- a/src/snapshot/snapshot-freshness/recovery.ts +++ b/src/snapshot/snapshot-freshness/recovery.ts @@ -3,7 +3,7 @@ import { type SnapshotCaptureAnnotations, } from '@agent-device/contracts/capture'; import type { SnapshotState } from '@agent-device/kernel/snapshot'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; import type { SnapshotFreshnessReason, SnapshotFreshnessWindow } from './types.ts'; /** diff --git a/src/utils/__tests__/daemon-client-lifecycle.test.ts b/src/utils/__tests__/daemon-client-lifecycle.test.ts index 1cd2476566..8c893593ac 100644 --- a/src/utils/__tests__/daemon-client-lifecycle.test.ts +++ b/src/utils/__tests__/daemon-client-lifecycle.test.ts @@ -7,16 +7,16 @@ import path from 'node:path'; import { afterEach, test, vi } from 'vitest'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); - return { - ...actual, - runCmdDetached: vi.fn(), - runCmdDetachedMonitored: vi.fn(), - runCmdSync: vi.fn(() => ({ exitCode: 1, stdout: '', stderr: '' })), - sleep: vi.fn(async () => {}), - }; -}); +vi.mock('@agent-device/host-kit/command', async (importOriginal) => ({ + ...(await importOriginal()), + runCmdDetached: vi.fn(), + runCmdDetachedMonitored: vi.fn(), + runCmdSync: vi.fn(() => ({ exitCode: 1, stdout: '', stderr: '' })), +})); +vi.mock('@agent-device/host-kit/retry', async (importOriginal) => ({ + ...(await importOriginal()), + sleep: vi.fn(async () => {}), +})); import { resolveDaemonPaths, type DaemonPaths } from '../../daemon/config.ts'; import { @@ -36,12 +36,11 @@ import { AppError } from '@agent-device/kernel/errors'; import { runCmdDetachedMonitored, runCmdSync, - readProcessStartTime, shellQuoteIfNeeded, - sleep, -} from '@agent-device/host-kit/exec'; - -import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; +} from '@agent-device/host-kit/command'; +import { readProcessStartTime } from '@agent-device/host-kit/process'; +import { sleep } from '@agent-device/host-kit/retry'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/version'; type DaemonInfoFixture = { port?: number; diff --git a/src/utils/__tests__/daemon-client.test.ts b/src/utils/__tests__/daemon-client.test.ts index a25af4b20d..29de065b30 100644 --- a/src/utils/__tests__/daemon-client.test.ts +++ b/src/utils/__tests__/daemon-client.test.ts @@ -11,13 +11,13 @@ import { listenOnLoopback, supportsLoopbackBind, } from '../../__tests__/test-utils/loopback.ts'; +import { runCmdBackground } from '@agent-device/host-kit/command'; import { - runCmdBackground, isProcessAlive, readProcessCommand, readProcessStartTime, waitForProcessExit, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; import { sendToDaemon } from '../../daemon/client/daemon-client.ts'; import { computeDaemonCodeSignature } from '../../daemon/code-signature.ts'; import { downloadRemoteArtifact } from '../../remote/daemon-artifacts.ts'; @@ -34,7 +34,7 @@ import { } from '../../daemon/client/daemon-client-timeout.ts'; import { resolveDaemonPaths } from '../../daemon/config.ts'; import { stopProcessForTakeover } from '../../daemon/daemon-process.ts'; -import { findProjectRoot, readVersion } from '@agent-device/host-kit/values'; +import { findProjectRoot, readVersion } from '@agent-device/host-kit/version'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; // readProcessStartTime/readProcessCommand shell out to `ps` with a 1s @@ -52,8 +52,8 @@ const { mockReadProcessStartTime, mockReadProcessCommand } = vi.hoisted(() => ({ mockReadProcessCommand: vi.fn<(pid: number) => string | null | undefined>(), })); -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/process', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, readProcessStartTime: (pid: number) => { diff --git a/src/utils/__tests__/exec-boundary-faults.test.ts b/src/utils/__tests__/exec-boundary-faults.test.ts index 6d20af36ad..f3cab30b86 100644 --- a/src/utils/__tests__/exec-boundary-faults.test.ts +++ b/src/utils/__tests__/exec-boundary-faults.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { test } from 'vitest'; import { AppError } from '@agent-device/kernel/errors'; import { createFailNthCommandExecutor } from '../../__tests__/test-utils/exec-faults.ts'; -import { runCmd, withCommandExecutorOverride } from '@agent-device/host-kit/exec'; +import { runCmd, withCommandExecutorOverride } from '@agent-device/host-kit/command'; test('fail-Nth executor drives one deterministic command failure without hiding later calls', async () => { const failure = new AppError('COMMAND_FAILED', 'injected command failure', { diff --git a/src/utils/__tests__/process-exit.test.ts b/src/utils/__tests__/process-exit.test.ts index 7966e76dd5..f499a7788a 100644 --- a/src/utils/__tests__/process-exit.test.ts +++ b/src/utils/__tests__/process-exit.test.ts @@ -1,13 +1,13 @@ import assert from 'node:assert/strict'; import { afterEach, test, vi } from 'vitest'; -vi.mock('@agent-device/host-kit/exec', async (importOriginal) => { - const actual = await importOriginal(); +vi.mock('@agent-device/host-kit/retry', async (importOriginal) => { + const actual = await importOriginal(); return { ...actual, sleep: vi.fn(async () => {}) }; }); import { exitAfterFlush } from '../process-exit.ts'; -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; type FakeWriteStream = { writableLength: number; diff --git a/src/utils/__tests__/swift-cache.test.ts b/src/utils/__tests__/swift-cache.test.ts index ce43c22cd4..d19d95e81e 100644 --- a/src/utils/__tests__/swift-cache.test.ts +++ b/src/utils/__tests__/swift-cache.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from '../../__tests__/test-utils/tmp-dir.ts'; -vi.mock(import('@agent-device/host-kit/exec'), async (importOriginal) => ({ +vi.mock(import('@agent-device/host-kit/command'), async (importOriginal) => ({ ...(await importOriginal()), runCmd: vi.fn(async (_cmd: string, args: string[]) => { const outputPath = args[args.indexOf('-o') + 1]!; @@ -13,7 +13,7 @@ vi.mock(import('@agent-device/host-kit/exec'), async (importOriginal) => ({ }), })); -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { compileSwiftSourceFile, compileSwiftSourceText } from '../swift-cache.ts'; const mockRunCmd = vi.mocked(runCmd); diff --git a/src/utils/process-exit.ts b/src/utils/process-exit.ts index 82a2799723..c364c370b7 100644 --- a/src/utils/process-exit.ts +++ b/src/utils/process-exit.ts @@ -1,4 +1,4 @@ -import { sleep } from '@agent-device/host-kit/exec'; +import { sleep } from '@agent-device/host-kit/retry'; const FLUSH_TIMEOUT_MS = 2000; diff --git a/src/utils/result-serialization.ts b/src/utils/result-serialization.ts index f34cf97649..829b412ab7 100644 --- a/src/utils/result-serialization.ts +++ b/src/utils/result-serialization.ts @@ -15,7 +15,7 @@ import type { SessionCloseResult, } from '@agent-device/contracts/client'; import { isSerialAddressablePlatform, type PublicPlatform } from '@agent-device/kernel/device'; -import { successText, withSuccessText } from '@agent-device/host-kit/values'; +import { successText, withSuccessText } from '@agent-device/kernel/success-text'; export function buildAppIdentifiers(params: { session?: string; diff --git a/src/utils/screenshot-result.ts b/src/utils/screenshot-result.ts index 09507e019e..816bcc501c 100644 --- a/src/utils/screenshot-result.ts +++ b/src/utils/screenshot-result.ts @@ -1,6 +1,6 @@ import type { ScreenshotResultData } from '@agent-device/contracts/capture'; import type { ScreenshotOverlayRef } from '@agent-device/kernel/snapshot'; -import { isRecord, parsePoint, parseRect } from '@agent-device/host-kit/values'; +import { isRecord, parsePoint, parseRect } from '@agent-device/kernel/record'; export function pickScreenshotResultData(value: ScreenshotResultData): ScreenshotResultData { return { diff --git a/src/utils/source-value.test.ts b/src/utils/source-value.test.ts index 167f05bc41..74b5e76cd9 100644 --- a/src/utils/source-value.test.ts +++ b/src/utils/source-value.test.ts @@ -3,7 +3,7 @@ import { buildPrimaryEnvVarName, parseSourceValue, type SourceValueDefinition, -} from '@agent-device/host-kit/values'; +} from '@agent-device/kernel/source-value'; const LABEL = 'config file'; diff --git a/src/utils/swift-cache.ts b/src/utils/swift-cache.ts index 196d3afb4d..ad382f5a8b 100644 --- a/src/utils/swift-cache.ts +++ b/src/utils/swift-cache.ts @@ -4,8 +4,9 @@ import os from 'node:os'; import path from 'node:path'; import { trimEdgeDashes } from '@agent-device/kernel/collections'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd, readProcessStartTime } from '@agent-device/host-kit/exec'; -import { acquireProcessLock } from '@agent-device/host-kit/fs'; +import { runCmd } from '@agent-device/host-kit/command'; +import { readProcessStartTime } from '@agent-device/host-kit/process'; +import { acquireProcessLock } from '@agent-device/host-kit/file'; const SWIFT_CACHE_VERSION = '2'; const LOCK_RETRY_DELAY_MS = 25; diff --git a/src/utils/update-check.ts b/src/utils/update-check.ts index f3f4df0762..e430e336a2 100644 --- a/src/utils/update-check.ts +++ b/src/utils/update-check.ts @@ -1,7 +1,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmdDetached } from '@agent-device/host-kit/exec'; +import { runCmdDetached } from '@agent-device/host-kit/command'; const PACKAGE_NAME = 'agent-device'; const UPDATE_CHECK_INTERVAL_MS = 14 * 24 * 60 * 60 * 1000; diff --git a/src/utils/video.ts b/src/utils/video.ts index d5cda8ac22..c3634b2bcd 100644 --- a/src/utils/video.ts +++ b/src/utils/video.ts @@ -1,6 +1,7 @@ import fs from 'node:fs'; import { AppError } from '@agent-device/kernel/errors'; -import { runCmd, sleep } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; +import { sleep } from '@agent-device/host-kit/retry'; import { buildSwiftToolEnv, compileSwiftSourceText } from './swift-cache.ts'; import { hasPlayableWebmStructure } from './video-webm.ts'; diff --git a/test/integration/android-emulator-e2e/live-form-scenario.ts b/test/integration/android-emulator-e2e/live-form-scenario.ts index c99fe2abbf..e273a54717 100644 --- a/test/integration/android-emulator-e2e/live-form-scenario.ts +++ b/test/integration/android-emulator-e2e/live-form-scenario.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import path from 'node:path'; import { PUBLIC_COMMANDS } from '../../../src/command-catalog.ts'; -import { parseRect } from '@agent-device/host-kit/values'; +import { parseRect } from '@agent-device/kernel/record'; import type { CliJsonResult } from '../cli-json.ts'; import { assertElementText, diff --git a/test/integration/cli-exit-flush.test.ts b/test/integration/cli-exit-flush.test.ts index f1de1d70aa..6d3be13c68 100644 --- a/test/integration/cli-exit-flush.test.ts +++ b/test/integration/cli-exit-flush.test.ts @@ -2,7 +2,7 @@ import test from 'node:test'; import assert from 'node:assert/strict'; import path from 'node:path'; import { pathToFileURL } from 'node:url'; -import { runCmd } from '@agent-device/host-kit/exec'; +import { runCmd } from '@agent-device/host-kit/command'; import { PAYLOAD_MARKER } from './support/exit-payload.ts'; const SUPPORT_DIR = path.join(import.meta.dirname, 'support'); diff --git a/test/integration/cli-json.ts b/test/integration/cli-json.ts index 3845dbf3ed..9b41042c5f 100644 --- a/test/integration/cli-json.ts +++ b/test/integration/cli-json.ts @@ -1,4 +1,4 @@ -import { runCmd, runCmdSync, type ExecResult } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdSync, type ExecResult } from '@agent-device/host-kit/command'; const CLI_TIMEOUT_MS = 120_000; diff --git a/test/integration/client-api-doc-snippets.test.ts b/test/integration/client-api-doc-snippets.test.ts index 37868cbfc0..62657a3023 100644 --- a/test/integration/client-api-doc-snippets.test.ts +++ b/test/integration/client-api-doc-snippets.test.ts @@ -4,7 +4,7 @@ import path from 'node:path'; import assert from 'node:assert/strict'; import test from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; // Compiles every fenced ```ts snippet in website/docs/docs/client-api.md against // agent-device's real `agent-device/*` subpath sources, so a doc snippet that no diff --git a/test/integration/daemon-leak-oracle-cli.test.ts b/test/integration/daemon-leak-oracle-cli.test.ts index d68fdf12b4..3c7645c7ef 100644 --- a/test/integration/daemon-leak-oracle-cli.test.ts +++ b/test/integration/daemon-leak-oracle-cli.test.ts @@ -3,7 +3,8 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { runCmdSync, readProcessCommand, readProcessStartTime } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; +import { readProcessCommand, readProcessStartTime } from '@agent-device/host-kit/process'; // #1781 B1: the oracle's `after-close` checkpoint is only meaningful when it can // name the sessions that closed — without them it would accept every unfinalized diff --git a/test/integration/daemon-replace-exit-flush.test.ts b/test/integration/daemon-replace-exit-flush.test.ts index 6331d51972..59e02e7120 100644 --- a/test/integration/daemon-replace-exit-flush.test.ts +++ b/test/integration/daemon-replace-exit-flush.test.ts @@ -5,7 +5,7 @@ import os from 'node:os'; import path from 'node:path'; import { skipWhenLoopbackUnavailable } from '../../src/__tests__/test-utils/loopback.ts'; import { stopProcessForTakeover } from '../../src/daemon/daemon-process.ts'; -import { isProcessAlive } from '@agent-device/host-kit/exec'; +import { isProcessAlive } from '@agent-device/host-kit/process'; import { assertNoDaemonLeaks } from './support/daemon-leak-oracle.ts'; import { runCliJson } from './test-helpers.ts'; diff --git a/test/integration/installed-package-metro.test.ts b/test/integration/installed-package-metro.test.ts index d1d8ba0ece..ce663509f0 100644 --- a/test/integration/installed-package-metro.test.ts +++ b/test/integration/installed-package-metro.test.ts @@ -8,7 +8,7 @@ import path from 'node:path'; import type { Duplex } from 'node:stream'; import { fileURLToPath } from 'node:url'; import { closeLoopbackServer, listenOnLoopback } from '../../src/__tests__/test-utils/loopback.ts'; -import { runCmd, runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdSync } from '@agent-device/host-kit/command'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..'); const SUBPROCESS_TIMEOUT_MS = 120_000; diff --git a/test/integration/limrun-public-types.test.ts b/test/integration/limrun-public-types.test.ts index c91d55b68e..6accf62a49 100644 --- a/test/integration/limrun-public-types.test.ts +++ b/test/integration/limrun-public-types.test.ts @@ -3,7 +3,7 @@ import fs from 'node:fs'; import path from 'node:path'; import test from 'node:test'; import { fileURLToPath } from 'node:url'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..'); const TSC_BIN = path.join(repoRoot, 'node_modules/.bin/tsc'); diff --git a/test/integration/provider-scenarios/active-session-script-publication.test.ts b/test/integration/provider-scenarios/active-session-script-publication.test.ts index 7af4418f83..927bb060d8 100644 --- a/test/integration/provider-scenarios/active-session-script-publication.test.ts +++ b/test/integration/provider-scenarios/active-session-script-publication.test.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; -import { emitDiagnostic } from '@agent-device/host-kit/exec'; +import { emitDiagnostic } from '@agent-device/host-kit/diagnostics'; import { INTERNAL_COMMANDS } from '../../../src/command-catalog.ts'; import { test } from 'vitest'; import { assertRpcError, assertRpcOk } from './assertions.ts'; diff --git a/test/integration/provider-scenarios/android-world.ts b/test/integration/provider-scenarios/android-world.ts index bc88ad9858..4c349a22c8 100644 --- a/test/integration/provider-scenarios/android-world.ts +++ b/test/integration/provider-scenarios/android-world.ts @@ -14,7 +14,7 @@ import { ANDROID_SNAPSHOT_HELPER_FIXTURE_ARTIFACT, androidSnapshotHelperOutput, } from '../../../src/__tests__/test-utils/android-snapshot-helper.ts'; -import { runCmd, runCmdBackground } from '@agent-device/host-kit/exec'; +import { runCmd, runCmdBackground } from '@agent-device/host-kit/command'; import { validPng } from './assertions.ts'; import { PROVIDER_SCENARIO_ANDROID } from './fixtures.ts'; import { diff --git a/test/integration/provider-scenarios/harness.ts b/test/integration/provider-scenarios/harness.ts index b8a0e99433..60d2bbacc8 100644 --- a/test/integration/provider-scenarios/harness.ts +++ b/test/integration/provider-scenarios/harness.ts @@ -22,7 +22,8 @@ import { trackDownloadableArtifact } from '../../../src/daemon/artifact-tracking import { LeaseRegistry } from '../../../src/daemon/lease-registry.ts'; import { SessionStore } from '../../../src/daemon/session-store.ts'; import type { DaemonRequest, DaemonResponse, SessionState } from '../../../src/daemon/types.ts'; -import { runCmdBackground, createOwnedProcessRecordStore } from '@agent-device/host-kit/exec'; +import { runCmdBackground } from '@agent-device/host-kit/command'; +import { createOwnedProcessRecordStore } from '@agent-device/host-kit/process'; import { withClientReplayScriptSources } from '../../../src/__tests__/test-utils/replay-script-source.ts'; import type { DeviceInventoryProvider, diff --git a/test/integration/provider-scenarios/providers.ts b/test/integration/provider-scenarios/providers.ts index c858c16236..1da7e848f9 100644 --- a/test/integration/provider-scenarios/providers.ts +++ b/test/integration/provider-scenarios/providers.ts @@ -6,7 +6,7 @@ import type { AppleToolProvider, AppleToolSubcommandExecutor, } from '../../../src/platforms/apple/core/tool-provider.ts'; -import type { ExecResult } from '@agent-device/host-kit/exec'; +import { type ExecResult } from '@agent-device/host-kit/command'; import type { ProviderScenarioTranscript } from './transcript.ts'; export type FlatToolCall = [string, ...string[]]; diff --git a/test/integration/smoke-clean-xcuitest-derived.test.ts b/test/integration/smoke-clean-xcuitest-derived.test.ts index 9114f95bad..14299151a6 100644 --- a/test/integration/smoke-clean-xcuitest-derived.test.ts +++ b/test/integration/smoke-clean-xcuitest-derived.test.ts @@ -4,7 +4,7 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..'); const scriptPath = path.join(repoRoot, 'scripts', 'clean-xcuitest-derived.mjs'); diff --git a/test/integration/smoke-cli.test.ts b/test/integration/smoke-cli.test.ts index b0055d21a1..8d98b19bc2 100644 --- a/test/integration/smoke-cli.test.ts +++ b/test/integration/smoke-cli.test.ts @@ -1,6 +1,6 @@ import test from 'node:test'; import assert from 'node:assert/strict'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; function runCli(args: string[]): { status: number; stdout: string; stderr: string } { const result = runCmdSync( diff --git a/test/integration/smoke-daemon-clean.test.ts b/test/integration/smoke-daemon-clean.test.ts index 7a861eb6f2..8a814cce3b 100644 --- a/test/integration/smoke-daemon-clean.test.ts +++ b/test/integration/smoke-daemon-clean.test.ts @@ -4,7 +4,8 @@ import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; import { skipWhenLoopbackUnavailable } from '../../src/__tests__/test-utils/loopback.ts'; -import { runCmdSync, isProcessAlive } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; +import { isProcessAlive } from '@agent-device/host-kit/process'; import { stopProcessForTakeover } from '../../src/daemon/daemon-process.ts'; import { assertNoDaemonLeaks } from './support/daemon-leak-oracle.ts'; diff --git a/test/integration/smoke-web-platform.test.ts b/test/integration/smoke-web-platform.test.ts index 191dd1fea6..d6f2b4cee2 100644 --- a/test/integration/smoke-web-platform.test.ts +++ b/test/integration/smoke-web-platform.test.ts @@ -28,7 +28,7 @@ import { listHostProcesses, readProcessStartTime, stopPidsWithEscalation, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; const TEST_NAME = 'live web platform e2e smoke'; const SHUTDOWN_TEST_NAME = 'live web platform e2e daemon-shutdown browser cleanup'; diff --git a/test/integration/support/daemon-leak-model.ts b/test/integration/support/daemon-leak-model.ts index fcfced1cd3..a3f9cc4a8f 100644 --- a/test/integration/support/daemon-leak-model.ts +++ b/test/integration/support/daemon-leak-model.ts @@ -27,7 +27,7 @@ // still live, or no longer matches and therefore cannot be // proved dead. The latter fails closed rather than allowing // pid reuse to turn unknown evidence into a green checkpoint. -import { uniquePositivePids } from '@agent-device/host-kit/exec'; +import { uniquePositivePids } from '@agent-device/host-kit/process'; import type { OwnedProcessRecord } from '@agent-device/contracts/platform-runtime-host'; export type DaemonLeakPhase = 'after-close' | 'after-shutdown'; diff --git a/test/integration/support/daemon-leak-oracle.ts b/test/integration/support/daemon-leak-oracle.ts index 7439ed93b6..cb1f7b245a 100644 --- a/test/integration/support/daemon-leak-oracle.ts +++ b/test/integration/support/daemon-leak-oracle.ts @@ -9,7 +9,7 @@ import { readHostProcessIdentityObservations, readProcessCommand, readOwnedProcessRecordFile, -} from '@agent-device/host-kit/exec'; +} from '@agent-device/host-kit/process'; import { AppError } from '@agent-device/kernel/errors'; import type { OwnedProcessRecord } from '@agent-device/contracts/platform-runtime-host'; diff --git a/test/integration/test-helpers.ts b/test/integration/test-helpers.ts index d7affeea05..1356e55889 100644 --- a/test/integration/test-helpers.ts +++ b/test/integration/test-helpers.ts @@ -2,7 +2,7 @@ import assert from 'node:assert/strict'; import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'; import path from 'node:path'; import { PNG } from '@agent-device/capture-kit/png'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { type CliJsonResult, formatResultDebug, runSourceCliJsonSync } from './cli-json.ts'; const RECORDING_INSPECT_TIMEOUT_MS = 60_000; diff --git a/test/output-economy/output-economy.baseline.test.ts b/test/output-economy/output-economy.baseline.test.ts index c5c1eabf53..53460c793f 100644 --- a/test/output-economy/output-economy.baseline.test.ts +++ b/test/output-economy/output-economy.baseline.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs'; import path from 'node:path'; import { describe, expect, test } from 'vitest'; import { defaultHintForCode, retriableForErrorCode } from '@agent-device/kernel/errors'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { findEconomyBudgetIncreases, formatEconomyBudgetIncreases, diff --git a/test/output-economy/owner-files-no-leak.test.ts b/test/output-economy/owner-files-no-leak.test.ts index 7c4d33e39c..e7bf23ac46 100644 --- a/test/output-economy/owner-files-no-leak.test.ts +++ b/test/output-economy/owner-files-no-leak.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from 'vitest'; import fs from 'node:fs'; import path from 'node:path'; -import { runCmdSync } from '@agent-device/host-kit/exec'; +import { runCmdSync } from '@agent-device/host-kit/command'; import { COMMAND_OWNER_FILES } from '../../src/core/command-descriptor/owner-files.ts'; import { getDaemonRouteOwnerFiles } from '../../src/daemon/route-owner-files.ts'; From bc8ae932b688e5843096a93e8959ced2bd1499a2 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 19:15:42 +0000 Subject: [PATCH 3/8] chore: drop the migration inventories and trim the touched comments Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- packages/kernel/src/scoped-provider.ts | 4 +- scratch-exports.json | 198 -------------------- scratch-symbol-map.json | 148 --------------- scripts/layering/package-boundaries.test.ts | 5 - src/__tests__/eager-closure-budgets.ts | 6 - 5 files changed, 1 insertion(+), 360 deletions(-) delete mode 100644 scratch-exports.json delete mode 100644 scratch-symbol-map.json diff --git a/packages/kernel/src/scoped-provider.ts b/packages/kernel/src/scoped-provider.ts index 40bb59086c..32615dbd07 100644 --- a/packages/kernel/src/scoped-provider.ts +++ b/packages/kernel/src/scoped-provider.ts @@ -28,9 +28,7 @@ export function createScopedProvider( /** * Wraps every method call on `target` in `runScope`, so leaf code below the - * method resolves scope-injected state (AsyncLocalStorage transports) instead - * of the local default. Shared by the Android adb-provider and Apple - * runner-provider interactor seams. + * method resolves scope-injected state instead of the local default. */ export function withMethodScope( target: T, diff --git a/scratch-exports.json b/scratch-exports.json deleted file mode 100644 index bbba4dbb14..0000000000 --- a/scratch-exports.json +++ /dev/null @@ -1,198 +0,0 @@ -{ - "archive-extraction-tar": [["extractTarArchive", "value"]], - "archive-extraction-zip": [["extractZipArchive", "value"]], - "archive-extraction": [ - ["SupportedArchiveType", "type"], - ["ExtractArchiveOptions", "type"], - ["extractArchiveSafely", "value"], - ["archiveTypeFromPath", "value"] - ], - "archive-safety": [ - ["ArchiveManifestEntry", "type"], - ["ArchiveBudget", "value"], - ["reserveArchiveManifest", "value"], - ["sameArchiveManifestEntry", "value"], - ["normalizeArchiveEntryName", "value"], - ["resolveArchiveOutputPath", "value"], - ["archiveError", "value"] - ], - "artifact-limits": [ - ["MAX_ARTIFACT_COMPRESSED_BYTES", "value"], - ["MAX_ARCHIVE_EXPANDED_BYTES", "value"], - ["MAX_ARCHIVE_ENTRIES", "value"], - ["MAX_ARCHIVE_NESTING_DEPTH", "value"] - ], - "atomic-file": [ - ["AtomicPublishMode", "type"], - ["publishFileSync", "value"], - ["withAtomicPublishTempPathSync", "value"], - ["isAtomicPublishTemporaryPath", "value"] - ], - "byte-limit-stream": [ - ["ByteLimitStream", "type"], - ["createByteLimitStream", "value"] - ], - "device-isolation": [ - ["resolveIosSimulatorDeviceSetPath", "value"], - ["parseSerialAllowlist", "value"], - ["resolveAndroidSerialAllowlist", "value"] - ], - "diagnostics": [ - ["createRequestId", "value"], - ["withDiagnosticsScope", "value"], - ["updateDiagnosticsScope", "value"], - ["getDiagnosticsMeta", "value"], - ["registerDiagnosticSensitiveValue", "value"], - ["countDiagnosticEventsByPhase", "value"], - ["emitDiagnostic", "value"], - ["withDiagnosticTimer", "value"], - ["FlushedDiagnosticsRecord", "type"], - ["flushDiagnosticsToSessionFile", "value"] - ], - "env-map": [["EnvMap", "type"]], - "exec": [ - ["ExecResult", "type"], - ["ExecOptions", "type"], - ["ExecBackgroundResult", "type"], - ["ExecDetachedExit", "type"], - ["ExecDetachedProcess", "type"], - ["ExecBackgroundOptions", "type"], - ["CommandExecutorOverride", "type"], - ["withCommandExecutorOverride", "value"], - ["withoutCommandExecutorOverride", "value"], - ["runCmd", "value"], - ["runCmdStreaming", "value"], - ["coerceExecResult", "value"], - ["whichCmd", "value"], - ["resolveExecutableOverridePath", "value"], - ["resolveFileOverridePath", "value"], - ["runCmdSync", "value"], - ["runCmdDetached", "value"], - ["runCmdDetachedMonitored", "value"], - ["runCmdBackground", "value"], - ["requireExecSuccess", "value"], - ["execFailureDetails", "value"], - ["isExecutablePath", "value"] - ], - "host-process": [ - ["HostProcessInfo", "type"], - ["HostProcessIdentityObservation", "type"], - ["ListHostProcessesOptions", "type"], - ["StopPidsWithEscalationOptions", "type"], - ["isProcessAlive", "value"], - ["isProcessGroupAlive", "value"], - ["readProcessStartTime", "value"], - ["readProcessCommand", "value"], - ["isProcessZombie", "value"], - ["readHostProcessIdentityObservations", "value"], - ["parseHostProcessList", "value"], - ["listHostProcesses", "value"], - ["expandProcessTree", "value"], - ["uniquePositivePids", "value"], - ["signalPidsBestEffort", "value"], - ["signalProcessGroupBestEffort", "value"], - ["waitForProcessExit", "value"], - ["stopPidsWithEscalation", "value"] - ], - "location-coordinates": [ - ["LocationCoordinateLabel", "type"], - ["LocationCoordinates", "type"], - ["readLocationCoordinate", "value"], - ["requireLocationCoordinates", "value"] - ], - "method-scope": [["withMethodScope", "value"]], - "owned-process-reaper": [ - ["OwnedProcessReapSummary", "type"], - ["reapOwnedProcessRecordsAtStartup", "value"] - ], - "owned-process-record": [ - ["OwnedProcessRecordRead", "type"], - ["OwnedProcessRecordStore", "type"], - ["createOwnedProcessRecordStore", "value"], - ["readOwnedProcessRecordFile", "value"] - ], - "owner-identity": [ - ["OwnerIdentity", "type"], - ["OwnerLiveness", "type"], - ["readCurrentOwnerIdentity", "value"], - ["ownerIdentityMatches", "value"], - ["ownerIdentityDiffers", "value"], - ["classifyOwnerLiveness", "value"], - ["classifyOwnerLivenessFromObservation", "value"] - ], - "parsing": [ - ["readRequiredString", "value"], - ["readOptionalString", "value"], - ["readNullableString", "value"], - ["readRequiredNumber", "value"], - ["readRequiredPlatform", "value"], - ["readRequiredDeviceKind", "value"], - ["readDeviceTarget", "value"], - ["parseRect", "value"], - ["parsePoint", "value"], - ["asRecord", "value"], - ["isRecord", "value"], - ["asOptionalRecord", "value"], - ["stripUndefined", "value"], - ["splitNonEmptyTrimmedLines", "value"] - ], - "path-resolution": [ - ["expandUserHomePath", "value"], - ["resolveUserPath", "value"] - ], - "process-lock": [ - ["ProcessLockOwner", "type"], - ["acquireProcessLock", "value"] - ], - "project-root": [["resolveAgentDeviceProjectRoot", "value"]], - "request-cancel": [ - ["RequestAbortRegistration", "type"], - ["resolveRequestTrackingId", "value"], - ["registerRequestAbort", "value"], - ["markRequestCanceled", "value"], - ["clearRequestCanceled", "value"], - ["clearRequestAbortRegistration", "value"], - ["isRequestCanceled", "value"], - ["getRequestSignal", "value"], - ["throwIfRequestCanceled", "value"] - ], - "request-progress": [ - ["withRequestProgressSink", "value"], - ["emitRequestProgress", "value"] - ], - "retry": [ - ["isEnvTruthy", "value"], - ["Deadline", "value"], - ["retryWithPolicy", "value"] - ], - "scoped-provider": [ - ["ScopedProvider", "type"], - ["createScopedProvider", "value"] - ], - "shell-quote": [ - ["shellQuote", "value"], - ["shellQuoteIfNeeded", "value"] - ], - "source-value": [ - ["SourceValueDefinition", "type"], - ["buildPrimaryEnvVarName", "value"], - ["parseSourceValue", "value"], - ["parseBooleanLiteral", "value"] - ], - "success-text": [ - ["successText", "value"], - ["withSuccessText", "value"], - ["readCommandMessage", "value"] - ], - "timeouts": [["sleep", "value"]], - "ttl-memo": [ - ["TtlMemo", "type"], - ["TtlMemoOptions", "type"], - ["createTtlMemo", "value"], - ["resetAllProcessMemosForTests", "value"] - ], - "version": [ - ["readVersion", "value"], - ["findProjectRoot", "value"] - ] -} diff --git a/scratch-symbol-map.json b/scratch-symbol-map.json deleted file mode 100644 index 2329c52aec..0000000000 --- a/scratch-symbol-map.json +++ /dev/null @@ -1,148 +0,0 @@ -{ - "ExecResult": "@agent-device/host-kit/command", - "ExecOptions": "@agent-device/host-kit/command", - "ExecBackgroundResult": "@agent-device/host-kit/command", - "ExecDetachedExit": "@agent-device/host-kit/command", - "ExecDetachedProcess": "@agent-device/host-kit/command", - "ExecBackgroundOptions": "@agent-device/host-kit/command", - "CommandExecutorOverride": "@agent-device/host-kit/command", - "withCommandExecutorOverride": "@agent-device/host-kit/command", - "withoutCommandExecutorOverride": "@agent-device/host-kit/command", - "runCmd": "@agent-device/host-kit/command", - "runCmdStreaming": "@agent-device/host-kit/command", - "coerceExecResult": "@agent-device/host-kit/command", - "whichCmd": "@agent-device/host-kit/command", - "resolveExecutableOverridePath": "@agent-device/host-kit/command", - "resolveFileOverridePath": "@agent-device/host-kit/command", - "runCmdSync": "@agent-device/host-kit/command", - "runCmdDetached": "@agent-device/host-kit/command", - "runCmdDetachedMonitored": "@agent-device/host-kit/command", - "runCmdBackground": "@agent-device/host-kit/command", - "requireExecSuccess": "@agent-device/host-kit/command", - "execFailureDetails": "@agent-device/host-kit/command", - "isExecutablePath": "@agent-device/host-kit/command", - "shellQuote": "@agent-device/host-kit/command", - "shellQuoteIfNeeded": "@agent-device/host-kit/command", - "HostProcessInfo": "@agent-device/host-kit/process", - "HostProcessIdentityObservation": "@agent-device/host-kit/process", - "ListHostProcessesOptions": "@agent-device/host-kit/process", - "StopPidsWithEscalationOptions": "@agent-device/host-kit/process", - "isProcessAlive": "@agent-device/host-kit/process", - "isProcessGroupAlive": "@agent-device/host-kit/process", - "readProcessStartTime": "@agent-device/host-kit/process", - "readProcessCommand": "@agent-device/host-kit/process", - "isProcessZombie": "@agent-device/host-kit/process", - "readHostProcessIdentityObservations": "@agent-device/host-kit/process", - "parseHostProcessList": "@agent-device/host-kit/process", - "listHostProcesses": "@agent-device/host-kit/process", - "expandProcessTree": "@agent-device/host-kit/process", - "uniquePositivePids": "@agent-device/host-kit/process", - "signalPidsBestEffort": "@agent-device/host-kit/process", - "signalProcessGroupBestEffort": "@agent-device/host-kit/process", - "waitForProcessExit": "@agent-device/host-kit/process", - "stopPidsWithEscalation": "@agent-device/host-kit/process", - "OwnerIdentity": "@agent-device/host-kit/process", - "OwnerLiveness": "@agent-device/host-kit/process", - "readCurrentOwnerIdentity": "@agent-device/host-kit/process", - "ownerIdentityMatches": "@agent-device/host-kit/process", - "ownerIdentityDiffers": "@agent-device/host-kit/process", - "classifyOwnerLiveness": "@agent-device/host-kit/process", - "classifyOwnerLivenessFromObservation": "@agent-device/host-kit/process", - "OwnedProcessRecordRead": "@agent-device/host-kit/process", - "OwnedProcessRecordStore": "@agent-device/host-kit/process", - "createOwnedProcessRecordStore": "@agent-device/host-kit/process", - "readOwnedProcessRecordFile": "@agent-device/host-kit/process", - "OwnedProcessReapSummary": "@agent-device/host-kit/process", - "reapOwnedProcessRecordsAtStartup": "@agent-device/host-kit/process", - "createRequestId": "@agent-device/host-kit/diagnostics", - "withDiagnosticsScope": "@agent-device/host-kit/diagnostics", - "updateDiagnosticsScope": "@agent-device/host-kit/diagnostics", - "getDiagnosticsMeta": "@agent-device/host-kit/diagnostics", - "registerDiagnosticSensitiveValue": "@agent-device/host-kit/diagnostics", - "countDiagnosticEventsByPhase": "@agent-device/host-kit/diagnostics", - "emitDiagnostic": "@agent-device/host-kit/diagnostics", - "withDiagnosticTimer": "@agent-device/host-kit/diagnostics", - "FlushedDiagnosticsRecord": "@agent-device/host-kit/diagnostics", - "flushDiagnosticsToSessionFile": "@agent-device/host-kit/diagnostics", - "isEnvTruthy": "@agent-device/host-kit/retry", - "Deadline": "@agent-device/host-kit/retry", - "retryWithPolicy": "@agent-device/host-kit/retry", - "sleep": "@agent-device/host-kit/retry", - "SupportedArchiveType": "@agent-device/host-kit/archive", - "ExtractArchiveOptions": "@agent-device/host-kit/archive", - "extractArchiveSafely": "@agent-device/host-kit/archive", - "archiveTypeFromPath": "@agent-device/host-kit/archive", - "extractTarArchive": "@agent-device/host-kit/archive", - "extractZipArchive": "@agent-device/host-kit/archive", - "ArchiveManifestEntry": "@agent-device/host-kit/archive", - "ArchiveBudget": "@agent-device/host-kit/archive", - "reserveArchiveManifest": "@agent-device/host-kit/archive", - "sameArchiveManifestEntry": "@agent-device/host-kit/archive", - "normalizeArchiveEntryName": "@agent-device/host-kit/archive", - "resolveArchiveOutputPath": "@agent-device/host-kit/archive", - "archiveError": "@agent-device/host-kit/archive", - "MAX_ARTIFACT_COMPRESSED_BYTES": "@agent-device/host-kit/archive", - "MAX_ARCHIVE_EXPANDED_BYTES": "@agent-device/host-kit/archive", - "MAX_ARCHIVE_ENTRIES": "@agent-device/host-kit/archive", - "MAX_ARCHIVE_NESTING_DEPTH": "@agent-device/host-kit/archive", - "ByteLimitStream": "@agent-device/host-kit/archive", - "createByteLimitStream": "@agent-device/host-kit/archive", - "AtomicPublishMode": "@agent-device/host-kit/file", - "publishFileSync": "@agent-device/host-kit/file", - "withAtomicPublishTempPathSync": "@agent-device/host-kit/file", - "isAtomicPublishTemporaryPath": "@agent-device/host-kit/file", - "ProcessLockOwner": "@agent-device/host-kit/file", - "acquireProcessLock": "@agent-device/host-kit/file", - "expandUserHomePath": "@agent-device/host-kit/file", - "resolveUserPath": "@agent-device/host-kit/file", - "readVersion": "@agent-device/host-kit/version", - "findProjectRoot": "@agent-device/host-kit/version", - "resolveAgentDeviceProjectRoot": "@agent-device/host-kit/version", - "RequestAbortRegistration": "@agent-device/host-kit/request", - "resolveRequestTrackingId": "@agent-device/host-kit/request", - "registerRequestAbort": "@agent-device/host-kit/request", - "markRequestCanceled": "@agent-device/host-kit/request", - "clearRequestCanceled": "@agent-device/host-kit/request", - "clearRequestAbortRegistration": "@agent-device/host-kit/request", - "isRequestCanceled": "@agent-device/host-kit/request", - "getRequestSignal": "@agent-device/host-kit/request", - "throwIfRequestCanceled": "@agent-device/host-kit/request", - "withRequestProgressSink": "@agent-device/host-kit/request", - "emitRequestProgress": "@agent-device/host-kit/request", - "readRequiredString": "@agent-device/kernel/record", - "readOptionalString": "@agent-device/kernel/record", - "readNullableString": "@agent-device/kernel/record", - "readRequiredNumber": "@agent-device/kernel/record", - "readRequiredPlatform": "@agent-device/kernel/record", - "readRequiredDeviceKind": "@agent-device/kernel/record", - "readDeviceTarget": "@agent-device/kernel/record", - "parseRect": "@agent-device/kernel/record", - "parsePoint": "@agent-device/kernel/record", - "asRecord": "@agent-device/kernel/record", - "isRecord": "@agent-device/kernel/record", - "asOptionalRecord": "@agent-device/kernel/record", - "stripUndefined": "@agent-device/kernel/record", - "splitNonEmptyTrimmedLines": "@agent-device/kernel/record", - "SourceValueDefinition": "@agent-device/kernel/source-value", - "buildPrimaryEnvVarName": "@agent-device/kernel/source-value", - "parseSourceValue": "@agent-device/kernel/source-value", - "parseBooleanLiteral": "@agent-device/kernel/source-value", - "EnvMap": "@agent-device/kernel/source-value", - "successText": "@agent-device/kernel/success-text", - "withSuccessText": "@agent-device/kernel/success-text", - "readCommandMessage": "@agent-device/kernel/success-text", - "TtlMemo": "@agent-device/kernel/ttl-memo", - "TtlMemoOptions": "@agent-device/kernel/ttl-memo", - "createTtlMemo": "@agent-device/kernel/ttl-memo", - "resetAllProcessMemosForTests": "@agent-device/kernel/ttl-memo", - "ScopedProvider": "@agent-device/kernel/scoped-provider", - "createScopedProvider": "@agent-device/kernel/scoped-provider", - "withMethodScope": "@agent-device/kernel/scoped-provider", - "LocationCoordinateLabel": "@agent-device/kernel/location-coordinates", - "LocationCoordinates": "@agent-device/kernel/location-coordinates", - "readLocationCoordinate": "@agent-device/kernel/location-coordinates", - "requireLocationCoordinates": "@agent-device/kernel/location-coordinates", - "resolveIosSimulatorDeviceSetPath": "@agent-device/kernel/device-isolation", - "parseSerialAllowlist": "@agent-device/kernel/device-isolation", - "resolveAndroidSerialAllowlist": "@agent-device/kernel/device-isolation" -} diff --git a/scripts/layering/package-boundaries.test.ts b/scripts/layering/package-boundaries.test.ts index 99c8ec13f8..42037013eb 100644 --- a/scripts/layering/package-boundaries.test.ts +++ b/scripts/layering/package-boundaries.test.ts @@ -453,8 +453,6 @@ test('the real tree parses, declares, and passes R11', () => { true, 'capture-kit stays a private implementation package', ); - // #2082 W1 host-mechanics subpaths; any further subpath widens this key list - // and fails the assertion, same as the platform-apple pin below. assert.deepEqual([...captureKitPackage.exportTargets.keys()].sort(), [ '@agent-device/capture-kit', '@agent-device/capture-kit/mobile-snapshot-semantics', @@ -482,9 +480,6 @@ test('the real tree parses, declares, and passes R11', () => { true, 'host-kit stays a private implementation package', ); - // One narrow capability port over the host machine per export; any further - // subpath widens this key list and fails the assertion, same as the - // capture-kit pin above. assert.deepEqual([...hostKitPackage.exportTargets.keys()].sort(), [ '@agent-device/host-kit/archive', '@agent-device/host-kit/command', diff --git a/src/__tests__/eager-closure-budgets.ts b/src/__tests__/eager-closure-budgets.ts index da0bbf96ae..5cbf0424e4 100644 --- a/src/__tests__/eager-closure-budgets.ts +++ b/src/__tests__/eager-closure-budgets.ts @@ -135,8 +135,6 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/capture-kit/src/snapshot-quality-verdict.ts': 2, // --- @agent-device/host-kit --- - // One capability port per export: the row is what a consumer of that - // capability evaluates, so a port that grew unrelated mechanics shows here. 'packages/host-kit/src/archive.ts': 9, 'packages/host-kit/src/command.ts': 7, 'packages/host-kit/src/diagnostics.ts': 3, @@ -211,7 +209,6 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/contracts/src/keyboard.ts': 1, 'packages/contracts/src/logs-runtime-plan.ts': 5, 'packages/contracts/src/managed-web-backend.ts': 1, - // #2082 W1: snapshot semantics moved out of root src. 'packages/contracts/src/navigation.ts': 1, 'packages/contracts/src/network-runtime-plan.ts': 5, 'packages/contracts/src/network-runtime.ts': 1, @@ -259,10 +256,8 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/kernel/src/errors.ts': 2, // Added by #2041: keyed async lock moved from src/utils for the extracted IME lifecycle. 'packages/kernel/src/keyed-lock.ts': 1, - // #2082 W1: geometry/vocabulary sunk below contracts. 'packages/kernel/src/rect-center.ts': 2, 'packages/kernel/src/rect.ts': 1, - // #2082 W1: pure primitives that were never host mechanics. 'packages/kernel/src/device-isolation.ts': 1, 'packages/kernel/src/location-coordinates.ts': 3, 'packages/kernel/src/record.ts': 3, @@ -275,7 +270,6 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ 'packages/kernel/src/snapshot.ts': 1, // --- @agent-device/maestro --- - // +1 in #2082 W1: internal/shared.ts reuses @agent-device/kernel/rect-center. 'packages/maestro/src/index.ts': 106, // --- @agent-device/platform-*: ADR-0019's metadata-eager/implementation-lazy façades. Each From c8b6eb19ef687d5ec493466d24306325de620b71 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 19:37:22 +0000 Subject: [PATCH 4/8] docs: trim the touched host-kit and mutation-lane comments Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- .../host-kit/src/internal/project-root.ts | 3 +-- packages/host-kit/src/internal/version.ts | 5 +--- scripts/mutation/workspace-aliases.test.ts | 4 +-- vitest.mutation.config.ts | 25 +++++-------------- 4 files changed, 9 insertions(+), 28 deletions(-) diff --git a/packages/host-kit/src/internal/project-root.ts b/packages/host-kit/src/internal/project-root.ts index d41846d5a2..d2cadf5cf7 100644 --- a/packages/host-kit/src/internal/project-root.ts +++ b/packages/host-kit/src/internal/project-root.ts @@ -1,7 +1,6 @@ import fs from 'node:fs'; import path from 'node:path'; -/** Walks up from `startDirectory` to the manifest named `agent-device`; the first manifest found is the fallback for renamed or vendored installs. */ export function resolveAgentDeviceProjectRoot(startDirectory: string): string { let current = startDirectory; let nearest: string | null = null; @@ -13,7 +12,7 @@ export function resolveAgentDeviceProjectRoot(startDirectory: string): string { const name = (JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as { name?: unknown }).name; if (name === 'agent-device') return current; } catch { - // an unreadable manifest is not the root; keep walking + // Unreadable manifests are not the root. } } current = path.dirname(current); diff --git a/packages/host-kit/src/internal/version.ts b/packages/host-kit/src/internal/version.ts index 76bffe9cf1..85fd105cb4 100644 --- a/packages/host-kit/src/internal/version.ts +++ b/packages/host-kit/src/internal/version.ts @@ -4,7 +4,6 @@ import { fileURLToPath } from 'node:url'; import { resolveAgentDeviceProjectRoot } from './project-root.ts'; import { createTtlMemo } from '@agent-device/kernel/ttl-memo'; -// Immutable for a process's lifetime, so resolved once; the process-memo reset clears them between tests. const versionMemo = createTtlMemo(); const projectRootMemo = createTtlMemo<'self', string>(); @@ -18,9 +17,7 @@ export function readVersion(root: string = findProjectRoot()): string { version?: unknown; }; } catch { - // An absent or unreadable package.json is not memoized: the caller may be - // asking about a root that is still being materialized (a runner or helper - // package), and '0.0.0' must not stick to it for the rest of the process. + // Not memoized: the root may still be materializing. return '0.0.0'; } const version = typeof pkg.version === 'string' ? pkg.version : '0.0.0'; diff --git a/scripts/mutation/workspace-aliases.test.ts b/scripts/mutation/workspace-aliases.test.ts index f8e5eeaaa7..f172da8b78 100644 --- a/scripts/mutation/workspace-aliases.test.ts +++ b/scripts/mutation/workspace-aliases.test.ts @@ -27,9 +27,7 @@ test('Stryker aliases every exported workspace subpath exactly', () => { }); test('disk manifests alias an untracked sandbox copy the tracked reader cannot see', () => { - // Inside the repository tree, like the real sandbox under .tmp/stryker: - // `git ls-files` runs but lists nothing, which is the exact blindness the - // disk reader exists for. + // Must sit inside the repository tree: `git ls-files` has to run and list nothing. fs.mkdirSync(path.join(repoRoot, '.tmp'), { recursive: true }); const sandboxRoot = fs.mkdtempSync(path.join(repoRoot, '.tmp', 'stryker-sandbox-fixture-')); try { diff --git a/vitest.mutation.config.ts b/vitest.mutation.config.ts index 9491794ad8..3f0260aae4 100644 --- a/vitest.mutation.config.ts +++ b/vitest.mutation.config.ts @@ -7,31 +7,18 @@ import { SERIALIZED_TESTS, SETUP_FILES } from './vitest.config.ts'; const repoRoot = path.dirname(fileURLToPath(import.meta.url)); -// Workspace-package aliases for the Stryker sandbox (#1490 W0). Stryker copies -// the tree into .tmp/stryker and symlinks node_modules back to the real repo, -// so a `@agent-device/*` specifier resolved through pnpm's link escapes the -// sandbox: mutants written into the sandbox copy never load, and -// `vitest related` finds no tests for a mutated package file. Aliasing each -// EXPORTED specifier to its source file — resolved relative to this config, -// which Stryker copies into the sandbox — keeps resolution inside the mutated -// tree. Entries come from the shared exports-map reader, never a wildcard, so -// this cannot resolve package internals the boundary forbids (R11). +// Every `@agent-device/*` specifier must resolve to source inside the sandbox, +// or mutants load from the real tree through pnpm's node_modules link. Entries +// come from the exports-map reader, never a wildcard, so this cannot reach +// package internals (R11). const inStrykerSandbox = repoRoot.includes(path.join('.tmp', 'stryker')); const workspaceAliases = workspaceSourceAliases( repoRoot, inStrykerSandbox ? 'disk-manifests' : 'tracked-manifests', ); -// Test scope for the decision-kernel mutation lane (issue #1415). -// -// `scripts/mutation/run.ts` derives the per-run scope from Vitest's module graph -// (`vitest related` over the mutated files) and hands it over through -// AGENT_DEVICE_MUTATION_TEST_FILES; the fallback is the deterministic unit suite, -// which keeps `pnpm exec stryker run` usable by hand. Excluded either way: the -// real-subprocess-spawn tests (SERIALIZED_TESTS — #1823, only `fuzz-worker` still -// runs them in a serialized Vitest project) and the CLI-capture tests — see -// scripts/mutation/test-scope.ts for why, and why excluding them cannot hide a -// surviving mutant. +// The per-run scope arrives through AGENT_DEVICE_MUTATION_TEST_FILES; the +// unit suite is the fallback that keeps `pnpm exec stryker run` usable by hand. const scope = readTestScope(); export default defineConfig({ From a7c8df6e8bb77f9c791a7f971381b136a38f40b6 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 20:09:24 +0000 Subject: [PATCH 5/8] docs: keep tool directives only in the touched files Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- packages/host-kit/src/internal/project-root.ts | 4 +--- packages/host-kit/src/internal/tmp-dir.fixtures.ts | 8 -------- packages/host-kit/src/internal/version.ts | 1 - packages/kernel/src/collections.ts | 6 +----- scripts/mutation/workspace-aliases.test.ts | 1 - vitest.mutation.config.ts | 6 ------ 6 files changed, 2 insertions(+), 24 deletions(-) diff --git a/packages/host-kit/src/internal/project-root.ts b/packages/host-kit/src/internal/project-root.ts index d2cadf5cf7..7a14754025 100644 --- a/packages/host-kit/src/internal/project-root.ts +++ b/packages/host-kit/src/internal/project-root.ts @@ -11,9 +11,7 @@ export function resolveAgentDeviceProjectRoot(startDirectory: string): string { try { const name = (JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as { name?: unknown }).name; if (name === 'agent-device') return current; - } catch { - // Unreadable manifests are not the root. - } + } catch {} } current = path.dirname(current); } diff --git a/packages/host-kit/src/internal/tmp-dir.fixtures.ts b/packages/host-kit/src/internal/tmp-dir.fixtures.ts index edf03d27a4..d26147671c 100644 --- a/packages/host-kit/src/internal/tmp-dir.fixtures.ts +++ b/packages/host-kit/src/internal/tmp-dir.fixtures.ts @@ -1,21 +1,13 @@ -// Package tests cannot reach root test helpers (R11); fixture copy of tmp-dir.ts. import fs from 'node:fs'; import fsPromises from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; -/** - * Creates a fresh scratch directory for one test. Cleanup is automatic: the - * unit suite redirects TMPDIR to a per-run directory (scripts/vitest-tmpdir-global-setup.ts) - * that gets removed in one recursive rm after every worker finishes, so - * individual tests never need their own afterEach/afterAll for this. - */ // fallow-ignore-next-line code-duplication export async function mkdtempForTest(prefix: string): Promise { return fsPromises.mkdtemp(path.join(os.tmpdir(), prefix)); } -/** Sync counterpart of {@link mkdtempForTest}, for setup code that can't await. */ export function mkdtempForTestSync(prefix: string): string { return fs.mkdtempSync(path.join(os.tmpdir(), prefix)); } diff --git a/packages/host-kit/src/internal/version.ts b/packages/host-kit/src/internal/version.ts index 85fd105cb4..bc10587fea 100644 --- a/packages/host-kit/src/internal/version.ts +++ b/packages/host-kit/src/internal/version.ts @@ -17,7 +17,6 @@ export function readVersion(root: string = findProjectRoot()): string { version?: unknown; }; } catch { - // Not memoized: the root may still be materializing. return '0.0.0'; } const version = typeof pkg.version === 'string' ? pkg.version : '0.0.0'; diff --git a/packages/kernel/src/collections.ts b/packages/kernel/src/collections.ts index c0d38c735c..4722319bd2 100644 --- a/packages/kernel/src/collections.ts +++ b/packages/kernel/src/collections.ts @@ -17,11 +17,7 @@ function sortKeysDeep(value: unknown): unknown { ); } -/** - * Linear-time edge trim. The regex form (`/^-+|-+$/g`) backtracks polynomially - * on long dash runs (CodeQL js/polynomial-redos), and callers build their - * inputs from caller-supplied strings such as file paths and cache names. - */ +// Linear-time trim; the regex form trips CodeQL js/polynomial-redos. export function trimEdgeDashes(value: string): string { let start = 0; let end = value.length; diff --git a/scripts/mutation/workspace-aliases.test.ts b/scripts/mutation/workspace-aliases.test.ts index f172da8b78..6940f4d3db 100644 --- a/scripts/mutation/workspace-aliases.test.ts +++ b/scripts/mutation/workspace-aliases.test.ts @@ -27,7 +27,6 @@ test('Stryker aliases every exported workspace subpath exactly', () => { }); test('disk manifests alias an untracked sandbox copy the tracked reader cannot see', () => { - // Must sit inside the repository tree: `git ls-files` has to run and list nothing. fs.mkdirSync(path.join(repoRoot, '.tmp'), { recursive: true }); const sandboxRoot = fs.mkdtempSync(path.join(repoRoot, '.tmp', 'stryker-sandbox-fixture-')); try { diff --git a/vitest.mutation.config.ts b/vitest.mutation.config.ts index 3f0260aae4..9e31dff3dc 100644 --- a/vitest.mutation.config.ts +++ b/vitest.mutation.config.ts @@ -7,18 +7,12 @@ import { SERIALIZED_TESTS, SETUP_FILES } from './vitest.config.ts'; const repoRoot = path.dirname(fileURLToPath(import.meta.url)); -// Every `@agent-device/*` specifier must resolve to source inside the sandbox, -// or mutants load from the real tree through pnpm's node_modules link. Entries -// come from the exports-map reader, never a wildcard, so this cannot reach -// package internals (R11). const inStrykerSandbox = repoRoot.includes(path.join('.tmp', 'stryker')); const workspaceAliases = workspaceSourceAliases( repoRoot, inStrykerSandbox ? 'disk-manifests' : 'tracked-manifests', ); -// The per-run scope arrives through AGENT_DEVICE_MUTATION_TEST_FILES; the -// unit suite is the fallback that keeps `pnpm exec stryker run` usable by hand. const scope = readTestScope(); export default defineConfig({ From bb53b0ef5a5140bbfec3e2df2213eb4b26af6b35 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 20:26:30 +0000 Subject: [PATCH 6/8] docs: keep tool directives only across the touched tree Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- packages/capture-kit/src/tmp-dir.fixtures.ts | 8 ------- packages/kernel/src/scoped-provider.ts | 4 ---- src/__tests__/test-utils/host-process-mock.ts | 22 ------------------- .../web/agent-browser-lifecycle.test.ts | 2 -- 4 files changed, 36 deletions(-) diff --git a/packages/capture-kit/src/tmp-dir.fixtures.ts b/packages/capture-kit/src/tmp-dir.fixtures.ts index f562d3030a..6df3c9f35c 100644 --- a/packages/capture-kit/src/tmp-dir.fixtures.ts +++ b/packages/capture-kit/src/tmp-dir.fixtures.ts @@ -1,20 +1,12 @@ -// Package tests cannot reach root test helpers (R11); fixture copy of tmp-dir.ts. import fs from 'node:fs'; import fsPromises from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; -/** - * Creates a fresh scratch directory for one test. Cleanup is automatic: the - * unit suite redirects TMPDIR to a per-run directory (scripts/vitest-tmpdir-global-setup.ts) - * that gets removed in one recursive rm after every worker finishes, so - * individual tests never need their own afterEach/afterAll for this. - */ export async function mkdtempForTest(prefix: string): Promise { return fsPromises.mkdtemp(path.join(os.tmpdir(), prefix)); } -/** Sync counterpart of {@link mkdtempForTest}, for setup code that can't await. */ export function mkdtempForTestSync(prefix: string): string { return fs.mkdtempSync(path.join(os.tmpdir(), prefix)); } diff --git a/packages/kernel/src/scoped-provider.ts b/packages/kernel/src/scoped-provider.ts index 32615dbd07..b6e64a8239 100644 --- a/packages/kernel/src/scoped-provider.ts +++ b/packages/kernel/src/scoped-provider.ts @@ -26,10 +26,6 @@ export function createScopedProvider( }; } -/** - * Wraps every method call on `target` in `runScope`, so leaf code below the - * method resolves scope-injected state instead of the local default. - */ export function withMethodScope( target: T, runScope: (task: () => Promise) => Promise, diff --git a/src/__tests__/test-utils/host-process-mock.ts b/src/__tests__/test-utils/host-process-mock.ts index 4b33394cf2..95f9b8098a 100644 --- a/src/__tests__/test-utils/host-process-mock.ts +++ b/src/__tests__/test-utils/host-process-mock.ts @@ -2,26 +2,6 @@ type HostProcessModule = typeof import('@agent-device/host-kit/process'); type HostProcessIdentityObservation = import('@agent-device/host-kit/process').HostProcessIdentityObservation; -/** - * `vi.mock` factory for the host-kit `exec` seam in tests that seed a "live" - * owner from the test process's own identity (readCurrentOwnerIdentity and - * friends) and later have production code re-read it during classification. - * - * readProcessStartTime shells out to `ps` with a 1s timeout; under full-suite - * CPU contention a re-read can miss that deadline and return null, mismatching - * the seeded value and flipping a genuinely-live owner to 'owner-process-dead'. - * This factory assigns our own pid a stable synthetic start time, then serves - * that value so every read is self-consistent without a subprocess. Other pids read as null, same - * as a real `ps` miss. isProcessAlive stays real (a plain `kill(pid, 0)` - * syscall, not a subprocess), so fabricated dead-pid fixtures still classify - * as dead through that non-flaky check. - * - * Usage: `vi.mock('@agent-device/host-kit/process', async (importOriginal) => - * (await import('/test-utils/host-process-mock.ts')).pinOwnProcessStartTime(importOriginal))` - */ -// Consumed by three suites, but only through `(await import(...)).pinOwnProcessStartTime` -// inside `vi.mock` factories — vitest hoists those above static imports, so the dynamic -// form is required and fallow cannot trace the consumers statically. export async function pinOwnProcessStartTime( importOriginal: () => Promise, ): Promise { @@ -29,8 +9,6 @@ export async function pinOwnProcessStartTime( const ownStartTime = 'test-process-start-time'; return { ...actual, - // The seam mock cannot reach readCurrentOwnerIdentity's internal - // readProcessStartTime call, so the recorded identity is pinned here too. readCurrentOwnerIdentity: () => ({ pid: process.pid, startTime: ownStartTime }), readProcessStartTime: (pid: number) => { if (pid !== process.pid) return null; diff --git a/src/platforms/web/agent-browser-lifecycle.test.ts b/src/platforms/web/agent-browser-lifecycle.test.ts index 6901a98bb8..d8652e2f87 100644 --- a/src/platforms/web/agent-browser-lifecycle.test.ts +++ b/src/platforms/web/agent-browser-lifecycle.test.ts @@ -18,8 +18,6 @@ vi.mock('@agent-device/host-kit/process', async (importOriginal) => { const actual = await importOriginal(); return { ...actual, - // The port mock cannot reach listHostProcesses' internal runCmd call, so - // the ps read is routed through its runCommand injection point instead. listHostProcesses: async (options: Parameters[0]) => await actual.listHostProcesses({ ...options, runCommand: runCmdMock }), readProcessStartTime: (pid: number) => `start-${pid}`, From 4ea386653c2ae5d08b4b0af881a24a3a6f12e869 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 20:39:07 +0000 Subject: [PATCH 7/8] fix: point the Swift parity comment at the real TS twin and test The W1 move rewrote this citation to packages/contracts/src/mobile-snapshot-semantics.ts, which does not exist: the module went to capture-kit while isTapPointInsideViewport itself went to packages/contracts/src/snapshot-visibility.ts. The TS test line was left pointing at the pre-move path. Both now resolve. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- .../AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift b/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift index 8571450abb..379f78b734 100644 --- a/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +++ b/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift @@ -11,8 +11,8 @@ import XCTest // This is pure geometry on purpose — no XCUIElement — so the exact decision // can be proven against the golden fixture table shared with the TS twin: // table: contracts/fixtures/tap-point-policy.json -// TS twin: packages/contracts/src/mobile-snapshot-semantics.ts#isTapPointInsideViewport -// TS test: src/snapshot/__tests__/tap-point-policy-parity.test.ts +// TS twin: packages/contracts/src/snapshot-visibility.ts#isTapPointInsideViewport +// TS test: packages/contracts/src/snapshot-tap-point-policy.test.ts // Drift on either side turns CI red without needing a simulator. enum TapPointPolicy { static func isAllowed(elementFrame: CGRect, windowFrame: CGRect) -> Bool { From f87c0fe4feda9dce1b342f8871d2c65361a9c178 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 27 Aug 2026 20:44:23 +0000 Subject: [PATCH 8/8] fix: repoint comment citations at the homes this refactor moved them to The W1 move left ~20 comment citations pointing at src/utils/*.ts and src/request/*.ts paths that no longer exist. Each now names the capability port that owns the symbol, which survives further file moves: exec -> host-kit/command host-process, owner-identity -> host-kit/process diagnostics -> host-kit/diagnostics atomic-file, process-lock -> host-kit/file retry -> host-kit/retry request progress/cancel -> host-kit/request version -> host-kit/version ttl-memo, source-value, parsing, device-isolation, keyed-lock, success-text -> kernel subpaths Comment-only; no closure, budget, or behavior change. ADR citations are left as written, being dated records of the decision rather than live references. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_018VngeKZH6zBuJzNBk5YzUH --- packages/kernel/src/errors.ts | 2 +- ...r-lease-filesystem-boundary-faults.test.ts | 2 +- .../__tests__/runner-session-fixtures.ts | 4 ++-- packages/platform-apple/src/runner/host.ts | 24 +++++++++---------- src/__tests__/eager-closure-budgets.ts | 2 +- src/__tests__/exec-wrap-guard.test.ts | 4 ++-- src/__tests__/hermetic-signal-setup.ts | 4 ++-- .../daemon-client-timeout-route.test.ts | 2 +- src/daemon/client/daemon-client-lifecycle.ts | 2 +- .../provider-scenarios/android-world.ts | 2 +- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/kernel/src/errors.ts b/packages/kernel/src/errors.ts index c6d756f8d5..5b611c2942 100644 --- a/packages/kernel/src/errors.ts +++ b/packages/kernel/src/errors.ts @@ -69,7 +69,7 @@ export type ErrorCause = { * lifted onto the normalized error, stripped from details. * - `processExitError` + `stdout`/`stderr`/`exitCode` — marks a wrap of a real * process exit so normalizeError can surface the first meaningful stderr line; - * build these via `execFailureDetails`/`requireExecSuccess` in src/utils/exec.ts + * build these via `execFailureDetails`/`requireExecSuccess` in @agent-device/host-kit/command * rather than by hand. * - `retriable` — typed retry signal hoisted to the wire error shape. * - `reason` — machine-dispatchable sub-classification within a code. diff --git a/packages/platform-apple/src/runner/__tests__/runner-lease-filesystem-boundary-faults.test.ts b/packages/platform-apple/src/runner/__tests__/runner-lease-filesystem-boundary-faults.test.ts index d3ffe80326..e4a6de8428 100644 --- a/packages/platform-apple/src/runner/__tests__/runner-lease-filesystem-boundary-faults.test.ts +++ b/packages/platform-apple/src/runner/__tests__/runner-lease-filesystem-boundary-faults.test.ts @@ -24,7 +24,7 @@ afterEach(() => { delete process.env.AGENT_DEVICE_IOS_RUNNER_LEASE_DIR; }); -/** Mirrors the canonical same-directory temp-path shape of src/utils/atomic-file.ts. */ +/** Mirrors the canonical same-directory temp-path shape of @agent-device/host-kit/file. */ function isPublishTemporaryPath(value: unknown, destination: string): boolean { if (typeof value !== 'string') return false; if (path.dirname(value) !== path.dirname(destination)) return false; diff --git a/packages/platform-apple/src/runner/__tests__/runner-session-fixtures.ts b/packages/platform-apple/src/runner/__tests__/runner-session-fixtures.ts index 4ea1efabbe..56a192f941 100644 --- a/packages/platform-apple/src/runner/__tests__/runner-session-fixtures.ts +++ b/packages/platform-apple/src/runner/__tests__/runner-session-fixtures.ts @@ -9,7 +9,7 @@ import type { RunnerSession } from '../runner-session-types.ts'; // Fabricated runner sessions, leases, background children, and transport // payloads shared by the runner-session tests. The child pids here are made up // (`4242`): nothing in a test may deliver a real signal to them, so the owning -// tests mock the signal seam in `src/utils/host-process.ts` — see +// tests mock the signal seam in `@agent-device/host-kit/process` — see // `src/__tests__/hermetic-signal-setup.ts` and #1824. export function makeRunnerSession(overrides: Partial = {}): RunnerSession { @@ -150,7 +150,7 @@ type OwnerLivenessVerdict = | 'owner-state-dir-gone' | 'unknown'; -// classifyOwnerLiveness's real default (src/utils/owner-identity.ts) calls its +// classifyOwnerLiveness's real default (@agent-device/host-kit/process) calls its // OWN direct imports of isProcessAlive/readProcessStartTime rather than going // through the package host, so overriding those two host slots does not reach // it. This double is built over the SAME mocks a suite configures for them, so diff --git a/packages/platform-apple/src/runner/host.ts b/packages/platform-apple/src/runner/host.ts index ab5d181b6a..95af11fff8 100644 --- a/packages/platform-apple/src/runner/host.ts +++ b/packages/platform-apple/src/runner/host.ts @@ -136,7 +136,7 @@ export type IosPhysicalDeviceRunnerControl = { }; export type AppleRunnerHost = { - // Process execution (src/utils/exec.ts) + // Process execution (@agent-device/host-kit/command) runCmdStreaming(cmd: string, args: string[], options?: ExecStreamOptions): Promise; runCmdSync(cmd: string, args: string[], options?: ExecOptions): ExecResult; runCmdBackground( @@ -149,14 +149,14 @@ export type AppleRunnerHost = { message: string, extra?: Record | ((result: ExecResult) => Record), ): ExecResult; - // Diagnostics (src/utils/diagnostics.ts) + // Diagnostics (@agent-device/host-kit/diagnostics) emitDiagnostic(event: DiagnosticEventInput): void; withDiagnosticTimer( phase: string, fn: () => Promise | T, data?: Record, ): Promise; - // Retry (src/utils/retry.ts) + // Retry (@agent-device/host-kit/retry) retryWithPolicy( fn: (context: RetryAttemptContext) => Promise, policy?: RetryPolicy, @@ -164,17 +164,17 @@ export type AppleRunnerHost = { ): Promise; isEnvTruthy(value: string | undefined): boolean; deadlineFromTimeoutMs(timeoutMs: number, nowMs?: number): Deadline; - // Host process probes and signals (src/utils/host-process.ts) + // Host process probes and signals (@agent-device/host-kit/process) isProcessAlive(pid: number): boolean; isProcessGroupAlive(pid: number): boolean; readProcessStartTime(pid: number): string | null; readProcessCommand(pid: number): string | null; signalPidsBestEffort(pidsToSignal: readonly number[], signal: NodeJS.Signals): number; signalProcessGroupBestEffort(pid: number, signal: NodeJS.Signals): boolean; - // Project identity (src/utils/version.ts) + // Project identity (@agent-device/host-kit/version) findProjectRoot(): string; readVersion(root?: string): string; - // Locks (src/utils/process-lock.ts, src/utils/keyed-lock.ts) + // Locks (@agent-device/host-kit/file, @agent-device/kernel/keyed-lock) acquireProcessLock(params: { lockDirPath: string; owner: ProcessLockOwner; @@ -188,26 +188,26 @@ export type AppleRunnerHost = { key: string, task: () => Promise, ): Promise; - // Atomic publish (src/utils/atomic-file.ts) + // Atomic publish (@agent-device/host-kit/file) publishFileSync(options: { destination: string; contents: string; mode?: number; publish?: 'replace' | 'link-exclusive'; }): void; - // Owner liveness (src/utils/owner-identity.ts) + // Owner liveness (@agent-device/host-kit/process) classifyOwnerLiveness(params: { owner: { pid: number; startTime: string | null }; stateDir?: string; }): OwnerLiveness; - // Memoization (src/utils/ttl-memo.ts) + // Memoization (@agent-device/kernel/ttl-memo) createTtlMemo(options?: TtlMemoOptions): TtlMemo; - // Parsing helpers (src/utils/source-value.ts, src/utils/parsing.ts) + // Parsing helpers (@agent-device/kernel/source-value, @agent-device/kernel/record) parseBooleanLiteral(value: string): boolean | undefined; isRecord(value: unknown): value is Record; - // Simulator device-set isolation (src/utils/device-isolation.ts) + // Simulator device-set isolation (@agent-device/kernel/device-isolation) resolveIosSimulatorDeviceSetPath(flagValue: string | undefined): string | undefined; - // Request progress and cancellation (src/request/progress.ts, src/request/cancel.ts) + // Request progress and cancellation (@agent-device/host-kit/request) emitRequestProgress(event: RequestProgressEvent): void; getRequestSignal(requestId: string | undefined): AbortSignal | undefined; isRequestCanceled(requestId: string | undefined): boolean; diff --git a/src/__tests__/eager-closure-budgets.ts b/src/__tests__/eager-closure-budgets.ts index 5cbf0424e4..a8cc04988a 100644 --- a/src/__tests__/eager-closure-budgets.ts +++ b/src/__tests__/eager-closure-budgets.ts @@ -353,7 +353,7 @@ export const FACADE_BUDGETS: Readonly> = Object.freeze({ */ export const HUB_BUDGETS: Readonly> = Object.freeze({ // 363 -> 365 in #2004, which cuts per-invocation work and pays two modules for it: - // `src/utils/ttl-memo.ts` (version.ts now resolves the package version and the project root + // `@agent-device/kernel/ttl-memo` (version.ts now resolves the package version and the project root // once per process instead of re-reading package.json several times an invocation) and // `src/daemon/client/daemon-launch-spec.ts` (the launch-entry probe, split out of the 726-line // daemon-client-lifecycle.ts). Both run on the path every local command already takes, so diff --git a/src/__tests__/exec-wrap-guard.test.ts b/src/__tests__/exec-wrap-guard.test.ts index 3410af03ea..f49ff92259 100644 --- a/src/__tests__/exec-wrap-guard.test.ts +++ b/src/__tests__/exec-wrap-guard.test.ts @@ -12,7 +12,7 @@ import { test } from 'vitest'; // whose details carry `processExitError: true`. Before PR #1072 ~49 call sites // spread the trio by hand and silently missed the flag, so users saw // " exited with code N" with no cause. The fix is centralized in -// `execFailureDetails` / `requireExecSuccess` (src/utils/exec.ts); this guard +// `execFailureDetails` / `requireExecSuccess` (@agent-device/host-kit/command); this guard // keeps new call sites from drifting back to inline spreads. // // A site that intentionally rebuilds the trio WITHOUT the flag (reachable at @@ -99,7 +99,7 @@ test('AppError details never rebuild the exec stdout/stderr/exitCode trio inline [], `Inline exec stdout/stderr/exitCode spreads in AppError details miss the processExitError flag, ` + `so normalizeError cannot surface the stderr excerpt. Build the details with ` + - `execFailureDetails()/requireExecSuccess() from src/utils/exec.ts, or — when the throw is ` + + `execFailureDetails()/requireExecSuccess() from @agent-device/host-kit/command, or — when the throw is ` + `reachable at exit 0 or the excerpt would degrade the message — opt out with a ` + `"// ${ALLOW_MARKER} " comment above the new AppError(...) call. Violations:\n` + violations.join('\n'), diff --git a/src/__tests__/hermetic-signal-setup.ts b/src/__tests__/hermetic-signal-setup.ts index 2fbaf09035..f381b37219 100644 --- a/src/__tests__/hermetic-signal-setup.ts +++ b/src/__tests__/hermetic-signal-setup.ts @@ -20,7 +20,7 @@ import { afterAll, afterEach, expect } from 'vitest'; // Signal 0 is a liveness probe (`isProcessAlive`), not a signal; it stays free. // Tests that drive a real kill path against a fabricated pid mock the seam — // `signalPidsBestEffort` / `signalProcessGroupBestEffort` in -// `src/utils/host-process.ts` for the direct writes, the exec/tool-provider +// `@agent-device/host-kit/process` for the direct writes, the exec/tool-provider // seam for a spawned `pkill` — the same way they already mock the liveness // reads. @@ -151,7 +151,7 @@ function failOnRefusedSignals(scope: string): void { `${scope} tried to signal ${count} process(es) this vitest worker did not spawn. ` + 'A unit test may signal only itself and its own direct children (and their process ' + 'groups); mock the seam instead — signalPidsBestEffort / signalProcessGroupBestEffort in ' + - 'src/utils/host-process.ts, the exec or tool-provider seam for a spawned pkill, or ' + + '@agent-device/host-kit/process, the exec or tool-provider seam for a spawned pkill, or ' + `vi.spyOn(process, 'kill'). If the pid is a descendant this test really owns, signal the ` + `direct child (or its group via the negative pid) rather than the grandchild.\n${report}`, ); 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 c626662b51..d01562e128 100644 --- a/src/daemon/client/__tests__/daemon-client-timeout-route.test.ts +++ b/src/daemon/client/__tests__/daemon-client-timeout-route.test.ts @@ -4,7 +4,7 @@ // as a pure formatter, but a pure-formatter test cannot catch a bug in // CLEANUP ELIGIBILITY: whether `cleanupTimedOutIosRunnerBuilds` (the Apple // xcodebuild pkill sweep) actually runs. This file spies on the real -// process-execution seam (`runCmdSync`, src/utils/exec.ts) and drives an +// process-execution seam (`runCmdSync`, @agent-device/host-kit/command) and drives an // actual socket/HTTP timeout through `sendRequest` so the assertions exercise // the same code path a real client does. // diff --git a/src/daemon/client/daemon-client-lifecycle.ts b/src/daemon/client/daemon-client-lifecycle.ts index e57a1aa0d8..ab5b0ac92d 100644 --- a/src/daemon/client/daemon-client-lifecycle.ts +++ b/src/daemon/client/daemon-client-lifecycle.ts @@ -532,7 +532,7 @@ export function isActiveReplaySessionResponse( * emitted when a name is available, explicit state dir or not. Attached to * both a structured `hint` field (for `--json` consumers) and appended to * `message` — the only field the default text renderer surfaces - * (`src/utils/success-text.ts`) — so the hint reaches a caller in either mode. + * (`@agent-device/kernel/success-text`) — so the hint reaches a caller in either mode. * * `data.session` is used verbatim, never reconstructed as `default`: an * EXPLICIT `--session ` is used as-is by `resolveEffectiveSessionName`, diff --git a/test/integration/provider-scenarios/android-world.ts b/test/integration/provider-scenarios/android-world.ts index 4c349a22c8..90ee1e4716 100644 --- a/test/integration/provider-scenarios/android-world.ts +++ b/test/integration/provider-scenarios/android-world.ts @@ -274,7 +274,7 @@ function argsStartWith(args: string[], prefix: string[]): boolean { // The real device shell unwraps a single-quoted argument (and collapses the // `'\''` escape back to `'`) before `cmd` ever sees it, so this harness has // to mirror that unwrap to keep modelling what the device actually receives -// — the inverse of the quoting in src/utils/shell-quote.ts. +// — the inverse of the quoting in @agent-device/host-kit/command. function unquoteAndroidShellArg(value: string): string { if (!value.startsWith("'") || !value.endsWith("'") || value.length < 2) return value; return value.slice(1, -1).replaceAll("'\\''", "'");