Files
deepseek-harness/apps/cli/src/startup-diagnostics.ts
T

69 lines
2.5 KiB
TypeScript

/** Save original startup diagnostics while keeping the terminal report concise. */
import { randomUUID } from 'node:crypto'
import { mkdir, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
import { inspect } from 'node:util'
import type { StartupError } from '@deepseek-ai/dsh-app-boot'
/** Launcher-owned context; no environment values or plugin configurations are collected. */
interface StartupDiagnosticContext {
home: string
version: string
profile: string
}
/** Wait for stderr to finish the write before the failed process exits. */
function writeStderr(text: string): Promise<void> {
return new Promise((resolve, reject) => {
process.stderr.write(text, (error) => {
if (error) reject(error)
else resolve()
})
})
}
/**
* Print the startup summary and save a private, uniquely named report under DSH_HOME/logs.
* Failed writes print the complete report to stderr instead of claiming a saved path.
* @param error - startup audit failure retaining plugin metadata and original errors.
* @param context - resolved Harness home, application version, and selected profile.
* @param write - terminal output sink; awaited before returning, defaults to stderr.
* @returns after saving or printing the report and completing terminal writes.
*/
export async function reportStartupFailure(
error: StartupError,
context: StartupDiagnosticContext,
write: (text: string) => void | Promise<void> = writeStderr,
): Promise<void> {
const now = new Date().toISOString()
const report = 'WARNING: Raw diagnostics may contain configuration or credential values from plugin errors. Review before sharing.\n\n' + inspect({
timestamp: now,
dshVersion: context.version,
nodeVersion: process.version,
platform: process.platform,
arch: process.arch,
profile: context.profile,
error,
}, {
depth: null,
maxArrayLength: null,
maxStringLength: null,
showHidden: true,
customInspect: false,
getters: false,
colors: false,
}) + '\n'
await write(`${error.message}\n`)
const logDir = join(context.home, 'logs')
const logPath = join(logDir, `startup-${now.replaceAll(':', '-')}-${randomUUID()}.log`)
try {
await mkdir(logDir, { recursive: true, mode: 0o700 })
await writeFile(logPath, report, { flag: 'wx', mode: 0o600 })
} catch (writeError) {
await write(`\ndsh: warning: could not write startup diagnostics: ${String(writeError)}\nFull diagnostics:\n${report}`)
return
}
await write(`\nFull diagnostics: ${logPath}\n`)
}