refactor(cli)!: the launcher parses only its own flags

Launcher flags come first and end at the first token dsh does not
recognize; everything after reaches the booted app verbatim, so
dsh --profile tui --resume <id> works with no launcher change and
dsh --profile web --help prints the web app's help. A bare dsh -h, which
has no app to hand the flag to, still prints the launcher's own.

src/web.ts is deleted: the Web flag family, its LAN-trust sampling, and the
one-shot task positional now live in their bundles, and runProfile no
longer knows any row id. What the startup row decides comes back as a
launcher-owned patch layer above every layer a user can edit, so a live
config edit recomposes the tree without resetting a served port.

dsh web and dsh --profile web finally boot through one path, which also
gives --profile web the harness-source prompt section that only the alias
used to add.
This commit is contained in:
Turtle
2026-08-06 20:52:26 +08:00
parent 82728808d4
commit 37cbd155f5
16 changed files with 518 additions and 522 deletions

View File

@@ -10,7 +10,7 @@
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { loadLayeredEnv } from '@deepseek-ai/dsh-app-boot'
import { loadEnv } from '@deepseek-ai/dsh-app-boot'
import { parseDshArgs } from './args.ts'
// Both the source tree (apps/cli/src) and the bundled bin (apps/cli/lib) sit
@@ -24,33 +24,19 @@ function readVersion(): string {
return typeof manifest.version === 'string' ? manifest.version : '0.0.0'
}
loadEnv('dsh')
const invocation = parseDshArgs(process.argv.slice(2), readVersion())
switch (invocation.mode) {
case 'profile': {
const { runProfile } = await import('./profile-boot.ts')
await runProfile({
environment: loadLayeredEnv('dsh'),
profile: invocation.profile,
patchFiles: invocation.patches,
args: invocation.args,
})
break
}
case 'run': {
const { runProfile } = await import('./profile-boot.ts')
await runProfile({
environment: loadLayeredEnv('dsh'),
profile: invocation.profile,
patchFiles: invocation.patches,
task: invocation.task,
})
break
}
case 'web': {
const { runWeb } = await import('./web.ts')
await runWeb(invocation, loadLayeredEnv('dsh'))
break
}
case 'plugin': {
const { runPlugin } = await import('./plugin.ts')
process.exit(runPlugin(invocation.profile, invocation.args))