agent-handoff 0.3.0 → 0.5.0

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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/cli/commands/init.ts","../src/cli/commands/status.ts","../src/core/workspace.ts","../src/core/workflow-parser.ts","../src/core/state-machine.ts","../src/cli/commands/next.ts","../src/core/prompt-generator.ts","../src/core/clipboard.ts","../src/core/events-writer.ts","../src/cli/commands/validate.ts","../src/core/artifact-validator.ts","../src/cli/commands/advance.ts","../src/cli/commands/config.ts","../src/core/config.ts","../src/cli/commands/report.ts","../src/adapters/trae/operation-reporter.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createRequire } from 'module';\nimport { Command } from 'commander';\nimport { initCommand } from './cli/commands/init.js';\nimport { statusCommand } from './cli/commands/status.js';\nimport { nextCommand } from './cli/commands/next.js';\nimport { validateCommand } from './cli/commands/validate.js';\nimport { advanceCommand } from './cli/commands/advance.js';\nimport { configCommand } from './cli/commands/config.js';\nimport { reportCommand } from './cli/commands/report.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json');\n\nconst program = new Command();\n\nprogram\n .name('agent-handoff')\n .description('轻量级多 Agent 协作接力工具')\n .version(version);\n\nprogram.addCommand(initCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(nextCommand);\nprogram.addCommand(validateCommand);\nprogram.addCommand(advanceCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(reportCommand);\n\nprogram.parse();\n","import { Command } from 'commander';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nexport const initCommand = new Command('init')\n .description('创建新的 workspace')\n .argument('<name>', 'workspace 名称')\n .option('-p, --path <path>', '父目录路径', process.cwd())\n .action(async (name: string, options: { path: string }) => {\n const workspacePath = path.resolve(options.path, name);\n\n try {\n await fs.access(workspacePath);\n console.error(`Error: workspace \"${name}\" already exists at ${workspacePath}`);\n process.exit(1);\n } catch {\n // 目录不存在,继续创建\n }\n\n try {\n await fs.mkdir(workspacePath, { recursive: true });\n await fs.mkdir(path.join(workspacePath, 'steps'), { recursive: true });\n\n const workflowTemplate = `name: ${name}\nsteps:\n - id: clarify\n executor: trae\n input: brief.md\n output: steps/01-clarify/output.md\n acceptance:\n - 澄清需求范围与非目标\n - 产出结构化需求文档\n`;\n\n const stateTemplate = JSON.stringify({\n currentIndex: 0,\n status: 'running',\n updatedAt: new Date().toISOString(),\n }, null, 2);\n\n const briefTemplate = `# brief:需求描述\n\n## 背景\n(请描述项目背景)\n\n## 目标\n(请描述本轮目标)\n\n## 非目标\n(请描述本轮不做的事情)\n\n## 验收标准\n(请描述验收标准)\n`;\n\n await fs.writeFile(path.join(workspacePath, 'workflow.yaml'), workflowTemplate);\n await fs.writeFile(path.join(workspacePath, 'state.json'), stateTemplate);\n await fs.writeFile(path.join(workspacePath, 'brief.md'), briefTemplate);\n\n console.log(`✅ Created workspace \"${name}\" at ${workspacePath}`);\n console.log(`\nNext steps:\n 1. Edit brief.md to describe your requirements\n 2. Run \"agent-handoff status ${name}\" to check workspace status\n 3. Run \"agent-handoff next ${name}\" to get the first step prompt\n`);\n } catch (error) {\n console.error(`Error creating workspace: ${error}`);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { computeState } from '../../core/state-machine.js';\n\nexport const statusCommand = new Command('status')\n .description('显示 workspace 状态')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-j, --json', 'JSON 格式输出')\n .action(async (workspace: string, options: { json: boolean }) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const stateResult = computeState(info.workflow, info.stepOutputs);\n\n if (options.json) {\n const jsonOutput = {\n name: info.workflow.name,\n path: workspacePath,\n status: stateResult.status,\n currentIndex: stateResult.currentIndex,\n totalSteps: info.workflow.steps.length,\n completedSteps: stateResult.completedSteps.length,\n steps: info.workflow.steps.map((step, index) => ({\n index,\n id: step.id,\n executor: step.executor,\n workItemId: step.workItemId,\n completed: info.stepOutputs.get(step.id) ?? false,\n })),\n };\n console.log(JSON.stringify(jsonOutput, null, 2));\n } else {\n console.log(`Workspace: ${info.workflow.name}`);\n console.log(`Status: ${stateResult.status}`);\n console.log('');\n console.log('Steps:');\n\n info.workflow.steps.forEach((step, index) => {\n const completed = info.stepOutputs.get(step.id) ?? false;\n const statusIcon = completed ? '✅' : '⬜';\n const stepNum = String(index + 1).padStart(2, '0');\n let line = ` ${statusIcon} ${stepNum}-${step.id} (${step.executor})`;\n if (step.workItemId) {\n line += ` [${step.workItemId}]`;\n }\n console.log(line);\n });\n\n console.log('');\n if (stateResult.status === 'done') {\n console.log('Current: completed');\n } else {\n const currentStep = info.workflow.steps[stateResult.currentIndex];\n console.log(`Current: step ${stateResult.currentIndex + 1} (${currentStep?.id})`);\n }\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { Workflow } from './models/workflow.js';\nimport { State } from './models/state.js';\nimport { parseWorkflow } from './workflow-parser.js';\n\nexport interface WorkspaceInfo {\n path: string;\n exists: boolean;\n hasWorkflow: boolean;\n hasState: boolean;\n workflow?: Workflow;\n state?: State;\n stepOutputs: Map<string, boolean>;\n}\n\nexport async function loadWorkspace(workspacePath: string): Promise<WorkspaceInfo> {\n const absolutePath = path.resolve(workspacePath);\n const workflowPath = path.join(absolutePath, 'workflow.yaml');\n const statePath = path.join(absolutePath, 'state.json');\n\n let exists = false;\n let hasWorkflow = false;\n let hasState = false;\n let workflow: Workflow | undefined;\n let state: State | undefined;\n let stepOutputs = new Map<string, boolean>();\n\n try {\n await fs.access(absolutePath);\n exists = true;\n } catch {\n return {\n path: absolutePath,\n exists: false,\n hasWorkflow: false,\n hasState: false,\n stepOutputs,\n };\n }\n\n try {\n await fs.access(workflowPath);\n hasWorkflow = true;\n workflow = await parseWorkflow(workflowPath);\n } catch {\n hasWorkflow = false;\n }\n\n try {\n const stateContent = await fs.readFile(statePath, 'utf-8');\n hasState = true;\n state = JSON.parse(stateContent) as State;\n } catch {\n hasState = false;\n }\n\n if (workflow) {\n stepOutputs = await detectStepOutputs(absolutePath, workflow);\n }\n\n return {\n path: absolutePath,\n exists,\n hasWorkflow,\n hasState,\n workflow,\n state,\n stepOutputs,\n };\n}\n\nexport async function detectStepOutputs(\n workspacePath: string,\n workflow: Workflow\n): Promise<Map<string, boolean>> {\n const outputs = new Map<string, boolean>();\n\n for (const step of workflow.steps) {\n const outputPath = path.join(workspacePath, step.output);\n try {\n const content = await fs.readFile(outputPath, 'utf-8');\n outputs.set(step.id, content.trim().length > 0);\n } catch {\n outputs.set(step.id, false);\n }\n }\n\n return outputs;\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function fileNotEmpty(filePath: string): Promise<boolean> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return content.trim().length > 0;\n } catch {\n return false;\n }\n}\n","import fs from 'fs/promises';\nimport YAML from 'yaml';\nimport { Workflow, Step, Executor } from './models/workflow';\n\nexport async function parseWorkflow(filePath: string): Promise<Workflow> {\n const content = await fs.readFile(filePath, 'utf-8');\n const parsed = YAML.parse(content);\n \n if (!parsed || typeof parsed !== 'object') {\n throw new Error(`Invalid workflow.yaml: ${filePath}`);\n }\n \n if (!parsed.name || typeof parsed.name !== 'string') {\n throw new Error('workflow.yaml missing required field: name');\n }\n \n if (!Array.isArray(parsed.steps) || parsed.steps.length === 0) {\n throw new Error('workflow.yaml missing required field: steps (non-empty array)');\n }\n \n const steps: Step[] = parsed.steps.map((step: Record<string, unknown>, index: number) => {\n if (!step.id || typeof step.id !== 'string') {\n throw new Error(`Step ${index} missing required field: id`);\n }\n if (!step.executor || typeof step.executor !== 'string') {\n throw new Error(`Step ${index} missing required field: executor`);\n }\n if (!step.input || typeof step.input !== 'string') {\n throw new Error(`Step ${index} missing required field: input`);\n }\n if (!step.output || typeof step.output !== 'string') {\n throw new Error(`Step ${index} missing required field: output`);\n }\n \n return {\n id: step.id,\n executor: step.executor as Executor,\n input: step.input,\n output: step.output,\n workItemId: step.workItemId as string | undefined,\n acceptance: step.acceptance as string[] | undefined,\n };\n });\n \n return {\n name: parsed.name,\n steps,\n };\n}\n\nexport function validateWorkflow(workflow: Workflow): string[] {\n const errors: string[] = [];\n \n if (!workflow.name || workflow.name.trim() === '') {\n errors.push('workflow.name is required');\n }\n \n if (!workflow.steps || workflow.steps.length === 0) {\n errors.push('workflow.steps is required and must be non-empty');\n return errors;\n }\n \n workflow.steps.forEach((step, index) => {\n if (!step.id || step.id.trim() === '') {\n errors.push(`steps[${index}].id is required`);\n }\n if (!step.executor) {\n errors.push(`steps[${index}].executor is required`);\n }\n if (!step.input || step.input.trim() === '') {\n errors.push(`steps[${index}].input is required`);\n }\n if (!step.output || step.output.trim() === '') {\n errors.push(`steps[${index}].output is required`);\n }\n if (!step.output.startsWith('steps/')) {\n errors.push(`steps[${index}].output should start with 'steps/'`);\n }\n });\n \n return errors;\n}\n","import { Workflow } from './models/workflow';\nimport { State, WorkflowStatus } from './models/state';\n\nexport interface StateMachineResult {\n currentIndex: number;\n status: WorkflowStatus;\n nextStepIndex: number | null;\n completedSteps: number[];\n pendingSteps: number[];\n}\n\nexport function computeState(\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): StateMachineResult {\n if (!workflow.steps || workflow.steps.length === 0) {\n return {\n currentIndex: 0,\n status: 'done',\n nextStepIndex: null,\n completedSteps: [],\n pendingSteps: [],\n };\n }\n\n const completedSteps: number[] = [];\n const pendingSteps: number[] = [];\n let currentIndex = 0;\n let status: WorkflowStatus = 'running';\n\n for (let i = 0; i < workflow.steps.length; i++) {\n const step = workflow.steps[i];\n const outputExists = stepOutputs.get(step.id) ?? false;\n\n if (outputExists) {\n completedSteps.push(i);\n } else {\n pendingSteps.push(i);\n }\n }\n\n const firstPendingIndex = pendingSteps[0];\n\n if (firstPendingIndex === undefined) {\n currentIndex = workflow.steps.length;\n status = 'done';\n } else {\n currentIndex = firstPendingIndex;\n status = 'running';\n }\n\n return {\n currentIndex,\n status,\n nextStepIndex: status === 'done' ? null : currentIndex,\n completedSteps,\n pendingSteps,\n };\n}\n\nexport function advanceState(\n state: State,\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): State {\n const result = computeState(workflow, stepOutputs);\n\n return {\n ...state,\n currentIndex: result.currentIndex,\n status: result.status,\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport function isWorkflowComplete(\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): boolean {\n if (!workflow.steps || workflow.steps.length === 0) {\n return true;\n }\n\n return workflow.steps.every((step) => stepOutputs.get(step.id) === true);\n}\n\nexport function getCurrentStep(\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): { index: number; step: typeof workflow.steps[0] } | null {\n const result = computeState(workflow, stepOutputs);\n\n if (result.status === 'done' || result.nextStepIndex === null) {\n return null;\n }\n\n return {\n index: result.nextStepIndex,\n step: workflow.steps[result.nextStepIndex],\n };\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { computeState, getCurrentStep } from '../../core/state-machine.js';\nimport { generatePrompt } from '../../core/prompt-generator.js';\nimport { copyToClipboard, isClipboardSupported } from '../../core/clipboard.js';\nimport { writeEvent } from '../../core/events-writer.js';\n\nexport const nextCommand = new Command('next')\n .description('输出下一步执行指令和 prompt')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-c, --copy', '复制 prompt 到剪贴板')\n .option('--no-event', '不写入事件日志')\n .action(async (workspace: string, options: { copy: boolean; event: boolean }) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const stateResult = computeState(info.workflow, info.stepOutputs);\n\n if (stateResult.status === 'done') {\n console.log(`Workflow \"${info.workflow.name}\" 已完成所有步骤。`);\n console.log('无下一步操作。');\n return;\n }\n\n const currentStep = getCurrentStep(info.workflow, info.stepOutputs);\n\n if (!currentStep) {\n console.log(`Workflow \"${info.workflow.name}\" 已完成所有步骤。`);\n console.log('无下一步操作。');\n return;\n }\n\n const { step, index } = currentStep;\n\n console.log(`Step: ${step.id}`);\n console.log(`Executor: ${step.executor}`);\n if (step.workItemId) {\n console.log(`Work Item: ${step.workItemId}`);\n }\n console.log('');\n console.log('Input:');\n console.log(` - ${step.input}`);\n console.log('');\n console.log('Output:');\n console.log(` - ${step.output}`);\n console.log('');\n console.log('Prompt:');\n console.log('────────────────────────────────────────');\n\n const prompt = generatePrompt({\n workflow: info.workflow,\n step,\n stepIndex: index,\n workspacePath: info.path,\n });\n\n console.log(prompt);\n console.log('────────────────────────────────────────');\n console.log('');\n\n if (options.event) {\n await writeEvent({\n workspacePath,\n step: { index: index + 1, id: step.id },\n type: 'step.started',\n summary: `开始执行步骤: ${step.id}`,\n workItemId: step.workItemId,\n links: [step.input],\n });\n }\n\n if (options.copy) {\n if (!isClipboardSupported()) {\n console.log('⚠️ 剪贴板功能在当前环境不可用');\n console.log('请手动复制上面的 Prompt');\n } else {\n const result = await copyToClipboard(prompt);\n if (result.success) {\n console.log('✅ Prompt 已复制到剪贴板');\n } else {\n console.log(`❌ 复制失败: ${result.error}`);\n console.log('请手动复制上面的 Prompt');\n }\n }\n } else {\n console.log('提示:将上述 Prompt 复制到 TRAE 新 Task 中执行');\n console.log(' 使用 --copy 选项可自动复制到剪贴板');\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n","import { Workflow, Step } from './models/workflow.js';\n\nexport interface PromptContext {\n workflow: Workflow;\n step: Step;\n stepIndex: number;\n workspacePath: string;\n}\n\nexport function generatePrompt(context: PromptContext): string {\n const { workflow, step, stepIndex } = context;\n const totalSteps = workflow.steps.length;\n const stepNum = stepIndex + 1;\n\n let prompt = `# 任务:${step.id}\n\n## 上下文\n- Workflow: ${workflow.name}\n- Step: ${stepNum} / ${totalSteps}\n- Executor: ${step.executor}`;\n\n if (step.workItemId) {\n prompt += `\\n- Work Item: ${step.workItemId}`;\n }\n\n prompt += `\n\n## 输入产物\n请阅读以下输入产物:\n- ${step.input}\n\n## 输出产物\n请将结果写入:\n- ${step.output}`;\n\n if (step.acceptance && step.acceptance.length > 0) {\n prompt += `\n\n## 验收标准`;\n for (const criteria of step.acceptance) {\n prompt += `\\n- ${criteria}`;\n }\n }\n\n prompt += `\n\n## 输出要求\n完成后请在 output.md 中包含以下区块:\n- 产物更新\n- 关键决策\n- 风险与待确认\n- 下一步交接\n\n---\nAgentHandoff Step Prompt`;\n\n return prompt;\n}\n","import clipboard from 'clipboardy';\n\nexport interface ClipboardResult {\n success: boolean;\n error?: string;\n}\n\nlet clipboardSupported: boolean | null = null;\n\nexport function isClipboardSupported(): boolean {\n if (clipboardSupported !== null) {\n return clipboardSupported;\n }\n\n try {\n clipboardSupported = true;\n return true;\n } catch {\n clipboardSupported = false;\n return false;\n }\n}\n\nexport async function copyToClipboard(text: string): Promise<ClipboardResult> {\n try {\n await clipboard.write(text);\n return { success: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: errorMessage,\n };\n }\n}\n\nexport async function readFromClipboard(): Promise<string> {\n try {\n return await clipboard.read();\n } catch {\n return '';\n }\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { Event, EventType, EventStep } from './models/event.js';\n\nexport interface WriteEventOptions {\n workspacePath: string;\n step: EventStep;\n type: EventType;\n summary: string;\n workItemId?: string;\n links?: string[];\n data?: Record<string, unknown>;\n}\n\nexport interface EventsWriterResult {\n success: boolean;\n event: Event;\n error?: string;\n}\n\nexport async function writeEvent(options: WriteEventOptions): Promise<EventsWriterResult> {\n const { workspacePath, step, type, summary, workItemId, links, data } = options;\n\n const event: Event = {\n ts: new Date().toISOString(),\n step,\n type,\n summary,\n ...(workItemId && { workItemId }),\n ...(links && links.length > 0 && { links }),\n ...(data && { data }),\n };\n\n try {\n const eventsPath = path.join(workspacePath, 'events.jsonl');\n const line = JSON.stringify(event) + '\\n';\n await fs.appendFile(eventsPath, line, 'utf-8');\n\n return {\n success: true,\n event,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n event,\n error: errorMessage,\n };\n }\n}\n\nexport async function readEvents(workspacePath: string): Promise<Event[]> {\n const eventsPath = path.join(workspacePath, 'events.jsonl');\n\n try {\n const content = await fs.readFile(eventsPath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim());\n\n const events: Event[] = [];\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Event;\n events.push(event);\n } catch {\n // Skip invalid lines\n }\n }\n\n return events;\n } catch {\n return [];\n }\n}\n\nexport async function getLatestEvent(workspacePath: string): Promise<Event | null> {\n const events = await readEvents(workspacePath);\n if (events.length === 0) {\n return null;\n }\n return events[events.length - 1];\n}\n\nexport async function getEventsByStep(workspacePath: string, stepId: string): Promise<Event[]> {\n const events = await readEvents(workspacePath);\n return events.filter((event) => event.step.id === stepId);\n}\n\nexport async function getEventsByType(workspacePath: string, type: EventType): Promise<Event[]> {\n const events = await readEvents(workspacePath);\n return events.filter((event) => event.type === type);\n}\n\nexport async function getEventsByWorkItem(\n workspacePath: string,\n workItemId: string\n): Promise<Event[]> {\n const events = await readEvents(workspacePath);\n return events.filter((event) => event.workItemId === workItemId);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { validateWorkspaceArtifacts } from '../../core/artifact-validator.js';\n\nexport const validateCommand = new Command('validate')\n .description('校验 workspace 产物结构')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('--strict', '严格模式(将警告视为错误)')\n .option('-j, --json', 'JSON 格式输出')\n .action(async (workspace: string, options: { strict: boolean; json: boolean }) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const result = await validateWorkspaceArtifacts(workspacePath);\n\n if (options.json) {\n const jsonOutput = {\n valid: options.strict ? result.valid && result.warningCount === 0 : result.valid,\n workspace: workspacePath,\n totalSteps: result.totalSteps,\n validSteps: result.validSteps,\n errorCount: result.errorCount,\n warningCount: result.warningCount,\n steps: Array.from(result.stepResults.entries()).map(([stepId, stepResult]) => ({\n stepId,\n valid: options.strict ? stepResult.valid && stepResult.warnings.length === 0 : stepResult.valid,\n errors: stepResult.errors,\n warnings: stepResult.warnings,\n })),\n };\n console.log(JSON.stringify(jsonOutput, null, 2));\n } else {\n console.log(`Workspace: ${info.workflow.name}`);\n console.log('');\n\n for (const step of info.workflow.steps) {\n const stepResult = result.stepResults.get(step.id);\n if (!stepResult) continue;\n\n const icon = stepResult.valid ? '✅' : '❌';\n console.log(`${icon} ${step.output} - ${stepResult.valid ? 'Valid' : 'Invalid'}`);\n\n if (!stepResult.valid) {\n for (const error of stepResult.errors) {\n console.log(` - ${error.message}`);\n }\n }\n\n if (stepResult.warnings.length > 0) {\n for (const warning of stepResult.warnings) {\n console.log(` ⚠️ ${warning.message}`);\n }\n }\n }\n\n console.log('');\n\n const hasErrors = result.errorCount > 0;\n const hasWarnings = result.warningCount > 0;\n const strictFail = options.strict && hasWarnings;\n\n if (!hasErrors && !strictFail) {\n console.log('All artifacts validated successfully.');\n if (hasWarnings) {\n console.log(`⚠️ ${result.warningCount} warning(s) found.`);\n }\n } else {\n const totalErrors = result.errorCount + (strictFail ? result.warningCount : 0);\n console.log(`Validation failed with ${totalErrors} error(s).`);\n }\n\n if (hasErrors || strictFail) {\n process.exit(1);\n }\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { loadWorkspace } from './workspace.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n}\n\nexport interface ValidationError {\n type: 'missing_section' | 'empty_section' | 'invalid_format';\n section: string;\n message: string;\n}\n\nexport interface ValidationWarning {\n type: 'short_content' | 'missing_detail';\n section: string;\n message: string;\n}\n\nexport const REQUIRED_SECTIONS = [\n '产物更新',\n '关键决策',\n '风险与待确认',\n '下一步交接',\n] as const;\n\nexport type RequiredSection = (typeof REQUIRED_SECTIONS)[number];\n\nexport interface WorkspaceValidationResult {\n valid: boolean;\n stepResults: Map<string, ValidationResult>;\n totalSteps: number;\n validSteps: number;\n errorCount: number;\n warningCount: number;\n}\n\nconst MIN_CONTENT_LENGTH = 10;\n\nexport function validateArtifact(content: string): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n for (const section of REQUIRED_SECTIONS) {\n const sectionResult = findSection(content, section);\n\n if (!sectionResult.found) {\n errors.push({\n type: 'missing_section',\n section,\n message: `缺少必要区块: ${section}`,\n });\n } else if (!sectionResult.hasContent) {\n errors.push({\n type: 'empty_section',\n section,\n message: `区块内容为空: ${section}`,\n });\n } else if (sectionResult.contentLength < MIN_CONTENT_LENGTH) {\n warnings.push({\n type: 'short_content',\n section,\n message: `区块内容过短 (${sectionResult.contentLength} 字符): ${section}`,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\ninterface SectionResult {\n found: boolean;\n hasContent: boolean;\n contentLength: number;\n}\n\nfunction findSection(content: string, sectionName: string): SectionResult {\n const patterns = [\n new RegExp(`^##\\\\s+${escapeRegex(sectionName)}[^\\\\n]*$`, 'm'),\n new RegExp(`^###\\\\s+${escapeRegex(sectionName)}[^\\\\n]*$`, 'm'),\n ];\n\n let matchIndex = -1;\n let matchLength = 0;\n\n for (const pattern of patterns) {\n const match = content.match(pattern);\n if (match && match.index !== undefined) {\n matchIndex = match.index;\n matchLength = match[0].length;\n break;\n }\n }\n\n if (matchIndex === -1) {\n return { found: false, hasContent: false, contentLength: 0 };\n }\n\n const contentStart = matchIndex + matchLength;\n const remainingContent = content.slice(contentStart);\n\n const nextSectionMatch = remainingContent.match(/^#{1,3}\\s+/m);\n const sectionContent = nextSectionMatch\n ? remainingContent.slice(0, nextSectionMatch.index)\n : remainingContent;\n\n const trimmedContent = sectionContent.trim();\n\n return {\n found: true,\n hasContent: trimmedContent.length > 0,\n contentLength: trimmedContent.length,\n };\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport async function validateArtifactFile(\n filePath: string\n): Promise<ValidationResult> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return validateArtifact(content);\n } catch {\n return {\n valid: false,\n errors: [\n {\n type: 'invalid_format',\n section: '',\n message: `无法读取文件: ${filePath}`,\n },\n ],\n warnings: [],\n };\n }\n}\n\nexport async function validateWorkspaceArtifacts(\n workspacePath: string\n): Promise<WorkspaceValidationResult> {\n const workspace = await loadWorkspace(workspacePath);\n const stepResults = new Map<string, ValidationResult>();\n let validSteps = 0;\n let errorCount = 0;\n let warningCount = 0;\n\n if (!workspace.workflow) {\n return {\n valid: false,\n stepResults,\n totalSteps: 0,\n validSteps: 0,\n errorCount: 1,\n warningCount: 0,\n };\n }\n\n for (const step of workspace.workflow.steps) {\n const outputPath = path.join(workspace.path, step.output);\n const result = await validateArtifactFile(outputPath);\n stepResults.set(step.id, result);\n\n if (result.valid) {\n validSteps++;\n }\n errorCount += result.errors.length;\n warningCount += result.warnings.length;\n }\n\n return {\n valid: errorCount === 0,\n stepResults,\n totalSteps: workspace.workflow.steps.length,\n validSteps,\n errorCount,\n warningCount,\n };\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { computeState, getCurrentStep } from '../../core/state-machine.js';\nimport { writeEvent } from '../../core/events-writer.js';\nimport { EventType } from '../../core/models/event.js';\n\nexport const advanceCommand = new Command('advance')\n .description('推进 workspace 状态')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-e, --event <type>', '事件类型', 'step.done')\n .option('-s, --summary <text>', '事件摘要')\n .option('--no-state', '不更新 state.json')\n .option('--skip-event', '不写入事件日志')\n .action(\n async (\n workspace: string,\n options: { event: string; summary?: string; state: boolean; skipEvent: boolean }\n ) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const stateResult = computeState(info.workflow, info.stepOutputs);\n\n console.log(`Workspace: ${info.workflow.name}`);\n\n if (stateResult.status === 'done') {\n console.log('Status: done');\n console.log('');\n console.log('⚠️ Workflow already completed. No steps to advance.');\n return;\n }\n\n const currentStep = getCurrentStep(info.workflow, info.stepOutputs);\n\n if (!currentStep) {\n console.log('Status: done');\n console.log('');\n console.log('⚠️ Workflow already completed. No steps to advance.');\n return;\n }\n\n const { step, index } = currentStep;\n\n console.log(`Current step: ${step.id} (index: ${index})`);\n console.log('');\n\n const eventType = options.event as EventType;\n const eventSummary = options.summary || getDefaultSummary(eventType, step.id);\n\n if (!options.skipEvent) {\n const result = await writeEvent({\n workspacePath,\n step: { index: index + 1, id: step.id },\n type: eventType,\n summary: eventSummary,\n workItemId: step.workItemId,\n links: [step.output],\n });\n\n if (result.success) {\n console.log(`✅ Event written: ${eventType}`);\n console.log(` Summary: ${eventSummary}`);\n if (step.workItemId) {\n console.log(` Work Item: ${step.workItemId}`);\n }\n if (step.output) {\n console.log(` Links: ${step.output}`);\n }\n } else {\n console.log(`❌ Failed to write event: ${result.error}`);\n }\n }\n\n if (options.state) {\n const statePath = path.join(workspacePath, 'state.json');\n const newIndex = index + 1;\n const isDone = newIndex >= info.workflow.steps.length;\n\n const newState = {\n currentIndex: newIndex,\n status: isDone ? 'done' : 'running',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.writeFile(statePath, JSON.stringify(newState, null, 2));\n console.log('');\n console.log(`✅ State updated: ${statePath}`);\n console.log(` Current index: ${newState.currentIndex}`);\n console.log(` Status: ${newState.status}`);\n\n if (isDone) {\n console.log('');\n console.log('🎉 Workflow completed!');\n } else {\n const nextStep = info.workflow.steps[newIndex];\n console.log(` Next step: ${nextStep.id}`);\n }\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n\nfunction getDefaultSummary(eventType: EventType, stepId: string): string {\n const summaries: Record<EventType, string> = {\n 'step.started': `开始执行步骤: ${stepId}`,\n 'step.done': `步骤完成: ${stepId}`,\n 'artifact.updated': '产物已更新',\n 'workflow.updated': '工作流已更新',\n 'verify.passed': '验证通过',\n 'verify.failed': '验证失败',\n 'accept.passed': '验收通过',\n 'accept.failed': '验收失败',\n 'issue.raised': '发现问题',\n 'handoff.sent': '已交接给下一步',\n 'automation.session': '自动化会话已记录',\n };\n return summaries[eventType] || `事件: ${eventType}`;\n}\n","import { Command } from 'commander';\nimport os from 'os';\nimport {\n loadConfig,\n findConfigFile,\n initConfigFile,\n DEFAULT_CONFIG,\n} from '../../core/config.js';\n\nexport const configCommand = new Command('config')\n .description('查看或管理配置')\n .argument('[action]', '操作: show, init', 'show')\n .option('-g, --global', '操作全局配置')\n .option('--verbose', '显示详细信息')\n .action(async (action: string, options: { global: boolean; verbose: boolean }) => {\n try {\n if (action === 'show') {\n await showConfig(options);\n } else if (action === 'init') {\n await initConfig(options);\n } else if (action === 'list') {\n await listConfig();\n } else {\n console.error(`Unknown action: ${action}`);\n console.log('Available actions: show, init, list');\n process.exit(1);\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n\nasync function showConfig(options: { global: boolean; verbose: boolean }): Promise<void> {\n const targetPath = options.global ? os.homedir() : process.cwd();\n const config = await loadConfig(targetPath);\n\n if (options.verbose) {\n const configFile = await findConfigFile(targetPath);\n if (configFile) {\n console.log(`Config file: ${configFile}`);\n console.log('');\n } else {\n console.log('No config file found, using defaults');\n console.log('');\n }\n }\n\n console.log(JSON.stringify(config, null, 2));\n}\n\nasync function initConfig(options: { global: boolean; verbose: boolean }): Promise<void> {\n const targetPath = options.global ? os.homedir() : process.cwd();\n const configPath = await initConfigFile(targetPath, options.global);\n\n console.log(`✅ Created config file: ${configPath}`);\n console.log('');\n console.log('Default configuration:');\n console.log(JSON.stringify(DEFAULT_CONFIG, null, 2));\n}\n\nasync function listConfig(): Promise<void> {\n console.log('Configuration options:');\n console.log('');\n console.log(' defaultWorkspace - 默认 workspace 路径');\n console.log(' events.enabled - 是否启用事件日志 (default: true)');\n console.log(' events.logStepStarted - 是否记录 step.started (default: true)');\n console.log(' events.logStepDone - 是否记录 step.done (default: true)');\n console.log(' clipboard.autoCopy - 是否自动复制 prompt (default: false)');\n console.log(' prompt.templatePath - 自定义 prompt 模板路径');\n console.log(' prompt.language - prompt 语言 (default: zh)');\n console.log(' validation.strict - 严格校验模式 (default: false)');\n console.log(' validation.warnOnShortContent - 内容过短时警告 (default: true)');\n console.log('');\n console.log('Config file locations (in order of priority):');\n console.log(' .agenthandoffrc');\n console.log(' .agenthandoffrc.json');\n console.log(' .agenthandoffrc.yaml');\n console.log(' package.json#agenthandoff');\n console.log(` ~/.agenthandoffrc (global)`);\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\n\nexport interface AgentHandoffConfig {\n defaultWorkspace?: string;\n events?: {\n enabled: boolean;\n logStepStarted: boolean;\n logStepDone: boolean;\n };\n automation?: {\n enabled: boolean;\n provider: 'nutjs';\n screenshot: boolean;\n timeout: number;\n retries: number;\n confidence?: number;\n };\n clipboard?: {\n autoCopy: boolean;\n };\n prompt?: {\n templatePath?: string;\n language: 'zh' | 'en';\n };\n validation?: {\n strict: boolean;\n warnOnShortContent: boolean;\n };\n}\n\nexport const DEFAULT_CONFIG: AgentHandoffConfig = {\n events: {\n enabled: true,\n logStepStarted: true,\n logStepDone: true,\n },\n automation: {\n enabled: false,\n provider: 'nutjs',\n screenshot: false,\n timeout: 30000,\n retries: 3,\n confidence: 0.8,\n },\n clipboard: {\n autoCopy: false,\n },\n prompt: {\n language: 'zh',\n },\n validation: {\n strict: false,\n warnOnShortContent: true,\n },\n};\n\nconst CONFIG_FILES = [\n '.agenthandoffrc',\n '.agenthandoffrc.json',\n '.agenthandoffrc.yaml',\n '.agenthandoffrc.yml',\n];\n\nconst configCache = new Map<string, AgentHandoffConfig>();\n\nexport async function findConfigFile(startPath: string): Promise<string | null> {\n let currentPath = path.resolve(startPath);\n const homePath = os.homedir();\n\n while (true) {\n for (const configFile of CONFIG_FILES) {\n const filePath = path.join(currentPath, configFile);\n try {\n await fs.access(filePath);\n return filePath;\n } catch {\n // File doesn't exist, continue\n }\n }\n\n const packageJsonPath = path.join(currentPath, 'package.json');\n try {\n const content = await fs.readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n if (pkg.agenthandoff) {\n return packageJsonPath;\n }\n } catch {\n // File doesn't exist or invalid, continue\n }\n\n if (currentPath === homePath || currentPath === path.dirname(currentPath)) {\n break;\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\nexport async function loadConfigFile(filePath: string): Promise<Partial<AgentHandoffConfig>> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const ext = path.extname(filePath);\n\n if (ext === '.yaml' || ext === '.yml') {\n return parseYaml(content);\n }\n\n if (filePath.endsWith('package.json')) {\n const pkg = JSON.parse(content);\n return pkg.agenthandoff || {};\n }\n\n return JSON.parse(content);\n } catch {\n return {};\n }\n}\n\nfunction parseYaml(content: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const lines = content.split('\\n');\n let currentObj: Record<string, unknown> = result;\n const stack: Array<{ obj: Record<string, unknown> }> = [];\n\n for (const line of lines) {\n if (!line.trim() || line.trim().startsWith('#')) {\n continue;\n }\n\n const indent = line.search(/\\S/);\n const trimmed = line.trim();\n\n if (trimmed.includes(':')) {\n const colonIndex = trimmed.indexOf(':');\n const key = trimmed.slice(0, colonIndex).trim();\n const value = trimmed.slice(colonIndex + 1).trim();\n\n if (value === '') {\n if (stack.length > 0) {\n const expectedIndent = stack.length * 2;\n if (indent < expectedIndent) {\n while (stack.length > 0 && indent < stack.length * 2) {\n stack.pop();\n }\n if (stack.length > 0) {\n currentObj = stack[stack.length - 1].obj as Record<string, unknown>;\n } else {\n currentObj = result;\n }\n }\n }\n\n const newObj: Record<string, unknown> = {};\n currentObj[key] = newObj;\n stack.push({ obj: currentObj });\n currentObj = newObj;\n } else {\n let parsedValue: unknown = value;\n if (value === 'true') parsedValue = true;\n else if (value === 'false') parsedValue = false;\n else if (value === 'null') parsedValue = null;\n else if (/^\\d+$/.test(value)) parsedValue = parseInt(value, 10);\n else if (/^\\d+\\.\\d+$/.test(value)) parsedValue = parseFloat(value);\n else if (value.startsWith('\"') && value.endsWith('\"')) {\n parsedValue = value.slice(1, -1);\n } else if (value.startsWith(\"'\") && value.endsWith(\"'\")) {\n parsedValue = value.slice(1, -1);\n }\n\n currentObj[key] = parsedValue;\n }\n }\n }\n\n return result;\n}\n\nexport function mergeConfig(\n base: AgentHandoffConfig,\n override: Partial<AgentHandoffConfig>\n): AgentHandoffConfig {\n const result: AgentHandoffConfig = JSON.parse(JSON.stringify(base));\n\n for (const key of Object.keys(override) as Array<keyof AgentHandoffConfig>) {\n const overrideValue = override[key];\n if (overrideValue === undefined) continue;\n\n if (\n typeof overrideValue === 'object' &&\n overrideValue !== null &&\n !Array.isArray(overrideValue)\n ) {\n const baseValue = result[key];\n if (\n typeof baseValue === 'object' &&\n baseValue !== null &&\n !Array.isArray(baseValue)\n ) {\n // Deep merge for nested objects\n (result as Record<string, unknown>)[key] = mergeConfig(\n baseValue as AgentHandoffConfig,\n overrideValue as Partial<AgentHandoffConfig>\n );\n } else {\n (result as Record<string, unknown>)[key] = overrideValue;\n }\n } else {\n (result as Record<string, unknown>)[key] = overrideValue;\n }\n }\n\n return result;\n}\n\nexport async function loadConfig(workspacePath?: string): Promise<AgentHandoffConfig> {\n const startPath = workspacePath ? path.resolve(workspacePath) : process.cwd();\n const cacheKey = startPath;\n\n if (configCache.has(cacheKey)) {\n return configCache.get(cacheKey)!;\n }\n\n let config = JSON.parse(JSON.stringify(DEFAULT_CONFIG)) as AgentHandoffConfig;\n\n const globalConfigPath = path.join(os.homedir(), '.agenthandoffrc');\n try {\n await fs.access(globalConfigPath);\n const globalConfig = await loadConfigFile(globalConfigPath);\n config = mergeConfig(config, globalConfig);\n } catch {\n // Global config doesn't exist\n }\n\n const localConfigFile = await findConfigFile(startPath);\n if (localConfigFile) {\n const localConfig = await loadConfigFile(localConfigFile);\n config = mergeConfig(config, localConfig);\n }\n\n configCache.set(cacheKey, config);\n return config;\n}\n\nexport function clearConfigCache(): void {\n configCache.clear();\n}\n\nexport async function initConfigFile(targetPath: string, global = false): Promise<string> {\n const configPath = global\n ? path.join(os.homedir(), '.agenthandoffrc')\n : path.join(targetPath, '.agenthandoffrc');\n\n const content = JSON.stringify(DEFAULT_CONFIG, null, 2);\n await fs.writeFile(configPath, content, 'utf-8');\n\n return configPath;\n}\n","import { Command } from 'commander';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { OperationReporter } from '../../adapters/trae/operation-reporter.js';\n\ntype ReportFormat = 'json' | 'markdown' | 'html';\n\nexport const reportCommand = new Command('report')\n .description('生成自动化操作报告')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-f, --format <format>', '报告格式: json, markdown, html', 'markdown')\n .option('-s, --session <id>', '指定 session ID')\n .option('--screenshots', '包含截图', false)\n .option('-o, --output <path>', '输出路径')\n .action(\n async (\n workspace: string,\n options: { format: ReportFormat; session?: string; screenshots: boolean; output?: string }\n ) => {\n const workspacePath = path.resolve(workspace);\n const logDir = path.join(workspacePath, 'operations');\n\n try {\n let sessionFile: string;\n if (options.session) {\n sessionFile = path.join(logDir, `operations-${options.session}.jsonl`);\n } else {\n const files = await fs.readdir(logDir);\n const jsonlFiles = files\n .filter((f) => f.endsWith('.jsonl'))\n .sort()\n .reverse();\n if (jsonlFiles.length === 0) {\n console.error('Error: no operation logs found');\n process.exit(1);\n }\n sessionFile = path.join(logDir, jsonlFiles[0]);\n }\n\n const content = await fs.readFile(sessionFile, 'utf-8');\n const lines = content.split('\\n').filter((l) => l.trim());\n const session = JSON.parse(lines[lines.length - 1]);\n\n const reporter = new OperationReporter(session);\n const report = reporter.generate({\n format: options.format,\n includeScreenshots: options.screenshots,\n });\n\n if (options.output) {\n await fs.writeFile(path.resolve(options.output), report, 'utf-8');\n console.log(`✅ Report saved to: ${options.output}`);\n } else {\n console.log(report);\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n\n","import fs from 'fs/promises';\nimport { TraeSession } from './types';\n\nexport interface ReportOptions {\n format: 'json' | 'markdown' | 'html';\n includeScreenshots: boolean;\n}\n\nexport class OperationReporter {\n private session: TraeSession;\n\n constructor(session: TraeSession) {\n this.session = session;\n }\n\n generate(options: ReportOptions): string {\n switch (options.format) {\n case 'json':\n return this.generateJson();\n case 'markdown':\n return this.generateMarkdown(options.includeScreenshots);\n case 'html':\n return this.generateHtml(options.includeScreenshots);\n default:\n return this.generateMarkdown(options.includeScreenshots);\n }\n }\n\n private generateJson(): string {\n return JSON.stringify(this.session, null, 2);\n }\n\n private generateMarkdown(includeScreenshots: boolean): string {\n const lines: string[] = [\n '# Automation Session Report',\n '',\n `**Session ID:** ${this.session.id}`,\n `**Started At:** ${this.session.startedAt}`,\n `**Workspace:** ${this.session.workspacePath}`,\n `**Step ID:** ${this.session.stepId}`,\n ...(this.session.status ? [`**Status:** ${this.session.status}`] : []),\n ...(this.session.error ? [`**Error:** ${this.session.error}`] : []),\n '',\n `## Operations (${this.session.operations.length})`,\n '',\n ];\n\n this.session.operations.forEach((op, index) => {\n lines.push(`### ${index + 1}. ${op.type}`);\n if (op.target) {\n lines.push(`- **Target:** ${op.target}`);\n }\n if (op.value) {\n lines.push(\n `- **Value:** ${op.value.substring(0, 100)}${op.value.length > 100 ? '...' : ''}`\n );\n }\n lines.push(`- **Timestamp:** ${new Date(op.timestamp).toISOString()}`);\n lines.push('');\n });\n\n if (includeScreenshots && this.session.screenshots.length > 0) {\n lines.push(`## Screenshots (${this.session.screenshots.length})`);\n lines.push('');\n this.session.screenshots.forEach((screenshot, index) => {\n lines.push(`### Screenshot ${index + 1}`);\n lines.push(`![Screenshot ${index + 1}](${screenshot})`);\n lines.push('');\n });\n }\n\n return lines.join('\\n');\n }\n\n private generateHtml(includeScreenshots: boolean): string {\n const operationsHtml = this.session.operations\n .map(\n (op, index) => `\n <div class=\"operation\">\n <h3>${index + 1}. ${op.type}</h3>\n ${op.target ? `<p><strong>Target:</strong> ${op.target}</p>` : ''}\n ${\n op.value\n ? `<p><strong>Value:</strong> ${op.value.substring(0, 100)}${\n op.value.length > 100 ? '...' : ''\n }</p>`\n : ''\n }\n <p><strong>Timestamp:</strong> ${new Date(op.timestamp).toISOString()}</p>\n </div>\n `\n )\n .join('');\n\n const screenshotsHtml =\n includeScreenshots && this.session.screenshots.length > 0\n ? `\n <h2>Screenshots (${this.session.screenshots.length})</h2>\n ${this.session.screenshots\n .map(\n (s, i) => `\n <div class=\"screenshot\">\n <h3>Screenshot ${i + 1}</h3>\n <img src=\"${s}\" alt=\"Screenshot ${i + 1}\" />\n </div>\n `\n )\n .join('')}\n `\n : '';\n\n const statusLine = this.session.status\n ? `<p><strong>Status:</strong> ${this.session.status}</p>`\n : '';\n const errorLine = this.session.error ? `<p><strong>Error:</strong> ${this.session.error}</p>` : '';\n\n return `\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Automation Session Report</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n max-width: 800px;\n margin: 0 auto;\n padding: 20px;\n background: #f5f5f5;\n }\n .header {\n background: white;\n padding: 20px;\n border-radius: 8px;\n margin-bottom: 20px;\n }\n .operation {\n background: white;\n padding: 15px;\n border-radius: 8px;\n margin-bottom: 10px;\n }\n .screenshot img {\n max-width: 100%;\n border-radius: 8px;\n }\n h1 { color: #333; }\n h2 { color: #555; border-bottom: 1px solid #eee; padding-bottom: 10px; }\n h3 { color: #666; margin: 0 0 10px 0; }\n p { margin: 5px 0; color: #666; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <h1>Automation Session Report</h1>\n <p><strong>Session ID:</strong> ${this.session.id}</p>\n <p><strong>Started At:</strong> ${this.session.startedAt}</p>\n <p><strong>Workspace:</strong> ${this.session.workspacePath}</p>\n <p><strong>Step ID:</strong> ${this.session.stepId}</p>\n ${statusLine}\n ${errorLine}\n </div>\n\n <h2>Operations (${this.session.operations.length})</h2>\n ${operationsHtml}\n\n ${screenshotsHtml}\n</body>\n</html>\n `.trim();\n }\n\n async saveToFile(outputPath: string, options: ReportOptions): Promise<string> {\n const content = this.generate(options);\n await fs.writeFile(outputPath, content, 'utf-8');\n return outputPath;\n }\n}\n\n"],"mappings":";;;AACA,SAAS,qBAAqB;AAC9B,SAAS,WAAAA,gBAAe;;;ACFxB,SAAS,eAAe;AACxB,OAAO,QAAQ;AACf,OAAO,UAAU;AAEV,IAAM,cAAc,IAAI,QAAQ,MAAM,EAC1C,YAAY,oCAAgB,EAC5B,SAAS,UAAU,wBAAc,EACjC,OAAO,qBAAqB,kCAAS,QAAQ,IAAI,CAAC,EAClD,OAAO,OAAO,MAAc,YAA8B;AACzD,QAAM,gBAAgB,KAAK,QAAQ,QAAQ,MAAM,IAAI;AAErD,MAAI;AACF,UAAM,GAAG,OAAO,aAAa;AAC7B,YAAQ,MAAM,qBAAqB,IAAI,uBAAuB,aAAa,EAAE;AAC7E,YAAQ,KAAK,CAAC;AAAA,EAChB,QAAQ;AAAA,EAER;AAEA,MAAI;AACF,UAAM,GAAG,MAAM,eAAe,EAAE,WAAW,KAAK,CAAC;AACjD,UAAM,GAAG,MAAM,KAAK,KAAK,eAAe,OAAO,GAAG,EAAE,WAAW,KAAK,CAAC;AAErE,UAAM,mBAAmB,SAAS,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWtC,UAAM,gBAAgB,KAAK,UAAU;AAAA,MACnC,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,GAAG,MAAM,CAAC;AAEV,UAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAetB,UAAM,GAAG,UAAU,KAAK,KAAK,eAAe,eAAe,GAAG,gBAAgB;AAC9E,UAAM,GAAG,UAAU,KAAK,KAAK,eAAe,YAAY,GAAG,aAAa;AACxE,UAAM,GAAG,UAAU,KAAK,KAAK,eAAe,UAAU,GAAG,aAAa;AAEtE,YAAQ,IAAI,6BAAwB,IAAI,QAAQ,aAAa,EAAE;AAC/D,YAAQ,IAAI;AAAA;AAAA;AAAA,iCAGe,IAAI;AAAA,+BACN,IAAI;AAAA,CAClC;AAAA,EACG,SAAS,OAAO;AACd,YAAQ,MAAM,6BAA6B,KAAK,EAAE;AAClD,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;;;ACtEH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,WAAU;;;ACDjB,OAAOC,SAAQ;AACf,OAAOC,WAAU;;;ACDjB,OAAOC,SAAQ;AACf,OAAO,UAAU;AAGjB,eAAsB,cAAc,UAAqC;AACvE,QAAM,UAAU,MAAMA,IAAG,SAAS,UAAU,OAAO;AACnD,QAAM,SAAS,KAAK,MAAM,OAAO;AAEjC,MAAI,CAAC,UAAU,OAAO,WAAW,UAAU;AACzC,UAAM,IAAI,MAAM,0BAA0B,QAAQ,EAAE;AAAA,EACtD;AAEA,MAAI,CAAC,OAAO,QAAQ,OAAO,OAAO,SAAS,UAAU;AACnD,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AAEA,MAAI,CAAC,MAAM,QAAQ,OAAO,KAAK,KAAK,OAAO,MAAM,WAAW,GAAG;AAC7D,UAAM,IAAI,MAAM,+DAA+D;AAAA,EACjF;AAEA,QAAM,QAAgB,OAAO,MAAM,IAAI,CAAC,MAA+B,UAAkB;AACvF,QAAI,CAAC,KAAK,MAAM,OAAO,KAAK,OAAO,UAAU;AAC3C,YAAM,IAAI,MAAM,QAAQ,KAAK,6BAA6B;AAAA,IAC5D;AACA,QAAI,CAAC,KAAK,YAAY,OAAO,KAAK,aAAa,UAAU;AACvD,YAAM,IAAI,MAAM,QAAQ,KAAK,mCAAmC;AAAA,IAClE;AACA,QAAI,CAAC,KAAK,SAAS,OAAO,KAAK,UAAU,UAAU;AACjD,YAAM,IAAI,MAAM,QAAQ,KAAK,gCAAgC;AAAA,IAC/D;AACA,QAAI,CAAC,KAAK,UAAU,OAAO,KAAK,WAAW,UAAU;AACnD,YAAM,IAAI,MAAM,QAAQ,KAAK,iCAAiC;AAAA,IAChE;AAEA,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,MACb,YAAY,KAAK;AAAA,MACjB,YAAY,KAAK;AAAA,IACnB;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,MAAM,OAAO;AAAA,IACb;AAAA,EACF;AACF;;;ADhCA,eAAsB,cAAc,eAA+C;AACjF,QAAM,eAAeC,MAAK,QAAQ,aAAa;AAC/C,QAAM,eAAeA,MAAK,KAAK,cAAc,eAAe;AAC5D,QAAM,YAAYA,MAAK,KAAK,cAAc,YAAY;AAEtD,MAAI,SAAS;AACb,MAAI,cAAc;AAClB,MAAI,WAAW;AACf,MAAI;AACJ,MAAI;AACJ,MAAI,cAAc,oBAAI,IAAqB;AAE3C,MAAI;AACF,UAAMC,IAAG,OAAO,YAAY;AAC5B,aAAS;AAAA,EACX,QAAQ;AACN,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,UAAU;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAEA,MAAI;AACF,UAAMA,IAAG,OAAO,YAAY;AAC5B,kBAAc;AACd,eAAW,MAAM,cAAc,YAAY;AAAA,EAC7C,QAAQ;AACN,kBAAc;AAAA,EAChB;AAEA,MAAI;AACF,UAAM,eAAe,MAAMA,IAAG,SAAS,WAAW,OAAO;AACzD,eAAW;AACX,YAAQ,KAAK,MAAM,YAAY;AAAA,EACjC,QAAQ;AACN,eAAW;AAAA,EACb;AAEA,MAAI,UAAU;AACZ,kBAAc,MAAM,kBAAkB,cAAc,QAAQ;AAAA,EAC9D;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAsB,kBACpB,eACA,UAC+B;AAC/B,QAAM,UAAU,oBAAI,IAAqB;AAEzC,aAAW,QAAQ,SAAS,OAAO;AACjC,UAAM,aAAaD,MAAK,KAAK,eAAe,KAAK,MAAM;AACvD,QAAI;AACF,YAAM,UAAU,MAAMC,IAAG,SAAS,YAAY,OAAO;AACrD,cAAQ,IAAI,KAAK,IAAI,QAAQ,KAAK,EAAE,SAAS,CAAC;AAAA,IAChD,QAAQ;AACN,cAAQ,IAAI,KAAK,IAAI,KAAK;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO;AACT;;;AE9EO,SAAS,aACd,UACA,aACoB;AACpB,MAAI,CAAC,SAAS,SAAS,SAAS,MAAM,WAAW,GAAG;AAClD,WAAO;AAAA,MACL,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,gBAAgB,CAAC;AAAA,MACjB,cAAc,CAAC;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,iBAA2B,CAAC;AAClC,QAAM,eAAyB,CAAC;AAChC,MAAI,eAAe;AACnB,MAAI,SAAyB;AAE7B,WAAS,IAAI,GAAG,IAAI,SAAS,MAAM,QAAQ,KAAK;AAC9C,UAAM,OAAO,SAAS,MAAM,CAAC;AAC7B,UAAM,eAAe,YAAY,IAAI,KAAK,EAAE,KAAK;AAEjD,QAAI,cAAc;AAChB,qBAAe,KAAK,CAAC;AAAA,IACvB,OAAO;AACL,mBAAa,KAAK,CAAC;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,oBAAoB,aAAa,CAAC;AAExC,MAAI,sBAAsB,QAAW;AACnC,mBAAe,SAAS,MAAM;AAC9B,aAAS;AAAA,EACX,OAAO;AACL,mBAAe;AACf,aAAS;AAAA,EACX;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,eAAe,WAAW,SAAS,OAAO;AAAA,IAC1C;AAAA,IACA;AAAA,EACF;AACF;AA4BO,SAAS,eACd,UACA,aAC0D;AAC1D,QAAM,SAAS,aAAa,UAAU,WAAW;AAEjD,MAAI,OAAO,WAAW,UAAU,OAAO,kBAAkB,MAAM;AAC7D,WAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,OAAO,OAAO;AAAA,IACd,MAAM,SAAS,MAAM,OAAO,aAAa;AAAA,EAC3C;AACF;;;AH/FO,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC9C,YAAY,qCAAiB,EAC7B,SAAS,eAAe,0BAAgB,GAAG,EAC3C,OAAO,cAAc,+BAAW,EAChC,OAAO,OAAO,WAAmB,YAA+B;AAC/D,QAAM,gBAAgBC,MAAK,QAAQ,SAAS;AAE5C,MAAI;AACF,UAAM,OAAO,MAAM,cAAc,aAAa;AAE9C,QAAI,CAAC,KAAK,QAAQ;AAChB,cAAQ,MAAM,+BAA+B,aAAa,EAAE;AAC5D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,KAAK,aAAa;AACrB,cAAQ,MAAM,qCAAqC,aAAa,EAAE;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,KAAK,UAAU;AAClB,cAAQ,MAAM,sCAAsC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,cAAc,aAAa,KAAK,UAAU,KAAK,WAAW;AAEhE,QAAI,QAAQ,MAAM;AAChB,YAAM,aAAa;AAAA,QACjB,MAAM,KAAK,SAAS;AAAA,QACpB,MAAM;AAAA,QACN,QAAQ,YAAY;AAAA,QACpB,cAAc,YAAY;AAAA,QAC1B,YAAY,KAAK,SAAS,MAAM;AAAA,QAChC,gBAAgB,YAAY,eAAe;AAAA,QAC3C,OAAO,KAAK,SAAS,MAAM,IAAI,CAAC,MAAM,WAAW;AAAA,UAC/C;AAAA,UACA,IAAI,KAAK;AAAA,UACT,UAAU,KAAK;AAAA,UACf,YAAY,KAAK;AAAA,UACjB,WAAW,KAAK,YAAY,IAAI,KAAK,EAAE,KAAK;AAAA,QAC9C,EAAE;AAAA,MACJ;AACA,cAAQ,IAAI,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AAAA,IACjD,OAAO;AACL,cAAQ,IAAI,cAAc,KAAK,SAAS,IAAI,EAAE;AAC9C,cAAQ,IAAI,WAAW,YAAY,MAAM,EAAE;AAC3C,cAAQ,IAAI,EAAE;AACd,cAAQ,IAAI,QAAQ;AAEpB,WAAK,SAAS,MAAM,QAAQ,CAAC,MAAM,UAAU;AAC3C,cAAM,YAAY,KAAK,YAAY,IAAI,KAAK,EAAE,KAAK;AACnD,cAAM,aAAa,YAAY,WAAM;AACrC,cAAM,UAAU,OAAO,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AACjD,YAAI,OAAO,KAAK,UAAU,IAAI,OAAO,IAAI,KAAK,EAAE,KAAK,KAAK,QAAQ;AAClE,YAAI,KAAK,YAAY;AACnB,kBAAQ,KAAK,KAAK,UAAU;AAAA,QAC9B;AACA,gBAAQ,IAAI,IAAI;AAAA,MAClB,CAAC;AAED,cAAQ,IAAI,EAAE;AACd,UAAI,YAAY,WAAW,QAAQ;AACjC,gBAAQ,IAAI,oBAAoB;AAAA,MAClC,OAAO;AACL,cAAM,cAAc,KAAK,SAAS,MAAM,YAAY,YAAY;AAChE,gBAAQ,IAAI,iBAAiB,YAAY,eAAe,CAAC,KAAK,aAAa,EAAE,GAAG;AAAA,MAClF;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,UAAU,KAAK,EAAE;AAC/B,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;;;AI9EH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,WAAU;;;ACQV,SAAS,eAAe,SAAgC;AAC7D,QAAM,EAAE,UAAU,MAAM,UAAU,IAAI;AACtC,QAAM,aAAa,SAAS,MAAM;AAClC,QAAM,UAAU,YAAY;AAE5B,MAAI,SAAS,uBAAQ,KAAK,EAAE;AAAA;AAAA;AAAA,cAGhB,SAAS,IAAI;AAAA,UACjB,OAAO,MAAM,UAAU;AAAA,cACnB,KAAK,QAAQ;AAEzB,MAAI,KAAK,YAAY;AACnB,cAAU;AAAA,eAAkB,KAAK,UAAU;AAAA,EAC7C;AAEA,YAAU;AAAA;AAAA;AAAA;AAAA,IAIR,KAAK,KAAK;AAAA;AAAA;AAAA;AAAA,IAIV,KAAK,MAAM;AAEb,MAAI,KAAK,cAAc,KAAK,WAAW,SAAS,GAAG;AACjD,cAAU;AAAA;AAAA;AAGV,eAAW,YAAY,KAAK,YAAY;AACtC,gBAAU;AAAA,IAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,YAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAYV,SAAO;AACT;;;ACzDA,OAAO,eAAe;AAOtB,IAAI,qBAAqC;AAElC,SAAS,uBAAgC;AAC9C,MAAI,uBAAuB,MAAM;AAC/B,WAAO;AAAA,EACT;AAEA,MAAI;AACF,yBAAqB;AACrB,WAAO;AAAA,EACT,QAAQ;AACN,yBAAqB;AACrB,WAAO;AAAA,EACT;AACF;AAEA,eAAsB,gBAAgB,MAAwC;AAC5E,MAAI;AACF,UAAM,UAAU,MAAM,IAAI;AAC1B,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,WAAO;AAAA,MACL,SAAS;AAAA,MACT,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;AClCA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAmBjB,eAAsB,WAAW,SAAyD;AACxF,QAAM,EAAE,eAAe,MAAM,MAAM,SAAS,YAAY,OAAO,KAAK,IAAI;AAExE,QAAM,QAAe;AAAA,IACnB,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,cAAc,EAAE,WAAW;AAAA,IAC/B,GAAI,SAAS,MAAM,SAAS,KAAK,EAAE,MAAM;AAAA,IACzC,GAAI,QAAQ,EAAE,KAAK;AAAA,EACrB;AAEA,MAAI;AACF,UAAM,aAAaA,MAAK,KAAK,eAAe,cAAc;AAC1D,UAAM,OAAO,KAAK,UAAU,KAAK,IAAI;AACrC,UAAMD,IAAG,WAAW,YAAY,MAAM,OAAO;AAE7C,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,WAAO;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA,OAAO;AAAA,IACT;AAAA,EACF;AACF;;;AH1CO,IAAM,cAAc,IAAIE,SAAQ,MAAM,EAC1C,YAAY,qEAAmB,EAC/B,SAAS,eAAe,0BAAgB,GAAG,EAC3C,OAAO,cAAc,8CAAgB,EACrC,OAAO,cAAc,4CAAS,EAC9B,OAAO,OAAO,WAAmB,YAA+C;AAC/E,QAAM,gBAAgBC,MAAK,QAAQ,SAAS;AAE5C,MAAI;AACF,UAAM,OAAO,MAAM,cAAc,aAAa;AAE9C,QAAI,CAAC,KAAK,QAAQ;AAChB,cAAQ,MAAM,+BAA+B,aAAa,EAAE;AAC5D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,KAAK,aAAa;AACrB,cAAQ,MAAM,qCAAqC,aAAa,EAAE;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,KAAK,UAAU;AAClB,cAAQ,MAAM,sCAAsC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,cAAc,aAAa,KAAK,UAAU,KAAK,WAAW;AAEhE,QAAI,YAAY,WAAW,QAAQ;AACjC,cAAQ,IAAI,aAAa,KAAK,SAAS,IAAI,oDAAY;AACvD,cAAQ,IAAI,4CAAS;AACrB;AAAA,IACF;AAEA,UAAM,cAAc,eAAe,KAAK,UAAU,KAAK,WAAW;AAElE,QAAI,CAAC,aAAa;AAChB,cAAQ,IAAI,aAAa,KAAK,SAAS,IAAI,oDAAY;AACvD,cAAQ,IAAI,4CAAS;AACrB;AAAA,IACF;AAEA,UAAM,EAAE,MAAM,MAAM,IAAI;AAExB,YAAQ,IAAI,SAAS,KAAK,EAAE,EAAE;AAC9B,YAAQ,IAAI,aAAa,KAAK,QAAQ,EAAE;AACxC,QAAI,KAAK,YAAY;AACnB,cAAQ,IAAI,cAAc,KAAK,UAAU,EAAE;AAAA,IAC7C;AACA,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,QAAQ;AACpB,YAAQ,IAAI,OAAO,KAAK,KAAK,EAAE;AAC/B,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,SAAS;AACrB,YAAQ,IAAI,OAAO,KAAK,MAAM,EAAE;AAChC,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,SAAS;AACrB,YAAQ,IAAI,kPAA0C;AAEtD,UAAM,SAAS,eAAe;AAAA,MAC5B,UAAU,KAAK;AAAA,MACf;AAAA,MACA,WAAW;AAAA,MACX,eAAe,KAAK;AAAA,IACtB,CAAC;AAED,YAAQ,IAAI,MAAM;AAClB,YAAQ,IAAI,kPAA0C;AACtD,YAAQ,IAAI,EAAE;AAEd,QAAI,QAAQ,OAAO;AACjB,YAAM,WAAW;AAAA,QACf;AAAA,QACA,MAAM,EAAE,OAAO,QAAQ,GAAG,IAAI,KAAK,GAAG;AAAA,QACtC,MAAM;AAAA,QACN,SAAS,yCAAW,KAAK,EAAE;AAAA,QAC3B,YAAY,KAAK;AAAA,QACjB,OAAO,CAAC,KAAK,KAAK;AAAA,MACpB,CAAC;AAAA,IACH;AAEA,QAAI,QAAQ,MAAM;AAChB,UAAI,CAAC,qBAAqB,GAAG;AAC3B,gBAAQ,IAAI,8FAAmB;AAC/B,gBAAQ,IAAI,yDAAiB;AAAA,MAC/B,OAAO;AACL,cAAM,SAAS,MAAM,gBAAgB,MAAM;AAC3C,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,0DAAkB;AAAA,QAChC,OAAO;AACL,kBAAQ,IAAI,oCAAW,OAAO,KAAK,EAAE;AACrC,kBAAQ,IAAI,yDAAiB;AAAA,QAC/B;AAAA,MACF;AAAA,IACF,OAAO;AACL,cAAQ,IAAI,oGAAmC;AAC/C,cAAQ,IAAI,8FAA6B;AAAA,IAC3C;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,UAAU,KAAK,EAAE;AAC/B,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;;;AI9GH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,WAAU;;;ACDjB,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAqBV,IAAM,oBAAoB;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAaA,IAAM,qBAAqB;AAEpB,SAAS,iBAAiB,SAAmC;AAClE,QAAM,SAA4B,CAAC;AACnC,QAAM,WAAgC,CAAC;AAEvC,aAAW,WAAW,mBAAmB;AACvC,UAAM,gBAAgB,YAAY,SAAS,OAAO;AAElD,QAAI,CAAC,cAAc,OAAO;AACxB,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN;AAAA,QACA,SAAS,yCAAW,OAAO;AAAA,MAC7B,CAAC;AAAA,IACH,WAAW,CAAC,cAAc,YAAY;AACpC,aAAO,KAAK;AAAA,QACV,MAAM;AAAA,QACN;AAAA,QACA,SAAS,yCAAW,OAAO;AAAA,MAC7B,CAAC;AAAA,IACH,WAAW,cAAc,gBAAgB,oBAAoB;AAC3D,eAAS,KAAK;AAAA,QACZ,MAAM;AAAA,QACN;AAAA,QACA,SAAS,yCAAW,cAAc,aAAa,mBAAS,OAAO;AAAA,MACjE,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO,OAAO,WAAW;AAAA,IACzB;AAAA,IACA;AAAA,EACF;AACF;AAQA,SAAS,YAAY,SAAiB,aAAoC;AACxE,QAAM,WAAW;AAAA,IACf,IAAI,OAAO,UAAU,YAAY,WAAW,CAAC,YAAY,GAAG;AAAA,IAC5D,IAAI,OAAO,WAAW,YAAY,WAAW,CAAC,YAAY,GAAG;AAAA,EAC/D;AAEA,MAAI,aAAa;AACjB,MAAI,cAAc;AAElB,aAAW,WAAW,UAAU;AAC9B,UAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,QAAI,SAAS,MAAM,UAAU,QAAW;AACtC,mBAAa,MAAM;AACnB,oBAAc,MAAM,CAAC,EAAE;AACvB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,eAAe,IAAI;AACrB,WAAO,EAAE,OAAO,OAAO,YAAY,OAAO,eAAe,EAAE;AAAA,EAC7D;AAEA,QAAM,eAAe,aAAa;AAClC,QAAM,mBAAmB,QAAQ,MAAM,YAAY;AAEnD,QAAM,mBAAmB,iBAAiB,MAAM,aAAa;AAC7D,QAAM,iBAAiB,mBACnB,iBAAiB,MAAM,GAAG,iBAAiB,KAAK,IAChD;AAEJ,QAAM,iBAAiB,eAAe,KAAK;AAE3C,SAAO;AAAA,IACL,OAAO;AAAA,IACP,YAAY,eAAe,SAAS;AAAA,IACpC,eAAe,eAAe;AAAA,EAChC;AACF;AAEA,SAAS,YAAY,KAAqB;AACxC,SAAO,IAAI,QAAQ,uBAAuB,MAAM;AAClD;AAEA,eAAsB,qBACpB,UAC2B;AAC3B,MAAI;AACF,UAAM,UAAU,MAAMC,IAAG,SAAS,UAAU,OAAO;AACnD,WAAO,iBAAiB,OAAO;AAAA,EACjC,QAAQ;AACN,WAAO;AAAA,MACL,OAAO;AAAA,MACP,QAAQ;AAAA,QACN;AAAA,UACE,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS,yCAAW,QAAQ;AAAA,QAC9B;AAAA,MACF;AAAA,MACA,UAAU,CAAC;AAAA,IACb;AAAA,EACF;AACF;AAEA,eAAsB,2BACpB,eACoC;AACpC,QAAM,YAAY,MAAM,cAAc,aAAa;AACnD,QAAM,cAAc,oBAAI,IAA8B;AACtD,MAAI,aAAa;AACjB,MAAI,aAAa;AACjB,MAAI,eAAe;AAEnB,MAAI,CAAC,UAAU,UAAU;AACvB,WAAO;AAAA,MACL,OAAO;AAAA,MACP;AAAA,MACA,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAAA,EACF;AAEA,aAAW,QAAQ,UAAU,SAAS,OAAO;AAC3C,UAAM,aAAaC,MAAK,KAAK,UAAU,MAAM,KAAK,MAAM;AACxD,UAAM,SAAS,MAAM,qBAAqB,UAAU;AACpD,gBAAY,IAAI,KAAK,IAAI,MAAM;AAE/B,QAAI,OAAO,OAAO;AAChB;AAAA,IACF;AACA,kBAAc,OAAO,OAAO;AAC5B,oBAAgB,OAAO,SAAS;AAAA,EAClC;AAEA,SAAO;AAAA,IACL,OAAO,eAAe;AAAA,IACtB;AAAA,IACA,YAAY,UAAU,SAAS,MAAM;AAAA,IACrC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ADtLO,IAAM,kBAAkB,IAAIC,SAAQ,UAAU,EAClD,YAAY,iDAAmB,EAC/B,SAAS,eAAe,0BAAgB,GAAG,EAC3C,OAAO,YAAY,gFAAe,EAClC,OAAO,cAAc,+BAAW,EAChC,OAAO,OAAO,WAAmB,YAAgD;AAChF,QAAM,gBAAgBC,MAAK,QAAQ,SAAS;AAE5C,MAAI;AACF,UAAM,OAAO,MAAM,cAAc,aAAa;AAE9C,QAAI,CAAC,KAAK,QAAQ;AAChB,cAAQ,MAAM,+BAA+B,aAAa,EAAE;AAC5D,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,KAAK,aAAa;AACrB,cAAQ,MAAM,qCAAqC,aAAa,EAAE;AAClE,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,QAAI,CAAC,KAAK,UAAU;AAClB,cAAQ,MAAM,sCAAsC;AACpD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,SAAS,MAAM,2BAA2B,aAAa;AAE7D,QAAI,QAAQ,MAAM;AAChB,YAAM,aAAa;AAAA,QACjB,OAAO,QAAQ,SAAS,OAAO,SAAS,OAAO,iBAAiB,IAAI,OAAO;AAAA,QAC3E,WAAW;AAAA,QACX,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,YAAY,OAAO;AAAA,QACnB,cAAc,OAAO;AAAA,QACrB,OAAO,MAAM,KAAK,OAAO,YAAY,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,QAAQ,UAAU,OAAO;AAAA,UAC7E;AAAA,UACA,OAAO,QAAQ,SAAS,WAAW,SAAS,WAAW,SAAS,WAAW,IAAI,WAAW;AAAA,UAC1F,QAAQ,WAAW;AAAA,UACnB,UAAU,WAAW;AAAA,QACvB,EAAE;AAAA,MACJ;AACA,cAAQ,IAAI,KAAK,UAAU,YAAY,MAAM,CAAC,CAAC;AAAA,IACjD,OAAO;AACL,cAAQ,IAAI,cAAc,KAAK,SAAS,IAAI,EAAE;AAC9C,cAAQ,IAAI,EAAE;AAEd,iBAAW,QAAQ,KAAK,SAAS,OAAO;AACtC,cAAM,aAAa,OAAO,YAAY,IAAI,KAAK,EAAE;AACjD,YAAI,CAAC,WAAY;AAEjB,cAAM,OAAO,WAAW,QAAQ,WAAM;AACtC,gBAAQ,IAAI,GAAG,IAAI,IAAI,KAAK,MAAM,MAAM,WAAW,QAAQ,UAAU,SAAS,EAAE;AAEhF,YAAI,CAAC,WAAW,OAAO;AACrB,qBAAW,SAAS,WAAW,QAAQ;AACrC,oBAAQ,IAAI,QAAQ,MAAM,OAAO,EAAE;AAAA,UACrC;AAAA,QACF;AAEA,YAAI,WAAW,SAAS,SAAS,GAAG;AAClC,qBAAW,WAAW,WAAW,UAAU;AACzC,oBAAQ,IAAI,oBAAU,QAAQ,OAAO,EAAE;AAAA,UACzC;AAAA,QACF;AAAA,MACF;AAEA,cAAQ,IAAI,EAAE;AAEd,YAAM,YAAY,OAAO,aAAa;AACtC,YAAM,cAAc,OAAO,eAAe;AAC1C,YAAM,aAAa,QAAQ,UAAU;AAErC,UAAI,CAAC,aAAa,CAAC,YAAY;AAC7B,gBAAQ,IAAI,uCAAuC;AACnD,YAAI,aAAa;AACf,kBAAQ,IAAI,iBAAO,OAAO,YAAY,oBAAoB;AAAA,QAC5D;AAAA,MACF,OAAO;AACL,cAAM,cAAc,OAAO,cAAc,aAAa,OAAO,eAAe;AAC5E,gBAAQ,IAAI,0BAA0B,WAAW,YAAY;AAAA,MAC/D;AAEA,UAAI,aAAa,YAAY;AAC3B,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAAA,IACF;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,UAAU,KAAK,EAAE;AAC/B,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;;;AEjGH,SAAS,WAAAC,gBAAe;AACxB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AAMR,IAAM,iBAAiB,IAAIC,SAAQ,SAAS,EAChD,YAAY,qCAAiB,EAC7B,SAAS,eAAe,0BAAgB,GAAG,EAC3C,OAAO,sBAAsB,4BAAQ,WAAW,EAChD,OAAO,wBAAwB,0BAAM,EACrC,OAAO,cAAc,+BAAgB,EACrC,OAAO,gBAAgB,4CAAS,EAChC;AAAA,EACC,OACE,WACA,YACG;AACH,UAAM,gBAAgBC,MAAK,QAAQ,SAAS;AAE5C,QAAI;AACF,YAAM,OAAO,MAAM,cAAc,aAAa;AAE9C,UAAI,CAAC,KAAK,QAAQ;AAChB,gBAAQ,MAAM,+BAA+B,aAAa,EAAE;AAC5D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,CAAC,KAAK,aAAa;AACrB,gBAAQ,MAAM,qCAAqC,aAAa,EAAE;AAClE,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,UAAI,CAAC,KAAK,UAAU;AAClB,gBAAQ,MAAM,sCAAsC;AACpD,gBAAQ,KAAK,CAAC;AAAA,MAChB;AAEA,YAAM,cAAc,aAAa,KAAK,UAAU,KAAK,WAAW;AAEhE,cAAQ,IAAI,cAAc,KAAK,SAAS,IAAI,EAAE;AAE9C,UAAI,YAAY,WAAW,QAAQ;AACjC,gBAAQ,IAAI,cAAc;AAC1B,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,gEAAsD;AAClE;AAAA,MACF;AAEA,YAAM,cAAc,eAAe,KAAK,UAAU,KAAK,WAAW;AAElE,UAAI,CAAC,aAAa;AAChB,gBAAQ,IAAI,cAAc;AAC1B,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,gEAAsD;AAClE;AAAA,MACF;AAEA,YAAM,EAAE,MAAM,MAAM,IAAI;AAExB,cAAQ,IAAI,iBAAiB,KAAK,EAAE,YAAY,KAAK,GAAG;AACxD,cAAQ,IAAI,EAAE;AAEd,YAAM,YAAY,QAAQ;AAC1B,YAAM,eAAe,QAAQ,WAAW,kBAAkB,WAAW,KAAK,EAAE;AAE5E,UAAI,CAAC,QAAQ,WAAW;AACtB,cAAM,SAAS,MAAM,WAAW;AAAA,UAC9B;AAAA,UACA,MAAM,EAAE,OAAO,QAAQ,GAAG,IAAI,KAAK,GAAG;AAAA,UACtC,MAAM;AAAA,UACN,SAAS;AAAA,UACT,YAAY,KAAK;AAAA,UACjB,OAAO,CAAC,KAAK,MAAM;AAAA,QACrB,CAAC;AAED,YAAI,OAAO,SAAS;AAClB,kBAAQ,IAAI,yBAAoB,SAAS,EAAE;AAC3C,kBAAQ,IAAI,cAAc,YAAY,EAAE;AACxC,cAAI,KAAK,YAAY;AACnB,oBAAQ,IAAI,gBAAgB,KAAK,UAAU,EAAE;AAAA,UAC/C;AACA,cAAI,KAAK,QAAQ;AACf,oBAAQ,IAAI,YAAY,KAAK,MAAM,EAAE;AAAA,UACvC;AAAA,QACF,OAAO;AACL,kBAAQ,IAAI,iCAA4B,OAAO,KAAK,EAAE;AAAA,QACxD;AAAA,MACF;AAEA,UAAI,QAAQ,OAAO;AACjB,cAAM,YAAYA,MAAK,KAAK,eAAe,YAAY;AACvD,cAAM,WAAW,QAAQ;AACzB,cAAM,SAAS,YAAY,KAAK,SAAS,MAAM;AAE/C,cAAM,WAAW;AAAA,UACf,cAAc;AAAA,UACd,QAAQ,SAAS,SAAS;AAAA,UAC1B,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,QACpC;AAEA,cAAMC,IAAG,UAAU,WAAW,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAC/D,gBAAQ,IAAI,EAAE;AACd,gBAAQ,IAAI,yBAAoB,SAAS,EAAE;AAC3C,gBAAQ,IAAI,oBAAoB,SAAS,YAAY,EAAE;AACvD,gBAAQ,IAAI,aAAa,SAAS,MAAM,EAAE;AAE1C,YAAI,QAAQ;AACV,kBAAQ,IAAI,EAAE;AACd,kBAAQ,IAAI,+BAAwB;AAAA,QACtC,OAAO;AACL,gBAAM,WAAW,KAAK,SAAS,MAAM,QAAQ;AAC7C,kBAAQ,IAAI,gBAAgB,SAAS,EAAE,EAAE;AAAA,QAC3C;AAAA,MACF;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,KAAK,EAAE;AAC/B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF;AAEF,SAAS,kBAAkB,WAAsB,QAAwB;AACvE,QAAM,YAAuC;AAAA,IAC3C,gBAAgB,yCAAW,MAAM;AAAA,IACjC,aAAa,6BAAS,MAAM;AAAA,IAC5B,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,IAChB,sBAAsB;AAAA,EACxB;AACA,SAAO,UAAU,SAAS,KAAK,iBAAO,SAAS;AACjD;;;AC3IA,SAAS,WAAAC,gBAAe;AACxB,OAAOC,SAAQ;;;ACDf,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAO,QAAQ;AA8BR,IAAM,iBAAqC;AAAA,EAChD,QAAQ;AAAA,IACN,SAAS;AAAA,IACT,gBAAgB;AAAA,IAChB,aAAa;AAAA,EACf;AAAA,EACA,YAAY;AAAA,IACV,SAAS;AAAA,IACT,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,SAAS;AAAA,IACT,YAAY;AAAA,EACd;AAAA,EACA,WAAW;AAAA,IACT,UAAU;AAAA,EACZ;AAAA,EACA,QAAQ;AAAA,IACN,UAAU;AAAA,EACZ;AAAA,EACA,YAAY;AAAA,IACV,QAAQ;AAAA,IACR,oBAAoB;AAAA,EACtB;AACF;AAEA,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,cAAc,oBAAI,IAAgC;AAExD,eAAsB,eAAe,WAA2C;AAC9E,MAAI,cAAcA,MAAK,QAAQ,SAAS;AACxC,QAAM,WAAW,GAAG,QAAQ;AAE5B,SAAO,MAAM;AACX,eAAW,cAAc,cAAc;AACrC,YAAM,WAAWA,MAAK,KAAK,aAAa,UAAU;AAClD,UAAI;AACF,cAAMD,IAAG,OAAO,QAAQ;AACxB,eAAO;AAAA,MACT,QAAQ;AAAA,MAER;AAAA,IACF;AAEA,UAAM,kBAAkBC,MAAK,KAAK,aAAa,cAAc;AAC7D,QAAI;AACF,YAAM,UAAU,MAAMD,IAAG,SAAS,iBAAiB,OAAO;AAC1D,YAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,UAAI,IAAI,cAAc;AACpB,eAAO;AAAA,MACT;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,QAAI,gBAAgB,YAAY,gBAAgBC,MAAK,QAAQ,WAAW,GAAG;AACzE;AAAA,IACF;AACA,kBAAcA,MAAK,QAAQ,WAAW;AAAA,EACxC;AAEA,SAAO;AACT;AAEA,eAAsB,eAAe,UAAwD;AAC3F,MAAI;AACF,UAAM,UAAU,MAAMD,IAAG,SAAS,UAAU,OAAO;AACnD,UAAM,MAAMC,MAAK,QAAQ,QAAQ;AAEjC,QAAI,QAAQ,WAAW,QAAQ,QAAQ;AACrC,aAAO,UAAU,OAAO;AAAA,IAC1B;AAEA,QAAI,SAAS,SAAS,cAAc,GAAG;AACrC,YAAM,MAAM,KAAK,MAAM,OAAO;AAC9B,aAAO,IAAI,gBAAgB,CAAC;AAAA,IAC9B;AAEA,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,SAAS,UAAU,SAA0C;AAC3D,QAAM,SAAkC,CAAC;AACzC,QAAM,QAAQ,QAAQ,MAAM,IAAI;AAChC,MAAI,aAAsC;AAC1C,QAAM,QAAiD,CAAC;AAExD,aAAW,QAAQ,OAAO;AACxB,QAAI,CAAC,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE,WAAW,GAAG,GAAG;AAC/C;AAAA,IACF;AAEA,UAAM,SAAS,KAAK,OAAO,IAAI;AAC/B,UAAM,UAAU,KAAK,KAAK;AAE1B,QAAI,QAAQ,SAAS,GAAG,GAAG;AACzB,YAAM,aAAa,QAAQ,QAAQ,GAAG;AACtC,YAAM,MAAM,QAAQ,MAAM,GAAG,UAAU,EAAE,KAAK;AAC9C,YAAM,QAAQ,QAAQ,MAAM,aAAa,CAAC,EAAE,KAAK;AAEjD,UAAI,UAAU,IAAI;AAChB,YAAI,MAAM,SAAS,GAAG;AACpB,gBAAM,iBAAiB,MAAM,SAAS;AACtC,cAAI,SAAS,gBAAgB;AAC3B,mBAAO,MAAM,SAAS,KAAK,SAAS,MAAM,SAAS,GAAG;AACpD,oBAAM,IAAI;AAAA,YACZ;AACA,gBAAI,MAAM,SAAS,GAAG;AACpB,2BAAa,MAAM,MAAM,SAAS,CAAC,EAAE;AAAA,YACvC,OAAO;AACL,2BAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAEA,cAAM,SAAkC,CAAC;AACzC,mBAAW,GAAG,IAAI;AAClB,cAAM,KAAK,EAAE,KAAK,WAAW,CAAC;AAC9B,qBAAa;AAAA,MACf,OAAO;AACL,YAAI,cAAuB;AAC3B,YAAI,UAAU,OAAQ,eAAc;AAAA,iBAC3B,UAAU,QAAS,eAAc;AAAA,iBACjC,UAAU,OAAQ,eAAc;AAAA,iBAChC,QAAQ,KAAK,KAAK,EAAG,eAAc,SAAS,OAAO,EAAE;AAAA,iBACrD,aAAa,KAAK,KAAK,EAAG,eAAc,WAAW,KAAK;AAAA,iBACxD,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AACrD,wBAAc,MAAM,MAAM,GAAG,EAAE;AAAA,QACjC,WAAW,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAG;AACvD,wBAAc,MAAM,MAAM,GAAG,EAAE;AAAA,QACjC;AAEA,mBAAW,GAAG,IAAI;AAAA,MACpB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,YACd,MACA,UACoB;AACpB,QAAM,SAA6B,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;AAElE,aAAW,OAAO,OAAO,KAAK,QAAQ,GAAsC;AAC1E,UAAM,gBAAgB,SAAS,GAAG;AAClC,QAAI,kBAAkB,OAAW;AAEjC,QACE,OAAO,kBAAkB,YACzB,kBAAkB,QAClB,CAAC,MAAM,QAAQ,aAAa,GAC5B;AACA,YAAM,YAAY,OAAO,GAAG;AAC5B,UACE,OAAO,cAAc,YACrB,cAAc,QACd,CAAC,MAAM,QAAQ,SAAS,GACxB;AAEA,QAAC,OAAmC,GAAG,IAAI;AAAA,UACzC;AAAA,UACA;AAAA,QACF;AAAA,MACF,OAAO;AACL,QAAC,OAAmC,GAAG,IAAI;AAAA,MAC7C;AAAA,IACF,OAAO;AACL,MAAC,OAAmC,GAAG,IAAI;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,WAAW,eAAqD;AACpF,QAAM,YAAY,gBAAgBA,MAAK,QAAQ,aAAa,IAAI,QAAQ,IAAI;AAC5E,QAAM,WAAW;AAEjB,MAAI,YAAY,IAAI,QAAQ,GAAG;AAC7B,WAAO,YAAY,IAAI,QAAQ;AAAA,EACjC;AAEA,MAAI,SAAS,KAAK,MAAM,KAAK,UAAU,cAAc,CAAC;AAEtD,QAAM,mBAAmBA,MAAK,KAAK,GAAG,QAAQ,GAAG,iBAAiB;AAClE,MAAI;AACF,UAAMD,IAAG,OAAO,gBAAgB;AAChC,UAAM,eAAe,MAAM,eAAe,gBAAgB;AAC1D,aAAS,YAAY,QAAQ,YAAY;AAAA,EAC3C,QAAQ;AAAA,EAER;AAEA,QAAM,kBAAkB,MAAM,eAAe,SAAS;AACtD,MAAI,iBAAiB;AACnB,UAAM,cAAc,MAAM,eAAe,eAAe;AACxD,aAAS,YAAY,QAAQ,WAAW;AAAA,EAC1C;AAEA,cAAY,IAAI,UAAU,MAAM;AAChC,SAAO;AACT;AAMA,eAAsB,eAAe,YAAoB,SAAS,OAAwB;AACxF,QAAM,aAAa,SACfE,MAAK,KAAK,GAAG,QAAQ,GAAG,iBAAiB,IACzCA,MAAK,KAAK,YAAY,iBAAiB;AAE3C,QAAM,UAAU,KAAK,UAAU,gBAAgB,MAAM,CAAC;AACtD,QAAMC,IAAG,UAAU,YAAY,SAAS,OAAO;AAE/C,SAAO;AACT;;;AD3PO,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC9C,YAAY,4CAAS,EACrB,SAAS,YAAY,4BAAkB,MAAM,EAC7C,OAAO,gBAAgB,sCAAQ,EAC/B,OAAO,aAAa,sCAAQ,EAC5B,OAAO,OAAO,QAAgB,YAAmD;AAChF,MAAI;AACF,QAAI,WAAW,QAAQ;AACrB,YAAM,WAAW,OAAO;AAAA,IAC1B,WAAW,WAAW,QAAQ;AAC5B,YAAM,WAAW,OAAO;AAAA,IAC1B,WAAW,WAAW,QAAQ;AAC5B,YAAM,WAAW;AAAA,IACnB,OAAO;AACL,cAAQ,MAAM,mBAAmB,MAAM,EAAE;AACzC,cAAQ,IAAI,qCAAqC;AACjD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,SAAS,OAAO;AACd,YAAQ,MAAM,UAAU,KAAK,EAAE;AAC/B,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF,CAAC;AAEH,eAAe,WAAW,SAA+D;AACvF,QAAM,aAAa,QAAQ,SAASC,IAAG,QAAQ,IAAI,QAAQ,IAAI;AAC/D,QAAM,SAAS,MAAM,WAAW,UAAU;AAE1C,MAAI,QAAQ,SAAS;AACnB,UAAM,aAAa,MAAM,eAAe,UAAU;AAClD,QAAI,YAAY;AACd,cAAQ,IAAI,gBAAgB,UAAU,EAAE;AACxC,cAAQ,IAAI,EAAE;AAAA,IAChB,OAAO;AACL,cAAQ,IAAI,sCAAsC;AAClD,cAAQ,IAAI,EAAE;AAAA,IAChB;AAAA,EACF;AAEA,UAAQ,IAAI,KAAK,UAAU,QAAQ,MAAM,CAAC,CAAC;AAC7C;AAEA,eAAe,WAAW,SAA+D;AACvF,QAAM,aAAa,QAAQ,SAASA,IAAG,QAAQ,IAAI,QAAQ,IAAI;AAC/D,QAAM,aAAa,MAAM,eAAe,YAAY,QAAQ,MAAM;AAElE,UAAQ,IAAI,+BAA0B,UAAU,EAAE;AAClD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,IAAI,KAAK,UAAU,gBAAgB,MAAM,CAAC,CAAC;AACrD;AAEA,eAAe,aAA4B;AACzC,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,8DAA0C;AACtD,UAAQ,IAAI,2FAAmD;AAC/D,UAAQ,IAAI,iFAA6D;AACzE,UAAQ,IAAI,6EAAyD;AACrE,UAAQ,IAAI,uFAAyD;AACrE,UAAQ,IAAI,6EAA0C;AACtD,UAAQ,IAAI,4DAAkD;AAC9D,UAAQ,IAAI,gFAAkD;AAC9D,UAAQ,IAAI,8FAA2D;AACvE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,+CAA+C;AAC3D,UAAQ,IAAI,mBAAmB;AAC/B,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,IAAI,wBAAwB;AACpC,UAAQ,IAAI,6BAA6B;AACzC,UAAQ,IAAI,8BAA8B;AAC5C;;;AEhFA,SAAS,WAAAC,gBAAe;AACxB,OAAOC,SAAQ;AACf,OAAOC,YAAU;;;ACFjB,OAAOC,SAAQ;AAQR,IAAM,oBAAN,MAAwB;AAAA,EACrB;AAAA,EAER,YAAY,SAAsB;AAChC,SAAK,UAAU;AAAA,EACjB;AAAA,EAEA,SAAS,SAAgC;AACvC,YAAQ,QAAQ,QAAQ;AAAA,MACtB,KAAK;AACH,eAAO,KAAK,aAAa;AAAA,MAC3B,KAAK;AACH,eAAO,KAAK,iBAAiB,QAAQ,kBAAkB;AAAA,MACzD,KAAK;AACH,eAAO,KAAK,aAAa,QAAQ,kBAAkB;AAAA,MACrD;AACE,eAAO,KAAK,iBAAiB,QAAQ,kBAAkB;AAAA,IAC3D;AAAA,EACF;AAAA,EAEQ,eAAuB;AAC7B,WAAO,KAAK,UAAU,KAAK,SAAS,MAAM,CAAC;AAAA,EAC7C;AAAA,EAEQ,iBAAiB,oBAAqC;AAC5D,UAAM,QAAkB;AAAA,MACtB;AAAA,MACA;AAAA,MACA,mBAAmB,KAAK,QAAQ,EAAE;AAAA,MAClC,mBAAmB,KAAK,QAAQ,SAAS;AAAA,MACzC,kBAAkB,KAAK,QAAQ,aAAa;AAAA,MAC5C,gBAAgB,KAAK,QAAQ,MAAM;AAAA,MACnC,GAAI,KAAK,QAAQ,SAAS,CAAC,eAAe,KAAK,QAAQ,MAAM,EAAE,IAAI,CAAC;AAAA,MACpE,GAAI,KAAK,QAAQ,QAAQ,CAAC,cAAc,KAAK,QAAQ,KAAK,EAAE,IAAI,CAAC;AAAA,MACjE;AAAA,MACA,kBAAkB,KAAK,QAAQ,WAAW,MAAM;AAAA,MAChD;AAAA,IACF;AAEA,SAAK,QAAQ,WAAW,QAAQ,CAAC,IAAI,UAAU;AAC7C,YAAM,KAAK,OAAO,QAAQ,CAAC,KAAK,GAAG,IAAI,EAAE;AACzC,UAAI,GAAG,QAAQ;AACb,cAAM,KAAK,iBAAiB,GAAG,MAAM,EAAE;AAAA,MACzC;AACA,UAAI,GAAG,OAAO;AACZ,cAAM;AAAA,UACJ,gBAAgB,GAAG,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,GAAG,MAAM,SAAS,MAAM,QAAQ,EAAE;AAAA,QACjF;AAAA,MACF;AACA,YAAM,KAAK,oBAAoB,IAAI,KAAK,GAAG,SAAS,EAAE,YAAY,CAAC,EAAE;AACrE,YAAM,KAAK,EAAE;AAAA,IACf,CAAC;AAED,QAAI,sBAAsB,KAAK,QAAQ,YAAY,SAAS,GAAG;AAC7D,YAAM,KAAK,mBAAmB,KAAK,QAAQ,YAAY,MAAM,GAAG;AAChE,YAAM,KAAK,EAAE;AACb,WAAK,QAAQ,YAAY,QAAQ,CAAC,YAAY,UAAU;AACtD,cAAM,KAAK,kBAAkB,QAAQ,CAAC,EAAE;AACxC,cAAM,KAAK,gBAAgB,QAAQ,CAAC,KAAK,UAAU,GAAG;AACtD,cAAM,KAAK,EAAE;AAAA,MACf,CAAC;AAAA,IACH;AAEA,WAAO,MAAM,KAAK,IAAI;AAAA,EACxB;AAAA,EAEQ,aAAa,oBAAqC;AACxD,UAAM,iBAAiB,KAAK,QAAQ,WACjC;AAAA,MACC,CAAC,IAAI,UAAU;AAAA;AAAA,cAET,QAAQ,CAAC,KAAK,GAAG,IAAI;AAAA,UACzB,GAAG,SAAS,+BAA+B,GAAG,MAAM,SAAS,EAAE;AAAA,UAE/D,GAAG,QACC,8BAA8B,GAAG,MAAM,UAAU,GAAG,GAAG,CAAC,GACtD,GAAG,MAAM,SAAS,MAAM,QAAQ,EAClC,SACA,EACN;AAAA,yCACiC,IAAI,KAAK,GAAG,SAAS,EAAE,YAAY,CAAC;AAAA;AAAA;AAAA,IAGvE,EACC,KAAK,EAAE;AAEV,UAAM,kBACJ,sBAAsB,KAAK,QAAQ,YAAY,SAAS,IACpD;AAAA,2BACiB,KAAK,QAAQ,YAAY,MAAM;AAAA,UAChD,KAAK,QAAQ,YACZ;AAAA,MACC,CAAC,GAAG,MAAM;AAAA;AAAA,6BAEO,IAAI,CAAC;AAAA,wBACV,CAAC,qBAAqB,IAAI,CAAC;AAAA;AAAA;AAAA,IAGzC,EACC,KAAK,EAAE,CAAC;AAAA,UAET;AAEN,UAAM,aAAa,KAAK,QAAQ,SAC5B,+BAA+B,KAAK,QAAQ,MAAM,SAClD;AACJ,UAAM,YAAY,KAAK,QAAQ,QAAQ,8BAA8B,KAAK,QAAQ,KAAK,SAAS;AAEhG,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sCAwC2B,KAAK,QAAQ,EAAE;AAAA,sCACf,KAAK,QAAQ,SAAS;AAAA,qCACvB,KAAK,QAAQ,aAAa;AAAA,mCAC5B,KAAK,QAAQ,MAAM;AAAA,MAChD,UAAU;AAAA,MACV,SAAS;AAAA;AAAA;AAAA,oBAGK,KAAK,QAAQ,WAAW,MAAM;AAAA,IAC9C,cAAc;AAAA;AAAA,IAEd,eAAe;AAAA;AAAA;AAAA,MAGb,KAAK;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,YAAoB,SAAyC;AAC5E,UAAM,UAAU,KAAK,SAAS,OAAO;AACrC,UAAMA,IAAG,UAAU,YAAY,SAAS,OAAO;AAC/C,WAAO;AAAA,EACT;AACF;;;AD3KO,IAAM,gBAAgB,IAAIC,SAAQ,QAAQ,EAC9C,YAAY,wDAAW,EACvB,SAAS,eAAe,0BAAgB,GAAG,EAC3C,OAAO,yBAAyB,kDAA8B,UAAU,EACxE,OAAO,sBAAsB,yBAAe,EAC5C,OAAO,iBAAiB,4BAAQ,KAAK,EACrC,OAAO,uBAAuB,0BAAM,EACpC;AAAA,EACC,OACE,WACA,YACG;AACH,UAAM,gBAAgBC,OAAK,QAAQ,SAAS;AAC5C,UAAM,SAASA,OAAK,KAAK,eAAe,YAAY;AAEpD,QAAI;AACF,UAAI;AACJ,UAAI,QAAQ,SAAS;AACnB,sBAAcA,OAAK,KAAK,QAAQ,cAAc,QAAQ,OAAO,QAAQ;AAAA,MACvE,OAAO;AACL,cAAM,QAAQ,MAAMC,IAAG,QAAQ,MAAM;AACrC,cAAM,aAAa,MAChB,OAAO,CAAC,MAAM,EAAE,SAAS,QAAQ,CAAC,EAClC,KAAK,EACL,QAAQ;AACX,YAAI,WAAW,WAAW,GAAG;AAC3B,kBAAQ,MAAM,gCAAgC;AAC9C,kBAAQ,KAAK,CAAC;AAAA,QAChB;AACA,sBAAcD,OAAK,KAAK,QAAQ,WAAW,CAAC,CAAC;AAAA,MAC/C;AAEA,YAAM,UAAU,MAAMC,IAAG,SAAS,aAAa,OAAO;AACtD,YAAM,QAAQ,QAAQ,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC;AACxD,YAAM,UAAU,KAAK,MAAM,MAAM,MAAM,SAAS,CAAC,CAAC;AAElD,YAAM,WAAW,IAAI,kBAAkB,OAAO;AAC9C,YAAM,SAAS,SAAS,SAAS;AAAA,QAC/B,QAAQ,QAAQ;AAAA,QAChB,oBAAoB,QAAQ;AAAA,MAC9B,CAAC;AAED,UAAI,QAAQ,QAAQ;AAClB,cAAMA,IAAG,UAAUD,OAAK,QAAQ,QAAQ,MAAM,GAAG,QAAQ,OAAO;AAChE,gBAAQ,IAAI,2BAAsB,QAAQ,MAAM,EAAE;AAAA,MACpD,OAAO;AACL,gBAAQ,IAAI,MAAM;AAAA,MACpB;AAAA,IACF,SAAS,OAAO;AACd,cAAQ,MAAM,UAAU,KAAK,EAAE;AAC/B,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF;AACF;;;AfjDF,IAAME,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,EAAE,QAAQ,IAAIA,SAAQ,iBAAiB;AAE7C,IAAM,UAAU,IAAIC,SAAQ;AAE5B,QACG,KAAK,eAAe,EACpB,YAAY,qEAAmB,EAC/B,QAAQ,OAAO;AAElB,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,WAAW;AAC9B,QAAQ,WAAW,eAAe;AAClC,QAAQ,WAAW,cAAc;AACjC,QAAQ,WAAW,aAAa;AAChC,QAAQ,WAAW,aAAa;AAEhC,QAAQ,MAAM;","names":["Command","Command","path","fs","path","fs","path","fs","Command","path","Command","path","fs","path","Command","path","Command","path","fs","path","fs","path","Command","path","Command","path","fs","Command","path","fs","Command","os","fs","path","path","fs","Command","os","Command","fs","path","fs","Command","path","fs","require","Command"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/cli/commands/init.ts","../src/cli/commands/status.ts","../src/core/workspace.ts","../src/core/workflow-parser.ts","../src/core/state-machine.ts","../src/cli/commands/next.ts","../src/core/prompt-generator.ts","../src/core/clipboard.ts","../src/core/events-writer.ts","../src/cli/commands/validate.ts","../src/core/artifact-validator.ts","../src/cli/commands/advance.ts","../src/cli/commands/config.ts","../src/core/config.ts","../src/cli/commands/report.ts","../src/adapters/trae/operation-reporter.ts","../src/cli/commands/export.ts","../src/export/web/exporter.ts","../src/core/events-reader.ts","../src/export/web/artifact-indexer.ts","../src/export/web/artifact-renderer.ts","../src/export/web/timeline-renderer.ts","../src/cli/commands/index.ts","../src/core/index/indexer.ts","../src/core/index/registry.ts","../src/cli/commands/search.ts","../src/core/search/search.ts","../src/cli/commands/diff.ts","../src/core/diff/diff.ts","../src/cli/commands/stats.ts","../src/core/stats/stats.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { createRequire } from 'module';\nimport { Command } from 'commander';\nimport { initCommand } from './cli/commands/init.js';\nimport { statusCommand } from './cli/commands/status.js';\nimport { nextCommand } from './cli/commands/next.js';\nimport { validateCommand } from './cli/commands/validate.js';\nimport { advanceCommand } from './cli/commands/advance.js';\nimport { configCommand } from './cli/commands/config.js';\nimport { reportCommand } from './cli/commands/report.js';\nimport { exportCommand } from './cli/commands/export.js';\nimport { indexCommand } from './cli/commands/index.js';\nimport { searchCommand } from './cli/commands/search.js';\nimport { diffCommand } from './cli/commands/diff.js';\nimport { statsCommand } from './cli/commands/stats.js';\n\nconst require = createRequire(import.meta.url);\nconst { version } = require('../package.json');\n\nconst program = new Command();\n\nprogram\n .name('agent-handoff')\n .description('轻量级多 Agent 协作接力工具')\n .version(version);\n\nprogram.addCommand(initCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(nextCommand);\nprogram.addCommand(validateCommand);\nprogram.addCommand(advanceCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(reportCommand);\nprogram.addCommand(exportCommand);\nprogram.addCommand(indexCommand);\nprogram.addCommand(searchCommand);\nprogram.addCommand(diffCommand);\nprogram.addCommand(statsCommand);\n\nprogram.parse();\n","import { Command } from 'commander';\nimport fs from 'fs/promises';\nimport path from 'path';\n\nexport const initCommand = new Command('init')\n .description('创建新的 workspace')\n .argument('<name>', 'workspace 名称')\n .option('-p, --path <path>', '父目录路径', process.cwd())\n .action(async (name: string, options: { path: string }) => {\n const workspacePath = path.resolve(options.path, name);\n\n try {\n await fs.access(workspacePath);\n console.error(`Error: workspace \"${name}\" already exists at ${workspacePath}`);\n process.exit(1);\n } catch {\n // 目录不存在,继续创建\n }\n\n try {\n await fs.mkdir(workspacePath, { recursive: true });\n await fs.mkdir(path.join(workspacePath, 'steps'), { recursive: true });\n\n const workflowTemplate = `name: ${name}\nsteps:\n - id: clarify\n executor: trae\n input: brief.md\n output: steps/01-clarify/output.md\n acceptance:\n - 澄清需求范围与非目标\n - 产出结构化需求文档\n`;\n\n const stateTemplate = JSON.stringify({\n currentIndex: 0,\n status: 'running',\n updatedAt: new Date().toISOString(),\n }, null, 2);\n\n const briefTemplate = `# brief:需求描述\n\n## 背景\n(请描述项目背景)\n\n## 目标\n(请描述本轮目标)\n\n## 非目标\n(请描述本轮不做的事情)\n\n## 验收标准\n(请描述验收标准)\n`;\n\n await fs.writeFile(path.join(workspacePath, 'workflow.yaml'), workflowTemplate);\n await fs.writeFile(path.join(workspacePath, 'state.json'), stateTemplate);\n await fs.writeFile(path.join(workspacePath, 'brief.md'), briefTemplate);\n\n console.log(`✅ Created workspace \"${name}\" at ${workspacePath}`);\n console.log(`\nNext steps:\n 1. Edit brief.md to describe your requirements\n 2. Run \"agent-handoff status ${name}\" to check workspace status\n 3. Run \"agent-handoff next ${name}\" to get the first step prompt\n`);\n } catch (error) {\n console.error(`Error creating workspace: ${error}`);\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { computeState } from '../../core/state-machine.js';\n\nexport const statusCommand = new Command('status')\n .description('显示 workspace 状态')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-j, --json', 'JSON 格式输出')\n .action(async (workspace: string, options: { json: boolean }) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const stateResult = computeState(info.workflow, info.stepOutputs);\n\n if (options.json) {\n const jsonOutput = {\n name: info.workflow.name,\n path: workspacePath,\n status: stateResult.status,\n currentIndex: stateResult.currentIndex,\n totalSteps: info.workflow.steps.length,\n completedSteps: stateResult.completedSteps.length,\n steps: info.workflow.steps.map((step, index) => ({\n index,\n id: step.id,\n executor: step.executor,\n workItemId: step.workItemId,\n completed: info.stepOutputs.get(step.id) ?? false,\n })),\n };\n console.log(JSON.stringify(jsonOutput, null, 2));\n } else {\n console.log(`Workspace: ${info.workflow.name}`);\n console.log(`Status: ${stateResult.status}`);\n console.log('');\n console.log('Steps:');\n\n info.workflow.steps.forEach((step, index) => {\n const completed = info.stepOutputs.get(step.id) ?? false;\n const statusIcon = completed ? '✅' : '⬜';\n const stepNum = String(index + 1).padStart(2, '0');\n let line = ` ${statusIcon} ${stepNum}-${step.id} (${step.executor})`;\n if (step.workItemId) {\n line += ` [${step.workItemId}]`;\n }\n console.log(line);\n });\n\n console.log('');\n if (stateResult.status === 'done') {\n console.log('Current: completed');\n } else {\n const currentStep = info.workflow.steps[stateResult.currentIndex];\n console.log(`Current: step ${stateResult.currentIndex + 1} (${currentStep?.id})`);\n }\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { Workflow } from './models/workflow.js';\nimport { State } from './models/state.js';\nimport { parseWorkflow } from './workflow-parser.js';\n\nexport interface WorkspaceInfo {\n path: string;\n exists: boolean;\n hasWorkflow: boolean;\n hasState: boolean;\n workflow?: Workflow;\n state?: State;\n stepOutputs: Map<string, boolean>;\n}\n\nexport async function loadWorkspace(workspacePath: string): Promise<WorkspaceInfo> {\n const absolutePath = path.resolve(workspacePath);\n const workflowPath = path.join(absolutePath, 'workflow.yaml');\n const statePath = path.join(absolutePath, 'state.json');\n\n let exists = false;\n let hasWorkflow = false;\n let hasState = false;\n let workflow: Workflow | undefined;\n let state: State | undefined;\n let stepOutputs = new Map<string, boolean>();\n\n try {\n await fs.access(absolutePath);\n exists = true;\n } catch {\n return {\n path: absolutePath,\n exists: false,\n hasWorkflow: false,\n hasState: false,\n stepOutputs,\n };\n }\n\n try {\n await fs.access(workflowPath);\n hasWorkflow = true;\n workflow = await parseWorkflow(workflowPath);\n } catch {\n hasWorkflow = false;\n }\n\n try {\n const stateContent = await fs.readFile(statePath, 'utf-8');\n hasState = true;\n state = JSON.parse(stateContent) as State;\n } catch {\n hasState = false;\n }\n\n if (workflow) {\n stepOutputs = await detectStepOutputs(absolutePath, workflow);\n }\n\n return {\n path: absolutePath,\n exists,\n hasWorkflow,\n hasState,\n workflow,\n state,\n stepOutputs,\n };\n}\n\nexport async function detectStepOutputs(\n workspacePath: string,\n workflow: Workflow\n): Promise<Map<string, boolean>> {\n const outputs = new Map<string, boolean>();\n\n for (const step of workflow.steps) {\n const outputPath = path.join(workspacePath, step.output);\n try {\n const content = await fs.readFile(outputPath, 'utf-8');\n outputs.set(step.id, content.trim().length > 0);\n } catch {\n outputs.set(step.id, false);\n }\n }\n\n return outputs;\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function fileNotEmpty(filePath: string): Promise<boolean> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return content.trim().length > 0;\n } catch {\n return false;\n }\n}\n","import fs from 'fs/promises';\nimport YAML from 'yaml';\nimport { Workflow, Step, Executor } from './models/workflow';\n\nexport async function parseWorkflow(filePath: string): Promise<Workflow> {\n const content = await fs.readFile(filePath, 'utf-8');\n const parsed = YAML.parse(content);\n \n if (!parsed || typeof parsed !== 'object') {\n throw new Error(`Invalid workflow.yaml: ${filePath}`);\n }\n \n if (!parsed.name || typeof parsed.name !== 'string') {\n throw new Error('workflow.yaml missing required field: name');\n }\n \n if (!Array.isArray(parsed.steps) || parsed.steps.length === 0) {\n throw new Error('workflow.yaml missing required field: steps (non-empty array)');\n }\n \n const steps: Step[] = parsed.steps.map((step: Record<string, unknown>, index: number) => {\n if (!step.id || typeof step.id !== 'string') {\n throw new Error(`Step ${index} missing required field: id`);\n }\n if (!step.executor || typeof step.executor !== 'string') {\n throw new Error(`Step ${index} missing required field: executor`);\n }\n if (!step.input || typeof step.input !== 'string') {\n throw new Error(`Step ${index} missing required field: input`);\n }\n if (!step.output || typeof step.output !== 'string') {\n throw new Error(`Step ${index} missing required field: output`);\n }\n \n return {\n id: step.id,\n executor: step.executor as Executor,\n input: step.input,\n output: step.output,\n workItemId: step.workItemId as string | undefined,\n acceptance: step.acceptance as string[] | undefined,\n };\n });\n \n return {\n name: parsed.name,\n steps,\n };\n}\n\nexport function validateWorkflow(workflow: Workflow): string[] {\n const errors: string[] = [];\n \n if (!workflow.name || workflow.name.trim() === '') {\n errors.push('workflow.name is required');\n }\n \n if (!workflow.steps || workflow.steps.length === 0) {\n errors.push('workflow.steps is required and must be non-empty');\n return errors;\n }\n \n workflow.steps.forEach((step, index) => {\n if (!step.id || step.id.trim() === '') {\n errors.push(`steps[${index}].id is required`);\n }\n if (!step.executor) {\n errors.push(`steps[${index}].executor is required`);\n }\n if (!step.input || step.input.trim() === '') {\n errors.push(`steps[${index}].input is required`);\n }\n if (!step.output || step.output.trim() === '') {\n errors.push(`steps[${index}].output is required`);\n }\n if (!step.output.startsWith('steps/')) {\n errors.push(`steps[${index}].output should start with 'steps/'`);\n }\n });\n \n return errors;\n}\n","import { Workflow } from './models/workflow';\nimport { State, WorkflowStatus } from './models/state';\n\nexport interface StateMachineResult {\n currentIndex: number;\n status: WorkflowStatus;\n nextStepIndex: number | null;\n completedSteps: number[];\n pendingSteps: number[];\n}\n\nexport function computeState(\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): StateMachineResult {\n if (!workflow.steps || workflow.steps.length === 0) {\n return {\n currentIndex: 0,\n status: 'done',\n nextStepIndex: null,\n completedSteps: [],\n pendingSteps: [],\n };\n }\n\n const completedSteps: number[] = [];\n const pendingSteps: number[] = [];\n let currentIndex = 0;\n let status: WorkflowStatus = 'running';\n\n for (let i = 0; i < workflow.steps.length; i++) {\n const step = workflow.steps[i];\n const outputExists = stepOutputs.get(step.id) ?? false;\n\n if (outputExists) {\n completedSteps.push(i);\n } else {\n pendingSteps.push(i);\n }\n }\n\n const firstPendingIndex = pendingSteps[0];\n\n if (firstPendingIndex === undefined) {\n currentIndex = workflow.steps.length;\n status = 'done';\n } else {\n currentIndex = firstPendingIndex;\n status = 'running';\n }\n\n return {\n currentIndex,\n status,\n nextStepIndex: status === 'done' ? null : currentIndex,\n completedSteps,\n pendingSteps,\n };\n}\n\nexport function advanceState(\n state: State,\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): State {\n const result = computeState(workflow, stepOutputs);\n\n return {\n ...state,\n currentIndex: result.currentIndex,\n status: result.status,\n updatedAt: new Date().toISOString(),\n };\n}\n\nexport function isWorkflowComplete(\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): boolean {\n if (!workflow.steps || workflow.steps.length === 0) {\n return true;\n }\n\n return workflow.steps.every((step) => stepOutputs.get(step.id) === true);\n}\n\nexport function getCurrentStep(\n workflow: Workflow,\n stepOutputs: Map<string, boolean>\n): { index: number; step: typeof workflow.steps[0] } | null {\n const result = computeState(workflow, stepOutputs);\n\n if (result.status === 'done' || result.nextStepIndex === null) {\n return null;\n }\n\n return {\n index: result.nextStepIndex,\n step: workflow.steps[result.nextStepIndex],\n };\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { computeState, getCurrentStep } from '../../core/state-machine.js';\nimport { generatePrompt } from '../../core/prompt-generator.js';\nimport { copyToClipboard, isClipboardSupported } from '../../core/clipboard.js';\nimport { writeEvent } from '../../core/events-writer.js';\n\nexport const nextCommand = new Command('next')\n .description('输出下一步执行指令和 prompt')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-c, --copy', '复制 prompt 到剪贴板')\n .option('--no-event', '不写入事件日志')\n .action(async (workspace: string, options: { copy: boolean; event: boolean }) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const stateResult = computeState(info.workflow, info.stepOutputs);\n\n if (stateResult.status === 'done') {\n console.log(`Workflow \"${info.workflow.name}\" 已完成所有步骤。`);\n console.log('无下一步操作。');\n return;\n }\n\n const currentStep = getCurrentStep(info.workflow, info.stepOutputs);\n\n if (!currentStep) {\n console.log(`Workflow \"${info.workflow.name}\" 已完成所有步骤。`);\n console.log('无下一步操作。');\n return;\n }\n\n const { step, index } = currentStep;\n\n console.log(`Step: ${step.id}`);\n console.log(`Executor: ${step.executor}`);\n if (step.workItemId) {\n console.log(`Work Item: ${step.workItemId}`);\n }\n console.log('');\n console.log('Input:');\n console.log(` - ${step.input}`);\n console.log('');\n console.log('Output:');\n console.log(` - ${step.output}`);\n console.log('');\n console.log('Prompt:');\n console.log('────────────────────────────────────────');\n\n const prompt = generatePrompt({\n workflow: info.workflow,\n step,\n stepIndex: index,\n workspacePath: info.path,\n });\n\n console.log(prompt);\n console.log('────────────────────────────────────────');\n console.log('');\n\n if (options.event) {\n await writeEvent({\n workspacePath,\n step: { index: index + 1, id: step.id },\n type: 'step.started',\n summary: `开始执行步骤: ${step.id}`,\n workItemId: step.workItemId,\n links: [step.input],\n });\n }\n\n if (options.copy) {\n if (!isClipboardSupported()) {\n console.log('⚠️ 剪贴板功能在当前环境不可用');\n console.log('请手动复制上面的 Prompt');\n } else {\n const result = await copyToClipboard(prompt);\n if (result.success) {\n console.log('✅ Prompt 已复制到剪贴板');\n } else {\n console.log(`❌ 复制失败: ${result.error}`);\n console.log('请手动复制上面的 Prompt');\n }\n }\n } else {\n console.log('提示:将上述 Prompt 复制到 TRAE 新 Task 中执行');\n console.log(' 使用 --copy 选项可自动复制到剪贴板');\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n","import { Workflow, Step } from './models/workflow.js';\n\nexport interface PromptContext {\n workflow: Workflow;\n step: Step;\n stepIndex: number;\n workspacePath: string;\n}\n\nexport function generatePrompt(context: PromptContext): string {\n const { workflow, step, stepIndex } = context;\n const totalSteps = workflow.steps.length;\n const stepNum = stepIndex + 1;\n\n let prompt = `# 任务:${step.id}\n\n## 上下文\n- Workflow: ${workflow.name}\n- Step: ${stepNum} / ${totalSteps}\n- Executor: ${step.executor}`;\n\n if (step.workItemId) {\n prompt += `\\n- Work Item: ${step.workItemId}`;\n }\n\n prompt += `\n\n## 输入产物\n请阅读以下输入产物:\n- ${step.input}\n\n## 输出产物\n请将结果写入:\n- ${step.output}`;\n\n if (step.acceptance && step.acceptance.length > 0) {\n prompt += `\n\n## 验收标准`;\n for (const criteria of step.acceptance) {\n prompt += `\\n- ${criteria}`;\n }\n }\n\n prompt += `\n\n## 输出要求\n完成后请在 output.md 中包含以下区块:\n- 产物更新\n- 关键决策\n- 风险与待确认\n- 下一步交接\n\n---\nAgentHandoff Step Prompt`;\n\n return prompt;\n}\n","import clipboard from 'clipboardy';\n\nexport interface ClipboardResult {\n success: boolean;\n error?: string;\n}\n\nlet clipboardSupported: boolean | null = null;\n\nexport function isClipboardSupported(): boolean {\n if (clipboardSupported !== null) {\n return clipboardSupported;\n }\n\n try {\n clipboardSupported = true;\n return true;\n } catch {\n clipboardSupported = false;\n return false;\n }\n}\n\nexport async function copyToClipboard(text: string): Promise<ClipboardResult> {\n try {\n await clipboard.write(text);\n return { success: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: errorMessage,\n };\n }\n}\n\nexport async function readFromClipboard(): Promise<string> {\n try {\n return await clipboard.read();\n } catch {\n return '';\n }\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { Event, EventType, EventStep } from './models/event.js';\n\nexport interface WriteEventOptions {\n workspacePath: string;\n step: EventStep;\n type: EventType;\n summary: string;\n workItemId?: string;\n links?: string[];\n data?: Record<string, unknown>;\n}\n\nexport interface EventsWriterResult {\n success: boolean;\n event: Event;\n error?: string;\n}\n\nexport async function writeEvent(options: WriteEventOptions): Promise<EventsWriterResult> {\n const { workspacePath, step, type, summary, workItemId, links, data } = options;\n\n const event: Event = {\n ts: new Date().toISOString(),\n step,\n type,\n summary,\n ...(workItemId && { workItemId }),\n ...(links && links.length > 0 && { links }),\n ...(data && { data }),\n };\n\n try {\n const eventsPath = path.join(workspacePath, 'events.jsonl');\n const line = JSON.stringify(event) + '\\n';\n await fs.appendFile(eventsPath, line, 'utf-8');\n\n return {\n success: true,\n event,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n event,\n error: errorMessage,\n };\n }\n}\n\nexport async function readEvents(workspacePath: string): Promise<Event[]> {\n const eventsPath = path.join(workspacePath, 'events.jsonl');\n\n try {\n const content = await fs.readFile(eventsPath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim());\n\n const events: Event[] = [];\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Event;\n events.push(event);\n } catch {\n // Skip invalid lines\n }\n }\n\n return events;\n } catch {\n return [];\n }\n}\n\nexport async function getLatestEvent(workspacePath: string): Promise<Event | null> {\n const events = await readEvents(workspacePath);\n if (events.length === 0) {\n return null;\n }\n return events[events.length - 1];\n}\n\nexport async function getEventsByStep(workspacePath: string, stepId: string): Promise<Event[]> {\n const events = await readEvents(workspacePath);\n return events.filter((event) => event.step.id === stepId);\n}\n\nexport async function getEventsByType(workspacePath: string, type: EventType): Promise<Event[]> {\n const events = await readEvents(workspacePath);\n return events.filter((event) => event.type === type);\n}\n\nexport async function getEventsByWorkItem(\n workspacePath: string,\n workItemId: string\n): Promise<Event[]> {\n const events = await readEvents(workspacePath);\n return events.filter((event) => event.workItemId === workItemId);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { validateWorkspaceArtifacts } from '../../core/artifact-validator.js';\n\nexport const validateCommand = new Command('validate')\n .description('校验 workspace 产物结构')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('--strict', '严格模式(将警告视为错误)')\n .option('-j, --json', 'JSON 格式输出')\n .action(async (workspace: string, options: { strict: boolean; json: boolean }) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const result = await validateWorkspaceArtifacts(workspacePath);\n\n if (options.json) {\n const jsonOutput = {\n valid: options.strict ? result.valid && result.warningCount === 0 : result.valid,\n workspace: workspacePath,\n totalSteps: result.totalSteps,\n validSteps: result.validSteps,\n errorCount: result.errorCount,\n warningCount: result.warningCount,\n steps: Array.from(result.stepResults.entries()).map(([stepId, stepResult]) => ({\n stepId,\n valid: options.strict ? stepResult.valid && stepResult.warnings.length === 0 : stepResult.valid,\n errors: stepResult.errors,\n warnings: stepResult.warnings,\n })),\n };\n console.log(JSON.stringify(jsonOutput, null, 2));\n } else {\n console.log(`Workspace: ${info.workflow.name}`);\n console.log('');\n\n for (const step of info.workflow.steps) {\n const stepResult = result.stepResults.get(step.id);\n if (!stepResult) continue;\n\n const icon = stepResult.valid ? '✅' : '❌';\n console.log(`${icon} ${step.output} - ${stepResult.valid ? 'Valid' : 'Invalid'}`);\n\n if (!stepResult.valid) {\n for (const error of stepResult.errors) {\n console.log(` - ${error.message}`);\n }\n }\n\n if (stepResult.warnings.length > 0) {\n for (const warning of stepResult.warnings) {\n console.log(` ⚠️ ${warning.message}`);\n }\n }\n }\n\n console.log('');\n\n const hasErrors = result.errorCount > 0;\n const hasWarnings = result.warningCount > 0;\n const strictFail = options.strict && hasWarnings;\n\n if (!hasErrors && !strictFail) {\n console.log('All artifacts validated successfully.');\n if (hasWarnings) {\n console.log(`⚠️ ${result.warningCount} warning(s) found.`);\n }\n } else {\n const totalErrors = result.errorCount + (strictFail ? result.warningCount : 0);\n console.log(`Validation failed with ${totalErrors} error(s).`);\n }\n\n if (hasErrors || strictFail) {\n process.exit(1);\n }\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { loadWorkspace } from './workspace.js';\n\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationError[];\n warnings: ValidationWarning[];\n}\n\nexport interface ValidationError {\n type: 'missing_section' | 'empty_section' | 'invalid_format';\n section: string;\n message: string;\n}\n\nexport interface ValidationWarning {\n type: 'short_content' | 'missing_detail';\n section: string;\n message: string;\n}\n\nexport const REQUIRED_SECTIONS = [\n '产物更新',\n '关键决策',\n '风险与待确认',\n '下一步交接',\n] as const;\n\nexport type RequiredSection = (typeof REQUIRED_SECTIONS)[number];\n\nexport interface WorkspaceValidationResult {\n valid: boolean;\n stepResults: Map<string, ValidationResult>;\n totalSteps: number;\n validSteps: number;\n errorCount: number;\n warningCount: number;\n}\n\nconst MIN_CONTENT_LENGTH = 10;\n\nexport function validateArtifact(content: string): ValidationResult {\n const errors: ValidationError[] = [];\n const warnings: ValidationWarning[] = [];\n\n for (const section of REQUIRED_SECTIONS) {\n const sectionResult = findSection(content, section);\n\n if (!sectionResult.found) {\n errors.push({\n type: 'missing_section',\n section,\n message: `缺少必要区块: ${section}`,\n });\n } else if (!sectionResult.hasContent) {\n errors.push({\n type: 'empty_section',\n section,\n message: `区块内容为空: ${section}`,\n });\n } else if (sectionResult.contentLength < MIN_CONTENT_LENGTH) {\n warnings.push({\n type: 'short_content',\n section,\n message: `区块内容过短 (${sectionResult.contentLength} 字符): ${section}`,\n });\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\ninterface SectionResult {\n found: boolean;\n hasContent: boolean;\n contentLength: number;\n}\n\nfunction findSection(content: string, sectionName: string): SectionResult {\n const patterns = [\n new RegExp(`^##\\\\s+${escapeRegex(sectionName)}[^\\\\n]*$`, 'm'),\n new RegExp(`^###\\\\s+${escapeRegex(sectionName)}[^\\\\n]*$`, 'm'),\n ];\n\n let matchIndex = -1;\n let matchLength = 0;\n\n for (const pattern of patterns) {\n const match = content.match(pattern);\n if (match && match.index !== undefined) {\n matchIndex = match.index;\n matchLength = match[0].length;\n break;\n }\n }\n\n if (matchIndex === -1) {\n return { found: false, hasContent: false, contentLength: 0 };\n }\n\n const contentStart = matchIndex + matchLength;\n const remainingContent = content.slice(contentStart);\n\n const nextSectionMatch = remainingContent.match(/^#{1,3}\\s+/m);\n const sectionContent = nextSectionMatch\n ? remainingContent.slice(0, nextSectionMatch.index)\n : remainingContent;\n\n const trimmedContent = sectionContent.trim();\n\n return {\n found: true,\n hasContent: trimmedContent.length > 0,\n contentLength: trimmedContent.length,\n };\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport async function validateArtifactFile(\n filePath: string\n): Promise<ValidationResult> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n return validateArtifact(content);\n } catch {\n return {\n valid: false,\n errors: [\n {\n type: 'invalid_format',\n section: '',\n message: `无法读取文件: ${filePath}`,\n },\n ],\n warnings: [],\n };\n }\n}\n\nexport async function validateWorkspaceArtifacts(\n workspacePath: string\n): Promise<WorkspaceValidationResult> {\n const workspace = await loadWorkspace(workspacePath);\n const stepResults = new Map<string, ValidationResult>();\n let validSteps = 0;\n let errorCount = 0;\n let warningCount = 0;\n\n if (!workspace.workflow) {\n return {\n valid: false,\n stepResults,\n totalSteps: 0,\n validSteps: 0,\n errorCount: 1,\n warningCount: 0,\n };\n }\n\n for (const step of workspace.workflow.steps) {\n const outputPath = path.join(workspace.path, step.output);\n const result = await validateArtifactFile(outputPath);\n stepResults.set(step.id, result);\n\n if (result.valid) {\n validSteps++;\n }\n errorCount += result.errors.length;\n warningCount += result.warnings.length;\n }\n\n return {\n valid: errorCount === 0,\n stepResults,\n totalSteps: workspace.workflow.steps.length,\n validSteps,\n errorCount,\n warningCount,\n };\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport fs from 'fs/promises';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { computeState, getCurrentStep } from '../../core/state-machine.js';\nimport { writeEvent } from '../../core/events-writer.js';\nimport { EventType } from '../../core/models/event.js';\n\nexport const advanceCommand = new Command('advance')\n .description('推进 workspace 状态')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-e, --event <type>', '事件类型', 'step.done')\n .option('-s, --summary <text>', '事件摘要')\n .option('--no-state', '不更新 state.json')\n .option('--skip-event', '不写入事件日志')\n .action(\n async (\n workspace: string,\n options: { event: string; summary?: string; state: boolean; skipEvent: boolean }\n ) => {\n const workspacePath = path.resolve(workspace);\n\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.workflow) {\n console.error(`Error: failed to parse workflow.yaml`);\n process.exit(1);\n }\n\n const stateResult = computeState(info.workflow, info.stepOutputs);\n\n console.log(`Workspace: ${info.workflow.name}`);\n\n if (stateResult.status === 'done') {\n console.log('Status: done');\n console.log('');\n console.log('⚠️ Workflow already completed. No steps to advance.');\n return;\n }\n\n const currentStep = getCurrentStep(info.workflow, info.stepOutputs);\n\n if (!currentStep) {\n console.log('Status: done');\n console.log('');\n console.log('⚠️ Workflow already completed. No steps to advance.');\n return;\n }\n\n const { step, index } = currentStep;\n\n console.log(`Current step: ${step.id} (index: ${index})`);\n console.log('');\n\n const eventType = options.event as EventType;\n const eventSummary = options.summary || getDefaultSummary(eventType, step.id);\n\n if (!options.skipEvent) {\n const result = await writeEvent({\n workspacePath,\n step: { index: index + 1, id: step.id },\n type: eventType,\n summary: eventSummary,\n workItemId: step.workItemId,\n links: [step.output],\n });\n\n if (result.success) {\n console.log(`✅ Event written: ${eventType}`);\n console.log(` Summary: ${eventSummary}`);\n if (step.workItemId) {\n console.log(` Work Item: ${step.workItemId}`);\n }\n if (step.output) {\n console.log(` Links: ${step.output}`);\n }\n } else {\n console.log(`❌ Failed to write event: ${result.error}`);\n }\n }\n\n if (options.state) {\n const statePath = path.join(workspacePath, 'state.json');\n const newIndex = index + 1;\n const isDone = newIndex >= info.workflow.steps.length;\n\n const newState = {\n currentIndex: newIndex,\n status: isDone ? 'done' : 'running',\n updatedAt: new Date().toISOString(),\n };\n\n await fs.writeFile(statePath, JSON.stringify(newState, null, 2));\n console.log('');\n console.log(`✅ State updated: ${statePath}`);\n console.log(` Current index: ${newState.currentIndex}`);\n console.log(` Status: ${newState.status}`);\n\n if (isDone) {\n console.log('');\n console.log('🎉 Workflow completed!');\n } else {\n const nextStep = info.workflow.steps[newIndex];\n console.log(` Next step: ${nextStep.id}`);\n }\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n\nfunction getDefaultSummary(eventType: EventType, stepId: string): string {\n const summaries: Record<EventType, string> = {\n 'step.started': `开始执行步骤: ${stepId}`,\n 'step.done': `步骤完成: ${stepId}`,\n 'artifact.updated': '产物已更新',\n 'workflow.updated': '工作流已更新',\n 'verify.passed': '验证通过',\n 'verify.failed': '验证失败',\n 'accept.passed': '验收通过',\n 'accept.failed': '验收失败',\n 'issue.raised': '发现问题',\n 'handoff.sent': '已交接给下一步',\n 'automation.session': '自动化会话已记录',\n };\n return summaries[eventType] || `事件: ${eventType}`;\n}\n","import { Command } from 'commander';\nimport os from 'os';\nimport {\n loadConfig,\n findConfigFile,\n initConfigFile,\n DEFAULT_CONFIG,\n} from '../../core/config.js';\n\nexport const configCommand = new Command('config')\n .description('查看或管理配置')\n .argument('[action]', '操作: show, init', 'show')\n .option('-g, --global', '操作全局配置')\n .option('--verbose', '显示详细信息')\n .action(async (action: string, options: { global: boolean; verbose: boolean }) => {\n try {\n if (action === 'show') {\n await showConfig(options);\n } else if (action === 'init') {\n await initConfig(options);\n } else if (action === 'list') {\n await listConfig();\n } else {\n console.error(`Unknown action: ${action}`);\n console.log('Available actions: show, init, list');\n process.exit(1);\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n });\n\nasync function showConfig(options: { global: boolean; verbose: boolean }): Promise<void> {\n const targetPath = options.global ? os.homedir() : process.cwd();\n const config = await loadConfig(targetPath);\n\n if (options.verbose) {\n const configFile = await findConfigFile(targetPath);\n if (configFile) {\n console.log(`Config file: ${configFile}`);\n console.log('');\n } else {\n console.log('No config file found, using defaults');\n console.log('');\n }\n }\n\n console.log(JSON.stringify(config, null, 2));\n}\n\nasync function initConfig(options: { global: boolean; verbose: boolean }): Promise<void> {\n const targetPath = options.global ? os.homedir() : process.cwd();\n const configPath = await initConfigFile(targetPath, options.global);\n\n console.log(`✅ Created config file: ${configPath}`);\n console.log('');\n console.log('Default configuration:');\n console.log(JSON.stringify(DEFAULT_CONFIG, null, 2));\n}\n\nasync function listConfig(): Promise<void> {\n console.log('Configuration options:');\n console.log('');\n console.log(' defaultWorkspace - 默认 workspace 路径');\n console.log(' events.enabled - 是否启用事件日志 (default: true)');\n console.log(' events.logStepStarted - 是否记录 step.started (default: true)');\n console.log(' events.logStepDone - 是否记录 step.done (default: true)');\n console.log(' clipboard.autoCopy - 是否自动复制 prompt (default: false)');\n console.log(' prompt.templatePath - 自定义 prompt 模板路径');\n console.log(' prompt.language - prompt 语言 (default: zh)');\n console.log(' validation.strict - 严格校验模式 (default: false)');\n console.log(' validation.warnOnShortContent - 内容过短时警告 (default: true)');\n console.log('');\n console.log('Config file locations (in order of priority):');\n console.log(' .agenthandoffrc');\n console.log(' .agenthandoffrc.json');\n console.log(' .agenthandoffrc.yaml');\n console.log(' package.json#agenthandoff');\n console.log(` ~/.agenthandoffrc (global)`);\n}\n","import fs from 'fs/promises';\nimport path from 'path';\nimport os from 'os';\n\nexport interface AgentHandoffConfig {\n defaultWorkspace?: string;\n events?: {\n enabled: boolean;\n logStepStarted: boolean;\n logStepDone: boolean;\n };\n automation?: {\n enabled: boolean;\n provider: 'nutjs';\n screenshot: boolean;\n timeout: number;\n retries: number;\n confidence?: number;\n };\n clipboard?: {\n autoCopy: boolean;\n };\n prompt?: {\n templatePath?: string;\n language: 'zh' | 'en';\n };\n validation?: {\n strict: boolean;\n warnOnShortContent: boolean;\n };\n}\n\nexport const DEFAULT_CONFIG: AgentHandoffConfig = {\n events: {\n enabled: true,\n logStepStarted: true,\n logStepDone: true,\n },\n automation: {\n enabled: false,\n provider: 'nutjs',\n screenshot: false,\n timeout: 30000,\n retries: 3,\n confidence: 0.8,\n },\n clipboard: {\n autoCopy: false,\n },\n prompt: {\n language: 'zh',\n },\n validation: {\n strict: false,\n warnOnShortContent: true,\n },\n};\n\nconst CONFIG_FILES = [\n '.agenthandoffrc',\n '.agenthandoffrc.json',\n '.agenthandoffrc.yaml',\n '.agenthandoffrc.yml',\n];\n\nconst configCache = new Map<string, AgentHandoffConfig>();\n\nexport async function findConfigFile(startPath: string): Promise<string | null> {\n let currentPath = path.resolve(startPath);\n const homePath = os.homedir();\n\n while (true) {\n for (const configFile of CONFIG_FILES) {\n const filePath = path.join(currentPath, configFile);\n try {\n await fs.access(filePath);\n return filePath;\n } catch {\n // File doesn't exist, continue\n }\n }\n\n const packageJsonPath = path.join(currentPath, 'package.json');\n try {\n const content = await fs.readFile(packageJsonPath, 'utf-8');\n const pkg = JSON.parse(content);\n if (pkg.agenthandoff) {\n return packageJsonPath;\n }\n } catch {\n // File doesn't exist or invalid, continue\n }\n\n if (currentPath === homePath || currentPath === path.dirname(currentPath)) {\n break;\n }\n currentPath = path.dirname(currentPath);\n }\n\n return null;\n}\n\nexport async function loadConfigFile(filePath: string): Promise<Partial<AgentHandoffConfig>> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const ext = path.extname(filePath);\n\n if (ext === '.yaml' || ext === '.yml') {\n return parseYaml(content);\n }\n\n if (filePath.endsWith('package.json')) {\n const pkg = JSON.parse(content);\n return pkg.agenthandoff || {};\n }\n\n return JSON.parse(content);\n } catch {\n return {};\n }\n}\n\nfunction parseYaml(content: string): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const lines = content.split('\\n');\n let currentObj: Record<string, unknown> = result;\n const stack: Array<{ obj: Record<string, unknown> }> = [];\n\n for (const line of lines) {\n if (!line.trim() || line.trim().startsWith('#')) {\n continue;\n }\n\n const indent = line.search(/\\S/);\n const trimmed = line.trim();\n\n if (trimmed.includes(':')) {\n const colonIndex = trimmed.indexOf(':');\n const key = trimmed.slice(0, colonIndex).trim();\n const value = trimmed.slice(colonIndex + 1).trim();\n\n if (value === '') {\n if (stack.length > 0) {\n const expectedIndent = stack.length * 2;\n if (indent < expectedIndent) {\n while (stack.length > 0 && indent < stack.length * 2) {\n stack.pop();\n }\n if (stack.length > 0) {\n currentObj = stack[stack.length - 1].obj as Record<string, unknown>;\n } else {\n currentObj = result;\n }\n }\n }\n\n const newObj: Record<string, unknown> = {};\n currentObj[key] = newObj;\n stack.push({ obj: currentObj });\n currentObj = newObj;\n } else {\n let parsedValue: unknown = value;\n if (value === 'true') parsedValue = true;\n else if (value === 'false') parsedValue = false;\n else if (value === 'null') parsedValue = null;\n else if (/^\\d+$/.test(value)) parsedValue = parseInt(value, 10);\n else if (/^\\d+\\.\\d+$/.test(value)) parsedValue = parseFloat(value);\n else if (value.startsWith('\"') && value.endsWith('\"')) {\n parsedValue = value.slice(1, -1);\n } else if (value.startsWith(\"'\") && value.endsWith(\"'\")) {\n parsedValue = value.slice(1, -1);\n }\n\n currentObj[key] = parsedValue;\n }\n }\n }\n\n return result;\n}\n\nexport function mergeConfig(\n base: AgentHandoffConfig,\n override: Partial<AgentHandoffConfig>\n): AgentHandoffConfig {\n const result: AgentHandoffConfig = JSON.parse(JSON.stringify(base));\n\n for (const key of Object.keys(override) as Array<keyof AgentHandoffConfig>) {\n const overrideValue = override[key];\n if (overrideValue === undefined) continue;\n\n if (\n typeof overrideValue === 'object' &&\n overrideValue !== null &&\n !Array.isArray(overrideValue)\n ) {\n const baseValue = result[key];\n if (\n typeof baseValue === 'object' &&\n baseValue !== null &&\n !Array.isArray(baseValue)\n ) {\n // Deep merge for nested objects\n (result as Record<string, unknown>)[key] = mergeConfig(\n baseValue as AgentHandoffConfig,\n overrideValue as Partial<AgentHandoffConfig>\n );\n } else {\n (result as Record<string, unknown>)[key] = overrideValue;\n }\n } else {\n (result as Record<string, unknown>)[key] = overrideValue;\n }\n }\n\n return result;\n}\n\nexport async function loadConfig(workspacePath?: string): Promise<AgentHandoffConfig> {\n const startPath = workspacePath ? path.resolve(workspacePath) : process.cwd();\n const cacheKey = startPath;\n\n if (configCache.has(cacheKey)) {\n return configCache.get(cacheKey)!;\n }\n\n let config = JSON.parse(JSON.stringify(DEFAULT_CONFIG)) as AgentHandoffConfig;\n\n const globalConfigPath = path.join(os.homedir(), '.agenthandoffrc');\n try {\n await fs.access(globalConfigPath);\n const globalConfig = await loadConfigFile(globalConfigPath);\n config = mergeConfig(config, globalConfig);\n } catch {\n // Global config doesn't exist\n }\n\n const localConfigFile = await findConfigFile(startPath);\n if (localConfigFile) {\n const localConfig = await loadConfigFile(localConfigFile);\n config = mergeConfig(config, localConfig);\n }\n\n configCache.set(cacheKey, config);\n return config;\n}\n\nexport function clearConfigCache(): void {\n configCache.clear();\n}\n\nexport async function initConfigFile(targetPath: string, global = false): Promise<string> {\n const configPath = global\n ? path.join(os.homedir(), '.agenthandoffrc')\n : path.join(targetPath, '.agenthandoffrc');\n\n const content = JSON.stringify(DEFAULT_CONFIG, null, 2);\n await fs.writeFile(configPath, content, 'utf-8');\n\n return configPath;\n}\n","import { Command } from 'commander';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { OperationReporter } from '../../adapters/trae/operation-reporter.js';\n\ntype ReportFormat = 'json' | 'markdown' | 'html';\n\nexport const reportCommand = new Command('report')\n .description('生成自动化操作报告')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('-f, --format <format>', '报告格式: json, markdown, html', 'markdown')\n .option('-s, --session <id>', '指定 session ID')\n .option('--screenshots', '包含截图', false)\n .option('-o, --output <path>', '输出路径')\n .action(\n async (\n workspace: string,\n options: { format: ReportFormat; session?: string; screenshots: boolean; output?: string }\n ) => {\n const workspacePath = path.resolve(workspace);\n const logDir = path.join(workspacePath, 'operations');\n\n try {\n let sessionFile: string;\n if (options.session) {\n sessionFile = path.join(logDir, `operations-${options.session}.jsonl`);\n } else {\n const files = await fs.readdir(logDir);\n const jsonlFiles = files\n .filter((f) => f.endsWith('.jsonl'))\n .sort()\n .reverse();\n if (jsonlFiles.length === 0) {\n console.error('Error: no operation logs found');\n process.exit(1);\n }\n sessionFile = path.join(logDir, jsonlFiles[0]);\n }\n\n const content = await fs.readFile(sessionFile, 'utf-8');\n const lines = content.split('\\n').filter((l) => l.trim());\n const session = JSON.parse(lines[lines.length - 1]);\n\n const reporter = new OperationReporter(session);\n const report = reporter.generate({\n format: options.format,\n includeScreenshots: options.screenshots,\n });\n\n if (options.output) {\n await fs.writeFile(path.resolve(options.output), report, 'utf-8');\n console.log(`✅ Report saved to: ${options.output}`);\n } else {\n console.log(report);\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n\n","import fs from 'fs/promises';\nimport { TraeSession } from './types';\n\nexport interface ReportOptions {\n format: 'json' | 'markdown' | 'html';\n includeScreenshots: boolean;\n}\n\nexport class OperationReporter {\n private session: TraeSession;\n\n constructor(session: TraeSession) {\n this.session = session;\n }\n\n generate(options: ReportOptions): string {\n switch (options.format) {\n case 'json':\n return this.generateJson();\n case 'markdown':\n return this.generateMarkdown(options.includeScreenshots);\n case 'html':\n return this.generateHtml(options.includeScreenshots);\n default:\n return this.generateMarkdown(options.includeScreenshots);\n }\n }\n\n private generateJson(): string {\n return JSON.stringify(this.session, null, 2);\n }\n\n private generateMarkdown(includeScreenshots: boolean): string {\n const lines: string[] = [\n '# Automation Session Report',\n '',\n `**Session ID:** ${this.session.id}`,\n `**Started At:** ${this.session.startedAt}`,\n `**Workspace:** ${this.session.workspacePath}`,\n `**Step ID:** ${this.session.stepId}`,\n ...(this.session.status ? [`**Status:** ${this.session.status}`] : []),\n ...(this.session.error ? [`**Error:** ${this.session.error}`] : []),\n '',\n `## Operations (${this.session.operations.length})`,\n '',\n ];\n\n this.session.operations.forEach((op, index) => {\n lines.push(`### ${index + 1}. ${op.type}`);\n if (op.target) {\n lines.push(`- **Target:** ${op.target}`);\n }\n if (op.value) {\n lines.push(\n `- **Value:** ${op.value.substring(0, 100)}${op.value.length > 100 ? '...' : ''}`\n );\n }\n lines.push(`- **Timestamp:** ${new Date(op.timestamp).toISOString()}`);\n lines.push('');\n });\n\n if (includeScreenshots && this.session.screenshots.length > 0) {\n lines.push(`## Screenshots (${this.session.screenshots.length})`);\n lines.push('');\n this.session.screenshots.forEach((screenshot, index) => {\n lines.push(`### Screenshot ${index + 1}`);\n lines.push(`![Screenshot ${index + 1}](${screenshot})`);\n lines.push('');\n });\n }\n\n return lines.join('\\n');\n }\n\n private generateHtml(includeScreenshots: boolean): string {\n const operationsHtml = this.session.operations\n .map(\n (op, index) => `\n <div class=\"operation\">\n <h3>${index + 1}. ${op.type}</h3>\n ${op.target ? `<p><strong>Target:</strong> ${op.target}</p>` : ''}\n ${\n op.value\n ? `<p><strong>Value:</strong> ${op.value.substring(0, 100)}${\n op.value.length > 100 ? '...' : ''\n }</p>`\n : ''\n }\n <p><strong>Timestamp:</strong> ${new Date(op.timestamp).toISOString()}</p>\n </div>\n `\n )\n .join('');\n\n const screenshotsHtml =\n includeScreenshots && this.session.screenshots.length > 0\n ? `\n <h2>Screenshots (${this.session.screenshots.length})</h2>\n ${this.session.screenshots\n .map(\n (s, i) => `\n <div class=\"screenshot\">\n <h3>Screenshot ${i + 1}</h3>\n <img src=\"${s}\" alt=\"Screenshot ${i + 1}\" />\n </div>\n `\n )\n .join('')}\n `\n : '';\n\n const statusLine = this.session.status\n ? `<p><strong>Status:</strong> ${this.session.status}</p>`\n : '';\n const errorLine = this.session.error ? `<p><strong>Error:</strong> ${this.session.error}</p>` : '';\n\n return `\n<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Automation Session Report</title>\n <style>\n body {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n max-width: 800px;\n margin: 0 auto;\n padding: 20px;\n background: #f5f5f5;\n }\n .header {\n background: white;\n padding: 20px;\n border-radius: 8px;\n margin-bottom: 20px;\n }\n .operation {\n background: white;\n padding: 15px;\n border-radius: 8px;\n margin-bottom: 10px;\n }\n .screenshot img {\n max-width: 100%;\n border-radius: 8px;\n }\n h1 { color: #333; }\n h2 { color: #555; border-bottom: 1px solid #eee; padding-bottom: 10px; }\n h3 { color: #666; margin: 0 0 10px 0; }\n p { margin: 5px 0; color: #666; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <h1>Automation Session Report</h1>\n <p><strong>Session ID:</strong> ${this.session.id}</p>\n <p><strong>Started At:</strong> ${this.session.startedAt}</p>\n <p><strong>Workspace:</strong> ${this.session.workspacePath}</p>\n <p><strong>Step ID:</strong> ${this.session.stepId}</p>\n ${statusLine}\n ${errorLine}\n </div>\n\n <h2>Operations (${this.session.operations.length})</h2>\n ${operationsHtml}\n\n ${screenshotsHtml}\n</body>\n</html>\n `.trim();\n }\n\n async saveToFile(outputPath: string, options: ReportOptions): Promise<string> {\n const content = this.generate(options);\n await fs.writeFile(outputPath, content, 'utf-8');\n return outputPath;\n }\n}\n\n","import { Command } from 'commander';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { exportWebTimeline } from '../../export/web/exporter.js';\n\nexport const exportCommand = new Command('export')\n .description('导出静态产物(例如 Web Timeline)')\n .argument('[workspace]', 'workspace 路径', '.')\n .requiredOption('--format <format>', '导出格式: web', 'web')\n .option('-o, --output <dir>', '导出目录(默认 <workspace>/timeline)')\n .option('--limit <n>', '只导出最近 n 条事件', (v) => parseInt(v, 10))\n .action(\n async (\n workspace: string,\n options: { format: string; output?: string; limit?: number }\n ) => {\n const workspacePath = path.resolve(workspace);\n try {\n const info = await loadWorkspace(workspacePath);\n\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n\n if (!info.hasWorkflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (options.format !== 'web') {\n console.error(`Error: unsupported format: ${options.format}`);\n process.exit(1);\n }\n\n const outputDir = options.output\n ? path.resolve(options.output)\n : path.join(workspacePath, 'timeline');\n\n const result = await exportWebTimeline({\n workspacePath,\n outputDir,\n limit: options.limit,\n });\n\n console.log(`✅ Exported to: ${result.outputDir}`);\n console.log(` index: ${result.indexPath}`);\n console.log(` events: ${result.eventsCount} (invalid lines: ${result.invalidLines})`);\n console.log(` artifacts: ${result.artifactsCount}`);\n console.log('');\n console.log(`打开方式(macOS):open ${path.join(result.outputDir, 'index.html')}`);\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { readEventsJsonl, toTimelineItems } from '../../core/events-reader.js';\nimport { buildArtifactLinkMap } from './artifact-indexer.js';\nimport { renderArtifactPage } from './artifact-renderer.js';\nimport { renderWebTimeline } from './timeline-renderer.js';\n\nexport interface ExportWebTimelineOptions {\n workspacePath: string;\n outputDir: string;\n limit?: number;\n}\n\nexport interface ExportWebTimelineResult {\n outputDir: string;\n indexPath: string;\n eventsCount: number;\n invalidLines: number;\n artifactsCount: number;\n}\n\nasync function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport async function exportWebTimeline(options: ExportWebTimelineOptions): Promise<ExportWebTimelineResult> {\n const { events, invalidLines } = await readEventsJsonl({\n workspacePath: options.workspacePath,\n limit: options.limit,\n });\n\n const items = toTimelineItems(events);\n\n const linkSet = new Set<string>();\n for (const item of items) {\n for (const link of item.links || []) {\n linkSet.add(link);\n }\n }\n\n const mappings = buildArtifactLinkMap([...linkSet]);\n const linkHrefMap: Record<string, string> = {};\n for (const m of mappings) {\n linkHrefMap[m.original] = m.outputHtmlPath;\n }\n\n const out = path.resolve(options.outputDir);\n await ensureDir(out);\n await ensureDir(path.join(out, 'assets'));\n await ensureDir(path.join(out, 'artifacts'));\n\n for (const m of mappings) {\n const artifactSourcePath = path.join(options.workspacePath, m.original);\n let content: string;\n try {\n content = await fs.readFile(artifactSourcePath, 'utf-8');\n } catch {\n content = `文件不存在或无法读取: ${m.original}`;\n }\n\n const html = renderArtifactPage({\n title: m.title,\n originalPath: m.original,\n content,\n });\n\n const fullOutPath = path.join(out, m.outputHtmlPath);\n await ensureDir(path.dirname(fullOutPath));\n await fs.writeFile(fullOutPath, html, 'utf-8');\n }\n\n const timeline = renderWebTimeline({\n title: 'AgentHandoff Timeline',\n workspaceName: path.basename(path.resolve(options.workspacePath)),\n generatedAt: new Date().toISOString(),\n items,\n includeAssets: true,\n linkHrefMap,\n });\n\n await fs.writeFile(path.join(out, 'index.html'), timeline.html, 'utf-8');\n for (const [rel, content] of Object.entries(timeline.assets)) {\n const full = path.join(out, rel);\n await ensureDir(path.dirname(full));\n await fs.writeFile(full, content, 'utf-8');\n }\n\n return {\n outputDir: out,\n indexPath: path.join(out, 'index.html'),\n eventsCount: items.length,\n invalidLines,\n artifactsCount: mappings.length,\n };\n}\n\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { Event } from './models/event.js';\n\nexport interface ReadEventsOptions {\n workspacePath: string;\n limit?: number;\n}\n\nexport interface ReadEventsResult {\n events: Event[];\n invalidLines: number;\n}\n\nexport interface TimelineItem {\n ts: string;\n stepId: string;\n stepIndex: number;\n type: string;\n summary: string;\n workItemId?: string;\n links?: string[];\n data?: Record<string, unknown>;\n}\n\nexport async function readEventsJsonl(options: ReadEventsOptions): Promise<ReadEventsResult> {\n const eventsPath = path.join(options.workspacePath, 'events.jsonl');\n\n try {\n const content = await fs.readFile(eventsPath, 'utf-8');\n const lines = content.split('\\n').filter((line) => line.trim());\n\n const events: Event[] = [];\n let invalidLines = 0;\n\n for (const line of lines) {\n try {\n const event = JSON.parse(line) as Event;\n events.push(event);\n } catch {\n invalidLines += 1;\n }\n }\n\n events.sort((a, b) => {\n const ats = a.ts ?? '';\n const bts = b.ts ?? '';\n if (ats < bts) return -1;\n if (ats > bts) return 1;\n return 0;\n });\n\n const limited =\n typeof options.limit === 'number' && options.limit > 0 ? events.slice(-options.limit) : events;\n\n return { events: limited, invalidLines };\n } catch {\n return { events: [], invalidLines: 0 };\n }\n}\n\nexport function toTimelineItems(events: Event[]): TimelineItem[] {\n return events.map((event) => ({\n ts: event.ts,\n stepId: event.step.id,\n stepIndex: event.step.index,\n type: event.type,\n summary: event.summary,\n ...(event.workItemId && { workItemId: event.workItemId }),\n ...(event.links && event.links.length > 0 && { links: event.links }),\n ...(event.data && { data: event.data }),\n }));\n}\n\n","import crypto from 'crypto';\n\nexport interface ArtifactLinkMapping {\n original: string;\n outputHtmlPath: string;\n title: string;\n}\n\nfunction sanitizeSegments(segments: string[]): string[] {\n const result: string[] = [];\n for (const seg of segments) {\n const trimmed = seg.trim();\n if (!trimmed || trimmed === '.') continue;\n if (trimmed === '..') {\n result.push('__');\n continue;\n }\n result.push(trimmed);\n }\n return result;\n}\n\nfunction toSafeFilename(original: string): string {\n const rawSegments = original.split(/[\\\\/]+/g);\n const safeSegments = sanitizeSegments(rawSegments);\n const base = safeSegments.join('-') || 'artifact';\n const normalized = base.replace(/[^a-zA-Z0-9._-]+/g, '_');\n\n const suffix = '.html';\n const maxLen = 180;\n if (normalized.length + suffix.length <= maxLen) {\n return normalized + suffix;\n }\n\n const hash = crypto.createHash('sha1').update(original).digest('hex').slice(0, 10);\n const headLen = Math.max(16, maxLen - suffix.length - 1 - hash.length);\n const head = normalized.slice(0, headLen);\n return `${head}-${hash}${suffix}`;\n}\n\nexport function buildArtifactLinkMap(links: string[]): ArtifactLinkMapping[] {\n const seen = new Set<string>();\n const mappings: ArtifactLinkMapping[] = [];\n\n for (const link of links) {\n const original = String(link);\n if (seen.has(original)) continue;\n seen.add(original);\n\n const filename = toSafeFilename(original);\n const outputHtmlPath = `artifacts/${filename}`;\n mappings.push({ original, outputHtmlPath, title: original });\n }\n\n return mappings;\n}\n\n","export interface RenderArtifactOptions {\n title: string;\n originalPath: string;\n content: string;\n}\n\nfunction escapeHtml(input: string): string {\n return input\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;');\n}\n\nexport function renderArtifactPage(options: RenderArtifactOptions): string {\n const title = escapeHtml(options.title);\n const originalPath = escapeHtml(options.originalPath);\n const content = escapeHtml(options.content);\n\n return [\n '<!doctype html>',\n '<html lang=\"zh-CN\">',\n '<head>',\n '<meta charset=\"utf-8\" />',\n '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />',\n `<title>${title}</title>`,\n '<style>',\n 'body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial; color: #111827; background: #ffffff; }',\n '.container { max-width: 1040px; margin: 0 auto; padding: 24px; }',\n 'h1 { font-size: 18px; margin: 0 0 8px; }',\n '.path { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; font-size: 12px; color: #374151; }',\n 'pre { margin-top: 16px; background: #0b1020; color: #e5e7eb; padding: 12px; border-radius: 10px; overflow: auto; font-size: 12px; line-height: 1.5; }',\n '</style>',\n '</head>',\n '<body>',\n '<div class=\"container\">',\n `<h1>${title}</h1>`,\n `<div class=\"path\">${originalPath}</div>`,\n `<pre>${content}</pre>`,\n '</div>',\n '</body>',\n '</html>',\n '',\n ].join('\\n');\n}\n\n","import { TimelineItem } from '../../core/events-reader.js';\n\nexport interface RenderWebTimelineOptions {\n title: string;\n workspaceName: string;\n generatedAt: string;\n items: TimelineItem[];\n includeAssets: boolean;\n linkHrefMap?: Record<string, string>;\n}\n\nexport interface RenderWebTimelineResult {\n html: string;\n assets: Record<string, string>;\n}\n\nfunction escapeHtml(input: string): string {\n return input\n .replaceAll('&', '&amp;')\n .replaceAll('<', '&lt;')\n .replaceAll('>', '&gt;')\n .replaceAll('\"', '&quot;')\n .replaceAll(\"'\", '&#39;');\n}\n\nfunction renderLinks(links: string[], linkHrefMap?: Record<string, string>): string {\n const items = links\n .map((link) => {\n const href = linkHrefMap && linkHrefMap[link] ? linkHrefMap[link] : link;\n const safeLabel = escapeHtml(link);\n const safeHref = escapeHtml(href);\n return `<a href=\"${safeHref}\" data-link=\"${safeLabel}\" target=\"_blank\" rel=\"noopener noreferrer\">${safeLabel}</a>`;\n })\n .join('');\n return `<div class=\"links\">${items}</div>`;\n}\n\nfunction renderData(data: Record<string, unknown>): string {\n const json = escapeHtml(JSON.stringify(data, null, 2));\n return `<details><summary>data</summary><pre>${json}</pre></details>`;\n}\n\nexport function renderWebTimeline(options: RenderWebTimelineOptions): RenderWebTimelineResult {\n const assets: Record<string, string> = {};\n\n if (options.includeAssets) {\n assets['assets/viewer.css'] = getDefaultCss();\n assets['assets/viewer.js'] = getDefaultJs();\n }\n\n const title = escapeHtml(options.title);\n const workspaceName = escapeHtml(options.workspaceName);\n const generatedAt = escapeHtml(options.generatedAt);\n\n const eventsJson = escapeHtml(JSON.stringify(options.items));\n const linkMapJson = escapeHtml(JSON.stringify(options.linkHrefMap || {}));\n\n const headAssets = options.includeAssets\n ? `<link rel=\"stylesheet\" href=\"assets/viewer.css\" />`\n : '';\n const bodyAssets = options.includeAssets ? `<script src=\"assets/viewer.js\"></script>` : '';\n\n const list = options.items\n .map((item) => {\n const ts = escapeHtml(item.ts);\n const stepId = escapeHtml(item.stepId);\n const type = escapeHtml(item.type);\n const summary = escapeHtml(item.summary);\n\n const workItem = item.workItemId ? `<span class=\"badge\">${escapeHtml(item.workItemId)}</span>` : '';\n\n const links =\n item.links && item.links.length > 0 ? renderLinks(item.links, options.linkHrefMap) : '';\n const data = item.data ? renderData(item.data) : '';\n\n return [\n `<div class=\"item\" data-step=\"${stepId}\" data-type=\"${type}\">`,\n `<div class=\"row\">`,\n `<span class=\"ts\">${ts}</span>`,\n `<span class=\"badge\">${stepId}</span>`,\n `<span class=\"type\">${type}</span>`,\n workItem,\n `</div>`,\n `<div class=\"summary\">${summary}</div>`,\n links,\n data,\n `</div>`,\n ].join('');\n })\n .join('');\n\n const html = [\n '<!doctype html>',\n '<html lang=\"zh-CN\">',\n '<head>',\n '<meta charset=\"utf-8\" />',\n '<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />',\n `<title>${title}</title>`,\n headAssets,\n '</head>',\n '<body>',\n '<div class=\"container\">',\n '<header>',\n `<h1>${workspaceName} Timeline</h1>`,\n `<div class=\"meta\">Generated at ${generatedAt}</div>`,\n '</header>',\n '<section class=\"filters\" id=\"timeline-filters\">',\n '<div class=\"filters-row\">',\n '<input id=\"filter-q\" type=\"search\" placeholder=\"搜索 summary / data...\" />',\n '<select id=\"filter-step\"></select>',\n '<select id=\"filter-type\"></select>',\n '<select id=\"filter-workItem\"></select>',\n '<button id=\"filter-clear\" type=\"button\">清空筛选</button>',\n '</div>',\n '<div class=\"filters-meta\" id=\"filters-meta\"></div>',\n '</section>',\n `<script id=\"__EVENTS__\" type=\"application/json\">${eventsJson}</script>`,\n `<script id=\"__LINK_HREF_MAP__\" type=\"application/json\">${linkMapJson}</script>`,\n `<div class=\"list\" id=\"timeline-list\">${list}</div>`,\n '</div>',\n bodyAssets,\n '</body>',\n '</html>',\n ]\n .filter((x) => x !== '')\n .join('\\n');\n\n return { html, assets };\n}\n\nfunction getDefaultCss(): string {\n return [\n '* { box-sizing: border-box; }',\n 'body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, \"Apple Color Emoji\", \"Segoe UI Emoji\"; color: #111827; background: #ffffff; }',\n '.container { max-width: 1040px; margin: 0 auto; padding: 24px; }',\n 'header { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; border-bottom: 1px solid #e5e7eb; padding-bottom: 12px; margin-bottom: 16px; }',\n 'h1 { font-size: 20px; margin: 0; }',\n '.meta { font-size: 12px; color: #6b7280; }',\n '.filters { margin: 12px 0 16px; padding: 12px; border: 1px solid #e5e7eb; border-radius: 10px; background: #fafafa; }',\n '.filters-row { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr auto; gap: 10px; align-items: center; }',\n '.filters-row input, .filters-row select { width: 100%; padding: 8px 10px; border-radius: 8px; border: 1px solid #d1d5db; font-size: 13px; background: #fff; }',\n '.filters-row button { padding: 8px 12px; border-radius: 8px; border: 1px solid #d1d5db; background: #fff; cursor: pointer; }',\n '.filters-row button:hover { background: #f3f4f6; }',\n '.filters-meta { margin-top: 8px; font-size: 12px; color: #6b7280; }',\n '.list { display: flex; flex-direction: column; gap: 10px; }',\n '.item { border: 1px solid #e5e7eb; border-radius: 10px; padding: 12px; }',\n '.row { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }',\n '.ts { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; font-size: 12px; color: #374151; }',\n '.badge { display: inline-flex; align-items: center; padding: 2px 8px; border-radius: 999px; font-size: 12px; background: #eff6ff; color: #1d4ed8; border: 1px solid #dbeafe; }',\n '.type { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; font-size: 12px; color: #111827; background: #f3f4f6; padding: 2px 8px; border-radius: 8px; }',\n '.summary { margin-top: 8px; white-space: pre-wrap; line-height: 1.45; }',\n '.links { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; }',\n '.links a { font-size: 12px; color: #2563eb; text-decoration: none; border-bottom: 1px dashed #93c5fd; }',\n '.links a:hover { border-bottom-style: solid; }',\n 'details { margin-top: 10px; }',\n 'pre { background: #0b1020; color: #e5e7eb; padding: 10px; border-radius: 10px; overflow: auto; font-size: 12px; line-height: 1.5; }',\n '',\n ].join('\\n');\n}\n\nfunction getDefaultJs(): string {\n return [\n '(() => {',\n ' const g = globalThis;',\n ' const doc = g.document;',\n ' if (!doc || typeof doc.getElementById !== \"function\") return;',\n ' const el = doc.getElementById(\"__EVENTS__\");',\n ' if (!el) return;',\n ' const qInput = doc.getElementById(\"filter-q\");',\n ' const stepSelect = doc.getElementById(\"filter-step\");',\n ' const typeSelect = doc.getElementById(\"filter-type\");',\n ' const workItemSelect = doc.getElementById(\"filter-workItem\");',\n ' const clearBtn = doc.getElementById(\"filter-clear\");',\n ' const listEl = doc.getElementById(\"timeline-list\");',\n ' const metaEl = doc.getElementById(\"filters-meta\");',\n ' const HTMLInput = g.HTMLInputElement;',\n ' const HTMLSelect = g.HTMLSelectElement;',\n ' const HTMLButton = g.HTMLButtonElement;',\n ' const HTMLElementCtor = g.HTMLElement;',\n ' if (!HTMLInput || !HTMLSelect || !HTMLButton || !HTMLElementCtor) return;',\n ' if (',\n ' !(qInput instanceof HTMLInput) ||',\n ' !(stepSelect instanceof HTMLSelect) ||',\n ' !(typeSelect instanceof HTMLSelect) ||',\n ' !(workItemSelect instanceof HTMLSelect) ||',\n ' !(clearBtn instanceof HTMLButton) ||',\n ' !(listEl instanceof HTMLElementCtor)',\n ' ) {',\n ' return;',\n ' }',\n ' let events;',\n ' try {',\n ' events = JSON.parse(el.textContent || \"[]\");',\n ' } catch {',\n ' return;',\n ' }',\n ' const linkMapEl = doc.getElementById(\"__LINK_HREF_MAP__\");',\n ' let linkHrefMap = {};',\n ' if (linkMapEl && typeof linkMapEl.textContent === \"string\" && linkMapEl.textContent.trim()) {',\n ' try {',\n ' linkHrefMap = JSON.parse(linkMapEl.textContent) || {};',\n ' } catch {',\n ' linkHrefMap = {};',\n ' }',\n ' }',\n ' const safeText = (v) => (v == null ? \"\" : String(v));',\n ' const normalize = (v) => safeText(v).toLowerCase();',\n ' const getUniqueSorted = (arr) =>',\n ' Array.from(new Set(arr.filter((x) => x != null && String(x).trim() !== \"\").map(String))).sort();',\n ' const steps = getUniqueSorted(events.map((e) => e.stepId));',\n ' const types = getUniqueSorted(events.map((e) => e.type));',\n ' const workItems = getUniqueSorted(events.map((e) => e.workItemId));',\n ' const setOptions = (select, values, labelAll) => {',\n ' select.innerHTML = \"\";',\n ' const optAll = doc.createElement(\"option\");',\n ' optAll.value = \"\";',\n ' optAll.textContent = labelAll;',\n ' select.appendChild(optAll);',\n ' for (const v of values) {',\n ' const opt = doc.createElement(\"option\");',\n ' opt.value = v;',\n ' opt.textContent = v;',\n ' select.appendChild(opt);',\n ' }',\n ' };',\n ' setOptions(stepSelect, steps, \"全部 step\");',\n ' setOptions(typeSelect, types, \"全部 type\");',\n ' setOptions(workItemSelect, workItems, \"全部 workItem\");',\n ' const getQuery = () => new URLSearchParams(g.location ? g.location.search : \"\");',\n ' const applyFromUrl = () => {',\n ' const qs = getQuery();',\n ' qInput.value = safeText(qs.get(\"q\") || \"\");',\n ' stepSelect.value = safeText(qs.get(\"step\") || \"\");',\n ' typeSelect.value = safeText(qs.get(\"type\") || \"\");',\n ' workItemSelect.value = safeText(qs.get(\"workItem\") || \"\");',\n ' };',\n ' const writeUrl = () => {',\n ' if (!g.history || !g.location) return;',\n ' const qs = new URLSearchParams();',\n ' if (qInput.value.trim()) qs.set(\"q\", qInput.value.trim());',\n ' if (stepSelect.value) qs.set(\"step\", stepSelect.value);',\n ' if (typeSelect.value) qs.set(\"type\", typeSelect.value);',\n ' if (workItemSelect.value) qs.set(\"workItem\", workItemSelect.value);',\n ' const qsStr = qs.toString();',\n ' const next = qsStr ? `${g.location.pathname}?${qsStr}` : g.location.pathname;',\n ' g.history.replaceState(null, \"\", next);',\n ' };',\n ' const escapeHtml = (input) =>',\n ' safeText(input)',\n ' .replaceAll(\"&\", \"&amp;\")',\n ' .replaceAll(\"<\", \"&lt;\")',\n ' .replaceAll(\">\", \"&gt;\")',\n ' .replaceAll(\"\\\\\"\", \"&quot;\")',\n ' .replaceAll(\"\\\\\\'\", \"&#39;\");',\n ' const renderLinks = (links) => {',\n ' if (!Array.isArray(links) || links.length === 0) return \"\";',\n ' const html = links',\n ' .map((l) => {',\n ' const href = linkHrefMap && linkHrefMap[l] ? linkHrefMap[l] : l;',\n ' const safeHref = escapeHtml(href);',\n ' const label = escapeHtml(l);',\n ' return `<a href=\"${safeHref}\" target=\"_blank\" rel=\"noopener noreferrer\">${label}</a>`;',\n ' })',\n ' .join(\"\");',\n ' return `<div class=\"links\">${html}</div>`;',\n ' };',\n ' const renderData = (data) => {',\n ' if (!data) return \"\";',\n ' let json = \"\";',\n ' try {',\n ' json = JSON.stringify(data, null, 2);',\n ' } catch {',\n ' json = safeText(data);',\n ' }',\n ' return `<details><summary>data</summary><pre>${escapeHtml(json)}</pre></details>`;',\n ' };',\n ' const renderList = (items) => {',\n ' listEl.innerHTML = items',\n ' .map((item) => {',\n ' const ts = escapeHtml(item.ts);',\n ' const stepId = escapeHtml(item.stepId);',\n ' const type = escapeHtml(item.type);',\n ' const summary = escapeHtml(item.summary);',\n ' const workItem = item.workItemId ? `<span class=\"badge\">${escapeHtml(item.workItemId)}</span>` : \"\";',\n ' return [',\n ' `<div class=\"item\" data-step=\"${stepId}\" data-type=\"${type}\">`,',\n ' `<div class=\"row\">`,',\n ' `<span class=\"ts\">${ts}</span>`,',\n ' `<span class=\"badge\">${stepId}</span>`,',\n ' `<span class=\"type\">${type}</span>`,',\n ' workItem,',\n ' `</div>`,',\n ' `<div class=\"summary\">${summary}</div>`,',\n ' renderLinks(item.links),',\n ' renderData(item.data),',\n ' `</div>`,',\n ' ].join(\"\");',\n ' })',\n ' .join(\"\");',\n ' };',\n ' const applyFilters = () => {',\n ' const q = normalize(qInput.value.trim());',\n ' const step = safeText(stepSelect.value);',\n ' const type = safeText(typeSelect.value);',\n ' const workItem = safeText(workItemSelect.value);',\n ' const filtered = events.filter((e) => {',\n ' if (step && safeText(e.stepId) !== step) return false;',\n ' if (type && safeText(e.type) !== type) return false;',\n ' if (workItem && safeText(e.workItemId) !== workItem) return false;',\n ' if (!q) return true;',\n ' const hay1 = normalize(e.summary);',\n ' let hay2 = \"\";',\n ' try {',\n ' hay2 = normalize(JSON.stringify(e.data || {}));',\n ' } catch {',\n ' hay2 = normalize(String(e.data || \"\"));',\n ' }',\n ' return hay1.includes(q) || hay2.includes(q);',\n ' });',\n ' renderList(filtered);',\n ' if (metaEl) {',\n ' metaEl.textContent = `显示 ${filtered.length} / ${events.length}`;',\n ' }',\n ' writeUrl();',\n ' };',\n ' applyFromUrl();',\n ' applyFilters();',\n ' qInput.addEventListener(\"input\", applyFilters);',\n ' stepSelect.addEventListener(\"change\", applyFilters);',\n ' typeSelect.addEventListener(\"change\", applyFilters);',\n ' workItemSelect.addEventListener(\"change\", applyFilters);',\n ' clearBtn.addEventListener(\"click\", () => {',\n ' qInput.value = \"\";',\n ' stepSelect.value = \"\";',\n ' typeSelect.value = \"\";',\n ' workItemSelect.value = \"\";',\n ' applyFilters();',\n ' });',\n '})();',\n '',\n ].join('\\n');\n}\n","import { Command } from 'commander';\nimport fs from 'fs/promises';\nimport path from 'path';\nimport { loadWorkspace } from '../../core/workspace.js';\nimport { buildWorkspaceIndex } from '../../core/index/indexer.js';\nimport { listWorkspaces, registerWorkspace, unregisterWorkspace } from '../../core/index/registry.js';\n\nasync function ensureDir(dir: string): Promise<void> {\n await fs.mkdir(dir, { recursive: true });\n}\n\nexport const indexCommand = new Command('index')\n .description('生成 workspace 索引,并支持 registry 管理')\n .argument('[workspace]', 'workspace 路径', '.')\n .option('--add', '将 workspace 加入 registry')\n .option('--list', '列出 registry 中的 workspaces')\n .option('--remove <pathOrName>', '从 registry 删除 workspace(path 或 name)')\n .option('--output <file>', '输出索引文件路径(默认 <workspace>/.agenthandoff/index.json)')\n .option('--json', '以 JSON 输出结果到 stdout')\n .action(\n async (\n workspace: string,\n options: { add?: boolean; list?: boolean; remove?: string; output?: string; json?: boolean }\n ) => {\n try {\n if (options.list) {\n const items = await listWorkspaces();\n if (options.json) {\n console.log(JSON.stringify(items, null, 2));\n return;\n }\n if (items.length === 0) {\n console.log('Registry is empty');\n return;\n }\n for (const item of items) {\n console.log(`${item.name}\\t${item.path}`);\n }\n return;\n }\n\n if (options.remove) {\n await unregisterWorkspace(options.remove);\n console.log(`✅ Removed from registry: ${options.remove}`);\n return;\n }\n\n const workspacePath = path.resolve(workspace);\n const info = await loadWorkspace(workspacePath);\n if (!info.exists) {\n console.error(`Error: workspace not found: ${workspacePath}`);\n process.exit(1);\n }\n if (!info.hasWorkflow || !info.workflow) {\n console.error(`Error: workflow.yaml not found in ${workspacePath}`);\n process.exit(1);\n }\n\n if (options.add) {\n await registerWorkspace(workspacePath, info.workflow.name);\n }\n\n const index = await buildWorkspaceIndex(workspacePath);\n const outputFile = options.output\n ? path.resolve(options.output)\n : path.join(workspacePath, '.agenthandoff', 'index.json');\n\n await ensureDir(path.dirname(outputFile));\n await fs.writeFile(outputFile, JSON.stringify(index, null, 2) + '\\n', 'utf-8');\n\n if (options.json) {\n console.log(JSON.stringify(index, null, 2));\n return;\n }\n\n console.log(`✅ Indexed: ${workspacePath}`);\n console.log(` output: ${outputFile}`);\n console.log(` steps: ${index.steps.length}`);\n console.log(` artifacts: ${index.artifacts.length}`);\n console.log(` events: ${index.events.length}`);\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { loadWorkspace, fileExists } from '../workspace.js';\nimport { readEventsJsonl, toTimelineItems } from '../events-reader.js';\nimport { WorkspaceIndex, WorkspaceIndexArtifact } from './types.js';\n\nasync function readPreview(filePath: string, maxChars: number): Promise<string | undefined> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const sliced = content.slice(0, maxChars);\n return sliced;\n } catch {\n return undefined;\n }\n}\n\nasync function statInfo(filePath: string): Promise<{ bytes?: number; updatedAt?: string }> {\n try {\n const st = await fs.stat(filePath);\n return { bytes: st.size, updatedAt: st.mtime.toISOString() };\n } catch {\n return {};\n }\n}\n\nasync function addArtifact(\n workspacePath: string,\n relPath: string,\n kind: WorkspaceIndexArtifact['kind']\n): Promise<WorkspaceIndexArtifact> {\n const full = path.join(workspacePath, relPath);\n const exists = await fileExists(full);\n if (!exists) {\n return { path: relPath, kind };\n }\n\n const { bytes, updatedAt } = await statInfo(full);\n const preview = await readPreview(full, 2000);\n return { path: relPath, kind, bytes, updatedAt, ...(preview !== undefined && { preview }) };\n}\n\nexport async function buildWorkspaceIndex(workspacePath: string): Promise<WorkspaceIndex> {\n const info = await loadWorkspace(workspacePath);\n if (!info.exists) {\n throw new Error(`workspace not found: ${path.resolve(workspacePath)}`);\n }\n if (!info.hasWorkflow || !info.workflow) {\n throw new Error(`workflow.yaml not found in ${path.resolve(workspacePath)}`);\n }\n\n const abs = info.path;\n const indexedAt = new Date().toISOString();\n const workspaceName = path.basename(abs);\n\n const steps = await Promise.all(\n info.workflow.steps.map(async (step, i) => {\n const outputRel = step.output;\n const outputFull = path.join(abs, outputRel);\n const outputExists = await fileExists(outputFull);\n return { id: step.id, index: i + 1, outputPath: outputRel, outputExists };\n })\n );\n\n const artifacts: WorkspaceIndexArtifact[] = [];\n\n const briefRel = 'brief.md';\n if (await fileExists(path.join(abs, briefRel))) {\n artifacts.push(await addArtifact(abs, briefRel, 'brief'));\n }\n\n for (const step of info.workflow.steps) {\n const rel = step.output;\n artifacts.push(await addArtifact(abs, rel, 'step.output'));\n }\n\n const { events } = await readEventsJsonl({ workspacePath: abs });\n const items = toTimelineItems(events);\n const indexedEvents = items.map((item) => ({\n ts: item.ts,\n stepId: item.stepId,\n stepIndex: item.stepIndex,\n type: item.type,\n summary: item.summary,\n ...(item.workItemId && { workItemId: item.workItemId }),\n ...(item.links && item.links.length > 0 && { links: item.links }),\n }));\n\n return {\n version: 1,\n workspacePath: abs,\n workspaceName,\n indexedAt,\n workflowName: info.workflow.name,\n steps,\n artifacts,\n events: indexedEvents,\n };\n}\n\n","import fs from 'fs/promises';\nimport os from 'os';\nimport path from 'path';\n\nexport interface WorkspaceRegistryItem {\n name: string;\n path: string;\n addedAt: string;\n updatedAt: string;\n}\n\nexport interface WorkspaceRegistry {\n version: 1;\n items: WorkspaceRegistryItem[];\n}\n\nexport interface RegistryStore {\n load(): Promise<WorkspaceRegistry>;\n save(registry: WorkspaceRegistry): Promise<void>;\n}\n\nfunction getHomeDir(): string | null {\n try {\n const envHome = process.env.HOME;\n if (envHome && envHome.trim()) return envHome;\n const home = os.homedir();\n if (home && home.trim()) return home;\n return null;\n } catch {\n return null;\n }\n}\n\nfunction defaultRegistryFilePath(): string {\n const home = getHomeDir();\n const base = home ? home : process.cwd();\n return path.join(base, '.agenthandoff', 'registry.json');\n}\n\nasync function ensureParentDir(filePath: string): Promise<void> {\n await fs.mkdir(path.dirname(filePath), { recursive: true });\n}\n\nfunction normalizeRegistry(registry: unknown): WorkspaceRegistry {\n if (\n typeof registry === 'object' &&\n registry !== null &&\n 'version' in registry &&\n (registry as { version?: unknown }).version === 1 &&\n 'items' in registry &&\n Array.isArray((registry as { items?: unknown }).items)\n ) {\n const items = (registry as { items: unknown[] }).items\n .map((item) => {\n if (typeof item !== 'object' || item === null) return null;\n const obj = item as Record<string, unknown>;\n const name = typeof obj.name === 'string' ? obj.name : '';\n const itemPath = typeof obj.path === 'string' ? obj.path : '';\n const addedAt = typeof obj.addedAt === 'string' ? obj.addedAt : '';\n const updatedAt = typeof obj.updatedAt === 'string' ? obj.updatedAt : '';\n if (!name || !itemPath) return null;\n return { name, path: itemPath, addedAt, updatedAt };\n })\n .filter((x): x is WorkspaceRegistryItem => Boolean(x));\n\n return { version: 1, items };\n }\n\n return { version: 1, items: [] };\n}\n\nexport function createDefaultRegistryStore(): RegistryStore {\n const filePath = defaultRegistryFilePath();\n\n return {\n async load(): Promise<WorkspaceRegistry> {\n try {\n const raw = await fs.readFile(filePath, 'utf-8');\n const parsed = JSON.parse(raw) as unknown;\n return normalizeRegistry(parsed);\n } catch {\n return { version: 1, items: [] };\n }\n },\n async save(registry: WorkspaceRegistry): Promise<void> {\n await ensureParentDir(filePath);\n const normalized = normalizeRegistry(registry);\n await fs.writeFile(filePath, JSON.stringify(normalized, null, 2) + '\\n', 'utf-8');\n },\n };\n}\n\nfunction defaultNameForPath(workspacePath: string): string {\n const abs = path.resolve(workspacePath);\n return path.basename(abs) || abs;\n}\n\nexport async function registerWorkspace(workspacePath: string, name?: string): Promise<void> {\n const store = createDefaultRegistryStore();\n const registry = await store.load();\n const absPath = path.resolve(workspacePath);\n const now = new Date().toISOString();\n const itemName = (name && name.trim()) ? name.trim() : defaultNameForPath(absPath);\n\n const existingIndex = registry.items.findIndex((i) => path.resolve(i.path) === absPath);\n if (existingIndex >= 0) {\n const existing = registry.items[existingIndex];\n registry.items[existingIndex] = {\n ...existing,\n name: itemName,\n updatedAt: now,\n addedAt: existing.addedAt || now,\n path: absPath,\n };\n } else {\n registry.items.push({\n name: itemName,\n path: absPath,\n addedAt: now,\n updatedAt: now,\n });\n }\n\n await store.save(registry);\n}\n\nexport async function unregisterWorkspace(pathOrName: string): Promise<void> {\n const store = createDefaultRegistryStore();\n const registry = await store.load();\n const token = String(pathOrName).trim();\n if (!token) return;\n\n const abs = path.resolve(token);\n registry.items = registry.items.filter((item) => {\n const itemAbs = path.resolve(item.path);\n return itemAbs !== abs && item.name !== token;\n });\n\n await store.save(registry);\n}\n\nexport async function listWorkspaces(): Promise<WorkspaceRegistryItem[]> {\n const store = createDefaultRegistryStore();\n const registry = await store.load();\n return [...registry.items].sort((a, b) => a.name.localeCompare(b.name));\n}\n","import { Command } from 'commander';\nimport { listWorkspaces } from '../../core/index/registry.js';\nimport { search } from '../../core/search/search.js';\n\nfunction collect(value: string, previous: string[] = []): string[] {\n return previous.concat([value]);\n}\n\nexport const searchCommand = new Command('search')\n .description('在 workspace 索引上执行搜索')\n .argument('<query>', '搜索关键词')\n .option('--workspace <pathOrName>', '指定 workspace(可重复)', collect, [])\n .option('--step <id>', '筛选 stepId(可重复)', collect, [])\n .option('--type <type>', '筛选事件类型(可重复)', collect, [])\n .option('--work-item <id>', '筛选 workItemId(可重复)', collect, [])\n .option('--limit <n>', '限制结果数量', (v) => parseInt(v, 10))\n .option('--json', '以 JSON 输出结果')\n .action(\n async (\n query: string,\n options: {\n workspace?: string[];\n step?: string[];\n type?: string[];\n workItem?: string[];\n limit?: number;\n json?: boolean;\n }\n ) => {\n try {\n const registryItems = await listWorkspaces();\n const workspaces = options.workspace || [];\n const registryOnly = workspaces.length === 0;\n const results = await search(\n {\n q: query,\n workspace: workspaces,\n stepId: options.step,\n type: options.type,\n workItemId: options.workItem,\n limit: options.limit,\n },\n { targets: 'all', registryOnly }\n );\n\n if (options.json) {\n console.log(JSON.stringify(results, null, 2));\n return;\n }\n\n if (!registryOnly && registryItems.length === 0) {\n console.log('⚠️ registry 为空,使用命令行指定的 workspace');\n }\n\n if (results.length === 0) {\n console.log('未找到匹配结果');\n if (registryItems.length === 0 && registryOnly) {\n console.log('提示:请先运行 agent-handoff index --add 注册 workspace');\n }\n return;\n }\n\n for (const hit of results) {\n console.log(`${hit.workspaceName}\\t${hit.kind}\\t${hit.title}`);\n if (hit.snippet) {\n console.log(` ${hit.snippet}`);\n }\n }\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { listWorkspaces } from '../index/registry.js';\nimport { SearchHit, SearchOptions, SearchQuery } from './types.js';\n\ninterface IndexEvent {\n ts: string;\n stepId: string;\n stepIndex: number;\n type: string;\n summary: string;\n workItemId?: string;\n links?: string[];\n}\n\ninterface IndexArtifact {\n path: string;\n kind: string;\n preview?: string;\n}\n\ninterface WorkspaceIndexFile {\n version: number;\n workspacePath: string;\n workspaceName: string;\n indexedAt: string;\n workflowName?: string;\n steps?: Array<{ id: string; index: number }>;\n artifacts?: IndexArtifact[];\n events?: IndexEvent[];\n}\n\ninterface WorkspaceTarget {\n name: string;\n path: string;\n}\n\nasync function readIndexFile(workspacePath: string, indexDir?: string): Promise<WorkspaceIndexFile | null> {\n const indexFile = indexDir\n ? path.join(indexDir, 'index.json')\n : path.join(workspacePath, '.agenthandoff', 'index.json');\n try {\n const raw = await fs.readFile(indexFile, 'utf-8');\n return JSON.parse(raw) as WorkspaceIndexFile;\n } catch {\n return null;\n }\n}\n\nfunction toLower(input: string): string {\n return input.toLowerCase();\n}\n\nfunction normalizeList(values?: string[]): string[] | undefined {\n if (!values || values.length === 0) return undefined;\n return values.map((v) => v.trim()).filter((v) => v.length > 0);\n}\n\nfunction textIncludes(haystack: string, needle: string): boolean {\n return toLower(haystack).includes(needle);\n}\n\nfunction matchOptional(value: string | undefined, filter?: string[]): boolean {\n if (!filter || filter.length === 0) return true;\n if (!value) return false;\n return filter.includes(value);\n}\n\nfunction makeSnippet(text: string, q: string): string {\n const lower = toLower(text);\n const idx = lower.indexOf(q);\n if (idx < 0) {\n return text.length > 160 ? text.slice(0, 160) : text;\n }\n const start = Math.max(0, idx - 40);\n const end = Math.min(text.length, idx + q.length + 80);\n return text.slice(start, end);\n}\n\nfunction scoreHit(hit: SearchHit): number {\n return hit.score;\n}\n\nasync function resolveTargets(query: SearchQuery, options: SearchOptions): Promise<WorkspaceTarget[]> {\n const workspaceFilters = normalizeList(query.workspace);\n const registryItems = options.registryOnly ? await listWorkspaces() : [];\n const targets: WorkspaceTarget[] = [];\n\n if (registryItems.length > 0) {\n for (const item of registryItems) {\n if (!workspaceFilters || workspaceFilters.includes(item.name) || workspaceFilters.includes(item.path)) {\n targets.push({ name: item.name, path: item.path });\n }\n }\n }\n\n if (!options.registryOnly && workspaceFilters && workspaceFilters.length > 0) {\n for (const token of workspaceFilters) {\n const exists = targets.some((t) => t.path === token || t.name === token);\n if (!exists) {\n targets.push({ name: path.basename(token), path: token });\n }\n }\n }\n\n return targets;\n}\n\nexport async function search(query: SearchQuery, options: SearchOptions): Promise<SearchHit[]> {\n const q = query.q.trim();\n const qLower = toLower(q);\n const stepFilter = normalizeList(query.stepId);\n const typeFilter = normalizeList(query.type);\n const workItemFilter = normalizeList(query.workItemId);\n const limit = query.limit && query.limit > 0 ? query.limit : undefined;\n\n const targets = await resolveTargets(query, options);\n const hits: SearchHit[] = [];\n\n for (const target of targets) {\n const index = await readIndexFile(target.path, options.indexDir);\n if (!index) {\n continue;\n }\n const workspaceName = index.workspaceName || target.name;\n const workspacePath = index.workspacePath || target.path;\n\n if (options.targets === 'events' || options.targets === 'all') {\n const events = index.events || [];\n for (const event of events) {\n if (!matchOptional(event.stepId, stepFilter)) continue;\n if (!matchOptional(event.type, typeFilter)) continue;\n if (!matchOptional(event.workItemId, workItemFilter)) continue;\n if (!textIncludes(event.summary || '', qLower)) continue;\n\n hits.push({\n workspaceName,\n workspacePath,\n kind: 'event',\n score: 1,\n title: `${event.type} · ${event.stepId}`,\n snippet: makeSnippet(event.summary || '', qLower),\n meta: {\n ts: event.ts,\n stepId: event.stepId,\n stepIndex: event.stepIndex,\n type: event.type,\n workItemId: event.workItemId,\n },\n });\n }\n }\n\n if (options.targets === 'artifacts' || options.targets === 'all') {\n const artifacts = index.artifacts || [];\n for (const artifact of artifacts) {\n const preview = artifact.preview || '';\n if (!textIncludes(preview, qLower)) continue;\n hits.push({\n workspaceName,\n workspacePath,\n kind: 'artifact',\n score: 1,\n title: artifact.path,\n snippet: makeSnippet(preview, qLower),\n link: artifact.path,\n meta: {\n path: artifact.path,\n kind: artifact.kind,\n },\n });\n }\n }\n }\n\n hits.sort((a, b) => {\n const scoreDiff = scoreHit(b) - scoreHit(a);\n if (scoreDiff !== 0) return scoreDiff;\n const aTs = typeof a.meta.ts === 'string' ? a.meta.ts : '';\n const bTs = typeof b.meta.ts === 'string' ? b.meta.ts : '';\n return bTs.localeCompare(aTs);\n });\n\n return limit ? hits.slice(0, limit) : hits;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { listWorkspaces } from '../../core/index/registry.js';\nimport { diffWorkspaces, formatDiffResult } from '../../core/diff/diff.js';\n\nfunction collect(value: string, previous: string[] = []): string[] {\n return previous.concat([value]);\n}\n\nasync function resolveWorkspaceToken(token: string): Promise<string> {\n const resolved = path.resolve(token);\n const items = await listWorkspaces().catch(() => []);\n const byName = items.find((i) => i.name === token);\n if (byName) return byName.path;\n return resolved;\n}\n\nexport const diffCommand = new Command('diff')\n .description('对两个 workspace 进行 diff(基于 index.json)')\n .argument('<left>', '左侧 workspace(path 或 registry name)')\n .argument('<right>', '右侧 workspace(path 或 registry name)')\n .option('--format <format>', '输出格式:text|markdown|json', 'text')\n .option('--path <path>', '仅对指定文件做 diff(可重复)', collect, [])\n .option('--context <n>', 'diff context 行数', (v) => parseInt(v, 10))\n .action(\n async (\n left: string,\n right: string,\n options: { format: string; path?: string[]; context?: number }\n ) => {\n try {\n const leftPath = await resolveWorkspaceToken(left);\n const rightPath = await resolveWorkspaceToken(right);\n const format = options.format === 'markdown' || options.format === 'json' ? options.format : 'text';\n const paths = options.path && options.path.length > 0 ? options.path : undefined;\n\n const result = await diffWorkspaces({\n leftWorkspace: leftPath,\n rightWorkspace: rightPath,\n format,\n paths,\n contextLines: options.context,\n });\n\n if (format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(formatDiffResult(result, format));\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { DiffOptions, DiffResult } from './types.js';\n\ninterface WorkspaceIndexFile {\n version: number;\n workspacePath: string;\n workspaceName: string;\n indexedAt: string;\n workflowName?: string;\n steps?: Array<{ id: string; index: number; outputPath?: string; outputExists?: boolean }>;\n artifacts?: Array<{ path: string; kind: string }>;\n events?: Array<{ ts: string; summary: string }>;\n}\n\nasync function readIndex(workspacePath: string): Promise<WorkspaceIndexFile> {\n const abs = path.resolve(workspacePath);\n const indexPath = path.join(abs, '.agenthandoff', 'index.json');\n try {\n const raw = await fs.readFile(indexPath, 'utf-8');\n return JSON.parse(raw) as WorkspaceIndexFile;\n } catch {\n throw new Error(`index not found: ${indexPath}. 请先运行 agent-handoff index`);\n }\n}\n\nasync function readTextFile(filePath: string): Promise<string | null> {\n try {\n return await fs.readFile(filePath, 'utf-8');\n } catch {\n return null;\n }\n}\n\nfunction uniqueSorted(values: string[]): string[] {\n return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));\n}\n\nfunction defaultArtifactPaths(index: WorkspaceIndexFile): string[] {\n const artifacts = index.artifacts || [];\n const paths = artifacts.map((a) => a.path);\n return paths.filter((p) => p === 'brief.md' || /^steps\\/[^/]+\\/output\\.md$/.test(p));\n}\n\ntype Op = { t: 'equal' | 'add' | 'del'; line: string };\n\nfunction buildLcsOps(a: string[], b: string[]): Op[] {\n const n = a.length;\n const m = b.length;\n const dp: number[][] = Array.from({ length: n + 1 }, () => new Array<number>(m + 1).fill(0));\n\n for (let i = n - 1; i >= 0; i--) {\n for (let j = m - 1; j >= 0; j--) {\n dp[i][j] = a[i] === b[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);\n }\n }\n\n const ops: Op[] = [];\n let i = 0;\n let j = 0;\n while (i < n && j < m) {\n if (a[i] === b[j]) {\n ops.push({ t: 'equal', line: a[i] });\n i++;\n j++;\n } else if (dp[i + 1][j] >= dp[i][j + 1]) {\n ops.push({ t: 'del', line: a[i] });\n i++;\n } else {\n ops.push({ t: 'add', line: b[j] });\n j++;\n }\n }\n while (i < n) {\n ops.push({ t: 'del', line: a[i] });\n i++;\n }\n while (j < m) {\n ops.push({ t: 'add', line: b[j] });\n j++;\n }\n return ops;\n}\n\nfunction formatUnifiedDiff(filePath: string, left: string | null, right: string | null, contextLines: number): string {\n const leftLines = (left ?? '').split('\\n');\n const rightLines = (right ?? '').split('\\n');\n const ops = buildLcsOps(leftLines, rightLines);\n\n const lines: string[] = [];\n lines.push(`--- a/${filePath}`);\n lines.push(`+++ b/${filePath}`);\n\n let aLine = 1;\n let bLine = 1;\n let i = 0;\n\n const consumeEqual = (count: number): void => {\n for (let k = 0; k < count && i < ops.length; k++) {\n const op = ops[i];\n if (op.t !== 'equal') break;\n aLine++;\n bLine++;\n i++;\n }\n };\n\n while (i < ops.length) {\n while (i < ops.length && ops[i].t === 'equal') {\n i++;\n aLine++;\n bLine++;\n }\n if (i >= ops.length) break;\n\n const hunkStart = Math.max(0, i - contextLines);\n let hunkEnd = i;\n let trailingContext = 0;\n while (hunkEnd < ops.length) {\n if (ops[hunkEnd].t === 'equal') {\n trailingContext++;\n if (trailingContext > contextLines) break;\n } else {\n trailingContext = 0;\n }\n hunkEnd++;\n }\n\n let aStart = aLine;\n let bStart = bLine;\n for (let k = i - 1; k >= hunkStart; k--) {\n const op = ops[k];\n if (op.t === 'equal' || op.t === 'del') aStart--;\n if (op.t === 'equal' || op.t === 'add') bStart--;\n }\n\n let aLen = 0;\n let bLen = 0;\n for (let k = hunkStart; k < hunkEnd; k++) {\n const op = ops[k];\n if (op.t === 'equal' || op.t === 'del') aLen++;\n if (op.t === 'equal' || op.t === 'add') bLen++;\n }\n\n lines.push(`@@ -${aStart},${aLen} +${bStart},${bLen} @@`);\n\n for (let k = hunkStart; k < hunkEnd; k++) {\n const op = ops[k];\n if (op.t === 'equal') lines.push(` ${op.line}`);\n if (op.t === 'del') lines.push(`-${op.line}`);\n if (op.t === 'add') lines.push(`+${op.line}`);\n }\n\n i = hunkEnd;\n consumeEqual(contextLines);\n }\n\n return lines.join('\\n');\n}\n\nfunction diffWorkflow(left: WorkspaceIndexFile, right: WorkspaceIndexFile): { changed: boolean; details?: string; changedSteps: number } {\n const leftSteps = left.steps || [];\n const rightSteps = right.steps || [];\n const leftIds = leftSteps.map((s) => s.id);\n const rightIds = rightSteps.map((s) => s.id);\n\n const leftSet = new Set(leftIds);\n const rightSet = new Set(rightIds);\n\n const added = rightIds.filter((id) => !leftSet.has(id));\n const removed = leftIds.filter((id) => !rightSet.has(id));\n\n let changedSteps = 0;\n const maxLen = Math.max(leftIds.length, rightIds.length);\n for (let i = 0; i < maxLen; i++) {\n if (leftIds[i] !== rightIds[i]) changedSteps++;\n }\n\n const orderChanged = added.length === 0 && removed.length === 0 && leftIds.join('|') !== rightIds.join('|');\n const changed = added.length > 0 || removed.length > 0 || orderChanged;\n\n if (!changed) {\n return { changed: false, changedSteps: 0 };\n }\n\n const parts: string[] = [];\n if (added.length > 0) parts.push(`added: ${added.join(', ')}`);\n if (removed.length > 0) parts.push(`removed: ${removed.join(', ')}`);\n if (orderChanged) parts.push('order: changed');\n return { changed: true, details: parts.join('\\n'), changedSteps };\n}\n\nfunction diffEvents(left: WorkspaceIndexFile, right: WorkspaceIndexFile): DiffResult['events'] {\n const leftEvents = left.events || [];\n const rightEvents = right.events || [];\n const leftCount = leftEvents.length;\n const rightCount = rightEvents.length;\n const added = rightCount > leftCount ? rightCount - leftCount : 0;\n const latest = rightEvents[rightEvents.length - 1];\n return {\n leftCount,\n rightCount,\n added,\n ...(latest ? { latestRight: { ts: latest.ts, summary: latest.summary } } : {}),\n };\n}\n\nexport async function diffWorkspaces(options: DiffOptions): Promise<DiffResult> {\n const leftWs = path.resolve(options.leftWorkspace);\n const rightWs = path.resolve(options.rightWorkspace);\n\n const leftIndex = await readIndex(leftWs);\n const rightIndex = await readIndex(rightWs);\n\n const contextLines = typeof options.contextLines === 'number' && options.contextLines >= 0 ? options.contextLines : 3;\n\n const requestedPaths = options.paths && options.paths.length > 0 ? options.paths : undefined;\n const leftPaths = requestedPaths ? requestedPaths : defaultArtifactPaths(leftIndex);\n const rightPaths = requestedPaths ? requestedPaths : defaultArtifactPaths(rightIndex);\n const paths = uniqueSorted([...leftPaths, ...rightPaths]);\n\n const results: DiffResult['artifacts'] = [];\n let addedArtifacts = 0;\n let removedArtifacts = 0;\n let changedArtifacts = 0;\n\n for (const rel of paths) {\n const leftText = await readTextFile(path.join(leftWs, rel));\n const rightText = await readTextFile(path.join(rightWs, rel));\n if (leftText === null && rightText === null) {\n continue;\n }\n\n if (leftText === null && rightText !== null) {\n addedArtifacts++;\n const diff = formatUnifiedDiff(rel, '', rightText, contextLines);\n results.push({ path: rel, status: 'added', diff });\n continue;\n }\n\n if (leftText !== null && rightText === null) {\n removedArtifacts++;\n const diff = formatUnifiedDiff(rel, leftText, '', contextLines);\n results.push({ path: rel, status: 'removed', diff });\n continue;\n }\n\n if (leftText !== rightText) {\n changedArtifacts++;\n const diff = formatUnifiedDiff(rel, leftText, rightText, contextLines);\n results.push({ path: rel, status: 'changed', diff });\n continue;\n }\n\n results.push({ path: rel, status: 'unchanged' });\n }\n\n const wf = diffWorkflow(leftIndex, rightIndex);\n const summary = {\n left: { name: leftIndex.workspaceName, path: leftWs },\n right: { name: rightIndex.workspaceName, path: rightWs },\n changedArtifacts,\n addedArtifacts,\n removedArtifacts,\n changedSteps: wf.changedSteps,\n };\n\n return {\n summary,\n artifacts: results.sort((a, b) => a.path.localeCompare(b.path)),\n workflow: wf.changed ? { changed: true, details: wf.details } : { changed: false },\n events: diffEvents(leftIndex, rightIndex),\n };\n}\n\nexport function formatDiffResult(result: DiffResult, format: 'text' | 'markdown'): string {\n const lines: string[] = [];\n const s = result.summary;\n lines.push(`left: ${s.left.name}\\t${s.left.path}`);\n lines.push(`right: ${s.right.name}\\t${s.right.path}`);\n lines.push(\n `artifacts: changed=${s.changedArtifacts} added=${s.addedArtifacts} removed=${s.removedArtifacts} stepsChanged=${s.changedSteps}`\n );\n\n if (result.workflow?.changed) {\n lines.push('');\n lines.push('workflow: changed');\n if (result.workflow.details) lines.push(result.workflow.details);\n }\n\n if (result.events) {\n lines.push('');\n lines.push(`events: left=${result.events.leftCount} right=${result.events.rightCount} added=${result.events.added}`);\n if (result.events.latestRight) {\n lines.push(`latest: ${result.events.latestRight.ts}\\t${result.events.latestRight.summary}`);\n }\n }\n\n for (const a of result.artifacts) {\n if (a.status === 'unchanged') continue;\n lines.push('');\n lines.push(`${a.status}: ${a.path}`);\n if (a.diff) {\n if (format === 'markdown') {\n lines.push('```diff');\n lines.push(a.diff);\n lines.push('```');\n } else {\n lines.push(a.diff);\n }\n }\n }\n\n return lines.join('\\n');\n}\n\n","import { Command } from 'commander';\nimport path from 'path';\nimport { listWorkspaces } from '../../core/index/registry.js';\nimport { buildStats } from '../../core/stats/stats.js';\n\nfunction isValidFormat(value: string): value is 'json' | 'markdown' {\n return value === 'json' || value === 'markdown';\n}\n\nasync function resolveWorkspaceToken(token: string): Promise<string> {\n const resolved = path.resolve(token);\n const items = await listWorkspaces().catch(() => []);\n const byName = items.find((i) => i.name === token);\n return byName ? byName.path : resolved;\n}\n\nfunction formatMarkdown(result: Awaited<ReturnType<typeof buildStats>>): string {\n const lines: string[] = [];\n lines.push('| Workspace | Steps | Events | Automation |');\n lines.push('|---|---|---|---|');\n for (const ws of result.workspaces) {\n const steps = `${ws.stepsDone}/${ws.stepsTotal}`;\n const events = `${ws.eventsTotal}`;\n const automation = `${ws.automation?.sessions ?? 0}`;\n lines.push(`| ${ws.workspaceName} | ${steps} | ${events} | ${automation} |`);\n }\n if (result.workspaces.length === 0) {\n lines.push('| - | - | - | - |');\n }\n return lines.join('\\n');\n}\n\nexport const statsCommand = new Command('stats')\n .description('输出 workspace 统计信息')\n .argument('[workspaces...]', 'workspace 路径或 registry name')\n .option('--registry', '统计 registry 中所有 workspace')\n .option('--mode <mode>', 'summary|full', 'summary')\n .option('--format <format>', 'json|markdown', 'markdown')\n .action(\n async (\n workspaces: string[],\n options: { registry?: boolean; mode: string; format: string }\n ) => {\n try {\n const mode = options.mode === 'full' ? 'full' : 'summary';\n const format = isValidFormat(options.format) ? options.format : 'markdown';\n let targets: string[] = [];\n\n if (options.registry) {\n const items = await listWorkspaces();\n targets = items.map((i) => i.path);\n } else if (workspaces.length > 0) {\n targets = await Promise.all(workspaces.map(resolveWorkspaceToken));\n }\n\n if (targets.length === 0) {\n console.log('未找到可统计的 workspace');\n return;\n }\n\n const result = await buildStats({ workspaces: targets, mode });\n\n if (format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n return;\n }\n\n console.log(formatMarkdown(result));\n } catch (error) {\n console.error(`Error: ${error}`);\n process.exit(1);\n }\n }\n );\n\n","import fs from 'fs/promises';\nimport path from 'path';\nimport { StatsQuery, StatsResult, WorkspaceStats } from './types.js';\n\ninterface IndexEvent {\n ts: string;\n stepId?: string;\n type?: string;\n summary?: string;\n}\n\ninterface WorkspaceIndexFile {\n version: number;\n workspacePath: string;\n workspaceName: string;\n indexedAt: string;\n steps?: Array<{ id: string; index: number; outputExists?: boolean }>;\n events?: IndexEvent[];\n}\n\nasync function readIndex(workspacePath: string): Promise<WorkspaceIndexFile | null> {\n const abs = path.resolve(workspacePath);\n const indexPath = path.join(abs, '.agenthandoff', 'index.json');\n try {\n const raw = await fs.readFile(indexPath, 'utf-8');\n return JSON.parse(raw) as WorkspaceIndexFile;\n } catch {\n return null;\n }\n}\n\nfunction countEventsByType(events: IndexEvent[]): Record<string, number> {\n const counts: Record<string, number> = {};\n for (const ev of events) {\n const type = ev.type || 'unknown';\n counts[type] = (counts[type] || 0) + 1;\n }\n return counts;\n}\n\nfunction buildDurations(events: IndexEvent[]): Array<{\n stepId: string;\n startedAt?: string;\n doneAt?: string;\n durationMs?: number;\n}> {\n const map = new Map<string, { startedAt?: string; doneAt?: string }>();\n for (const ev of events) {\n if (!ev.stepId || !ev.type || !ev.ts) continue;\n const key = ev.stepId;\n const current = map.get(key) || {};\n if (ev.type === 'step.started') {\n if (!current.startedAt || ev.ts < current.startedAt) current.startedAt = ev.ts;\n }\n if (ev.type === 'step.done') {\n if (!current.doneAt || ev.ts > current.doneAt) current.doneAt = ev.ts;\n }\n map.set(key, current);\n }\n\n const items: Array<{ stepId: string; startedAt?: string; doneAt?: string; durationMs?: number }> = [];\n for (const [stepId, v] of map.entries()) {\n let durationMs: number | undefined;\n if (v.startedAt && v.doneAt) {\n const start = new Date(v.startedAt).getTime();\n const end = new Date(v.doneAt).getTime();\n if (!Number.isNaN(start) && !Number.isNaN(end) && end >= start) {\n durationMs = end - start;\n }\n }\n items.push({ stepId, startedAt: v.startedAt, doneAt: v.doneAt, ...(durationMs !== undefined && { durationMs }) });\n }\n\n return items.sort((a, b) => a.stepId.localeCompare(b.stepId));\n}\n\nfunction buildWorkspaceStats(index: WorkspaceIndexFile, mode: 'summary' | 'full'): WorkspaceStats {\n const steps = index.steps || [];\n const stepsTotal = steps.length;\n const stepsDone = steps.filter((s) => Boolean(s.outputExists)).length;\n const events = index.events || [];\n const eventsTotal = events.length;\n const eventsByType = countEventsByType(events);\n const automationSessions = events.filter((e) => e.type === 'automation.session').length;\n\n const stats: WorkspaceStats = {\n workspaceName: index.workspaceName,\n workspacePath: index.workspacePath,\n indexedAt: index.indexedAt,\n stepsTotal,\n stepsDone,\n eventsTotal,\n eventsByType,\n automation: {\n sessions: automationSessions,\n summary: {},\n },\n };\n\n if (mode === 'full') {\n stats.durations = buildDurations(events);\n }\n\n return stats;\n}\n\nexport async function buildStats(query: StatsQuery): Promise<StatsResult> {\n const workspaces = query.workspaces || [];\n const results: WorkspaceStats[] = [];\n\n for (const ws of workspaces) {\n const index = await readIndex(ws);\n if (!index) continue;\n results.push(buildWorkspaceStats(index, query.mode));\n }\n\n return {\n generatedAt: new Date().toISOString(),\n workspaces: results,\n };\n}\n"],"mappings":"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CA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,eAAuB;AAC9B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;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","names":["Command","Command","path","fs","path","fs","path","fs","Command","path","Command","path","fs","path","Command","path","Command","path","fs","path","fs","path","Command","path","Command","path","fs","Command","path","fs","Command","os","fs","path","path","fs","Command","os","Command","fs","path","fs","Command","path","fs","Command","path","fs","path","fs","path","escapeHtml","fs","path","Command","path","Command","fs","path","fs","path","fs","path","fs","os","path","ensureDir","fs","Command","path","Command","fs","path","path","fs","Command","Command","path","fs","path","i","j","collect","path","Command","Command","path","fs","path","readIndex","resolveWorkspaceToken","path","Command","require","Command"]}