@xdevops/issue-auto-finish 1.0.2 → 1.0.4
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/KnowledgeAnalyzer-EZSJT2MJ.js +13 -0
- package/dist/KnowledgeAnalyzer-EZSJT2MJ.js.map +1 -0
- package/dist/KnowledgeStore-4ROC6F56.js +10 -0
- package/dist/KnowledgeStore-4ROC6F56.js.map +1 -0
- package/dist/ai-runner/AIRunner.d.ts +2 -0
- package/dist/ai-runner/AIRunner.d.ts.map +1 -1
- package/dist/ai-runner/BaseAIRunner.d.ts +9 -0
- package/dist/ai-runner/BaseAIRunner.d.ts.map +1 -1
- package/dist/ai-runner-RGAJPOOW.js +16 -0
- package/dist/ai-runner-RGAJPOOW.js.map +1 -0
- package/dist/analyze-ONQDTYCN.js +72 -0
- package/dist/analyze-ONQDTYCN.js.map +1 -0
- package/dist/chunk-3JUHZGX5.js +171 -0
- package/dist/chunk-3JUHZGX5.js.map +1 -0
- package/dist/chunk-5JYCGAU3.js +318 -0
- package/dist/chunk-5JYCGAU3.js.map +1 -0
- package/dist/chunk-5VUB3UUK.js +643 -0
- package/dist/chunk-5VUB3UUK.js.map +1 -0
- package/dist/{chunk-OWVT3Z34.js → chunk-JFYAXNNS.js} +121 -31
- package/dist/chunk-JFYAXNNS.js.map +1 -0
- package/dist/chunk-MH6LHFPB.js +188 -0
- package/dist/chunk-MH6LHFPB.js.map +1 -0
- package/dist/{chunk-TBIEB3JY.js → chunk-N5YK6YVI.js} +592 -767
- package/dist/chunk-N5YK6YVI.js.map +1 -0
- package/dist/{chunk-RIUI4ROA.js → chunk-PECYMYAK.js} +2 -2
- package/dist/{chunk-I3T573SU.js → chunk-PTIL5AY2.js} +65 -2
- package/dist/chunk-PTIL5AY2.js.map +1 -0
- package/dist/chunk-SWG2Y7YX.js +410 -0
- package/dist/chunk-SWG2Y7YX.js.map +1 -0
- package/dist/chunk-TZ6C7HL5.js +59 -0
- package/dist/chunk-TZ6C7HL5.js.map +1 -0
- package/dist/{chunk-IDUKWCC2.js → chunk-VFQYIC6L.js} +1151 -80
- package/dist/chunk-VFQYIC6L.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +8 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli.js +67 -3
- package/dist/cli.js.map +1 -1
- package/dist/clients/GongfengClient.d.ts +5 -0
- package/dist/clients/GongfengClient.d.ts.map +1 -1
- package/dist/config-6GFBDMGD.js +7 -0
- package/dist/config-6GFBDMGD.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/{doctor-B26Q6JWI.js → doctor-ZPGIBA5N.js} +3 -3
- package/dist/events/EventBus.d.ts +1 -1
- package/dist/events/EventBus.d.ts.map +1 -1
- package/dist/git/GitOperations.d.ts +12 -0
- package/dist/git/GitOperations.d.ts.map +1 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -5
- package/dist/{init-L3VIWCOV.js → init-QDTII4SP.js} +10 -5
- package/dist/init-QDTII4SP.js.map +1 -0
- package/dist/knowledge/KnowledgeAnalyzer.d.ts +31 -0
- package/dist/knowledge/KnowledgeAnalyzer.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeDefaults.d.ts +7 -0
- package/dist/knowledge/KnowledgeDefaults.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeEntry.d.ts +30 -0
- package/dist/knowledge/KnowledgeEntry.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeLoader.d.ts +18 -0
- package/dist/knowledge/KnowledgeLoader.d.ts.map +1 -0
- package/dist/knowledge/KnowledgeStore.d.ts +35 -0
- package/dist/knowledge/KnowledgeStore.d.ts.map +1 -0
- package/dist/knowledge/ProjectKnowledge.d.ts +79 -0
- package/dist/knowledge/ProjectKnowledge.d.ts.map +1 -0
- package/dist/knowledge/analyze-prompt.d.ts +2 -0
- package/dist/knowledge/analyze-prompt.d.ts.map +1 -0
- package/dist/knowledge/importers/GongfengExtractor.d.ts +27 -0
- package/dist/knowledge/importers/GongfengExtractor.d.ts.map +1 -0
- package/dist/knowledge/importers/IwikiImporter.d.ts +21 -0
- package/dist/knowledge/importers/IwikiImporter.d.ts.map +1 -0
- package/dist/knowledge/index.d.ts +12 -0
- package/dist/knowledge/index.d.ts.map +1 -0
- package/dist/lib.js +19 -10
- package/dist/orchestrator/PipelineOrchestrator.d.ts +5 -1
- package/dist/orchestrator/PipelineOrchestrator.d.ts.map +1 -1
- package/dist/phases/BasePhase.d.ts.map +1 -1
- package/dist/poller/IssuePoller.d.ts +5 -0
- package/dist/poller/IssuePoller.d.ts.map +1 -1
- package/dist/prompts/chat-templates.d.ts +4 -0
- package/dist/prompts/chat-templates.d.ts.map +1 -0
- package/dist/prompts/templates.d.ts +11 -0
- package/dist/prompts/templates.d.ts.map +1 -1
- package/dist/rules/RuleResolver.d.ts +4 -0
- package/dist/rules/RuleResolver.d.ts.map +1 -1
- package/dist/run.js +11 -5
- package/dist/run.js.map +1 -1
- package/dist/services/ChatService.d.ts +39 -0
- package/dist/services/ChatService.d.ts.map +1 -0
- package/dist/shutdown/ShutdownSignal.d.ts +3 -0
- package/dist/shutdown/ShutdownSignal.d.ts.map +1 -0
- package/dist/{start-TVN4SS6E.js → start-EDOZC5WL.js} +1 -1
- package/dist/tracker/IssueState.d.ts +1 -0
- package/dist/tracker/IssueState.d.ts.map +1 -1
- package/dist/tracker/IssueTracker.d.ts +2 -0
- package/dist/tracker/IssueTracker.d.ts.map +1 -1
- package/dist/updater/AutoUpdater.d.ts +33 -0
- package/dist/updater/AutoUpdater.d.ts.map +1 -0
- package/dist/updater/UpdateExecutor.d.ts +7 -0
- package/dist/updater/UpdateExecutor.d.ts.map +1 -0
- package/dist/updater/VersionChecker.d.ts +22 -0
- package/dist/updater/VersionChecker.d.ts.map +1 -0
- package/dist/web/WebServer.d.ts +4 -0
- package/dist/web/WebServer.d.ts.map +1 -1
- package/dist/web/routes/api.d.ts +4 -0
- package/dist/web/routes/api.d.ts.map +1 -1
- package/dist/web/routes/chat.d.ts +7 -0
- package/dist/web/routes/chat.d.ts.map +1 -0
- package/dist/web/routes/knowledge.d.ts +13 -0
- package/dist/web/routes/knowledge.d.ts.map +1 -0
- package/dist/web/routes/setup.d.ts.map +1 -1
- package/dist/webhook/CommandExecutor.d.ts +4 -0
- package/dist/webhook/CommandExecutor.d.ts.map +1 -1
- package/dist/webhook/CommandParser.d.ts +2 -2
- package/dist/webhook/CommandParser.d.ts.map +1 -1
- package/dist/webhook/WebhookHandler.d.ts +8 -0
- package/dist/webhook/WebhookHandler.d.ts.map +1 -1
- package/dist/webhook/WebhookServer.d.ts +2 -0
- package/dist/webhook/WebhookServer.d.ts.map +1 -1
- package/package.json +4 -2
- package/src/web/frontend/dist/assets/index-AcJ0lPIv.js +67 -0
- package/src/web/frontend/dist/assets/index-BbRt5BAr.css +1 -0
- package/src/web/frontend/dist/index.html +2 -2
- package/dist/chunk-I3T573SU.js.map +0 -1
- package/dist/chunk-IDUKWCC2.js.map +0 -1
- package/dist/chunk-OWVT3Z34.js.map +0 -1
- package/dist/chunk-TBIEB3JY.js.map +0 -1
- package/dist/init-L3VIWCOV.js.map +0 -1
- package/src/web/frontend/dist/assets/index-CQdlU9PE.js +0 -65
- package/src/web/frontend/dist/assets/index-CgMEkyZJ.css +0 -1
- /package/dist/{chunk-RIUI4ROA.js.map → chunk-PECYMYAK.js.map} +0 -0
- /package/dist/{doctor-B26Q6JWI.js.map → doctor-ZPGIBA5N.js.map} +0 -0
- /package/dist/{start-TVN4SS6E.js.map → start-EDOZC5WL.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/supplement/SupplementStore.ts","../src/poller/IssuePoller.ts","../src/web/WebServer.ts","../src/web/routes/api.ts","../src/web/routes/brainstorm.ts","../src/web/routes/chat.ts","../src/web/routes/knowledge.ts","../src/services/ChatService.ts","../src/prompts/chat-templates.ts","../src/webhook/WebhookServer.ts","../src/webhook/WebhookHandler.ts","../src/webhook/CommandParser.ts","../src/webhook/CommandExecutor.ts","../src/webhook/NoteDeduplicator.ts","../src/webhook/IntentRecognizer.ts","../src/web/AgentLogStore.ts","../src/updater/VersionChecker.ts","../src/updater/UpdateExecutor.ts","../src/updater/AutoUpdater.ts","../src/index.ts"],"sourcesContent":["import fs from 'node:fs';\nimport path from 'node:path';\nimport { logger as rootLogger } from '../logger.js';\n\nconst logger = rootLogger.child('SupplementStore');\n\nexport interface SupplementInfo {\n requirements: string;\n acceptanceCriteria: string;\n scope: string;\n constraints: string;\n references: string;\n freeText: string;\n tapdId: string;\n updatedAt: string;\n}\n\nexport class SupplementStore {\n private dir: string;\n\n constructor(dataDir: string) {\n this.dir = path.join(dataDir, 'supplements');\n }\n\n private filePath(issueIid: number): string {\n return path.join(this.dir, `${issueIid}.json`);\n }\n\n private ensureDir(): void {\n if (!fs.existsSync(this.dir)) {\n fs.mkdirSync(this.dir, { recursive: true });\n }\n }\n\n get(issueIid: number): SupplementInfo | null {\n const fp = this.filePath(issueIid);\n if (!fs.existsSync(fp)) return null;\n try {\n const raw = fs.readFileSync(fp, 'utf-8');\n return JSON.parse(raw) as SupplementInfo;\n } catch (err) {\n logger.error('Failed to read supplement', { issueIid, error: (err as Error).message });\n return null;\n }\n }\n\n save(issueIid: number, data: Omit<SupplementInfo, 'updatedAt'>): SupplementInfo {\n this.ensureDir();\n const info: SupplementInfo = {\n ...data,\n updatedAt: new Date().toISOString(),\n };\n fs.writeFileSync(this.filePath(issueIid), JSON.stringify(info, null, 2), 'utf-8');\n logger.info('Supplement saved', { issueIid });\n return info;\n }\n\n delete(issueIid: number): boolean {\n const fp = this.filePath(issueIid);\n if (!fs.existsSync(fp)) return false;\n try {\n fs.unlinkSync(fp);\n logger.info('Supplement deleted', { issueIid });\n return true;\n } catch {\n return false;\n }\n }\n\n toPromptText(issueIid: number): string {\n const info = this.get(issueIid);\n if (!info) return '';\n\n const sections: string[] = [];\n\n if (info.requirements.trim()) {\n sections.push(`### 补充需求说明\\n${info.requirements.trim()}`);\n }\n if (info.acceptanceCriteria.trim()) {\n sections.push(`### 验收标准\\n${info.acceptanceCriteria.trim()}`);\n }\n if (info.scope.trim()) {\n sections.push(`### 变更范围\\n${info.scope.trim()}`);\n }\n if (info.constraints.trim()) {\n sections.push(`### 约束条件\\n${info.constraints.trim()}`);\n }\n if (info.references.trim()) {\n sections.push(`### 参考链接\\n${info.references.trim()}`);\n }\n if (info.freeText.trim()) {\n sections.push(`### 其他补充\\n${info.freeText.trim()}`);\n }\n\n if (sections.length === 0) return '';\n return `## 补充信息\\n\\n${sections.join('\\n\\n')}`;\n }\n}\n","import { Config } from '../config.js';\nimport { GongfengClient, GongfengIssue } from '../clients/GongfengClient.js';\nimport { IssueTracker } from '../tracker/IssueTracker.js';\nimport { IssueRecord, IssueState } from '../tracker/IssueState.js';\nimport { PipelineOrchestrator } from '../orchestrator/PipelineOrchestrator.js';\nimport { isShuttingDown } from '../shutdown/ShutdownSignal.js';\nimport { eventBus } from '../events/EventBus.js';\nimport { logger as rootLogger } from '../logger.js';\nimport { t } from '../i18n/index.js';\n\nconst logger = rootLogger.child('IssuePoller');\n\nconst AUTO_FINISH_LABEL = 'auto-finish';\nconst AUTO_APPROVE_CHECK_INTERVAL_MS = 30_000;\n\nexport class IssuePoller {\n private config: Config;\n private gongfeng: GongfengClient;\n private tracker: IssueTracker;\n private orchestrator: PipelineOrchestrator;\n private discoveryTimer: ReturnType<typeof setInterval> | null = null;\n private driveTimer: ReturnType<typeof setInterval> | null = null;\n private activeIssues = new Set<number>();\n private lastAutoApproveCheckMs = 0;\n private discoveryPaused = false;\n\n constructor(\n config: Config,\n gongfeng: GongfengClient,\n tracker: IssueTracker,\n orchestrator: PipelineOrchestrator,\n ) {\n this.config = config;\n this.gongfeng = gongfeng;\n this.tracker = tracker;\n this.orchestrator = orchestrator;\n }\n\n start(): void {\n const { discoveryIntervalMs, driveIntervalMs } = this.config.poll;\n logger.info('Issue poller starting', { discoveryIntervalMs, driveIntervalMs });\n\n this.discover();\n this.drive();\n\n this.discoveryTimer = setInterval(() => this.discover(), discoveryIntervalMs);\n this.driveTimer = setInterval(() => this.drive(), driveIntervalMs);\n }\n\n stop(): void {\n if (this.discoveryTimer) {\n clearInterval(this.discoveryTimer);\n this.discoveryTimer = null;\n }\n if (this.driveTimer) {\n clearInterval(this.driveTimer);\n this.driveTimer = null;\n }\n logger.info('Issue poller stopped');\n }\n\n getActiveIssueIids(): number[] {\n return [...this.activeIssues];\n }\n\n getActiveCount(): number {\n return this.activeIssues.size;\n }\n\n forceReleaseIssue(issueIid: number): boolean {\n const had = this.activeIssues.has(issueIid);\n if (had) {\n this.activeIssues.delete(issueIid);\n logger.info('Force-released issue from activeIssues', { issueIid });\n }\n return had;\n }\n\n pauseDiscovery(): void {\n this.discoveryPaused = true;\n logger.info('Discovery paused (auto-update drain)');\n }\n\n resumeDiscovery(): void {\n this.discoveryPaused = false;\n logger.info('Discovery resumed');\n }\n\n private async discover(): Promise<void> {\n if (isShuttingDown()) return;\n if (this.discoveryPaused) return;\n try {\n logger.debug('Discovering new issues...');\n const issues = await this.gongfeng.listIssues('opened', AUTO_FINISH_LABEL);\n const newIssues = this.filterNewIssues(issues);\n\n if (newIssues.length === 0) {\n logger.debug('No new issues found');\n return;\n }\n\n logger.info('Discovered new issues', { count: newIssues.length });\n for (const issue of newIssues) {\n this.tracker.create({\n issueId: issue.id,\n issueIid: issue.iid,\n issueTitle: issue.title,\n state: IssueState.Pending,\n branchName: `${this.config.project.branchPrefix}-${issue.iid}`,\n });\n }\n } catch (err) {\n logger.error('Discovery cycle failed', { error: (err as Error).message });\n }\n }\n\n private drive(): void {\n if (isShuttingDown()) return;\n\n this.maybeAutoApproveWaiting();\n\n const maxConcurrent = this.config.poll.maxConcurrent;\n const available = maxConcurrent - this.activeIssues.size;\n if (available <= 0) {\n logger.debug('Skipping drive — at concurrency limit', {\n active: this.activeIssues.size,\n max: maxConcurrent,\n });\n return;\n }\n\n const drivable = this.tracker\n .getDrivableIssues(this.config.poll.maxRetries)\n .filter((r) => !this.activeIssues.has(r.issueIid));\n\n if (drivable.length === 0) {\n return;\n }\n\n const batch = drivable.slice(0, available);\n logger.info('Driving issues', {\n batchSize: batch.length,\n active: this.activeIssues.size,\n max: maxConcurrent,\n });\n\n for (const record of batch) {\n this.activeIssues.add(record.issueIid);\n this.processInBackground(record);\n }\n }\n\n private maybeAutoApproveWaiting(): void {\n const autoLabels = this.config.review.autoApproveLabels;\n if (!autoLabels.length) return;\n\n const now = Date.now();\n if (now - this.lastAutoApproveCheckMs < AUTO_APPROVE_CHECK_INTERVAL_MS) return;\n this.lastAutoApproveCheckMs = now;\n\n const waiting = this.tracker\n .getAll()\n .filter((r) => r.state === IssueState.WaitingForReview);\n if (!waiting.length) return;\n\n this.autoApproveByLabels(waiting, autoLabels).catch((err) => {\n logger.warn('Auto-approve check failed', { error: (err as Error).message });\n });\n }\n\n private async autoApproveByLabels(\n records: IssueRecord[],\n autoLabels: string[],\n ): Promise<void> {\n for (const record of records) {\n try {\n const issue = await this.gongfeng.getIssueDetail(record.issueId);\n const matched = issue.labels.filter((l) => autoLabels.includes(l));\n if (matched.length === 0) continue;\n\n logger.info('Auto-approving waiting issue (label matched)', {\n iid: record.issueIid,\n matchedLabels: matched,\n });\n this.tracker.updateState(record.issueIid, IssueState.ReviewApproved);\n eventBus.emitTyped('review:approved', { issueIid: record.issueIid });\n\n try {\n await this.gongfeng.createIssueNote(\n record.issueId,\n t('poller.autoApproveComment', { labels: matched.join(', ') }),\n );\n } catch { /* ignore */ }\n } catch (err) {\n logger.warn('Failed to check auto-approve labels', {\n iid: record.issueIid,\n error: (err as Error).message,\n });\n }\n }\n }\n\n private async processInBackground(record: IssueRecord): Promise<void> {\n try {\n const issue = await this.resolveIssue(record.issueId);\n if (!issue) {\n logger.warn('Could not resolve issue from API, skipping', { iid: record.issueIid });\n return;\n }\n await this.orchestrator.processIssue(issue);\n } catch (err) {\n logger.error('Failed to process issue', {\n iid: record.issueIid,\n error: (err as Error).message,\n });\n } finally {\n this.activeIssues.delete(record.issueIid);\n }\n }\n\n private async resolveIssue(issueId: number): Promise<GongfengIssue | null> {\n try {\n return await this.gongfeng.getIssueDetail(issueId);\n } catch {\n return null;\n }\n }\n\n private filterNewIssues(issues: GongfengIssue[]): GongfengIssue[] {\n return issues.filter((issue) => {\n if (!issue.labels.includes(AUTO_FINISH_LABEL)) return false;\n if (issue.labels.some((l) => l === 'auto-finish:done')) return false;\n\n const record = this.tracker.get(issue.iid);\n if (record) return false;\n\n return true;\n });\n }\n}\n","import express from 'express';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { createApiRouter, ApiRouterDeps } from './routes/api.js';\nimport { createSetupRouter } from './routes/setup.js';\nimport { createBrainstormRouter } from './routes/brainstorm.js';\nimport { createChatRouter } from './routes/chat.js';\nimport { createKnowledgeRouter } from './routes/knowledge.js';\nimport { BrainstormService } from '../services/BrainstormService.js';\nimport { ChatService } from '../services/ChatService.js';\nimport { KnowledgeStore } from '../knowledge/KnowledgeStore.js';\nimport { IwikiImporter } from '../knowledge/importers/IwikiImporter.js';\nimport { IssueTracker } from '../tracker/IssueTracker.js';\nimport { Config } from '../config.js';\nimport { AgentLogStore } from './AgentLogStore.js';\nimport { PipelineOrchestrator } from '../orchestrator/PipelineOrchestrator.js';\nimport { GitOperations } from '../git/GitOperations.js';\nimport { GongfengClient } from '../clients/GongfengClient.js';\nimport { SupplementStore } from '../supplement/SupplementStore.js';\nimport { AutoUpdater } from '../updater/AutoUpdater.js';\nimport { logger as rootLogger } from '../logger.js';\nimport type { IssuePoller } from '../poller/IssuePoller.js';\nimport type { Server } from 'node:http';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst logger = rootLogger.child('WebServer');\n\nexport interface WebServerDeps {\n tracker: IssueTracker;\n config: Config;\n agentLogStore: AgentLogStore;\n orchestrator: PipelineOrchestrator;\n gongfeng: GongfengClient;\n supplementStore: SupplementStore;\n mainGit?: GitOperations;\n autoUpdater?: AutoUpdater;\n poller?: IssuePoller;\n}\n\nexport class WebServer {\n private app: express.Application;\n private server: Server | null = null;\n private port: number;\n\n constructor(deps: WebServerDeps);\n constructor(tracker: IssueTracker, config: Config, agentLogStore: AgentLogStore, orchestrator: PipelineOrchestrator, mainGit?: GitOperations);\n constructor(\n trackerOrDeps: IssueTracker | WebServerDeps,\n config?: Config,\n agentLogStore?: AgentLogStore,\n orchestrator?: PipelineOrchestrator,\n mainGit?: GitOperations,\n ) {\n let apiDeps: ApiRouterDeps;\n\n if (trackerOrDeps instanceof IssueTracker) {\n this.port = config!.web.port;\n apiDeps = {\n tracker: trackerOrDeps,\n config: config!,\n agentLogStore: agentLogStore!,\n orchestrator: orchestrator!,\n mainGit,\n gongfeng: undefined as unknown as GongfengClient,\n supplementStore: undefined as unknown as SupplementStore,\n };\n } else {\n const deps = trackerOrDeps;\n this.port = deps.config.web.port;\n apiDeps = {\n tracker: deps.tracker,\n config: deps.config,\n agentLogStore: deps.agentLogStore,\n orchestrator: deps.orchestrator,\n mainGit: deps.mainGit,\n gongfeng: deps.gongfeng,\n supplementStore: deps.supplementStore,\n autoUpdater: deps.autoUpdater,\n poller: deps.poller,\n };\n }\n\n this.app = express();\n this.app.use(express.json());\n\n const setupRouter = createSetupRouter({ serviceMode: true });\n this.app.use(setupRouter);\n\n const apiRouter = createApiRouter(apiDeps);\n this.app.use(apiRouter);\n\n if (apiDeps.config.brainstorm.enabled) {\n const brainstormService = new BrainstormService(apiDeps.config);\n const brainstormRouter = createBrainstormRouter({\n brainstormService,\n gongfeng: apiDeps.gongfeng,\n });\n this.app.use(brainstormRouter);\n }\n\n const knowledgeDataDir = path.join(apiDeps.config.project.workDir, 'data', 'knowledge');\n const knowledgeStore = new KnowledgeStore(knowledgeDataDir);\n\n if (apiDeps.config.chat.enabled) {\n const chatService = new ChatService(apiDeps.config, knowledgeStore);\n const chatRouter = createChatRouter({ chatService });\n this.app.use(chatRouter);\n }\n\n const iwikiImporter = new IwikiImporter(knowledgeStore, {\n authCookie: apiDeps.config.iwiki?.authCookie,\n authToken: apiDeps.config.iwiki?.authToken,\n });\n\n // Migrate legacy knowledge.json if present\n const legacyKnowledgePath = path.join(apiDeps.config.project.workDir, 'knowledge.json');\n knowledgeStore.migrateFromLegacy(legacyKnowledgePath);\n\n const knowledgeRouter = createKnowledgeRouter({\n knowledgeStore,\n iwikiImporter,\n config: apiDeps.config,\n });\n this.app.use(knowledgeRouter);\n\n const publicDir = apiDeps.config.web.frontendDistDir;\n this.app.use(express.static(publicDir));\n\n this.app.get('{*path}', (_req, res) => {\n res.sendFile(path.join(publicDir, 'index.html'));\n });\n }\n\n start(): Promise<void> {\n return new Promise((resolve) => {\n this.server = this.app.listen(this.port, () => {\n logger.info(`Web UI available at http://localhost:${this.port}`);\n resolve();\n });\n });\n }\n\n stop(): void {\n if (this.server) {\n this.server.close();\n this.server = null;\n logger.info('Web server stopped');\n }\n }\n}\n","import { Router, Request, Response } from 'express';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { marked } from 'marked';\nimport { IssueTracker } from '../../tracker/IssueTracker.js';\nimport { IssueState } from '../../tracker/IssueState.js';\nimport { Config } from '../../config.js';\nimport { AgentLogStore } from '../AgentLogStore.js';\nimport { PipelineOrchestrator } from '../../orchestrator/PipelineOrchestrator.js';\nimport { GitOperations } from '../../git/GitOperations.js';\nimport { GongfengClient } from '../../clients/GongfengClient.js';\nimport { SupplementStore } from '../../supplement/SupplementStore.js';\nimport { PlanPersistence } from '../../persistence/PlanPersistence.js';\nimport { getPipelineDef } from '../../pipeline/PipelineDefinition.js';\nimport type { PipelineDef } from '../../pipeline/PipelineDefinition.js';\nimport { eventBus, EventPayload } from '../../events/EventBus.js';\nimport {\n getNoteSyncEnabled, setNoteSyncOverride, isNoteSyncEnabledForIssue,\n} from '../../notesync/NoteSyncSettings.js';\nimport { getE2eEnabled, setE2eOverride } from '../../e2e/E2eSettings.js';\nimport { logger as rootLogger } from '../../logger.js';\nimport { t } from '../../i18n/index.js';\nimport type { AutoUpdater } from '../../updater/AutoUpdater.js';\nimport type { IssuePoller } from '../../poller/IssuePoller.js';\n\nconst logger = rootLogger.child('ApiRoutes');\n\nconst startTime = Date.now();\n\nexport interface ApiRouterDeps {\n tracker: IssueTracker;\n config: Config;\n agentLogStore: AgentLogStore;\n orchestrator: PipelineOrchestrator;\n gongfeng: GongfengClient;\n supplementStore: SupplementStore;\n mainGit?: GitOperations;\n autoUpdater?: AutoUpdater;\n poller?: IssuePoller;\n}\n\nfunction buildPreviewInfo(iid: number, orch: PipelineOrchestrator) {\n const ports = orch.getPortAllocator().getPortsForIssue(iid);\n if (!ports) return null;\n const dsm = orch.getDevServerManager();\n const status = dsm.getStatus(iid);\n return {\n ...status,\n ports,\n previewUrl: orch.buildPreviewUrl(iid),\n host: orch.getPreviewHost(),\n };\n}\n\nexport function createApiRouter(deps: ApiRouterDeps): Router;\nexport function createApiRouter(tracker: IssueTracker, config: Config, agentLogStore: AgentLogStore, orchestrator: PipelineOrchestrator, mainGit?: GitOperations): Router;\nexport function createApiRouter(\n trackerOrDeps: IssueTracker | ApiRouterDeps,\n config?: Config,\n agentLogStore?: AgentLogStore,\n orchestrator?: PipelineOrchestrator,\n mainGit?: GitOperations,\n): Router {\n let tracker: IssueTracker;\n let cfg: Config;\n let logStore: AgentLogStore;\n let orch: PipelineOrchestrator;\n let git: GitOperations | undefined;\n let gongfeng: GongfengClient | undefined;\n let supplementStore: SupplementStore | undefined;\n let autoUpdater: AutoUpdater | undefined;\n let poller: IssuePoller | undefined;\n\n if (config !== undefined) {\n tracker = trackerOrDeps as IssueTracker;\n cfg = config!;\n logStore = agentLogStore!;\n orch = orchestrator!;\n git = mainGit;\n } else {\n const deps = trackerOrDeps as ApiRouterDeps;\n tracker = deps.tracker;\n cfg = deps.config;\n logStore = deps.agentLogStore;\n orch = deps.orchestrator;\n git = deps.mainGit;\n gongfeng = deps.gongfeng;\n supplementStore = deps.supplementStore;\n autoUpdater = deps.autoUpdater;\n poller = deps.poller;\n }\n\n const router = Router();\n\n router.get('/api/issues', (_req: Request, res: Response) => {\n const issues = tracker.getAll();\n res.json(issues);\n });\n\n router.get('/api/issues/:iid', async (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n const progress = await readProgress(iid, cfg, tracker, git);\n const preview = buildPreviewInfo(iid, orch);\n res.json({ ...record, progress, preview });\n });\n\n function getIssuePipelineDef(iid: number): PipelineDef {\n const record = tracker.get(iid);\n const mode = record?.pipelineMode ?? orch.getPipelineDef().mode;\n return getPipelineDef(mode === 'plan-mode' ? 'plan-mode' : 'classic');\n }\n\n router.get('/api/issues/:iid/plans/:filename', async (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const filename = req.params.filename;\n const def = getIssuePipelineDef(iid);\n const allowed = [\n ...def.planFiles.map(f => f.filename),\n 'progress.json', 'issue-meta.json',\n ];\n if (!allowed.includes(filename)) {\n res.status(400).json({ error: 'Invalid filename' });\n return;\n }\n const content = await readPlanFile(iid, filename, cfg, tracker, git);\n if (content === null) {\n res.status(404).json({ error: 'Plan file not found' });\n return;\n }\n if (filename.endsWith('.json')) {\n res.json(JSON.parse(content));\n return;\n }\n if (req.query.format === 'html') {\n const html = await marked(content);\n res.type('html').send(html);\n return;\n }\n res.type('text/markdown').send(content);\n });\n\n router.post('/api/issues/:iid/retry', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const ok = tracker.resetForRetry(iid);\n if (!ok) {\n res.status(400).json({ error: 'Issue is not in failed state or not found' });\n return;\n }\n res.json({ success: true, message: `Issue #${iid} reset for retry` });\n });\n\n router.post('/api/issues/:iid/cancel', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const ok = tracker.delete(iid);\n if (!ok) {\n res.status(404).json({ error: 'Issue not found in tracker' });\n return;\n }\n res.json({ success: true, message: `Issue #${iid} removed from tracker` });\n });\n\n router.post('/api/issues/:iid/restart', async (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n try {\n poller?.forceReleaseIssue(iid);\n await orch.restartIssue(iid);\n res.json({ success: true, message: `Issue #${iid} restarted` });\n } catch (err) {\n const msg = (err as Error).message;\n logger.error('Restart failed', { iid, error: msg });\n res.status(400).json({ error: msg });\n }\n });\n\n router.post('/api/issues/:iid/retry-from-phase', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const { phase } = req.body as { phase?: string };\n const def = getIssuePipelineDef(iid);\n const validPhases = def.phases.filter(p => p.kind === 'ai').map(p => p.name);\n if (!phase || !validPhases.includes(phase)) {\n res.status(400).json({ error: `Invalid phase. Must be one of: ${validPhases.join(', ')}` });\n return;\n }\n try {\n orch.retryFromPhase(iid, phase);\n res.json({ success: true, message: `Issue #${iid} reset to phase: ${phase}` });\n } catch (err) {\n const msg = (err as Error).message;\n logger.error('Retry-from-phase failed', { iid, phase, error: msg });\n res.status(400).json({ error: msg });\n }\n });\n\n router.put('/api/issues/:iid/plans/:filename', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const filename = req.params.filename;\n const def = getIssuePipelineDef(iid);\n const editableFiles = def.planFiles.filter(f => f.editable).map(f => f.filename);\n if (!editableFiles.includes(filename)) {\n res.status(400).json({ error: `File not editable. Allowed: ${editableFiles.join(', ')}` });\n return;\n }\n const { content } = req.body as { content?: string };\n if (typeof content !== 'string') {\n res.status(400).json({ error: 'Request body must contain a \"content\" string field' });\n return;\n }\n const planDir = getWorktreePlanDir(iid, cfg);\n const filePath = path.join(planDir, filename);\n if (!fs.existsSync(planDir)) {\n res.status(404).json({ error: 'Plan directory not found (worktree may have been cleaned)' });\n return;\n }\n fs.writeFileSync(filePath, content, 'utf-8');\n logger.info('Plan file updated', { iid, filename });\n res.json({ success: true, message: `Plan file ${filename} saved` });\n });\n\n router.get('/api/issues/:iid/logs', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n const logs = logStore.getLogs(iid);\n res.json(logs);\n });\n\n // --- Supplement endpoints ---\n\n router.get('/api/issues/:iid/supplement', (req: Request, res: Response) => {\n if (!supplementStore) {\n res.status(501).json({ error: 'Supplement store not available' });\n return;\n }\n const iid = parseInt(req.params.iid, 10);\n const info = supplementStore.get(iid);\n res.json(info);\n });\n\n router.put('/api/issues/:iid/supplement', (req: Request, res: Response) => {\n if (!supplementStore) {\n res.status(501).json({ error: 'Supplement store not available' });\n return;\n }\n const iid = parseInt(req.params.iid, 10);\n const body = req.body as Record<string, unknown>;\n const data = {\n requirements: String(body.requirements || ''),\n acceptanceCriteria: String(body.acceptanceCriteria || ''),\n scope: String(body.scope || ''),\n constraints: String(body.constraints || ''),\n references: String(body.references || ''),\n freeText: String(body.freeText || ''),\n tapdId: String(body.tapdId || ''),\n };\n const saved = supplementStore.save(iid, data);\n res.json({ success: true, data: saved });\n });\n\n // --- Gongfeng issue browsing ---\n\n router.get('/api/gongfeng/issues', async (req: Request, res: Response) => {\n if (!gongfeng) {\n res.status(501).json({ error: 'Gongfeng client not available' });\n return;\n }\n try {\n const search = (req.query.search as string) || '';\n const page = parseInt(req.query.page as string, 10) || 1;\n const perPage = parseInt(req.query.per_page as string, 10) || 20;\n\n const result = await gongfeng.listIssuesAdvanced({\n state: 'opened',\n search: search || undefined,\n page,\n perPage,\n });\n\n const trackedIids = new Set(tracker.getAll().map((r) => r.issueIid));\n\n res.json({\n issues: result.issues,\n total: result.total,\n trackedIids: Array.from(trackedIids),\n });\n } catch (err) {\n const msg = (err as Error).message;\n logger.error('Failed to fetch gongfeng issues', { error: msg });\n res.status(500).json({ error: msg });\n }\n });\n\n // --- Start processing an issue ---\n\n router.post('/api/issues/start', async (req: Request, res: Response) => {\n if (!gongfeng) {\n res.status(501).json({ error: 'Gongfeng client not available' });\n return;\n }\n const body = req.body as {\n issueId?: number;\n issueIid?: number;\n issueTitle?: string;\n supplement?: Record<string, string>;\n };\n if (!body.issueId || !body.issueIid || !body.issueTitle) {\n res.status(400).json({ error: 'issueId, issueIid, and issueTitle are required' });\n return;\n }\n\n const existing = tracker.get(body.issueIid);\n if (existing) {\n res.status(409).json({ error: `Issue #${body.issueIid} is already being tracked` });\n return;\n }\n\n try {\n await gongfeng.addLabel(body.issueId, 'auto-finish');\n } catch (err) {\n logger.warn('Failed to add auto-finish label', { error: (err as Error).message });\n }\n\n const branchName = `${cfg.project.branchPrefix}-${body.issueIid}`;\n const record = tracker.create({\n issueId: body.issueId,\n issueIid: body.issueIid,\n issueTitle: body.issueTitle,\n state: IssueState.Pending,\n branchName,\n });\n\n if (supplementStore && body.supplement) {\n supplementStore.save(body.issueIid, {\n requirements: String(body.supplement.requirements || ''),\n acceptanceCriteria: String(body.supplement.acceptanceCriteria || ''),\n scope: String(body.supplement.scope || ''),\n constraints: String(body.supplement.constraints || ''),\n references: String(body.supplement.references || ''),\n freeText: String(body.supplement.freeText || ''),\n tapdId: String(body.supplement.tapdId || ''),\n });\n }\n\n res.json({ success: true, record });\n });\n\n // --- Review Gate endpoints ---\n\n router.post('/api/issues/:iid/approve-plan', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n if (record.state !== IssueState.WaitingForReview) {\n res.status(400).json({ error: `Issue is not waiting for review (current state: ${record.state})` });\n return;\n }\n tracker.updateState(iid, IssueState.ReviewApproved);\n const def = getIssuePipelineDef(iid);\n const reviewSpec = def.phases.find(p => p.kind === 'gate');\n if (reviewSpec) {\n const workDir = getWorktreeWorkDir(iid, cfg);\n const planPersistence = new PlanPersistence(workDir, iid);\n planPersistence.updatePhaseProgress(reviewSpec.name, 'completed');\n }\n eventBus.emitTyped('review:approved', { issueIid: iid });\n logger.info('Plan approved', { iid });\n res.json({ success: true, message: `Issue #${iid} plan approved, will resume on next drive cycle` });\n });\n\n router.post('/api/issues/:iid/reject-plan', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n if (record.state !== IssueState.WaitingForReview) {\n res.status(400).json({ error: `Issue is not waiting for review (current state: ${record.state})` });\n return;\n }\n const { feedback } = req.body as { feedback?: string };\n if (!feedback || typeof feedback !== 'string') {\n res.status(400).json({ error: 'Feedback is required' });\n return;\n }\n const workDir = getWorktreeWorkDir(iid, cfg);\n if (fs.existsSync(workDir)) {\n const planPersistence = new PlanPersistence(workDir, iid);\n planPersistence.writeReviewFeedback(feedback);\n }\n tracker.updateState(iid, IssueState.BranchCreated);\n eventBus.emitTyped('review:rejected', { issueIid: iid, feedback });\n logger.info('Plan rejected', { iid, feedback: feedback.slice(0, 100) });\n\n if (gongfeng && isNoteSyncEnabledForIssue(iid, tracker, cfg)) {\n const baseUrl = cfg.issueNoteSync.webBaseUrl.replace(/\\/$/, '');\n const planFile = record.pipelineMode === 'plan-mode' ? '01-plan.md' : '02-design.md';\n const history = fs.existsSync(workDir)\n ? new PlanPersistence(workDir, iid).readReviewHistory()\n : [];\n const round = history.length;\n const note = [\n t('api.reviewFeedback', { round }),\n '',\n feedback,\n '',\n '---',\n t('api.viewPlan', { url: `${baseUrl}/doc/${iid}/${planFile}` }),\n t('api.viewDetail', { url: `${baseUrl}/?issue=${iid}` }),\n ].join('\\n');\n gongfeng.createIssueNote(record.issueId, note).catch((err) => {\n logger.warn('Failed to sync review feedback to issue', { error: (err as Error).message });\n });\n }\n\n res.json({ success: true, message: `Issue #${iid} plan rejected, will re-plan on next drive cycle` });\n });\n\n router.post('/api/issues/:iid/skip-review', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n if (record.state !== IssueState.WaitingForReview) {\n res.status(400).json({ error: `Issue is not waiting for review (current state: ${record.state})` });\n return;\n }\n tracker.updateState(iid, IssueState.ReviewApproved);\n const def = getIssuePipelineDef(iid);\n const reviewSpec = def.phases.find(p => p.kind === 'gate');\n if (reviewSpec) {\n const workDir = getWorktreeWorkDir(iid, cfg);\n const planPersistence = new PlanPersistence(workDir, iid);\n planPersistence.updatePhaseProgress(reviewSpec.name, 'completed');\n }\n eventBus.emitTyped('review:approved', { issueIid: iid });\n logger.info('Review skipped', { iid });\n res.json({ success: true, message: `Issue #${iid} review skipped` });\n });\n\n router.get('/api/issues/:iid/review-history', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n const workDir = getWorktreeWorkDir(iid, cfg);\n if (!fs.existsSync(workDir)) {\n res.json([]);\n return;\n }\n const planPersistence = new PlanPersistence(workDir, iid);\n res.json(planPersistence.readReviewHistory());\n });\n\n // --- Note Sync toggle endpoints ---\n\n router.put('/api/issues/:iid/note-sync', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n const { enabled } = req.body as { enabled?: boolean | null };\n const value = enabled === null ? undefined : enabled;\n tracker.updateState(iid, record.state, { issueNoteSyncEnabled: value } as any);\n logger.info('Issue note-sync toggled', { iid, enabled: value });\n res.json({ success: true, issueNoteSyncEnabled: value ?? null });\n });\n\n router.put('/api/system/note-sync', (req: Request, res: Response) => {\n const { enabled } = req.body as { enabled?: boolean };\n if (typeof enabled !== 'boolean') {\n res.status(400).json({ error: 'enabled must be a boolean' });\n return;\n }\n setNoteSyncOverride(enabled);\n logger.info('System note-sync toggled', { enabled });\n res.json({ success: true, issueNoteSyncEnabled: enabled });\n });\n\n // --- Preview endpoints ---\n\n router.get('/api/issues/:iid/preview', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n const preview = buildPreviewInfo(iid, orch);\n res.json(preview ?? { running: false });\n });\n\n router.post('/api/issues/:iid/stop-preview', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n orch.stopPreviewServers(iid);\n res.json({ success: true, message: `Preview servers stopped for issue #${iid}` });\n });\n\n // --- E2E UI toggle endpoints ---\n\n router.put('/api/issues/:iid/e2e', (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const record = tracker.get(iid);\n if (!record) {\n res.status(404).json({ error: 'Issue not found' });\n return;\n }\n const { enabled } = req.body as { enabled?: boolean | null };\n const value = enabled === null ? undefined : enabled;\n tracker.updateState(iid, record.state, { e2eEnabled: value } as any);\n logger.info('Issue e2e toggled', { iid, enabled: value });\n res.json({ success: true, e2eEnabled: value ?? null });\n });\n\n router.put('/api/system/e2e', (req: Request, res: Response) => {\n const { enabled } = req.body as { enabled?: boolean };\n if (typeof enabled !== 'boolean') {\n res.status(400).json({ error: 'enabled must be a boolean' });\n return;\n }\n setE2eOverride(enabled);\n logger.info('System e2e toggled', { enabled });\n res.json({ success: true, e2eEnabled: enabled });\n });\n\n router.get('/api/system/status', (_req: Request, res: Response) => {\n const runningPreviews = orch.getDevServerManager().getRunningIssues();\n res.json({\n uptime: Date.now() - startTime,\n startedAt: new Date(startTime).toISOString(),\n config: {\n discoveryIntervalMs: cfg.poll.discoveryIntervalMs,\n driveIntervalMs: cfg.poll.driveIntervalMs,\n maxRetries: cfg.poll.maxRetries,\n aiMode: cfg.ai.mode,\n pipelineMode: orch.getPipelineDef().mode,\n baseBranch: cfg.project.baseBranch,\n projectPath: cfg.gongfeng.projectPath,\n gongfengBaseUrl: cfg.gongfeng.apiUrl.replace(/\\/$/, ''),\n issueNoteSyncEnabled: getNoteSyncEnabled(cfg),\n e2eEnabled: getE2eEnabled(cfg),\n previewEnabled: cfg.preview.enabled,\n locale: cfg.locale,\n },\n issues: {\n total: tracker.getAll().length,\n active: tracker.getAllActive().length,\n },\n preview: {\n runningCount: runningPreviews.length,\n runningIssues: runningPreviews,\n },\n });\n });\n\n router.get('/api/events', (req: Request, res: Response) => {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n const heartbeat = setInterval(() => {\n res.write(`event: heartbeat\\ndata: ${JSON.stringify({ time: new Date().toISOString() })}\\n\\n`);\n }, 15_000);\n\n const handler = (_eventName: string | symbol, payload: EventPayload) => {\n try {\n res.write(`event: ${payload.type}\\ndata: ${JSON.stringify(payload)}\\n\\n`);\n } catch {\n logger.warn('Failed to write SSE event');\n }\n };\n\n eventBus.on('*', handler);\n res.write(`event: connected\\ndata: ${JSON.stringify({ time: new Date().toISOString() })}\\n\\n`);\n\n req.on('close', () => {\n clearInterval(heartbeat);\n eventBus.off('*', handler);\n });\n });\n\n // --- Standalone document viewer (linked from issue notes) ---\n\n router.get('/doc/:iid/:filename', async (req: Request, res: Response) => {\n const iid = parseInt(req.params.iid, 10);\n const filename = req.params.filename;\n const record = tracker.get(iid);\n const title = record?.issueTitle ?? `Issue #${iid}`;\n\n const def = getIssuePipelineDef(iid);\n const allowed = def.planFiles.map(f => f.filename);\n if (!allowed.includes(filename)) {\n res.status(400).type('html').send(renderDocPage(iid, title, t('api.invalidFilename'), filename));\n return;\n }\n\n const content = await readPlanFile(iid, filename, cfg, tracker, git);\n if (content === null) {\n res.status(404).type('html').send(renderDocPage(iid, title, t('api.docNotGenerated'), filename));\n return;\n }\n\n const htmlBody = await marked(content);\n res.type('html').send(renderDocPage(iid, title, htmlBody, filename));\n });\n\n // --- Auto-update endpoints ---\n\n router.get('/api/system/update-status', (_req: Request, res: Response) => {\n if (!autoUpdater) {\n res.status(501).json({ error: 'Auto-updater not available' });\n return;\n }\n res.json(autoUpdater.getStatus());\n });\n\n router.post('/api/system/update-check', async (_req: Request, res: Response) => {\n if (!autoUpdater) {\n res.status(501).json({ error: 'Auto-updater not available' });\n return;\n }\n try {\n const result = await autoUpdater.checkForUpdate();\n res.json(result);\n } catch (err) {\n const msg = (err as Error).message;\n logger.error('Manual update check failed', { error: msg });\n res.status(500).json({ error: msg });\n }\n });\n\n router.post('/api/system/update', async (_req: Request, res: Response) => {\n if (!autoUpdater) {\n res.status(501).json({ error: 'Auto-updater not available' });\n return;\n }\n try {\n res.json({ success: true, message: 'Update triggered' });\n // Fire and forget — the process will be restarted by PM2\n autoUpdater.triggerUpdate().catch((err) => {\n logger.error('Manual update failed', { error: (err as Error).message });\n });\n } catch (err) {\n const msg = (err as Error).message;\n logger.error('Failed to trigger update', { error: msg });\n res.status(500).json({ error: msg });\n }\n });\n\n return router;\n}\n\nconst DOC_LABELS_FUNC = (filename: string): string => t(`docLabel.${filename}`) || filename;\n\nfunction renderDocPage(iid: number, issueTitle: string, htmlBody: string, filename: string): string {\n const docLabel = DOC_LABELS_FUNC(filename);\n return `<!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>Issue #${iid} — ${docLabel}</title>\n<style>\n body { font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Helvetica, Arial, sans-serif; margin: 0; padding: 0; color: #24292f; background: #f6f8fa; }\n .header { background: #fff; border-bottom: 1px solid #d0d7de; padding: 12px 24px; display: flex; align-items: center; gap: 12px; }\n .header .crumb { font-size: 14px; color: #57606a; }\n .header .crumb a { color: #0969da; text-decoration: none; }\n .header .crumb a:hover { text-decoration: underline; }\n .header .crumb .sep { margin: 0 4px; color: #8b949e; }\n .container { max-width: 900px; margin: 24px auto; background: #fff; border: 1px solid #d0d7de; border-radius: 6px; padding: 32px 40px; }\n .markdown-body h1 { font-size: 1.6em; border-bottom: 1px solid #d0d7de; padding-bottom: .3em; }\n .markdown-body h2 { font-size: 1.3em; border-bottom: 1px solid #d0d7de; padding-bottom: .3em; }\n .markdown-body h3 { font-size: 1.1em; }\n .markdown-body pre { background: #f6f8fa; border: 1px solid #d0d7de; border-radius: 6px; padding: 16px; overflow-x: auto; }\n .markdown-body code { background: #f6f8fa; border-radius: 3px; padding: 0.2em 0.4em; font-size: 85%; }\n .markdown-body pre code { background: none; padding: 0; }\n .markdown-body table { border-collapse: collapse; width: 100%; }\n .markdown-body th, .markdown-body td { border: 1px solid #d0d7de; padding: 6px 13px; }\n .markdown-body th { background: #f6f8fa; }\n .markdown-body blockquote { margin: 0; padding: 0 1em; color: #57606a; border-left: 3px solid #d0d7de; }\n .markdown-body ul, .markdown-body ol { padding-left: 2em; }\n .markdown-body li { margin-top: 0.25em; }\n .markdown-body p { margin: 8px 0; }\n .markdown-body a { color: #0969da; }\n</style>\n</head>\n<body>\n <div class=\"header\">\n <div class=\"crumb\">\n <a href=\"/?issue=${iid}\">Issue #${iid}</a>\n <span class=\"sep\">/</span>\n <strong>${docLabel}</strong>\n <span class=\"sep\">·</span>\n <span style=\"font-size:12px;color:#57606a\">${escapeHtml(issueTitle)}</span>\n <span class=\"sep\">·</span>\n <a href=\"/?issue=${iid}\" style=\"font-size:12px\">${t('api.viewInDashboard')}</a>\n </div>\n </div>\n <div class=\"container\">\n <div class=\"markdown-body\">${htmlBody}</div>\n </div>\n</body>\n</html>`;\n}\n\nfunction escapeHtml(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"');\n}\n\nfunction getWorktreeWorkDir(issueIid: number, config: Config): string {\n return path.join(\n config.project.worktreeBaseDir,\n `issue-${issueIid}`,\n config.project.projectSubDir,\n );\n}\n\nfunction getWorktreePlanDir(issueIid: number, config: Config): string {\n return path.join(getWorktreeWorkDir(issueIid, config), '.claude-plan', `issue-${issueIid}`);\n}\n\nfunction getPlanGitPath(issueIid: number, filename: string, config: Config): string {\n return path.posix.join(config.project.projectSubDir, '.claude-plan', `issue-${issueIid}`, filename);\n}\n\nasync function readPlanFileFromGit(\n issueIid: number,\n filename: string,\n config: Config,\n tracker: IssueTracker,\n mainGit?: GitOperations,\n): Promise<string | null> {\n if (!mainGit) return null;\n const record = tracker.get(issueIid);\n if (!record) return null;\n const gitPath = getPlanGitPath(issueIid, filename, config);\n return mainGit.showFile(record.branchName, gitPath);\n}\n\nconst VERIFY_REPORT_FALLBACKS: Record<string, string> = {\n '02-verify-report.md': '04-verify-report.md',\n};\n\nasync function readPlanFile(\n issueIid: number,\n filename: string,\n config: Config,\n tracker: IssueTracker,\n mainGit?: GitOperations,\n): Promise<string | null> {\n const planDir = getWorktreePlanDir(issueIid, config);\n const filePath = path.join(planDir, filename);\n if (fs.existsSync(filePath)) {\n try {\n return fs.readFileSync(filePath, 'utf-8');\n } catch {\n return null;\n }\n }\n const content = await readPlanFileFromGit(issueIid, filename, config, tracker, mainGit);\n if (content !== null) return content;\n\n const fallback = VERIFY_REPORT_FALLBACKS[filename];\n if (fallback) {\n return readPlanFile(issueIid, fallback, config, tracker, mainGit);\n }\n return null;\n}\n\nasync function readProgress(\n issueIid: number,\n config: Config,\n tracker: IssueTracker,\n mainGit?: GitOperations,\n): Promise<unknown | null> {\n const content = await readPlanFile(issueIid, 'progress.json', config, tracker, mainGit);\n if (!content) return null;\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n","import { Router, Request, Response } from 'express';\nimport { BrainstormService, type BrainstormStreamEvent } from '../../services/BrainstormService.js';\nimport { GongfengClient } from '../../clients/GongfengClient.js';\nimport { logger as rootLogger } from '../../logger.js';\n\nconst logger = rootLogger.child('BrainstormRoutes');\n\nexport interface BrainstormRouterDeps {\n brainstormService: BrainstormService;\n gongfeng: GongfengClient;\n}\n\nfunction sseWriter(res: Response) {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n return (event: BrainstormStreamEvent) => {\n try {\n res.write(`event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`);\n } catch {\n logger.warn('Failed to write SSE brainstorm event');\n }\n };\n}\n\nexport function createBrainstormRouter(deps: BrainstormRouterDeps): Router {\n const router = Router();\n const { brainstormService, gongfeng } = deps;\n\n router.post('/api/brainstorm/sessions', (req: Request, res: Response) => {\n try {\n const { transcript } = req.body as { transcript?: string };\n if (!transcript?.trim()) {\n res.status(400).json({ error: 'transcript is required' });\n return;\n }\n const session = brainstormService.createSession(transcript.trim());\n res.json({ success: true, session });\n } catch (err) {\n logger.error('Failed to create brainstorm session', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n router.get('/api/brainstorm/sessions/:id', (req: Request, res: Response) => {\n const session = brainstormService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n res.json({ success: true, session });\n });\n\n router.post('/api/brainstorm/sessions/:id/generate', async (req: Request, res: Response) => {\n const session = brainstormService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n\n const write = sseWriter(res);\n try {\n await brainstormService.generate(req.params.id, write);\n res.write(`event: done\\ndata: ${JSON.stringify({ type: 'done' })}\\n\\n`);\n } catch (err) {\n write({ type: 'error', data: { message: (err as Error).message } });\n } finally {\n res.end();\n }\n });\n\n router.post('/api/brainstorm/sessions/:id/review', async (req: Request, res: Response) => {\n const session = brainstormService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n\n const write = sseWriter(res);\n try {\n await brainstormService.review(req.params.id, write);\n res.write(`event: done\\ndata: ${JSON.stringify({ type: 'done' })}\\n\\n`);\n } catch (err) {\n write({ type: 'error', data: { message: (err as Error).message } });\n } finally {\n res.end();\n }\n });\n\n router.post('/api/brainstorm/sessions/:id/refine', async (req: Request, res: Response) => {\n const session = brainstormService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n\n const write = sseWriter(res);\n try {\n await brainstormService.refine(req.params.id, write);\n res.write(`event: done\\ndata: ${JSON.stringify({ type: 'done' })}\\n\\n`);\n } catch (err) {\n write({ type: 'error', data: { message: (err as Error).message } });\n } finally {\n res.end();\n }\n });\n\n router.post('/api/brainstorm/sessions/:id/auto-refine', async (req: Request, res: Response) => {\n const session = brainstormService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n\n const { rounds } = req.body as { rounds?: number };\n const write = sseWriter(res);\n try {\n await brainstormService.autoRefine(req.params.id, rounds, write);\n res.write(`event: done\\ndata: ${JSON.stringify({ type: 'done' })}\\n\\n`);\n } catch (err) {\n write({ type: 'error', data: { message: (err as Error).message } });\n } finally {\n res.end();\n }\n });\n\n router.post('/api/brainstorm/sessions/:id/create-issue', async (req: Request, res: Response) => {\n const session = brainstormService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n if (!session.currentSdd) {\n res.status(400).json({ error: 'No SDD generated yet' });\n return;\n }\n\n try {\n const { title, addAutoFinishLabel } = req.body as {\n title?: string;\n addAutoFinishLabel?: boolean;\n };\n const issueTitle = title?.trim() || extractTitle(session.currentSdd);\n const labels = addAutoFinishLabel !== false ? ['auto-finish'] : [];\n const issue = await gongfeng.createIssue(issueTitle, session.currentSdd, labels);\n logger.info('Issue created from brainstorm', { issueIid: issue.iid, sessionId: session.id });\n res.json({ success: true, issue });\n } catch (err) {\n logger.error('Failed to create issue from brainstorm', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n return router;\n}\n\nfunction extractTitle(sdd: string): string {\n const firstLine = sdd.split('\\n').find(l => l.trim());\n if (firstLine) {\n return firstLine.replace(/^#+\\s*/, '').trim().slice(0, 200);\n }\n return '脑暴生成的需求';\n}\n","import { Router, Request, Response } from 'express';\nimport { ChatService, type ChatStreamEvent } from '../../services/ChatService.js';\nimport { logger as rootLogger } from '../../logger.js';\n\nconst logger = rootLogger.child('ChatRoutes');\n\nexport interface ChatRouterDeps {\n chatService: ChatService;\n}\n\nfunction sseWriter(res: Response) {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n return (event: ChatStreamEvent) => {\n try {\n res.write(`event: ${event.type}\\ndata: ${JSON.stringify(event)}\\n\\n`);\n } catch {\n logger.warn('Failed to write SSE chat event');\n }\n };\n}\n\nexport function createChatRouter(deps: ChatRouterDeps): Router {\n const router = Router();\n const { chatService } = deps;\n\n // Create session\n router.post('/api/chat/sessions', (req: Request, res: Response) => {\n try {\n const { title } = req.body as { title?: string };\n const session = chatService.createSession(title?.trim());\n res.json({ success: true, session });\n } catch (err) {\n logger.error('Failed to create chat session', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // List sessions\n router.get('/api/chat/sessions', (_req: Request, res: Response) => {\n try {\n const sessions = chatService.listSessions();\n res.json({ success: true, sessions });\n } catch (err) {\n logger.error('Failed to list chat sessions', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // Get session\n router.get('/api/chat/sessions/:id', (req: Request, res: Response) => {\n const session = chatService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n res.json({ success: true, session });\n });\n\n // Delete session\n router.delete('/api/chat/sessions/:id', (req: Request, res: Response) => {\n const deleted = chatService.deleteSession(req.params.id);\n if (!deleted) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n res.json({ success: true });\n });\n\n // Send message (SSE streaming response)\n router.post('/api/chat/sessions/:id/messages', async (req: Request, res: Response) => {\n const session = chatService.getSession(req.params.id);\n if (!session) {\n res.status(404).json({ error: 'Session not found' });\n return;\n }\n\n const { content } = req.body as { content?: string };\n if (!content?.trim()) {\n res.status(400).json({ error: 'content is required' });\n return;\n }\n\n const write = sseWriter(res);\n try {\n await chatService.sendMessage(req.params.id, content.trim(), write);\n res.write(`event: done\\ndata: ${JSON.stringify({ type: 'done' })}\\n\\n`);\n } catch (err) {\n write({ type: 'error', data: { message: (err as Error).message } });\n } finally {\n res.end();\n }\n });\n\n return router;\n}\n","import { Router, Request, Response } from 'express';\nimport { logger as rootLogger } from '../../logger.js';\nimport type { KnowledgeStore } from '../../knowledge/KnowledgeStore.js';\nimport type { IwikiImporter } from '../../knowledge/importers/IwikiImporter.js';\nimport type { GongfengExtractor } from '../../knowledge/importers/GongfengExtractor.js';\nimport type { KnowledgeEntryType } from '../../knowledge/KnowledgeEntry.js';\nimport type { Config } from '../../config.js';\n\nconst logger = rootLogger.child('KnowledgeRoutes');\n\nexport interface KnowledgeRouterDeps {\n knowledgeStore: KnowledgeStore;\n iwikiImporter: IwikiImporter;\n gongfengExtractor?: GongfengExtractor;\n config: Config;\n}\n\nexport function createKnowledgeRouter(deps: KnowledgeRouterDeps): Router {\n const router = Router();\n const { knowledgeStore, iwikiImporter, gongfengExtractor, config } = deps;\n\n // GET /api/knowledge/entries - list entries\n router.get('/api/knowledge/entries', (req: Request, res: Response) => {\n try {\n const type = req.query.type as KnowledgeEntryType | undefined;\n const q = req.query.q as string | undefined;\n\n let entries;\n if (q) {\n entries = knowledgeStore.search(q);\n } else {\n entries = knowledgeStore.list(type || undefined);\n }\n res.json({ success: true, entries });\n } catch (err) {\n logger.error('Failed to list knowledge entries', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // GET /api/knowledge/entries/:id - get single entry with content\n router.get('/api/knowledge/entries/:id', (req: Request, res: Response) => {\n try {\n const entry = knowledgeStore.get(req.params.id);\n if (!entry) {\n res.status(404).json({ error: 'Entry not found' });\n return;\n }\n res.json({ success: true, entry });\n } catch (err) {\n logger.error('Failed to get knowledge entry', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // POST /api/knowledge/entries - create custom entry\n router.post('/api/knowledge/entries', (req: Request, res: Response) => {\n try {\n const { title, content, tags, type } = req.body as {\n title?: string;\n content?: string;\n tags?: string[];\n type?: KnowledgeEntryType;\n };\n if (!title?.trim() || !content?.trim()) {\n res.status(400).json({ error: 'title and content are required' });\n return;\n }\n const entry = knowledgeStore.create({\n type: type || 'custom',\n title: title.trim(),\n content: content.trim(),\n tags: tags || [],\n });\n res.json({ success: true, entry });\n } catch (err) {\n logger.error('Failed to create knowledge entry', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // PUT /api/knowledge/entries/:id - update entry\n router.put('/api/knowledge/entries/:id', (req: Request, res: Response) => {\n try {\n const { title, content, tags } = req.body as {\n title?: string;\n content?: string;\n tags?: string[];\n };\n const entry = knowledgeStore.update(req.params.id, { title, content, tags });\n if (!entry) {\n res.status(404).json({ error: 'Entry not found' });\n return;\n }\n res.json({ success: true, entry });\n } catch (err) {\n logger.error('Failed to update knowledge entry', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // DELETE /api/knowledge/entries/:id\n router.delete('/api/knowledge/entries/:id', (req: Request, res: Response) => {\n try {\n const deleted = knowledgeStore.delete(req.params.id);\n if (!deleted) {\n res.status(404).json({ error: 'Entry not found' });\n return;\n }\n res.json({ success: true });\n } catch (err) {\n logger.error('Failed to delete knowledge entry', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // POST /api/knowledge/analyze - full analysis (SSE with progress)\n router.post('/api/knowledge/analyze', (req: Request, res: Response) => {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n const workDir = config.project.workDir;\n const startedAt = new Date().toISOString();\n const total = 4;\n let heartbeat: ReturnType<typeof setInterval> | undefined;\n let closed = false;\n\n function sendProgress(data: Record<string, unknown>) {\n if (closed) return;\n try { res.write('data: ' + JSON.stringify({ ...data, startedAt }) + '\\n\\n'); } catch { /* client gone */ }\n }\n\n (async () => {\n try {\n sendProgress({ step: 'collecting', current: 1, total, message: '收集项目信息...' });\n const { collectStaticInfo } = await import('../../knowledge/KnowledgeAnalyzer.js');\n await collectStaticInfo(workDir);\n\n sendProgress({ step: 'analyzing', current: 2, total, message: 'AI 分析中...' });\n const aiStart = Date.now();\n heartbeat = setInterval(() => {\n sendProgress({ step: 'analyzing', current: 2, total, message: 'AI 分析中...', elapsed: Date.now() - aiStart });\n }, 3000);\n\n const { createAIRunner } = await import('../../ai-runner/index.js');\n const runner = createAIRunner(config.ai);\n const { analyze } = await import('../../knowledge/KnowledgeAnalyzer.js');\n const knowledge = await analyze({ workDir, aiRunner: runner });\n clearInterval(heartbeat);\n heartbeat = undefined;\n\n sendProgress({ step: 'saving', current: 3, total, message: '保存分析结果...' });\n const { projectKnowledgeToMarkdown } = await import('../../knowledge/KnowledgeStore.js');\n const markdown = projectKnowledgeToMarkdown(knowledge);\n knowledgeStore.upsertProjectMeta(markdown, knowledge);\n knowledgeStore.setLastAnalyzedAt(knowledge.generatedAt);\n\n sendProgress({ step: 'done', current: 4, total, message: '分析完成' });\n } catch (err) {\n if (heartbeat) clearInterval(heartbeat);\n sendProgress({ step: 'error', error: (err as Error).message });\n } finally {\n res.end();\n }\n })();\n\n req.on('close', () => {\n closed = true;\n if (heartbeat) clearInterval(heartbeat);\n res.end();\n });\n });\n\n // POST /api/knowledge/analyze-incremental - incremental analysis (SSE with progress)\n router.post('/api/knowledge/analyze-incremental', (req: Request, res: Response) => {\n res.setHeader('Content-Type', 'text/event-stream');\n res.setHeader('Cache-Control', 'no-cache');\n res.setHeader('Connection', 'keep-alive');\n res.setHeader('X-Accel-Buffering', 'no');\n res.flushHeaders();\n\n const startedAt = new Date().toISOString();\n const total = 3;\n let heartbeat: ReturnType<typeof setInterval> | undefined;\n let closed = false;\n\n function sendProgress(data: Record<string, unknown>) {\n if (closed) return;\n try { res.write('data: ' + JSON.stringify({ ...data, startedAt }) + '\\n\\n'); } catch { /* client gone */ }\n }\n\n (async () => {\n try {\n sendProgress({ step: 'collecting', current: 1, total, message: '检测变更并收集信息...' });\n\n const { createAIRunner } = await import('../../ai-runner/index.js');\n const { analyzeIncremental } = await import('../../knowledge/KnowledgeAnalyzer.js');\n const runner = createAIRunner(config.ai);\n\n sendProgress({ step: 'analyzing', current: 2, total, message: '增量分析中...' });\n const aiStart = Date.now();\n heartbeat = setInterval(() => {\n sendProgress({ step: 'analyzing', current: 2, total, message: '增量分析中...', elapsed: Date.now() - aiStart });\n }, 3000);\n\n const result = await analyzeIncremental({\n workDir: config.project.workDir,\n aiRunner: runner,\n store: knowledgeStore,\n });\n clearInterval(heartbeat);\n heartbeat = undefined;\n\n if (!result) {\n sendProgress({ step: 'no_changes', current: total, total, message: '自上次分析以来无变更' });\n } else {\n sendProgress({ step: 'done', current: 3, total, message: '增量分析完成', changedFiles: result.changedFiles });\n }\n } catch (err) {\n if (heartbeat) clearInterval(heartbeat);\n sendProgress({ step: 'error', error: (err as Error).message });\n } finally {\n res.end();\n }\n })();\n\n req.on('close', () => {\n closed = true;\n if (heartbeat) clearInterval(heartbeat);\n res.end();\n });\n });\n\n // POST /api/knowledge/import/iwiki - import iwiki page\n router.post('/api/knowledge/import/iwiki', async (req: Request, res: Response) => {\n try {\n const { url } = req.body as { url?: string };\n if (!url?.trim()) {\n res.status(400).json({ error: 'url is required' });\n return;\n }\n const entry = await iwikiImporter.importFromUrl(url.trim());\n res.json({ success: true, entry });\n } catch (err) {\n logger.error('Failed to import iwiki page', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // POST /api/knowledge/import/gongfeng - extract from gongfeng\n router.post('/api/knowledge/import/gongfeng', async (req: Request, res: Response) => {\n try {\n if (!gongfengExtractor) {\n res.status(400).json({ error: 'Gongfeng extractor not available' });\n return;\n }\n const { type, iid } = req.body as { type?: 'issue' | 'mr'; iid?: number };\n if (!type || !iid) {\n res.status(400).json({ error: 'type and iid are required' });\n return;\n }\n const workDir = config.project.workDir;\n const entry = type === 'issue'\n ? await gongfengExtractor.extractFromIssue(iid, workDir)\n : await gongfengExtractor.extractFromMR(iid, workDir);\n res.json({ success: true, entry });\n } catch (err) {\n logger.error('Failed to extract from gongfeng', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // POST /api/knowledge/entries/:id/sync - re-sync iwiki/gongfeng entry\n router.post('/api/knowledge/entries/:id/sync', async (req: Request, res: Response) => {\n try {\n const entry = knowledgeStore.get(req.params.id);\n if (!entry) {\n res.status(404).json({ error: 'Entry not found' });\n return;\n }\n if (entry.type === 'iwiki') {\n const updated = await iwikiImporter.sync(req.params.id);\n res.json({ success: true, entry: updated });\n } else {\n res.status(400).json({ error: 'Only iwiki entries support sync' });\n }\n } catch (err) {\n logger.error('Failed to sync entry', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n // GET /api/knowledge/stats\n router.get('/api/knowledge/stats', (_req: Request, res: Response) => {\n try {\n const stats = knowledgeStore.getStats();\n res.json({ success: true, stats });\n } catch (err) {\n logger.error('Failed to get knowledge stats', { error: (err as Error).message });\n res.status(500).json({ error: (err as Error).message });\n }\n });\n\n return router;\n}\n","import { randomUUID } from 'node:crypto';\nimport { logger as rootLogger } from '../logger.js';\nimport type { AIRunner, StreamEvent } from '../ai-runner/AIRunner.js';\nimport { createAIRunner, type AIConfig } from '../ai-runner/index.js';\nimport type { ChatAgentConfig, Config } from '../config.js';\nimport { buildChatSystemPrompt } from '../prompts/chat-templates.js';\nimport { getProjectKnowledge } from '../knowledge/index.js';\nimport type { KnowledgeStore } from '../knowledge/KnowledgeStore.js';\n\nconst logger = rootLogger.child('Chat');\n\nexport interface ChatMessage {\n id: string;\n role: 'user' | 'assistant';\n content: string;\n timestamp: string;\n}\n\nexport type ChatSessionStatus = 'idle' | 'thinking' | 'error';\n\nexport interface ChatSession {\n id: string;\n title: string;\n messages: ChatMessage[];\n status: ChatSessionStatus;\n error?: string;\n aiSessionId?: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface ChatStreamEvent {\n type: 'message:chunk' | 'message:complete' | 'message:thinking' | 'error' | 'done';\n data: unknown;\n messageId?: string;\n}\n\nfunction agentConfigToAIConfig(\n agentCfg: ChatAgentConfig,\n timeoutMs: number,\n): AIConfig {\n return {\n mode: agentCfg.mode,\n binary: agentCfg.binary,\n phaseTimeoutMs: timeoutMs,\n nvmNodeVersion: agentCfg.nvmNodeVersion,\n model: agentCfg.model,\n };\n}\n\nexport class ChatService {\n private sessions = new Map<string, ChatSession>();\n private runner: AIRunner;\n private config: Config['chat'];\n private workDir: string;\n private knowledgeStore?: KnowledgeStore;\n\n constructor(config: Config, knowledgeStore?: KnowledgeStore) {\n this.config = config.chat;\n this.workDir = config.project.workDir;\n this.knowledgeStore = knowledgeStore;\n this.runner = createAIRunner(\n agentConfigToAIConfig(this.config.agent, this.config.timeoutMs),\n );\n }\n\n createSession(title?: string): ChatSession {\n const session: ChatSession = {\n id: randomUUID(),\n title: title || '新对话',\n messages: [],\n status: 'idle',\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n this.sessions.set(session.id, session);\n logger.info('Created chat session', { sessionId: session.id });\n return session;\n }\n\n getSession(id: string): ChatSession | undefined {\n return this.sessions.get(id);\n }\n\n listSessions(): ChatSession[] {\n return Array.from(this.sessions.values())\n .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n }\n\n deleteSession(id: string): boolean {\n return this.sessions.delete(id);\n }\n\n async sendMessage(\n sessionId: string,\n content: string,\n onEvent?: (event: ChatStreamEvent) => void,\n ): Promise<ChatMessage> {\n const session = this.requireSession(sessionId);\n\n if (session.messages.length >= this.config.maxSessionMessages) {\n throw new Error(`Session message limit reached (${this.config.maxSessionMessages})`);\n }\n\n const userMessage: ChatMessage = {\n id: randomUUID(),\n role: 'user',\n content,\n timestamp: new Date().toISOString(),\n };\n session.messages.push(userMessage);\n session.status = 'thinking';\n session.updatedAt = new Date().toISOString();\n\n const assistantMessageId = randomUUID();\n let assistantContent = '';\n\n try {\n // Immediately emit thinking event before spawning AI CLI\n onEvent?.({\n type: 'message:thinking',\n data: { status: 'connecting' },\n messageId: assistantMessageId,\n });\n\n const isFirstMessage = session.messages.length === 1;\n const knowledgeEntries = this.knowledgeStore?.getAllEntries();\n const prompt = isFirstMessage\n ? `${buildChatSystemPrompt(getProjectKnowledge(), knowledgeEntries)}\\n\\n用户问题:${content}`\n : content;\n\n const result = await this.runner.run({\n prompt,\n workDir: this.workDir,\n timeoutMs: this.config.timeoutMs,\n sessionId: session.aiSessionId,\n continueSession: !!session.aiSessionId,\n onStreamEvent: (evt: StreamEvent) => {\n // Accumulate actual AI text from assistant and text events only\n if (evt.content && typeof evt.content === 'object') {\n const content = evt.content as Record<string, unknown>;\n if (content.type === 'assistant') {\n const message = content.message as { content?: Array<{ type?: string; text?: string }> } | undefined;\n if (message?.content && Array.isArray(message.content)) {\n for (const block of message.content) {\n if (block.type === 'text' && block.text) {\n assistantContent += block.text;\n }\n }\n }\n }\n } else if (evt.content && typeof evt.content === 'string') {\n // raw/partial text events\n if (evt.type === 'partial' || evt.type === 'raw') {\n assistantContent += evt.content;\n }\n }\n // Always forward all events to frontend for streaming display\n onEvent?.({\n type: 'message:chunk',\n data: evt,\n messageId: assistantMessageId,\n });\n },\n });\n\n // Prefer accumulated assistant text (actual AI reply) over result.output (may be summary)\n const finalContent = assistantContent.trim()\n ? assistantContent\n : (result.success ? result.output : (result.output || 'AI 未返回内容'));\n\n const assistantMessage: ChatMessage = {\n id: assistantMessageId,\n role: 'assistant',\n content: finalContent,\n timestamp: new Date().toISOString(),\n };\n session.messages.push(assistantMessage);\n session.aiSessionId = result.sessionId ?? session.aiSessionId;\n session.status = result.success ? 'idle' : 'error';\n if (!result.success) {\n session.error = result.output;\n }\n session.updatedAt = new Date().toISOString();\n\n if (session.title === '新对话' && session.messages.length >= 2) {\n session.title = content.slice(0, 50) + (content.length > 50 ? '...' : '');\n }\n\n onEvent?.({\n type: 'message:complete',\n data: { message: assistantMessage },\n messageId: assistantMessageId,\n });\n\n return assistantMessage;\n } catch (err) {\n session.status = 'error';\n session.error = (err as Error).message;\n session.updatedAt = new Date().toISOString();\n\n onEvent?.({\n type: 'error',\n data: { message: (err as Error).message },\n messageId: assistantMessageId,\n });\n\n throw err;\n }\n }\n\n private requireSession(id: string): ChatSession {\n const session = this.sessions.get(id);\n if (!session) {\n throw new Error(`Chat session not found: ${id}`);\n }\n return session;\n }\n}\n","import type { ProjectKnowledge } from '../knowledge/ProjectKnowledge.js';\nimport type { KnowledgeEntry } from '../knowledge/KnowledgeEntry.js';\n\nconst SUMMARY_MAX_CHARS = 500;\n\nexport function buildChatSystemPrompt(\n knowledge: ProjectKnowledge | null,\n knowledgeEntries?: KnowledgeEntry[],\n): string {\n let knowledgeSection = '';\n\n if (knowledge) {\n const parts: string[] = [];\n if (knowledge.structure) {\n parts.push(`- 主要语言:${knowledge.structure.primaryLanguage}`);\n if (knowledge.structure.frameworks.length > 0) {\n parts.push(`- 框架:${knowledge.structure.frameworks.join(', ')}`);\n }\n if (knowledge.structure.description) {\n parts.push(`- 描述:${knowledge.structure.description}`);\n }\n }\n if (knowledge.toolchain) {\n parts.push(`- 包管理器:${knowledge.toolchain.packageManager}`);\n }\n if (parts.length > 0) {\n knowledgeSection = `\\n**项目知识库:**\\n${parts.join('\\n')}\\n`;\n }\n }\n\n let entriesSection = '';\n if (knowledgeEntries && knowledgeEntries.length > 0) {\n const entryParts = knowledgeEntries.map(e => {\n const typeLabel = ({ 'project-meta': '项目分析', custom: '自定义', iwiki: 'iwiki文档', gongfeng: '工蜂提炼' })[e.type] || e.type;\n const summary = e.content.length > SUMMARY_MAX_CHARS\n ? e.content.slice(0, SUMMARY_MAX_CHARS) + '...'\n : e.content;\n return `### [${typeLabel}] ${e.title}\\n${summary}`;\n });\n entriesSection = `\\n**知识条目(共 ${knowledgeEntries.length} 条):**\\n\\n${entryParts.join('\\n\\n')}\\n`;\n }\n\n return `你是一个智能助手,专注于为开发者提供技术咨询和项目帮助。\n\n你的职责:\n1. 解答技术问题(编程语言、框架、工具链等)\n2. 提供项目相关的使用指南和最佳实践\n3. 帮助分析和解决开发中遇到的问题\n4. 给出代码示例和实现建议\n\n回复原则:\n- 使用清晰简洁的语言\n- 给出具体可操作的建议\n- 必要时提供代码示例\n- 如果不确定,明确说明并给出可能的方向\n- 使用 Markdown 格式组织回复\n${knowledgeSection}${entriesSection}\n请直接回答用户的问题,不要输出多余的寒暄。`;\n}\n","import express from 'express';\nimport { createWebhookRouter, WebhookHandlerDeps } from './WebhookHandler.js';\nimport { IntentRecognizer } from './IntentRecognizer.js';\nimport type { IssueTracker } from '../tracker/IssueTracker.js';\nimport type { PipelineOrchestrator } from '../orchestrator/PipelineOrchestrator.js';\nimport type { SupplementStore } from '../supplement/SupplementStore.js';\nimport type { GongfengClient } from '../clients/GongfengClient.js';\nimport type { Config } from '../config.js';\nimport type { IssuePoller } from '../poller/IssuePoller.js';\nimport { logger as rootLogger } from '../logger.js';\nimport type { Server } from 'node:http';\n\nconst logger = rootLogger.child('WebhookServer');\n\nexport interface WebhookServerDeps {\n tracker: IssueTracker;\n orchestrator: PipelineOrchestrator;\n supplementStore: SupplementStore;\n gongfeng: GongfengClient;\n config: Config;\n poller?: IssuePoller;\n}\n\nexport class WebhookServer {\n private app: express.Application;\n private server: Server | null = null;\n private port: number;\n\n constructor(deps: WebhookServerDeps) {\n this.port = deps.config.webhook.port;\n\n // 使用 webhook.llmBinary(默认 claude-internal)而非 ai.binary,\n // 因为意图识别需要轻量级 CLI stdin/stdout 接口,cursor CLI 不支持此模式。\n // 详见 IntentRecognizer.ts 类注释。\n const intentRecognizer = deps.config.webhook.llmFallback\n ? new IntentRecognizer({\n binary: deps.config.webhook.llmBinary,\n nvmNodeVersion: deps.config.ai.nvmNodeVersion,\n model: deps.config.ai.model,\n })\n : undefined;\n\n const handlerDeps: WebhookHandlerDeps = {\n tracker: deps.tracker,\n orchestrator: deps.orchestrator,\n supplementStore: deps.supplementStore,\n gongfeng: deps.gongfeng,\n config: deps.config,\n intentRecognizer,\n poller: deps.poller,\n };\n\n this.app = express();\n this.app.use(express.json());\n this.app.use(createWebhookRouter(handlerDeps));\n\n this.app.get('/health', (_req, res) => {\n res.json({ status: 'ok', service: 'webhook' });\n });\n }\n\n start(): Promise<void> {\n return new Promise((resolve) => {\n this.server = this.app.listen(this.port, () => {\n logger.info(`Webhook server listening on port ${this.port}`);\n resolve();\n });\n });\n }\n\n stop(): void {\n if (this.server) {\n this.server.close();\n this.server = null;\n logger.info('Webhook server stopped');\n }\n }\n}\n","import { Router, Request, Response } from 'express';\nimport { containsTrigger, extractCommandText, parseExact } from './CommandParser.js';\nimport { IntentRecognizer } from './IntentRecognizer.js';\nimport { CommandExecutor, CommandExecutorDeps } from './CommandExecutor.js';\nimport { NoteDeduplicator } from './NoteDeduplicator.js';\nimport type { Config } from '../config.js';\nimport { logger as rootLogger } from '../logger.js';\nimport { t } from '../i18n/index.js';\n\nconst logger = rootLogger.child('WebhookHandler');\n\nexport interface NoteEvent {\n object_kind: string;\n event_type?: string;\n user: { username: string; name: string; user_id?: number };\n object_attributes: {\n id: number;\n note: string;\n noteable_type: string;\n noteable_id: number | string;\n };\n issue?: {\n id: number | null;\n iid: number;\n title: string;\n };\n merge_request?: {\n id: number;\n iid: number;\n title: string;\n source_branch: string;\n target_branch: string;\n state: string;\n };\n}\n\nexport interface WebhookHandlerDeps extends CommandExecutorDeps {\n config: Config;\n intentRecognizer?: IntentRecognizer;\n}\n\nexport function createWebhookRouter(deps: WebhookHandlerDeps): Router {\n const router = Router();\n const executor = new CommandExecutor(deps);\n const dedup = new NoteDeduplicator();\n const { config, intentRecognizer } = deps;\n\n const selfToken = config.gongfeng.privateToken;\n\n router.post('/webhook/gongfeng', async (req: Request, res: Response) => {\n if (!config.webhook.enabled) {\n res.status(403).json({ error: 'Webhook is disabled' });\n return;\n }\n\n if (config.webhook.secret) {\n const token = req.headers['x-gitlab-token'] as string | undefined;\n if (token !== config.webhook.secret) {\n logger.warn('Webhook token mismatch');\n res.status(401).json({ error: 'Invalid token' });\n return;\n }\n }\n\n const event = req.body as NoteEvent;\n\n const noteBody = event.object_attributes.note;\n if (!containsTrigger(noteBody)) {\n res.json({ ignored: true, reason: 'no trigger found' });\n return;\n }\n\n if (isSelfNote(event, selfToken)) {\n res.json({ ignored: true, reason: 'self-posted note' });\n return;\n }\n\n const noteId = event.object_attributes.id;\n if (dedup.isDuplicate(noteId)) {\n logger.debug('Duplicate note, skipping', { noteId });\n res.json({ ignored: true, reason: 'duplicate' });\n return;\n }\n\n if (isNoteOnIssue(event)) {\n const issueIid = event.issue?.iid;\n const issueId = event.issue?.id;\n if (!issueIid) {\n res.status(400).json({ error: 'Missing issue iid in webhook payload' });\n return;\n }\n if (!issueId) {\n logger.info('Webhook received with null issue id (likely a test ping)', { issueIid });\n res.json({ accepted: true, noteId, issueIid, test: true });\n return;\n }\n\n res.json({ accepted: true, noteId, issueIid });\n\n processCommandAsync(\n noteBody, issueIid, issueId, executor, intentRecognizer, config,\n deps.tracker, deps.gongfeng,\n );\n } else if (isNoteOnMergeRequest(event)) {\n const mr = event.merge_request!;\n res.json({ accepted: true, noteId, mrIid: mr.iid });\n\n processMRCommandAsync(\n noteBody, mr, executor, deps.tracker, deps.gongfeng,\n );\n } else {\n res.json({ ignored: true, reason: 'not a note on issue or MR' });\n }\n });\n\n return router;\n}\n\nconst HELP_TEXT_FUNC = () => t('webhook.helpText');\n\nasync function processCommandAsync(\n noteBody: string,\n issueIid: number,\n issueId: number,\n executor: CommandExecutor,\n intentRecognizer: IntentRecognizer | undefined,\n config: Config,\n tracker: { get(iid: number): { state: string } | undefined },\n gongfeng: { createIssueNote(issueId: number, body: string): Promise<void> },\n): Promise<void> {\n try {\n const cmdText = extractCommandText(noteBody);\n if (!cmdText) return;\n\n let command = parseExact(cmdText);\n\n if (!command && intentRecognizer && config.webhook.llmFallback) {\n const record = tracker.get(issueIid);\n const state = record?.state;\n logger.info('Falling back to LLM intent recognition', { issueIid });\n command = await intentRecognizer.recognize(cmdText, state);\n }\n\n if (!command) {\n logger.info('Could not parse command from note', { issueIid, text: cmdText.slice(0, 100) });\n await gongfeng.createIssueNote(issueId, HELP_TEXT_FUNC()).catch((e) =>\n logger.warn('Failed to reply help text', { error: (e as Error).message }),\n );\n return;\n }\n\n await executor.execute(issueIid, issueId, command);\n } catch (err) {\n logger.error('Failed to process webhook command', {\n issueIid,\n error: (err as Error).message,\n });\n }\n}\n\nfunction isNoteOnIssue(event: NoteEvent): boolean {\n return (\n event.object_kind === 'note' &&\n event.object_attributes?.noteable_type?.toLowerCase() === 'issue' &&\n !!event.issue\n );\n}\n\nfunction isNoteOnMergeRequest(event: NoteEvent): boolean {\n return (\n event.object_kind === 'note' &&\n (event.object_attributes?.noteable_type?.toLowerCase() === 'review'\n || event.object_attributes?.noteable_type?.toLowerCase() === 'mergerequest') &&\n !!event.merge_request\n );\n}\n\nconst MR_SUPPORTED_INTENTS = new Set(['fix-conflict', 'status']);\n\nasync function processMRCommandAsync(\n noteBody: string,\n mr: NonNullable<NoteEvent['merge_request']>,\n executor: CommandExecutor,\n tracker: { get(iid: number): { state: string; branchName: string; issueId: number } | undefined; getAll(): Array<{ issueIid: number; issueId: number; branchName: string }> },\n gongfeng: { createIssueNote(issueId: number, body: string): Promise<void>; createMergeRequestNote(mrIid: number, body: string): Promise<void> },\n): Promise<void> {\n try {\n const cmdText = extractCommandText(noteBody);\n if (!cmdText) return;\n\n const command = parseExact(cmdText);\n if (!command) {\n await gongfeng.createMergeRequestNote(mr.iid, HELP_TEXT_FUNC()).catch((e) =>\n logger.warn('Failed to reply help text on MR', { error: (e as Error).message }),\n );\n return;\n }\n\n if (!MR_SUPPORTED_INTENTS.has(command.intent)) {\n await gongfeng.createMergeRequestNote(\n mr.iid,\n `\\`${command.intent}\\` command is not supported on MR comments. Please use Issue comments instead.`,\n ).catch((e) =>\n logger.warn('Failed to reply on MR', { error: (e as Error).message }),\n );\n return;\n }\n\n // Find issue by source branch\n const allRecords = tracker.getAll();\n const record = allRecords.find(r => r.branchName === mr.source_branch);\n if (!record) {\n await gongfeng.createMergeRequestNote(\n mr.iid,\n `Could not find a tracked issue for branch \\`${mr.source_branch}\\`.`,\n ).catch((e) =>\n logger.warn('Failed to reply on MR', { error: (e as Error).message }),\n );\n return;\n }\n\n const result = await executor.execute(record.issueIid, record.issueId, command);\n\n // Also reply on the MR\n try {\n const prefix = result.success ? '' : '> **Failed**\\n>\\n> ';\n await gongfeng.createMergeRequestNote(mr.iid, `${prefix}${result.message}`);\n } catch (err) {\n logger.warn('Failed to reply on MR', { mrIid: mr.iid, error: (err as Error).message });\n }\n } catch (err) {\n logger.error('Failed to process MR webhook command', {\n mrIid: mr.iid,\n error: (err as Error).message,\n });\n }\n}\n\n/**\n * Heuristic to avoid processing notes posted by the bot itself.\n * We check if the note author username matches the token owner.\n * This is imperfect but works for most setups.\n */\nfunction isSelfNote(_event: NoteEvent, _selfToken: string): boolean {\n // Gongfeng webhook payloads include user info but not a direct token mapping.\n // For now, we rely on the fact that bot-posted notes won't contain @issue-auto.\n // A more robust check can be added by comparing event.user.username against\n // a configured bot username (WEBHOOK_BOT_USERNAME env var).\n return false;\n}\n","export type CommandIntent =\n | 'retry'\n | 'retry-from'\n | 'supplement'\n | 'approve'\n | 'reject'\n | 'status'\n | 'restart'\n | 'preview'\n | 'stop-preview'\n | 'clean-notes'\n | 'fix-conflict';\n\nexport interface ParsedCommand {\n intent: CommandIntent;\n phase?: string;\n context?: string;\n feedback?: string;\n}\n\nconst TRIGGERS = ['@issue-auto', '@iaf'];\n\nconst PHASE_ALIAS: Record<string, string> = {\n '分析': 'analysis', '需求分析': 'analysis',\n '设计': 'design', '系统设计': 'design',\n '实现': 'implement', '实施': 'implement', '编码': 'implement',\n '验证': 'verify', '测试': 'verify',\n '规划': 'plan', '构建': 'build',\n};\n\nfunction resolvePhase(raw: string): string {\n const lower = raw.toLowerCase();\n return PHASE_ALIAS[lower] ?? lower;\n}\n\nconst EXACT_PATTERNS: Array<{\n regex: RegExp;\n build: (match: RegExpMatchArray) => ParsedCommand;\n}> = [\n {\n regex: /retry-from\\s+(\\S+)/i,\n build: (m) => ({ intent: 'retry-from', phase: resolvePhase(m[1]) }),\n },\n {\n regex: /(?:从|回到)\\s*(\\S+?)\\s*(?:阶段)?(?:重[试来做新]|开始)/,\n build: (m) => ({ intent: 'retry-from', phase: resolvePhase(m[1]) }),\n },\n {\n regex: /retry\\b/i,\n build: () => ({ intent: 'retry' }),\n },\n {\n regex: /重试|再试/,\n build: () => ({ intent: 'retry' }),\n },\n {\n regex: /restart\\b/i,\n build: () => ({ intent: 'restart' }),\n },\n {\n regex: /(?:重新开始|从头(?:开始|来|做)|重做)/,\n build: () => ({ intent: 'restart' }),\n },\n {\n regex: /approve\\b/i,\n build: () => ({ intent: 'approve' }),\n },\n {\n regex: /(?:批准|通过|同意|LGTM)/i,\n build: () => ({ intent: 'approve' }),\n },\n {\n regex: /reject\\s+([\\s\\S]+)/i,\n build: (m) => ({ intent: 'reject', feedback: m[1].trim() }),\n },\n {\n regex: /(?:驳回|拒绝|打回)[::\\s]*([\\s\\S]+)/,\n build: (m) => ({ intent: 'reject', feedback: m[1].trim() }),\n },\n {\n regex: /supplement\\s+([\\s\\S]+)/i,\n build: (m) => ({ intent: 'supplement', context: m[1].trim() }),\n },\n {\n regex: /(?:补充)[::\\s]*([\\s\\S]+)/,\n build: (m) => ({ intent: 'supplement', context: m[1].trim() }),\n },\n {\n regex: /status\\b/i,\n build: () => ({ intent: 'status' }),\n },\n {\n regex: /(?:状态|什么状态|进度|查询)/,\n build: () => ({ intent: 'status' }),\n },\n {\n regex: /stop-preview\\b/i,\n build: () => ({ intent: 'stop-preview' }),\n },\n {\n regex: /(?:停止预览|关闭预览|停止体验)/,\n build: () => ({ intent: 'stop-preview' }),\n },\n {\n regex: /preview\\b/i,\n build: () => ({ intent: 'preview' }),\n },\n {\n regex: /(?:预览|体验|preview环境)/,\n build: () => ({ intent: 'preview' }),\n },\n {\n regex: /clean-notes\\b/i,\n build: () => ({ intent: 'clean-notes' }),\n },\n {\n regex: /(?:清理评论|清除评论|删除评论)/,\n build: () => ({ intent: 'clean-notes' }),\n },\n {\n regex: /fix-conflict\\b/i,\n build: () => ({ intent: 'fix-conflict' }),\n },\n {\n regex: /(?:修复冲突|解决冲突|处理冲突|冲突修复|fix\\s*冲突)/,\n build: () => ({ intent: 'fix-conflict' }),\n },\n];\n\nexport function containsTrigger(text: string): boolean {\n const lower = text.toLowerCase();\n return TRIGGERS.some(t => lower.includes(t));\n}\n\n/**\n * Extract the portion of text after the trigger (@issue-auto or @IAF).\n * Returns null if trigger is not found.\n */\nexport function extractCommandText(text: string): string | null {\n const lower = text.toLowerCase();\n for (const trigger of TRIGGERS) {\n const idx = lower.indexOf(trigger);\n if (idx >= 0) return text.slice(idx + trigger.length).trim();\n }\n return null;\n}\n\n/**\n * Try to parse an exact command from the text after the trigger.\n * Returns null if no pattern matches (caller should fall back to LLM).\n */\nexport function parseExact(commandText: string): ParsedCommand | null {\n for (const { regex, build } of EXACT_PATTERNS) {\n const match = commandText.match(regex);\n if (match) return build(match);\n }\n return null;\n}\n\n/**\n * Full parse pipeline: extract trigger text, then try exact match.\n * Returns null if trigger not found or no exact match.\n */\nexport function parseCommand(fullText: string): ParsedCommand | null {\n const commandText = extractCommandText(fullText);\n if (commandText === null) return null;\n return parseExact(commandText);\n}\n","import type { ParsedCommand } from './CommandParser.js';\nimport type { IssueTracker } from '../tracker/IssueTracker.js';\nimport type { PipelineOrchestrator } from '../orchestrator/PipelineOrchestrator.js';\nimport type { SupplementStore } from '../supplement/SupplementStore.js';\nimport type { GongfengClient } from '../clients/GongfengClient.js';\nimport type { Config } from '../config.js';\nimport type { IssuePoller } from '../poller/IssuePoller.js';\nimport { IssueState } from '../tracker/IssueState.js';\nimport { getPipelineDef, collectStateLabels } from '../pipeline/PipelineDefinition.js';\nimport { PlanPersistence } from '../persistence/PlanPersistence.js';\nimport { eventBus } from '../events/EventBus.js';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport { logger as rootLogger } from '../logger.js';\nimport { t } from '../i18n/index.js';\n\nconst logger = rootLogger.child('CommandExecutor');\n\nexport interface CommandExecutorDeps {\n tracker: IssueTracker;\n orchestrator: PipelineOrchestrator;\n supplementStore: SupplementStore;\n gongfeng: GongfengClient;\n config: Config;\n poller?: IssuePoller;\n}\n\nexport interface ExecutionResult {\n success: boolean;\n message: string;\n}\n\nexport class CommandExecutor {\n private tracker: IssueTracker;\n private orchestrator: PipelineOrchestrator;\n private supplementStore: SupplementStore;\n private gongfeng: GongfengClient;\n private config: Config;\n private poller?: IssuePoller;\n\n constructor(deps: CommandExecutorDeps) {\n this.tracker = deps.tracker;\n this.orchestrator = deps.orchestrator;\n this.supplementStore = deps.supplementStore;\n this.gongfeng = deps.gongfeng;\n this.config = deps.config;\n this.poller = deps.poller;\n }\n\n async execute(\n issueIid: number,\n issueId: number,\n command: ParsedCommand,\n ): Promise<ExecutionResult> {\n logger.info('Executing webhook command', { issueIid, command });\n\n let result: ExecutionResult;\n try {\n result = await this.dispatch(issueIid, command);\n } catch (err) {\n const msg = (err as Error).message;\n logger.error('Webhook command failed', { issueIid, error: msg });\n result = { success: false, message: msg };\n }\n\n await this.replyToIssue(issueId, result);\n return result;\n }\n\n private async dispatch(iid: number, cmd: ParsedCommand): Promise<ExecutionResult> {\n switch (cmd.intent) {\n case 'retry': return this.handleRetry(iid);\n case 'retry-from': return this.handleRetryFrom(iid, cmd.phase, cmd.context);\n case 'supplement': return this.handleSupplement(iid, cmd.context);\n case 'approve': return this.handleApprove(iid);\n case 'reject': return this.handleReject(iid, cmd.feedback);\n case 'status': return this.handleStatus(iid);\n case 'restart': return this.handleRestart(iid);\n case 'preview': return this.handlePreview(iid);\n case 'stop-preview': return this.handleStopPreview(iid);\n case 'clean-notes': return this.handleCleanNotes(iid);\n case 'fix-conflict': return this.handleFixConflict(iid);\n default: return { success: false, message: 'Unknown command' };\n }\n }\n\n private handleRetry(iid: number): ExecutionResult {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n if (record.state !== IssueState.Failed) {\n return this.fail(`Issue not in failed state (current: ${record.state})`);\n }\n const ok = this.tracker.resetForRetry(iid);\n if (!ok) return this.fail('Reset for retry failed');\n return this.ok(`Issue #${iid} has been reset and will retry on the next drive cycle.`);\n }\n\n private handleRetryFrom(iid: number, phase?: string, ctx?: string): ExecutionResult {\n if (!phase) return this.fail('Phase is required for retry-from (e.g. design, implement)');\n if (ctx) this.saveSupplement(iid, ctx);\n\n try {\n this.orchestrator.retryFromPhase(iid, phase);\n } catch (err) {\n return this.fail((err as Error).message);\n }\n\n const extra = ctx ? '\\nSupplement info recorded.' : '';\n return this.ok(`Issue #${iid} will restart from **${phase}** phase.${extra}`);\n }\n\n private handleSupplement(iid: number, ctx?: string): ExecutionResult {\n if (!ctx?.trim()) return this.fail('Supplement content cannot be empty');\n this.saveSupplement(iid, ctx);\n return this.ok('Supplement info recorded. AI will reference it on next execution.');\n }\n\n private handleApprove(iid: number): ExecutionResult {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n if (record.state !== IssueState.WaitingForReview) {\n return this.fail(`Issue not waiting for review (current: ${record.state})`);\n }\n\n this.tracker.updateState(iid, IssueState.ReviewApproved);\n const def = this.getIssuePipelineDef(record);\n const gate = def.phases.find((p) => p.kind === 'gate');\n if (gate) {\n const workDir = this.getWorktreeWorkDir(iid);\n if (fs.existsSync(workDir)) {\n new PlanPersistence(workDir, iid).updatePhaseProgress(gate.name, 'completed');\n }\n }\n eventBus.emitTyped('review:approved', { issueIid: iid });\n return this.ok('Plan approved. Continuing to next phases.');\n }\n\n private handleReject(iid: number, feedback?: string): ExecutionResult {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n if (record.state !== IssueState.WaitingForReview) {\n return this.fail(`Issue not waiting for review (current: ${record.state})`);\n }\n if (!feedback?.trim()) return this.fail('Feedback is required when rejecting');\n\n const workDir = this.getWorktreeWorkDir(iid);\n if (fs.existsSync(workDir)) {\n new PlanPersistence(workDir, iid).writeReviewFeedback(feedback);\n }\n this.tracker.updateState(iid, IssueState.BranchCreated);\n eventBus.emitTyped('review:rejected', { issueIid: iid, feedback });\n return this.ok('Plan rejected. Will re-plan based on feedback.');\n }\n\n private handleStatus(iid: number): ExecutionResult {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n\n const def = this.getIssuePipelineDef(record);\n const labels = collectStateLabels(def);\n const stateLabel = labels.get(record.state) ?? record.state;\n\n const lines = [\n `**Issue #${iid} Status**`,\n '',\n `- State: **${stateLabel}**`,\n `- Branch: \\`${record.branchName}\\``,\n `- Attempts: ${record.attempts}`,\n `- Pipeline: ${record.pipelineMode ?? 'N/A'}`,\n ];\n if (record.lastError) lines.push(`- Last error: ${record.lastError.slice(0, 200)}`);\n if (record.mrUrl) lines.push(`- MR: ${record.mrUrl}`);\n\n const previewUrl = this.orchestrator.buildPreviewUrl(iid);\n if (previewUrl) {\n const dsm = this.orchestrator.getDevServerManager();\n const status = dsm.getStatus(iid);\n lines.push(`- Preview: ${status.running ? `🌐 ${previewUrl}` : t('cmd.previewStopped')}`);\n }\n\n const baseUrl = this.config.issueNoteSync.webBaseUrl.replace(/\\/$/, '');\n lines.push('', `[View in dashboard](${baseUrl}/?issue=${iid})`);\n return this.ok(lines.join('\\n'));\n }\n\n private async handleRestart(iid: number): Promise<ExecutionResult> {\n try {\n this.poller?.forceReleaseIssue(iid);\n await this.orchestrator.restartIssue(iid);\n } catch (err) {\n return this.fail((err as Error).message);\n }\n return this.ok(`Issue #${iid} has been fully reset and will restart from scratch.`);\n }\n\n private handlePreview(iid: number): ExecutionResult {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n\n const previewUrl = this.orchestrator.buildPreviewUrl(iid);\n if (!previewUrl) {\n return this.ok(\n t('cmd.previewNotStarted', { iid }),\n );\n }\n\n const dsm = this.orchestrator.getDevServerManager();\n const status = dsm.getStatus(iid);\n const ports = this.orchestrator.getPortAllocator().getPortsForIssue(iid);\n const host = this.orchestrator.getPreviewHost();\n\n const lines = [\n '🌐 **Preview Environment**',\n '',\n `| ${t('cmd.previewTable.component')} | ${t('cmd.previewTable.address')} |`,\n `|------|------|`,\n `| ${t('cmd.previewTable.frontend')} | ${previewUrl} |`,\n `| ${t('cmd.previewTable.backendApi')} | http://${host}:${ports!.backendPort}/api |`,\n '',\n `${t('cmd.previewTable.status')}: ${status.running ? t('cmd.previewRunning') : t('cmd.previewStopped')}`,\n ];\n if (status.startedAt) lines.push(`${t('cmd.previewTable.startedAt')}: ${status.startedAt}`);\n\n return this.ok(lines.join('\\n'));\n }\n\n private handleStopPreview(iid: number): ExecutionResult {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n\n const dsm = this.orchestrator.getDevServerManager();\n const status = dsm.getStatus(iid);\n if (!status.running) {\n return this.ok(t('cmd.noPreview', { iid }));\n }\n\n this.orchestrator.stopPreviewServers(iid);\n return this.ok(t('cmd.previewStoppedMsg', { iid }));\n }\n\n private async handleCleanNotes(iid: number): Promise<ExecutionResult> {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n\n try {\n const deleted = await this.gongfeng.cleanupAgentNotes(record.issueId);\n return this.ok(t('cmd.cleanNotesSuccess', { count: deleted }));\n } catch (err) {\n return this.fail((err as Error).message);\n }\n }\n\n private handleFixConflict(iid: number): ExecutionResult {\n const record = this.tracker.get(iid);\n if (!record) return this.notTracked(iid);\n\n // Only allow in Completed state or Failed with failedAtState=ResolvingConflict\n const isCompleted = record.state === IssueState.Completed;\n const isConflictRetry = record.state === IssueState.Failed\n && record.failedAtState === IssueState.ResolvingConflict;\n\n if (!isCompleted && !isConflictRetry) {\n return this.fail(t('conflict.invalidState', { state: record.state }));\n }\n\n if (!record.mrUrl) {\n return this.fail(t('conflict.noMr', { iid }));\n }\n\n // Fire-and-forget: trigger conflict resolution asynchronously\n this.orchestrator.resolveConflict(iid).catch((err) => {\n logger.error('Async conflict resolution failed', { iid, error: (err as Error).message });\n });\n\n return this.ok(t('conflict.startedMsg'));\n }\n\n private saveSupplement(iid: number, context: string): void {\n const existing = this.supplementStore.get(iid);\n const prev = existing?.freeText?.trim() ?? '';\n const merged = prev ? `${prev}\\n\\n---\\n${context}` : context;\n this.supplementStore.save(iid, {\n requirements: existing?.requirements ?? '',\n acceptanceCriteria: existing?.acceptanceCriteria ?? '',\n scope: existing?.scope ?? '',\n constraints: existing?.constraints ?? '',\n references: existing?.references ?? '',\n freeText: merged,\n tapdId: existing?.tapdId ?? '',\n });\n }\n\n private async replyToIssue(issueId: number, result: ExecutionResult): Promise<void> {\n try {\n const prefix = result.success ? '' : '> **Failed**\\n>\\n> ';\n await this.gongfeng.createIssueNote(issueId, `${prefix}${result.message}`);\n } catch (err) {\n logger.warn('Failed to reply', { issueId, error: (err as Error).message });\n }\n }\n\n private ok(message: string): ExecutionResult {\n return { success: true, message };\n }\n\n private fail(message: string): ExecutionResult {\n return { success: false, message };\n }\n\n private notTracked(iid: number): ExecutionResult {\n return this.fail(`Issue #${iid} is not tracked. Add the auto-finish label to start.`);\n }\n\n private getIssuePipelineDef(record: { pipelineMode?: string }) {\n const mode = record.pipelineMode === 'plan-mode' ? 'plan-mode' : 'classic';\n return getPipelineDef(mode);\n }\n\n private getWorktreeWorkDir(iid: number): string {\n return path.join(\n this.config.project.worktreeBaseDir,\n `issue-${iid}`,\n this.config.project.projectSubDir,\n );\n }\n}\n","/**\n * LRU-based deduplication for webhook note IDs.\n * Prevents the same note from being processed twice\n * (e.g. due to webhook retries or duplicate deliveries).\n */\nexport class NoteDeduplicator {\n private seen: Map<number, number>;\n private maxSize: number;\n\n constructor(maxSize: number = 1000) {\n this.seen = new Map();\n this.maxSize = maxSize;\n }\n\n /**\n * Returns true if this noteId has already been processed.\n * If not, marks it as processed and returns false.\n */\n isDuplicate(noteId: number): boolean {\n if (this.seen.has(noteId)) return true;\n this.seen.set(noteId, Date.now());\n this.evictIfNeeded();\n return false;\n }\n\n get size(): number {\n return this.seen.size;\n }\n\n private evictIfNeeded(): void {\n if (this.seen.size <= this.maxSize) return;\n const oldest = this.seen.keys().next().value;\n if (oldest !== undefined) {\n this.seen.delete(oldest);\n }\n }\n}\n","import { spawn } from 'node:child_process';\nimport type { ParsedCommand, CommandIntent } from './CommandParser.js';\nimport { logger as rootLogger } from '../logger.js';\nimport { t } from '../i18n/index.js';\n\nconst logger = rootLogger.child('IntentRecognizer');\n\nconst VALID_INTENTS: CommandIntent[] = [\n 'retry', 'retry-from', 'supplement', 'approve', 'reject', 'status', 'restart', 'fix-conflict',\n];\n\nconst VALID_PHASES = [\n 'analysis', 'design', 'implement', 'verify', 'plan', 'build',\n];\n\nconst SYSTEM_PROMPT_FUNC = () => t('intent.systemPrompt');\n\nexport interface IntentRecognizerConfig {\n binary: string;\n nvmNodeVersion: string;\n model?: string;\n timeoutMs?: number;\n}\n\n/**\n * 通过 LLM 将自然语言评论解析为结构化指令。\n *\n * **为什么默认使用 claude-internal / codebuddy 而非跟随 AI_RUNNER_MODE?**\n *\n * - `cursor` CLI 不支持 `-p`(stdin prompt)、`--output-format`、`--model` 等参数,\n * 且需要连接 VS Code Server,无法在 PM2 无头进程中运行。\n * - `cursor-agent` 是面向多步骤编码任务的完整 IDE agent,对简单的意图分类来说过重。\n * - `claude-internal` 和 `codebuddy` 都提供轻量级 CLI 接口,支持 stdin 传入 prompt\n * 并返回纯文本,适合在后台服务中做短文本意图识别。\n *\n * 因此 `WEBHOOK_LLM_BINARY` 配置独立于 `AI_RUNNER_MODE`,默认值为 `claude-internal`。\n *\n * @see WebhookServer.ts — 构造 IntentRecognizer 时使用 config.webhook.llmBinary\n * @see config.ts — WEBHOOK_LLM_BINARY 环境变量定义\n */\nexport class IntentRecognizer {\n private binary: string;\n private nvmNodeVersion: string;\n private model?: string;\n private timeoutMs: number;\n\n constructor(config: IntentRecognizerConfig) {\n this.binary = config.binary;\n this.nvmNodeVersion = config.nvmNodeVersion;\n this.model = config.model;\n this.timeoutMs = config.timeoutMs ?? 30_000;\n }\n\n async recognize(userComment: string, issueState?: string): Promise<ParsedCommand | null> {\n const stateHint = issueState ? `\\n当前 Issue 状态: ${issueState}` : '';\n const userPrompt = `${SYSTEM_PROMPT_FUNC()}\\n\\n用户评论:${stateHint}\\n${userComment}`;\n\n try {\n const rawOutput = await this.runLLM(userPrompt);\n return this.parseResponse(rawOutput);\n } catch (err) {\n logger.error('Intent recognition failed', { error: (err as Error).message });\n return null;\n }\n }\n\n /** Visible for testing */\n parseResponse(raw: string): ParsedCommand | null {\n const jsonMatch = raw.match(/\\{[\\s\\S]*\\}/);\n if (!jsonMatch) {\n logger.warn('No JSON found in LLM response', { raw: raw.slice(0, 200) });\n return null;\n }\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(jsonMatch[0]);\n } catch {\n logger.warn('Failed to parse JSON from LLM', { raw: jsonMatch[0].slice(0, 200) });\n return null;\n }\n\n if (parsed.intent === null || parsed.intent === 'null') return null;\n\n const intent = String(parsed.intent) as CommandIntent;\n if (!VALID_INTENTS.includes(intent)) {\n logger.warn('Invalid intent from LLM', { intent });\n return null;\n }\n\n const result: ParsedCommand = { intent };\n\n if (parsed.phase && parsed.phase !== 'null') {\n const phase = String(parsed.phase).toLowerCase();\n if (VALID_PHASES.includes(phase)) {\n result.phase = phase;\n }\n }\n\n if (parsed.context && parsed.context !== 'null') {\n result.context = String(parsed.context).trim();\n }\n\n if (parsed.feedback && parsed.feedback !== 'null') {\n result.feedback = String(parsed.feedback).trim();\n }\n\n return result;\n }\n\n private runLLM(prompt: string): Promise<string> {\n return new Promise((resolve, reject) => {\n const args = ['-p', '-', '--output-format', 'text', '--verbose'];\n if (this.model) args.push('--model', this.model);\n\n const { CLAUDECODE, ...env } = process.env;\n const child = spawn(this.binary, args, {\n env: { ...env, NODE_VERSION: this.nvmNodeVersion },\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n let stdout = '';\n let stderr = '';\n\n child.stdout.on('data', (d) => { stdout += d.toString(); });\n child.stderr.on('data', (d) => { stderr += d.toString(); });\n\n const timer = setTimeout(() => {\n child.kill('SIGTERM');\n reject(new Error(`Intent recognition timed out after ${this.timeoutMs}ms`));\n }, this.timeoutMs);\n\n child.on('close', (code) => {\n clearTimeout(timer);\n if (code !== 0) {\n logger.warn('LLM process exited with non-zero code', { code, stderr: stderr.slice(0, 300) });\n }\n resolve(stdout);\n });\n\n child.on('error', (err) => {\n clearTimeout(timer);\n reject(err);\n });\n\n child.stdin.write(prompt);\n child.stdin.end();\n });\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { eventBus, EventPayload } from '../events/EventBus.js';\nimport { logger as rootLogger } from '../logger.js';\n\nconst logger = rootLogger.child('AgentLogStore');\n\nexport interface AgentLogEntry {\n type: string;\n phase?: string;\n timestamp: string;\n summary: string;\n}\n\nconst MAX_LOGS_PER_ISSUE = 20000;\n\nconst DEBUG_EVENT_TYPES = new Set([\n 'thinking', 'content_block_start', 'content_block_delta',\n 'content_block_stop', 'message_start', 'message_delta',\n 'message_stop', 'ping',\n]);\n\nexport class AgentLogStore {\n private logDir: string;\n\n constructor(dataDir: string) {\n this.logDir = path.join(dataDir, 'agent-logs');\n if (!fs.existsSync(this.logDir)) {\n fs.mkdirSync(this.logDir, { recursive: true });\n }\n }\n\n public startListening(): void {\n eventBus.on('agent:output', (payload: EventPayload) => {\n this.handleAgentOutput(payload);\n });\n\n eventBus.on('pipeline:progress', (payload: EventPayload) => {\n this.handlePipelineProgress(payload);\n });\n\n logger.info('AgentLogStore listening for events');\n }\n\n public getLogs(issueIid: number): AgentLogEntry[] {\n const filePath = this.logFilePath(issueIid);\n if (!fs.existsSync(filePath)) return [];\n\n try {\n const raw = fs.readFileSync(filePath, 'utf-8').trim();\n if (!raw) return [];\n return raw.split('\\n').map(line => JSON.parse(line) as AgentLogEntry);\n } catch (err) {\n logger.warn('Failed to read agent logs', { issueIid, error: (err as Error).message });\n return [];\n }\n }\n\n public clearLogs(issueIid: number): void {\n const filePath = this.logFilePath(issueIid);\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n }\n\n private logFilePath(issueIid: number): string {\n return path.join(this.logDir, `${issueIid}.jsonl`);\n }\n\n private appendLog(issueIid: number, entry: AgentLogEntry): void {\n const filePath = this.logFilePath(issueIid);\n try {\n fs.appendFileSync(filePath, `${JSON.stringify(entry)}\\n`, 'utf-8');\n this.trimIfNeeded(issueIid, filePath);\n } catch (err) {\n logger.warn('Failed to write agent log', { issueIid, error: (err as Error).message });\n }\n }\n\n private trimIfNeeded(issueIid: number, filePath: string): void {\n try {\n const raw = fs.readFileSync(filePath, 'utf-8').trim();\n if (!raw) return;\n const lines = raw.split('\\n');\n if (lines.length > MAX_LOGS_PER_ISSUE) {\n const trimmed = lines.slice(-MAX_LOGS_PER_ISSUE);\n fs.writeFileSync(filePath, `${trimmed.join('\\n')}\\n`, 'utf-8');\n logger.info('Agent logs trimmed', { issueIid, from: lines.length, to: trimmed.length });\n }\n } catch {\n // best-effort trimming\n }\n }\n\n private handleAgentOutput(payload: EventPayload): void {\n const d = payload.data as { issueIid?: number; phase?: string; event?: { type?: string; content?: unknown; timestamp?: string } };\n if (!d?.issueIid || !d.event) return;\n\n const eventType = d.event.type || 'raw';\n if (DEBUG_EVENT_TYPES.has(eventType)) return;\n\n const entry: AgentLogEntry = {\n type: eventType,\n phase: d.phase,\n timestamp: d.event.timestamp || payload.timestamp,\n summary: this.summarizeContent(d.event),\n };\n this.appendLog(d.issueIid, entry);\n }\n\n private handlePipelineProgress(payload: EventPayload): void {\n const d = payload.data as { issueIid?: number; step?: string; message?: string };\n if (!d?.issueIid) return;\n\n const entry: AgentLogEntry = {\n type: 'system',\n phase: d.step,\n timestamp: payload.timestamp,\n summary: d.message || '',\n };\n this.appendLog(d.issueIid, entry);\n }\n\n private summarizeContent(event: { type?: string; content?: unknown; timestamp?: string }): string {\n const { content } = event;\n if (!content || typeof content === 'string') return String(content || '');\n\n if (event.type === 'assistant') {\n return this.extractAssistantText(content);\n }\n if (event.type === 'tool_use') {\n return this.extractToolUseText(content);\n }\n if (event.type === 'tool_result') {\n const text = typeof (content as Record<string, unknown>).content === 'string'\n ? (content as Record<string, unknown>).content as string\n : JSON.stringify((content as Record<string, unknown>).content || '');\n return text.slice(0, 150);\n }\n if (event.type === 'result') {\n const r = content as Record<string, unknown>;\n return ((r.result as string) || JSON.stringify(content)).slice(0, 200);\n }\n\n return JSON.stringify(content).slice(0, 150);\n }\n\n private extractAssistantText(content: unknown): string {\n const msg = (content as Record<string, unknown>).message || content;\n if (typeof msg === 'string') return msg.slice(0, 200);\n const m = msg as Record<string, unknown>;\n if (m.text) return (m.text as string).slice(0, 200);\n if (m.content) {\n const parts = Array.isArray(m.content) ? m.content : [m.content];\n const texts = parts\n .filter((c: Record<string, unknown>) => c.type === 'text')\n .map((c: Record<string, unknown>) => c.text)\n .join(' ');\n return texts.slice(0, 200) || JSON.stringify(content).slice(0, 150);\n }\n return JSON.stringify(content).slice(0, 150);\n }\n\n private extractToolUseText(content: unknown): string {\n const c = content as Record<string, unknown>;\n const tool = c.tool as Record<string, unknown> | undefined;\n const name = tool?.name || c.name || '?';\n const input = (tool?.input || c.input || {}) as Record<string, unknown>;\n const detail = input.path || input.command || input.file_path || '';\n return name + (detail ? `: ${detail}` : '');\n }\n}\n","import { readFileSync, existsSync } from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { logger as rootLogger } from '../logger.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst logger = rootLogger.child('VersionChecker');\n\nexport interface VersionCheckResult {\n currentVersion: string;\n latestVersion: string;\n hasUpdate: boolean;\n}\n\n/**\n * Compare two semver version strings (major.minor.patch).\n * Returns: 1 if a > b, -1 if a < b, 0 if equal.\n */\nexport function compareSemver(a: string, b: string): number {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const va = pa[i] ?? 0;\n const vb = pb[i] ?? 0;\n if (va > vb) return 1;\n if (va < vb) return -1;\n }\n return 0;\n}\n\nexport class VersionChecker {\n private registry: string;\n private packageName: string;\n private currentVersion: string;\n\n constructor(registry: string) {\n this.registry = registry.replace(/\\/$/, '');\n const pkg = this.readPackageJson();\n this.packageName = pkg.name;\n this.currentVersion = pkg.version;\n }\n\n getCurrentVersion(): string {\n return this.currentVersion;\n }\n\n getPackageName(): string {\n return this.packageName;\n }\n\n async check(): Promise<VersionCheckResult> {\n const latestVersion = await this.fetchLatestVersion();\n const hasUpdate = compareSemver(latestVersion, this.currentVersion) > 0;\n\n logger.info('Version check completed', {\n current: this.currentVersion,\n latest: latestVersion,\n hasUpdate,\n });\n\n return {\n currentVersion: this.currentVersion,\n latestVersion,\n hasUpdate,\n };\n }\n\n private async fetchLatestVersion(): Promise<string> {\n const url = `${this.registry}/${encodeURIComponent(this.packageName)}`;\n const response = await fetch(url, {\n signal: AbortSignal.timeout(15_000),\n headers: { Accept: 'application/json' },\n });\n\n if (!response.ok) {\n throw new Error(`Registry returned HTTP ${response.status} for ${this.packageName}`);\n }\n\n const data = (await response.json()) as { 'dist-tags'?: { latest?: string } };\n const latest = data['dist-tags']?.latest;\n if (!latest) {\n throw new Error(`No latest version found in dist-tags for ${this.packageName}`);\n }\n\n return latest;\n }\n\n private readPackageJson(): { name: string; version: string } {\n for (let dir = __dirname; dir !== path.dirname(dir); dir = path.dirname(dir)) {\n const candidate = path.join(dir, 'package.json');\n if (existsSync(candidate)) {\n try {\n const content = JSON.parse(readFileSync(candidate, 'utf-8'));\n if (content.name && content.version) return content;\n } catch { /* skip */ }\n }\n }\n throw new Error('Could not find package.json');\n }\n}\n","import { execFile } from 'node:child_process';\nimport { cpSync, existsSync, rmSync } from 'node:fs';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { logger as rootLogger } from '../logger.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst logger = rootLogger.child('UpdateExecutor');\n\nfunction findProjectRoot(): string {\n for (let dir = __dirname; dir !== path.dirname(dir); dir = path.dirname(dir)) {\n if (existsSync(path.join(dir, 'package.json'))) {\n return dir;\n }\n }\n throw new Error('Could not find project root');\n}\n\nfunction run(cmd: string, args: string[], cwd: string, timeoutMs: number): Promise<string> {\n return new Promise((resolve, reject) => {\n execFile(cmd, args, { cwd, timeout: timeoutMs, maxBuffer: 10 * 1024 * 1024 }, (err, stdout, stderr) => {\n if (err) {\n reject(new Error(`${cmd} ${args.join(' ')} failed: ${stderr || err.message}`));\n return;\n }\n resolve(stdout);\n });\n });\n}\n\nexport class UpdateExecutor {\n private packageName: string;\n private projectRoot: string;\n\n constructor(packageName: string) {\n this.packageName = packageName;\n this.projectRoot = findProjectRoot();\n }\n\n async execute(targetVersion: string): Promise<void> {\n const distDir = path.join(this.projectRoot, 'dist');\n const backupDir = path.join(this.projectRoot, 'dist.backup');\n\n // Step 1: Backup dist/\n logger.info('Backing up dist directory...');\n if (existsSync(backupDir)) {\n rmSync(backupDir, { recursive: true, force: true });\n }\n if (existsSync(distDir)) {\n cpSync(distDir, backupDir, { recursive: true });\n }\n\n try {\n // Step 2: pnpm update\n logger.info('Running pnpm update...', { package: this.packageName, targetVersion });\n await run('pnpm', ['update', this.packageName], this.projectRoot, 120_000);\n\n // Step 3: pnpm build\n logger.info('Running pnpm build...');\n await run('pnpm', ['build'], this.projectRoot, 120_000);\n } catch (err) {\n // Rollback: restore dist from backup\n logger.error('Update failed, rolling back dist...', { error: (err as Error).message });\n if (existsSync(backupDir)) {\n if (existsSync(distDir)) {\n rmSync(distDir, { recursive: true, force: true });\n }\n cpSync(backupDir, distDir, { recursive: true });\n }\n throw err;\n } finally {\n if (existsSync(backupDir)) {\n rmSync(backupDir, { recursive: true, force: true });\n }\n }\n\n // Step 4: pm2 reload\n logger.info('Reloading via PM2...');\n try {\n await run('pm2', ['reload', 'issue-auto-finish'], this.projectRoot, 30_000);\n } catch (err) {\n logger.warn('PM2 reload failed, the process may need manual restart', {\n error: (err as Error).message,\n });\n throw err;\n }\n\n logger.info('Update completed successfully', { version: targetVersion });\n }\n}\n","import { Config } from '../config.js';\nimport { IssuePoller } from '../poller/IssuePoller.js';\nimport { VersionChecker, VersionCheckResult } from './VersionChecker.js';\nimport { UpdateExecutor } from './UpdateExecutor.js';\nimport { eventBus } from '../events/EventBus.js';\nimport { logger as rootLogger } from '../logger.js';\n\nconst logger = rootLogger.child('AutoUpdater');\n\nexport type UpdaterState = 'idle' | 'checking' | 'update-available' | 'draining' | 'updating' | 'completed' | 'failed';\n\nexport interface UpdateStatus {\n state: UpdaterState;\n enabled: boolean;\n currentVersion: string;\n latestVersion: string | null;\n lastCheckAt: string | null;\n lastError: string | null;\n}\n\nconst INITIAL_DELAY_MS = 30_000;\n\nexport class AutoUpdater {\n private config: Config;\n private poller: IssuePoller;\n private versionChecker: VersionChecker;\n private updateExecutor: UpdateExecutor;\n\n private state: UpdaterState = 'idle';\n private latestVersion: string | null = null;\n private lastCheckAt: string | null = null;\n private lastError: string | null = null;\n private updateInProgress = false;\n\n private checkTimer: ReturnType<typeof setInterval> | null = null;\n private initialTimer: ReturnType<typeof setTimeout> | null = null;\n\n constructor(config: Config, poller: IssuePoller) {\n this.config = config;\n this.poller = poller;\n this.versionChecker = new VersionChecker(config.autoUpdate.registry);\n this.updateExecutor = new UpdateExecutor(this.versionChecker.getPackageName());\n }\n\n start(): void {\n if (!this.config.autoUpdate.enabled) {\n logger.info('Auto-update is disabled');\n return;\n }\n\n logger.info('Auto-updater starting', {\n intervalMs: this.config.autoUpdate.intervalMs,\n registry: this.config.autoUpdate.registry,\n });\n\n // Delay first check to let the service stabilize\n this.initialTimer = setTimeout(() => {\n this.initialTimer = null;\n this.performCheck();\n this.checkTimer = setInterval(() => this.performCheck(), this.config.autoUpdate.intervalMs);\n }, INITIAL_DELAY_MS);\n }\n\n stop(): void {\n if (this.initialTimer) {\n clearTimeout(this.initialTimer);\n this.initialTimer = null;\n }\n if (this.checkTimer) {\n clearInterval(this.checkTimer);\n this.checkTimer = null;\n }\n logger.info('Auto-updater stopped');\n }\n\n getStatus(): UpdateStatus {\n return {\n state: this.state,\n enabled: this.config.autoUpdate.enabled,\n currentVersion: this.versionChecker.getCurrentVersion(),\n latestVersion: this.latestVersion,\n lastCheckAt: this.lastCheckAt,\n lastError: this.lastError,\n };\n }\n\n async checkForUpdate(): Promise<VersionCheckResult> {\n this.state = 'checking';\n eventBus.emitTyped('update:checking', {});\n\n try {\n const result = await this.versionChecker.check();\n this.latestVersion = result.latestVersion;\n this.lastCheckAt = new Date().toISOString();\n this.lastError = null;\n\n if (result.hasUpdate) {\n this.state = 'update-available';\n eventBus.emitTyped('update:available', {\n currentVersion: result.currentVersion,\n latestVersion: result.latestVersion,\n });\n } else {\n this.state = 'idle';\n }\n\n return result;\n } catch (err) {\n const message = (err as Error).message;\n this.lastError = message;\n this.state = 'failed';\n eventBus.emitTyped('update:failed', { error: message });\n throw err;\n }\n }\n\n async triggerUpdate(): Promise<void> {\n if (this.updateInProgress) {\n logger.warn('Update already in progress, skipping');\n return;\n }\n this.updateInProgress = true;\n\n try {\n // Check for update if we haven't yet\n if (!this.latestVersion) {\n const result = await this.checkForUpdate();\n if (!result.hasUpdate) {\n logger.info('No update available');\n return;\n }\n }\n\n const targetVersion = this.latestVersion!;\n\n // Drain: pause discovery and wait for active issues\n this.state = 'draining';\n logger.info('Draining active issues before update...');\n this.poller.pauseDiscovery();\n\n const drainStart = Date.now();\n const drainTimeout = this.config.autoUpdate.drainTimeoutMs;\n while (this.poller.getActiveCount() > 0 && Date.now() - drainStart < drainTimeout) {\n logger.info('Waiting for active issues to complete...', {\n active: this.poller.getActiveCount(),\n });\n await new Promise(resolve => setTimeout(resolve, 5_000));\n }\n\n if (this.poller.getActiveCount() > 0) {\n logger.warn('Drain timeout reached, proceeding with update', {\n active: this.poller.getActiveCount(),\n });\n }\n\n // Execute update\n this.state = 'updating';\n eventBus.emitTyped('update:downloading', { version: targetVersion });\n logger.info('Executing update...', { targetVersion });\n\n await this.updateExecutor.execute(targetVersion);\n\n this.state = 'completed';\n eventBus.emitTyped('update:completed', { version: targetVersion });\n logger.info('Update completed', { version: targetVersion });\n } catch (err) {\n const message = (err as Error).message;\n this.lastError = message;\n this.state = 'failed';\n eventBus.emitTyped('update:failed', { error: message });\n logger.error('Update failed', { error: message });\n\n // Resume discovery on failure\n this.poller.resumeDiscovery();\n } finally {\n this.updateInProgress = false;\n }\n }\n\n private async performCheck(): Promise<void> {\n if (this.updateInProgress) return;\n\n try {\n const result = await this.checkForUpdate();\n if (result.hasUpdate) {\n logger.info('New version available, starting update', {\n current: result.currentVersion,\n latest: result.latestVersion,\n });\n await this.triggerUpdate();\n }\n } catch (err) {\n logger.warn('Periodic version check failed', { error: (err as Error).message });\n }\n }\n}\n","import { loadConfig } from './config.js';\nimport { setLocale } from './i18n/index.js';\nimport { loadKnowledge } from './knowledge/index.js';\nimport { logger } from './logger.js';\nimport { GongfengClient } from './clients/GongfengClient.js';\nimport { GitOperations } from './git/GitOperations.js';\nimport { createAIRunner } from './ai-runner/index.js';\nimport { IssueTracker } from './tracker/IssueTracker.js';\nimport { SupplementStore } from './supplement/SupplementStore.js';\nimport { PipelineOrchestrator } from './orchestrator/PipelineOrchestrator.js';\nimport { validatePhaseRegistry } from './phases/PhaseFactory.js';\nimport { CLASSIC_PIPELINE, PLAN_MODE_PIPELINE } from './pipeline/PipelineDefinition.js';\nimport { IssuePoller } from './poller/IssuePoller.js';\nimport { WebServer } from './web/WebServer.js';\nimport { WebhookServer } from './webhook/WebhookServer.js';\nimport { AgentLogStore } from './web/AgentLogStore.js';\nimport { AutoUpdater } from './updater/AutoUpdater.js';\nimport { setShuttingDown } from './shutdown/ShutdownSignal.js';\nimport path from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\nexport async function main(): Promise<void> {\n logger.info('Issue Auto-Finish service starting...');\n\n const config = loadConfig();\n setLocale(config.locale);\n loadKnowledge(config.knowledgePath);\n\n const allAiPhaseNames = [\n ...CLASSIC_PIPELINE.phases.filter(p => p.kind === 'ai').map(p => p.name),\n ...PLAN_MODE_PIPELINE.phases.filter(p => p.kind === 'ai').map(p => p.name),\n ];\n validatePhaseRegistry([...new Set(allAiPhaseNames)]);\n\n // Initialize components\n const gongfeng = new GongfengClient(config.gongfeng);\n const git = new GitOperations(config.project.gitRootDir);\n const aiRunner = createAIRunner(config.ai);\n const dataDir = path.resolve(__dirname, '../data');\n const tracker = new IssueTracker(dataDir);\n\n const supplementStore = new SupplementStore(dataDir);\n\n const agentLogStore = new AgentLogStore(dataDir);\n agentLogStore.startListening();\n\n const orchestrator = new PipelineOrchestrator(config, gongfeng, git, aiRunner, tracker, supplementStore);\n const poller = new IssuePoller(config, gongfeng, tracker, orchestrator);\n\n let webServer: WebServer | null = null;\n const autoUpdater = new AutoUpdater(config, poller);\n\n if (config.web.enabled) {\n webServer = new WebServer({ tracker, config, agentLogStore, orchestrator, gongfeng, supplementStore, mainGit: git, autoUpdater, poller });\n await webServer.start();\n }\n\n let webhookServer: WebhookServer | null = null;\n if (config.webhook.enabled) {\n webhookServer = new WebhookServer({ tracker, config, orchestrator, gongfeng, supplementStore, poller });\n await webhookServer.start();\n }\n\n // --- Startup recovery ---\n const recoveredCount = tracker.recoverInterruptedIssues();\n if (recoveredCount > 0) {\n logger.info('Recovered interrupted issues on startup', { count: recoveredCount });\n }\n await orchestrator.cleanupStaleState();\n\n // --- Graceful shutdown ---\n let shutdownInProgress = false;\n const shutdown = async (): Promise<void> => {\n if (shutdownInProgress) return;\n shutdownInProgress = true;\n\n logger.info('Graceful shutdown initiated');\n\n // 1. Set global shutdown signal — blocks new tasks from starting\n setShuttingDown();\n\n // 2. Stop auto-updater\n autoUpdater.stop();\n\n // 3. Stop polling timers — no new discover/drive cycles\n poller.stop();\n\n // 4. Kill all AI runner child processes\n aiRunner.killAll();\n\n // 5. Stop all DevServer child processes\n orchestrator.getDevServerManager().stopAll();\n\n // 6. Wait for active processIssue() calls to respond to shutdown signal (max 5s)\n const drainStart = Date.now();\n const DRAIN_TIMEOUT_MS = 5_000;\n while (poller.getActiveCount() > 0 && Date.now() - drainStart < DRAIN_TIMEOUT_MS) {\n logger.info('Waiting for active issues to drain...', { active: poller.getActiveCount() });\n await new Promise(resolve => setTimeout(resolve, 500));\n }\n if (poller.getActiveCount() > 0) {\n logger.warn('Drain timeout reached, proceeding with shutdown', { active: poller.getActiveCount() });\n }\n\n // 7. Stop HTTP servers\n webServer?.stop();\n webhookServer?.stop();\n\n logger.info('Graceful shutdown complete');\n process.exit(0);\n };\n\n process.on('SIGINT', () => { shutdown(); });\n process.on('SIGTERM', () => { shutdown(); });\n\n // Start polling\n poller.start();\n autoUpdater.start();\n\n logger.info('Issue Auto-Finish service started', {\n projectPath: config.gongfeng.projectPath,\n workDir: config.project.workDir,\n discoveryIntervalMs: config.poll.discoveryIntervalMs,\n driveIntervalMs: config.poll.driveIntervalMs,\n webUI: config.web.enabled ? `http://localhost:${config.web.port}` : 'disabled',\n webhook: config.webhook.enabled ? `http://localhost:${config.webhook.port}/webhook/gongfeng` : 'disabled',\n });\n}\n"],"mappings":"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","names":["logger","logger","path","fs","path","logger","path","fs","Router","logger","Router","Router","logger","sseWriter","Router","Router","logger","Router","createAIRunner","logger","content","path","logger","express","Router","t","path","fs","logger","fs","path","logger","Router","logger","logger","express","fs","path","logger","path","fs","path","fileURLToPath","__dirname","path","fileURLToPath","logger","existsSync","path","fileURLToPath","__dirname","path","fileURLToPath","logger","existsSync","logger","path","fileURLToPath","__dirname"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/analyze.ts"],"names":[],"mappings":"AAOA,UAAU,qBAAqB;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAsBD,wBAAsB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoC/E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDrE"}
|