diff --git a/apps/web/tests/chat-continuous-conversation.e2e.ts b/apps/web/tests/chat-continuous-conversation.e2e.ts index a7b659dab2..cd15f2e054 100644 --- a/apps/web/tests/chat-continuous-conversation.e2e.ts +++ b/apps/web/tests/chat-continuous-conversation.e2e.ts @@ -12,14 +12,13 @@ import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest' import { CallId, type StreamChunk } from '@deepseek-ai/dsh-llm' import type { ReplayEntry, ReplayOverrideDoc } from '@deepseek-ai/dsh-llm-replay' import type { SessionEvent, SessionId } from '@deepseek-ai/dsh-session' -import { conversationContextKey } from '@deepseek-ai/dsh-client-runtime/client' import { launchWebScaffold, watchConsole, webSnapshotMode, type WebScaffold, } from './scaffold.ts' -import { connectFreshWorkspace, newEnglishPage, saveFailureShot } from './support.ts' +import { connectFreshWorkspace, conversationContextKey, newEnglishPage, saveFailureShot } from './support.ts' const MODE = webSnapshotMode() const TURN_COUNT = 12 diff --git a/apps/web/tests/chat-long-interactions.e2e.ts b/apps/web/tests/chat-long-interactions.e2e.ts index aca85146b5..58d97e5e3e 100644 --- a/apps/web/tests/chat-long-interactions.e2e.ts +++ b/apps/web/tests/chat-long-interactions.e2e.ts @@ -11,7 +11,6 @@ import { afterAll, beforeAll, describe, expect, it, onTestFailed } from 'vitest' import type { StreamChunk } from '@deepseek-ai/dsh-llm' import type { ReplayEntry, ReplayOverrideDoc } from '@deepseek-ai/dsh-llm-replay' import { SessionId, type SessionEvent } from '@deepseek-ai/dsh-session' -import { conversationContextKey } from '@deepseek-ai/dsh-client-runtime/client' import { createChatScrollFixture } from './chat-scroll-fixture.ts' import { launchWebScaffold, @@ -20,7 +19,7 @@ import { webSnapshotMode, type WebScaffold, } from './scaffold.ts' -import { newEnglishPage, saveFailureShot } from './support.ts' +import { conversationContextKey, newEnglishPage, saveFailureShot } from './support.ts' const MODE = webSnapshotMode() const SESSION_ID = 'chat-long-interactions-e2e' diff --git a/apps/web/tests/support.ts b/apps/web/tests/support.ts index ee2a1a1a62..38d0849784 100644 --- a/apps/web/tests/support.ts +++ b/apps/web/tests/support.ts @@ -119,3 +119,17 @@ export async function saveFailureShot(page: Page, name: string): Promise { // Best-effort evidence: a dead page/browser at failure time must not mask the real assertion error. } } + +/** + * The conversation engine's Context key format, restated here rather than + * imported: these specs live in the Host compiler aggregate, which must not + * reach the Client plane. The engine's own copy is + * `conversationContextKey` in dsh-client-runtime; a drift between them makes + * the key miss its rendered node, so the assertion fails loudly. + * @param kind - Definition kind. + * @param id - Definition-local business identity. + * @returns the engine-owned Context key. + */ +export function conversationContextKey(kind: string, id: string): string { + return `${kind.length}:${kind}${id}` +} diff --git a/packages/api/gateway/tsconfig.client.json b/packages/api/gateway/tsconfig.client.json new file mode 100644 index 0000000000..de257c951a --- /dev/null +++ b/packages/api/gateway/tsconfig.client.json @@ -0,0 +1,22 @@ +{ + "extends": "../../../tsconfig.base.client.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types", + "tsBuildInfoFile": "lib/tsconfig.client.tsbuildinfo" + }, + "files": [ + "src/client/index.ts" + ], + "references": [ + { + "path": "../../../vendor/cordis" + }, + { + "path": "../../client/connection/tsconfig.client.json" + }, + { + "path": "../../typert/type-meta" + } + ] +} diff --git a/packages/api/gateway/tsconfig.host.json b/packages/api/gateway/tsconfig.host.json new file mode 100644 index 0000000000..5c12e43cc2 --- /dev/null +++ b/packages/api/gateway/tsconfig.host.json @@ -0,0 +1,30 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types", + "tsBuildInfoFile": "lib/tsconfig.host.tsbuildinfo" + }, + "files": [ + "src/index.ts", + "src/invariant.ts", + "src/types.ts" + ], + "references": [ + { + "path": "../../../vendor/cosmokit" + }, + { + "path": "../../../vendor/cordis" + }, + { + "path": "../../support/invariants" + }, + { + "path": "../../client/connection/tsconfig.host.json" + }, + { + "path": "../../typert/type-meta" + } + ] +} diff --git a/packages/api/gateway/tsconfig.json b/packages/api/gateway/tsconfig.json index fea39663f7..2eca820546 100644 --- a/packages/api/gateway/tsconfig.json +++ b/packages/api/gateway/tsconfig.json @@ -1,27 +1,11 @@ { - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "lib/types" - }, - "include": [ - "src" - ], + "files": [], "references": [ { - "path": "../../../vendor/cosmokit" + "path": "./tsconfig.host.json" }, { - "path": "../../../vendor/cordis" - }, - { - "path": "../../support/invariants" - }, - { - "path": "../../client/connection" - }, - { - "path": "../../typert/type-meta" + "path": "./tsconfig.client.json" } ] } diff --git a/packages/api/remotes/tsconfig.client.json b/packages/api/remotes/tsconfig.client.json index 256258c668..8f28b83a6e 100644 --- a/packages/api/remotes/tsconfig.client.json +++ b/packages/api/remotes/tsconfig.client.json @@ -15,7 +15,10 @@ "path": "../../../vendor/cordis" }, { - "path": "../gateway" + "path": "../gateway/tsconfig.client.json" + }, + { + "path": "../../client/connection/tsconfig.client.json" }, { "path": "../../credentials/credentials" diff --git a/packages/client/connection/tsconfig.client.json b/packages/client/connection/tsconfig.client.json new file mode 100644 index 0000000000..91ec8b42c7 --- /dev/null +++ b/packages/client/connection/tsconfig.client.json @@ -0,0 +1,49 @@ +{ + "extends": "../../../tsconfig.base.client.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types", + "tsBuildInfoFile": "lib/tsconfig.client.tsbuildinfo" + }, + "files": [ + "src/api-path.ts", + "src/client/api.ts", + "src/client/connection.ts", + "src/client/fixture.ts", + "src/client/index.ts", + "src/client/random-uuid.ts", + "src/client/rpc.ts", + "src/client/web-api-client.ts", + "src/loopback-hostname.ts", + "src/rpc.ts" + ], + "references": [ + { + "path": "../../../vendor/cordis" + }, + { + "path": "../../attachment/attachment" + }, + { + "path": "../../core/session" + }, + { + "path": "../../core/tools" + }, + { + "path": "../../host/apiproxy" + }, + { + "path": "../../interaction/commands" + }, + { + "path": "../../llm/llm" + }, + { + "path": "../../support/invariants" + }, + { + "path": "../../util/brand" + } + ] +} diff --git a/packages/client/connection/tsconfig.host.json b/packages/client/connection/tsconfig.host.json new file mode 100644 index 0000000000..dca9b1a1b2 --- /dev/null +++ b/packages/client/connection/tsconfig.host.json @@ -0,0 +1,33 @@ +{ + "extends": "../../../tsconfig.base.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types", + "tsBuildInfoFile": "lib/tsconfig.host.tsbuildinfo" + }, + "files": [ + "src/api-path.ts", + "src/api-request-trust.ts", + "src/http-bridge.ts", + "src/index.ts", + "src/invariant.ts", + "src/loopback-hostname.ts", + "src/rpc-host.ts", + "src/rpc.ts", + "src/websocket-downlink.ts" + ], + "references": [ + { + "path": "../../attachment/attachment" + }, + { + "path": "../../host/apiproxy" + }, + { + "path": "../../host/webserver" + }, + { + "path": "../../support/invariants" + } + ] +} diff --git a/packages/client/connection/tsconfig.json b/packages/client/connection/tsconfig.json index 7bf86ffefe..2eca820546 100644 --- a/packages/client/connection/tsconfig.json +++ b/packages/client/connection/tsconfig.json @@ -1,46 +1,11 @@ { - "extends": "../../../tsconfig.base.client.json", - "compilerOptions": { - "rootDir": "src", - "outDir": "lib/types", - "types": ["node"] - }, - "include": [ - "src" - ], + "files": [], "references": [ { - "path": "../../attachment/attachment" + "path": "./tsconfig.host.json" }, { - "path": "../../llm/llm" - }, - { - "path": "../../core/session" - }, - { - "path": "../../interaction/commands" - }, - { - "path": "../../util/brand" - }, - { - "path": "../../host/apiproxy" - }, - { - "path": "../../host/webserver" - }, - { - "path": "../../interaction/user-approval" - }, - { - "path": "../../interaction/user-interaction" - }, - { - "path": "../../support/invariants" + "path": "./tsconfig.client.json" } - ], - "exclude": [ - "**/*.legacy.*" ] } diff --git a/tsconfig.client.json b/tsconfig.client.json index a054cb8751..9e2a7778d7 100644 --- a/tsconfig.client.json +++ b/tsconfig.client.json @@ -19,10 +19,7 @@ "packages/client/*/src/css-modules.d.ts", "packages/client/*/tests/**/*.ts", "packages/client/*/tests/**/*.tsx", - "packages/host/directory-picker-browse/tests/**/*.ts", - "packages/host/directory-picker-browse/tests/**/*.tsx", - "packages/host/directory-picker-native/tests/**/*.ts", - "packages/host/directory-picker-native/tests/**/*.tsx", + "packages/api/gateway/tests/client.spec.ts", "packages/client/tsdown.client.ts", "scripts/client-bundle-css.spec.ts", "scripts/client-bundle-purity.spec.ts" @@ -32,11 +29,6 @@ // smoke policy). webserver has zero workspace deps and no cordis merge, // so it cannot drag host-side Context augmentation into this program. { "path": "./packages/host/webserver" }, - // Dual-face host leaf: the node half is the native picking backend, the - // browser half registers the picking flow into ui-workspace's slot — - // client-side Context merges keep it out of the host program. - { "path": "./packages/host/directory-picker-native" }, - { "path": "./packages/host/directory-picker-browse" }, // Compaction seam: the client-runtime pin test value-imports the canonical // checkpoint const from the cordis-free dsh-compact/checkpoint leaf and // deliberately never loads the dsh-compact package root or the host-side @@ -51,9 +43,12 @@ { "path": "./packages/client/web-react" }, { "path": "./packages/client/modules" }, { "path": "./packages/client/hmr" }, - { "path": "./packages/client/connection" }, + { "path": "./packages/client/connection/tsconfig.client.json" }, + // The carrier's node-half spec rides this aggregate's package test glob, so + // its Host face is referenced here too — the mirror of the webserver leaf. + { "path": "./packages/client/connection/tsconfig.host.json" }, { "path": "./packages/typert/registry" }, - { "path": "./packages/api/gateway" }, + { "path": "./packages/api/gateway/tsconfig.client.json" }, { "path": "./packages/api/remotes/tsconfig.client.json" }, { "path": "./packages/client/runtime" }, { "path": "./packages/client/test-runtime" }, @@ -69,6 +64,8 @@ { "path": "./packages/client/ui-skill" }, { "path": "./packages/client/ui-subagent" }, { "path": "./packages/client/ui-task" }, + { "path": "./packages/client/ui-directory-picker" }, + { "path": "./packages/client/ui-directory-picker-native" }, { "path": "./packages/client/ui-goal" }, { "path": "./packages/client/ui-model" }, { "path": "./packages/client/ui-agent-preset" }, diff --git a/tsconfig.host.json b/tsconfig.host.json index 90a254f72a..ef02fc557f 100644 --- a/tsconfig.host.json +++ b/tsconfig.host.json @@ -89,8 +89,7 @@ ], "exclude": [ "packages/client/**", - "packages/host/directory-picker-browse/**", - "packages/host/directory-picker-native/**", + "packages/api/gateway/tests/client.spec.ts", "scripts/client-bundle-css.spec.ts", "packages/typert/generator/tests/fixtures/**", "scripts/client-bundle-purity.spec.ts" @@ -120,7 +119,7 @@ { "path": "./packages/core/scope" }, { "path": "./packages/typert/type-meta" }, { "path": "./packages/typert/registry" }, - { "path": "./packages/api/gateway" }, + { "path": "./packages/api/gateway/tsconfig.host.json" }, { "path": "./packages/api/remotes/tsconfig.host.json" }, { "path": "./packages/typert/loader" }, { "path": "./packages/session/session-persistence" }, @@ -270,11 +269,6 @@ { "path": "./packages/host/apiproxy" }, { "path": "./packages/host/directory-picker" }, { "path": "./packages/host/directory-picker-auto" }, - // Dual-face backend leaves stay client-registered (their tests and client - // halves are excluded above); these references only let the adaptive - // chooser's composition test import each backend's NODE entry, whose - // declarations carry no client-side Context merge — the mirror of the - // client aggregate's webserver reference. { "path": "./packages/host/directory-picker-browse" }, { "path": "./packages/host/directory-picker-native" }, { "path": "./packages/host/frontend-static" },