Merge remote-tracking branch 'origin/master' into worktree/fix-minimal-preset-prompt

This commit is contained in:
Yichen Jiang
2026-08-10 22:15:30 +08:00
219 changed files with 2486 additions and 4026 deletions
+2 -2
View File
@@ -97,9 +97,9 @@ describe('client bundle purity gate', () => {
it('carries exactly one documented temporary exemption: runtime/client (store engine pending rehoming)', () => {
expect(resolveId('@deepseek-ai/dsh-client-runtime/client')).toBeNull()
const dshClientChannels = CLIENT_EXTERNALS.filter(
const clientChannels = CLIENT_EXTERNALS.filter(
entry => entry.startsWith('@deepseek-ai/') && entry.endsWith('/client'))
expect(dshClientChannels).toEqual(['@deepseek-ai/dsh-client-runtime/client'])
expect(clientChannels).toEqual(['@deepseek-ai/dsh-client-runtime/client'])
})
})
+21 -2
View File
@@ -1,9 +1,28 @@
import { mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises'
import { mkdir, mkdtemp, readFile, rm, symlink, writeFile } from 'node:fs/promises'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { expect, it } from 'vitest'
import type { TsdownBundle } from 'tsdown'
import { watchClientPlugins } from './dev-web.ts'
import { discoverPluginDirs, watchClientPlugins } from './dev-web.ts'
it('discovers dsh.client packages with sibling roles', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-dev-web-discovery-'))
try {
const current = join(root, 'packages', 'client', 'current')
await mkdir(current, { recursive: true })
await writeFile(join(current, 'package.json'), JSON.stringify({
dsh: {
bundle: { patch: './cordis.patch.yml' },
client: { platform: 'web' },
profile: { bundles: [] },
},
}))
expect(discoverPluginDirs(root)).toEqual(['packages/client/current'])
} finally {
await rm(root, { recursive: true, force: true })
}
})
it('rebuilds a client-plugin bundle after its source changes', async () => {
const root = await mkdtemp(join(tmpdir(), 'dsh-dev-web-watch-'))
+8 -6
View File
@@ -1,5 +1,5 @@
/**
* Watch-build for client-plugin HMR: runs every dshClient plugin package
* Watch-build for client-plugin HMR: runs every `dsh.client` plugin package
* through the tsdown JS API in watch mode. Reload signaling is not this
* script's business — the host webserver stat-polls the bundles it serves and
* broadcasts `rebuilt` frames itself (`dsh web --dev`), so any process that
@@ -27,7 +27,7 @@ const repoRoot = fileURLToPath(new URL('..', import.meta.url))
/**
* Discover the watch workspace by declaration: every packages/<group>/<name>
* whose package.json carries `dshClient` with platform "web" is a client
* whose package.json carries `dsh.client` with platform "web" is a client
* plugin bundle emitter. Scanned once at startup — a package added while
* watching means restarting this script.
* @param root - repository root containing the grouped package directories.
@@ -36,8 +36,10 @@ const repoRoot = fileURLToPath(new URL('..', import.meta.url))
export function discoverPluginDirs(root = repoRoot): string[] {
const dirs: string[] = []
for (const manifestPath of globSync('packages/*/*/package.json', { cwd: root }).sort()) {
const manifest = JSON.parse(readFileSync(join(root, manifestPath), 'utf8')) as { dshClient?: { platform?: unknown } }
if (manifest.dshClient?.platform === 'web') dirs.push(dirname(manifestPath).split(sep).join('/'))
const manifest = JSON.parse(readFileSync(join(root, manifestPath), 'utf8')) as {
dsh?: { client?: { platform?: unknown } }
}
if (manifest.dsh?.client?.platform === 'web') dirs.push(dirname(manifestPath).split(sep).join('/'))
}
return dirs
}
@@ -88,7 +90,7 @@ const isMain = invokedPath !== undefined && import.meta.url === pathToFileURL(re
if (isMain) {
const pluginDirs = discoverPluginDirs()
if (pluginDirs.length === 0) {
console.error('dev-web: no dshClient (platform "web") packages found under packages/')
console.error('dev-web: no dsh.client (platform "web") packages found under packages/')
process.exit(1)
}
@@ -106,7 +108,7 @@ if (isMain) {
await watchClientPlugins(repoRoot, pluginDirs, pollInterval)
console.log(
`dev-web: watching ${String(pluginDirs.length)} dshClient plugin packages`
`dev-web: watching ${String(pluginDirs.length)} dsh.client plugin packages`
+ `${pollInterval !== undefined ? ` (polling ${String(pollInterval)}ms)` : ''}:\n ${pluginDirs.join('\n ')}`,
)
}
+1 -1
View File
@@ -512,7 +512,7 @@ const SERVICE_ROLES: ServiceRole[] = [
title: 'Client plugin graph host',
mode: 'core',
consumers: ['hmr'],
note: 'Composes the __DSH_BOOT__ entry graph from an incremental dshClient scan, serves plugin bundles, and notifies rebuilt/graph-changed subscribers.',
note: 'Composes the __DSH_BOOT__ entry graph from an incremental dsh.client scan, serves plugin bundles, and notifies rebuilt/graph-changed subscribers.',
},
{
key: 'workflows',
+1 -13
View File
@@ -227,7 +227,7 @@ describe('Node 24 lane ownership', () => {
const subject = withPnpmEntrypoint(() => gatesForMode('ci-consumers'))
expect(defaultConcurrency('ci-consumers', subject.length, 4)).toEqual({
workers: 11,
workers: 10,
source: 'ci-consumers gate count',
})
expect(subject.map(item => item.id)).toEqual([
@@ -241,7 +241,6 @@ describe('Node 24 lane ownership', () => {
'doc-typecheck',
'node-next-types',
'built-bin-smoke',
'github-repository-plugin-e2e',
])
expect(subject.find(item => item.id === 'publint')?.needs).toEqual(['build'])
expect(subject.find(item => item.id === 'built-package-invariants')?.needs).toEqual(['publint'])
@@ -252,7 +251,6 @@ describe('Node 24 lane ownership', () => {
'doc-typecheck',
'node-next-types',
'built-bin-smoke',
'github-repository-plugin-e2e',
]) {
expect(subject.find(item => item.id === id)?.needs).toEqual(['built-package-invariants'])
}
@@ -266,16 +264,6 @@ describe('Node 24 lane ownership', () => {
'packages/subagent/subagent-claude-code/tests/loader-composition.e2e.ts',
]),
)
const githubRepositoryPlugin = subject.find(item => item.id === 'github-repository-plugin-e2e')
expect(githubRepositoryPlugin).toMatchObject({
label: 'GitHub repository Plugin dsh run',
env: {
DSH_REQUIRE_GITHUB_REPOSITORY_PLUGIN_E2E: '1',
},
})
expect(githubRepositoryPlugin?.args).toEqual(
expect.arrayContaining(['apps/cli/tests/github-repository-plugin.built.e2e.ts']),
)
expect(subject.find(item => item.id === 'web-snapshot')).toMatchObject({
displayCommand: 'DSH_SNAPSHOT=replay pnpm run test:web:built',
env: { DSH_SNAPSHOT: 'replay' },
+1 -16
View File
@@ -406,7 +406,6 @@ function ciConsumerGates(): Gate[] {
needs: validatedBuild,
}),
builtBinSmokeGate(validatedBuild),
githubRepositoryPluginE2eGate(validatedBuild),
]
}
@@ -518,7 +517,7 @@ function coverageGates(): Gate[] {
}
// Example and package snapshots boot their bins in `lib` mode (built artifacts under plain Node,
// plugins via real exports); repository-script snapshots execute their real source entry path.
// plugins via real exports); script snapshots execute their real source entry path.
// Callers wait either on `build` or on a validation gate that transitively owns that build.
function snapshotGate(needs: string[] = ['build']): Gate {
return pnpmScript('snapshot', 'test:snapshot', {
@@ -639,20 +638,6 @@ function builtBinSmokeGate(needs: string[] = ['build']): Gate {
})
}
function githubRepositoryPluginE2eGate(needs: string[]): Gate {
return pnpmExec('github-repository-plugin-e2e', [
'vitest',
'run',
'--config',
'vitest.e2e.config.ts',
'apps/cli/tests/github-repository-plugin.built.e2e.ts',
], {
label: 'GitHub repository Plugin dsh run',
needs,
env: { DSH_REQUIRE_GITHUB_REPOSITORY_PLUGIN_E2E: '1' },
})
}
/**
* Reject a gate list whose graph cannot be executed unambiguously.
* @param gates - complete aggregate to validate.