From c8b10a16be96385fd563838aa1f91fbce0377785 Mon Sep 17 00:00:00 2001 From: turtle1999 Date: Thu, 24 Sep 2026 18:32:48 +0800 Subject: [PATCH 1/3] fix(boot): report skipped profile bundles once per start loadProfileDirectory printed each skipped bundle on every call, and startup, runtime resolution, the config editor, the plugin manager, and HMR all load the profile, so one incompatible bundle printed the same warning six times at startup and again on each Web page load. Loading now returns the skips in Profile.skippedBundles, and the CLI and Desktop launchers print them once per start with reportSkippedBundles. --- apps/cli/src/profile-boot.ts | 2 ++ apps/cli/tests/resolved-profile-boot.spec.ts | 4 +-- apps/cli/tests/web-agent-presets.e2e.ts | 2 +- apps/desktop-host/src/index.ts | 3 +- apps/web/tests/scaffold.ts | 2 +- packages/boot/app-boot/README.i18n.yaml | 4 +-- packages/boot/app-boot/README.md | 4 +-- packages/boot/app-boot/README.zh.md | 4 +-- packages/boot/app-boot/src/index.ts | 2 ++ packages/boot/app-boot/src/profile.ts | 31 ++++++++++++++--- .../boot/app-boot/tests/config-schema.spec.ts | 2 +- .../tests/linked-resolution-matrix.spec.ts | 2 +- .../app-boot/tests/profile-resolution.spec.ts | 2 +- packages/boot/app-boot/tests/profile.spec.ts | 34 +++++++++---------- 14 files changed, 62 insertions(+), 36 deletions(-) diff --git a/apps/cli/src/profile-boot.ts b/apps/cli/src/profile-boot.ts index 9e40d01f70..b795f627ca 100644 --- a/apps/cli/src/profile-boot.ts +++ b/apps/cli/src/profile-boot.ts @@ -23,6 +23,7 @@ import { installFailLoud, loadOverlayPatches, loadProfile, + reportSkippedBundles, PluginPackages, PROFILE_PATCH_FILENAME, PROFILE_TEMPLATES, @@ -166,6 +167,7 @@ export function initializeProfileFromDefault( export function prepareProfile(name: string, userLayer = true, fromDefaultProfile?: string): Profile { if (fromDefaultProfile !== undefined) initializeProfileFromDefault(name, fromDefaultProfile) const profile = loadProfile(NAME, name, INSTALL_ANCHOR, undefined, { userLayer }) + reportSkippedBundles(NAME, profile) writeFileSync(join(profile.dir, PROFILE_ROOT_FILENAME), PROFILE_ROOT_CONFIG) return profile } diff --git a/apps/cli/tests/resolved-profile-boot.spec.ts b/apps/cli/tests/resolved-profile-boot.spec.ts index 0df34251c6..6e7bc52060 100644 --- a/apps/cli/tests/resolved-profile-boot.spec.ts +++ b/apps/cli/tests/resolved-profile-boot.spec.ts @@ -60,7 +60,7 @@ describe('runProfile with an application-owned profile', () => { throw failure }) if (stage === 'composition') vi.mocked(createRuntimeResolution).mockRejectedValueOnce(failure) - const profile: Profile = { + const profile: Profile = { skippedBundles: [], name: 'desktop', dir: home, patchPath: join(home, 'cordis.patch.yml'), patches: [], layers: [], } @@ -121,7 +121,7 @@ describe('runProfile with an application-owned profile', () => { writeFileSync(profilePatch, '- id: target\n config: { profile: true, priority: profile }\n') writeFileSync(overlay, '- id: target\n config: { overlay: true, priority: overlay }\n') writeFileSync(join(home, 'cordis.yml'), '- id: stale\n') - const profile: Profile = { + const profile: Profile = { skippedBundles: [], name: 'desktop', dir: home, patchPath: profilePatch, patches: [{ id: 'target', config: { profile: true, priority: 'profile' } }], layers: [{ diff --git a/apps/cli/tests/web-agent-presets.e2e.ts b/apps/cli/tests/web-agent-presets.e2e.ts index d4dc6653f2..00b6462177 100644 --- a/apps/cli/tests/web-agent-presets.e2e.ts +++ b/apps/cli/tests/web-agent-presets.e2e.ts @@ -133,7 +133,7 @@ async function bootWeb( await mkdir(dirname(link), { recursive: true }) await symlink(packageDir, link, 'junction') } - let profile: Profile = { + let profile: Profile = { skippedBundles: [], name: 'spec', dir: profileDir, layers: [], diff --git a/apps/desktop-host/src/index.ts b/apps/desktop-host/src/index.ts index ecbff835ce..b7df4941dc 100644 --- a/apps/desktop-host/src/index.ts +++ b/apps/desktop-host/src/index.ts @@ -2,7 +2,7 @@ import { delimiter, join } from 'node:path' import { inspect } from 'node:util' -import { loadLayeredEnv, loadProfileDirectory } from '@deepseek-ai/dsh-app-boot' +import { loadLayeredEnv, loadProfileDirectory, reportSkippedBundles } from '@deepseek-ai/dsh-app-boot' import { runProfile } from '@deepseek-ai/dsh/profile-boot' import type {} from '@deepseek-ai/dsh-client-connection' import type {} from '@deepseek-ai/dsh-host-webserver' @@ -20,6 +20,7 @@ async function main(): Promise { installOfficeEngineResolution(runtimeDir) const installAnchor = join(runtimeDir, 'node_modules', '@deepseek-ai', 'dsh', 'package.json') const profile = loadProfileDirectory('dsh', projectDir, installAnchor) + reportSkippedBundles('dsh', profile) const application = runProfile({ environment: loadLayeredEnv('dsh'), profile: 'desktop', diff --git a/apps/web/tests/scaffold.ts b/apps/web/tests/scaffold.ts index 9fde2ea346..c04e2df259 100644 --- a/apps/web/tests/scaffold.ts +++ b/apps/web/tests/scaffold.ts @@ -734,7 +734,7 @@ export async function launchWebScaffold(options: LaunchOptions = {}): Promise` and combines installable bundles with its own `cordis.patch.yml`. A bundle's `dsh.bundle.patch` names one patch file or an ordered list of files; `bundlePatchFiles` validates the declaration and `bundlePatchPaths` resolves it to absolute paths; the layer concatenates their patch lists in that order. The YAML composition enables or disables HMR. The shipped `web` template uses live reload, while the other shipped templates apply patches only at startup. `sdk-minimal` names only its standalone bundle; the other templates retain base-plus-mode stacks. `dsh --profile --from-default-profile