Files
deepseek-harness/apps/cli/src/bin.ts
T
Turtle cd6b4ee3c9 feat(cli)!: dsh boots profiles; plugin subcommand manages them via pnpm
dsh --profile <name> replaces the fixed entry modes: --config and -p are
removed, --patch adds overlays over the composed profile, a positional task
selects one-shot mode (requires the headless-runner row), and dsh web stays as
the alias for --profile web carrying the Web flag family as patches. dsh
plugin --profile <name> forwards verbatim to pnpm in the profile directory,
initializes on first use, and reconciles the dsh.plugins layer list after
add/remove (patch-less packages warn and stay plain dependencies). Config
dumps and the keyless web e2e scaffold compose the same bundle layers over the
same empty root as the boot.
2026-08-06 06:29:06 +08:00

59 lines
2.0 KiB
JavaScript

#!/usr/bin/env node
/**
* dsh — command-line entry. Dynamic imports per mode keep unrelated modes out
* of each dispatch path; the adapter prints and exits for
* `--help`/`--version`/a parse error, so only a valid mode reaches the switch.
* @module @deepseek-ai/dsh/bin
*/
/* v8 ignore file -- built-bin acceptance exercises this self-executing dispatch. */
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
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
// one directory under apps/cli, so the checked-in manifest resolves with the
// same relative hop from either artifact.
/** This app's version, read from its checked-in package.json. */
function readVersion(): string {
const manifest = JSON.parse(
readFileSync(fileURLToPath(new URL('../package.json', import.meta.url)), 'utf8'),
) as { version?: unknown }
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({
profile: invocation.profile,
patchFiles: invocation.patches,
...invocation.task !== undefined && { task: invocation.task },
})
break
}
case 'web': {
const { runWeb } = await import('./web.ts')
await runWeb(invocation)
break
}
case 'plugin': {
const { runPlugin } = await import('./plugin.ts')
process.exit(runPlugin(invocation.profile, invocation.args))
break
}
case 'dump-config': {
const { runDumpConfig } = await import('./dump-config.ts')
runDumpConfig(invocation.profile, invocation.defaultOnly, invocation.patches)
break
}
default:
invocation satisfies never
throw new Error(`dsh: unhandled invocation mode ${JSON.stringify(invocation)}`)
}