dsh-lark-bot 0.8.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -11
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/plugin.js +1 -1
- package/dist/plugin.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/dsh/event-channel.ts","../src/config/dsh-compat.ts","../src/config/dsh-runtime.ts","../src/adapters/dsh/own-package.ts","../src/adapters/dsh/acp-runtime.ts","../src/adapters/dsh/acp-adapter.ts","../src/cli.ts","../src/cli/commands/doctor.ts","../src/adapters/index.ts","../src/adapters/dsh/adapter.ts","../src/adapters/dsh/availability.ts","../src/adapters/dsh/translate.ts","../src/adapters/dsh/sdk-adapter.ts","../src/adapters/dsh/sdk-translate.ts","../src/adapters/dsh/sdk-runtime.ts","../src/config/app-paths.ts","../src/config/env.ts","../src/config/profile-store.ts","../src/platform/atomic-write.ts","../src/cli/commands/run.ts","../src/bot/active-runs.ts","../src/config/security.ts","../src/core/logger.ts","../src/bot/approvals.ts","../src/bot/concurrency-store.ts","../src/bot/density-store.ts","../src/bot/model-store.ts","../src/bot/pending-queue.ts","../src/bot/questions.ts","../src/bot/retention-store.ts","../src/bot/role-store.ts","../src/bot/run-policy.ts","../src/bridge/channel.ts","../src/commands/index.ts","../src/card/workspace-card.ts","../src/card/density.ts","../src/bridge/run-flow.ts","../src/card/run-state.ts","../src/card/run-renderer.ts","../src/card/approval-card.ts","../src/card/question-card.ts","../src/config/dsh-config.ts","../src/commands/models.ts","../src/commands/archive.ts","../src/commands/roles.ts","../src/commands/notify.ts","../src/bridge/lark-channel.ts","../src/bridge/scope-directory.ts","../src/notify/server.ts","../src/config/access-manager.ts","../src/onboard/registration.ts","../src/media/attachments.ts","../src/session/store.ts","../src/session/archive.ts","../src/workspace/git-worktree.ts","../src/workspace/store.ts","../src/guardian/heartbeat.ts","../src/cli/commands/setup.ts","../src/guardian/install.ts","../src/guardian/process.ts","../src/guardian/state.ts","../src/cli/commands/guardian.ts","../src/guardian/service.ts","../src/guardian/control.ts","../src/guardian/safe-profile.ts"],"sourcesContent":["/** Ordered async queue used to stream translated events out of a run. */\nexport class EventChannel<T> implements AsyncIterable<T> {\n private static readonly END = Symbol('event-channel-end');\n private readonly queue: T[] = [];\n private readonly waiters: Array<(event: T) => void> = [];\n private closed = false;\n\n push(event: T): void {\n if (this.closed) return;\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter(event);\n } else {\n this.queue.push(event);\n }\n }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n for (const waiter of this.waiters.splice(0)) {\n waiter(EventChannel.END as unknown as T);\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\n for (;;) {\n if (this.closed && this.queue.length === 0) return;\n const queued = this.queue.shift();\n if (queued !== undefined) {\n yield queued;\n continue;\n }\n const value = await new Promise<T>((resolve) => {\n this.waiters.push(resolve);\n });\n if (value === EventChannel.END) return;\n yield value;\n }\n }\n}\n","/**\n * Single source of truth for the DeepSeek Harness compatibility matrix.\n *\n * The bridge pins exact pre-release versions so a release is reproducible.\n * When upstream publishes a stable version, bump every field here, update\n * `package.json` (exact version), run `pnpm ci:local` plus the compatibility\n * probe, then refresh `verifiedAt`. See `docs/COMPATIBILITY.md`.\n */\nexport interface DshCompatibility {\n /** DeepSeek Harness CLI (`dsh`) version verified against this bot release. */\n harness: string;\n /** `@deepseek-ai/dsh-sdk-client` version the bridge is pinned to. */\n sdkClient: string;\n /** `@deepseek-ai/dsh-sdk-jsonrpc-server` version installed into SDK runtime profiles. */\n sdkServer: string;\n /** `@deepseek-ai/dsh-acp` version installed into ACP runtime profiles. */\n acp: string;\n /** Node.js engine requirement. */\n node: string;\n /** ISO date of the last end-to-end verification. */\n verifiedAt: string;\n}\n\nexport const DSH_COMPATIBILITY: DshCompatibility = {\n harness: '0.1.0-rc.6',\n sdkClient: '0.1.0-rc.6',\n sdkServer: '0.1.0-rc.6',\n acp: '0.1.0-rc.6',\n node: '>=22.19.0',\n verifiedAt: '2026-08-15',\n};\n","import { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface DshRuntimeSpec {\n command: string;\n args: string[];\n bin?: string;\n}\n\nconst DS_HARNESS_RELATIVE = join('@deepseek-ai', 'dsh', 'lib', 'bin.js');\n\nexport function resolveDshHome(\n home: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n return env.DSH_HOME?.trim() || join(home, '.dsh');\n}\n\nfunction firstExisting(...paths: string[]): string | undefined {\n return paths.find((path) => existsSync(path));\n}\n\nfunction children(root: string): string[] {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())\n .map((entry) => join(root, entry.name));\n } catch {\n return [];\n }\n}\n\nexport function discoverDshBin(\n home: string,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n const dshHome = resolveDshHome(home, env);\n\n const candidates = [\n join(dshHome, 'profiles', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.npm', '_npx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.cache', 'pnpm', 'dlx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.local', 'share', 'pnpm', 'node_modules', DS_HARNESS_RELATIVE),\n ];\n\n const direct = firstExisting(...candidates);\n if (direct) return direct;\n\n for (const root of [join(home, '.npm', '_npx'), join(home, '.cache', 'pnpm', 'dlx')]) {\n for (const child of children(root)) {\n const path = join(child, 'node_modules', DS_HARNESS_RELATIVE);\n if (existsSync(path)) return path;\n }\n }\n\n return undefined;\n}\n\nexport function resolveDshRuntime(\n input: {\n command?: string;\n args?: string[];\n home: string;\n env?: NodeJS.ProcessEnv;\n },\n): DshRuntimeSpec {\n if (input.command || input.args) {\n return {\n command: input.command ?? 'node',\n args: input.args ?? ['--profile', 'headless'],\n };\n }\n\n const bin = discoverDshBin(input.home, input.env);\n if (bin) {\n return {\n command: 'node',\n args: [bin, '--profile', 'headless'],\n bin,\n };\n }\n\n return {\n command: 'dsh',\n args: ['--profile', 'headless'],\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nexport interface OwnPackageInfo {\n name: string;\n root: string;\n}\n\n/**\n * Locate the running dsh-lark-bot package (source checkout or installed\n * dist). The managed dsh runtime profiles link this package in so their patch\n * rows (`dsh-lark-bot/notify`, …) resolve through the profile's node_modules.\n *\n * The module may be bundled (e.g. `dist/cli.js`) or unbundled\n * (`dist/adapters/.../sdk-runtime.js`), so the package root cannot be derived\n * from a fixed `import.meta.url` depth: walk upward until a package.json\n * whose name is one of ours is found.\n */\nexport function ownPackageInfo(): OwnPackageInfo {\n return findOwnPackageRoot(dirname(fileURLToPath(import.meta.url)));\n}\n\n/**\n * Walk upward from `startDir` until a package.json whose name is one of ours\n * is found. Extracted for testability; bundled and unbundled layouts both\n * resolve to the package root.\n */\nexport function findOwnPackageRoot(startDir: string): OwnPackageInfo {\n let dir = startDir;\n for (let depth = 0; depth < 8; depth += 1) {\n const pkgPath = join(dir, 'package.json');\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n name?: unknown;\n };\n if (typeof pkg.name === 'string' && isOwnPackageName(pkg.name)) {\n return { name: pkg.name, root: dir };\n }\n } catch {\n // Not a readable manifest at this level; keep walking upward.\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // Fallback: the canonical name and the current working directory.\n return { name: 'dsh-lark-bot', root: process.cwd() };\n}\n\nfunction isOwnPackageName(name: string): boolean {\n return (\n name === 'dsh-lark-bot' ||\n name === 'dsh-feishu-bot' ||\n /^@[^/]+\\/(dsh-lark-bot|dsh-feishu-bot)$/.test(name)\n );\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { DSH_COMPATIBILITY } from '../../config/dsh-compat.js';\nimport { discoverDshBin, resolveDshHome } from '../../config/dsh-runtime.js';\nimport { ownPackageInfo } from './own-package.js';\n\nexport const ACP_PACKAGE = '@deepseek-ai/dsh-acp';\nexport const ACP_VERSION = DSH_COMPATIBILITY.acp;\nexport const ACP_BASE_BUNDLE = '@deepseek-ai/dsh-base';\nexport const DEFAULT_ACP_PROFILE = 'dsh-lark-acp';\n\nexport interface AcpRuntimeOptions {\n home: string;\n env?: NodeJS.ProcessEnv;\n command?: string;\n args?: string[];\n bin?: string;\n profile?: string;\n provider?: string;\n model?: string;\n install?: (profileRoot: string) => Promise<void>;\n}\n\nexport interface AcpLaunchSpec {\n command: string;\n args: string[];\n profile: string;\n}\n\nexport interface AcpProfileEnsureResult {\n ok: boolean;\n created: boolean;\n error?: string;\n}\n\nexport function acpProfileRoot(home: string, profile: string, env?: NodeJS.ProcessEnv): string {\n return join(resolveDshHome(home, env), 'profiles', profile);\n}\n\nfunction packageJsonFor(profile: string): string {\n const own = ownPackageInfo();\n return `${JSON.stringify(\n {\n name: `dsh-profile-${profile}`,\n private: true,\n dependencies: {\n [ACP_PACKAGE]: ACP_VERSION,\n [own.name]: `link:${own.root}`,\n },\n dsh: {\n profile: {\n bundles: [ACP_BASE_BUNDLE],\n },\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nexport function acpPatchYaml(provider: string, model: string): string {\n const own = ownPackageInfo();\n return [\n '# dsh-lark ACP JSON-RPC runtime overlay (managed by dsh-lark-bot).',\n '# stdout is reserved for ACP JSON-RPC frames; no console logger may load.',\n '- insert:',\n ' - id: acp',\n ` name: '${ACP_PACKAGE}'`,\n ' config:',\n ` provider: ${provider}`,\n ` model: ${model}`,\n '',\n '# Unattended IM runtime: interactive user questions cannot be answered',\n '# through Feishu, so the tool is disabled (default-deny).',\n '- id: user-questions',\n ' disabled: true',\n '',\n '- id: system-prompt',\n ' config:',\n ' persona: >-',\n ' You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.',\n '',\n '- id: hmr',\n ' disabled: true',\n '',\n // In-process bridge callback tool (same contract as the SDK runtime).\n '- insert:',\n ' - id: lark-notify',\n ` name: '${own.name}/notify'`,\n ' config:',\n ' endpoint: !!js process.env.DSH_LARK_NOTIFY_URL',\n ' token: !!js process.env.DSH_LARK_NOTIFY_TOKEN',\n '',\n ].join('\\n');\n}\n\nfunction acpPluginInstalled(profileRoot: string): boolean {\n const candidates = [\n join(profileRoot, 'node_modules', ACP_PACKAGE),\n join(profileRoot, '..', 'node_modules', ACP_PACKAGE),\n ];\n return candidates.some((path) => existsSync(path));\n}\n\nexport function isAcpProfileReady(profileRoot: string): boolean {\n const own = ownPackageInfo();\n return (\n existsSync(join(profileRoot, 'package.json')) &&\n existsSync(join(profileRoot, 'cordis.yml')) &&\n existsSync(join(profileRoot, 'cordis.patch.yml')) &&\n acpPluginInstalled(profileRoot) &&\n ownPackageLinked(profileRoot, own.name)\n );\n}\n\n/** True when the profile's node_modules link resolves to this package. */\nfunction ownPackageLinked(profileRoot: string, ownName: string): boolean {\n const linkPath = join(profileRoot, 'node_modules', ownName);\n try {\n const real = realpathSync(linkPath);\n const pkg = JSON.parse(readFileSync(join(real, 'package.json'), 'utf8')) as {\n name?: unknown;\n dsh?: { bundle?: { patch?: unknown } };\n };\n return (\n pkg.name === ownName &&\n pkg.dsh?.bundle?.patch !== undefined\n );\n } catch {\n return false;\n }\n}\n\nfunction runPnpmInstall(profileRoot: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['install'], {\n cwd: profileRoot,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let output = '';\n child.stdout.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n reject(error);\n });\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n const tail = output.trim().split('\\n').slice(-8).join('\\n');\n reject(new Error(`pnpm install exited with code ${String(code)}\\n${tail}`));\n });\n });\n}\n\n/**\n * Ensure the ACP runtime profile exists under the shared dsh installation.\n * The profile composes `@deepseek-ai/dsh-base` with the official\n * `@deepseek-ai/dsh-acp` plugin (approval policy stays `ask`; the bridge\n * answers through `session/request_permission`).\n */\nexport async function ensureAcpProfile(\n options: AcpRuntimeOptions,\n): Promise<AcpProfileEnsureResult> {\n const profile = options.profile ?? DEFAULT_ACP_PROFILE;\n const root = acpProfileRoot(options.home, profile, options.env);\n const provider = options.provider ?? 'deepseek-official';\n const model = options.model ?? 'deepseek-v4-flash';\n const ready = isAcpProfileReady(root);\n\n try {\n await mkdir(root, { recursive: true });\n await writeFile(join(root, 'package.json'), packageJsonFor(profile), 'utf8');\n await writeFile(join(root, 'cordis.yml'), '[]\\n', 'utf8');\n await writeFile(join(root, 'cordis.patch.yml'), acpPatchYaml(provider, model), 'utf8');\n if (!ready) {\n const install = options.install ?? runPnpmInstall;\n await install(root);\n }\n if (!isAcpProfileReady(root)) {\n return {\n ok: false,\n created: true,\n error: `${ACP_PACKAGE}@${ACP_VERSION} or bridge package was not found after install`,\n };\n }\n return { ok: true, created: !ready };\n } catch (error) {\n return {\n ok: false,\n created: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/** Resolve the launch spec for the ACP runtime subprocess. */\nexport function resolveAcpLaunch(options: AcpRuntimeOptions): AcpLaunchSpec {\n const profile = options.profile ?? DEFAULT_ACP_PROFILE;\n if (options.command || options.args) {\n return {\n command: options.command ?? 'node',\n args: options.args ?? ['--profile', profile],\n profile,\n };\n }\n const bin = options.bin ?? discoverDshBin(options.home, options.env);\n if (bin) {\n return { command: 'node', args: [bin, '--profile', profile], profile };\n }\n return { command: 'dsh', args: ['--profile', profile], profile };\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n spawn as defaultSpawn,\n type ChildProcess,\n type SpawnOptionsWithoutStdio,\n} from 'node:child_process';\nimport { homedir } from 'node:os';\nimport { Readable as NodeReadable, Writable as NodeWritable } from 'node:stream';\nimport {\n ClientSideConnection,\n ndJsonStream,\n PROTOCOL_VERSION,\n type Agent as AcpAgent,\n type Client as AcpClient,\n type ContentBlock as AcpContentBlock,\n type RequestPermissionRequest,\n type RequestPermissionResponse,\n type SessionNotification,\n} from '@agentclientprotocol/sdk';\nimport type { RuntimeEnv } from '../../config/env.js';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentEvent,\n AgentRun,\n AgentRunOptions,\n ApprovalOutcome,\n ApprovalRequest,\n} from '../types.js';\nimport { ensureAcpProfile, resolveAcpLaunch, type AcpLaunchSpec } from './acp-runtime.js';\nimport { EventChannel } from './event-channel.js';\n\nexport interface AcpAdapterOptions {\n launch: AcpLaunchSpec;\n provider: string;\n model: string;\n probeTimeoutMs?: number;\n spawn?: (command: string, args: string[], options: SpawnOptionsWithoutStdio) => ChildProcess;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction textOfContent(content: unknown): string {\n if (!isRecord(content) || typeof content.text !== 'string') return '';\n return content.text;\n}\n\n/** Translate an ACP session update into bridge events (forward-compatible). */\nexport function translateAcpUpdate(notification: SessionNotification): AgentEvent[] {\n const update = notification.update;\n if (!isRecord(update)) return [];\n switch (update.sessionUpdate) {\n case 'agent_message_chunk':\n return textOfContent(update.content)\n ? [{ type: 'text', delta: textOfContent(update.content) }]\n : [];\n case 'agent_thought_chunk':\n return textOfContent(update.content)\n ? [{ type: 'thinking', delta: textOfContent(update.content) }]\n : [];\n case 'tool_call': {\n if (typeof update.toolCallId !== 'string') return [];\n return [\n {\n type: 'tool_use',\n id: update.toolCallId,\n name: typeof update.title === 'string' ? update.title : 'tool',\n input: update.rawInput ?? {},\n },\n ];\n }\n default:\n return [];\n }\n}\n\nfunction mapApprovalOutcome(\n outcome: ApprovalOutcome,\n options: RequestPermissionRequest['options'],\n): RequestPermissionResponse {\n if (outcome === 'cancelled') {\n return { outcome: { outcome: 'cancelled' } };\n }\n const wanted: 'allow_once' | 'reject_once' =\n outcome === 'allowed-once' ? 'allow_once' : 'reject_once';\n const option = options.find((item) => item.kind === wanted);\n if (!option) return { outcome: { outcome: 'cancelled' } };\n return { outcome: { outcome: 'selected', optionId: option.optionId } };\n}\n\nfunction buildPromptText(prompt: string, images: readonly string[] | undefined): string {\n return images?.length\n ? `${prompt}\\n\\nImage files attached to this message:\\n${images.join('\\n')}`\n : prompt;\n}\n\nfunction waitForChildExit(\n child: ChildProcess,\n timeoutMs: number,\n): Promise<{ code: number | null; timedOut: boolean }> {\n if (child.exitCode !== null || child.signalCode !== null) {\n return Promise.resolve({ code: child.exitCode, timedOut: false });\n }\n return new Promise((resolve) => {\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n child.removeListener('exit', onExit);\n resolve({ code: child.exitCode, timedOut: true });\n }, timeoutMs)\n : undefined;\n const onExit = (code: number | null): void => {\n if (timer !== undefined) clearTimeout(timer);\n resolve({ code, timedOut: false });\n };\n child.once('exit', onExit);\n });\n}\n\nasync function disposeChild(child: ChildProcess, graceMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return;\n child.stdin?.end();\n if (!(await waitForChildExit(child, graceMs)).timedOut) return;\n child.kill('SIGTERM');\n if (!(await waitForChildExit(child, graceMs)).timedOut) return;\n child.kill('SIGKILL');\n}\n\n/**\n * Official ACP adapter. Spawns the `dsh-lark-acp` runtime and speaks the\n * Agent Client Protocol over stdio as a client: `session/request_permission`\n * maps to Feishu approval cards through `AgentRunOptions.onApprovalRequest`.\n * ACP sessions are fresh per run (no resume), matching the upstream server.\n */\nexport class AcpDshAdapter implements AgentAdapter {\n readonly id = 'dsh-acp';\n readonly displayName = 'DeepSeek Harness (ACP)';\n\n private readonly launch: AcpLaunchSpec;\n private readonly model: string;\n private readonly probeTimeoutMs: number;\n private readonly spawn: AcpAdapterOptions['spawn'];\n private readonly stopGraceMs: number;\n\n constructor(options: AcpAdapterOptions) {\n this.launch = options.launch;\n this.model = options.model;\n this.probeTimeoutMs = options.probeTimeoutMs ?? 15_000;\n this.spawn = options.spawn;\n this.stopGraceMs = 5_000;\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n async checkAvailability(): Promise<AgentAvailability> {\n const child = this.spawnChild(process.cwd());\n if (!child.stdin || !child.stdout) {\n await disposeChild(child, this.stopGraceMs);\n return { ok: false, error: 'ACP child did not expose protocol streams', version: undefined };\n }\n const conn = new ClientSideConnection(\n () => ({\n requestPermission: () => Promise.resolve({ outcome: { outcome: 'cancelled' } }),\n sessionUpdate: () => Promise.resolve(),\n }),\n ndJsonStream(\n NodeWritable.toWeb(child.stdin) as WritableStream<Uint8Array>,\n NodeReadable.toWeb(child.stdout) as ReadableStream<Uint8Array>,\n ),\n );\n try {\n const info = await withTimeout(\n conn.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} }),\n this.probeTimeoutMs,\n );\n const name = info.agentInfo?.name ?? 'deepseek-harness-acp';\n const version = info.agentInfo?.version ?? 'unknown';\n return { ok: true, error: undefined, version: `${name}@${version}` };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n version: undefined,\n };\n } finally {\n await disposeChild(child, this.stopGraceMs);\n }\n }\n\n run(options: AgentRunOptions): AgentRun {\n const cwd = options.cwd ?? process.cwd();\n const model = options.model ?? this.model;\n const stopRequested = { value: false };\n const channel = new EventChannel<AgentEvent>();\n const child = this.spawnChild(cwd);\n let serverSessionId: string | undefined;\n let conn: ClientSideConnection | undefined;\n let hadError = false;\n const clientSessionId = `acp-${randomUUID().replaceAll('-', '')}`;\n\n const makeClient = (_agent: AcpAgent): AcpClient => ({\n sessionUpdate: async (notification: SessionNotification) => {\n for (const event of translateAcpUpdate(notification)) {\n if (event.type === 'error') hadError = true;\n channel.push(event);\n }\n },\n requestPermission: async (request: RequestPermissionRequest) => {\n if (!options.onApprovalRequest) {\n return { outcome: { outcome: 'cancelled' } };\n }\n const approval: ApprovalRequest = {\n id: request.toolCall.toolCallId,\n sessionId: request.sessionId,\n toolName:\n typeof request.toolCall.title === 'string' ? request.toolCall.title : 'tool',\n reason: undefined,\n options: request.options.map((item) => ({\n optionId: item.optionId,\n name: item.name,\n kind: item.kind,\n })),\n };\n const outcome = await options.onApprovalRequest(approval);\n return mapApprovalOutcome(outcome, request.options);\n },\n });\n\n const task = (async () => {\n if (!child.stdin || !child.stdout) {\n throw new Error('ACP child did not expose protocol streams');\n }\n conn = new ClientSideConnection(\n makeClient,\n ndJsonStream(\n NodeWritable.toWeb(child.stdin) as WritableStream<Uint8Array>,\n NodeReadable.toWeb(child.stdout) as ReadableStream<Uint8Array>,\n ),\n );\n await conn.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} });\n const created = await conn.newSession({ cwd, mcpServers: [] });\n serverSessionId = created.sessionId;\n const blocks: AcpContentBlock[] = [\n { type: 'text', text: buildPromptText(options.prompt, options.images) },\n ];\n const response = await conn.prompt({ sessionId: serverSessionId, prompt: blocks });\n if (response.stopReason === 'cancelled') {\n if (!stopRequested.value) {\n channel.push({ type: 'error', message: 'ACP turn cancelled', terminationReason: 'interrupted' });\n hadError = true;\n }\n return;\n }\n if (response.stopReason === 'refusal' || response.stopReason === 'max_turn_requests') {\n channel.push({\n type: 'error',\n message: `ACP turn stopped with reason: ${response.stopReason}`,\n terminationReason: 'failed',\n });\n hadError = true;\n return;\n }\n if (response.usage) {\n const usage: AgentEvent = {\n type: 'usage',\n ...(typeof response.usage.inputTokens === 'number'\n ? { inputTokens: response.usage.inputTokens }\n : {}),\n ...(typeof response.usage.outputTokens === 'number'\n ? { outputTokens: response.usage.outputTokens }\n : {}),\n };\n channel.push(usage);\n }\n })().catch((error: unknown) => {\n if (!stopRequested.value) {\n channel.push({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n terminationReason: 'failed',\n });\n hadError = true;\n }\n }).finally(() => {\n channel.close();\n });\n\n async function* events(): AsyncGenerator<AgentEvent> {\n yield {\n type: 'system',\n sessionId: clientSessionId,\n cwd,\n model,\n };\n for await (const event of channel) {\n yield event;\n }\n await task;\n if (!hadError) {\n yield {\n type: 'done',\n sessionId: clientSessionId,\n terminationReason: stopRequested.value ? 'interrupted' : 'normal',\n };\n }\n }\n\n return {\n runId: options.runId,\n events: events(),\n stop: async () => {\n stopRequested.value = true;\n if (conn && serverSessionId !== undefined) {\n try {\n await conn.cancel({ sessionId: serverSessionId });\n } catch {\n // The child may already be gone; teardown below is authoritative.\n }\n }\n await disposeChild(child, this.stopGraceMs);\n },\n waitForExit: (timeoutMs) =>\n waitForChildExit(child, timeoutMs).then((result) => !result.timedOut && result.code !== null),\n };\n }\n\n private spawnChild(cwd: string): ChildProcess {\n const spawnFn = this.spawn ?? defaultSpawn;\n return spawnFn(this.launch.command, this.launch.args, {\n cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n }\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error(`ACP probe timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n promise.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error: unknown) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** Build the ACP adapter for the configured env (used by `buildAgentAdapter`). */\nexport async function buildAcpAgentAdapter(\n env: RuntimeEnv,\n preferences: { stopGraceMs: number | undefined; model: string | undefined },\n): Promise<AcpDshAdapter> {\n const runtimeOptions = {\n home: homedir(),\n env: process.env,\n provider: env.provider,\n model: preferences.model ?? env.model,\n ...(env.dshExplicit ? { command: env.dshCommand, args: env.dshArgs } : {}),\n };\n const ensure = await ensureAcpProfile(runtimeOptions);\n if (!ensure.ok) {\n throw new Error(\n `ACP runtime profile setup failed: ${ensure.error ?? 'unknown error'} ` +\n '(install pnpm, or set DSH_LARK_ADAPTER=headless for the legacy adapter)',\n );\n }\n const launch = resolveAcpLaunch(runtimeOptions);\n return new AcpDshAdapter({\n launch,\n provider: env.provider,\n model: preferences.model ?? env.model,\n });\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\nimport { runDoctor } from './cli/commands/doctor.js';\nimport { runBot } from './cli/commands/run.js';\nimport { runSetup } from './cli/commands/setup.js';\nimport {\n installGuardianCommand,\n runGuardian,\n statusGuardianCommand,\n uninstallGuardianCommand,\n} from './cli/commands/guardian.js';\n\nfunction packageVersion(): string {\n const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf8');\n const pkg = JSON.parse(raw) as { version?: unknown };\n return typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n}\n\nexport interface StartOptions {\n profile?: string;\n workspace?: string;\n appId?: string;\n appSecret?: string;\n tenant?: string;\n}\n\nfunction addBotOptions(command: Command): Command {\n return command\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark');\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name('dsh-lark-bot')\n .description('Bridge DeepSeek Harness into Feishu / Lark')\n .version(packageVersion(), '-v, --version');\n\n program\n .command('setup')\n .description(\n 'Install this package as a standard dsh profile bundle (single install path)',\n )\n .option('--profile <name>', 'dsh profile to install into (default: dsh-lark)')\n .option('--guardian', 'also install the safety-net guardian service')\n .action(async (opts: { profile?: string; guardian?: boolean }) => {\n await runSetup({\n ...(opts.profile ? { profile: opts.profile } : {}),\n ...(opts.guardian ? { guardian: true } : {}),\n });\n });\n\n program\n .command('doctor')\n .description('Run local diagnostics')\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark')\n .action(async (opts: StartOptions) => {\n await runDoctor({ ...opts, version: packageVersion() });\n });\n\n addBotOptions(\n program\n .command('run', { hidden: true })\n .description('Run the bridge engine directly (diagnostics; the dsh plugin runs it in-process)'),\n ).action(async (opts: StartOptions) => {\n await runBot(opts);\n });\n\n const guardian = program\n .command('guardian')\n .description(\n 'Safety-net guardian: a minimal process independent of dsh that keeps the Feishu rescue entrance alive',\n );\n\n guardian\n .command('run')\n .description('Run the guardian in the foreground (system service entry point)')\n .option('--dsh-profile <name>', 'dsh profile to watch / relaunch (default from state)')\n .option('--bridge-profile <name>', 'bridge state profile with Feishu credentials')\n .action(async (opts: { dshProfile?: string; bridgeProfile?: string }) => {\n await runGuardian(opts);\n });\n\n guardian\n .command('install')\n .description('Install the guardian as a system-level resident service')\n .option('--dsh-profile <name>', 'dsh profile to watch / relaunch (default: dsh-lark)')\n .option('--bridge-profile <name>', 'bridge state profile (default: default)')\n .action(async (opts: { dshProfile?: string; bridgeProfile?: string }) => {\n await installGuardianCommand(opts);\n });\n\n guardian\n .command('uninstall')\n .description('Remove the system service entry (state file is kept)')\n .action(async () => {\n await uninstallGuardianCommand();\n });\n\n guardian\n .command('status')\n .description('Show guardian / dsh / safe-mode state')\n .option('--dsh-profile <name>', 'dsh profile to inspect')\n .option('--bridge-profile <name>', 'bridge state profile to inspect')\n .action(async (opts: { dshProfile?: string; bridgeProfile?: string }) => {\n await statusGuardianCommand(opts);\n });\n\n return program;\n}\n\nexport async function main(argv: readonly string[] = process.argv): Promise<void> {\n await buildProgram().parseAsync([...argv]);\n}\n\n/**\n * True when this module is being executed directly (e.g. `node dist/cli.js run`)\n * rather than imported by a bin wrapper. The background service runs\n * `node <package>/dist/cli.js run`, so the bundle must self-execute in that case.\n */\nexport function isDirectInvocation(\n entry: string | undefined = process.argv[1],\n metaUrl: string = import.meta.url,\n): boolean {\n if (!entry) return false;\n try {\n return realpathSync(entry) === fileURLToPath(metaUrl);\n } catch {\n return false;\n }\n}\n\nif (isDirectInvocation()) {\n await main();\n}\n","import { stat } from 'node:fs/promises';\nimport { buildAgentAdapter } from '../../adapters/index.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport type { StartOptions } from '../../cli.js';\n\nexport interface DoctorOptions extends StartOptions {\n version?: string;\n output?: (text: string) => void;\n}\n\nexport async function runDoctor(options: DoctorOptions): Promise<void> {\n const env = loadRuntimeEnv({\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n });\n const paths = resolveAppPaths(env.home);\n const profileName = options.profile ?? 'default';\n const store = new ConfigStore(paths.configFile);\n await store.load();\n const profile = store.getProfile(profileName);\n\n const lines: string[] = [\n 'dsh-lark-bot doctor',\n `version: ${options.version ?? 'unknown'}`,\n `node: ${process.version}`,\n `profile: ${profileName}`,\n `home: ${paths.root}`,\n `adapter: ${env.adapterMode}`,\n `dsh_command: ${env.dshCommand}`,\n `dsh_args: ${env.dshArgs.join(',')}`,\n ];\n\n let critical = false;\n\n if (!profile) {\n lines.push('config: missing');\n critical = true;\n } else {\n lines.push(\n [\n 'config: ok',\n `tenant=${profile.tenant}`,\n `app_id=${profile.accounts.appId}`,\n `app_secret=${profile.accounts.appSecret ? 'present' : 'missing'}`,\n `allowed_users=${profile.access.allowedUsers.length}`,\n `allowed_chats=${profile.access.allowedChats.length}`,\n ].join(' '),\n );\n if (!profile.accounts.appId || !profile.accounts.appSecret) critical = true;\n }\n\n const workspace =\n options.workspace ??\n profile?.workspaces.default ??\n env.workspace ??\n paths.profilePath(profileName, 'workspace');\n try {\n const info = await stat(workspace);\n lines.push(`workspace: ${workspace} (${info.isDirectory() ? 'directory' : 'not-directory'})`);\n } catch {\n lines.push(`workspace: ${workspace} (missing)`);\n }\n\n try {\n const adapter = await buildAgentAdapter(env, {\n stopGraceMs: profile?.preferences.stopGraceMs,\n model: profile?.preferences.model,\n });\n const availability = await adapter.checkAvailability();\n if (availability.ok) {\n lines.push(`dsh: ok${availability.version ? ` (${availability.version})` : ''}`);\n } else {\n lines.push(`dsh: unavailable (${availability.error ?? 'unknown'})`);\n critical = true;\n }\n await adapter.dispose?.();\n } catch (error) {\n lines.push(`dsh: unavailable (${error instanceof Error ? error.message : String(error)})`);\n critical = true;\n }\n\n const output = options.output ?? ((text: string) => process.stdout.write(text));\n output(`${lines.join('\\n')}\\n`);\n if (critical) process.exitCode = 1;\n}\n","import { homedir } from 'node:os';\nimport type { RuntimeEnv } from '../config/env.js';\nimport { DshAdapter } from './dsh/adapter.js';\nimport { SdkDshAdapter } from './dsh/sdk-adapter.js';\nimport { ensureSdkProfile, resolveSdkLaunch } from './dsh/sdk-runtime.js';\nimport type { AgentAdapter } from './types.js';\n\nexport interface AdapterPreferences {\n stopGraceMs: number | undefined;\n model: string | undefined;\n}\n\n/**\n * Build the agent adapter for the configured mode:\n * - `sdk` (default): official `@deepseek-ai/dsh-sdk-client` runtime.\n * - `acp`: official ACP server runtime with approval cards.\n * - `headless`: legacy subprocess fallback (kept for compatibility).\n */\nexport async function buildAgentAdapter(\n env: RuntimeEnv,\n preferences: AdapterPreferences = { stopGraceMs: undefined, model: undefined },\n): Promise<AgentAdapter> {\n switch (env.adapterMode) {\n case 'headless': {\n const options: ConstructorParameters<typeof DshAdapter>[0] = {\n command: env.dshCommand,\n args: env.dshArgs,\n };\n if (preferences.stopGraceMs !== undefined) {\n options.stopGraceMs = preferences.stopGraceMs;\n }\n return new DshAdapter(options);\n }\n case 'acp': {\n const { buildAcpAgentAdapter } = await import('./dsh/acp-adapter.js');\n return buildAcpAgentAdapter(env, preferences);\n }\n case 'sdk':\n default: {\n const runtimeOptions = {\n home: homedir(),\n env: process.env,\n ...(env.dshExplicit\n ? { command: env.dshCommand, args: env.dshArgs }\n : {}),\n };\n const ensure = await ensureSdkProfile(runtimeOptions);\n if (!ensure.ok) {\n throw new Error(\n `SDK runtime profile setup failed: ${ensure.error ?? 'unknown error'} ` +\n '(install pnpm, or set DSH_LARK_ADAPTER=headless for the legacy adapter)',\n );\n }\n const launch = resolveSdkLaunch(runtimeOptions);\n return new SdkDshAdapter({\n launch,\n provider: env.provider,\n model: preferences.model ?? env.model,\n ...(env.maxTokens === undefined ? {} : { maxTokens: env.maxTokens }),\n });\n }\n }\n}\n","import { spawn } from 'cross-spawn';\nimport { createInterface } from 'node:readline';\nimport type { ChildProcess } from 'node:child_process';\nimport { checkDshAvailability } from './availability.js';\nimport { plainOutputEvent, translateDshLine } from './translate.js';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentEvent,\n AgentRun,\n AgentRunOptions,\n} from '../types.js';\n\nexport interface DshAdapterOptions {\n command?: string;\n args?: string[];\n stopGraceMs?: number;\n}\n\ntype DshChild = ChildProcess;\n\nexport class DshAdapter implements AgentAdapter {\n readonly id = 'dsh';\n readonly displayName = 'DeepSeek Harness';\n\n private readonly command: string;\n private readonly args: string[];\n private readonly stopGraceMs: number;\n\n constructor(options: DshAdapterOptions = {}) {\n this.command = options.command ?? 'dsh';\n this.args = options.args ?? ['--profile', 'headless'];\n this.stopGraceMs = options.stopGraceMs ?? 5_000;\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n checkAvailability(): Promise<AgentAvailability> {\n return checkDshAvailability({ command: this.command, args: this.args });\n }\n\n run(options: AgentRunOptions): AgentRun {\n const prompt =\n options.images?.length\n ? `${options.prompt}\\n\\nImage files attached to this message:\\n${options.images.join('\\n')}`\n : options.prompt;\n\n const child = spawn(\n this.command,\n [...this.args, prompt],\n {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n },\n ) as DshChild;\n\n child.stdin?.end();\n\n const stderrChunks: Buffer[] = [];\n let runtimeError: Error | null = null;\n child.stderr?.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n child.on('error', (error: Error) => {\n runtimeError = error;\n });\n\n return {\n runId: options.runId,\n events: createEventStream(child, stderrChunks, () => runtimeError, {\n sessionId: options.sessionId,\n cwd: options.cwd,\n model: options.model,\n }),\n stop: () => stopChild(child, this.stopGraceMs),\n waitForExit: (timeoutMs) => waitForChildExit(child, timeoutMs),\n };\n }\n}\n\nasync function* createEventStream(\n child: DshChild,\n stderrChunks: Buffer[],\n getError: () => Error | null,\n system: {\n sessionId: string | undefined;\n cwd: string | undefined;\n model: string | undefined;\n },\n): AsyncGenerator<AgentEvent> {\n if (!child.pid) {\n const error = getError();\n yield {\n type: 'error',\n message: error ? `failed to spawn dsh: ${error.message}` : 'spawn returned no pid',\n terminationReason: 'failed',\n };\n return;\n }\n\n yield {\n type: 'system',\n sessionId: system.sessionId,\n cwd: system.cwd,\n model: system.model,\n };\n\n if (!child.stdout) {\n yield {\n type: 'error',\n message: 'dsh stdout stream is unavailable',\n terminationReason: 'failed',\n };\n return;\n }\n\n const lines = createInterface({ input: child.stdout, crlfDelay: Infinity });\n const plainLines: string[] = [];\n let emittedProtocol = false;\n let terminalEmitted = false;\n\n for await (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const events = translateDshLine(trimmed);\n if (events.length > 0) {\n emittedProtocol = true;\n for (const event of events) {\n if (event.type === 'done' || event.type === 'error') terminalEmitted = true;\n yield event;\n }\n } else {\n plainLines.push(trimmed);\n }\n }\n\n const exitCode = await waitForExitResult(child, 0).then((value) => value.code);\n const runtimeError = getError();\n\n if (!terminalEmitted) {\n if (exitCode !== null && exitCode !== 0) {\n const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();\n const detail = stderr ? `: ${stderr.slice(0, 500)}` : '';\n yield {\n type: 'error',\n message: `dsh exited with code ${exitCode}${detail}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (runtimeError) {\n yield {\n type: 'error',\n message: `dsh runtime error: ${runtimeError.message}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (emittedProtocol) {\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n } else {\n yield* plainOutputEvent(plainLines.join('\\n'));\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n }\n }\n}\n\nasync function waitForExitResult(\n child: DshChild,\n timeoutMs: number,\n): Promise<{ code: number | null; timedOut: boolean }> {\n if (child.exitCode !== null || child.signalCode !== null) {\n return { code: child.exitCode, timedOut: false };\n }\n\n return new Promise((resolve) => {\n const onExit = (code: number | null): void => {\n if (timer !== undefined) clearTimeout(timer);\n resolve({ code, timedOut: false });\n };\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n child.removeListener('exit', onExit);\n resolve({ code: child.exitCode, timedOut: true });\n }, timeoutMs)\n : undefined;\n child.once('exit', onExit);\n });\n}\n\nasync function stopChild(child: DshChild, graceMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return;\n child.kill('SIGTERM');\n const stopped = await waitForExitResult(child, graceMs);\n if (!stopped.timedOut) return;\n child.kill('SIGKILL');\n}\n\nasync function waitForChildExit(child: DshChild, timeoutMs: number): Promise<boolean> {\n const result = await waitForExitResult(child, timeoutMs);\n return !result.timedOut && result.code !== null;\n}\n","import { spawn } from 'cross-spawn';\nimport { existsSync } from 'node:fs';\nimport type { AgentAvailability } from '../types.js';\n\nexport interface AvailabilityCheckOptions {\n command: string;\n args?: string[];\n timeoutMs?: number;\n}\n\nexport async function checkDshAvailability(\n options: AvailabilityCheckOptions,\n): Promise<AgentAvailability> {\n const timeoutMs = options.timeoutMs ?? 5_000;\n const versionArgs = options.command === 'node' && options.args?.[0] && existsSync(options.args[0])\n ? [options.args[0], '--version']\n : ['--version'];\n\n return new Promise((resolve) => {\n const child = spawn(options.command, versionArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const finish = (result: AgentAvailability): void => {\n if (settled) return;\n settled = true;\n resolve(result);\n };\n\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n finish({ ok: false, error: `timed out after ${timeoutMs}ms`, version: undefined });\n }, timeoutMs);\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n clearTimeout(timer);\n finish({ ok: false, error: error.message, version: undefined });\n });\n child.on('exit', (code) => {\n clearTimeout(timer);\n const version = stdout.trim();\n if (code !== 0 && !version) {\n finish({ ok: false, error: stderr.trim() || `exited with code ${String(code)}`, version: undefined });\n return;\n }\n finish({ ok: true, error: undefined, version: version || undefined });\n });\n });\n}\n","import type { AgentEvent } from '../types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function translateDshLine(line: string): AgentEvent[] {\n const trimmed = line.trim();\n if (!trimmed) return [];\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isRecord(parsed) || typeof parsed.type !== 'string') return [];\n\n switch (parsed.type) {\n case 'system':\n return [\n {\n type: 'system',\n sessionId: stringValue(parsed.sessionId),\n cwd: stringValue(parsed.cwd),\n model: stringValue(parsed.model),\n },\n ];\n case 'text':\n return [{ type: 'text', delta: stringValue(parsed.delta) ?? '' }];\n case 'final_text':\n return [{ type: 'final_text', content: stringValue(parsed.content) ?? '' }];\n case 'thinking':\n return [{ type: 'thinking', delta: stringValue(parsed.delta) ?? '' }];\n case 'tool_use':\n return [\n {\n type: 'tool_use',\n id: stringValue(parsed.id) ?? 'unknown',\n name: stringValue(parsed.name) ?? 'tool',\n input: parsed.input,\n },\n ];\n case 'tool_result':\n return [\n {\n type: 'tool_result',\n id: stringValue(parsed.id) ?? 'unknown',\n output: stringValue(parsed.output) ?? '',\n isError: parsed.isError === true,\n },\n ];\n case 'done':\n return [\n {\n type: 'done',\n sessionId: stringValue(parsed.sessionId),\n terminationReason: 'normal',\n },\n ];\n case 'error':\n return [\n {\n type: 'error',\n message: stringValue(parsed.message) ?? 'dsh failed',\n terminationReason: 'failed',\n },\n ];\n default:\n return [];\n }\n } catch {\n return [];\n }\n}\n\nexport function plainOutputEvent(output: string): AgentEvent[] {\n const trimmed = output.trim();\n return trimmed ? [{ type: 'final_text', content: trimmed }] : [];\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n DeepSeekHarness,\n HarnessClient,\n} from '@deepseek-ai/dsh-sdk-client';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentRun,\n AgentRunOptions,\n} from '../types.js';\nimport { createSdkRun } from './sdk-translate.js';\nimport type { SdkLaunchSpec } from './sdk-runtime.js';\n\nexport interface SdkAdapterOptions {\n /** Launch spec for the SDK runtime subprocess (command + args, no cwd). */\n launch: SdkLaunchSpec;\n provider: string;\n model: string;\n maxTokens?: number;\n /** Per-request timeout for the availability probe. */\n probeTimeoutMs?: number;\n /** Injectable harness factory for tests. */\n harnessFactory?: (cwd: string) => DeepSeekHarness;\n}\n\ninterface RuntimeEntry {\n harness: DeepSeekHarness;\n}\n\nfunction waitWithTimeout(promise: Promise<unknown>, timeoutMs: number): Promise<boolean> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), timeoutMs > 0 ? timeoutMs : 5_000);\n promise.then(\n () => {\n clearTimeout(timer);\n resolve(true);\n },\n () => {\n clearTimeout(timer);\n resolve(true);\n },\n );\n });\n}\n\n/**\n * Official DeepSeek Harness SDK adapter. Replaces the hand-written headless\n * subprocess protocol with `@deepseek-ai/dsh-sdk-client`: one runtime per\n * workspace cwd, native `session(id)` continuation, and token-level streaming\n * events (`assistant/chunk` reasoning/text deltas).\n */\nexport class SdkDshAdapter implements AgentAdapter {\n readonly id = 'dsh-sdk';\n readonly displayName = 'DeepSeek Harness (SDK)';\n\n private readonly launch: SdkLaunchSpec;\n private readonly provider: string;\n private readonly model: string;\n private readonly maxTokens: number | undefined;\n private readonly probeTimeoutMs: number;\n private readonly harnessFactory: (cwd: string) => DeepSeekHarness;\n private readonly runtimes = new Map<string, RuntimeEntry>();\n private disposed = false;\n\n constructor(options: SdkAdapterOptions) {\n this.launch = options.launch;\n this.provider = options.provider;\n this.model = options.model;\n this.maxTokens = options.maxTokens;\n this.probeTimeoutMs = options.probeTimeoutMs ?? 15_000;\n this.harnessFactory = options.harnessFactory ?? ((cwd) => this.createHarness(cwd));\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n async checkAvailability(): Promise<AgentAvailability> {\n if (this.disposed) {\n return { ok: false, error: 'adapter disposed', version: undefined };\n }\n const client = new HarnessClient({\n command: this.launch.command,\n args: this.launch.args,\n cwd: process.cwd(),\n requestTimeoutMs: this.probeTimeoutMs,\n });\n try {\n client.start();\n const info = await client.initialize({\n cwd: process.cwd(),\n provider: this.provider,\n model: this.model,\n ...(this.maxTokens === undefined ? {} : { maxTokens: this.maxTokens }),\n });\n return {\n ok: true,\n error: undefined,\n version: `${info.serverInfo.name}@${info.serverInfo.version}`,\n };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n version: undefined,\n };\n } finally {\n await client.close();\n }\n }\n\n run(options: AgentRunOptions): AgentRun {\n const cwd = options.cwd ?? process.cwd();\n const entry = this.runtimeFor(cwd);\n const sessionId =\n options.sessionId ?? `session-${randomUUID().replaceAll('-', '')}`;\n const stopRequested = { value: false };\n const handle = createSdkRun(entry.harness, options.prompt, {\n sessionId,\n cwd,\n model: options.model ?? this.model,\n images: options.images,\n stopRequested,\n });\n\n return {\n runId: options.runId,\n events: handle.events,\n stop: async () => {\n stopRequested.value = true;\n await this.closeRuntime(cwd);\n },\n waitForExit: (timeoutMs) => waitWithTimeout(handle.settled, timeoutMs),\n };\n }\n\n /** Close every runtime subprocess (used on bridge shutdown). */\n async dispose(): Promise<void> {\n this.disposed = true;\n const entries = [...this.runtimes.values()];\n this.runtimes.clear();\n await Promise.allSettled(\n entries.map((entry) => entry.harness.close()),\n );\n }\n\n private createHarness(cwd: string): DeepSeekHarness {\n return new DeepSeekHarness({\n launch: {\n command: this.launch.command,\n args: this.launch.args,\n cwd,\n },\n cwd,\n provider: this.provider,\n model: this.model,\n ...(this.maxTokens === undefined ? {} : { maxTokens: this.maxTokens }),\n });\n }\n\n private runtimeFor(cwd: string): RuntimeEntry {\n if (this.disposed) {\n throw new Error('SdkDshAdapter is disposed');\n }\n const existing = this.runtimes.get(cwd);\n if (existing) return existing;\n const entry: RuntimeEntry = { harness: this.harnessFactory(cwd) };\n this.runtimes.set(cwd, entry);\n return entry;\n }\n\n private async closeRuntime(cwd: string): Promise<void> {\n const entry = this.runtimes.get(cwd);\n if (!entry) return;\n this.runtimes.delete(cwd);\n try {\n await entry.harness.close();\n } catch (error) {\n // Closing is best-effort; the runtime process teardown ladder is\n // already idempotent inside the SDK client.\n void error;\n }\n }\n}\n","import type { DeepSeekHarness, HarnessNotification } from '@deepseek-ai/dsh-sdk-client';\nimport type { AgentEvent } from '../types.js';\nimport { EventChannel } from './event-channel.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction safeParseJson(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value) as unknown;\n } catch {\n return value;\n }\n}\n\nfunction textOfBlocks(blocks: unknown): string {\n if (!Array.isArray(blocks)) return '';\n return blocks\n .filter(isRecord)\n .filter((block) => block.type === 'text' && typeof block.text === 'string')\n .map((block) => block.text as string)\n .join('');\n}\n\ninterface ToolDeltaTracker {\n emitted: Set<string>;\n}\n\nfunction translateChunk(chunk: unknown, tracker: ToolDeltaTracker): AgentEvent[] {\n if (!isRecord(chunk)) return [];\n switch (chunk.type) {\n case 'reasoning-delta':\n return typeof chunk.text === 'string' && chunk.text\n ? [{ type: 'thinking', delta: chunk.text }]\n : [];\n case 'text-delta':\n return typeof chunk.text === 'string' && chunk.text\n ? [{ type: 'text', delta: chunk.text }]\n : [];\n case 'tool-call-delta': {\n const id = stringValue(chunk.id);\n if (!id || tracker.emitted.has(id)) return [];\n tracker.emitted.add(id);\n return [\n {\n type: 'tool_use',\n id,\n name: stringValue(chunk.name) ?? 'tool',\n input: {},\n },\n ];\n }\n default:\n return [];\n }\n}\n\nfunction translateToolResult(data: unknown): AgentEvent[] {\n if (!isRecord(data)) return [];\n const message = isRecord(data.message) ? data.message : undefined;\n const block = Array.isArray(message?.content) ? message.content[0] : undefined;\n const toolCallId = stringValue(\n isRecord(block) ? block.toolCallId : undefined,\n );\n if (!toolCallId) return [];\n const output = textOfBlocks(isRecord(block) ? block.content : undefined);\n const isError =\n data.error !== undefined || (isRecord(block) ? block.isError === true : false);\n return [\n {\n type: 'tool_result',\n id: toolCallId,\n output,\n isError,\n },\n ];\n}\n\nfunction translateAssistantMessage(data: unknown): AgentEvent[] {\n if (!isRecord(data) || !isRecord(data.usage)) return [];\n const usage = data.usage;\n const inputTokens =\n typeof usage.inputTokens === 'number' ? usage.inputTokens : undefined;\n const outputTokens =\n typeof usage.outputTokens === 'number' ? usage.outputTokens : undefined;\n if (inputTokens === undefined && outputTokens === undefined) return [];\n return [\n {\n type: 'usage',\n ...(inputTokens === undefined ? {} : { inputTokens }),\n ...(outputTokens === undefined ? {} : { outputTokens }),\n },\n ];\n}\n\nfunction translateTurnEnd(data: unknown): AgentEvent[] {\n if (!isRecord(data) || !isRecord(data.reason) || data.reason.kind !== 'error') return [];\n const failure = isRecord(data.reason.error) ? data.reason.error : undefined;\n const message = stringValue(failure?.message) ?? 'dsh turn failed';\n return [{ type: 'error', message, terminationReason: 'failed' }];\n}\n\n/**\n * Translate one SDK session event into bridge `AgentEvent`s.\n * Token-level `assistant/chunk` deltas give the streaming (typewriter) card\n * experience: reasoning deltas feed the thinking section, text deltas feed\n * the output block, tool deltas surface live tool activity.\n */\nexport function translateSessionEvent(\n event: unknown,\n tracker: ToolDeltaTracker,\n): AgentEvent[] {\n if (!isRecord(event) || typeof event.type !== 'string') return [];\n switch (event.type) {\n case 'assistant/chunk':\n return translateChunk(isRecord(event.data) ? event.data.chunk : undefined, tracker);\n case 'tool/call': {\n const data = isRecord(event.data) ? event.data : undefined;\n const id = stringValue(data?.callId);\n if (!id) return [];\n return [\n {\n type: 'tool_use',\n id,\n name: stringValue(data?.name) ?? 'tool',\n input: safeParseJson(data?.arguments),\n },\n ];\n }\n case 'tool/result':\n return translateToolResult(event.data);\n case 'assistant/message':\n return translateAssistantMessage(event.data);\n case 'turn/end':\n return translateTurnEnd(event.data);\n default:\n return [];\n }\n}\n\nfunction translateNotification(\n notification: HarnessNotification,\n sessionId: string,\n tracker: ToolDeltaTracker,\n): AgentEvent[] {\n if (notification.method !== 'session.event') return [];\n const params = isRecord(notification.params) ? notification.params : undefined;\n if (params?.sessionId !== sessionId) return [];\n return translateSessionEvent(params.event, tracker);\n}\n\nexport interface SdkRunOptions {\n sessionId: string;\n cwd: string | undefined;\n model: string | undefined;\n images: readonly string[] | undefined;\n stopRequested: { value: boolean };\n}\n\nexport interface SdkRunHandle {\n events: AsyncIterable<AgentEvent>;\n /** Resolves when the underlying SDK turn settles (success or failure). */\n settled: Promise<void>;\n}\n\nfunction buildPromptText(prompt: string, images: readonly string[] | undefined): string {\n return images?.length\n ? `${prompt}\\n\\nImage files attached to this message:\\n${images.join('\\n')}`\n : prompt;\n}\n\n/**\n * Run one prompt on a harness session and stream the result as `AgentEvent`s.\n * The SDK client owns the runtime handshake; this helper owns the\n * notification-to-event translation and the run lifecycle.\n */\nexport function createSdkRun(\n harness: DeepSeekHarness,\n prompt: string,\n options: SdkRunOptions,\n): SdkRunHandle {\n const channel = new EventChannel<AgentEvent>();\n const tracker: ToolDeltaTracker = { emitted: new Set() };\n let hadError = false;\n\n const task = harness\n .run(buildPromptText(prompt, options.images), {\n sessionId: options.sessionId,\n onNotification: (notification) => {\n for (const event of translateNotification(notification, options.sessionId, tracker)) {\n if (event.type === 'error') hadError = true;\n channel.push(event);\n }\n },\n })\n .catch((error: unknown) => {\n if (!options.stopRequested.value) {\n channel.push({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n terminationReason: 'failed',\n });\n hadError = true;\n }\n })\n .finally(() => {\n channel.close();\n });\n\n async function* events(): AsyncGenerator<AgentEvent> {\n yield {\n type: 'system',\n sessionId: options.sessionId,\n cwd: options.cwd,\n model: options.model,\n };\n for await (const event of channel) {\n yield event;\n }\n await task;\n if (!hadError) {\n yield {\n type: 'done',\n sessionId: options.sessionId,\n terminationReason: options.stopRequested.value ? 'interrupted' : 'normal',\n };\n }\n }\n\n return { events: events(), settled: task.then(() => undefined) };\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { DSH_COMPATIBILITY } from '../../config/dsh-compat.js';\nimport { discoverDshBin, resolveDshHome } from '../../config/dsh-runtime.js';\nimport { ownPackageInfo } from './own-package.js';\n\nexport const SDK_SERVER_PACKAGE = '@deepseek-ai/dsh-sdk-jsonrpc-server';\nexport const SDK_SERVER_VERSION = DSH_COMPATIBILITY.sdkServer;\nexport const SDK_BASE_BUNDLE = '@deepseek-ai/dsh-base';\nexport const DEFAULT_SDK_PROFILE = 'dsh-lark';\n\nexport interface SdkRuntimeOptions {\n /** OS home directory used to resolve the shared dsh installation. */\n home: string;\n /** Environment snapshot for dsh home resolution (defaults to process.env). */\n env?: NodeJS.ProcessEnv;\n /** Explicit runtime command; overrides auto-discovery (from DSH_LARK_DSH_COMMAND). */\n command?: string;\n /** Explicit runtime args; overrides auto-discovery (from DSH_LARK_DSH_ARGS). */\n args?: string[];\n /** Discovered dsh bin path; used when command/args are not explicit. */\n bin?: string;\n /** Profile name for the SDK runtime composition. */\n profile?: string;\n /** Injectable installer for tests. */\n install?: (profileRoot: string) => Promise<void>;\n}\n\nexport interface SdkLaunchSpec {\n command: string;\n args: string[];\n profile: string;\n}\n\nexport interface SdkProfileEnsureResult {\n ok: boolean;\n created: boolean;\n error?: string;\n}\n\nexport function sdkProfileRoot(home: string, profile: string, env?: NodeJS.ProcessEnv): string {\n return join(resolveDshHome(home, env), 'profiles', profile);\n}\n\nfunction packageJsonFor(profile: string): string {\n const own = ownPackageInfo();\n return `${JSON.stringify(\n {\n name: `dsh-profile-${profile}`,\n private: true,\n dependencies: {\n [SDK_SERVER_PACKAGE]: SDK_SERVER_VERSION,\n [own.name]: `link:${own.root}`,\n },\n dsh: {\n profile: {\n bundles: [SDK_BASE_BUNDLE],\n },\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction patchYamlFor(): string {\n const own = ownPackageInfo();\n return [\n '# dsh-lark SDK JSON-RPC runtime overlay (managed by dsh-lark-bot).',\n '# stdout is reserved for SDK JSON-RPC frames; no console logger may load.',\n '- insert:',\n ' - id: sdk-jsonrpc-server',\n ` name: '${SDK_SERVER_PACKAGE}'`,\n ' config:',\n ' maxTokensAsSuccess: true',\n '',\n '# Unattended IM runtime: interactive user questions cannot be answered',\n '# through Feishu, so the tool is disabled (default-deny).',\n '- id: user-questions',\n ' disabled: true',\n '',\n '- id: system-prompt',\n ' config:',\n ' persona: >-',\n ' You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.',\n '',\n '- id: hmr',\n ' disabled: true',\n '',\n // In-process bridge callback tool: lets the agent mention users and push\n // messages to other chats/topics through the running bridge process.\n '- insert:',\n ' - id: lark-notify',\n ` name: '${own.name}/notify'`,\n ' config:',\n ' endpoint: !!js process.env.DSH_LARK_NOTIFY_URL',\n ' token: !!js process.env.DSH_LARK_NOTIFY_TOKEN',\n '',\n ].join('\\n');\n}\n\nfunction sdkServerInstalled(profileRoot: string): boolean {\n const candidates = [\n join(profileRoot, 'node_modules', SDK_SERVER_PACKAGE),\n join(profileRoot, '..', 'node_modules', SDK_SERVER_PACKAGE),\n ];\n return candidates.some((path) => existsSync(path));\n}\n\nexport function isSdkProfileReady(profileRoot: string): boolean {\n const own = ownPackageInfo();\n return (\n existsSync(join(profileRoot, 'package.json')) &&\n existsSync(join(profileRoot, 'cordis.yml')) &&\n existsSync(join(profileRoot, 'cordis.patch.yml')) &&\n sdkServerInstalled(profileRoot) &&\n ownPackageLinked(profileRoot, own.name)\n );\n}\n\n/** True when the profile's node_modules link resolves to this package. */\nfunction ownPackageLinked(profileRoot: string, ownName: string): boolean {\n const linkPath = join(profileRoot, 'node_modules', ownName);\n try {\n const real = realpathSync(linkPath);\n const pkg = JSON.parse(readFileSync(join(real, 'package.json'), 'utf8')) as {\n name?: unknown;\n dsh?: { bundle?: { patch?: unknown } };\n };\n return (\n pkg.name === ownName &&\n pkg.dsh?.bundle?.patch !== undefined\n );\n } catch {\n return false;\n }\n}\n\nfunction runPnpmInstall(profileRoot: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['install'], {\n cwd: profileRoot,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let output = '';\n child.stdout.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n reject(error);\n });\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n const tail = output.trim().split('\\n').slice(-8).join('\\n');\n reject(new Error(`pnpm install exited with code ${String(code)}\\n${tail}`));\n });\n });\n}\n\n/**\n * Ensure the SDK runtime profile exists under the shared dsh installation.\n * The profile is a managed composition: `@deepseek-ai/dsh-base` bundle plus\n * the official `@deepseek-ai/dsh-sdk-jsonrpc-server` plugin. Idempotent.\n */\nexport async function ensureSdkProfile(\n options: SdkRuntimeOptions,\n): Promise<SdkProfileEnsureResult> {\n const profile = options.profile ?? DEFAULT_SDK_PROFILE;\n const root = sdkProfileRoot(options.home, profile, options.env);\n if (isSdkProfileReady(root)) return { ok: true, created: false };\n\n try {\n await mkdir(root, { recursive: true });\n await writeFile(join(root, 'package.json'), packageJsonFor(profile), 'utf8');\n await writeFile(join(root, 'cordis.yml'), '[]\\n', 'utf8');\n await writeFile(join(root, 'cordis.patch.yml'), patchYamlFor(), 'utf8');\n const install = options.install ?? runPnpmInstall;\n if (!isSdkProfileReady(root)) {\n await install(root);\n }\n if (!isSdkProfileReady(root)) {\n return {\n ok: false,\n created: true,\n error: `${SDK_SERVER_PACKAGE}@${SDK_SERVER_VERSION} was not found after install`,\n };\n }\n return { ok: true, created: true };\n } catch (error) {\n return {\n ok: false,\n created: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/** Resolve the launch spec for the SDK runtime subprocess. */\nexport function resolveSdkLaunch(options: SdkRuntimeOptions): SdkLaunchSpec {\n const profile = options.profile ?? DEFAULT_SDK_PROFILE;\n if (options.command || options.args) {\n return {\n command: options.command ?? 'node',\n args: options.args ?? ['--profile', profile],\n profile,\n };\n }\n const bin = options.bin ?? discoverDshBin(options.home, options.env);\n if (bin) {\n return { command: 'node', args: [bin, '--profile', profile], profile };\n }\n return { command: 'dsh', args: ['--profile', profile], profile };\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\nexport interface AppPaths {\n root: string;\n configFile: string;\n activeProfileFile: string;\n profileDir: (profile: string) => string;\n profilePath: (profile: string, ...parts: string[]) => string;\n sessionsFile: (profile: string) => string;\n sessionCatalogFile: (profile: string) => string;\n archivesDir: (profile: string) => string;\n workspacesFile: (profile: string) => string;\n mediaDir: (profile: string) => string;\n logsDir: (profile: string) => string;\n}\n\nexport function defaultHome(): string {\n const override = process.env.DSH_LARK_HOME?.trim();\n return override ? resolve(override) : join(homedir(), '.dsh-lark');\n}\n\nexport function resolveAppPaths(root: string = defaultHome()): AppPaths {\n const profileDir = (profile: string): string => join(root, 'profiles', profile);\n const profilePath = (profile: string, ...parts: string[]): string =>\n join(profileDir(profile), ...parts);\n\n return {\n root,\n configFile: join(root, 'config.json'),\n activeProfileFile: join(root, 'active-profile'),\n profileDir,\n profilePath,\n sessionsFile: (profile) => profilePath(profile, 'sessions.json'),\n sessionCatalogFile: (profile) => profilePath(profile, 'sessions.json.catalog.json'),\n archivesDir: (profile) => profilePath(profile, 'archives'),\n workspacesFile: (profile) => profilePath(profile, 'workspaces.json'),\n mediaDir: (profile) => profilePath(profile, 'media'),\n logsDir: (profile) => profilePath(profile, 'logs'),\n };\n}\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { resolveDshRuntime } from './dsh-runtime.js';\n\nexport type LarkTenant = 'feishu' | 'lark';\nexport type AdapterMode = 'sdk' | 'acp' | 'headless';\n\nexport interface RuntimeEnv {\n home: string;\n tenant: LarkTenant;\n appId: string | undefined;\n appSecret: string | undefined;\n workspace: string | undefined;\n dshCommand: string;\n dshArgs: string[];\n /** True when DSH_LARK_DSH_COMMAND / DSH_LARK_DSH_ARGS were set explicitly. */\n dshExplicit: boolean;\n adapterMode: AdapterMode;\n provider: string;\n model: string;\n maxTokens: number | undefined;\n runTimeoutMs: number;\n stopGraceMs: number;\n /** Max agent runs allowed concurrently per scope (default 2). */\n scopeConcurrency: number;\n /** Live messages kept per scope before overflow is archived (default 40). */\n retentionMsgs: number;\n /** Max archives retained per scope before pruning (default 50, 0 disables). */\n archiveMax: number;\n /** Archives older than this many days are pruned (default 90, 0 disables). */\n archiveMaxAgeDays: number;\n accessDefaultDeny: boolean;\n eventFreshnessMs: number;\n /** Bridge engine heartbeat interval (guardian liveness signal), default 5000. */\n heartbeatMs: number;\n /** Guardian disabled switch (DSH_LARK_GUARDIAN_DISABLED=1 keeps it stopped). */\n guardianDisabled: boolean;\n /** dsh profile the guardian watches / relaunches (default `dsh-lark`). */\n guardianProfile: string;\n /** Bridge state profile providing Feishu credentials (default `default`). */\n guardianBridgeProfile: string;\n /** Guardian watchdog poll interval, default 2000. */\n guardianPollMs: number;\n /** Heartbeat staleness threshold before takeover, default 15000. */\n guardianStaleMs: number;\n /**\n * When a dsh process is alive but the bridge heartbeat has been stale for\n * longer than this, treat the engine as dead and take over (default 120000).\n */\n guardianEngineDeadMs: number;\n}\n\nconst DEFAULTS = {\n tenant: 'feishu' as const,\n provider: 'deepseek-official',\n model: 'deepseek-v4-flash',\n runTimeoutMs: 300_000,\n stopGraceMs: 5_000,\n scopeConcurrency: 2,\n retentionMsgs: 40,\n archiveMax: 50,\n archiveMaxAgeDays: 90,\n heartbeatMs: 5_000,\n guardianPollMs: 2_000,\n guardianStaleMs: 15_000,\n guardianEngineDeadMs: 120_000,\n guardianProfile: 'dsh-lark',\n guardianBridgeProfile: 'default',\n};\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction parseTenant(value: string | undefined): LarkTenant {\n const tenant = nonEmpty(value) ?? DEFAULTS.tenant;\n if (tenant !== 'feishu' && tenant !== 'lark') {\n throw new Error(`DSH_LARK_TENANT must be \"feishu\" or \"lark\", got \"${tenant}\"`);\n }\n return tenant;\n}\n\nfunction parseDshArgs(value: string | undefined): string[] {\n const raw = value?.trim();\n if (!raw) return [];\n return raw\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction parseTimeout(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.runTimeoutMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_RUN_TIMEOUT_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseStopGrace(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.stopGraceMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_STOP_GRACE_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseAdapterMode(value: string | undefined): AdapterMode {\n const mode = nonEmpty(value) ?? 'sdk';\n if (mode !== 'sdk' && mode !== 'acp' && mode !== 'headless') {\n throw new Error(`DSH_LARK_ADAPTER must be \"sdk\", \"acp\" or \"headless\", got \"${mode}\"`);\n }\n return mode;\n}\n\nfunction parseMaxTokens(value: string | undefined): number | undefined {\n const raw = value?.trim();\n if (!raw) return undefined;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`DSH_LARK_MAX_TOKENS must be a positive integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseBoolean(value: string | undefined, fallback: boolean): boolean {\n const raw = value?.trim().toLowerCase();\n if (!raw) return fallback;\n if (raw === '1' || raw === 'true' || raw === 'yes') return true;\n if (raw === '0' || raw === 'false' || raw === 'no') return false;\n return fallback;\n}\n\nfunction parseFreshness(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return 600_000;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_EVENT_FRESHNESS_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number, name: string): number {\n const raw = value?.trim();\n if (!raw) return fallback;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`${name} must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseMinOneInt(value: string | undefined, fallback: number, name: string): number {\n const raw = value?.trim();\n if (!raw) return fallback;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new Error(`${name} must be a positive integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parsePositiveIntMin(value: string | undefined, fallback: number, name: string): number {\n const raw = value?.trim();\n if (!raw) return fallback;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new Error(`${name} must be a positive integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nexport function loadRuntimeEnv(\n source: NodeJS.ProcessEnv = process.env,\n): RuntimeEnv {\n const homeOverride = nonEmpty(source.DSH_LARK_HOME);\n const workspace = nonEmpty(source.DSH_LARK_WORKSPACE);\n const home = homeOverride ? resolve(homeOverride) : join(homedir(), '.dsh-lark');\n const osHome = homedir();\n const explicitCommand = nonEmpty(source.DSH_LARK_DSH_COMMAND);\n const rawDshArgs = nonEmpty(source.DSH_LARK_DSH_ARGS);\n const dshExplicit = explicitCommand !== undefined || rawDshArgs !== undefined;\n const dshRuntime = resolveDshRuntime({\n home: osHome,\n env: source,\n ...(explicitCommand ? { command: explicitCommand } : {}),\n ...(rawDshArgs ? { args: parseDshArgs(rawDshArgs) } : {}),\n });\n\n return {\n home,\n tenant: parseTenant(source.DSH_LARK_TENANT),\n appId: nonEmpty(source.DSH_LARK_APP_ID),\n appSecret: nonEmpty(source.DSH_LARK_APP_SECRET),\n workspace: workspace ? resolve(workspace) : undefined,\n dshCommand: dshRuntime.command,\n dshArgs: dshRuntime.args,\n dshExplicit,\n adapterMode: parseAdapterMode(source.DSH_LARK_ADAPTER),\n provider: nonEmpty(source.DSH_LARK_PROVIDER) ?? DEFAULTS.provider,\n model: nonEmpty(source.DSH_LARK_MODEL) ?? DEFAULTS.model,\n maxTokens: parseMaxTokens(source.DSH_LARK_MAX_TOKENS),\n runTimeoutMs: parseTimeout(source.DSH_LARK_RUN_TIMEOUT_MS),\n stopGraceMs: parseStopGrace(source.DSH_LARK_STOP_GRACE_MS),\n scopeConcurrency: parseMinOneInt(\n source.DSH_LARK_SCOPE_CONCURRENCY,\n DEFAULTS.scopeConcurrency,\n 'DSH_LARK_SCOPE_CONCURRENCY',\n ),\n retentionMsgs: parsePositiveInt(\n source.DSH_LARK_RETENTION_MSGS,\n DEFAULTS.retentionMsgs,\n 'DSH_LARK_RETENTION_MSGS',\n ),\n archiveMax: parsePositiveInt(\n source.DSH_LARK_ARCHIVE_MAX,\n DEFAULTS.archiveMax,\n 'DSH_LARK_ARCHIVE_MAX',\n ),\n archiveMaxAgeDays: parsePositiveInt(\n source.DSH_LARK_ARCHIVE_MAX_AGE_DAYS,\n DEFAULTS.archiveMaxAgeDays,\n 'DSH_LARK_ARCHIVE_MAX_AGE_DAYS',\n ),\n accessDefaultDeny: parseBoolean(source.DSH_LARK_ACCESS_DEFAULT_DENY, false),\n eventFreshnessMs: parseFreshness(source.DSH_LARK_EVENT_FRESHNESS_MS),\n heartbeatMs: parsePositiveIntMin(\n source.DSH_LARK_HEARTBEAT_MS,\n DEFAULTS.heartbeatMs,\n 'DSH_LARK_HEARTBEAT_MS',\n ),\n guardianDisabled: parseBoolean(source.DSH_LARK_GUARDIAN_DISABLED, false),\n guardianProfile:\n nonEmpty(source.DSH_LARK_GUARDIAN_PROFILE) ?? DEFAULTS.guardianProfile,\n guardianBridgeProfile:\n nonEmpty(source.DSH_LARK_GUARDIAN_BRIDGE_PROFILE) ?? DEFAULTS.guardianBridgeProfile,\n guardianPollMs: parsePositiveIntMin(\n source.DSH_LARK_GUARDIAN_POLL_MS,\n DEFAULTS.guardianPollMs,\n 'DSH_LARK_GUARDIAN_POLL_MS',\n ),\n guardianStaleMs: parsePositiveIntMin(\n source.DSH_LARK_GUARDIAN_STALE_MS,\n DEFAULTS.guardianStaleMs,\n 'DSH_LARK_GUARDIAN_STALE_MS',\n ),\n guardianEngineDeadMs: parsePositiveIntMin(\n source.DSH_LARK_GUARDIAN_ENGINE_DEAD_MS,\n DEFAULTS.guardianEngineDeadMs,\n 'DSH_LARK_GUARDIAN_ENGINE_DEAD_MS',\n ),\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport type { LarkTenant } from './env.js';\n\nexport interface ProfileConfig {\n schemaVersion: 1;\n agentKind: 'dsh';\n tenant: LarkTenant;\n accounts: {\n appId: string;\n appSecret: string;\n };\n workspaces: {\n default: string | undefined;\n };\n preferences: {\n model: string | undefined;\n stopGraceMs: number | undefined;\n runTimeoutMs: number | undefined;\n };\n access: {\n allowedUsers: string[];\n allowedChats: string[];\n admins: string[];\n };\n}\n\nexport interface RootConfig {\n schemaVersion: 1;\n activeProfile: string;\n profiles: Record<string, ProfileConfig>;\n}\n\nexport class ConfigStore {\n private data: RootConfig | undefined;\n\n constructor(private readonly path: string) {}\n\n async load(): Promise<RootConfig> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<RootConfig>;\n this.data = {\n schemaVersion: 1,\n activeProfile: parsed.activeProfile ?? 'default',\n profiles: Object.fromEntries(\n Object.entries(parsed.profiles ?? {}).map(([name, profile]) => [\n name,\n {\n ...profile,\n access: {\n allowedUsers: profile.access?.allowedUsers ?? [],\n allowedChats: profile.access?.allowedChats ?? [],\n admins: profile.access?.admins ?? [],\n },\n },\n ]),\n ),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = {\n schemaVersion: 1,\n activeProfile: 'default',\n profiles: {},\n };\n }\n return this.data;\n }\n\n getActiveProfile(): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[data.activeProfile];\n }\n\n getProfile(name: string): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[name];\n }\n\n async saveProfile(\n name: string,\n input: {\n tenant: LarkTenant;\n appId: string;\n appSecret: string;\n workspace?: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n operatorOpenId?: string;\n access?: {\n allowedUsers?: string[];\n allowedChats?: string[];\n admins?: string[];\n };\n },\n ): Promise<void> {\n const data = this.getData();\n const existing = data.profiles[name];\n const profile: ProfileConfig = {\n schemaVersion: 1,\n agentKind: 'dsh',\n tenant: input.tenant,\n accounts: {\n appId: input.appId,\n appSecret: input.appSecret,\n },\n workspaces: {\n default: input.workspace ?? existing?.workspaces.default ?? undefined,\n },\n preferences: {\n model: input.model ?? existing?.preferences.model ?? undefined,\n stopGraceMs: input.stopGraceMs ?? existing?.preferences.stopGraceMs ?? undefined,\n runTimeoutMs: input.runTimeoutMs ?? existing?.preferences.runTimeoutMs ?? undefined,\n },\n access: {\n allowedUsers: input.access?.allowedUsers ?? existing?.access?.allowedUsers ?? [],\n allowedChats: input.access?.allowedChats ?? existing?.access?.allowedChats ?? [],\n admins: input.access?.admins ?? existing?.access?.admins ?? [],\n },\n };\n if (input.operatorOpenId && !profile.access.allowedUsers.includes(input.operatorOpenId)) {\n profile.access.allowedUsers.push(input.operatorOpenId);\n profile.access.admins.push(input.operatorOpenId);\n }\n data.profiles[name] = profile;\n data.activeProfile = name;\n await this.persist();\n }\n\n private getData(): RootConfig {\n if (!this.data) {\n throw new Error('ConfigStore must be loaded before use');\n }\n return this.data;\n }\n\n private async persist(): Promise<void> {\n const data = this.getData();\n await mkdir(dirname(this.path), { recursive: true });\n await writeFileAtomic(this.path, `${JSON.stringify(data, null, 2)}\\n`, {\n mode: 0o600,\n });\n }\n}\n","import { randomBytes } from 'node:crypto';\nimport { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number;\n}\n\nexport async function writeFileAtomic(\n target: string,\n data: string,\n options: AtomicWriteOptions = {},\n): Promise<void> {\n const directory = dirname(target);\n await mkdir(directory, { recursive: true });\n const temporary = join(directory, `.${randomBytes(8).toString('hex')}.tmp`);\n\n try {\n await writeFile(temporary, data, options.mode === undefined ? undefined : { mode: options.mode });\n await rename(temporary, target);\n } catch (error) {\n await rmSilently(temporary);\n throw error;\n }\n}\n\nasync function rmSilently(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n try {\n await rm(path, { force: true });\n } catch {\n // best effort cleanup only\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport type { AgentAdapter } from '../../adapters/types.js';\nimport type { LarkChannel, NormalizedMessage } from '@larksuite/channel';\nimport type { RuntimeEnv } from '../../config/env.js';\nimport { buildAgentAdapter } from '../../adapters/index.js';\nimport { ActiveRuns } from '../../bot/active-runs.js';\nimport { ApprovalRegistry } from '../../bot/approvals.js';\nimport { ConcurrencyStore } from '../../bot/concurrency-store.js';\nimport { DensityStore } from '../../bot/density-store.js';\nimport { ModelStore } from '../../bot/model-store.js';\nimport { PendingQueue } from '../../bot/pending-queue.js';\nimport { QuestionRegistry } from '../../bot/questions.js';\nimport { RetentionStore } from '../../bot/retention-store.js';\nimport { RoleStore } from '../../bot/role-store.js';\nimport { RunPolicyStore } from '../../bot/run-policy.js';\nimport { startChannel } from '../../bridge/channel.js';\nimport { adaptLarkChannel } from '../../bridge/lark-channel.js';\nimport { runAgentBatch } from '../../bridge/run-flow.js';\nimport { ScopeDirectory } from '../../bridge/scope-directory.js';\nimport type { StreamingChannel } from '../../bridge/types.js';\nimport { generateNotifyToken, NotifyServer } from '../../notify/server.js';\nimport type { StartOptions } from '../../cli.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { AccessManager } from '../../config/access-manager.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport { DshProviderManager } from '../../config/dsh-config.js';\nimport { log } from '../../core/logger.js';\nimport { onboardPersonalAgent } from '../../onboard/registration.js';\nimport { prepareAttachments } from '../../media/attachments.js';\nimport { SessionStore } from '../../session/store.js';\nimport { SessionArchive } from '../../session/archive.js';\nimport { GitWorktreeManager } from '../../workspace/git-worktree.js';\nimport { WorkspaceStore } from '../../workspace/store.js';\nimport { startHeartbeat } from '../../guardian/heartbeat.js';\n\nconst DEBOUNCE_MS = 600;\n\nexport interface BridgeEngineStatus {\n state: 'running' | 'stopped';\n profile: string;\n home: string;\n adapterId: string;\n startedAt: string | undefined;\n workspace: string | undefined;\n notifyUrl: string | undefined;\n}\n\nexport interface BridgeEngine {\n readonly profile: string;\n readonly home: string;\n status(): BridgeEngineStatus;\n stop(): Promise<void>;\n}\n\nexport interface BridgeEngineOptions {\n env: RuntimeEnv;\n profileName: string;\n /** Allow first-run QR onboarding when no credentials exist. */\n allowOnboarding: boolean;\n /** Injectable channel factory (tests / host integration). */\n createChannel?: Parameters<typeof startChannel>[0]['createChannel'];\n /** Injectable adapter (tests); otherwise built from env. */\n adapter?: AgentAdapter;\n}\n\nexport interface EnsureProfileOptions {\n env: RuntimeEnv;\n profileName: string;\n allowOnboarding: boolean;\n}\n\nexport async function ensureBotProfile(\n store: ConfigStore,\n options: EnsureProfileOptions,\n): Promise<boolean> {\n const { env, profileName } = options;\n if (env.appId && env.appSecret) {\n const profileInput: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: env.tenant,\n appId: env.appId,\n appSecret: env.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (env.workspace !== undefined) profileInput.workspace = env.workspace;\n await store.saveProfile(profileName, profileInput);\n }\n\n if (store.getProfile(profileName)) return true;\n\n if (!options.allowOnboarding) {\n throw new Error('未检测到飞书 / Lark 应用凭据,且未允许扫码绑定。');\n }\n\n try {\n const created = await onboardPersonalAgent();\n const onboardingProfile: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: created.tenant,\n appId: created.appId,\n appSecret: created.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (created.operatorOpenId !== undefined) {\n onboardingProfile.operatorOpenId = created.operatorOpenId;\n }\n if (env.workspace !== undefined) onboardingProfile.workspace = env.workspace;\n await store.saveProfile(profileName, onboardingProfile);\n return true;\n } catch (error) {\n log.fail('onboarding', error);\n throw new Error(`扫码创建应用失败:${errorMessage(error)}`);\n }\n}\n\nfunction mergeStartEnv(options: StartOptions): NodeJS.ProcessEnv {\n return {\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n };\n}\n\n/**\n * Start the bridge engine. Runs the full Feishu channel pipeline (stores,\n * adapter, card queue, notify server) and returns a handle that can be\n * stopped. No process-level signal handling: the CLI wrapper owns signals,\n * and the dsh bundle plugin owns lifecycle via the cordis context.\n */\nexport async function startBridgeEngine(\n options: BridgeEngineOptions,\n): Promise<BridgeEngine> {\n const env = options.env;\n const paths = resolveAppPaths(env.home);\n const profileName = options.profileName;\n const configStore = new ConfigStore(paths.configFile);\n await configStore.load();\n\n const ready = await ensureBotProfile(configStore, {\n env,\n profileName,\n allowOnboarding: options.allowOnboarding,\n });\n if (!ready) {\n throw new Error('bot profile 未就绪。');\n }\n const activeProfile = configStore.getProfile(profileName);\n if (!activeProfile) {\n throw new Error('本地配置读取失败,请检查后重试。');\n }\n\n const defaultWorkspace =\n activeProfile.workspaces.default ?? env.workspace ?? paths.profilePath(profileName, 'workspace');\n await mkdir(defaultWorkspace, { recursive: true });\n\n const sessions = new SessionStore(paths.sessionsFile(profileName));\n const archiver = new SessionArchive(paths.archivesDir(profileName));\n const workspaces = new WorkspaceStore(paths.workspacesFile(profileName));\n const roleStore = new RoleStore(paths.profilePath(profileName, 'roles.json'));\n const scopeDirectory = new ScopeDirectory(paths.profilePath(profileName, 'scopes.json'));\n const worktreeManager = new GitWorktreeManager({\n worktreesRoot: paths.profilePath(profileName, 'worktrees'),\n });\n await Promise.all([\n sessions.load(),\n workspaces.load(),\n roleStore.load(),\n scopeDirectory.load(),\n ]);\n\n const adapter =\n options.adapter ??\n (await buildAgentAdapter(env, {\n stopGraceMs: activeProfile.preferences.stopGraceMs ?? env.stopGraceMs,\n model: activeProfile.preferences.model,\n }));\n const activeRuns = new ActiveRuns();\n const runPolicies = new RunPolicyStore();\n const concurrencyStore = new ConcurrencyStore();\n const retentionStore = new RetentionStore();\n const approvals = new ApprovalRegistry();\n const questions = new QuestionRegistry();\n const densityStore = new DensityStore();\n const models = new ModelStore();\n const dshConfig = new DshProviderManager({ env: process.env });\n let streaming: StreamingChannel | undefined;\n let larkChannel: LarkChannel | undefined;\n const notifyToken = generateNotifyToken();\n const notifyServer = new NotifyServer({\n token: notifyToken,\n resolve: (message) => {\n if (message.scope) {\n return scopeDirectory.resolve(message.scope);\n }\n if (message.chatId) {\n return scopeDirectory.resolveChat(message.chatId);\n }\n return undefined;\n },\n send: async (destination, payload) => {\n if (!streaming) throw new Error('bridge channel is not ready');\n await streaming.sendMarkdown(destination.chatId, payload.text, {\n ...(destination.threadId ? { threadId: destination.threadId } : {}),\n ...(payload.mentions ? { mentions: payload.mentions } : {}),\n });\n },\n });\n process.env.DSH_LARK_NOTIFY_TOKEN = notifyToken;\n\n const pending = new PendingQueue<NormalizedMessage>(\n DEBOUNCE_MS,\n async (scope, batch) => {\n if (!streaming) return;\n const first = batch[0];\n if (!first) return;\n pending.block(scope);\n try {\n const attachments = await prepareAttachments(\n larkChannel,\n first,\n paths.mediaDir(profileName),\n );\n const messages = [\n first.content,\n ...attachments.textFileNotes,\n ].filter(Boolean);\n const role = roleStore.roleForScope(scope);\n const runInput: Parameters<typeof runAgentBatch>[0] = {\n scope,\n chatId: first.chatId,\n messages,\n adapter,\n sessions,\n workspaces,\n workspaceManager: worktreeManager,\n activeRuns,\n runPolicies,\n archiver,\n ...(role === undefined ? {} : { role }),\n approvals,\n questions,\n densityStore,\n channel: streaming,\n defaultWorkspace,\n replyTo: first.messageId,\n runTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n maxConcurrency: concurrencyStore.get(scope) ?? env.scopeConcurrency,\n retention: retentionStore.get(scope) ?? env.retentionMsgs,\n images: attachments.imagePaths,\n model:\n models.get(scope) ??\n role?.model ??\n activeProfile.preferences.model ??\n (await dshConfig.defaultModel().catch(() => undefined)) ??\n env.model,\n };\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n runInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n await runAgentBatch(runInput);\n } finally {\n pending.unblock(scope);\n }\n },\n (scope) => concurrencyStore.get(scope) ?? env.scopeConcurrency,\n );\n\n const channelInput: Parameters<typeof startChannel>[0] = {\n appId: activeProfile.accounts.appId,\n appSecret: activeProfile.accounts.appSecret,\n tenant: activeProfile.tenant,\n adapter,\n sessions,\n workspaces,\n activeRuns,\n runPolicies,\n concurrencyStore,\n defaultScopeConcurrency: env.scopeConcurrency,\n retentionStore,\n roleStore,\n scopeDirectory,\n archiver,\n defaultRetention: env.retentionMsgs,\n archiveMax: env.archiveMax,\n archiveMaxAgeDays: env.archiveMaxAgeDays,\n approvals,\n questions,\n densityStore,\n models,\n dshConfig,\n defaultRunTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n defaultModel: activeProfile.preferences.model ?? env.model,\n accessManager: new AccessManager(configStore, profileName),\n pending,\n defaultWorkspace,\n accessDefaultDeny: env.accessDefaultDeny,\n eventFreshnessMs: env.eventFreshnessMs,\n allowedUsers: activeProfile.access.allowedUsers,\n allowedChats: activeProfile.access.allowedChats,\n ...(options.createChannel ? { createChannel: options.createChannel } : {}),\n };\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n channelInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n const bridge = await startChannel(channelInput);\n streaming = adaptLarkChannel(bridge.channel);\n larkChannel = bridge.channel;\n await notifyServer.start();\n process.env.DSH_LARK_NOTIFY_URL = notifyServer.url ?? '';\n const heartbeat = startHeartbeat(\n paths.profilePath(profileName, 'guardian', 'heartbeat.json'),\n process.pid,\n env.heartbeatMs,\n );\n\n const startedAt = new Date().toISOString();\n log.info('cli', 'started', {\n profile: profileName,\n home: paths.root,\n tenant: activeProfile.tenant,\n workspace: defaultWorkspace,\n mode: 'engine',\n });\n\n let stopped = false;\n return {\n profile: profileName,\n home: paths.root,\n status: () => ({\n state: stopped ? 'stopped' : 'running',\n profile: profileName,\n home: paths.root,\n adapterId: adapter.id,\n startedAt,\n workspace: defaultWorkspace,\n notifyUrl: notifyServer.url,\n }),\n stop: async () => {\n if (stopped) return;\n stopped = true;\n heartbeat.stop();\n await notifyServer.stop();\n await bridge.disconnect();\n await adapter.dispose?.();\n await Promise.all([\n sessions.flush(),\n workspaces.flush(),\n roleStore.flush(),\n scopeDirectory.flush(),\n ]);\n },\n };\n}\n\nexport async function runBot(options: StartOptions): Promise<void> {\n const env = loadRuntimeEnv(mergeStartEnv(options));\n const profileName = options.profile ?? 'default';\n const engine = await startBridgeEngine({\n env,\n profileName,\n allowOnboarding: false,\n });\n process.stdout.write(`dsh-lark-bot 已启动,profile=${profileName}\\n`);\n await waitForShutdown();\n await engine.stop();\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction waitForShutdown(): Promise<void> {\n return new Promise((resolve) => {\n const shutdown = (): void => {\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n resolve();\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","export interface ActiveRunHandle {\n runId: string;\n stop(): Promise<void>;\n}\n\n/**\n * Tracks every running agent run, keyed by scope. A scope can hold several\n * concurrent runs (multi-agent collaboration); `interrupt` stops them all,\n * while `interruptRun` targets one run by id.\n */\nexport class ActiveRuns {\n private readonly runs = new Map<string, Map<string, ActiveRunHandle>>();\n\n set(scope: string, handle: ActiveRunHandle): void {\n const scoped = this.runs.get(scope) ?? new Map<string, ActiveRunHandle>();\n scoped.set(handle.runId, handle);\n this.runs.set(scope, scoped);\n }\n\n /** First active run for the scope, if any (backward-compatible accessor). */\n get(scope: string): ActiveRunHandle | undefined {\n return this.runs.get(scope)?.values().next().value;\n }\n\n list(scope: string): ActiveRunHandle[] {\n return [...(this.runs.get(scope)?.values() ?? [])];\n }\n\n count(scope: string): number {\n return this.runs.get(scope)?.size ?? 0;\n }\n\n has(scope: string): boolean {\n return (this.runs.get(scope)?.size ?? 0) > 0;\n }\n\n delete(scope: string, runId: string): boolean {\n const scoped = this.runs.get(scope);\n if (!scoped) return false;\n const removed = scoped.delete(runId);\n if (scoped.size === 0) this.runs.delete(scope);\n return removed;\n }\n\n /** Stop every active run in the scope. Returns how many were interrupted. */\n async interrupt(scope: string): Promise<number> {\n const scoped = this.runs.get(scope);\n if (!scoped || scoped.size === 0) return 0;\n const handles = [...scoped.values()];\n this.runs.delete(scope);\n await Promise.allSettled(handles.map((handle) => handle.stop()));\n return handles.length;\n }\n\n /** Stop one run by id. Returns whether the run existed. */\n async interruptRun(scope: string, runId: string): Promise<boolean> {\n const scoped = this.runs.get(scope);\n const handle = scoped?.get(runId);\n if (!handle) return false;\n scoped?.delete(runId);\n if (scoped?.size === 0) this.runs.delete(scope);\n await handle.stop();\n return true;\n }\n}\n","import { realpathSync } from 'node:fs';\nimport { isIP } from 'node:net';\nimport { isAbsolute, relative, resolve, sep } from 'node:path';\n\nconst REDACTED = '[redacted]';\n\nconst SECRET_PATTERNS: readonly { label: string; pattern: RegExp; keyed: boolean }[] = [\n { label: 'bearer', pattern: /\\bBearer\\s+[A-Za-z0-9._~+/=-]{8,}/g, keyed: false },\n { label: 'deepseek-key', pattern: /\\bsk-[A-Za-z0-9_-]{8,}/g, keyed: false },\n { label: 'api-key', pattern: /\\b(api[_-]?key)\\s*[=:]\\s*[\"']?[A-Za-z0-9._~+/=-]{8,}/gi, keyed: true },\n];\n\n/** Redact common secret shapes (Bearer / sk- / api_key=…) from free text. */\nexport function redactSecrets(text: string): string {\n let result = text;\n for (const { pattern, keyed } of SECRET_PATTERNS) {\n result = keyed\n ? result.replace(pattern, (_match, keyName: string) => `${keyName}=${REDACTED}`)\n : result.replace(pattern, REDACTED);\n }\n return result;\n}\n\nfunction resolveReal(path: string): string {\n try {\n return realpathSync(path);\n } catch {\n return resolve(path);\n }\n}\n\n/**\n * Path containment: `candidate` is inside (or equal to) `root`.\n * Uses realpath when the path exists so symlink escapes are rejected.\n */\nexport function isPathWithin(root: string, candidate: string): boolean {\n const rootReal = resolveReal(root);\n const candidateReal = resolveReal(candidate);\n const rel = relative(rootReal, candidateReal);\n return (\n rel === '' ||\n (!isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${sep}`))\n );\n}\n\n/**\n * Truncate text to `maxBytes` UTF-8 without splitting a multi-byte sequence\n * or a UTF-16 surrogate pair.\n */\nexport function truncateUtf8Safe(text: string, maxBytes: number): string {\n if (maxBytes <= 0) return '';\n if (Buffer.byteLength(text, 'utf8') <= maxBytes) return text;\n let slice = text.slice(0, maxBytes);\n while (Buffer.byteLength(slice, 'utf8') > maxBytes && slice.length > 0) {\n slice = slice.slice(0, -1);\n }\n const code = slice.charCodeAt(slice.length - 1);\n if (code >= 0xd800 && code <= 0xdbff) {\n slice = slice.slice(0, -1);\n }\n return slice;\n}\n\n/** Reject stale events (e.g. replayed/duplicated IM messages). */\nexport function isEventFresh(\n timestampMs: number | undefined,\n windowMs: number,\n now: number = Date.now(),\n): boolean {\n if (timestampMs === undefined) return true;\n return now - timestampMs <= windowMs;\n}\n\n/** Interactive tools that cannot be answered back through IM; default-deny. */\nexport const DEFAULT_DENIED_INTERACTIVE_TOOLS: readonly string[] = [\n 'ask_user_question',\n 'terminal',\n 'browser',\n 'vim',\n 'code',\n];\n\nexport function isDeniedTool(name: string): boolean {\n const normalized = name.trim().toLowerCase();\n return DEFAULT_DENIED_INTERACTIVE_TOOLS.includes(normalized);\n}\n\nfunction ipv4IsPrivate(parts: number[]): boolean {\n const [a, b] = parts;\n if (a === 0 || a === 10 || a === 127) return true;\n if (a === 169 && b === 254) return true;\n if (a === 172 && b !== undefined && b >= 16 && b <= 31) return true;\n if (a === 192 && b === 168) return true;\n if (a === 100 && b !== undefined && b >= 64 && b <= 127) return true;\n return false;\n}\n\nfunction ipv6IsPrivate(host: string): boolean {\n const normalized = host.toLowerCase();\n if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1') return true;\n if (normalized === '::' || normalized.startsWith('0:')) return true;\n if (normalized.startsWith('fe80:')) return true;\n if (normalized.startsWith('fc') || normalized.startsWith('fd')) return true;\n return false;\n}\n\n/**\n * SSRF guard: only http(s) URLs whose hostname is a public address are safe.\n * Loopback, link-local, private, CGNAT and IPv6 ULA ranges are rejected.\n */\nexport function isSafeHttpUrl(url: string): boolean {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return false;\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return false;\n let host = parsed.hostname.toLowerCase();\n if (host.startsWith('[') && host.endsWith(']')) {\n host = host.slice(1, -1);\n }\n if (host === 'localhost' || host.endsWith('.localhost')) return false;\n const ipVersion = isIP(host);\n if (ipVersion === 4) {\n return !ipv4IsPrivate(host.split('.').map((part) => Number(part)));\n }\n if (ipVersion === 6) {\n return !ipv6IsPrivate(host);\n }\n // Hostnames resolve later; the URL-level guard is the transport boundary.\n return true;\n}\n","import type { Writable } from 'node:stream';\nimport { redactSecrets } from '../config/security.js';\n\ntype LogLevel = 'info' | 'warn' | 'error';\n\nexport interface LogFields {\n [key: string]: unknown;\n}\n\nconst REDACTED = '[redacted]';\nconst SENSITIVE_KEY = /(secret|token|password|api[_-]?key)/i;\n\nfunction redactValue(value: unknown, key: string, depth: number): unknown {\n if (SENSITIVE_KEY.test(key)) return REDACTED;\n if (typeof value === 'string') return redactSecrets(value);\n if (depth === 0) return value;\n if (Array.isArray(value)) {\n return value.map((item, index) => redactValue(item, `${key}.${index}`, depth - 1));\n }\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n out[childKey] = redactValue(childValue, childKey, depth - 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactFields(fields: LogFields, depth = 4): LogFields {\n return redactValue(fields, '', depth) as LogFields;\n}\n\nfunction serializeMessage(\n level: LogLevel,\n category: string,\n event: string,\n fields: LogFields,\n): string {\n const entry = {\n time: new Date().toISOString(),\n level,\n category,\n event,\n fields: redactFields(fields),\n };\n return JSON.stringify(entry);\n}\n\nexport interface Logger {\n info(category: string, event: string, fields?: LogFields): void;\n warn(category: string, event: string, fields?: LogFields): void;\n error(category: string, event: string, fields?: LogFields): void;\n fail(category: string, error: unknown, fields?: LogFields): void;\n}\n\nexport function createLogger(output: Writable = process.stderr): Logger {\n const write = (level: LogLevel, category: string, event: string, fields: LogFields): void => {\n output.write(`${serializeMessage(level, category, event, fields)}\\n`);\n };\n\n return {\n info: (category, event, fields = {}) => write('info', category, event, fields),\n warn: (category, event, fields = {}) => write('warn', category, event, fields),\n error: (category, event, fields = {}) => write('error', category, event, fields),\n fail(category, error, fields = {}) {\n const message = error instanceof Error ? error.message : String(error);\n write('error', category, 'fail', { message, ...fields });\n },\n };\n}\n\nexport const log = createLogger();\n","import type { ApprovalOutcome, ApprovalRequest } from '../adapters/types.js';\nimport { log } from '../core/logger.js';\n\ninterface PendingApproval {\n request: ApprovalRequest;\n resolve: (outcome: ApprovalOutcome) => void;\n settled: boolean;\n}\n\n/**\n * Pending approval registry. Cards are rendered by the caller; this store\n * correlates card button clicks with the ACP `request_permission` promise and\n * guarantees every request is settled when a run ends or is disposed.\n */\nexport class ApprovalRegistry {\n private readonly pending = new Map<string, PendingApproval>();\n\n register(scope: string, request: ApprovalRequest): Promise<ApprovalOutcome> {\n const key = `${scope}:${request.id}`;\n const existing = this.pending.get(key);\n if (existing) return Promise.resolve('cancelled');\n return new Promise<ApprovalOutcome>((resolve) => {\n this.pending.set(key, { request, resolve, settled: false });\n });\n }\n\n resolve(scope: string, id: string, outcome: ApprovalOutcome): boolean {\n const key = `${scope}:${id}`;\n const pending = this.pending.get(key);\n if (!pending || pending.settled) return false;\n pending.settled = true;\n this.pending.delete(key);\n pending.resolve(outcome);\n return true;\n }\n\n /** Settle every pending approval for a scope (run end / dispose). */\n settleAll(scope: string, outcome: ApprovalOutcome): number {\n let count = 0;\n for (const [key, pending] of this.pending) {\n if (!key.startsWith(`${scope}:`)) continue;\n if (pending.settled) continue;\n pending.settled = true;\n this.pending.delete(key);\n pending.resolve(outcome);\n count += 1;\n }\n if (count > 0) {\n log.warn('approvals', 'settled-pending', { scope, outcome, count });\n }\n return count;\n }\n\n pendingCount(scope: string): number {\n let count = 0;\n for (const key of this.pending.keys()) {\n if (key.startsWith(`${scope}:`)) count += 1;\n }\n return count;\n }\n}\n","/**\n * Per-scope concurrent-run overrides. `undefined` means the profile /\n * environment default applies. Mirrors `RunPolicyStore` semantics.\n */\nexport class ConcurrencyStore {\n private readonly limits = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.limits.get(scope);\n }\n\n set(scope: string, limit: number): void {\n this.limits.set(scope, limit);\n }\n\n clear(scope: string): boolean {\n return this.limits.delete(scope);\n }\n}\n","import type { CardDensity } from '../card/density.js';\n\n/** Per-scope card density overrides on top of a default. */\nexport class DensityStore {\n private readonly overrides = new Map<string, CardDensity>();\n\n constructor(private readonly defaultDensity: CardDensity = 'standard') {}\n\n get(scope: string): CardDensity {\n return this.overrides.get(scope) ?? this.defaultDensity;\n }\n\n set(scope: string, density: CardDensity): void {\n this.overrides.set(scope, density);\n }\n\n clear(scope: string): boolean {\n return this.overrides.delete(scope);\n }\n}\n","export class ModelStore {\n private readonly overrides = new Map<string, string>();\n\n get(scope: string): string | undefined {\n return this.overrides.get(scope);\n }\n\n set(scope: string, model: string): void {\n this.overrides.set(scope, model);\n }\n\n clear(scope: string): boolean {\n return this.overrides.delete(scope);\n }\n}\n","export type PendingFlush<T> = (scope: string, batch: T[]) => void | Promise<void>;\n\n/**\n * Per-scope debounced message queue with bounded concurrency. A scope may run\n * several flushes in parallel up to `concurrencyFor(scope)`; `block` stops\n * NEW flushes from starting while already-running ones finish, and `unblock`\n * resumes scheduling.\n */\nexport class PendingQueue<T> {\n private readonly pending = new Map<string, T[]>();\n private readonly timers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly blocked = new Set<string>();\n private readonly flushingCount = new Map<string, number>();\n\n constructor(\n private readonly quietMs: number,\n private readonly onFlush: PendingFlush<T>,\n private readonly concurrencyFor: (scope: string) => number = () => 1,\n ) {}\n\n push(scope: string, item: T): void {\n const batch = this.pending.get(scope) ?? [];\n batch.push(item);\n this.pending.set(scope, batch);\n this.schedule(scope);\n }\n\n block(scope: string): void {\n this.blocked.add(scope);\n this.clearTimer(scope);\n }\n\n unblock(scope: string): void {\n this.blocked.delete(scope);\n this.schedule(scope);\n }\n\n async flushNow(scope: string): Promise<void> {\n this.clearTimer(scope);\n const limit = this.concurrencyFor(scope);\n const active = this.flushingCount.get(scope) ?? 0;\n if (active >= limit) return;\n\n const batch = this.pending.get(scope) ?? [];\n this.pending.delete(scope);\n if (batch.length === 0) return;\n\n this.flushingCount.set(scope, active + 1);\n try {\n await this.onFlush(scope, batch);\n } finally {\n const next = (this.flushingCount.get(scope) ?? 1) - 1;\n if (next <= 0) this.flushingCount.delete(scope);\n else this.flushingCount.set(scope, next);\n this.schedule(scope);\n }\n }\n\n hasPending(scope: string): boolean {\n return (this.pending.get(scope)?.length ?? 0) > 0;\n }\n\n isBlocked(scope: string): boolean {\n return this.blocked.has(scope);\n }\n\n isFlushing(scope: string): boolean {\n return (this.flushingCount.get(scope) ?? 0) > 0;\n }\n\n activeFlushes(scope: string): number {\n return this.flushingCount.get(scope) ?? 0;\n }\n\n private schedule(scope: string): void {\n if (this.blocked.has(scope)) return;\n if ((this.flushingCount.get(scope) ?? 0) >= this.concurrencyFor(scope)) return;\n if (this.timers.has(scope)) return;\n if (!this.hasPending(scope)) return;\n\n this.timers.set(\n scope,\n setTimeout(() => {\n this.timers.delete(scope);\n void this.flushNow(scope);\n }, this.quietMs),\n );\n }\n\n private clearTimer(scope: string): void {\n const timer = this.timers.get(scope);\n if (timer === undefined) return;\n clearTimeout(timer);\n this.timers.delete(scope);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { QuestionCardInput } from '../card/question-card.js';\n\ninterface PendingQuestion {\n input: QuestionCardInput;\n resolve: (answer: string | string[] | undefined) => void;\n settled: boolean;\n}\n\n/**\n * Pending question-card registry. `/ask` registers a card; the card submit\n * action resolves it, and the answer is recorded back into the session.\n */\nexport class QuestionRegistry {\n private readonly pending = new Map<string, PendingQuestion>();\n\n register(\n scope: string,\n input: Omit<QuestionCardInput, 'id'>,\n ): { id: string; promise: Promise<string | string[] | undefined> } {\n const id = `question-${randomUUID().replaceAll('-', '')}`;\n const full: QuestionCardInput = { ...input, id };\n const promise = new Promise<string | string[] | undefined>((resolve) => {\n this.pending.set(`${scope}:${id}`, { input: full, resolve, settled: false });\n });\n return { id, promise };\n }\n\n resolve(scope: string, id: string, answer: string | string[] | undefined): boolean {\n const pending = this.pending.get(`${scope}:${id}`);\n if (!pending || pending.settled) return false;\n pending.settled = true;\n this.pending.delete(`${scope}:${id}`);\n pending.resolve(answer);\n return true;\n }\n\n settleAll(scope: string): number {\n let count = 0;\n for (const [key, pending] of this.pending) {\n if (!key.startsWith(`${scope}:`)) continue;\n if (pending.settled) continue;\n pending.settled = true;\n this.pending.delete(key);\n pending.resolve(undefined);\n count += 1;\n }\n return count;\n }\n\n get(scope: string, id: string): QuestionCardInput | undefined {\n return this.pending.get(`${scope}:${id}`)?.input;\n }\n}\n","/**\n * Per-scope live-message retention overrides. `undefined` means the profile /\n * environment default applies. Mirrors `RunPolicyStore` semantics.\n */\nexport class RetentionStore {\n private readonly retentions = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.retentions.get(scope);\n }\n\n set(scope: string, retention: number): void {\n this.retentions.set(scope, retention);\n }\n\n clear(scope: string): boolean {\n return this.retentions.delete(scope);\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface RoleDefinition {\n id: string;\n name: string;\n /** System-style persona/instructions applied to every run of this role. */\n persona: string;\n /** Optional model override for this role (below the per-scope /model use). */\n model?: string;\n /** Optional comma-separated tool guidance shown to the agent. */\n tools?: string;\n /** Optional role rules text injected like an AGENTS.md. */\n agentsMd?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface RoleStoreInput {\n id: string;\n name: string;\n persona: string;\n model?: string;\n tools?: string;\n agentsMd?: string;\n}\n\ninterface RoleData {\n roles: Record<string, RoleDefinition>;\n scopeRoles: Record<string, string>;\n}\n\n/**\n * Persisted role registry: named agent roles (persona / model / tools guidance /\n * role rules) plus per-scope role bindings. Stored per profile at\n * `<profile>/roles.json` (0600). Memory of bindings survives restarts.\n */\nexport class RoleStore {\n private data: RoleData = { roles: {}, scopeRoles: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<RoleData>;\n this.data = {\n roles: parsed.roles ?? {},\n scopeRoles: parsed.scopeRoles ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = { roles: {}, scopeRoles: {} };\n }\n }\n\n list(): RoleDefinition[] {\n return Object.values(this.data.roles).sort((a, b) => a.id.localeCompare(b.id));\n }\n\n get(id: string): RoleDefinition | undefined {\n return this.data.roles[id];\n }\n\n upsert(input: RoleStoreInput): RoleDefinition {\n const existing = this.data.roles[input.id];\n const now = new Date().toISOString();\n const role: RoleDefinition = {\n id: input.id,\n name: input.name,\n persona: input.persona,\n ...(input.model === undefined ? {} : { model: input.model }),\n ...(input.tools === undefined ? {} : { tools: input.tools }),\n ...(input.agentsMd === undefined ? {} : { agentsMd: input.agentsMd }),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n };\n this.data.roles[input.id] = role;\n this.schedulePersist();\n return role;\n }\n\n remove(id: string): boolean {\n if (!(id in this.data.roles)) return false;\n delete this.data.roles[id];\n for (const [scope, roleId] of Object.entries(this.data.scopeRoles)) {\n if (roleId === id) delete this.data.scopeRoles[scope];\n }\n this.schedulePersist();\n return true;\n }\n\n roleForScope(scope: string): RoleDefinition | undefined {\n const roleId = this.data.scopeRoles[scope];\n return roleId === undefined ? undefined : this.data.roles[roleId];\n }\n\n setScopeRole(scope: string, roleId: string): boolean {\n if (!(roleId in this.data.roles)) return false;\n this.data.scopeRoles[scope] = roleId;\n this.schedulePersist();\n return true;\n }\n\n clearScopeRole(scope: string): boolean {\n if (!(scope in this.data.scopeRoles)) return false;\n delete this.data.scopeRoles[scope];\n this.schedulePersist();\n return true;\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = {\n roles: { ...this.data.roles },\n scopeRoles: { ...this.data.scopeRoles },\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('role-store', error, { step: 'persist' });\n });\n }\n}\n","export class RunPolicyStore {\n private readonly timeouts = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.timeouts.get(scope);\n }\n\n set(scope: string, runTimeoutMs: number): void {\n this.timeouts.set(scope, runTimeoutMs);\n }\n\n clear(scope: string): boolean {\n return this.timeouts.delete(scope);\n }\n}\n","import { createLarkChannel, type LarkChannel, type NormalizedMessage } from '@larksuite/channel';\nimport type { AgentAdapter } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { ApprovalRegistry } from '../bot/approvals.js';\nimport type { DensityStore } from '../bot/density-store.js';\nimport type { ConcurrencyStore } from '../bot/concurrency-store.js';\nimport type { ModelStore } from '../bot/model-store.js';\nimport type { PendingQueue } from '../bot/pending-queue.js';\nimport type { QuestionRegistry } from '../bot/questions.js';\nimport type { RetentionStore } from '../bot/retention-store.js';\nimport type { RoleStore } from '../bot/role-store.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport { tryHandleCommand, type CommandChannel } from '../commands/index.js';\nimport { extractQuestionAnswer } from '../card/question-card.js';\nimport type { AccessManager } from '../config/access-manager.js';\nimport type { DshProviderManager } from '../config/dsh-config.js';\nimport { isEventFresh } from '../config/security.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { SessionArchive } from '../session/archive.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport { adaptLarkChannel } from './lark-channel.js';\nimport type { ScopeDirectory } from './scope-directory.js';\n\nexport interface StartChannelDeps {\n appId: string;\n appSecret: string;\n tenant: 'feishu' | 'lark';\n adapter: AgentAdapter;\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n concurrencyStore: ConcurrencyStore;\n defaultScopeConcurrency: number;\n retentionStore: RetentionStore;\n roleStore: RoleStore;\n scopeDirectory?: ScopeDirectory;\n archiver: SessionArchive;\n defaultRetention: number;\n archiveMax: number;\n archiveMaxAgeDays: number;\n defaultRunTimeoutMs: number;\n accessManager: AccessManager;\n pending: PendingQueue<NormalizedMessage>;\n approvals?: ApprovalRegistry;\n questions?: QuestionRegistry;\n densityStore?: DensityStore;\n models: ModelStore;\n dshConfig: DshProviderManager;\n defaultWorkspace: string;\n defaultModel: string;\n allowedUsers?: string[];\n allowedChats?: string[];\n accessDefaultDeny?: boolean;\n eventFreshnessMs?: number;\n stopGraceMs?: number;\n createChannel?: typeof createLarkChannel;\n}\n\nexport interface BridgeChannel {\n channel: LarkChannel;\n disconnect(): Promise<void>;\n}\n\nexport async function startChannel(deps: StartChannelDeps): Promise<BridgeChannel> {\n const channel = (deps.createChannel ?? createLarkChannel)({\n appId: deps.appId,\n appSecret: deps.appSecret,\n domain:\n deps.tenant === 'lark' ? 'https://open.larksuite.com' : 'https://open.feishu.cn',\n source: 'dsh-lark-bot',\n policy: {\n dmMode: deps.allowedUsers?.length\n ? 'allowlist'\n : deps.accessDefaultDeny === true\n ? 'disabled'\n : 'open',\n requireMention: true,\n respondToMentionAll: false,\n ...(deps.allowedUsers ? { dmAllowlist: deps.allowedUsers } : {}),\n ...(deps.allowedChats ? { groupAllowlist: deps.allowedChats } : {}),\n },\n safety: {\n chatQueue: { enabled: false },\n },\n outbound: {\n streamThrottleMs: 400,\n },\n includeRawEvent: true,\n resolveChatMode: true,\n handshakeTimeoutMs: 8_000,\n httpTimeoutMs: 30_000,\n respectProxyEnv: true,\n });\n\n const streaming = adaptLarkChannel(channel);\n const commandChannel: CommandChannel = streaming;\n\n channel.on({\n message: async (msg) => {\n const scope = scopeForMessage(msg);\n deps.scopeDirectory?.register(scope, msg.chatId, msg.threadId);\n if (\n deps.eventFreshnessMs !== undefined &&\n deps.eventFreshnessMs > 0 &&\n !isEventFresh(msg.createTime, deps.eventFreshnessMs)\n ) {\n log.warn('channel', 'stale-message-dropped', {\n scope,\n ageMs: Date.now() - msg.createTime,\n });\n return;\n }\n const context = {\n scope,\n chatId: msg.chatId,\n messageId: msg.messageId,\n threadId: msg.threadId,\n chatMode: msg.chatMode ?? msg.chatType,\n sessions: deps.sessions,\n workspaces: deps.workspaces,\n activeRuns: deps.activeRuns,\n runPolicies: deps.runPolicies,\n concurrencyStore: deps.concurrencyStore,\n defaultScopeConcurrency: deps.defaultScopeConcurrency,\n retentionStore: deps.retentionStore,\n roleStore: deps.roleStore,\n scopeDirectory: deps.scopeDirectory ?? EMPTY_SCOPE_DIRECTORY,\n archiver: deps.archiver,\n defaultRetention: deps.defaultRetention,\n archiveMax: deps.archiveMax,\n archiveMaxAgeDays: deps.archiveMaxAgeDays,\n defaultRunTimeoutMs: deps.defaultRunTimeoutMs,\n accessManager: deps.accessManager,\n approvals: deps.approvals,\n questions: deps.questions,\n densityStore: deps.densityStore,\n models: deps.models,\n dshConfig: deps.dshConfig,\n channel: commandChannel,\n defaultWorkspace: deps.defaultWorkspace,\n defaultModel: deps.defaultModel,\n senderId: msg.senderId,\n };\n\n const handled = await tryHandleCommand(msg.content, context).catch((error: unknown) => {\n log.fail('channel-command', error, { scope });\n return false;\n });\n if (!handled) deps.pending.push(scope, msg);\n },\n cardAction: async (event) => {\n const value =\n event.action.value && typeof event.action.value === 'object'\n ? (event.action.value as Record<string, unknown>)\n : undefined;\n const scope = event.raw\n ? await resolveCardScope(event.chatId, event.raw as { message?: { thread_id?: string } })\n : event.chatId;\n if (value?.cmd === 'stop') {\n await deps.activeRuns.interrupt(scope);\n return;\n }\n if (value?.cmd === 'approve' && typeof value.id === 'string' && deps.approvals) {\n const outcome = value.outcome === 'allow' ? 'allowed-once' : 'rejected';\n deps.approvals.resolve(scope, value.id, outcome);\n return;\n }\n if (value?.cmd === 'question-submit' && typeof value.id === 'string' && deps.questions) {\n const question = deps.questions.get(scope, value.id);\n const form = event.action.formValue;\n if (question) {\n const answer = extractQuestionAnswer(\n question.kind,\n form?.answer,\n question.options,\n );\n deps.questions.resolve(scope, value.id, answer);\n }\n }\n },\n reconnecting: () => {\n log.warn('channel', 'reconnecting', {});\n },\n reconnected: () => {\n log.info('channel', 'reconnected', {});\n },\n error: (error) => {\n log.fail('channel', error);\n },\n });\n\n await channel.connect();\n return {\n channel,\n disconnect: () => channel.disconnect(),\n };\n}\n\nconst EMPTY_SCOPE_DIRECTORY: ScopeDirectory = {\n register: () => {},\n resolve: () => undefined,\n resolveChat: () => undefined,\n knownScopes: () => [],\n flush: async () => {},\n} as unknown as ScopeDirectory;\n\nfunction scopeForMessage(msg: NormalizedMessage): string {\n if (msg.chatMode === 'topic' && msg.threadId) return `${msg.chatId}:${msg.threadId}`;\n return msg.chatId;\n}\n\nasync function resolveCardScope(\n chatId: string,\n raw: { message?: { thread_id?: string } },\n): Promise<string> {\n return raw.message?.thread_id ? `${chatId}:${raw.message.thread_id}` : chatId;\n}\n","import { resolve } from 'node:path';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { ApprovalRegistry } from '../bot/approvals.js';\nimport type { DensityStore } from '../bot/density-store.js';\nimport type { ConcurrencyStore } from '../bot/concurrency-store.js';\nimport type { QuestionRegistry } from '../bot/questions.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport type { RetentionStore } from '../bot/retention-store.js';\nimport type { RoleStore } from '../bot/role-store.js';\nimport type { AccessManager } from '../config/access-manager.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { SessionArchive } from '../session/archive.js';\nimport type { ScopeDirectory } from '../bridge/scope-directory.js';\nimport type { SendOptions } from '../bridge/send-options.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport { renderWorkspaceCard } from '../card/workspace-card.js';\nimport { parseCardDensity, type CardDensity } from '../card/density.js';\nimport { questionHandlerFor } from '../bridge/run-flow.js';\nimport type { ModelStore } from '../bot/model-store.js';\nimport type { DshProviderManager } from '../config/dsh-config.js';\nimport {\n handleKey,\n handleModel,\n handleProvider,\n handleProviders,\n} from './models.js';\nimport { handleArchive, handleRetention } from './archive.js';\nimport { handleRole } from './roles.js';\nimport { handleNotify } from './notify.js';\n\nexport interface CommandChannel {\n sendMarkdown(\n chatId: string,\n markdown: string,\n options?: SendOptions,\n ): Promise<void>;\n sendCard?(chatId: string, card: object): Promise<void>;\n}\n\nexport interface CommandContext {\n scope: string;\n chatId: string;\n messageId: string;\n threadId: string | undefined;\n chatMode: 'p2p' | 'group' | 'topic';\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n concurrencyStore: ConcurrencyStore;\n defaultScopeConcurrency: number;\n retentionStore: RetentionStore;\n roleStore: RoleStore;\n scopeDirectory: ScopeDirectory;\n archiver: SessionArchive;\n defaultRetention: number;\n archiveMax: number;\n archiveMaxAgeDays: number;\n approvals: ApprovalRegistry | undefined;\n questions: QuestionRegistry | undefined;\n densityStore: DensityStore | undefined;\n models: ModelStore;\n dshConfig: DshProviderManager;\n defaultRunTimeoutMs: number;\n defaultModel: string;\n senderId: string | undefined;\n accessManager: AccessManager;\n channel: CommandChannel;\n defaultWorkspace: string;\n}\n\ntype Handler = (args: string, ctx: CommandContext) => Promise<void>;\n\nconst HELP = [\n '**dsh-lark-bot 命令**',\n '',\n '- `/new` `/reset` — 开始新会话',\n '- `/cd <path>` — 切换工作目录并重置会话',\n '- `/ws list|save <name>|use <name>|remove <name>` — 管理工作空间',\n '- `/status` — 查看当前状态',\n '- `/resume` — 查看当前会话最近上下文',\n '- `/stop` — 终止当前任务',\n '- `/timeout [N|off|default]` — 查看或设置当前会话运行超时',\n '- `/concurrency [N|default]` — 查看或设置当前 scope 的并行任务数',\n '- `/role list|show <id>|set <id>|clear` — 查看 / 绑定角色',\n '- `/role save <id> <name> [--persona 文案] [--model <id>] [--tools <csv>] [--rules 文案]` — 创建/更新角色(管理员)',\n '- `/role remove <id>` — 删除角色(管理员)',\n '- `/notify <scope|chatId> <text>` — 跨会话发送通知(管理员)',\n '- `/notify list` — 查看已注册 scope',\n '- `/retention [N|default]` — 查看或设置当前会话保留消息条数(超出自动归档)',\n '- `/archive [note]`、`/archive list [N]`、`/archive clean` — 归档 / 查看 / 清理会话',\n '- `/density [compact|standard|detailed]` — 查看或设置卡片密度',\n '- `/model` — 查看当前模型与 dsh 可用模型',\n '- `/model use <id>` — 热切换当前会话模型(下一轮生效)',\n '- `/model default <id>` — 写入 dsh 默认模型 agent-default-model(管理员)',\n '- `/model add|remove <provider> <modelId>` — 管理 provider 的模型(管理员)',\n '- `/providers` — 查看 dsh providers / 模型 / 凭据状态',\n '- `/provider add|update|remove <id>` — 管理 provider(管理员;deepseek-official 与自定义 pi-ai)',\n '- `/key set|remove|list <引用名>` — 管理 dsh 凭据(set/remove 需管理员)',\n '- `/ask <问题>` — 发送结构化问答卡(回答将记入会话)',\n '- `/invite user|admin|group <id>` — 管理访问白名单',\n '- `/help` — 显示本帮助',\n].join('\\n');\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nasync function handleNew(_args: string, ctx: CommandContext): Promise<void> {\n const interrupted = await ctx.activeRuns.interrupt(ctx.scope);\n ctx.sessions.clear(ctx.scope);\n await reply(\n ctx,\n interrupted > 0 ? `已中断 ${String(interrupted)} 个任务并开始新会话。` : '已开始新会话。',\n );\n}\n\nasync function handleCd(args: string, ctx: CommandContext): Promise<void> {\n const path = args.trim();\n if (!path) {\n await reply(ctx, '用法:`/cd <path>`');\n return;\n }\n const cwd = resolve(path);\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换工作目录:\\`${cwd}\\`,会话已重置。`);\n}\n\nasync function handleWs(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n const name = rest.join(' ').trim();\n\n if (!sub || sub === 'list') {\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const named = ctx.workspaces.listNamed();\n const index = ctx.workspaces.listIndex();\n if (ctx.channel.sendCard) {\n await ctx.channel.sendCard(ctx.chatId, renderWorkspaceCard({ current, index }));\n return;\n }\n const lines = Object.entries(named).map(\n ([key, value]) => `- **${key}** → \\`${value}\\`${value === current ? ' ← 当前' : ''}`,\n );\n await reply(\n ctx,\n [\n `当前 cwd:\\`${current}\\``,\n '',\n ...(lines.length > 0 ? lines : ['暂无命名工作空间。']),\n ].join('\\n'),\n );\n return;\n }\n\n if (sub === 'save') {\n if (!name) {\n await reply(ctx, '用法:`/ws save <name>`');\n return;\n }\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n ctx.workspaces.saveNamed(name, current);\n await reply(ctx, `已保存工作空间:**${name}** → \\`${current}\\``);\n return;\n }\n\n if (sub === 'use') {\n if (!name) {\n await reply(ctx, '用法:`/ws use <name>`');\n return;\n }\n const cwd = ctx.workspaces.getNamed(name);\n if (!cwd) {\n await reply(ctx, `未找到工作空间:**${name}**`);\n return;\n }\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.workspaces.touchNamed(name);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换到工作空间:**${name}** → \\`${cwd}\\``);\n return;\n }\n\n if (sub === 'remove') {\n if (!name) {\n await reply(ctx, '用法:`/ws remove <name>`');\n return;\n }\n const removed = ctx.workspaces.removeNamed(name);\n await reply(ctx, removed ? `已删除工作空间:**${name}**` : `未找到工作空间:**${name}**`);\n return;\n }\n\n await reply(ctx, '未知 `/ws` 子命令,请使用 list / save / use / remove。');\n}\n\nasync function handleStatus(_args: string, ctx: CommandContext): Promise<void> {\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const session = ctx.sessions.getRaw(ctx.scope)?.sessionId ?? '(无)';\n const active = ctx.activeRuns.list(ctx.scope);\n const role = ctx.roleStore.roleForScope(ctx.scope);\n const scopeLabel =\n ctx.chatMode === 'topic' ? `${ctx.scope}(话题独立 session)` : ctx.scope;\n const runLines = active.map((run) => ` - \\`${run.runId}\\``);\n const roleLine = role ? `🎭 **role**: \\`${role.id}\\` (${role.name})` : undefined;\n\n await reply(\n ctx,\n [\n `🧭 **scope**: \\`${scopeLabel}\\``,\n `📁 **cwd**: \\`${cwd}\\``,\n `🔗 **session**: \\`${session}\\``,\n ...(roleLine ? [roleLine] : []),\n `🏃 **active runs**: ${String(active.length)}`,\n ...runLines,\n ].join('\\n'),\n );\n}\n\nasync function handleResume(_args: string, ctx: CommandContext): Promise<void> {\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const history = ctx.sessions.historyFor(ctx.scope, cwd);\n if (history.length === 0) {\n await reply(ctx, '当前会话没有历史上下文。');\n return;\n }\n\n const recent = history.slice(-6).map((message) => {\n const speaker = message.role === 'user' ? '👤' : '🤖';\n return `${speaker} ${message.content.slice(0, 300)}`;\n });\n\n await reply(ctx, [`当前 scope:\\`${ctx.scope}\\``, '', ...recent].join('\\n'));\n}\n\nasync function handleStop(_args: string, ctx: CommandContext): Promise<void> {\n const stopped = await ctx.activeRuns.interrupt(ctx.scope);\n await reply(\n ctx,\n stopped > 0 ? `已请求终止当前 scope 的全部 ${String(stopped)} 个任务。` : '当前没有运行中的任务。',\n );\n}\n\nasync function handleTimeout(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effectiveMs = ctx.runPolicies.get(ctx.scope) ?? ctx.defaultRunTimeoutMs;\n\n if (!input) {\n const minutes = effectiveMs > 0 ? Math.round(effectiveMs / 60_000) : 0;\n await reply(\n ctx,\n minutes > 0\n ? `当前会话运行超时:${minutes} 分钟。可用 \\`/timeout <N|off|default>\\` 调整。`\n : '当前会话运行超时:关闭。',\n );\n return;\n }\n\n if (input === 'off') {\n ctx.runPolicies.set(ctx.scope, 0);\n await reply(ctx, '已关闭当前会话运行超时。');\n return;\n }\n\n if (input === 'default') {\n ctx.runPolicies.clear(ctx.scope);\n await reply(ctx, '已恢复默认运行超时。');\n return;\n }\n\n const minutes = Number(input);\n if (!Number.isInteger(minutes) || minutes <= 0) {\n await reply(ctx, '用法:`/timeout <N|off|default>`,N 为大于 0 的分钟数。');\n return;\n }\n\n ctx.runPolicies.set(ctx.scope, minutes * 60_000);\n await reply(ctx, `已设置当前会话运行超时:${minutes} 分钟。`);\n}\n\nasync function handleConcurrency(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effective = ctx.concurrencyStore.get(ctx.scope) ?? ctx.defaultScopeConcurrency;\n\n if (!input) {\n await reply(\n ctx,\n `当前 scope 的并行任务数:**${String(effective)}**。可用 \\`/concurrency <N|default>\\` 调整(N ≥ 1)。`,\n );\n return;\n }\n\n if (input === 'default') {\n ctx.concurrencyStore.clear(ctx.scope);\n await reply(ctx, `已恢复默认并行任务数(${String(ctx.defaultScopeConcurrency)})。`);\n return;\n }\n\n const n = Number(input);\n if (!Number.isInteger(n) || n < 1) {\n await reply(ctx, '用法:`/concurrency <N|default>`,N 为大于等于 1 的整数。');\n return;\n }\n\n ctx.concurrencyStore.set(ctx.scope, n);\n await reply(ctx, `已设置当前 scope 的并行任务数:**${String(n)}**。`);\n}\n\nasync function handleDensity(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim().toLowerCase();\n if (!input) {\n const current = ctx.densityStore?.get(ctx.scope) ?? 'standard';\n await reply(\n ctx,\n `当前卡片密度:**${current}**。可用 \\`/density compact|standard|detailed\\` 调整。`,\n );\n return;\n }\n if (input === 'default') {\n ctx.densityStore?.clear(ctx.scope);\n await reply(ctx, '已恢复默认卡片密度。');\n return;\n }\n const density: CardDensity | undefined = parseCardDensity(input);\n if (!density) {\n await reply(ctx, '用法:`/density [compact|standard|detailed|default]`');\n return;\n }\n ctx.densityStore?.set(ctx.scope, density);\n await reply(ctx, `已设置当前会话卡片密度:**${density}**。`);\n}\n\nasync function handleAsk(args: string, ctx: CommandContext): Promise<void> {\n const question = args.trim();\n if (!question) {\n await reply(ctx, '用法:`/ask <问题>`');\n return;\n }\n if (!ctx.questions) {\n await reply(ctx, '问答卡未启用(请确认 questions 已接线)。');\n return;\n }\n const answer = await questionHandlerFor({\n questions: ctx.questions,\n channel: ctx.channel,\n chatId: ctx.chatId,\n scope: ctx.scope,\n })({\n kind: 'text',\n question,\n id: '',\n });\n if (answer !== undefined) {\n const text = Array.isArray(answer) ? answer.join('、') : answer;\n ctx.sessions.recordExchange(ctx.scope, ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace, [text], undefined);\n await reply(ctx, `已记录你的回答,并写入会话上下文。`);\n } else {\n await reply(ctx, '未收到回答(卡片可能已超时或被忽略)。');\n }\n}\n\nasync function handleInvite(args: string, ctx: CommandContext): Promise<void> {\n const [kind, ...rest] = args.trim().split(/\\s+/);\n const id = rest.join(' ').trim();\n\n if (kind === 'list') {\n const snapshot = ctx.accessManager.snapshot();\n await reply(\n ctx,\n [\n '**访问白名单**',\n `users: ${snapshot.allowedUsers.join(', ') || '(空)'}`,\n `chats: ${snapshot.allowedChats.join(', ') || '(空)'}`,\n `admins: ${snapshot.admins.join(', ') || '(空)'}`,\n ].join('\\n'),\n );\n return;\n }\n\n if (!kind || !id) {\n await reply(\n ctx,\n '用法:`/invite user|admin|group <id>`、`/invite list`、`/invite remove user|group <id>`',\n );\n return;\n }\n\n if (kind === 'user') {\n await ctx.accessManager.addUser(id);\n await reply(ctx, `已允许用户:\\`${id}\\``);\n return;\n }\n\n if (kind === 'admin') {\n await ctx.accessManager.addAdmin(id);\n await reply(ctx, `已设为管理员:\\`${id}\\``);\n return;\n }\n\n if (kind === 'group') {\n await ctx.accessManager.addChat(id);\n await reply(ctx, `已允许群聊:\\`${id}\\``);\n return;\n }\n\n if (kind === 'remove') {\n const [sub, target] = rest;\n if (sub === 'user' && target) {\n await ctx.accessManager.removeUser(target);\n await reply(ctx, `已移除用户:\\`${target}\\``);\n return;\n }\n if (sub === 'group' && target) {\n await ctx.accessManager.removeChat(target);\n await reply(ctx, `已移除群聊:\\`${target}\\``);\n return;\n }\n await reply(ctx, '用法:`/invite remove user <id>` 或 `/invite remove group <chatId>`');\n return;\n }\n\n await reply(ctx, '未知 `/invite` 类型,请使用 user / admin / group / list / remove。');\n}\n\nasync function handleHelp(_args: string, ctx: CommandContext): Promise<void> {\n await reply(ctx, HELP);\n}\n\nconst handlers: Record<string, Handler> = {\n '/new': handleNew,\n '/reset': handleNew,\n '/cd': handleCd,\n '/ws': handleWs,\n '/status': handleStatus,\n '/resume': handleResume,\n '/stop': handleStop,\n '/timeout': handleTimeout,\n '/concurrency': handleConcurrency,\n '/role': handleRole,\n '/notify': handleNotify,\n '/retention': handleRetention,\n '/archive': handleArchive,\n '/density': handleDensity,\n '/model': handleModel,\n '/providers': handleProviders,\n '/provider': handleProvider,\n '/key': handleKey,\n '/ask': handleAsk,\n '/invite': handleInvite,\n '/help': handleHelp,\n};\n\nexport async function tryHandleCommand(text: string, ctx: CommandContext): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed.startsWith('/')) return false;\n const [command, ...rest] = trimmed.split(/\\s+/);\n const handler = handlers[command ?? ''];\n if (!handler) return false;\n await handler(rest.join(' '), ctx);\n return true;\n}\n","export function renderWorkspaceCard(input: {\n current: string;\n index: Array<{ name: string; cwd: string; lastUsed: number | undefined }>;\n}): object {\n const entries = input.index;\n const markdown = [\n `**当前工作目录**\\n\\`${input.current}\\``,\n '',\n ...(entries.length > 0\n ? entries.map(({ name, cwd, lastUsed }) =>\n `- **${name}** → \\`${cwd}\\`${lastUsed ? ` · ${new Date(lastUsed).toLocaleString()}` : ''}`,\n )\n : ['暂无命名工作空间。']),\n ].join('\\n');\n\n return {\n schema: '2.0',\n config: {\n summary: { content: '工作空间导航' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: markdown,\n },\n ],\n },\n };\n}\n","export type CardDensity = 'compact' | 'standard' | 'detailed';\n\nexport const CARD_DENSITIES: readonly CardDensity[] = ['compact', 'standard', 'detailed'];\n\nexport function parseCardDensity(value: string | undefined): CardDensity | undefined {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) return undefined;\n if ((CARD_DENSITIES as readonly string[]).includes(normalized)) {\n return normalized as CardDensity;\n }\n return undefined;\n}\n","import { randomUUID } from 'node:crypto';\nimport type { AgentAdapter, AgentEvent } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport { ApprovalRegistry } from '../bot/approvals.js';\nimport type { DensityStore } from '../bot/density-store.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport type { QuestionRegistry } from '../bot/questions.js';\nimport {\n finalizeIfRunning,\n initialState,\n markIdleTimeout,\n markInterrupted,\n reduce,\n type RunState,\n} from '../card/run-state.js';\nimport { renderCard } from '../card/run-renderer.js';\nimport { renderApprovalCard } from '../card/approval-card.js';\nimport { renderQuestionCard } from '../card/question-card.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { SessionArchive } from '../session/archive.js';\nimport type { RoleDefinition } from '../bot/role-store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport type { GitWorktreeManager } from '../workspace/git-worktree.js';\nimport type { StreamingChannel } from './types.js';\nimport type { ApprovalOutcome, ApprovalRequest } from '../adapters/types.js';\nimport type { QuestionCardInput } from '../card/question-card.js';\n\nexport interface RunFlowInput {\n scope: string;\n chatId: string;\n messages: string[];\n adapter: AgentAdapter;\n sessions: SessionStore;\n archiver?: SessionArchive;\n role?: RoleDefinition;\n /** Live messages kept before overflow is archived; defaults to 40. */\n retention?: number;\n archiveMax?: number;\n archiveMaxAgeDays?: number;\n workspaces: WorkspaceStore;\n workspaceManager?: GitWorktreeManager;\n activeRuns: ActiveRuns;\n runPolicies?: RunPolicyStore;\n /** Max concurrent runs allowed in the scope (queue enforces; guard is a fallback). */\n maxConcurrency?: number;\n approvals?: ApprovalRegistry;\n questions?: QuestionRegistry;\n densityStore?: DensityStore;\n channel: StreamingChannel;\n defaultWorkspace: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n images?: string[];\n replyTo?: string;\n}\n\nexport async function runAgentBatch(input: RunFlowInput): Promise<void> {\n const replyOptions = input.replyTo ? { replyTo: input.replyTo } : {};\n\n const activeBefore = input.activeRuns.count(input.scope);\n if (input.maxConcurrency !== undefined && activeBefore >= input.maxConcurrency) {\n await input.channel.sendMarkdown(input.chatId, '当前会话的并行任务数已达上限,请稍后再试或 `/stop` 部分任务。', {\n ...replyOptions,\n });\n return;\n }\n\n const requestedCwd = input.workspaces.cwdFor(input.scope) ?? input.defaultWorkspace;\n const workspace = input.workspaceManager\n ? await input.workspaceManager.ensure(input.scope, requestedCwd)\n : { cwd: requestedCwd };\n const cwd = workspace.cwd;\n // Only the first run in a scope resumes the native dsh session: concurrent\n // runs get fresh sessions so they never share one wire session id.\n const sessionId =\n activeBefore === 0\n ? input.sessions.resumeFor(input.scope, cwd)\n : undefined;\n const history = input.sessions.historyFor(input.scope, cwd);\n const prompt = buildPrompt(history, input.messages, input.role);\n const runId = randomUUID();\n\n const run = input.adapter.run({\n runId,\n prompt,\n cwd,\n sessionId,\n model: input.model,\n images: input.images,\n stopGraceMs: input.stopGraceMs,\n ...(input.approvals\n ? {\n onApprovalRequest: approvalHandlerFor({\n approvals: input.approvals,\n channel: input.channel,\n chatId: input.chatId,\n scope: input.scope,\n }),\n }\n : {}),\n });\n input.activeRuns.set(input.scope, { runId, stop: run.stop });\n\n let state: RunState = initialState;\n const stopRequested = { value: false };\n const timeoutMs = input.runPolicies?.get(input.scope) ?? input.runTimeoutMs ?? 0;\n let timedOut = false;\n let assistantOutput = '';\n const density = input.densityStore?.get(input.scope) ?? 'standard';\n\n try {\n await input.channel.streamCard(\n input.chatId,\n renderCard(state, density),\n async (controller) => {\n const consume = async (): Promise<void> => {\n for await (const event of run.events) {\n if (timedOut) return;\n state = applyEvent(state, event, stopRequested);\n if (event.type === 'final_text') {\n assistantOutput = event.content;\n } else if (event.type === 'text') {\n assistantOutput += event.delta;\n }\n if (event.type === 'system' && event.sessionId) {\n input.sessions.set(input.scope, event.sessionId, event.cwd ?? cwd);\n }\n await controller.update(renderCard(state, density));\n }\n };\n\n let timeoutTimer: NodeJS.Timeout | undefined;\n const timeoutPromise =\n timeoutMs > 0\n ? new Promise<void>((resolve) => {\n timeoutTimer = setTimeout(() => {\n timedOut = true;\n void run.stop();\n resolve();\n }, timeoutMs);\n })\n : undefined;\n\n try {\n if (timeoutPromise) {\n await Promise.race([consume(), timeoutPromise]);\n } else {\n await consume();\n }\n\n state = timedOut\n ? markIdleTimeout(state, timeoutMs / 60_000)\n : finalizeIfRunning(state);\n await controller.update(renderCard(state, density));\n } finally {\n if (timeoutTimer !== undefined) clearTimeout(timeoutTimer);\n }\n },\n replyOptions,\n );\n input.sessions.recordExchange(input.scope, cwd, input.messages, assistantOutput, {\n ...(input.retention === undefined ? {} : { retention: input.retention }),\n ...(input.archiver\n ? {\n onArchive: (overflow) =>\n input.archiver!.archive({\n scope: input.scope,\n cwd,\n messages: overflow,\n source: 'retention',\n }).then(() => pruneArchives(input)),\n }\n : {}),\n });\n } catch (error) {\n log.fail('run-flow', error, { scope: input.scope, runId });\n state = markInterrupted(state);\n try {\n await input.channel.sendMarkdown(input.chatId, `⚠️ agent 运行失败:${errorMessage(error)}`, {\n ...replyOptions,\n });\n } catch {\n // best effort; the card may already have failed\n }\n } finally {\n input.activeRuns.delete(input.scope, runId);\n if (input.approvals) {\n input.approvals.settleAll(input.scope, 'cancelled');\n }\n if (input.questions) {\n input.questions.settleAll(input.scope);\n }\n }\n}\n\nasync function pruneArchives(input: RunFlowInput): Promise<void> {\n if (!input.archiver) return;\n await input.archiver.prune({\n ...(input.archiveMax !== undefined && input.archiveMax > 0\n ? { maxArchives: input.archiveMax }\n : {}),\n ...(input.archiveMaxAgeDays !== undefined && input.archiveMaxAgeDays > 0\n ? { maxAgeMs: input.archiveMaxAgeDays * 24 * 60 * 60 * 1000 }\n : {}),\n });\n}\n\n/** Build the per-run approval handler wiring ACP requests to approval cards. */\nexport function approvalHandlerFor(\n input: {\n approvals: ApprovalRegistry | undefined;\n channel: { sendCard?: (chatId: string, card: object) => Promise<void> };\n chatId: string;\n scope: string;\n },\n): (request: ApprovalRequest) => Promise<ApprovalOutcome> {\n return async (request) => {\n if (!input.approvals || !input.channel.sendCard) return 'cancelled';\n const promise = input.approvals.register(input.scope, request);\n try {\n await input.channel.sendCard(\n input.chatId,\n renderApprovalCard({\n id: request.id,\n toolName: request.toolName,\n reason: request.reason,\n options: request.options,\n }),\n );\n } catch (error) {\n log.fail('approval-card', error, { scope: input.scope });\n input.approvals.settleAll(input.scope, 'cancelled');\n return 'cancelled';\n }\n return promise;\n };\n}\n\n/** Build the per-run question handler wiring `/ask` cards back to sessions. */\nexport function questionHandlerFor(\n input: {\n questions: QuestionRegistry | undefined;\n channel: { sendCard?: (chatId: string, card: object) => Promise<void> };\n chatId: string;\n scope: string;\n },\n): (question: QuestionCardInput) => Promise<string | string[] | undefined> {\n return async (question) => {\n if (!input.questions || !input.channel.sendCard) return undefined;\n const { id, promise } = input.questions.register(input.scope, {\n kind: question.kind,\n question: question.question,\n ...(question.options === undefined ? {} : { options: question.options }),\n ...(question.placeholder === undefined ? {} : { placeholder: question.placeholder }),\n });\n try {\n await input.channel.sendCard(input.chatId, renderQuestionCard({ ...question, id }));\n } catch (error) {\n log.fail('question-card', error, { scope: input.scope });\n input.questions.settleAll(input.scope);\n return undefined;\n }\n return promise;\n };\n}\n\nfunction buildPrompt(\n history: Array<{ role: 'user' | 'assistant'; content: string }>,\n messages: string[],\n role: RoleDefinition | undefined,\n): string {\n const rolePreamble = role ? renderRolePreamble(role) : undefined;\n const userText = messages.join('\\n\\n');\n if (history.length === 0 && !rolePreamble) return userText;\n\n const transcript = history\n .map((message) => `${message.role === 'user' ? 'User' : 'Assistant'}: ${message.content}`)\n .join('\\n\\n');\n\n const parts: string[] = [];\n if (rolePreamble) parts.push(rolePreamble, '');\n if (history.length > 0) {\n parts.push('Continue the conversation using the history below.', '', transcript, '');\n }\n parts.push(`Current user message:\\n${userText}`);\n return parts.join('\\n');\n}\n\nfunction renderRolePreamble(role: RoleDefinition): string {\n const lines = [\n `[Role instructions]`,\n `Role: ${role.name} (${role.id})`,\n `Persona: ${role.persona}`,\n ];\n if (role.model) lines.push(`Model preference: ${role.model}`);\n if (role.tools) lines.push(`Tools guidance: ${role.tools}`);\n if (role.agentsMd) {\n lines.push('', 'Role rules (AGENTS.md):', role.agentsMd);\n }\n lines.push(\n '',\n 'Stay in this role for the whole turn unless the user explicitly changes it.',\n );\n return lines.join('\\n');\n}\n\nfunction applyEvent(\n state: RunState,\n event: AgentEvent,\n stopRequested: { value: boolean },\n): RunState {\n if (event.type === 'done' && event.terminationReason === 'interrupted') {\n stopRequested.value = true;\n return markInterrupted(state);\n }\n if (event.type === 'error' && event.terminationReason === 'timeout') {\n return markIdleTimeout(state, 0);\n }\n return reduce(state, event);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import type { AgentEvent } from '../adapters/types.js';\n\nexport type ToolStatus = 'running' | 'done' | 'error';\n\nexport interface ToolEntry {\n id: string;\n name: string;\n input: unknown;\n status: ToolStatus;\n output?: string;\n}\n\nexport type Block =\n | { kind: 'text'; content: string; streaming: boolean }\n | { kind: 'tool'; tool: ToolEntry };\n\nexport type FooterStatus = 'thinking' | 'tool_running' | 'streaming' | null;\nexport type Terminal = 'running' | 'done' | 'interrupted' | 'error' | 'idle_timeout';\n\nexport interface RunState {\n blocks: Block[];\n reasoning: { content: string; active: boolean };\n usage: { inputTokens: number | undefined; outputTokens: number | undefined } | undefined;\n footer: FooterStatus;\n terminal: Terminal;\n errorMsg: string | undefined;\n idleTimeoutMinutes: number | undefined;\n}\n\nexport const initialState: RunState = {\n blocks: [],\n reasoning: { content: '', active: false },\n usage: undefined,\n footer: 'thinking',\n terminal: 'running',\n errorMsg: undefined,\n idleTimeoutMinutes: undefined,\n};\n\nfunction closeStreamingText(blocks: Block[]): Block[] {\n return blocks.map((block) =>\n block.kind === 'text' && block.streaming ? { ...block, streaming: false } : block,\n );\n}\n\nexport function reduce(state: RunState, event: AgentEvent): RunState {\n switch (event.type) {\n case 'text': {\n const last = state.blocks[state.blocks.length - 1];\n if (last?.kind === 'text' && last.streaming) {\n return {\n ...state,\n blocks: [\n ...state.blocks.slice(0, -1),\n { ...last, content: last.content + event.delta },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n return {\n ...state,\n blocks: [...state.blocks, { kind: 'text', content: event.delta, streaming: true }],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n\n case 'thinking':\n return {\n ...state,\n reasoning: {\n content: state.reasoning.content + event.delta,\n active: true,\n },\n footer: 'thinking',\n };\n\n case 'final_text':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n { kind: 'text', content: event.content, streaming: false },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: null,\n };\n\n case 'usage':\n return {\n ...state,\n usage: {\n inputTokens: event.inputTokens,\n outputTokens: event.outputTokens,\n },\n };\n\n case 'tool_use':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n {\n kind: 'tool',\n tool: {\n id: event.id,\n name: event.name,\n input: event.input,\n status: 'running',\n },\n },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'tool_running',\n };\n\n case 'tool_result':\n return {\n ...state,\n blocks: state.blocks.map((block) => {\n if (block.kind !== 'tool' || block.tool.id !== event.id) return block;\n return {\n ...block,\n tool: {\n ...block.tool,\n status: event.isError ? 'error' : 'done',\n output: event.output,\n },\n };\n }),\n };\n\n case 'error':\n return {\n ...state,\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'error',\n errorMsg: event.terminationReason === 'failed' ? event.message : undefined,\n idleTimeoutMinutes: undefined,\n footer: null,\n };\n\n case 'done':\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'done',\n footer: null,\n };\n\n default:\n return state;\n }\n}\n\nexport function markInterrupted(state: RunState): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'interrupted',\n footer: null,\n };\n}\n\nexport function markIdleTimeout(state: RunState, minutes: number): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'idle_timeout',\n footer: null,\n idleTimeoutMinutes: minutes,\n };\n}\n\nexport function finalizeIfRunning(state: RunState): RunState {\n if (state.terminal !== 'running') return state;\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'done',\n footer: null,\n };\n}\n","import type { Block, FooterStatus, RunState, ToolEntry } from './run-state.js';\nimport type { CardDensity } from './density.js';\n\nfunction markdown(content: string): object {\n return { tag: 'markdown', content };\n}\n\nfunction noteMd(content: string): object {\n return { tag: 'markdown', content, text_size: 'notation' };\n}\n\nfunction footerStatus(status: Exclude<FooterStatus, null>): object {\n const text =\n status === 'thinking'\n ? '🧠 正在思考'\n : status === 'tool_running'\n ? '🧰 正在调用工具'\n : '✍️ 正在输出';\n return noteMd(text);\n}\n\nfunction summaryText(state: RunState): string {\n if (state.terminal === 'interrupted') return '已中断';\n if (state.terminal === 'idle_timeout') return '已超时';\n if (state.terminal === 'error') return '出错';\n if (state.terminal === 'done') return '已完成';\n if (state.footer === 'tool_running') return '正在调用工具';\n if (state.footer === 'streaming') return '正在输出';\n return '思考中';\n}\n\nfunction stopButton(): object {\n return {\n tag: 'button',\n text: { tag: 'plain_text', content: '⏹ 终止' },\n type: 'danger',\n value: { cmd: 'stop' },\n };\n}\n\nfunction textBlock(block: Extract<Block, { kind: 'text' }>): object {\n return markdown(block.content);\n}\n\nfunction toolBlock(tool: ToolEntry): object {\n const icon = tool.status === 'error' ? '⚠️' : tool.status === 'done' ? '✅' : '⏳';\n return markdown(`${icon} **${tool.name}**`);\n}\n\nfunction usageLine(state: RunState): string {\n if (!state.usage) return '';\n const parts: string[] = [];\n if (state.usage.inputTokens !== undefined) parts.push(`in ${state.usage.inputTokens}`);\n if (state.usage.outputTokens !== undefined) parts.push(`out ${state.usage.outputTokens}`);\n return parts.length ? `(tokens ${parts.join(' · ')})` : '';\n}\n\nfunction renderStandard(state: RunState): object {\n const elements: object[] = [];\n\n if (state.reasoning.content) {\n elements.push(\n noteMd(\n state.reasoning.active\n ? '🧠 正在思考…'\n : `🧠 思考完成:${state.reasoning.content.slice(0, 300)}`,\n ),\n );\n }\n\n for (const block of state.blocks) {\n if (block.kind === 'text') {\n elements.push(textBlock(block));\n } else if (block.tool.status !== 'done') {\n elements.push(toolBlock(block.tool));\n }\n }\n\n if (state.terminal === 'interrupted') {\n elements.push(noteMd('_⏹ 已被中断_'));\n } else if (state.terminal === 'idle_timeout') {\n elements.push(noteMd(`_⏱ ${state.idleTimeoutMinutes ?? 0} 分钟无响应,已自动终止_`));\n } else if (state.terminal === 'error' && state.errorMsg) {\n elements.push(noteMd(`⚠️ agent 失败:${state.errorMsg}`));\n } else if (state.terminal === 'done' && elements.length === 0) {\n elements.push(noteMd('_(未返回内容)_'));\n } else if (state.terminal === 'done') {\n const usage = usageLine(state);\n if (usage) elements.push(noteMd(usage));\n }\n\n if (state.terminal === 'running') {\n if (state.footer) elements.push(footerStatus(state.footer));\n elements.push(stopButton());\n }\n\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n\nfunction renderCompact(state: RunState): object {\n const elements: object[] = [noteMd(summaryText(state))];\n if (state.terminal === 'running' && state.footer) {\n elements.push(footerStatus(state.footer));\n }\n if (state.terminal === 'running') {\n elements.push(stopButton());\n }\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n\nfunction renderDetailed(state: RunState): object {\n const elements: object[] = [];\n\n if (state.reasoning.content) {\n elements.push(\n noteMd(\n state.reasoning.active\n ? '🧠 正在思考…'\n : `🧠 **思考过程**\\n${state.reasoning.content.slice(0, 2000)}`,\n ),\n );\n }\n\n for (const block of state.blocks) {\n if (block.kind === 'text') {\n elements.push(textBlock(block));\n continue;\n }\n const tool = block.tool;\n const icon = tool.status === 'error' ? '⚠️' : tool.status === 'done' ? '✅' : '⏳';\n const lines = [`${icon} **${tool.name}**`];\n if (tool.input !== undefined && tool.input !== '') {\n lines.push(`输入:\\`\\`\\`\\n${safeJsonPreview(tool.input)}\\n\\`\\`\\``);\n }\n if (tool.output) {\n lines.push(`输出:${tool.output.slice(0, 500)}`);\n }\n elements.push(markdown(lines.join('\\n')));\n }\n\n if (state.terminal === 'interrupted') {\n elements.push(noteMd('_⏹ 已被中断_'));\n } else if (state.terminal === 'idle_timeout') {\n elements.push(noteMd(`_⏱ ${state.idleTimeoutMinutes ?? 0} 分钟无响应,已自动终止_`));\n } else if (state.terminal === 'error' && state.errorMsg) {\n elements.push(noteMd(`⚠️ agent 失败:${state.errorMsg}`));\n } else if (state.terminal === 'done') {\n const usage = usageLine(state);\n if (usage) elements.push(noteMd(usage));\n }\n\n if (state.terminal === 'running') {\n if (state.footer) elements.push(footerStatus(state.footer));\n elements.push(stopButton());\n }\n\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n\nfunction safeJsonPreview(value: unknown): string {\n if (typeof value === 'string') return value.slice(0, 300);\n try {\n return JSON.stringify(value).slice(0, 300);\n } catch {\n return String(value).slice(0, 300);\n }\n}\n\n/** Render the run card at the requested density (compact / standard / detailed). */\nexport function renderCard(state: RunState, density: CardDensity = 'standard'): object {\n if (density === 'compact') return renderCompact(state);\n if (density === 'detailed') return renderDetailed(state);\n return renderStandard(state);\n}\n","import type { ApprovalOption } from '../adapters/types.js';\n\nexport interface ApprovalCardInput {\n id: string;\n toolName: string;\n reason: string | undefined;\n options: readonly ApprovalOption[];\n}\n\n/**\n * Feishu approval card for ACP `session/request_permission`: one-shot\n * allow / reject buttons, mirroring the options offered by the harness.\n */\nexport function renderApprovalCard(input: ApprovalCardInput): object {\n const allow = input.options.find((option) => option.kind === 'allow_once') ??\n input.options.find((option) => option.kind === 'allow_always');\n const reject = input.options.find((option) => option.kind === 'reject_once') ??\n input.options.find((option) => option.kind === 'reject_always');\n\n const markdown = [\n '🔐 **审批请求**',\n '',\n `**工具** \\`${input.toolName}\\``,\n ...(input.reason ? ['', input.reason] : []),\n ].join('\\n');\n\n const actions = [\n ...(allow\n ? [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: `✅ ${allow.name}` },\n type: 'primary',\n value: { cmd: 'approve', id: input.id, outcome: 'allow' },\n },\n ]\n : []),\n ...(reject\n ? [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: `⛔ ${reject.name}` },\n type: 'danger',\n value: { cmd: 'approve', id: input.id, outcome: 'reject' },\n },\n ]\n : []),\n ];\n\n return {\n schema: '2.0',\n config: {\n summary: { content: '审批请求' },\n },\n body: {\n elements: [\n { tag: 'markdown', content: markdown },\n { tag: 'action', actions },\n ],\n },\n };\n}\n","export type QuestionKind = 'single' | 'multi' | 'text';\n\nexport interface QuestionCardInput {\n id: string;\n kind: QuestionKind;\n question: string;\n options?: string[];\n placeholder?: string;\n}\n\nfunction formElement(input: QuestionCardInput): object {\n if (input.kind === 'text') {\n return {\n tag: 'input',\n name: 'answer',\n placeholder: { tag: 'plain_text', content: input.placeholder ?? '请输入答案…' },\n };\n }\n const options = (input.options ?? []).map((option, index) => ({\n text: { tag: 'plain_text', content: option },\n value: `option-${index}`,\n }));\n if (input.kind === 'multi') {\n return {\n tag: 'multi_select_static',\n name: 'answer',\n placeholder: { tag: 'plain_text', content: '请选择(可多选)…' },\n options,\n };\n }\n return {\n tag: 'select_static',\n name: 'answer',\n placeholder: { tag: 'plain_text', content: '请选择…' },\n options,\n };\n}\n\n/** Structured question card: single choice, multi choice, or free text. */\nexport function renderQuestionCard(input: QuestionCardInput): object {\n return {\n schema: '2.0',\n config: {\n summary: { content: '问题' },\n },\n body: {\n elements: [\n { tag: 'markdown', content: `❓ ${input.question}` },\n formElement(input),\n {\n tag: 'action',\n actions: [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '提交' },\n type: 'primary',\n value: { cmd: 'question-submit', id: input.id },\n },\n ],\n },\n ],\n },\n };\n}\n\n/**\n * Normalize a card action value into an answer for the question kind.\n * `answer` shapes: string (text / single select) or string[] (multi select).\n */\nexport function extractQuestionAnswer(\n kind: QuestionKind,\n value: unknown,\n options?: string[],\n): string | string[] | undefined {\n const answer = value;\n if (kind === 'text') {\n return typeof answer === 'string' && answer.trim() ? answer.trim() : undefined;\n }\n const selected = Array.isArray(answer)\n ? answer.map((item) => String(item))\n : typeof answer === 'string' && answer\n ? [answer]\n : [];\n if (selected.length === 0) return undefined;\n const labels = options ?? [];\n const resolved = selected.map((item) => {\n const match = /^option-(\\d+)$/.exec(item);\n if (match) {\n const index = Number(match[1]);\n return labels[index] ?? item;\n }\n return item;\n });\n return kind === 'single' ? resolved[0] : resolved;\n}\n","import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { Document, parseDocument } from 'yaml';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { resolveDshHome } from './dsh-runtime.js';\n\nexport const DEEPSEEK_NAMESPACE = 'llm-deepseek';\nexport const DEEPSEEK_PROVIDER = 'deepseek-official';\nexport const DEEPSEEK_DEFAULT_API_KEY_ENV = 'DEEPSEEK_API_KEY';\nexport const PIAI_NAMESPACE = 'llm-pi-ai';\nexport const AGENT_DEFAULT_MODEL_NAMESPACE = 'agent-default-model';\n\n/**\n * Wire protocols a dsh-llm-pi-ai profile may name. Mirrors\n * `supportedProtocols()` from @deepseek-ai/dsh-llm-pi-ai; anything else is\n * refused at configuration time by the official validator.\n */\nexport const SUPPORTED_PI_AI_PROTOCOLS = [\n 'openai-completions',\n 'openai-responses',\n 'anthropic-messages',\n] as const;\nexport type PiAiProtocol = (typeof SUPPORTED_PI_AI_PROTOCOLS)[number];\n\nconst PROVIDER_ID_PATTERN = /^[a-z][a-z0-9._-]*$/;\n/** POSIX identifier rule enforced by dsh-credentials for `.credentials.yaml`. */\nconst CREDENTIAL_REF_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport interface DshModelEntry {\n id: string;\n name: string | undefined;\n contextWindow: number | undefined;\n maxTokens: number | undefined;\n}\n\nexport interface DshProviderSummary {\n id: string;\n displayName: string;\n namespace: string;\n configured: boolean;\n credentialRef: string | undefined;\n credentialReady: boolean;\n models: DshModelEntry[];\n /** Whether dsh-lark-bot can add/update/remove this provider via chat. */\n managed: boolean;\n}\n\nexport interface DshProviderManagerOptions {\n home?: string;\n env?: NodeJS.ProcessEnv;\n settingsFile?: string;\n credentialsFile?: string;\n}\n\nexport interface DshPiAiProviderInput {\n id: string;\n displayName?: string;\n apiKeyEnv?: string;\n api?: string;\n baseURL?: string;\n models?: DshModelEntry[];\n}\n\nconst DEFAULT_DEEPSEEK_MODELS: DshModelEntry[] = [\n { id: 'deepseek-v4-flash', name: 'DeepSeek-V4-Flash', contextWindow: undefined, maxTokens: undefined },\n { id: 'deepseek-v4-pro', name: 'DeepSeek-V4-Pro', contextWindow: undefined, maxTokens: undefined },\n];\n\nconst LOCK_TIMEOUT_MS = 10_000;\n\nfunction isMapLike(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction deepEqualJson(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nfunction parseModels(value: unknown): DshModelEntry[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const models: DshModelEntry[] = [];\n for (const raw of value) {\n if (!isMapLike(raw) || typeof raw.id !== 'string' || raw.id.length === 0) continue;\n models.push({\n id: raw.id,\n name: typeof raw.name === 'string' ? raw.name : undefined,\n contextWindow:\n typeof raw.contextWindow === 'number' ? raw.contextWindow : undefined,\n maxTokens: typeof raw.maxTokens === 'number' ? raw.maxTokens : undefined,\n });\n }\n return models;\n}\n\n/** Raw model entries preserved verbatim so exotic fields survive round-trips. */\nfunction rawModels(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter((entry): entry is Record<string, unknown> => isMapLike(entry));\n}\n\nfunction modelRecord(input: DshModelEntry): Record<string, unknown> {\n const record: Record<string, unknown> = { id: input.id };\n if (input.name !== undefined) record.name = input.name;\n if (input.contextWindow !== undefined) record.contextWindow = input.contextWindow;\n if (input.maxTokens !== undefined) record.maxTokens = input.maxTokens;\n return record;\n}\n\nfunction validateProviderId(id: string): void {\n if (!PROVIDER_ID_PATTERN.test(id)) {\n throw new Error(`provider id 必须是小写字母开头且仅含 a-z 0-9 . _ -,得到 \"${id}\"`);\n }\n}\n\nfunction validateBaseUrl(url: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new Error(`baseURL 不是合法 URL:${url}`);\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error(`baseURL 仅支持 http/https:${url}`);\n }\n}\n\nfunction assertProtocol(api: string): asserts api is PiAiProtocol {\n if (!(SUPPORTED_PI_AI_PROTOCOLS as readonly string[]).includes(api)) {\n throw new Error(`不支持的 API 协议 \"${api}\",可选:${SUPPORTED_PI_AI_PROTOCOLS.join(' / ')}`);\n }\n}\n\n/** Comment-preserving leaf patch used by dsh-settings-file. */\nfunction patchNode(\n document: Document,\n path: readonly (string | number)[],\n current: unknown,\n next: unknown,\n): void {\n if (isMapLike(current) && isMapLike(next)) {\n for (const key of Object.keys(current)) {\n if (!(key in next)) document.deleteIn([...path, key]);\n }\n for (const [key, value] of Object.entries(next)) {\n patchNode(document, [...path, key], current[key], value);\n }\n return;\n }\n if (!deepEqualJson(current, next)) document.setIn([...path], next);\n}\n\nfunction parseYamlMap(text: string | undefined, filename: string): Record<string, unknown> {\n if (text === undefined || text.trim().length === 0) return {};\n const document = parseDocument(text, { prettyErrors: true });\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh config at ${filename}: ${document.errors.map((e) => e.message).join('; ')}`);\n }\n const root = document.toJS() ?? {};\n if (!isMapLike(root)) {\n throw new TypeError(`dsh config ${filename} must be a mapping`);\n }\n return root;\n}\n\nasync function readOptional(file: string): Promise<string | undefined> {\n try {\n return await readFile(file, 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw error;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Cross-process writer lock compatible with dsh's own protocol: an exclusive\n * `<file>.lock` sibling created with the `wx` flag, released by removal.\n */\nasync function withFileLock<T>(filename: string, operation: () => Promise<T>): Promise<T> {\n const lockPath = `${filename}.lock`;\n const deadline = Date.now() + LOCK_TIMEOUT_MS;\n for (;;) {\n try {\n await writeFile(lockPath, `${process.pid}\\n`, { flag: 'wx' });\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;\n if (Date.now() >= deadline) {\n throw new Error(`dsh config lock timed out at ${lockPath}`);\n }\n await sleep(80 + Math.random() * 120);\n }\n }\n try {\n return await operation();\n } finally {\n await rm(lockPath, { force: true }).catch(() => undefined);\n }\n}\n\nexport class DshProviderManager {\n private readonly home: string;\n private readonly env: NodeJS.ProcessEnv;\n private readonly settingsFile: string;\n private readonly credentialsFile: string;\n\n constructor(options: DshProviderManagerOptions = {}) {\n this.home = options.home ?? homedir();\n this.env = options.env ?? process.env;\n const dshHome = resolveDshHome(this.home, this.env);\n this.settingsFile = options.settingsFile ?? join(dshHome, 'settings.yaml');\n this.credentialsFile = options.credentialsFile ?? join(dshHome, '.credentials.yaml');\n }\n\n async readSettings(): Promise<Record<string, unknown>> {\n return parseYamlMap(await readOptional(this.settingsFile), this.settingsFile);\n }\n\n async readCredentials(): Promise<Record<string, string>> {\n const root = parseYamlMap(await readOptional(this.credentialsFile), this.credentialsFile);\n const entries: Record<string, string> = {};\n for (const [key, value] of Object.entries(root)) {\n if (typeof value === 'string' && value.length > 0) entries[key] = value;\n }\n return entries;\n }\n\n async hasCredential(ref: string): Promise<boolean> {\n const entries = await this.readCredentials();\n if (entries[ref]) return true;\n return Boolean(this.env[ref]?.trim());\n }\n\n async listCredentialRefs(): Promise<string[]> {\n return Object.keys(await this.readCredentials());\n }\n\n async listProviders(): Promise<DshProviderSummary[]> {\n const settings = await this.readSettings();\n return [await this.describeDeepseek(settings), ...(await this.describePiAi(settings))];\n }\n\n private async describeDeepseek(settings: Record<string, unknown>): Promise<DshProviderSummary> {\n const deepseek = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const credentialRef =\n typeof deepseek.apiKeyEnv === 'string' && deepseek.apiKeyEnv.length > 0\n ? deepseek.apiKeyEnv\n : DEEPSEEK_DEFAULT_API_KEY_ENV;\n return {\n id: DEEPSEEK_PROVIDER,\n displayName: 'DeepSeek',\n namespace: DEEPSEEK_NAMESPACE,\n configured: Object.keys(deepseek).length > 0,\n credentialRef,\n credentialReady: await this.hasCredential(credentialRef),\n models: parseModels(deepseek.models) ?? DEFAULT_DEEPSEEK_MODELS,\n managed: true,\n };\n }\n\n private async describePiAi(settings: Record<string, unknown>): Promise<DshProviderSummary[]> {\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const summaries: DshProviderSummary[] = [];\n for (const [id, raw] of Object.entries(providers)) {\n const profile = isMapLike(raw) ? raw : {};\n const ref =\n typeof profile.apiKeyEnv === 'string' && profile.apiKeyEnv.length > 0\n ? profile.apiKeyEnv\n : undefined;\n summaries.push({\n id,\n displayName: typeof profile.displayName === 'string' ? profile.displayName : id,\n namespace: PIAI_NAMESPACE,\n configured: true,\n credentialRef: ref,\n credentialReady: ref === undefined ? false : await this.hasCredential(ref),\n models: parseModels(profile.models) ?? [],\n managed: true,\n });\n }\n return summaries;\n }\n\n async defaultModel(): Promise<string | undefined> {\n const settings = await this.readSettings();\n const section = settings[AGENT_DEFAULT_MODEL_NAMESPACE];\n return isMapLike(section) && typeof section.model === 'string' ? section.model : undefined;\n }\n\n async setDefaultModel(model: string): Promise<void> {\n if (!model.trim()) throw new Error('默认模型不能为空');\n await this.writeNamespace(AGENT_DEFAULT_MODEL_NAMESPACE, { model });\n }\n\n async upsertDeepseekProvider(input: {\n baseURL?: string;\n apiKeyEnv?: string;\n apiKey?: string;\n }): Promise<void> {\n const settings = await this.readSettings();\n const current = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const section = { ...current };\n if (input.baseURL !== undefined) {\n validateBaseUrl(input.baseURL);\n section.baseURL = input.baseURL;\n }\n if (input.apiKeyEnv !== undefined) section.apiKeyEnv = input.apiKeyEnv;\n if (input.apiKey !== undefined) {\n const ref =\n typeof section.apiKeyEnv === 'string' && section.apiKeyEnv.length > 0\n ? section.apiKeyEnv\n : DEEPSEEK_DEFAULT_API_KEY_ENV;\n await this.setCredential(ref, input.apiKey);\n }\n await this.writeNamespace(DEEPSEEK_NAMESPACE, section);\n }\n\n async removeDeepseekProvider(): Promise<void> {\n const settings = await this.readSettings();\n const section = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n await this.deleteNamespace(DEEPSEEK_NAMESPACE);\n await this.removeCredential(\n typeof section.apiKeyEnv === 'string' && section.apiKeyEnv.length > 0\n ? section.apiKeyEnv\n : DEEPSEEK_DEFAULT_API_KEY_ENV,\n );\n }\n\n async addDeepseekModel(input: DshModelEntry): Promise<void> {\n const settings = await this.readSettings();\n const current = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const models =\n rawModels(current.models).length > 0\n ? rawModels(current.models)\n : DEFAULT_DEEPSEEK_MODELS.map((model) => modelRecord(model));\n if (models.some((model) => model.id === input.id)) {\n throw new Error(`模型 ${input.id} 已存在于 ${DEEPSEEK_PROVIDER}`);\n }\n await this.writeNamespace(DEEPSEEK_NAMESPACE, {\n ...current,\n models: [...models, modelRecord(input)],\n });\n }\n\n async removeDeepseekModel(id: string): Promise<boolean> {\n const settings = await this.readSettings();\n const current = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const models = rawModels(current.models);\n if (models.length === 0) return false;\n const next = models.filter((model) => model.id !== id);\n if (next.length === models.length) return false;\n await this.writeNamespace(DEEPSEEK_NAMESPACE, { ...current, models: next });\n return true;\n }\n\n async upsertPiAiProvider(input: DshPiAiProviderInput): Promise<void> {\n validateProviderId(input.id);\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const existing = isMapLike(providers[input.id]) ? providers[input.id] : undefined;\n const section: Record<string, unknown> = existing === undefined ? {} : { ...existing };\n\n if (input.displayName !== undefined) section.displayName = input.displayName;\n if (input.apiKeyEnv !== undefined) section.apiKeyEnv = input.apiKeyEnv;\n if (input.api !== undefined) {\n assertProtocol(input.api);\n section.api = input.api;\n }\n if (input.baseURL !== undefined) {\n validateBaseUrl(input.baseURL);\n section.baseURL = input.baseURL;\n }\n if (input.models !== undefined) section.models = input.models.map(modelRecord);\n\n if (existing === undefined) {\n if (typeof section.api !== 'string') {\n throw new Error('新增自定义 provider 必须指定 --api(openai-completions / openai-responses / anthropic-messages)');\n }\n assertProtocol(section.api);\n if (typeof section.baseURL !== 'string') {\n throw new Error('新增自定义 provider 必须指定 --base-url');\n }\n validateBaseUrl(section.baseURL);\n const models = rawModels(section.models);\n if (models.length === 0) {\n throw new Error('新增自定义 provider 至少需要一个 --model(models 不能为空)');\n }\n for (const model of models) {\n if (typeof model.id !== 'string' || model.id.length === 0) {\n throw new Error(`--model 缺少有效 id:${JSON.stringify(model)}`);\n }\n }\n }\n\n await this.writeNamespace(PIAI_NAMESPACE, {\n ...piAi,\n providers: { ...providers, [input.id]: section },\n });\n }\n\n async removePiAiProvider(id: string): Promise<boolean> {\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n if (!(id in providers)) return false;\n const next: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(providers)) {\n if (key !== id) next[key] = value;\n }\n if (Object.keys(next).length === 0) {\n await this.deleteNamespace(PIAI_NAMESPACE);\n } else {\n await this.writeNamespace(PIAI_NAMESPACE, { ...piAi, providers: next });\n }\n return true;\n }\n\n async addPiAiModel(providerId: string, input: DshModelEntry): Promise<void> {\n validateProviderId(providerId);\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const section = isMapLike(providers[providerId]) ? providers[providerId] : undefined;\n if (section === undefined) {\n throw new Error(`provider ${providerId} 不存在,请先用 /provider add 创建`);\n }\n const models = rawModels(section.models);\n if (models.some((model) => model.id === input.id)) {\n throw new Error(`模型 ${input.id} 已存在于 ${providerId}`);\n }\n await this.writeNamespace(PIAI_NAMESPACE, {\n ...piAi,\n providers: {\n ...providers,\n [providerId]: { ...section, models: [...models, modelRecord(input)] },\n },\n });\n }\n\n async removePiAiModel(providerId: string, modelId: string): Promise<boolean> {\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const section = isMapLike(providers[providerId]) ? providers[providerId] : undefined;\n if (section === undefined) {\n throw new Error(`provider ${providerId} 不存在`);\n }\n const models = rawModels(section.models);\n const next = models.filter((model) => model.id !== modelId);\n if (next.length === models.length) return false;\n await this.writeNamespace(PIAI_NAMESPACE, {\n ...piAi,\n providers: {\n ...providers,\n [providerId]: { ...section, models: next },\n },\n });\n return true;\n }\n\n async setCredential(ref: string, value: string): Promise<void> {\n if (!CREDENTIAL_REF_PATTERN.test(ref)) {\n throw new Error(`非法凭据引用名:${ref}(应为 POSIX 环境变量名,如 OPENAI_API_KEY)`);\n }\n if (value.length === 0) throw new Error('凭据值不能为空');\n await mkdir(dirname(this.credentialsFile), { recursive: true, mode: 0o700 });\n await withFileLock(this.credentialsFile, async () => {\n const text = await readOptional(this.credentialsFile);\n const root = parseYamlMap(text, this.credentialsFile);\n const document = text === undefined || text.trim().length === 0\n ? new Document()\n : parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh credentials at ${this.credentialsFile}`);\n }\n patchNode(document, [ref], root[ref], value);\n await writeFileAtomic(this.credentialsFile, document.toString(), { mode: 0o600 });\n });\n }\n\n async removeCredential(ref: string): Promise<boolean> {\n let removed = false;\n await withFileLock(this.credentialsFile, async () => {\n const text = await readOptional(this.credentialsFile);\n if (text === undefined || text.trim().length === 0) return;\n const document = parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh credentials at ${this.credentialsFile}`);\n }\n if (document.has(ref)) {\n document.deleteIn([ref]);\n removed = true;\n await writeFileAtomic(this.credentialsFile, document.toString(), { mode: 0o600 });\n }\n });\n return removed;\n }\n\n private async writeNamespace(ns: string, section: Record<string, unknown>): Promise<void> {\n await mkdir(dirname(this.settingsFile), { recursive: true });\n await withFileLock(this.settingsFile, async () => {\n const text = await readOptional(this.settingsFile);\n const root = parseYamlMap(text, this.settingsFile);\n if (text === undefined || text.trim().length === 0) {\n await writeFileAtomic(this.settingsFile, new Document({ [ns]: section }).toString(), {});\n return;\n }\n const document = parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh settings at ${this.settingsFile}`);\n }\n patchNode(document, [ns], root[ns], section);\n await writeFileAtomic(this.settingsFile, document.toString(), {});\n });\n }\n\n private async deleteNamespace(ns: string): Promise<void> {\n await withFileLock(this.settingsFile, async () => {\n const text = await readOptional(this.settingsFile);\n if (text === undefined || text.trim().length === 0) return;\n const document = parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh settings at ${this.settingsFile}`);\n }\n if (document.has(ns)) {\n document.deleteIn([ns]);\n await writeFileAtomic(this.settingsFile, document.toString(), {});\n }\n });\n }\n}\n","import type { DshModelEntry, DshProviderSummary } from '../config/dsh-config.js';\nimport { DEEPSEEK_PROVIDER, SUPPORTED_PI_AI_PROTOCOLS } from '../config/dsh-config.js';\nimport type { CommandContext } from './index.js';\n\ninterface ParsedArgs {\n positionals: string[];\n flags: Record<string, string | undefined>;\n repeated: Record<string, string[]>;\n}\n\nfunction parseArgs(input: string): ParsedArgs {\n const tokens = input.trim().split(/\\s+/).filter(Boolean);\n const positionals: string[] = [];\n const flags: Record<string, string | undefined> = {};\n const repeated: Record<string, string[]> = {};\n for (let index = 0; index < tokens.length; index += 1) {\n const token = tokens[index] ?? '';\n if (!token.startsWith('--')) {\n positionals.push(token);\n continue;\n }\n const name = token.slice(2);\n const next = tokens[index + 1];\n let value: string | undefined;\n if (next !== undefined && !next.startsWith('--')) {\n value = next;\n index += 1;\n }\n flags[name] = value;\n if (value !== undefined) {\n const list = repeated[name] ?? [];\n list.push(value);\n repeated[name] = list;\n }\n }\n return { positionals, flags, repeated };\n}\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nfunction requireAdmin(ctx: CommandContext): boolean {\n if (!ctx.accessManager.isAdmin(ctx.senderId)) {\n void reply(ctx, '仅管理员可执行该操作。');\n return false;\n }\n return true;\n}\n\nfunction formatModel(model: { id: string; name: string | undefined }): string {\n return model.name ? `\\`${model.id}\\` (${model.name})` : `\\`${model.id}\\``;\n}\n\nfunction credentialLabel(provider: DshProviderSummary): string {\n if (provider.credentialReady) return '凭据就绪';\n return provider.credentialRef === undefined ? '未配置凭据' : '凭据缺失';\n}\n\nfunction formatProviders(providers: readonly DshProviderSummary[]): string {\n const lines = providers.map((provider) => {\n const state = provider.configured ? '已配置' : '未配置';\n const models = provider.models.length > 0\n ? provider.models.map((model) => model.id).join(', ')\n : '(无)';\n return `- **${provider.id}** (${provider.displayName}) — ${state} · ${credentialLabel(provider)}\\n models: ${models}`;\n });\n return lines.join('\\n');\n}\n\nasync function findModelOwner(\n ctx: CommandContext,\n id: string,\n): Promise<DshProviderSummary | undefined> {\n const providers = await ctx.dshConfig.listProviders();\n return providers.find((provider) => provider.models.some((model) => model.id === id));\n}\n\nfunction deepseekModelInput(args: {\n id: string;\n flags: Record<string, string | undefined>;\n}): DshModelEntry {\n return {\n id: args.id,\n name: args.flags.name,\n contextWindow: undefined,\n maxTokens: undefined,\n };\n}\n\nexport async function handleModel(args: string, ctx: CommandContext): Promise<void> {\n const { positionals, flags } = parseArgs(args);\n const [sub, ...rest] = positionals;\n\n if (!sub) {\n const active = ctx.models.get(ctx.scope) ?? ctx.defaultModel;\n const dshDefault = await ctx.dshConfig.defaultModel();\n const providers = await ctx.dshConfig.listProviders();\n const modelLines = providers.flatMap((provider) =>\n provider.models.map((model) => `- ${formatModel(model)} ← ${provider.id}`),\n );\n await reply(\n ctx,\n [\n `**当前会话模型**:\\`${active}\\``,\n `**dsh 默认模型**(agent-default-model):\\`${dshDefault ?? '(未设置)'}\\``,\n `**bot 回退默认**(profile / DSH_LARK_MODEL):\\`${ctx.defaultModel}\\``,\n '',\n '**可用模型**(dsh 已配置):',\n ...(modelLines.length > 0 ? modelLines : ['(暂无)']),\n '',\n '用法:`/model use <id>`、`/model default <id>`、`/model reset`、`/model add|remove <provider> <modelId> [--name <name>]`',\n ].join('\\n'),\n );\n return;\n }\n\n if (sub === 'use') {\n const id = rest.join(' ').trim();\n if (!id) {\n await reply(ctx, '用法:`/model use <modelId>`');\n return;\n }\n const provider = await findModelOwner(ctx, id);\n if (!provider) {\n await reply(ctx, `未找到模型 \\`${id}\\`,可用 /model 查看列表。`);\n return;\n }\n ctx.models.set(ctx.scope, id);\n await reply(ctx, `已热切换当前会话模型:\\`${id}\\`(下一轮消息生效,无需重启 bot)。`);\n return;\n }\n\n if (sub === 'reset') {\n const cleared = ctx.models.clear(ctx.scope);\n await reply(ctx, cleared ? '已清除当前会话模型覆盖,恢复 bot 默认模型。' : '当前会话没有模型覆盖。');\n return;\n }\n\n if (sub === 'default') {\n const id = rest.join(' ').trim();\n if (!id) {\n await reply(ctx, '用法:`/model default <modelId>`');\n return;\n }\n const provider = await findModelOwner(ctx, id);\n if (!provider) {\n await reply(ctx, `未找到模型 \\`${id}\\`,可用 /model 查看列表。`);\n return;\n }\n if (!requireAdmin(ctx)) return;\n await ctx.dshConfig.setDefaultModel(id);\n await reply(ctx, `已写入 dsh 默认模型(agent-default-model):\\`${id}\\`,新会话生效。`);\n return;\n }\n\n if (sub === 'add' || sub === 'remove') {\n if (!requireAdmin(ctx)) return;\n const providerId = rest[0];\n const id = rest[1];\n if (!providerId || !id) {\n await reply(ctx, `用法:\\`/model ${sub} <provider> <modelId> [--name <name>]\\``);\n return;\n }\n if (sub === 'add') {\n if (providerId === DEEPSEEK_PROVIDER) {\n await ctx.dshConfig.addDeepseekModel(deepseekModelInput({ id, flags }));\n await reply(ctx, `已添加模型:\\`${providerId}\\` → \\`${id}\\`(settings.yaml 已更新,下一请求生效)。`);\n } else {\n await ctx.dshConfig.addPiAiModel(providerId, deepseekModelInput({ id, flags }));\n await reply(ctx, `已添加模型:\\`${providerId}\\` → \\`${id}\\`(settings.yaml 已更新,下一请求生效)。`);\n }\n } else if (providerId === DEEPSEEK_PROVIDER) {\n const removed = await ctx.dshConfig.removeDeepseekModel(id);\n await reply(ctx, removed ? `已删除模型:\\`${providerId}\\` → \\`${id}\\`。` : `未找到模型:\\`${id}\\`。`);\n } else {\n const removed = await ctx.dshConfig.removePiAiModel(providerId, id);\n await reply(ctx, removed ? `已删除模型:\\`${providerId}\\` → \\`${id}\\`。` : `未找到模型:\\`${id}\\`。`);\n }\n return;\n }\n\n await reply(ctx, '未知 `/model` 子命令,请使用 use / default / reset / add / remove。');\n}\n\nexport async function handleProviders(_args: string, ctx: CommandContext): Promise<void> {\n const providers = await ctx.dshConfig.listProviders();\n const dshDefault = await ctx.dshConfig.defaultModel();\n await reply(\n ctx,\n [\n '**dsh 已配置 providers**',\n '',\n ...formatProviders(providers).split('\\n'),\n '',\n `dsh 默认模型:\\`${dshDefault ?? '(未设置)'}\\``,\n '',\n '管理:`/provider add|update|remove`、`/model add|remove`、`/key set|remove`(需管理员)',\n ].join('\\n'),\n );\n}\n\nexport async function handleProvider(args: string, ctx: CommandContext): Promise<void> {\n const { positionals, flags, repeated } = parseArgs(args);\n const [sub, id] = positionals;\n\n if ((sub === 'add' || sub === 'update') && id) {\n if (!requireAdmin(ctx)) return;\n const deepseekFlags = ['base-url', 'api-key-env', 'api-key'];\n const piAiFlags = [\n 'display-name',\n 'api-key-env',\n 'api',\n 'base-url',\n 'model',\n ];\n const provided = new Set([...Object.keys(flags), ...Object.keys(repeated)]);\n\n if (id === DEEPSEEK_PROVIDER) {\n const unsupported = [...provided].filter((name) => !deepseekFlags.includes(name));\n if (unsupported.length > 0) {\n await reply(ctx, `\\`deepseek-official\\` 仅支持 ${deepseekFlags.map((name) => `--${name}`).join(' / ')},不支持的参数:${unsupported.map((name) => `--${name}`).join('、')}`);\n return;\n }\n if (provided.size === 0) {\n await reply(ctx, '用法:`/provider add|update deepseek-official --base-url <url> [--api-key-env <ref>] [--api-key <key>]`');\n return;\n }\n await ctx.dshConfig.upsertDeepseekProvider({\n ...(flags['base-url'] ? { baseURL: flags['base-url'] } : {}),\n ...(flags['api-key-env'] ? { apiKeyEnv: flags['api-key-env'] } : {}),\n ...(flags['api-key'] ? { apiKey: flags['api-key'] } : {}),\n });\n await reply(\n ctx,\n `已${sub === 'add' ? '添加/更新' : '更新'} provider:\\`${id}\\`。凭据${flags['api-key'] ? '已写入 .credentials.yaml(值已隐藏)' : '不变'};其他字段按参数更新。`,\n );\n return;\n }\n\n const unsupported = [...provided].filter((name) => !piAiFlags.includes(name));\n if (unsupported.length > 0) {\n await reply(ctx, `不支持的参数:${unsupported.map((name) => `--${name}`).join('、')}。可用:${piAiFlags.map((name) => `--${name}`).join(' / ')}`);\n return;\n }\n if (provided.size === 0) {\n await reply(ctx, '用法:`/provider add|update <id> --api <protocol> --base-url <url> --model <modelId> [--display-name <name>] [--api-key-env <ref>]`');\n return;\n }\n const models = (repeated.model ?? []).map((modelId) => ({\n id: modelId,\n name: undefined,\n contextWindow: undefined,\n maxTokens: undefined,\n }));\n try {\n await ctx.dshConfig.upsertPiAiProvider({\n id,\n ...(flags['display-name'] ? { displayName: flags['display-name'] } : {}),\n ...(flags['api-key-env'] ? { apiKeyEnv: flags['api-key-env'] } : {}),\n ...(flags.api ? { api: flags.api } : {}),\n ...(flags['base-url'] ? { baseURL: flags['base-url'] } : {}),\n ...(models.length > 0 ? { models } : {}),\n });\n const protocolNote = flags.api ? `协议 \\`${flags.api}\\`` : '协议不变';\n const modelNote = models.length > 0 ? `,models 已${sub === 'add' ? '写入' : '替换为'} ${models.length} 个` : '';\n await reply(\n ctx,\n [\n `已${sub === 'add' ? '添加' : '更新'} provider:\\`${id}\\`(${protocolNote}${modelNote})。`,\n '',\n '凭据请用 `/key set <引用名> <值>` 写入(或配置对应环境变量),密钥不会显示在聊天中。',\n `协议可选:${SUPPORTED_PI_AI_PROTOCOLS.join(' / ')}`,\n ].join('\\n'),\n );\n } catch (error) {\n await reply(ctx, `操作失败:${error instanceof Error ? error.message : String(error)}`);\n }\n return;\n }\n\n if (sub === 'remove' && id) {\n if (!requireAdmin(ctx)) return;\n if (id === DEEPSEEK_PROVIDER) {\n await ctx.dshConfig.removeDeepseekProvider();\n await reply(\n ctx,\n `已删除 provider:\\`${id}\\`(含 settings 中 llm-deepseek 段及对应凭据)。此操作会移除 dsh 官方 DeepSeek 配置,请谨慎。`,\n );\n return;\n }\n const removed = await ctx.dshConfig.removePiAiProvider(id);\n await reply(ctx, removed ? `已删除 provider:\\`${id}\\`(settings.yaml 已更新)。` : `未找到 provider:\\`${id}\\`。`);\n return;\n }\n\n await reply(\n ctx,\n [\n '用法:',\n '- `/provider add <id> --api <protocol> --base-url <url> --model <modelId> [--model <modelId> ...] [--display-name <name>] [--api-key-env <ref>]`',\n '- `/provider update <id> [--api <protocol>] [--base-url <url>] [--model <modelId> ...] [--display-name <name>] [--api-key-env <ref>]`',\n '- `/provider remove <id>`',\n '',\n `\\`deepseek-official\\` 仅支持 --base-url / --api-key-env / --api-key;其他 id 走 llm-pi-ai 自定义 provider(协议可选:${SUPPORTED_PI_AI_PROTOCOLS.join(' / ')})。`,\n ].join('\\n'),\n );\n}\n\nexport async function handleKey(args: string, ctx: CommandContext): Promise<void> {\n const { positionals } = parseArgs(args);\n const [sub, ...rest] = positionals;\n\n if (!sub || sub === 'list') {\n const refs = await ctx.dshConfig.listCredentialRefs();\n await reply(\n ctx,\n [\n '**dsh 凭据**(仅显示引用名,不显示值):',\n ...(refs.length > 0 ? refs.map((ref) => `- \\`${ref}\\``) : ['(.credentials.yaml 暂无条目)']),\n '',\n '提示:环境变量中的凭据不会显示在这里;provider 的 apiKeyEnv 可引用任意环境变量。',\n ].join('\\n'),\n );\n return;\n }\n\n if (!requireAdmin(ctx)) return;\n\n if (sub === 'set') {\n const ref = rest[0];\n const value = rest.slice(1).join(' ').trim();\n if (!ref || !value) {\n await reply(ctx, '用法:`/key set <引用名> <值>`');\n return;\n }\n try {\n await ctx.dshConfig.setCredential(ref, value);\n } catch (error) {\n await reply(ctx, `写入失败:${error instanceof Error ? error.message : String(error)}`);\n return;\n }\n await reply(\n ctx,\n `已写入凭据 \\`${ref}\\` 到 \\`~/.dsh/.credentials.yaml\\`(0600,值已隐藏)。建议在私聊中使用;群聊里粘贴的密钥会对群成员可见。`,\n );\n return;\n }\n\n if (sub === 'remove') {\n const ref = rest[0];\n if (!ref) {\n await reply(ctx, '用法:`/key remove <引用名>`');\n return;\n }\n const removed = await ctx.dshConfig.removeCredential(ref);\n await reply(ctx, removed ? `已删除凭据 \\`${ref}\\`。` : `未找到凭据 \\`${ref}\\`。`);\n return;\n }\n\n await reply(ctx, '用法:`/key set <引用名> <值>`、`/key remove <引用名>`、`/key list`');\n}\n","import type { CommandContext } from './index.js';\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\n/** `/archive [note]` — export the full live session transcript to durable storage. */\nexport async function handleArchive(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const archiver = ctx.archiver;\n\n if (sub === 'list') {\n const limitInput = rest[0] ?? '5';\n const limit = Number(limitInput);\n const n = Number.isInteger(limit) && limit > 0 ? limit : 5;\n const records = (await archiver.list(ctx.scope)).slice(0, n);\n if (records.length === 0) {\n await reply(ctx, '当前 scope 还没有归档记录。');\n return;\n }\n const lines = records.map(\n (record) =>\n `- \\`${record.archiveId}\\` · ${String(record.messageCount)} msgs · ${record.source} · ${record.archivedAt}`,\n );\n await reply(ctx, [`**当前 scope 归档记录**`, '', ...lines].join('\\n'));\n return;\n }\n\n if (sub === 'clean') {\n const pruneOptions = {\n ...(ctx.archiveMax > 0 ? { maxArchives: ctx.archiveMax } : {}),\n ...(ctx.archiveMaxAgeDays > 0\n ? { maxAgeMs: ctx.archiveMaxAgeDays * 24 * 60 * 60 * 1000 }\n : {}),\n };\n const removed = await archiver.prune(pruneOptions);\n await reply(ctx, removed > 0 ? `已清理 ${String(removed)} 条过期归档。` : '没有需要清理的归档。');\n return;\n }\n\n const history = ctx.sessions.fullHistoryFor(ctx.scope, cwd);\n const note = args.trim() || undefined;\n const record = await archiver.archive({\n scope: ctx.scope,\n cwd,\n messages: history,\n source: 'manual',\n ...(note === undefined ? {} : { note }),\n });\n const commit = record.gitCommit ? `(git commit \\`${record.gitCommit}\\`)` : '';\n await reply(\n ctx,\n [\n `已归档当前会话:**${String(record.messageCount)}** 条消息${commit}`,\n `- Markdown: \\`${record.markdownPath}\\``,\n `- JSONL: \\`${record.jsonlPath}\\``,\n '',\n '历史消息会按保留策略自动归档;可用 `/retention` 调整保留条数。',\n ].join('\\n'),\n );\n await archiver.prune({\n ...(ctx.archiveMax > 0 ? { maxArchives: ctx.archiveMax } : {}),\n ...(ctx.archiveMaxAgeDays > 0\n ? { maxAgeMs: ctx.archiveMaxAgeDays * 24 * 60 * 60 * 1000 }\n : {}),\n });\n}\n\n/** `/retention [N|default]` — view or set the live message retention window. */\nexport async function handleRetention(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effective = ctx.retentionStore.get(ctx.scope) ?? ctx.defaultRetention;\n\n if (!input) {\n await reply(\n ctx,\n `当前会话保留最近 **${String(effective)}** 条消息(超出部分自动归档)。可用 \\`/retention <N|default>\\` 调整。`,\n );\n return;\n }\n\n if (input === 'default') {\n ctx.retentionStore.clear(ctx.scope);\n await reply(ctx, `已恢复默认保留条数(${String(ctx.defaultRetention)})。`);\n return;\n }\n\n const n = Number(input);\n if (!Number.isInteger(n) || n <= 0) {\n await reply(ctx, '用法:`/retention <N|default>`,N 为大于 0 的条数。');\n return;\n }\n\n ctx.retentionStore.set(ctx.scope, n);\n await reply(ctx, `已设置当前会话保留最近 **${String(n)}** 条消息。`);\n}\n","import type { RoleStore } from '../bot/role-store.js';\nimport type { CommandContext } from './index.js';\n\ninterface ParsedRoleArgs {\n positionals: string[];\n flags: Record<string, string | undefined>;\n}\n\n/**\n * Parse `/role save <id> <name> --flag value...` where long flags consume\n * everything up to the next flag, so multi-word persona/rules text works.\n */\nfunction parseRoleArgs(input: string): ParsedRoleArgs {\n const positionals: string[] = [];\n const flags: Record<string, string | undefined> = {};\n let rest = input.trim();\n while (rest) {\n const flagMatch = rest.match(/^--([a-z-]+)\\s*/);\n if (!flagMatch) {\n const token = rest.split(/\\s+/, 1)[0] ?? '';\n positionals.push(token);\n rest = rest.slice(token.length).trim();\n continue;\n }\n const flag = flagMatch[1] ?? '';\n rest = rest.slice(flagMatch[0].length);\n const nextFlag = rest.search(/\\s--[a-z-]+(?:\\s|$)/);\n if (nextFlag === -1) {\n flags[flag] = rest.trim();\n rest = '';\n } else {\n flags[flag] = rest.slice(0, nextFlag).trim();\n rest = rest.slice(nextFlag).trim();\n }\n }\n return { positionals, flags };\n}\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nfunction requireAdmin(ctx: CommandContext): boolean {\n if (!ctx.accessManager.isAdmin(ctx.senderId)) {\n void reply(ctx, '仅管理员可执行该操作。');\n return false;\n }\n return true;\n}\n\nfunction describeRole(role: NonNullable<ReturnType<RoleStore['get']>>): string {\n const lines = [\n `**${role.name}** (\\`${role.id}\\`)`,\n '',\n role.persona,\n ];\n if (role.model) lines.push('', `- model: \\`${role.model}\\``);\n if (role.tools) lines.push(`- tools: \\`${role.tools}\\``);\n if (role.agentsMd) lines.push('', '**rules (AGENTS.md):**', '', role.agentsMd);\n return lines.join('\\n');\n}\n\n/** `/role list` — list roles and the current scope binding. */\nasync function handleRoleList(ctx: CommandContext): Promise<void> {\n const roles = ctx.roleStore.list();\n const current = ctx.roleStore.roleForScope(ctx.scope);\n if (roles.length === 0) {\n await reply(ctx, '还没有定义角色。管理员可用 `/role save <id> <name> --persona <text>` 创建。');\n return;\n }\n const lines = roles.map((role) => {\n const marker = role.id === current?.id ? ' ← 当前 scope' : '';\n return `- \\`${role.id}\\` — **${role.name}**${marker}`;\n });\n await reply(ctx, ['**角色列表**', '', ...lines].join('\\n'));\n}\n\n/** `/role show <id>` — show role details. */\nasync function handleRoleShow(args: string, ctx: CommandContext): Promise<void> {\n const id = args.trim();\n const role = ctx.roleStore.get(id);\n if (!role) {\n await reply(ctx, `未找到角色:\\`${id}\\``);\n return;\n }\n await reply(ctx, describeRole(role));\n}\n\n/** `/role set <id>` / `/role clear` — bind or unbind the current scope. */\nasync function handleRoleSet(args: string, ctx: CommandContext): Promise<void> {\n const id = args.trim();\n if (!ctx.roleStore.setScopeRole(ctx.scope, id)) {\n await reply(ctx, `未找到角色:\\`${id}\\`,请先 \\`/role save\\` 创建。`);\n return;\n }\n await reply(ctx, `当前 scope 已绑定角色:\\`${id}\\`。下一轮消息生效。`);\n}\n\nasync function handleRoleClear(_args: string, ctx: CommandContext): Promise<void> {\n const cleared = ctx.roleStore.clearScopeRole(ctx.scope);\n await reply(ctx, cleared ? '已解除当前 scope 的角色绑定。' : '当前 scope 未绑定角色。');\n}\n\n/** `/role save <id> <name> [--persona ..] [--model ..] [--tools ..] [--rules ..]` — admin. */\nasync function handleRoleSave(args: string, ctx: CommandContext): Promise<void> {\n if (!requireAdmin(ctx)) return;\n const { positionals, flags } = parseRoleArgs(args);\n const [id, name] = positionals;\n if (!id || !name) {\n await reply(\n ctx,\n '用法:`/role save <id> <name> [--persona <text>] [--model <id>] [--tools <csv>] [--rules <text>]`',\n );\n return;\n }\n const existing = ctx.roleStore.get(id);\n const persona = flags.persona ?? existing?.persona;\n if (!persona) {\n await reply(ctx, '`--persona` 必填(或更新已有角色时省略以保留原 persona)。');\n return;\n }\n const model = flags.model ?? existing?.model;\n const tools = flags.tools ?? existing?.tools;\n const agentsMd = flags.rules ?? existing?.agentsMd;\n ctx.roleStore.upsert({\n id,\n name,\n persona,\n ...(model === undefined ? {} : { model }),\n ...(tools === undefined ? {} : { tools }),\n ...(agentsMd === undefined ? {} : { agentsMd }),\n });\n await reply(ctx, `角色已保存:\\`${id}\\`(${name})。`);\n}\n\n/** `/role remove <id>` — admin. */\nasync function handleRoleRemove(args: string, ctx: CommandContext): Promise<void> {\n if (!requireAdmin(ctx)) return;\n const id = args.trim();\n const removed = ctx.roleStore.remove(id);\n await reply(ctx, removed ? `已删除角色:\\`${id}\\`(相关 scope 绑定一并清除)。` : `未找到角色:\\`${id}\\``);\n}\n\nexport async function handleRole(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n switch (sub) {\n case 'list':\n case undefined:\n case '':\n await handleRoleList(ctx);\n return;\n case 'show':\n await handleRoleShow(rest.join(' ').trim(), ctx);\n return;\n case 'set':\n await handleRoleSet(rest.join(' ').trim(), ctx);\n return;\n case 'clear':\n await handleRoleClear('', ctx);\n return;\n case 'save':\n await handleRoleSave(rest.join(' ').trim(), ctx);\n return;\n case 'remove':\n await handleRoleRemove(rest.join(' ').trim(), ctx);\n return;\n default:\n await reply(ctx, '未知 `/role` 子命令,请使用 list / show / set / clear / save / remove。');\n }\n}\n","import type { CommandContext } from './index.js';\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\n/** `/notify <scope|chatId> <text>` — admin-only cross-session messaging. */\nasync function handleNotifySend(args: string, ctx: CommandContext): Promise<void> {\n if (!ctx.accessManager.isAdmin(ctx.senderId)) {\n await reply(ctx, '仅管理员可执行该操作。');\n return;\n }\n const match = args.trim().match(/^(\\S+)\\s+([\\s\\S]+)$/);\n if (!match) {\n await reply(ctx, '用法:`/notify <scope|chatId> <text>`');\n return;\n }\n const target = match[1] ?? '';\n const text = match[2]?.trim() ?? '';\n if (!text) {\n await reply(ctx, '用法:`/notify <scope|chatId> <text>`');\n return;\n }\n\n const destination =\n ctx.scopeDirectory.resolve(target) ?? ctx.scopeDirectory.resolveChat(target);\n if (!destination) {\n await reply(\n ctx,\n `未知的目标 scope/chat:\\`${target}\\`。可用 \\`/notify list\\` 查看已注册的 scope。`,\n );\n return;\n }\n await ctx.channel.sendMarkdown(destination.chatId, text, {\n ...(destination.threadId ? { threadId: destination.threadId } : {}),\n });\n await reply(ctx, `已发送通知到 \\`${target}\\`(chat \\`${destination.chatId}\\`)。`);\n}\n\n/** `/notify list` — show every scope known to the bridge. */\nasync function handleNotifyList(_args: string, ctx: CommandContext): Promise<void> {\n const scopes = ctx.scopeDirectory.knownScopes();\n if (scopes.length === 0) {\n await reply(ctx, '暂无已注册的 scope(至少需要一个会话发过消息)。');\n return;\n }\n const lines = scopes.map((scope) => {\n const entry = ctx.scopeDirectory.resolve(scope);\n return `- \\`${scope}\\` → chat \\`${entry?.chatId ?? ''}\\`${entry?.threadId ? ` / thread \\`${entry.threadId}\\`` : ''}`;\n });\n await reply(ctx, ['**已注册 scope**', '', ...lines].join('\\n'));\n}\n\nexport async function handleNotify(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n if (sub === 'list') {\n await handleNotifyList(rest.join(' ').trim(), ctx);\n return;\n }\n await handleNotifySend(args, ctx);\n}\n","import type {\n CardStreamController as LarkCardStreamController,\n LarkChannel,\n MentionInfo,\n SendOptions,\n} from '@larksuite/channel';\nimport type { CommandChannel } from '../commands/index.js';\nimport type { StreamingChannel } from './types.js';\nimport type { MentionTarget, SendOptions as BridgeSendOptions } from './send-options.js';\n\nfunction toLarkSendOptions(options: BridgeSendOptions | undefined): SendOptions {\n const sendOptions: SendOptions = {};\n if (options?.replyTo) sendOptions.replyTo = options.replyTo;\n if (options?.threadId) sendOptions.replyInThread = true;\n if (options?.mentions && options.mentions.length > 0) {\n sendOptions.mentions = options.mentions\n .map((mention: MentionTarget): MentionInfo | undefined => ({\n key: `out-${mention.userId}`,\n ...(mention.userId.startsWith('ou_') || mention.userId.startsWith('on_')\n ? { openId: mention.userId }\n : { userId: mention.userId }),\n ...(mention.name === undefined ? {} : { name: mention.name }),\n }))\n .filter((mention): mention is MentionInfo => mention !== undefined);\n }\n return sendOptions;\n}\n\nexport function adaptLarkChannel(channel: LarkChannel): StreamingChannel {\n const base: CommandChannel = {\n async sendMarkdown(chatId, markdown, options) {\n await channel.send(chatId, { markdown }, toLarkSendOptions(options));\n },\n };\n\n return {\n ...base,\n async sendCard(chatId, card, options) {\n await channel.send(chatId, { card }, toLarkSendOptions(options));\n },\n async streamCard(chatId, initial, producer, options) {\n await channel.stream(\n chatId,\n {\n card: {\n initial,\n producer: async (controller: LarkCardStreamController) => {\n await producer(controller);\n },\n },\n },\n toLarkSendOptions(options),\n );\n },\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface ScopeEntry {\n scope: string;\n chatId: string;\n threadId: string | undefined;\n lastSeenAt: string;\n}\n\ninterface ScopeData {\n entries: Record<string, ScopeEntry>;\n}\n\n/**\n * Persistent scope → chat/thread directory. Every inbound message registers\n * its scope, so the bridge can later push outbound notifications to other\n * chats/topics (cross-session messaging). Persisted per profile at\n * `<profile>/scopes.json` so targets survive restarts.\n */\nexport class ScopeDirectory {\n private data: ScopeData = { entries: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<ScopeData>;\n this.data = { entries: parsed.entries ?? {} };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = { entries: {} };\n }\n }\n\n register(scope: string, chatId: string, threadId: string | undefined): void {\n const existing = this.data.entries[scope];\n this.data.entries[scope] = {\n scope,\n chatId,\n threadId: threadId ?? existing?.threadId,\n lastSeenAt: new Date().toISOString(),\n };\n this.schedulePersist();\n }\n\n /** Resolve a scope key to its chat destination. */\n resolve(scope: string): { chatId: string; threadId: string | undefined } | undefined {\n const entry = this.data.entries[scope];\n if (!entry) return undefined;\n return { chatId: entry.chatId, threadId: entry.threadId };\n }\n\n /** Direct chat lookup by chatId (also matches topic scopes by prefix). */\n resolveChat(chatId: string): { chatId: string; threadId: string | undefined } | undefined {\n if (this.data.entries[chatId]) return this.resolve(chatId);\n const entry = Object.values(this.data.entries).find((item) => item.chatId === chatId);\n return entry ? { chatId: entry.chatId, threadId: entry.threadId } : undefined;\n }\n\n knownScopes(): string[] {\n return Object.keys(this.data.entries);\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = {\n entries: Object.fromEntries(\n Object.entries(this.data.entries).map(([scope, entry]) => [\n scope,\n { ...entry },\n ]),\n ),\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('scope-directory', error, { step: 'persist' });\n });\n }\n}\n","import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport { randomBytes } from 'node:crypto';\nimport { log } from '../core/logger.js';\nimport type { MentionTarget } from '../bridge/types.js';\n\nexport interface NotifyMessage {\n token: string;\n /** Scope key (chat id or `chat:thread`); resolved via the scope directory. */\n scope?: string;\n /** Direct chat id fallback when scope is unknown. */\n chatId?: string;\n threadId?: string;\n text: string;\n mentions?: MentionTarget[];\n}\n\nexport interface NotifyDestination {\n chatId: string;\n threadId: string | undefined;\n}\n\nexport interface NotifyServerDeps {\n token: string;\n port?: number;\n /** Resolve a scope/chat target to a concrete chat destination. */\n resolve: (message: NotifyMessage) => NotifyDestination | undefined;\n /** Send the outbound message (mentions supported). */\n send: (\n destination: NotifyDestination,\n payload: { text: string; mentions?: MentionTarget[] },\n ) => Promise<void>;\n}\n\n/**\n * Localhost-only callback server for the dsh `lark_notify` tool. The dsh\n * runtime (a child process) calls back into the bridge process over\n * `http://127.0.0.1:<port>/notify` with a shared token, so agents can mention\n * users and push messages to other chats/topics without exposing anything to\n * the network.\n */\nexport class NotifyServer {\n private server: Server | undefined;\n private readonly token: string;\n private readonly deps: NotifyServerDeps;\n url: string | undefined;\n\n constructor(deps: NotifyServerDeps) {\n this.deps = deps;\n this.token = deps.token;\n }\n\n async start(): Promise<void> {\n if (this.server) return;\n const server = createServer((req, res) => {\n void this.handle(req, res);\n });\n this.server = server;\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(this.deps.port ?? 0, '127.0.0.1', () => {\n const address = server.address() as AddressInfo;\n this.url = `http://127.0.0.1:${String(address.port)}/notify`;\n resolve();\n });\n });\n log.info('notify', 'server-started', { url: this.url });\n }\n\n async stop(): Promise<void> {\n const server = this.server;\n this.server = undefined;\n if (!server) return;\n await new Promise<void>((resolve) => {\n server.close(() => resolve());\n server.closeAllConnections?.();\n });\n }\n\n private async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const respond = (status: number, body: Record<string, unknown>): void => {\n res.writeHead(status, { 'content-type': 'application/json' });\n res.end(`${JSON.stringify(body)}\\n`);\n };\n if (req.method !== 'POST' || req.url !== '/notify') {\n respond(404, { ok: false, error: 'not found' });\n return;\n }\n try {\n const body = await readBody(req);\n const message = JSON.parse(body) as NotifyMessage;\n if (message.token !== this.token) {\n respond(401, { ok: false, error: 'invalid token' });\n return;\n }\n if (!message.text?.trim()) {\n respond(400, { ok: false, error: 'text is required' });\n return;\n }\n const destination = this.deps.resolve(message);\n if (!destination) {\n respond(404, { ok: false, error: `unknown scope/chat: ${message.scope ?? message.chatId ?? ''}` });\n return;\n }\n await this.deps.send(destination, {\n text: message.text,\n ...(message.mentions === undefined ? {} : { mentions: message.mentions }),\n });\n respond(200, { ok: true, chatId: destination.chatId, threadId: destination.threadId ?? null });\n } catch (error) {\n log.fail('notify', error);\n respond(500, { ok: false, error: error instanceof Error ? error.message : String(error) });\n }\n }\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n if (chunks.reduce((size, item) => size + item.length, 0) > 1_000_000) {\n reject(new Error('payload too large'));\n req.destroy();\n }\n });\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n req.on('error', reject);\n });\n}\n\nexport function generateNotifyToken(): string {\n return `dsh-lark-${randomBytes(18).toString('hex')}`;\n}\n","import type { ConfigStore, ProfileConfig } from './profile-store.js';\n\nexport interface AccessSnapshot {\n allowedUsers: string[];\n allowedChats: string[];\n admins: string[];\n}\n\nexport class AccessManager {\n constructor(\n private readonly store: ConfigStore,\n private readonly profileName: string,\n ) {}\n\n snapshot(): AccessSnapshot {\n const profile = this.profile();\n return {\n allowedUsers: [...profile.access.allowedUsers],\n allowedChats: [...profile.access.allowedChats],\n admins: [...profile.access.admins],\n };\n }\n\n isAdmin(openId: string | undefined): boolean {\n return Boolean(openId && this.snapshot().admins.includes(openId));\n }\n\n async addUser(id: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);\n await this.persist(snapshot);\n }\n\n async addAdmin(id: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);\n if (!snapshot.admins.includes(id)) snapshot.admins.push(id);\n await this.persist(snapshot);\n }\n\n async addChat(chatId: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedChats.includes(chatId)) snapshot.allowedChats.push(chatId);\n await this.persist(snapshot);\n }\n\n async removeUser(id: string): Promise<void> {\n const snapshot = this.snapshot();\n snapshot.allowedUsers = snapshot.allowedUsers.filter((item) => item !== id);\n snapshot.admins = snapshot.admins.filter((item) => item !== id);\n await this.persist(snapshot);\n }\n\n async removeChat(chatId: string): Promise<void> {\n const snapshot = this.snapshot();\n snapshot.allowedChats = snapshot.allowedChats.filter((item) => item !== chatId);\n await this.persist(snapshot);\n }\n\n private profile(): ProfileConfig {\n const profile = this.store.getProfile(this.profileName);\n if (!profile) throw new Error(`profile not found: ${this.profileName}`);\n return profile;\n }\n\n private async persist(snapshot: AccessSnapshot): Promise<void> {\n const profile = this.profile();\n await this.store.saveProfile(this.profileName, {\n tenant: profile.tenant,\n appId: profile.accounts.appId,\n appSecret: profile.accounts.appSecret,\n access: snapshot,\n });\n }\n}\n","import { registerApp, type RegisterAppOptions, type RegisterAppResult } from '@larksuite/channel';\nimport qrcode from 'qrcode-terminal';\nimport type { LarkTenant } from '../config/env.js';\n\nexport interface OnboardedApp {\n appId: string;\n appSecret: string;\n tenant: LarkTenant;\n operatorOpenId: string | undefined;\n}\n\nexport interface RegistrationDeps {\n register?: (options: RegisterAppOptions) => Promise<RegisterAppResult>;\n renderQr?: (value: string) => void;\n print?: (line: string) => void;\n source?: string;\n signal?: AbortSignal;\n}\n\nconst DEFAULT_SOURCE = 'dsh-lark-bot';\n\nexport async function onboardPersonalAgent(\n deps: RegistrationDeps = {},\n): Promise<OnboardedApp> {\n const register = deps.register ?? registerApp;\n const renderQr = deps.renderQr ?? ((value) => qrcode.generate(value, { small: true }));\n const print = deps.print ?? ((line) => process.stdout.write(`${line}\\n`));\n\n print('');\n print('未检测到飞书 / Lark 应用凭据,进入扫码创建向导。');\n print('');\n\n const result = await register({\n source: deps.source ?? DEFAULT_SOURCE,\n ...(deps.signal ? { signal: deps.signal } : {}),\n onQRCodeReady: (info) => {\n print('请使用飞书 / Lark App 扫描以下二维码,创建或选择 PersonalAgent 应用:');\n print('');\n renderQr(info.url);\n print('');\n const minutes = Math.max(1, Math.round(info.expireIn / 60));\n print(`二维码有效期约 ${minutes} 分钟。`);\n print(`也可以直接在浏览器打开:${info.url}`);\n print('');\n },\n onStatusChange: (info) => {\n if (info.status === 'domain_switched') {\n print('已识别到国际版租户,自动切换到 larksuite.com 域名。');\n } else if (info.status === 'slow_down') {\n print('轮询速度过快,已自动降速。');\n }\n },\n });\n\n const tenant: LarkTenant = result.user_info?.tenant_brand === 'lark' ? 'lark' : 'feishu';\n\n print('✓ PersonalAgent 应用创建 / 绑定成功。');\n print(` App ID: ${result.client_id}`);\n print(` Tenant: ${tenant}`);\n print('');\n\n return {\n appId: result.client_id,\n appSecret: result.client_secret,\n tenant,\n operatorOpenId: result.user_info?.open_id,\n };\n}\n","import { mkdir, readFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { isPathWithin, truncateUtf8Safe } from '../config/security.js';\nimport type {\n LarkChannel,\n NormalizedMessage,\n} from '@larksuite/channel';\n\nexport interface PreparedAttachments {\n imagePaths: string[];\n textFileNotes: string[];\n}\n\nconst MAX_TEXT_FILE_BYTES = 256_000;\n\nfunction assertSafeMediaName(mediaDir: string, destination: string): void {\n if (!isPathWithin(mediaDir, destination)) {\n throw new Error(`unsafe attachment destination rejected: ${destination}`);\n }\n}\n\nexport async function prepareAttachments(\n channel: LarkChannel | undefined,\n message: NormalizedMessage,\n mediaDir: string,\n): Promise<PreparedAttachments> {\n await mkdir(mediaDir, { recursive: true });\n const result: PreparedAttachments = { imagePaths: [], textFileNotes: [] };\n\n for (const resource of message.resources) {\n if (!channel || resource.type !== 'image' && resource.type !== 'file') continue;\n const destination = join(mediaDir, `${message.messageId}-${resource.fileKey}`);\n assertSafeMediaName(mediaDir, destination);\n await channel.downloadResourceToFile(\n message.messageId,\n resource.fileKey,\n resource.type,\n destination,\n );\n\n if (resource.type === 'image') {\n result.imagePaths.push(destination);\n continue;\n }\n\n const info = await stat(destination);\n if (info.size > MAX_TEXT_FILE_BYTES) {\n result.textFileNotes.push(`[attachment: ${resource.fileName ?? resource.fileKey}] ${destination}`);\n continue;\n }\n\n const content = await readFile(destination, 'utf8');\n const safeContent = truncateUtf8Safe(content, MAX_TEXT_FILE_BYTES);\n result.textFileNotes.push(\n `[attachment: ${resource.fileName ?? resource.fileKey}]\\n${safeContent}`,\n );\n }\n\n return result;\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface SessionRecord {\n sessionId: string | undefined;\n cwd: string;\n messages: ChatMessage[];\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport interface RecordExchangeOptions {\n /** Max live messages kept for the scope (overflow is archived, then trimmed). */\n retention?: number;\n /** Called with the messages that fall outside the retention window. */\n onArchive?: (overflow: ChatMessage[]) => void | Promise<void>;\n}\n\ninterface SessionData {\n chats: Record<string, SessionRecord>;\n}\n\nexport class SessionStore {\n private data: SessionData = { chats: {} };\n private saving: Promise<void> = Promise.resolve();\n private pendingArchive: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<SessionData>;\n this.data = {\n chats: Object.fromEntries(\n Object.entries(parsed.chats ?? {}).map(([scope, record]) => [\n scope,\n {\n sessionId: record.sessionId,\n cwd: record.cwd,\n messages: record.messages ?? [],\n },\n ]),\n ),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n getRaw(scopeId: string): SessionRecord | undefined {\n return this.data.chats[scopeId];\n }\n\n set(scopeId: string, sessionId: string | undefined, cwd: string): void {\n const existing = this.data.chats[scopeId];\n this.data.chats[scopeId] = {\n sessionId: sessionId ?? existing?.sessionId,\n cwd,\n messages: existing?.messages ?? [],\n };\n this.schedulePersist();\n }\n\n historyFor(scopeId: string, cwd: string): ChatMessage[] {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.messages : [];\n }\n\n recordExchange(\n scopeId: string,\n cwd: string,\n userMessages: string[],\n assistantMessage: string | undefined,\n options: RecordExchangeOptions = {},\n ): void {\n const existing = this.data.chats[scopeId];\n const next: ChatMessage[] = [...(existing?.messages ?? [])];\n\n for (const content of userMessages) {\n if (content.trim()) next.push({ role: 'user', content });\n }\n\n if (assistantMessage?.trim()) {\n next.push({ role: 'assistant', content: assistantMessage });\n }\n\n const retention = options.retention ?? 40;\n let kept: ChatMessage[] = next;\n if (retention > 0 && next.length > retention) {\n const overflow = next.slice(0, next.length - retention);\n kept = next.slice(-retention);\n this.pendingArchive = this.pendingArchive\n .then(async () => {\n await options.onArchive?.(overflow);\n })\n .catch((error: unknown) => {\n log.fail('session', error, { scope: scopeId, step: 'archive-overflow' });\n });\n }\n\n this.data.chats[scopeId] = {\n sessionId: existing?.sessionId,\n cwd,\n messages: kept,\n };\n this.schedulePersist();\n }\n\n /** Full live transcript for a scope (subject to the current retention window). */\n fullHistoryFor(scopeId: string, cwd: string): ChatMessage[] {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? [...record.messages] : [];\n }\n\n clear(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n fork(scopeId: string, newScopeId: string, cwd: string): boolean {\n const source = this.data.chats[scopeId];\n if (!source) return false;\n this.data.chats[newScopeId] = {\n sessionId: undefined,\n cwd,\n messages: [...source.messages],\n };\n this.schedulePersist();\n return true;\n }\n\n resumeFor(scopeId: string, cwd: string): string | undefined {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.sessionId : undefined;\n }\n\n async flush(): Promise<void> {\n await this.pendingArchive;\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = this.snapshot();\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('session', error, { step: 'persist' });\n });\n }\n\n private snapshot(): SessionData {\n return {\n chats: Object.fromEntries(\n Object.entries(this.data.chats).map(([key, record]) => [\n key,\n {\n ...record,\n messages: [...record.messages],\n },\n ]),\n ),\n };\n }\n}\n","import { execFile } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { access, mkdir, readdir, readFile, unlink, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { promisify } from 'node:util';\nimport { log } from '../core/logger.js';\nimport type { ChatMessage } from './store.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport type ArchiveSource = 'manual' | 'retention';\n\nexport interface ArchiveRecord {\n /** Stable archive id: `20260815T020000Z-<short hex>`. */\n archiveId: string;\n scope: string;\n cwd: string | undefined;\n source: ArchiveSource;\n note: string | undefined;\n messageCount: number;\n archivedAt: string;\n jsonlPath: string;\n markdownPath: string;\n gitCommit: string | undefined;\n}\n\nexport interface ArchiveInput {\n scope: string;\n cwd: string | undefined;\n messages: readonly ChatMessage[];\n source?: ArchiveSource;\n note?: string;\n}\n\nexport interface ArchivePruneOptions {\n /** Keep at most this many archives per scope (oldest removed first). */\n maxArchives?: number;\n /** Remove archives older than this many milliseconds. */\n maxAgeMs?: number;\n}\n\nfunction slugify(scope: string): string {\n const slug = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^[.]+/, '')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64);\n return slug || 'session';\n}\n\nfunction timestampId(): string {\n const stamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\\.\\d{3}/, '');\n return `${stamp}-${randomBytes(3).toString('hex')}`;\n}\n\nfunction renderMarkdown(\n input: ArchiveInput,\n record: { archiveId: string; archivedAt: string; source: ArchiveSource },\n): string {\n const lines: string[] = [\n `# dsh-lark-bot 会话归档 · Session Archive`,\n '',\n `- archiveId: \\`${record.archiveId}\\``,\n `- scope: \\`${input.scope}\\``,\n ...(input.cwd ? [`- cwd: \\`${input.cwd}\\``] : []),\n `- source: ${record.source}`,\n `- archivedAt: ${record.archivedAt}`,\n ...(input.note ? [`- note: ${input.note}`] : []),\n '',\n ];\n if (input.messages.length === 0) {\n lines.push('*(no messages)*');\n }\n for (const message of input.messages) {\n const speaker =\n message.role === 'user'\n ? 'User'\n : 'Assistant';\n lines.push(`## ${speaker}`, '', message.content, '');\n }\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction renderJsonl(input: ArchiveInput, record: { archiveId: string; archivedAt: string; source: ArchiveSource }): string {\n const header = {\n type: 'dsh-lark-archive',\n schemaVersion: 1,\n archiveId: record.archiveId,\n scope: input.scope,\n cwd: input.cwd,\n source: record.source,\n note: input.note,\n archivedAt: record.archivedAt,\n };\n const rows = [\n JSON.stringify(header),\n ...input.messages.map((message) =>\n JSON.stringify({\n role: message.role,\n content: message.content,\n }),\n ),\n ];\n return `${rows.join('\\n')}\\n`;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Durable session/task archival: every archive is written as a human-readable\n * Markdown transcript plus a machine-readable JSONL payload under\n * `<profile>/archives/<scope-slug>/`. When `git` is available, the archive\n * root is lazily initialized as its own Git repository and each archive is\n * committed, giving an auditable, replayable history that survives local\n * retention trimming.\n */\nexport class SessionArchive {\n private gitInitialized: boolean | undefined;\n\n constructor(\n private readonly archiveDir: string,\n private readonly runGit: (args: string[], cwd: string) => Promise<string> = defaultRunGit,\n ) {}\n\n async archive(input: ArchiveInput): Promise<ArchiveRecord> {\n const scopeSlug = slugify(input.scope);\n const id = timestampId();\n const archivedAt = new Date().toISOString();\n const source = input.source ?? 'manual';\n const scopeDir = join(this.archiveDir, scopeSlug);\n const jsonlPath = join(scopeDir, `${id}.jsonl`);\n const markdownPath = join(scopeDir, `${id}.md`);\n await mkdir(scopeDir, { recursive: true });\n await Promise.all([\n writeFile(jsonlPath, renderJsonl(input, { archiveId: id, archivedAt, source }), 'utf8'),\n writeFile(\n markdownPath,\n renderMarkdown(input, { archiveId: id, archivedAt, source }),\n 'utf8',\n ),\n ]);\n\n let gitCommit: string | undefined;\n try {\n await this.ensureGit();\n await this.runGit(['add', '-A', '.'], this.archiveDir);\n await this.runGit(\n ['commit', '-m', `archive ${id} (${source}, ${String(input.messages.length)} messages)`, '--no-verify'],\n this.archiveDir,\n );\n gitCommit = (await this.runGit(['rev-parse', '--short', 'HEAD'], this.archiveDir)).trim();\n } catch (error) {\n // Git is an optional transport: files are already durable on disk.\n log.warn('archive', 'git-commit-failed', {\n scope: input.scope,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n return {\n archiveId: id,\n scope: input.scope,\n cwd: input.cwd,\n source,\n note: input.note,\n messageCount: input.messages.length,\n archivedAt,\n jsonlPath,\n markdownPath,\n gitCommit,\n };\n }\n\n async list(scope?: string): Promise<ArchiveRecord[]> {\n const records: ArchiveRecord[] = [];\n const scopeDirs: Array<{ name: string; dir: string }> = [];\n if (scope === undefined) {\n if (!(await exists(this.archiveDir))) return [];\n for (const entry of await readdir(this.archiveDir, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n scopeDirs.push({ name: entry.name, dir: join(this.archiveDir, entry.name) });\n }\n } else {\n const dir = join(this.archiveDir, slugify(scope));\n if (!(await exists(dir))) return [];\n scopeDirs.push({ name: slugify(scope), dir });\n }\n for (const entry of scopeDirs) {\n const dir = entry.dir;\n const files = await readdir(dir);\n for (const file of files) {\n if (!file.endsWith('.md')) continue;\n const id = file.slice(0, -'.md'.length);\n const markdownPath = join(dir, file);\n const jsonlPath = join(dir, `${id}.jsonl`);\n const header = await readArchiveHeader(jsonlPath);\n if (!header) continue;\n records.push({\n archiveId: id,\n scope: header.scope ?? entry.name,\n cwd: header.cwd,\n source: header.source ?? 'manual',\n note: header.note,\n messageCount: header.messageCount ?? 0,\n archivedAt: header.archivedAt ?? '',\n jsonlPath,\n markdownPath,\n gitCommit: undefined,\n });\n }\n }\n return records.sort(\n (a, b) =>\n b.archivedAt.localeCompare(a.archivedAt) ||\n b.archiveId.localeCompare(a.archiveId),\n );\n }\n\n /** Remove archives beyond per-scope count/age limits. Returns the number removed. */\n async prune(options: ArchivePruneOptions = {}): Promise<number> {\n const records = await this.list();\n const byScope = new Map<string, ArchiveRecord[]>();\n for (const record of records) {\n const bucket = byScope.get(record.scope) ?? [];\n bucket.push(record);\n byScope.set(record.scope, bucket);\n }\n const now = Date.now();\n let removed = 0;\n for (const [scope, scoped] of byScope) {\n // Newest first: prune from the oldest end while keeping the newest\n // `maxArchives` records within the age window.\n const ordered = [...scoped].sort(\n (a, b) =>\n b.archivedAt.localeCompare(a.archivedAt) ||\n b.archiveId.localeCompare(a.archiveId),\n );\n const keep: ArchiveRecord[] = [];\n let keptCount = 0;\n for (const record of ordered) {\n const tooOld =\n options.maxAgeMs !== undefined &&\n record.archivedAt !== '' &&\n now - Date.parse(record.archivedAt) > options.maxAgeMs;\n const beyondCount =\n options.maxArchives !== undefined &&\n keptCount >= options.maxArchives;\n if (tooOld || beyondCount) {\n await safeRemove(record.markdownPath);\n await safeRemove(record.jsonlPath);\n removed += 1;\n log.info('archive', 'pruned', { scope, archiveId: record.archiveId });\n } else {\n keep.push(record);\n keptCount += 1;\n }\n }\n }\n if (removed > 0) {\n try {\n await this.ensureGit();\n await this.runGit(['add', '-A', '.'], this.archiveDir);\n await this.runGit(['commit', '-m', `prune ${String(removed)} archives`, '--no-verify'], this.archiveDir);\n } catch (error) {\n log.warn('archive', 'git-prune-commit-failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return removed;\n }\n\n private async ensureGit(): Promise<void> {\n if (this.gitInitialized !== undefined) return;\n await mkdir(this.archiveDir, { recursive: true });\n if (!(await exists(join(this.archiveDir, '.git')))) {\n await this.runGit(['init', '-q'], this.archiveDir);\n try {\n await this.runGit(['config', 'user.name', 'dsh-lark-bot'], this.archiveDir);\n await this.runGit(['config', 'user.email', 'dsh-lark-bot@localhost'], this.archiveDir);\n } catch {\n // Local git identity is optional; commits fall back to global config.\n }\n }\n this.gitInitialized = true;\n }\n}\n\nasync function defaultRunGit(args: string[], cwd: string): Promise<string> {\n const result = await execFileAsync('git', args, { cwd, encoding: 'utf8' });\n return result.stdout;\n}\n\ninterface ArchiveHeader {\n scope?: string;\n cwd?: string;\n source?: ArchiveSource;\n note?: string;\n messageCount?: number;\n archivedAt?: string;\n}\n\nasync function readArchiveHeader(jsonlPath: string): Promise<ArchiveHeader | undefined> {\n try {\n const raw = await readFile(jsonlPath, 'utf8');\n const firstLine = raw.split('\\n', 1)[0];\n if (!firstLine) return undefined;\n const header = JSON.parse(firstLine) as Record<string, unknown>;\n if (header.type !== 'dsh-lark-archive') return undefined;\n const parsed: ArchiveHeader = {};\n if (typeof header.scope === 'string') parsed.scope = header.scope;\n if (typeof header.cwd === 'string') parsed.cwd = header.cwd;\n if (header.source === 'manual' || header.source === 'retention') parsed.source = header.source;\n if (typeof header.note === 'string') parsed.note = header.note;\n if (typeof header.messageCount === 'number') parsed.messageCount = header.messageCount;\n if (typeof header.archivedAt === 'string') parsed.archivedAt = header.archivedAt;\n return parsed;\n } catch {\n return undefined;\n }\n}\n\nasync function safeRemove(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch {\n // Best effort; the archive file may already be gone.\n }\n}\n\nexport function archiveDisplay(record: ArchiveRecord): string {\n const commit = record.gitCommit ? ` (git ${record.gitCommit})` : '';\n return `\\`${record.archiveId}\\` · ${record.messageCount} msgs · ${record.source}${commit}`;\n}\n","import { execFile } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { promisify } from 'node:util';\nimport { isPathWithin } from '../config/security.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport type GitRunner = (args: string[], cwd: string) => Promise<string>;\n\nexport interface WorktreeEnsureResult {\n cwd: string;\n created: boolean;\n branch?: string;\n}\n\nexport interface GitWorktreeOptions {\n worktreesRoot: string;\n runGit?: GitRunner;\n copyRulesFile?: (source: string, target: string) => Promise<void>;\n}\n\nasync function defaultRunGit(args: string[], cwd: string): Promise<string> {\n const result = await execFileAsync('git', args, {\n cwd,\n encoding: 'utf8',\n });\n return result.stdout;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function defaultCopyRulesFile(source: string, target: string): Promise<void> {\n await mkdir(dirname(target), { recursive: true });\n await copyFile(source, target);\n}\n\nfunction slugify(scope: string): string {\n const slug = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^[.]+/, '')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64);\n return slug || 'session';\n}\n\nexport class GitWorktreeManager {\n private readonly runGit: GitRunner;\n private readonly copyRulesFile: (source: string, target: string) => Promise<void>;\n\n constructor(private readonly options: GitWorktreeOptions) {\n this.runGit = options.runGit ?? defaultRunGit;\n this.copyRulesFile = options.copyRulesFile ?? defaultCopyRulesFile;\n }\n\n async ensure(scope: string, base: string): Promise<WorktreeEnsureResult> {\n const isGit = await this.isGitRepository(base);\n if (!isGit) return { cwd: base, created: false };\n\n const slug = slugify(scope);\n const target = join(this.options.worktreesRoot, slug);\n if (!isPathWithin(this.options.worktreesRoot, target)) {\n throw new Error(`unsafe worktree target rejected: ${target}`);\n }\n if (await exists(target)) {\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: false };\n }\n\n const branch = `dsh-lark/${slug}-${Date.now().toString(36)}-${randomBytes(3).toString('hex')}`;\n await mkdir(this.options.worktreesRoot, { recursive: true });\n await this.runGit(['worktree', 'add', '-b', branch, target, 'HEAD'], base);\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: true, branch };\n }\n\n async isGitRepository(cwd: string): Promise<boolean> {\n try {\n const result = await this.runGit(['rev-parse', '--is-inside-work-tree'], cwd);\n return result.trim() === 'true';\n } catch {\n return false;\n }\n }\n\n private async ensureProjectRules(base: string, target: string): Promise<void> {\n const destination = join(target, 'AGENTS.md');\n if (await exists(destination)) return;\n\n const sourceCandidates = [join(base, '.dsh-lark', 'AGENTS.md'), join(base, 'AGENTS.md')];\n for (const source of sourceCandidates) {\n if (await exists(source)) {\n await this.copyRulesFile(source, destination);\n return;\n }\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\ninterface WorkspaceData {\n chats: Record<string, { cwd: string }>;\n named: Record<string, string>;\n lastUsed: Record<string, number>;\n}\n\nexport class WorkspaceStore {\n private data: WorkspaceData = { chats: {}, named: {}, lastUsed: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<WorkspaceData>;\n this.data = {\n chats: parsed.chats ?? {},\n named: parsed.named ?? {},\n lastUsed: parsed.lastUsed ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n cwdFor(scopeId: string): string | undefined {\n return this.data.chats[scopeId]?.cwd;\n }\n\n setCwd(scopeId: string, cwd: string): void {\n this.data.chats[scopeId] = { cwd };\n this.schedulePersist();\n }\n\n removeCwd(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n listNamed(): Record<string, string> {\n return { ...this.data.named };\n }\n\n getNamed(name: string): string | undefined {\n return this.data.named[name];\n }\n\n saveNamed(name: string, cwd: string): void {\n this.data.named[name] = cwd;\n this.data.lastUsed[name] = Date.now();\n this.schedulePersist();\n }\n\n touchNamed(name: string): void {\n if (!(name in this.data.named)) return;\n this.data.lastUsed[name] = Date.now();\n this.schedulePersist();\n }\n\n removeNamed(name: string): boolean {\n if (!(name in this.data.named)) return false;\n delete this.data.named[name];\n delete this.data.lastUsed[name];\n this.schedulePersist();\n return true;\n }\n\n listIndex(): Array<{ name: string; cwd: string; lastUsed: number | undefined }> {\n return Object.entries(this.data.named)\n .map(([name, cwd]) => ({ name, cwd, lastUsed: this.data.lastUsed[name] }))\n .sort((a, b) => (b.lastUsed ?? 0) - (a.lastUsed ?? 0));\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot: WorkspaceData = {\n chats: { ...this.data.chats },\n named: { ...this.data.named },\n lastUsed: { ...this.data.lastUsed },\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('workspace', error, { step: 'persist' });\n });\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\n\n/**\n * Safety-net guardian heartbeat.\n *\n * The bridge engine (running inside the dsh process) writes a small JSON\n * heartbeat file under the bridge profile directory every few seconds. The\n * guardian — a separate, minimal process — only trusts a fresh heartbeat (or\n * a live dsh process) as \"dsh is up\"; when the heartbeat goes stale AND no\n * dsh process is observable, the guardian takes over the Feishu channel.\n *\n * The heartbeat is deliberately tiny and dependency-free so the guardian can\n * read it without importing the bridge, sessions, adapters or any plugin.\n */\n\nexport interface HeartbeatPayload {\n pid: number;\n startedAt: string;\n ts: number;\n}\n\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 5_000;\n\nexport async function readHeartbeat(\n file: string,\n): Promise<HeartbeatPayload | undefined> {\n try {\n const raw = await readFile(file, 'utf8');\n const parsed = JSON.parse(raw) as Partial<HeartbeatPayload>;\n if (\n typeof parsed.pid !== 'number' ||\n typeof parsed.startedAt !== 'string' ||\n typeof parsed.ts !== 'number'\n ) {\n return undefined;\n }\n return {\n pid: parsed.pid,\n startedAt: parsed.startedAt,\n ts: parsed.ts,\n };\n } catch {\n return undefined;\n }\n}\n\nexport function heartbeatAgeMs(\n payload: HeartbeatPayload,\n now: number = Date.now(),\n): number {\n return Math.max(0, now - payload.ts);\n}\n\nexport function isHeartbeatFresh(\n payload: HeartbeatPayload | undefined,\n maxAgeMs: number,\n now: number = Date.now(),\n): boolean {\n if (payload === undefined) return false;\n return heartbeatAgeMs(payload, now) < maxAgeMs;\n}\n\nexport interface HeartbeatHandle {\n stop(): void;\n}\n\n/**\n * Write a heartbeat immediately and then every `intervalMs`. Returns a handle\n * whose `stop()` clears the timer. Failures are swallowed (the guardian treats\n * a stale/missing heartbeat as \"dsh is down\", which is the safe failure mode).\n */\nexport function startHeartbeat(\n file: string,\n pid: number,\n intervalMs: number = DEFAULT_HEARTBEAT_INTERVAL_MS,\n): HeartbeatHandle {\n const startedAt = new Date().toISOString();\n let stopped = false;\n\n const beat = async (): Promise<void> => {\n if (stopped) return;\n const payload: HeartbeatPayload = { pid, startedAt, ts: Date.now() };\n try {\n await writeFileAtomic(file, `${JSON.stringify(payload)}\\n`, {\n mode: 0o600,\n });\n } catch {\n // A failed write must never take the bridge down; the guardian will see\n // the stale/missing heartbeat and take over when appropriate.\n }\n };\n\n void beat();\n const timer = setInterval(() => {\n void beat();\n }, intervalMs);\n timer.unref?.();\n\n return {\n stop(): void {\n stopped = true;\n clearInterval(timer);\n },\n };\n}\n","import { spawn } from 'node:child_process';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { discoverDshBin, resolveDshHome } from '../../config/dsh-runtime.js';\nimport { ownPackageInfo } from '../../adapters/dsh/own-package.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { installGuardian } from '../../guardian/install.js';\n\nexport interface SetupOptions {\n /** dsh profile to install the bundle into (default `dsh-lark`). */\n profile?: string;\n /** Package spec for `dsh plugin add` (defaults to this package's npm name). */\n packageSpec?: string;\n /** DSH_HOME override (tests). */\n dshHome?: string;\n /** dsh CLI bin override (tests). */\n bin?: string;\n /** Also install the safety-net guardian as a system service. */\n guardian?: boolean;\n /** Injectable guardian installer (tests). */\n installGuardianFn?: typeof installGuardian;\n}\n\n/**\n * The single install-deploy path: installs this package as a standard dsh\n * profile bundle into `<name>`, pre-approving pnpm's build-script policy so\n * `dsh plugin add` succeeds out of the box. First boot of the profile prints\n * the QR code for one-time Feishu binding.\n */\nexport async function runSetup(options: SetupOptions = {}): Promise<void> {\n const profile = options.profile ?? 'dsh-lark';\n const own = ownPackageInfo();\n const packageSpec = options.packageSpec ?? process.env.DSH_LARK_SETUP_PACKAGE ?? own.name;\n const dshHome = options.dshHome ?? resolveDshHome(homedir(), process.env);\n const bin = options.bin ?? discoverDshBin(homedir(), process.env);\n if (!bin) {\n throw new Error(\n '未找到本机 dsh 安装(`@deepseek-ai/dsh`)。请先安装 DeepSeek Harness,再运行本命令。',\n );\n }\n\n // Pre-approve pnpm >= 10 build scripts so the first `dsh plugin add`\n // succeeds without a manual pnpm-workspace.yaml edit (protobufjs is a\n // transitive dependency of the Feishu channel SDK).\n const profileDir = join(dshHome, 'profiles', profile);\n await mkdir(profileDir, { recursive: true });\n await approveBuilds(profileDir);\n\n process.stdout.write(\n `正在把 ${packageSpec} 安装到 dsh profile \\`${profile}\\`($DSH_HOME=${dshHome})...\\n`,\n );\n await runDshPlugin(bin, profile, packageSpec);\n\n if (options.guardian) {\n const install = options.installGuardianFn ?? installGuardian;\n const guardianResult = await install({\n env: loadRuntimeEnv(process.env),\n dshProfile: profile,\n });\n for (const message of guardianResult.messages) {\n process.stdout.write(`${message}\\n`);\n }\n if (!guardianResult.ok) {\n process.stdout.write(\n '\\n注意:guardian 服务未完全启用,请按上方提示手动执行;也可稍后重跑 `dsh-lark-bot guardian install`。\\n',\n );\n }\n }\n\n process.stdout.write(\n [\n '',\n '✅ 安装完成。启动方式(唯一的部署路径):',\n '',\n ` dsh --profile ${profile}`,\n '',\n '首次启动会在终端打印二维码,用飞书 / Lark 扫码完成一次性绑定;',\n '绑定后 dsh 即以标准插件方式加载 dsh-lark-bot 的桥接引擎。',\n ...(options.guardian\n ? [\n '',\n '安全网守护已安装:dsh 下线后仍可通过飞书发送 /safemode 进入仅核心安全模式自救。',\n '查看状态:dsh-lark-bot guardian status',\n ]\n : [\n '',\n '提示:可加 --guardian 同时安装「安全网守护」(dsh 全部下线后的飞书救援通道)。',\n ]),\n '',\n ].join('\\n'),\n );\n}\n\nfunction runDshPlugin(bin: string, profile: string, packageSpec: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(\n 'node',\n [bin, 'plugin', '--profile', profile, 'add', packageSpec],\n { stdio: 'inherit' },\n );\n child.once('error', reject);\n child.once('exit', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`dsh plugin add exited with code ${String(code)}`));\n });\n });\n}\n\nasync function approveBuilds(profileDir: string): Promise<void> {\n const workspaceFile = join(profileDir, 'pnpm-workspace.yaml');\n let existing = '';\n try {\n existing = await readFile(workspaceFile, 'utf8');\n } catch {\n // No workspace file yet; create one.\n }\n const allowBuilds = [\n 'protobufjs: true',\n ...(ownPackageInfo().name.startsWith('@') ? [] : [`${ownPackageInfo().name}: true`]),\n ].join('\\n');\n if (!existing.includes('allowBuilds')) {\n existing = existing.trimEnd() ? `${existing.trimEnd()}\\n\\nallowBuilds:\\n ${allowBuilds}\\n` : `allowBuilds:\\n ${allowBuilds}\\n`;\n } else if (!existing.includes('protobufjs: true')) {\n existing = existing.replace(/(allowBuilds:\\s*\\n)/, `$1 ${allowBuilds}\\n`);\n }\n await writeFile(workspaceFile, existing, 'utf8');\n}\n","import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { ownPackageInfo } from '../adapters/dsh/own-package.js';\nimport type { RuntimeEnv } from '../config/env.js';\nimport { captureOutput } from './process.js';\nimport {\n loadGuardianState,\n newGuardianState,\n saveGuardianState,\n type GuardianState,\n} from './state.js';\n\n/**\n * System-level installation of the safety-net guardian.\n *\n * The guardian is a minimal Node process that must survive dsh / Cordis\n * going down, so it is registered with the operating system's user-level\n * service manager (systemd user unit on Linux, launchd LaunchAgent on macOS,\n * Startup entry on Windows). The unit only runs `dsh-lark-bot guardian run`;\n * all dsh knowledge lives in `~/.dsh-lark/guardian.json`.\n */\n\nexport const GUARDIAN_LABEL = 'dsh-lark-guardian';\n\nexport interface InstallGuardianOptions {\n env: RuntimeEnv;\n dshProfile?: string;\n bridgeProfile?: string;\n /** Skip writing service files; only persist the state mapping (tests). */\n dryRun?: boolean;\n /** Injectable command runner for activation (tests). */\n run?: (command: string, args: readonly string[]) => Promise<{ code: number; stdout: string; stderr: string }>;\n rootOverride?: string;\n userOverride?: string;\n}\n\nexport interface InstallResult {\n ok: boolean;\n messages: string[];\n}\n\nfunction guardianCliEntry(): string {\n return join(ownPackageInfo().root, 'dist', 'cli.js');\n}\n\nfunction serviceDirectory(platform: NodeJS.Platform, root: string): string {\n switch (platform) {\n case 'linux':\n return join(root, '.config', 'systemd', 'user');\n case 'darwin':\n return join(root, 'Library', 'LaunchAgents');\n case 'win32':\n return join(\n process.env.APPDATA ?? join(root, 'AppData', 'Roaming'),\n 'Microsoft',\n 'Windows',\n 'Start Menu',\n 'Programs',\n 'Startup',\n );\n default:\n return join(root, '.dsh-lark', 'guardian');\n }\n}\n\nexport function systemdUnit(\n nodeBin: string,\n cliEntry: string,\n env: Record<string, string> = {},\n): string {\n const envLines = Object.entries(env)\n .map(([key, value]) => `Environment=${key}=${value}`)\n .join('\\n');\n return [\n '[Unit]',\n 'Description=dsh-lark-bot safety-net guardian (Feishu rescue when dsh is down)',\n 'After=network-online.target',\n 'Wants=network-online.target',\n '',\n '[Service]',\n 'Type=simple',\n `ExecStart=${nodeBin} ${cliEntry} guardian run`,\n 'Restart=on-failure',\n 'RestartSec=5',\n ...(envLines ? [envLines] : []),\n '',\n '[Install]',\n 'WantedBy=default.target',\n '',\n ].join('\\n');\n}\n\nexport function launchdPlist(\n nodeBin: string,\n cliEntry: string,\n label: string = `io.dsh-lark.${GUARDIAN_LABEL}`,\n logPath: string = '/tmp/dsh-lark-guardian.log',\n): string {\n return [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n '<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">',\n '<plist version=\"1.0\">',\n '<dict>',\n ` <key>Label</key><string>${label}</string>`,\n ' <key>ProgramArguments</key>',\n ' <array>',\n ` <string>${nodeBin}</string>`,\n ` <string>${cliEntry}</string>`,\n ' <string>guardian</string>',\n ' <string>run</string>',\n ' </array>',\n ' <key>RunAtLoad</key><true/>',\n ' <key>KeepAlive</key><true/>',\n ` <key>StandardOutPath</key><string>${logPath}</string>`,\n ` <key>StandardErrorPath</key><string>${logPath}</string>`,\n '</dict>',\n '</plist>',\n '',\n ].join('\\n');\n}\n\nexport function windowsStartupCmd(\n nodeBin: string,\n cliEntry: string,\n): string {\n return [\n '@echo off',\n 'REM dsh-lark-bot safety-net guardian - keep the Feishu rescue entrance alive.',\n `start \"\" /b \"${nodeBin}\" \"${cliEntry}\" guardian run`,\n '',\n ].join('\\r\\n');\n}\n\nfunction defaultRun(\n command: string,\n args: readonly string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return captureOutput(command, args, 30_000);\n}\n\nexport async function installGuardian(\n options: InstallGuardianOptions,\n): Promise<InstallResult> {\n const messages: string[] = [];\n const root = options.rootOverride ?? homedir();\n const dshProfile = options.dshProfile ?? options.env.guardianProfile;\n const bridgeProfile = options.bridgeProfile ?? options.env.guardianBridgeProfile;\n const stateFile = join(root, '.dsh-lark', 'guardian.json');\n const fallback = newGuardianState({ dshProfile, bridgeProfile });\n const existing = await loadGuardianState(stateFile, fallback);\n const state: GuardianState = {\n ...existing,\n dshProfile: existing.dshProfile === dshProfile ? existing.dshProfile : dshProfile,\n bridgeProfile:\n existing.bridgeProfile === bridgeProfile ? existing.bridgeProfile : bridgeProfile,\n safeProfile: existing.safeProfile || `${dshProfile}-safe`,\n };\n await saveGuardianState(stateFile, state);\n messages.push(`守护状态已写入 ${stateFile}(dsh profile=${state.dshProfile})`);\n\n if (options.dryRun) {\n return { ok: true, messages };\n }\n\n const nodeBin = process.execPath;\n const cliEntry = guardianCliEntry();\n const directory = serviceDirectory(process.platform, root);\n await mkdir(directory, { recursive: true });\n\n if (process.platform === 'linux') {\n const unitPath = join(directory, `${GUARDIAN_LABEL}.service`);\n await writeFile(\n unitPath,\n systemdUnit(nodeBin, cliEntry, { DSH_LARK_GUARDIAN_DISABLED: '0' }),\n 'utf8',\n );\n messages.push(`systemd user unit 已写入 ${unitPath}`);\n const run = options.run ?? defaultRun;\n const reload = await run('systemctl', ['--user', 'daemon-reload']);\n const enable = await run('systemctl', ['--user', 'enable', '--now', `${GUARDIAN_LABEL}.service`]);\n if (reload.code === 0 && enable.code === 0) {\n messages.push('守护服务已启用并启动(systemctl --user)。');\n } else {\n messages.push(\n '未能自动启用服务(可能需要图形会话 / systemd user 实例)。请手动执行:',\n );\n messages.push(` systemctl --user daemon-reload && systemctl --user enable --now ${GUARDIAN_LABEL}.service`);\n return { ok: false, messages };\n }\n } else if (process.platform === 'darwin') {\n const label = `io.dsh-lark.${GUARDIAN_LABEL}`;\n const plistPath = join(directory, `${label}.plist`);\n await writeFile(plistPath, launchdPlist(nodeBin, cliEntry), 'utf8');\n messages.push(`launchd LaunchAgent 已写入 ${plistPath}`);\n const run = options.run ?? defaultRun;\n const uid = typeof options.userOverride === 'string' ? options.userOverride : String(process.getuid?.() ?? 501);\n const bootstrap = await run('launchctl', ['bootstrap', `gui/${uid}`, plistPath]);\n if (bootstrap.code === 0) {\n messages.push('守护服务已加载(launchctl bootstrap)。');\n } else {\n messages.push(\n '未能自动加载 LaunchAgent。请手动执行(或改用旧版 launchctl load -w):',\n );\n messages.push(` launchctl bootstrap gui/${uid} ${plistPath}`);\n return { ok: false, messages };\n }\n } else if (process.platform === 'win32') {\n const cmdPath = join(directory, `${GUARDIAN_LABEL}.cmd`);\n await writeFile(cmdPath, windowsStartupCmd(nodeBin, cliEntry), 'utf8');\n messages.push(`Windows 启动项已写入 ${cmdPath}(登录后自动常驻)。`);\n } else {\n const fallbackPath = join(directory, `${GUARDIAN_LABEL}.sh`);\n await writeFile(\n fallbackPath,\n `#!/bin/sh\\nexec \"${nodeBin}\" \"${cliEntry}\" guardian run\\n`,\n 'utf8',\n );\n messages.push(\n `当前平台不支持自动注册服务;已写入启动脚本 ${fallbackPath},请按需配置常驻。`,\n );\n }\n\n return { ok: true, messages };\n}\n\nexport async function uninstallGuardian(\n options: Pick<InstallGuardianOptions, 'env' | 'run' | 'rootOverride' | 'userOverride'>,\n): Promise<InstallResult> {\n const messages: string[] = [];\n const root = options.rootOverride ?? homedir();\n const run = options.run ?? defaultRun;\n\n if (process.platform === 'linux') {\n await run('systemctl', ['--user', 'disable', '--now', `${GUARDIAN_LABEL}.service`]);\n const unitPath = join(root, '.config', 'systemd', 'user', `${GUARDIAN_LABEL}.service`);\n await rm(unitPath, { force: true });\n await run('systemctl', ['--user', 'daemon-reload']);\n messages.push('systemd user unit 已移除并停止。');\n } else if (process.platform === 'darwin') {\n const label = `io.dsh-lark.${GUARDIAN_LABEL}`;\n const plistPath = join(root, 'Library', 'LaunchAgents', `${label}.plist`);\n const uid = typeof options.userOverride === 'string' ? options.userOverride : String(process.getuid?.() ?? 501);\n await run('launchctl', ['bootout', `gui/${uid}`, plistPath]);\n await rm(plistPath, { force: true });\n messages.push('launchd LaunchAgent 已移除。');\n } else if (process.platform === 'win32') {\n const startupDir = join(\n process.env.APPDATA ?? join(root, 'AppData', 'Roaming'),\n 'Microsoft',\n 'Windows',\n 'Start Menu',\n 'Programs',\n 'Startup',\n );\n await rm(join(startupDir, `${GUARDIAN_LABEL}.cmd`), { force: true });\n messages.push('Windows 启动项已移除。');\n } else {\n const fallbackPath = join(root, '.dsh-lark', 'guardian', `${GUARDIAN_LABEL}.sh`);\n await rm(fallbackPath, { force: true });\n messages.push('启动脚本已移除。');\n }\n\n messages.push('守护状态文件(~/.dsh-lark/guardian.json)已保留,可随时重新安装。');\n return { ok: true, messages };\n}\n\nexport async function readGuardianUnit(platform: NodeJS.Platform, root: string): Promise<string | undefined> {\n if (platform === 'linux') {\n const path = join(root, '.config', 'systemd', 'user', `${GUARDIAN_LABEL}.service`);\n return existsSync(path) ? readFile(path, 'utf8') : undefined;\n }\n if (platform === 'darwin') {\n const path = join(root, 'Library', 'LaunchAgents', `io.dsh-lark.${GUARDIAN_LABEL}.plist`);\n return existsSync(path) ? readFile(path, 'utf8') : undefined;\n }\n return undefined;\n}\n\nexport function guardianStatePath(root: string): string {\n return join(root, '.dsh-lark', 'guardian.json');\n}\n","import { spawn } from 'node:child_process';\n\n/**\n * Minimal process observation used by the safety-net guardian.\n *\n * The guardian must decide whether \"dsh is up\" without importing any dsh\n * code: a fresh bridge heartbeat is authoritative, and a live `dsh --profile\n * <name>` process is the fallback (it also catches the case where the bridge\n * never got to write a heartbeat because the profile boot failed).\n */\n\nexport interface ProfileProcess {\n pid: number;\n cmdline: string;\n}\n\nfunction hasProfileFlag(cmdline: string, dshProfile: string): boolean {\n // Match `--profile <name>` with either `=` or space separation; token-level\n // so `--profile dsh-lark-safe` never matches `dsh-lark`.\n const pattern = new RegExp(\n `(?:^|\\\\s)--profile(?:\\\\s+|=)${escapeRegExp(dshProfile)}(?:\\\\s|$)`,\n );\n return pattern.test(cmdline);\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function looksLikeDshProcess(cmdline: string): boolean {\n return (\n cmdline.includes('@deepseek-ai/dsh') ||\n /(?:^|\\s)dsh(?:\\.exe)?(?:\\s|$)/.test(cmdline)\n );\n}\n\nexport function matchProfileProcess(\n cmdline: string,\n dshProfile: string,\n): boolean {\n return hasProfileFlag(cmdline, dshProfile) && looksLikeDshProcess(cmdline);\n}\n\n/**\n * List `{ pid, cmdline }` for every process on the machine. Uses `ps` on\n * POSIX and PowerShell's CIM query on Windows; both are available on the\n * supported platforms.\n */\nexport async function listProcesses(): Promise<ProfileProcess[]> {\n if (process.platform === 'win32') {\n return listProcessesWindows();\n }\n return listProcessesPosix();\n}\n\nasync function listProcessesPosix(): Promise<ProfileProcess[]> {\n const { stdout } = await captureOutput('ps', ['-axo', 'pid=,args='], 10_000);\n const result: ProfileProcess[] = [];\n for (const line of stdout.split('\\n')) {\n const match = /^\\s*(\\d+)\\s+(.+)$/.exec(line);\n if (match) {\n result.push({ pid: Number(match[1]), cmdline: match[2] ?? '' });\n }\n }\n return result;\n}\n\nasync function listProcessesWindows(): Promise<ProfileProcess[]> {\n const { stdout } = await captureOutput(\n 'powershell.exe',\n [\n '-NoProfile',\n '-NonInteractive',\n '-Command',\n 'Get-CimInstance Win32_Process | Select-Object ProcessId, CommandLine | ConvertTo-Csv -NoTypeInformation',\n ],\n 10_000,\n );\n const result: ProfileProcess[] = [];\n for (const line of stdout.split('\\n').slice(1)) {\n const [pid, ...rest] = line.trim().split(',');\n const numeric = Number(pid?.replace(/\"/g, ''));\n if (Number.isInteger(numeric) && rest.length > 0) {\n // Csv quoting can split command lines; join everything after the pid.\n result.push({ pid: numeric, cmdline: rest.join(',').replace(/^\"|\"$/g, '') });\n }\n }\n return result;\n}\n\nexport async function captureOutput(\n command: string,\n args: readonly string[],\n timeoutMs: number = 30_000,\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const child = spawn(command, [...args], {\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n });\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', () => {\n resolve({ code: 1, stdout: '', stderr });\n });\n child.on('close', (code) => {\n resolve({ code: code ?? 1, stdout, stderr });\n });\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n resolve({ code: 1, stdout, stderr });\n }, timeoutMs);\n child.once('close', () => clearTimeout(timer));\n });\n}\n\nexport async function findProfileProcess(\n dshProfile: string,\n): Promise<ProfileProcess | undefined> {\n const processes = await listProcesses();\n return processes.find((entry) => matchProfileProcess(entry.cmdline, dshProfile));\n}\n\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\nexport interface DetachedSpawn {\n pid?: number | undefined;\n}\n\n/**\n * Spawn a detached process that keeps running after the guardian exits\n * (used to relaunch the full dsh profile when leaving safe mode). stdio is\n * ignored so the relaunched profile never shares the guardian's console.\n */\nexport function spawnDetached(\n command: string,\n args: readonly string[],\n env: NodeJS.ProcessEnv = process.env,\n): DetachedSpawn {\n const child = spawn(command, [...args], {\n detached: process.platform !== 'win32',\n stdio: 'ignore',\n windowsHide: true,\n env: { ...env },\n });\n if (child.pid !== undefined && process.platform !== 'win32') {\n child.unref();\n }\n return { pid: child.pid };\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\n\n/**\n * Persistent guardian state (`~/.dsh-lark/guardian.json`).\n *\n * The guardian is a separate minimal process, so everything it needs to\n * resume after a restart lives here:\n * - which dsh profile to watch / relaunch and which bridge profile provides\n * the Feishu credentials and access lists;\n * - whether the dsh profile was ever observed up (the takeover gate: we only\n * occupy the Feishu channel after the profile has actually run);\n * - the current mode (`standby` / `takeover` / `safe`).\n */\n\nexport type GuardianMode = 'standby' | 'takeover' | 'safe';\n\nexport interface GuardianState {\n schemaVersion: 1;\n dshProfile: string;\n bridgeProfile: string;\n safeProfile: string;\n /** True once the dsh profile was observed running (heartbeat or process). */\n profileSeenUp: boolean;\n mode: GuardianMode;\n /** PID of the full-profile relaunch spawned when exiting safe mode. */\n relaunchedPid?: number | undefined;\n updatedAt: string;\n}\n\nexport const DEFAULT_DSH_PROFILE = 'dsh-lark';\nexport const DEFAULT_BRIDGE_PROFILE = 'default';\n\nexport function defaultSafeProfile(dshProfile: string): string {\n return `${dshProfile}-safe`;\n}\n\nexport function newGuardianState(input: {\n dshProfile?: string;\n bridgeProfile?: string;\n}): GuardianState {\n const dshProfile = input.dshProfile ?? DEFAULT_DSH_PROFILE;\n return {\n schemaVersion: 1,\n dshProfile,\n bridgeProfile: input.bridgeProfile ?? DEFAULT_BRIDGE_PROFILE,\n safeProfile: defaultSafeProfile(dshProfile),\n profileSeenUp: false,\n mode: 'standby',\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport async function loadGuardianState(\n file: string,\n fallback: GuardianState,\n): Promise<GuardianState> {\n try {\n const raw = await readFile(file, 'utf8');\n const parsed = JSON.parse(raw) as Partial<GuardianState>;\n if (parsed.schemaVersion !== 1) return fallback;\n const dshProfile = typeof parsed.dshProfile === 'string' ? parsed.dshProfile : fallback.dshProfile;\n const bridgeProfile =\n typeof parsed.bridgeProfile === 'string' ? parsed.bridgeProfile : fallback.bridgeProfile;\n return {\n schemaVersion: 1,\n dshProfile,\n bridgeProfile,\n safeProfile:\n typeof parsed.safeProfile === 'string'\n ? parsed.safeProfile\n : defaultSafeProfile(dshProfile),\n profileSeenUp: parsed.profileSeenUp === true || fallback.profileSeenUp === true,\n mode: parsed.mode === 'takeover' || parsed.mode === 'safe' ? parsed.mode : 'standby',\n relaunchedPid:\n typeof parsed.relaunchedPid === 'number' ? parsed.relaunchedPid : undefined,\n updatedAt: parsed.updatedAt ?? new Date().toISOString(),\n };\n } catch {\n return fallback;\n }\n}\n\nexport async function saveGuardianState(\n file: string,\n state: GuardianState,\n): Promise<void> {\n const next: GuardianState = { ...state, updatedAt: new Date().toISOString() };\n await mkdir(dirname(file), { recursive: true });\n await writeFileAtomic(file, `${JSON.stringify(next, null, 2)}\\n`, { mode: 0o600 });\n}\n\n/** Mutate a copy of the state and persist it; used for small updates. */\nexport async function updateGuardianState(\n file: string,\n state: GuardianState,\n patch: Partial<GuardianState>,\n): Promise<GuardianState> {\n const next: GuardianState = { ...state, ...patch };\n await saveGuardianState(file, next);\n return next;\n}\n","import { join } from 'node:path';\nimport { loadRuntimeEnv, type RuntimeEnv } from '../../config/env.js';\nimport {\n guardianLayoutFor,\n buildGuardianService,\n} from '../../guardian/service.js';\nimport {\n heartbeatAgeMs,\n isHeartbeatFresh,\n readHeartbeat,\n} from '../../guardian/heartbeat.js';\nimport {\n installGuardian,\n uninstallGuardian,\n type InstallResult,\n} from '../../guardian/install.js';\nimport { findProfileProcess } from '../../guardian/process.js';\nimport {\n loadGuardianState,\n newGuardianState,\n} from '../../guardian/state.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\n\nexport interface GuardianCommandOptions {\n dshProfile?: string;\n bridgeProfile?: string;\n}\n\nfunction envWithOverrides(options: GuardianCommandOptions): RuntimeEnv {\n const env = loadRuntimeEnv(process.env);\n if (options.dshProfile) env.guardianProfile = options.dshProfile;\n if (options.bridgeProfile) env.guardianBridgeProfile = options.bridgeProfile;\n return env;\n}\n\nfunction printLines(lines: readonly string[]): void {\n process.stdout.write(`${lines.join('\\n')}\\n`);\n}\n\n/** Run the guardian in the foreground (the system service entry point). */\nexport async function runGuardian(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n if (env.guardianDisabled) {\n printLines(['安全网守护已禁用(DSH_LARK_GUARDIAN_DISABLED=1),进程退出。']);\n return;\n }\n const service = await buildGuardianService(env);\n await service.start();\n printLines([\n `安全网守护运行中(pid=${process.pid},dsh profile=${service.snapshot().dshProfile})。`,\n 'dsh 正常运行时保持静默;dsh 下线后自动接管飞书通道,等待 /safemode 控制信号。',\n ]);\n await waitForShutdown();\n await service.stop();\n}\n\n/** Install the guardian as a system-level resident service. */\nexport async function installGuardianCommand(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n const result = await installGuardian({ env, ...(options.dshProfile ? { dshProfile: options.dshProfile } : {}) });\n printResult(result);\n if (!result.ok) process.exitCode = 1;\n}\n\nexport async function uninstallGuardianCommand(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n const result = await uninstallGuardian({ env });\n printResult(result);\n}\n\n/** Print a human-readable guardian status without starting the service. */\nexport async function statusGuardianCommand(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n const paths = resolveAppPaths(env.home);\n const fallback = newGuardianState({\n dshProfile: env.guardianProfile,\n bridgeProfile: env.guardianBridgeProfile,\n });\n const state = await loadGuardianState(join(paths.root, 'guardian.json'), fallback);\n const layout = guardianLayoutFor(env, state.bridgeProfile);\n const heartbeat = await readHeartbeat(layout.heartbeatFile);\n const processFound = await findProfileProcess(state.dshProfile);\n const up =\n isHeartbeatFresh(heartbeat, env.guardianStaleMs) || processFound !== undefined;\n printLines([\n '安全网守护状态',\n '---------------',\n `模式:${state.mode}`,\n `dsh profile:${state.dshProfile}`,\n `安全 profile:${state.safeProfile}`,\n `桥接 profile:${state.bridgeProfile}`,\n `dsh 是否在线:${up ? '是' : '否'}${processFound ? `(pid ${processFound.pid})` : ''}`,\n `心跳龄:${heartbeat ? `${heartbeatAgeMs(heartbeat)}ms` : '无'}`,\n `已观察过 dsh 运行:${state.profileSeenUp ? '是' : '否'}`,\n `守护进程 pid:${process.pid}`,\n `状态文件:${layout.stateFile}`,\n `心跳文件:${layout.heartbeatFile}`,\n ]);\n}\n\nfunction printResult(result: InstallResult): void {\n for (const message of result.messages) {\n process.stdout.write(`${message}\\n`);\n }\n}\n\nfunction waitForShutdown(): Promise<void> {\n return new Promise((resolve) => {\n const shutdown = (): void => {\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n resolve();\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import { randomUUID } from 'node:crypto';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { createLarkChannel, type LarkChannel, type NormalizedMessage } from '@larksuite/channel';\nimport { DshAdapter } from '../adapters/dsh/adapter.js';\nimport type { AgentAdapter } from '../adapters/types.js';\nimport { resolveAppPaths, type AppPaths } from '../config/app-paths.js';\nimport { discoverDshBin } from '../config/dsh-runtime.js';\nimport type { RuntimeEnv } from '../config/env.js';\nimport { ConfigStore, type ProfileConfig } from '../config/profile-store.js';\nimport { isEventFresh } from '../config/security.js';\nimport { log } from '../core/logger.js';\nimport {\n parseGuardianCommand,\n safemodeHelpText,\n} from './control.js';\nimport type { GuardianControlKind } from './control.js';\nimport {\n isHeartbeatFresh,\n readHeartbeat,\n heartbeatAgeMs,\n} from './heartbeat.js';\nimport {\n captureOutput,\n findProfileProcess,\n spawnDetached,\n type DetachedSpawn,\n type ProfileProcess,\n} from './process.js';\nimport {\n ensureSafeProfile,\n probeSafeProfile,\n type SafeProfileProbeResult,\n} from './safe-profile.js';\nimport {\n loadGuardianState,\n newGuardianState,\n saveGuardianState,\n type GuardianState,\n} from './state.js';\n\n/**\n * Safety-net guardian service.\n *\n * A minimal process independent of dsh / Cordis that:\n * 1. stays silent (no Feishu connection) while the dsh profile is up\n * (fresh bridge heartbeat or live `dsh --profile <name>` process);\n * 2. after the profile has been observed up once, takes over the Feishu\n * channel when dsh goes down and accepts control signals\n * (`/safemode` family);\n * 3. on `/safemode`, provisions a core-only safe profile\n * (`dsh-base` + `dsh-headless`, no third-party plugins) and proxies a\n * restricted conversation to it for self-healing;\n * 4. on `/safemode exit`, relaunches the full profile, disconnects and\n * hands the channel back.\n */\n\nexport interface GuardianServiceOptions {\n stateFile: string;\n configFile: string;\n heartbeatFile: string;\n home: string;\n /** Explicit dsh bin override (tests / unusual installs); else auto-discovered. */\n dshBin?: string;\n env?: NodeJS.ProcessEnv;\n dshProfile: string;\n bridgeProfile: string;\n safeProfile: string;\n pollMs?: number;\n staleMs?: number;\n /** Live-process grace: heartbeat stale this long means the engine is dead. */\n engineDeadMs?: number;\n /** Consecutive polls dsh must be down before taking over (flap guard). */\n takeoverGracePolls?: number;\n /** Delay between the `/safemode exit` reply and channel disconnect (ms). */\n sendDelayMs?: number;\n now?: () => number;\n createChannel?: typeof createLarkChannel;\n adapter?: AgentAdapter;\n findProcess?: (dshProfile: string) => Promise<ProfileProcess | undefined>;\n spawnDetachedFn?: typeof spawnDetached;\n probeSafeProfileFn?: (\n input: {\n bin: string;\n dshProfile: string;\n home: string;\n env?: NodeJS.ProcessEnv;\n },\n ) => Promise<SafeProfileProbeResult>;\n runPluginList?: (\n bin: string,\n dshProfile: string,\n ) => Promise<{ stdout: string; stderr: string }>;\n saveState?: (state: GuardianState) => Promise<void>;\n logger?: Pick<typeof log, 'info' | 'warn' | 'fail'>;\n}\n\nexport interface GuardianSnapshot {\n mode: GuardianState['mode'];\n dshProfile: string;\n bridgeProfile: string;\n safeProfile: string;\n profileSeenUp: boolean;\n dshUp: boolean;\n heartbeatAgeMs: number | undefined;\n channelConnected: boolean;\n pid: number;\n dshBin: string | undefined;\n relaunchedPid: number | undefined;\n updatedAt: string;\n}\n\ninterface TranscriptEntry {\n role: 'user' | 'assistant';\n content: string;\n}\n\nconst MAX_TRANSCRIPT_ENTRIES = 30;\nconst SAFE_RUN_TIMEOUT_MS = 10 * 60_000;\n\nexport class GuardianService {\n private readonly options: Required<\n Pick<\n GuardianServiceOptions,\n | 'stateFile'\n | 'configFile'\n | 'heartbeatFile'\n | 'home'\n | 'dshProfile'\n | 'bridgeProfile'\n | 'safeProfile'\n | 'pollMs'\n | 'staleMs'\n | 'engineDeadMs'\n | 'takeoverGracePolls'\n | 'sendDelayMs'\n >\n > &\n Pick<\n GuardianServiceOptions,\n | 'env'\n | 'createChannel'\n | 'adapter'\n | 'findProcess'\n | 'spawnDetachedFn'\n | 'probeSafeProfileFn'\n | 'runPluginList'\n | 'dshBin'\n | 'saveState'\n | 'logger'\n | 'now'\n >;\n\n private state: GuardianState;\n private channel: LarkChannel | undefined;\n private safeAdapter: AgentAdapter | undefined;\n private readonly transcripts = new Map<string, TranscriptEntry[]>();\n private downStreak = 0;\n private lastHeartbeatFreshAt: number | undefined;\n private timer: NodeJS.Timeout | undefined;\n private ticking = false;\n private stopped = false;\n private dshBin: string | undefined;\n private config: ProfileConfig | undefined;\n private readonly eventFreshnessMs: number;\n private readonly activeMessages = new Set<Promise<void>>();\n\n constructor(options: GuardianServiceOptions) {\n this.options = {\n pollMs: options.pollMs ?? 2_000,\n staleMs: options.staleMs ?? 15_000,\n engineDeadMs: options.engineDeadMs ?? 120_000,\n takeoverGracePolls: options.takeoverGracePolls ?? 2,\n sendDelayMs: options.sendDelayMs ?? 600,\n stateFile: options.stateFile,\n configFile: options.configFile,\n heartbeatFile: options.heartbeatFile,\n home: options.home,\n dshProfile: options.dshProfile,\n bridgeProfile: options.bridgeProfile,\n safeProfile: options.safeProfile,\n ...defined({\n env: options.env,\n createChannel: options.createChannel,\n adapter: options.adapter,\n findProcess: options.findProcess,\n spawnDetachedFn: options.spawnDetachedFn,\n probeSafeProfileFn: options.probeSafeProfileFn,\n runPluginList: options.runPluginList,\n dshBin: options.dshBin,\n saveState: options.saveState,\n logger: options.logger,\n now: options.now,\n }),\n };\n this.state = newGuardianState({\n dshProfile: options.dshProfile,\n bridgeProfile: options.bridgeProfile,\n });\n this.eventFreshnessMs = parseFreshness(this.options.env?.DSH_LARK_EVENT_FRESHNESS_MS);\n }\n\n get mode(): GuardianState['mode'] {\n return this.state.mode;\n }\n\n async start(): Promise<void> {\n const loaded = await loadGuardianState(this.options.stateFile, this.state);\n if (loaded.dshProfile !== this.options.dshProfile) {\n // The state file is authoritative once written; adopt it so the\n // guardian keeps monitoring the profile it was installed for.\n this.state = loaded;\n } else {\n this.state = loaded;\n }\n await this.loadContext();\n await this.save();\n await this.tick();\n this.timer = setInterval(() => {\n void this.tick();\n }, this.options.pollMs);\n this.timer.unref?.();\n this.log().info('guardian', 'started', {\n dshProfile: this.state.dshProfile,\n bridgeProfile: this.state.bridgeProfile,\n mode: this.state.mode,\n pollMs: this.options.pollMs,\n });\n }\n\n async stop(): Promise<void> {\n if (this.stopped) return;\n this.stopped = true;\n if (this.timer) clearInterval(this.timer);\n this.timer = undefined;\n await Promise.allSettled([...this.activeMessages]);\n await this.disconnectChannel();\n await this.safeAdapter?.dispose?.();\n this.log().info('guardian', 'stopped', {});\n }\n\n snapshot(): GuardianSnapshot {\n return {\n mode: this.state.mode,\n dshProfile: this.state.dshProfile,\n bridgeProfile: this.state.bridgeProfile,\n safeProfile: this.state.safeProfile,\n profileSeenUp: this.state.profileSeenUp,\n dshUp: this.dshUp,\n heartbeatAgeMs: this.lastHeartbeatAgeMs,\n channelConnected: this.channel !== undefined,\n pid: process.pid,\n dshBin: this.dshBin,\n relaunchedPid: this.state.relaunchedPid,\n updatedAt: this.state.updatedAt,\n };\n }\n\n private dshUp = false;\n private lastHeartbeatAgeMs: number | undefined;\n\n private log() {\n return this.options.logger ?? log;\n }\n\n private async loadContext(): Promise<void> {\n const store = new ConfigStore(this.options.configFile);\n await store.load();\n this.config = store.getProfile(this.state.bridgeProfile);\n this.dshBin =\n this.options.dshBin ?? discoverDshBin(this.options.home, this.options.env ?? process.env);\n }\n\n private async save(): Promise<void> {\n if (this.options.saveState) {\n await this.options.saveState(this.state);\n return;\n }\n await saveGuardianState(this.options.stateFile, this.state);\n }\n\n private async setMode(mode: GuardianState['mode']): Promise<void> {\n if (this.state.mode === mode) return;\n this.state.mode = mode;\n await this.save();\n }\n\n private async setSeenUp(): Promise<void> {\n if (this.state.profileSeenUp) return;\n this.state.profileSeenUp = true;\n await this.save();\n }\n\n private async tick(): Promise<void> {\n if (this.stopped || this.ticking) return;\n this.ticking = true;\n try {\n const heartbeat = await readHeartbeat(this.options.heartbeatFile);\n const now = (this.options.now ?? Date.now)();\n const heartbeatFresh = isHeartbeatFresh(heartbeat, this.options.staleMs, now);\n this.lastHeartbeatAgeMs = heartbeat ? heartbeatAgeMs(heartbeat, now) : undefined;\n if (heartbeatFresh) this.lastHeartbeatFreshAt = now;\n const processFound = await (this.options.findProcess ?? findProfileProcess)(\n this.state.dshProfile,\n );\n const processAlive = processFound !== undefined;\n const engineDead =\n this.lastHeartbeatFreshAt !== undefined &&\n now - this.lastHeartbeatFreshAt > this.options.engineDeadMs;\n // A live process alone does not mean the channel is owned: if the bridge\n // engine's heartbeat has been stale long enough, the engine is dead even\n // though the dsh process survives — take over so the rescue entrance\n // stays reachable.\n const up = heartbeatFresh || (processAlive && !engineDead);\n this.dshUp = up;\n\n if (up) {\n this.downStreak = 0;\n await this.setSeenUp();\n if (this.state.mode !== 'standby' || this.channel !== undefined) {\n // The full profile came back (or the user started it manually):\n // release the Feishu channel and leave safe mode immediately.\n await this.disconnectChannel();\n this.transcripts.clear();\n await this.setMode('standby');\n }\n return;\n }\n\n // dsh is down.\n if (!this.state.profileSeenUp) return; // never observed up: stay silent\n this.downStreak += 1;\n if (this.downStreak < this.options.takeoverGracePolls) return;\n await this.ensureChannel();\n } catch (error) {\n this.log().fail('guardian', error);\n } finally {\n this.ticking = false;\n }\n }\n\n private async ensureChannel(): Promise<void> {\n if (this.channel !== undefined) return;\n const config = this.config ?? (await this.reloadConfig());\n if (!config) {\n this.log().warn('guardian', 'no-bridge-profile', {\n bridgeProfile: this.state.bridgeProfile,\n });\n return;\n }\n const create = this.options.createChannel ?? createLarkChannel;\n const channel = create({\n appId: config.accounts.appId,\n appSecret: config.accounts.appSecret,\n domain:\n config.tenant === 'lark' ? 'https://open.larksuite.com' : 'https://open.feishu.cn',\n source: 'dsh-lark-bot-guardian',\n policy: {\n dmMode: config.access.allowedUsers.length ? 'allowlist' : 'open',\n requireMention: true,\n respondToMentionAll: false,\n ...(config.access.allowedUsers.length\n ? { dmAllowlist: config.access.allowedUsers }\n : {}),\n ...(config.access.allowedChats.length\n ? { groupAllowlist: config.access.allowedChats }\n : {}),\n },\n safety: {\n chatQueue: { enabled: false },\n },\n outbound: {\n streamThrottleMs: 400,\n },\n includeRawEvent: true,\n resolveChatMode: true,\n handshakeTimeoutMs: 8_000,\n httpTimeoutMs: 30_000,\n respectProxyEnv: true,\n });\n\n channel.on({\n message: (msg) => this.track(this.handleMessage(msg)),\n error: (error) => {\n this.log().fail('guardian-channel', error);\n },\n reconnecting: () => {\n this.log().warn('guardian-channel', 'reconnecting', {});\n },\n reconnected: () => {\n this.log().info('guardian-channel', 'reconnected', {});\n },\n });\n\n try {\n await channel.connect();\n this.channel = channel;\n // Keep `safe` (restart mid-safe-mode); otherwise mark takeover.\n if (this.state.mode !== 'safe') await this.setMode('takeover');\n this.log().info('guardian', 'channel-taken-over', {\n dshProfile: this.state.dshProfile,\n });\n } catch (error) {\n this.log().fail('guardian-channel', error);\n }\n }\n\n private async reloadConfig(): Promise<ProfileConfig | undefined> {\n await this.loadContext();\n return this.config;\n }\n\n private async disconnectChannel(): Promise<void> {\n const channel = this.channel;\n this.channel = undefined;\n if (!channel) return;\n try {\n await channel.disconnect();\n } catch (error) {\n this.log().fail('guardian-channel', error);\n }\n if (this.state.mode !== 'standby') {\n await this.setMode('standby');\n }\n }\n\n private scopeFor(msg: NormalizedMessage): string {\n if (msg.chatMode === 'topic' && msg.threadId) return `${msg.chatId}:${msg.threadId}`;\n return msg.chatId;\n }\n\n private authorized(msg: NormalizedMessage): boolean {\n const access = this.config?.access;\n if (!access) return false;\n const controllers = access.admins.length > 0 ? access.admins : access.allowedUsers;\n return controllers.includes(msg.senderId);\n }\n\n private async sendMarkdown(\n chatId: string,\n markdown: string,\n replyTo?: string,\n ): Promise<void> {\n if (!this.channel) return;\n try {\n await this.channel.send(\n chatId,\n { markdown },\n replyTo ? { replyTo } : undefined,\n );\n } catch (error) {\n this.log().fail('guardian-send', error);\n }\n }\n\n private async handleMessage(msg: NormalizedMessage): Promise<void> {\n if (!this.authorized(msg)) {\n this.log().warn('guardian', 'unauthorized-message-dropped', {\n senderId: msg.senderId,\n scope: this.scopeFor(msg),\n });\n return;\n }\n if (this.eventFreshnessMs > 0 && !isEventFresh(msg.createTime, this.eventFreshnessMs)) {\n this.log().warn('guardian', 'stale-message-dropped', {\n ageMs: Date.now() - msg.createTime,\n });\n return;\n }\n\n const scope = this.scopeFor(msg);\n const control = parseGuardianCommand(msg.content);\n if (control) {\n await this.handleControl(control.kind, msg);\n return;\n }\n\n if (this.state.mode === 'safe') {\n await this.runSafeTask(scope, msg);\n return;\n }\n\n await this.sendMarkdown(\n msg.chatId,\n [\n 'dsh 未在运行,守护进程已接管飞书通道。',\n '',\n '发送 `/safemode` 进入仅核心安全模式(dsh 主核心 + 官方 headless,不加载任何第三方插件),',\n '或发送 `/safemode status` 查看状态。',\n ].join('\\n'),\n msg.messageId,\n );\n }\n\n private track(promise: Promise<void>): Promise<void> {\n this.activeMessages.add(promise);\n void promise.finally(() => {\n this.activeMessages.delete(promise);\n });\n return promise;\n }\n\n private async handleControl(\n kind: GuardianControlKind,\n msg: NormalizedMessage,\n ): Promise<void> {\n switch (kind) {\n case 'safemode':\n await this.enterSafeMode(msg);\n return;\n case 'safemode-status':\n await this.sendStatus(msg);\n return;\n case 'safemode-plugins':\n await this.sendPluginList(msg);\n return;\n case 'safemode-exit':\n await this.exitSafeMode(msg);\n return;\n case 'safemode-help':\n await this.sendMarkdown(msg.chatId, safemodeHelpText(), msg.messageId);\n return;\n }\n }\n\n private async enterSafeMode(msg: NormalizedMessage): Promise<void> {\n if (this.state.mode === 'safe') {\n await this.sendMarkdown(\n msg.chatId,\n '已在安全模式中。发送普通消息与 dsh 核心对话;`/safemode exit` 退出。',\n msg.messageId,\n );\n return;\n }\n await this.sendMarkdown(\n msg.chatId,\n '正在进入安全模式:仅挂载 dsh 主核心(`dsh-base` + `dsh-headless`),不加载任何第三方插件…',\n msg.messageId,\n );\n try {\n await ensureSafeProfile({\n home: this.options.home,\n dshProfile: this.state.dshProfile,\n env: this.options.env ?? process.env,\n });\n const bin = this.dshBin;\n if (!bin) {\n await this.sendMarkdown(\n msg.chatId,\n '未找到本机 dsh 安装,无法进入安全模式。请先确认 `dsh` 可用。',\n msg.messageId,\n );\n return;\n }\n const probe = await (this.options.probeSafeProfileFn ?? probeSafeProfile)({\n bin,\n dshProfile: this.state.dshProfile,\n home: this.options.home,\n env: this.options.env ?? process.env,\n });\n if (!probe.ok) {\n await this.sendMarkdown(\n msg.chatId,\n [\n '安全模式就绪检查失败(dsh 核心无法解析):',\n '',\n '```',\n (probe.error ?? 'unknown error').slice(0, 1_500),\n '```',\n ].join('\\n'),\n msg.messageId,\n );\n return;\n }\n this.safeAdapter ??=\n this.options.adapter ??\n new DshAdapter({\n command: 'node',\n args: [bin, '--profile', this.state.safeProfile],\n stopGraceMs: 5_000,\n });\n await this.setMode('safe');\n await this.sendMarkdown(\n msg.chatId,\n [\n '安全模式已就绪:dsh 主核心运行中,第三方插件未加载。',\n '',\n '现在可以直接对话进行自愈(定位 / 修复 / 禁用损坏插件),例如:',\n '- “列出当前 profile 安装的插件并检查哪个最近变坏”',\n '- “用 `/safemode plugins` 查看插件清单”',\n '- 修复完成后发送 `/safemode exit` 重启完整 profile。',\n ].join('\\n'),\n msg.messageId,\n );\n } catch (error) {\n await this.sendMarkdown(\n msg.chatId,\n `进入安全模式失败:${error instanceof Error ? error.message : String(error)}`,\n msg.messageId,\n );\n }\n }\n\n private async sendStatus(msg: NormalizedMessage): Promise<void> {\n const snapshot = this.snapshot();\n await this.sendMarkdown(\n msg.chatId,\n [\n `模式:${snapshot.mode}`,\n `dsh profile:${snapshot.dshProfile}`,\n `安全 profile:${snapshot.safeProfile}`,\n `dsh 是否在线:${snapshot.dshUp ? '是' : '否'}`,\n `心跳龄:${snapshot.heartbeatAgeMs === undefined ? '无' : `${snapshot.heartbeatAgeMs}ms`}`,\n `飞书通道:${snapshot.channelConnected ? '守护已接管' : '未连接'}`,\n `dsh bin:${snapshot.dshBin ?? '未发现'}`,\n `守护 pid:${snapshot.pid}`,\n `已观察过 dsh 运行:${snapshot.profileSeenUp ? '是' : '否'}`,\n ].join('\\n'),\n msg.messageId,\n );\n }\n\n private async sendPluginList(msg: NormalizedMessage): Promise<void> {\n const bin = this.dshBin;\n if (!bin) {\n await this.sendMarkdown(\n msg.chatId,\n '未找到本机 dsh 安装,无法列出插件。',\n msg.messageId,\n );\n return;\n }\n const run = this.options.runPluginList ?? defaultRunPluginList;\n const result = await run(bin, this.state.dshProfile);\n const output = [result.stdout, result.stderr].filter(Boolean).join('\\n').trim();\n await this.sendMarkdown(\n msg.chatId,\n [\n `profile \\`${this.state.dshProfile}\\` 已安装的插件(依赖清单):`,\n '',\n '```',\n (output || '(空)').slice(0, 3_000),\n '```',\n ].join('\\n'),\n msg.messageId,\n );\n }\n\n private async exitSafeMode(msg: NormalizedMessage): Promise<void> {\n if (this.state.mode !== 'safe') {\n await this.sendMarkdown(\n msg.chatId,\n '当前不在安全模式,无需退出。',\n msg.messageId,\n );\n return;\n }\n const bin = this.dshBin;\n if (!bin) {\n await this.sendMarkdown(\n msg.chatId,\n '未找到本机 dsh 安装,无法重启完整 profile。',\n msg.messageId,\n );\n return;\n }\n const spawn = this.options.spawnDetachedFn ?? spawnDetached;\n const spawned: DetachedSpawn = spawn('node', [bin, '--profile', this.state.dshProfile]);\n if (spawned.pid !== undefined) this.state.relaunchedPid = spawned.pid;\n await this.save();\n await this.sendMarkdown(\n msg.chatId,\n [\n `正在退出安全模式并重启完整 profile(\\`${this.state.dshProfile}\\`)…`,\n '守护进程将断开飞书连接并把通道交还给 dsh 桥接引擎。',\n ].join('\\n'),\n msg.messageId,\n );\n // Give the reply a moment to flush before releasing the channel.\n await delay(this.options.sendDelayMs);\n this.transcripts.clear();\n await this.disconnectChannel();\n }\n\n private async runSafeTask(scope: string, msg: NormalizedMessage): Promise<void> {\n const adapter = this.safeAdapter;\n if (!adapter) {\n await this.sendMarkdown(\n msg.chatId,\n '安全模式未就绪,请先发送 `/safemode`。',\n msg.messageId,\n );\n return;\n }\n const transcript = this.transcripts.get(scope) ?? [];\n const prompt = buildSafePrompt(transcript, msg.content);\n await this.sendMarkdown(\n msg.chatId,\n '(安全模式 · dsh 核心处理中…)',\n msg.messageId,\n );\n\n const run = adapter.run({\n runId: randomUUID(),\n prompt,\n cwd: this.config?.workspaces.default,\n sessionId: undefined,\n model: undefined,\n images: undefined,\n stopGraceMs: 5_000,\n });\n const textParts: string[] = [];\n let finalText: string | undefined;\n let errorText: string | undefined;\n let terminal = false;\n try {\n for await (const event of run.events) {\n if (event.type === 'text' && event.delta) textParts.push(event.delta);\n if (event.type === 'final_text') finalText = event.content;\n if (event.type === 'error') {\n errorText = event.message;\n terminal = true;\n }\n if (event.type === 'done') terminal = true;\n }\n } catch (error) {\n errorText = error instanceof Error ? error.message : String(error);\n terminal = true;\n }\n\n if (!terminal) {\n await run.waitForExit(SAFE_RUN_TIMEOUT_MS);\n }\n\n if (errorText) {\n await this.sendMarkdown(\n msg.chatId,\n `(安全模式 · dsh 核心错误)\\n${errorText.slice(0, 2_000)}`,\n msg.messageId,\n );\n return;\n }\n const answer = finalText ?? textParts.join('').trim();\n if (!answer) {\n await this.sendMarkdown(\n msg.chatId,\n '(安全模式 · dsh 核心未返回内容)',\n msg.messageId,\n );\n return;\n }\n await this.sendMarkdown(msg.chatId, answer, msg.messageId);\n this.transcripts.set(scope, pushTranscript(transcript, [\n { role: 'user', content: msg.content },\n { role: 'assistant', content: answer },\n ]));\n }\n}\n\nfunction buildSafePrompt(\n transcript: readonly TranscriptEntry[],\n current: string,\n): string {\n if (transcript.length === 0) return current;\n const history = transcript\n .map((entry) => `${entry.role === 'user' ? '用户' : '助手'}: ${entry.content}`)\n .join('\\n');\n return [\n '以下是本次安全模式对话的上下文(用于连续性,不是新任务指令):',\n '',\n history,\n '',\n `用户: ${current}`,\n ].join('\\n');\n}\n\nfunction pushTranscript(\n existing: readonly TranscriptEntry[],\n entries: readonly TranscriptEntry[],\n): TranscriptEntry[] {\n return [...existing, ...entries].slice(-MAX_TRANSCRIPT_ENTRIES);\n}\n\nasync function defaultRunPluginList(\n bin: string,\n dshProfile: string,\n): Promise<{ stdout: string; stderr: string }> {\n return captureOutput('node', [bin, 'plugin', '--profile', dshProfile, 'list'], 60_000);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseFreshness(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return 600_000;\n const parsed = Number(raw);\n return Number.isInteger(parsed) && parsed >= 0 ? parsed : 600_000;\n}\n\ntype DefinedValues<T> = { [K in keyof T]: Exclude<T[K], undefined> };\n\n/** Copy only defined values, satisfying exactOptionalPropertyTypes. */\nfunction defined<T extends Record<string, unknown>>(input: T): DefinedValues<T> {\n const output: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) output[key] = value;\n }\n return output as DefinedValues<T>;\n}\n\n/** Resolve the guardian's file layout for a runtime env (used by the CLI). */\nexport interface GuardianLayout {\n paths: AppPaths;\n stateFile: string;\n heartbeatFile: string;\n configFile: string;\n}\n\nexport function guardianLayoutFor(\n env: RuntimeEnv,\n bridgeProfile: string,\n): GuardianLayout {\n const paths = resolveAppPaths(env.home);\n return {\n paths,\n stateFile: join(paths.root, 'guardian.json'),\n heartbeatFile: paths.profilePath(bridgeProfile, 'guardian', 'heartbeat.json'),\n configFile: paths.configFile,\n };\n}\n\nexport async function buildGuardianService(\n env: RuntimeEnv,\n overrides: Partial<GuardianServiceOptions> = {},\n): Promise<GuardianService> {\n const paths = resolveAppPaths(env.home);\n const stateFile = join(paths.root, 'guardian.json');\n const fallback = newGuardianState({\n dshProfile: env.guardianProfile,\n bridgeProfile: env.guardianBridgeProfile,\n });\n const state = await loadGuardianState(stateFile, fallback);\n return new GuardianService({\n stateFile,\n configFile: paths.configFile,\n heartbeatFile: paths.profilePath(state.bridgeProfile, 'guardian', 'heartbeat.json'),\n home: homedir(),\n env: process.env,\n dshProfile: state.dshProfile,\n bridgeProfile: state.bridgeProfile,\n safeProfile: state.safeProfile,\n pollMs: env.guardianPollMs,\n staleMs: env.guardianStaleMs,\n engineDeadMs: env.guardianEngineDeadMs,\n ...overrides,\n });\n}\n","/**\n * Control signals understood by the safety-net guardian.\n *\n * While the dsh profile is down the guardian is the only Feishu listener, so\n * these commands are the user's rescue entrance. They are intentionally few\n * and stable:\n *\n * - `/safemode` enter core-only safe mode (mount dsh core, no\n * third-party plugins) and start the restricted\n * conversation;\n * - `/safemode status` report guardian / dsh / safe-mode state;\n * - `/safemode plugins` list plugins installed into the broken profile\n * (diagnostics for self-healing);\n * - `/safemode exit` leave safe mode, relaunch the full profile and\n * hand the Feishu channel back;\n * - `/safemode help` print the above.\n */\n\nexport type GuardianControlKind =\n | 'safemode'\n | 'safemode-status'\n | 'safemode-plugins'\n | 'safemode-exit'\n | 'safemode-help';\n\nexport interface GuardianControl {\n kind: GuardianControlKind;\n /** Normalized argument after the command word, if any. */\n argument: string;\n}\n\nconst COMMAND_RE = /^\\/(safemode)(?:\\s+(.+))?$/i;\n\nexport function parseGuardianCommand(text: string): GuardianControl | undefined {\n const trimmed = text.trim();\n const match = COMMAND_RE.exec(trimmed);\n if (!match) return undefined;\n const argument = match[2]?.trim().toLowerCase() ?? '';\n switch (argument) {\n case '':\n case 'start':\n case 'enter':\n return { kind: 'safemode', argument };\n case 'status':\n return { kind: 'safemode-status', argument };\n case 'plugins':\n case 'list':\n return { kind: 'safemode-plugins', argument };\n case 'exit':\n case 'quit':\n case 'leave':\n case 'restore':\n return { kind: 'safemode-exit', argument };\n case 'help':\n case '?':\n return { kind: 'safemode-help', argument };\n default:\n // Unknown sub-command: treat as help so the user sees valid options.\n return { kind: 'safemode-help', argument };\n }\n}\n\nexport const SAFEMODE_HELP = [\n '/safemode — 进入仅核心安全模式(dsh 主核心 + 官方 headless,不加载任何第三方插件)',\n '/safemode status — 查看守护状态',\n '/safemode plugins — 列出故障 profile 已安装的插件',\n '/safemode exit — 退出安全模式,重启完整 profile 并交还飞书通道',\n '',\n '安全模式下发送普通消息即可与 dsh 核心对话,进行定位 / 修复 / 禁用损坏插件的自愈操作。',\n].join('\\n');\n\nexport const SAFEMODE_HELP_EN = [\n '/safemode — enter core-only safe mode (dsh core + official headless, no third-party plugins)',\n '/safemode status — show guardian state',\n '/safemode plugins — list plugins installed into the broken profile',\n '/safemode exit — leave safe mode, relaunch the full profile and hand the channel back',\n '',\n 'In safe mode, send normal messages to converse with the dsh core for self-healing.',\n].join('\\n');\n\nexport function safemodeHelpText(): string {\n return `${SAFEMODE_HELP}\\n\\n${SAFEMODE_HELP_EN}`;\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { resolveDshHome } from '../config/dsh-runtime.js';\n\n/**\n * Core-only \"safe mode\" dsh profile provisioning.\n *\n * Safe mode must mount the dsh main core and NO third-party plugins (this is\n * what makes it useful when a broken plugin kills the full profile boot).\n * The minimal composition is the official core bundle plus the official\n * one-shot headless app — exactly the shipped `headless` template, under a\n * dedicated profile name we own (`<dsh-profile>-safe`) so it can never be\n * polluted by plugins installed into other profiles.\n *\n * Both bundles resolve from the dsh installation's own dependency closure\n * (dsh heals `$DSH_HOME/profiles/node_modules` on boot), so no pnpm install\n * is needed and the safe profile boots even when the normal profile's\n * node_modules / third-party plugins are broken.\n */\n\nexport const SAFE_CORE_BUNDLES = [\n '@deepseek-ai/dsh-base',\n '@deepseek-ai/dsh-headless',\n] as const;\n\nexport interface SafeProfileEnsureOptions {\n /** OS home used to resolve `~/.dsh` (same as the bridge runtime). */\n home: string;\n /** dsh profile name whose safe variant we manage (`dsh-lark` → `dsh-lark-safe`). */\n dshProfile: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface SafeProfileEnsureResult {\n root: string;\n created: boolean;\n}\n\nexport function safeProfileName(dshProfile: string): string {\n return `${dshProfile}-safe`;\n}\n\nexport function safeProfileRoot(\n home: string,\n dshProfile: string,\n env?: NodeJS.ProcessEnv,\n): string {\n return join(resolveDshHome(home, env), 'profiles', safeProfileName(dshProfile));\n}\n\n/**\n * Create the safe profile files when missing (existing files are never\n * overwritten, so a manually adjusted safe profile keeps working). Returns\n * the profile root and whether anything was created.\n */\nexport async function ensureSafeProfile(\n options: SafeProfileEnsureOptions,\n): Promise<SafeProfileEnsureResult> {\n const root = safeProfileRoot(options.home, options.dshProfile, options.env);\n const name = safeProfileName(options.dshProfile);\n await mkdir(root, { recursive: true });\n let created = false;\n\n const manifest = join(root, 'package.json');\n if (!existsSync(manifest)) {\n await writeFile(\n manifest,\n `${JSON.stringify(\n {\n name: `dsh-profile-${name}`,\n private: true,\n dependencies: {},\n dsh: {\n profile: {\n bundles: [...SAFE_CORE_BUNDLES],\n },\n },\n },\n null,\n 2,\n )}\\n`,\n 'utf8',\n );\n created = true;\n }\n\n const rootConfig = join(root, 'cordis.yml');\n if (!existsSync(rootConfig)) {\n await writeFile(\n rootConfig,\n '# dsh profile root - an empty entry list; the tree is composed as patches.\\n[]\\n',\n 'utf8',\n );\n created = true;\n }\n\n const userPatch = join(root, 'cordis.patch.yml');\n if (!existsSync(userPatch)) {\n // Deliberately empty: safe mode mounts only the core bundles, no\n // third-party rows and no bridge plugin.\n await writeFile(userPatch, '[]\\n', 'utf8');\n created = true;\n }\n\n const workspace = join(root, 'pnpm-workspace.yaml');\n if (!existsSync(workspace)) {\n await writeFile(\n workspace,\n [\n 'packages:',\n ' - .',\n '',\n '',\n 'nodeLinker: hoisted',\n 'autoInstallPeers: false',\n '',\n ].join('\\n'),\n 'utf8',\n );\n created = true;\n }\n\n return { root, created };\n}\n\nexport interface SafeProfileProbeOptions {\n /** Absolute dsh bin (`@deepseek-ai/dsh/lib/bin.js`) or the `dsh` launcher. */\n bin: string;\n /** dsh profile name whose safe variant is probed. */\n dshProfile: string;\n /** OS home used to resolve `~/.dsh`. */\n home: string;\n env?: NodeJS.ProcessEnv;\n /** Injectable runner for tests. */\n run?: (\n command: string,\n args: readonly string[],\n ) => Promise<{ code: number; stdout: string; stderr: string }>;\n}\n\nexport interface SafeProfileProbeResult {\n ok: boolean;\n stdout: string;\n stderr: string;\n error?: string;\n}\n\nasync function defaultRun(\n command: string,\n args: readonly string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n const { spawn } = await import('node:child_process');\n return new Promise((resolve) => {\n const child = spawn(command, [...args], { stdio: ['ignore', 'pipe', 'pipe'] });\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (error: Error) => {\n resolve({ code: 1, stdout, stderr: `${error.message}\\n` });\n });\n child.on('close', (code) => {\n resolve({ code: code ?? 1, stdout, stderr });\n });\n });\n}\n\n/**\n * Probe the safe profile with the boot-free `dsh --dump-config` invocation:\n * it composes the bundle layers and the user patch without mounting any\n * plugin, which is exactly the \"can the core still resolve\" check. Failures\n * (unresolvable bundles / broken patch) are surfaced to the user in Feishu.\n */\nexport async function probeSafeProfile(\n options: SafeProfileProbeOptions,\n): Promise<SafeProfileProbeResult> {\n const run = options.run ?? defaultRun;\n const profile = safeProfileName(options.dshProfile);\n const result = await run(options.bin, ['--profile', profile, '--dump-config']);\n if (result.code === 0) {\n return { ok: true, stdout: result.stdout, stderr: result.stderr };\n }\n const tail = result.stderr.trim().split('\\n').slice(-5).join('\\n');\n return {\n ok: false,\n stdout: result.stdout,\n stderr: result.stderr,\n error: tail || `dsh --profile ${profile} --dump-config exited with code ${result.code}`,\n };\n}\n"],"mappings":"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","names":["resolve","existsSync","join","spawn","existsSync","realpathSync","readFileSync","mkdir","writeFile","join","packageJsonFor","ownPackageLinked","runPnpmInstall","resolve","randomUUID","isRecord","buildPromptText","waitForChildExit","resolve","readFileSync","realpathSync","fileURLToPath","homedir","spawn","resolve","spawn","resolve","isRecord","stringValue","resolve","spawn","existsSync","readFileSync","join","resolve","buildAcpAgentAdapter","homedir","homedir","join","join","resolve","homedir","mkdir","dirname","mkdir","writeFile","dirname","join","rm","mkdir","dirname","mkdir","realpathSync","resolve","REDACTED","resolve","randomUUID","resolve","readFile","readFile","resolve","markdown","randomUUID","markdown","randomUUID","resolve","mkdir","readFile","writeFile","homedir","dirname","join","readFile","resolve","writeFile","homedir","join","mkdir","dirname","markdown","unsupported","reply","markdown","record","reply","markdown","requireAdmin","reply","markdown","reply","markdown","resolve","minutes","markdown","readFile","readFile","randomBytes","resolve","randomBytes","mkdir","readFile","stat","join","mkdir","join","stat","readFile","readFile","readFile","randomBytes","mkdir","readFile","writeFile","join","randomBytes","join","mkdir","writeFile","readFile","execFile","randomBytes","access","mkdir","dirname","join","promisify","execFileAsync","promisify","execFile","defaultRunGit","exists","access","mkdir","dirname","slugify","join","randomBytes","readFile","readFile","readFile","readFile","errorMessage","mkdir","resolve","spawn","mkdir","readFile","writeFile","homedir","join","mkdir","readFile","rm","writeFile","existsSync","homedir","join","spawn","resolve","spawn","readFile","dirname","mkdir","readFile","mkdir","dirname","join","homedir","mkdir","writeFile","rm","homedir","join","mkdir","resolve","spawn","readFile","writeFile","join","randomUUID","homedir","join","createLarkChannel","mkdir","writeFile","existsSync","join","defaultRun","spawn","resolve","parseFreshness","createLarkChannel","access","markdown","spawn","randomUUID","resolve","join","homedir","waitForShutdown","join","resolve","readFileSync","realpathSync","fileURLToPath"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/dsh/event-channel.ts","../src/config/dsh-compat.ts","../src/config/dsh-runtime.ts","../src/adapters/dsh/own-package.ts","../src/adapters/dsh/acp-runtime.ts","../src/adapters/dsh/acp-adapter.ts","../src/cli.ts","../src/cli/commands/doctor.ts","../src/adapters/index.ts","../src/adapters/dsh/adapter.ts","../src/adapters/dsh/availability.ts","../src/adapters/dsh/translate.ts","../src/adapters/dsh/sdk-adapter.ts","../src/adapters/dsh/sdk-translate.ts","../src/adapters/dsh/sdk-runtime.ts","../src/config/app-paths.ts","../src/config/env.ts","../src/config/profile-store.ts","../src/platform/atomic-write.ts","../src/cli/commands/run.ts","../src/bot/active-runs.ts","../src/config/security.ts","../src/core/logger.ts","../src/bot/approvals.ts","../src/bot/concurrency-store.ts","../src/bot/density-store.ts","../src/bot/model-store.ts","../src/bot/pending-queue.ts","../src/bot/questions.ts","../src/bot/retention-store.ts","../src/bot/role-store.ts","../src/bot/run-policy.ts","../src/bridge/channel.ts","../src/commands/index.ts","../src/card/workspace-card.ts","../src/card/density.ts","../src/bridge/run-flow.ts","../src/card/run-state.ts","../src/card/run-renderer.ts","../src/card/approval-card.ts","../src/card/question-card.ts","../src/config/dsh-config.ts","../src/commands/models.ts","../src/commands/archive.ts","../src/commands/roles.ts","../src/commands/notify.ts","../src/bridge/lark-channel.ts","../src/bridge/scope-directory.ts","../src/notify/server.ts","../src/config/access-manager.ts","../src/onboard/registration.ts","../src/media/attachments.ts","../src/session/store.ts","../src/session/archive.ts","../src/workspace/git-worktree.ts","../src/workspace/store.ts","../src/guardian/heartbeat.ts","../src/cli/commands/setup.ts","../src/guardian/install.ts","../src/guardian/process.ts","../src/guardian/state.ts","../src/cli/commands/guardian.ts","../src/guardian/service.ts","../src/guardian/control.ts","../src/guardian/safe-profile.ts"],"sourcesContent":["/** Ordered async queue used to stream translated events out of a run. */\nexport class EventChannel<T> implements AsyncIterable<T> {\n private static readonly END = Symbol('event-channel-end');\n private readonly queue: T[] = [];\n private readonly waiters: Array<(event: T) => void> = [];\n private closed = false;\n\n push(event: T): void {\n if (this.closed) return;\n const waiter = this.waiters.shift();\n if (waiter) {\n waiter(event);\n } else {\n this.queue.push(event);\n }\n }\n\n close(): void {\n if (this.closed) return;\n this.closed = true;\n for (const waiter of this.waiters.splice(0)) {\n waiter(EventChannel.END as unknown as T);\n }\n }\n\n async *[Symbol.asyncIterator](): AsyncIterator<T> {\n for (;;) {\n if (this.closed && this.queue.length === 0) return;\n const queued = this.queue.shift();\n if (queued !== undefined) {\n yield queued;\n continue;\n }\n const value = await new Promise<T>((resolve) => {\n this.waiters.push(resolve);\n });\n if (value === EventChannel.END) return;\n yield value;\n }\n }\n}\n","/**\n * Single source of truth for the DeepSeek Harness compatibility matrix.\n *\n * The bridge pins exact pre-release versions so a release is reproducible.\n * When upstream publishes a stable version, bump every field here, update\n * `package.json` (exact version), run `pnpm ci:local` plus the compatibility\n * probe, then refresh `verifiedAt`. See `docs/COMPATIBILITY.md`.\n */\nexport interface DshCompatibility {\n /** DeepSeek Harness CLI (`dsh`) version verified against this bot release. */\n harness: string;\n /** `@deepseek-ai/dsh-sdk-client` version the bridge is pinned to. */\n sdkClient: string;\n /** `@deepseek-ai/dsh-sdk-jsonrpc-server` version installed into SDK runtime profiles. */\n sdkServer: string;\n /** `@deepseek-ai/dsh-acp` version installed into ACP runtime profiles. */\n acp: string;\n /** Node.js engine requirement. */\n node: string;\n /** ISO date of the last end-to-end verification. */\n verifiedAt: string;\n}\n\nexport const DSH_COMPATIBILITY: DshCompatibility = {\n harness: '0.1.0-rc.6',\n sdkClient: '0.1.0-rc.6',\n sdkServer: '0.1.0-rc.6',\n acp: '0.1.0-rc.6',\n node: '>=22.19.0',\n verifiedAt: '2026-08-15',\n};\n","import { existsSync, readdirSync } from 'node:fs';\nimport { join } from 'node:path';\n\nexport interface DshRuntimeSpec {\n command: string;\n args: string[];\n bin?: string;\n}\n\nconst DS_HARNESS_RELATIVE = join('@deepseek-ai', 'dsh', 'lib', 'bin.js');\n\nexport function resolveDshHome(\n home: string,\n env: NodeJS.ProcessEnv = process.env,\n): string {\n return env.DSH_HOME?.trim() || join(home, '.dsh');\n}\n\nfunction firstExisting(...paths: string[]): string | undefined {\n return paths.find((path) => existsSync(path));\n}\n\nfunction children(root: string): string[] {\n try {\n return readdirSync(root, { withFileTypes: true })\n .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())\n .map((entry) => join(root, entry.name));\n } catch {\n return [];\n }\n}\n\nexport function discoverDshBin(\n home: string,\n env: NodeJS.ProcessEnv = process.env,\n): string | undefined {\n const dshHome = resolveDshHome(home, env);\n\n const candidates = [\n join(dshHome, 'profiles', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.npm', '_npx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.cache', 'pnpm', 'dlx', 'node_modules', DS_HARNESS_RELATIVE),\n join(home, '.local', 'share', 'pnpm', 'node_modules', DS_HARNESS_RELATIVE),\n ];\n\n const direct = firstExisting(...candidates);\n if (direct) return direct;\n\n for (const root of [join(home, '.npm', '_npx'), join(home, '.cache', 'pnpm', 'dlx')]) {\n for (const child of children(root)) {\n const path = join(child, 'node_modules', DS_HARNESS_RELATIVE);\n if (existsSync(path)) return path;\n }\n }\n\n return undefined;\n}\n\nexport function resolveDshRuntime(\n input: {\n command?: string;\n args?: string[];\n home: string;\n env?: NodeJS.ProcessEnv;\n },\n): DshRuntimeSpec {\n if (input.command || input.args) {\n return {\n command: input.command ?? 'node',\n args: input.args ?? ['--profile', 'headless'],\n };\n }\n\n const bin = discoverDshBin(input.home, input.env);\n if (bin) {\n return {\n command: 'node',\n args: [bin, '--profile', 'headless'],\n bin,\n };\n }\n\n return {\n command: 'dsh',\n args: ['--profile', 'headless'],\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { dirname, join } from 'node:path';\n\nexport interface OwnPackageInfo {\n name: string;\n root: string;\n}\n\n/**\n * Locate the running dsh-lark-bot package (source checkout or installed\n * dist). The managed dsh runtime profiles link this package in so their patch\n * rows (`dsh-lark-bot/notify`, …) resolve through the profile's node_modules.\n *\n * The module may be bundled (e.g. `dist/cli.js`) or unbundled\n * (`dist/adapters/.../sdk-runtime.js`), so the package root cannot be derived\n * from a fixed `import.meta.url` depth: walk upward until a package.json\n * whose name is one of ours is found.\n */\nexport function ownPackageInfo(): OwnPackageInfo {\n return findOwnPackageRoot(dirname(fileURLToPath(import.meta.url)));\n}\n\n/**\n * Walk upward from `startDir` until a package.json whose name is one of ours\n * is found. Extracted for testability; bundled and unbundled layouts both\n * resolve to the package root.\n */\nexport function findOwnPackageRoot(startDir: string): OwnPackageInfo {\n let dir = startDir;\n for (let depth = 0; depth < 8; depth += 1) {\n const pkgPath = join(dir, 'package.json');\n try {\n const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as {\n name?: unknown;\n };\n if (typeof pkg.name === 'string' && isOwnPackageName(pkg.name)) {\n return { name: pkg.name, root: dir };\n }\n } catch {\n // Not a readable manifest at this level; keep walking upward.\n }\n const parent = dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // Fallback: the canonical name and the current working directory.\n return { name: 'dsh-lark-bot', root: process.cwd() };\n}\n\nfunction isOwnPackageName(name: string): boolean {\n return (\n name === 'dsh-lark-bot' ||\n name === 'dsh-feishu-bot' ||\n /^@[^/]+\\/(dsh-lark-bot|dsh-feishu-bot)$/.test(name)\n );\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { DSH_COMPATIBILITY } from '../../config/dsh-compat.js';\nimport { discoverDshBin, resolveDshHome } from '../../config/dsh-runtime.js';\nimport { ownPackageInfo } from './own-package.js';\n\nexport const ACP_PACKAGE = '@deepseek-ai/dsh-acp';\nexport const ACP_VERSION = DSH_COMPATIBILITY.acp;\nexport const ACP_BASE_BUNDLE = '@deepseek-ai/dsh-base';\nexport const DEFAULT_ACP_PROFILE = 'dsh-lark-acp';\n\nexport interface AcpRuntimeOptions {\n home: string;\n env?: NodeJS.ProcessEnv;\n command?: string;\n args?: string[];\n bin?: string;\n profile?: string;\n provider?: string;\n model?: string;\n install?: (profileRoot: string) => Promise<void>;\n}\n\nexport interface AcpLaunchSpec {\n command: string;\n args: string[];\n profile: string;\n}\n\nexport interface AcpProfileEnsureResult {\n ok: boolean;\n created: boolean;\n error?: string;\n}\n\nexport function acpProfileRoot(home: string, profile: string, env?: NodeJS.ProcessEnv): string {\n return join(resolveDshHome(home, env), 'profiles', profile);\n}\n\nfunction packageJsonFor(profile: string): string {\n const own = ownPackageInfo();\n return `${JSON.stringify(\n {\n name: `dsh-profile-${profile}`,\n private: true,\n dependencies: {\n [ACP_PACKAGE]: ACP_VERSION,\n [own.name]: `link:${own.root}`,\n },\n dsh: {\n profile: {\n bundles: [ACP_BASE_BUNDLE],\n },\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nexport function acpPatchYaml(provider: string, model: string): string {\n const own = ownPackageInfo();\n return [\n '# dsh-lark ACP JSON-RPC runtime overlay (managed by dsh-lark-bot).',\n '# stdout is reserved for ACP JSON-RPC frames; no console logger may load.',\n '- insert:',\n ' - id: acp',\n ` name: '${ACP_PACKAGE}'`,\n ' config:',\n ` provider: ${provider}`,\n ` model: ${model}`,\n '',\n '# Unattended IM runtime: interactive user questions cannot be answered',\n '# through Feishu, so the tool is disabled (default-deny).',\n '- id: user-questions',\n ' disabled: true',\n '',\n '- id: system-prompt',\n ' config:',\n ' persona: >-',\n ' You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.',\n '',\n '- id: hmr',\n ' disabled: true',\n '',\n // In-process bridge callback tool (same contract as the SDK runtime).\n '- insert:',\n ' - id: lark-notify',\n ` name: '${own.name}/notify'`,\n ' config:',\n ' endpoint: !!js process.env.DSH_LARK_NOTIFY_URL',\n ' token: !!js process.env.DSH_LARK_NOTIFY_TOKEN',\n '',\n ].join('\\n');\n}\n\nfunction acpPluginInstalled(profileRoot: string): boolean {\n const candidates = [\n join(profileRoot, 'node_modules', ACP_PACKAGE),\n join(profileRoot, '..', 'node_modules', ACP_PACKAGE),\n ];\n return candidates.some((path) => existsSync(path));\n}\n\nexport function isAcpProfileReady(profileRoot: string): boolean {\n const own = ownPackageInfo();\n return (\n existsSync(join(profileRoot, 'package.json')) &&\n existsSync(join(profileRoot, 'cordis.yml')) &&\n existsSync(join(profileRoot, 'cordis.patch.yml')) &&\n acpPluginInstalled(profileRoot) &&\n ownPackageLinked(profileRoot, own.name)\n );\n}\n\n/** True when the profile's node_modules link resolves to this package. */\nfunction ownPackageLinked(profileRoot: string, ownName: string): boolean {\n const linkPath = join(profileRoot, 'node_modules', ownName);\n try {\n const real = realpathSync(linkPath);\n const pkg = JSON.parse(readFileSync(join(real, 'package.json'), 'utf8')) as {\n name?: unknown;\n dsh?: { bundle?: { patch?: unknown } };\n };\n return (\n pkg.name === ownName &&\n pkg.dsh?.bundle?.patch !== undefined\n );\n } catch {\n return false;\n }\n}\n\nfunction runPnpmInstall(profileRoot: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['install'], {\n cwd: profileRoot,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let output = '';\n child.stdout.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n reject(error);\n });\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n const tail = output.trim().split('\\n').slice(-8).join('\\n');\n reject(new Error(`pnpm install exited with code ${String(code)}\\n${tail}`));\n });\n });\n}\n\n/**\n * Ensure the ACP runtime profile exists under the shared dsh installation.\n * The profile composes `@deepseek-ai/dsh-base` with the official\n * `@deepseek-ai/dsh-acp` plugin (approval policy stays `ask`; the bridge\n * answers through `session/request_permission`).\n */\nexport async function ensureAcpProfile(\n options: AcpRuntimeOptions,\n): Promise<AcpProfileEnsureResult> {\n const profile = options.profile ?? DEFAULT_ACP_PROFILE;\n const root = acpProfileRoot(options.home, profile, options.env);\n const provider = options.provider ?? 'deepseek-official';\n const model = options.model ?? 'deepseek-v4-flash';\n const ready = isAcpProfileReady(root);\n\n try {\n await mkdir(root, { recursive: true });\n await writeFile(join(root, 'package.json'), packageJsonFor(profile), 'utf8');\n await writeFile(join(root, 'cordis.yml'), '[]\\n', 'utf8');\n await writeFile(join(root, 'cordis.patch.yml'), acpPatchYaml(provider, model), 'utf8');\n if (!ready) {\n const install = options.install ?? runPnpmInstall;\n await install(root);\n }\n if (!isAcpProfileReady(root)) {\n return {\n ok: false,\n created: true,\n error: `${ACP_PACKAGE}@${ACP_VERSION} or bridge package was not found after install`,\n };\n }\n return { ok: true, created: !ready };\n } catch (error) {\n return {\n ok: false,\n created: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/** Resolve the launch spec for the ACP runtime subprocess. */\nexport function resolveAcpLaunch(options: AcpRuntimeOptions): AcpLaunchSpec {\n const profile = options.profile ?? DEFAULT_ACP_PROFILE;\n if (options.command || options.args) {\n return {\n command: options.command ?? 'node',\n args: options.args ?? ['--profile', profile],\n profile,\n };\n }\n const bin = options.bin ?? discoverDshBin(options.home, options.env);\n if (bin) {\n return { command: 'node', args: [bin, '--profile', profile], profile };\n }\n return { command: 'dsh', args: ['--profile', profile], profile };\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n spawn as defaultSpawn,\n type ChildProcess,\n type SpawnOptionsWithoutStdio,\n} from 'node:child_process';\nimport { homedir } from 'node:os';\nimport { Readable as NodeReadable, Writable as NodeWritable } from 'node:stream';\nimport {\n ClientSideConnection,\n ndJsonStream,\n PROTOCOL_VERSION,\n type Agent as AcpAgent,\n type Client as AcpClient,\n type ContentBlock as AcpContentBlock,\n type RequestPermissionRequest,\n type RequestPermissionResponse,\n type SessionNotification,\n} from '@agentclientprotocol/sdk';\nimport type { RuntimeEnv } from '../../config/env.js';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentEvent,\n AgentRun,\n AgentRunOptions,\n ApprovalOutcome,\n ApprovalRequest,\n} from '../types.js';\nimport { ensureAcpProfile, resolveAcpLaunch, type AcpLaunchSpec } from './acp-runtime.js';\nimport { EventChannel } from './event-channel.js';\n\nexport interface AcpAdapterOptions {\n launch: AcpLaunchSpec;\n provider: string;\n model: string;\n probeTimeoutMs?: number;\n spawn?: (command: string, args: string[], options: SpawnOptionsWithoutStdio) => ChildProcess;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction textOfContent(content: unknown): string {\n if (!isRecord(content) || typeof content.text !== 'string') return '';\n return content.text;\n}\n\n/** Translate an ACP session update into bridge events (forward-compatible). */\nexport function translateAcpUpdate(notification: SessionNotification): AgentEvent[] {\n const update = notification.update;\n if (!isRecord(update)) return [];\n switch (update.sessionUpdate) {\n case 'agent_message_chunk':\n return textOfContent(update.content)\n ? [{ type: 'text', delta: textOfContent(update.content) }]\n : [];\n case 'agent_thought_chunk':\n return textOfContent(update.content)\n ? [{ type: 'thinking', delta: textOfContent(update.content) }]\n : [];\n case 'tool_call': {\n if (typeof update.toolCallId !== 'string') return [];\n return [\n {\n type: 'tool_use',\n id: update.toolCallId,\n name: typeof update.title === 'string' ? update.title : 'tool',\n input: update.rawInput ?? {},\n },\n ];\n }\n default:\n return [];\n }\n}\n\nfunction mapApprovalOutcome(\n outcome: ApprovalOutcome,\n options: RequestPermissionRequest['options'],\n): RequestPermissionResponse {\n if (outcome === 'cancelled') {\n return { outcome: { outcome: 'cancelled' } };\n }\n const wanted: 'allow_once' | 'reject_once' =\n outcome === 'allowed-once' ? 'allow_once' : 'reject_once';\n const option = options.find((item) => item.kind === wanted);\n if (!option) return { outcome: { outcome: 'cancelled' } };\n return { outcome: { outcome: 'selected', optionId: option.optionId } };\n}\n\nfunction buildPromptText(prompt: string, images: readonly string[] | undefined): string {\n return images?.length\n ? `${prompt}\\n\\nImage files attached to this message:\\n${images.join('\\n')}`\n : prompt;\n}\n\nfunction waitForChildExit(\n child: ChildProcess,\n timeoutMs: number,\n): Promise<{ code: number | null; timedOut: boolean }> {\n if (child.exitCode !== null || child.signalCode !== null) {\n return Promise.resolve({ code: child.exitCode, timedOut: false });\n }\n return new Promise((resolve) => {\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n child.removeListener('exit', onExit);\n resolve({ code: child.exitCode, timedOut: true });\n }, timeoutMs)\n : undefined;\n const onExit = (code: number | null): void => {\n if (timer !== undefined) clearTimeout(timer);\n resolve({ code, timedOut: false });\n };\n child.once('exit', onExit);\n });\n}\n\nasync function disposeChild(child: ChildProcess, graceMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return;\n child.stdin?.end();\n if (!(await waitForChildExit(child, graceMs)).timedOut) return;\n child.kill('SIGTERM');\n if (!(await waitForChildExit(child, graceMs)).timedOut) return;\n child.kill('SIGKILL');\n}\n\n/**\n * Official ACP adapter. Spawns the `dsh-lark-acp` runtime and speaks the\n * Agent Client Protocol over stdio as a client: `session/request_permission`\n * maps to Feishu approval cards through `AgentRunOptions.onApprovalRequest`.\n * ACP sessions are fresh per run (no resume), matching the upstream server.\n */\nexport class AcpDshAdapter implements AgentAdapter {\n readonly id = 'dsh-acp';\n readonly displayName = 'DeepSeek Harness (ACP)';\n\n private readonly launch: AcpLaunchSpec;\n private readonly model: string;\n private readonly probeTimeoutMs: number;\n private readonly spawn: AcpAdapterOptions['spawn'];\n private readonly stopGraceMs: number;\n\n constructor(options: AcpAdapterOptions) {\n this.launch = options.launch;\n this.model = options.model;\n this.probeTimeoutMs = options.probeTimeoutMs ?? 15_000;\n this.spawn = options.spawn;\n this.stopGraceMs = 5_000;\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n async checkAvailability(): Promise<AgentAvailability> {\n const child = this.spawnChild(process.cwd());\n if (!child.stdin || !child.stdout) {\n await disposeChild(child, this.stopGraceMs);\n return { ok: false, error: 'ACP child did not expose protocol streams', version: undefined };\n }\n const conn = new ClientSideConnection(\n () => ({\n requestPermission: () => Promise.resolve({ outcome: { outcome: 'cancelled' } }),\n sessionUpdate: () => Promise.resolve(),\n }),\n ndJsonStream(\n NodeWritable.toWeb(child.stdin) as WritableStream<Uint8Array>,\n NodeReadable.toWeb(child.stdout) as ReadableStream<Uint8Array>,\n ),\n );\n try {\n const info = await withTimeout(\n conn.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} }),\n this.probeTimeoutMs,\n );\n const name = info.agentInfo?.name ?? 'deepseek-harness-acp';\n const version = info.agentInfo?.version ?? 'unknown';\n return { ok: true, error: undefined, version: `${name}@${version}` };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n version: undefined,\n };\n } finally {\n await disposeChild(child, this.stopGraceMs);\n }\n }\n\n run(options: AgentRunOptions): AgentRun {\n const cwd = options.cwd ?? process.cwd();\n const model = options.model ?? this.model;\n const stopRequested = { value: false };\n const channel = new EventChannel<AgentEvent>();\n const child = this.spawnChild(cwd);\n let serverSessionId: string | undefined;\n let conn: ClientSideConnection | undefined;\n let hadError = false;\n const clientSessionId = `acp-${randomUUID().replaceAll('-', '')}`;\n\n const makeClient = (_agent: AcpAgent): AcpClient => ({\n sessionUpdate: async (notification: SessionNotification) => {\n for (const event of translateAcpUpdate(notification)) {\n if (event.type === 'error') hadError = true;\n channel.push(event);\n }\n },\n requestPermission: async (request: RequestPermissionRequest) => {\n if (!options.onApprovalRequest) {\n return { outcome: { outcome: 'cancelled' } };\n }\n const approval: ApprovalRequest = {\n id: request.toolCall.toolCallId,\n sessionId: request.sessionId,\n toolName:\n typeof request.toolCall.title === 'string' ? request.toolCall.title : 'tool',\n reason: undefined,\n options: request.options.map((item) => ({\n optionId: item.optionId,\n name: item.name,\n kind: item.kind,\n })),\n };\n const outcome = await options.onApprovalRequest(approval);\n return mapApprovalOutcome(outcome, request.options);\n },\n });\n\n const task = (async () => {\n if (!child.stdin || !child.stdout) {\n throw new Error('ACP child did not expose protocol streams');\n }\n conn = new ClientSideConnection(\n makeClient,\n ndJsonStream(\n NodeWritable.toWeb(child.stdin) as WritableStream<Uint8Array>,\n NodeReadable.toWeb(child.stdout) as ReadableStream<Uint8Array>,\n ),\n );\n await conn.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} });\n const created = await conn.newSession({ cwd, mcpServers: [] });\n serverSessionId = created.sessionId;\n const blocks: AcpContentBlock[] = [\n { type: 'text', text: buildPromptText(options.prompt, options.images) },\n ];\n const response = await conn.prompt({ sessionId: serverSessionId, prompt: blocks });\n if (response.stopReason === 'cancelled') {\n if (!stopRequested.value) {\n channel.push({ type: 'error', message: 'ACP turn cancelled', terminationReason: 'interrupted' });\n hadError = true;\n }\n return;\n }\n if (response.stopReason === 'refusal' || response.stopReason === 'max_turn_requests') {\n channel.push({\n type: 'error',\n message: `ACP turn stopped with reason: ${response.stopReason}`,\n terminationReason: 'failed',\n });\n hadError = true;\n return;\n }\n if (response.usage) {\n const usage: AgentEvent = {\n type: 'usage',\n ...(typeof response.usage.inputTokens === 'number'\n ? { inputTokens: response.usage.inputTokens }\n : {}),\n ...(typeof response.usage.outputTokens === 'number'\n ? { outputTokens: response.usage.outputTokens }\n : {}),\n };\n channel.push(usage);\n }\n })().catch((error: unknown) => {\n if (!stopRequested.value) {\n channel.push({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n terminationReason: 'failed',\n });\n hadError = true;\n }\n }).finally(() => {\n channel.close();\n });\n\n async function* events(): AsyncGenerator<AgentEvent> {\n yield {\n type: 'system',\n sessionId: clientSessionId,\n cwd,\n model,\n };\n for await (const event of channel) {\n yield event;\n }\n await task;\n if (!hadError) {\n yield {\n type: 'done',\n sessionId: clientSessionId,\n terminationReason: stopRequested.value ? 'interrupted' : 'normal',\n };\n }\n }\n\n return {\n runId: options.runId,\n events: events(),\n stop: async () => {\n stopRequested.value = true;\n if (conn && serverSessionId !== undefined) {\n try {\n await conn.cancel({ sessionId: serverSessionId });\n } catch {\n // The child may already be gone; teardown below is authoritative.\n }\n }\n await disposeChild(child, this.stopGraceMs);\n },\n waitForExit: (timeoutMs) =>\n waitForChildExit(child, timeoutMs).then((result) => !result.timedOut && result.code !== null),\n };\n }\n\n private spawnChild(cwd: string): ChildProcess {\n const spawnFn = this.spawn ?? defaultSpawn;\n return spawnFn(this.launch.command, this.launch.args, {\n cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n }\n}\n\nfunction withTimeout<T>(promise: Promise<T>, timeoutMs: number): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error(`ACP probe timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n promise.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error: unknown) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n}\n\n/** Build the ACP adapter for the configured env (used by `buildAgentAdapter`). */\nexport async function buildAcpAgentAdapter(\n env: RuntimeEnv,\n preferences: { stopGraceMs: number | undefined; model: string | undefined },\n): Promise<AcpDshAdapter> {\n const runtimeOptions = {\n home: homedir(),\n env: process.env,\n provider: env.provider,\n model: preferences.model ?? env.model,\n ...(env.dshExplicit ? { command: env.dshCommand, args: env.dshArgs } : {}),\n };\n const ensure = await ensureAcpProfile(runtimeOptions);\n if (!ensure.ok) {\n throw new Error(\n `ACP runtime profile setup failed: ${ensure.error ?? 'unknown error'} ` +\n '(install pnpm, or set DSH_LARK_ADAPTER=headless for the legacy adapter)',\n );\n }\n const launch = resolveAcpLaunch(runtimeOptions);\n return new AcpDshAdapter({\n launch,\n provider: env.provider,\n model: preferences.model ?? env.model,\n });\n}\n","import { readFileSync, realpathSync } from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\nimport { runDoctor } from './cli/commands/doctor.js';\nimport { runBot } from './cli/commands/run.js';\nimport { runSetup } from './cli/commands/setup.js';\nimport {\n installGuardianCommand,\n runGuardian,\n statusGuardianCommand,\n uninstallGuardianCommand,\n} from './cli/commands/guardian.js';\n\nfunction packageVersion(): string {\n const raw = readFileSync(new URL('../package.json', import.meta.url), 'utf8');\n const pkg = JSON.parse(raw) as { version?: unknown };\n return typeof pkg.version === 'string' ? pkg.version : '0.0.0';\n}\n\nexport interface StartOptions {\n profile?: string;\n workspace?: string;\n appId?: string;\n appSecret?: string;\n tenant?: string;\n}\n\nfunction addBotOptions(command: Command): Command {\n return command\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark');\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n\n program\n .name('dsh-lark-bot')\n .description('Bridge DeepSeek Harness into Feishu / Lark')\n .version(packageVersion(), '-v, --version');\n\n program\n .command('setup')\n .description(\n 'Install this package as a standard dsh profile bundle (single install path)',\n )\n .option('--profile <name>', 'dsh profile to install into (default: dsh-lark)')\n .option('--guardian', 'also install the safety-net guardian service')\n .action(async (opts: { profile?: string; guardian?: boolean }) => {\n await runSetup({\n ...(opts.profile ? { profile: opts.profile } : {}),\n ...(opts.guardian ? { guardian: true } : {}),\n });\n });\n\n program\n .command('doctor')\n .description('Run local diagnostics')\n .option('--profile <name>', 'profile name')\n .option('--workspace <path>', 'initial working directory')\n .option('--app-id <id>', 'existing Lark/Feishu app id')\n .option('--app-secret <secret>', 'existing Lark/Feishu app secret')\n .option('--tenant <tenant>', 'feishu or lark')\n .action(async (opts: StartOptions) => {\n await runDoctor({ ...opts, version: packageVersion() });\n });\n\n addBotOptions(\n program\n .command('run', { hidden: true })\n .description('Run the bridge engine directly (diagnostics; the dsh plugin runs it in-process)'),\n ).action(async (opts: StartOptions) => {\n await runBot(opts);\n });\n\n const guardian = program\n .command('guardian')\n .description(\n 'Safety-net guardian: a minimal process independent of dsh that keeps the Feishu rescue entrance alive',\n );\n\n guardian\n .command('run')\n .description('Run the guardian in the foreground (system service entry point)')\n .option('--dsh-profile <name>', 'dsh profile to watch / relaunch (default from state)')\n .option('--bridge-profile <name>', 'bridge state profile with Feishu credentials')\n .action(async (opts: { dshProfile?: string; bridgeProfile?: string }) => {\n await runGuardian(opts);\n });\n\n guardian\n .command('install')\n .description('Install the guardian as a system-level resident service')\n .option('--dsh-profile <name>', 'dsh profile to watch / relaunch (default: dsh-lark)')\n .option('--bridge-profile <name>', 'bridge state profile (default: default)')\n .action(async (opts: { dshProfile?: string; bridgeProfile?: string }) => {\n await installGuardianCommand(opts);\n });\n\n guardian\n .command('uninstall')\n .description('Remove the system service entry (state file is kept)')\n .action(async () => {\n await uninstallGuardianCommand();\n });\n\n guardian\n .command('status')\n .description('Show guardian / dsh / safe-mode state')\n .option('--dsh-profile <name>', 'dsh profile to inspect')\n .option('--bridge-profile <name>', 'bridge state profile to inspect')\n .action(async (opts: { dshProfile?: string; bridgeProfile?: string }) => {\n await statusGuardianCommand(opts);\n });\n\n return program;\n}\n\nexport async function main(argv: readonly string[] = process.argv): Promise<void> {\n await buildProgram().parseAsync([...argv]);\n}\n\n/**\n * True when this module is being executed directly (e.g. `node dist/cli.js run`)\n * rather than imported by a bin wrapper. The background service runs\n * `node <package>/dist/cli.js run`, so the bundle must self-execute in that case.\n */\nexport function isDirectInvocation(\n entry: string | undefined = process.argv[1],\n metaUrl: string = import.meta.url,\n): boolean {\n if (!entry) return false;\n try {\n return realpathSync(entry) === fileURLToPath(metaUrl);\n } catch {\n return false;\n }\n}\n\nif (isDirectInvocation()) {\n await main();\n}\n","import { stat } from 'node:fs/promises';\nimport { buildAgentAdapter } from '../../adapters/index.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport type { StartOptions } from '../../cli.js';\n\nexport interface DoctorOptions extends StartOptions {\n version?: string;\n output?: (text: string) => void;\n}\n\nexport async function runDoctor(options: DoctorOptions): Promise<void> {\n const env = loadRuntimeEnv({\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n });\n const paths = resolveAppPaths(env.home);\n const profileName = options.profile ?? 'default';\n const store = new ConfigStore(paths.configFile);\n await store.load();\n const profile = store.getProfile(profileName);\n\n const lines: string[] = [\n 'dsh-lark-bot doctor',\n `version: ${options.version ?? 'unknown'}`,\n `node: ${process.version}`,\n `profile: ${profileName}`,\n `home: ${paths.root}`,\n `adapter: ${env.adapterMode}`,\n `dsh_command: ${env.dshCommand}`,\n `dsh_args: ${env.dshArgs.join(',')}`,\n ];\n\n let critical = false;\n\n if (!profile) {\n lines.push('config: missing');\n critical = true;\n } else {\n lines.push(\n [\n 'config: ok',\n `tenant=${profile.tenant}`,\n `app_id=${profile.accounts.appId}`,\n `app_secret=${profile.accounts.appSecret ? 'present' : 'missing'}`,\n `allowed_users=${profile.access.allowedUsers.length}`,\n `allowed_chats=${profile.access.allowedChats.length}`,\n ].join(' '),\n );\n if (!profile.accounts.appId || !profile.accounts.appSecret) critical = true;\n }\n\n const workspace =\n options.workspace ??\n profile?.workspaces.default ??\n env.workspace ??\n paths.profilePath(profileName, 'workspace');\n try {\n const info = await stat(workspace);\n lines.push(`workspace: ${workspace} (${info.isDirectory() ? 'directory' : 'not-directory'})`);\n } catch {\n lines.push(`workspace: ${workspace} (missing)`);\n }\n\n try {\n const adapter = await buildAgentAdapter(env, {\n stopGraceMs: profile?.preferences.stopGraceMs,\n model: profile?.preferences.model,\n });\n const availability = await adapter.checkAvailability();\n if (availability.ok) {\n lines.push(`dsh: ok${availability.version ? ` (${availability.version})` : ''}`);\n } else {\n lines.push(`dsh: unavailable (${availability.error ?? 'unknown'})`);\n critical = true;\n }\n await adapter.dispose?.();\n } catch (error) {\n lines.push(`dsh: unavailable (${error instanceof Error ? error.message : String(error)})`);\n critical = true;\n }\n\n const output = options.output ?? ((text: string) => process.stdout.write(text));\n output(`${lines.join('\\n')}\\n`);\n if (critical) process.exitCode = 1;\n}\n","import { homedir } from 'node:os';\nimport type { RuntimeEnv } from '../config/env.js';\nimport { DshAdapter } from './dsh/adapter.js';\nimport { SdkDshAdapter } from './dsh/sdk-adapter.js';\nimport { ensureSdkProfile, resolveSdkLaunch } from './dsh/sdk-runtime.js';\nimport type { AgentAdapter } from './types.js';\n\nexport interface AdapterPreferences {\n stopGraceMs: number | undefined;\n model: string | undefined;\n}\n\n/**\n * Build the agent adapter for the configured mode:\n * - `sdk` (default): official `@deepseek-ai/dsh-sdk-client` runtime.\n * - `acp`: official ACP server runtime with approval cards.\n * - `headless`: legacy subprocess fallback (kept for compatibility).\n */\nexport async function buildAgentAdapter(\n env: RuntimeEnv,\n preferences: AdapterPreferences = { stopGraceMs: undefined, model: undefined },\n): Promise<AgentAdapter> {\n switch (env.adapterMode) {\n case 'headless': {\n const options: ConstructorParameters<typeof DshAdapter>[0] = {\n command: env.dshCommand,\n args: env.dshArgs,\n };\n if (preferences.stopGraceMs !== undefined) {\n options.stopGraceMs = preferences.stopGraceMs;\n }\n return new DshAdapter(options);\n }\n case 'acp': {\n const { buildAcpAgentAdapter } = await import('./dsh/acp-adapter.js');\n return buildAcpAgentAdapter(env, preferences);\n }\n case 'sdk':\n default: {\n const runtimeOptions = {\n home: homedir(),\n env: process.env,\n ...(env.dshExplicit\n ? { command: env.dshCommand, args: env.dshArgs }\n : {}),\n };\n const ensure = await ensureSdkProfile(runtimeOptions);\n if (!ensure.ok) {\n throw new Error(\n `SDK runtime profile setup failed: ${ensure.error ?? 'unknown error'} ` +\n '(install pnpm, or set DSH_LARK_ADAPTER=headless for the legacy adapter)',\n );\n }\n const launch = resolveSdkLaunch(runtimeOptions);\n return new SdkDshAdapter({\n launch,\n provider: env.provider,\n model: preferences.model ?? env.model,\n ...(env.maxTokens === undefined ? {} : { maxTokens: env.maxTokens }),\n });\n }\n }\n}\n","import { spawn } from 'cross-spawn';\nimport { createInterface } from 'node:readline';\nimport type { ChildProcess } from 'node:child_process';\nimport { checkDshAvailability } from './availability.js';\nimport { plainOutputEvent, translateDshLine } from './translate.js';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentEvent,\n AgentRun,\n AgentRunOptions,\n} from '../types.js';\n\nexport interface DshAdapterOptions {\n command?: string;\n args?: string[];\n stopGraceMs?: number;\n}\n\ntype DshChild = ChildProcess;\n\nexport class DshAdapter implements AgentAdapter {\n readonly id = 'dsh';\n readonly displayName = 'DeepSeek Harness';\n\n private readonly command: string;\n private readonly args: string[];\n private readonly stopGraceMs: number;\n\n constructor(options: DshAdapterOptions = {}) {\n this.command = options.command ?? 'dsh';\n this.args = options.args ?? ['--profile', 'headless'];\n this.stopGraceMs = options.stopGraceMs ?? 5_000;\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n checkAvailability(): Promise<AgentAvailability> {\n return checkDshAvailability({ command: this.command, args: this.args });\n }\n\n run(options: AgentRunOptions): AgentRun {\n const prompt =\n options.images?.length\n ? `${options.prompt}\\n\\nImage files attached to this message:\\n${options.images.join('\\n')}`\n : options.prompt;\n\n const child = spawn(\n this.command,\n [...this.args, prompt],\n {\n cwd: options.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n },\n ) as DshChild;\n\n child.stdin?.end();\n\n const stderrChunks: Buffer[] = [];\n let runtimeError: Error | null = null;\n child.stderr?.on('data', (chunk: Buffer) => {\n stderrChunks.push(chunk);\n });\n child.on('error', (error: Error) => {\n runtimeError = error;\n });\n\n return {\n runId: options.runId,\n events: createEventStream(child, stderrChunks, () => runtimeError, {\n sessionId: options.sessionId,\n cwd: options.cwd,\n model: options.model,\n }),\n stop: () => stopChild(child, this.stopGraceMs),\n waitForExit: (timeoutMs) => waitForChildExit(child, timeoutMs),\n };\n }\n}\n\nasync function* createEventStream(\n child: DshChild,\n stderrChunks: Buffer[],\n getError: () => Error | null,\n system: {\n sessionId: string | undefined;\n cwd: string | undefined;\n model: string | undefined;\n },\n): AsyncGenerator<AgentEvent> {\n if (!child.pid) {\n const error = getError();\n yield {\n type: 'error',\n message: error ? `failed to spawn dsh: ${error.message}` : 'spawn returned no pid',\n terminationReason: 'failed',\n };\n return;\n }\n\n yield {\n type: 'system',\n sessionId: system.sessionId,\n cwd: system.cwd,\n model: system.model,\n };\n\n if (!child.stdout) {\n yield {\n type: 'error',\n message: 'dsh stdout stream is unavailable',\n terminationReason: 'failed',\n };\n return;\n }\n\n const lines = createInterface({ input: child.stdout, crlfDelay: Infinity });\n const plainLines: string[] = [];\n let emittedProtocol = false;\n let terminalEmitted = false;\n\n for await (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const events = translateDshLine(trimmed);\n if (events.length > 0) {\n emittedProtocol = true;\n for (const event of events) {\n if (event.type === 'done' || event.type === 'error') terminalEmitted = true;\n yield event;\n }\n } else {\n plainLines.push(trimmed);\n }\n }\n\n const exitCode = await waitForExitResult(child, 0).then((value) => value.code);\n const runtimeError = getError();\n\n if (!terminalEmitted) {\n if (exitCode !== null && exitCode !== 0) {\n const stderr = Buffer.concat(stderrChunks).toString('utf8').trim();\n const detail = stderr ? `: ${stderr.slice(0, 500)}` : '';\n yield {\n type: 'error',\n message: `dsh exited with code ${exitCode}${detail}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (runtimeError) {\n yield {\n type: 'error',\n message: `dsh runtime error: ${runtimeError.message}`,\n terminationReason: 'failed',\n };\n return;\n }\n\n if (emittedProtocol) {\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n } else {\n yield* plainOutputEvent(plainLines.join('\\n'));\n yield { type: 'done', sessionId: system.sessionId, terminationReason: 'normal' };\n }\n }\n}\n\nasync function waitForExitResult(\n child: DshChild,\n timeoutMs: number,\n): Promise<{ code: number | null; timedOut: boolean }> {\n if (child.exitCode !== null || child.signalCode !== null) {\n return { code: child.exitCode, timedOut: false };\n }\n\n return new Promise((resolve) => {\n const onExit = (code: number | null): void => {\n if (timer !== undefined) clearTimeout(timer);\n resolve({ code, timedOut: false });\n };\n const timer =\n timeoutMs > 0\n ? setTimeout(() => {\n child.removeListener('exit', onExit);\n resolve({ code: child.exitCode, timedOut: true });\n }, timeoutMs)\n : undefined;\n child.once('exit', onExit);\n });\n}\n\nasync function stopChild(child: DshChild, graceMs: number): Promise<void> {\n if (child.exitCode !== null || child.signalCode !== null) return;\n child.kill('SIGTERM');\n const stopped = await waitForExitResult(child, graceMs);\n if (!stopped.timedOut) return;\n child.kill('SIGKILL');\n}\n\nasync function waitForChildExit(child: DshChild, timeoutMs: number): Promise<boolean> {\n const result = await waitForExitResult(child, timeoutMs);\n return !result.timedOut && result.code !== null;\n}\n","import { spawn } from 'cross-spawn';\nimport { existsSync } from 'node:fs';\nimport type { AgentAvailability } from '../types.js';\n\nexport interface AvailabilityCheckOptions {\n command: string;\n args?: string[];\n timeoutMs?: number;\n}\n\nexport async function checkDshAvailability(\n options: AvailabilityCheckOptions,\n): Promise<AgentAvailability> {\n const timeoutMs = options.timeoutMs ?? 5_000;\n const versionArgs = options.command === 'node' && options.args?.[0] && existsSync(options.args[0])\n ? [options.args[0], '--version']\n : ['--version'];\n\n return new Promise((resolve) => {\n const child = spawn(options.command, versionArgs, {\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let stdout = '';\n let stderr = '';\n let settled = false;\n\n const finish = (result: AgentAvailability): void => {\n if (settled) return;\n settled = true;\n resolve(result);\n };\n\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n finish({ ok: false, error: `timed out after ${timeoutMs}ms`, version: undefined });\n }, timeoutMs);\n\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n clearTimeout(timer);\n finish({ ok: false, error: error.message, version: undefined });\n });\n child.on('exit', (code) => {\n clearTimeout(timer);\n const version = stdout.trim();\n if (code !== 0 && !version) {\n finish({ ok: false, error: stderr.trim() || `exited with code ${String(code)}`, version: undefined });\n return;\n }\n finish({ ok: true, error: undefined, version: version || undefined });\n });\n });\n}\n","import type { AgentEvent } from '../types.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function translateDshLine(line: string): AgentEvent[] {\n const trimmed = line.trim();\n if (!trimmed) return [];\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (!isRecord(parsed) || typeof parsed.type !== 'string') return [];\n\n switch (parsed.type) {\n case 'system':\n return [\n {\n type: 'system',\n sessionId: stringValue(parsed.sessionId),\n cwd: stringValue(parsed.cwd),\n model: stringValue(parsed.model),\n },\n ];\n case 'text':\n return [{ type: 'text', delta: stringValue(parsed.delta) ?? '' }];\n case 'final_text':\n return [{ type: 'final_text', content: stringValue(parsed.content) ?? '' }];\n case 'thinking':\n return [{ type: 'thinking', delta: stringValue(parsed.delta) ?? '' }];\n case 'tool_use':\n return [\n {\n type: 'tool_use',\n id: stringValue(parsed.id) ?? 'unknown',\n name: stringValue(parsed.name) ?? 'tool',\n input: parsed.input,\n },\n ];\n case 'tool_result':\n return [\n {\n type: 'tool_result',\n id: stringValue(parsed.id) ?? 'unknown',\n output: stringValue(parsed.output) ?? '',\n isError: parsed.isError === true,\n },\n ];\n case 'done':\n return [\n {\n type: 'done',\n sessionId: stringValue(parsed.sessionId),\n terminationReason: 'normal',\n },\n ];\n case 'error':\n return [\n {\n type: 'error',\n message: stringValue(parsed.message) ?? 'dsh failed',\n terminationReason: 'failed',\n },\n ];\n default:\n return [];\n }\n } catch {\n return [];\n }\n}\n\nexport function plainOutputEvent(output: string): AgentEvent[] {\n const trimmed = output.trim();\n return trimmed ? [{ type: 'final_text', content: trimmed }] : [];\n}\n","import { randomUUID } from 'node:crypto';\nimport {\n DeepSeekHarness,\n HarnessClient,\n} from '@deepseek-ai/dsh-sdk-client';\nimport type {\n AgentAdapter,\n AgentAvailability,\n AgentRun,\n AgentRunOptions,\n} from '../types.js';\nimport { createSdkRun } from './sdk-translate.js';\nimport type { SdkLaunchSpec } from './sdk-runtime.js';\n\nexport interface SdkAdapterOptions {\n /** Launch spec for the SDK runtime subprocess (command + args, no cwd). */\n launch: SdkLaunchSpec;\n provider: string;\n model: string;\n maxTokens?: number;\n /** Per-request timeout for the availability probe. */\n probeTimeoutMs?: number;\n /** Injectable harness factory for tests. */\n harnessFactory?: (cwd: string) => DeepSeekHarness;\n}\n\ninterface RuntimeEntry {\n harness: DeepSeekHarness;\n}\n\nfunction waitWithTimeout(promise: Promise<unknown>, timeoutMs: number): Promise<boolean> {\n return new Promise((resolve) => {\n const timer = setTimeout(() => resolve(false), timeoutMs > 0 ? timeoutMs : 5_000);\n promise.then(\n () => {\n clearTimeout(timer);\n resolve(true);\n },\n () => {\n clearTimeout(timer);\n resolve(true);\n },\n );\n });\n}\n\n/**\n * Official DeepSeek Harness SDK adapter. Replaces the hand-written headless\n * subprocess protocol with `@deepseek-ai/dsh-sdk-client`: one runtime per\n * workspace cwd, native `session(id)` continuation, and token-level streaming\n * events (`assistant/chunk` reasoning/text deltas).\n */\nexport class SdkDshAdapter implements AgentAdapter {\n readonly id = 'dsh-sdk';\n readonly displayName = 'DeepSeek Harness (SDK)';\n\n private readonly launch: SdkLaunchSpec;\n private readonly provider: string;\n private readonly model: string;\n private readonly maxTokens: number | undefined;\n private readonly probeTimeoutMs: number;\n private readonly harnessFactory: (cwd: string) => DeepSeekHarness;\n private readonly runtimes = new Map<string, RuntimeEntry>();\n private disposed = false;\n\n constructor(options: SdkAdapterOptions) {\n this.launch = options.launch;\n this.provider = options.provider;\n this.model = options.model;\n this.maxTokens = options.maxTokens;\n this.probeTimeoutMs = options.probeTimeoutMs ?? 15_000;\n this.harnessFactory = options.harnessFactory ?? ((cwd) => this.createHarness(cwd));\n }\n\n async isAvailable(): Promise<boolean> {\n return (await this.checkAvailability()).ok;\n }\n\n async checkAvailability(): Promise<AgentAvailability> {\n if (this.disposed) {\n return { ok: false, error: 'adapter disposed', version: undefined };\n }\n const client = new HarnessClient({\n command: this.launch.command,\n args: this.launch.args,\n cwd: process.cwd(),\n requestTimeoutMs: this.probeTimeoutMs,\n });\n try {\n client.start();\n const info = await client.initialize({\n cwd: process.cwd(),\n provider: this.provider,\n model: this.model,\n ...(this.maxTokens === undefined ? {} : { maxTokens: this.maxTokens }),\n });\n return {\n ok: true,\n error: undefined,\n version: `${info.serverInfo.name}@${info.serverInfo.version}`,\n };\n } catch (error) {\n return {\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n version: undefined,\n };\n } finally {\n await client.close();\n }\n }\n\n run(options: AgentRunOptions): AgentRun {\n const cwd = options.cwd ?? process.cwd();\n const entry = this.runtimeFor(cwd);\n const sessionId =\n options.sessionId ?? `session-${randomUUID().replaceAll('-', '')}`;\n const stopRequested = { value: false };\n const handle = createSdkRun(entry.harness, options.prompt, {\n sessionId,\n cwd,\n model: options.model ?? this.model,\n images: options.images,\n stopRequested,\n });\n\n return {\n runId: options.runId,\n events: handle.events,\n stop: async () => {\n stopRequested.value = true;\n await this.closeRuntime(cwd);\n },\n waitForExit: (timeoutMs) => waitWithTimeout(handle.settled, timeoutMs),\n };\n }\n\n /** Close every runtime subprocess (used on bridge shutdown). */\n async dispose(): Promise<void> {\n this.disposed = true;\n const entries = [...this.runtimes.values()];\n this.runtimes.clear();\n await Promise.allSettled(\n entries.map((entry) => entry.harness.close()),\n );\n }\n\n private createHarness(cwd: string): DeepSeekHarness {\n return new DeepSeekHarness({\n launch: {\n command: this.launch.command,\n args: this.launch.args,\n cwd,\n },\n cwd,\n provider: this.provider,\n model: this.model,\n ...(this.maxTokens === undefined ? {} : { maxTokens: this.maxTokens }),\n });\n }\n\n private runtimeFor(cwd: string): RuntimeEntry {\n if (this.disposed) {\n throw new Error('SdkDshAdapter is disposed');\n }\n const existing = this.runtimes.get(cwd);\n if (existing) return existing;\n const entry: RuntimeEntry = { harness: this.harnessFactory(cwd) };\n this.runtimes.set(cwd, entry);\n return entry;\n }\n\n private async closeRuntime(cwd: string): Promise<void> {\n const entry = this.runtimes.get(cwd);\n if (!entry) return;\n this.runtimes.delete(cwd);\n try {\n await entry.harness.close();\n } catch (error) {\n // Closing is best-effort; the runtime process teardown ladder is\n // already idempotent inside the SDK client.\n void error;\n }\n }\n}\n","import type { DeepSeekHarness, HarnessNotification } from '@deepseek-ai/dsh-sdk-client';\nimport type { AgentEvent } from '../types.js';\nimport { EventChannel } from './event-channel.js';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction stringValue(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined;\n}\n\nfunction safeParseJson(value: unknown): unknown {\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value) as unknown;\n } catch {\n return value;\n }\n}\n\nfunction textOfBlocks(blocks: unknown): string {\n if (!Array.isArray(blocks)) return '';\n return blocks\n .filter(isRecord)\n .filter((block) => block.type === 'text' && typeof block.text === 'string')\n .map((block) => block.text as string)\n .join('');\n}\n\ninterface ToolDeltaTracker {\n emitted: Set<string>;\n}\n\nfunction translateChunk(chunk: unknown, tracker: ToolDeltaTracker): AgentEvent[] {\n if (!isRecord(chunk)) return [];\n switch (chunk.type) {\n case 'reasoning-delta':\n return typeof chunk.text === 'string' && chunk.text\n ? [{ type: 'thinking', delta: chunk.text }]\n : [];\n case 'text-delta':\n return typeof chunk.text === 'string' && chunk.text\n ? [{ type: 'text', delta: chunk.text }]\n : [];\n case 'tool-call-delta': {\n const id = stringValue(chunk.id);\n if (!id || tracker.emitted.has(id)) return [];\n tracker.emitted.add(id);\n return [\n {\n type: 'tool_use',\n id,\n name: stringValue(chunk.name) ?? 'tool',\n input: {},\n },\n ];\n }\n default:\n return [];\n }\n}\n\nfunction translateToolResult(data: unknown): AgentEvent[] {\n if (!isRecord(data)) return [];\n const message = isRecord(data.message) ? data.message : undefined;\n const block = Array.isArray(message?.content) ? message.content[0] : undefined;\n const toolCallId = stringValue(\n isRecord(block) ? block.toolCallId : undefined,\n );\n if (!toolCallId) return [];\n const output = textOfBlocks(isRecord(block) ? block.content : undefined);\n const isError =\n data.error !== undefined || (isRecord(block) ? block.isError === true : false);\n return [\n {\n type: 'tool_result',\n id: toolCallId,\n output,\n isError,\n },\n ];\n}\n\nfunction translateAssistantMessage(data: unknown): AgentEvent[] {\n if (!isRecord(data) || !isRecord(data.usage)) return [];\n const usage = data.usage;\n const inputTokens =\n typeof usage.inputTokens === 'number' ? usage.inputTokens : undefined;\n const outputTokens =\n typeof usage.outputTokens === 'number' ? usage.outputTokens : undefined;\n if (inputTokens === undefined && outputTokens === undefined) return [];\n return [\n {\n type: 'usage',\n ...(inputTokens === undefined ? {} : { inputTokens }),\n ...(outputTokens === undefined ? {} : { outputTokens }),\n },\n ];\n}\n\nfunction translateTurnEnd(data: unknown): AgentEvent[] {\n if (!isRecord(data) || !isRecord(data.reason) || data.reason.kind !== 'error') return [];\n const failure = isRecord(data.reason.error) ? data.reason.error : undefined;\n const message = stringValue(failure?.message) ?? 'dsh turn failed';\n return [{ type: 'error', message, terminationReason: 'failed' }];\n}\n\n/**\n * Translate one SDK session event into bridge `AgentEvent`s.\n * Token-level `assistant/chunk` deltas give the streaming (typewriter) card\n * experience: reasoning deltas feed the thinking section, text deltas feed\n * the output block, tool deltas surface live tool activity.\n */\nexport function translateSessionEvent(\n event: unknown,\n tracker: ToolDeltaTracker,\n): AgentEvent[] {\n if (!isRecord(event) || typeof event.type !== 'string') return [];\n switch (event.type) {\n case 'assistant/chunk':\n return translateChunk(isRecord(event.data) ? event.data.chunk : undefined, tracker);\n case 'tool/call': {\n const data = isRecord(event.data) ? event.data : undefined;\n const id = stringValue(data?.callId);\n if (!id) return [];\n return [\n {\n type: 'tool_use',\n id,\n name: stringValue(data?.name) ?? 'tool',\n input: safeParseJson(data?.arguments),\n },\n ];\n }\n case 'tool/result':\n return translateToolResult(event.data);\n case 'assistant/message':\n return translateAssistantMessage(event.data);\n case 'turn/end':\n return translateTurnEnd(event.data);\n default:\n return [];\n }\n}\n\nfunction translateNotification(\n notification: HarnessNotification,\n sessionId: string,\n tracker: ToolDeltaTracker,\n): AgentEvent[] {\n if (notification.method !== 'session.event') return [];\n const params = isRecord(notification.params) ? notification.params : undefined;\n if (params?.sessionId !== sessionId) return [];\n return translateSessionEvent(params.event, tracker);\n}\n\nexport interface SdkRunOptions {\n sessionId: string;\n cwd: string | undefined;\n model: string | undefined;\n images: readonly string[] | undefined;\n stopRequested: { value: boolean };\n}\n\nexport interface SdkRunHandle {\n events: AsyncIterable<AgentEvent>;\n /** Resolves when the underlying SDK turn settles (success or failure). */\n settled: Promise<void>;\n}\n\nfunction buildPromptText(prompt: string, images: readonly string[] | undefined): string {\n return images?.length\n ? `${prompt}\\n\\nImage files attached to this message:\\n${images.join('\\n')}`\n : prompt;\n}\n\n/**\n * Run one prompt on a harness session and stream the result as `AgentEvent`s.\n * The SDK client owns the runtime handshake; this helper owns the\n * notification-to-event translation and the run lifecycle.\n */\nexport function createSdkRun(\n harness: DeepSeekHarness,\n prompt: string,\n options: SdkRunOptions,\n): SdkRunHandle {\n const channel = new EventChannel<AgentEvent>();\n const tracker: ToolDeltaTracker = { emitted: new Set() };\n let hadError = false;\n\n const task = harness\n .run(buildPromptText(prompt, options.images), {\n sessionId: options.sessionId,\n onNotification: (notification) => {\n for (const event of translateNotification(notification, options.sessionId, tracker)) {\n if (event.type === 'error') hadError = true;\n channel.push(event);\n }\n },\n })\n .catch((error: unknown) => {\n if (!options.stopRequested.value) {\n channel.push({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n terminationReason: 'failed',\n });\n hadError = true;\n }\n })\n .finally(() => {\n channel.close();\n });\n\n async function* events(): AsyncGenerator<AgentEvent> {\n yield {\n type: 'system',\n sessionId: options.sessionId,\n cwd: options.cwd,\n model: options.model,\n };\n for await (const event of channel) {\n yield event;\n }\n await task;\n if (!hadError) {\n yield {\n type: 'done',\n sessionId: options.sessionId,\n terminationReason: options.stopRequested.value ? 'interrupted' : 'normal',\n };\n }\n }\n\n return { events: events(), settled: task.then(() => undefined) };\n}\n","import { spawn } from 'node:child_process';\nimport { existsSync, realpathSync } from 'node:fs';\nimport { readFileSync } from 'node:fs';\nimport { mkdir, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { DSH_COMPATIBILITY } from '../../config/dsh-compat.js';\nimport { discoverDshBin, resolveDshHome } from '../../config/dsh-runtime.js';\nimport { ownPackageInfo } from './own-package.js';\n\nexport const SDK_SERVER_PACKAGE = '@deepseek-ai/dsh-sdk-jsonrpc-server';\nexport const SDK_SERVER_VERSION = DSH_COMPATIBILITY.sdkServer;\nexport const SDK_BASE_BUNDLE = '@deepseek-ai/dsh-base';\nexport const DEFAULT_SDK_PROFILE = 'dsh-lark-sdk';\n\nexport interface SdkRuntimeOptions {\n /** OS home directory used to resolve the shared dsh installation. */\n home: string;\n /** Environment snapshot for dsh home resolution (defaults to process.env). */\n env?: NodeJS.ProcessEnv;\n /** Explicit runtime command; overrides auto-discovery (from DSH_LARK_DSH_COMMAND). */\n command?: string;\n /** Explicit runtime args; overrides auto-discovery (from DSH_LARK_DSH_ARGS). */\n args?: string[];\n /** Discovered dsh bin path; used when command/args are not explicit. */\n bin?: string;\n /** Profile name for the SDK runtime composition. */\n profile?: string;\n /** Injectable installer for tests. */\n install?: (profileRoot: string) => Promise<void>;\n}\n\nexport interface SdkLaunchSpec {\n command: string;\n args: string[];\n profile: string;\n}\n\nexport interface SdkProfileEnsureResult {\n ok: boolean;\n created: boolean;\n error?: string;\n}\n\nexport function sdkProfileRoot(home: string, profile: string, env?: NodeJS.ProcessEnv): string {\n return join(resolveDshHome(home, env), 'profiles', profile);\n}\n\nfunction packageJsonFor(profile: string): string {\n const own = ownPackageInfo();\n return `${JSON.stringify(\n {\n name: `dsh-profile-${profile}`,\n private: true,\n dependencies: {\n [SDK_SERVER_PACKAGE]: SDK_SERVER_VERSION,\n [own.name]: `link:${own.root}`,\n },\n dsh: {\n profile: {\n bundles: [SDK_BASE_BUNDLE],\n },\n },\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction patchYamlFor(): string {\n const own = ownPackageInfo();\n return [\n '# dsh-lark SDK JSON-RPC runtime overlay (managed by dsh-lark-bot).',\n '# stdout is reserved for SDK JSON-RPC frames; no console logger may load.',\n '- insert:',\n ' - id: sdk-jsonrpc-server',\n ` name: '${SDK_SERVER_PACKAGE}'`,\n ' config:',\n ' maxTokensAsSuccess: true',\n '',\n '# Unattended IM runtime: interactive user questions cannot be answered',\n '# through Feishu, so the tool is disabled (default-deny).',\n '- id: user-questions',\n ' disabled: true',\n '',\n '- id: system-prompt',\n ' config:',\n ' persona: >-',\n ' You are a coding agent powered by the {{model}} model. Your working directory is {{cwd}}.',\n '',\n '- id: hmr',\n ' disabled: true',\n '',\n // In-process bridge callback tool: lets the agent mention users and push\n // messages to other chats/topics through the running bridge process.\n '- insert:',\n ' - id: lark-notify',\n ` name: '${own.name}/notify'`,\n ' config:',\n ' endpoint: !!js process.env.DSH_LARK_NOTIFY_URL',\n ' token: !!js process.env.DSH_LARK_NOTIFY_TOKEN',\n '',\n ].join('\\n');\n}\n\nfunction sdkServerInstalled(profileRoot: string): boolean {\n const candidates = [\n join(profileRoot, 'node_modules', SDK_SERVER_PACKAGE),\n join(profileRoot, '..', 'node_modules', SDK_SERVER_PACKAGE),\n ];\n return candidates.some((path) => existsSync(path));\n}\n\nexport function isSdkProfileReady(profileRoot: string): boolean {\n const own = ownPackageInfo();\n return (\n existsSync(join(profileRoot, 'package.json')) &&\n existsSync(join(profileRoot, 'cordis.yml')) &&\n existsSync(join(profileRoot, 'cordis.patch.yml')) &&\n sdkServerInstalled(profileRoot) &&\n ownPackageLinked(profileRoot, own.name)\n );\n}\n\n/** True when the profile's node_modules link resolves to this package. */\nfunction ownPackageLinked(profileRoot: string, ownName: string): boolean {\n const linkPath = join(profileRoot, 'node_modules', ownName);\n try {\n const real = realpathSync(linkPath);\n const pkg = JSON.parse(readFileSync(join(real, 'package.json'), 'utf8')) as {\n name?: unknown;\n dsh?: { bundle?: { patch?: unknown } };\n };\n return (\n pkg.name === ownName &&\n pkg.dsh?.bundle?.patch !== undefined\n );\n } catch {\n return false;\n }\n}\n\nfunction runPnpmInstall(profileRoot: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn('pnpm', ['install'], {\n cwd: profileRoot,\n stdio: ['ignore', 'pipe', 'pipe'],\n });\n let output = '';\n child.stdout.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.stderr.on('data', (chunk: Buffer) => {\n output += chunk.toString('utf8');\n });\n child.on('error', (error) => {\n reject(error);\n });\n child.on('close', (code) => {\n if (code === 0) {\n resolve();\n return;\n }\n const tail = output.trim().split('\\n').slice(-8).join('\\n');\n reject(new Error(`pnpm install exited with code ${String(code)}\\n${tail}`));\n });\n });\n}\n\n/**\n * Ensure the SDK runtime profile exists under the shared dsh installation.\n * The profile is a managed composition: `@deepseek-ai/dsh-base` bundle plus\n * the official `@deepseek-ai/dsh-sdk-jsonrpc-server` plugin. Idempotent.\n */\nexport async function ensureSdkProfile(\n options: SdkRuntimeOptions,\n): Promise<SdkProfileEnsureResult> {\n const profile = options.profile ?? DEFAULT_SDK_PROFILE;\n const root = sdkProfileRoot(options.home, profile, options.env);\n if (isSdkProfileReady(root)) return { ok: true, created: false };\n\n try {\n await mkdir(root, { recursive: true });\n await writeFile(join(root, 'package.json'), packageJsonFor(profile), 'utf8');\n await writeFile(join(root, 'cordis.yml'), '[]\\n', 'utf8');\n await writeFile(join(root, 'cordis.patch.yml'), patchYamlFor(), 'utf8');\n const install = options.install ?? runPnpmInstall;\n if (!isSdkProfileReady(root)) {\n await install(root);\n }\n if (!isSdkProfileReady(root)) {\n return {\n ok: false,\n created: true,\n error: `${SDK_SERVER_PACKAGE}@${SDK_SERVER_VERSION} was not found after install`,\n };\n }\n return { ok: true, created: true };\n } catch (error) {\n return {\n ok: false,\n created: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/** Resolve the launch spec for the SDK runtime subprocess. */\nexport function resolveSdkLaunch(options: SdkRuntimeOptions): SdkLaunchSpec {\n const profile = options.profile ?? DEFAULT_SDK_PROFILE;\n if (options.command || options.args) {\n return {\n command: options.command ?? 'node',\n args: options.args ?? ['--profile', profile],\n profile,\n };\n }\n const bin = options.bin ?? discoverDshBin(options.home, options.env);\n if (bin) {\n return { command: 'node', args: [bin, '--profile', profile], profile };\n }\n return { command: 'dsh', args: ['--profile', profile], profile };\n}\n","import { homedir } from 'node:os';\nimport { join, resolve } from 'node:path';\n\nexport interface AppPaths {\n root: string;\n configFile: string;\n activeProfileFile: string;\n profileDir: (profile: string) => string;\n profilePath: (profile: string, ...parts: string[]) => string;\n sessionsFile: (profile: string) => string;\n sessionCatalogFile: (profile: string) => string;\n archivesDir: (profile: string) => string;\n workspacesFile: (profile: string) => string;\n mediaDir: (profile: string) => string;\n logsDir: (profile: string) => string;\n}\n\nexport function defaultHome(): string {\n const override = process.env.DSH_LARK_HOME?.trim();\n return override ? resolve(override) : join(homedir(), '.dsh-lark');\n}\n\nexport function resolveAppPaths(root: string = defaultHome()): AppPaths {\n const profileDir = (profile: string): string => join(root, 'profiles', profile);\n const profilePath = (profile: string, ...parts: string[]): string =>\n join(profileDir(profile), ...parts);\n\n return {\n root,\n configFile: join(root, 'config.json'),\n activeProfileFile: join(root, 'active-profile'),\n profileDir,\n profilePath,\n sessionsFile: (profile) => profilePath(profile, 'sessions.json'),\n sessionCatalogFile: (profile) => profilePath(profile, 'sessions.json.catalog.json'),\n archivesDir: (profile) => profilePath(profile, 'archives'),\n workspacesFile: (profile) => profilePath(profile, 'workspaces.json'),\n mediaDir: (profile) => profilePath(profile, 'media'),\n logsDir: (profile) => profilePath(profile, 'logs'),\n };\n}\n","import { join, resolve } from 'node:path';\nimport { homedir } from 'node:os';\nimport { resolveDshRuntime } from './dsh-runtime.js';\n\nexport type LarkTenant = 'feishu' | 'lark';\nexport type AdapterMode = 'sdk' | 'acp' | 'headless';\n\nexport interface RuntimeEnv {\n home: string;\n tenant: LarkTenant;\n appId: string | undefined;\n appSecret: string | undefined;\n workspace: string | undefined;\n dshCommand: string;\n dshArgs: string[];\n /** True when DSH_LARK_DSH_COMMAND / DSH_LARK_DSH_ARGS were set explicitly. */\n dshExplicit: boolean;\n adapterMode: AdapterMode;\n provider: string;\n model: string;\n maxTokens: number | undefined;\n runTimeoutMs: number;\n stopGraceMs: number;\n /** Max agent runs allowed concurrently per scope (default 2). */\n scopeConcurrency: number;\n /** Live messages kept per scope before overflow is archived (default 40). */\n retentionMsgs: number;\n /** Max archives retained per scope before pruning (default 50, 0 disables). */\n archiveMax: number;\n /** Archives older than this many days are pruned (default 90, 0 disables). */\n archiveMaxAgeDays: number;\n accessDefaultDeny: boolean;\n eventFreshnessMs: number;\n /** Bridge engine heartbeat interval (guardian liveness signal), default 5000. */\n heartbeatMs: number;\n /** Guardian disabled switch (DSH_LARK_GUARDIAN_DISABLED=1 keeps it stopped). */\n guardianDisabled: boolean;\n /** dsh profile the guardian watches / relaunches (default `dsh-lark`). */\n guardianProfile: string;\n /** Bridge state profile providing Feishu credentials (default `default`). */\n guardianBridgeProfile: string;\n /** Guardian watchdog poll interval, default 2000. */\n guardianPollMs: number;\n /** Heartbeat staleness threshold before takeover, default 15000. */\n guardianStaleMs: number;\n /**\n * When a dsh process is alive but the bridge heartbeat has been stale for\n * longer than this, treat the engine as dead and take over (default 120000).\n */\n guardianEngineDeadMs: number;\n}\n\nconst DEFAULTS = {\n tenant: 'feishu' as const,\n provider: 'deepseek-official',\n model: 'deepseek-v4-flash',\n runTimeoutMs: 300_000,\n stopGraceMs: 5_000,\n scopeConcurrency: 2,\n retentionMsgs: 40,\n archiveMax: 50,\n archiveMaxAgeDays: 90,\n heartbeatMs: 5_000,\n guardianPollMs: 2_000,\n guardianStaleMs: 15_000,\n guardianEngineDeadMs: 120_000,\n guardianProfile: 'dsh-lark',\n guardianBridgeProfile: 'default',\n};\n\nfunction nonEmpty(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction parseTenant(value: string | undefined): LarkTenant {\n const tenant = nonEmpty(value) ?? DEFAULTS.tenant;\n if (tenant !== 'feishu' && tenant !== 'lark') {\n throw new Error(`DSH_LARK_TENANT must be \"feishu\" or \"lark\", got \"${tenant}\"`);\n }\n return tenant;\n}\n\nfunction parseDshArgs(value: string | undefined): string[] {\n const raw = value?.trim();\n if (!raw) return [];\n return raw\n .split(',')\n .map((item) => item.trim())\n .filter(Boolean);\n}\n\nfunction parseTimeout(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.runTimeoutMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_RUN_TIMEOUT_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseStopGrace(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return DEFAULTS.stopGraceMs;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_STOP_GRACE_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseAdapterMode(value: string | undefined): AdapterMode {\n const mode = nonEmpty(value) ?? 'sdk';\n if (mode !== 'sdk' && mode !== 'acp' && mode !== 'headless') {\n throw new Error(`DSH_LARK_ADAPTER must be \"sdk\", \"acp\" or \"headless\", got \"${mode}\"`);\n }\n return mode;\n}\n\nfunction parseMaxTokens(value: string | undefined): number | undefined {\n const raw = value?.trim();\n if (!raw) return undefined;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed <= 0) {\n throw new Error(`DSH_LARK_MAX_TOKENS must be a positive integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseBoolean(value: string | undefined, fallback: boolean): boolean {\n const raw = value?.trim().toLowerCase();\n if (!raw) return fallback;\n if (raw === '1' || raw === 'true' || raw === 'yes') return true;\n if (raw === '0' || raw === 'false' || raw === 'no') return false;\n return fallback;\n}\n\nfunction parseFreshness(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return 600_000;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`DSH_LARK_EVENT_FRESHNESS_MS must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number, name: string): number {\n const raw = value?.trim();\n if (!raw) return fallback;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 0) {\n throw new Error(`${name} must be a non-negative integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parseMinOneInt(value: string | undefined, fallback: number, name: string): number {\n const raw = value?.trim();\n if (!raw) return fallback;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new Error(`${name} must be a positive integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nfunction parsePositiveIntMin(value: string | undefined, fallback: number, name: string): number {\n const raw = value?.trim();\n if (!raw) return fallback;\n const parsed = Number(raw);\n if (!Number.isInteger(parsed) || parsed < 1) {\n throw new Error(`${name} must be a positive integer, got \"${raw}\"`);\n }\n return parsed;\n}\n\nexport function loadRuntimeEnv(\n source: NodeJS.ProcessEnv = process.env,\n): RuntimeEnv {\n const homeOverride = nonEmpty(source.DSH_LARK_HOME);\n const workspace = nonEmpty(source.DSH_LARK_WORKSPACE);\n const home = homeOverride ? resolve(homeOverride) : join(homedir(), '.dsh-lark');\n const osHome = homedir();\n const explicitCommand = nonEmpty(source.DSH_LARK_DSH_COMMAND);\n const rawDshArgs = nonEmpty(source.DSH_LARK_DSH_ARGS);\n const dshExplicit = explicitCommand !== undefined || rawDshArgs !== undefined;\n const dshRuntime = resolveDshRuntime({\n home: osHome,\n env: source,\n ...(explicitCommand ? { command: explicitCommand } : {}),\n ...(rawDshArgs ? { args: parseDshArgs(rawDshArgs) } : {}),\n });\n\n return {\n home,\n tenant: parseTenant(source.DSH_LARK_TENANT),\n appId: nonEmpty(source.DSH_LARK_APP_ID),\n appSecret: nonEmpty(source.DSH_LARK_APP_SECRET),\n workspace: workspace ? resolve(workspace) : undefined,\n dshCommand: dshRuntime.command,\n dshArgs: dshRuntime.args,\n dshExplicit,\n adapterMode: parseAdapterMode(source.DSH_LARK_ADAPTER),\n provider: nonEmpty(source.DSH_LARK_PROVIDER) ?? DEFAULTS.provider,\n model: nonEmpty(source.DSH_LARK_MODEL) ?? DEFAULTS.model,\n maxTokens: parseMaxTokens(source.DSH_LARK_MAX_TOKENS),\n runTimeoutMs: parseTimeout(source.DSH_LARK_RUN_TIMEOUT_MS),\n stopGraceMs: parseStopGrace(source.DSH_LARK_STOP_GRACE_MS),\n scopeConcurrency: parseMinOneInt(\n source.DSH_LARK_SCOPE_CONCURRENCY,\n DEFAULTS.scopeConcurrency,\n 'DSH_LARK_SCOPE_CONCURRENCY',\n ),\n retentionMsgs: parsePositiveInt(\n source.DSH_LARK_RETENTION_MSGS,\n DEFAULTS.retentionMsgs,\n 'DSH_LARK_RETENTION_MSGS',\n ),\n archiveMax: parsePositiveInt(\n source.DSH_LARK_ARCHIVE_MAX,\n DEFAULTS.archiveMax,\n 'DSH_LARK_ARCHIVE_MAX',\n ),\n archiveMaxAgeDays: parsePositiveInt(\n source.DSH_LARK_ARCHIVE_MAX_AGE_DAYS,\n DEFAULTS.archiveMaxAgeDays,\n 'DSH_LARK_ARCHIVE_MAX_AGE_DAYS',\n ),\n accessDefaultDeny: parseBoolean(source.DSH_LARK_ACCESS_DEFAULT_DENY, false),\n eventFreshnessMs: parseFreshness(source.DSH_LARK_EVENT_FRESHNESS_MS),\n heartbeatMs: parsePositiveIntMin(\n source.DSH_LARK_HEARTBEAT_MS,\n DEFAULTS.heartbeatMs,\n 'DSH_LARK_HEARTBEAT_MS',\n ),\n guardianDisabled: parseBoolean(source.DSH_LARK_GUARDIAN_DISABLED, false),\n guardianProfile:\n nonEmpty(source.DSH_LARK_GUARDIAN_PROFILE) ?? DEFAULTS.guardianProfile,\n guardianBridgeProfile:\n nonEmpty(source.DSH_LARK_GUARDIAN_BRIDGE_PROFILE) ?? DEFAULTS.guardianBridgeProfile,\n guardianPollMs: parsePositiveIntMin(\n source.DSH_LARK_GUARDIAN_POLL_MS,\n DEFAULTS.guardianPollMs,\n 'DSH_LARK_GUARDIAN_POLL_MS',\n ),\n guardianStaleMs: parsePositiveIntMin(\n source.DSH_LARK_GUARDIAN_STALE_MS,\n DEFAULTS.guardianStaleMs,\n 'DSH_LARK_GUARDIAN_STALE_MS',\n ),\n guardianEngineDeadMs: parsePositiveIntMin(\n source.DSH_LARK_GUARDIAN_ENGINE_DEAD_MS,\n DEFAULTS.guardianEngineDeadMs,\n 'DSH_LARK_GUARDIAN_ENGINE_DEAD_MS',\n ),\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { mkdir } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport type { LarkTenant } from './env.js';\n\nexport interface ProfileConfig {\n schemaVersion: 1;\n agentKind: 'dsh';\n tenant: LarkTenant;\n accounts: {\n appId: string;\n appSecret: string;\n };\n workspaces: {\n default: string | undefined;\n };\n preferences: {\n model: string | undefined;\n stopGraceMs: number | undefined;\n runTimeoutMs: number | undefined;\n };\n access: {\n allowedUsers: string[];\n allowedChats: string[];\n admins: string[];\n };\n}\n\nexport interface RootConfig {\n schemaVersion: 1;\n activeProfile: string;\n profiles: Record<string, ProfileConfig>;\n}\n\nexport class ConfigStore {\n private data: RootConfig | undefined;\n\n constructor(private readonly path: string) {}\n\n async load(): Promise<RootConfig> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<RootConfig>;\n this.data = {\n schemaVersion: 1,\n activeProfile: parsed.activeProfile ?? 'default',\n profiles: Object.fromEntries(\n Object.entries(parsed.profiles ?? {}).map(([name, profile]) => [\n name,\n {\n ...profile,\n access: {\n allowedUsers: profile.access?.allowedUsers ?? [],\n allowedChats: profile.access?.allowedChats ?? [],\n admins: profile.access?.admins ?? [],\n },\n },\n ]),\n ),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = {\n schemaVersion: 1,\n activeProfile: 'default',\n profiles: {},\n };\n }\n return this.data;\n }\n\n getActiveProfile(): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[data.activeProfile];\n }\n\n getProfile(name: string): ProfileConfig | undefined {\n const data = this.getData();\n return data.profiles[name];\n }\n\n async saveProfile(\n name: string,\n input: {\n tenant: LarkTenant;\n appId: string;\n appSecret: string;\n workspace?: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n operatorOpenId?: string;\n access?: {\n allowedUsers?: string[];\n allowedChats?: string[];\n admins?: string[];\n };\n },\n ): Promise<void> {\n const data = this.getData();\n const existing = data.profiles[name];\n const profile: ProfileConfig = {\n schemaVersion: 1,\n agentKind: 'dsh',\n tenant: input.tenant,\n accounts: {\n appId: input.appId,\n appSecret: input.appSecret,\n },\n workspaces: {\n default: input.workspace ?? existing?.workspaces.default ?? undefined,\n },\n preferences: {\n model: input.model ?? existing?.preferences.model ?? undefined,\n stopGraceMs: input.stopGraceMs ?? existing?.preferences.stopGraceMs ?? undefined,\n runTimeoutMs: input.runTimeoutMs ?? existing?.preferences.runTimeoutMs ?? undefined,\n },\n access: {\n allowedUsers: input.access?.allowedUsers ?? existing?.access?.allowedUsers ?? [],\n allowedChats: input.access?.allowedChats ?? existing?.access?.allowedChats ?? [],\n admins: input.access?.admins ?? existing?.access?.admins ?? [],\n },\n };\n if (input.operatorOpenId && !profile.access.allowedUsers.includes(input.operatorOpenId)) {\n profile.access.allowedUsers.push(input.operatorOpenId);\n profile.access.admins.push(input.operatorOpenId);\n }\n data.profiles[name] = profile;\n data.activeProfile = name;\n await this.persist();\n }\n\n private getData(): RootConfig {\n if (!this.data) {\n throw new Error('ConfigStore must be loaded before use');\n }\n return this.data;\n }\n\n private async persist(): Promise<void> {\n const data = this.getData();\n await mkdir(dirname(this.path), { recursive: true });\n await writeFileAtomic(this.path, `${JSON.stringify(data, null, 2)}\\n`, {\n mode: 0o600,\n });\n }\n}\n","import { randomBytes } from 'node:crypto';\nimport { mkdir, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\n\nexport interface AtomicWriteOptions {\n mode?: number;\n}\n\nexport async function writeFileAtomic(\n target: string,\n data: string,\n options: AtomicWriteOptions = {},\n): Promise<void> {\n const directory = dirname(target);\n await mkdir(directory, { recursive: true });\n const temporary = join(directory, `.${randomBytes(8).toString('hex')}.tmp`);\n\n try {\n await writeFile(temporary, data, options.mode === undefined ? undefined : { mode: options.mode });\n await rename(temporary, target);\n } catch (error) {\n await rmSilently(temporary);\n throw error;\n }\n}\n\nasync function rmSilently(path: string): Promise<void> {\n const { rm } = await import('node:fs/promises');\n try {\n await rm(path, { force: true });\n } catch {\n // best effort cleanup only\n }\n}\n","import { mkdir } from 'node:fs/promises';\nimport type { AgentAdapter } from '../../adapters/types.js';\nimport type { LarkChannel, NormalizedMessage } from '@larksuite/channel';\nimport type { RuntimeEnv } from '../../config/env.js';\nimport { buildAgentAdapter } from '../../adapters/index.js';\nimport { ActiveRuns } from '../../bot/active-runs.js';\nimport { ApprovalRegistry } from '../../bot/approvals.js';\nimport { ConcurrencyStore } from '../../bot/concurrency-store.js';\nimport { DensityStore } from '../../bot/density-store.js';\nimport { ModelStore } from '../../bot/model-store.js';\nimport { PendingQueue } from '../../bot/pending-queue.js';\nimport { QuestionRegistry } from '../../bot/questions.js';\nimport { RetentionStore } from '../../bot/retention-store.js';\nimport { RoleStore } from '../../bot/role-store.js';\nimport { RunPolicyStore } from '../../bot/run-policy.js';\nimport { startChannel } from '../../bridge/channel.js';\nimport { adaptLarkChannel } from '../../bridge/lark-channel.js';\nimport { runAgentBatch } from '../../bridge/run-flow.js';\nimport { ScopeDirectory } from '../../bridge/scope-directory.js';\nimport type { StreamingChannel } from '../../bridge/types.js';\nimport { generateNotifyToken, NotifyServer } from '../../notify/server.js';\nimport type { StartOptions } from '../../cli.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\nimport { AccessManager } from '../../config/access-manager.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { ConfigStore } from '../../config/profile-store.js';\nimport { DshProviderManager } from '../../config/dsh-config.js';\nimport { log } from '../../core/logger.js';\nimport { onboardPersonalAgent } from '../../onboard/registration.js';\nimport { prepareAttachments } from '../../media/attachments.js';\nimport { SessionStore } from '../../session/store.js';\nimport { SessionArchive } from '../../session/archive.js';\nimport { GitWorktreeManager } from '../../workspace/git-worktree.js';\nimport { WorkspaceStore } from '../../workspace/store.js';\nimport { startHeartbeat } from '../../guardian/heartbeat.js';\n\nconst DEBOUNCE_MS = 600;\n\nexport interface BridgeEngineStatus {\n state: 'running' | 'stopped';\n profile: string;\n home: string;\n adapterId: string;\n startedAt: string | undefined;\n workspace: string | undefined;\n notifyUrl: string | undefined;\n}\n\nexport interface BridgeEngine {\n readonly profile: string;\n readonly home: string;\n status(): BridgeEngineStatus;\n stop(): Promise<void>;\n}\n\nexport interface BridgeEngineOptions {\n env: RuntimeEnv;\n profileName: string;\n /** Allow first-run QR onboarding when no credentials exist. */\n allowOnboarding: boolean;\n /** Injectable channel factory (tests / host integration). */\n createChannel?: Parameters<typeof startChannel>[0]['createChannel'];\n /** Injectable adapter (tests); otherwise built from env. */\n adapter?: AgentAdapter;\n}\n\nexport interface EnsureProfileOptions {\n env: RuntimeEnv;\n profileName: string;\n allowOnboarding: boolean;\n}\n\nexport async function ensureBotProfile(\n store: ConfigStore,\n options: EnsureProfileOptions,\n): Promise<boolean> {\n const { env, profileName } = options;\n if (env.appId && env.appSecret) {\n const profileInput: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: env.tenant,\n appId: env.appId,\n appSecret: env.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (env.workspace !== undefined) profileInput.workspace = env.workspace;\n await store.saveProfile(profileName, profileInput);\n }\n\n if (store.getProfile(profileName)) return true;\n\n if (!options.allowOnboarding) {\n throw new Error('未检测到飞书 / Lark 应用凭据,且未允许扫码绑定。');\n }\n\n try {\n const created = await onboardPersonalAgent();\n const onboardingProfile: Parameters<ConfigStore['saveProfile']>[1] = {\n tenant: created.tenant,\n appId: created.appId,\n appSecret: created.appSecret,\n model: env.model,\n stopGraceMs: env.stopGraceMs,\n runTimeoutMs: env.runTimeoutMs,\n };\n if (created.operatorOpenId !== undefined) {\n onboardingProfile.operatorOpenId = created.operatorOpenId;\n }\n if (env.workspace !== undefined) onboardingProfile.workspace = env.workspace;\n await store.saveProfile(profileName, onboardingProfile);\n return true;\n } catch (error) {\n log.fail('onboarding', error);\n throw new Error(`扫码创建应用失败:${errorMessage(error)}`);\n }\n}\n\nfunction mergeStartEnv(options: StartOptions): NodeJS.ProcessEnv {\n return {\n ...process.env,\n ...(options.workspace ? { DSH_LARK_WORKSPACE: options.workspace } : {}),\n ...(options.tenant ? { DSH_LARK_TENANT: options.tenant } : {}),\n ...(options.appId ? { DSH_LARK_APP_ID: options.appId } : {}),\n ...(options.appSecret ? { DSH_LARK_APP_SECRET: options.appSecret } : {}),\n };\n}\n\n/**\n * Start the bridge engine. Runs the full Feishu channel pipeline (stores,\n * adapter, card queue, notify server) and returns a handle that can be\n * stopped. No process-level signal handling: the CLI wrapper owns signals,\n * and the dsh bundle plugin owns lifecycle via the cordis context.\n */\nexport async function startBridgeEngine(\n options: BridgeEngineOptions,\n): Promise<BridgeEngine> {\n const env = options.env;\n const paths = resolveAppPaths(env.home);\n const profileName = options.profileName;\n const configStore = new ConfigStore(paths.configFile);\n await configStore.load();\n\n const ready = await ensureBotProfile(configStore, {\n env,\n profileName,\n allowOnboarding: options.allowOnboarding,\n });\n if (!ready) {\n throw new Error('bot profile 未就绪。');\n }\n const activeProfile = configStore.getProfile(profileName);\n if (!activeProfile) {\n throw new Error('本地配置读取失败,请检查后重试。');\n }\n\n const defaultWorkspace =\n activeProfile.workspaces.default ?? env.workspace ?? paths.profilePath(profileName, 'workspace');\n await mkdir(defaultWorkspace, { recursive: true });\n\n const sessions = new SessionStore(paths.sessionsFile(profileName));\n const archiver = new SessionArchive(paths.archivesDir(profileName));\n const workspaces = new WorkspaceStore(paths.workspacesFile(profileName));\n const roleStore = new RoleStore(paths.profilePath(profileName, 'roles.json'));\n const scopeDirectory = new ScopeDirectory(paths.profilePath(profileName, 'scopes.json'));\n const worktreeManager = new GitWorktreeManager({\n worktreesRoot: paths.profilePath(profileName, 'worktrees'),\n });\n await Promise.all([\n sessions.load(),\n workspaces.load(),\n roleStore.load(),\n scopeDirectory.load(),\n ]);\n\n const adapter =\n options.adapter ??\n (await buildAgentAdapter(env, {\n stopGraceMs: activeProfile.preferences.stopGraceMs ?? env.stopGraceMs,\n model: activeProfile.preferences.model,\n }));\n const activeRuns = new ActiveRuns();\n const runPolicies = new RunPolicyStore();\n const concurrencyStore = new ConcurrencyStore();\n const retentionStore = new RetentionStore();\n const approvals = new ApprovalRegistry();\n const questions = new QuestionRegistry();\n const densityStore = new DensityStore();\n const models = new ModelStore();\n const dshConfig = new DshProviderManager({ env: process.env });\n let streaming: StreamingChannel | undefined;\n let larkChannel: LarkChannel | undefined;\n const notifyToken = generateNotifyToken();\n const notifyServer = new NotifyServer({\n token: notifyToken,\n resolve: (message) => {\n if (message.scope) {\n return scopeDirectory.resolve(message.scope);\n }\n if (message.chatId) {\n return scopeDirectory.resolveChat(message.chatId);\n }\n return undefined;\n },\n send: async (destination, payload) => {\n if (!streaming) throw new Error('bridge channel is not ready');\n await streaming.sendMarkdown(destination.chatId, payload.text, {\n ...(destination.threadId ? { threadId: destination.threadId } : {}),\n ...(payload.mentions ? { mentions: payload.mentions } : {}),\n });\n },\n });\n process.env.DSH_LARK_NOTIFY_TOKEN = notifyToken;\n\n const pending = new PendingQueue<NormalizedMessage>(\n DEBOUNCE_MS,\n async (scope, batch) => {\n if (!streaming) return;\n const first = batch[0];\n if (!first) return;\n pending.block(scope);\n try {\n const attachments = await prepareAttachments(\n larkChannel,\n first,\n paths.mediaDir(profileName),\n );\n const messages = [\n first.content,\n ...attachments.textFileNotes,\n ].filter(Boolean);\n const role = roleStore.roleForScope(scope);\n const runInput: Parameters<typeof runAgentBatch>[0] = {\n scope,\n chatId: first.chatId,\n messages,\n adapter,\n sessions,\n workspaces,\n workspaceManager: worktreeManager,\n activeRuns,\n runPolicies,\n archiver,\n ...(role === undefined ? {} : { role }),\n approvals,\n questions,\n densityStore,\n channel: streaming,\n defaultWorkspace,\n replyTo: first.messageId,\n runTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n maxConcurrency: concurrencyStore.get(scope) ?? env.scopeConcurrency,\n retention: retentionStore.get(scope) ?? env.retentionMsgs,\n images: attachments.imagePaths,\n model:\n models.get(scope) ??\n role?.model ??\n activeProfile.preferences.model ??\n (await dshConfig.defaultModel().catch(() => undefined)) ??\n env.model,\n };\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n runInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n await runAgentBatch(runInput);\n } finally {\n pending.unblock(scope);\n }\n },\n (scope) => concurrencyStore.get(scope) ?? env.scopeConcurrency,\n );\n\n const channelInput: Parameters<typeof startChannel>[0] = {\n appId: activeProfile.accounts.appId,\n appSecret: activeProfile.accounts.appSecret,\n tenant: activeProfile.tenant,\n adapter,\n sessions,\n workspaces,\n activeRuns,\n runPolicies,\n concurrencyStore,\n defaultScopeConcurrency: env.scopeConcurrency,\n retentionStore,\n roleStore,\n scopeDirectory,\n archiver,\n defaultRetention: env.retentionMsgs,\n archiveMax: env.archiveMax,\n archiveMaxAgeDays: env.archiveMaxAgeDays,\n approvals,\n questions,\n densityStore,\n models,\n dshConfig,\n defaultRunTimeoutMs: activeProfile.preferences.runTimeoutMs ?? env.runTimeoutMs,\n defaultModel: activeProfile.preferences.model ?? env.model,\n accessManager: new AccessManager(configStore, profileName),\n pending,\n defaultWorkspace,\n accessDefaultDeny: env.accessDefaultDeny,\n eventFreshnessMs: env.eventFreshnessMs,\n allowedUsers: activeProfile.access.allowedUsers,\n allowedChats: activeProfile.access.allowedChats,\n ...(options.createChannel ? { createChannel: options.createChannel } : {}),\n };\n if (activeProfile.preferences.stopGraceMs !== undefined) {\n channelInput.stopGraceMs = activeProfile.preferences.stopGraceMs;\n }\n const bridge = await startChannel(channelInput);\n streaming = adaptLarkChannel(bridge.channel);\n larkChannel = bridge.channel;\n await notifyServer.start();\n process.env.DSH_LARK_NOTIFY_URL = notifyServer.url ?? '';\n const heartbeat = startHeartbeat(\n paths.profilePath(profileName, 'guardian', 'heartbeat.json'),\n process.pid,\n env.heartbeatMs,\n );\n\n const startedAt = new Date().toISOString();\n log.info('cli', 'started', {\n profile: profileName,\n home: paths.root,\n tenant: activeProfile.tenant,\n workspace: defaultWorkspace,\n mode: 'engine',\n });\n\n let stopped = false;\n return {\n profile: profileName,\n home: paths.root,\n status: () => ({\n state: stopped ? 'stopped' : 'running',\n profile: profileName,\n home: paths.root,\n adapterId: adapter.id,\n startedAt,\n workspace: defaultWorkspace,\n notifyUrl: notifyServer.url,\n }),\n stop: async () => {\n if (stopped) return;\n stopped = true;\n heartbeat.stop();\n await notifyServer.stop();\n await bridge.disconnect();\n await adapter.dispose?.();\n await Promise.all([\n sessions.flush(),\n workspaces.flush(),\n roleStore.flush(),\n scopeDirectory.flush(),\n ]);\n },\n };\n}\n\nexport async function runBot(options: StartOptions): Promise<void> {\n const env = loadRuntimeEnv(mergeStartEnv(options));\n const profileName = options.profile ?? 'default';\n const engine = await startBridgeEngine({\n env,\n profileName,\n allowOnboarding: false,\n });\n process.stdout.write(`dsh-lark-bot 已启动,profile=${profileName}\\n`);\n await waitForShutdown();\n await engine.stop();\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction waitForShutdown(): Promise<void> {\n return new Promise((resolve) => {\n const shutdown = (): void => {\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n resolve();\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","export interface ActiveRunHandle {\n runId: string;\n stop(): Promise<void>;\n}\n\n/**\n * Tracks every running agent run, keyed by scope. A scope can hold several\n * concurrent runs (multi-agent collaboration); `interrupt` stops them all,\n * while `interruptRun` targets one run by id.\n */\nexport class ActiveRuns {\n private readonly runs = new Map<string, Map<string, ActiveRunHandle>>();\n\n set(scope: string, handle: ActiveRunHandle): void {\n const scoped = this.runs.get(scope) ?? new Map<string, ActiveRunHandle>();\n scoped.set(handle.runId, handle);\n this.runs.set(scope, scoped);\n }\n\n /** First active run for the scope, if any (backward-compatible accessor). */\n get(scope: string): ActiveRunHandle | undefined {\n return this.runs.get(scope)?.values().next().value;\n }\n\n list(scope: string): ActiveRunHandle[] {\n return [...(this.runs.get(scope)?.values() ?? [])];\n }\n\n count(scope: string): number {\n return this.runs.get(scope)?.size ?? 0;\n }\n\n has(scope: string): boolean {\n return (this.runs.get(scope)?.size ?? 0) > 0;\n }\n\n delete(scope: string, runId: string): boolean {\n const scoped = this.runs.get(scope);\n if (!scoped) return false;\n const removed = scoped.delete(runId);\n if (scoped.size === 0) this.runs.delete(scope);\n return removed;\n }\n\n /** Stop every active run in the scope. Returns how many were interrupted. */\n async interrupt(scope: string): Promise<number> {\n const scoped = this.runs.get(scope);\n if (!scoped || scoped.size === 0) return 0;\n const handles = [...scoped.values()];\n this.runs.delete(scope);\n await Promise.allSettled(handles.map((handle) => handle.stop()));\n return handles.length;\n }\n\n /** Stop one run by id. Returns whether the run existed. */\n async interruptRun(scope: string, runId: string): Promise<boolean> {\n const scoped = this.runs.get(scope);\n const handle = scoped?.get(runId);\n if (!handle) return false;\n scoped?.delete(runId);\n if (scoped?.size === 0) this.runs.delete(scope);\n await handle.stop();\n return true;\n }\n}\n","import { realpathSync } from 'node:fs';\nimport { isIP } from 'node:net';\nimport { isAbsolute, relative, resolve, sep } from 'node:path';\n\nconst REDACTED = '[redacted]';\n\nconst SECRET_PATTERNS: readonly { label: string; pattern: RegExp; keyed: boolean }[] = [\n { label: 'bearer', pattern: /\\bBearer\\s+[A-Za-z0-9._~+/=-]{8,}/g, keyed: false },\n { label: 'deepseek-key', pattern: /\\bsk-[A-Za-z0-9_-]{8,}/g, keyed: false },\n { label: 'api-key', pattern: /\\b(api[_-]?key)\\s*[=:]\\s*[\"']?[A-Za-z0-9._~+/=-]{8,}/gi, keyed: true },\n];\n\n/** Redact common secret shapes (Bearer / sk- / api_key=…) from free text. */\nexport function redactSecrets(text: string): string {\n let result = text;\n for (const { pattern, keyed } of SECRET_PATTERNS) {\n result = keyed\n ? result.replace(pattern, (_match, keyName: string) => `${keyName}=${REDACTED}`)\n : result.replace(pattern, REDACTED);\n }\n return result;\n}\n\nfunction resolveReal(path: string): string {\n try {\n return realpathSync(path);\n } catch {\n return resolve(path);\n }\n}\n\n/**\n * Path containment: `candidate` is inside (or equal to) `root`.\n * Uses realpath when the path exists so symlink escapes are rejected.\n */\nexport function isPathWithin(root: string, candidate: string): boolean {\n const rootReal = resolveReal(root);\n const candidateReal = resolveReal(candidate);\n const rel = relative(rootReal, candidateReal);\n return (\n rel === '' ||\n (!isAbsolute(rel) && rel !== '..' && !rel.startsWith(`..${sep}`))\n );\n}\n\n/**\n * Truncate text to `maxBytes` UTF-8 without splitting a multi-byte sequence\n * or a UTF-16 surrogate pair.\n */\nexport function truncateUtf8Safe(text: string, maxBytes: number): string {\n if (maxBytes <= 0) return '';\n if (Buffer.byteLength(text, 'utf8') <= maxBytes) return text;\n let slice = text.slice(0, maxBytes);\n while (Buffer.byteLength(slice, 'utf8') > maxBytes && slice.length > 0) {\n slice = slice.slice(0, -1);\n }\n const code = slice.charCodeAt(slice.length - 1);\n if (code >= 0xd800 && code <= 0xdbff) {\n slice = slice.slice(0, -1);\n }\n return slice;\n}\n\n/** Reject stale events (e.g. replayed/duplicated IM messages). */\nexport function isEventFresh(\n timestampMs: number | undefined,\n windowMs: number,\n now: number = Date.now(),\n): boolean {\n if (timestampMs === undefined) return true;\n return now - timestampMs <= windowMs;\n}\n\n/** Interactive tools that cannot be answered back through IM; default-deny. */\nexport const DEFAULT_DENIED_INTERACTIVE_TOOLS: readonly string[] = [\n 'ask_user_question',\n 'terminal',\n 'browser',\n 'vim',\n 'code',\n];\n\nexport function isDeniedTool(name: string): boolean {\n const normalized = name.trim().toLowerCase();\n return DEFAULT_DENIED_INTERACTIVE_TOOLS.includes(normalized);\n}\n\nfunction ipv4IsPrivate(parts: number[]): boolean {\n const [a, b] = parts;\n if (a === 0 || a === 10 || a === 127) return true;\n if (a === 169 && b === 254) return true;\n if (a === 172 && b !== undefined && b >= 16 && b <= 31) return true;\n if (a === 192 && b === 168) return true;\n if (a === 100 && b !== undefined && b >= 64 && b <= 127) return true;\n return false;\n}\n\nfunction ipv6IsPrivate(host: string): boolean {\n const normalized = host.toLowerCase();\n if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1') return true;\n if (normalized === '::' || normalized.startsWith('0:')) return true;\n if (normalized.startsWith('fe80:')) return true;\n if (normalized.startsWith('fc') || normalized.startsWith('fd')) return true;\n return false;\n}\n\n/**\n * SSRF guard: only http(s) URLs whose hostname is a public address are safe.\n * Loopback, link-local, private, CGNAT and IPv6 ULA ranges are rejected.\n */\nexport function isSafeHttpUrl(url: string): boolean {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return false;\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') return false;\n let host = parsed.hostname.toLowerCase();\n if (host.startsWith('[') && host.endsWith(']')) {\n host = host.slice(1, -1);\n }\n if (host === 'localhost' || host.endsWith('.localhost')) return false;\n const ipVersion = isIP(host);\n if (ipVersion === 4) {\n return !ipv4IsPrivate(host.split('.').map((part) => Number(part)));\n }\n if (ipVersion === 6) {\n return !ipv6IsPrivate(host);\n }\n // Hostnames resolve later; the URL-level guard is the transport boundary.\n return true;\n}\n","import type { Writable } from 'node:stream';\nimport { redactSecrets } from '../config/security.js';\n\ntype LogLevel = 'info' | 'warn' | 'error';\n\nexport interface LogFields {\n [key: string]: unknown;\n}\n\nconst REDACTED = '[redacted]';\nconst SENSITIVE_KEY = /(secret|token|password|api[_-]?key)/i;\n\nfunction redactValue(value: unknown, key: string, depth: number): unknown {\n if (SENSITIVE_KEY.test(key)) return REDACTED;\n if (typeof value === 'string') return redactSecrets(value);\n if (depth === 0) return value;\n if (Array.isArray(value)) {\n return value.map((item, index) => redactValue(item, `${key}.${index}`, depth - 1));\n }\n if (value && typeof value === 'object') {\n const out: Record<string, unknown> = {};\n for (const [childKey, childValue] of Object.entries(value)) {\n out[childKey] = redactValue(childValue, childKey, depth - 1);\n }\n return out;\n }\n return value;\n}\n\nexport function redactFields(fields: LogFields, depth = 4): LogFields {\n return redactValue(fields, '', depth) as LogFields;\n}\n\nfunction serializeMessage(\n level: LogLevel,\n category: string,\n event: string,\n fields: LogFields,\n): string {\n const entry = {\n time: new Date().toISOString(),\n level,\n category,\n event,\n fields: redactFields(fields),\n };\n return JSON.stringify(entry);\n}\n\nexport interface Logger {\n info(category: string, event: string, fields?: LogFields): void;\n warn(category: string, event: string, fields?: LogFields): void;\n error(category: string, event: string, fields?: LogFields): void;\n fail(category: string, error: unknown, fields?: LogFields): void;\n}\n\nexport function createLogger(output: Writable = process.stderr): Logger {\n const write = (level: LogLevel, category: string, event: string, fields: LogFields): void => {\n output.write(`${serializeMessage(level, category, event, fields)}\\n`);\n };\n\n return {\n info: (category, event, fields = {}) => write('info', category, event, fields),\n warn: (category, event, fields = {}) => write('warn', category, event, fields),\n error: (category, event, fields = {}) => write('error', category, event, fields),\n fail(category, error, fields = {}) {\n const message = error instanceof Error ? error.message : String(error);\n write('error', category, 'fail', { message, ...fields });\n },\n };\n}\n\nexport const log = createLogger();\n","import type { ApprovalOutcome, ApprovalRequest } from '../adapters/types.js';\nimport { log } from '../core/logger.js';\n\ninterface PendingApproval {\n request: ApprovalRequest;\n resolve: (outcome: ApprovalOutcome) => void;\n settled: boolean;\n}\n\n/**\n * Pending approval registry. Cards are rendered by the caller; this store\n * correlates card button clicks with the ACP `request_permission` promise and\n * guarantees every request is settled when a run ends or is disposed.\n */\nexport class ApprovalRegistry {\n private readonly pending = new Map<string, PendingApproval>();\n\n register(scope: string, request: ApprovalRequest): Promise<ApprovalOutcome> {\n const key = `${scope}:${request.id}`;\n const existing = this.pending.get(key);\n if (existing) return Promise.resolve('cancelled');\n return new Promise<ApprovalOutcome>((resolve) => {\n this.pending.set(key, { request, resolve, settled: false });\n });\n }\n\n resolve(scope: string, id: string, outcome: ApprovalOutcome): boolean {\n const key = `${scope}:${id}`;\n const pending = this.pending.get(key);\n if (!pending || pending.settled) return false;\n pending.settled = true;\n this.pending.delete(key);\n pending.resolve(outcome);\n return true;\n }\n\n /** Settle every pending approval for a scope (run end / dispose). */\n settleAll(scope: string, outcome: ApprovalOutcome): number {\n let count = 0;\n for (const [key, pending] of this.pending) {\n if (!key.startsWith(`${scope}:`)) continue;\n if (pending.settled) continue;\n pending.settled = true;\n this.pending.delete(key);\n pending.resolve(outcome);\n count += 1;\n }\n if (count > 0) {\n log.warn('approvals', 'settled-pending', { scope, outcome, count });\n }\n return count;\n }\n\n pendingCount(scope: string): number {\n let count = 0;\n for (const key of this.pending.keys()) {\n if (key.startsWith(`${scope}:`)) count += 1;\n }\n return count;\n }\n}\n","/**\n * Per-scope concurrent-run overrides. `undefined` means the profile /\n * environment default applies. Mirrors `RunPolicyStore` semantics.\n */\nexport class ConcurrencyStore {\n private readonly limits = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.limits.get(scope);\n }\n\n set(scope: string, limit: number): void {\n this.limits.set(scope, limit);\n }\n\n clear(scope: string): boolean {\n return this.limits.delete(scope);\n }\n}\n","import type { CardDensity } from '../card/density.js';\n\n/** Per-scope card density overrides on top of a default. */\nexport class DensityStore {\n private readonly overrides = new Map<string, CardDensity>();\n\n constructor(private readonly defaultDensity: CardDensity = 'standard') {}\n\n get(scope: string): CardDensity {\n return this.overrides.get(scope) ?? this.defaultDensity;\n }\n\n set(scope: string, density: CardDensity): void {\n this.overrides.set(scope, density);\n }\n\n clear(scope: string): boolean {\n return this.overrides.delete(scope);\n }\n}\n","export class ModelStore {\n private readonly overrides = new Map<string, string>();\n\n get(scope: string): string | undefined {\n return this.overrides.get(scope);\n }\n\n set(scope: string, model: string): void {\n this.overrides.set(scope, model);\n }\n\n clear(scope: string): boolean {\n return this.overrides.delete(scope);\n }\n}\n","export type PendingFlush<T> = (scope: string, batch: T[]) => void | Promise<void>;\n\n/**\n * Per-scope debounced message queue with bounded concurrency. A scope may run\n * several flushes in parallel up to `concurrencyFor(scope)`; `block` stops\n * NEW flushes from starting while already-running ones finish, and `unblock`\n * resumes scheduling.\n */\nexport class PendingQueue<T> {\n private readonly pending = new Map<string, T[]>();\n private readonly timers = new Map<string, ReturnType<typeof setTimeout>>();\n private readonly blocked = new Set<string>();\n private readonly flushingCount = new Map<string, number>();\n\n constructor(\n private readonly quietMs: number,\n private readonly onFlush: PendingFlush<T>,\n private readonly concurrencyFor: (scope: string) => number = () => 1,\n ) {}\n\n push(scope: string, item: T): void {\n const batch = this.pending.get(scope) ?? [];\n batch.push(item);\n this.pending.set(scope, batch);\n this.schedule(scope);\n }\n\n block(scope: string): void {\n this.blocked.add(scope);\n this.clearTimer(scope);\n }\n\n unblock(scope: string): void {\n this.blocked.delete(scope);\n this.schedule(scope);\n }\n\n async flushNow(scope: string): Promise<void> {\n this.clearTimer(scope);\n const limit = this.concurrencyFor(scope);\n const active = this.flushingCount.get(scope) ?? 0;\n if (active >= limit) return;\n\n const batch = this.pending.get(scope) ?? [];\n this.pending.delete(scope);\n if (batch.length === 0) return;\n\n this.flushingCount.set(scope, active + 1);\n try {\n await this.onFlush(scope, batch);\n } finally {\n const next = (this.flushingCount.get(scope) ?? 1) - 1;\n if (next <= 0) this.flushingCount.delete(scope);\n else this.flushingCount.set(scope, next);\n this.schedule(scope);\n }\n }\n\n hasPending(scope: string): boolean {\n return (this.pending.get(scope)?.length ?? 0) > 0;\n }\n\n isBlocked(scope: string): boolean {\n return this.blocked.has(scope);\n }\n\n isFlushing(scope: string): boolean {\n return (this.flushingCount.get(scope) ?? 0) > 0;\n }\n\n activeFlushes(scope: string): number {\n return this.flushingCount.get(scope) ?? 0;\n }\n\n private schedule(scope: string): void {\n if (this.blocked.has(scope)) return;\n if ((this.flushingCount.get(scope) ?? 0) >= this.concurrencyFor(scope)) return;\n if (this.timers.has(scope)) return;\n if (!this.hasPending(scope)) return;\n\n this.timers.set(\n scope,\n setTimeout(() => {\n this.timers.delete(scope);\n void this.flushNow(scope);\n }, this.quietMs),\n );\n }\n\n private clearTimer(scope: string): void {\n const timer = this.timers.get(scope);\n if (timer === undefined) return;\n clearTimeout(timer);\n this.timers.delete(scope);\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport type { QuestionCardInput } from '../card/question-card.js';\n\ninterface PendingQuestion {\n input: QuestionCardInput;\n resolve: (answer: string | string[] | undefined) => void;\n settled: boolean;\n}\n\n/**\n * Pending question-card registry. `/ask` registers a card; the card submit\n * action resolves it, and the answer is recorded back into the session.\n */\nexport class QuestionRegistry {\n private readonly pending = new Map<string, PendingQuestion>();\n\n register(\n scope: string,\n input: Omit<QuestionCardInput, 'id'>,\n ): { id: string; promise: Promise<string | string[] | undefined> } {\n const id = `question-${randomUUID().replaceAll('-', '')}`;\n const full: QuestionCardInput = { ...input, id };\n const promise = new Promise<string | string[] | undefined>((resolve) => {\n this.pending.set(`${scope}:${id}`, { input: full, resolve, settled: false });\n });\n return { id, promise };\n }\n\n resolve(scope: string, id: string, answer: string | string[] | undefined): boolean {\n const pending = this.pending.get(`${scope}:${id}`);\n if (!pending || pending.settled) return false;\n pending.settled = true;\n this.pending.delete(`${scope}:${id}`);\n pending.resolve(answer);\n return true;\n }\n\n settleAll(scope: string): number {\n let count = 0;\n for (const [key, pending] of this.pending) {\n if (!key.startsWith(`${scope}:`)) continue;\n if (pending.settled) continue;\n pending.settled = true;\n this.pending.delete(key);\n pending.resolve(undefined);\n count += 1;\n }\n return count;\n }\n\n get(scope: string, id: string): QuestionCardInput | undefined {\n return this.pending.get(`${scope}:${id}`)?.input;\n }\n}\n","/**\n * Per-scope live-message retention overrides. `undefined` means the profile /\n * environment default applies. Mirrors `RunPolicyStore` semantics.\n */\nexport class RetentionStore {\n private readonly retentions = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.retentions.get(scope);\n }\n\n set(scope: string, retention: number): void {\n this.retentions.set(scope, retention);\n }\n\n clear(scope: string): boolean {\n return this.retentions.delete(scope);\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface RoleDefinition {\n id: string;\n name: string;\n /** System-style persona/instructions applied to every run of this role. */\n persona: string;\n /** Optional model override for this role (below the per-scope /model use). */\n model?: string;\n /** Optional comma-separated tool guidance shown to the agent. */\n tools?: string;\n /** Optional role rules text injected like an AGENTS.md. */\n agentsMd?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface RoleStoreInput {\n id: string;\n name: string;\n persona: string;\n model?: string;\n tools?: string;\n agentsMd?: string;\n}\n\ninterface RoleData {\n roles: Record<string, RoleDefinition>;\n scopeRoles: Record<string, string>;\n}\n\n/**\n * Persisted role registry: named agent roles (persona / model / tools guidance /\n * role rules) plus per-scope role bindings. Stored per profile at\n * `<profile>/roles.json` (0600). Memory of bindings survives restarts.\n */\nexport class RoleStore {\n private data: RoleData = { roles: {}, scopeRoles: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<RoleData>;\n this.data = {\n roles: parsed.roles ?? {},\n scopeRoles: parsed.scopeRoles ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = { roles: {}, scopeRoles: {} };\n }\n }\n\n list(): RoleDefinition[] {\n return Object.values(this.data.roles).sort((a, b) => a.id.localeCompare(b.id));\n }\n\n get(id: string): RoleDefinition | undefined {\n return this.data.roles[id];\n }\n\n upsert(input: RoleStoreInput): RoleDefinition {\n const existing = this.data.roles[input.id];\n const now = new Date().toISOString();\n const role: RoleDefinition = {\n id: input.id,\n name: input.name,\n persona: input.persona,\n ...(input.model === undefined ? {} : { model: input.model }),\n ...(input.tools === undefined ? {} : { tools: input.tools }),\n ...(input.agentsMd === undefined ? {} : { agentsMd: input.agentsMd }),\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n };\n this.data.roles[input.id] = role;\n this.schedulePersist();\n return role;\n }\n\n remove(id: string): boolean {\n if (!(id in this.data.roles)) return false;\n delete this.data.roles[id];\n for (const [scope, roleId] of Object.entries(this.data.scopeRoles)) {\n if (roleId === id) delete this.data.scopeRoles[scope];\n }\n this.schedulePersist();\n return true;\n }\n\n roleForScope(scope: string): RoleDefinition | undefined {\n const roleId = this.data.scopeRoles[scope];\n return roleId === undefined ? undefined : this.data.roles[roleId];\n }\n\n setScopeRole(scope: string, roleId: string): boolean {\n if (!(roleId in this.data.roles)) return false;\n this.data.scopeRoles[scope] = roleId;\n this.schedulePersist();\n return true;\n }\n\n clearScopeRole(scope: string): boolean {\n if (!(scope in this.data.scopeRoles)) return false;\n delete this.data.scopeRoles[scope];\n this.schedulePersist();\n return true;\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = {\n roles: { ...this.data.roles },\n scopeRoles: { ...this.data.scopeRoles },\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('role-store', error, { step: 'persist' });\n });\n }\n}\n","export class RunPolicyStore {\n private readonly timeouts = new Map<string, number>();\n\n get(scope: string): number | undefined {\n return this.timeouts.get(scope);\n }\n\n set(scope: string, runTimeoutMs: number): void {\n this.timeouts.set(scope, runTimeoutMs);\n }\n\n clear(scope: string): boolean {\n return this.timeouts.delete(scope);\n }\n}\n","import { createLarkChannel, type LarkChannel, type NormalizedMessage } from '@larksuite/channel';\nimport type { AgentAdapter } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { ApprovalRegistry } from '../bot/approvals.js';\nimport type { DensityStore } from '../bot/density-store.js';\nimport type { ConcurrencyStore } from '../bot/concurrency-store.js';\nimport type { ModelStore } from '../bot/model-store.js';\nimport type { PendingQueue } from '../bot/pending-queue.js';\nimport type { QuestionRegistry } from '../bot/questions.js';\nimport type { RetentionStore } from '../bot/retention-store.js';\nimport type { RoleStore } from '../bot/role-store.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport { tryHandleCommand, type CommandChannel } from '../commands/index.js';\nimport { extractQuestionAnswer } from '../card/question-card.js';\nimport type { AccessManager } from '../config/access-manager.js';\nimport type { DshProviderManager } from '../config/dsh-config.js';\nimport { isEventFresh } from '../config/security.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { SessionArchive } from '../session/archive.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport { adaptLarkChannel } from './lark-channel.js';\nimport type { ScopeDirectory } from './scope-directory.js';\n\nexport interface StartChannelDeps {\n appId: string;\n appSecret: string;\n tenant: 'feishu' | 'lark';\n adapter: AgentAdapter;\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n concurrencyStore: ConcurrencyStore;\n defaultScopeConcurrency: number;\n retentionStore: RetentionStore;\n roleStore: RoleStore;\n scopeDirectory?: ScopeDirectory;\n archiver: SessionArchive;\n defaultRetention: number;\n archiveMax: number;\n archiveMaxAgeDays: number;\n defaultRunTimeoutMs: number;\n accessManager: AccessManager;\n pending: PendingQueue<NormalizedMessage>;\n approvals?: ApprovalRegistry;\n questions?: QuestionRegistry;\n densityStore?: DensityStore;\n models: ModelStore;\n dshConfig: DshProviderManager;\n defaultWorkspace: string;\n defaultModel: string;\n allowedUsers?: string[];\n allowedChats?: string[];\n accessDefaultDeny?: boolean;\n eventFreshnessMs?: number;\n stopGraceMs?: number;\n createChannel?: typeof createLarkChannel;\n}\n\nexport interface BridgeChannel {\n channel: LarkChannel;\n disconnect(): Promise<void>;\n}\n\nexport async function startChannel(deps: StartChannelDeps): Promise<BridgeChannel> {\n const channel = (deps.createChannel ?? createLarkChannel)({\n appId: deps.appId,\n appSecret: deps.appSecret,\n domain:\n deps.tenant === 'lark' ? 'https://open.larksuite.com' : 'https://open.feishu.cn',\n source: 'dsh-lark-bot',\n policy: {\n dmMode: deps.allowedUsers?.length\n ? 'allowlist'\n : deps.accessDefaultDeny === true\n ? 'disabled'\n : 'open',\n requireMention: true,\n respondToMentionAll: false,\n ...(deps.allowedUsers ? { dmAllowlist: deps.allowedUsers } : {}),\n ...(deps.allowedChats ? { groupAllowlist: deps.allowedChats } : {}),\n },\n safety: {\n chatQueue: { enabled: false },\n },\n outbound: {\n streamThrottleMs: 400,\n },\n includeRawEvent: true,\n resolveChatMode: true,\n handshakeTimeoutMs: 8_000,\n httpTimeoutMs: 30_000,\n respectProxyEnv: true,\n });\n\n const streaming = adaptLarkChannel(channel);\n const commandChannel: CommandChannel = streaming;\n\n channel.on({\n message: async (msg) => {\n const scope = scopeForMessage(msg);\n deps.scopeDirectory?.register(scope, msg.chatId, msg.threadId);\n if (\n deps.eventFreshnessMs !== undefined &&\n deps.eventFreshnessMs > 0 &&\n !isEventFresh(msg.createTime, deps.eventFreshnessMs)\n ) {\n log.warn('channel', 'stale-message-dropped', {\n scope,\n ageMs: Date.now() - msg.createTime,\n });\n return;\n }\n const context = {\n scope,\n chatId: msg.chatId,\n messageId: msg.messageId,\n threadId: msg.threadId,\n chatMode: msg.chatMode ?? msg.chatType,\n sessions: deps.sessions,\n workspaces: deps.workspaces,\n activeRuns: deps.activeRuns,\n runPolicies: deps.runPolicies,\n concurrencyStore: deps.concurrencyStore,\n defaultScopeConcurrency: deps.defaultScopeConcurrency,\n retentionStore: deps.retentionStore,\n roleStore: deps.roleStore,\n scopeDirectory: deps.scopeDirectory ?? EMPTY_SCOPE_DIRECTORY,\n archiver: deps.archiver,\n defaultRetention: deps.defaultRetention,\n archiveMax: deps.archiveMax,\n archiveMaxAgeDays: deps.archiveMaxAgeDays,\n defaultRunTimeoutMs: deps.defaultRunTimeoutMs,\n accessManager: deps.accessManager,\n approvals: deps.approvals,\n questions: deps.questions,\n densityStore: deps.densityStore,\n models: deps.models,\n dshConfig: deps.dshConfig,\n channel: commandChannel,\n defaultWorkspace: deps.defaultWorkspace,\n defaultModel: deps.defaultModel,\n senderId: msg.senderId,\n };\n\n const handled = await tryHandleCommand(msg.content, context).catch((error: unknown) => {\n log.fail('channel-command', error, { scope });\n return false;\n });\n if (!handled) deps.pending.push(scope, msg);\n },\n cardAction: async (event) => {\n const value =\n event.action.value && typeof event.action.value === 'object'\n ? (event.action.value as Record<string, unknown>)\n : undefined;\n const scope = event.raw\n ? await resolveCardScope(event.chatId, event.raw as { message?: { thread_id?: string } })\n : event.chatId;\n if (value?.cmd === 'stop') {\n await deps.activeRuns.interrupt(scope);\n return;\n }\n if (value?.cmd === 'approve' && typeof value.id === 'string' && deps.approvals) {\n const outcome = value.outcome === 'allow' ? 'allowed-once' : 'rejected';\n deps.approvals.resolve(scope, value.id, outcome);\n return;\n }\n if (value?.cmd === 'question-submit' && typeof value.id === 'string' && deps.questions) {\n const question = deps.questions.get(scope, value.id);\n const form = event.action.formValue;\n if (question) {\n const answer = extractQuestionAnswer(\n question.kind,\n form?.answer,\n question.options,\n );\n deps.questions.resolve(scope, value.id, answer);\n }\n }\n },\n reconnecting: () => {\n log.warn('channel', 'reconnecting', {});\n },\n reconnected: () => {\n log.info('channel', 'reconnected', {});\n },\n error: (error) => {\n log.fail('channel', error);\n },\n });\n\n await channel.connect();\n return {\n channel,\n disconnect: () => channel.disconnect(),\n };\n}\n\nconst EMPTY_SCOPE_DIRECTORY: ScopeDirectory = {\n register: () => {},\n resolve: () => undefined,\n resolveChat: () => undefined,\n knownScopes: () => [],\n flush: async () => {},\n} as unknown as ScopeDirectory;\n\nfunction scopeForMessage(msg: NormalizedMessage): string {\n if (msg.chatMode === 'topic' && msg.threadId) return `${msg.chatId}:${msg.threadId}`;\n return msg.chatId;\n}\n\nasync function resolveCardScope(\n chatId: string,\n raw: { message?: { thread_id?: string } },\n): Promise<string> {\n return raw.message?.thread_id ? `${chatId}:${raw.message.thread_id}` : chatId;\n}\n","import { resolve } from 'node:path';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport type { ApprovalRegistry } from '../bot/approvals.js';\nimport type { DensityStore } from '../bot/density-store.js';\nimport type { ConcurrencyStore } from '../bot/concurrency-store.js';\nimport type { QuestionRegistry } from '../bot/questions.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport type { RetentionStore } from '../bot/retention-store.js';\nimport type { RoleStore } from '../bot/role-store.js';\nimport type { AccessManager } from '../config/access-manager.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { SessionArchive } from '../session/archive.js';\nimport type { ScopeDirectory } from '../bridge/scope-directory.js';\nimport type { SendOptions } from '../bridge/send-options.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport { renderWorkspaceCard } from '../card/workspace-card.js';\nimport { parseCardDensity, type CardDensity } from '../card/density.js';\nimport { questionHandlerFor } from '../bridge/run-flow.js';\nimport type { ModelStore } from '../bot/model-store.js';\nimport type { DshProviderManager } from '../config/dsh-config.js';\nimport {\n handleKey,\n handleModel,\n handleProvider,\n handleProviders,\n} from './models.js';\nimport { handleArchive, handleRetention } from './archive.js';\nimport { handleRole } from './roles.js';\nimport { handleNotify } from './notify.js';\n\nexport interface CommandChannel {\n sendMarkdown(\n chatId: string,\n markdown: string,\n options?: SendOptions,\n ): Promise<void>;\n sendCard?(chatId: string, card: object): Promise<void>;\n}\n\nexport interface CommandContext {\n scope: string;\n chatId: string;\n messageId: string;\n threadId: string | undefined;\n chatMode: 'p2p' | 'group' | 'topic';\n sessions: SessionStore;\n workspaces: WorkspaceStore;\n activeRuns: ActiveRuns;\n runPolicies: RunPolicyStore;\n concurrencyStore: ConcurrencyStore;\n defaultScopeConcurrency: number;\n retentionStore: RetentionStore;\n roleStore: RoleStore;\n scopeDirectory: ScopeDirectory;\n archiver: SessionArchive;\n defaultRetention: number;\n archiveMax: number;\n archiveMaxAgeDays: number;\n approvals: ApprovalRegistry | undefined;\n questions: QuestionRegistry | undefined;\n densityStore: DensityStore | undefined;\n models: ModelStore;\n dshConfig: DshProviderManager;\n defaultRunTimeoutMs: number;\n defaultModel: string;\n senderId: string | undefined;\n accessManager: AccessManager;\n channel: CommandChannel;\n defaultWorkspace: string;\n}\n\ntype Handler = (args: string, ctx: CommandContext) => Promise<void>;\n\nconst HELP = [\n '**dsh-lark-bot 命令**',\n '',\n '- `/new` `/reset` — 开始新会话',\n '- `/cd <path>` — 切换工作目录并重置会话',\n '- `/ws list|save <name>|use <name>|remove <name>` — 管理工作空间',\n '- `/status` — 查看当前状态',\n '- `/resume` — 查看当前会话最近上下文',\n '- `/stop` — 终止当前任务',\n '- `/timeout [N|off|default]` — 查看或设置当前会话运行超时',\n '- `/concurrency [N|default]` — 查看或设置当前 scope 的并行任务数',\n '- `/role list|show <id>|set <id>|clear` — 查看 / 绑定角色',\n '- `/role save <id> <name> [--persona 文案] [--model <id>] [--tools <csv>] [--rules 文案]` — 创建/更新角色(管理员)',\n '- `/role remove <id>` — 删除角色(管理员)',\n '- `/notify <scope|chatId> <text>` — 跨会话发送通知(管理员)',\n '- `/notify list` — 查看已注册 scope',\n '- `/retention [N|default]` — 查看或设置当前会话保留消息条数(超出自动归档)',\n '- `/archive [note]`、`/archive list [N]`、`/archive clean` — 归档 / 查看 / 清理会话',\n '- `/density [compact|standard|detailed]` — 查看或设置卡片密度',\n '- `/model` — 查看当前模型与 dsh 可用模型',\n '- `/model use <id>` — 热切换当前会话模型(下一轮生效)',\n '- `/model default <id>` — 写入 dsh 默认模型 agent-default-model(管理员)',\n '- `/model add|remove <provider> <modelId>` — 管理 provider 的模型(管理员)',\n '- `/providers` — 查看 dsh providers / 模型 / 凭据状态',\n '- `/provider add|update|remove <id>` — 管理 provider(管理员;deepseek-official 与自定义 pi-ai)',\n '- `/key set|remove|list <引用名>` — 管理 dsh 凭据(set/remove 需管理员)',\n '- `/ask <问题>` — 发送结构化问答卡(回答将记入会话)',\n '- `/invite user|admin|group <id>` — 管理访问白名单',\n '- `/help` — 显示本帮助',\n].join('\\n');\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nasync function handleNew(_args: string, ctx: CommandContext): Promise<void> {\n const interrupted = await ctx.activeRuns.interrupt(ctx.scope);\n ctx.sessions.clear(ctx.scope);\n await reply(\n ctx,\n interrupted > 0 ? `已中断 ${String(interrupted)} 个任务并开始新会话。` : '已开始新会话。',\n );\n}\n\nasync function handleCd(args: string, ctx: CommandContext): Promise<void> {\n const path = args.trim();\n if (!path) {\n await reply(ctx, '用法:`/cd <path>`');\n return;\n }\n const cwd = resolve(path);\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换工作目录:\\`${cwd}\\`,会话已重置。`);\n}\n\nasync function handleWs(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n const name = rest.join(' ').trim();\n\n if (!sub || sub === 'list') {\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const named = ctx.workspaces.listNamed();\n const index = ctx.workspaces.listIndex();\n if (ctx.channel.sendCard) {\n await ctx.channel.sendCard(ctx.chatId, renderWorkspaceCard({ current, index }));\n return;\n }\n const lines = Object.entries(named).map(\n ([key, value]) => `- **${key}** → \\`${value}\\`${value === current ? ' ← 当前' : ''}`,\n );\n await reply(\n ctx,\n [\n `当前 cwd:\\`${current}\\``,\n '',\n ...(lines.length > 0 ? lines : ['暂无命名工作空间。']),\n ].join('\\n'),\n );\n return;\n }\n\n if (sub === 'save') {\n if (!name) {\n await reply(ctx, '用法:`/ws save <name>`');\n return;\n }\n const current = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n ctx.workspaces.saveNamed(name, current);\n await reply(ctx, `已保存工作空间:**${name}** → \\`${current}\\``);\n return;\n }\n\n if (sub === 'use') {\n if (!name) {\n await reply(ctx, '用法:`/ws use <name>`');\n return;\n }\n const cwd = ctx.workspaces.getNamed(name);\n if (!cwd) {\n await reply(ctx, `未找到工作空间:**${name}**`);\n return;\n }\n await ctx.activeRuns.interrupt(ctx.scope);\n ctx.workspaces.setCwd(ctx.scope, cwd);\n ctx.workspaces.touchNamed(name);\n ctx.sessions.clear(ctx.scope);\n await reply(ctx, `已切换到工作空间:**${name}** → \\`${cwd}\\``);\n return;\n }\n\n if (sub === 'remove') {\n if (!name) {\n await reply(ctx, '用法:`/ws remove <name>`');\n return;\n }\n const removed = ctx.workspaces.removeNamed(name);\n await reply(ctx, removed ? `已删除工作空间:**${name}**` : `未找到工作空间:**${name}**`);\n return;\n }\n\n await reply(ctx, '未知 `/ws` 子命令,请使用 list / save / use / remove。');\n}\n\nasync function handleStatus(_args: string, ctx: CommandContext): Promise<void> {\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const session = ctx.sessions.getRaw(ctx.scope)?.sessionId ?? '(无)';\n const active = ctx.activeRuns.list(ctx.scope);\n const role = ctx.roleStore.roleForScope(ctx.scope);\n const scopeLabel =\n ctx.chatMode === 'topic' ? `${ctx.scope}(话题独立 session)` : ctx.scope;\n const runLines = active.map((run) => ` - \\`${run.runId}\\``);\n const roleLine = role ? `🎭 **role**: \\`${role.id}\\` (${role.name})` : undefined;\n\n await reply(\n ctx,\n [\n `🧭 **scope**: \\`${scopeLabel}\\``,\n `📁 **cwd**: \\`${cwd}\\``,\n `🔗 **session**: \\`${session}\\``,\n ...(roleLine ? [roleLine] : []),\n `🏃 **active runs**: ${String(active.length)}`,\n ...runLines,\n ].join('\\n'),\n );\n}\n\nasync function handleResume(_args: string, ctx: CommandContext): Promise<void> {\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const history = ctx.sessions.historyFor(ctx.scope, cwd);\n if (history.length === 0) {\n await reply(ctx, '当前会话没有历史上下文。');\n return;\n }\n\n const recent = history.slice(-6).map((message) => {\n const speaker = message.role === 'user' ? '👤' : '🤖';\n return `${speaker} ${message.content.slice(0, 300)}`;\n });\n\n await reply(ctx, [`当前 scope:\\`${ctx.scope}\\``, '', ...recent].join('\\n'));\n}\n\nasync function handleStop(_args: string, ctx: CommandContext): Promise<void> {\n const stopped = await ctx.activeRuns.interrupt(ctx.scope);\n await reply(\n ctx,\n stopped > 0 ? `已请求终止当前 scope 的全部 ${String(stopped)} 个任务。` : '当前没有运行中的任务。',\n );\n}\n\nasync function handleTimeout(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effectiveMs = ctx.runPolicies.get(ctx.scope) ?? ctx.defaultRunTimeoutMs;\n\n if (!input) {\n const minutes = effectiveMs > 0 ? Math.round(effectiveMs / 60_000) : 0;\n await reply(\n ctx,\n minutes > 0\n ? `当前会话运行超时:${minutes} 分钟。可用 \\`/timeout <N|off|default>\\` 调整。`\n : '当前会话运行超时:关闭。',\n );\n return;\n }\n\n if (input === 'off') {\n ctx.runPolicies.set(ctx.scope, 0);\n await reply(ctx, '已关闭当前会话运行超时。');\n return;\n }\n\n if (input === 'default') {\n ctx.runPolicies.clear(ctx.scope);\n await reply(ctx, '已恢复默认运行超时。');\n return;\n }\n\n const minutes = Number(input);\n if (!Number.isInteger(minutes) || minutes <= 0) {\n await reply(ctx, '用法:`/timeout <N|off|default>`,N 为大于 0 的分钟数。');\n return;\n }\n\n ctx.runPolicies.set(ctx.scope, minutes * 60_000);\n await reply(ctx, `已设置当前会话运行超时:${minutes} 分钟。`);\n}\n\nasync function handleConcurrency(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effective = ctx.concurrencyStore.get(ctx.scope) ?? ctx.defaultScopeConcurrency;\n\n if (!input) {\n await reply(\n ctx,\n `当前 scope 的并行任务数:**${String(effective)}**。可用 \\`/concurrency <N|default>\\` 调整(N ≥ 1)。`,\n );\n return;\n }\n\n if (input === 'default') {\n ctx.concurrencyStore.clear(ctx.scope);\n await reply(ctx, `已恢复默认并行任务数(${String(ctx.defaultScopeConcurrency)})。`);\n return;\n }\n\n const n = Number(input);\n if (!Number.isInteger(n) || n < 1) {\n await reply(ctx, '用法:`/concurrency <N|default>`,N 为大于等于 1 的整数。');\n return;\n }\n\n ctx.concurrencyStore.set(ctx.scope, n);\n await reply(ctx, `已设置当前 scope 的并行任务数:**${String(n)}**。`);\n}\n\nasync function handleDensity(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim().toLowerCase();\n if (!input) {\n const current = ctx.densityStore?.get(ctx.scope) ?? 'standard';\n await reply(\n ctx,\n `当前卡片密度:**${current}**。可用 \\`/density compact|standard|detailed\\` 调整。`,\n );\n return;\n }\n if (input === 'default') {\n ctx.densityStore?.clear(ctx.scope);\n await reply(ctx, '已恢复默认卡片密度。');\n return;\n }\n const density: CardDensity | undefined = parseCardDensity(input);\n if (!density) {\n await reply(ctx, '用法:`/density [compact|standard|detailed|default]`');\n return;\n }\n ctx.densityStore?.set(ctx.scope, density);\n await reply(ctx, `已设置当前会话卡片密度:**${density}**。`);\n}\n\nasync function handleAsk(args: string, ctx: CommandContext): Promise<void> {\n const question = args.trim();\n if (!question) {\n await reply(ctx, '用法:`/ask <问题>`');\n return;\n }\n if (!ctx.questions) {\n await reply(ctx, '问答卡未启用(请确认 questions 已接线)。');\n return;\n }\n const answer = await questionHandlerFor({\n questions: ctx.questions,\n channel: ctx.channel,\n chatId: ctx.chatId,\n scope: ctx.scope,\n })({\n kind: 'text',\n question,\n id: '',\n });\n if (answer !== undefined) {\n const text = Array.isArray(answer) ? answer.join('、') : answer;\n ctx.sessions.recordExchange(ctx.scope, ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace, [text], undefined);\n await reply(ctx, `已记录你的回答,并写入会话上下文。`);\n } else {\n await reply(ctx, '未收到回答(卡片可能已超时或被忽略)。');\n }\n}\n\nasync function handleInvite(args: string, ctx: CommandContext): Promise<void> {\n const [kind, ...rest] = args.trim().split(/\\s+/);\n const id = rest.join(' ').trim();\n\n if (kind === 'list') {\n const snapshot = ctx.accessManager.snapshot();\n await reply(\n ctx,\n [\n '**访问白名单**',\n `users: ${snapshot.allowedUsers.join(', ') || '(空)'}`,\n `chats: ${snapshot.allowedChats.join(', ') || '(空)'}`,\n `admins: ${snapshot.admins.join(', ') || '(空)'}`,\n ].join('\\n'),\n );\n return;\n }\n\n if (!kind || !id) {\n await reply(\n ctx,\n '用法:`/invite user|admin|group <id>`、`/invite list`、`/invite remove user|group <id>`',\n );\n return;\n }\n\n if (kind === 'user') {\n await ctx.accessManager.addUser(id);\n await reply(ctx, `已允许用户:\\`${id}\\``);\n return;\n }\n\n if (kind === 'admin') {\n await ctx.accessManager.addAdmin(id);\n await reply(ctx, `已设为管理员:\\`${id}\\``);\n return;\n }\n\n if (kind === 'group') {\n await ctx.accessManager.addChat(id);\n await reply(ctx, `已允许群聊:\\`${id}\\``);\n return;\n }\n\n if (kind === 'remove') {\n const [sub, target] = rest;\n if (sub === 'user' && target) {\n await ctx.accessManager.removeUser(target);\n await reply(ctx, `已移除用户:\\`${target}\\``);\n return;\n }\n if (sub === 'group' && target) {\n await ctx.accessManager.removeChat(target);\n await reply(ctx, `已移除群聊:\\`${target}\\``);\n return;\n }\n await reply(ctx, '用法:`/invite remove user <id>` 或 `/invite remove group <chatId>`');\n return;\n }\n\n await reply(ctx, '未知 `/invite` 类型,请使用 user / admin / group / list / remove。');\n}\n\nasync function handleHelp(_args: string, ctx: CommandContext): Promise<void> {\n await reply(ctx, HELP);\n}\n\nconst handlers: Record<string, Handler> = {\n '/new': handleNew,\n '/reset': handleNew,\n '/cd': handleCd,\n '/ws': handleWs,\n '/status': handleStatus,\n '/resume': handleResume,\n '/stop': handleStop,\n '/timeout': handleTimeout,\n '/concurrency': handleConcurrency,\n '/role': handleRole,\n '/notify': handleNotify,\n '/retention': handleRetention,\n '/archive': handleArchive,\n '/density': handleDensity,\n '/model': handleModel,\n '/providers': handleProviders,\n '/provider': handleProvider,\n '/key': handleKey,\n '/ask': handleAsk,\n '/invite': handleInvite,\n '/help': handleHelp,\n};\n\nexport async function tryHandleCommand(text: string, ctx: CommandContext): Promise<boolean> {\n const trimmed = text.trim();\n if (!trimmed.startsWith('/')) return false;\n const [command, ...rest] = trimmed.split(/\\s+/);\n const handler = handlers[command ?? ''];\n if (!handler) return false;\n await handler(rest.join(' '), ctx);\n return true;\n}\n","export function renderWorkspaceCard(input: {\n current: string;\n index: Array<{ name: string; cwd: string; lastUsed: number | undefined }>;\n}): object {\n const entries = input.index;\n const markdown = [\n `**当前工作目录**\\n\\`${input.current}\\``,\n '',\n ...(entries.length > 0\n ? entries.map(({ name, cwd, lastUsed }) =>\n `- **${name}** → \\`${cwd}\\`${lastUsed ? ` · ${new Date(lastUsed).toLocaleString()}` : ''}`,\n )\n : ['暂无命名工作空间。']),\n ].join('\\n');\n\n return {\n schema: '2.0',\n config: {\n summary: { content: '工作空间导航' },\n },\n body: {\n elements: [\n {\n tag: 'markdown',\n content: markdown,\n },\n ],\n },\n };\n}\n","export type CardDensity = 'compact' | 'standard' | 'detailed';\n\nexport const CARD_DENSITIES: readonly CardDensity[] = ['compact', 'standard', 'detailed'];\n\nexport function parseCardDensity(value: string | undefined): CardDensity | undefined {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) return undefined;\n if ((CARD_DENSITIES as readonly string[]).includes(normalized)) {\n return normalized as CardDensity;\n }\n return undefined;\n}\n","import { randomUUID } from 'node:crypto';\nimport type { AgentAdapter, AgentEvent } from '../adapters/types.js';\nimport type { ActiveRuns } from '../bot/active-runs.js';\nimport { ApprovalRegistry } from '../bot/approvals.js';\nimport type { DensityStore } from '../bot/density-store.js';\nimport type { RunPolicyStore } from '../bot/run-policy.js';\nimport type { QuestionRegistry } from '../bot/questions.js';\nimport {\n finalizeIfRunning,\n initialState,\n markIdleTimeout,\n markInterrupted,\n reduce,\n type RunState,\n} from '../card/run-state.js';\nimport { renderCard } from '../card/run-renderer.js';\nimport { renderApprovalCard } from '../card/approval-card.js';\nimport { renderQuestionCard } from '../card/question-card.js';\nimport { log } from '../core/logger.js';\nimport type { SessionStore } from '../session/store.js';\nimport type { SessionArchive } from '../session/archive.js';\nimport type { RoleDefinition } from '../bot/role-store.js';\nimport type { WorkspaceStore } from '../workspace/store.js';\nimport type { GitWorktreeManager } from '../workspace/git-worktree.js';\nimport type { StreamingChannel } from './types.js';\nimport type { ApprovalOutcome, ApprovalRequest } from '../adapters/types.js';\nimport type { QuestionCardInput } from '../card/question-card.js';\n\nexport interface RunFlowInput {\n scope: string;\n chatId: string;\n messages: string[];\n adapter: AgentAdapter;\n sessions: SessionStore;\n archiver?: SessionArchive;\n role?: RoleDefinition;\n /** Live messages kept before overflow is archived; defaults to 40. */\n retention?: number;\n archiveMax?: number;\n archiveMaxAgeDays?: number;\n workspaces: WorkspaceStore;\n workspaceManager?: GitWorktreeManager;\n activeRuns: ActiveRuns;\n runPolicies?: RunPolicyStore;\n /** Max concurrent runs allowed in the scope (queue enforces; guard is a fallback). */\n maxConcurrency?: number;\n approvals?: ApprovalRegistry;\n questions?: QuestionRegistry;\n densityStore?: DensityStore;\n channel: StreamingChannel;\n defaultWorkspace: string;\n model?: string;\n stopGraceMs?: number;\n runTimeoutMs?: number;\n images?: string[];\n replyTo?: string;\n}\n\nexport async function runAgentBatch(input: RunFlowInput): Promise<void> {\n const replyOptions = input.replyTo ? { replyTo: input.replyTo } : {};\n\n const activeBefore = input.activeRuns.count(input.scope);\n if (input.maxConcurrency !== undefined && activeBefore >= input.maxConcurrency) {\n await input.channel.sendMarkdown(input.chatId, '当前会话的并行任务数已达上限,请稍后再试或 `/stop` 部分任务。', {\n ...replyOptions,\n });\n return;\n }\n\n const requestedCwd = input.workspaces.cwdFor(input.scope) ?? input.defaultWorkspace;\n const workspace = input.workspaceManager\n ? await input.workspaceManager.ensure(input.scope, requestedCwd)\n : { cwd: requestedCwd };\n const cwd = workspace.cwd;\n // Only the first run in a scope resumes the native dsh session: concurrent\n // runs get fresh sessions so they never share one wire session id.\n const sessionId =\n activeBefore === 0\n ? input.sessions.resumeFor(input.scope, cwd)\n : undefined;\n const history = input.sessions.historyFor(input.scope, cwd);\n const prompt = buildPrompt(history, input.messages, input.role);\n const runId = randomUUID();\n\n const run = input.adapter.run({\n runId,\n prompt,\n cwd,\n sessionId,\n model: input.model,\n images: input.images,\n stopGraceMs: input.stopGraceMs,\n ...(input.approvals\n ? {\n onApprovalRequest: approvalHandlerFor({\n approvals: input.approvals,\n channel: input.channel,\n chatId: input.chatId,\n scope: input.scope,\n }),\n }\n : {}),\n });\n input.activeRuns.set(input.scope, { runId, stop: run.stop });\n\n let state: RunState = initialState;\n const stopRequested = { value: false };\n const timeoutMs = input.runPolicies?.get(input.scope) ?? input.runTimeoutMs ?? 0;\n let timedOut = false;\n let assistantOutput = '';\n const density = input.densityStore?.get(input.scope) ?? 'standard';\n\n try {\n await input.channel.streamCard(\n input.chatId,\n renderCard(state, density),\n async (controller) => {\n const consume = async (): Promise<void> => {\n for await (const event of run.events) {\n if (timedOut) return;\n state = applyEvent(state, event, stopRequested);\n if (event.type === 'final_text') {\n assistantOutput = event.content;\n } else if (event.type === 'text') {\n assistantOutput += event.delta;\n }\n if (event.type === 'system' && event.sessionId) {\n input.sessions.set(input.scope, event.sessionId, event.cwd ?? cwd);\n }\n await controller.update(renderCard(state, density));\n }\n };\n\n let timeoutTimer: NodeJS.Timeout | undefined;\n const timeoutPromise =\n timeoutMs > 0\n ? new Promise<void>((resolve) => {\n timeoutTimer = setTimeout(() => {\n timedOut = true;\n void run.stop();\n resolve();\n }, timeoutMs);\n })\n : undefined;\n\n try {\n if (timeoutPromise) {\n await Promise.race([consume(), timeoutPromise]);\n } else {\n await consume();\n }\n\n state = timedOut\n ? markIdleTimeout(state, timeoutMs / 60_000)\n : finalizeIfRunning(state);\n await controller.update(renderCard(state, density));\n } finally {\n if (timeoutTimer !== undefined) clearTimeout(timeoutTimer);\n }\n },\n replyOptions,\n );\n input.sessions.recordExchange(input.scope, cwd, input.messages, assistantOutput, {\n ...(input.retention === undefined ? {} : { retention: input.retention }),\n ...(input.archiver\n ? {\n onArchive: (overflow) =>\n input.archiver!.archive({\n scope: input.scope,\n cwd,\n messages: overflow,\n source: 'retention',\n }).then(() => pruneArchives(input)),\n }\n : {}),\n });\n } catch (error) {\n log.fail('run-flow', error, { scope: input.scope, runId });\n state = markInterrupted(state);\n try {\n await input.channel.sendMarkdown(input.chatId, `⚠️ agent 运行失败:${errorMessage(error)}`, {\n ...replyOptions,\n });\n } catch {\n // best effort; the card may already have failed\n }\n } finally {\n input.activeRuns.delete(input.scope, runId);\n if (input.approvals) {\n input.approvals.settleAll(input.scope, 'cancelled');\n }\n if (input.questions) {\n input.questions.settleAll(input.scope);\n }\n }\n}\n\nasync function pruneArchives(input: RunFlowInput): Promise<void> {\n if (!input.archiver) return;\n await input.archiver.prune({\n ...(input.archiveMax !== undefined && input.archiveMax > 0\n ? { maxArchives: input.archiveMax }\n : {}),\n ...(input.archiveMaxAgeDays !== undefined && input.archiveMaxAgeDays > 0\n ? { maxAgeMs: input.archiveMaxAgeDays * 24 * 60 * 60 * 1000 }\n : {}),\n });\n}\n\n/** Build the per-run approval handler wiring ACP requests to approval cards. */\nexport function approvalHandlerFor(\n input: {\n approvals: ApprovalRegistry | undefined;\n channel: { sendCard?: (chatId: string, card: object) => Promise<void> };\n chatId: string;\n scope: string;\n },\n): (request: ApprovalRequest) => Promise<ApprovalOutcome> {\n return async (request) => {\n if (!input.approvals || !input.channel.sendCard) return 'cancelled';\n const promise = input.approvals.register(input.scope, request);\n try {\n await input.channel.sendCard(\n input.chatId,\n renderApprovalCard({\n id: request.id,\n toolName: request.toolName,\n reason: request.reason,\n options: request.options,\n }),\n );\n } catch (error) {\n log.fail('approval-card', error, { scope: input.scope });\n input.approvals.settleAll(input.scope, 'cancelled');\n return 'cancelled';\n }\n return promise;\n };\n}\n\n/** Build the per-run question handler wiring `/ask` cards back to sessions. */\nexport function questionHandlerFor(\n input: {\n questions: QuestionRegistry | undefined;\n channel: { sendCard?: (chatId: string, card: object) => Promise<void> };\n chatId: string;\n scope: string;\n },\n): (question: QuestionCardInput) => Promise<string | string[] | undefined> {\n return async (question) => {\n if (!input.questions || !input.channel.sendCard) return undefined;\n const { id, promise } = input.questions.register(input.scope, {\n kind: question.kind,\n question: question.question,\n ...(question.options === undefined ? {} : { options: question.options }),\n ...(question.placeholder === undefined ? {} : { placeholder: question.placeholder }),\n });\n try {\n await input.channel.sendCard(input.chatId, renderQuestionCard({ ...question, id }));\n } catch (error) {\n log.fail('question-card', error, { scope: input.scope });\n input.questions.settleAll(input.scope);\n return undefined;\n }\n return promise;\n };\n}\n\nfunction buildPrompt(\n history: Array<{ role: 'user' | 'assistant'; content: string }>,\n messages: string[],\n role: RoleDefinition | undefined,\n): string {\n const rolePreamble = role ? renderRolePreamble(role) : undefined;\n const userText = messages.join('\\n\\n');\n if (history.length === 0 && !rolePreamble) return userText;\n\n const transcript = history\n .map((message) => `${message.role === 'user' ? 'User' : 'Assistant'}: ${message.content}`)\n .join('\\n\\n');\n\n const parts: string[] = [];\n if (rolePreamble) parts.push(rolePreamble, '');\n if (history.length > 0) {\n parts.push('Continue the conversation using the history below.', '', transcript, '');\n }\n parts.push(`Current user message:\\n${userText}`);\n return parts.join('\\n');\n}\n\nfunction renderRolePreamble(role: RoleDefinition): string {\n const lines = [\n `[Role instructions]`,\n `Role: ${role.name} (${role.id})`,\n `Persona: ${role.persona}`,\n ];\n if (role.model) lines.push(`Model preference: ${role.model}`);\n if (role.tools) lines.push(`Tools guidance: ${role.tools}`);\n if (role.agentsMd) {\n lines.push('', 'Role rules (AGENTS.md):', role.agentsMd);\n }\n lines.push(\n '',\n 'Stay in this role for the whole turn unless the user explicitly changes it.',\n );\n return lines.join('\\n');\n}\n\nfunction applyEvent(\n state: RunState,\n event: AgentEvent,\n stopRequested: { value: boolean },\n): RunState {\n if (event.type === 'done' && event.terminationReason === 'interrupted') {\n stopRequested.value = true;\n return markInterrupted(state);\n }\n if (event.type === 'error' && event.terminationReason === 'timeout') {\n return markIdleTimeout(state, 0);\n }\n return reduce(state, event);\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n","import type { AgentEvent } from '../adapters/types.js';\n\nexport type ToolStatus = 'running' | 'done' | 'error';\n\nexport interface ToolEntry {\n id: string;\n name: string;\n input: unknown;\n status: ToolStatus;\n output?: string;\n}\n\nexport type Block =\n | { kind: 'text'; content: string; streaming: boolean }\n | { kind: 'tool'; tool: ToolEntry };\n\nexport type FooterStatus = 'thinking' | 'tool_running' | 'streaming' | null;\nexport type Terminal = 'running' | 'done' | 'interrupted' | 'error' | 'idle_timeout';\n\nexport interface RunState {\n blocks: Block[];\n reasoning: { content: string; active: boolean };\n usage: { inputTokens: number | undefined; outputTokens: number | undefined } | undefined;\n footer: FooterStatus;\n terminal: Terminal;\n errorMsg: string | undefined;\n idleTimeoutMinutes: number | undefined;\n}\n\nexport const initialState: RunState = {\n blocks: [],\n reasoning: { content: '', active: false },\n usage: undefined,\n footer: 'thinking',\n terminal: 'running',\n errorMsg: undefined,\n idleTimeoutMinutes: undefined,\n};\n\nfunction closeStreamingText(blocks: Block[]): Block[] {\n return blocks.map((block) =>\n block.kind === 'text' && block.streaming ? { ...block, streaming: false } : block,\n );\n}\n\nexport function reduce(state: RunState, event: AgentEvent): RunState {\n switch (event.type) {\n case 'text': {\n const last = state.blocks[state.blocks.length - 1];\n if (last?.kind === 'text' && last.streaming) {\n return {\n ...state,\n blocks: [\n ...state.blocks.slice(0, -1),\n { ...last, content: last.content + event.delta },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n return {\n ...state,\n blocks: [...state.blocks, { kind: 'text', content: event.delta, streaming: true }],\n reasoning: { ...state.reasoning, active: false },\n footer: 'streaming',\n };\n }\n\n case 'thinking':\n return {\n ...state,\n reasoning: {\n content: state.reasoning.content + event.delta,\n active: true,\n },\n footer: 'thinking',\n };\n\n case 'final_text':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n { kind: 'text', content: event.content, streaming: false },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: null,\n };\n\n case 'usage':\n return {\n ...state,\n usage: {\n inputTokens: event.inputTokens,\n outputTokens: event.outputTokens,\n },\n };\n\n case 'tool_use':\n return {\n ...state,\n blocks: [\n ...closeStreamingText(state.blocks),\n {\n kind: 'tool',\n tool: {\n id: event.id,\n name: event.name,\n input: event.input,\n status: 'running',\n },\n },\n ],\n reasoning: { ...state.reasoning, active: false },\n footer: 'tool_running',\n };\n\n case 'tool_result':\n return {\n ...state,\n blocks: state.blocks.map((block) => {\n if (block.kind !== 'tool' || block.tool.id !== event.id) return block;\n return {\n ...block,\n tool: {\n ...block.tool,\n status: event.isError ? 'error' : 'done',\n output: event.output,\n },\n };\n }),\n };\n\n case 'error':\n return {\n ...state,\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'error',\n errorMsg: event.terminationReason === 'failed' ? event.message : undefined,\n idleTimeoutMinutes: undefined,\n footer: null,\n };\n\n case 'done':\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal:\n event.terminationReason === 'interrupted'\n ? 'interrupted'\n : event.terminationReason === 'timeout'\n ? 'idle_timeout'\n : 'done',\n footer: null,\n };\n\n default:\n return state;\n }\n}\n\nexport function markInterrupted(state: RunState): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'interrupted',\n footer: null,\n };\n}\n\nexport function markIdleTimeout(state: RunState, minutes: number): RunState {\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'idle_timeout',\n footer: null,\n idleTimeoutMinutes: minutes,\n };\n}\n\nexport function finalizeIfRunning(state: RunState): RunState {\n if (state.terminal !== 'running') return state;\n return {\n ...state,\n blocks: closeStreamingText(state.blocks),\n reasoning: { ...state.reasoning, active: false },\n terminal: 'done',\n footer: null,\n };\n}\n","import type { Block, FooterStatus, RunState, ToolEntry } from './run-state.js';\nimport type { CardDensity } from './density.js';\n\nfunction markdown(content: string): object {\n return { tag: 'markdown', content };\n}\n\nfunction noteMd(content: string): object {\n return { tag: 'markdown', content, text_size: 'notation' };\n}\n\nfunction footerStatus(status: Exclude<FooterStatus, null>): object {\n const text =\n status === 'thinking'\n ? '🧠 正在思考'\n : status === 'tool_running'\n ? '🧰 正在调用工具'\n : '✍️ 正在输出';\n return noteMd(text);\n}\n\nfunction summaryText(state: RunState): string {\n if (state.terminal === 'interrupted') return '已中断';\n if (state.terminal === 'idle_timeout') return '已超时';\n if (state.terminal === 'error') return '出错';\n if (state.terminal === 'done') return '已完成';\n if (state.footer === 'tool_running') return '正在调用工具';\n if (state.footer === 'streaming') return '正在输出';\n return '思考中';\n}\n\nfunction stopButton(): object {\n return {\n tag: 'button',\n text: { tag: 'plain_text', content: '⏹ 终止' },\n type: 'danger',\n value: { cmd: 'stop' },\n };\n}\n\nfunction textBlock(block: Extract<Block, { kind: 'text' }>): object {\n return markdown(block.content);\n}\n\nfunction toolBlock(tool: ToolEntry): object {\n const icon = tool.status === 'error' ? '⚠️' : tool.status === 'done' ? '✅' : '⏳';\n return markdown(`${icon} **${tool.name}**`);\n}\n\nfunction usageLine(state: RunState): string {\n if (!state.usage) return '';\n const parts: string[] = [];\n if (state.usage.inputTokens !== undefined) parts.push(`in ${state.usage.inputTokens}`);\n if (state.usage.outputTokens !== undefined) parts.push(`out ${state.usage.outputTokens}`);\n return parts.length ? `(tokens ${parts.join(' · ')})` : '';\n}\n\nfunction renderStandard(state: RunState): object {\n const elements: object[] = [];\n\n if (state.reasoning.content) {\n elements.push(\n noteMd(\n state.reasoning.active\n ? '🧠 正在思考…'\n : `🧠 思考完成:${state.reasoning.content.slice(0, 300)}`,\n ),\n );\n }\n\n for (const block of state.blocks) {\n if (block.kind === 'text') {\n elements.push(textBlock(block));\n } else if (block.tool.status !== 'done') {\n elements.push(toolBlock(block.tool));\n }\n }\n\n if (state.terminal === 'interrupted') {\n elements.push(noteMd('_⏹ 已被中断_'));\n } else if (state.terminal === 'idle_timeout') {\n elements.push(noteMd(`_⏱ ${state.idleTimeoutMinutes ?? 0} 分钟无响应,已自动终止_`));\n } else if (state.terminal === 'error' && state.errorMsg) {\n elements.push(noteMd(`⚠️ agent 失败:${state.errorMsg}`));\n } else if (state.terminal === 'done' && elements.length === 0) {\n elements.push(noteMd('_(未返回内容)_'));\n } else if (state.terminal === 'done') {\n const usage = usageLine(state);\n if (usage) elements.push(noteMd(usage));\n }\n\n if (state.terminal === 'running') {\n if (state.footer) elements.push(footerStatus(state.footer));\n elements.push(stopButton());\n }\n\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n\nfunction renderCompact(state: RunState): object {\n const elements: object[] = [noteMd(summaryText(state))];\n if (state.terminal === 'running' && state.footer) {\n elements.push(footerStatus(state.footer));\n }\n if (state.terminal === 'running') {\n elements.push(stopButton());\n }\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n\nfunction renderDetailed(state: RunState): object {\n const elements: object[] = [];\n\n if (state.reasoning.content) {\n elements.push(\n noteMd(\n state.reasoning.active\n ? '🧠 正在思考…'\n : `🧠 **思考过程**\\n${state.reasoning.content.slice(0, 2000)}`,\n ),\n );\n }\n\n for (const block of state.blocks) {\n if (block.kind === 'text') {\n elements.push(textBlock(block));\n continue;\n }\n const tool = block.tool;\n const icon = tool.status === 'error' ? '⚠️' : tool.status === 'done' ? '✅' : '⏳';\n const lines = [`${icon} **${tool.name}**`];\n if (tool.input !== undefined && tool.input !== '') {\n lines.push(`输入:\\`\\`\\`\\n${safeJsonPreview(tool.input)}\\n\\`\\`\\``);\n }\n if (tool.output) {\n lines.push(`输出:${tool.output.slice(0, 500)}`);\n }\n elements.push(markdown(lines.join('\\n')));\n }\n\n if (state.terminal === 'interrupted') {\n elements.push(noteMd('_⏹ 已被中断_'));\n } else if (state.terminal === 'idle_timeout') {\n elements.push(noteMd(`_⏱ ${state.idleTimeoutMinutes ?? 0} 分钟无响应,已自动终止_`));\n } else if (state.terminal === 'error' && state.errorMsg) {\n elements.push(noteMd(`⚠️ agent 失败:${state.errorMsg}`));\n } else if (state.terminal === 'done') {\n const usage = usageLine(state);\n if (usage) elements.push(noteMd(usage));\n }\n\n if (state.terminal === 'running') {\n if (state.footer) elements.push(footerStatus(state.footer));\n elements.push(stopButton());\n }\n\n return {\n schema: '2.0',\n config: {\n streaming_mode: state.terminal === 'running',\n summary: { content: summaryText(state) },\n },\n body: { elements },\n };\n}\n\nfunction safeJsonPreview(value: unknown): string {\n if (typeof value === 'string') return value.slice(0, 300);\n try {\n return JSON.stringify(value).slice(0, 300);\n } catch {\n return String(value).slice(0, 300);\n }\n}\n\n/** Render the run card at the requested density (compact / standard / detailed). */\nexport function renderCard(state: RunState, density: CardDensity = 'standard'): object {\n if (density === 'compact') return renderCompact(state);\n if (density === 'detailed') return renderDetailed(state);\n return renderStandard(state);\n}\n","import type { ApprovalOption } from '../adapters/types.js';\n\nexport interface ApprovalCardInput {\n id: string;\n toolName: string;\n reason: string | undefined;\n options: readonly ApprovalOption[];\n}\n\n/**\n * Feishu approval card for ACP `session/request_permission`: one-shot\n * allow / reject buttons, mirroring the options offered by the harness.\n */\nexport function renderApprovalCard(input: ApprovalCardInput): object {\n const allow = input.options.find((option) => option.kind === 'allow_once') ??\n input.options.find((option) => option.kind === 'allow_always');\n const reject = input.options.find((option) => option.kind === 'reject_once') ??\n input.options.find((option) => option.kind === 'reject_always');\n\n const markdown = [\n '🔐 **审批请求**',\n '',\n `**工具** \\`${input.toolName}\\``,\n ...(input.reason ? ['', input.reason] : []),\n ].join('\\n');\n\n const actions = [\n ...(allow\n ? [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: `✅ ${allow.name}` },\n type: 'primary',\n value: { cmd: 'approve', id: input.id, outcome: 'allow' },\n },\n ]\n : []),\n ...(reject\n ? [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: `⛔ ${reject.name}` },\n type: 'danger',\n value: { cmd: 'approve', id: input.id, outcome: 'reject' },\n },\n ]\n : []),\n ];\n\n return {\n schema: '2.0',\n config: {\n summary: { content: '审批请求' },\n },\n body: {\n elements: [\n { tag: 'markdown', content: markdown },\n { tag: 'action', actions },\n ],\n },\n };\n}\n","export type QuestionKind = 'single' | 'multi' | 'text';\n\nexport interface QuestionCardInput {\n id: string;\n kind: QuestionKind;\n question: string;\n options?: string[];\n placeholder?: string;\n}\n\nfunction formElement(input: QuestionCardInput): object {\n if (input.kind === 'text') {\n return {\n tag: 'input',\n name: 'answer',\n placeholder: { tag: 'plain_text', content: input.placeholder ?? '请输入答案…' },\n };\n }\n const options = (input.options ?? []).map((option, index) => ({\n text: { tag: 'plain_text', content: option },\n value: `option-${index}`,\n }));\n if (input.kind === 'multi') {\n return {\n tag: 'multi_select_static',\n name: 'answer',\n placeholder: { tag: 'plain_text', content: '请选择(可多选)…' },\n options,\n };\n }\n return {\n tag: 'select_static',\n name: 'answer',\n placeholder: { tag: 'plain_text', content: '请选择…' },\n options,\n };\n}\n\n/** Structured question card: single choice, multi choice, or free text. */\nexport function renderQuestionCard(input: QuestionCardInput): object {\n return {\n schema: '2.0',\n config: {\n summary: { content: '问题' },\n },\n body: {\n elements: [\n { tag: 'markdown', content: `❓ ${input.question}` },\n formElement(input),\n {\n tag: 'action',\n actions: [\n {\n tag: 'button',\n text: { tag: 'plain_text', content: '提交' },\n type: 'primary',\n value: { cmd: 'question-submit', id: input.id },\n },\n ],\n },\n ],\n },\n };\n}\n\n/**\n * Normalize a card action value into an answer for the question kind.\n * `answer` shapes: string (text / single select) or string[] (multi select).\n */\nexport function extractQuestionAnswer(\n kind: QuestionKind,\n value: unknown,\n options?: string[],\n): string | string[] | undefined {\n const answer = value;\n if (kind === 'text') {\n return typeof answer === 'string' && answer.trim() ? answer.trim() : undefined;\n }\n const selected = Array.isArray(answer)\n ? answer.map((item) => String(item))\n : typeof answer === 'string' && answer\n ? [answer]\n : [];\n if (selected.length === 0) return undefined;\n const labels = options ?? [];\n const resolved = selected.map((item) => {\n const match = /^option-(\\d+)$/.exec(item);\n if (match) {\n const index = Number(match[1]);\n return labels[index] ?? item;\n }\n return item;\n });\n return kind === 'single' ? resolved[0] : resolved;\n}\n","import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { Document, parseDocument } from 'yaml';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { resolveDshHome } from './dsh-runtime.js';\n\nexport const DEEPSEEK_NAMESPACE = 'llm-deepseek';\nexport const DEEPSEEK_PROVIDER = 'deepseek-official';\nexport const DEEPSEEK_DEFAULT_API_KEY_ENV = 'DEEPSEEK_API_KEY';\nexport const PIAI_NAMESPACE = 'llm-pi-ai';\nexport const AGENT_DEFAULT_MODEL_NAMESPACE = 'agent-default-model';\n\n/**\n * Wire protocols a dsh-llm-pi-ai profile may name. Mirrors\n * `supportedProtocols()` from @deepseek-ai/dsh-llm-pi-ai; anything else is\n * refused at configuration time by the official validator.\n */\nexport const SUPPORTED_PI_AI_PROTOCOLS = [\n 'openai-completions',\n 'openai-responses',\n 'anthropic-messages',\n] as const;\nexport type PiAiProtocol = (typeof SUPPORTED_PI_AI_PROTOCOLS)[number];\n\nconst PROVIDER_ID_PATTERN = /^[a-z][a-z0-9._-]*$/;\n/** POSIX identifier rule enforced by dsh-credentials for `.credentials.yaml`. */\nconst CREDENTIAL_REF_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nexport interface DshModelEntry {\n id: string;\n name: string | undefined;\n contextWindow: number | undefined;\n maxTokens: number | undefined;\n}\n\nexport interface DshProviderSummary {\n id: string;\n displayName: string;\n namespace: string;\n configured: boolean;\n credentialRef: string | undefined;\n credentialReady: boolean;\n models: DshModelEntry[];\n /** Whether dsh-lark-bot can add/update/remove this provider via chat. */\n managed: boolean;\n}\n\nexport interface DshProviderManagerOptions {\n home?: string;\n env?: NodeJS.ProcessEnv;\n settingsFile?: string;\n credentialsFile?: string;\n}\n\nexport interface DshPiAiProviderInput {\n id: string;\n displayName?: string;\n apiKeyEnv?: string;\n api?: string;\n baseURL?: string;\n models?: DshModelEntry[];\n}\n\nconst DEFAULT_DEEPSEEK_MODELS: DshModelEntry[] = [\n { id: 'deepseek-v4-flash', name: 'DeepSeek-V4-Flash', contextWindow: undefined, maxTokens: undefined },\n { id: 'deepseek-v4-pro', name: 'DeepSeek-V4-Pro', contextWindow: undefined, maxTokens: undefined },\n];\n\nconst LOCK_TIMEOUT_MS = 10_000;\n\nfunction isMapLike(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction deepEqualJson(a: unknown, b: unknown): boolean {\n return JSON.stringify(a) === JSON.stringify(b);\n}\n\nfunction parseModels(value: unknown): DshModelEntry[] | undefined {\n if (!Array.isArray(value)) return undefined;\n const models: DshModelEntry[] = [];\n for (const raw of value) {\n if (!isMapLike(raw) || typeof raw.id !== 'string' || raw.id.length === 0) continue;\n models.push({\n id: raw.id,\n name: typeof raw.name === 'string' ? raw.name : undefined,\n contextWindow:\n typeof raw.contextWindow === 'number' ? raw.contextWindow : undefined,\n maxTokens: typeof raw.maxTokens === 'number' ? raw.maxTokens : undefined,\n });\n }\n return models;\n}\n\n/** Raw model entries preserved verbatim so exotic fields survive round-trips. */\nfunction rawModels(value: unknown): Record<string, unknown>[] {\n if (!Array.isArray(value)) return [];\n return value.filter((entry): entry is Record<string, unknown> => isMapLike(entry));\n}\n\nfunction modelRecord(input: DshModelEntry): Record<string, unknown> {\n const record: Record<string, unknown> = { id: input.id };\n if (input.name !== undefined) record.name = input.name;\n if (input.contextWindow !== undefined) record.contextWindow = input.contextWindow;\n if (input.maxTokens !== undefined) record.maxTokens = input.maxTokens;\n return record;\n}\n\nfunction validateProviderId(id: string): void {\n if (!PROVIDER_ID_PATTERN.test(id)) {\n throw new Error(`provider id 必须是小写字母开头且仅含 a-z 0-9 . _ -,得到 \"${id}\"`);\n }\n}\n\nfunction validateBaseUrl(url: string): void {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n throw new Error(`baseURL 不是合法 URL:${url}`);\n }\n if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {\n throw new Error(`baseURL 仅支持 http/https:${url}`);\n }\n}\n\nfunction assertProtocol(api: string): asserts api is PiAiProtocol {\n if (!(SUPPORTED_PI_AI_PROTOCOLS as readonly string[]).includes(api)) {\n throw new Error(`不支持的 API 协议 \"${api}\",可选:${SUPPORTED_PI_AI_PROTOCOLS.join(' / ')}`);\n }\n}\n\n/** Comment-preserving leaf patch used by dsh-settings-file. */\nfunction patchNode(\n document: Document,\n path: readonly (string | number)[],\n current: unknown,\n next: unknown,\n): void {\n if (isMapLike(current) && isMapLike(next)) {\n for (const key of Object.keys(current)) {\n if (!(key in next)) document.deleteIn([...path, key]);\n }\n for (const [key, value] of Object.entries(next)) {\n patchNode(document, [...path, key], current[key], value);\n }\n return;\n }\n if (!deepEqualJson(current, next)) document.setIn([...path], next);\n}\n\nfunction parseYamlMap(text: string | undefined, filename: string): Record<string, unknown> {\n if (text === undefined || text.trim().length === 0) return {};\n const document = parseDocument(text, { prettyErrors: true });\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh config at ${filename}: ${document.errors.map((e) => e.message).join('; ')}`);\n }\n const root = document.toJS() ?? {};\n if (!isMapLike(root)) {\n throw new TypeError(`dsh config ${filename} must be a mapping`);\n }\n return root;\n}\n\nasync function readOptional(file: string): Promise<string | undefined> {\n try {\n return await readFile(file, 'utf8');\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined;\n throw error;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Cross-process writer lock compatible with dsh's own protocol: an exclusive\n * `<file>.lock` sibling created with the `wx` flag, released by removal.\n */\nasync function withFileLock<T>(filename: string, operation: () => Promise<T>): Promise<T> {\n const lockPath = `${filename}.lock`;\n const deadline = Date.now() + LOCK_TIMEOUT_MS;\n for (;;) {\n try {\n await writeFile(lockPath, `${process.pid}\\n`, { flag: 'wx' });\n break;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'EEXIST') throw error;\n if (Date.now() >= deadline) {\n throw new Error(`dsh config lock timed out at ${lockPath}`);\n }\n await sleep(80 + Math.random() * 120);\n }\n }\n try {\n return await operation();\n } finally {\n await rm(lockPath, { force: true }).catch(() => undefined);\n }\n}\n\nexport class DshProviderManager {\n private readonly home: string;\n private readonly env: NodeJS.ProcessEnv;\n private readonly settingsFile: string;\n private readonly credentialsFile: string;\n\n constructor(options: DshProviderManagerOptions = {}) {\n this.home = options.home ?? homedir();\n this.env = options.env ?? process.env;\n const dshHome = resolveDshHome(this.home, this.env);\n this.settingsFile = options.settingsFile ?? join(dshHome, 'settings.yaml');\n this.credentialsFile = options.credentialsFile ?? join(dshHome, '.credentials.yaml');\n }\n\n async readSettings(): Promise<Record<string, unknown>> {\n return parseYamlMap(await readOptional(this.settingsFile), this.settingsFile);\n }\n\n async readCredentials(): Promise<Record<string, string>> {\n const root = parseYamlMap(await readOptional(this.credentialsFile), this.credentialsFile);\n const entries: Record<string, string> = {};\n for (const [key, value] of Object.entries(root)) {\n if (typeof value === 'string' && value.length > 0) entries[key] = value;\n }\n return entries;\n }\n\n async hasCredential(ref: string): Promise<boolean> {\n const entries = await this.readCredentials();\n if (entries[ref]) return true;\n return Boolean(this.env[ref]?.trim());\n }\n\n async listCredentialRefs(): Promise<string[]> {\n return Object.keys(await this.readCredentials());\n }\n\n async listProviders(): Promise<DshProviderSummary[]> {\n const settings = await this.readSettings();\n return [await this.describeDeepseek(settings), ...(await this.describePiAi(settings))];\n }\n\n private async describeDeepseek(settings: Record<string, unknown>): Promise<DshProviderSummary> {\n const deepseek = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const credentialRef =\n typeof deepseek.apiKeyEnv === 'string' && deepseek.apiKeyEnv.length > 0\n ? deepseek.apiKeyEnv\n : DEEPSEEK_DEFAULT_API_KEY_ENV;\n return {\n id: DEEPSEEK_PROVIDER,\n displayName: 'DeepSeek',\n namespace: DEEPSEEK_NAMESPACE,\n configured: Object.keys(deepseek).length > 0,\n credentialRef,\n credentialReady: await this.hasCredential(credentialRef),\n models: parseModels(deepseek.models) ?? DEFAULT_DEEPSEEK_MODELS,\n managed: true,\n };\n }\n\n private async describePiAi(settings: Record<string, unknown>): Promise<DshProviderSummary[]> {\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const summaries: DshProviderSummary[] = [];\n for (const [id, raw] of Object.entries(providers)) {\n const profile = isMapLike(raw) ? raw : {};\n const ref =\n typeof profile.apiKeyEnv === 'string' && profile.apiKeyEnv.length > 0\n ? profile.apiKeyEnv\n : undefined;\n summaries.push({\n id,\n displayName: typeof profile.displayName === 'string' ? profile.displayName : id,\n namespace: PIAI_NAMESPACE,\n configured: true,\n credentialRef: ref,\n credentialReady: ref === undefined ? false : await this.hasCredential(ref),\n models: parseModels(profile.models) ?? [],\n managed: true,\n });\n }\n return summaries;\n }\n\n async defaultModel(): Promise<string | undefined> {\n const settings = await this.readSettings();\n const section = settings[AGENT_DEFAULT_MODEL_NAMESPACE];\n return isMapLike(section) && typeof section.model === 'string' ? section.model : undefined;\n }\n\n async setDefaultModel(model: string): Promise<void> {\n if (!model.trim()) throw new Error('默认模型不能为空');\n await this.writeNamespace(AGENT_DEFAULT_MODEL_NAMESPACE, { model });\n }\n\n async upsertDeepseekProvider(input: {\n baseURL?: string;\n apiKeyEnv?: string;\n apiKey?: string;\n }): Promise<void> {\n const settings = await this.readSettings();\n const current = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const section = { ...current };\n if (input.baseURL !== undefined) {\n validateBaseUrl(input.baseURL);\n section.baseURL = input.baseURL;\n }\n if (input.apiKeyEnv !== undefined) section.apiKeyEnv = input.apiKeyEnv;\n if (input.apiKey !== undefined) {\n const ref =\n typeof section.apiKeyEnv === 'string' && section.apiKeyEnv.length > 0\n ? section.apiKeyEnv\n : DEEPSEEK_DEFAULT_API_KEY_ENV;\n await this.setCredential(ref, input.apiKey);\n }\n await this.writeNamespace(DEEPSEEK_NAMESPACE, section);\n }\n\n async removeDeepseekProvider(): Promise<void> {\n const settings = await this.readSettings();\n const section = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n await this.deleteNamespace(DEEPSEEK_NAMESPACE);\n await this.removeCredential(\n typeof section.apiKeyEnv === 'string' && section.apiKeyEnv.length > 0\n ? section.apiKeyEnv\n : DEEPSEEK_DEFAULT_API_KEY_ENV,\n );\n }\n\n async addDeepseekModel(input: DshModelEntry): Promise<void> {\n const settings = await this.readSettings();\n const current = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const models =\n rawModels(current.models).length > 0\n ? rawModels(current.models)\n : DEFAULT_DEEPSEEK_MODELS.map((model) => modelRecord(model));\n if (models.some((model) => model.id === input.id)) {\n throw new Error(`模型 ${input.id} 已存在于 ${DEEPSEEK_PROVIDER}`);\n }\n await this.writeNamespace(DEEPSEEK_NAMESPACE, {\n ...current,\n models: [...models, modelRecord(input)],\n });\n }\n\n async removeDeepseekModel(id: string): Promise<boolean> {\n const settings = await this.readSettings();\n const current = isMapLike(settings[DEEPSEEK_NAMESPACE])\n ? settings[DEEPSEEK_NAMESPACE]\n : {};\n const models = rawModels(current.models);\n if (models.length === 0) return false;\n const next = models.filter((model) => model.id !== id);\n if (next.length === models.length) return false;\n await this.writeNamespace(DEEPSEEK_NAMESPACE, { ...current, models: next });\n return true;\n }\n\n async upsertPiAiProvider(input: DshPiAiProviderInput): Promise<void> {\n validateProviderId(input.id);\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const existing = isMapLike(providers[input.id]) ? providers[input.id] : undefined;\n const section: Record<string, unknown> = existing === undefined ? {} : { ...existing };\n\n if (input.displayName !== undefined) section.displayName = input.displayName;\n if (input.apiKeyEnv !== undefined) section.apiKeyEnv = input.apiKeyEnv;\n if (input.api !== undefined) {\n assertProtocol(input.api);\n section.api = input.api;\n }\n if (input.baseURL !== undefined) {\n validateBaseUrl(input.baseURL);\n section.baseURL = input.baseURL;\n }\n if (input.models !== undefined) section.models = input.models.map(modelRecord);\n\n if (existing === undefined) {\n if (typeof section.api !== 'string') {\n throw new Error('新增自定义 provider 必须指定 --api(openai-completions / openai-responses / anthropic-messages)');\n }\n assertProtocol(section.api);\n if (typeof section.baseURL !== 'string') {\n throw new Error('新增自定义 provider 必须指定 --base-url');\n }\n validateBaseUrl(section.baseURL);\n const models = rawModels(section.models);\n if (models.length === 0) {\n throw new Error('新增自定义 provider 至少需要一个 --model(models 不能为空)');\n }\n for (const model of models) {\n if (typeof model.id !== 'string' || model.id.length === 0) {\n throw new Error(`--model 缺少有效 id:${JSON.stringify(model)}`);\n }\n }\n }\n\n await this.writeNamespace(PIAI_NAMESPACE, {\n ...piAi,\n providers: { ...providers, [input.id]: section },\n });\n }\n\n async removePiAiProvider(id: string): Promise<boolean> {\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n if (!(id in providers)) return false;\n const next: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(providers)) {\n if (key !== id) next[key] = value;\n }\n if (Object.keys(next).length === 0) {\n await this.deleteNamespace(PIAI_NAMESPACE);\n } else {\n await this.writeNamespace(PIAI_NAMESPACE, { ...piAi, providers: next });\n }\n return true;\n }\n\n async addPiAiModel(providerId: string, input: DshModelEntry): Promise<void> {\n validateProviderId(providerId);\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const section = isMapLike(providers[providerId]) ? providers[providerId] : undefined;\n if (section === undefined) {\n throw new Error(`provider ${providerId} 不存在,请先用 /provider add 创建`);\n }\n const models = rawModels(section.models);\n if (models.some((model) => model.id === input.id)) {\n throw new Error(`模型 ${input.id} 已存在于 ${providerId}`);\n }\n await this.writeNamespace(PIAI_NAMESPACE, {\n ...piAi,\n providers: {\n ...providers,\n [providerId]: { ...section, models: [...models, modelRecord(input)] },\n },\n });\n }\n\n async removePiAiModel(providerId: string, modelId: string): Promise<boolean> {\n const settings = await this.readSettings();\n const piAi = isMapLike(settings[PIAI_NAMESPACE]) ? settings[PIAI_NAMESPACE] : {};\n const providers = isMapLike(piAi.providers) ? piAi.providers : {};\n const section = isMapLike(providers[providerId]) ? providers[providerId] : undefined;\n if (section === undefined) {\n throw new Error(`provider ${providerId} 不存在`);\n }\n const models = rawModels(section.models);\n const next = models.filter((model) => model.id !== modelId);\n if (next.length === models.length) return false;\n await this.writeNamespace(PIAI_NAMESPACE, {\n ...piAi,\n providers: {\n ...providers,\n [providerId]: { ...section, models: next },\n },\n });\n return true;\n }\n\n async setCredential(ref: string, value: string): Promise<void> {\n if (!CREDENTIAL_REF_PATTERN.test(ref)) {\n throw new Error(`非法凭据引用名:${ref}(应为 POSIX 环境变量名,如 OPENAI_API_KEY)`);\n }\n if (value.length === 0) throw new Error('凭据值不能为空');\n await mkdir(dirname(this.credentialsFile), { recursive: true, mode: 0o700 });\n await withFileLock(this.credentialsFile, async () => {\n const text = await readOptional(this.credentialsFile);\n const root = parseYamlMap(text, this.credentialsFile);\n const document = text === undefined || text.trim().length === 0\n ? new Document()\n : parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh credentials at ${this.credentialsFile}`);\n }\n patchNode(document, [ref], root[ref], value);\n await writeFileAtomic(this.credentialsFile, document.toString(), { mode: 0o600 });\n });\n }\n\n async removeCredential(ref: string): Promise<boolean> {\n let removed = false;\n await withFileLock(this.credentialsFile, async () => {\n const text = await readOptional(this.credentialsFile);\n if (text === undefined || text.trim().length === 0) return;\n const document = parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh credentials at ${this.credentialsFile}`);\n }\n if (document.has(ref)) {\n document.deleteIn([ref]);\n removed = true;\n await writeFileAtomic(this.credentialsFile, document.toString(), { mode: 0o600 });\n }\n });\n return removed;\n }\n\n private async writeNamespace(ns: string, section: Record<string, unknown>): Promise<void> {\n await mkdir(dirname(this.settingsFile), { recursive: true });\n await withFileLock(this.settingsFile, async () => {\n const text = await readOptional(this.settingsFile);\n const root = parseYamlMap(text, this.settingsFile);\n if (text === undefined || text.trim().length === 0) {\n await writeFileAtomic(this.settingsFile, new Document({ [ns]: section }).toString(), {});\n return;\n }\n const document = parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh settings at ${this.settingsFile}`);\n }\n patchNode(document, [ns], root[ns], section);\n await writeFileAtomic(this.settingsFile, document.toString(), {});\n });\n }\n\n private async deleteNamespace(ns: string): Promise<void> {\n await withFileLock(this.settingsFile, async () => {\n const text = await readOptional(this.settingsFile);\n if (text === undefined || text.trim().length === 0) return;\n const document = parseDocument(text);\n if (document.errors.length > 0) {\n throw new Error(`invalid dsh settings at ${this.settingsFile}`);\n }\n if (document.has(ns)) {\n document.deleteIn([ns]);\n await writeFileAtomic(this.settingsFile, document.toString(), {});\n }\n });\n }\n}\n","import type { DshModelEntry, DshProviderSummary } from '../config/dsh-config.js';\nimport { DEEPSEEK_PROVIDER, SUPPORTED_PI_AI_PROTOCOLS } from '../config/dsh-config.js';\nimport type { CommandContext } from './index.js';\n\ninterface ParsedArgs {\n positionals: string[];\n flags: Record<string, string | undefined>;\n repeated: Record<string, string[]>;\n}\n\nfunction parseArgs(input: string): ParsedArgs {\n const tokens = input.trim().split(/\\s+/).filter(Boolean);\n const positionals: string[] = [];\n const flags: Record<string, string | undefined> = {};\n const repeated: Record<string, string[]> = {};\n for (let index = 0; index < tokens.length; index += 1) {\n const token = tokens[index] ?? '';\n if (!token.startsWith('--')) {\n positionals.push(token);\n continue;\n }\n const name = token.slice(2);\n const next = tokens[index + 1];\n let value: string | undefined;\n if (next !== undefined && !next.startsWith('--')) {\n value = next;\n index += 1;\n }\n flags[name] = value;\n if (value !== undefined) {\n const list = repeated[name] ?? [];\n list.push(value);\n repeated[name] = list;\n }\n }\n return { positionals, flags, repeated };\n}\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nfunction requireAdmin(ctx: CommandContext): boolean {\n if (!ctx.accessManager.isAdmin(ctx.senderId)) {\n void reply(ctx, '仅管理员可执行该操作。');\n return false;\n }\n return true;\n}\n\nfunction formatModel(model: { id: string; name: string | undefined }): string {\n return model.name ? `\\`${model.id}\\` (${model.name})` : `\\`${model.id}\\``;\n}\n\nfunction credentialLabel(provider: DshProviderSummary): string {\n if (provider.credentialReady) return '凭据就绪';\n return provider.credentialRef === undefined ? '未配置凭据' : '凭据缺失';\n}\n\nfunction formatProviders(providers: readonly DshProviderSummary[]): string {\n const lines = providers.map((provider) => {\n const state = provider.configured ? '已配置' : '未配置';\n const models = provider.models.length > 0\n ? provider.models.map((model) => model.id).join(', ')\n : '(无)';\n return `- **${provider.id}** (${provider.displayName}) — ${state} · ${credentialLabel(provider)}\\n models: ${models}`;\n });\n return lines.join('\\n');\n}\n\nasync function findModelOwner(\n ctx: CommandContext,\n id: string,\n): Promise<DshProviderSummary | undefined> {\n const providers = await ctx.dshConfig.listProviders();\n return providers.find((provider) => provider.models.some((model) => model.id === id));\n}\n\nfunction deepseekModelInput(args: {\n id: string;\n flags: Record<string, string | undefined>;\n}): DshModelEntry {\n return {\n id: args.id,\n name: args.flags.name,\n contextWindow: undefined,\n maxTokens: undefined,\n };\n}\n\nexport async function handleModel(args: string, ctx: CommandContext): Promise<void> {\n const { positionals, flags } = parseArgs(args);\n const [sub, ...rest] = positionals;\n\n if (!sub) {\n const active = ctx.models.get(ctx.scope) ?? ctx.defaultModel;\n const dshDefault = await ctx.dshConfig.defaultModel();\n const providers = await ctx.dshConfig.listProviders();\n const modelLines = providers.flatMap((provider) =>\n provider.models.map((model) => `- ${formatModel(model)} ← ${provider.id}`),\n );\n await reply(\n ctx,\n [\n `**当前会话模型**:\\`${active}\\``,\n `**dsh 默认模型**(agent-default-model):\\`${dshDefault ?? '(未设置)'}\\``,\n `**bot 回退默认**(profile / DSH_LARK_MODEL):\\`${ctx.defaultModel}\\``,\n '',\n '**可用模型**(dsh 已配置):',\n ...(modelLines.length > 0 ? modelLines : ['(暂无)']),\n '',\n '用法:`/model use <id>`、`/model default <id>`、`/model reset`、`/model add|remove <provider> <modelId> [--name <name>]`',\n ].join('\\n'),\n );\n return;\n }\n\n if (sub === 'use') {\n const id = rest.join(' ').trim();\n if (!id) {\n await reply(ctx, '用法:`/model use <modelId>`');\n return;\n }\n const provider = await findModelOwner(ctx, id);\n if (!provider) {\n await reply(ctx, `未找到模型 \\`${id}\\`,可用 /model 查看列表。`);\n return;\n }\n ctx.models.set(ctx.scope, id);\n await reply(ctx, `已热切换当前会话模型:\\`${id}\\`(下一轮消息生效,无需重启 bot)。`);\n return;\n }\n\n if (sub === 'reset') {\n const cleared = ctx.models.clear(ctx.scope);\n await reply(ctx, cleared ? '已清除当前会话模型覆盖,恢复 bot 默认模型。' : '当前会话没有模型覆盖。');\n return;\n }\n\n if (sub === 'default') {\n const id = rest.join(' ').trim();\n if (!id) {\n await reply(ctx, '用法:`/model default <modelId>`');\n return;\n }\n const provider = await findModelOwner(ctx, id);\n if (!provider) {\n await reply(ctx, `未找到模型 \\`${id}\\`,可用 /model 查看列表。`);\n return;\n }\n if (!requireAdmin(ctx)) return;\n await ctx.dshConfig.setDefaultModel(id);\n await reply(ctx, `已写入 dsh 默认模型(agent-default-model):\\`${id}\\`,新会话生效。`);\n return;\n }\n\n if (sub === 'add' || sub === 'remove') {\n if (!requireAdmin(ctx)) return;\n const providerId = rest[0];\n const id = rest[1];\n if (!providerId || !id) {\n await reply(ctx, `用法:\\`/model ${sub} <provider> <modelId> [--name <name>]\\``);\n return;\n }\n if (sub === 'add') {\n if (providerId === DEEPSEEK_PROVIDER) {\n await ctx.dshConfig.addDeepseekModel(deepseekModelInput({ id, flags }));\n await reply(ctx, `已添加模型:\\`${providerId}\\` → \\`${id}\\`(settings.yaml 已更新,下一请求生效)。`);\n } else {\n await ctx.dshConfig.addPiAiModel(providerId, deepseekModelInput({ id, flags }));\n await reply(ctx, `已添加模型:\\`${providerId}\\` → \\`${id}\\`(settings.yaml 已更新,下一请求生效)。`);\n }\n } else if (providerId === DEEPSEEK_PROVIDER) {\n const removed = await ctx.dshConfig.removeDeepseekModel(id);\n await reply(ctx, removed ? `已删除模型:\\`${providerId}\\` → \\`${id}\\`。` : `未找到模型:\\`${id}\\`。`);\n } else {\n const removed = await ctx.dshConfig.removePiAiModel(providerId, id);\n await reply(ctx, removed ? `已删除模型:\\`${providerId}\\` → \\`${id}\\`。` : `未找到模型:\\`${id}\\`。`);\n }\n return;\n }\n\n await reply(ctx, '未知 `/model` 子命令,请使用 use / default / reset / add / remove。');\n}\n\nexport async function handleProviders(_args: string, ctx: CommandContext): Promise<void> {\n const providers = await ctx.dshConfig.listProviders();\n const dshDefault = await ctx.dshConfig.defaultModel();\n await reply(\n ctx,\n [\n '**dsh 已配置 providers**',\n '',\n ...formatProviders(providers).split('\\n'),\n '',\n `dsh 默认模型:\\`${dshDefault ?? '(未设置)'}\\``,\n '',\n '管理:`/provider add|update|remove`、`/model add|remove`、`/key set|remove`(需管理员)',\n ].join('\\n'),\n );\n}\n\nexport async function handleProvider(args: string, ctx: CommandContext): Promise<void> {\n const { positionals, flags, repeated } = parseArgs(args);\n const [sub, id] = positionals;\n\n if ((sub === 'add' || sub === 'update') && id) {\n if (!requireAdmin(ctx)) return;\n const deepseekFlags = ['base-url', 'api-key-env', 'api-key'];\n const piAiFlags = [\n 'display-name',\n 'api-key-env',\n 'api',\n 'base-url',\n 'model',\n ];\n const provided = new Set([...Object.keys(flags), ...Object.keys(repeated)]);\n\n if (id === DEEPSEEK_PROVIDER) {\n const unsupported = [...provided].filter((name) => !deepseekFlags.includes(name));\n if (unsupported.length > 0) {\n await reply(ctx, `\\`deepseek-official\\` 仅支持 ${deepseekFlags.map((name) => `--${name}`).join(' / ')},不支持的参数:${unsupported.map((name) => `--${name}`).join('、')}`);\n return;\n }\n if (provided.size === 0) {\n await reply(ctx, '用法:`/provider add|update deepseek-official --base-url <url> [--api-key-env <ref>] [--api-key <key>]`');\n return;\n }\n await ctx.dshConfig.upsertDeepseekProvider({\n ...(flags['base-url'] ? { baseURL: flags['base-url'] } : {}),\n ...(flags['api-key-env'] ? { apiKeyEnv: flags['api-key-env'] } : {}),\n ...(flags['api-key'] ? { apiKey: flags['api-key'] } : {}),\n });\n await reply(\n ctx,\n `已${sub === 'add' ? '添加/更新' : '更新'} provider:\\`${id}\\`。凭据${flags['api-key'] ? '已写入 .credentials.yaml(值已隐藏)' : '不变'};其他字段按参数更新。`,\n );\n return;\n }\n\n const unsupported = [...provided].filter((name) => !piAiFlags.includes(name));\n if (unsupported.length > 0) {\n await reply(ctx, `不支持的参数:${unsupported.map((name) => `--${name}`).join('、')}。可用:${piAiFlags.map((name) => `--${name}`).join(' / ')}`);\n return;\n }\n if (provided.size === 0) {\n await reply(ctx, '用法:`/provider add|update <id> --api <protocol> --base-url <url> --model <modelId> [--display-name <name>] [--api-key-env <ref>]`');\n return;\n }\n const models = (repeated.model ?? []).map((modelId) => ({\n id: modelId,\n name: undefined,\n contextWindow: undefined,\n maxTokens: undefined,\n }));\n try {\n await ctx.dshConfig.upsertPiAiProvider({\n id,\n ...(flags['display-name'] ? { displayName: flags['display-name'] } : {}),\n ...(flags['api-key-env'] ? { apiKeyEnv: flags['api-key-env'] } : {}),\n ...(flags.api ? { api: flags.api } : {}),\n ...(flags['base-url'] ? { baseURL: flags['base-url'] } : {}),\n ...(models.length > 0 ? { models } : {}),\n });\n const protocolNote = flags.api ? `协议 \\`${flags.api}\\`` : '协议不变';\n const modelNote = models.length > 0 ? `,models 已${sub === 'add' ? '写入' : '替换为'} ${models.length} 个` : '';\n await reply(\n ctx,\n [\n `已${sub === 'add' ? '添加' : '更新'} provider:\\`${id}\\`(${protocolNote}${modelNote})。`,\n '',\n '凭据请用 `/key set <引用名> <值>` 写入(或配置对应环境变量),密钥不会显示在聊天中。',\n `协议可选:${SUPPORTED_PI_AI_PROTOCOLS.join(' / ')}`,\n ].join('\\n'),\n );\n } catch (error) {\n await reply(ctx, `操作失败:${error instanceof Error ? error.message : String(error)}`);\n }\n return;\n }\n\n if (sub === 'remove' && id) {\n if (!requireAdmin(ctx)) return;\n if (id === DEEPSEEK_PROVIDER) {\n await ctx.dshConfig.removeDeepseekProvider();\n await reply(\n ctx,\n `已删除 provider:\\`${id}\\`(含 settings 中 llm-deepseek 段及对应凭据)。此操作会移除 dsh 官方 DeepSeek 配置,请谨慎。`,\n );\n return;\n }\n const removed = await ctx.dshConfig.removePiAiProvider(id);\n await reply(ctx, removed ? `已删除 provider:\\`${id}\\`(settings.yaml 已更新)。` : `未找到 provider:\\`${id}\\`。`);\n return;\n }\n\n await reply(\n ctx,\n [\n '用法:',\n '- `/provider add <id> --api <protocol> --base-url <url> --model <modelId> [--model <modelId> ...] [--display-name <name>] [--api-key-env <ref>]`',\n '- `/provider update <id> [--api <protocol>] [--base-url <url>] [--model <modelId> ...] [--display-name <name>] [--api-key-env <ref>]`',\n '- `/provider remove <id>`',\n '',\n `\\`deepseek-official\\` 仅支持 --base-url / --api-key-env / --api-key;其他 id 走 llm-pi-ai 自定义 provider(协议可选:${SUPPORTED_PI_AI_PROTOCOLS.join(' / ')})。`,\n ].join('\\n'),\n );\n}\n\nexport async function handleKey(args: string, ctx: CommandContext): Promise<void> {\n const { positionals } = parseArgs(args);\n const [sub, ...rest] = positionals;\n\n if (!sub || sub === 'list') {\n const refs = await ctx.dshConfig.listCredentialRefs();\n await reply(\n ctx,\n [\n '**dsh 凭据**(仅显示引用名,不显示值):',\n ...(refs.length > 0 ? refs.map((ref) => `- \\`${ref}\\``) : ['(.credentials.yaml 暂无条目)']),\n '',\n '提示:环境变量中的凭据不会显示在这里;provider 的 apiKeyEnv 可引用任意环境变量。',\n ].join('\\n'),\n );\n return;\n }\n\n if (!requireAdmin(ctx)) return;\n\n if (sub === 'set') {\n const ref = rest[0];\n const value = rest.slice(1).join(' ').trim();\n if (!ref || !value) {\n await reply(ctx, '用法:`/key set <引用名> <值>`');\n return;\n }\n try {\n await ctx.dshConfig.setCredential(ref, value);\n } catch (error) {\n await reply(ctx, `写入失败:${error instanceof Error ? error.message : String(error)}`);\n return;\n }\n await reply(\n ctx,\n `已写入凭据 \\`${ref}\\` 到 \\`~/.dsh/.credentials.yaml\\`(0600,值已隐藏)。建议在私聊中使用;群聊里粘贴的密钥会对群成员可见。`,\n );\n return;\n }\n\n if (sub === 'remove') {\n const ref = rest[0];\n if (!ref) {\n await reply(ctx, '用法:`/key remove <引用名>`');\n return;\n }\n const removed = await ctx.dshConfig.removeCredential(ref);\n await reply(ctx, removed ? `已删除凭据 \\`${ref}\\`。` : `未找到凭据 \\`${ref}\\`。`);\n return;\n }\n\n await reply(ctx, '用法:`/key set <引用名> <值>`、`/key remove <引用名>`、`/key list`');\n}\n","import type { CommandContext } from './index.js';\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\n/** `/archive [note]` — export the full live session transcript to durable storage. */\nexport async function handleArchive(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n const cwd = ctx.workspaces.cwdFor(ctx.scope) ?? ctx.defaultWorkspace;\n const archiver = ctx.archiver;\n\n if (sub === 'list') {\n const limitInput = rest[0] ?? '5';\n const limit = Number(limitInput);\n const n = Number.isInteger(limit) && limit > 0 ? limit : 5;\n const records = (await archiver.list(ctx.scope)).slice(0, n);\n if (records.length === 0) {\n await reply(ctx, '当前 scope 还没有归档记录。');\n return;\n }\n const lines = records.map(\n (record) =>\n `- \\`${record.archiveId}\\` · ${String(record.messageCount)} msgs · ${record.source} · ${record.archivedAt}`,\n );\n await reply(ctx, [`**当前 scope 归档记录**`, '', ...lines].join('\\n'));\n return;\n }\n\n if (sub === 'clean') {\n const pruneOptions = {\n ...(ctx.archiveMax > 0 ? { maxArchives: ctx.archiveMax } : {}),\n ...(ctx.archiveMaxAgeDays > 0\n ? { maxAgeMs: ctx.archiveMaxAgeDays * 24 * 60 * 60 * 1000 }\n : {}),\n };\n const removed = await archiver.prune(pruneOptions);\n await reply(ctx, removed > 0 ? `已清理 ${String(removed)} 条过期归档。` : '没有需要清理的归档。');\n return;\n }\n\n const history = ctx.sessions.fullHistoryFor(ctx.scope, cwd);\n const note = args.trim() || undefined;\n const record = await archiver.archive({\n scope: ctx.scope,\n cwd,\n messages: history,\n source: 'manual',\n ...(note === undefined ? {} : { note }),\n });\n const commit = record.gitCommit ? `(git commit \\`${record.gitCommit}\\`)` : '';\n await reply(\n ctx,\n [\n `已归档当前会话:**${String(record.messageCount)}** 条消息${commit}`,\n `- Markdown: \\`${record.markdownPath}\\``,\n `- JSONL: \\`${record.jsonlPath}\\``,\n '',\n '历史消息会按保留策略自动归档;可用 `/retention` 调整保留条数。',\n ].join('\\n'),\n );\n await archiver.prune({\n ...(ctx.archiveMax > 0 ? { maxArchives: ctx.archiveMax } : {}),\n ...(ctx.archiveMaxAgeDays > 0\n ? { maxAgeMs: ctx.archiveMaxAgeDays * 24 * 60 * 60 * 1000 }\n : {}),\n });\n}\n\n/** `/retention [N|default]` — view or set the live message retention window. */\nexport async function handleRetention(args: string, ctx: CommandContext): Promise<void> {\n const input = args.trim();\n const effective = ctx.retentionStore.get(ctx.scope) ?? ctx.defaultRetention;\n\n if (!input) {\n await reply(\n ctx,\n `当前会话保留最近 **${String(effective)}** 条消息(超出部分自动归档)。可用 \\`/retention <N|default>\\` 调整。`,\n );\n return;\n }\n\n if (input === 'default') {\n ctx.retentionStore.clear(ctx.scope);\n await reply(ctx, `已恢复默认保留条数(${String(ctx.defaultRetention)})。`);\n return;\n }\n\n const n = Number(input);\n if (!Number.isInteger(n) || n <= 0) {\n await reply(ctx, '用法:`/retention <N|default>`,N 为大于 0 的条数。');\n return;\n }\n\n ctx.retentionStore.set(ctx.scope, n);\n await reply(ctx, `已设置当前会话保留最近 **${String(n)}** 条消息。`);\n}\n","import type { RoleStore } from '../bot/role-store.js';\nimport type { CommandContext } from './index.js';\n\ninterface ParsedRoleArgs {\n positionals: string[];\n flags: Record<string, string | undefined>;\n}\n\n/**\n * Parse `/role save <id> <name> --flag value...` where long flags consume\n * everything up to the next flag, so multi-word persona/rules text works.\n */\nfunction parseRoleArgs(input: string): ParsedRoleArgs {\n const positionals: string[] = [];\n const flags: Record<string, string | undefined> = {};\n let rest = input.trim();\n while (rest) {\n const flagMatch = rest.match(/^--([a-z-]+)\\s*/);\n if (!flagMatch) {\n const token = rest.split(/\\s+/, 1)[0] ?? '';\n positionals.push(token);\n rest = rest.slice(token.length).trim();\n continue;\n }\n const flag = flagMatch[1] ?? '';\n rest = rest.slice(flagMatch[0].length);\n const nextFlag = rest.search(/\\s--[a-z-]+(?:\\s|$)/);\n if (nextFlag === -1) {\n flags[flag] = rest.trim();\n rest = '';\n } else {\n flags[flag] = rest.slice(0, nextFlag).trim();\n rest = rest.slice(nextFlag).trim();\n }\n }\n return { positionals, flags };\n}\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\nfunction requireAdmin(ctx: CommandContext): boolean {\n if (!ctx.accessManager.isAdmin(ctx.senderId)) {\n void reply(ctx, '仅管理员可执行该操作。');\n return false;\n }\n return true;\n}\n\nfunction describeRole(role: NonNullable<ReturnType<RoleStore['get']>>): string {\n const lines = [\n `**${role.name}** (\\`${role.id}\\`)`,\n '',\n role.persona,\n ];\n if (role.model) lines.push('', `- model: \\`${role.model}\\``);\n if (role.tools) lines.push(`- tools: \\`${role.tools}\\``);\n if (role.agentsMd) lines.push('', '**rules (AGENTS.md):**', '', role.agentsMd);\n return lines.join('\\n');\n}\n\n/** `/role list` — list roles and the current scope binding. */\nasync function handleRoleList(ctx: CommandContext): Promise<void> {\n const roles = ctx.roleStore.list();\n const current = ctx.roleStore.roleForScope(ctx.scope);\n if (roles.length === 0) {\n await reply(ctx, '还没有定义角色。管理员可用 `/role save <id> <name> --persona <text>` 创建。');\n return;\n }\n const lines = roles.map((role) => {\n const marker = role.id === current?.id ? ' ← 当前 scope' : '';\n return `- \\`${role.id}\\` — **${role.name}**${marker}`;\n });\n await reply(ctx, ['**角色列表**', '', ...lines].join('\\n'));\n}\n\n/** `/role show <id>` — show role details. */\nasync function handleRoleShow(args: string, ctx: CommandContext): Promise<void> {\n const id = args.trim();\n const role = ctx.roleStore.get(id);\n if (!role) {\n await reply(ctx, `未找到角色:\\`${id}\\``);\n return;\n }\n await reply(ctx, describeRole(role));\n}\n\n/** `/role set <id>` / `/role clear` — bind or unbind the current scope. */\nasync function handleRoleSet(args: string, ctx: CommandContext): Promise<void> {\n const id = args.trim();\n if (!ctx.roleStore.setScopeRole(ctx.scope, id)) {\n await reply(ctx, `未找到角色:\\`${id}\\`,请先 \\`/role save\\` 创建。`);\n return;\n }\n await reply(ctx, `当前 scope 已绑定角色:\\`${id}\\`。下一轮消息生效。`);\n}\n\nasync function handleRoleClear(_args: string, ctx: CommandContext): Promise<void> {\n const cleared = ctx.roleStore.clearScopeRole(ctx.scope);\n await reply(ctx, cleared ? '已解除当前 scope 的角色绑定。' : '当前 scope 未绑定角色。');\n}\n\n/** `/role save <id> <name> [--persona ..] [--model ..] [--tools ..] [--rules ..]` — admin. */\nasync function handleRoleSave(args: string, ctx: CommandContext): Promise<void> {\n if (!requireAdmin(ctx)) return;\n const { positionals, flags } = parseRoleArgs(args);\n const [id, name] = positionals;\n if (!id || !name) {\n await reply(\n ctx,\n '用法:`/role save <id> <name> [--persona <text>] [--model <id>] [--tools <csv>] [--rules <text>]`',\n );\n return;\n }\n const existing = ctx.roleStore.get(id);\n const persona = flags.persona ?? existing?.persona;\n if (!persona) {\n await reply(ctx, '`--persona` 必填(或更新已有角色时省略以保留原 persona)。');\n return;\n }\n const model = flags.model ?? existing?.model;\n const tools = flags.tools ?? existing?.tools;\n const agentsMd = flags.rules ?? existing?.agentsMd;\n ctx.roleStore.upsert({\n id,\n name,\n persona,\n ...(model === undefined ? {} : { model }),\n ...(tools === undefined ? {} : { tools }),\n ...(agentsMd === undefined ? {} : { agentsMd }),\n });\n await reply(ctx, `角色已保存:\\`${id}\\`(${name})。`);\n}\n\n/** `/role remove <id>` — admin. */\nasync function handleRoleRemove(args: string, ctx: CommandContext): Promise<void> {\n if (!requireAdmin(ctx)) return;\n const id = args.trim();\n const removed = ctx.roleStore.remove(id);\n await reply(ctx, removed ? `已删除角色:\\`${id}\\`(相关 scope 绑定一并清除)。` : `未找到角色:\\`${id}\\``);\n}\n\nexport async function handleRole(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n switch (sub) {\n case 'list':\n case undefined:\n case '':\n await handleRoleList(ctx);\n return;\n case 'show':\n await handleRoleShow(rest.join(' ').trim(), ctx);\n return;\n case 'set':\n await handleRoleSet(rest.join(' ').trim(), ctx);\n return;\n case 'clear':\n await handleRoleClear('', ctx);\n return;\n case 'save':\n await handleRoleSave(rest.join(' ').trim(), ctx);\n return;\n case 'remove':\n await handleRoleRemove(rest.join(' ').trim(), ctx);\n return;\n default:\n await reply(ctx, '未知 `/role` 子命令,请使用 list / show / set / clear / save / remove。');\n }\n}\n","import type { CommandContext } from './index.js';\n\nasync function reply(ctx: CommandContext, markdown: string): Promise<void> {\n await ctx.channel.sendMarkdown(ctx.chatId, markdown, {\n replyTo: ctx.messageId,\n });\n}\n\n/** `/notify <scope|chatId> <text>` — admin-only cross-session messaging. */\nasync function handleNotifySend(args: string, ctx: CommandContext): Promise<void> {\n if (!ctx.accessManager.isAdmin(ctx.senderId)) {\n await reply(ctx, '仅管理员可执行该操作。');\n return;\n }\n const match = args.trim().match(/^(\\S+)\\s+([\\s\\S]+)$/);\n if (!match) {\n await reply(ctx, '用法:`/notify <scope|chatId> <text>`');\n return;\n }\n const target = match[1] ?? '';\n const text = match[2]?.trim() ?? '';\n if (!text) {\n await reply(ctx, '用法:`/notify <scope|chatId> <text>`');\n return;\n }\n\n const destination =\n ctx.scopeDirectory.resolve(target) ?? ctx.scopeDirectory.resolveChat(target);\n if (!destination) {\n await reply(\n ctx,\n `未知的目标 scope/chat:\\`${target}\\`。可用 \\`/notify list\\` 查看已注册的 scope。`,\n );\n return;\n }\n await ctx.channel.sendMarkdown(destination.chatId, text, {\n ...(destination.threadId ? { threadId: destination.threadId } : {}),\n });\n await reply(ctx, `已发送通知到 \\`${target}\\`(chat \\`${destination.chatId}\\`)。`);\n}\n\n/** `/notify list` — show every scope known to the bridge. */\nasync function handleNotifyList(_args: string, ctx: CommandContext): Promise<void> {\n const scopes = ctx.scopeDirectory.knownScopes();\n if (scopes.length === 0) {\n await reply(ctx, '暂无已注册的 scope(至少需要一个会话发过消息)。');\n return;\n }\n const lines = scopes.map((scope) => {\n const entry = ctx.scopeDirectory.resolve(scope);\n return `- \\`${scope}\\` → chat \\`${entry?.chatId ?? ''}\\`${entry?.threadId ? ` / thread \\`${entry.threadId}\\`` : ''}`;\n });\n await reply(ctx, ['**已注册 scope**', '', ...lines].join('\\n'));\n}\n\nexport async function handleNotify(args: string, ctx: CommandContext): Promise<void> {\n const [sub, ...rest] = args.trim().split(/\\s+/);\n if (sub === 'list') {\n await handleNotifyList(rest.join(' ').trim(), ctx);\n return;\n }\n await handleNotifySend(args, ctx);\n}\n","import type {\n CardStreamController as LarkCardStreamController,\n LarkChannel,\n MentionInfo,\n SendOptions,\n} from '@larksuite/channel';\nimport type { CommandChannel } from '../commands/index.js';\nimport type { StreamingChannel } from './types.js';\nimport type { MentionTarget, SendOptions as BridgeSendOptions } from './send-options.js';\n\nfunction toLarkSendOptions(options: BridgeSendOptions | undefined): SendOptions {\n const sendOptions: SendOptions = {};\n if (options?.replyTo) sendOptions.replyTo = options.replyTo;\n if (options?.threadId) sendOptions.replyInThread = true;\n if (options?.mentions && options.mentions.length > 0) {\n sendOptions.mentions = options.mentions\n .map((mention: MentionTarget): MentionInfo | undefined => ({\n key: `out-${mention.userId}`,\n ...(mention.userId.startsWith('ou_') || mention.userId.startsWith('on_')\n ? { openId: mention.userId }\n : { userId: mention.userId }),\n ...(mention.name === undefined ? {} : { name: mention.name }),\n }))\n .filter((mention): mention is MentionInfo => mention !== undefined);\n }\n return sendOptions;\n}\n\nexport function adaptLarkChannel(channel: LarkChannel): StreamingChannel {\n const base: CommandChannel = {\n async sendMarkdown(chatId, markdown, options) {\n await channel.send(chatId, { markdown }, toLarkSendOptions(options));\n },\n };\n\n return {\n ...base,\n async sendCard(chatId, card, options) {\n await channel.send(chatId, { card }, toLarkSendOptions(options));\n },\n async streamCard(chatId, initial, producer, options) {\n await channel.stream(\n chatId,\n {\n card: {\n initial,\n producer: async (controller: LarkCardStreamController) => {\n await producer(controller);\n },\n },\n },\n toLarkSendOptions(options),\n );\n },\n };\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface ScopeEntry {\n scope: string;\n chatId: string;\n threadId: string | undefined;\n lastSeenAt: string;\n}\n\ninterface ScopeData {\n entries: Record<string, ScopeEntry>;\n}\n\n/**\n * Persistent scope → chat/thread directory. Every inbound message registers\n * its scope, so the bridge can later push outbound notifications to other\n * chats/topics (cross-session messaging). Persisted per profile at\n * `<profile>/scopes.json` so targets survive restarts.\n */\nexport class ScopeDirectory {\n private data: ScopeData = { entries: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<ScopeData>;\n this.data = { entries: parsed.entries ?? {} };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error;\n this.data = { entries: {} };\n }\n }\n\n register(scope: string, chatId: string, threadId: string | undefined): void {\n const existing = this.data.entries[scope];\n this.data.entries[scope] = {\n scope,\n chatId,\n threadId: threadId ?? existing?.threadId,\n lastSeenAt: new Date().toISOString(),\n };\n this.schedulePersist();\n }\n\n /** Resolve a scope key to its chat destination. */\n resolve(scope: string): { chatId: string; threadId: string | undefined } | undefined {\n const entry = this.data.entries[scope];\n if (!entry) return undefined;\n return { chatId: entry.chatId, threadId: entry.threadId };\n }\n\n /** Direct chat lookup by chatId (also matches topic scopes by prefix). */\n resolveChat(chatId: string): { chatId: string; threadId: string | undefined } | undefined {\n if (this.data.entries[chatId]) return this.resolve(chatId);\n const entry = Object.values(this.data.entries).find((item) => item.chatId === chatId);\n return entry ? { chatId: entry.chatId, threadId: entry.threadId } : undefined;\n }\n\n knownScopes(): string[] {\n return Object.keys(this.data.entries);\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = {\n entries: Object.fromEntries(\n Object.entries(this.data.entries).map(([scope, entry]) => [\n scope,\n { ...entry },\n ]),\n ),\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('scope-directory', error, { step: 'persist' });\n });\n }\n}\n","import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport { randomBytes } from 'node:crypto';\nimport { log } from '../core/logger.js';\nimport type { MentionTarget } from '../bridge/types.js';\n\nexport interface NotifyMessage {\n token: string;\n /** Scope key (chat id or `chat:thread`); resolved via the scope directory. */\n scope?: string;\n /** Direct chat id fallback when scope is unknown. */\n chatId?: string;\n threadId?: string;\n text: string;\n mentions?: MentionTarget[];\n}\n\nexport interface NotifyDestination {\n chatId: string;\n threadId: string | undefined;\n}\n\nexport interface NotifyServerDeps {\n token: string;\n port?: number;\n /** Resolve a scope/chat target to a concrete chat destination. */\n resolve: (message: NotifyMessage) => NotifyDestination | undefined;\n /** Send the outbound message (mentions supported). */\n send: (\n destination: NotifyDestination,\n payload: { text: string; mentions?: MentionTarget[] },\n ) => Promise<void>;\n}\n\n/**\n * Localhost-only callback server for the dsh `lark_notify` tool. The dsh\n * runtime (a child process) calls back into the bridge process over\n * `http://127.0.0.1:<port>/notify` with a shared token, so agents can mention\n * users and push messages to other chats/topics without exposing anything to\n * the network.\n */\nexport class NotifyServer {\n private server: Server | undefined;\n private readonly token: string;\n private readonly deps: NotifyServerDeps;\n url: string | undefined;\n\n constructor(deps: NotifyServerDeps) {\n this.deps = deps;\n this.token = deps.token;\n }\n\n async start(): Promise<void> {\n if (this.server) return;\n const server = createServer((req, res) => {\n void this.handle(req, res);\n });\n this.server = server;\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(this.deps.port ?? 0, '127.0.0.1', () => {\n const address = server.address() as AddressInfo;\n this.url = `http://127.0.0.1:${String(address.port)}/notify`;\n resolve();\n });\n });\n log.info('notify', 'server-started', { url: this.url });\n }\n\n async stop(): Promise<void> {\n const server = this.server;\n this.server = undefined;\n if (!server) return;\n await new Promise<void>((resolve) => {\n server.close(() => resolve());\n server.closeAllConnections?.();\n });\n }\n\n private async handle(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const respond = (status: number, body: Record<string, unknown>): void => {\n res.writeHead(status, { 'content-type': 'application/json' });\n res.end(`${JSON.stringify(body)}\\n`);\n };\n if (req.method !== 'POST' || req.url !== '/notify') {\n respond(404, { ok: false, error: 'not found' });\n return;\n }\n try {\n const body = await readBody(req);\n const message = JSON.parse(body) as NotifyMessage;\n if (message.token !== this.token) {\n respond(401, { ok: false, error: 'invalid token' });\n return;\n }\n if (!message.text?.trim()) {\n respond(400, { ok: false, error: 'text is required' });\n return;\n }\n const destination = this.deps.resolve(message);\n if (!destination) {\n respond(404, { ok: false, error: `unknown scope/chat: ${message.scope ?? message.chatId ?? ''}` });\n return;\n }\n await this.deps.send(destination, {\n text: message.text,\n ...(message.mentions === undefined ? {} : { mentions: message.mentions }),\n });\n respond(200, { ok: true, chatId: destination.chatId, threadId: destination.threadId ?? null });\n } catch (error) {\n log.fail('notify', error);\n respond(500, { ok: false, error: error instanceof Error ? error.message : String(error) });\n }\n }\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n if (chunks.reduce((size, item) => size + item.length, 0) > 1_000_000) {\n reject(new Error('payload too large'));\n req.destroy();\n }\n });\n req.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));\n req.on('error', reject);\n });\n}\n\nexport function generateNotifyToken(): string {\n return `dsh-lark-${randomBytes(18).toString('hex')}`;\n}\n","import type { ConfigStore, ProfileConfig } from './profile-store.js';\n\nexport interface AccessSnapshot {\n allowedUsers: string[];\n allowedChats: string[];\n admins: string[];\n}\n\nexport class AccessManager {\n constructor(\n private readonly store: ConfigStore,\n private readonly profileName: string,\n ) {}\n\n snapshot(): AccessSnapshot {\n const profile = this.profile();\n return {\n allowedUsers: [...profile.access.allowedUsers],\n allowedChats: [...profile.access.allowedChats],\n admins: [...profile.access.admins],\n };\n }\n\n isAdmin(openId: string | undefined): boolean {\n return Boolean(openId && this.snapshot().admins.includes(openId));\n }\n\n async addUser(id: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);\n await this.persist(snapshot);\n }\n\n async addAdmin(id: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedUsers.includes(id)) snapshot.allowedUsers.push(id);\n if (!snapshot.admins.includes(id)) snapshot.admins.push(id);\n await this.persist(snapshot);\n }\n\n async addChat(chatId: string): Promise<void> {\n const snapshot = this.snapshot();\n if (!snapshot.allowedChats.includes(chatId)) snapshot.allowedChats.push(chatId);\n await this.persist(snapshot);\n }\n\n async removeUser(id: string): Promise<void> {\n const snapshot = this.snapshot();\n snapshot.allowedUsers = snapshot.allowedUsers.filter((item) => item !== id);\n snapshot.admins = snapshot.admins.filter((item) => item !== id);\n await this.persist(snapshot);\n }\n\n async removeChat(chatId: string): Promise<void> {\n const snapshot = this.snapshot();\n snapshot.allowedChats = snapshot.allowedChats.filter((item) => item !== chatId);\n await this.persist(snapshot);\n }\n\n private profile(): ProfileConfig {\n const profile = this.store.getProfile(this.profileName);\n if (!profile) throw new Error(`profile not found: ${this.profileName}`);\n return profile;\n }\n\n private async persist(snapshot: AccessSnapshot): Promise<void> {\n const profile = this.profile();\n await this.store.saveProfile(this.profileName, {\n tenant: profile.tenant,\n appId: profile.accounts.appId,\n appSecret: profile.accounts.appSecret,\n access: snapshot,\n });\n }\n}\n","import { registerApp, type RegisterAppOptions, type RegisterAppResult } from '@larksuite/channel';\nimport qrcode from 'qrcode-terminal';\nimport type { LarkTenant } from '../config/env.js';\n\nexport interface OnboardedApp {\n appId: string;\n appSecret: string;\n tenant: LarkTenant;\n operatorOpenId: string | undefined;\n}\n\nexport interface RegistrationDeps {\n register?: (options: RegisterAppOptions) => Promise<RegisterAppResult>;\n renderQr?: (value: string) => void;\n print?: (line: string) => void;\n source?: string;\n signal?: AbortSignal;\n}\n\nconst DEFAULT_SOURCE = 'dsh-lark-bot';\n\nexport async function onboardPersonalAgent(\n deps: RegistrationDeps = {},\n): Promise<OnboardedApp> {\n const register = deps.register ?? registerApp;\n const renderQr = deps.renderQr ?? ((value) => qrcode.generate(value, { small: true }));\n const print = deps.print ?? ((line) => process.stdout.write(`${line}\\n`));\n\n print('');\n print('未检测到飞书 / Lark 应用凭据,进入扫码创建向导。');\n print('');\n\n const result = await register({\n source: deps.source ?? DEFAULT_SOURCE,\n ...(deps.signal ? { signal: deps.signal } : {}),\n onQRCodeReady: (info) => {\n print('请使用飞书 / Lark App 扫描以下二维码,创建或选择 PersonalAgent 应用:');\n print('');\n renderQr(info.url);\n print('');\n const minutes = Math.max(1, Math.round(info.expireIn / 60));\n print(`二维码有效期约 ${minutes} 分钟。`);\n print(`也可以直接在浏览器打开:${info.url}`);\n print('');\n },\n onStatusChange: (info) => {\n if (info.status === 'domain_switched') {\n print('已识别到国际版租户,自动切换到 larksuite.com 域名。');\n } else if (info.status === 'slow_down') {\n print('轮询速度过快,已自动降速。');\n }\n },\n });\n\n const tenant: LarkTenant = result.user_info?.tenant_brand === 'lark' ? 'lark' : 'feishu';\n\n print('✓ PersonalAgent 应用创建 / 绑定成功。');\n print(` App ID: ${result.client_id}`);\n print(` Tenant: ${tenant}`);\n print('');\n\n return {\n appId: result.client_id,\n appSecret: result.client_secret,\n tenant,\n operatorOpenId: result.user_info?.open_id,\n };\n}\n","import { mkdir, readFile, stat } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { isPathWithin, truncateUtf8Safe } from '../config/security.js';\nimport type {\n LarkChannel,\n NormalizedMessage,\n} from '@larksuite/channel';\n\nexport interface PreparedAttachments {\n imagePaths: string[];\n textFileNotes: string[];\n}\n\nconst MAX_TEXT_FILE_BYTES = 256_000;\n\nfunction assertSafeMediaName(mediaDir: string, destination: string): void {\n if (!isPathWithin(mediaDir, destination)) {\n throw new Error(`unsafe attachment destination rejected: ${destination}`);\n }\n}\n\nexport async function prepareAttachments(\n channel: LarkChannel | undefined,\n message: NormalizedMessage,\n mediaDir: string,\n): Promise<PreparedAttachments> {\n await mkdir(mediaDir, { recursive: true });\n const result: PreparedAttachments = { imagePaths: [], textFileNotes: [] };\n\n for (const resource of message.resources) {\n if (!channel || resource.type !== 'image' && resource.type !== 'file') continue;\n const destination = join(mediaDir, `${message.messageId}-${resource.fileKey}`);\n assertSafeMediaName(mediaDir, destination);\n await channel.downloadResourceToFile(\n message.messageId,\n resource.fileKey,\n resource.type,\n destination,\n );\n\n if (resource.type === 'image') {\n result.imagePaths.push(destination);\n continue;\n }\n\n const info = await stat(destination);\n if (info.size > MAX_TEXT_FILE_BYTES) {\n result.textFileNotes.push(`[attachment: ${resource.fileName ?? resource.fileKey}] ${destination}`);\n continue;\n }\n\n const content = await readFile(destination, 'utf8');\n const safeContent = truncateUtf8Safe(content, MAX_TEXT_FILE_BYTES);\n result.textFileNotes.push(\n `[attachment: ${resource.fileName ?? resource.fileKey}]\\n${safeContent}`,\n );\n }\n\n return result;\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\nexport interface SessionRecord {\n sessionId: string | undefined;\n cwd: string;\n messages: ChatMessage[];\n}\n\nexport interface ChatMessage {\n role: 'user' | 'assistant';\n content: string;\n}\n\nexport interface RecordExchangeOptions {\n /** Max live messages kept for the scope (overflow is archived, then trimmed). */\n retention?: number;\n /** Called with the messages that fall outside the retention window. */\n onArchive?: (overflow: ChatMessage[]) => void | Promise<void>;\n}\n\ninterface SessionData {\n chats: Record<string, SessionRecord>;\n}\n\nexport class SessionStore {\n private data: SessionData = { chats: {} };\n private saving: Promise<void> = Promise.resolve();\n private pendingArchive: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<SessionData>;\n this.data = {\n chats: Object.fromEntries(\n Object.entries(parsed.chats ?? {}).map(([scope, record]) => [\n scope,\n {\n sessionId: record.sessionId,\n cwd: record.cwd,\n messages: record.messages ?? [],\n },\n ]),\n ),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n getRaw(scopeId: string): SessionRecord | undefined {\n return this.data.chats[scopeId];\n }\n\n set(scopeId: string, sessionId: string | undefined, cwd: string): void {\n const existing = this.data.chats[scopeId];\n this.data.chats[scopeId] = {\n sessionId: sessionId ?? existing?.sessionId,\n cwd,\n messages: existing?.messages ?? [],\n };\n this.schedulePersist();\n }\n\n historyFor(scopeId: string, cwd: string): ChatMessage[] {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.messages : [];\n }\n\n recordExchange(\n scopeId: string,\n cwd: string,\n userMessages: string[],\n assistantMessage: string | undefined,\n options: RecordExchangeOptions = {},\n ): void {\n const existing = this.data.chats[scopeId];\n const next: ChatMessage[] = [...(existing?.messages ?? [])];\n\n for (const content of userMessages) {\n if (content.trim()) next.push({ role: 'user', content });\n }\n\n if (assistantMessage?.trim()) {\n next.push({ role: 'assistant', content: assistantMessage });\n }\n\n const retention = options.retention ?? 40;\n let kept: ChatMessage[] = next;\n if (retention > 0 && next.length > retention) {\n const overflow = next.slice(0, next.length - retention);\n kept = next.slice(-retention);\n this.pendingArchive = this.pendingArchive\n .then(async () => {\n await options.onArchive?.(overflow);\n })\n .catch((error: unknown) => {\n log.fail('session', error, { scope: scopeId, step: 'archive-overflow' });\n });\n }\n\n this.data.chats[scopeId] = {\n sessionId: existing?.sessionId,\n cwd,\n messages: kept,\n };\n this.schedulePersist();\n }\n\n /** Full live transcript for a scope (subject to the current retention window). */\n fullHistoryFor(scopeId: string, cwd: string): ChatMessage[] {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? [...record.messages] : [];\n }\n\n clear(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n fork(scopeId: string, newScopeId: string, cwd: string): boolean {\n const source = this.data.chats[scopeId];\n if (!source) return false;\n this.data.chats[newScopeId] = {\n sessionId: undefined,\n cwd,\n messages: [...source.messages],\n };\n this.schedulePersist();\n return true;\n }\n\n resumeFor(scopeId: string, cwd: string): string | undefined {\n const record = this.data.chats[scopeId];\n return record && record.cwd === cwd ? record.sessionId : undefined;\n }\n\n async flush(): Promise<void> {\n await this.pendingArchive;\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot = this.snapshot();\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('session', error, { step: 'persist' });\n });\n }\n\n private snapshot(): SessionData {\n return {\n chats: Object.fromEntries(\n Object.entries(this.data.chats).map(([key, record]) => [\n key,\n {\n ...record,\n messages: [...record.messages],\n },\n ]),\n ),\n };\n }\n}\n","import { execFile } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { access, mkdir, readdir, readFile, unlink, writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { promisify } from 'node:util';\nimport { log } from '../core/logger.js';\nimport type { ChatMessage } from './store.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport type ArchiveSource = 'manual' | 'retention';\n\nexport interface ArchiveRecord {\n /** Stable archive id: `20260815T020000Z-<short hex>`. */\n archiveId: string;\n scope: string;\n cwd: string | undefined;\n source: ArchiveSource;\n note: string | undefined;\n messageCount: number;\n archivedAt: string;\n jsonlPath: string;\n markdownPath: string;\n gitCommit: string | undefined;\n}\n\nexport interface ArchiveInput {\n scope: string;\n cwd: string | undefined;\n messages: readonly ChatMessage[];\n source?: ArchiveSource;\n note?: string;\n}\n\nexport interface ArchivePruneOptions {\n /** Keep at most this many archives per scope (oldest removed first). */\n maxArchives?: number;\n /** Remove archives older than this many milliseconds. */\n maxAgeMs?: number;\n}\n\nfunction slugify(scope: string): string {\n const slug = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^[.]+/, '')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64);\n return slug || 'session';\n}\n\nfunction timestampId(): string {\n const stamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\\.\\d{3}/, '');\n return `${stamp}-${randomBytes(3).toString('hex')}`;\n}\n\nfunction renderMarkdown(\n input: ArchiveInput,\n record: { archiveId: string; archivedAt: string; source: ArchiveSource },\n): string {\n const lines: string[] = [\n `# dsh-lark-bot 会话归档 · Session Archive`,\n '',\n `- archiveId: \\`${record.archiveId}\\``,\n `- scope: \\`${input.scope}\\``,\n ...(input.cwd ? [`- cwd: \\`${input.cwd}\\``] : []),\n `- source: ${record.source}`,\n `- archivedAt: ${record.archivedAt}`,\n ...(input.note ? [`- note: ${input.note}`] : []),\n '',\n ];\n if (input.messages.length === 0) {\n lines.push('*(no messages)*');\n }\n for (const message of input.messages) {\n const speaker =\n message.role === 'user'\n ? 'User'\n : 'Assistant';\n lines.push(`## ${speaker}`, '', message.content, '');\n }\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction renderJsonl(input: ArchiveInput, record: { archiveId: string; archivedAt: string; source: ArchiveSource }): string {\n const header = {\n type: 'dsh-lark-archive',\n schemaVersion: 1,\n archiveId: record.archiveId,\n scope: input.scope,\n cwd: input.cwd,\n source: record.source,\n note: input.note,\n archivedAt: record.archivedAt,\n };\n const rows = [\n JSON.stringify(header),\n ...input.messages.map((message) =>\n JSON.stringify({\n role: message.role,\n content: message.content,\n }),\n ),\n ];\n return `${rows.join('\\n')}\\n`;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Durable session/task archival: every archive is written as a human-readable\n * Markdown transcript plus a machine-readable JSONL payload under\n * `<profile>/archives/<scope-slug>/`. When `git` is available, the archive\n * root is lazily initialized as its own Git repository and each archive is\n * committed, giving an auditable, replayable history that survives local\n * retention trimming.\n */\nexport class SessionArchive {\n private gitInitialized: boolean | undefined;\n\n constructor(\n private readonly archiveDir: string,\n private readonly runGit: (args: string[], cwd: string) => Promise<string> = defaultRunGit,\n ) {}\n\n async archive(input: ArchiveInput): Promise<ArchiveRecord> {\n const scopeSlug = slugify(input.scope);\n const id = timestampId();\n const archivedAt = new Date().toISOString();\n const source = input.source ?? 'manual';\n const scopeDir = join(this.archiveDir, scopeSlug);\n const jsonlPath = join(scopeDir, `${id}.jsonl`);\n const markdownPath = join(scopeDir, `${id}.md`);\n await mkdir(scopeDir, { recursive: true });\n await Promise.all([\n writeFile(jsonlPath, renderJsonl(input, { archiveId: id, archivedAt, source }), 'utf8'),\n writeFile(\n markdownPath,\n renderMarkdown(input, { archiveId: id, archivedAt, source }),\n 'utf8',\n ),\n ]);\n\n let gitCommit: string | undefined;\n try {\n await this.ensureGit();\n await this.runGit(['add', '-A', '.'], this.archiveDir);\n await this.runGit(\n ['commit', '-m', `archive ${id} (${source}, ${String(input.messages.length)} messages)`, '--no-verify'],\n this.archiveDir,\n );\n gitCommit = (await this.runGit(['rev-parse', '--short', 'HEAD'], this.archiveDir)).trim();\n } catch (error) {\n // Git is an optional transport: files are already durable on disk.\n log.warn('archive', 'git-commit-failed', {\n scope: input.scope,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n\n return {\n archiveId: id,\n scope: input.scope,\n cwd: input.cwd,\n source,\n note: input.note,\n messageCount: input.messages.length,\n archivedAt,\n jsonlPath,\n markdownPath,\n gitCommit,\n };\n }\n\n async list(scope?: string): Promise<ArchiveRecord[]> {\n const records: ArchiveRecord[] = [];\n const scopeDirs: Array<{ name: string; dir: string }> = [];\n if (scope === undefined) {\n if (!(await exists(this.archiveDir))) return [];\n for (const entry of await readdir(this.archiveDir, { withFileTypes: true })) {\n if (!entry.isDirectory()) continue;\n scopeDirs.push({ name: entry.name, dir: join(this.archiveDir, entry.name) });\n }\n } else {\n const dir = join(this.archiveDir, slugify(scope));\n if (!(await exists(dir))) return [];\n scopeDirs.push({ name: slugify(scope), dir });\n }\n for (const entry of scopeDirs) {\n const dir = entry.dir;\n const files = await readdir(dir);\n for (const file of files) {\n if (!file.endsWith('.md')) continue;\n const id = file.slice(0, -'.md'.length);\n const markdownPath = join(dir, file);\n const jsonlPath = join(dir, `${id}.jsonl`);\n const header = await readArchiveHeader(jsonlPath);\n if (!header) continue;\n records.push({\n archiveId: id,\n scope: header.scope ?? entry.name,\n cwd: header.cwd,\n source: header.source ?? 'manual',\n note: header.note,\n messageCount: header.messageCount ?? 0,\n archivedAt: header.archivedAt ?? '',\n jsonlPath,\n markdownPath,\n gitCommit: undefined,\n });\n }\n }\n return records.sort(\n (a, b) =>\n b.archivedAt.localeCompare(a.archivedAt) ||\n b.archiveId.localeCompare(a.archiveId),\n );\n }\n\n /** Remove archives beyond per-scope count/age limits. Returns the number removed. */\n async prune(options: ArchivePruneOptions = {}): Promise<number> {\n const records = await this.list();\n const byScope = new Map<string, ArchiveRecord[]>();\n for (const record of records) {\n const bucket = byScope.get(record.scope) ?? [];\n bucket.push(record);\n byScope.set(record.scope, bucket);\n }\n const now = Date.now();\n let removed = 0;\n for (const [scope, scoped] of byScope) {\n // Newest first: prune from the oldest end while keeping the newest\n // `maxArchives` records within the age window.\n const ordered = [...scoped].sort(\n (a, b) =>\n b.archivedAt.localeCompare(a.archivedAt) ||\n b.archiveId.localeCompare(a.archiveId),\n );\n const keep: ArchiveRecord[] = [];\n let keptCount = 0;\n for (const record of ordered) {\n const tooOld =\n options.maxAgeMs !== undefined &&\n record.archivedAt !== '' &&\n now - Date.parse(record.archivedAt) > options.maxAgeMs;\n const beyondCount =\n options.maxArchives !== undefined &&\n keptCount >= options.maxArchives;\n if (tooOld || beyondCount) {\n await safeRemove(record.markdownPath);\n await safeRemove(record.jsonlPath);\n removed += 1;\n log.info('archive', 'pruned', { scope, archiveId: record.archiveId });\n } else {\n keep.push(record);\n keptCount += 1;\n }\n }\n }\n if (removed > 0) {\n try {\n await this.ensureGit();\n await this.runGit(['add', '-A', '.'], this.archiveDir);\n await this.runGit(['commit', '-m', `prune ${String(removed)} archives`, '--no-verify'], this.archiveDir);\n } catch (error) {\n log.warn('archive', 'git-prune-commit-failed', {\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n return removed;\n }\n\n private async ensureGit(): Promise<void> {\n if (this.gitInitialized !== undefined) return;\n await mkdir(this.archiveDir, { recursive: true });\n if (!(await exists(join(this.archiveDir, '.git')))) {\n await this.runGit(['init', '-q'], this.archiveDir);\n try {\n await this.runGit(['config', 'user.name', 'dsh-lark-bot'], this.archiveDir);\n await this.runGit(['config', 'user.email', 'dsh-lark-bot@localhost'], this.archiveDir);\n } catch {\n // Local git identity is optional; commits fall back to global config.\n }\n }\n this.gitInitialized = true;\n }\n}\n\nasync function defaultRunGit(args: string[], cwd: string): Promise<string> {\n const result = await execFileAsync('git', args, { cwd, encoding: 'utf8' });\n return result.stdout;\n}\n\ninterface ArchiveHeader {\n scope?: string;\n cwd?: string;\n source?: ArchiveSource;\n note?: string;\n messageCount?: number;\n archivedAt?: string;\n}\n\nasync function readArchiveHeader(jsonlPath: string): Promise<ArchiveHeader | undefined> {\n try {\n const raw = await readFile(jsonlPath, 'utf8');\n const firstLine = raw.split('\\n', 1)[0];\n if (!firstLine) return undefined;\n const header = JSON.parse(firstLine) as Record<string, unknown>;\n if (header.type !== 'dsh-lark-archive') return undefined;\n const parsed: ArchiveHeader = {};\n if (typeof header.scope === 'string') parsed.scope = header.scope;\n if (typeof header.cwd === 'string') parsed.cwd = header.cwd;\n if (header.source === 'manual' || header.source === 'retention') parsed.source = header.source;\n if (typeof header.note === 'string') parsed.note = header.note;\n if (typeof header.messageCount === 'number') parsed.messageCount = header.messageCount;\n if (typeof header.archivedAt === 'string') parsed.archivedAt = header.archivedAt;\n return parsed;\n } catch {\n return undefined;\n }\n}\n\nasync function safeRemove(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch {\n // Best effort; the archive file may already be gone.\n }\n}\n\nexport function archiveDisplay(record: ArchiveRecord): string {\n const commit = record.gitCommit ? ` (git ${record.gitCommit})` : '';\n return `\\`${record.archiveId}\\` · ${record.messageCount} msgs · ${record.source}${commit}`;\n}\n","import { execFile } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { access, copyFile, mkdir } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { promisify } from 'node:util';\nimport { isPathWithin } from '../config/security.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport type GitRunner = (args: string[], cwd: string) => Promise<string>;\n\nexport interface WorktreeEnsureResult {\n cwd: string;\n created: boolean;\n branch?: string;\n}\n\nexport interface GitWorktreeOptions {\n worktreesRoot: string;\n runGit?: GitRunner;\n copyRulesFile?: (source: string, target: string) => Promise<void>;\n}\n\nasync function defaultRunGit(args: string[], cwd: string): Promise<string> {\n const result = await execFileAsync('git', args, {\n cwd,\n encoding: 'utf8',\n });\n return result.stdout;\n}\n\nasync function exists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n}\n\nasync function defaultCopyRulesFile(source: string, target: string): Promise<void> {\n await mkdir(dirname(target), { recursive: true });\n await copyFile(source, target);\n}\n\nfunction slugify(scope: string): string {\n const slug = scope\n .trim()\n .replace(/[^a-zA-Z0-9._-]+/g, '-')\n .replace(/^[.]+/, '')\n .replace(/^-+|-+$/g, '')\n .slice(0, 64);\n return slug || 'session';\n}\n\nexport class GitWorktreeManager {\n private readonly runGit: GitRunner;\n private readonly copyRulesFile: (source: string, target: string) => Promise<void>;\n\n constructor(private readonly options: GitWorktreeOptions) {\n this.runGit = options.runGit ?? defaultRunGit;\n this.copyRulesFile = options.copyRulesFile ?? defaultCopyRulesFile;\n }\n\n async ensure(scope: string, base: string): Promise<WorktreeEnsureResult> {\n const isGit = await this.isGitRepository(base);\n if (!isGit) return { cwd: base, created: false };\n\n const slug = slugify(scope);\n const target = join(this.options.worktreesRoot, slug);\n if (!isPathWithin(this.options.worktreesRoot, target)) {\n throw new Error(`unsafe worktree target rejected: ${target}`);\n }\n if (await exists(target)) {\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: false };\n }\n\n const branch = `dsh-lark/${slug}-${Date.now().toString(36)}-${randomBytes(3).toString('hex')}`;\n await mkdir(this.options.worktreesRoot, { recursive: true });\n await this.runGit(['worktree', 'add', '-b', branch, target, 'HEAD'], base);\n await this.ensureProjectRules(base, target);\n return { cwd: target, created: true, branch };\n }\n\n async isGitRepository(cwd: string): Promise<boolean> {\n try {\n const result = await this.runGit(['rev-parse', '--is-inside-work-tree'], cwd);\n return result.trim() === 'true';\n } catch {\n return false;\n }\n }\n\n private async ensureProjectRules(base: string, target: string): Promise<void> {\n const destination = join(target, 'AGENTS.md');\n if (await exists(destination)) return;\n\n const sourceCandidates = [join(base, '.dsh-lark', 'AGENTS.md'), join(base, 'AGENTS.md')];\n for (const source of sourceCandidates) {\n if (await exists(source)) {\n await this.copyRulesFile(source, destination);\n return;\n }\n }\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\nimport { log } from '../core/logger.js';\n\ninterface WorkspaceData {\n chats: Record<string, { cwd: string }>;\n named: Record<string, string>;\n lastUsed: Record<string, number>;\n}\n\nexport class WorkspaceStore {\n private data: WorkspaceData = { chats: {}, named: {}, lastUsed: {} };\n private saving: Promise<void> = Promise.resolve();\n private readonly path: string;\n\n constructor(path: string) {\n this.path = path;\n }\n\n async load(): Promise<void> {\n try {\n const raw = await readFile(this.path, 'utf8');\n const parsed = JSON.parse(raw) as Partial<WorkspaceData>;\n this.data = {\n chats: parsed.chats ?? {},\n named: parsed.named ?? {},\n lastUsed: parsed.lastUsed ?? {},\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return;\n throw error;\n }\n }\n\n cwdFor(scopeId: string): string | undefined {\n return this.data.chats[scopeId]?.cwd;\n }\n\n setCwd(scopeId: string, cwd: string): void {\n this.data.chats[scopeId] = { cwd };\n this.schedulePersist();\n }\n\n removeCwd(scopeId: string): boolean {\n if (!(scopeId in this.data.chats)) return false;\n delete this.data.chats[scopeId];\n this.schedulePersist();\n return true;\n }\n\n listNamed(): Record<string, string> {\n return { ...this.data.named };\n }\n\n getNamed(name: string): string | undefined {\n return this.data.named[name];\n }\n\n saveNamed(name: string, cwd: string): void {\n this.data.named[name] = cwd;\n this.data.lastUsed[name] = Date.now();\n this.schedulePersist();\n }\n\n touchNamed(name: string): void {\n if (!(name in this.data.named)) return;\n this.data.lastUsed[name] = Date.now();\n this.schedulePersist();\n }\n\n removeNamed(name: string): boolean {\n if (!(name in this.data.named)) return false;\n delete this.data.named[name];\n delete this.data.lastUsed[name];\n this.schedulePersist();\n return true;\n }\n\n listIndex(): Array<{ name: string; cwd: string; lastUsed: number | undefined }> {\n return Object.entries(this.data.named)\n .map(([name, cwd]) => ({ name, cwd, lastUsed: this.data.lastUsed[name] }))\n .sort((a, b) => (b.lastUsed ?? 0) - (a.lastUsed ?? 0));\n }\n\n async flush(): Promise<void> {\n await this.saving;\n }\n\n private schedulePersist(): void {\n const snapshot: WorkspaceData = {\n chats: { ...this.data.chats },\n named: { ...this.data.named },\n lastUsed: { ...this.data.lastUsed },\n };\n this.saving = this.saving\n .then(async () => {\n await writeFileAtomic(this.path, `${JSON.stringify(snapshot, null, 2)}\\n`, {\n mode: 0o600,\n });\n })\n .catch((error: unknown) => {\n log.fail('workspace', error, { step: 'persist' });\n });\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\n\n/**\n * Safety-net guardian heartbeat.\n *\n * The bridge engine (running inside the dsh process) writes a small JSON\n * heartbeat file under the bridge profile directory every few seconds. The\n * guardian — a separate, minimal process — only trusts a fresh heartbeat (or\n * a live dsh process) as \"dsh is up\"; when the heartbeat goes stale AND no\n * dsh process is observable, the guardian takes over the Feishu channel.\n *\n * The heartbeat is deliberately tiny and dependency-free so the guardian can\n * read it without importing the bridge, sessions, adapters or any plugin.\n */\n\nexport interface HeartbeatPayload {\n pid: number;\n startedAt: string;\n ts: number;\n}\n\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 5_000;\n\nexport async function readHeartbeat(\n file: string,\n): Promise<HeartbeatPayload | undefined> {\n try {\n const raw = await readFile(file, 'utf8');\n const parsed = JSON.parse(raw) as Partial<HeartbeatPayload>;\n if (\n typeof parsed.pid !== 'number' ||\n typeof parsed.startedAt !== 'string' ||\n typeof parsed.ts !== 'number'\n ) {\n return undefined;\n }\n return {\n pid: parsed.pid,\n startedAt: parsed.startedAt,\n ts: parsed.ts,\n };\n } catch {\n return undefined;\n }\n}\n\nexport function heartbeatAgeMs(\n payload: HeartbeatPayload,\n now: number = Date.now(),\n): number {\n return Math.max(0, now - payload.ts);\n}\n\nexport function isHeartbeatFresh(\n payload: HeartbeatPayload | undefined,\n maxAgeMs: number,\n now: number = Date.now(),\n): boolean {\n if (payload === undefined) return false;\n return heartbeatAgeMs(payload, now) < maxAgeMs;\n}\n\nexport interface HeartbeatHandle {\n stop(): void;\n}\n\n/**\n * Write a heartbeat immediately and then every `intervalMs`. Returns a handle\n * whose `stop()` clears the timer. Failures are swallowed (the guardian treats\n * a stale/missing heartbeat as \"dsh is down\", which is the safe failure mode).\n */\nexport function startHeartbeat(\n file: string,\n pid: number,\n intervalMs: number = DEFAULT_HEARTBEAT_INTERVAL_MS,\n): HeartbeatHandle {\n const startedAt = new Date().toISOString();\n let stopped = false;\n\n const beat = async (): Promise<void> => {\n if (stopped) return;\n const payload: HeartbeatPayload = { pid, startedAt, ts: Date.now() };\n try {\n await writeFileAtomic(file, `${JSON.stringify(payload)}\\n`, {\n mode: 0o600,\n });\n } catch {\n // A failed write must never take the bridge down; the guardian will see\n // the stale/missing heartbeat and take over when appropriate.\n }\n };\n\n void beat();\n const timer = setInterval(() => {\n void beat();\n }, intervalMs);\n timer.unref?.();\n\n return {\n stop(): void {\n stopped = true;\n clearInterval(timer);\n },\n };\n}\n","import { spawn } from 'node:child_process';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { discoverDshBin, resolveDshHome } from '../../config/dsh-runtime.js';\nimport { ownPackageInfo } from '../../adapters/dsh/own-package.js';\nimport { loadRuntimeEnv } from '../../config/env.js';\nimport { installGuardian } from '../../guardian/install.js';\n\nexport interface SetupOptions {\n /** dsh profile to install the bundle into (default `dsh-lark`). */\n profile?: string;\n /** Package spec for `dsh plugin add` (defaults to this package's npm name). */\n packageSpec?: string;\n /** DSH_HOME override (tests). */\n dshHome?: string;\n /** dsh CLI bin override (tests). */\n bin?: string;\n /** Also install the safety-net guardian as a system service. */\n guardian?: boolean;\n /** Injectable guardian installer (tests). */\n installGuardianFn?: typeof installGuardian;\n}\n\n/**\n * The single install-deploy path: installs this package as a standard dsh\n * profile bundle into `<name>`, pre-approving pnpm's build-script policy so\n * `dsh plugin add` succeeds out of the box. First boot of the profile prints\n * the QR code for one-time Feishu binding.\n */\nexport async function runSetup(options: SetupOptions = {}): Promise<void> {\n const profile = options.profile ?? 'dsh-lark';\n const own = ownPackageInfo();\n const packageSpec = options.packageSpec ?? process.env.DSH_LARK_SETUP_PACKAGE ?? own.name;\n const dshHome = options.dshHome ?? resolveDshHome(homedir(), process.env);\n const bin = options.bin ?? discoverDshBin(homedir(), process.env);\n if (!bin) {\n throw new Error(\n '未找到本机 dsh 安装(`@deepseek-ai/dsh`)。请先安装 DeepSeek Harness,再运行本命令。',\n );\n }\n\n // Pre-approve pnpm >= 10 build scripts so the first `dsh plugin add`\n // succeeds without a manual pnpm-workspace.yaml edit (protobufjs is a\n // transitive dependency of the Feishu channel SDK).\n const profileDir = join(dshHome, 'profiles', profile);\n await mkdir(profileDir, { recursive: true });\n await approveBuilds(profileDir);\n\n process.stdout.write(\n `正在把 ${packageSpec} 安装到 dsh profile \\`${profile}\\`($DSH_HOME=${dshHome})...\\n`,\n );\n await runDshPlugin(bin, profile, packageSpec);\n\n if (options.guardian) {\n const install = options.installGuardianFn ?? installGuardian;\n const guardianResult = await install({\n env: loadRuntimeEnv(process.env),\n dshProfile: profile,\n });\n for (const message of guardianResult.messages) {\n process.stdout.write(`${message}\\n`);\n }\n if (!guardianResult.ok) {\n process.stdout.write(\n '\\n注意:guardian 服务未完全启用,请按上方提示手动执行;也可稍后重跑 `dsh-lark-bot guardian install`。\\n',\n );\n }\n }\n\n process.stdout.write(\n [\n '',\n '✅ 安装完成。启动方式(唯一的部署路径):',\n '',\n ` dsh --profile ${profile}`,\n '',\n '首次启动会在终端打印二维码,用飞书 / Lark 扫码完成一次性绑定;',\n '绑定后 dsh 即以标准插件方式加载 dsh-lark-bot 的桥接引擎。',\n ...(options.guardian\n ? [\n '',\n '安全网守护已安装:dsh 下线后仍可通过飞书发送 /safemode 进入仅核心安全模式自救。',\n '查看状态:dsh-lark-bot guardian status',\n ]\n : [\n '',\n '提示:可加 --guardian 同时安装「安全网守护」(dsh 全部下线后的飞书救援通道)。',\n ]),\n '',\n ].join('\\n'),\n );\n}\n\nfunction runDshPlugin(bin: string, profile: string, packageSpec: string): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(\n 'node',\n [bin, 'plugin', '--profile', profile, 'add', packageSpec],\n { stdio: 'inherit' },\n );\n child.once('error', reject);\n child.once('exit', (code) => {\n if (code === 0) resolve();\n else reject(new Error(`dsh plugin add exited with code ${String(code)}`));\n });\n });\n}\n\nasync function approveBuilds(profileDir: string): Promise<void> {\n const workspaceFile = join(profileDir, 'pnpm-workspace.yaml');\n let existing = '';\n try {\n existing = await readFile(workspaceFile, 'utf8');\n } catch {\n // No workspace file yet; create one.\n }\n const allowBuilds = [\n 'protobufjs: true',\n ...(ownPackageInfo().name.startsWith('@') ? [] : [`${ownPackageInfo().name}: true`]),\n ].join('\\n');\n if (!existing.includes('allowBuilds')) {\n existing = existing.trimEnd() ? `${existing.trimEnd()}\\n\\nallowBuilds:\\n ${allowBuilds}\\n` : `allowBuilds:\\n ${allowBuilds}\\n`;\n } else if (!existing.includes('protobufjs: true')) {\n existing = existing.replace(/(allowBuilds:\\s*\\n)/, `$1 ${allowBuilds}\\n`);\n }\n await writeFile(workspaceFile, existing, 'utf8');\n}\n","import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { ownPackageInfo } from '../adapters/dsh/own-package.js';\nimport type { RuntimeEnv } from '../config/env.js';\nimport { captureOutput } from './process.js';\nimport {\n loadGuardianState,\n newGuardianState,\n saveGuardianState,\n type GuardianState,\n} from './state.js';\n\n/**\n * System-level installation of the safety-net guardian.\n *\n * The guardian is a minimal Node process that must survive dsh / Cordis\n * going down, so it is registered with the operating system's user-level\n * service manager (systemd user unit on Linux, launchd LaunchAgent on macOS,\n * Startup entry on Windows). The unit only runs `dsh-lark-bot guardian run`;\n * all dsh knowledge lives in `~/.dsh-lark/guardian.json`.\n */\n\nexport const GUARDIAN_LABEL = 'dsh-lark-guardian';\n\nexport interface InstallGuardianOptions {\n env: RuntimeEnv;\n dshProfile?: string;\n bridgeProfile?: string;\n /** Skip writing service files; only persist the state mapping (tests). */\n dryRun?: boolean;\n /** Injectable command runner for activation (tests). */\n run?: (command: string, args: readonly string[]) => Promise<{ code: number; stdout: string; stderr: string }>;\n rootOverride?: string;\n userOverride?: string;\n}\n\nexport interface InstallResult {\n ok: boolean;\n messages: string[];\n}\n\nfunction guardianCliEntry(): string {\n return join(ownPackageInfo().root, 'dist', 'cli.js');\n}\n\nfunction serviceDirectory(platform: NodeJS.Platform, root: string): string {\n switch (platform) {\n case 'linux':\n return join(root, '.config', 'systemd', 'user');\n case 'darwin':\n return join(root, 'Library', 'LaunchAgents');\n case 'win32':\n return join(\n process.env.APPDATA ?? join(root, 'AppData', 'Roaming'),\n 'Microsoft',\n 'Windows',\n 'Start Menu',\n 'Programs',\n 'Startup',\n );\n default:\n return join(root, '.dsh-lark', 'guardian');\n }\n}\n\nexport function systemdUnit(\n nodeBin: string,\n cliEntry: string,\n env: Record<string, string> = {},\n): string {\n const envLines = Object.entries(env)\n .map(([key, value]) => `Environment=${key}=${value}`)\n .join('\\n');\n return [\n '[Unit]',\n 'Description=dsh-lark-bot safety-net guardian (Feishu rescue when dsh is down)',\n 'After=network-online.target',\n 'Wants=network-online.target',\n '',\n '[Service]',\n 'Type=simple',\n `ExecStart=${nodeBin} ${cliEntry} guardian run`,\n 'Restart=on-failure',\n 'RestartSec=5',\n ...(envLines ? [envLines] : []),\n '',\n '[Install]',\n 'WantedBy=default.target',\n '',\n ].join('\\n');\n}\n\nexport function launchdPlist(\n nodeBin: string,\n cliEntry: string,\n label: string = `io.dsh-lark.${GUARDIAN_LABEL}`,\n logPath: string = '/tmp/dsh-lark-guardian.log',\n): string {\n return [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n '<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">',\n '<plist version=\"1.0\">',\n '<dict>',\n ` <key>Label</key><string>${label}</string>`,\n ' <key>ProgramArguments</key>',\n ' <array>',\n ` <string>${nodeBin}</string>`,\n ` <string>${cliEntry}</string>`,\n ' <string>guardian</string>',\n ' <string>run</string>',\n ' </array>',\n ' <key>RunAtLoad</key><true/>',\n ' <key>KeepAlive</key><true/>',\n ` <key>StandardOutPath</key><string>${logPath}</string>`,\n ` <key>StandardErrorPath</key><string>${logPath}</string>`,\n '</dict>',\n '</plist>',\n '',\n ].join('\\n');\n}\n\nexport function windowsStartupCmd(\n nodeBin: string,\n cliEntry: string,\n): string {\n return [\n '@echo off',\n 'REM dsh-lark-bot safety-net guardian - keep the Feishu rescue entrance alive.',\n `start \"\" /b \"${nodeBin}\" \"${cliEntry}\" guardian run`,\n '',\n ].join('\\r\\n');\n}\n\nfunction defaultRun(\n command: string,\n args: readonly string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return captureOutput(command, args, 30_000);\n}\n\nexport async function installGuardian(\n options: InstallGuardianOptions,\n): Promise<InstallResult> {\n const messages: string[] = [];\n const root = options.rootOverride ?? homedir();\n const dshProfile = options.dshProfile ?? options.env.guardianProfile;\n const bridgeProfile = options.bridgeProfile ?? options.env.guardianBridgeProfile;\n const stateFile = join(root, '.dsh-lark', 'guardian.json');\n const fallback = newGuardianState({ dshProfile, bridgeProfile });\n const existing = await loadGuardianState(stateFile, fallback);\n const state: GuardianState = {\n ...existing,\n dshProfile: existing.dshProfile === dshProfile ? existing.dshProfile : dshProfile,\n bridgeProfile:\n existing.bridgeProfile === bridgeProfile ? existing.bridgeProfile : bridgeProfile,\n safeProfile: existing.safeProfile || `${dshProfile}-safe`,\n };\n await saveGuardianState(stateFile, state);\n messages.push(`守护状态已写入 ${stateFile}(dsh profile=${state.dshProfile})`);\n\n if (options.dryRun) {\n return { ok: true, messages };\n }\n\n const nodeBin = process.execPath;\n const cliEntry = guardianCliEntry();\n const directory = serviceDirectory(process.platform, root);\n await mkdir(directory, { recursive: true });\n\n if (process.platform === 'linux') {\n const unitPath = join(directory, `${GUARDIAN_LABEL}.service`);\n await writeFile(\n unitPath,\n systemdUnit(nodeBin, cliEntry, { DSH_LARK_GUARDIAN_DISABLED: '0' }),\n 'utf8',\n );\n messages.push(`systemd user unit 已写入 ${unitPath}`);\n const run = options.run ?? defaultRun;\n const reload = await run('systemctl', ['--user', 'daemon-reload']);\n const enable = await run('systemctl', ['--user', 'enable', '--now', `${GUARDIAN_LABEL}.service`]);\n if (reload.code === 0 && enable.code === 0) {\n messages.push('守护服务已启用并启动(systemctl --user)。');\n } else {\n messages.push(\n '未能自动启用服务(可能需要图形会话 / systemd user 实例)。请手动执行:',\n );\n messages.push(` systemctl --user daemon-reload && systemctl --user enable --now ${GUARDIAN_LABEL}.service`);\n return { ok: false, messages };\n }\n } else if (process.platform === 'darwin') {\n const label = `io.dsh-lark.${GUARDIAN_LABEL}`;\n const plistPath = join(directory, `${label}.plist`);\n await writeFile(plistPath, launchdPlist(nodeBin, cliEntry), 'utf8');\n messages.push(`launchd LaunchAgent 已写入 ${plistPath}`);\n const run = options.run ?? defaultRun;\n const uid = typeof options.userOverride === 'string' ? options.userOverride : String(process.getuid?.() ?? 501);\n const bootstrap = await run('launchctl', ['bootstrap', `gui/${uid}`, plistPath]);\n if (bootstrap.code === 0) {\n messages.push('守护服务已加载(launchctl bootstrap)。');\n } else {\n messages.push(\n '未能自动加载 LaunchAgent。请手动执行(或改用旧版 launchctl load -w):',\n );\n messages.push(` launchctl bootstrap gui/${uid} ${plistPath}`);\n return { ok: false, messages };\n }\n } else if (process.platform === 'win32') {\n const cmdPath = join(directory, `${GUARDIAN_LABEL}.cmd`);\n await writeFile(cmdPath, windowsStartupCmd(nodeBin, cliEntry), 'utf8');\n messages.push(`Windows 启动项已写入 ${cmdPath}(登录后自动常驻)。`);\n } else {\n const fallbackPath = join(directory, `${GUARDIAN_LABEL}.sh`);\n await writeFile(\n fallbackPath,\n `#!/bin/sh\\nexec \"${nodeBin}\" \"${cliEntry}\" guardian run\\n`,\n 'utf8',\n );\n messages.push(\n `当前平台不支持自动注册服务;已写入启动脚本 ${fallbackPath},请按需配置常驻。`,\n );\n }\n\n return { ok: true, messages };\n}\n\nexport async function uninstallGuardian(\n options: Pick<InstallGuardianOptions, 'env' | 'run' | 'rootOverride' | 'userOverride'>,\n): Promise<InstallResult> {\n const messages: string[] = [];\n const root = options.rootOverride ?? homedir();\n const run = options.run ?? defaultRun;\n\n if (process.platform === 'linux') {\n await run('systemctl', ['--user', 'disable', '--now', `${GUARDIAN_LABEL}.service`]);\n const unitPath = join(root, '.config', 'systemd', 'user', `${GUARDIAN_LABEL}.service`);\n await rm(unitPath, { force: true });\n await run('systemctl', ['--user', 'daemon-reload']);\n messages.push('systemd user unit 已移除并停止。');\n } else if (process.platform === 'darwin') {\n const label = `io.dsh-lark.${GUARDIAN_LABEL}`;\n const plistPath = join(root, 'Library', 'LaunchAgents', `${label}.plist`);\n const uid = typeof options.userOverride === 'string' ? options.userOverride : String(process.getuid?.() ?? 501);\n await run('launchctl', ['bootout', `gui/${uid}`, plistPath]);\n await rm(plistPath, { force: true });\n messages.push('launchd LaunchAgent 已移除。');\n } else if (process.platform === 'win32') {\n const startupDir = join(\n process.env.APPDATA ?? join(root, 'AppData', 'Roaming'),\n 'Microsoft',\n 'Windows',\n 'Start Menu',\n 'Programs',\n 'Startup',\n );\n await rm(join(startupDir, `${GUARDIAN_LABEL}.cmd`), { force: true });\n messages.push('Windows 启动项已移除。');\n } else {\n const fallbackPath = join(root, '.dsh-lark', 'guardian', `${GUARDIAN_LABEL}.sh`);\n await rm(fallbackPath, { force: true });\n messages.push('启动脚本已移除。');\n }\n\n messages.push('守护状态文件(~/.dsh-lark/guardian.json)已保留,可随时重新安装。');\n return { ok: true, messages };\n}\n\nexport async function readGuardianUnit(platform: NodeJS.Platform, root: string): Promise<string | undefined> {\n if (platform === 'linux') {\n const path = join(root, '.config', 'systemd', 'user', `${GUARDIAN_LABEL}.service`);\n return existsSync(path) ? readFile(path, 'utf8') : undefined;\n }\n if (platform === 'darwin') {\n const path = join(root, 'Library', 'LaunchAgents', `io.dsh-lark.${GUARDIAN_LABEL}.plist`);\n return existsSync(path) ? readFile(path, 'utf8') : undefined;\n }\n return undefined;\n}\n\nexport function guardianStatePath(root: string): string {\n return join(root, '.dsh-lark', 'guardian.json');\n}\n","import { spawn } from 'node:child_process';\n\n/**\n * Minimal process observation used by the safety-net guardian.\n *\n * The guardian must decide whether \"dsh is up\" without importing any dsh\n * code: a fresh bridge heartbeat is authoritative, and a live `dsh --profile\n * <name>` process is the fallback (it also catches the case where the bridge\n * never got to write a heartbeat because the profile boot failed).\n */\n\nexport interface ProfileProcess {\n pid: number;\n cmdline: string;\n}\n\nfunction hasProfileFlag(cmdline: string, dshProfile: string): boolean {\n // Match `--profile <name>` with either `=` or space separation; token-level\n // so `--profile dsh-lark-safe` never matches `dsh-lark`.\n const pattern = new RegExp(\n `(?:^|\\\\s)--profile(?:\\\\s+|=)${escapeRegExp(dshProfile)}(?:\\\\s|$)`,\n );\n return pattern.test(cmdline);\n}\n\nfunction escapeRegExp(value: string): string {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function looksLikeDshProcess(cmdline: string): boolean {\n return (\n cmdline.includes('@deepseek-ai/dsh') ||\n /(?:^|\\s)dsh(?:\\.exe)?(?:\\s|$)/.test(cmdline)\n );\n}\n\nexport function matchProfileProcess(\n cmdline: string,\n dshProfile: string,\n): boolean {\n return hasProfileFlag(cmdline, dshProfile) && looksLikeDshProcess(cmdline);\n}\n\n/**\n * List `{ pid, cmdline }` for every process on the machine. Uses `ps` on\n * POSIX and PowerShell's CIM query on Windows; both are available on the\n * supported platforms.\n */\nexport async function listProcesses(): Promise<ProfileProcess[]> {\n if (process.platform === 'win32') {\n return listProcessesWindows();\n }\n return listProcessesPosix();\n}\n\nasync function listProcessesPosix(): Promise<ProfileProcess[]> {\n const { stdout } = await captureOutput('ps', ['-axo', 'pid=,args='], 10_000);\n const result: ProfileProcess[] = [];\n for (const line of stdout.split('\\n')) {\n const match = /^\\s*(\\d+)\\s+(.+)$/.exec(line);\n if (match) {\n result.push({ pid: Number(match[1]), cmdline: match[2] ?? '' });\n }\n }\n return result;\n}\n\nasync function listProcessesWindows(): Promise<ProfileProcess[]> {\n const { stdout } = await captureOutput(\n 'powershell.exe',\n [\n '-NoProfile',\n '-NonInteractive',\n '-Command',\n 'Get-CimInstance Win32_Process | Select-Object ProcessId, CommandLine | ConvertTo-Csv -NoTypeInformation',\n ],\n 10_000,\n );\n const result: ProfileProcess[] = [];\n for (const line of stdout.split('\\n').slice(1)) {\n const [pid, ...rest] = line.trim().split(',');\n const numeric = Number(pid?.replace(/\"/g, ''));\n if (Number.isInteger(numeric) && rest.length > 0) {\n // Csv quoting can split command lines; join everything after the pid.\n result.push({ pid: numeric, cmdline: rest.join(',').replace(/^\"|\"$/g, '') });\n }\n }\n return result;\n}\n\nexport async function captureOutput(\n command: string,\n args: readonly string[],\n timeoutMs: number = 30_000,\n): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const child = spawn(command, [...args], {\n stdio: ['ignore', 'pipe', 'pipe'],\n windowsHide: true,\n });\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', () => {\n resolve({ code: 1, stdout: '', stderr });\n });\n child.on('close', (code) => {\n resolve({ code: code ?? 1, stdout, stderr });\n });\n const timer = setTimeout(() => {\n child.kill('SIGKILL');\n resolve({ code: 1, stdout, stderr });\n }, timeoutMs);\n child.once('close', () => clearTimeout(timer));\n });\n}\n\nexport async function findProfileProcess(\n dshProfile: string,\n): Promise<ProfileProcess | undefined> {\n const processes = await listProcesses();\n return processes.find((entry) => matchProfileProcess(entry.cmdline, dshProfile));\n}\n\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return (error as NodeJS.ErrnoException).code === 'EPERM';\n }\n}\n\nexport interface DetachedSpawn {\n pid?: number | undefined;\n}\n\n/**\n * Spawn a detached process that keeps running after the guardian exits\n * (used to relaunch the full dsh profile when leaving safe mode). stdio is\n * ignored so the relaunched profile never shares the guardian's console.\n */\nexport function spawnDetached(\n command: string,\n args: readonly string[],\n env: NodeJS.ProcessEnv = process.env,\n): DetachedSpawn {\n const child = spawn(command, [...args], {\n detached: process.platform !== 'win32',\n stdio: 'ignore',\n windowsHide: true,\n env: { ...env },\n });\n if (child.pid !== undefined && process.platform !== 'win32') {\n child.unref();\n }\n return { pid: child.pid };\n}\n","import { readFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport { mkdir } from 'node:fs/promises';\nimport { writeFileAtomic } from '../platform/atomic-write.js';\n\n/**\n * Persistent guardian state (`~/.dsh-lark/guardian.json`).\n *\n * The guardian is a separate minimal process, so everything it needs to\n * resume after a restart lives here:\n * - which dsh profile to watch / relaunch and which bridge profile provides\n * the Feishu credentials and access lists;\n * - whether the dsh profile was ever observed up (the takeover gate: we only\n * occupy the Feishu channel after the profile has actually run);\n * - the current mode (`standby` / `takeover` / `safe`).\n */\n\nexport type GuardianMode = 'standby' | 'takeover' | 'safe';\n\nexport interface GuardianState {\n schemaVersion: 1;\n dshProfile: string;\n bridgeProfile: string;\n safeProfile: string;\n /** True once the dsh profile was observed running (heartbeat or process). */\n profileSeenUp: boolean;\n mode: GuardianMode;\n /** PID of the full-profile relaunch spawned when exiting safe mode. */\n relaunchedPid?: number | undefined;\n updatedAt: string;\n}\n\nexport const DEFAULT_DSH_PROFILE = 'dsh-lark';\nexport const DEFAULT_BRIDGE_PROFILE = 'default';\n\nexport function defaultSafeProfile(dshProfile: string): string {\n return `${dshProfile}-safe`;\n}\n\nexport function newGuardianState(input: {\n dshProfile?: string;\n bridgeProfile?: string;\n}): GuardianState {\n const dshProfile = input.dshProfile ?? DEFAULT_DSH_PROFILE;\n return {\n schemaVersion: 1,\n dshProfile,\n bridgeProfile: input.bridgeProfile ?? DEFAULT_BRIDGE_PROFILE,\n safeProfile: defaultSafeProfile(dshProfile),\n profileSeenUp: false,\n mode: 'standby',\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport async function loadGuardianState(\n file: string,\n fallback: GuardianState,\n): Promise<GuardianState> {\n try {\n const raw = await readFile(file, 'utf8');\n const parsed = JSON.parse(raw) as Partial<GuardianState>;\n if (parsed.schemaVersion !== 1) return fallback;\n const dshProfile = typeof parsed.dshProfile === 'string' ? parsed.dshProfile : fallback.dshProfile;\n const bridgeProfile =\n typeof parsed.bridgeProfile === 'string' ? parsed.bridgeProfile : fallback.bridgeProfile;\n return {\n schemaVersion: 1,\n dshProfile,\n bridgeProfile,\n safeProfile:\n typeof parsed.safeProfile === 'string'\n ? parsed.safeProfile\n : defaultSafeProfile(dshProfile),\n profileSeenUp: parsed.profileSeenUp === true || fallback.profileSeenUp === true,\n mode: parsed.mode === 'takeover' || parsed.mode === 'safe' ? parsed.mode : 'standby',\n relaunchedPid:\n typeof parsed.relaunchedPid === 'number' ? parsed.relaunchedPid : undefined,\n updatedAt: parsed.updatedAt ?? new Date().toISOString(),\n };\n } catch {\n return fallback;\n }\n}\n\nexport async function saveGuardianState(\n file: string,\n state: GuardianState,\n): Promise<void> {\n const next: GuardianState = { ...state, updatedAt: new Date().toISOString() };\n await mkdir(dirname(file), { recursive: true });\n await writeFileAtomic(file, `${JSON.stringify(next, null, 2)}\\n`, { mode: 0o600 });\n}\n\n/** Mutate a copy of the state and persist it; used for small updates. */\nexport async function updateGuardianState(\n file: string,\n state: GuardianState,\n patch: Partial<GuardianState>,\n): Promise<GuardianState> {\n const next: GuardianState = { ...state, ...patch };\n await saveGuardianState(file, next);\n return next;\n}\n","import { join } from 'node:path';\nimport { loadRuntimeEnv, type RuntimeEnv } from '../../config/env.js';\nimport {\n guardianLayoutFor,\n buildGuardianService,\n} from '../../guardian/service.js';\nimport {\n heartbeatAgeMs,\n isHeartbeatFresh,\n readHeartbeat,\n} from '../../guardian/heartbeat.js';\nimport {\n installGuardian,\n uninstallGuardian,\n type InstallResult,\n} from '../../guardian/install.js';\nimport { findProfileProcess } from '../../guardian/process.js';\nimport {\n loadGuardianState,\n newGuardianState,\n} from '../../guardian/state.js';\nimport { resolveAppPaths } from '../../config/app-paths.js';\n\nexport interface GuardianCommandOptions {\n dshProfile?: string;\n bridgeProfile?: string;\n}\n\nfunction envWithOverrides(options: GuardianCommandOptions): RuntimeEnv {\n const env = loadRuntimeEnv(process.env);\n if (options.dshProfile) env.guardianProfile = options.dshProfile;\n if (options.bridgeProfile) env.guardianBridgeProfile = options.bridgeProfile;\n return env;\n}\n\nfunction printLines(lines: readonly string[]): void {\n process.stdout.write(`${lines.join('\\n')}\\n`);\n}\n\n/** Run the guardian in the foreground (the system service entry point). */\nexport async function runGuardian(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n if (env.guardianDisabled) {\n printLines(['安全网守护已禁用(DSH_LARK_GUARDIAN_DISABLED=1),进程退出。']);\n return;\n }\n const service = await buildGuardianService(env);\n await service.start();\n printLines([\n `安全网守护运行中(pid=${process.pid},dsh profile=${service.snapshot().dshProfile})。`,\n 'dsh 正常运行时保持静默;dsh 下线后自动接管飞书通道,等待 /safemode 控制信号。',\n ]);\n await waitForShutdown();\n await service.stop();\n}\n\n/** Install the guardian as a system-level resident service. */\nexport async function installGuardianCommand(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n const result = await installGuardian({ env, ...(options.dshProfile ? { dshProfile: options.dshProfile } : {}) });\n printResult(result);\n if (!result.ok) process.exitCode = 1;\n}\n\nexport async function uninstallGuardianCommand(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n const result = await uninstallGuardian({ env });\n printResult(result);\n}\n\n/** Print a human-readable guardian status without starting the service. */\nexport async function statusGuardianCommand(\n options: GuardianCommandOptions = {},\n): Promise<void> {\n const env = envWithOverrides(options);\n const paths = resolveAppPaths(env.home);\n const fallback = newGuardianState({\n dshProfile: env.guardianProfile,\n bridgeProfile: env.guardianBridgeProfile,\n });\n const state = await loadGuardianState(join(paths.root, 'guardian.json'), fallback);\n const layout = guardianLayoutFor(env, state.bridgeProfile);\n const heartbeat = await readHeartbeat(layout.heartbeatFile);\n const processFound = await findProfileProcess(state.dshProfile);\n const up =\n isHeartbeatFresh(heartbeat, env.guardianStaleMs) || processFound !== undefined;\n printLines([\n '安全网守护状态',\n '---------------',\n `模式:${state.mode}`,\n `dsh profile:${state.dshProfile}`,\n `安全 profile:${state.safeProfile}`,\n `桥接 profile:${state.bridgeProfile}`,\n `dsh 是否在线:${up ? '是' : '否'}${processFound ? `(pid ${processFound.pid})` : ''}`,\n `心跳龄:${heartbeat ? `${heartbeatAgeMs(heartbeat)}ms` : '无'}`,\n `已观察过 dsh 运行:${state.profileSeenUp ? '是' : '否'}`,\n `守护进程 pid:${process.pid}`,\n `状态文件:${layout.stateFile}`,\n `心跳文件:${layout.heartbeatFile}`,\n ]);\n}\n\nfunction printResult(result: InstallResult): void {\n for (const message of result.messages) {\n process.stdout.write(`${message}\\n`);\n }\n}\n\nfunction waitForShutdown(): Promise<void> {\n return new Promise((resolve) => {\n // The guardian service's poll timer is unref'd (so embedding and tests do\n // not pin the process), therefore the foreground service entry must hold\n // the event loop itself until SIGINT / SIGTERM arrives; otherwise Node\n // drains the loop and exits with an unsettled top-level await.\n const keepAlive = setInterval(() => {}, 2 ** 31 - 1);\n const shutdown = (): void => {\n clearInterval(keepAlive);\n process.off('SIGINT', shutdown);\n process.off('SIGTERM', shutdown);\n resolve();\n };\n process.once('SIGINT', shutdown);\n process.once('SIGTERM', shutdown);\n });\n}\n","import { randomUUID } from 'node:crypto';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { createLarkChannel, type LarkChannel, type NormalizedMessage } from '@larksuite/channel';\nimport { DshAdapter } from '../adapters/dsh/adapter.js';\nimport type { AgentAdapter } from '../adapters/types.js';\nimport { resolveAppPaths, type AppPaths } from '../config/app-paths.js';\nimport { discoverDshBin } from '../config/dsh-runtime.js';\nimport type { RuntimeEnv } from '../config/env.js';\nimport { ConfigStore, type ProfileConfig } from '../config/profile-store.js';\nimport { isEventFresh } from '../config/security.js';\nimport { log } from '../core/logger.js';\nimport {\n parseGuardianCommand,\n safemodeHelpText,\n} from './control.js';\nimport type { GuardianControlKind } from './control.js';\nimport {\n isHeartbeatFresh,\n readHeartbeat,\n heartbeatAgeMs,\n} from './heartbeat.js';\nimport {\n captureOutput,\n findProfileProcess,\n spawnDetached,\n type DetachedSpawn,\n type ProfileProcess,\n} from './process.js';\nimport {\n ensureSafeProfile,\n probeSafeProfile,\n type SafeProfileProbeResult,\n} from './safe-profile.js';\nimport {\n loadGuardianState,\n newGuardianState,\n saveGuardianState,\n type GuardianState,\n} from './state.js';\n\n/**\n * Safety-net guardian service.\n *\n * A minimal process independent of dsh / Cordis that:\n * 1. stays silent (no Feishu connection) while the dsh profile is up\n * (fresh bridge heartbeat or live `dsh --profile <name>` process);\n * 2. after the profile has been observed up once, takes over the Feishu\n * channel when dsh goes down and accepts control signals\n * (`/safemode` family);\n * 3. on `/safemode`, provisions a core-only safe profile\n * (`dsh-base` + `dsh-headless`, no third-party plugins) and proxies a\n * restricted conversation to it for self-healing;\n * 4. on `/safemode exit`, relaunches the full profile, disconnects and\n * hands the channel back.\n */\n\nexport interface GuardianServiceOptions {\n stateFile: string;\n configFile: string;\n heartbeatFile: string;\n home: string;\n /** Explicit dsh bin override (tests / unusual installs); else auto-discovered. */\n dshBin?: string;\n env?: NodeJS.ProcessEnv;\n dshProfile: string;\n bridgeProfile: string;\n safeProfile: string;\n pollMs?: number;\n staleMs?: number;\n /** Live-process grace: heartbeat stale this long means the engine is dead. */\n engineDeadMs?: number;\n /** Consecutive polls dsh must be down before taking over (flap guard). */\n takeoverGracePolls?: number;\n /** Delay between the `/safemode exit` reply and channel disconnect (ms). */\n sendDelayMs?: number;\n now?: () => number;\n createChannel?: typeof createLarkChannel;\n adapter?: AgentAdapter;\n findProcess?: (dshProfile: string) => Promise<ProfileProcess | undefined>;\n spawnDetachedFn?: typeof spawnDetached;\n probeSafeProfileFn?: (\n input: {\n bin: string;\n dshProfile: string;\n home: string;\n env?: NodeJS.ProcessEnv;\n },\n ) => Promise<SafeProfileProbeResult>;\n runPluginList?: (\n bin: string,\n dshProfile: string,\n ) => Promise<{ stdout: string; stderr: string }>;\n saveState?: (state: GuardianState) => Promise<void>;\n logger?: Pick<typeof log, 'info' | 'warn' | 'fail'>;\n}\n\nexport interface GuardianSnapshot {\n mode: GuardianState['mode'];\n dshProfile: string;\n bridgeProfile: string;\n safeProfile: string;\n profileSeenUp: boolean;\n dshUp: boolean;\n heartbeatAgeMs: number | undefined;\n channelConnected: boolean;\n pid: number;\n dshBin: string | undefined;\n relaunchedPid: number | undefined;\n updatedAt: string;\n}\n\ninterface TranscriptEntry {\n role: 'user' | 'assistant';\n content: string;\n}\n\nconst MAX_TRANSCRIPT_ENTRIES = 30;\nconst SAFE_RUN_TIMEOUT_MS = 10 * 60_000;\n\nexport class GuardianService {\n private readonly options: Required<\n Pick<\n GuardianServiceOptions,\n | 'stateFile'\n | 'configFile'\n | 'heartbeatFile'\n | 'home'\n | 'dshProfile'\n | 'bridgeProfile'\n | 'safeProfile'\n | 'pollMs'\n | 'staleMs'\n | 'engineDeadMs'\n | 'takeoverGracePolls'\n | 'sendDelayMs'\n >\n > &\n Pick<\n GuardianServiceOptions,\n | 'env'\n | 'createChannel'\n | 'adapter'\n | 'findProcess'\n | 'spawnDetachedFn'\n | 'probeSafeProfileFn'\n | 'runPluginList'\n | 'dshBin'\n | 'saveState'\n | 'logger'\n | 'now'\n >;\n\n private state: GuardianState;\n private channel: LarkChannel | undefined;\n private safeAdapter: AgentAdapter | undefined;\n private readonly transcripts = new Map<string, TranscriptEntry[]>();\n private downStreak = 0;\n private lastHeartbeatFreshAt: number | undefined;\n private timer: NodeJS.Timeout | undefined;\n private ticking = false;\n private stopped = false;\n private dshBin: string | undefined;\n private config: ProfileConfig | undefined;\n private readonly eventFreshnessMs: number;\n private readonly activeMessages = new Set<Promise<void>>();\n\n constructor(options: GuardianServiceOptions) {\n this.options = {\n pollMs: options.pollMs ?? 2_000,\n staleMs: options.staleMs ?? 15_000,\n engineDeadMs: options.engineDeadMs ?? 120_000,\n takeoverGracePolls: options.takeoverGracePolls ?? 2,\n sendDelayMs: options.sendDelayMs ?? 600,\n stateFile: options.stateFile,\n configFile: options.configFile,\n heartbeatFile: options.heartbeatFile,\n home: options.home,\n dshProfile: options.dshProfile,\n bridgeProfile: options.bridgeProfile,\n safeProfile: options.safeProfile,\n ...defined({\n env: options.env,\n createChannel: options.createChannel,\n adapter: options.adapter,\n findProcess: options.findProcess,\n spawnDetachedFn: options.spawnDetachedFn,\n probeSafeProfileFn: options.probeSafeProfileFn,\n runPluginList: options.runPluginList,\n dshBin: options.dshBin,\n saveState: options.saveState,\n logger: options.logger,\n now: options.now,\n }),\n };\n this.state = newGuardianState({\n dshProfile: options.dshProfile,\n bridgeProfile: options.bridgeProfile,\n });\n this.eventFreshnessMs = parseFreshness(this.options.env?.DSH_LARK_EVENT_FRESHNESS_MS);\n }\n\n get mode(): GuardianState['mode'] {\n return this.state.mode;\n }\n\n async start(): Promise<void> {\n const loaded = await loadGuardianState(this.options.stateFile, this.state);\n if (loaded.dshProfile !== this.options.dshProfile) {\n // The state file is authoritative once written; adopt it so the\n // guardian keeps monitoring the profile it was installed for.\n this.state = loaded;\n } else {\n this.state = loaded;\n }\n await this.loadContext();\n await this.save();\n await this.tick();\n this.timer = setInterval(() => {\n void this.tick();\n }, this.options.pollMs);\n this.timer.unref?.();\n this.log().info('guardian', 'started', {\n dshProfile: this.state.dshProfile,\n bridgeProfile: this.state.bridgeProfile,\n mode: this.state.mode,\n pollMs: this.options.pollMs,\n });\n }\n\n async stop(): Promise<void> {\n if (this.stopped) return;\n this.stopped = true;\n if (this.timer) clearInterval(this.timer);\n this.timer = undefined;\n await Promise.allSettled([...this.activeMessages]);\n await this.disconnectChannel();\n await this.safeAdapter?.dispose?.();\n this.log().info('guardian', 'stopped', {});\n }\n\n snapshot(): GuardianSnapshot {\n return {\n mode: this.state.mode,\n dshProfile: this.state.dshProfile,\n bridgeProfile: this.state.bridgeProfile,\n safeProfile: this.state.safeProfile,\n profileSeenUp: this.state.profileSeenUp,\n dshUp: this.dshUp,\n heartbeatAgeMs: this.lastHeartbeatAgeMs,\n channelConnected: this.channel !== undefined,\n pid: process.pid,\n dshBin: this.dshBin,\n relaunchedPid: this.state.relaunchedPid,\n updatedAt: this.state.updatedAt,\n };\n }\n\n private dshUp = false;\n private lastHeartbeatAgeMs: number | undefined;\n\n private log() {\n return this.options.logger ?? log;\n }\n\n private async loadContext(): Promise<void> {\n const store = new ConfigStore(this.options.configFile);\n await store.load();\n this.config = store.getProfile(this.state.bridgeProfile);\n this.dshBin =\n this.options.dshBin ?? discoverDshBin(this.options.home, this.options.env ?? process.env);\n }\n\n private async save(): Promise<void> {\n if (this.options.saveState) {\n await this.options.saveState(this.state);\n return;\n }\n await saveGuardianState(this.options.stateFile, this.state);\n }\n\n private async setMode(mode: GuardianState['mode']): Promise<void> {\n if (this.state.mode === mode) return;\n this.state.mode = mode;\n await this.save();\n }\n\n private async setSeenUp(): Promise<void> {\n if (this.state.profileSeenUp) return;\n this.state.profileSeenUp = true;\n await this.save();\n }\n\n private async tick(): Promise<void> {\n if (this.stopped || this.ticking) return;\n this.ticking = true;\n try {\n const heartbeat = await readHeartbeat(this.options.heartbeatFile);\n const now = (this.options.now ?? Date.now)();\n const heartbeatFresh = isHeartbeatFresh(heartbeat, this.options.staleMs, now);\n this.lastHeartbeatAgeMs = heartbeat ? heartbeatAgeMs(heartbeat, now) : undefined;\n if (heartbeatFresh) this.lastHeartbeatFreshAt = now;\n const processFound = await (this.options.findProcess ?? findProfileProcess)(\n this.state.dshProfile,\n );\n const processAlive = processFound !== undefined;\n const engineDead =\n this.lastHeartbeatFreshAt !== undefined &&\n now - this.lastHeartbeatFreshAt > this.options.engineDeadMs;\n // A live process alone does not mean the channel is owned: if the bridge\n // engine's heartbeat has been stale long enough, the engine is dead even\n // though the dsh process survives — take over so the rescue entrance\n // stays reachable.\n const up = heartbeatFresh || (processAlive && !engineDead);\n this.dshUp = up;\n\n if (up) {\n this.downStreak = 0;\n await this.setSeenUp();\n if (this.state.mode !== 'standby' || this.channel !== undefined) {\n // The full profile came back (or the user started it manually):\n // release the Feishu channel and leave safe mode immediately.\n await this.disconnectChannel();\n this.transcripts.clear();\n await this.setMode('standby');\n }\n return;\n }\n\n // dsh is down.\n if (!this.state.profileSeenUp) return; // never observed up: stay silent\n this.downStreak += 1;\n if (this.downStreak < this.options.takeoverGracePolls) return;\n await this.ensureChannel();\n } catch (error) {\n this.log().fail('guardian', error);\n } finally {\n this.ticking = false;\n }\n }\n\n private async ensureChannel(): Promise<void> {\n if (this.channel !== undefined) return;\n const config = this.config ?? (await this.reloadConfig());\n if (!config) {\n this.log().warn('guardian', 'no-bridge-profile', {\n bridgeProfile: this.state.bridgeProfile,\n });\n return;\n }\n const create = this.options.createChannel ?? createLarkChannel;\n const channel = create({\n appId: config.accounts.appId,\n appSecret: config.accounts.appSecret,\n domain:\n config.tenant === 'lark' ? 'https://open.larksuite.com' : 'https://open.feishu.cn',\n source: 'dsh-lark-bot-guardian',\n policy: {\n dmMode: config.access.allowedUsers.length ? 'allowlist' : 'open',\n requireMention: true,\n respondToMentionAll: false,\n ...(config.access.allowedUsers.length\n ? { dmAllowlist: config.access.allowedUsers }\n : {}),\n ...(config.access.allowedChats.length\n ? { groupAllowlist: config.access.allowedChats }\n : {}),\n },\n safety: {\n chatQueue: { enabled: false },\n },\n outbound: {\n streamThrottleMs: 400,\n },\n includeRawEvent: true,\n resolveChatMode: true,\n handshakeTimeoutMs: 8_000,\n httpTimeoutMs: 30_000,\n respectProxyEnv: true,\n });\n\n channel.on({\n message: (msg) => this.track(this.handleMessage(msg)),\n error: (error) => {\n this.log().fail('guardian-channel', error);\n },\n reconnecting: () => {\n this.log().warn('guardian-channel', 'reconnecting', {});\n },\n reconnected: () => {\n this.log().info('guardian-channel', 'reconnected', {});\n },\n });\n\n try {\n await channel.connect();\n this.channel = channel;\n // Keep `safe` (restart mid-safe-mode); otherwise mark takeover.\n if (this.state.mode !== 'safe') await this.setMode('takeover');\n this.log().info('guardian', 'channel-taken-over', {\n dshProfile: this.state.dshProfile,\n });\n } catch (error) {\n this.log().fail('guardian-channel', error);\n }\n }\n\n private async reloadConfig(): Promise<ProfileConfig | undefined> {\n await this.loadContext();\n return this.config;\n }\n\n private async disconnectChannel(): Promise<void> {\n const channel = this.channel;\n this.channel = undefined;\n if (!channel) return;\n try {\n await channel.disconnect();\n } catch (error) {\n this.log().fail('guardian-channel', error);\n }\n if (this.state.mode !== 'standby') {\n await this.setMode('standby');\n }\n }\n\n private scopeFor(msg: NormalizedMessage): string {\n if (msg.chatMode === 'topic' && msg.threadId) return `${msg.chatId}:${msg.threadId}`;\n return msg.chatId;\n }\n\n private authorized(msg: NormalizedMessage): boolean {\n const access = this.config?.access;\n if (!access) return false;\n const controllers = access.admins.length > 0 ? access.admins : access.allowedUsers;\n return controllers.includes(msg.senderId);\n }\n\n private async sendMarkdown(\n chatId: string,\n markdown: string,\n replyTo?: string,\n ): Promise<void> {\n if (!this.channel) return;\n try {\n await this.channel.send(\n chatId,\n { markdown },\n replyTo ? { replyTo } : undefined,\n );\n } catch (error) {\n this.log().fail('guardian-send', error);\n }\n }\n\n private async handleMessage(msg: NormalizedMessage): Promise<void> {\n if (!this.authorized(msg)) {\n this.log().warn('guardian', 'unauthorized-message-dropped', {\n senderId: msg.senderId,\n scope: this.scopeFor(msg),\n });\n return;\n }\n if (this.eventFreshnessMs > 0 && !isEventFresh(msg.createTime, this.eventFreshnessMs)) {\n this.log().warn('guardian', 'stale-message-dropped', {\n ageMs: Date.now() - msg.createTime,\n });\n return;\n }\n\n const scope = this.scopeFor(msg);\n const control = parseGuardianCommand(msg.content);\n if (control) {\n await this.handleControl(control.kind, msg);\n return;\n }\n\n if (this.state.mode === 'safe') {\n await this.runSafeTask(scope, msg);\n return;\n }\n\n await this.sendMarkdown(\n msg.chatId,\n [\n 'dsh 未在运行,守护进程已接管飞书通道。',\n '',\n '发送 `/safemode` 进入仅核心安全模式(dsh 主核心 + 官方 headless,不加载任何第三方插件),',\n '或发送 `/safemode status` 查看状态。',\n ].join('\\n'),\n msg.messageId,\n );\n }\n\n private track(promise: Promise<void>): Promise<void> {\n this.activeMessages.add(promise);\n void promise.finally(() => {\n this.activeMessages.delete(promise);\n });\n return promise;\n }\n\n private async handleControl(\n kind: GuardianControlKind,\n msg: NormalizedMessage,\n ): Promise<void> {\n switch (kind) {\n case 'safemode':\n await this.enterSafeMode(msg);\n return;\n case 'safemode-status':\n await this.sendStatus(msg);\n return;\n case 'safemode-plugins':\n await this.sendPluginList(msg);\n return;\n case 'safemode-exit':\n await this.exitSafeMode(msg);\n return;\n case 'safemode-help':\n await this.sendMarkdown(msg.chatId, safemodeHelpText(), msg.messageId);\n return;\n }\n }\n\n private async enterSafeMode(msg: NormalizedMessage): Promise<void> {\n if (this.state.mode === 'safe') {\n await this.sendMarkdown(\n msg.chatId,\n '已在安全模式中。发送普通消息与 dsh 核心对话;`/safemode exit` 退出。',\n msg.messageId,\n );\n return;\n }\n await this.sendMarkdown(\n msg.chatId,\n '正在进入安全模式:仅挂载 dsh 主核心(`dsh-base` + `dsh-headless`),不加载任何第三方插件…',\n msg.messageId,\n );\n try {\n await ensureSafeProfile({\n home: this.options.home,\n dshProfile: this.state.dshProfile,\n env: this.options.env ?? process.env,\n });\n const bin = this.dshBin;\n if (!bin) {\n await this.sendMarkdown(\n msg.chatId,\n '未找到本机 dsh 安装,无法进入安全模式。请先确认 `dsh` 可用。',\n msg.messageId,\n );\n return;\n }\n const probe = await (this.options.probeSafeProfileFn ?? probeSafeProfile)({\n bin,\n dshProfile: this.state.dshProfile,\n home: this.options.home,\n env: this.options.env ?? process.env,\n });\n if (!probe.ok) {\n await this.sendMarkdown(\n msg.chatId,\n [\n '安全模式就绪检查失败(dsh 核心无法解析):',\n '',\n '```',\n (probe.error ?? 'unknown error').slice(0, 1_500),\n '```',\n ].join('\\n'),\n msg.messageId,\n );\n return;\n }\n this.safeAdapter ??=\n this.options.adapter ??\n new DshAdapter({\n command: 'node',\n args: [bin, '--profile', this.state.safeProfile],\n stopGraceMs: 5_000,\n });\n await this.setMode('safe');\n await this.sendMarkdown(\n msg.chatId,\n [\n '安全模式已就绪:dsh 主核心运行中,第三方插件未加载。',\n '',\n '现在可以直接对话进行自愈(定位 / 修复 / 禁用损坏插件),例如:',\n '- “列出当前 profile 安装的插件并检查哪个最近变坏”',\n '- “用 `/safemode plugins` 查看插件清单”',\n '- 修复完成后发送 `/safemode exit` 重启完整 profile。',\n ].join('\\n'),\n msg.messageId,\n );\n } catch (error) {\n await this.sendMarkdown(\n msg.chatId,\n `进入安全模式失败:${error instanceof Error ? error.message : String(error)}`,\n msg.messageId,\n );\n }\n }\n\n private async sendStatus(msg: NormalizedMessage): Promise<void> {\n const snapshot = this.snapshot();\n await this.sendMarkdown(\n msg.chatId,\n [\n `模式:${snapshot.mode}`,\n `dsh profile:${snapshot.dshProfile}`,\n `安全 profile:${snapshot.safeProfile}`,\n `dsh 是否在线:${snapshot.dshUp ? '是' : '否'}`,\n `心跳龄:${snapshot.heartbeatAgeMs === undefined ? '无' : `${snapshot.heartbeatAgeMs}ms`}`,\n `飞书通道:${snapshot.channelConnected ? '守护已接管' : '未连接'}`,\n `dsh bin:${snapshot.dshBin ?? '未发现'}`,\n `守护 pid:${snapshot.pid}`,\n `已观察过 dsh 运行:${snapshot.profileSeenUp ? '是' : '否'}`,\n ].join('\\n'),\n msg.messageId,\n );\n }\n\n private async sendPluginList(msg: NormalizedMessage): Promise<void> {\n const bin = this.dshBin;\n if (!bin) {\n await this.sendMarkdown(\n msg.chatId,\n '未找到本机 dsh 安装,无法列出插件。',\n msg.messageId,\n );\n return;\n }\n const run = this.options.runPluginList ?? defaultRunPluginList;\n const result = await run(bin, this.state.dshProfile);\n const output = [result.stdout, result.stderr].filter(Boolean).join('\\n').trim();\n await this.sendMarkdown(\n msg.chatId,\n [\n `profile \\`${this.state.dshProfile}\\` 已安装的插件(依赖清单):`,\n '',\n '```',\n (output || '(空)').slice(0, 3_000),\n '```',\n ].join('\\n'),\n msg.messageId,\n );\n }\n\n private async exitSafeMode(msg: NormalizedMessage): Promise<void> {\n if (this.state.mode !== 'safe') {\n await this.sendMarkdown(\n msg.chatId,\n '当前不在安全模式,无需退出。',\n msg.messageId,\n );\n return;\n }\n const bin = this.dshBin;\n if (!bin) {\n await this.sendMarkdown(\n msg.chatId,\n '未找到本机 dsh 安装,无法重启完整 profile。',\n msg.messageId,\n );\n return;\n }\n const spawn = this.options.spawnDetachedFn ?? spawnDetached;\n const spawned: DetachedSpawn = spawn('node', [bin, '--profile', this.state.dshProfile]);\n if (spawned.pid !== undefined) this.state.relaunchedPid = spawned.pid;\n await this.save();\n await this.sendMarkdown(\n msg.chatId,\n [\n `正在退出安全模式并重启完整 profile(\\`${this.state.dshProfile}\\`)…`,\n '守护进程将断开飞书连接并把通道交还给 dsh 桥接引擎。',\n ].join('\\n'),\n msg.messageId,\n );\n // Give the reply a moment to flush before releasing the channel.\n await delay(this.options.sendDelayMs);\n this.transcripts.clear();\n await this.disconnectChannel();\n }\n\n private async runSafeTask(scope: string, msg: NormalizedMessage): Promise<void> {\n const adapter = this.safeAdapter;\n if (!adapter) {\n await this.sendMarkdown(\n msg.chatId,\n '安全模式未就绪,请先发送 `/safemode`。',\n msg.messageId,\n );\n return;\n }\n const transcript = this.transcripts.get(scope) ?? [];\n const prompt = buildSafePrompt(transcript, msg.content);\n await this.sendMarkdown(\n msg.chatId,\n '(安全模式 · dsh 核心处理中…)',\n msg.messageId,\n );\n\n const run = adapter.run({\n runId: randomUUID(),\n prompt,\n cwd: this.config?.workspaces.default,\n sessionId: undefined,\n model: undefined,\n images: undefined,\n stopGraceMs: 5_000,\n });\n const textParts: string[] = [];\n let finalText: string | undefined;\n let errorText: string | undefined;\n let terminal = false;\n try {\n for await (const event of run.events) {\n if (event.type === 'text' && event.delta) textParts.push(event.delta);\n if (event.type === 'final_text') finalText = event.content;\n if (event.type === 'error') {\n errorText = event.message;\n terminal = true;\n }\n if (event.type === 'done') terminal = true;\n }\n } catch (error) {\n errorText = error instanceof Error ? error.message : String(error);\n terminal = true;\n }\n\n if (!terminal) {\n await run.waitForExit(SAFE_RUN_TIMEOUT_MS);\n }\n\n if (errorText) {\n await this.sendMarkdown(\n msg.chatId,\n `(安全模式 · dsh 核心错误)\\n${errorText.slice(0, 2_000)}`,\n msg.messageId,\n );\n return;\n }\n const answer = finalText ?? textParts.join('').trim();\n if (!answer) {\n await this.sendMarkdown(\n msg.chatId,\n '(安全模式 · dsh 核心未返回内容)',\n msg.messageId,\n );\n return;\n }\n await this.sendMarkdown(msg.chatId, answer, msg.messageId);\n this.transcripts.set(scope, pushTranscript(transcript, [\n { role: 'user', content: msg.content },\n { role: 'assistant', content: answer },\n ]));\n }\n}\n\nfunction buildSafePrompt(\n transcript: readonly TranscriptEntry[],\n current: string,\n): string {\n if (transcript.length === 0) return current;\n const history = transcript\n .map((entry) => `${entry.role === 'user' ? '用户' : '助手'}: ${entry.content}`)\n .join('\\n');\n return [\n '以下是本次安全模式对话的上下文(用于连续性,不是新任务指令):',\n '',\n history,\n '',\n `用户: ${current}`,\n ].join('\\n');\n}\n\nfunction pushTranscript(\n existing: readonly TranscriptEntry[],\n entries: readonly TranscriptEntry[],\n): TranscriptEntry[] {\n return [...existing, ...entries].slice(-MAX_TRANSCRIPT_ENTRIES);\n}\n\nasync function defaultRunPluginList(\n bin: string,\n dshProfile: string,\n): Promise<{ stdout: string; stderr: string }> {\n return captureOutput('node', [bin, 'plugin', '--profile', dshProfile, 'list'], 60_000);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction parseFreshness(value: string | undefined): number {\n const raw = value?.trim();\n if (!raw) return 600_000;\n const parsed = Number(raw);\n return Number.isInteger(parsed) && parsed >= 0 ? parsed : 600_000;\n}\n\ntype DefinedValues<T> = { [K in keyof T]: Exclude<T[K], undefined> };\n\n/** Copy only defined values, satisfying exactOptionalPropertyTypes. */\nfunction defined<T extends Record<string, unknown>>(input: T): DefinedValues<T> {\n const output: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(input)) {\n if (value !== undefined) output[key] = value;\n }\n return output as DefinedValues<T>;\n}\n\n/** Resolve the guardian's file layout for a runtime env (used by the CLI). */\nexport interface GuardianLayout {\n paths: AppPaths;\n stateFile: string;\n heartbeatFile: string;\n configFile: string;\n}\n\nexport function guardianLayoutFor(\n env: RuntimeEnv,\n bridgeProfile: string,\n): GuardianLayout {\n const paths = resolveAppPaths(env.home);\n return {\n paths,\n stateFile: join(paths.root, 'guardian.json'),\n heartbeatFile: paths.profilePath(bridgeProfile, 'guardian', 'heartbeat.json'),\n configFile: paths.configFile,\n };\n}\n\nexport async function buildGuardianService(\n env: RuntimeEnv,\n overrides: Partial<GuardianServiceOptions> = {},\n): Promise<GuardianService> {\n const paths = resolveAppPaths(env.home);\n const stateFile = join(paths.root, 'guardian.json');\n const fallback = newGuardianState({\n dshProfile: env.guardianProfile,\n bridgeProfile: env.guardianBridgeProfile,\n });\n const state = await loadGuardianState(stateFile, fallback);\n return new GuardianService({\n stateFile,\n configFile: paths.configFile,\n heartbeatFile: paths.profilePath(state.bridgeProfile, 'guardian', 'heartbeat.json'),\n home: homedir(),\n env: process.env,\n dshProfile: state.dshProfile,\n bridgeProfile: state.bridgeProfile,\n safeProfile: state.safeProfile,\n pollMs: env.guardianPollMs,\n staleMs: env.guardianStaleMs,\n engineDeadMs: env.guardianEngineDeadMs,\n ...overrides,\n });\n}\n","/**\n * Control signals understood by the safety-net guardian.\n *\n * While the dsh profile is down the guardian is the only Feishu listener, so\n * these commands are the user's rescue entrance. They are intentionally few\n * and stable:\n *\n * - `/safemode` enter core-only safe mode (mount dsh core, no\n * third-party plugins) and start the restricted\n * conversation;\n * - `/safemode status` report guardian / dsh / safe-mode state;\n * - `/safemode plugins` list plugins installed into the broken profile\n * (diagnostics for self-healing);\n * - `/safemode exit` leave safe mode, relaunch the full profile and\n * hand the Feishu channel back;\n * - `/safemode help` print the above.\n */\n\nexport type GuardianControlKind =\n | 'safemode'\n | 'safemode-status'\n | 'safemode-plugins'\n | 'safemode-exit'\n | 'safemode-help';\n\nexport interface GuardianControl {\n kind: GuardianControlKind;\n /** Normalized argument after the command word, if any. */\n argument: string;\n}\n\nconst COMMAND_RE = /^\\/(safemode)(?:\\s+(.+))?$/i;\n\nexport function parseGuardianCommand(text: string): GuardianControl | undefined {\n const trimmed = text.trim();\n const match = COMMAND_RE.exec(trimmed);\n if (!match) return undefined;\n const argument = match[2]?.trim().toLowerCase() ?? '';\n switch (argument) {\n case '':\n case 'start':\n case 'enter':\n return { kind: 'safemode', argument };\n case 'status':\n return { kind: 'safemode-status', argument };\n case 'plugins':\n case 'list':\n return { kind: 'safemode-plugins', argument };\n case 'exit':\n case 'quit':\n case 'leave':\n case 'restore':\n return { kind: 'safemode-exit', argument };\n case 'help':\n case '?':\n return { kind: 'safemode-help', argument };\n default:\n // Unknown sub-command: treat as help so the user sees valid options.\n return { kind: 'safemode-help', argument };\n }\n}\n\nexport const SAFEMODE_HELP = [\n '/safemode — 进入仅核心安全模式(dsh 主核心 + 官方 headless,不加载任何第三方插件)',\n '/safemode status — 查看守护状态',\n '/safemode plugins — 列出故障 profile 已安装的插件',\n '/safemode exit — 退出安全模式,重启完整 profile 并交还飞书通道',\n '',\n '安全模式下发送普通消息即可与 dsh 核心对话,进行定位 / 修复 / 禁用损坏插件的自愈操作。',\n].join('\\n');\n\nexport const SAFEMODE_HELP_EN = [\n '/safemode — enter core-only safe mode (dsh core + official headless, no third-party plugins)',\n '/safemode status — show guardian state',\n '/safemode plugins — list plugins installed into the broken profile',\n '/safemode exit — leave safe mode, relaunch the full profile and hand the channel back',\n '',\n 'In safe mode, send normal messages to converse with the dsh core for self-healing.',\n].join('\\n');\n\nexport function safemodeHelpText(): string {\n return `${SAFEMODE_HELP}\\n\\n${SAFEMODE_HELP_EN}`;\n}\n","import { mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { resolveDshHome } from '../config/dsh-runtime.js';\n\n/**\n * Core-only \"safe mode\" dsh profile provisioning.\n *\n * Safe mode must mount the dsh main core and NO third-party plugins (this is\n * what makes it useful when a broken plugin kills the full profile boot).\n * The minimal composition is the official core bundle plus the official\n * one-shot headless app — exactly the shipped `headless` template, under a\n * dedicated profile name we own (`<dsh-profile>-safe`) so it can never be\n * polluted by plugins installed into other profiles.\n *\n * Both bundles resolve from the dsh installation's own dependency closure\n * (dsh heals `$DSH_HOME/profiles/node_modules` on boot), so no pnpm install\n * is needed and the safe profile boots even when the normal profile's\n * node_modules / third-party plugins are broken.\n */\n\nexport const SAFE_CORE_BUNDLES = [\n '@deepseek-ai/dsh-base',\n '@deepseek-ai/dsh-headless',\n] as const;\n\nexport interface SafeProfileEnsureOptions {\n /** OS home used to resolve `~/.dsh` (same as the bridge runtime). */\n home: string;\n /** dsh profile name whose safe variant we manage (`dsh-lark` → `dsh-lark-safe`). */\n dshProfile: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface SafeProfileEnsureResult {\n root: string;\n created: boolean;\n}\n\nexport function safeProfileName(dshProfile: string): string {\n return `${dshProfile}-safe`;\n}\n\nexport function safeProfileRoot(\n home: string,\n dshProfile: string,\n env?: NodeJS.ProcessEnv,\n): string {\n return join(resolveDshHome(home, env), 'profiles', safeProfileName(dshProfile));\n}\n\n/**\n * Create the safe profile files when missing (existing files are never\n * overwritten, so a manually adjusted safe profile keeps working). Returns\n * the profile root and whether anything was created.\n */\nexport async function ensureSafeProfile(\n options: SafeProfileEnsureOptions,\n): Promise<SafeProfileEnsureResult> {\n const root = safeProfileRoot(options.home, options.dshProfile, options.env);\n const name = safeProfileName(options.dshProfile);\n await mkdir(root, { recursive: true });\n let created = false;\n\n const manifest = join(root, 'package.json');\n if (!existsSync(manifest)) {\n await writeFile(\n manifest,\n `${JSON.stringify(\n {\n name: `dsh-profile-${name}`,\n private: true,\n dependencies: {},\n dsh: {\n profile: {\n bundles: [...SAFE_CORE_BUNDLES],\n },\n },\n },\n null,\n 2,\n )}\\n`,\n 'utf8',\n );\n created = true;\n }\n\n const rootConfig = join(root, 'cordis.yml');\n if (!existsSync(rootConfig)) {\n await writeFile(\n rootConfig,\n '# dsh profile root - an empty entry list; the tree is composed as patches.\\n[]\\n',\n 'utf8',\n );\n created = true;\n }\n\n const userPatch = join(root, 'cordis.patch.yml');\n if (!existsSync(userPatch)) {\n // Deliberately empty: safe mode mounts only the core bundles, no\n // third-party rows and no bridge plugin.\n await writeFile(userPatch, '[]\\n', 'utf8');\n created = true;\n }\n\n const workspace = join(root, 'pnpm-workspace.yaml');\n if (!existsSync(workspace)) {\n await writeFile(\n workspace,\n [\n 'packages:',\n ' - .',\n '',\n '',\n 'nodeLinker: hoisted',\n 'autoInstallPeers: false',\n '',\n ].join('\\n'),\n 'utf8',\n );\n created = true;\n }\n\n return { root, created };\n}\n\nexport interface SafeProfileProbeOptions {\n /** Absolute dsh bin (`@deepseek-ai/dsh/lib/bin.js`) or the `dsh` launcher. */\n bin: string;\n /** dsh profile name whose safe variant is probed. */\n dshProfile: string;\n /** OS home used to resolve `~/.dsh`. */\n home: string;\n env?: NodeJS.ProcessEnv;\n /** Injectable runner for tests. */\n run?: (\n command: string,\n args: readonly string[],\n ) => Promise<{ code: number; stdout: string; stderr: string }>;\n}\n\nexport interface SafeProfileProbeResult {\n ok: boolean;\n stdout: string;\n stderr: string;\n error?: string;\n}\n\nasync function defaultRun(\n command: string,\n args: readonly string[],\n): Promise<{ code: number; stdout: string; stderr: string }> {\n const { spawn } = await import('node:child_process');\n return new Promise((resolve) => {\n const child = spawn(command, [...args], { stdio: ['ignore', 'pipe', 'pipe'] });\n let stdout = '';\n let stderr = '';\n child.stdout?.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8');\n });\n child.stderr?.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8');\n });\n child.on('error', (error: Error) => {\n resolve({ code: 1, stdout, stderr: `${error.message}\\n` });\n });\n child.on('close', (code) => {\n resolve({ code: code ?? 1, stdout, stderr });\n });\n });\n}\n\n/**\n * Probe the safe profile with the boot-free `dsh --dump-config` invocation:\n * it composes the bundle layers and the user patch without mounting any\n * plugin, which is exactly the \"can the core still resolve\" check. Failures\n * (unresolvable bundles / broken patch) are surfaced to the user in Feishu.\n */\nexport async function probeSafeProfile(\n options: SafeProfileProbeOptions,\n): Promise<SafeProfileProbeResult> {\n const run = options.run ?? defaultRun;\n const profile = safeProfileName(options.dshProfile);\n const result = await run(options.bin, ['--profile', profile, '--dump-config']);\n if (result.code === 0) {\n return { ok: true, stdout: result.stdout, stderr: result.stderr };\n }\n const tail = result.stderr.trim().split('\\n').slice(-5).join('\\n');\n return {\n ok: false,\n stdout: result.stdout,\n stderr: result.stderr,\n error: tail || `dsh --profile ${profile} --dump-config exited with code ${result.code}`,\n };\n}\n"],"mappings":"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","names":["resolve","existsSync","join","spawn","existsSync","realpathSync","readFileSync","mkdir","writeFile","join","packageJsonFor","ownPackageLinked","runPnpmInstall","resolve","randomUUID","isRecord","buildPromptText","waitForChildExit","resolve","readFileSync","realpathSync","fileURLToPath","homedir","spawn","resolve","spawn","resolve","isRecord","stringValue","resolve","spawn","existsSync","readFileSync","join","resolve","buildAcpAgentAdapter","homedir","homedir","join","join","resolve","homedir","mkdir","dirname","mkdir","writeFile","dirname","join","rm","mkdir","dirname","mkdir","realpathSync","resolve","REDACTED","resolve","randomUUID","resolve","readFile","readFile","resolve","markdown","randomUUID","markdown","randomUUID","resolve","mkdir","readFile","writeFile","homedir","dirname","join","readFile","resolve","writeFile","homedir","join","mkdir","dirname","markdown","unsupported","reply","markdown","record","reply","markdown","requireAdmin","reply","markdown","reply","markdown","resolve","minutes","markdown","readFile","readFile","randomBytes","resolve","randomBytes","mkdir","readFile","stat","join","mkdir","join","stat","readFile","readFile","readFile","randomBytes","mkdir","readFile","writeFile","join","randomBytes","join","mkdir","writeFile","readFile","execFile","randomBytes","access","mkdir","dirname","join","promisify","execFileAsync","promisify","execFile","defaultRunGit","exists","access","mkdir","dirname","slugify","join","randomBytes","readFile","readFile","readFile","readFile","errorMessage","mkdir","resolve","spawn","mkdir","readFile","writeFile","homedir","join","mkdir","readFile","rm","writeFile","existsSync","homedir","join","spawn","resolve","spawn","readFile","dirname","mkdir","readFile","mkdir","dirname","join","homedir","mkdir","writeFile","rm","homedir","join","mkdir","resolve","spawn","readFile","writeFile","join","randomUUID","homedir","join","createLarkChannel","mkdir","writeFile","existsSync","join","defaultRun","spawn","resolve","parseFreshness","createLarkChannel","access","markdown","spawn","randomUUID","resolve","join","homedir","waitForShutdown","join","resolve","readFileSync","realpathSync","fileURLToPath"]}
|