mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-10-26 16:55:08 +00:00
Merge pull request #6924 from deepseek-harness/turtle/extract-bundle-lists-349637056285
refactor(boot): move official bundle lists out of app-boot
This commit is contained in:
commit
2e0ce8d448
84 files changed
+564
-173
No files matched your search
+2
-2
@@ -12,8 +12,8 @@
|
||||
en: a15c7c13f167e5ac
|
||||
zh: 63bcc2ef60c2f344
|
||||
/agent-note-boot-the-preview-worker-from-the-shipped-profile-and-fetch-lazy-chunks-on-demand/decision/boot-the-same-profile-as-the-served-web-deployment:
|
||||
en: caf1ca77192dcb20
|
||||
zh: d663e2cbb05fe4fc
|
||||
en: 9b957e37f290abaf
|
||||
zh: 06a4599c8fe449ad
|
||||
/agent-note-boot-the-preview-worker-from-the-shipped-profile-and-fetch-lazy-chunks-on-demand/decision/node-internal-module-interfaces-in-the-worker:
|
||||
en: 37d8e809eaa21d25
|
||||
zh: 8c7c31bd6f45c823
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ Measured: with no bundle enabled, the two compositions differ in only one of 188
|
||||
The served launch path (apps/cli, app-boot) carries no Preview-specific code; the webworker packages reproduce it:
|
||||
|
||||
- **packer**
|
||||
- Package roster = `PROFILE_TEMPLATES[profile].bundles` + `OPTIONAL_BUNDLES` + the rows named in those bundles' patch files; the bundle packages themselves also enter the image (patches, locale, and icon through the publish view). Both tables are read from app-boot, the same source the Plugins page uses.
|
||||
- Package roster = `PROFILE_TEMPLATES[profile].bundles` + `OPTIONAL_BUNDLES` + the rows named in those bundles' patch files; the bundle packages themselves also enter the image (patches, locale, and icon through the publish view). Both tables are read from `@deepseek-ai/dsh-official-bundles`, the same source the Plugins page uses.
|
||||
- The image carries a manifest-only `node_modules/@deepseek-ai/dsh/package.json` (a verbatim copy of `apps/cli/package.json`) as the installation anchor, and the image manifest names it in `installation`.
|
||||
- The image carries no composed configuration and no `config/cordis.yml`; the image manifest records the `profile` the Worker boots.
|
||||
- The image carries a home patch, `home/cordis.patch.yml`: for each row the runtime's `PLATFORM_ENTRY_CONFIG` names (`session-persistence-jsonl`), the config the template's bundle layers compose with the required fields over it (`compression: none`). A patch replaces a row's whole config, so the composed fields stay; the bundle files read at pack time are the ones in the image.
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ Status: implemented
|
||||
正式启动链路(apps/cli、app-boot)不含 Preview 专用代码;由 webworker 包复现这条链路:
|
||||
|
||||
- **packer**
|
||||
- 收包清单 = `PROFILE_TEMPLATES[profile].bundles` + `OPTIONAL_BUNDLES` + 这些 bundle 补丁文件里的行;bundle 包本身也打进镜像(补丁、locale、icon 走 publish view)。两张表从 app-boot 读,与插件页同一来源。
|
||||
- 收包清单 = `PROFILE_TEMPLATES[profile].bundles` + `OPTIONAL_BUNDLES` + 这些 bundle 补丁文件里的行;bundle 包本身也打进镜像(补丁、locale、icon 走 publish view)。两张表从 `@deepseek-ai/dsh-official-bundles` 读,与插件页同一来源。
|
||||
- 镜像里放一份只含清单的 `node_modules/@deepseek-ai/dsh/package.json`(原样复制 `apps/cli/package.json`),作为安装锚点,镜像 manifest 在 `installation` 里记录它。
|
||||
- 镜像不带组合好的配置,也没有 `config/cordis.yml`;镜像 manifest 记录 Worker 要启动的 `profile`。
|
||||
- 镜像带一份 home patch `home/cordis.patch.yml`:对运行时 `PLATFORM_ENTRY_CONFIG` 列出的每一行(`session-persistence-jsonl`),写入模板各 bundle 层合成出的配置,并在其上设置所需字段(`compression: none`)。补丁会整体替换一行的配置,所以保留合成出的字段;打包时读取的 bundle 文件就是镜像里的那些。
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
en: dc43ba84345e1405
|
||||
zh: dbc03572ab7710d2
|
||||
/agent-note-ship-optional-bundles-with-the-installation/decision:
|
||||
en: 1362533f342b31f4
|
||||
zh: 90689262acefb43d
|
||||
en: 64a2cb7602842c44
|
||||
zh: bfcb3ef4a81773b4
|
||||
/agent-note-ship-optional-bundles-with-the-installation/alternatives-considered:
|
||||
en: 95b48b61757f1f13
|
||||
zh: e9fb2d6ea492a4bc
|
||||
|
||||
@@ -10,7 +10,7 @@ The Web plugin page manages only the bundles a person installed into the profile
|
||||
|
||||
## Decision
|
||||
|
||||
The launcher names in `OPTIONAL_BUNDLES` (`packages/boot/app-boot/src/profile.ts`, beside the profile templates) the bundles the installation ships for a person to switch on. Each must be a runtime dependency of `apps/cli` that declares `dsh.bundle.patch`, and no shipped profile template selects it. The plugin manager's `listBundles` reports such a bundle as `optional`: switched off until selected, never removable, resolved from the installation like any installation-supplied bundle. The Web plugin page presents offered optional bundles in its Official group, tagged experimental when the package is experimental, ahead of the profile's own installed bundles. The [persistent-terminal bundle](../../../../packages/experimental/terminal-bundle/README.md) remains available to the Host but has no page switch, even when enabled; its existing profile selection remains intact.
|
||||
The launcher names in `OPTIONAL_BUNDLES` (`packages/boot/official-bundles/src/bundles.ts`, beside the profile templates) the bundles the installation ships for a person to switch on. Each must be a runtime dependency of `apps/cli` that declares `dsh.bundle.patch`, and no shipped profile template selects it. The plugin manager's `listBundles` reports such a bundle as `optional`: switched off until selected, never removable, resolved from the installation like any installation-supplied bundle. The Web plugin page presents offered optional bundles in its Official group, tagged experimental when the package is experimental, ahead of the profile's own installed bundles. The [persistent-terminal bundle](../../../../packages/experimental/terminal-bundle/README.md) remains available to the Host but has no page switch, even when enabled; its existing profile selection remains intact.
|
||||
|
||||
Default-product isolation keeps its rules with one declared exception: an optional bundle's dependency graph is outside the default product. The static gate skips the `dependencies` edge from `@deepseek-ai/dsh` to a listed bundle and still rejects a runtime import, a shipped composition, a preset, or a default template that names it, an experimental dependency the list does not name, and a listed name that is not a runtime dependency or not a bundle. The workspace-constraints check accepts the same `dependencies` edges and no other runtime section, and the packed-install release check skips them from the installed entry package while requiring each listed bundle to be installed.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ Web 插件页只管理用户装进 profile 的组合包。像 Agent Teams 这样
|
||||
|
||||
## 决策
|
||||
|
||||
启动器在 `OPTIONAL_BUNDLES`(`packages/boot/app-boot/src/profile.ts`,与 profile 模板并列)里点名安装随附、供用户开启的组合包。每一个都必须是 `apps/cli` 声明了 `dsh.bundle.patch` 的运行时依赖,且不被任何随附 profile 模板选中。插件管理器的 `listBundles` 把这类组合包报告为 `optional`:选中前保持关闭、永不可卸载、像其他安装提供的组合包一样从安装目录解析。Web 插件页在「官方」分组展示可供选择的可选组合包,属于实验包的带实验性标签,排在 profile 自己已安装的组合包之前。[持久终端组合包](../../../../packages/experimental/terminal-bundle/README.zh.md)仍可供 Host 使用,但即使已启用也不提供页面开关;已有的 profile 选择保持不变。
|
||||
启动器在 `OPTIONAL_BUNDLES`(`packages/boot/official-bundles/src/bundles.ts`,与 profile 模板并列)里点名安装随附、供用户开启的组合包。每一个都必须是 `apps/cli` 声明了 `dsh.bundle.patch` 的运行时依赖,且不被任何随附 profile 模板选中。插件管理器的 `listBundles` 把这类组合包报告为 `optional`:选中前保持关闭、永不可卸载、像其他安装提供的组合包一样从安装目录解析。Web 插件页在「官方」分组展示可供选择的可选组合包,属于实验包的带实验性标签,排在 profile 自己已安装的组合包之前。[持久终端组合包](../../../../packages/experimental/terminal-bundle/README.zh.md)仍可供 Host 使用,但即使已启用也不提供页面开关;已有的 profile 选择保持不变。
|
||||
|
||||
默认产品隔离的规则保持不变,只声明一个例外:可选组合包的依赖图在默认产品之外。静态门禁跳过从 `@deepseek-ai/dsh` 到列表中组合包的 `dependencies` 边,仍然拒绝运行时 import、随附组合、preset 或默认模板对它的引用,拒绝列表没有点名的实验依赖,也拒绝不是运行时依赖或不是组合包的列表项。workspace 约束检查接受同样的 `dependencies` 边而不接受其他运行时依赖段;发布时的 packed-install 检查对已安装入口包跳过这些边,并要求列表中的每个组合包都已安装。
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
"@deepseek-ai/dsh-jobs-local": "workspace:*",
|
||||
"@deepseek-ai/dsh-launch-environment": "workspace:*",
|
||||
"@deepseek-ai/dsh-mcp-client": "workspace:*",
|
||||
"@deepseek-ai/dsh-official-bundles": "workspace:*",
|
||||
"@deepseek-ai/dsh-persona": "workspace:*",
|
||||
"@deepseek-ai/dsh-plan-mode": "workspace:*",
|
||||
"@deepseek-ai/dsh-pwsh-local": "workspace:*",
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
/** Profile package management and explicit, exact-version compatibility approvals. */
|
||||
import { runPluginCommand, runProfilePnpm, setProfileVersionExemption, type PackageOperationOptions } from '@deepseek-ai/dsh-plugin-manager/operations'
|
||||
import { INSTALL_ANCHOR } from './profile-boot.ts'
|
||||
import { DEFAULT_PROFILE_BUNDLES, initProfile, PROFILE_TEMPLATES, readProfileCompatibility, resolveProfileDir, type ProfileContext } from '@deepseek-ai/dsh-app-boot'
|
||||
import { initProfile, readProfileCompatibility, resolveProfileDir, type ProfileContext } from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES, DEFAULT_PROFILE_BUNDLES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { withFileLock } from '@deepseek-ai/dsh-atomic-write'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { mkdir } from 'node:fs/promises'
|
||||
|
||||
@@ -26,12 +26,12 @@ import {
|
||||
reportSkippedBundles,
|
||||
PluginPackages,
|
||||
PROFILE_PATCH_FILENAME,
|
||||
PROFILE_TEMPLATES,
|
||||
resolveProfileDir,
|
||||
type ProfileContext,
|
||||
type Profile,
|
||||
type RuntimeResolution,
|
||||
} from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { resolveDshHome } from '@deepseek-ai/dsh-home-paths'
|
||||
import { installProxyFromEnvironment } from '@deepseek-ai/dsh-http-proxy'
|
||||
import { DSH_LAUNCH_ENVIRONMENT_KEY, type LaunchEnvironmentSnapshot } from '@deepseek-ai/dsh-launch-environment'
|
||||
|
||||
@@ -13,7 +13,8 @@ import { setTimeout as delay } from 'node:timers/promises'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import WebSocket from 'ws'
|
||||
import { initProfile, PROFILE_TEMPLATES } from '@deepseek-ai/dsh-app-boot'
|
||||
import { initProfile } from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
|
||||
const REPO_ROOT = fileURLToPath(new URL('../../..', import.meta.url))
|
||||
const BUILT_BIN = join(REPO_ROOT, 'apps/cli/lib/bin.js')
|
||||
|
||||
@@ -3,7 +3,8 @@ import { existsSync, mkdtempSync, readFileSync, rmSync } from 'node:fs'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { expect, it, onTestFinished, vi } from 'vitest'
|
||||
import { getDshRuntimeVersion, initProfile, PROFILE_TEMPLATES, readProfileVersionExemptions } from '@deepseek-ai/dsh-app-boot'
|
||||
import { getDshRuntimeVersion, initProfile, readProfileVersionExemptions } from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { runPluginCommand, runProfilePnpm } from '@deepseek-ai/dsh-plugin-manager/operations'
|
||||
import { runPlugin } from '../src/plugin.ts'
|
||||
|
||||
|
||||
@@ -7,11 +7,11 @@ import { fileURLToPath } from 'node:url'
|
||||
import {
|
||||
initProfile,
|
||||
PROFILE_PATCH_FILENAME,
|
||||
PROFILE_TEMPLATES,
|
||||
readProfileManifest,
|
||||
resolveProfileDir,
|
||||
writeProfileManifest,
|
||||
} from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { execa } from 'execa'
|
||||
import { initializeProfileFromDefault } from '../src/profile-boot.ts'
|
||||
|
||||
@@ -5,7 +5,8 @@ import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { composeEntries, loadProfile, PROFILE_TEMPLATES } from '@deepseek-ai/dsh-app-boot'
|
||||
import { composeEntries, loadProfile } from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
|
||||
const installAnchor = fileURLToPath(new URL('../package.json', import.meta.url))
|
||||
const resourcePackage = '@deepseek-ai/dsh-mcp-resources'
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
{
|
||||
"path": "../../packages/boot/app-boot"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/boot/official-bundles"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/boot/cmdline"
|
||||
},
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
"@deepseek-ai/dsh-client-ui-settings-general": "workspace:*",
|
||||
"@deepseek-ai/dsh-client-ui-sidebar-browser": "workspace:*",
|
||||
"@deepseek-ai/dsh-home-paths": "workspace:*",
|
||||
"@deepseek-ai/dsh-official-bundles": "workspace:*",
|
||||
"@deepseek-ai/node-addon-system": "workspace:~",
|
||||
"@electron/get": "^5.1.0",
|
||||
"@electron/notarize": "2.5.0",
|
||||
|
||||
@@ -22,9 +22,8 @@ import {
|
||||
import type { DesktopPaths } from './paths.ts'
|
||||
import type { DesktopRelease } from './release.ts'
|
||||
import { readDesktopRuntime } from './runtime-tree.ts'
|
||||
import {
|
||||
initProfile, PROFILE_TEMPLATES, removeLinkProjections, sanitizeProfile, type ProfileTemplate,
|
||||
} from '@deepseek-ai/dsh-app-boot'
|
||||
import { initProfile, removeLinkProjections, sanitizeProfile } from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES, type ProfileTemplate } from '@deepseek-ai/dsh-official-bundles'
|
||||
|
||||
const PROJECT_NAME = '@deepseek-ai/dsh-desktop-runtime'
|
||||
const DSH_PACKAGE = '@deepseek-ai/dsh'
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
{
|
||||
"path": "../../packages/boot/app-boot"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/boot/official-bundles"
|
||||
},
|
||||
{
|
||||
"path": "../../packages/util/home-paths"
|
||||
},
|
||||
|
||||
@@ -32,7 +32,7 @@ import { fileURLToPath } from 'node:url'
|
||||
import { chromium } from 'playwright'
|
||||
import type { Browser, Page } from 'playwright'
|
||||
import { expect, it } from 'vitest'
|
||||
import { OPTIONAL_BUNDLES } from '@deepseek-ai/dsh-app-boot'
|
||||
import { OPTIONAL_BUNDLES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import {
|
||||
packPreviewFixture, packRepositoryImage, previewFixtures, WRAPPER_CONTRACT,
|
||||
} from '@deepseek-ai/dsh-experimental-webworker-packer'
|
||||
|
||||
@@ -2485,7 +2485,7 @@ export interface PlanModeConfig {
|
||||
|
||||
- `inject`: `loader` · `profileContext`
|
||||
- `refs`: [`NpmFileSource`](subsystems/boot.md)
|
||||
- `source`: [`packages/boot/plugin-manager/src/index.ts:50`](../packages/boot/plugin-manager/src/index.ts)
|
||||
- `source`: [`packages/boot/plugin-manager/src/index.ts:51`](../packages/boot/plugin-manager/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** The pnpm executable, registries, and limits for diagnostics, lookups and connection checks. */
|
||||
@@ -4864,6 +4864,7 @@ Imported as libraries by other packages; a `cordis.yml` cannot load them.
|
||||
| `@deepseek-ai/dsh-llm-mock-server` | — | [`packages/test-support/llm-mock-server/src/index.ts`](../packages/test-support/llm-mock-server/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-loader-smoke` | — | [`packages/test-support/loader-smoke/src/index.ts`](../packages/test-support/loader-smoke/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-native-command` | — | [`packages/util/native-command/src/index.ts`](../packages/util/native-command/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-official-bundles` | — | [`packages/boot/official-bundles/src/index.ts`](../packages/boot/official-bundles/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-output-retention` | — | [`packages/util/output-retention/src/index.ts`](../packages/util/output-retention/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-package-manifest` | — | [`packages/util/package-manifest/src/index.ts`](../packages/util/package-manifest/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-plugin-detail` | — | [`packages/util/plugin-detail/src/index.ts`](../packages/util/plugin-detail/src/index.ts) |
|
||||
|
||||
@@ -2487,7 +2487,7 @@ export interface PlanModeConfig {
|
||||
|
||||
- `inject`: `loader` · `profileContext`
|
||||
- `refs`: [`NpmFileSource`](subsystems/boot.zh.md)
|
||||
- `source`: [`packages/boot/plugin-manager/src/index.ts:50`](../packages/boot/plugin-manager/src/index.ts)
|
||||
- `source`: [`packages/boot/plugin-manager/src/index.ts:51`](../packages/boot/plugin-manager/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** The pnpm executable, registries, and limits for diagnostics, lookups and connection checks. */
|
||||
@@ -4866,6 +4866,7 @@ export interface Config {
|
||||
| `@deepseek-ai/dsh-llm-mock-server` | — | [`packages/test-support/llm-mock-server/src/index.ts`](../packages/test-support/llm-mock-server/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-loader-smoke` | — | [`packages/test-support/loader-smoke/src/index.ts`](../packages/test-support/loader-smoke/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-native-command` | — | [`packages/util/native-command/src/index.ts`](../packages/util/native-command/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-official-bundles` | — | [`packages/boot/official-bundles/src/index.ts`](../packages/boot/official-bundles/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-output-retention` | — | [`packages/util/output-retention/src/index.ts`](../packages/util/output-retention/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-package-manifest` | — | [`packages/util/package-manifest/src/index.ts`](../packages/util/package-manifest/src/index.ts) |
|
||||
| `@deepseek-ai/dsh-plugin-detail` | — | [`packages/util/plugin-detail/src/index.ts`](../packages/util/plugin-detail/src/index.ts) |
|
||||
|
||||
@@ -26,7 +26,7 @@ This matrix shows which packages dispatch each harness-owned event and which pac
|
||||
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:607`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:586`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:593`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `app-boot/config-reload` | `emit` | [`packages/boot/app-boot/src/index.ts:54`](../packages/boot/app-boot/src/index.ts) | [`app-boot`](../packages/boot/app-boot) (`emit`) | [`settings`](../packages/settings/settings) |
|
||||
| `app-boot/config-reload` | `emit` | [`packages/boot/app-boot/src/index.ts:53`](../packages/boot/app-boot/src/index.ts) | [`app-boot`](../packages/boot/app-boot) (`emit`) | [`settings`](../packages/settings/settings) |
|
||||
| `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:87`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes`, `server` |
|
||||
| `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | - |
|
||||
| `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:89`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `remotes` |
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
| `api-session/error` | `emit` | [`packages/api/session-controller/src/types.ts:607`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/removed` | `emit` | [`packages/api/session-controller/src/types.ts:586`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `api-session/status` | `emit` | [`packages/api/session-controller/src/types.ts:593`](../packages/api/session-controller/src/types.ts) | `session-controller` (`emit`) | `remotes` |
|
||||
| `app-boot/config-reload` | `emit` | [`packages/boot/app-boot/src/index.ts:54`](../packages/boot/app-boot/src/index.ts) | [`app-boot`](../packages/boot/app-boot) (`emit`) | [`settings`](../packages/settings/settings) |
|
||||
| `app-boot/config-reload` | `emit` | [`packages/boot/app-boot/src/index.ts:53`](../packages/boot/app-boot/src/index.ts) | [`app-boot`](../packages/boot/app-boot) (`emit`) | [`settings`](../packages/settings/settings) |
|
||||
| `approval/request` | `waterfall` | [`packages/interaction/user-approval/src/types.ts:87`](../packages/interaction/user-approval/src/types.ts) | [`user-approval`](../packages/interaction/user-approval) (`waterfall`) | [`acp`](../packages/acp/acp), `remotes`, `server` |
|
||||
| `authorization/settled` | `emit` | [`packages/credentials/authorization/src/index.ts:57`](../packages/credentials/authorization/src/index.ts) | [`authorization`](../packages/credentials/authorization) (`events.dispatch`) | - |
|
||||
| `commands/change` | `emit` | [`packages/interaction/commands/src/types.ts:89`](../packages/interaction/commands/src/types.ts) | [`commands`](../packages/interaction/commands) (`events.dispatch`) | `remotes` |
|
||||
|
||||
@@ -134,6 +134,7 @@ flowchart TD
|
||||
pkg_cmdline["cmdline"]
|
||||
pkg_config_editor["config-editor"]
|
||||
pkg_hmr["hmr"]
|
||||
pkg_official_bundles["official-bundles"]
|
||||
pkg_plugin_manager["plugin-manager"]
|
||||
pkg_plugin_market["plugin-market"]
|
||||
end
|
||||
@@ -1485,6 +1486,7 @@ flowchart TD
|
||||
| [`api-remote-access`](../packages/api/remote-access) | `api` | — |
|
||||
| [`api-workspace-files`](../packages/api/workspace-files) | `api` | — |
|
||||
| [`cmdline`](../packages/boot/cmdline) | `boot` | — |
|
||||
| [`official-bundles`](../packages/boot/official-bundles) | `boot` | — |
|
||||
| [`acp-app`](../packages/bundle/acp-app) | `bundle` | — |
|
||||
| [`base`](../packages/bundle/base) | `bundle` | — |
|
||||
| [`sdk-app`](../packages/bundle/sdk-app) | `bundle` | — |
|
||||
|
||||
@@ -136,6 +136,7 @@ flowchart TD
|
||||
pkg_cmdline["cmdline"]
|
||||
pkg_config_editor["config-editor"]
|
||||
pkg_hmr["hmr"]
|
||||
pkg_official_bundles["official-bundles"]
|
||||
pkg_plugin_manager["plugin-manager"]
|
||||
pkg_plugin_market["plugin-market"]
|
||||
end
|
||||
@@ -1487,6 +1488,7 @@ flowchart TD
|
||||
| [`api-remote-access`](../packages/api/remote-access) | `api` | — |
|
||||
| [`api-workspace-files`](../packages/api/workspace-files) | `api` | — |
|
||||
| [`cmdline`](../packages/boot/cmdline) | `boot` | — |
|
||||
| [`official-bundles`](../packages/boot/official-bundles) | `boot` | — |
|
||||
| [`acp-app`](../packages/bundle/acp-app) | `bundle` | — |
|
||||
| [`base`](../packages/bundle/base) | `bundle` | — |
|
||||
| [`sdk-app`](../packages/bundle/sdk-app) | `bundle` | — |
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
# Bilingual-pair consistency record for guide.md (docs/i18n/README.md): per heading
|
||||
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
||||
# After editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-rc.2/official-bundle-lists/guide.md
|
||||
/:
|
||||
en: d6f85fefe3671f5d
|
||||
zh: 2719b3d5ba1b2120
|
||||
/import-bundle-lists-from-deepseek-ai-dsh-official-bundles:
|
||||
en: 89f87bcf95ee4262
|
||||
zh: 00bbb48605743bcc
|
||||
/import-bundle-lists-from-deepseek-ai-dsh-official-bundles/change:
|
||||
en: 0d8984d9bead43c6
|
||||
zh: 60939a14fcf1ba9a
|
||||
/import-bundle-lists-from-deepseek-ai-dsh-official-bundles/migration:
|
||||
en: 6db29a6197a38b9e
|
||||
zh: f1b445be37526806
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "The bundle lists and profile templates move from @deepseek-ai/dsh-app-boot to @deepseek-ai/dsh-official-bundles."
|
||||
---
|
||||
|
||||
# Import bundle lists from `@deepseek-ai/dsh-official-bundles`
|
||||
|
||||
English | [中文](guide.zh.md)
|
||||
|
||||
## Change
|
||||
|
||||
`@deepseek-ai/dsh-app-boot` no longer exports `PROFILE_TEMPLATES`, `ProfileTemplate`, `DEFAULT_PROFILE_BUNDLES`, `OPTIONAL_BUNDLES`, `ON_DEMAND_BUNDLES`, `OFFICIAL_ON_DEMAND_CATALOG`, or `OfficialBundleCatalogEntry`. The new published package `@deepseek-ai/dsh-official-bundles` exports them with unchanged values and types. Code that imports any of these names from `@deepseek-ai/dsh-app-boot` fails to compile or load. The `dsh` launcher, profiles, and bundle selection behave as before.
|
||||
|
||||
## Migration
|
||||
|
||||
1. Add `@deepseek-ai/dsh-official-bundles` to the `dependencies` of each package that imports one of these names.
|
||||
2. Change those imports from `@deepseek-ai/dsh-app-boot` to `@deepseek-ai/dsh-official-bundles`, for example `import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'`. Keep importing every other name, such as `initProfile` or `loadProfile`, from `@deepseek-ai/dsh-app-boot`.
|
||||
3. Run your type check or build; it succeeds when no import of a moved name from `@deepseek-ai/dsh-app-boot` remains. See the [package README](../../../../packages/boot/official-bundles/README.md) for each list.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "组合包列表和 profile 模板从 @deepseek-ai/dsh-app-boot 移至 @deepseek-ai/dsh-official-bundles。"
|
||||
---
|
||||
|
||||
# 从 `@deepseek-ai/dsh-official-bundles` 导入组合包列表
|
||||
|
||||
[English](guide.md) | 中文
|
||||
|
||||
## 变更
|
||||
|
||||
`@deepseek-ai/dsh-app-boot` 不再导出 `PROFILE_TEMPLATES`、`ProfileTemplate`、`DEFAULT_PROFILE_BUNDLES`、`OPTIONAL_BUNDLES`、`ON_DEMAND_BUNDLES`、`OFFICIAL_ON_DEMAND_CATALOG` 和 `OfficialBundleCatalogEntry`。新发布的包 `@deepseek-ai/dsh-official-bundles` 导出它们,值和类型不变。从 `@deepseek-ai/dsh-app-boot` 导入这些名称的代码将无法编译或加载。`dsh` 启动器、profile 和组合包选择的行为不变。
|
||||
|
||||
## 迁移
|
||||
|
||||
1. 在每个导入这些名称的包的 `dependencies` 中加入 `@deepseek-ai/dsh-official-bundles`。
|
||||
2. 把这些导入从 `@deepseek-ai/dsh-app-boot` 改为 `@deepseek-ai/dsh-official-bundles`,例如 `import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'`。其他名称(如 `initProfile` 或 `loadProfile`)仍从 `@deepseek-ai/dsh-app-boot` 导入。
|
||||
3. 运行类型检查或构建;不再有从 `@deepseek-ai/dsh-app-boot` 导入已移动名称的代码时即通过。各列表的说明见[包 README](../../../../packages/boot/official-bundles/README.zh.md)。
|
||||
@@ -15,8 +15,8 @@
|
||||
en: ffc55792d6e922e1
|
||||
zh: 83bd759638857e2d
|
||||
/packages/package-groups:
|
||||
en: ff0b0b8388457f47
|
||||
zh: b9ace22bb3cbad48
|
||||
en: d67996086e3b4f28
|
||||
zh: cb758b1fcee5ab3e
|
||||
/packages/release-expectations:
|
||||
en: 236081c1659b25ab
|
||||
zh: 809110adf003802e
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ Every package lives in exactly one group; new packages join existing groups, and
|
||||
| [`sdk/`](sdk/README.md) | Out-of-process SDK: JSON-RPC protocol and TypeScript client/server |
|
||||
| [`acp/`](acp/README.md) | Automation-only Agent Client Protocol server |
|
||||
| [`interaction/`](interaction/README.md) | Human-collaboration plane: approval/interaction seams, permission preset, commands, ask-user tool |
|
||||
| [`boot/`](boot/README.md) | Shared app-bin boot glue |
|
||||
| [`boot/`](boot/README.md) | Shared app-bin boot glue and installation bundle lists |
|
||||
| [`host/`](host/README.md) | Web GUI host services, directory picking, application launch, plugin inventory, and product telemetry |
|
||||
| [`client/`](client/README.md) | Web-GUI browser half: shell, wire, object services, slots, `ui-*` plugins |
|
||||
| [`test-support/`](test-support/README.md) | Test infrastructure (testkits, replay, Loader smokes) |
|
||||
|
||||
@@ -75,7 +75,7 @@ harness 由 `packages/` 下的 npm 包组装而成,按能力系列分组:会
|
||||
| [`sdk/`](sdk/README.zh.md) | 进程外 SDK:JSON-RPC 协议与 TypeScript 客户端/服务器 |
|
||||
| [`acp/`](acp/README.zh.md) | 仅面向自动化的 ACP(Agent Client Protocol)服务器 |
|
||||
| [`interaction/`](interaction/README.zh.md) | 人机协作平面:批准/交互 seam、权限预设、命令、询问用户的工具 |
|
||||
| [`boot/`](boot/README.zh.md) | 共享的 app bin 启动粘合层 |
|
||||
| [`boot/`](boot/README.zh.md) | 共享的 app bin 启动粘合层与安装方组合包列表 |
|
||||
| [`host/`](host/README.zh.md) | Web GUI 宿主服务、目录选择、应用启动、插件清单和产品遥测 |
|
||||
| [`client/`](client/README.zh.md) | web GUI 浏览器半侧:shell、协议层、对象服务、slot、`ui-*` 插件 |
|
||||
| [`test-support/`](test-support/README.zh.md) | 测试基础设施(testkit、回放、Loader 冒烟测试) |
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
en: 09848f4d056e4fc1
|
||||
zh: 8df6139cff0288f6
|
||||
/boot-shared-app-bin-boot-glue/packages:
|
||||
en: 626cbd4bc04cf9bb
|
||||
zh: 3c2f6154e58908c2
|
||||
en: 71736c39fd71952c
|
||||
zh: 2033a18debd8a2d8
|
||||
/boot-shared-app-bin-boot-glue/related-documentation:
|
||||
en: 77af4b40ee7b98a3
|
||||
zh: e9b4e817823b973d
|
||||
|
||||
@@ -23,6 +23,7 @@ The boot group launches profile applications and manages their installed composi
|
||||
| Package | Role | ctx key |
|
||||
|---|---|---|
|
||||
| [`app-boot`](app-boot/README.md) | Boots a dsh app from a `cordis.yml`: loads `.env`, applies profile and patch layers, and reports startup failures clearly | (library for the bins) |
|
||||
| [`official-bundles`](official-bundles/README.md) | Lists the bundles the installation ships in profile templates, offers switched off, installs on demand, or retires | (library) |
|
||||
| [`cmdline`](cmdline/README.md) | Lets the app own its flags, `--help`, and exit code; passes everything after the launcher's flags through verbatim | `cmdlineArgs`, `appExit` |
|
||||
| [`hmr`](hmr/README.md) | Coordinates module and configuration reloads with package mutations | `hmr` |
|
||||
| [`config-editor`](config-editor/README.md) | Persists active profile configuration through Loader reconciliation | `configEditor` |
|
||||
|
||||
@@ -23,6 +23,7 @@ boot 组负责启动 profile 应用并管理其已安装组合。`app-boot` 解
|
||||
| 包 | 职责 | ctx 键 |
|
||||
|---|---|---|
|
||||
| [`app-boot`](app-boot/README.zh.md) | 从 `cordis.yml` 启动 dsh 应用:加载 `.env`、应用 profile 与 patch 层,并清晰报告启动失败 | (供各 bin 使用的库) |
|
||||
| [`official-bundles`](official-bundles/README.zh.md) | 列出安装随附于 profile 模板、默认关闭提供、按需安装或已退役的组合包 | (库) |
|
||||
| [`cmdline`](cmdline/README.zh.md) | 让应用持有自己的 flag、`--help` 与退出码;启动器自身 flag 之后的一切原样传入 | `cmdlineArgs`、`appExit` |
|
||||
| [`hmr`](hmr/README.zh.md) | 协调模块与配置重载,并与包修改互斥执行 | `hmr` |
|
||||
| [`config-editor`](config-editor/README.zh.md) | 通过 Loader 应用并持久化当前 profile 配置 | `configEditor` |
|
||||
|
||||
@@ -33,8 +33,8 @@
|
||||
en: c4a301652b851ce9
|
||||
zh: 784871e19cd9db0a
|
||||
/deepseek-ai-dsh-app-boot/use-this-package/reading-plugin-display-metadata:
|
||||
en: a9afb263b03d112c
|
||||
zh: 31f5e797cd953c15
|
||||
en: b737278c1bc065e7
|
||||
zh: f42bdbfe267581d1
|
||||
/deepseek-ai-dsh-app-boot/use-this-package/startup-and-reload-failures:
|
||||
en: dc13dfa1f79292e4
|
||||
zh: d51682ced7a18ac2
|
||||
|
||||
@@ -86,7 +86,7 @@ The projector preserves native omission behavior by checking literal defaults ag
|
||||
|
||||
Use `readPluginMeta(specifier, parentURL)` or `ctx.pluginPackages.metaOf(specifier, parentURL)` to read installed package display text without importing or activating the plugin. Lookup uses the complete package specifier and the caller's resolution base, respecting Node exports. File paths and file URLs return no metadata without resolving resources. For a package-root specifier, missing locale fields fall back to the accessible `package.json`; a subpath specifier never reads a `package.json`. Malformed metadata returns an `error` diagnostic. Results retain translations for Client-side language selection. The reader also loads an image data URL, even when locale text is complete: a package root uses its manifest `icon`, or `<package>/icon` when that field is omitted; a subpath uses `<specifier>/icon`. An icon error preserves valid text alongside the diagnostic. See [Plugin display metadata](../../../docs/cookbook/adding-a-package.md#plugin-display-metadata) for the author format.
|
||||
|
||||
`ON_DEMAND_BUNDLES` names the public Official packages installed only on request. `OFFICIAL_ON_DEMAND_CATALOG` embeds their package-owned localized metadata and icons for offline discovery; `pnpm gen-official-bundle-catalog` explicitly updates generated content, and `verify-official-bundle-catalog` checks resource completeness and freshness; builds consume the committed catalog without importing provider code. The catalog contains no install target: [Plugin Manager](../plugin-manager/README.md#use-this-package) derives it from the running version and installation and uses the ordinary bundle installer. The [product-use check](../../../scripts/verify-product-use.ts) composes shipped and on-demand selections against Web without executing providers.
|
||||
The profile templates, installation-owned profile tuples, and retired bundle list that app-boot applies live in [`@deepseek-ai/dsh-official-bundles`](../official-bundles/README.md), together with the installation's default, optional, and on-demand bundle lists.
|
||||
|
||||
<a id="startup-and-reload-failures"></a>
|
||||
### Startup and reload failures
|
||||
|
||||
@@ -86,7 +86,7 @@ profile 导入插件前,DSH 会将其声明的 DSH 版本要求与 `getDshRunt
|
||||
|
||||
使用 `readPluginMeta(specifier, parentURL)` 或 `ctx.pluginPackages.metaOf(specifier, parentURL)` 读取已安装包的展示文本,无需导入或激活插件。查询使用完整包标识与调用方的解析基准,并遵循 Node exports。文件路径与文件 URL 不解析资源,直接返回无元信息。包根标识缺失的 locale 字段回退到可访问的 `package.json`;子路径标识从不读取 `package.json`。格式错误的元信息返回 `error` 诊断。结果保留翻译,由 Client 选择语言。即使 locale 文本完整,读取器也会加载图片 data URL:包根使用清单 `icon`,省略该字段时使用 `<包名>/icon`;子路径使用 `<标识>/icon`。图标出错时,保留有效文本并附上诊断。作者格式见[插件展示元信息](../../../docs/cookbook/adding-a-package.zh.md#plugin-display-metadata)。
|
||||
|
||||
`ON_DEMAND_BUNDLES` 列出仅按需安装的官方公开包。`OFFICIAL_ON_DEMAND_CATALOG` 内嵌这些包拥有的本地化元信息和图标,支持离线发现;`pnpm gen-official-bundle-catalog` 显式更新生成内容,`verify-official-bundle-catalog` 检查资源完整性与新鲜度;构建只读取已提交的目录,不导入提供者代码。目录不保存安装目标;[插件管理器](../plugin-manager/README.zh.md#use-this-package)根据当前版本和安装位置确定目标,并使用普通组合包安装器。[产品用途检查](../../../scripts/verify-product-use.ts)将随附和按需选择与 Web 组合,但不执行提供者。
|
||||
app-boot 应用的 profile 模板、安装方拥有的 profile 组合包元组和已退役组合包列表位于 [`@deepseek-ai/dsh-official-bundles`](../official-bundles/README.zh.md),安装方的默认、可选和按需组合包列表也在该包中。
|
||||
|
||||
<a id="startup-and-reload-failures"></a>
|
||||
### 启动与重载失败
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@deepseek-ai/dsh-atomic-write": "workspace:*",
|
||||
"@deepseek-ai/dsh-official-bundles": "workspace:*",
|
||||
"@deepseek-ai/dsh-package-manifest": "workspace:*",
|
||||
"@eslint-community/regexpp": "^4.12.2",
|
||||
"ajv": "^8.20.0",
|
||||
|
||||
@@ -29,7 +29,6 @@ import { ProfileRuntimeResolution, type RuntimeResolution } from './profile.ts'
|
||||
import { ResolutionRestartRequired } from './profile-resolution/resolver.ts'
|
||||
export { prepareProfileEntries, prepareProfilePatches } from './compatibility-preflight.ts'
|
||||
export { readPluginMeta, resolvePluginResource } from './package-meta.ts'
|
||||
export { ON_DEMAND_BUNDLES, OFFICIAL_ON_DEMAND_CATALOG, type OfficialBundleCatalogEntry } from './official-bundles.ts'
|
||||
export { generateConfigSchema, type ConfigSchemaDump, type NativeConfigSchema } from './config-schema/index.ts'
|
||||
export { createConfigProjector, LOADER_EXPRESSION_SCHEMA, type ConfigProjection } from './config-schema/projector.ts'
|
||||
export { isNativeConfigSchema } from './config-schema/native.ts'
|
||||
@@ -59,8 +58,6 @@ export {
|
||||
composeEntries,
|
||||
createRuntimeResolution,
|
||||
ProfileRuntimeResolution,
|
||||
DEFAULT_PROFILE_BUNDLES,
|
||||
OPTIONAL_BUNDLES,
|
||||
bundlePatchFiles,
|
||||
bundlePatchPaths,
|
||||
initProfile,
|
||||
@@ -68,7 +65,6 @@ export {
|
||||
loadProfile,
|
||||
loadProfileDirectory,
|
||||
PROFILE_PATCH_FILENAME,
|
||||
PROFILE_TEMPLATES,
|
||||
PROFILES_DIR,
|
||||
readProfileManifest,
|
||||
reportSkippedBundles,
|
||||
@@ -83,7 +79,6 @@ export {
|
||||
type RuntimeResolutionOptions,
|
||||
type RuntimeResolutionEntry,
|
||||
type RuntimeResolution,
|
||||
type ProfileTemplate,
|
||||
} from './profile.ts'
|
||||
export {
|
||||
PluginPackages,
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
/** Package admission shared by offline catalog generation and release ordering. */
|
||||
|
||||
/** Public DSH release members available through the ordinary on-demand bundle installer. */
|
||||
export const ON_DEMAND_BUNDLES: readonly string[] = [
|
||||
'@deepseek-ai/dsh-subagent-claude-code',
|
||||
'@deepseek-ai/dsh-subagent-codex',
|
||||
]
|
||||
@@ -28,6 +28,7 @@ import type { EntryOptions } from '@deepseek-ai/cordis-plugin-loader'
|
||||
import { applyEntryPatches, type PatchOptions } from '@deepseek-ai/cordis-plugin-include'
|
||||
import { resolveDshHome } from '@deepseek-ai/dsh-home-paths'
|
||||
import type { DshBundleManifest, DshPackageManifest } from '@deepseek-ai/dsh-package-manifest'
|
||||
import { INSTALLATION_OWNED_PROFILE_TUPLES, PROFILE_TEMPLATES, RETIRED_BUNDLES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { evaluatePluginCompatibility, pluginCompatibilityWarning } from './plugin-compatibility.ts'
|
||||
import { readProfileVersionExemptions } from './profile-compatibility.ts'
|
||||
import { loadOverlayPatches } from './index.ts'
|
||||
@@ -39,12 +40,6 @@ export const PROFILES_DIR = 'profiles'
|
||||
/** The user patch layer inside a profile directory (hot-reloaded on long-lived surfaces). */
|
||||
export const PROFILE_PATCH_FILENAME = 'cordis.patch.yml'
|
||||
|
||||
/** Installation-owned defaults used when a shipped profile is first opened. */
|
||||
export interface ProfileTemplate {
|
||||
/** Ordered bundle layer list. */
|
||||
bundles: readonly string[]
|
||||
}
|
||||
|
||||
/** Package metadata accepted by the profile reader; local profiles need no published identity. */
|
||||
export type ProfileManifest = Partial<DshPackageManifest>
|
||||
|
||||
@@ -175,68 +170,6 @@ export function resolveProfileDir(name: string, home: string = resolveDshHome())
|
||||
return join(home, PROFILES_DIR, name)
|
||||
}
|
||||
|
||||
/** The shipped profile templates auto-initialized on first use, by name. */
|
||||
export const PROFILE_TEMPLATES: Record<string, ProfileTemplate> = {
|
||||
acp: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-acp-app'],
|
||||
},
|
||||
web: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'],
|
||||
},
|
||||
headless: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-headless'],
|
||||
},
|
||||
sdk: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-sdk-app'],
|
||||
},
|
||||
'sdk-minimal': {
|
||||
bundles: ['@deepseek-ai/dsh-sdk-minimal'],
|
||||
},
|
||||
}
|
||||
|
||||
/** Installation-owned bundle tuples normalized to the shipped template. */
|
||||
const INSTALLATION_OWNED_PROFILE_TUPLES: Record<string, readonly string[]> = {
|
||||
headless: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app', '@deepseek-ai/dsh-headless'],
|
||||
}
|
||||
|
||||
/**
|
||||
* Bundles an earlier release shipped and the installation no longer carries;
|
||||
* {@link loadProfileDirectory} removes them from the profile's bundle list.
|
||||
*/
|
||||
const RETIRED_BUNDLES: ReadonlySet<string> = new Set([
|
||||
// The Web composition mounts Schedule itself
|
||||
// ([upgrade guide](../../../../docs/upgrade-guide/v0.2.0-rc.2/schedule-bundle-retired/guide.md)).
|
||||
'@deepseek-ai/dsh-experimental-schedule-bundle',
|
||||
])
|
||||
|
||||
/** The bundle list a `dsh plugin` init uses for a name with no shipped template. */
|
||||
export const DEFAULT_PROFILE_BUNDLES: readonly string[] = ['@deepseek-ai/dsh-base']
|
||||
|
||||
/**
|
||||
* The bundles the dsh installation ships for a person to switch on: each a
|
||||
* runtime dependency of the installation that declares `dsh.bundle.patch`,
|
||||
* an `icon`, and `./locale/*.json` display metadata, selected by no shipped
|
||||
* template, and offered switched off by the plugin manager except persistent
|
||||
* terminals, which have no page switch
|
||||
* ([rationale](../../../../.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md),
|
||||
* [admission](../../../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md)).
|
||||
*/
|
||||
export const OPTIONAL_BUNDLES: readonly string[] = [
|
||||
'@deepseek-ai/dsh-cua-bundle',
|
||||
'@deepseek-ai/dsh-experimental-session-search',
|
||||
'@deepseek-ai/dsh-experimental-ralph-bundle',
|
||||
'@deepseek-ai/dsh-experimental-terminal-bundle',
|
||||
'@deepseek-ai/dsh-experimental-badge-skill-bundle',
|
||||
'@deepseek-ai/dsh-experimental-session-titles-bundle',
|
||||
'@deepseek-ai/dsh-experimental-agent-team-profile',
|
||||
'@deepseek-ai/dsh-experimental-voice-input-bundle',
|
||||
'@deepseek-ai/dsh-experimental-cot-translation-bundle',
|
||||
'@deepseek-ai/dsh-experimental-auto-review',
|
||||
'@deepseek-ai/dsh-experimental-inspector-profile',
|
||||
'@deepseek-ai/dsh-experimental-plugin-market-bundle',
|
||||
'@deepseek-ai/dsh-experimental-tool-worktree',
|
||||
]
|
||||
|
||||
const PROFILE_PATCH_TEMPLATE = `# Your patch layer for this dsh profile, applied after every bundle layer:
|
||||
# a top-level YAML array of loader patch entries (id-targeted config
|
||||
# overrides, disables, and insert lists; \`!!js\` expressions allowed).
|
||||
|
||||
@@ -4,7 +4,8 @@ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, renameSy
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { afterEach, expect, it, vi } from 'vitest'
|
||||
import { initProfile, PROFILE_PATCH_FILENAME, PROFILE_TEMPLATES, readProfileManifest, sanitizeProfile } from '../src/index.ts'
|
||||
import { initProfile, PROFILE_PATCH_FILENAME, readProfileManifest, sanitizeProfile } from '../src/index.ts'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
|
||||
vi.mock('node:fs', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof import('node:fs')>()
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
loadProfileDirectory,
|
||||
PROFILE_COMPATIBILITY_FILENAME,
|
||||
PROFILE_PATCH_FILENAME,
|
||||
PROFILE_TEMPLATES,
|
||||
readProfileManifest,
|
||||
readProfilePatches,
|
||||
removeLinkProjections,
|
||||
@@ -32,6 +31,7 @@ import {
|
||||
type Profile,
|
||||
type RuntimeResolution,
|
||||
} from '../src/index.ts'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { installRuntimeInterception } from '../src/profile-resolution/resolver.ts'
|
||||
|
||||
const tempRoots: string[] = []
|
||||
@@ -341,16 +341,6 @@ describe('loadProfile', () => {
|
||||
const home = tmp()
|
||||
expect(() => loadProfile('t', 'custom', anchor, home))
|
||||
.toThrow('profile "custom" does not exist')
|
||||
expect(PROFILE_TEMPLATES.web?.bundles).toContain('@deepseek-ai/dsh-base')
|
||||
expect(PROFILE_TEMPLATES.acp).toEqual({
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-acp-app'],
|
||||
})
|
||||
expect(PROFILE_TEMPLATES.sdk).toEqual({
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-sdk-app'],
|
||||
})
|
||||
expect(PROFILE_TEMPLATES['sdk-minimal']).toEqual({
|
||||
bundles: ['@deepseek-ai/dsh-sdk-minimal'],
|
||||
})
|
||||
loadProfile('t', 'web', anchor, home)
|
||||
expect(readProfileManifest('t', resolveProfileDir('web', home)).dsh?.profile?.bundles)
|
||||
.toEqual([...PROFILE_TEMPLATES.web?.bundles ?? []])
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
{
|
||||
"path": "../../util/home-paths"
|
||||
},
|
||||
{
|
||||
"path": "../official-bundles"
|
||||
},
|
||||
{
|
||||
"path": "../../util/package-manifest"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
# Bilingual-pair consistency record for README.md (docs/i18n/README.md): per heading
|
||||
# section, a hash of its English and Chinese blocks outside code blocks and generated regions.
|
||||
# After editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write packages/boot/official-bundles/README.md
|
||||
/:
|
||||
en: bf83ae511baf1048
|
||||
zh: f8966b8dd39c5b9a
|
||||
/deepseek-ai-dsh-official-bundles:
|
||||
en: bb5c2cd3ee2ee02b
|
||||
zh: cf78cfef3b92ab25
|
||||
/deepseek-ai-dsh-official-bundles/summary:
|
||||
en: 3d64166b71a685bc
|
||||
zh: 424e1f77fc987115
|
||||
/deepseek-ai-dsh-official-bundles/table-of-contents:
|
||||
en: 80b31a934611cb4a
|
||||
zh: 05f3f7f9cb2fd881
|
||||
/deepseek-ai-dsh-official-bundles/use-this-package:
|
||||
en: 62c8aa1af42d91d7
|
||||
zh: 39674a200b42b0d2
|
||||
/deepseek-ai-dsh-official-bundles/use-this-package/profile-templates:
|
||||
en: 60ef21314c76c3ec
|
||||
zh: f769091957235e12
|
||||
/deepseek-ai-dsh-official-bundles/use-this-package/optional-and-retired-bundles:
|
||||
en: c0940eb304bbacd1
|
||||
zh: bbc4f72b7a49c676
|
||||
/deepseek-ai-dsh-official-bundles/use-this-package/on-demand-bundles:
|
||||
en: 10dac368736afde3
|
||||
zh: 7684ca22ba4b5a67
|
||||
/deepseek-ai-dsh-official-bundles/understand-the-implementation:
|
||||
en: 2986cf8f3115a483
|
||||
zh: 3eb2dade2666bbc6
|
||||
/deepseek-ai-dsh-official-bundles/understand-the-implementation/source-map:
|
||||
en: af30ccf226fbb7d4
|
||||
zh: f39ae7a50b2aaa80
|
||||
/deepseek-ai-dsh-official-bundles/further-exploration:
|
||||
en: 16a331e64c81b2a5
|
||||
zh: abfe9b1a1294b6b3
|
||||
/deepseek-ai-dsh-official-bundles/known-limitations-and-deferred-work:
|
||||
en: 6631976cc7404166
|
||||
zh: edb2094b17bc4009
|
||||
/deepseek-ai-dsh-official-bundles/known-limitations-and-deferred-work/dev-note:
|
||||
en: e67f633dc6fe7773
|
||||
zh: 3bb0c20c93f16f98
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
description: "Installation-owned lists of official dsh bundles: shipped profile templates, the default bundle list, and the optional, on-demand, and retired bundles."
|
||||
kind: "package-library"
|
||||
---
|
||||
|
||||
# @deepseek-ai/dsh-official-bundles
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
## Summary
|
||||
|
||||
`@deepseek-ai/dsh-official-bundles` holds the bundle package names the dsh installation decides on: which bundles each shipped profile starts with, which bundles it ships switched off, which official bundles install on request, and which bundles earlier releases shipped and profiles drop. [`dsh-app-boot`](../app-boot/README.md) applies these lists when it loads a profile; the plugin manager, the CLI, Desktop, the WebWorker image packer, and repository checks read them directly. The package holds data only, so adding or removing a bundle leaves app-boot untouched. Use it as a direct library dependency, not through `cordis.yml`.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Use this package](#use-this-package)
|
||||
- [Understand the implementation](#understand-the-implementation)
|
||||
- [Further Exploration](#further-exploration)
|
||||
- [Known Limitations and Deferred Work](#known-limitations-and-deferred-work)
|
||||
- [Dev Note](#dev-note)
|
||||
|
||||
-----
|
||||
|
||||
<a id="use-this-package"></a>
|
||||
## Use this package
|
||||
|
||||
Edit this package when the installation's bundle selection changes; read it wherever code must agree with the launcher about that selection.
|
||||
|
||||
### Profile templates
|
||||
|
||||
`PROFILE_TEMPLATES` maps each shipped profile name (`web`, `headless`, `acp`, `sdk`, `sdk-minimal`) to its ordered bundle layer list. App-boot initializes a missing shipped profile from its template, and `dsh --profile <name> --from-default-profile <template>` copies one into a custom profile. `DEFAULT_PROFILE_BUNDLES` is the list `dsh plugin` uses for a profile name with no template. `INSTALLATION_OWNED_PROFILE_TUPLES` names bundle lists that an earlier release wrote into a shipped profile; app-boot replaces an exact match with the current template.
|
||||
|
||||
### Optional and retired bundles
|
||||
|
||||
`OPTIONAL_BUNDLES` names the bundles the installation ships for a person to switch on. Each must be a runtime dependency of the `dsh` app that declares `dsh.bundle.patch`, an icon, and `./locale/*.json` display metadata, and no template may select it; [`verify-default-product-isolation`](../../../scripts/verify-default-product-isolation.ts) checks these rules. The [plugin manager](../plugin-manager/README.md#use-this-package) reports these bundles as `optional`. `RETIRED_BUNDLES` names bundles the installation no longer carries; app-boot removes them from a profile's bundle list when it loads the profile.
|
||||
|
||||
### On-demand bundles
|
||||
|
||||
`ON_DEMAND_BUNDLES` names the public Official packages installed only on request. `OFFICIAL_ON_DEMAND_CATALOG` embeds their package-owned localized metadata and icons for offline discovery; `pnpm gen-official-bundle-catalog` explicitly updates generated content, and `verify-official-bundle-catalog` checks resource completeness and freshness; builds consume the committed catalog without importing provider code. The catalog contains no install target: the plugin manager derives it from the running version and installation and uses the ordinary bundle installer. The [product-use check](../../../scripts/verify-product-use.ts) composes shipped and on-demand selections against Web without executing providers.
|
||||
|
||||
-----
|
||||
|
||||
<a id="understand-the-implementation"></a>
|
||||
## Understand the implementation
|
||||
|
||||
<details>
|
||||
<summary>Implementation internals — click to expand</summary>
|
||||
|
||||
Repository checks read the lists in `src/bundles.ts` as TypeScript literals without executing them, so each list stays a static array or object literal of package names.
|
||||
|
||||
### Source map
|
||||
|
||||
| File | Role |
|
||||
|---|---|
|
||||
| [`src/bundles.ts`](src/bundles.ts) | Profile templates and the default, installation-owned, retired, optional, and on-demand bundle lists |
|
||||
| [`src/catalog.generated.ts`](src/catalog.generated.ts) | Generated offline metadata for the on-demand bundles |
|
||||
| [`src/index.ts`](src/index.ts) | Public exports and the catalog entry type |
|
||||
|
||||
</details>
|
||||
|
||||
-----
|
||||
|
||||
<a id="further-exploration"></a>
|
||||
## Further Exploration
|
||||
|
||||
- [dsh-app-boot](../app-boot/README.md) — profile loading that applies the templates and retired list.
|
||||
- [Shipped optional bundles](../../../.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md) — why the installation owns the optional list.
|
||||
- [Official on-demand bundles](../../../.agents/notes/implemented/architecture/2026-10-05-official-on-demand-bundles.md) — the offline catalog decision.
|
||||
|
||||
-----
|
||||
|
||||
## Known Limitations and Deferred Work
|
||||
|
||||
<a id="known-limitations-and-deferred-work"></a>
|
||||
|
||||
- **Lists are compiled into the installation** — changing a list requires a new dsh release; a profile cannot extend the optional or on-demand lists.
|
||||
|
||||
<a id="dev-note"></a>
|
||||
### Dev Note
|
||||
|
||||
<details>
|
||||
<summary>Working context for maintainers — click to expand</summary>
|
||||
|
||||
None.
|
||||
|
||||
</details>
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
description: "由安装方持有的官方 dsh 组合包列表:随附 profile 模板、默认组合包列表,以及可选、按需和已退役的组合包。"
|
||||
kind: "package-library"
|
||||
---
|
||||
|
||||
# @deepseek-ai/dsh-official-bundles
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
## 概述
|
||||
|
||||
`@deepseek-ai/dsh-official-bundles` 保存由 dsh 安装决定的组合包名称:每个随附 profile 以哪些组合包启动、随附但默认关闭哪些组合包、哪些官方组合包按请求安装,以及哪些组合包曾由早期版本随附、现在要从 profile 中移除。[`dsh-app-boot`](../app-boot/README.zh.md) 在加载 profile 时应用这些列表;插件管理器、CLI、Desktop、WebWorker 镜像打包器和仓库检查直接读取它们。本包只含数据,因此增加或移除组合包不会改动 app-boot。请把它作为直接的库依赖使用,而不是通过 `cordis.yml` 使用。
|
||||
|
||||
## 目录
|
||||
|
||||
- [使用本包](#use-this-package)
|
||||
- [理解实现](#understand-the-implementation)
|
||||
- [进一步探索](#further-exploration)
|
||||
- [已知限制与延期工作](#known-limitations-and-deferred-work)
|
||||
- [开发备注](#dev-note)
|
||||
|
||||
-----
|
||||
|
||||
<a id="use-this-package"></a>
|
||||
## 使用本包
|
||||
|
||||
安装的组合包选择发生变化时编辑本包;凡是代码必须与启动器就该选择保持一致的地方,都读取本包。
|
||||
|
||||
### Profile 模板
|
||||
|
||||
`PROFILE_TEMPLATES` 把每个随附 profile 名称(`web`、`headless`、`acp`、`sdk`、`sdk-minimal`)映射到其有序的组合包层列表。App-boot 用模板初始化缺失的随附 profile,`dsh --profile <name> --from-default-profile <template>` 把某个模板复制为自定义 profile。`DEFAULT_PROFILE_BUNDLES` 是 `dsh plugin` 对没有模板的 profile 名称使用的列表。`INSTALLATION_OWNED_PROFILE_TUPLES` 列出早期版本写入随附 profile 的组合包列表;app-boot 把与之完全一致的列表替换为当前模板。
|
||||
|
||||
### 可选与已退役组合包
|
||||
|
||||
`OPTIONAL_BUNDLES` 列出安装随附、供用户开启的组合包。每一项都必须是 `dsh` 应用的运行时依赖,并声明 `dsh.bundle.patch`、图标和 `./locale/*.json` 显示元信息,且不能被任何模板选中;[`verify-default-product-isolation`](../../../scripts/verify-default-product-isolation.ts) 检查这些规则。[插件管理器](../plugin-manager/README.zh.md#use-this-package)把这些组合包报告为 `optional`。`RETIRED_BUNDLES` 列出安装不再携带的组合包;app-boot 在加载 profile 时将它们从该 profile 的组合包列表中移除。
|
||||
|
||||
### 按需组合包
|
||||
|
||||
`ON_DEMAND_BUNDLES` 列出只在请求时安装的官方公开包。`OFFICIAL_ON_DEMAND_CATALOG` 内嵌这些包自己持有的本地化元信息和图标,用于离线发现;`pnpm gen-official-bundle-catalog` 显式更新生成内容,`verify-official-bundle-catalog` 检查资源完整性与时效;构建使用已提交的目录,不导入提供方代码。目录不包含安装目标:插件管理器根据运行中的版本和安装推导目标,并使用普通的组合包安装器。[产品使用检查](../../../scripts/verify-product-use.ts)针对 Web 组合随附选择和按需选择,不执行提供方。
|
||||
|
||||
-----
|
||||
|
||||
<a id="understand-the-implementation"></a>
|
||||
## 理解实现
|
||||
|
||||
<details>
|
||||
<summary>实现细节——点击展开</summary>
|
||||
|
||||
仓库检查把 `src/bundles.ts` 中的列表当作 TypeScript 字面量读取而不执行,因此每个列表都保持为由包名组成的静态数组或对象字面量。
|
||||
|
||||
### 源码地图
|
||||
|
||||
| 文件 | 职责 |
|
||||
|---|---|
|
||||
| [`src/bundles.ts`](src/bundles.ts) | Profile 模板,以及默认、安装持有、已退役、可选和按需组合包列表 |
|
||||
| [`src/catalog.generated.ts`](src/catalog.generated.ts) | 按需组合包的生成离线元信息 |
|
||||
| [`src/index.ts`](src/index.ts) | 公开导出与目录条目类型 |
|
||||
|
||||
</details>
|
||||
|
||||
-----
|
||||
|
||||
<a id="further-exploration"></a>
|
||||
## 进一步探索
|
||||
|
||||
- [dsh-app-boot](../app-boot/README.zh.md)——应用模板和退役列表的 profile 加载。
|
||||
- [随附可选组合包](../../../.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.zh.md)——为什么由安装持有可选列表。
|
||||
- [Official 按需组合包](../../../.agents/notes/implemented/architecture/2026-10-05-official-on-demand-bundles.zh.md)——离线目录的决策。
|
||||
|
||||
-----
|
||||
|
||||
## 已知限制与延期工作
|
||||
|
||||
<a id="known-limitations-and-deferred-work"></a>
|
||||
|
||||
- **列表编译进安装**——修改列表需要发布新的 dsh 版本;profile 无法扩展可选或按需列表。
|
||||
|
||||
<a id="dev-note"></a>
|
||||
### 开发备注
|
||||
|
||||
<details>
|
||||
<summary>维护者的工作上下文——点击展开</summary>
|
||||
|
||||
无。
|
||||
|
||||
</details>
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"name": "@deepseek-ai/dsh-official-bundles",
|
||||
"description": "Installation-owned lists of official dsh bundles: shipped profile templates, optional, on-demand, and retired bundles",
|
||||
"version": "0.2.1-rc.2",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/deepseek-ai/deepseek-harness.git",
|
||||
"directory": "packages/boot/official-bundles"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "lib/index.js",
|
||||
"types": "lib/types/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./lib/types/index.d.ts",
|
||||
"default": "./lib/index.js"
|
||||
},
|
||||
"./src/*": "./src/*",
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"files": [
|
||||
"lib/index.js",
|
||||
"lib/types/**/*.d.ts"
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@deepseek-ai/dsh-package-manifest": "workspace:*"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@deepseek-ai/cordis": "workspace:~"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@deepseek-ai/cordis": "workspace:~"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/** The bundle package names the dsh installation selects, offers, installs on demand, or retires. */
|
||||
|
||||
/** Installation-owned defaults used when a shipped profile is first opened. */
|
||||
export interface ProfileTemplate {
|
||||
/** Ordered bundle layer list. */
|
||||
bundles: readonly string[]
|
||||
}
|
||||
|
||||
/** The shipped profile templates auto-initialized on first use, by name. */
|
||||
export const PROFILE_TEMPLATES: Record<string, ProfileTemplate> = {
|
||||
acp: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-acp-app'],
|
||||
},
|
||||
web: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'],
|
||||
},
|
||||
headless: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-headless'],
|
||||
},
|
||||
sdk: {
|
||||
bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-sdk-app'],
|
||||
},
|
||||
'sdk-minimal': {
|
||||
bundles: ['@deepseek-ai/dsh-sdk-minimal'],
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Installation-owned bundle tuples that an earlier release wrote into a shipped profile; app-boot replaces an exact
|
||||
* match with the {@link PROFILE_TEMPLATES} entry of the same name and leaves every other list untouched.
|
||||
*/
|
||||
export const INSTALLATION_OWNED_PROFILE_TUPLES: Readonly<Record<string, readonly string[]>> = {
|
||||
headless: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app', '@deepseek-ai/dsh-headless'],
|
||||
}
|
||||
|
||||
/** Bundles an earlier release shipped and the installation no longer carries; app-boot removes them from profiles. */
|
||||
export const RETIRED_BUNDLES: ReadonlySet<string> = new Set([
|
||||
// The Web composition mounts Schedule itself
|
||||
// ([upgrade guide](../../../../docs/upgrade-guide/v0.2.0-rc.2/schedule-bundle-retired/guide.md)).
|
||||
'@deepseek-ai/dsh-experimental-schedule-bundle',
|
||||
])
|
||||
|
||||
/** The bundle list a `dsh plugin` init uses for a name with no shipped template. */
|
||||
export const DEFAULT_PROFILE_BUNDLES: readonly string[] = ['@deepseek-ai/dsh-base']
|
||||
|
||||
/**
|
||||
* The bundles the dsh installation ships for a person to switch on: each a
|
||||
* runtime dependency of the installation that declares `dsh.bundle.patch`,
|
||||
* an `icon`, and `./locale/*.json` display metadata, selected by no shipped
|
||||
* template, and offered switched off by the plugin manager except persistent
|
||||
* terminals, which have no page switch
|
||||
* ([rationale](../../../../.agents/notes/implemented/process/2026-09-15-shipped-optional-bundles.md),
|
||||
* [admission](../../../../.agents/notes/implemented/architecture/2026-09-21-experimental-capabilities-as-optional-bundles.md)).
|
||||
*/
|
||||
export const OPTIONAL_BUNDLES: readonly string[] = [
|
||||
'@deepseek-ai/dsh-cua-bundle',
|
||||
'@deepseek-ai/dsh-experimental-session-search',
|
||||
'@deepseek-ai/dsh-experimental-ralph-bundle',
|
||||
'@deepseek-ai/dsh-experimental-terminal-bundle',
|
||||
'@deepseek-ai/dsh-experimental-badge-skill-bundle',
|
||||
'@deepseek-ai/dsh-experimental-session-titles-bundle',
|
||||
'@deepseek-ai/dsh-experimental-agent-team-profile',
|
||||
'@deepseek-ai/dsh-experimental-voice-input-bundle',
|
||||
'@deepseek-ai/dsh-experimental-cot-translation-bundle',
|
||||
'@deepseek-ai/dsh-experimental-auto-review',
|
||||
'@deepseek-ai/dsh-experimental-inspector-profile',
|
||||
'@deepseek-ai/dsh-experimental-plugin-market-bundle',
|
||||
'@deepseek-ai/dsh-experimental-tool-worktree',
|
||||
]
|
||||
|
||||
/** Public DSH release members available through the ordinary on-demand bundle installer. */
|
||||
export const ON_DEMAND_BUNDLES: readonly string[] = [
|
||||
'@deepseek-ai/dsh-subagent-claude-code',
|
||||
'@deepseek-ai/dsh-subagent-codex',
|
||||
]
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
/** Generated offline Official bundle metadata. Run pnpm gen-official-bundle-catalog; do not edit. */
|
||||
|
||||
import type { OfficialBundleCatalogEntry } from './official-bundles.ts'
|
||||
import type { OfficialBundleCatalogEntry } from './index.ts'
|
||||
|
||||
/** Official on-demand entries, independent of installed packages and registry availability. */
|
||||
export const OFFICIAL_ON_DEMAND_CATALOG: readonly OfficialBundleCatalogEntry[] = [
|
||||
+9
-3
@@ -1,8 +1,14 @@
|
||||
/** Official bundles offered without installing their provider runtimes in the DSH distribution. */
|
||||
/**
|
||||
* Installation-owned lists of official DSH bundle packages, kept apart from the boot code that applies them.
|
||||
* @module @deepseek-ai/dsh-official-bundles
|
||||
*/
|
||||
|
||||
import type { PluginLocalizedMeta } from '@deepseek-ai/dsh-package-manifest'
|
||||
|
||||
export { ON_DEMAND_BUNDLES } from './official-bundle-packages.ts'
|
||||
export {
|
||||
DEFAULT_PROFILE_BUNDLES, INSTALLATION_OWNED_PROFILE_TUPLES, ON_DEMAND_BUNDLES, OPTIONAL_BUNDLES, PROFILE_TEMPLATES,
|
||||
RETIRED_BUNDLES, type ProfileTemplate,
|
||||
} from './bundles.ts'
|
||||
|
||||
/** Offline discovery metadata; installation state and the requested version belong to the running host. */
|
||||
export interface OfficialBundleCatalogEntry {
|
||||
@@ -12,4 +18,4 @@ export interface OfficialBundleCatalogEntry {
|
||||
readonly meta: Required<Pick<PluginLocalizedMeta, 'title' | 'description' | 'icon'>>
|
||||
}
|
||||
|
||||
export { OFFICIAL_ON_DEMAND_CATALOG } from './official-bundles.generated.ts'
|
||||
export { OFFICIAL_ON_DEMAND_CATALOG } from './catalog.generated.ts'
|
||||
+14
-2
@@ -1,7 +1,7 @@
|
||||
/** The offline catalog does not depend on installed provider packages or registry requests. */
|
||||
/** Shipped profile templates, and the offline catalog that does not depend on installed provider packages or registry requests. */
|
||||
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { OFFICIAL_ON_DEMAND_CATALOG, ON_DEMAND_BUNDLES } from '../src/official-bundles.ts'
|
||||
import { OFFICIAL_ON_DEMAND_CATALOG, ON_DEMAND_BUNDLES, PROFILE_TEMPLATES } from '../src/index.ts'
|
||||
|
||||
describe('Official on-demand catalog', () => {
|
||||
it('offers exactly the two native subagent integrations with offline localized metadata', () => {
|
||||
@@ -18,3 +18,15 @@ describe('Official on-demand catalog', () => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe('Shipped profile templates', () => {
|
||||
it('stack each mode bundle on base except the standalone minimal SDK', () => {
|
||||
expect(PROFILE_TEMPLATES).toEqual({
|
||||
acp: { bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-acp-app'] },
|
||||
web: { bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app'] },
|
||||
headless: { bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-headless'] },
|
||||
sdk: { bundles: ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-sdk-app'] },
|
||||
'sdk-minimal': { bundles: ['@deepseek-ai/dsh-sdk-minimal'] },
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"extends": "../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "src",
|
||||
"outDir": "lib/types"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../util/package-manifest"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -62,6 +62,7 @@
|
||||
"dependencies": {
|
||||
"@deepseek-ai/dsh-app-boot": "workspace:*",
|
||||
"@deepseek-ai/dsh-atomic-write": "workspace:*",
|
||||
"@deepseek-ai/dsh-official-bundles": "workspace:*",
|
||||
"@deepseek-ai/schemastery": "workspace:~",
|
||||
"execa": "^10.0.1",
|
||||
"semver": "^7.8.5",
|
||||
|
||||
@@ -19,11 +19,12 @@ import { readBundleDocument, readBundleImage, type BundleDetailOptions } from '.
|
||||
import { pluginEntryId, readPluginInventory } from '@deepseek-ai/dsh-host-plugin-inventory'
|
||||
import {
|
||||
readPluginMeta, readProfileManifest, resolveBundleDir, loadOverlayPatches, composeEntries,
|
||||
readProfilePatches, OPTIONAL_BUNDLES, bundlePatchPaths,
|
||||
readProfilePatches, bundlePatchPaths,
|
||||
evaluatePluginCompatibility, readProfileCompatibility, readProfileVersionExemptions,
|
||||
setProfileVersionExemption, PROFILE_COMPATIBILITY_FILENAME,
|
||||
OFFICIAL_ON_DEMAND_CATALOG, getDshRuntimeVersion, ResolutionRestartRequired,
|
||||
getDshRuntimeVersion, ResolutionRestartRequired,
|
||||
} from '@deepseek-ai/dsh-app-boot'
|
||||
import { OPTIONAL_BUNDLES, OFFICIAL_ON_DEMAND_CATALOG } from '@deepseek-ai/dsh-official-bundles'
|
||||
import type {} from '@deepseek-ai/dsh-hmr'
|
||||
import type { ProfileContext, ProfileManifest } from '@deepseek-ai/dsh-app-boot'
|
||||
import { bundleManifest, readProfileRegistry, registryArguments, runProfilePnpm, saveManifest, viewProfilePackage } from './operations.ts'
|
||||
|
||||
@@ -7,10 +7,11 @@ import { execa } from 'execa'
|
||||
import type { EntryOptions } from '@deepseek-ai/cordis-plugin-loader'
|
||||
import { withFileLock, writeFileAtomic } from '@deepseek-ai/dsh-atomic-write'
|
||||
import {
|
||||
DEFAULT_PROFILE_BUNDLES, bundlePatchPaths, initProfile, PROFILE_TEMPLATES, readProfileManifest,
|
||||
bundlePatchPaths, initProfile, readProfileManifest,
|
||||
resolveBundleDir, resolveProfileDir, loadOverlayPatches, composeEntries, readProfileVersionExemptions,
|
||||
evaluatePluginCompatibility, pluginCompatibilityWarning, type ProfileManifest,
|
||||
} from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES, DEFAULT_PROFILE_BUNDLES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { scrubbedParentEnv } from '@deepseek-ai/dsh-subprocess'
|
||||
import { parseInstallSpec } from './install-spec.ts'
|
||||
import { awaitTreeGone, leadsOwnGroup, treeAlive, type RunTree } from './run-tree.ts'
|
||||
|
||||
@@ -4,7 +4,8 @@ import { realpath } from 'node:fs/promises'
|
||||
import { join } from 'node:path'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { Service, type Context } from '@deepseek-ai/cordis'
|
||||
import { boot, getDshRuntimeVersion, initProfile, loadProfileDirectory, OFFICIAL_ON_DEMAND_CATALOG, readProfileManifest, readProfilePatches, type ProfileContext } from '@deepseek-ai/dsh-app-boot'
|
||||
import { boot, getDshRuntimeVersion, initProfile, loadProfileDirectory, readProfileManifest, readProfilePatches, type ProfileContext } from '@deepseek-ai/dsh-app-boot'
|
||||
import { OFFICIAL_ON_DEMAND_CATALOG } from '@deepseek-ai/dsh-official-bundles'
|
||||
import { remoteErrorOf } from '@deepseek-ai/dsh-typert-protocol'
|
||||
import { afterEach, expect, it, onTestFinished, vi } from 'vitest'
|
||||
import PluginManager, { type Config } from '../src/index.ts'
|
||||
|
||||
@@ -12,9 +12,10 @@ import type { Context } from '@deepseek-ai/cordis'
|
||||
import { afterAll, beforeAll, expect, it, onTestFinished, vi } from 'vitest'
|
||||
import {
|
||||
boot, composeEntries, initProfile, loadProfileDirectory, readProfilePatches, readProfileManifest,
|
||||
reconcileProfilePatches, OPTIONAL_BUNDLES, OFFICIAL_ON_DEMAND_CATALOG, PluginPackages, readPluginMeta, getDshRuntimeVersion,
|
||||
reconcileProfilePatches, PluginPackages, readPluginMeta, getDshRuntimeVersion,
|
||||
type ProfileContext, type RuntimeResolution,
|
||||
} from '@deepseek-ai/dsh-app-boot'
|
||||
import { OPTIONAL_BUNDLES, OFFICIAL_ON_DEMAND_CATALOG } from '@deepseek-ai/dsh-official-bundles'
|
||||
import PluginManager, { type Config, type PluginChange, type PluginInstallLogChunk, type PluginInstallProgress, type PluginInstallRequestId } from '../src/index.ts'
|
||||
import Hmr from '@deepseek-ai/dsh-hmr'
|
||||
import Timer from '@deepseek-ai/cordis-plugin-timer'
|
||||
|
||||
@@ -23,6 +23,9 @@
|
||||
{
|
||||
"path": "../app-boot"
|
||||
},
|
||||
{
|
||||
"path": "../official-bundles"
|
||||
},
|
||||
{
|
||||
"path": "../../util/atomic-write"
|
||||
},
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
en: 4e53164159b5ce41
|
||||
zh: 89582dc0294d0776
|
||||
/deepseek-ai-dsh-experimental-webworker-packer/use-this-package:
|
||||
en: 4b6067a6ffd4a33f
|
||||
zh: 8790e1a070a7a0f3
|
||||
en: 4d6954171c1237f2
|
||||
zh: 1a0b1d15583435dd
|
||||
/deepseek-ai-dsh-experimental-webworker-packer/model-experience:
|
||||
en: e16b355530dadc1c
|
||||
zh: 8488e03b253b7b33
|
||||
|
||||
@@ -29,12 +29,12 @@ The packer owns the internal `dsh.configTrees` declaration, its validation, and
|
||||
|
||||
The pack is a three-layer standard stack:
|
||||
|
||||
1. **Roster** — the shipped profile template's bundles and every bundle in app-boot's `OPTIONAL_BUNDLES`, each resolved from the CLI manifest as the launcher resolves it, plus every package their patch files name (insert lists and grouped rows included), plus the rows of every config tree the CLI declares in its `package.json` `dsh.configTrees`, materialized as a Node-style dependency closure. External peer edges never bind the worker; workspace peers stay on the chain. The CLI manifest itself enters the image alone at `node_modules/@deepseek-ai/dsh/package.json`, as the worker's bundle resolution anchor; the manifest records its name and the profile.
|
||||
1. **Roster** — the shipped profile template's bundles and every bundle in `OPTIONAL_BUNDLES` from [`dsh-official-bundles`](../../boot/official-bundles/README.md), each resolved from the CLI manifest as the launcher resolves it, plus every package their patch files name (insert lists and grouped rows included), plus the rows of every config tree the CLI declares in its `package.json` `dsh.configTrees`, materialized as a Node-style dependency closure. External peer edges never bind the worker; workspace peers stay on the chain. The CLI manifest itself enters the image alone at `node_modules/@deepseek-ai/dsh/package.json`, as the worker's bundle resolution anchor; the manifest records its name and the profile.
|
||||
2. **Publish view** — each workspace or vendored package contributes its built npm slice (`files` through picomatch) without source or workspace `dist/`. External packages retain published JavaScript under both `src/` and `dist/` because their `main` or `exports` may point there; only generic test, map, declaration, and archive exclusions apply.
|
||||
3. **Reachability sweep** — the runtime loader's own resolution walks from every non-wildcard workspace runtime export plus the worker assembly's seeds (`IMAGE_ENTRY_SEEDS`), lowering each reached module to the wrapper contract at pack time. Declaration-only condition trees do not seed the sweep; runtime requests for those exports still fail. The transform reports statically named imports, re-exports, and dynamic imports; calls through `require`; and module-scope direct calls of the form `createRequire(import.meta.url)('pkg')` through a named import from `node:module` or `module`, including an import alias. Page assets (`lib/client.js` behind `./client` exports) ship verbatim; an unresolvable request from our own code fails the pack, third-party ones are tolerated to fail loud at require time.
|
||||
4. **Lazy chunks** — every page chunk a page asset requests as a literal `require.async("./client.<name>.js")`, the only form the dynamic Client build emits, leaves the base image unless a `./client` export names it. Each becomes its own deterministic archive named `lazy/<sha256 of the archive>.tar.gz` beside the base image, and the manifest registers its path, size, and archive for the worker's lazy filesystem. A request for a chunk the package does not publish fails the pack.
|
||||
|
||||
`repository.ts` owns the repo-shaped inputs (workspace scan of `vendor/`, `packages/`, `native/system/packages/`, and `apps/`; the profile roster through app-boot's shipped templates, optional-bundle list, and bundle patch readers; the CLI manifest as the installation; the home patch, which sets the runtime's `PLATFORM_ENTRY_CONFIG` fields over each named row's config composed from the template's bundle layers); `pack.ts` owns none of them, so the same library packs a different tree by being called differently. The native scan makes the Landlock entry package an ordinary published-view dependency while its executable remains a Worker platform implementation. The CLI is `dsh-pack-vfs-image --out <file> [--profile web]`; it writes the lazy archives beside the base image, and `apps/web`'s `build:preview` runs it after the preview shell build.
|
||||
`repository.ts` owns the repo-shaped inputs (workspace scan of `vendor/`, `packages/`, `native/system/packages/`, and `apps/`; the profile roster through the shipped templates and optional-bundle list of `dsh-official-bundles` and app-boot's bundle patch readers; the CLI manifest as the installation; the home patch, which sets the runtime's `PLATFORM_ENTRY_CONFIG` fields over each named row's config composed from the template's bundle layers); `pack.ts` owns none of them, so the same library packs a different tree by being called differently. The native scan makes the Landlock entry package an ordinary published-view dependency while its executable remains a Worker platform implementation. The CLI is `dsh-pack-vfs-image --out <file> [--profile web]`; it writes the lazy archives beside the base image, and `apps/web`'s `build:preview` runs it after the preview shell build.
|
||||
|
||||
The repository adapter also declares the preview-only fixture trees under `webworker-runtime/tests/fixtures/`. The CLI packs each named fixture into a separate deterministic overlay archive plus a browser-readable manifest. Overlay files bypass npm publish-view and module-reachability exclusions, so dot directories and example source files remain intact; their mounts are limited to `home/` and `workspace/`. `packVfsOverlay` treats all files as opaque bytes.
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@ VFS 镜像打包器:把一份随附 profile 的 bundle 和安装提供的 opti
|
||||
|
||||
打包是三层标准栈:
|
||||
|
||||
1. **Roster**——随附 profile 模板的 bundle 和 app-boot `OPTIONAL_BUNDLES` 中的每个 bundle(各自按启动器的方式从 CLI manifest 解析),加上它们 patch 文件点名的每个包(含 insert 列表与分组行),再加上 CLI(命令行界面)在 `package.json` `dsh.configTrees` 里声明的每棵配置树的行,按 Node 式依赖闭包物化。外部 peer 边绝不会绑定到 worker,workspace peer 保留在链上。CLI manifest 本身单独进入镜像,位于 `node_modules/@deepseek-ai/dsh/package.json`,作为 worker 解析 bundle 的锚点;manifest 记录它的名称和 profile。
|
||||
1. **Roster**——随附 profile 模板的 bundle 和 [`dsh-official-bundles`](../../boot/official-bundles/README.zh.md) `OPTIONAL_BUNDLES` 中的每个 bundle(各自按启动器的方式从 CLI manifest 解析),加上它们 patch 文件点名的每个包(含 insert 列表与分组行),再加上 CLI(命令行界面)在 `package.json` `dsh.configTrees` 里声明的每棵配置树的行,按 Node 式依赖闭包物化。外部 peer 边绝不会绑定到 worker,workspace peer 保留在链上。CLI manifest 本身单独进入镜像,位于 `node_modules/@deepseek-ai/dsh/package.json`,作为 worker 解析 bundle 的锚点;manifest 记录它的名称和 profile。
|
||||
2. **发布视图**——每个 workspace 或 vendored 包贡献其构建后的 npm 切片(`files` 走 picomatch),不带源码和 workspace `dist/`。外部包的 `main` 或 `exports` 可能指向 `src/` 或 `dist/`,因此两处发布 JavaScript 都会保留,只应用通用的测试、map、声明与归档排除规则。
|
||||
3. **可达性 sweep**——用运行时加载器自己的解析, 从全部不含通配符的 workspace 运行时导出加 worker 装配种子 (`IMAGE_ENTRY_SEEDS`) 出发, 打包时把每个可达模块转换为符合包装层约定的形式. 仅含类型声明的条件树不作为扫描入口; 运行时代码请求这些导出仍会失败. 该转换会报告名称可静态确定的 import、re-export 与动态 import、经 `require` 发起的调用, 以及通过 `node:module` 或 `module` 具名导入 (含导入别名) 在模块作用域直接发起的 `createRequire(import.meta.url)('pkg')` 调用. 页面资产 (`./client` 导出背后的 `lib/client.js`) 原样直发; 自家代码的不可解析请求会让打包失败, 第三方不可解析请求则允许延后到 require 时明确失败.
|
||||
4. **懒加载 chunk**——页面资产以字面量 `require.async("./client.<name>.js")`(动态 Client 构建产出的唯一形式)请求的每个页面 chunk,除非被 `./client` 导出点名,否则移出基础镜像。每个 chunk 成为基础镜像旁的一个独立确定性归档,命名为 `lazy/<归档的 sha256>.tar.gz`;manifest 为 worker 的懒加载文件系统登记其路径、大小和归档。请求包未发布的 chunk 会让打包失败。
|
||||
|
||||
`repository.ts` 拥有仓库形态输入(`vendor/`、`packages/`、`native/system/packages/` 与 `apps/` 的 workspace 扫描;经 app-boot 的随附模板、optional bundle 列表和 bundle patch 读取器得出 profile roster;以 CLI manifest 作为安装清单;home patch 在模板各 bundle 层合成出的行配置之上设置运行时 `PLATFORM_ENTRY_CONFIG` 字段);`pack.ts` 一概不拥有,同一库换参即可打另一棵树。Native 扫描使 Landlock 入口包成为普通发布视图依赖,其可执行文件仍由 Worker 平台实现。CLI 为 `dsh-pack-vfs-image --out <file> [--profile web]`;它把懒加载归档写在基础镜像旁,`apps/web` 的 `build:preview` 在预览壳构建后运行它。
|
||||
`repository.ts` 拥有仓库形态输入(`vendor/`、`packages/`、`native/system/packages/` 与 `apps/` 的 workspace 扫描;经 `dsh-official-bundles` 的随附模板、optional bundle 列表和 app-boot 的 bundle patch 读取器得出 profile roster;以 CLI manifest 作为安装清单;home patch 在模板各 bundle 层合成出的行配置之上设置运行时 `PLATFORM_ENTRY_CONFIG` 字段);`pack.ts` 一概不拥有,同一库换参即可打另一棵树。Native 扫描使 Landlock 入口包成为普通发布视图依赖,其可执行文件仍由 Worker 平台实现。CLI 为 `dsh-pack-vfs-image --out <file> [--profile web]`;它把懒加载归档写在基础镜像旁,`apps/web` 的 `build:preview` 在预览壳构建后运行它。
|
||||
|
||||
仓库适配器还声明 `webworker-runtime/tests/fixtures/` 下仅用于 preview 的 fixture(测试前置数据) tree。CLI 会把每套具名 fixture 打成一份独立的确定性 overlay 归档,并写出浏览器可读的 manifest(元数据清单)。Overlay 文件绕过 npm 发布视图和模块可达性排除规则,因此点目录与示例源码会完整保留;其挂载位置仅限 `home/` 与 `workspace/`。`packVfsOverlay` 将所有文件视为不透明字节。
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
"@deepseek-ai/cordis-plugin-include": "workspace:~",
|
||||
"@deepseek-ai/dsh-app-boot": "workspace:*",
|
||||
"@deepseek-ai/dsh-experimental-webworker-runtime": "workspace:*",
|
||||
"@deepseek-ai/dsh-official-bundles": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-format": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-format-catalog": "workspace:*",
|
||||
"@deepseek-ai/dsh-session-format-v3-to-v4": "workspace:*",
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
import { existsSync, readFileSync, readdirSync } from 'node:fs'
|
||||
import { join, relative } from 'node:path'
|
||||
import {
|
||||
bundlePatchPaths, composeEntries, loadOverlayPatches, OPTIONAL_BUNDLES, PROFILE_TEMPLATES, resolveBundleDir,
|
||||
bundlePatchPaths, composeEntries, loadOverlayPatches, resolveBundleDir,
|
||||
} from '@deepseek-ai/dsh-app-boot'
|
||||
import { OPTIONAL_BUNDLES, PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include'
|
||||
import { PLATFORM_ENTRY_CONFIG } from '@deepseek-ai/dsh-experimental-webworker-runtime'
|
||||
import { collectModuleNames, packVfsImage, type ConfigTree, type ImageInstallation, type ImageTree, type PackResult } from './pack.ts'
|
||||
|
||||
@@ -9,7 +9,7 @@ import { tmpdir } from 'node:os'
|
||||
import { join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { describe, expect, it, type TestContext } from 'vitest'
|
||||
import { OPTIONAL_BUNDLES, PROFILE_TEMPLATES } from '@deepseek-ai/dsh-app-boot'
|
||||
import { OPTIONAL_BUNDLES, PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import yaml from 'js-yaml'
|
||||
import { entryListSchema } from '@deepseek-ai/cordis-plugin-include'
|
||||
import { HOME_PATCH_PATH, MANIFEST_PATH, packVfsImage } from '../src/pack.ts'
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
{
|
||||
"path": "../../boot/app-boot"
|
||||
},
|
||||
{
|
||||
"path": "../../boot/official-bundles"
|
||||
},
|
||||
{
|
||||
"path": "../webworker-runtime"
|
||||
},
|
||||
|
||||
@@ -23,7 +23,10 @@ import { exactPackageSpecifier, parseDshClient } from '@deepseek-ai/dsh-client-m
|
||||
import * as yaml from 'js-yaml'
|
||||
import { ClientRoster, type ClientRosterRow } from './roster.ts'
|
||||
|
||||
/** The `web` profile's bundle layers, in the order `dsh --profile web` applies them (app-boot `PROFILE_TEMPLATES.web`). */
|
||||
/**
|
||||
* The `web` profile's bundle layers, in the order `dsh --profile web` applies them
|
||||
* (`PROFILE_TEMPLATES.web` in `@deepseek-ai/dsh-official-bundles`).
|
||||
*/
|
||||
export const WEB_PROFILE_BUNDLES: readonly string[] = ['@deepseek-ai/dsh-base', '@deepseek-ai/dsh-web-app']
|
||||
|
||||
interface PackageManifest {
|
||||
|
||||
Generated
+25
@@ -393,6 +393,9 @@ importers:
|
||||
'@deepseek-ai/dsh-mcp-resources':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/mcp/mcp-resources
|
||||
'@deepseek-ai/dsh-official-bundles':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/boot/official-bundles
|
||||
'@deepseek-ai/dsh-persona':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/preset/persona
|
||||
@@ -737,6 +740,9 @@ importers:
|
||||
'@deepseek-ai/dsh-home-paths':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/util/home-paths
|
||||
'@deepseek-ai/dsh-official-bundles':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/boot/official-bundles
|
||||
'@deepseek-ai/dsh-util-file-drag':
|
||||
specifier: workspace:*
|
||||
version: link:../../packages/util/file-drag
|
||||
@@ -1954,6 +1960,9 @@ importers:
|
||||
'@deepseek-ai/dsh-atomic-write':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/atomic-write
|
||||
'@deepseek-ai/dsh-official-bundles':
|
||||
specifier: workspace:*
|
||||
version: link:../official-bundles
|
||||
'@deepseek-ai/dsh-package-manifest':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/package-manifest
|
||||
@@ -2105,6 +2114,16 @@ importers:
|
||||
specifier: ^0.28.2
|
||||
version: 0.28.2
|
||||
|
||||
packages/boot/official-bundles:
|
||||
dependencies:
|
||||
'@deepseek-ai/dsh-package-manifest':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/package-manifest
|
||||
devDependencies:
|
||||
'@deepseek-ai/cordis':
|
||||
specifier: workspace:~
|
||||
version: link:../../../vendor/cordis
|
||||
|
||||
packages/boot/plugin-manager:
|
||||
dependencies:
|
||||
'@deepseek-ai/dsh-app-boot':
|
||||
@@ -2113,6 +2132,9 @@ importers:
|
||||
'@deepseek-ai/dsh-atomic-write':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/atomic-write
|
||||
'@deepseek-ai/dsh-official-bundles':
|
||||
specifier: workspace:*
|
||||
version: link:../official-bundles
|
||||
'@deepseek-ai/dsh-plugin-detail':
|
||||
specifier: workspace:*
|
||||
version: link:../../util/plugin-detail
|
||||
@@ -10374,6 +10396,9 @@ importers:
|
||||
'@deepseek-ai/dsh-experimental-webworker-runtime':
|
||||
specifier: workspace:*
|
||||
version: link:../webworker-runtime
|
||||
'@deepseek-ai/dsh-official-bundles':
|
||||
specifier: workspace:*
|
||||
version: link:../../boot/official-bundles
|
||||
'@deepseek-ai/dsh-session-format':
|
||||
specifier: workspace:*
|
||||
version: link:../../session/session-format
|
||||
|
||||
@@ -20,7 +20,8 @@ import {
|
||||
import { hasTypertRemoteNavigation, isForbiddenPublicationFile } from './publication-payload.ts'
|
||||
import type { DshBundleManifest } from '../packages/util/package-manifest/src/types.ts'
|
||||
import { detailPath } from '../packages/util/plugin-detail/src/document.ts'
|
||||
import { OPTIONAL_BUNDLES, bundlePatchFiles } from '../packages/boot/app-boot/src/profile.ts'
|
||||
import { bundlePatchFiles } from '../packages/boot/app-boot/src/profile.ts'
|
||||
import { OPTIONAL_BUNDLES } from '../packages/boot/official-bundles/src/bundles.ts'
|
||||
import {
|
||||
PACKAGE_ASSET_EXPORT,
|
||||
PACKAGE_ASSET_EXPORT_TARGET,
|
||||
|
||||
@@ -59,6 +59,7 @@ const PACKAGE_LIBRARIES: Readonly<Record<string, string>> = {
|
||||
'packages/experimental/browser-use-runtime': 'Provider-owned browser resource management and MCP integration helpers; no plugin entry.',
|
||||
'packages/boot/app-boot': 'Boot library the app bins import; plain helper exports.',
|
||||
'packages/boot/cmdline': 'Command-line library the app bins import; plain module exports.',
|
||||
'packages/boot/official-bundles': 'Bundle-list data library the launcher and plugin manager import; plain constant exports.',
|
||||
'packages/client/store': 'Browser-side state primitives; plain function/type exports.',
|
||||
'packages/client/ui-primitives': 'Browser-side UI component library; plain component exports.',
|
||||
'packages/client/ui-slots': 'Browser-side slot-map declarations; plain type exports.',
|
||||
|
||||
@@ -5,7 +5,7 @@ import { existsSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { promisify } from 'node:util'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-app-boot'
|
||||
import { PROFILE_TEMPLATES } from '@deepseek-ai/dsh-official-bundles'
|
||||
import {
|
||||
computeTranslationPairingRecord,
|
||||
renderTranslationPairingRecord,
|
||||
|
||||
@@ -4,11 +4,11 @@ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, uti
|
||||
import { tmpdir } from 'node:os'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { afterEach, describe, expect, it } from 'vitest'
|
||||
import { ON_DEMAND_BUNDLES } from '../packages/boot/app-boot/src/official-bundles.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../packages/boot/official-bundles/src/index.ts'
|
||||
import { generateOfficialBundleCatalog, renderOfficialBundleCatalog, syncOfficialBundleCatalog } from './gen-official-bundle-catalog.ts'
|
||||
|
||||
const roots: string[] = []
|
||||
const output = 'packages/boot/app-boot/src/official-bundles.generated.ts'
|
||||
const output = 'packages/boot/official-bundles/src/catalog.generated.ts'
|
||||
|
||||
function write(root: string, path: string, content: unknown): void {
|
||||
mkdirSync(dirname(join(root, path)), { recursive: true })
|
||||
|
||||
@@ -5,11 +5,11 @@ import { resolve } from 'node:path'
|
||||
import { fileURLToPath, pathToFileURL } from 'node:url'
|
||||
import ts from 'typescript'
|
||||
import type { LocalizedText } from '../packages/util/package-manifest/src/types.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../packages/boot/app-boot/src/official-bundle-packages.ts'
|
||||
import type { OfficialBundleCatalogEntry } from '../packages/boot/app-boot/src/official-bundles.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../packages/boot/official-bundles/src/bundles.ts'
|
||||
import type { OfficialBundleCatalogEntry } from '../packages/boot/official-bundles/src/index.ts'
|
||||
import { readPluginMeta, resolvePluginResource } from '../packages/boot/app-boot/src/package-meta.ts'
|
||||
|
||||
const OUTPUT = 'packages/boot/app-boot/src/official-bundles.generated.ts'
|
||||
const OUTPUT = 'packages/boot/official-bundles/src/catalog.generated.ts'
|
||||
|
||||
/**
|
||||
* Read complete metadata without importing or activating any provider code.
|
||||
@@ -76,11 +76,11 @@ export function generateOfficialBundleCatalog(root: string, names: readonly stri
|
||||
/**
|
||||
* Render a source-plane catalog with no package imports or pinned runtime version.
|
||||
* @param entries - Validated metadata in catalog order.
|
||||
* @returns Deterministic TypeScript source for app-boot's generated module.
|
||||
* @returns Deterministic TypeScript source for the official-bundles generated module.
|
||||
*/
|
||||
export function renderOfficialBundleCatalog(entries: readonly OfficialBundleCatalogEntry[]): string {
|
||||
return '/** Generated offline Official bundle metadata. Run pnpm gen-official-bundle-catalog; do not edit. */\n\n'
|
||||
+ "import type { OfficialBundleCatalogEntry } from './official-bundles.ts'\n\n"
|
||||
+ "import type { OfficialBundleCatalogEntry } from './index.ts'\n\n"
|
||||
+ '/** Official on-demand entries, independent of installed packages and registry availability. */\n'
|
||||
+ 'export const OFFICIAL_ON_DEMAND_CATALOG: readonly OfficialBundleCatalogEntry[] = [\n'
|
||||
+ entries.map(entry => ' {\n'
|
||||
|
||||
@@ -8,7 +8,7 @@ import { join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { execa } from 'execa'
|
||||
import { describe, expect, it, onTestFinished } from 'vitest'
|
||||
import { ON_DEMAND_BUNDLES } from '../packages/boot/app-boot/src/official-bundle-packages.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../packages/boot/official-bundles/src/bundles.ts'
|
||||
import { generateOfficialBundleCatalog } from './gen-official-bundle-catalog.ts'
|
||||
import {
|
||||
createRegistryManifest,
|
||||
|
||||
@@ -8,7 +8,8 @@ import { describe, expect, it, onTestFinished } from 'vitest'
|
||||
import type { EntryOptions } from '@deepseek-ai/cordis-plugin-loader'
|
||||
import { loadOverlayPatches } from '../packages/boot/app-boot/src/index.ts'
|
||||
import { readPluginMeta } from '../packages/boot/app-boot/src/package-meta.ts'
|
||||
import { OPTIONAL_BUNDLES, PROFILE_TEMPLATES, bundlePatchPaths, composeEntries, initProfile, readProfileManifest } from '../packages/boot/app-boot/src/profile.ts'
|
||||
import { bundlePatchPaths, composeEntries, initProfile, readProfileManifest } from '../packages/boot/app-boot/src/profile.ts'
|
||||
import { OPTIONAL_BUNDLES, PROFILE_TEMPLATES } from '../packages/boot/official-bundles/src/bundles.ts'
|
||||
import type { DshBundleManifest } from '../packages/util/package-manifest/src/types.ts'
|
||||
import { createPluginProfile } from '../apps/desktop/src/project-manager.ts'
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { tmpdir } from 'node:os'
|
||||
import { dirname, join, resolve } from 'node:path'
|
||||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
import { officialClientBuildEnvironment, writeClientBuildRecord } from '../client-build-environment.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../../packages/boot/app-boot/src/official-bundles.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../../packages/boot/official-bundles/src/bundles.ts'
|
||||
import { releaseFamily, type ReleaseMember } from './families.ts'
|
||||
import { compareVersions, nextVendorVersion, planShared, reachesPayload } from './bump.ts'
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
readClientBuildRecord,
|
||||
} from '../client-build-environment.ts'
|
||||
import { validateTarballPayload } from '../publication-payload.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../../packages/boot/app-boot/src/official-bundle-packages.ts'
|
||||
import { ON_DEMAND_BUNDLES } from '../../packages/boot/official-bundles/src/bundles.ts'
|
||||
|
||||
/**
|
||||
* Dependency sections a consumer must publish after, because npm resolves them
|
||||
|
||||
@@ -4,7 +4,7 @@ import { existsSync, readFileSync, realpathSync } from 'node:fs'
|
||||
import { createRequire } from 'node:module'
|
||||
import { join } from 'node:path'
|
||||
import { hasExperimentalPackageReference } from '../experimental-package-policy.ts'
|
||||
import { OPTIONAL_BUNDLES } from '../../packages/boot/app-boot/src/profile.ts'
|
||||
import { OPTIONAL_BUNDLES } from '../../packages/boot/official-bundles/src/bundles.ts'
|
||||
|
||||
interface InstalledManifest {
|
||||
name: string
|
||||
|
||||
@@ -13,7 +13,7 @@ const roots: string[] = []
|
||||
const experimental = '@deepseek-ai/dsh-experimental-prototype'
|
||||
const core = '@deepseek-ai/dsh-core'
|
||||
const base = '@deepseek-ai/dsh-base'
|
||||
const profile = 'packages/boot/app-boot/src/profile.ts'
|
||||
const profile = 'packages/boot/official-bundles/src/bundles.ts'
|
||||
const preset = 'packages/bundle/web-app/presets/standard.patch.yml'
|
||||
const patch = 'packages/bundle/base/cordis.patch.yml'
|
||||
|
||||
@@ -488,6 +488,6 @@ describe('default product isolation', () => {
|
||||
])('rejects absent, empty, or uninspectable default profile definitions', (source) => {
|
||||
const root = fixture()
|
||||
write(root, profile, source)
|
||||
expect(() => verifyDefaultProductIsolation(root)).toThrow('profile')
|
||||
expect(() => verifyDefaultProductIsolation(root)).toThrow(`${profile}: `)
|
||||
})
|
||||
})
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
import { isExperimentalPackageName } from './experimental-package-policy.ts'
|
||||
// The independently published entry package owns platform-engine dependencies.
|
||||
const EXTERNAL_KIT_PACKAGES = new Set(['@deepseek-ai/libreoffice-kit'])
|
||||
const PROFILE_SOURCE = 'packages/boot/app-boot/src/profile.ts'
|
||||
const PROFILE_SOURCE = 'packages/boot/official-bundles/src/bundles.ts'
|
||||
const PRESET_PATTERN = 'packages/bundle/web-app/presets/*.patch.yml'
|
||||
const RUNTIME_SECTIONS = ['dependencies', 'optionalDependencies', 'peerDependencies'] as const
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ const NO_MODEL_EXPERIENCE_SECTION: Readonly<Record<string, string>> = {
|
||||
'packages/util/launch-environment': 'The package only resolves host environment values; model-facing consumers own any rendered use.',
|
||||
'packages/util/workspace-path': 'The package only formats Workspace paths for browser UI; it never constructs model input.',
|
||||
'packages/util/values': 'The package only validates, snapshots, compares, freezes, or rejects caller-owned values; consumers own every model-facing use.',
|
||||
'packages/boot/official-bundles': 'The package only lists bundle package names and their display metadata; the loaded plugin tree owns model context.',
|
||||
'packages/util/code-language': 'The package only maps a filename suffix to a syntax-highlighting language id; the read consumer owns the persisted hint.',
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,7 @@ const base = '@deepseek-ai/dsh-base'
|
||||
const core = '@deepseek-ai/dsh-core'
|
||||
const candidate = '@deepseek-ai/dsh-candidate'
|
||||
const candidateDir = 'packages/core/candidate'
|
||||
const profile = 'packages/boot/app-boot/src/profile.ts'
|
||||
const catalog = 'packages/boot/app-boot/src/official-bundle-packages.ts'
|
||||
const profile = 'packages/boot/official-bundles/src/bundles.ts'
|
||||
const patch = 'packages/bundle/base/cordis.patch.yml'
|
||||
|
||||
function pkg(root: string, directory: string, name: string, fields: Record<string, unknown> = {}): void {
|
||||
@@ -29,10 +28,10 @@ function pkg(root: string, directory: string, name: string, fields: Record<strin
|
||||
}
|
||||
|
||||
function profiles(root: string, optional: string[] = [], onDemand: string[] = []): void {
|
||||
write(root, catalog, `export const ON_DEMAND_BUNDLES = ${JSON.stringify(onDemand)}\n`)
|
||||
write(root, profile, `export const PROFILE_TEMPLATES = ${JSON.stringify(Object.fromEntries(
|
||||
['web', 'acp', 'headless', 'sdk', 'sdk-minimal'].map(name => [name, { bundles: [base] }]),
|
||||
))}\nexport const DEFAULT_PROFILE_BUNDLES = ['${base}']\nexport const OPTIONAL_BUNDLES = ${JSON.stringify(optional)}\n`)
|
||||
))}\nexport const DEFAULT_PROFILE_BUNDLES = ['${base}']\nexport const OPTIONAL_BUNDLES = ${JSON.stringify(optional)}\n`
|
||||
+ `export const ON_DEMAND_BUNDLES = ${JSON.stringify(onDemand)}\n`)
|
||||
}
|
||||
|
||||
function fixture(): string {
|
||||
@@ -142,7 +141,7 @@ describe('product package use', () => {
|
||||
const root = fixture()
|
||||
pkg(root, candidateDir, candidate)
|
||||
const children = [{ name: candidate }]
|
||||
if (!initial) write(root, 'packages/boot/app-boot/src/included.yml', children)
|
||||
if (!initial) write(root, 'packages/boot/official-bundles/src/included.yml', children)
|
||||
write(root, patch, [{ insert: [{ name: core }, {
|
||||
name: 'cordis:include', disabled: true, config: { path: './included.yml', ...(initial ? { initial: children } : {}) },
|
||||
}] }])
|
||||
@@ -162,12 +161,12 @@ describe('product package use', () => {
|
||||
it('applies Include patches before collecting runtime mounts and uses files ahead of initial entries', () => {
|
||||
const root = fixture()
|
||||
pkg(root, candidateDir, candidate)
|
||||
write(root, 'packages/boot/app-boot/src/included.yml', [{ id: 'child', name: candidate }])
|
||||
write(root, 'packages/boot/official-bundles/src/included.yml', [{ id: 'child', name: candidate }])
|
||||
write(root, patch, [{ insert: [{ name: core }, { name: 'cordis:include', config: {
|
||||
path: './included.yml', initial: [{ name: candidate }], patches: [{ id: 'child', disabled: true }],
|
||||
} }] }])
|
||||
expect(failures(root)).toContain('no product runtime use')
|
||||
write(root, 'packages/boot/app-boot/src/included.yml', [])
|
||||
write(root, 'packages/boot/official-bundles/src/included.yml', [])
|
||||
expect(failures(root)).toContain('no product runtime use')
|
||||
})
|
||||
|
||||
|
||||
@@ -14,8 +14,7 @@ import { isAgentPresetEntry, isCordisGroupEntry, loadCordisYaml } from './cordis
|
||||
import { PRODUCT_PACKAGE_POLICY, type ProductPackagePolicy } from './product-package-policy.ts'
|
||||
import { collectRuntimeLocalSourceSpecifiers, collectRuntimeSourceSpecifiers } from './verify-client-packages.ts'
|
||||
|
||||
const PROFILE_SOURCE = 'packages/boot/app-boot/src/profile.ts'
|
||||
const ON_DEMAND_SOURCE = 'packages/boot/app-boot/src/official-bundle-packages.ts'
|
||||
const PROFILE_SOURCE = 'packages/boot/official-bundles/src/bundles.ts'
|
||||
const PROFILES = ['acp', 'web', 'headless', 'sdk', 'sdk-minimal']
|
||||
const PICKER_SOURCE = 'packages/host/directory-picker-auto/src/index.ts'
|
||||
const DYNAMIC_MOUNTS: Readonly<Record<string, readonly string[]>> = {
|
||||
@@ -188,11 +187,9 @@ export function verifyProductUse(
|
||||
const profileFile = ts.createSourceFile(profilePath, readFileSync(profilePath, 'utf8'), ts.ScriptTarget.Latest, true)
|
||||
const templates = literalDeclaration(profileFile, 'PROFILE_TEMPLATES')
|
||||
const fallback = stringList(literalDeclaration(profileFile, 'DEFAULT_PROFILE_BUNDLES'), PROFILE_SOURCE)
|
||||
const catalogPath = resolve(root, ON_DEMAND_SOURCE)
|
||||
const catalogFile = ts.createSourceFile(catalogPath, readFileSync(catalogPath, 'utf8'), ts.ScriptTarget.Latest, true)
|
||||
const optionals = [
|
||||
...stringList(literalDeclaration(profileFile, 'OPTIONAL_BUNDLES'), PROFILE_SOURCE),
|
||||
...stringList(literalDeclaration(catalogFile, 'ON_DEMAND_BUNDLES'), ON_DEMAND_SOURCE),
|
||||
...stringList(literalDeclaration(profileFile, 'ON_DEMAND_BUNDLES'), PROFILE_SOURCE),
|
||||
]
|
||||
if (!isRecord(templates)) throw new Error(`${PROFILE_SOURCE}: PROFILE_TEMPLATES must be a literal object`)
|
||||
for (const name of PROFILES) if (!isRecord(templates[name])) failures.push(`${PROFILE_SOURCE}: missing shipped ${name} profile`)
|
||||
|
||||
@@ -452,6 +452,7 @@
|
||||
"@deepseek-ai/dsh-message-quotes": ["./packages/session/message-quotes/src"],
|
||||
"@deepseek-ai/dsh-native-command": ["./packages/util/native-command/src"],
|
||||
"@deepseek-ai/dsh-office-to-pdf": ["./packages/document/office-to-pdf/src"],
|
||||
"@deepseek-ai/dsh-official-bundles": ["./packages/boot/official-bundles/src"],
|
||||
"@deepseek-ai/dsh-output-retention": ["./packages/util/output-retention/src"],
|
||||
"@deepseek-ai/dsh-package-manifest": ["./packages/util/package-manifest/src"],
|
||||
"@deepseek-ai/dsh-permission-presets": ["./packages/interaction/permission-presets/src"],
|
||||
|
||||
@@ -488,6 +488,7 @@
|
||||
{ "path": "./packages/bundle/sdk-app" },
|
||||
{ "path": "./packages/bundle/sdk-minimal" },
|
||||
{ "path": "./packages/bundle/web-app" },
|
||||
{ "path": "./packages/boot/official-bundles" },
|
||||
{ "path": "./packages/boot/app-boot" },
|
||||
{ "path": "./packages/boot/cmdline" },
|
||||
{ "path": "./packages/sdk/server" },
|
||||
|
||||
Reference in new issue
Block a user