diff --git a/examples/sdk/tsconfig.json b/examples/sdk/tsconfig.json index 57d927c4e3..d395b543db 100644 --- a/examples/sdk/tsconfig.json +++ b/examples/sdk/tsconfig.json @@ -58,6 +58,7 @@ { "path": "../../packages/provision-kit" }, { "path": "../../packages/proxy" }, { "path": "../../packages/react-native" }, + { "path": "../../packages/remote" }, { "path": "../../packages/replay-port" }, { "path": "../../packages/replay-test" }, { "path": "../../packages/selectors" }, diff --git a/oxlint.config.ts b/oxlint.config.ts index e6fd79d90b..98badb7502 100644 --- a/oxlint.config.ts +++ b/oxlint.config.ts @@ -125,8 +125,8 @@ export default defineConfig({ files: [ 'src/daemon-client/daemon-client-rpc.ts', 'packages/daemon/src/server/downloadable-artifact-http.ts', - 'src/remote/remote-request-diagnostics.ts', - 'src/remote/upload-stream.ts', + 'packages/remote/src/remote-request-diagnostics.ts', + 'packages/remote/src/upload-stream.ts', ], rules: { 'unicorn/catch-error-name': 'off', diff --git a/package.json b/package.json index e77a80a9d9..e73efd8a74 100644 --- a/package.json +++ b/package.json @@ -311,6 +311,7 @@ "@agent-device/provision-kit": "workspace:*", "@agent-device/proxy": "workspace:*", "@agent-device/react-native": "workspace:*", + "@agent-device/remote": "workspace:*", "@agent-device/replay-port": "workspace:*", "@agent-device/replay-test": "workspace:*", "@agent-device/selectors": "workspace:*", diff --git a/packages/daemon/src/server/__tests__/atomic-publish-ownership.test.ts b/packages/daemon/src/server/__tests__/atomic-publish-ownership.test.ts index 1258c6e0c0..aba47c3202 100644 --- a/packages/daemon/src/server/__tests__/atomic-publish-ownership.test.ts +++ b/packages/daemon/src/server/__tests__/atomic-publish-ownership.test.ts @@ -12,7 +12,7 @@ const SIMPLE_PUBLISHERS = [ new URL('../provider-lease-expiry.ts', import.meta.url), new URL('../../core/session-script-writer.ts', import.meta.url), new URL('../../../../../packages/platform-apple/src/runner/runner-lease.ts', import.meta.url), - new URL('../../../../../src/remote/remote-connection-state.ts', import.meta.url), + new URL('../../../../../packages/remote/src/remote-connection-state.ts', import.meta.url), ] as const; const PROCESS_LOCK_SOURCE = new URL( diff --git a/packages/daemon/src/server/request-diagnostics-http.ts b/packages/daemon/src/server/request-diagnostics-http.ts index 079f0dc52d..4261cc4922 100644 --- a/packages/daemon/src/server/request-diagnostics-http.ts +++ b/packages/daemon/src/server/request-diagnostics-http.ts @@ -6,7 +6,7 @@ * DAEMON host. A remote caller — a CI runner driving an EAS/limrun simulator — * cannot read that filesystem, so the record has to be reachable over the same * base URL and token the caller already holds. The client side is - * `src/remote/remote-request-diagnostics.ts`. + * `packages/remote/src/remote-request-diagnostics.ts`. * * Scope: exactly one record, addressed the way the error names it * (`DaemonError.diagnosticsRecord`). A record that was never written (the diff --git a/packages/remote/package.json b/packages/remote/package.json new file mode 100644 index 0000000000..8e2d265197 --- /dev/null +++ b/packages/remote/package.json @@ -0,0 +1,43 @@ +{ + "name": "@agent-device/remote", + "version": "0.0.0", + "private": true, + "type": "module", + "description": "Remote-daemon client plumbing: remote config profiles and their provenance, the persisted remote connection state, request artifact upload/download, and remote diagnostics localization. Internal workspace package bundled into the published agent-device artifact.", + "dependencies": { + "@agent-device/capture-kit": "workspace:*", + "@agent-device/contracts": "workspace:*", + "@agent-device/daemon-contracts": "workspace:*", + "@agent-device/host-kit": "workspace:*", + "@agent-device/kernel": "workspace:*" + }, + "exports": { + "./daemon-artifacts": { + "types": "./src/daemon-artifacts.ts", + "default": "./src/daemon-artifacts.ts" + }, + "./remote-config": { + "types": "./src/remote-config.ts", + "default": "./src/remote-config.ts" + }, + "./remote-config-core": { + "types": "./src/remote-config-core.ts", + "default": "./src/remote-config-core.ts" + }, + "./remote-config-schema": { + "types": "./src/remote-config-schema.ts", + "default": "./src/remote-config-schema.ts" + }, + "./remote-connection-state": { + "types": "./src/remote-connection-state.ts", + "default": "./src/remote-connection-state.ts" + }, + "./remote-request-diagnostics": { + "types": "./src/remote-request-diagnostics.ts", + "default": "./src/remote-request-diagnostics.ts" + } + }, + "devDependencies": { + "@agent-device/test-kit": "workspace:*" + } +} diff --git a/src/remote/__tests__/artifact-download.test.ts b/packages/remote/src/__tests__/artifact-download.test.ts similarity index 100% rename from src/remote/__tests__/artifact-download.test.ts rename to packages/remote/src/__tests__/artifact-download.test.ts diff --git a/src/remote/__tests__/daemon-artifacts-save-script.test.ts b/packages/remote/src/__tests__/daemon-artifacts-save-script.test.ts similarity index 100% rename from src/remote/__tests__/daemon-artifacts-save-script.test.ts rename to packages/remote/src/__tests__/daemon-artifacts-save-script.test.ts diff --git a/src/remote/__tests__/daemon-artifacts-test-command.test.ts b/packages/remote/src/__tests__/daemon-artifacts-test-command.test.ts similarity index 100% rename from src/remote/__tests__/daemon-artifacts-test-command.test.ts rename to packages/remote/src/__tests__/daemon-artifacts-test-command.test.ts diff --git a/src/remote/__tests__/remote-config-public.test.ts b/packages/remote/src/__tests__/remote-config-public.test.ts similarity index 100% rename from src/remote/__tests__/remote-config-public.test.ts rename to packages/remote/src/__tests__/remote-config-public.test.ts diff --git a/src/remote/__tests__/remote-connection-state.test.ts b/packages/remote/src/__tests__/remote-connection-state.test.ts similarity index 100% rename from src/remote/__tests__/remote-connection-state.test.ts rename to packages/remote/src/__tests__/remote-connection-state.test.ts diff --git a/src/remote/__tests__/remote-request-diagnostics.test.ts b/packages/remote/src/__tests__/remote-request-diagnostics.test.ts similarity index 100% rename from src/remote/__tests__/remote-request-diagnostics.test.ts rename to packages/remote/src/__tests__/remote-request-diagnostics.test.ts diff --git a/src/remote/__tests__/upload-client-cancellation.test.ts b/packages/remote/src/__tests__/upload-client-cancellation.test.ts similarity index 100% rename from src/remote/__tests__/upload-client-cancellation.test.ts rename to packages/remote/src/__tests__/upload-client-cancellation.test.ts diff --git a/src/remote/__tests__/upload-client.test.ts b/packages/remote/src/__tests__/upload-client.test.ts similarity index 100% rename from src/remote/__tests__/upload-client.test.ts rename to packages/remote/src/__tests__/upload-client.test.ts diff --git a/src/remote/__tests__/upload-progress.test.ts b/packages/remote/src/__tests__/upload-progress.test.ts similarity index 73% rename from src/remote/__tests__/upload-progress.test.ts rename to packages/remote/src/__tests__/upload-progress.test.ts index 70b8dd3783..91423c4342 100644 --- a/src/remote/__tests__/upload-progress.test.ts +++ b/packages/remote/src/__tests__/upload-progress.test.ts @@ -1,20 +1,30 @@ -import { test } from 'vitest'; +import { test, vi } from 'vitest'; import assert from 'node:assert/strict'; -import { withCapturedStderr } from '../../__tests__/test-utils/stream-capture.ts'; import { createStderrUploadProgressReporter, type UploadProgressEvent, } from '../upload-progress.ts'; function renderEvents(events: UploadProgressEvent[]): string { - return withCapturedStderr( - () => { - const sink = createStderrUploadProgressReporter(); - assert.equal(sink !== undefined, true); - for (const event of events) sink!(event); - }, - { interactive: true }, - ); + let output = ''; + const write = vi.spyOn(process.stderr, 'write').mockImplementation((chunk: unknown) => { + output += String(chunk); + return true; + }); + vi.stubEnv('CI', undefined); + const isTTYDescriptor = Object.getOwnPropertyDescriptor(process.stderr, 'isTTY'); + Object.defineProperty(process.stderr, 'isTTY', { configurable: true, value: true }); + try { + const sink = createStderrUploadProgressReporter(); + assert.equal(sink !== undefined, true); + for (const event of events) sink!(event); + } finally { + if (isTTYDescriptor) Object.defineProperty(process.stderr, 'isTTY', isTTYDescriptor); + else delete (process.stderr as unknown as Record).isTTY; + write.mockRestore(); + vi.unstubAllEnvs(); + } + return output; } test('the stderr reporter formats start, resume, progress and fallback events', () => { diff --git a/src/remote/artifact-download.ts b/packages/remote/src/artifact-download.ts similarity index 100% rename from src/remote/artifact-download.ts rename to packages/remote/src/artifact-download.ts diff --git a/src/remote/daemon-artifacts.ts b/packages/remote/src/daemon-artifacts.ts similarity index 100% rename from src/remote/daemon-artifacts.ts rename to packages/remote/src/daemon-artifacts.ts diff --git a/src/remote/remote-config-core.ts b/packages/remote/src/remote-config-core.ts similarity index 100% rename from src/remote/remote-config-core.ts rename to packages/remote/src/remote-config-core.ts diff --git a/src/remote/remote-config-schema.ts b/packages/remote/src/remote-config-schema.ts similarity index 100% rename from src/remote/remote-config-schema.ts rename to packages/remote/src/remote-config-schema.ts diff --git a/src/remote/remote-config.ts b/packages/remote/src/remote-config.ts similarity index 100% rename from src/remote/remote-config.ts rename to packages/remote/src/remote-config.ts diff --git a/src/remote/remote-connection-state.ts b/packages/remote/src/remote-connection-state.ts similarity index 100% rename from src/remote/remote-connection-state.ts rename to packages/remote/src/remote-connection-state.ts diff --git a/src/remote/remote-request-diagnostics.ts b/packages/remote/src/remote-request-diagnostics.ts similarity index 100% rename from src/remote/remote-request-diagnostics.ts rename to packages/remote/src/remote-request-diagnostics.ts diff --git a/src/remote/upload-client-artifact.ts b/packages/remote/src/upload-client-artifact.ts similarity index 100% rename from src/remote/upload-client-artifact.ts rename to packages/remote/src/upload-client-artifact.ts diff --git a/src/remote/upload-client.ts b/packages/remote/src/upload-client.ts similarity index 100% rename from src/remote/upload-client.ts rename to packages/remote/src/upload-client.ts diff --git a/src/remote/upload-progress.ts b/packages/remote/src/upload-progress.ts similarity index 100% rename from src/remote/upload-progress.ts rename to packages/remote/src/upload-progress.ts diff --git a/src/remote/upload-stream.ts b/packages/remote/src/upload-stream.ts similarity index 100% rename from src/remote/upload-stream.ts rename to packages/remote/src/upload-stream.ts diff --git a/packages/remote/tsconfig.json b/packages/remote/tsconfig.json new file mode 100644 index 0000000000..c2bf98d842 --- /dev/null +++ b/packages/remote/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "noEmit": false, + "emitDeclarationOnly": true, + "declaration": true, + "declarationDir": "./dist-types", + "rootDir": "./src", + "tsBuildInfoFile": "./dist-types/index.tsbuildinfo" + }, + "include": ["src"], + "references": [ + { "path": "../capture-kit" }, + { "path": "../contracts" }, + { "path": "../daemon-contracts" }, + { "path": "../host-kit" }, + { "path": "../kernel" }, + { "path": "../test-kit" } + ] +} diff --git a/packages/replay-port/src/daemon-port/test-command.ts b/packages/replay-port/src/daemon-port/test-command.ts index 4450dd1a80..40e607f688 100644 --- a/packages/replay-port/src/daemon-port/test-command.ts +++ b/packages/replay-port/src/daemon-port/test-command.ts @@ -294,7 +294,7 @@ export async function runReplayTestCommand(command: ReplayTestCommand): Promise< /** * #2246: against a remote daemon, the client redirects `--artifacts-dir` to a temp directory on * THIS host before the suite runs (`prepareRemoteRequestArtifacts` in - * `src/remote/daemon-artifacts.ts`) — the caller's real `cwd` names no path here, so the + * `packages/remote/src/daemon-artifacts.ts`) — the caller's real `cwd` names no path here, so the * scheduler above must never resolve suite artifacts against it. `req.meta.clientArtifactPaths` * is how that client tells the daemon the real caller-local ROOT (e.g. `--artifacts-dir`, or its * default) it will pull the directory back into once the request returns — that root is resolved diff --git a/packages/replay-test/src/internal/session-test-artifacts.ts b/packages/replay-test/src/internal/session-test-artifacts.ts index a105181519..aa052def70 100644 --- a/packages/replay-test/src/internal/session-test-artifacts.ts +++ b/packages/replay-test/src/internal/session-test-artifacts.ts @@ -4,7 +4,7 @@ import { trimEdgeDashes } from '@agent-device/kernel/collections'; import type { ReplayTestAttemptOutcome } from '@agent-device/replay-test'; /** - * `test`'s default artifacts root when `--artifacts-dir` is not given. `src/remote/daemon-artifacts.ts` + * `test`'s default artifacts root when `--artifacts-dir` is not given. `packages/remote/src/daemon-artifacts.ts` * keeps its own copy of this literal (to redirect a remote request without resolving anything * against the daemon's `cwd`, #2246): pulling it from `@agent-device/contracts` instead grew this * package's eager import closure by 3 modules for one string, past its pinned budget diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 4f4f40ede8..8af7cc1611 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -88,6 +88,9 @@ importers: '@agent-device/react-native': specifier: workspace:* version: link:packages/react-native + '@agent-device/remote': + specifier: workspace:* + version: link:packages/remote '@agent-device/replay-port': specifier: workspace:* version: link:packages/replay-port @@ -706,6 +709,28 @@ importers: specifier: workspace:* version: link:../test-kit + packages/remote: + dependencies: + '@agent-device/capture-kit': + specifier: workspace:* + version: link:../capture-kit + '@agent-device/contracts': + specifier: workspace:* + version: link:../contracts + '@agent-device/daemon-contracts': + specifier: workspace:* + version: link:../daemon-contracts + '@agent-device/host-kit': + specifier: workspace:* + version: link:../host-kit + '@agent-device/kernel': + specifier: workspace:* + version: link:../kernel + devDependencies: + '@agent-device/test-kit': + specifier: workspace:* + version: link:../test-kit + packages/replay-port: dependencies: '@agent-device/ad-replay': diff --git a/scripts/__tests__/help-conformance-sample-producers.ts b/scripts/__tests__/help-conformance-sample-producers.ts index a453009400..4014451abf 100644 --- a/scripts/__tests__/help-conformance-sample-producers.ts +++ b/scripts/__tests__/help-conformance-sample-producers.ts @@ -36,7 +36,7 @@ import { renderConnectSuccess, } from '../../src/cli/commands/connection-presentation.ts'; import type { ConnectVerification } from '../../src/cli/connection/connect-provider-adapters.ts'; -import type { RemoteConnectionState } from '../../src/remote/remote-connection-state.ts'; +import type { RemoteConnectionState } from '@agent-device/remote/remote-connection-state'; import { AppError, normalizeError } from '@agent-device/kernel/errors'; import type { SnapshotQualityVerdict } from '@agent-device/kernel/snapshot'; import { renderSnapshotQualityWarnings } from '@agent-device/capture-kit/quality-warnings'; diff --git a/scripts/layering/architecture-ownership.ts b/scripts/layering/architecture-ownership.ts index 6faed92436..93338ce70f 100644 --- a/scripts/layering/architecture-ownership.ts +++ b/scripts/layering/architecture-ownership.ts @@ -117,7 +117,7 @@ export const CLIENT_SIDE_POLICY_NAME = 'client-side'; export const LOGICAL_MODULE_POLICIES = [ { name: CLIENT_SIDE_POLICY_NAME, - roots: ['src/cli.ts', 'src/cli/', 'src/client/', 'src/remote/', 'src/daemon-client/'], + roots: ['src/cli.ts', 'src/cli/', 'src/client/', 'packages/remote/src/', 'src/daemon-client/'], forbiddenTargetRoots: [DAEMON_SOURCE_ROOT], }, { diff --git a/scripts/layering/daemon-modularity.test.ts b/scripts/layering/daemon-modularity.test.ts index d0c8b33fc8..411b279be2 100644 --- a/scripts/layering/daemon-modularity.test.ts +++ b/scripts/layering/daemon-modularity.test.ts @@ -657,7 +657,7 @@ for (const file of [ 'src/cli.ts', 'src/cli/commands/daemon.ts', 'src/client/client-normalizers.ts', - 'src/remote/daemon-artifacts.ts', + 'packages/remote/src/daemon-artifacts.ts', 'src/daemon-client/daemon-client.ts', ]) { for (const [kind, source] of [ diff --git a/src/__tests__/cli-agent-cdp-session.test.ts b/src/__tests__/cli-agent-cdp-session.test.ts index ad56b4b7c2..6d4642b29b 100644 --- a/src/__tests__/cli-agent-cdp-session.test.ts +++ b/src/__tests__/cli-agent-cdp-session.test.ts @@ -18,7 +18,7 @@ import { installIsolatedCliTestEnv } from './cli-test-env.ts'; import { hashRemoteConfigFile, writeRemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import type { DaemonResponse } from '../daemon-client/daemon-client.ts'; afterEach(() => { diff --git a/src/__tests__/cli-close.test.ts b/src/__tests__/cli-close.test.ts index 9c7d88c5d4..550c877ed1 100644 --- a/src/__tests__/cli-close.test.ts +++ b/src/__tests__/cli-close.test.ts @@ -9,7 +9,7 @@ import { seedConnectionState, type StoredConnectionSeed, } from './remote-connection.fixtures.ts'; -import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; import type { DaemonRequest, DaemonResponse } from '../daemon-client/daemon-client.ts'; function runCliWithDaemonStartupFailure(argv: string[]): Promise { diff --git a/src/__tests__/cli-config-limrun.test.ts b/src/__tests__/cli-config-limrun.test.ts index 3ba7488af0..cde187e47d 100644 --- a/src/__tests__/cli-config-limrun.test.ts +++ b/src/__tests__/cli-config-limrun.test.ts @@ -6,7 +6,7 @@ import { hashRemoteConfigFile, readActiveConnectionState, writeRemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { runCliCapture } from './cli-capture.ts'; import { makeTempWorkspace } from './cli-config-fixtures.ts'; diff --git a/src/__tests__/cli-config.test.ts b/src/__tests__/cli-config.test.ts index a5bf157d53..ea362cfe14 100644 --- a/src/__tests__/cli-config.test.ts +++ b/src/__tests__/cli-config.test.ts @@ -6,7 +6,7 @@ import { hashRemoteConfigFile, readActiveConnectionState, readRemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { runCliCapture, type CapturedDaemonRequest } from './cli-capture.ts'; import { makeTempWorkspace } from './cli-config-fixtures.ts'; diff --git a/src/__tests__/cli-react-devtools-session.test.ts b/src/__tests__/cli-react-devtools-session.test.ts index db50422820..3dd382c482 100644 --- a/src/__tests__/cli-react-devtools-session.test.ts +++ b/src/__tests__/cli-react-devtools-session.test.ts @@ -14,7 +14,7 @@ import { installIsolatedCliTestEnv } from './cli-test-env.ts'; import { hashRemoteConfigFile, writeRemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import type { DaemonResponse } from '../daemon-client/daemon-client.ts'; afterEach(() => { diff --git a/src/__tests__/cloud-connect-auth.test.ts b/src/__tests__/cloud-connect-auth.test.ts index 3ea6e1cf8d..cfe18aef88 100644 --- a/src/__tests__/cloud-connect-auth.test.ts +++ b/src/__tests__/cloud-connect-auth.test.ts @@ -5,7 +5,7 @@ import path from 'node:path'; import { connectCommand } from '../cli/commands/connection.ts'; import { beginStdoutCapture } from './test-utils/stream-capture.ts'; import { resolveCloudAccessForConnect } from '../cli/auth-session.ts'; -import { readActiveConnectionState } from '../remote/remote-connection-state.ts'; +import { readActiveConnectionState } from '@agent-device/remote/remote-connection-state'; import type { AgentDeviceClient } from '../agent-device-client.ts'; import { mkdtempForTestSync } from '@agent-device/test-kit'; diff --git a/src/__tests__/cloud-connect-profile.test.ts b/src/__tests__/cloud-connect-profile.test.ts index 5e5c47bd13..2b0a7c580f 100644 --- a/src/__tests__/cloud-connect-profile.test.ts +++ b/src/__tests__/cloud-connect-profile.test.ts @@ -11,7 +11,7 @@ import { readActiveConnectionState, readRemoteConnectionState, type RemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import type { AgentDeviceClient } from '../agent-device-client.ts'; import { resolveConnectProviderProfile } from '../cli/connection/connect-provider-adapters.ts'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/__tests__/cloud-connect-testmu.test.ts b/src/__tests__/cloud-connect-testmu.test.ts index c94a3755de..bb73ac1906 100644 --- a/src/__tests__/cloud-connect-testmu.test.ts +++ b/src/__tests__/cloud-connect-testmu.test.ts @@ -6,7 +6,7 @@ import { runCliCapture } from './cli-capture.ts'; import { readActiveConnectionState, type RemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { AppError } from '@agent-device/kernel/errors'; import { verifyTestMuConnection } from '@agent-device/testmu/connection-verification'; import testMuPlugin from '@agent-device/testmu'; diff --git a/src/__tests__/lease-provider-profile-fields.test.ts b/src/__tests__/lease-provider-profile-fields.test.ts index 93877912d0..5a3c5090e1 100644 --- a/src/__tests__/lease-provider-profile-fields.test.ts +++ b/src/__tests__/lease-provider-profile-fields.test.ts @@ -16,7 +16,7 @@ import { createProviderDeviceRuntimeRequestProviders } from '../provider-device- import { hashRemoteConfigFile, writeRemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { createTransport } from './client-transport-fixture.ts'; import { runCliCapture } from './cli-capture.ts'; import { makeTempWorkspace } from './cli-config-fixtures.ts'; diff --git a/src/__tests__/remote-connection-harmonyos.test.ts b/src/__tests__/remote-connection-harmonyos.test.ts index 3c0f811458..989820d1f5 100644 --- a/src/__tests__/remote-connection-harmonyos.test.ts +++ b/src/__tests__/remote-connection-harmonyos.test.ts @@ -11,7 +11,7 @@ import { resolveRequestedLeaseBackend, } from '../cli/commands/connection-runtime.ts'; import { disconnectCommand } from '../cli/commands/connection.ts'; -import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; test('HarmonyOS platform resolves to its proxy lease backend', () => { diff --git a/src/__tests__/remote-connection-macos-app.test.ts b/src/__tests__/remote-connection-macos-app.test.ts index 8f08910ade..dfa5f22d69 100644 --- a/src/__tests__/remote-connection-macos-app.test.ts +++ b/src/__tests__/remote-connection-macos-app.test.ts @@ -6,7 +6,7 @@ import type { AgentDeviceClient } from '../agent-device-client.ts'; import { connectCommand, disconnectCommand } from '../cli/commands/connection.ts'; import { materializeRemoteConnectionForCommand } from '../cli/commands/connection-runtime.ts'; import { beginStdoutCapture } from './test-utils/stream-capture.ts'; -import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; import { LeaseRegistry } from '@agent-device/daemon/testing/lease-registry'; const LEASE_ID = 'a1b2c3d4e5f60718293a4b5c6d7e8f90'; diff --git a/src/__tests__/remote-connection-platform-axis.test.ts b/src/__tests__/remote-connection-platform-axis.test.ts index d81737ba0f..d90973b63f 100644 --- a/src/__tests__/remote-connection-platform-axis.test.ts +++ b/src/__tests__/remote-connection-platform-axis.test.ts @@ -22,7 +22,7 @@ import { import { connectCommand } from '../cli/commands/connection.ts'; import { materializeRemoteConnectionForCommand } from '../cli/commands/connection-runtime.ts'; import { AppError } from '@agent-device/kernel/errors'; -import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; afterEach(() => { vi.clearAllMocks(); diff --git a/src/__tests__/remote-connection-proxy-allocate-by-spec.test.ts b/src/__tests__/remote-connection-proxy-allocate-by-spec.test.ts index 22a6fbf71c..b2f213ee4b 100644 --- a/src/__tests__/remote-connection-proxy-allocate-by-spec.test.ts +++ b/src/__tests__/remote-connection-proxy-allocate-by-spec.test.ts @@ -19,7 +19,7 @@ vi.mock('@agent-device/react-native', async (importOriginal) => ({ })); import { materializeRemoteConnectionForCommand } from '../cli/commands/connection-runtime.ts'; -import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; const IPHONE_SIMULATOR = { platform: 'ios', diff --git a/src/__tests__/remote-connection-proxy-lease-id.test.ts b/src/__tests__/remote-connection-proxy-lease-id.test.ts index 4b3f4764cb..41c32f561a 100644 --- a/src/__tests__/remote-connection-proxy-lease-id.test.ts +++ b/src/__tests__/remote-connection-proxy-lease-id.test.ts @@ -15,7 +15,7 @@ vi.mock('@agent-device/react-native', async (importOriginal) => ({ })); import { materializeRemoteConnectionForCommand } from '../cli/commands/connection-runtime.ts'; -import { readRemoteConnectionState } from '../remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; const DAEMON_LEASE_ID = 'abc123abc123abc1'; diff --git a/src/__tests__/remote-connection.fixtures.ts b/src/__tests__/remote-connection.fixtures.ts index b50fcfc597..d0784c996a 100644 --- a/src/__tests__/remote-connection.fixtures.ts +++ b/src/__tests__/remote-connection.fixtures.ts @@ -6,7 +6,7 @@ import { hashRemoteConfigFile, writeRemoteConnectionState, type RemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { mkdtempForTestSync } from '@agent-device/test-kit'; export const unexpectedCommandCall = async (): Promise => { diff --git a/src/__tests__/remote-connection.test.ts b/src/__tests__/remote-connection.test.ts index 16a07ba398..533cfde65d 100644 --- a/src/__tests__/remote-connection.test.ts +++ b/src/__tests__/remote-connection.test.ts @@ -40,7 +40,7 @@ import { readActiveConnectionState, readRemoteConnectionState, writeRemoteConnectionState, -} from '../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import type { AgentDeviceClient } from '../agent-device-client.ts'; afterEach(() => { diff --git a/src/cli.ts b/src/cli.ts index 033fdfb6c7..8c0e8bd4c3 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -42,7 +42,7 @@ import { maybeRunUpgradeNotifier } from './cli/update-check.ts'; import { resolveRemoteConnectionDefaults, type RemoteConnectionRequestMetadata, -} from './remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { resolveRemoteAuthForCli } from './cli/auth-session.ts'; import type { FlagKey } from '@agent-device/command-registry/flag-types'; import type { CliFlags } from '@agent-device/contracts/command'; diff --git a/src/cli/commands/__tests__/connection.test.ts b/src/cli/commands/__tests__/connection.test.ts index 627261c589..6f2d849cb4 100644 --- a/src/cli/commands/__tests__/connection.test.ts +++ b/src/cli/commands/__tests__/connection.test.ts @@ -10,7 +10,7 @@ import { hashRemoteConfigFile, writeRemoteConnectionState, type RemoteConnectionState, -} from '../../../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { mkdtempForTestSync } from '@agent-device/test-kit'; type ConnectionFixture = { diff --git a/src/cli/commands/connection-context.test.ts b/src/cli/commands/connection-context.test.ts index a62b0e3408..24d66a3bb4 100644 --- a/src/cli/commands/connection-context.test.ts +++ b/src/cli/commands/connection-context.test.ts @@ -6,7 +6,7 @@ import { mkdtempForTestSync } from '@agent-device/test-kit'; import { hashRemoteConfigFile, writeRemoteConnectionState, -} from '../../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { resolveConnectContext } from './connection-context.ts'; test('unscoped connect contexts never adopt the ambient connection', () => { diff --git a/src/cli/commands/connection-context.ts b/src/cli/commands/connection-context.ts index cb21d3b311..3ab45c4c0f 100644 --- a/src/cli/commands/connection-context.ts +++ b/src/cli/commands/connection-context.ts @@ -5,7 +5,7 @@ import { hashRemoteConfigFile, readRemoteConnectionState, type RemoteConnectionState, -} from '../../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; export type ConnectContext = { session: string; diff --git a/src/cli/commands/connection-presentation.ts b/src/cli/commands/connection-presentation.ts index e901f5d195..c46349794f 100644 --- a/src/cli/commands/connection-presentation.ts +++ b/src/cli/commands/connection-presentation.ts @@ -1,4 +1,7 @@ -import { fingerprint, type RemoteConnectionState } from '../../remote/remote-connection-state.ts'; +import { + fingerprint, + type RemoteConnectionState, +} from '@agent-device/remote/remote-connection-state'; import type { ConnectVerification } from '../connection/connect-provider-adapters.ts'; import { connectionProviderCapabilities } from '../connection/provider-policy.ts'; import { shellQuoteIfNeeded } from '@agent-device/kernel/device-shell'; diff --git a/src/cli/commands/connection-runtime.ts b/src/cli/commands/connection-runtime.ts index b56eeb49b9..50de3a2dec 100644 --- a/src/cli/commands/connection-runtime.ts +++ b/src/cli/commands/connection-runtime.ts @@ -2,11 +2,11 @@ import crypto from 'node:crypto'; import type { MetroBridgeScope } from '@agent-device/contracts/remote'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; import { stopMetroTunnel } from '@agent-device/react-native'; -import { resolveRemoteConfigProfile } from '../../remote/remote-config.ts'; +import { resolveRemoteConfigProfile } from '@agent-device/remote/remote-config'; // Provenance-preserving file-only read (no ambient env defaults merged in) — // see resolvePreviousOwnDaemonAuthToken below for why this must not be // resolveRemoteConfigProfile. -import { readRemoteConfigFile } from '../../remote/remote-config-core.ts'; +import { readRemoteConfigFile } from '@agent-device/remote/remote-config-core'; import { shouldAgentCdpUseRemoteBridgeUrl } from './agent-cdp.ts'; import { isInactiveLeaseError } from '@agent-device/contracts/lease-scope'; import { @@ -19,7 +19,7 @@ import { writeRemoteConnectionState, type RemoteConnectionState, type RemoteConnectionRequestMetadata, -} from '../../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { profileToCliFlags } from '../remote-config-flags.ts'; import type { BatchStep } from '@agent-device/contracts/client'; import { AppError } from '@agent-device/kernel/errors'; diff --git a/src/cli/commands/connection.ts b/src/cli/commands/connection.ts index 3b8dc44d56..22b07570e8 100644 --- a/src/cli/commands/connection.ts +++ b/src/cli/commands/connection.ts @@ -3,7 +3,7 @@ import type { CloudProviderSessionResult, } from '@agent-device/contracts/observability'; import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; -import { resolveRemoteConfigProfile } from '../../remote/remote-config.ts'; +import { resolveRemoteConfigProfile } from '@agent-device/remote/remote-config'; import { readActiveConnectionState, buildRemoteConnectionRequestMetadata, @@ -16,7 +16,7 @@ import { writeRemoteConnectionState, type RemoteConnectionState, type RemoteConnectionRequestMetadata, -} from '../../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { AppError } from '@agent-device/kernel/errors'; import { connectProviderNamesForError, diff --git a/src/cli/commands/proxy-lease-device.ts b/src/cli/commands/proxy-lease-device.ts index 28494cbcee..32e3b48feb 100644 --- a/src/cli/commands/proxy-lease-device.ts +++ b/src/cli/commands/proxy-lease-device.ts @@ -11,7 +11,7 @@ import { resolveConnectionDeviceScope, type ConnectionDeviceScope, type RemoteConnectionState, -} from '../../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { AppError } from '@agent-device/kernel/errors'; import type { LeaseBackend } from '@agent-device/kernel/contracts'; import type { CliFlags } from '@agent-device/contracts/command'; diff --git a/src/cli/connection/cloud-profile.ts b/src/cli/connection/cloud-profile.ts index 37a8017b3a..62a9a3a462 100644 --- a/src/cli/connection/cloud-profile.ts +++ b/src/cli/connection/cloud-profile.ts @@ -1,4 +1,4 @@ -import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; +import type { RemoteConfigProfile } from '@agent-device/remote/remote-config-schema'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; import { type EnvMap } from '@agent-device/kernel/source-value'; diff --git a/src/cli/connection/connect-provider-adapters.ts b/src/cli/connection/connect-provider-adapters.ts index 0f7fadc22c..d4de3385bc 100644 --- a/src/cli/connection/connect-provider-adapters.ts +++ b/src/cli/connection/connect-provider-adapters.ts @@ -5,7 +5,7 @@ import { verifyLimrunConnection } from '@agent-device/provider-limrun'; import { readVersion } from '@agent-device/host-kit/version'; import { leaseBackendForPlatform } from '@agent-device/kernel/contracts'; import { AppError } from '@agent-device/kernel/errors'; -import { resolveRemoteConfigProfile } from '../../remote/remote-config.ts'; +import { resolveRemoteConfigProfile } from '@agent-device/remote/remote-config'; import { type EnvMap } from '@agent-device/kernel/source-value'; import { resolveCloudConnectProfile } from './cloud-profile.ts'; diff --git a/src/cli/connection/ended-lease.test.ts b/src/cli/connection/ended-lease.test.ts index eadfc340d2..c09d432a69 100644 --- a/src/cli/connection/ended-lease.test.ts +++ b/src/cli/connection/ended-lease.test.ts @@ -7,7 +7,7 @@ import { seedConnectionState, type StoredConnectionSeed, } from '../../__tests__/remote-connection.fixtures.ts'; -import { readRemoteConnectionState } from '../../remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; import { forgetEndedProxyLease } from './ended-lease.ts'; const LEASE_ID = 'abc123abc123abc1'; diff --git a/src/cli/connection/ended-lease.ts b/src/cli/connection/ended-lease.ts index c6e12f5ce4..0076a4412d 100644 --- a/src/cli/connection/ended-lease.ts +++ b/src/cli/connection/ended-lease.ts @@ -5,7 +5,7 @@ import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolu import { readRemoteConnectionState, writeRemoteConnectionState, -} from '../../remote/remote-connection-state.ts'; +} from '@agent-device/remote/remote-connection-state'; import { isHostAllocatedLease } from '../commands/connection-runtime.ts'; import { connectionProviderCapabilities } from './provider-policy.ts'; diff --git a/src/cli/connection/generated-config.ts b/src/cli/connection/generated-config.ts index aebdf467aa..48168ecb71 100644 --- a/src/cli/connection/generated-config.ts +++ b/src/cli/connection/generated-config.ts @@ -1,11 +1,11 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; -import { resolveRemoteConfigProfile } from '../../remote/remote-config.ts'; +import { resolveRemoteConfigProfile } from '@agent-device/remote/remote-config'; import type { RemoteConfigProfile, ResolvedRemoteConfigProfile, -} from '../../remote/remote-config-schema.ts'; +} from '@agent-device/remote/remote-config-schema'; import { AppError, asAppError } from '@agent-device/kernel/errors'; import { type EnvMap } from '@agent-device/kernel/source-value'; import type { CliFlags } from '@agent-device/contracts/command'; diff --git a/src/cli/connection/limrun-profile.ts b/src/cli/connection/limrun-profile.ts index 87cc8f0d12..e2868b5901 100644 --- a/src/cli/connection/limrun-profile.ts +++ b/src/cli/connection/limrun-profile.ts @@ -1,5 +1,5 @@ import { resolveDaemonPaths } from '@agent-device/daemon-contracts/daemon-resolution'; -import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; +import type { RemoteConfigProfile } from '@agent-device/remote/remote-config-schema'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; import { type EnvMap } from '@agent-device/kernel/source-value'; diff --git a/src/cli/connection/proxy-profile.ts b/src/cli/connection/proxy-profile.ts index 22f2658e9c..768bbfe7a6 100644 --- a/src/cli/connection/proxy-profile.ts +++ b/src/cli/connection/proxy-profile.ts @@ -1,4 +1,4 @@ -import type { RemoteConfigProfile } from '../../remote/remote-config-schema.ts'; +import type { RemoteConfigProfile } from '@agent-device/remote/remote-config-schema'; import { AppError } from '@agent-device/kernel/errors'; import type { CliFlags } from '@agent-device/contracts/command'; import { type EnvMap } from '@agent-device/kernel/source-value'; diff --git a/src/cli/remote-config-flags.ts b/src/cli/remote-config-flags.ts index d59693a92e..6127369bc9 100644 --- a/src/cli/remote-config-flags.ts +++ b/src/cli/remote-config-flags.ts @@ -2,8 +2,8 @@ import type { CliFlags } from '@agent-device/contracts/command'; import { REMOTE_CONFIG_FIELD_SPECS, type RemoteConfigProfile, -} from '../remote/remote-config-schema.ts'; -import { resolveRemoteConfigProfile } from '../remote/remote-config-core.ts'; +} from '@agent-device/remote/remote-config-schema'; +import { resolveRemoteConfigProfile } from '@agent-device/remote/remote-config-core'; // Remote config can supply defaults for any supported CLI flag that exists in the profile schema. // Command validation later strips unsupported defaults for the active command. diff --git a/src/commands/schema/option-schema.test.ts b/src/commands/schema/option-schema.test.ts index e893ee7ca1..b7a0c4d2ee 100644 --- a/src/commands/schema/option-schema.test.ts +++ b/src/commands/schema/option-schema.test.ts @@ -11,7 +11,7 @@ import { AppError } from '@agent-device/kernel/errors'; import { REMOTE_CONFIG_FIELD_SPECS, getRemoteConfigEnvNames, -} from '../../remote/remote-config-schema.ts'; +} from '@agent-device/remote/remote-config-schema'; test('option schema exposes config/env metadata for global options', () => { const spec = getOptionSpec('platform'); diff --git a/src/daemon-client/__tests__/daemon-client.test.ts b/src/daemon-client/__tests__/daemon-client.test.ts index 79e0ac109c..a7be7d788f 100644 --- a/src/daemon-client/__tests__/daemon-client.test.ts +++ b/src/daemon-client/__tests__/daemon-client.test.ts @@ -20,7 +20,7 @@ import { readProcessStartTime } from '@agent-device/host-kit/process'; import { sendToDaemon } from '../daemon-client.ts'; import { currentDaemonCodeSignature } from '../../__tests__/test-utils/daemon-http-fixture.ts'; import { computeDaemonCodeSignature } from '@agent-device/host-kit/code-signature'; -import { downloadRemoteArtifact } from '../../remote/daemon-artifacts.ts'; +import { downloadRemoteArtifact } from '@agent-device/remote/daemon-artifacts'; import { resolveDaemonStartupHint } from '../daemon-client-metadata.ts'; import { canConnectSocket } from '../daemon-client-transport.ts'; import { DAEMON_RPC_PROTOCOL_VERSION } from '@agent-device/contracts/daemon-http'; diff --git a/src/daemon-client/daemon-client-rpc.ts b/src/daemon-client/daemon-client-rpc.ts index 26c3b0c081..faa004b4cd 100644 --- a/src/daemon-client/daemon-client-rpc.ts +++ b/src/daemon-client/daemon-client-rpc.ts @@ -8,8 +8,8 @@ import { } from '@agent-device/kernel/errors'; import { sanitizeErrorCause } from '@agent-device/kernel/redaction'; import { createRequestId } from '@agent-device/host-kit/diagnostics'; -import { materializeRemoteArtifacts } from '../remote/daemon-artifacts.ts'; -import { localizeRemoteDaemonError } from '../remote/remote-request-diagnostics.ts'; +import { materializeRemoteArtifacts } from '@agent-device/remote/daemon-artifacts'; +import { localizeRemoteDaemonError } from '@agent-device/remote/remote-request-diagnostics'; import type { DaemonInfo } from './daemon-client-metadata.ts'; import { leaseScopeFromRequest, diff --git a/src/daemon-client/daemon-client.ts b/src/daemon-client/daemon-client.ts index 694076098a..b8e103c0b6 100644 --- a/src/daemon-client/daemon-client.ts +++ b/src/daemon-client/daemon-client.ts @@ -14,7 +14,7 @@ import { resolveCommandRequestTimeoutMs } from '@agent-device/command-registry/t import { prepareRemoteRequestArtifacts, type PreparedRemoteRequest, -} from '../remote/daemon-artifacts.ts'; +} from '@agent-device/remote/daemon-artifacts'; import type { DaemonClientSettings, EnsuredDaemon } from './daemon-client-lifecycle.ts'; import { createRequestGuard, sendRequest } from './daemon-client-transport.ts'; import { isRemoteDaemon, type DaemonInfo } from './daemon-client-metadata.ts'; diff --git a/src/sdk/remote-config.ts b/src/sdk/remote-config.ts index f4a8be73ba..315e44a2a2 100644 --- a/src/sdk/remote-config.ts +++ b/src/sdk/remote-config.ts @@ -1,2 +1,2 @@ -export type { RemoteConfigProfile } from '../remote/remote-config-schema.ts'; -export { resolveRemoteConfigProfile } from '../remote/remote-config.ts'; +export type { RemoteConfigProfile } from '@agent-device/remote/remote-config-schema'; +export { resolveRemoteConfigProfile } from '@agent-device/remote/remote-config'; diff --git a/test/integration/provider-scenarios/remote-daemon-client.test.ts b/test/integration/provider-scenarios/remote-daemon-client.test.ts index 4b332b8169..77b7ccd1b6 100644 --- a/test/integration/provider-scenarios/remote-daemon-client.test.ts +++ b/test/integration/provider-scenarios/remote-daemon-client.test.ts @@ -5,7 +5,7 @@ import os from 'node:os'; import path from 'node:path'; import { test } from 'vitest'; import { createAgentDeviceClient } from '../../../src/agent-device-client.ts'; -import { prepareRemoteRequestArtifacts } from '../../../src/remote/daemon-artifacts.ts'; +import { prepareRemoteRequestArtifacts } from '@agent-device/remote/daemon-artifacts'; import { createDaemonProxyServer } from '@agent-device/proxy'; import { normalizeAgentDeviceError } from '@agent-device/kernel/errors'; import { diff --git a/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts b/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts index 0b41ed7d57..7f2050a967 100644 --- a/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts +++ b/test/integration/provider-scenarios/remote-proxy-artifact-tenant.test.ts @@ -13,7 +13,7 @@ import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http import type { DaemonWireRequest } from '@agent-device/contracts/command'; import type { DaemonResponse } from '@agent-device/kernel/contracts'; import { normalizeAgentDeviceError } from '@agent-device/kernel/errors'; -import { downloadRemoteArtifact } from '../../../src/remote/daemon-artifacts.ts'; +import { downloadRemoteArtifact } from '@agent-device/remote/daemon-artifacts'; import { createDaemonProxyServer } from '@agent-device/proxy'; import { closeLoopbackServer, diff --git a/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts b/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts index 41b405f48c..04d6bc165f 100644 --- a/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts +++ b/test/integration/provider-scenarios/remote-proxy-request-diagnostics.test.ts @@ -19,7 +19,7 @@ import path from 'node:path'; import { test } from 'vitest'; import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; import { createDaemonProxyServer } from '@agent-device/proxy'; -import { localizeRemoteDaemonError } from '../../../src/remote/remote-request-diagnostics.ts'; +import { localizeRemoteDaemonError } from '@agent-device/remote/remote-request-diagnostics'; import { safeSessionName } from '@agent-device/host-kit/session-paths'; import type { DaemonError } from '@agent-device/kernel/errors'; import { diff --git a/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts b/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts index a804213089..05adb785e5 100644 --- a/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts +++ b/test/integration/provider-scenarios/remote-test-artifacts-directory.test.ts @@ -17,7 +17,7 @@ import { trackDownloadableArtifact, } from '@agent-device/daemon/testing/artifact-tracking'; import { createDaemonHttpServer } from '@agent-device/daemon/testing/server/http-server'; -import { downloadRemoteArtifact } from '../../../src/remote/daemon-artifacts.ts'; +import { downloadRemoteArtifact } from '@agent-device/remote/daemon-artifacts'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts b/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts index b72e6ce24a..420b10d655 100644 --- a/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts +++ b/test/integration/provider-scenarios/remote-test-artifacts-materialization.test.ts @@ -15,7 +15,7 @@ import { attachRemoteReplayTestArtifacts } from '@agent-device/replay-port/test- import { downloadRemoteArtifact, materializeRemoteArtifacts, -} from '../../../src/remote/daemon-artifacts.ts'; +} from '@agent-device/remote/daemon-artifacts'; import { closeLoopbackServer, listenOnLoopback, diff --git a/test/integration/remote-connection-process-isolation.test.ts b/test/integration/remote-connection-process-isolation.test.ts index ae80659b79..ef2261146d 100644 --- a/test/integration/remote-connection-process-isolation.test.ts +++ b/test/integration/remote-connection-process-isolation.test.ts @@ -3,7 +3,7 @@ import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; import { mkdtempForTestSync } from '@agent-device/test-kit'; -import { readRemoteConnectionState } from '../../src/remote/remote-connection-state.ts'; +import { readRemoteConnectionState } from '@agent-device/remote/remote-connection-state'; import { runSourceCliJsonSync } from './cli-json.ts'; test('separate CLI processes do not adopt and overwrite the ambient remote session', () => { diff --git a/test/wire-compat/closure-policy.ts b/test/wire-compat/closure-policy.ts index 92d0d3b415..c818236106 100644 --- a/test/wire-compat/closure-policy.ts +++ b/test/wire-compat/closure-policy.ts @@ -49,9 +49,9 @@ export const WIRE_CLOSURE_WAIVERS: Readonly> = { 'Client-side narrowing of the listed kernel DaemonRequest (token and session required, flags typed as CommandFlags); the declaration that fixes the shape is packages/kernel/src/contracts.ts#DaemonRequest.', 'packages/contracts/src/daemon-wire-request.ts#DaemonWireRequestMeta': 'Narrowing of the listed kernel DaemonRequestMeta (installSource, lockPlatform and the lease coordinates); the declaration that fixes the shape is packages/kernel/src/contracts.ts#DaemonRequestMeta.', - 'src/remote/upload-stream.ts#UploadStreamProgressOptions': + 'packages/remote/src/upload-stream.ts#UploadStreamProgressOptions': 'Byte-progress callback options for local upload rendering. The bytes counted are digested through the request/response declarations; these options never cross the wire.', - 'src/remote/upload-progress.ts#UploadProgressSink': + 'packages/remote/src/upload-progress.ts#UploadProgressSink': 'A callback for client-local upload progress rendering. Its events never leave the client, unlike the daemon progress stream, whose envelope and events are listed.', 'packages/contracts/src/request-progress.ts#RequestProgressSink': 'A callback type (event) => void. The event it receives is RequestProgressEvent, which is listed; the sink itself never crosses the wire.', diff --git a/test/wire-compat/ledger.json b/test/wire-compat/ledger.json index eb1371b85e..57c6410b8d 100644 --- a/test/wire-compat/ledger.json +++ b/test/wire-compat/ledger.json @@ -144,43 +144,43 @@ "packages/daemon/src/server/upload-http.ts#resolveUploadHttpRoute": "sha256:8837e62933cf57111a8070454877c5859aed65b4dcdba755f145346e30f82835", "packages/daemon/src/server/upload-http.ts#sendJson": "sha256:c2317b4b14a10731684c9160038005965856150f05f8923765a3fa833d2ecae9", "packages/daemon/src/server/upload-http.ts#sendUploadedArtifactResponse": "sha256:9e418403448d58a96284fed605762fa71f9349bf2c70ad79df69b2b3e27487d6", - "src/remote/artifact-download.ts#RemoteArtifactDownload": "sha256:f73a888f4f8c9d603701c505bb342787b1ca6559a13b15da2385e60349ecea8e", - "src/remote/artifact-download.ts#downloadRemoteArtifactFromUrl": "sha256:cde1ed3649d73da51a0413216aa24a561a2ec57d08ed533ffa985b95b1941cf6", - "src/remote/daemon-artifacts.ts#DaemonArtifactEndpoint": "sha256:45226717ac52c0af2a62f74e91549582d95f4a4abc49be87989e026291a88c82", - "src/remote/daemon-artifacts.ts#DownloadRemoteArtifactParams": "sha256:ba6d2f6ac51e05ccc5e0c940b355d62374e018b1ae6f6f744becf6e1760cbb63", - "src/remote/daemon-artifacts.ts#buildDaemonArtifactUrl": "sha256:06dcde057809b507f70f7bb5cdef9bde6515be84b67e45865cf19e70b8636208", - "src/remote/daemon-artifacts.ts#downloadRemoteArtifact": "sha256:f3ab09ce387577073ecc5bcd2528963e45f91b2c1e4cc57847c3e2732ccbb300", - "src/remote/daemon-artifacts.ts#isRemoteDaemon": "sha256:0f6a714c5f60ce4e8548d811b516d8b6241eca9f7e5414733732da395b8a00e7", - "src/remote/daemon-artifacts.ts#materializeRemoteArtifacts": "sha256:c3ea70cc9a218acfaa30f6c4ba55b80224c96aba10e4e9c7a17828fc851de77e", - "src/remote/daemon-artifacts.ts#resolveMaterializedArtifactPath": "sha256:cad37beddeb03ba70bc92118a5e45f552edfc00feec789758e390d1ea4c7d879", - "src/remote/remote-request-diagnostics.ts#RemoteDaemonErrorPayload": "sha256:8fbcbcdf4bae7b66a08e465a72593794f36364759f18f1a814cd39dfdb76f309", - "src/remote/remote-request-diagnostics.ts#RemoteDiagnosticsEndpoint": "sha256:c1d5fe2fe90c425502cf8b7c87d6606374d6af65b4e9faf942a416f683930bdc", - "src/remote/remote-request-diagnostics.ts#buildRemoteRequestDiagnosticsUrl": "sha256:30a1a9bf0df24d3564a616699916a3bb4360c2b4d21c4ad0562fb0c1e738d0a9", - "src/remote/remote-request-diagnostics.ts#fetchRemoteRequestDiagnostics": "sha256:6f68c317e4c0fe5de008ec1fe5e7e030a9d298ad4a7dfd561db933d22e12ae9e", - "src/remote/remote-request-diagnostics.ts#localizeRemoteDaemonError": "sha256:35cfa186ad64663ae4dbb4e102d49238532cd7e3b75e8337edcc3d1fd77f92d5", - "src/remote/upload-client-artifact.ts#PreparedUploadArtifact": "sha256:5c40027d47feda3c946e836372b9f08ad866ab1612708b0d506551545f931ea4", - "src/remote/upload-client.ts#ARTIFACT_HASH_ALGORITHM": "sha256:328c135ea5f9d89fd2c142b440d5402a61d19f9044bf0504dfc2c525e58c1909", - "src/remote/upload-client.ts#UploadPreflightResponse": "sha256:196a1d9ef41a1aec192589fa7ccb30cf71d971a005349d5d73eed42e6ab21327", - "src/remote/upload-client.ts#UploadPreflightResult": "sha256:bd8fc6d617c0630325455fd64d0fe319daaced198ee6745e4673a8ace3df460d", - "src/remote/upload-client.ts#UploadResponse": "sha256:499e01466b5e0e03413f8d3f1986f5af6bc120704c50a3747d84de422b3f0314", - "src/remote/upload-client.ts#finalizeDirectUpload": "sha256:61f2811d571e57dcca41689c7b1dd37db1fd7a982fbf5eaf33a33cf1541f6ee4", - "src/remote/upload-client.ts#isStringRecord": "sha256:b6d6b571b90baf0976d9c347c4a45a4363a4df5ad184ea1087cb3b9febd4b624", - "src/remote/upload-client.ts#parseUploadPreflightResult": "sha256:7ce3f43b45c03df8b7f2690432beedc7a537c1bba540961716862f8a632d5623", - "src/remote/upload-client.ts#requestUploadPreflight": "sha256:b8caf697f613d9b7e6176007d9cd7f367519338a76f50c1107687bd800ff0a5a", - "src/remote/upload-client.ts#shouldRetryDirectUpload": "sha256:29059f076ff7f2b9540ad15408be48792b2d63a601ef2b9fb2d54f5576d49bbd", - "src/remote/upload-client.ts#tryDirectUploadWithResume": "sha256:db1042b6b8f6969add9480f30a8649d83eecf60af38e80f00a4e789fcf925f97", - "src/remote/upload-client.ts#uploadDirectArtifact": "sha256:3edb622eabee720085a544a4d4e6fdd74c19ec25d3e14e7f9f06ea10d550c1c7", - "src/remote/upload-client.ts#uploadLegacyArtifact": "sha256:3acabacbdea5b7da7f3d8e6e87496728eb3b1df122c490751a9edabc1e9c9adc", - "src/remote/upload-stream.ts#MAX_UPLOAD_REDIRECTS": "sha256:12ff46dfe33a1dce95bdb79c90c17a3ba4f3919e7dc4b3a1b04590fff430f79f", - "src/remote/upload-stream.ts#UploadStreamResponse": "sha256:724e284c2a6bd7b4b3a49b1d8c61c8923d6cc24777c3d76224a69d190e56adce", - "src/remote/upload-stream.ts#buildUploadRequestHeaders": "sha256:827576b13a9f3e6cea445119a6a29b2ac5eaa23b66436cf810b2d09765c82a4c", - "src/remote/upload-stream.ts#firstHeaderValue": "sha256:f6dba645814124f2ea2267e64a5d27c3bcff6dfc00ed692946180fc20e3d41de", - "src/remote/upload-stream.ts#isUploadRedirectStatus": "sha256:4b18a4f97a02a7a609eba85d7d657b3cd2142d5ba6662a9b08cf4c0c9ed02006", - "src/remote/upload-stream.ts#isUploadResumeStatus": "sha256:9f730ccd1c3401c326f8df67d1fd8243fef757357a38a1f53736df2b90bd8fdc", - "src/remote/upload-stream.ts#parseNonNegativeIntegerHeader": "sha256:5cbe9c6994459d673d988a51407e65556e28175b187ce0a9d27cbb6331962834", - "src/remote/upload-stream.ts#parseUploadResumeOffset": "sha256:297184ea22a6dc1cda9aee17034122ae0ea2f43d0355647f6fcf02f3f4b5ca0e", - "src/remote/upload-stream.ts#streamFileToHttpRequest": "sha256:ce07ea33a275e06e4cceaf0c75a079bd0c7938f36df6817407dbb1cc8c4ff900", - "src/remote/upload-stream.ts#streamFileToHttpRequestAttempt": "sha256:aa73fb51890ca5e43d4aa80c1d2124b574568380a73b19eae7da0ee3e3e7acf8", + "packages/remote/src/artifact-download.ts#RemoteArtifactDownload": "sha256:f73a888f4f8c9d603701c505bb342787b1ca6559a13b15da2385e60349ecea8e", + "packages/remote/src/artifact-download.ts#downloadRemoteArtifactFromUrl": "sha256:cde1ed3649d73da51a0413216aa24a561a2ec57d08ed533ffa985b95b1941cf6", + "packages/remote/src/daemon-artifacts.ts#DaemonArtifactEndpoint": "sha256:45226717ac52c0af2a62f74e91549582d95f4a4abc49be87989e026291a88c82", + "packages/remote/src/daemon-artifacts.ts#DownloadRemoteArtifactParams": "sha256:ba6d2f6ac51e05ccc5e0c940b355d62374e018b1ae6f6f744becf6e1760cbb63", + "packages/remote/src/daemon-artifacts.ts#buildDaemonArtifactUrl": "sha256:06dcde057809b507f70f7bb5cdef9bde6515be84b67e45865cf19e70b8636208", + "packages/remote/src/daemon-artifacts.ts#downloadRemoteArtifact": "sha256:f3ab09ce387577073ecc5bcd2528963e45f91b2c1e4cc57847c3e2732ccbb300", + "packages/remote/src/daemon-artifacts.ts#isRemoteDaemon": "sha256:0f6a714c5f60ce4e8548d811b516d8b6241eca9f7e5414733732da395b8a00e7", + "packages/remote/src/daemon-artifacts.ts#materializeRemoteArtifacts": "sha256:c3ea70cc9a218acfaa30f6c4ba55b80224c96aba10e4e9c7a17828fc851de77e", + "packages/remote/src/daemon-artifacts.ts#resolveMaterializedArtifactPath": "sha256:cad37beddeb03ba70bc92118a5e45f552edfc00feec789758e390d1ea4c7d879", + "packages/remote/src/remote-request-diagnostics.ts#RemoteDaemonErrorPayload": "sha256:8fbcbcdf4bae7b66a08e465a72593794f36364759f18f1a814cd39dfdb76f309", + "packages/remote/src/remote-request-diagnostics.ts#RemoteDiagnosticsEndpoint": "sha256:c1d5fe2fe90c425502cf8b7c87d6606374d6af65b4e9faf942a416f683930bdc", + "packages/remote/src/remote-request-diagnostics.ts#buildRemoteRequestDiagnosticsUrl": "sha256:30a1a9bf0df24d3564a616699916a3bb4360c2b4d21c4ad0562fb0c1e738d0a9", + "packages/remote/src/remote-request-diagnostics.ts#fetchRemoteRequestDiagnostics": "sha256:6f68c317e4c0fe5de008ec1fe5e7e030a9d298ad4a7dfd561db933d22e12ae9e", + "packages/remote/src/remote-request-diagnostics.ts#localizeRemoteDaemonError": "sha256:35cfa186ad64663ae4dbb4e102d49238532cd7e3b75e8337edcc3d1fd77f92d5", + "packages/remote/src/upload-client-artifact.ts#PreparedUploadArtifact": "sha256:5c40027d47feda3c946e836372b9f08ad866ab1612708b0d506551545f931ea4", + "packages/remote/src/upload-client.ts#ARTIFACT_HASH_ALGORITHM": "sha256:328c135ea5f9d89fd2c142b440d5402a61d19f9044bf0504dfc2c525e58c1909", + "packages/remote/src/upload-client.ts#UploadPreflightResponse": "sha256:196a1d9ef41a1aec192589fa7ccb30cf71d971a005349d5d73eed42e6ab21327", + "packages/remote/src/upload-client.ts#UploadPreflightResult": "sha256:bd8fc6d617c0630325455fd64d0fe319daaced198ee6745e4673a8ace3df460d", + "packages/remote/src/upload-client.ts#UploadResponse": "sha256:499e01466b5e0e03413f8d3f1986f5af6bc120704c50a3747d84de422b3f0314", + "packages/remote/src/upload-client.ts#finalizeDirectUpload": "sha256:61f2811d571e57dcca41689c7b1dd37db1fd7a982fbf5eaf33a33cf1541f6ee4", + "packages/remote/src/upload-client.ts#isStringRecord": "sha256:b6d6b571b90baf0976d9c347c4a45a4363a4df5ad184ea1087cb3b9febd4b624", + "packages/remote/src/upload-client.ts#parseUploadPreflightResult": "sha256:7ce3f43b45c03df8b7f2690432beedc7a537c1bba540961716862f8a632d5623", + "packages/remote/src/upload-client.ts#requestUploadPreflight": "sha256:b8caf697f613d9b7e6176007d9cd7f367519338a76f50c1107687bd800ff0a5a", + "packages/remote/src/upload-client.ts#shouldRetryDirectUpload": "sha256:29059f076ff7f2b9540ad15408be48792b2d63a601ef2b9fb2d54f5576d49bbd", + "packages/remote/src/upload-client.ts#tryDirectUploadWithResume": "sha256:db1042b6b8f6969add9480f30a8649d83eecf60af38e80f00a4e789fcf925f97", + "packages/remote/src/upload-client.ts#uploadDirectArtifact": "sha256:3edb622eabee720085a544a4d4e6fdd74c19ec25d3e14e7f9f06ea10d550c1c7", + "packages/remote/src/upload-client.ts#uploadLegacyArtifact": "sha256:3acabacbdea5b7da7f3d8e6e87496728eb3b1df122c490751a9edabc1e9c9adc", + "packages/remote/src/upload-stream.ts#MAX_UPLOAD_REDIRECTS": "sha256:12ff46dfe33a1dce95bdb79c90c17a3ba4f3919e7dc4b3a1b04590fff430f79f", + "packages/remote/src/upload-stream.ts#UploadStreamResponse": "sha256:724e284c2a6bd7b4b3a49b1d8c61c8923d6cc24777c3d76224a69d190e56adce", + "packages/remote/src/upload-stream.ts#buildUploadRequestHeaders": "sha256:827576b13a9f3e6cea445119a6a29b2ac5eaa23b66436cf810b2d09765c82a4c", + "packages/remote/src/upload-stream.ts#firstHeaderValue": "sha256:f6dba645814124f2ea2267e64a5d27c3bcff6dfc00ed692946180fc20e3d41de", + "packages/remote/src/upload-stream.ts#isUploadRedirectStatus": "sha256:4b18a4f97a02a7a609eba85d7d657b3cd2142d5ba6662a9b08cf4c0c9ed02006", + "packages/remote/src/upload-stream.ts#isUploadResumeStatus": "sha256:9f730ccd1c3401c326f8df67d1fd8243fef757357a38a1f53736df2b90bd8fdc", + "packages/remote/src/upload-stream.ts#parseNonNegativeIntegerHeader": "sha256:5cbe9c6994459d673d988a51407e65556e28175b187ce0a9d27cbb6331962834", + "packages/remote/src/upload-stream.ts#parseUploadResumeOffset": "sha256:297184ea22a6dc1cda9aee17034122ae0ea2f43d0355647f6fcf02f3f4b5ca0e", + "packages/remote/src/upload-stream.ts#streamFileToHttpRequest": "sha256:ce07ea33a275e06e4cceaf0c75a079bd0c7938f36df6817407dbb1cc8c4ff900", + "packages/remote/src/upload-stream.ts#streamFileToHttpRequestAttempt": "sha256:aa73fb51890ca5e43d4aa80c1d2124b574568380a73b19eae7da0ee3e3e7acf8", "packages/contracts/src/daemon-http.ts#DAEMON_HTTP_INSTANCE_HEADER": "sha256:d2bb3f4846470188a0fc1724271da0f0bcbdf2337bd6bf331508142cadcb65d8", "packages/contracts/src/daemon-http.ts#DAEMON_HTTP_UPSTREAM_INSTANCE_HEADER": "sha256:4564c2ce437d30d7a823e3326f4375c0750ba8d42bec22b4d02e8eb7f7db2973", "packages/contracts/src/daemon-http.ts#DAEMON_HTTP_INSTANCE_MISMATCH_HEADER": "sha256:a197edaf7f9fa94a6aab269856aa852da3204cc586f5fd23198689eb11908b61", @@ -205,17 +205,17 @@ "rationale": "#2747 adds the 'screen-recording-contact-sheet' literal for the PNG that `record contact-sheet` publishes beside the recording it read. DaemonArtifactType already widens to `(string & {})`, so an artifactType value outside the known set was always valid on the wire; the literal only sharpens the type hint for code that opts into recognizing it. A released peer that does not know it never requests that field in a download and parses the artifact record by its `field`, so it carries the sheet as an unknown artifact instead of failing." }, { - "declaration": "src/remote/daemon-artifacts.ts#DownloadRemoteArtifactParams", + "declaration": "packages/remote/src/daemon-artifacts.ts#DownloadRemoteArtifactParams", "digest": "sha256:ba6d2f6ac51e05ccc5e0c940b355d62374e018b1ae6f6f744becf6e1760cbb63", "rationale": "#2246 adds the optional isDirectory field. It is pure client-local state — never serialized, never sent to the daemon — that tells the CLIENT'S OWN download logic to extract a tar body instead of writing it verbatim; the GET /artifacts/:id request and response framing are unchanged. Every existing call site (screenshot, recording) omits it and keeps writing a single file exactly as before. The signature also names the client request as DaemonWireRequest and the response as the kernel DaemonResponse instead of the daemon package aliases; only compile-time type names moved." }, { - "declaration": "src/remote/daemon-artifacts.ts#downloadRemoteArtifact", + "declaration": "packages/remote/src/daemon-artifacts.ts#downloadRemoteArtifact", "digest": "sha256:f3ab09ce387577073ecc5bcd2528963e45f91b2c1e4cc57847c3e2732ccbb300", "rationale": "#2246 selects a file or directory destination once. Directory downloads stage and safely extract beside the destination, propagate timeout cancellation through both operations, and atomically rename the complete top-level entry; returning that local path is client-only state. The GET /artifacts/:id request and response framing, and every existing file artifact call site's behavior, are unchanged." }, { - "declaration": "src/remote/daemon-artifacts.ts#materializeRemoteArtifacts", + "declaration": "packages/remote/src/daemon-artifacts.ts#materializeRemoteArtifacts", "digest": "sha256:c3ea70cc9a218acfaa30f6c4ba55b80224c96aba10e4e9c7a17828fc851de77e", "rationale": "#2246 passes isDirectory only for the new test-artifacts type and uses the exact path the client materializer published. Existing screenshot and recording artifacts still report their requested file path; only the new directory response gains its suite-invocation segment. The signature also names the client request as DaemonWireRequest and the response as the kernel DaemonResponse instead of the daemon package aliases; only compile-time type names moved." }, @@ -315,12 +315,12 @@ "rationale": "#2894 lets an iOS runner start outlive the caller whose deadline gave up on it, so a progress event can arrive after the response ended. The sink now also skips a response whose writable side has ended, next to the destroyed check it already had. No byte written to a live response changes: the envelope framing and payload are untouched, and a released client never sees an event it could not have received before." }, { - "declaration": "src/remote/upload-stream.ts#streamFileToHttpRequest", + "declaration": "packages/remote/src/upload-stream.ts#streamFileToHttpRequest", "digest": "sha256:ce07ea33a275e06e4cceaf0c75a079bd0c7938f36df6817407dbb1cc8c4ff900", "rationale": "#2946 widens the options with an optional abort signal handed to node:http.request. The request line, headers built by buildUploadRequestHeaders, and piped payload are unchanged, so an older daemon's 200/308 handling is unaffected." }, { - "declaration": "src/remote/upload-stream.ts#streamFileToHttpRequestAttempt", + "declaration": "packages/remote/src/upload-stream.ts#streamFileToHttpRequestAttempt", "digest": "sha256:aa73fb51890ca5e43d4aa80c1d2124b574568380a73b19eae7da0ee3e3e7acf8", "rationale": "#2946 passes the optional abort signal to the request and rejects with that signal's reason when it is what ended the stream. The released 308 resume contract is untouched: offset headers, resume start offsets, redirects, and payload bytes are computed exactly as before." }, @@ -410,12 +410,12 @@ "rationale": "The health-probe budget includes requester loading and response completion. The caller AbortSignal joins the probe timer only in-process; caller cancellation remains distinct from probe expiry. No signal, timedOut flag, request route, auth header or accepted health payload field changes on the wire, so released daemons and proxies parse and respond as before (ADR 0006)." }, { - "declaration": "src/remote/remote-request-diagnostics.ts#RemoteDiagnosticsEndpoint", + "declaration": "packages/remote/src/remote-request-diagnostics.ts#RemoteDiagnosticsEndpoint", "digest": "sha256:c1d5fe2fe90c425502cf8b7c87d6606374d6af65b4e9faf942a416f683930bdc", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, { - "declaration": "src/remote/remote-request-diagnostics.ts#fetchRemoteRequestDiagnostics", + "declaration": "packages/remote/src/remote-request-diagnostics.ts#fetchRemoteRequestDiagnostics", "digest": "sha256:6f68c317e4c0fe5de008ec1fe5e7e030a9d298ad4a7dfd561db933d22e12ae9e", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, @@ -425,32 +425,32 @@ "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006). The signature also names the client request as DaemonWireRequest and the kernel DaemonResponse instead of the daemon package aliases; only compile-time type names moved." }, { - "declaration": "src/remote/upload-client.ts#requestUploadPreflight", + "declaration": "packages/remote/src/upload-client.ts#requestUploadPreflight", "digest": "sha256:b8caf697f613d9b7e6176007d9cd7f367519338a76f50c1107687bd800ff0a5a", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, { - "declaration": "src/remote/upload-client.ts#uploadDirectArtifact", + "declaration": "packages/remote/src/upload-client.ts#uploadDirectArtifact", "digest": "sha256:3edb622eabee720085a544a4d4e6fdd74c19ec25d3e14e7f9f06ea10d550c1c7", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, { - "declaration": "src/remote/upload-client.ts#tryDirectUploadWithResume", + "declaration": "packages/remote/src/upload-client.ts#tryDirectUploadWithResume", "digest": "sha256:db1042b6b8f6969add9480f30a8649d83eecf60af38e80f00a4e789fcf925f97", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, { - "declaration": "src/remote/upload-client.ts#finalizeDirectUpload", + "declaration": "packages/remote/src/upload-client.ts#finalizeDirectUpload", "digest": "sha256:61f2811d571e57dcca41689c7b1dd37db1fd7a982fbf5eaf33a33cf1541f6ee4", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, { - "declaration": "src/remote/upload-client.ts#uploadLegacyArtifact", + "declaration": "packages/remote/src/upload-client.ts#uploadLegacyArtifact", "digest": "sha256:3acabacbdea5b7da7f3d8e6e87496728eb3b1df122c490751a9edabc1e9c9adc", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, { - "declaration": "src/remote/artifact-download.ts#downloadRemoteArtifactFromUrl", + "declaration": "packages/remote/src/artifact-download.ts#downloadRemoteArtifactFromUrl", "digest": "sha256:cde1ed3649d73da51a0413216aa24a561a2ec57d08ed533ffa985b95b1941cf6", "rationale": "Clients name a held agent-device lease in an optional x-agent-device-lease-id request header on upload, artifact download and request diagnostics HTTP calls, so a gateway can route them. Released daemons ignore unknown request headers and the proxy forwards only its allowlist, so routes, bodies and responses parse as before; with no lease held the request is unchanged (ADR 0006)." }, @@ -475,7 +475,7 @@ "rationale": "The client names its request as DaemonWireRequest (packages/contracts/src/daemon-wire-request.ts, a narrowing of the listed kernel DaemonRequest) and its response as the kernel DaemonResponse, instead of the daemon package's DaemonRequest/DaemonResponse aliases, so the daemon package is no longer a client import. The declaration's serialized fields, method names and framing are unchanged; only the compile-time type names in its signature moved, so a peer on protocol 2 parses exactly what it did." }, { - "declaration": "src/remote/daemon-artifacts.ts#resolveMaterializedArtifactPath", + "declaration": "packages/remote/src/daemon-artifacts.ts#resolveMaterializedArtifactPath", "digest": "sha256:cad37beddeb03ba70bc92118a5e45f552edfc00feec789758e390d1ea4c7d879", "rationale": "The client names its request as DaemonWireRequest (packages/contracts/src/daemon-wire-request.ts, a narrowing of the listed kernel DaemonRequest) and its response as the kernel DaemonResponse, instead of the daemon package's DaemonRequest/DaemonResponse aliases, so the daemon package is no longer a client import. The declaration's serialized fields, method names and framing are unchanged; only the compile-time type names in its signature moved, so a peer on protocol 2 parses exactly what it did." } diff --git a/test/wire-compat/surface.ts b/test/wire-compat/surface.ts index 1381795218..ef97aa1afa 100644 --- a/test/wire-compat/surface.ts +++ b/test/wire-compat/surface.ts @@ -54,16 +54,16 @@ const ARTIFACT_HTTP = 'packages/daemon/src/server/downloadable-artifact-http.ts' const REQUEST_DIAGNOSTICS_HTTP = 'packages/daemon/src/server/request-diagnostics-http.ts'; const SESSION_TENANT_SCOPE = 'packages/daemon/src/core/session-tenant-scope.ts'; const HTTP_REQUEST_TARGET = 'packages/daemon/src/server/http-request-target.ts'; -const REMOTE_REQUEST_DIAGNOSTICS = 'src/remote/remote-request-diagnostics.ts'; +const REMOTE_REQUEST_DIAGNOSTICS = 'packages/remote/src/remote-request-diagnostics.ts'; const PROGRESS_PROTOCOL = 'packages/daemon-contracts/src/request-progress-protocol.ts'; const CLIENT_RPC = 'src/daemon-client/daemon-client-rpc.ts'; const CLIENT_PROGRESS = 'src/daemon-client/daemon-client-progress.ts'; const CLIENT_TRANSPORT = 'src/daemon-client/daemon-client-transport.ts'; const DAEMON_PROXY = 'packages/proxy/src/daemon-proxy.ts'; -const UPLOAD_CLIENT = 'src/remote/upload-client.ts'; -const REMOTE_ARTIFACTS = 'src/remote/daemon-artifacts.ts'; -const ARTIFACT_DOWNLOAD = 'src/remote/artifact-download.ts'; -const UPLOAD_STREAM = 'src/remote/upload-stream.ts'; +const UPLOAD_CLIENT = 'packages/remote/src/upload-client.ts'; +const REMOTE_ARTIFACTS = 'packages/remote/src/daemon-artifacts.ts'; +const ARTIFACT_DOWNLOAD = 'packages/remote/src/artifact-download.ts'; +const UPLOAD_STREAM = 'packages/remote/src/upload-stream.ts'; function from(file: string, ...names: string[]): WireDeclarationRef[] { return names.map((name) => ({ file, name })); @@ -380,7 +380,7 @@ export const WIRE_SURFACE: readonly WireSurfaceGroup[] = [ ), // The prepared artifact whose fields (sha256, sizeBytes, fileName, // artifactType, contentType) ARE the preflight body the daemon parses. - ...from('src/remote/upload-client-artifact.ts', 'PreparedUploadArtifact'), + ...from('packages/remote/src/upload-client-artifact.ts', 'PreparedUploadArtifact'), // Consumer side of the resumable 308 contract. Listing the daemon's // `handleResumableUpload` proves it still PRODUCES 308; it says nothing // about the client still CONSUMING the released one. These own which diff --git a/test/wire-compat/wire-mutations.test.ts b/test/wire-compat/wire-mutations.test.ts index 68d760feb6..23e7c8e942 100644 --- a/test/wire-compat/wire-mutations.test.ts +++ b/test/wire-compat/wire-mutations.test.ts @@ -187,49 +187,49 @@ const MUTATIONS: readonly WireMutation[] = [ }, { breakClass: 'upload consumer: the preflight parser stops accepting a released response', - file: 'src/remote/upload-client.ts', + file: 'packages/remote/src/upload-client.ts', name: 'parseUploadPreflightResult', from: "preflight.ok !== true || typeof preflight.uploadId !== 'string'", to: 'preflight.ok !== true', }, { breakClass: 'upload consumer: the preflight response shape narrows', - file: 'src/remote/upload-client.ts', + file: 'packages/remote/src/upload-client.ts', name: 'UploadPreflightResponse', from: 'cacheHit?: boolean;', to: '', }, { breakClass: 'upload consumer: the legacy/finalize response shape narrows', - file: 'src/remote/upload-client.ts', + file: 'packages/remote/src/upload-client.ts', name: 'UploadResponse', from: 'uploadId: string;', to: 'id: string;', }, { breakClass: 'upload consumer: the finalize request body key is renamed', - file: 'src/remote/upload-client.ts', + file: 'packages/remote/src/upload-client.ts', name: 'finalizeDirectUpload', from: 'JSON.stringify({ uploadId: options.uploadId })', to: 'JSON.stringify({ id: options.uploadId })', }, { breakClass: 'upload consumer: the preflight ticket fields the daemon parses are renamed', - file: 'src/remote/upload-client-artifact.ts', + file: 'packages/remote/src/upload-client-artifact.ts', name: 'PreparedUploadArtifact', from: 'sha256: string;', to: 'checksum: string;', }, { breakClass: 'artifact consumer: the download request drops its tenant header', - file: 'src/remote/artifact-download.ts', + file: 'packages/remote/src/artifact-download.ts', name: 'downloadRemoteArtifactFromUrl', from: '...buildDaemonHttpTenantHeaders(params.requestScope?.tenantId),', to: '', }, { breakClass: 'artifact consumer: the artifact URL the client requests moves', - file: 'src/remote/daemon-artifacts.ts', + file: 'packages/remote/src/daemon-artifacts.ts', name: 'buildDaemonArtifactUrl', from: 'artifacts/', to: 'artifact/', @@ -241,42 +241,42 @@ const MUTATIONS: readonly WireMutation[] = [ // still the status it treats as "continue". { breakClass: '308 consumer: the client stops accepting a released offset header', - file: 'src/remote/upload-stream.ts', + file: 'packages/remote/src/upload-stream.ts', name: 'parseUploadResumeOffset', from: "headers['x-upload-offset'] ?? headers['upload-offset']", to: "headers['x-upload-offset']", }, { breakClass: '308 consumer: Range-header offset parsing narrows', - file: 'src/remote/upload-stream.ts', + file: 'packages/remote/src/upload-stream.ts', name: 'parseUploadResumeOffset', from: '/^bytes=0-(\\d+)$/', to: '/^bytes 0-(\\d+)$/', }, { breakClass: '308 consumer: the resumed request emits a different Content-Range', - file: 'src/remote/upload-stream.ts', + file: 'packages/remote/src/upload-stream.ts', name: 'buildUploadRequestHeaders', from: "'content-range': `bytes ${startOffset}-${payloadSize - 1}/${payloadSize}`,", to: "'content-range': `bytes=${startOffset}-${payloadSize - 1}/${payloadSize}`,", }, { breakClass: '308 consumer: the client stops treating 308 as resume-and-continue', - file: 'src/remote/upload-stream.ts', + file: 'packages/remote/src/upload-stream.ts', name: 'isUploadResumeStatus', from: 'statusCode === 308', to: 'statusCode === 208', }, { breakClass: '308 consumer: the streamed response shape a caller parses narrows', - file: 'src/remote/upload-stream.ts', + file: 'packages/remote/src/upload-stream.ts', name: 'UploadStreamResponse', from: 'statusMessage?: string;', to: '', }, { breakClass: '308 consumer: header value coercion drops a released form', - file: 'src/remote/upload-stream.ts', + file: 'packages/remote/src/upload-stream.ts', name: 'parseNonNegativeIntegerHeader', from: 'firstHeaderValue(value)', to: 'undefined', @@ -342,7 +342,7 @@ const CLOSURE_PROBES: readonly { reachedFrom: string; omit: string }[] = [ // The consumer half of the auxiliary upload boundary, added after review: // proves those files are genuinely wired into the walk, not just listed. reachedFrom: 'requestUploadPreflight', - omit: 'src/remote/upload-client-artifact.ts#PreparedUploadArtifact', + omit: 'packages/remote/src/upload-client-artifact.ts#PreparedUploadArtifact', }, ]; diff --git a/tsconfig.typecheck.json b/tsconfig.typecheck.json index f61d57960b..5c32314d90 100644 --- a/tsconfig.typecheck.json +++ b/tsconfig.typecheck.json @@ -29,6 +29,7 @@ { "path": "packages/provision-kit" }, { "path": "packages/proxy" }, { "path": "packages/react-native" }, + { "path": "packages/remote" }, { "path": "packages/replay-port" }, { "path": "packages/replay-test" }, { "path": "packages/selectors" }, diff --git a/tsdown.config.ts b/tsdown.config.ts index 479a45576e..853698fa50 100644 --- a/tsdown.config.ts +++ b/tsdown.config.ts @@ -56,8 +56,8 @@ const publicSdkChunkGroups = [ ], [ 'sdk-remote-config', - /src[\\/]remote[\\/]remote-config-schema\.d\.[cm]?ts$/, - /src[\\/]remote[\\/]remote-config-schema\.ts$/, + /packages[\\/]remote[\\/]src[\\/]remote-config-schema\.d\.[cm]?ts$/, + /packages[\\/]remote[\\/]src[\\/]remote-config-schema\.ts$/, ], ['sdk-selectors', /src[\\/]sdk[\\/]selectors\.d\.[cm]?ts$/, /src[\\/]sdk[\\/]selectors\.ts$/], ] as const; diff --git a/vitest.config.ts b/vitest.config.ts index 261e73155d..eab8d3bfc8 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -320,7 +320,7 @@ export default defineConfig({ 'src/bin.ts', 'src/client/client-types.ts', 'src/core/interactor-types.ts', - 'src/remote/remote-config.ts', + 'packages/remote/src/remote-config.ts', ], }, },