From 40af20cafea9eb8515b7598385caa1d13c97d8e8 Mon Sep 17 00:00:00 2001 From: imccyu <276526105+imccyu@users.noreply.github.com> Date: Tue, 11 Aug 2026 19:10:50 +0800 Subject: [PATCH] refactor(picker): split the directory-picker faces into their own packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The browse and native backends were dual-face packages: a Node backend plus a browser surface under one tsconfig that referenced Client packages. That put Client projects — and through them the Client runtime — inside the Host compiler aggregate, which builds before the generated Remote contributions exist. Each browser half moves to its own Client package, and both backends become Node-only. The interaction is still one choice: the adaptive chooser mounts the backend and its surface as a pair of Loader entries and tears both down in reverse, so a resolved kind still swaps both faces. Compositions that pin an interaction directly now pin the pair, and the chooser's runtime-string package list keeps naming everything a composing app must resolve. --- apps/cli/tests/web-agent-presets.e2e.ts | 5 +- apps/web/tests/pin-browse-picker.overlay.yml | 2 + apps/web/tests/scaffold.ts | 5 +- packages/bundle/web-app/package.json | 2 + .../ui-directory-picker-native/package.json | 72 +++++++++++++++++ .../src/client/flow.ts | 0 .../src/client/index.ts | 0 .../ui-directory-picker-native/src/index.ts | 10 +++ .../src/invariant.ts | 31 +++++++ .../tests/client-flow.spec.tsx | 0 .../ui-directory-picker-native/tsconfig.json | 24 ++++++ .../tsdown.config.ts | 3 + .../client/ui-directory-picker/package.json | 80 +++++++++++++++++++ .../src/client/DirectoryBrowser.module.css | 0 .../src/client/DirectoryBrowser.tsx | 0 .../ui-directory-picker}/src/client/flow.ts | 0 .../ui-directory-picker}/src/client/index.ts | 0 .../ui-directory-picker}/src/css-modules.d.ts | 0 .../client/ui-directory-picker/src/index.ts | 10 +++ .../ui-directory-picker/src/invariant.ts | 31 +++++++ .../tests/client-flow.spec.tsx | 0 .../tests/directory-browser.spec.tsx | 0 .../client/ui-directory-picker/tsconfig.json | 30 +++++++ .../ui-directory-picker/tsdown.config.ts | 3 + .../host/directory-picker-auto/package.json | 12 ++- .../host/directory-picker-auto/src/index.ts | 61 +++++++++----- .../host/directory-picker-browse/package.json | 34 +------- .../directory-picker-browse/tsconfig.json | 17 +--- .../directory-picker-browse/tsdown.config.ts | 16 +++- .../host/directory-picker-native/package.json | 25 +----- .../directory-picker-native/tsconfig.json | 11 +-- .../directory-picker-native/tsdown.config.ts | 48 ++++++----- scripts/verify-cordis-config.ts | 11 ++- 33 files changed, 407 insertions(+), 136 deletions(-) create mode 100644 packages/client/ui-directory-picker-native/package.json rename packages/{host/directory-picker-native => client/ui-directory-picker-native}/src/client/flow.ts (100%) rename packages/{host/directory-picker-native => client/ui-directory-picker-native}/src/client/index.ts (100%) create mode 100644 packages/client/ui-directory-picker-native/src/index.ts create mode 100644 packages/client/ui-directory-picker-native/src/invariant.ts rename packages/{host/directory-picker-native => client/ui-directory-picker-native}/tests/client-flow.spec.tsx (100%) create mode 100644 packages/client/ui-directory-picker-native/tsconfig.json create mode 100644 packages/client/ui-directory-picker-native/tsdown.config.ts create mode 100644 packages/client/ui-directory-picker/package.json rename packages/{host/directory-picker-browse => client/ui-directory-picker}/src/client/DirectoryBrowser.module.css (100%) rename packages/{host/directory-picker-browse => client/ui-directory-picker}/src/client/DirectoryBrowser.tsx (100%) rename packages/{host/directory-picker-browse => client/ui-directory-picker}/src/client/flow.ts (100%) rename packages/{host/directory-picker-browse => client/ui-directory-picker}/src/client/index.ts (100%) rename packages/{host/directory-picker-browse => client/ui-directory-picker}/src/css-modules.d.ts (100%) create mode 100644 packages/client/ui-directory-picker/src/index.ts create mode 100644 packages/client/ui-directory-picker/src/invariant.ts rename packages/{host/directory-picker-browse => client/ui-directory-picker}/tests/client-flow.spec.tsx (100%) rename packages/{host/directory-picker-browse => client/ui-directory-picker}/tests/directory-browser.spec.tsx (100%) create mode 100644 packages/client/ui-directory-picker/tsconfig.json create mode 100644 packages/client/ui-directory-picker/tsdown.config.ts diff --git a/apps/cli/tests/web-agent-presets.e2e.ts b/apps/cli/tests/web-agent-presets.e2e.ts index 8620a8f424..f34de5ad07 100644 --- a/apps/cli/tests/web-agent-presets.e2e.ts +++ b/apps/cli/tests/web-agent-presets.e2e.ts @@ -86,7 +86,10 @@ async function bootWeb(settingsFile: string, extra: PatchOptions[] = []): Promis // host and so waits for the webserver disabled above; the browse variant // supplies `directoryPicker` without one. { id: 'directory-picker', disabled: true }, - { insert: [{ id: 'directory-picker-browse', name: '@deepseek-ai/dsh-host-directory-picker-browse' }] }, + { insert: [ + { id: 'directory-picker-browse', name: '@deepseek-ai/dsh-host-directory-picker-browse' }, + { id: 'ui-directory-picker', name: '@deepseek-ai/dsh-client-ui-directory-picker' }, + ] }, // The roster AppCLIEntry would patch in; only the shipped root, so a // developer's own `~/.dsh/.preset` cannot change this test's outcome. // `default` here is the COMPOSITION default — the base layer the settings diff --git a/apps/web/tests/pin-browse-picker.overlay.yml b/apps/web/tests/pin-browse-picker.overlay.yml index c6bf121b69..e674f81d4c 100644 --- a/apps/web/tests/pin-browse-picker.overlay.yml +++ b/apps/web/tests/pin-browse-picker.overlay.yml @@ -9,3 +9,5 @@ - insert: - id: directory-picker-browse name: '@deepseek-ai/dsh-host-directory-picker-browse' + - id: ui-directory-picker + name: '@deepseek-ai/dsh-client-ui-directory-picker' diff --git a/apps/web/tests/scaffold.ts b/apps/web/tests/scaffold.ts index 87f75b383d..d3f373614e 100644 --- a/apps/web/tests/scaffold.ts +++ b/apps/web/tests/scaffold.ts @@ -439,7 +439,10 @@ export async function launchWebScaffold(options: LaunchOptions = {}): Promise {} + +/** + * Register this package's invariant companion. + * @param ctx - Cordis context carrying the invariant service. + * @returns the installed registration's disposer after setup succeeds. + */ +export const apply = (ctx: Context): Promise<() => void> => + Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install)) +/* jscpd:ignore-end */ diff --git a/packages/host/directory-picker-native/tests/client-flow.spec.tsx b/packages/client/ui-directory-picker-native/tests/client-flow.spec.tsx similarity index 100% rename from packages/host/directory-picker-native/tests/client-flow.spec.tsx rename to packages/client/ui-directory-picker-native/tests/client-flow.spec.tsx diff --git a/packages/client/ui-directory-picker-native/tsconfig.json b/packages/client/ui-directory-picker-native/tsconfig.json new file mode 100644 index 0000000000..25f63f1d78 --- /dev/null +++ b/packages/client/ui-directory-picker-native/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../../../tsconfig.base.client.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../../support/invariants" + }, + { + "path": "../ui-slots" + }, + { + "path": "../runtime" + }, + { + "path": "../ui-workspace" + } + ] +} diff --git a/packages/client/ui-directory-picker-native/tsdown.config.ts b/packages/client/ui-directory-picker-native/tsdown.config.ts new file mode 100644 index 0000000000..94d4ed5ea8 --- /dev/null +++ b/packages/client/ui-directory-picker-native/tsdown.config.ts @@ -0,0 +1,3 @@ +import { clientBundle } from '../tsdown.client.ts' + +export default clientBundle('@deepseek-ai/dsh-client-ui-directory-picker-native', ['lib/types/index.js', 'lib/types/invariant.js']) diff --git a/packages/client/ui-directory-picker/package.json b/packages/client/ui-directory-picker/package.json new file mode 100644 index 0000000000..fd3acf592d --- /dev/null +++ b/packages/client/ui-directory-picker/package.json @@ -0,0 +1,80 @@ +{ + "name": "@deepseek-ai/dsh-client-ui-directory-picker", + "description": "In-app directory browsing surface: the workspace directory-flow owner rendering the host's listing and creation primitives", + "version": "0.0.1-rc.1", + "publishConfig": { + "access": "restricted" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/deepseek-ai/deepseek-harness.git", + "directory": "packages/client/ui-directory-picker" + }, + "type": "module", + "main": "lib/index.js", + "types": "lib/types/index.d.ts", + "exports": { + ".": { + "types": "./lib/types/index.d.ts", + "default": "./lib/index.js" + }, + "./invariant": { + "types": "./lib/types/invariant.d.ts", + "default": "./lib/invariant.js" + }, + "./client": { + "types": "./lib/types/client/index.d.ts", + "default": "./lib/client.js" + }, + "./src/*": "./src/*", + "./package.json": "./package.json" + }, + "dsh": { + "client": { + "inject": [ + "@deepseek-ai/dsh-client-runtime", + "@deepseek-ai/dsh-client-ui-workspace", + "@deepseek-ai/dsh-client-locale" + ], + "platform": "web" + } + }, + "scripts": { + "bundle": "tsdown", + "watch": "tsdown --watch" + }, + "license": "BSD-3-Clause", + "dependencies": { + "clsx": "^2.0.0" + }, + "peerDependencies": { + "@deepseek-ai/dsh-client-locale": "workspace:^", + "@deepseek-ai/dsh-client-runtime": "workspace:^", + "@deepseek-ai/dsh-client-ui-primitives": "workspace:^", + "@deepseek-ai/dsh-client-ui-slots": "workspace:^", + "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", + "@deepseek-ai/dsh-invariants": "workspace:^", + "@deepseek-ai/cordis": "workspace:^", + "react": "^18.2.0" + }, + "devDependencies": { + "@deepseek-ai/dsh-client-locale": "workspace:^", + "@deepseek-ai/dsh-client-runtime": "workspace:^", + "@deepseek-ai/dsh-client-test-runtime": "workspace:^", + "@deepseek-ai/dsh-client-ui-primitives": "workspace:^", + "@deepseek-ai/dsh-client-ui-slots": "workspace:^", + "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", + "@deepseek-ai/dsh-invariants": "workspace:^", + "@testing-library/react": "^16.1.0", + "@types/react": "~18.3.1", + "@deepseek-ai/cordis": "workspace:^", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "files": [ + "lib/index.js", + "lib/invariant.js", + "lib/client.js", + "lib/types/**/*.d.ts" + ] +} diff --git a/packages/host/directory-picker-browse/src/client/DirectoryBrowser.module.css b/packages/client/ui-directory-picker/src/client/DirectoryBrowser.module.css similarity index 100% rename from packages/host/directory-picker-browse/src/client/DirectoryBrowser.module.css rename to packages/client/ui-directory-picker/src/client/DirectoryBrowser.module.css diff --git a/packages/host/directory-picker-browse/src/client/DirectoryBrowser.tsx b/packages/client/ui-directory-picker/src/client/DirectoryBrowser.tsx similarity index 100% rename from packages/host/directory-picker-browse/src/client/DirectoryBrowser.tsx rename to packages/client/ui-directory-picker/src/client/DirectoryBrowser.tsx diff --git a/packages/host/directory-picker-browse/src/client/flow.ts b/packages/client/ui-directory-picker/src/client/flow.ts similarity index 100% rename from packages/host/directory-picker-browse/src/client/flow.ts rename to packages/client/ui-directory-picker/src/client/flow.ts diff --git a/packages/host/directory-picker-browse/src/client/index.ts b/packages/client/ui-directory-picker/src/client/index.ts similarity index 100% rename from packages/host/directory-picker-browse/src/client/index.ts rename to packages/client/ui-directory-picker/src/client/index.ts diff --git a/packages/host/directory-picker-browse/src/css-modules.d.ts b/packages/client/ui-directory-picker/src/css-modules.d.ts similarity index 100% rename from packages/host/directory-picker-browse/src/css-modules.d.ts rename to packages/client/ui-directory-picker/src/css-modules.d.ts diff --git a/packages/client/ui-directory-picker/src/index.ts b/packages/client/ui-directory-picker/src/index.ts new file mode 100644 index 0000000000..6b812b5e75 --- /dev/null +++ b/packages/client/ui-directory-picker/src/index.ts @@ -0,0 +1,10 @@ +/** + * Directory-picker browsing surface, node half. Pure UI plugin: the empty + * apply exists so the plugin appears in the host cordis.yml / Loader; the + * browser half ships via exports["./client"], discovered through the + * package.json dsh.client declaration. The listing and creation primitives it + * drives live in `@deepseek-ai/dsh-host-directory-picker-browse`. + */ + +/** Host plugin body — no host-side behavior for this surface plugin. */ +export function apply(): void {} diff --git a/packages/client/ui-directory-picker/src/invariant.ts b/packages/client/ui-directory-picker/src/invariant.ts new file mode 100644 index 0000000000..722f8177d5 --- /dev/null +++ b/packages/client/ui-directory-picker/src/invariant.ts @@ -0,0 +1,31 @@ +/** + * Package-owned invariant companion for `@deepseek-ai/dsh-client-ui-directory-picker`. + * @module @deepseek-ai/dsh-client-ui-directory-picker/invariant + */ + +/* jscpd:ignore-start */ +import type { Context } from '@deepseek-ai/cordis' +import type { InvariantInstaller } from '@deepseek-ai/dsh-invariants' + +const PACKAGE_NAME = '@deepseek-ai/dsh-client-ui-directory-picker' + +/** Cordis companion plugin name. */ +export const name = 'client-ui-directory-picker-invariant' +/** Service required before the companion can reserve package ownership. */ +export const inject = ['invariants'] + +/** + * No runtime invariant: the plugin registers one workspace directory-flow + * owner whose disposal the HMR-safety spec proves, and every listing it shows + * is re-read from the Host on demand rather than held here. + */ +const install: InvariantInstaller = () => {} + +/** + * Register this package's invariant companion. + * @param ctx - Cordis context carrying the invariant service. + * @returns the installed registration's disposer after setup succeeds. + */ +export const apply = (ctx: Context): Promise<() => void> => + Promise.resolve(ctx.invariants.register(PACKAGE_NAME, install)) +/* jscpd:ignore-end */ diff --git a/packages/host/directory-picker-browse/tests/client-flow.spec.tsx b/packages/client/ui-directory-picker/tests/client-flow.spec.tsx similarity index 100% rename from packages/host/directory-picker-browse/tests/client-flow.spec.tsx rename to packages/client/ui-directory-picker/tests/client-flow.spec.tsx diff --git a/packages/host/directory-picker-browse/tests/directory-browser.spec.tsx b/packages/client/ui-directory-picker/tests/directory-browser.spec.tsx similarity index 100% rename from packages/host/directory-picker-browse/tests/directory-browser.spec.tsx rename to packages/client/ui-directory-picker/tests/directory-browser.spec.tsx diff --git a/packages/client/ui-directory-picker/tsconfig.json b/packages/client/ui-directory-picker/tsconfig.json new file mode 100644 index 0000000000..bd4e3dfc7f --- /dev/null +++ b/packages/client/ui-directory-picker/tsconfig.json @@ -0,0 +1,30 @@ +{ + "extends": "../../../tsconfig.base.client.json", + "compilerOptions": { + "rootDir": "src", + "outDir": "lib/types" + }, + "include": [ + "src" + ], + "references": [ + { + "path": "../../support/invariants" + }, + { + "path": "../ui-slots" + }, + { + "path": "../ui-primitives" + }, + { + "path": "../locale" + }, + { + "path": "../runtime" + }, + { + "path": "../ui-workspace" + } + ] +} diff --git a/packages/client/ui-directory-picker/tsdown.config.ts b/packages/client/ui-directory-picker/tsdown.config.ts new file mode 100644 index 0000000000..4900e78a04 --- /dev/null +++ b/packages/client/ui-directory-picker/tsdown.config.ts @@ -0,0 +1,3 @@ +import { clientBundle } from '../tsdown.client.ts' + +export default clientBundle('@deepseek-ai/dsh-client-ui-directory-picker', ['lib/types/index.js', 'lib/types/invariant.js']) diff --git a/packages/host/directory-picker-auto/package.json b/packages/host/directory-picker-auto/package.json index 572c1045c8..0c791b79a2 100644 --- a/packages/host/directory-picker-auto/package.json +++ b/packages/host/directory-picker-auto/package.json @@ -32,21 +32,25 @@ ], "license": "BSD-3-Clause", "peerDependencies": { + "@deepseek-ai/cordis": "workspace:^", "@deepseek-ai/cordis-plugin-loader": "workspace:^", + "@deepseek-ai/dsh-client-ui-directory-picker": "workspace:^", + "@deepseek-ai/dsh-client-ui-directory-picker-native": "workspace:^", "@deepseek-ai/dsh-host-directory-picker-browse": "workspace:^", "@deepseek-ai/dsh-host-directory-picker-native": "workspace:^", "@deepseek-ai/dsh-host-webserver": "workspace:^", - "@deepseek-ai/dsh-invariants": "workspace:^", - "@deepseek-ai/cordis": "workspace:^" + "@deepseek-ai/dsh-invariants": "workspace:^" }, "devDependencies": { + "@deepseek-ai/cordis": "workspace:^", "@deepseek-ai/cordis-plugin-include": "workspace:^", "@deepseek-ai/cordis-plugin-loader": "workspace:^", + "@deepseek-ai/dsh-client-ui-directory-picker": "workspace:^", + "@deepseek-ai/dsh-client-ui-directory-picker-native": "workspace:^", "@deepseek-ai/dsh-host-directory-picker": "workspace:^", "@deepseek-ai/dsh-host-directory-picker-browse": "workspace:^", "@deepseek-ai/dsh-host-directory-picker-native": "workspace:^", "@deepseek-ai/dsh-host-webserver": "workspace:^", - "@deepseek-ai/dsh-invariants": "workspace:^", - "@deepseek-ai/cordis": "workspace:^" + "@deepseek-ai/dsh-invariants": "workspace:^" } } diff --git a/packages/host/directory-picker-auto/src/index.ts b/packages/host/directory-picker-auto/src/index.ts index 91343463fd..0d836419a0 100644 --- a/packages/host/directory-picker-auto/src/index.ts +++ b/packages/host/directory-picker-auto/src/index.ts @@ -1,12 +1,13 @@ /** * Adaptive chooser of the directory-picker seam: resolves the host's * situation once at boot (bind host, SSH launch, display session, Linux - * chooser binary) and mounts the matching dual-face backend — `-native` or - * `-browse` — as a real Loader entry in the in-memory root tree. Because the - * backend arrives as an ordinary entry, its browser half is discovered - * exactly as a config-row's would be, so the seam's one-row-swaps-both-faces - * invariant holds for the resolved choice; pinning an interaction remains - * composing that backend row directly instead of this one. + * chooser binary) and mounts the matching interaction — `native` or `browse` + * — as real Loader entries in the in-memory root tree. Each interaction is a + * pair: the Host backend serving the seam capability and the client surface + * occupying ui-workspace's directory-flow holes. Both arrive as ordinary + * entries, so the surface is discovered exactly as a config-row's would be + * and one resolved choice still swaps both faces; pinning an interaction + * remains composing that pair directly instead of this row. * @module @deepseek-ai/dsh-host-directory-picker-auto */ @@ -28,7 +29,7 @@ export const name = 'directory-picker-auto' export const inject = ['httpServer', 'loader'] /** - * Backend package per resolved kind — fixed composition vocabulary, not a + * Host backend package per resolved kind — fixed composition vocabulary, not a * tunable. Exported because the reference is a runtime string the static * config gate cannot see in a yml row: `verify-cordis-config` requires every * app composing this chooser to declare both values as dependencies. @@ -39,10 +40,20 @@ export const BACKEND_PACKAGES: Record = { } /** - * Resolve the backend from one boot-time sample and mount it as a Loader - * entry; the effect's disposer removes the entry and joins the backend - * fiber's teardown, so unloading this plugin returns only after both faces - * of the mounted backend (and their dependents) quiesced. + * Client surface package per resolved kind, mounted with its backend so one + * resolved interaction still composes both faces. Declared as dependencies by + * every composing app for the same reason as {@link BACKEND_PACKAGES}. + */ +export const SURFACE_PACKAGES: Record = { + native: '@deepseek-ai/dsh-client-ui-directory-picker-native', + browse: '@deepseek-ai/dsh-client-ui-directory-picker', +} + +/** + * Resolve the interaction from one boot-time sample and mount its backend and + * surface as Loader entries; the effect's disposer removes both entries and + * joins their fibers' teardown, so unloading this plugin returns only after + * both faces of the mounted interaction (and their dependents) quiesced. * @param ctx - cordis context carrying the injected `httpServer` and `loader`. */ export async function apply(ctx: Context): Promise { @@ -54,16 +65,22 @@ export async function apply(ctx: Context): Promise { }) await ctx.effect(async () => { // Root-tree create: the Loader root is in-memory (write() is a no-op), so - // the mounted row can never be persisted back into a config file. - const id = await ctx.loader.create({ name: BACKEND_PACKAGES[backend] }) - return async () => { - // Tree teardown (group.stop) can have removed the entry already; - // nothing is left to unmount or await then. - const entry = ctx.loader.store[id] - if (entry === undefined) return - // remove() disposes the entry transactionally, so the chooser's unload - // signals completion only after the backend quiesced. - await ctx.loader.remove(id) + // the mounted rows can never be persisted back into a config file. The + // backend lands first: the surface's browser half drives the capability + // the backend registers. + const ids: string[] = [] + for (const name of [BACKEND_PACKAGES[backend], SURFACE_PACKAGES[backend]]) { + ids.push(await ctx.loader.create({ name })) } - }, 'directory-picker-auto: backend entry') + return async () => { + for (const id of ids.reverse()) { + // Tree teardown (group.stop) can have removed the entry already; + // nothing is left to unmount or await then. + if (ctx.loader.store[id] === undefined) continue + // remove() disposes the entry transactionally, so the chooser's unload + // signals completion only after that face quiesced. + await ctx.loader.remove(id) + } + } + }, 'directory-picker-auto: interaction entries') } diff --git a/packages/host/directory-picker-browse/package.json b/packages/host/directory-picker-browse/package.json index f134a00dbf..dbad0318a6 100644 --- a/packages/host/directory-picker-browse/package.json +++ b/packages/host/directory-picker-browse/package.json @@ -22,55 +22,25 @@ "types": "./lib/types/invariant.d.ts", "default": "./lib/invariant.js" }, - "./client": { - "types": "./lib/types/client/index.d.ts", - "default": "./lib/client.js" - }, "./src/*": "./src/*", "./package.json": "./package.json" }, "files": [ "lib/index.js", "lib/invariant.js", - "lib/client.js", "lib/types/**/*.d.ts" ], "license": "BSD-3-Clause", "dependencies": { "@deepseek-ai/dsh-host-directory-picker": "workspace:^", - "clsx": "^2.0.0", "@deepseek-ai/schemastery": "workspace:^" }, "peerDependencies": { - "@deepseek-ai/dsh-client-locale": "workspace:^", - "@deepseek-ai/dsh-client-runtime": "workspace:^", - "@deepseek-ai/dsh-client-ui-primitives": "workspace:^", - "@deepseek-ai/dsh-client-ui-slots": "workspace:^", - "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "@deepseek-ai/cordis": "workspace:^", - "react": "^18.2.0" + "@deepseek-ai/cordis": "workspace:^" }, "devDependencies": { - "@deepseek-ai/dsh-client-locale": "workspace:^", - "@deepseek-ai/dsh-client-runtime": "workspace:^", - "@deepseek-ai/dsh-client-test-runtime": "workspace:^", - "@deepseek-ai/dsh-client-ui-primitives": "workspace:^", - "@deepseek-ai/dsh-client-ui-slots": "workspace:^", - "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "@types/react": "~18.3.1", - "@deepseek-ai/cordis": "workspace:^", - "react": "^18.2.0" - }, - "dsh": { - "client": { - "inject": [ - "@deepseek-ai/dsh-client-runtime", - "@deepseek-ai/dsh-client-ui-workspace", - "@deepseek-ai/dsh-client-locale" - ], - "platform": "web" - } + "@deepseek-ai/cordis": "workspace:^" } } diff --git a/packages/host/directory-picker-browse/tsconfig.json b/packages/host/directory-picker-browse/tsconfig.json index 00dcdf8fde..b6a0f96d7e 100644 --- a/packages/host/directory-picker-browse/tsconfig.json +++ b/packages/host/directory-picker-browse/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.client.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "rootDir": "src", "outDir": "lib/types", @@ -16,21 +16,6 @@ }, { "path": "../../support/invariants" - }, - { - "path": "../../client/ui-slots" - }, - { - "path": "../../client/ui-primitives" - }, - { - "path": "../../client/locale" - }, - { - "path": "../../client/runtime" - }, - { - "path": "../../client/ui-workspace" } ] } diff --git a/packages/host/directory-picker-browse/tsdown.config.ts b/packages/host/directory-picker-browse/tsdown.config.ts index 4b2be38c3d..388cecbcb5 100644 --- a/packages/host/directory-picker-browse/tsdown.config.ts +++ b/packages/host/directory-picker-browse/tsdown.config.ts @@ -1,3 +1,15 @@ -import { clientBundle } from '../../client/tsdown.client.ts' +import { defineConfig } from 'tsdown' -export default clientBundle('@deepseek-ai/dsh-host-directory-picker-browse', ['lib/types/index.js', 'lib/types/invariant.js']) +/** Node-only backend: listing and creation primitives over the host filesystem. */ +export default defineConfig([ + { + entry: ['lib/types/index.js', 'lib/types/invariant.js'], + outDir: 'lib', + format: ['esm'], + platform: 'node', + target: 'es2024', + fixedExtension: false, + dts: false, + clean: false, + }, +]) diff --git a/packages/host/directory-picker-native/package.json b/packages/host/directory-picker-native/package.json index 4465553e07..fbc7ae16d5 100644 --- a/packages/host/directory-picker-native/package.json +++ b/packages/host/directory-picker-native/package.json @@ -22,10 +22,6 @@ "types": "./lib/types/invariant.d.ts", "default": "./lib/invariant.js" }, - "./client": { - "types": "./lib/types/client/index.d.ts", - "default": "./lib/client.js" - }, "./worker": { "types": "./lib/types/win32-dialog-worker.d.ts", "default": "./lib/worker.cjs" @@ -37,7 +33,6 @@ "lib/index.js", "lib/invariant.js", "lib/worker.cjs", - "lib/client.js", "lib/types/**/*.d.ts" ], "license": "BSD-3-Clause", @@ -47,30 +42,12 @@ "koffi": "^3.1.0" }, "peerDependencies": { - "@deepseek-ai/dsh-client-runtime": "workspace:^", - "@deepseek-ai/dsh-client-ui-slots": "workspace:^", - "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "@deepseek-ai/cordis": "workspace:^", - "react": "^18.2.0" + "@deepseek-ai/cordis": "workspace:^" }, "devDependencies": { - "@deepseek-ai/dsh-client-runtime": "workspace:^", - "@deepseek-ai/dsh-client-ui-slots": "workspace:^", - "@deepseek-ai/dsh-client-ui-workspace": "workspace:^", "@deepseek-ai/dsh-invariants": "workspace:^", - "@types/react": "~18.3.1", "@deepseek-ai/cordis": "workspace:^", - "react": "^18.2.0", "tsx": "^4.19.2" - }, - "dsh": { - "client": { - "inject": [ - "@deepseek-ai/dsh-client-runtime", - "@deepseek-ai/dsh-client-ui-workspace" - ], - "platform": "web" - } } } diff --git a/packages/host/directory-picker-native/tsconfig.json b/packages/host/directory-picker-native/tsconfig.json index 395595e836..6962312bd1 100644 --- a/packages/host/directory-picker-native/tsconfig.json +++ b/packages/host/directory-picker-native/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.base.client.json", + "extends": "../../../tsconfig.base.json", "compilerOptions": { "rootDir": "src", "outDir": "lib/types", @@ -19,15 +19,6 @@ }, { "path": "../../util/native-command" - }, - { - "path": "../../client/ui-slots" - }, - { - "path": "../../client/runtime" - }, - { - "path": "../../client/ui-workspace" } ] } diff --git a/packages/host/directory-picker-native/tsdown.config.ts b/packages/host/directory-picker-native/tsdown.config.ts index 6d02727f4e..13a7f74070 100644 --- a/packages/host/directory-picker-native/tsdown.config.ts +++ b/packages/host/directory-picker-native/tsdown.config.ts @@ -1,23 +1,31 @@ -import { clientBundle } from '../../client/tsdown.client.ts' +import { defineConfig } from 'tsdown' -// The Win32 dialog worker builds as its own CJS entry (mirroring -// dsh-workflow-workerthread's worker): path-loaded by the driver, inlining -// the dialog logic while koffi stays an external native require. -export default clientBundle( - '@deepseek-ai/dsh-host-directory-picker-native', - ['lib/types/index.js', 'lib/types/invariant.js'], +/** + * Node-only backend. The Win32 dialog worker builds as its own CJS entry + * (mirroring dsh-workflow-workerthread's worker): path-loaded by the driver, + * inlining the dialog logic while koffi stays an external native require. + */ +export default defineConfig([ { - companions: [{ - // The artifact is lib/worker.cjs (the ./worker export the workspace - // constraint keys on), bundled from the descriptive source entry. - entry: { worker: 'lib/types/win32-dialog-worker.js' }, - outDir: 'lib', - format: ['cjs'], - platform: 'node', - target: 'es2024', - fixedExtension: false, - dts: false, - clean: false, - }], + entry: ['lib/types/index.js', 'lib/types/invariant.js'], + outDir: 'lib', + format: ['esm'], + platform: 'node', + target: 'es2024', + fixedExtension: false, + dts: false, + clean: false, }, -) + { + // The artifact is lib/worker.cjs (the ./worker export the workspace + // constraint keys on), bundled from the descriptive source entry. + entry: { worker: 'lib/types/win32-dialog-worker.js' }, + outDir: 'lib', + format: ['cjs'], + platform: 'node', + target: 'es2024', + fixedExtension: false, + dts: false, + clean: false, + }, +]) diff --git a/scripts/verify-cordis-config.ts b/scripts/verify-cordis-config.ts index d834094d78..686f1ace61 100644 --- a/scripts/verify-cordis-config.ts +++ b/scripts/verify-cordis-config.ts @@ -42,14 +42,17 @@ const metadataFields = ['id', 'name', 'group', 'disabled', 'inject', 'intercept' const CHOOSER_PACKAGE = '@deepseek-ai/dsh-host-directory-picker-auto' /** - * The backends the chooser mounts by runtime string (mirror of its exported - * `BACKEND_PACKAGES`), invisible to yml-row scanning: a composition mounting - * the chooser must resolve both, or keyless Linux CI (which only ever - * resolves `browse`) hides a dropped `-native` dependency until a macOS boot. + * The packages the chooser mounts by runtime string (mirror of its exported + * `BACKEND_PACKAGES` and `SURFACE_PACKAGES`), invisible to yml-row scanning: a + * composition mounting the chooser must resolve every one, or keyless Linux CI + * (which only ever resolves `browse`) hides a dropped `-native` dependency + * until a macOS boot. */ const CHOOSER_BACKEND_PACKAGES = [ '@deepseek-ai/dsh-host-directory-picker-native', '@deepseek-ai/dsh-host-directory-picker-browse', + '@deepseek-ai/dsh-client-ui-directory-picker', + '@deepseek-ai/dsh-client-ui-directory-picker-native', ] const jsExprType = new yaml.Type('tag:yaml.org,2002:js', { kind: 'scalar',