Files
deepseek-harness/packages/sdk/scripts/src/command.ts
T

77 lines
2.8 KiB
TypeScript
Raw Normal View History

2026-07-15 18:17:38 +08:00
/**
2026-07-15 22:18:28 +08:00
* Internal dsh-sdk command composition used by the package bin.
2026-07-15 18:17:38 +08:00
*
* @module @deepseek-ai/dsh-scripts/command
*/
2026-07-15 22:18:28 +08:00
import { parseDshSdkArgs } from './args.ts'
2026-07-15 18:17:38 +08:00
import { runProjectBuild } from './build.ts'
import { runConfigCommand, type ConfigCommandContext } from './config.ts'
import { runCreatePluginCommand } from './create-plugin.ts'
2026-07-15 18:17:38 +08:00
import { runSDK } from './runtime.ts'
import { reportCommandTelemetry, type CommandTelemetryEvent } from './telemetry.ts'
2026-07-15 22:18:28 +08:00
import { DSH_SDK_TEMPLATES } from './templates/dsh-sdk-templates.ts'
2026-07-15 18:17:38 +08:00
2026-07-15 22:18:28 +08:00
/** Injectable process and command boundaries used by the dsh-sdk bin. */
export interface DshSdkCommandContext extends ConfigCommandContext {
2026-07-15 18:17:38 +08:00
cwd: string
stdin: NodeJS.ReadStream
stdout: NodeJS.WriteStream
stderr: NodeJS.WriteStream
run?: typeof runSDK
build?: typeof runProjectBuild
config?: typeof runConfigCommand
createPlugin?: typeof runCreatePluginCommand
telemetry?: (event: CommandTelemetryEvent) => Promise<void>
2026-07-15 18:17:38 +08:00
}
2026-07-15 22:18:28 +08:00
/** Run one parsed dsh-sdk command and return its process exit code. */
export async function runDshSdkCommand(
2026-07-15 18:17:38 +08:00
argv: readonly string[] = process.argv.slice(2),
2026-07-15 22:18:28 +08:00
context: DshSdkCommandContext = {
2026-07-15 18:17:38 +08:00
cwd: process.cwd(),
stdin: process.stdin,
stdout: process.stdout,
stderr: process.stderr,
},
): Promise<number> {
const startedAt = Date.now()
let command: string | undefined
let success = true
2026-07-15 18:17:38 +08:00
try {
2026-07-15 22:18:28 +08:00
const args = parseDshSdkArgs(argv)
2026-07-15 18:17:38 +08:00
if (args.help || !args.command) {
2026-07-15 22:18:28 +08:00
context.stdout.write(DSH_SDK_TEMPLATES.usage.render({}))
2026-07-15 18:17:38 +08:00
return 0
}
command = args.command
2026-07-15 18:17:38 +08:00
const run = context.run ?? runSDK
const build = context.build ?? runProjectBuild
const config = context.config ?? runConfigCommand
const createPlugin = context.createPlugin ?? runCreatePluginCommand
2026-07-15 18:17:38 +08:00
switch (args.command) {
case 'start': await run(args.target, { cwd: context.cwd, argv: args.forwarded }); break
case 'dev': await run(args.target, { cwd: context.cwd, dev: true, argv: args.forwarded }); break
case 'build': await build(args.forwarded, context.cwd); break
case 'config': {
const result = await config(context)
if (result.installError) { success = false; return 1 }
2026-07-15 18:17:38 +08:00
break
}
/* v8 ignore next -- Commander requires <source>, so create never dispatches without it */
case 'create': await createPlugin(args.source ?? '', context); break
2026-07-15 18:17:38 +08:00
}
return 0
} catch (error) {
success = false
2026-07-15 22:18:28 +08:00
context.stderr.write(`dsh-sdk: ${error instanceof Error ? error.message : String(error)}\n`)
2026-07-15 18:17:38 +08:00
return 1
} finally {
if (command !== undefined) {
/* v8 ignore next -- production telemetry wiring is exercised by the built-bin smoke */
const telemetry = context.telemetry ?? reportCommandTelemetry
await telemetry({ command, cwd: context.cwd, durationMs: Date.now() - startedAt, success })
}
2026-07-15 18:17:38 +08:00
}
}