@xdevops/issue-auto-finish 1.0.83 → 1.0.85

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.
Files changed (86) hide show
  1. package/dist/{LockNote-7OF7ADI2.js → LockNote-Z2CLDZNN.js} +3 -3
  2. package/dist/{ai-runner-MCGEQGXS.js → ai-runner-SVUNA3FX.js} +2 -2
  3. package/dist/{analyze-ZITN3CSH.js → analyze-SXXPE5XL.js} +3 -3
  4. package/dist/{braindump-LQU65XND.js → braindump-4E5SDMSZ.js} +6 -6
  5. package/dist/{chunk-7FLKETBC.js → chunk-4LFNFRCL.js} +13 -1
  6. package/dist/chunk-4LFNFRCL.js.map +1 -0
  7. package/dist/{chunk-HKI3BON6.js → chunk-4QV6D34Y.js} +3 -3
  8. package/dist/{chunk-UDCMSDNT.js → chunk-5UPYA6KH.js} +528 -214
  9. package/dist/chunk-5UPYA6KH.js.map +1 -0
  10. package/dist/{chunk-MV2CADMB.js → chunk-FWEW5E3B.js} +2 -2
  11. package/dist/{chunk-NZ7K73B7.js → chunk-GXFG4JU6.js} +2 -2
  12. package/dist/{chunk-3V3GQCB7.js → chunk-HDFNMVRQ.js} +2 -2
  13. package/dist/{chunk-3RNGPMRE.js → chunk-HOFYJEJ4.js} +7 -7
  14. package/dist/{chunk-LFN7NUFS.js → chunk-JINMYD56.js} +3 -3
  15. package/dist/{chunk-GV2ORWT3.js → chunk-K2OTLYJI.js} +118 -17
  16. package/dist/chunk-K2OTLYJI.js.map +1 -0
  17. package/dist/{chunk-GDTS2J2P.js → chunk-KTYPZTF4.js} +2 -2
  18. package/dist/{chunk-6S7ERGQ7.js → chunk-P4O4ZXEC.js} +10 -5
  19. package/dist/chunk-P4O4ZXEC.js.map +1 -0
  20. package/dist/{chunk-KWODU7HB.js → chunk-YCYVNRLF.js} +15 -1
  21. package/dist/chunk-YCYVNRLF.js.map +1 -0
  22. package/dist/cli.js +8 -8
  23. package/dist/{config-C7AKWCPA.js → config-QLINHCHD.js} +3 -3
  24. package/dist/{doctor-P2ZH6PFX.js → doctor-37JNBGDN.js} +3 -3
  25. package/dist/errors/PhaseAbortedError.d.ts +13 -0
  26. package/dist/errors/PhaseAbortedError.d.ts.map +1 -0
  27. package/dist/errors/index.d.ts +1 -0
  28. package/dist/errors/index.d.ts.map +1 -1
  29. package/dist/events/EventBus.d.ts +1 -1
  30. package/dist/events/EventBus.d.ts.map +1 -1
  31. package/dist/i18n/locales/en.d.ts.map +1 -1
  32. package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
  33. package/dist/index.js +11 -11
  34. package/dist/{init-D2BQIVVD.js → init-TDKDC6YP.js} +7 -7
  35. package/dist/lib.js +5 -5
  36. package/dist/lifecycle/ActionLifecycle.d.ts +1 -1
  37. package/dist/lifecycle/ActionLifecycle.d.ts.map +1 -1
  38. package/dist/lifecycle/ActionLifecycleManager.d.ts.map +1 -1
  39. package/dist/orchestrator/IssueProcessingContext.d.ts +3 -0
  40. package/dist/orchestrator/IssueProcessingContext.d.ts.map +1 -1
  41. package/dist/orchestrator/PipelineOrchestrator.d.ts +19 -0
  42. package/dist/orchestrator/PipelineOrchestrator.d.ts.map +1 -1
  43. package/dist/orchestrator/steps/FailureHandler.d.ts.map +1 -1
  44. package/dist/orchestrator/steps/PhaseLoopStep.d.ts.map +1 -1
  45. package/dist/phases/BasePhase.d.ts +10 -8
  46. package/dist/phases/BasePhase.d.ts.map +1 -1
  47. package/dist/phases/UatPhase.d.ts +32 -1
  48. package/dist/phases/UatPhase.d.ts.map +1 -1
  49. package/dist/pipeline/PipelineDefinition.d.ts.map +1 -1
  50. package/dist/prompts/templates.d.ts.map +1 -1
  51. package/dist/{restart-KFRHCALK.js → restart-RNXGTDWZ.js} +5 -5
  52. package/dist/run.js +11 -11
  53. package/dist/{start-46GW453L.js → start-27GRO4DP.js} +5 -5
  54. package/dist/tracker/IssueState.d.ts +4 -0
  55. package/dist/tracker/IssueState.d.ts.map +1 -1
  56. package/dist/tracker/IssueTracker.d.ts +2 -0
  57. package/dist/tracker/IssueTracker.d.ts.map +1 -1
  58. package/dist/webhook/CommandExecutor.d.ts +3 -0
  59. package/dist/webhook/CommandExecutor.d.ts.map +1 -1
  60. package/dist/webhook/CommandParser.d.ts +1 -1
  61. package/dist/webhook/CommandParser.d.ts.map +1 -1
  62. package/package.json +2 -1
  63. package/src/web/frontend/dist/assets/{index-GfpCL9Wn.js → index-C4NXoH9S.js} +55 -49
  64. package/src/web/frontend/dist/assets/{index-CPNbFsHB.css → index-C7lorIa0.css} +1 -1
  65. package/src/web/frontend/dist/index.html +2 -2
  66. package/dist/chunk-6S7ERGQ7.js.map +0 -1
  67. package/dist/chunk-7FLKETBC.js.map +0 -1
  68. package/dist/chunk-GV2ORWT3.js.map +0 -1
  69. package/dist/chunk-KWODU7HB.js.map +0 -1
  70. package/dist/chunk-UDCMSDNT.js.map +0 -1
  71. /package/dist/{LockNote-7OF7ADI2.js.map → LockNote-Z2CLDZNN.js.map} +0 -0
  72. /package/dist/{ai-runner-MCGEQGXS.js.map → ai-runner-SVUNA3FX.js.map} +0 -0
  73. /package/dist/{analyze-ZITN3CSH.js.map → analyze-SXXPE5XL.js.map} +0 -0
  74. /package/dist/{braindump-LQU65XND.js.map → braindump-4E5SDMSZ.js.map} +0 -0
  75. /package/dist/{chunk-HKI3BON6.js.map → chunk-4QV6D34Y.js.map} +0 -0
  76. /package/dist/{chunk-MV2CADMB.js.map → chunk-FWEW5E3B.js.map} +0 -0
  77. /package/dist/{chunk-NZ7K73B7.js.map → chunk-GXFG4JU6.js.map} +0 -0
  78. /package/dist/{chunk-3V3GQCB7.js.map → chunk-HDFNMVRQ.js.map} +0 -0
  79. /package/dist/{chunk-3RNGPMRE.js.map → chunk-HOFYJEJ4.js.map} +0 -0
  80. /package/dist/{chunk-LFN7NUFS.js.map → chunk-JINMYD56.js.map} +0 -0
  81. /package/dist/{chunk-GDTS2J2P.js.map → chunk-KTYPZTF4.js.map} +0 -0
  82. /package/dist/{config-C7AKWCPA.js.map → config-QLINHCHD.js.map} +0 -0
  83. /package/dist/{doctor-P2ZH6PFX.js.map → doctor-37JNBGDN.js.map} +0 -0
  84. /package/dist/{init-D2BQIVVD.js.map → init-TDKDC6YP.js.map} +0 -0
  85. /package/dist/{restart-KFRHCALK.js.map → restart-RNXGTDWZ.js.map} +0 -0
  86. /package/dist/{start-46GW453L.js.map → start-27GRO4DP.js.map} +0 -0
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  envSchema
3
- } from "./chunk-MV2CADMB.js";
3
+ } from "./chunk-FWEW5E3B.js";
4
4
  import {
5
5
  getLocalIP
6
6
  } from "./chunk-AKXDQH25.js";
@@ -863,4 +863,4 @@ export {
863
863
  PreflightChecker,
864
864
  ConfigGenerator
865
865
  };
866
- //# sourceMappingURL=chunk-GDTS2J2P.js.map
866
+ //# sourceMappingURL=chunk-KTYPZTF4.js.map
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-ACVOOHAR.js";
4
4
  import {
5
5
  t
6
- } from "./chunk-KWODU7HB.js";
6
+ } from "./chunk-YCYVNRLF.js";
7
7
  import {
8
8
  KNOWLEDGE_DEFAULTS
9
9
  } from "./chunk-B7TVVODN.js";
@@ -740,7 +740,11 @@ E2E \u9A8C\u8BC1\u5FC5\u987B**\u4E25\u683C\u6309\u987A\u5E8F**\u7ECF\u8FC7\u4E09
740
740
  - \u26A0\uFE0F **REPL \u6392\u969C\u540E\u5FC5\u987B\u91CD\u8DD1\u811A\u672C**\uFF1A\u5982\u679C\u4F7F\u7528\u4E86 REPL \u4EA4\u4E92\u5F0F\u63A2\u7D22\u6216\u4FEE\u6539\u4E86\u811A\u672C\uFF0C**\u5FC5\u987B\u9000\u51FA REPL \u540E\u91CD\u65B0\u6267\u884C \`--script\` \u6A21\u5F0F\u8FD0\u884C\u8BE5\u811A\u672C**\u3002REPL \u8FC7\u7A0B\u4E2D\u4EA7\u751F\u7684\u622A\u56FE\u662F\u8C03\u8BD5\u4E2D\u95F4\u72B6\u6001\uFF0C\u4E0D\u80FD\u4F5C\u4E3A\u6700\u7EC8\u9A8C\u8BC1\u7ED3\u679C\u3002\u53EA\u6709 \`--script\` \u6A21\u5F0F\u4EA7\u51FA\u7684\u622A\u56FE\u624D\u662F\u6709\u6548\u7684\u9A8C\u8BC1\u622A\u56FE
741
741
  - \u6700\u7EC8\u9A8C\u8BC1\u6807\u51C6\uFF1A\u6240\u6709\u811A\u672C\u90FD\u4EE5 \`--script\` \u6A21\u5F0F\u6210\u529F\u6267\u884C\uFF0C\u4EA7\u51FA\u7684\u622A\u56FE\u53CD\u6620\u6700\u7EC8\u6B63\u786E\u72B6\u6001
742
742
 
743
- \u5C06 E2E \u6D4B\u8BD5\u7ED3\u679C\u5199\u5165\u9A8C\u8BC1\u62A5\u544A\u7684 **E2E UI \u6D4B\u8BD5\u7ED3\u679C** \u7AE0\u8282\u3002`;
743
+ \u5C06\u6240\u6709 E2E \u6D4B\u8BD5\u7ED3\u679C\u6C47\u603B\u5199\u5165 \`.claude-plan/issue-${ctx.issueIid}/03-uat-report.md\`\uFF0C\u5305\u542B\uFF1A
744
+ - \u6D4B\u8BD5\u573A\u666F\u6E05\u5355
745
+ - \u6BCF\u4E2A\u573A\u666F\u7684\u6267\u884C\u7ED3\u679C\uFF08\u901A\u8FC7/\u5931\u8D25\uFF09
746
+ - \u622A\u56FE\u8DEF\u5F84\uFF08\u5982\u6709\uFF09
747
+ - \u5931\u8D25\u539F\u56E0\u5206\u6790\uFF08\u5982\u6709\u5931\u8D25\uFF09`;
744
748
  }
745
749
  function buildGenericE2ePrompt(ctx, ports) {
746
750
  const kv = getKnowledgeForPrompt();
@@ -773,10 +777,11 @@ cd ${frontendDir} && pnpm test:e2e
773
777
  a. \u5728 ${e2eDir}/ \u76EE\u5F55\u4E0B\u7F16\u5199\u9488\u5BF9\u672C\u6B21\u53D8\u66F4\u7684 ${e2eTool} \u6D4B\u8BD5
774
778
  b. ${serverSection.trim()}
775
779
  c. \u5982\u679C\u6D4B\u8BD5\u5931\u8D25\uFF0C\u5206\u6790\u5931\u8D25\u539F\u56E0\u5E76\u5C1D\u8BD5\u4FEE\u590D
776
- 7. \u5C06 E2E \u6D4B\u8BD5\u7ED3\u679C\u5199\u5165\u9A8C\u8BC1\u62A5\u544A\u7684 **E2E UI \u6D4B\u8BD5\u7ED3\u679C** \u7AE0\u8282\uFF0C\u5305\u62EC\uFF1A
780
+ 7. \u5C06 E2E \u6D4B\u8BD5\u7ED3\u679C\u5199\u5165 \`.claude-plan/issue-${ctx.issueIid}/03-uat-report.md\`\uFF0C\u5305\u62EC\uFF1A
777
781
  - \u5192\u70DF\u6D4B\u8BD5\u901A\u8FC7\u6570 / \u603B\u6570
778
782
  - \u4E13\u9879\u6D4B\u8BD5\u7ED3\u679C\u5217\u8868
779
- - \u5931\u8D25\u622A\u56FE\u8DEF\u5F84\uFF08\u5982\u6709\uFF09`;
783
+ - \u622A\u56FE\u8DEF\u5F84\uFF08\u5982\u6709\uFF09
784
+ - \u5931\u8D25\u539F\u56E0\u5206\u6790\uFF08\u5982\u6709\u5931\u8D25\uFF09`;
780
785
  }
781
786
  function conflictResolvePrompt(ctx) {
782
787
  const conflictFilesList = ctx.conflictFiles.map((f) => `- \`${f}\``).join("\n");
@@ -890,4 +895,4 @@ export {
890
895
  AsyncMutex,
891
896
  ConflictResolver
892
897
  };
893
- //# sourceMappingURL=chunk-6S7ERGQ7.js.map
898
+ //# sourceMappingURL=chunk-P4O4ZXEC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/git/GitOperations.ts","../src/events/EventBus.ts","../src/utils/AsyncMutex.ts","../src/tracker/BaseTracker.ts","../src/tracker/IssueRecordHelper.ts","../src/tracker/ExecutableTask.ts","../src/prompts/templates.ts","../src/git/ConflictResolver.ts"],"sourcesContent":["import { execFile } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { logger as rootLogger } from '../logger.js';\n\nconst execFileAsync = promisify(execFile);\nconst logger = rootLogger.child('GitOperations');\n\nexport class GitOperations {\n private workDir: string;\n\n constructor(workDir: string) {\n this.workDir = workDir;\n }\n\n private async exec(args: string[]): Promise<string> {\n logger.debug('git exec', { args });\n const { stdout } = await execFileAsync('git', args, {\n cwd: this.workDir,\n maxBuffer: 10 * 1024 * 1024,\n env: { ...process.env, HUSKY: '0' },\n });\n return stdout.trim();\n }\n\n async fetchAndPull(branch: string): Promise<void> {\n await this.exec(['fetch', 'origin']);\n await this.exec(['checkout', '-f', branch]);\n await this.exec(['pull', 'origin', branch]);\n logger.info('Fetched and pulled', { branch });\n }\n\n async fetch(): Promise<void> {\n await this.exec(['fetch', 'origin']);\n logger.info('Fetched from origin');\n }\n\n async createBranch(name: string, from: string): Promise<void> {\n // Create branch from origin/<from> without needing to checkout <from> first\n // Use -f to force checkout when untracked files conflict with the target\n await this.exec(['checkout', '-f', '-b', name, `origin/${from}`]);\n logger.info('Branch created', { name, from: `origin/${from}` });\n }\n\n async checkout(branch: string): Promise<void> {\n await this.exec(['checkout', '-f', branch]);\n logger.info('Checked out', { branch });\n }\n\n async add(files: string[]): Promise<void> {\n await this.exec(['add', ...files]);\n }\n\n async commit(message: string): Promise<void> {\n await this.exec(['commit', '--no-verify', '-m', message]);\n logger.info('Committed', { message: message.slice(0, 80) });\n }\n\n async push(branch: string): Promise<void> {\n await this.exec(['push', '--no-verify', '-u', 'origin', branch]);\n logger.info('Pushed', { branch });\n }\n\n async branchExists(name: string): Promise<boolean> {\n try {\n await this.exec(['rev-parse', '--verify', name]);\n return true;\n } catch {\n return false;\n }\n }\n\n async remoteBranchExists(name: string): Promise<boolean> {\n try {\n await this.exec(['ls-remote', '--exit-code', '--heads', 'origin', name]);\n return true;\n } catch {\n return false;\n }\n }\n\n async getCurrentBranch(): Promise<string> {\n return this.exec(['rev-parse', '--abbrev-ref', 'HEAD']);\n }\n\n async stash(): Promise<void> {\n await this.exec(['stash']);\n }\n\n async stashPop(): Promise<void> {\n await this.exec(['stash', 'pop']);\n }\n\n async hasChanges(): Promise<boolean> {\n const status = await this.exec(['status', '--porcelain']);\n return status.length > 0;\n }\n\n async addAndCommit(files: string[], message: string): Promise<void> {\n await this.add(files);\n await this.commit(message);\n }\n\n async fetchBranch(branch: string): Promise<void> {\n await this.exec(['fetch', 'origin', branch]);\n logger.info('Fetched specific branch', { branch });\n }\n\n async checkoutTrack(remoteBranch: string): Promise<void> {\n await this.fetchBranch(remoteBranch);\n await this.exec(['checkout', '-f', '-B', remoteBranch, 'FETCH_HEAD']);\n logger.info('Checked out remote branch via FETCH_HEAD', { remoteBranch });\n }\n\n async addCommitAndPush(files: string[], message: string, branch: string): Promise<void> {\n await this.add(files);\n await this.commit(message);\n await this.push(branch);\n }\n\n async deleteBranch(name: string): Promise<void> {\n await this.exec(['branch', '-D', name]);\n logger.info('Branch deleted', { name });\n }\n\n async deleteRemoteBranch(name: string): Promise<void> {\n await this.exec(['push', 'origin', '--delete', name]);\n logger.info('Remote branch deleted', { name });\n }\n\n async worktreeAdd(dir: string, newBranch: string, startPoint: string): Promise<void> {\n await this.exec(['worktree', 'add', '-b', newBranch, dir, startPoint]);\n logger.info('Worktree added (new branch)', { dir, newBranch, startPoint });\n }\n\n async worktreeAddExisting(dir: string, branch: string): Promise<void> {\n await this.exec(['worktree', 'add', dir, branch]);\n logger.info('Worktree added (existing branch)', { dir, branch });\n }\n\n async worktreeAddTracking(dir: string, remoteBranch: string): Promise<void> {\n await this.exec(['worktree', 'add', '--track', '-b', remoteBranch, dir, `origin/${remoteBranch}`]);\n logger.info('Worktree added (tracking remote)', { dir, remoteBranch });\n }\n\n async worktreeRemove(dir: string, force = false): Promise<void> {\n const args = ['worktree', 'remove', dir];\n if (force) args.push('--force');\n await this.exec(args);\n logger.info('Worktree removed', { dir, force });\n }\n\n async worktreePrune(): Promise<void> {\n await this.exec(['worktree', 'prune']);\n logger.info('Worktree pruned stale entries');\n }\n\n async worktreeList(): Promise<string[]> {\n const output = await this.exec(['worktree', 'list', '--porcelain']);\n return output\n .split('\\n')\n .filter((line) => line.startsWith('worktree '))\n .map((line) => line.replace('worktree ', ''));\n }\n\n async showFile(ref: string, filePath: string): Promise<string | null> {\n try {\n return await this.exec(['show', `${ref}:${filePath}`]);\n } catch {\n return null;\n }\n }\n\n async getConflictFiles(): Promise<string[]> {\n const output = await this.exec(['diff', '--name-only', '--diff-filter=U']);\n if (!output) return [];\n return output.split('\\n').filter(Boolean);\n }\n\n async rebase(targetRef: string): Promise<{ success: boolean; conflictFiles: string[] }> {\n try {\n await this.exec(['rebase', targetRef]);\n return { success: true, conflictFiles: [] };\n } catch (err) {\n const msg = (err as Error).message || '';\n if (msg.includes('CONFLICT') || msg.includes('could not apply')) {\n const conflictFiles = await this.getConflictFiles();\n return { success: false, conflictFiles };\n }\n throw err;\n }\n }\n\n async rebaseContinue(): Promise<{ done: boolean; conflictFiles: string[] }> {\n try {\n await this.exec(['-c', 'core.editor=true', 'rebase', '--continue']);\n return { done: true, conflictFiles: [] };\n } catch (err) {\n const msg = (err as Error).message || '';\n if (msg.includes('CONFLICT') || msg.includes('could not apply')) {\n const conflictFiles = await this.getConflictFiles();\n return { done: false, conflictFiles };\n }\n throw err;\n }\n }\n\n async rebaseAbort(): Promise<void> {\n await this.exec(['rebase', '--abort']);\n logger.info('Rebase aborted');\n }\n\n async isRebaseInProgress(): Promise<boolean> {\n const status = await this.exec(['status']);\n return status.includes('rebase in progress');\n }\n\n async forcePush(branch: string): Promise<void> {\n await this.exec(['push', '--no-verify', '--force-with-lease', '-u', 'origin', branch]);\n logger.info('Force pushed', { branch });\n }\n\n async mergeFF(branch: string): Promise<void> {\n await this.exec(['merge', '--ff-only', branch]);\n logger.info('Fast-forward merged', { branch });\n }\n\n async merge(branch: string, message: string): Promise<void> {\n await this.exec(['merge', '--no-ff', '--no-verify', '-m', message, branch]);\n logger.info('Merged', { branch, message: message.slice(0, 80) });\n }\n}\n","import { EventEmitter } from 'node:events';\n\nexport type EventType =\n | 'issue:created'\n | 'issue:stateChanged'\n | 'issue:failed'\n | 'issue:deleted'\n | 'issue:resetForRetry'\n | 'issue:restarted'\n | 'issue:retryFromPhase'\n | 'poll:tick'\n | 'heartbeat'\n | 'agent:output'\n | 'pipeline:progress'\n | 'review:requested'\n | 'review:approved'\n | 'review:rejected'\n | 'conflict:started'\n | 'conflict:resolved'\n | 'conflict:failed'\n | 'update:checking'\n | 'update:available'\n | 'update:downloading'\n | 'update:completed'\n | 'update:failed'\n // Braindump events\n | 'braindump:created'\n | 'braindump:split:done'\n | 'braindump:confirmed'\n | 'braindump:task:started'\n | 'braindump:task:completed'\n | 'braindump:task:merging'\n | 'braindump:task:merged'\n | 'braindump:task:failed'\n | 'braindump:completed'\n | 'braindump:failed'\n // Distill events\n | 'distill:diary:created'\n | 'distill:started'\n | 'distill:memory:updated'\n | 'distill:rule:generated'\n | 'distill:completed'\n | 'distill:failed'\n // Verify-fix loop events\n | 'verify:loopStarted'\n | 'verify:iterationComplete'\n | 'verify:loopExhausted'\n // Release events\n | 'release:gateRequested'\n // UAT async events\n | 'uat:gateRequested'\n | 'uat:completed'\n | 'uat:failed'\n // Phase abort/continue/redo events\n | 'issue:paused'\n | 'issue:continued'\n | 'issue:redone'\n // Preview reaper events\n | 'preview:reaped';\n\nexport interface EventPayload {\n type: EventType;\n data: unknown;\n timestamp: string;\n}\n\n/**\n * Typed event bus based on EventEmitter.\n *\n * Exported as a class so consumers can receive an instance via dependency\n * injection instead of relying on the global singleton.\n */\nexport class EventBus extends EventEmitter {\n emit(event: string | symbol, ...args: unknown[]): boolean {\n super.emit('*', event, ...args);\n return super.emit(event, ...args);\n }\n\n emitTyped(type: EventType, data: unknown): void {\n const payload: EventPayload = {\n type,\n data,\n timestamp: new Date().toISOString(),\n };\n this.emit(type, payload);\n }\n}\n\n/**\n * Global singleton — preserved for backward compatibility.\n *\n * New code should prefer receiving an `EventBus` instance via constructor\n * injection. The global singleton can be passed as the default value.\n */\nexport const eventBus = new EventBus();\n","/**\n * Promise-based async mutex for serializing access to shared resources\n * in a single Node.js process (e.g. mainGit operations, tracker file writes).\n */\nexport class AsyncMutex {\n private queue: Array<() => void> = [];\n private locked = false;\n\n async runExclusive<T>(fn: () => Promise<T>): Promise<T> {\n await this.acquire();\n try {\n return await fn();\n } finally {\n this.release();\n }\n }\n\n private acquire(): Promise<void> {\n if (!this.locked) {\n this.locked = true;\n return Promise.resolve();\n }\n return new Promise<void>((resolve) => {\n this.queue.push(resolve);\n });\n }\n\n private release(): void {\n const next = this.queue.shift();\n if (next) {\n next();\n } else {\n this.locked = false;\n }\n }\n\n get isLocked(): boolean {\n return this.locked;\n }\n\n get queueLength(): number {\n return this.queue.length;\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { logger as rootLogger } from '../logger.js';\n\n/**\n * BaseTracker — JSON 文件持久化的泛型 Tracker 基类。\n *\n * 集中公共的 load/save/get/getAll/delete 逻辑。\n * 子类通过构造函数参数注入 collectionKey 和 trackerName。\n */\nexport abstract class BaseTracker<TRecord> {\n protected readonly filePath: string;\n protected data: Record<string, Record<string, TRecord>>;\n\n /** JSON 根字段名(如 'issues' 或 'batches')*/\n protected readonly collectionKey: string;\n /** 临时文件前缀(如 'tracker' 或 'braindump-tracker')*/\n protected readonly trackerName: string;\n\n constructor(dataDir: string, filename: string, collectionKey: string, trackerName: string) {\n this.collectionKey = collectionKey;\n this.trackerName = trackerName;\n this.filePath = path.join(dataDir, filename);\n this.data = this.load();\n }\n\n protected load(): Record<string, Record<string, TRecord>> {\n try {\n if (fs.existsSync(this.filePath)) {\n const raw = fs.readFileSync(this.filePath, 'utf-8');\n return JSON.parse(raw);\n }\n } catch (err) {\n rootLogger.child(this.trackerName).error(\n 'Failed to load tracker data',\n { error: (err as Error).message },\n );\n }\n return { [this.collectionKey]: {} };\n }\n\n protected save(): void {\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const tmpPath = path.join(dir,\n `.${this.trackerName}-${process.pid}-${Date.now()}.tmp`);\n fs.writeFileSync(tmpPath, JSON.stringify(this.data, null, 2), 'utf-8');\n fs.renameSync(tmpPath, this.filePath);\n }\n\n /** 获取记录集合的引用 */\n protected get collection(): Record<string, TRecord> {\n return this.data[this.collectionKey] as Record<string, TRecord>;\n }\n\n protected getByKey(key: string): TRecord | undefined {\n return this.collection[key];\n }\n\n protected getAllRecords(): TRecord[] {\n return Object.values(this.collection);\n }\n\n protected setRecord(key: string, record: TRecord): void {\n this.collection[key] = record;\n }\n\n protected deleteByKey(key: string): boolean {\n if (!this.collection[key]) return false;\n delete this.collection[key];\n this.save();\n return true;\n }\n}\n","import type { IssueRecord } from './IssueState.js';\n\n/**\n * IssueRecord 身份字段辅助函数。\n *\n * 从 demandSpec 读取身份信息。\n */\n\n/** 获取显示 IID(工蜂 Issue IID) */\nexport function getIid(record: IssueRecord): number {\n return Number(record.demandSpec!.sourceRef.displayId);\n}\n\n/** 获取外部 ID(工蜂 Issue ID) */\nexport function getExternalId(record: IssueRecord): number {\n return Number(record.demandSpec!.sourceRef.externalId);\n}\n\n/** 获取标题 */\nexport function getTitle(record: IssueRecord): string {\n return record.demandSpec!.title;\n}\n","import type { IssueRecord } from './IssueState.js';\nimport type { BraindumpTask } from '../braindump/BraindumpState.js';\nimport type { ActionLifecycleManager } from '../lifecycle/ActionLifecycleManager.js';\nimport { getIid, getTitle } from './IssueRecordHelper.js';\n\n/**\n * UnifiedTaskStatus — 所有任务类型共享的通用状态枚举。\n *\n * 与 IssueState/BatchStatus/TaskStatus 共存,不替代它们。\n * 用于跨任务类型的通用逻辑(如统一 dashboard、统一恢复)。\n */\nexport type UnifiedTaskStatus =\n | 'idle' // 尚未开始\n | 'preparing' // 准备中(创建分支、安装依赖等)\n | 'running' // 执行中\n | 'waiting' // 等待外部输入(审核等)\n | 'merging' // 合并中\n | 'completed' // 完成\n | 'failed'; // 失败\n\n/**\n * ExecutableTask — 所有可执行任务的统一接口。\n *\n * IssueRecord 和 BraindumpTask 都可以投影为此接口,\n * 用于跨任务类型的通用操作。\n */\nexport interface ExecutableTask {\n /** 任务类型标识 */\n readonly kind: 'issue' | 'braindump-task';\n /** 唯一标识(issue: string(issueIid), braindump: taskId) */\n readonly taskId: string;\n /** 显示标题 */\n readonly title: string;\n /** 统一状态 */\n readonly status: UnifiedTaskStatus;\n /** 重试次数 */\n readonly attempts: number;\n /** 最后错误 */\n readonly lastError?: string;\n /** 创建时间 */\n readonly createdAt: string;\n /** 最后更新时间 */\n readonly updatedAt: string;\n /** 特性分支名 */\n readonly branchName?: string;\n /** 原始状态值(IssueState 或 TaskStatus) */\n readonly sourceState?: string;\n /** 过滤分类:active/completed/failed/blocked/idle/skipped */\n readonly stateCategory?: string;\n /** 预计算的状态展示标签(由后端投影时通过 ActionLifecycleManager.resolveLabel 生成) */\n readonly displayLabel?: string;\n\n /** 阶段进度快照(由后端投影时预计算)。\n * 各阶段按定义顺序排列,status 为 pending/in_progress/completed/failed。\n * 未提供时前端不渲染阶段进度列。 */\n readonly phaseProgress?: { name: string; label: string; status: 'pending' | 'in_progress' | 'completed' | 'failed' }[];\n}\n\n/**\n * ActionStatus → UnifiedTaskStatus 映射。\n *\n * 使用 ActionLifecycleManager 的 resolve() 返回的 ActionStatus 做语义映射:\n * - idle/skipped → 'idle'\n * - ready → 'preparing'\n * - running → 'running'\n * - waiting → 'waiting'\n * - done → 'completed'\n * - failed → 'failed'\n */\nexport function issueStateToUnified(actionStatus: string): UnifiedTaskStatus {\n switch (actionStatus) {\n case 'idle':\n case 'skipped':\n return 'idle';\n case 'ready':\n return 'preparing';\n case 'running':\n return 'running';\n case 'waiting':\n return 'waiting';\n case 'done':\n return 'completed';\n case 'failed':\n return 'failed';\n default:\n return 'idle';\n }\n}\n\n/**\n * TaskStatus → UnifiedTaskStatus 映射。\n */\nexport function taskStatusToUnified(status: string): UnifiedTaskStatus {\n switch (status) {\n case 'pending':\n case 'blocked':\n return 'idle';\n case 'running':\n return 'running';\n case 'done':\n return 'preparing'; // done but not yet merged\n case 'merging':\n case 'conflict_resolving':\n return 'merging';\n case 'merged':\n return 'completed';\n case 'failed':\n return 'failed';\n default:\n return 'idle';\n }\n}\n\n/** 从 UnifiedTaskStatus 派生 stateCategory(用于前端过滤) */\nexport function unifiedStatusToCategory(status: UnifiedTaskStatus): string {\n switch (status) {\n case 'running':\n case 'preparing':\n case 'merging':\n return 'active';\n case 'waiting':\n return 'blocked';\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'idle':\n default:\n return 'idle';\n }\n}\n\n/**\n * 为 Issue 计算 stateCategory(精确版,使用 ActionLifecycleManager)。\n * 比 unifiedStatusToCategory 更精准,能区分 skipped 等状态。\n */\nexport function issueStateCategory(record: IssueRecord, lm: ActionLifecycleManager): string {\n if (lm.isTerminal(record.state)) {\n if (record.state === 'failed') return 'failed';\n if (record.state === 'deployed') return 'deployed';\n if (record.state === 'completed') return 'completed';\n return 'skipped';\n }\n if (lm.isBlocked(record.state)) return 'blocked';\n return 'active';\n}\n\n// ── Adapters ──\n\n/** 将 IssueRecord 投影为 ExecutableTask */\nexport function issueToExecutableTask(\n record: IssueRecord,\n lm: ActionLifecycleManager,\n): ExecutableTask {\n const actionState = lm.resolve(record.state, record.currentPhase);\n\n // 预计算阶段进度快照\n const phaseStatusMap = lm.derivePhaseStatuses(record.state, record.currentPhase);\n const phaseDefs = lm.getPhaseDefs();\n const phaseProgress = phaseDefs.map(p => ({\n name: p.name,\n label: p.label,\n status: phaseStatusMap[p.name] ?? 'pending' as const,\n }));\n\n return {\n kind: 'issue',\n taskId: String(getIid(record)),\n title: getTitle(record),\n status: issueStateToUnified(actionState.status),\n attempts: record.attempts,\n lastError: record.lastError,\n createdAt: record.createdAt,\n updatedAt: record.updatedAt,\n branchName: record.branchName,\n sourceState: record.state,\n stateCategory: issueStateCategory(record, lm),\n displayLabel: lm.resolveLabel(record.state, record.currentPhase),\n phaseProgress,\n };\n}\n\n/** 将 BraindumpTask 投影为 ExecutableTask */\nexport function braindumpTaskToExecutableTask(\n task: BraindumpTask,\n batch: { createdAt: string; updatedAt: string },\n): ExecutableTask {\n const status = taskStatusToUnified(task.status);\n return {\n kind: 'braindump-task',\n taskId: task.id,\n title: task.title,\n status,\n attempts: task.attempts,\n lastError: task.lastError,\n createdAt: task.startedAt ?? batch.createdAt,\n updatedAt: task.completedAt ?? task.startedAt ?? batch.updatedAt,\n branchName: task.branchName,\n sourceState: task.status,\n stateCategory: unifiedStatusToCategory(status),\n };\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { t } from '../i18n/index.js';\nimport { getProjectKnowledge } from '../knowledge/index.js';\nimport { KNOWLEDGE_DEFAULTS } from '../knowledge/KnowledgeDefaults.js';\nimport type { ProjectKnowledge } from '../knowledge/ProjectKnowledge.js';\nimport type { DemandSpec } from '../demand/DemandSpec.js';\nimport type { RepoContext } from '../workspace/index.js';\n\nexport interface WorkspaceLayout {\n repos: RepoContext[];\n workspaceRoot: string;\n}\n\nexport interface PromptContext {\n issueTitle: string;\n issueDescription: string;\n issueIid: number;\n supplementText?: string;\n workspace?: WorkspaceLayout;\n}\n\nfunction planDir(iid: number): string {\n return `.claude-plan/issue-${iid}`;\n}\n\n/**\n * Build template variable map from knowledge config (or defaults).\n */\nexport function getKnowledgeForPrompt(): Record<string, string> {\n const k: ProjectKnowledge = getProjectKnowledge() ?? KNOWLEDGE_DEFAULTS;\n\n const codeStyleParts: string[] = [];\n if (k.codeStyle.indentStyle === 'spaces') {\n codeStyleParts.push(`${k.codeStyle.indentSize}空格缩进`);\n } else {\n codeStyleParts.push('Tab缩进');\n }\n codeStyleParts.push(`${k.codeStyle.lineWidth}字符行宽`);\n codeStyleParts.push('命名规范等');\n if (k.codeStyle.additionalRules?.length) {\n codeStyleParts.push(...k.codeStyle.additionalRules);\n }\n\n const knownIssueLines = k.knownIssues.map(issue => `- ${issue.description}${issue.advice ? `,${issue.advice}` : ''}`);\n\n return {\n dependencyCheckPath: k.toolchain.dependencyCheckPath ?? 'node_modules/.bin/eslint',\n installCommand: k.toolchain.installCommand,\n installFallbackCommand: k.toolchain.installFallbackCommand ?? `${k.toolchain.installCommand} --ignore-scripts`,\n lintCommand: k.toolchain.lintCommand ?? 'npm run lint',\n buildCommand: k.toolchain.buildCommand ?? 'npm run build',\n testCommand: k.toolchain.testCommand ?? 'npm test',\n testFilesCommand: k.toolchain.testFilesCommand\n ?? `${k.toolchain.testCommand ?? 'npm test'} -- <涉及变更的测试文件>`,\n knownIssuesSection: knownIssueLines.length > 0\n ? knownIssueLines.join('\\n')\n : '- 无已知预存问题',\n codeStyleDescription: codeStyleParts.join('、'),\n // E2E related\n e2eDir: k.structure.e2eDir ?? 'e2e',\n e2eTool: k.structure.e2eTool ?? 'E2E',\n frontendDir: k.structure.frontendDir ?? 'frontend',\n };\n}\n\n/**\n * 从 DemandSpec 构建 prompt 上下文,统一补充信息的格式化。\n */\nexport function demandToPromptContext(demand: DemandSpec): {\n title: string;\n description: string;\n displayId: string;\n supplementText: string;\n} {\n const parts: string[] = [];\n const s = demand.supplement;\n if (s?.requirements) parts.push(`### 补充需求说明\\n${s.requirements}`);\n if (s?.acceptanceCriteria) parts.push(`### 验收标准\\n${s.acceptanceCriteria}`);\n if (s?.scope) parts.push(`### 变更范围\\n${s.scope}`);\n if (s?.constraints) parts.push(`### 约束条件\\n${s.constraints}`);\n if (s?.references) parts.push(`### 参考链接\\n${s.references}`);\n if (s?.freeText) parts.push(`### 其他补充\\n${s.freeText}`);\n return {\n title: demand.title,\n description: demand.description,\n displayId: demand.sourceRef.displayId ?? demand.demandId,\n supplementText: parts.length ? `## 补充信息\\n\\n${parts.join('\\n\\n')}` : '',\n };\n}\n\n/**\n * Build a workspace layout section for multi-repo prompts.\n * Returns empty string when workspace has only one repo.\n */\nexport function buildWorkspaceSection(workspace?: WorkspaceLayout): string {\n if (!workspace || workspace.repos.length <= 1) return '';\n\n const lines: string[] = [\n '## 多仓库工作区',\n '',\n '当前工作区包含多个关联仓库,你可以跨仓库读写文件。各仓库相对于工作区根目录的布局如下:',\n '',\n '| 仓库 | 相对路径 | 角色 |',\n '|------|---------|------|',\n ];\n\n for (const repo of workspace.repos) {\n const relPath = repo.name + (repo.workDir !== repo.gitRootDir\n ? ` (项目目录: ${repo.name}/${repo.workDir.slice(repo.gitRootDir.length + 1)})`\n : '');\n const roleText = repo.role || (repo.isPrimary ? '主仓库' : '关联仓库');\n lines.push(`| ${repo.name} | \\`${relPath}\\` | ${roleText} |`);\n }\n\n lines.push('');\n lines.push('修改任一仓库的代码时,使用对应仓库的相对路径即可。请先阅读各仓库根目录下的 CLAUDE.md(如有)了解项目约定。');\n\n return lines.join('\\n');\n}\n\nexport function analysisPrompt(ctx: PromptContext): string {\n const supplementSection = ctx.supplementText ? `\\n\\n${ctx.supplementText}` : '';\n const pd = planDir(ctx.issueIid);\n return t('prompt.analysis', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n description: ctx.issueDescription,\n supplement: supplementSection,\n planDir: pd,\n });\n}\n\nexport function designPrompt(ctx: PromptContext): string {\n const supplementSection = ctx.supplementText ? `\\n\\n${ctx.supplementText}` : '';\n const pd = planDir(ctx.issueIid);\n return t('prompt.design', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n supplement: supplementSection,\n planDir: pd,\n });\n}\n\nexport function implementPrompt(ctx: PromptContext): string {\n const pd = planDir(ctx.issueIid);\n const kv = getKnowledgeForPrompt();\n return t('prompt.implement', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n planDir: pd,\n ...kv,\n });\n}\n\nexport function verifyPrompt(ctx: PromptContext): string {\n const pd = planDir(ctx.issueIid);\n const kv = getKnowledgeForPrompt();\n return t('prompt.verify', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n planDir: pd,\n ...kv,\n });\n}\n\nexport function planModeVerifyPrompt(ctx: PromptContext): string {\n const pd = planDir(ctx.issueIid);\n const kv = getKnowledgeForPrompt();\n const wsSection = buildWorkspaceSection(ctx.workspace);\n const base = t('prompt.planModeVerify', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n planDir: pd,\n ...kv,\n });\n return wsSection ? `${base}\\n\\n${wsSection}` : base;\n}\n\nexport function planPrompt(ctx: PromptContext): string {\n const supplementSection = ctx.supplementText ? `\\n\\n${ctx.supplementText}` : '';\n const wsSection = buildWorkspaceSection(ctx.workspace);\n const pd = planDir(ctx.issueIid);\n const base = t('prompt.plan', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n description: ctx.issueDescription,\n supplement: supplementSection,\n planDir: pd,\n });\n return wsSection ? `${base}\\n\\n${wsSection}` : base;\n}\n\nexport function buildPrompt(ctx: PromptContext): string {\n const pd = planDir(ctx.issueIid);\n const kv = getKnowledgeForPrompt();\n const wsSection = buildWorkspaceSection(ctx.workspace);\n const base = t('prompt.build', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n planDir: pd,\n ...kv,\n });\n return wsSection ? `${base}\\n\\n${wsSection}` : base;\n}\n\nexport interface ReviewRoundForPrompt {\n round: number;\n feedback: string;\n timestamp: string;\n}\n\nexport function rePlanPrompt(ctx: PromptContext, history: ReviewRoundForPrompt[]): string {\n const supplementSection = ctx.supplementText ? `\\n\\n${ctx.supplementText}` : '';\n const wsSection = buildWorkspaceSection(ctx.workspace);\n const pd = planDir(ctx.issueIid);\n const feedbackLines = history.map(\n r => t('prompt.rePlanRound', { round: r.round, timestamp: r.timestamp, feedback: r.feedback })\n ).join('\\n\\n');\n const base = t('prompt.rePlan', {\n iid: ctx.issueIid,\n title: ctx.issueTitle,\n description: ctx.issueDescription,\n supplement: supplementSection,\n historyCount: history.length,\n feedbackLines,\n planDir: pd,\n });\n return wsSection ? `${base}\\n\\n${wsSection}` : base;\n}\n\nexport interface E2ePromptPorts {\n backendPort: number;\n frontendPort: number;\n host: string;\n}\n\nexport interface UatToolConfig {\n vendorDir: string;\n configFile: string;\n}\n\n/**\n * Load all SKILL.md files from the vendor .cursor/skills/ directory.\n * Scans every sub-directory for SKILL.md, concatenates them in sorted order.\n * Falls back to a top-level SKILL.md if .cursor/skills/ doesn't exist.\n */\nfunction loadUatSkill(vendorDir: string): string | null {\n const skillsDir = path.join(vendorDir, '.cursor/skills');\n\n if (fs.existsSync(skillsDir)) {\n try {\n const entries = fs.readdirSync(skillsDir, { withFileTypes: true })\n .filter(e => e.isDirectory())\n .sort((a, b) => a.name.localeCompare(b.name));\n\n const parts: string[] = [];\n for (const entry of entries) {\n const skillFile = path.join(skillsDir, entry.name, 'SKILL.md');\n if (fs.existsSync(skillFile)) {\n try {\n parts.push(fs.readFileSync(skillFile, 'utf-8'));\n } catch { /* skip unreadable */ }\n }\n }\n if (parts.length > 0) return parts.join('\\n\\n---\\n\\n');\n } catch { /* fall through */ }\n }\n\n const fallback = path.join(vendorDir, 'SKILL.md');\n if (fs.existsSync(fallback)) {\n try { return fs.readFileSync(fallback, 'utf-8'); } catch { /* skip */ }\n }\n return null;\n}\n\nexport function e2eVerifyPromptSuffix(\n ctx: PromptContext,\n ports?: E2ePromptPorts,\n uatTool?: UatToolConfig,\n): string {\n if (uatTool?.vendorDir) {\n return buildOaUatPrompt(ctx, uatTool, ports);\n }\n return buildGenericE2ePrompt(ctx, ports);\n}\n\n/**\n * Load the \"e2e_prompt\" field from the oa_pc_uat config.json.\n * Returns the custom prompt string or null if not found / not set.\n */\nfunction loadUatConfigPrompt(configFile: string): string | null {\n if (!configFile || !fs.existsSync(configFile)) return null;\n try {\n const raw = JSON.parse(fs.readFileSync(configFile, 'utf-8'));\n if (typeof raw.e2e_prompt === 'string' && raw.e2e_prompt.trim()) {\n return raw.e2e_prompt.trim();\n }\n } catch { /* ignore parse errors */ }\n return null;\n}\n\nfunction buildOaUatPrompt(\n ctx: PromptContext,\n uatTool: UatToolConfig,\n ports?: E2ePromptPorts,\n): string {\n const vendorDir = uatTool.vendorDir;\n const configFile = uatTool.configFile\n || (fs.existsSync(path.join(vendorDir, 'config.json'))\n ? path.join(vendorDir, 'config.json')\n : '');\n\n const skillContent = loadUatSkill(vendorDir);\n const skillSection = skillContent\n ? `\\n\\n<uat-skills>\\n${skillContent}\\n</uat-skills>`\n : '';\n\n const configArg = configFile ? ` --config ${configFile}` : '';\n const outputDirArg = ` --output-dir ${vendorDir}/outputs/issue-${ctx.issueIid}`;\n const cfgLabel = configFile || 'config.json';\n const portHint = ports\n ? `\n\n> **⚠️ 端口覆盖(必须遵守)**\n> 系统已自动在动态端口启动前后端 Preview 服务,无需手动启动:\n> - 后端: http://${ports.host}:${ports.backendPort}\n> - 前端: https://${ports.host}:${ports.frontendPort}\n>\n> **在执行任何 E2E 脚本之前**,你必须先更新 \\`${cfgLabel}\\` 中的地址配置,\n> 将前端地址(base_url 等)改为 \\`https://${ports.host}:${ports.frontendPort}\\`,\n> 后端地址(api_url 等)改为 \\`http://${ports.host}:${ports.backendPort}\\`。\n> config.json 中原有的端口是开发环境默认值,不适用于当前 Preview 环境。`\n : `\n\n> **注意**:Preview 环境未启动。在执行 E2E 测试前,请确认前后端服务已运行。\n> 如果 \\`${cfgLabel}\\` 中配置的服务端口没有响应,请先手动启动前后端服务再执行脚本。`;\n\n const customPrompt = loadUatConfigPrompt(configFile);\n\n const cmdOverride = `\n\n> **⚠️ 命令参数覆盖**:项目指引中出现的所有 \\`python3 .../main.py\\` 命令,都必须替换为以下标准格式:\n> - 执行脚本:\\`python3 ${vendorDir}/main.py${configArg}${outputDirArg} --script <script.py> --headless\\`\n> - REPL 排障:\\`python3 ${vendorDir}/main.py${configArg}${outputDirArg} -i --headless\\`\n`;\n\n const instructionSection = customPrompt\n ? `\\n\\n### 项目 E2E 指引\\n\\n${customPrompt}\\n${cmdOverride}`\n : '';\n\n const defaultSteps = `\n### 执行要点\n\n1. 影响面分析:基于 \\`git diff\\` 分析本次变更影响的功能点\n2. 增量剧本生成:扫描 \\`uat-scripts/\\` 目录,仅为未覆盖场景生成新剧本\n3. 执行验证脚本:\n \\`\\`\\`bash\n python3 ${vendorDir}/main.py${configArg}${outputDirArg} --script <script.py> --headless\n \\`\\`\\`\n4. 失败时使用 REPL 排障:\n \\`\\`\\`bash\n python3 ${vendorDir}/main.py${configArg}${outputDirArg} -i --headless\n \\`\\`\\`\n5. 输出结构化验证总览(包含截图路径、执行结果、耗时)`;\n\n return `\n\n## E2E UI 验证(已启用 - OA Web UAT)\n\n本次变更已开启 E2E UI 自动验收,使用 oa_pc_uat 增量验证流水线。${portHint}\n\n**工具位置**: \\`${vendorDir}\\`\n${configFile ? `**配置文件**: \\`${configFile}\\`` : ''}\n**产物输出目录**: \\`${vendorDir}/outputs/issue-${ctx.issueIid}\\`(所有 --script 和 -i 命令必须携带 \\`${outputDirArg.trim()}\\` 参数)\n\n请严格按照以下 oa-web-uat skill 的流程执行端对端验证:\n${skillSection}\n${instructionSection}\n${customPrompt ? '' : defaultSteps}\n\n### ⛔ 阶段 Gate 约束(必须严格遵守)\n\nE2E 验证必须**严格按顺序**经过三个阶段,**禁止跳过或合并**:\n\n**Gate 1 — 影响面分析完成检查点**\n- 必须先通过 \\`git diff\\` 分析出具体的功能点清单\n- 产出物:功能点清单(列出每个受影响的功能名称、影响模块、需验证路径)\n- ❌ 如果没有产出功能点清单,禁止进入阶段 2\n\n**Gate 2 — 剧本生成完成检查点**\n- 必须先扫描 \\`uat-scripts/\\` 已有脚本,判断增量需求\n- 对于需要新增的场景,必须完成:编写 Markdown 用例 → 执行 \\`scenario-gen\\` 生成 result.json → 基于 result.json 编写 Python 脚本\n- 产出物:所有需要执行的 .py 脚本文件(已有 + 新增)必须实际存在于磁盘上\n- ✅ 验证方式:\\`ls -la\\` 确认每个脚本文件存在\n- ❌ 如果脚本文件不存在或未生成,禁止进入阶段 3\n- 📦 **中间产物归档**(Gate 2 通过后、进入 Gate 3 前执行):\n \\`\\`\\`bash\n mkdir -p ${vendorDir}/outputs/issue-${ctx.issueIid}/scenarios\n # 将 Markdown 用例、scenario-gen 的 result.json、生成的 .py 脚本都复制到产物目录\n cp <用例.md> ${vendorDir}/outputs/issue-${ctx.issueIid}/scenarios/\n cp <result.json> ${vendorDir}/outputs/issue-${ctx.issueIid}/scenarios/\n cp <生成的脚本.py> ${vendorDir}/outputs/issue-${ctx.issueIid}/scenarios/\n \\`\\`\\`\n 确保所有中间产物(用例 → 剧本 → 脚本)都可追溯。\n\n**Gate 3 — 执行阶段**\n- 只有 Gate 2 通过后才可以执行 \\`python3 ${vendorDir}/main.py${configArg}${outputDirArg} --script <script.py> --headless\\`\n- 每个脚本单独执行,逐一记录结果\n- 失败时进入 REPL 排障(\\`-i\\` 模式),排查并修复脚本\n- ⚠️ **REPL 排障后必须重跑脚本**:如果使用了 REPL 交互式探索或修改了脚本,**必须退出 REPL 后重新执行 \\`--script\\` 模式运行该脚本**。REPL 过程中产生的截图是调试中间状态,不能作为最终验证结果。只有 \\`--script\\` 模式产出的截图才是有效的验证截图\n- 最终验证标准:所有脚本都以 \\`--script\\` 模式成功执行,产出的截图反映最终正确状态\n\n将所有 E2E 测试结果汇总写入 \\`.claude-plan/issue-${ctx.issueIid}/03-uat-report.md\\`,包含:\n- 测试场景清单\n- 每个场景的执行结果(通过/失败)\n- 截图路径(如有)\n- 失败原因分析(如有失败)`;\n}\n\nfunction buildGenericE2ePrompt(ctx: PromptContext, ports?: E2ePromptPorts): string {\n const kv = getKnowledgeForPrompt();\n const frontendDir = kv.frontendDir;\n const e2eDir = kv.e2eDir;\n const e2eTool = kv.e2eTool;\n\n const serverSection = ports\n ? `\n**Preview 环境已启动(由系统管理,无需手动启动):**\n- 后端: http://${ports.host}:${ports.backendPort}\n- 前端: https://${ports.host}:${ports.frontendPort}\n\n执行 E2E 测试时请使用以下环境变量来连接已启动的服务:\n\\`\\`\\`bash\nE2E_PORT=${ports.frontendPort} E2E_HOST=${ports.host} E2E_BASE_URL=https://${ports.host}:${ports.frontendPort} \\\\\n cd ${frontendDir} && npx ${e2eTool.toLowerCase()} test\n\\`\\`\\`\n\n**注意**: 不要使用 pnpm test:e2e(它会尝试自行启动 webServer),直接用 npx ${e2eTool.toLowerCase()} test 即可复用已启动的前端。`\n : `\n执行 E2E 测试:\n\\`\\`\\`bash\ncd ${frontendDir} && pnpm test:e2e\n\\`\\`\\``;\n\n return `\n\n## E2E UI 验证(已启用)\n\n本次变更已开启 E2E UI 自动验收,请额外执行以下步骤:\n\n6. 如果本次变更涉及前端页面(${frontendDir}/ 目录有改动),请执行 UI E2E 验证:\n a. 在 ${e2eDir}/ 目录下编写针对本次变更的 ${e2eTool} 测试\n b. ${serverSection.trim()}\n c. 如果测试失败,分析失败原因并尝试修复\n7. 将 E2E 测试结果写入 \\`.claude-plan/issue-${ctx.issueIid}/03-uat-report.md\\`,包括:\n - 冒烟测试通过数 / 总数\n - 专项测试结果列表\n - 截图路径(如有)\n - 失败原因分析(如有失败)`;\n}\n\nexport interface ConflictResolveContext {\n issueIid: number;\n branchName: string;\n baseBranch: string;\n conflictFiles: string[];\n}\n\nexport function conflictResolvePrompt(ctx: ConflictResolveContext): string {\n const conflictFilesList = ctx.conflictFiles.map(f => `- \\`${f}\\``).join('\\n');\n return t('prompt.conflictResolve', {\n iid: ctx.issueIid,\n branch: ctx.branchName,\n baseBranch: ctx.baseBranch,\n conflictFilesList,\n });\n}\n\nexport function issueProgressComment(phase: string, status: string, detail?: string): string {\n const emoji: Record<string, string> = {\n analysis: '🔍', design: '📐', implement: '💻', verify: '✅',\n plan: '📋', review: '👀', build: '🔨', uat: '🧪',\n };\n const icon = emoji[phase] || '📋';\n const statusKey = status === 'completed' ? 'progress.completed' : status === 'failed' ? 'progress.failed' : 'progress.inProgress';\n const statusText = t(statusKey);\n let msg = t('progress.comment', { icon, phase, status: statusText });\n if (detail) {\n msg += `\\n\\n${detail}`;\n }\n return msg;\n}\n","import { GitOperations } from './GitOperations.js';\nimport type { AIRunner } from '../ai-runner/index.js';\nimport { conflictResolvePrompt } from '../prompts/templates.js';\nimport { logger as rootLogger } from '../logger.js';\n\nconst logger = rootLogger.child('ConflictResolver');\n\nexport interface ConflictResolveOptions {\n wtGit: GitOperations;\n targetRef: string;\n workDir: string;\n branchName: string;\n /** Identifier for logging and events (e.g. issueIid or taskId) */\n contextId: string | number;\n maxAttempts?: number;\n phaseTimeoutMs: number;\n onEvent?: (event: unknown) => void;\n}\n\n/**\n * Shared conflict resolution logic: rebase onto target, resolve conflicts with AI.\n * Extracted from PipelineOrchestrator.resolveConflict() for reuse by BraindumpOrchestrator.\n */\nexport class ConflictResolver {\n constructor(private aiRunner: AIRunner) {}\n\n /**\n * Rebase the current branch onto `targetRef` and resolve any conflicts using AI.\n * After successful resolution, the caller is responsible for force-pushing.\n *\n * @throws if conflicts cannot be resolved within maxAttempts\n */\n async resolve(opts: ConflictResolveOptions): Promise<void> {\n const { wtGit, targetRef, workDir, branchName, contextId, phaseTimeoutMs, onEvent } = opts;\n const maxAttempts = opts.maxAttempts ?? 20;\n\n // Abort residual rebase if any\n if (await wtGit.isRebaseInProgress()) {\n logger.warn('Found residual rebase in progress, aborting', { contextId });\n await wtGit.rebaseAbort();\n }\n\n // Attempt rebase\n const rebaseResult = await wtGit.rebase(targetRef);\n\n if (rebaseResult.success) {\n logger.info('Rebase succeeded without conflicts', { contextId });\n return;\n }\n\n // Has conflicts — resolve with AI\n let conflictFiles = rebaseResult.conflictFiles;\n let attempt = 0;\n\n while (conflictFiles.length > 0 && attempt < maxAttempts) {\n attempt++;\n logger.info('Resolving conflicts with AI', { contextId, attempt, conflictFiles });\n\n const prompt = conflictResolvePrompt({\n issueIid: typeof contextId === 'number' ? contextId : 0,\n branchName,\n baseBranch: targetRef.replace(/^origin\\//, ''),\n conflictFiles,\n });\n\n await this.aiRunner.run({\n prompt,\n workDir,\n timeoutMs: phaseTimeoutMs,\n onStreamEvent: onEvent ? (event: unknown) => onEvent(event) : undefined,\n });\n\n // Stage resolved files\n await wtGit.add(conflictFiles);\n\n // Continue rebase\n const continueResult = await wtGit.rebaseContinue();\n if (continueResult.done) {\n conflictFiles = [];\n } else {\n conflictFiles = continueResult.conflictFiles;\n }\n }\n\n if (conflictFiles.length > 0) {\n await wtGit.rebaseAbort();\n throw new Error(\n `Failed to resolve all conflicts after ${maxAttempts} attempts. Remaining: ${conflictFiles.join(', ')}`,\n );\n }\n\n logger.info('All conflicts resolved', { contextId, totalAttempts: attempt });\n }\n}\n"],"mappings":"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","names":["logger","fs","path","path","fs","logger"]}
@@ -47,6 +47,7 @@ var zhCN = {
47
47
  "state.phaseDone": "{label}\u5B8C\u6210",
48
48
  "state.phaseWaiting": "\u5F85{label}",
49
49
  "state.phaseApproved": "{label}\u901A\u8FC7",
50
+ "state.paused": "\u5DF2\u6682\u505C",
50
51
  // Orchestrator messages
51
52
  "orchestrator.retryComment": "\u{1F504} **\u81EA\u52A8\u5904\u7406\u91CD\u8BD5\u4E2D**\n\n\u68C0\u6D4B\u5230\u4E4B\u524D\u5904\u7406\u5931\u8D25\uFF0C\u6B63\u5728\u91CD\u8BD5...",
52
53
  "orchestrator.startComment": "\u{1F680} **\u81EA\u52A8\u5904\u7406\u5F00\u59CB**\n\n\u5DF2\u68C0\u6D4B\u5230 `auto-finish` \u6807\u7B7E\uFF0C\u5F00\u59CB\u81EA\u52A8\u5206\u6790\u548C\u5B9E\u65BD\u3002",
@@ -146,6 +147,9 @@ var zhCN = {
146
147
  "reaper.reaped": "\u5DF2\u81EA\u52A8\u6E05\u7406 Issue #{iid} \u7684\u8FC7\u671F Preview \u73AF\u5883\uFF08\u5DF2\u8FD0\u884C {hours}h\uFF09\u3002",
147
148
  "reaper.summary": "\u672C\u6B21\u6E05\u7406\u4E86 {count} \u4E2A\u8FC7\u671F Preview \u73AF\u5883\u3002",
148
149
  "cmd.cleanNotesSuccess": "\u{1F9F9} \u5DF2\u6E05\u7406 {count} \u6761 Agent \u8BC4\u8BBA\u3002",
150
+ "cmd.abortSuccess": "\u23F8 Issue #{iid} \u5F53\u524D\u9636\u6BB5\u5DF2\u4E2D\u6B62\u3002\u53EF\u901A\u8FC7 `@iaf continue` \u7EE7\u7EED\u6216 `@iaf redo` \u91CD\u505A\u3002",
151
+ "cmd.continueSuccess": "\u25B6 Issue #{iid} \u5DF2\u6062\u590D\u6267\u884C\uFF0C\u5C06\u5728\u4E0B\u6B21\u8F6E\u8BE2\u65F6\u7EE7\u7EED\u3002",
152
+ "cmd.redoSuccess": "\u{1F504} Issue #{iid} \u5F53\u524D\u9636\u6BB5\u5DF2\u91CD\u7F6E\uFF0C\u5C06\u5168\u65B0\u6267\u884C\u3002",
149
153
  // Intent recognizer
150
154
  "intent.systemPrompt": `\u4F60\u662F\u4E00\u4E2A\u6307\u4EE4\u89E3\u6790\u52A9\u624B\u3002\u7528\u6237\u4F1A\u5728\u5DE5\u8702(GitLab) Issue \u8BC4\u8BBA\u4E2D\u7528\u81EA\u7136\u8BED\u8A00\u63CF\u8FF0\u4ED6\u4EEC\u60F3\u8BA9\u81EA\u52A8\u5316\u7CFB\u7EDF\u505A\u4EC0\u4E48\u3002
151
155
  \u4F60\u9700\u8981\u4ECE\u7528\u6237\u7684\u8BC4\u8BBA\u4E2D\u63D0\u53D6\u51FA\u7ED3\u6784\u5316\u7684\u6307\u4EE4\u3002
@@ -158,6 +162,9 @@ var zhCN = {
158
162
  - reject: \u9A73\u56DE\u5F53\u524D\u65B9\u6848\uFF08\u9700\u8981\u63D0\u53D6 feedback\uFF09
159
163
  - status: \u67E5\u8BE2\u5F53\u524D\u5904\u7406\u72B6\u6001
160
164
  - restart: \u4ECE\u5934\u5F00\u59CB\uFF0C\u5B8C\u5168\u91CD\u505A
165
+ - abort: \u4E2D\u6B62/\u6682\u505C\u5F53\u524D\u9636\u6BB5\uFF08\u4FDD\u7559\u8FDB\u5EA6\uFF0C\u53EF\u6062\u590D\uFF09
166
+ - continue: \u4ECE\u6682\u505C\u5904\u7EE7\u7EED\u6267\u884C
167
+ - redo: \u91CD\u505A\u5F53\u524D\u9636\u6BB5\uFF08\u6E05\u9664\u4F1A\u8BDD\uFF0C\u5168\u65B0\u6267\u884C\uFF09
161
168
 
162
169
  \u53EF\u7528\u7684 phase\uFF08\u4EC5 retry-from \u65F6\u9700\u8981\uFF09:
163
170
  - analysis: \u9700\u6C42\u5206\u6790\u9636\u6BB5
@@ -566,6 +573,7 @@ var en = {
566
573
  "state.phaseDone": "{label} Done",
567
574
  "state.phaseWaiting": "Awaiting {label}",
568
575
  "state.phaseApproved": "{label} Approved",
576
+ "state.paused": "Paused",
569
577
  // Orchestrator messages
570
578
  "orchestrator.retryComment": "\u{1F504} **Auto-processing Retry**\n\nPrevious processing failed, retrying...",
571
579
  "orchestrator.startComment": "\u{1F680} **Auto-processing Started**\n\nDetected `auto-finish` label, starting automated analysis and implementation.",
@@ -665,6 +673,9 @@ var en = {
665
673
  "reaper.reaped": "Auto-cleaned expired preview for Issue #{iid} (ran for {hours}h).",
666
674
  "reaper.summary": "Cleaned up {count} expired preview environment(s).",
667
675
  "cmd.cleanNotesSuccess": "\u{1F9F9} Cleaned up {count} agent note(s).",
676
+ "cmd.abortSuccess": "\u23F8 Issue #{iid} current phase aborted. Use `@iaf continue` to resume or `@iaf redo` to restart the phase.",
677
+ "cmd.continueSuccess": "\u25B6 Issue #{iid} resumed. Will continue on the next poll cycle.",
678
+ "cmd.redoSuccess": "\u{1F504} Issue #{iid} current phase reset. Will execute fresh.",
668
679
  // Intent recognizer
669
680
  "intent.systemPrompt": `You are a command parsing assistant. Users will describe in natural language what they want the automation system to do in Gongfeng (GitLab) Issue comments.
670
681
  You need to extract structured commands from user comments.
@@ -677,6 +688,9 @@ Available intents:
677
688
  - reject: Reject current plan (need to extract feedback)
678
689
  - status: Query current processing status
679
690
  - restart: Start from scratch, redo everything
691
+ - abort: Abort/pause the current phase (preserves progress, can resume)
692
+ - continue: Resume execution from where it was paused
693
+ - redo: Redo current phase (clear session, fresh execution)
680
694
 
681
695
  Available phases (only needed for retry-from):
682
696
  - analysis: Requirements analysis phase
@@ -1067,4 +1081,4 @@ export {
1067
1081
  setLocale,
1068
1082
  t
1069
1083
  };
1070
- //# sourceMappingURL=chunk-KWODU7HB.js.map
1084
+ //# sourceMappingURL=chunk-YCYVNRLF.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/i18n/locales/zh-CN.ts","../src/i18n/locales/en.ts","../src/i18n/index.ts"],"sourcesContent":["export const zhCN: Record<string, string> = {\n // Phase labels\n 'phase.analysis': '分析',\n 'phase.design': '设计',\n 'phase.implement': '实现',\n 'phase.verify': '验证',\n 'phase.plan': '规划',\n 'phase.build': '实施',\n 'phase.release': '发布',\n 'phase.uat': 'UAT验证',\n 'phase.review': '审核',\n\n // Pipeline phase labels (used in PipelineDefinition)\n 'pipeline.phase.analysis': '分析',\n 'pipeline.phase.design': '设计',\n 'pipeline.phase.implement': '实施',\n 'pipeline.phase.verify': '验证',\n 'pipeline.phase.plan': '规划',\n 'pipeline.phase.review': '审核',\n 'pipeline.phase.build': '实施',\n 'pipeline.phase.release': '发布',\n 'pipeline.phase.uat': 'UAT验证',\n\n // Plan file labels\n 'planFile.01-analysis.md': '需求分析',\n 'planFile.02-design.md': '系统设计',\n 'planFile.03-todolist.md': '实施清单',\n 'planFile.04-verify-report.md': '验证报告',\n 'planFile.01-plan.md': '实施计划',\n 'planFile.02-verify-report.md': '验证报告',\n 'planFile.03-uat-report.md': 'UAT验证报告',\n 'planFile.review-feedback.md': '审核反馈',\n 'planFile.review-history.json': '审核历史',\n // 旧编号保留以兼容已持久化的数据\n 'planFile.03-release-detect.json': '发布检测报告',\n 'planFile.04-release-report.md': '发布报告',\n // UAT 阶段引入后 release 产物编号升至 05/06\n 'planFile.05-release-detect.json': '发布检测报告',\n 'planFile.06-release-report.md': '发布报告',\n\n // State labels (from collectStateLabels)\n 'state.pending': '待处理',\n 'state.skipped': '已跳过',\n 'state.branchCreated': '分支已创建',\n 'state.completed': '已完成',\n 'state.failed': '失败',\n 'state.resolvingConflict': '冲突修复中',\n 'state.phaseDoing': '{label}中',\n 'state.phaseDone': '{label}完成',\n 'state.phaseWaiting': '待{label}',\n 'state.phaseApproved': '{label}通过',\n 'state.paused': '已暂停',\n\n // Orchestrator messages\n 'orchestrator.retryComment': '🔄 **自动处理重试中**\\n\\n检测到之前处理失败,正在重试...',\n 'orchestrator.startComment': '🚀 **自动处理开始**\\n\\n已检测到 `auto-finish` 标签,开始自动分析和实施。',\n\n // Lock note messages (visible in issue timeline)\n 'lock.startMessage': '🚀 **自动处理开始**\\n\\n已检测到 `auto-finish` 标签,开始自动分析和实施。',\n 'lock.retryMessage': '🔄 **重试处理中**\\n\\n正在从上次失败处重试。',\n 'lock.completedMessage': '✅ **自动处理完成**',\n 'lock.failedMessage': '❌ **自动处理失败**\\n\\n处理过程遇到错误,可通过 `@iaf retry` 命令重试。',\n 'lock.cancelledMessage': '⏹️ **自动处理已取消**',\n 'lock.crashRecoveryMessage': '⚠️ **处理中断**\\n\\n节点异常重启,锁已自动释放。',\n 'lock.deployedMessage': '🚀 **已上线**\\n\\n该 Issue 已标记为已上线,worktree 已清理。',\n 'orchestrator.fetchProgress': '正在拉取最新代码...',\n 'orchestrator.worktreeProgress': '正在准备工作目录...',\n 'orchestrator.installProgress': '正在安装项目依赖 (npm install)...',\n 'orchestrator.initPlanProgress': '正在初始化计划目录...',\n 'orchestrator.phaseStartProgress': '准备就绪,开始执行阶段 (从 {phase} 开始)...',\n 'orchestrator.autoApproveComment': '⚡ **审核自动通过**\\n\\n检测到标签匹配 `autoApproveLabels` 配置,已自动跳过审核进入实施阶段。',\n 'orchestrator.createMrProgress': '正在创建合并请求...',\n 'orchestrator.uploadScreenshotsProgress': '正在上传 E2E 截图...',\n 'orchestrator.mrSection': '\\n\\n🔗 合并请求: {mrUrl}',\n 'orchestrator.mrFailSection': '\\n\\n⚠️ 合并请求创建失败,请手动创建。',\n 'orchestrator.completedComment': '✅ **自动处理完成**\\n\\n所有阶段已完成。分支: `{branch}`{mrSection}{previewSection}',\n 'orchestrator.failedComment': '❌ **自动处理失败**\\n\\n{error}\\n\\n将在下次轮询时重试(如果未超过最大重试次数)。',\n 'orchestrator.deployProgress': '正在启动 Preview 环境...',\n 'orchestrator.deployDoneProgress': 'Preview 环境已就绪: {url}',\n 'orchestrator.previewComment.title': '🌐 **Preview Environment 已就绪**',\n 'orchestrator.previewComment.tableHeader': '| 组件 | 地址 |',\n 'orchestrator.previewComment.tableSep': '|------|------|',\n 'orchestrator.previewComment.frontend': '前端',\n 'orchestrator.previewComment.backendApi': '后端 API',\n 'orchestrator.previewComment.hint': '可直接访问前端链接体验本次变更。',\n 'orchestrator.previewComment.expiry': 'Preview 将在 MR 合并后自动清理,或 {hours}h 后过期。',\n\n // BasePhase messages\n 'basePhase.aiStarting': '正在启动 AI Agent ({label})...',\n 'basePhase.aiResuming': '正在恢复上一次中断的 AI 会话 ({label})...',\n 'basePhase.resumePrompt': '上一次执行因中断而终止。请检查当前工作目录中已有的进度(包括已修改的文件和产物),从中断处继续完成任务。不要重复已经完成的工作。',\n 'basePhase.resumeFallback': '会话恢复失败,降级为全新执行',\n 'basePhase.rulesSection': '## 项目开发规范参考\\n以下是与本次任务相关的开发规范,请在编码时严格遵循:\\n\\n{rules}',\n 'basePhase.error': '错误: {message}',\n\n // IssuePoller messages\n 'poller.autoApproveComment': '⚡ **审核自动通过**\\n\\n检测到标签匹配 `autoApproveLabels` 配置(匹配: {labels}),已自动跳过审核进入实施阶段。',\n\n // Progress comment\n 'progress.completed': '已完成',\n 'progress.failed': '失败',\n 'progress.inProgress': '进行中',\n 'progress.comment': '{icon} **自动处理进度更新**\\n\\n阶段: **{phase}** — {status}',\n\n // NoteSync messages\n 'notesync.phaseCompleted': '{icon} **{label}阶段完成**',\n 'notesync.viewDoc': '📄 [查看完整{label}文档]({url})',\n 'notesync.viewDashboard': '📊 [在管理面板中查看详情]({url})',\n\n // MergeRequest messages\n 'mr.relatedIssue': '## 关联 Issue',\n 'mr.title': '标题',\n 'mr.branch': '分支',\n 'mr.issueDescription': '## Issue 描述',\n 'mr.noDescription': '(无描述)',\n 'mr.summaryFiles.01-analysis.md': '需求分析',\n 'mr.summaryFiles.01-plan.md': '实施计划',\n 'mr.summaryFiles.02-design.md': '系统设计',\n 'mr.summaryFiles.04-verify-report.md': '验证报告',\n 'mr.summaryFiles.02-verify-report.md': '验证报告',\n 'mr.aiSummary': '## AI 产物摘要',\n 'mr.autoCreated': '*此 MR 由 Issue Auto-Finish 系统自动创建*',\n 'mr.truncated': '...(已截断)',\n\n // Screenshot messages\n 'screenshot.title': '📸 **E2E 测试截图**',\n 'screenshot.truncated': '> ⚠️ 截图数量过多,仅展示前 20 张。',\n\n // Webhook handler\n 'webhook.helpText': [\n '无法识别指令,支持以下命令:',\n '',\n '| 命令 | 说明 |',\n '| --- | --- |',\n '| `@issue-auto status` / `状态` | 查询当前处理状态 |',\n '| `@issue-auto retry` / `重试` | 从失败处重试 |',\n '| `@issue-auto retry-from <阶段>` | 从指定阶段重试 |',\n '| `@issue-auto restart` / `重新开始` | 完全重做 |',\n '| `@issue-auto approve` / `通过` | 批准当前方案 |',\n '| `@issue-auto reject <原因>` / `驳回:<原因>` | 驳回方案 |',\n '| `@issue-auto supplement <内容>` / `补充:<内容>` | 补充上下文 |',\n '| `@issue-auto fix-conflict` / `修复冲突` | 自动修复 MR 合并冲突 |',\n '| `@issue-auto clean-notes` / `清理评论` | 删除 Agent 历史评论 |',\n ].join('\\n'),\n\n // Command executor\n 'cmd.previewNotStarted': 'Issue #{iid} 尚未启动 Preview 环境。\\nPreview 会在代码实现完成后自动启动(需启用 E2E 或 Preview 配置)。',\n 'cmd.previewStopped': '⏹ 已停止',\n 'cmd.previewRunning': '✅ 运行中',\n 'cmd.previewTable.component': '组件',\n 'cmd.previewTable.address': '地址',\n 'cmd.previewTable.frontend': '前端',\n 'cmd.previewTable.backendApi': '后端 API',\n 'cmd.previewTable.status': '状态',\n 'cmd.previewTable.startedAt': '启动于',\n 'cmd.noPreview': 'Issue #{iid} 没有正在运行的 Preview 环境。',\n 'cmd.previewStoppedMsg': 'Issue #{iid} 的 Preview 环境已停止。',\n 'cmd.previewStoppedAndCleaned': 'Issue #{iid} 的 Preview 环境已停止,worktree 已清理。',\n 'reaper.reaped': '已自动清理 Issue #{iid} 的过期 Preview 环境(已运行 {hours}h)。',\n 'reaper.summary': '本次清理了 {count} 个过期 Preview 环境。',\n 'cmd.cleanNotesSuccess': '🧹 已清理 {count} 条 Agent 评论。',\n 'cmd.abortSuccess': '⏸ Issue #{iid} 当前阶段已中止。可通过 `@iaf continue` 继续或 `@iaf redo` 重做。',\n 'cmd.continueSuccess': '▶ Issue #{iid} 已恢复执行,将在下次轮询时继续。',\n 'cmd.redoSuccess': '🔄 Issue #{iid} 当前阶段已重置,将全新执行。',\n\n // Intent recognizer\n 'intent.systemPrompt': `你是一个指令解析助手。用户会在工蜂(GitLab) Issue 评论中用自然语言描述他们想让自动化系统做什么。\n你需要从用户的评论中提取出结构化的指令。\n\n可用的 intent:\n- retry: 重试失败的任务(从上次失败的地方继续)\n- retry-from: 从指定阶段重新开始(需要提取 phase)\n- supplement: 补充额外的需求信息或上下文\n- approve: 批准/通过当前的设计方案\n- reject: 驳回当前方案(需要提取 feedback)\n- status: 查询当前处理状态\n- restart: 从头开始,完全重做\n- abort: 中止/暂停当前阶段(保留进度,可恢复)\n- continue: 从暂停处继续执行\n- redo: 重做当前阶段(清除会话,全新执行)\n\n可用的 phase(仅 retry-from 时需要):\n- analysis: 需求分析阶段\n- design: 系统设计阶段\n- implement: 代码实施阶段\n- verify: 验证测试阶段\n- uat: UAT/E2E 端对端验收测试阶段\n- plan: 规划阶段\n- build: 构建阶段\n\n规则:\n1. 如果用户同时表达了\"重试\"和\"补充信息\",优先使用 retry-from 或 retry 作为 intent,把补充信息放在 context 字段\n2. 如果用户只是在补充说明、提供额外信息,使用 supplement\n3. feedback 字段仅用于 reject 意图\n4. 如果无法判断用户意图,返回 null\n\n严格按以下 JSON 格式返回,不要添加任何其他文字:\n{\"intent\":\"...\",\"phase\":\"...或null\",\"context\":\"...或null\",\"feedback\":\"...或null\"}`,\n\n // API routes\n 'api.invalidFilename': '无效的文件名',\n 'api.docNotGenerated': '文档尚未生成',\n 'api.viewInDashboard': '在管理面板中查看',\n 'api.reviewFeedback': '👀 **方案审核反馈(第 {round} 轮)**',\n 'api.viewPlan': '📄 [查看实施计划]({url})',\n 'api.viewDetail': '📊 [在管理面板中查看详情]({url})',\n\n // Doc labels for api routes\n 'docLabel.01-analysis.md': '需求分析',\n 'docLabel.02-design.md': '系统设计',\n 'docLabel.03-todolist.md': '实施清单',\n 'docLabel.04-verify-report.md': '验证报告',\n 'docLabel.01-plan.md': '实施计划',\n 'docLabel.02-verify-report.md': '验证报告',\n 'docLabel.review-feedback.md': '审核反馈',\n\n // CLI DependencyChecker\n 'cli.bunInstallHint': '通过 Bun 官网安装: curl -fsSL https://bun.sh/install | bash',\n 'cli.cursorInstallHint': 'curl https://cursor.com/install -fsSL | bash',\n 'cli.checkingDep': '正在检查 {name} 状态...',\n 'cli.unknownDep': '未知依赖: {name}',\n 'cli.alreadyInstalled': '{name} 已安装 ({version})',\n 'cli.manualInstall': '{name} 需要手动安装: {hint}',\n 'cli.installing': '正在安装 {name}...',\n 'cli.installSuccess': '{name} 安装成功',\n 'cli.installFailed': '{name} 安装失败 (exit code: {code})',\n 'cli.installTimeout': '{name} 安装超时 ({seconds}s),请检查网络后重试',\n 'cli.aiInstallUnavailable': 'Claude Internal CLI 不可用,无法使用 AI 辅助安装',\n 'cli.aiInstalling': '正在使用 AI 辅助安装 {name}...',\n 'cli.aiInstallSuccess': '{name} 通过 AI 辅助安装成功',\n 'cli.aiInstallFailed': '{name} AI 辅助安装失败 (exit code: {code})',\n 'cli.aiInstallTimeout': '{name} AI 辅助安装超时 ({seconds}s)',\n 'cli.installAllStart': '开始批量安装依赖...',\n 'cli.installAllDone': '批量安装完成',\n 'cli.skippingInstalled': '跳过已安装: {name} ({version})',\n 'cli.tryingAiFallback': '默认安装失败,尝试 AI 辅助安装 {name}...',\n 'cli.noOutput': '安装命令未产生输出,请检查网络连接或手动执行安装命令',\n 'cli.verifyingInstall': '正在验证安装结果...',\n 'cli.manualInstallRequired': '请手动安装 {name}:{hint}',\n\n // Prompt templates\n 'prompt.analysis': `你是需求分析师。请分析以下工蜂 Issue 并输出需求分析文档。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}\n- 描述:\n{description}{supplement}\n\n## 输出要求\n请将分析结果写入 {planDir}/01-analysis.md,内容包括:\n1. **需求概述** — 用简洁的语言总结需求目标\n2. **功能点拆解** — 列出需要实现的具体功能点\n3. **影响范围分析** — 哪些模块/文件可能受到影响\n4. **非功能需求** — 性能、安全、兼容性等方面的考量\n5. **风险和依赖** — 潜在风险和外部依赖\n\n请先阅读项目根目录的 CLAUDE.md 了解项目架构,再进行分析。\n只输出文档内容,不要输出其他说明。`,\n\n 'prompt.design': `你是系统设计师。基于需求分析文档进行系统设计。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}{supplement}\n\n请先阅读:\n- {planDir}/01-analysis.md (需求分析)\n- CLAUDE.md (项目架构)\n\n## 输出要求\n请将设计文档写入 {planDir}/02-design.md,内容包括:\n1. **方案概述** — 整体设计思路\n2. **涉及的文件和模块** — 需要新建/修改的文件列表\n3. **数据模型变更** — 数据库或模型层的变更\n4. **接口设计** — API 接口定义\n5. **详细实施步骤** — 按顺序列出实施步骤\n\n请将实施 Todolist 写入 {planDir}/03-todolist.md,格式:\n- [ ] 步骤1: 具体描述\n- [ ] 步骤2: 具体描述\n...\n\n请确保 Todolist 足够详细,每个步骤可独立执行和验证。`,\n\n 'prompt.implement': `你是开发工程师。请按照设计文档和 Todolist 实施代码变更。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}\n\n请先阅读:\n- {planDir}/01-analysis.md (需求分析)\n- {planDir}/02-design.md (系统设计)\n- {planDir}/03-todolist.md (实施步骤)\n- CLAUDE.md (项目架构和代码规范)\n\n## 实施要求\n1. 逐项完成 03-todolist.md 中的任务\n2. 每完成一项,更新 03-todolist.md 中对应的勾选状态 (- [ ] → - [x])\n3. 严格遵循 CLAUDE.md 中的代码规范({codeStyleDescription})\n4. 不要过度工程化,只实现设计文档中要求的内容\n5. 确保代码安全,避免 OWASP Top 10 漏洞`,\n\n 'prompt.verify': `你是测试工程师。验证代码变更的正确性。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}\n\n## 前置检查\n在执行验证前,先确认依赖环境:\n1. 检查 {dependencyCheckPath} 是否存在\n2. 如不存在,运行 {installCommand};如果失败,尝试 {installFallbackCommand}\n3. 如果依赖始终无法安装完整,在报告中标注为\"环境问题\"并继续后续检查\n\n## 验证步骤\n1. 运行 {lintCommand} 检查代码风格\n2. 运行 {buildCommand} 检查编译\n3. 运行 {testFilesCommand} 运行相关测试\n4. 检查代码变更与 {planDir}/02-design.md 设计文档的一致性\n5. 检查 {planDir}/03-todolist.md 是否所有项都已完成\n\n## 已知的预存问题(忽略即可)\n{knownIssuesSection}\n- 如果某个 lint/build/test 的失败**不涉及本次变更的文件**,标注为\"预存问题\"\n\n将验证结果写入 {planDir}/04-verify-report.md,包括:\n- **Lint 结果**: 通过/失败及详情(区分本次变更 vs 预存问题)\n- **Build 结果**: 通过/失败及详情(区分本次变更 vs 预存问题)\n- **Test 结果**: 通过/失败及详情\n- **设计一致性检查**: 是否符合设计\n- **总结**: 整体评估和建议`,\n\n 'prompt.planModeVerify': `你是**严格的**测试工程师。验证代码变更的正确性。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}\n\n## 前置检查\n在执行验证前,先确认依赖环境:\n1. 检查 {dependencyCheckPath} 是否存在\n2. 如不存在,运行 {installCommand};如果失败,尝试 {installFallbackCommand}\n3. 如果依赖始终无法安装完整,在报告中标注为\"环境问题\"并继续后续检查\n\n## 验证步骤\n1. 运行 {lintCommand} 检查代码风格\n2. 运行 {buildCommand} 检查编译\n3. 运行 {testFilesCommand} 运行相关测试\n4. 检查代码变更与 {planDir}/01-plan.md 实施计划的一致性\n5. **严格检查** {planDir}/01-plan.md 中 Todolist 是否**所有项**都已完成(- [x])\n\n## 已知的预存问题(忽略即可)\n{knownIssuesSection}\n- 如果某个 lint/build/test 的失败**不涉及本次变更的文件**,标注为\"预存问题\"\n\n## 验证标准(必须全部满足才算通过)\n- Lint 零错误(本次变更相关)\n- Build 成功\n- 所有测试通过\n- Todolist 100% 完成(无未勾选项)\n- 代码符合实施计划\n\n将验证结果写入 {planDir}/02-verify-report.md,**必须**包括以下各节:\n- **Lint 结果**: 通过/失败 + 详情(区分本次变更 vs 预存问题)\n- **Build 结果**: 通过/失败 + 详情(区分本次变更 vs 预存问题)\n- **Test 结果**: 通过/失败 + 详情\n- **Todolist 检查**: X/Y 项完成 + 未完成项列表\n- **计划一致性检查**: 是否符合实施计划\n- **总结**: 验证通过/验证失败 + 具体原因\n\n**重要**: 如果任何一项检查失败,必须在\"总结\"中明确写\"验证失败\"。`,\n\n 'prompt.plan': `你是资深技术负责人。请一次性完成需求分析和方案设计。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}\n- 描述:\n{description}{supplement}\n\n## 输出要求\n请先阅读项目根目录的 CLAUDE.md 了解项目架构,再进行分析和设计。\n\n请将完整的实施计划写入 {planDir}/01-plan.md,内容包括:\n\n### 第一部分:需求分析\n1. **需求概述** — 用简洁的语言总结需求目标\n2. **功能点拆解** — 列出需要实现的具体功能点\n3. **影响范围分析** — 哪些模块/文件可能受到影响\n4. **非功能需求** — 性能、安全、兼容性等方面的考量\n5. **风险和依赖** — 潜在风险和外部依赖\n\n### 第二部分:系统设计\n1. **方案概述** — 整体设计思路\n2. **涉及的文件和模块** — 需要新建/修改的文件列表\n3. **数据模型变更** — 数据库或模型层的变更\n4. **接口设计** — API 接口定义\n5. **详细实施步骤** — 按顺序列出实施步骤\n\n### 第三部分:实施 Todolist\n- [ ] 步骤1: 具体描述\n- [ ] 步骤2: 具体描述\n...\n\n请确保 Todolist 足够详细,每个步骤可独立执行和验证。\n只输出文档内容,不要输出其他说明。不要修改任何代码文件。`,\n\n 'prompt.build': `你是开发工程师。请按照实施计划完成代码变更。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}\n\n请先阅读:\n- {planDir}/01-plan.md (完整实施计划,包含需求分析、系统设计和 Todolist)\n- CLAUDE.md (项目架构和代码规范)\n\n## 实施要求\n1. 严格按照 01-plan.md 中的 Todolist 逐项完成\n2. 每完成一项,更新 01-plan.md 中对应的勾选状态 (- [ ] → - [x])\n3. 严格遵循 CLAUDE.md 中的代码规范({codeStyleDescription})\n4. 不要过度工程化,只实现计划中要求的内容\n5. 确保代码安全,避免 OWASP Top 10 漏洞`,\n\n 'prompt.rePlan': `你是资深技术负责人。之前的实施计划未通过审核,请根据审核反馈修改计划。\n\n## Issue 信息\n- IID: #{iid}\n- 标题: {title}\n- 描述:\n{description}{supplement}\n\n## 审核反馈历史(共 {historyCount} 轮)\n{feedbackLines}\n\n请先阅读:\n- {planDir}/01-plan.md (当前实施计划)\n- {planDir}/review-feedback.md (审核反馈完整历史)\n- CLAUDE.md (项目架构)\n\n## 输出要求\n请综合所有轮次的审核反馈修改 {planDir}/01-plan.md,保持相同的文档结构。\n重点关注最新一轮的反馈,同时确保之前轮次提出的问题也已得到解决。\n只输出文档内容,不要输出其他说明。不要修改任何代码文件。`,\n\n 'prompt.rePlanRound': '### 第 {round} 轮 ({timestamp})\\n{feedback}',\n\n 'prompt.e2eSuffix.title': '## E2E UI 验证(已启用)',\n 'prompt.e2eSuffix.intro': '本次变更已开启 E2E UI 自动验收,请额外执行以下步骤:',\n 'prompt.e2eSuffix.previewNote': '**Preview 环境已启动(由系统管理,无需手动启动):**',\n 'prompt.e2eSuffix.backend': '后端',\n 'prompt.e2eSuffix.frontend': '前端',\n\n // Conflict resolution\n 'conflict.startComment': '🔧 **合并冲突修复开始**\\n\\n正在尝试将分支 `{branch}` rebase 到最新的 `{baseBranch}`...',\n 'conflict.noConflictComment': '✅ **Rebase 成功,没有冲突**\\n\\n分支 `{branch}` 已成功 rebase 到最新的 `{baseBranch}`,无需冲突修复。',\n 'conflict.resolvedComment': '✅ **合并冲突修复完成**\\n\\n分支 `{branch}` 已成功 rebase 到最新的 `{baseBranch}`,所有冲突已自动解决并通过验证。',\n 'conflict.failedComment': '❌ **合并冲突修复失败**\\n\\n{error}\\n\\n可通过 `@issue-auto fix-conflict` 重试。',\n 'conflict.mrResolvedComment': '✅ **合并冲突已自动修复**\\n\\n此 MR 的源分支已成功 rebase 到最新的目标分支,冲突已自动解决。请重新审查变更。',\n 'conflict.startedMsg': '🔧 冲突修复已启动,处理中请稍候...',\n 'conflict.invalidState': '当前状态不允许冲突修复(当前: {state})。仅在 Completed 或冲突修复失败后可触发。',\n 'conflict.noMr': 'Issue #{iid} 没有关联的 MR,无法执行冲突修复。',\n\n // Auto-update messages\n 'update.checking': '正在检查更新...',\n 'update.available': '发现新版本: v{latestVersion} (当前: v{currentVersion})',\n 'update.upToDate': '当前已是最新版本 (v{currentVersion})',\n 'update.draining': '正在等待活跃 Issue 完成...',\n 'update.updating': '正在更新到 v{version}...',\n 'update.completed': '更新完成,服务将自动重启',\n 'update.failed': '更新失败: {error}',\n\n 'prompt.conflictResolve': `你是一名资深开发工程师,正在处理 Git rebase 过程中产生的合并冲突。\n\n## 背景\n- Issue IID: #{iid}\n- 分支: \\`{branch}\\` 正在 rebase 到 \\`{baseBranch}\\`\n- 冲突文件列表:\n{conflictFilesList}\n\n## 任务\n请逐一解决上述冲突文件:\n\n1. 打开每个冲突文件,仔细阅读冲突标记(<<<<<<< HEAD / ======= / >>>>>>> ...)\n2. 理解双方修改的意图:\n - HEAD(当前分支)的修改目的\n - 对方分支的修改目的\n3. 正确合并代码,确保:\n - 保留双方有意义的修改\n - 完全移除所有冲突标记(<<<<<<<, =======, >>>>>>>)\n - 合并后的代码逻辑完整、可编译、可运行\n4. 如果某个文件的冲突涉及结构性变更(如函数签名变化),确保所有引用处也同步更新\n\n## 注意事项\n- 不要遗漏任何冲突标记\n- 不要引入新的 bug\n- 保持代码风格一致\n- 只修改冲突文件,不要做额外的代码改动`,\n\n // Distill (知识蒸馏)\n 'distill.diaryCreated': '📝 已记录 Issue #{iid} 的经验日记({outcome})',\n 'distill.started': '🧪 知识蒸馏开始...',\n 'distill.completed': '✅ 知识蒸馏完成 — 记忆: {memoryActions} 条, 规则: {ruleActions} 条, 向量: {vectorIndexed} 条',\n 'distill.failed': '❌ 知识蒸馏失败: {error}',\n 'distill.runEmpty': '暂无可蒸馏的日记数据',\n 'distill.noUndistilled': '暂无未蒸馏的日记(最少需要 {threshold} 条)',\n 'distill.statusTitle': '📊 **知识蒸馏状态**',\n 'distill.statusDiaries': '日记: {total} 条(未蒸馏: {undistilled} 条)',\n 'distill.statusMemories': '记忆: {count} 条',\n 'distill.statusRules': '规则: {count} 条',\n 'distill.statusVectors': '向量索引: {count} 条',\n 'distill.statusLastRun': '上次蒸馏: {time}',\n 'distill.statusNeverRun': '上次蒸馏: 尚未执行',\n 'distill.triggerSuccess': '🧪 知识蒸馏已触发,处理中请稍候...',\n\n // Build fix mode suffix (verify-fix loop)\n 'prompt.buildFixSuffix': `\n\n## ⚠️ 修复模式(第 {iteration} 轮修复)\n\n**重要**: 上一轮验证发现以下问题未通过,请在本轮优先修复:\n\n{failures}\n\n### 修复要求\n1. 仔细阅读验证报告中的具体错误信息\n2. 修复所有导致 lint/build/test 失败的问题\n3. 完成所有 Todolist 中未完成的项目(- [ ] → - [x]),特别是新增单测\n4. 不要引入新的问题\n5. 修复完成后确保 {lintCommand} 和 {buildCommand} 和 {testFilesCommand} 全部通过\n\n### 原始验证报告摘要\n\\`\\`\\`\n{rawReport}\n\\`\\`\\`\n`,\n\n // Plan mode fallback (for runners without native plan mode support)\n 'prompt.planModeFallback': `🏗️ **你现在是技术架构师,正在进行方案规划。**\n\n你的目标是产出一份深思熟虑的实施计划,而非直接编码。请像资深架构师评审需求那样思考:\n\n## 你的工作方式\n1. **充分调研** — 阅读项目代码、CLAUDE.md、相关模块,理解现有架构和约束\n2. **系统分析** — 梳理功能点、影响范围、模块间依赖关系\n3. **方案设计** — 提出清晰的技术方案,说明\"为什么这样做\"而不只是\"做什么\"\n4. **风险预判** — 识别潜在问题、边界情况、与现有代码的兼容性\n5. **输出文档** — 将分析结果写入结构化的计划文档\n\n## 约束\n本阶段仅做分析和文档输出。你必须使用文件写入工具将计划保存到指定路径,但不要修改项目代码文件,不要执行构建、测试或部署命令。后续的实施阶段会根据你的计划执行。`,\n\n // --- E2E Runner ---\n 'e2e.runnerCreated': 'E2E 验证阶段将使用独立 AI Runner({mode})',\n 'e2e.runnerFallback': 'E2E AI Runner 二进制({binary})未安装,回退使用主 Runner',\n};\n","export const en: Record<string, string> = {\n // Phase labels\n 'phase.analysis': 'Analysis',\n 'phase.design': 'Design',\n 'phase.implement': 'Implementation',\n 'phase.verify': 'Verification',\n 'phase.plan': 'Planning',\n 'phase.build': 'Build',\n 'phase.release': 'Release',\n 'phase.uat': 'UAT Verification',\n 'phase.review': 'Review',\n\n // Pipeline phase labels\n 'pipeline.phase.analysis': 'Analysis',\n 'pipeline.phase.design': 'Design',\n 'pipeline.phase.implement': 'Implementation',\n 'pipeline.phase.verify': 'Verification',\n 'pipeline.phase.plan': 'Planning',\n 'pipeline.phase.review': 'Review',\n 'pipeline.phase.build': 'Build',\n 'pipeline.phase.release': 'Release',\n 'pipeline.phase.uat': 'UAT Verification',\n\n // Plan file labels\n 'planFile.01-analysis.md': 'Requirements Analysis',\n 'planFile.02-design.md': 'System Design',\n 'planFile.03-todolist.md': 'Implementation Checklist',\n 'planFile.04-verify-report.md': 'Verification Report',\n 'planFile.01-plan.md': 'Implementation Plan',\n 'planFile.02-verify-report.md': 'Verification Report',\n 'planFile.03-uat-report.md': 'UAT Report',\n 'planFile.review-feedback.md': 'Review Feedback',\n 'planFile.review-history.json': 'Review History',\n // Old numbering kept for backward compatibility with persisted data\n 'planFile.03-release-detect.json': 'Release Detection Report',\n 'planFile.04-release-report.md': 'Release Report',\n // After UAT phase introduction, release artifacts shifted to 05/06\n 'planFile.05-release-detect.json': 'Release Detection Report',\n 'planFile.06-release-report.md': 'Release Report',\n\n // State labels\n 'state.pending': 'Pending',\n 'state.skipped': 'Skipped',\n 'state.branchCreated': 'Branch Created',\n 'state.completed': 'Completed',\n 'state.failed': 'Failed',\n 'state.resolvingConflict': 'Resolving Conflict',\n 'state.phaseDoing': '{label} In Progress',\n 'state.phaseDone': '{label} Done',\n 'state.phaseWaiting': 'Awaiting {label}',\n 'state.phaseApproved': '{label} Approved',\n 'state.paused': 'Paused',\n\n // Orchestrator messages\n 'orchestrator.retryComment': '🔄 **Auto-processing Retry**\\n\\nPrevious processing failed, retrying...',\n 'orchestrator.startComment': '🚀 **Auto-processing Started**\\n\\nDetected `auto-finish` label, starting automated analysis and implementation.',\n\n // Lock note messages (visible in issue timeline)\n 'lock.startMessage': '🚀 **Auto-processing Started**\\n\\nDetected `auto-finish` label, starting automated analysis and implementation.',\n 'lock.retryMessage': '🔄 **Retrying**\\n\\nRetrying from the last failure point.',\n 'lock.completedMessage': '✅ **Auto-processing Completed**',\n 'lock.failedMessage': '❌ **Auto-processing Failed**\\n\\nAn error occurred during processing. Use `@iaf retry` to retry.',\n 'lock.cancelledMessage': '⏹️ **Auto-processing Cancelled**',\n 'lock.crashRecoveryMessage': '⚠️ **Processing Interrupted**\\n\\nNode restarted unexpectedly, lock has been automatically released.',\n 'lock.deployedMessage': '🚀 **Deployed**\\n\\nThis issue has been marked as deployed and the worktree has been cleaned up.',\n 'orchestrator.fetchProgress': 'Fetching latest code...',\n 'orchestrator.worktreeProgress': 'Preparing working directory...',\n 'orchestrator.installProgress': 'Installing project dependencies (npm install)...',\n 'orchestrator.initPlanProgress': 'Initializing plan directory...',\n 'orchestrator.phaseStartProgress': 'Ready, starting phases (from {phase})...',\n 'orchestrator.autoApproveComment': '⚡ **Review Auto-approved**\\n\\nDetected label matching `autoApproveLabels` configuration, automatically skipping review and proceeding to implementation.',\n 'orchestrator.createMrProgress': 'Creating merge request...',\n 'orchestrator.uploadScreenshotsProgress': 'Uploading E2E screenshots...',\n 'orchestrator.mrSection': '\\n\\n🔗 Merge Request: {mrUrl}',\n 'orchestrator.mrFailSection': '\\n\\n⚠️ Failed to create merge request, please create manually.',\n 'orchestrator.completedComment': '✅ **Auto-processing Completed**\\n\\nAll phases completed. Branch: `{branch}`{mrSection}{previewSection}',\n 'orchestrator.failedComment': '❌ **Auto-processing Failed**\\n\\n{error}\\n\\nWill retry on next poll cycle (if max retries not exceeded).',\n 'orchestrator.deployProgress': 'Starting Preview environment...',\n 'orchestrator.deployDoneProgress': 'Preview environment ready: {url}',\n 'orchestrator.previewComment.title': '🌐 **Preview Environment Ready**',\n 'orchestrator.previewComment.tableHeader': '| Component | Address |',\n 'orchestrator.previewComment.tableSep': '|-----------|---------|',\n 'orchestrator.previewComment.frontend': 'Frontend',\n 'orchestrator.previewComment.backendApi': 'Backend API',\n 'orchestrator.previewComment.hint': 'Visit the frontend link to experience the changes.',\n 'orchestrator.previewComment.expiry': 'Preview will be cleaned up after MR merge, or expires in {hours}h.',\n\n // BasePhase messages\n 'basePhase.aiStarting': 'Starting AI Agent ({label})...',\n 'basePhase.aiResuming': 'Resuming previous AI session ({label})...',\n 'basePhase.resumePrompt': 'The previous execution was interrupted. Please check the existing progress in the working directory (including modified files and artifacts), and continue from where it left off. Do not repeat work that has already been completed.',\n 'basePhase.resumeFallback': 'Session resume failed, falling back to fresh execution',\n 'basePhase.rulesSection': '## Project Development Guidelines\\nThe following are development guidelines related to this task. Please strictly follow them when coding:\\n\\n{rules}',\n 'basePhase.error': 'Error: {message}',\n\n // IssuePoller messages\n 'poller.autoApproveComment': '⚡ **Review Auto-approved**\\n\\nDetected label matching `autoApproveLabels` configuration (matched: {labels}), automatically skipping review and proceeding to implementation.',\n\n // Progress comment\n 'progress.completed': 'Completed',\n 'progress.failed': 'Failed',\n 'progress.inProgress': 'In Progress',\n 'progress.comment': '{icon} **Auto-processing Progress Update**\\n\\nPhase: **{phase}** — {status}',\n\n // NoteSync messages\n 'notesync.phaseCompleted': '{icon} **{label} Phase Completed**',\n 'notesync.viewDoc': '📄 [View full {label} document]({url})',\n 'notesync.viewDashboard': '📊 [View details in dashboard]({url})',\n\n // MergeRequest messages\n 'mr.relatedIssue': '## Related Issue',\n 'mr.title': 'Title',\n 'mr.branch': 'Branch',\n 'mr.issueDescription': '## Issue Description',\n 'mr.noDescription': '(No description)',\n 'mr.summaryFiles.01-analysis.md': 'Requirements Analysis',\n 'mr.summaryFiles.01-plan.md': 'Implementation Plan',\n 'mr.summaryFiles.02-design.md': 'System Design',\n 'mr.summaryFiles.04-verify-report.md': 'Verification Report',\n 'mr.summaryFiles.02-verify-report.md': 'Verification Report',\n 'mr.aiSummary': '## AI Artifacts Summary',\n 'mr.autoCreated': '*This MR was automatically created by Issue Auto-Finish system*',\n 'mr.truncated': '...(truncated)',\n\n // Screenshot messages\n 'screenshot.title': '📸 **E2E Test Screenshots**',\n 'screenshot.truncated': '> ⚠️ Too many screenshots, showing only the first 20.',\n\n // Webhook handler\n 'webhook.helpText': [\n 'Unrecognized command. Available commands:',\n '',\n '| Command | Description |',\n '| --- | --- |',\n '| `@issue-auto status` | Check current processing status |',\n '| `@issue-auto retry` | Retry from failure point |',\n '| `@issue-auto retry-from <phase>` | Retry from specific phase |',\n '| `@issue-auto restart` | Start over from scratch |',\n '| `@issue-auto approve` | Approve current plan |',\n '| `@issue-auto reject <reason>` | Reject plan with feedback |',\n '| `@issue-auto supplement <content>` | Add supplementary context |',\n '| `@issue-auto fix-conflict` | Auto-resolve MR merge conflicts |',\n '| `@issue-auto clean-notes` | Delete agent history notes |',\n ].join('\\n'),\n\n // Command executor\n 'cmd.previewNotStarted': 'Issue #{iid} does not have a Preview environment yet.\\nPreview starts automatically after code implementation is complete (requires E2E or Preview to be enabled).',\n 'cmd.previewStopped': '⏹ Stopped',\n 'cmd.previewRunning': '✅ Running',\n 'cmd.previewTable.component': 'Component',\n 'cmd.previewTable.address': 'Address',\n 'cmd.previewTable.frontend': 'Frontend',\n 'cmd.previewTable.backendApi': 'Backend API',\n 'cmd.previewTable.status': 'Status',\n 'cmd.previewTable.startedAt': 'Started at',\n 'cmd.noPreview': 'Issue #{iid} does not have a running Preview environment.',\n 'cmd.previewStoppedMsg': 'Preview environment for Issue #{iid} has been stopped.',\n 'cmd.previewStoppedAndCleaned': 'Preview environment for Issue #{iid} stopped and worktree cleaned.',\n 'reaper.reaped': 'Auto-cleaned expired preview for Issue #{iid} (ran for {hours}h).',\n 'reaper.summary': 'Cleaned up {count} expired preview environment(s).',\n 'cmd.cleanNotesSuccess': '🧹 Cleaned up {count} agent note(s).',\n 'cmd.abortSuccess': '⏸ Issue #{iid} current phase aborted. Use `@iaf continue` to resume or `@iaf redo` to restart the phase.',\n 'cmd.continueSuccess': '▶ Issue #{iid} resumed. Will continue on the next poll cycle.',\n 'cmd.redoSuccess': '🔄 Issue #{iid} current phase reset. Will execute fresh.',\n\n // Intent recognizer\n 'intent.systemPrompt': `You are a command parsing assistant. Users will describe in natural language what they want the automation system to do in Gongfeng (GitLab) Issue comments.\nYou need to extract structured commands from user comments.\n\nAvailable intents:\n- retry: Retry failed task (continue from last failure point)\n- retry-from: Restart from a specific phase (need to extract phase)\n- supplement: Add additional requirement info or context\n- approve: Approve/pass the current design plan\n- reject: Reject current plan (need to extract feedback)\n- status: Query current processing status\n- restart: Start from scratch, redo everything\n- abort: Abort/pause the current phase (preserves progress, can resume)\n- continue: Resume execution from where it was paused\n- redo: Redo current phase (clear session, fresh execution)\n\nAvailable phases (only needed for retry-from):\n- analysis: Requirements analysis phase\n- design: System design phase\n- implement: Code implementation phase\n- verify: Verification testing phase\n- uat: UAT/E2E acceptance testing phase\n- plan: Planning phase\n- build: Build phase\n\nRules:\n1. If user expresses both \"retry\" and \"supplement info\", prioritize retry-from or retry as intent, put supplement info in context field\n2. If user is only supplementing/providing additional info, use supplement\n3. feedback field is only for reject intent\n4. If unable to determine user intent, return null\n\nStrictly return in the following JSON format, do not add any other text:\n{\"intent\":\"...\",\"phase\":\"...or null\",\"context\":\"...or null\",\"feedback\":\"...or null\"}`,\n\n // API routes\n 'api.invalidFilename': 'Invalid filename',\n 'api.docNotGenerated': 'Document not yet generated',\n 'api.viewInDashboard': 'View in dashboard',\n 'api.reviewFeedback': '👀 **Plan Review Feedback (Round {round})**',\n 'api.viewPlan': '📄 [View implementation plan]({url})',\n 'api.viewDetail': '📊 [View details in dashboard]({url})',\n\n // Doc labels for api routes\n 'docLabel.01-analysis.md': 'Requirements Analysis',\n 'docLabel.02-design.md': 'System Design',\n 'docLabel.03-todolist.md': 'Implementation Checklist',\n 'docLabel.04-verify-report.md': 'Verification Report',\n 'docLabel.01-plan.md': 'Implementation Plan',\n 'docLabel.02-verify-report.md': 'Verification Report',\n 'docLabel.review-feedback.md': 'Review Feedback',\n\n // CLI DependencyChecker\n 'cli.bunInstallHint': 'Install via Bun website: curl -fsSL https://bun.sh/install | bash',\n 'cli.cursorInstallHint': 'curl https://cursor.com/install -fsSL | bash',\n 'cli.checkingDep': 'Checking {name} status...',\n 'cli.unknownDep': 'Unknown dependency: {name}',\n 'cli.alreadyInstalled': '{name} already installed ({version})',\n 'cli.manualInstall': '{name} requires manual installation: {hint}',\n 'cli.installing': 'Installing {name}...',\n 'cli.installSuccess': '{name} installed successfully',\n 'cli.installFailed': '{name} installation failed (exit code: {code})',\n 'cli.installTimeout': '{name} installation timed out ({seconds}s), please check network and retry',\n 'cli.aiInstallUnavailable': 'Claude Internal CLI not available, cannot use AI-assisted installation',\n 'cli.aiInstalling': 'Using AI to install {name}...',\n 'cli.aiInstallSuccess': '{name} installed successfully via AI',\n 'cli.aiInstallFailed': '{name} AI-assisted installation failed (exit code: {code})',\n 'cli.aiInstallTimeout': '{name} AI-assisted installation timed out ({seconds}s)',\n 'cli.installAllStart': 'Starting batch dependency installation...',\n 'cli.installAllDone': 'Batch installation completed',\n 'cli.skippingInstalled': 'Skipping already installed: {name} ({version})',\n 'cli.tryingAiFallback': 'Default installation failed, trying AI-assisted installation for {name}...',\n 'cli.noOutput': 'Install command produced no output, please check network connection or run the install command manually',\n 'cli.verifyingInstall': 'Verifying installation result...',\n 'cli.manualInstallRequired': 'Please install {name} manually: {hint}',\n\n // Prompt templates\n 'prompt.analysis': `You are a requirements analyst. Please analyze the following Gongfeng Issue and output a requirements analysis document.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}\n- Description:\n{description}{supplement}\n\n## Output Requirements\nPlease write the analysis results to {planDir}/01-analysis.md, including:\n1. **Requirements Overview** — Summarize the requirements goal concisely\n2. **Feature Breakdown** — List specific features to implement\n3. **Impact Analysis** — Which modules/files may be affected\n4. **Non-functional Requirements** — Performance, security, compatibility considerations\n5. **Risks and Dependencies** — Potential risks and external dependencies\n\nPlease read the project's CLAUDE.md first to understand the architecture, then proceed with analysis.\nOnly output document content, no other explanations.`,\n\n 'prompt.design': `You are a system designer. Design the system based on the requirements analysis document.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}{supplement}\n\nPlease read first:\n- {planDir}/01-analysis.md (Requirements Analysis)\n- CLAUDE.md (Project Architecture)\n\n## Output Requirements\nPlease write the design document to {planDir}/02-design.md, including:\n1. **Solution Overview** — Overall design approach\n2. **Files and Modules Involved** — List of files to create/modify\n3. **Data Model Changes** — Database or model layer changes\n4. **API Design** — API interface definitions\n5. **Detailed Implementation Steps** — Step-by-step implementation plan\n\nPlease write the implementation Todolist to {planDir}/03-todolist.md, format:\n- [ ] Step 1: Specific description\n- [ ] Step 2: Specific description\n...\n\nEnsure the Todolist is detailed enough that each step can be independently executed and verified.`,\n\n 'prompt.implement': `You are a software engineer. Please implement code changes according to the design document and Todolist.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}\n\nPlease read first:\n- {planDir}/01-analysis.md (Requirements Analysis)\n- {planDir}/02-design.md (System Design)\n- {planDir}/03-todolist.md (Implementation Steps)\n- CLAUDE.md (Project Architecture and Code Standards)\n\n## Implementation Requirements\n1. Complete tasks in 03-todolist.md one by one\n2. After completing each item, update its checkbox status in 03-todolist.md (- [ ] → - [x])\n3. Strictly follow code standards in CLAUDE.md ({codeStyleDescription})\n4. Don't over-engineer, only implement what's required in the design document\n5. Ensure code security, avoid OWASP Top 10 vulnerabilities`,\n\n 'prompt.verify': `You are a test engineer. Verify the correctness of code changes.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}\n\n## Pre-checks\nBefore running verification, confirm the dependency environment:\n1. Check if {dependencyCheckPath} exists\n2. If not, run {installCommand}; if that fails, try {installFallbackCommand}\n3. If dependencies cannot be fully installed, mark as \"environment issue\" in the report and continue\n\n## Verification Steps\n1. Run {lintCommand} to check code style\n2. Run {buildCommand} to check compilation\n3. Run {testFilesCommand} to run relevant tests\n4. Check code changes against {planDir}/02-design.md design document consistency\n5. Check if all items in {planDir}/03-todolist.md are completed\n\n## Known Pre-existing Issues (can be ignored)\n{knownIssuesSection}\n- If a lint/build/test failure **does not involve files changed in this PR**, mark as \"pre-existing issue\"\n\nWrite verification results to {planDir}/04-verify-report.md, including:\n- **Lint Results**: Pass/fail with details (distinguish current changes vs pre-existing issues)\n- **Build Results**: Pass/fail with details (distinguish current changes vs pre-existing issues)\n- **Test Results**: Pass/fail with details\n- **Design Consistency Check**: Whether it matches the design\n- **Summary**: Overall assessment and recommendations`,\n\n 'prompt.planModeVerify': `You are a **strict** test engineer. Verify the correctness of code changes.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}\n\n## Pre-checks\nBefore running verification, confirm the dependency environment:\n1. Check if {dependencyCheckPath} exists\n2. If not, run {installCommand}; if that fails, try {installFallbackCommand}\n3. If dependencies cannot be fully installed, mark as \"environment issue\" in the report and continue\n\n## Verification Steps\n1. Run {lintCommand} to check code style\n2. Run {buildCommand} to check compilation\n3. Run {testFilesCommand} to run relevant tests\n4. Check code changes against {planDir}/01-plan.md implementation plan consistency\n5. **Strictly check** if **all items** in {planDir}/01-plan.md Todolist are completed (- [x])\n\n## Known Pre-existing Issues (can be ignored)\n{knownIssuesSection}\n- If a lint/build/test failure **does not involve files changed in this PR**, mark as \"pre-existing issue\"\n\n## Verification Criteria (ALL must pass)\n- Lint zero errors (related to current changes)\n- Build successful\n- All tests pass\n- Todolist 100% complete (no unchecked items)\n- Code matches implementation plan\n\nWrite verification results to {planDir}/02-verify-report.md, **must** include these sections:\n- **Lint Results**: Pass/Fail + details (distinguish current changes vs pre-existing issues)\n- **Build Results**: Pass/Fail + details (distinguish current changes vs pre-existing issues)\n- **Test Results**: Pass/Fail + details\n- **Todolist Check**: X/Y items completed + list of incomplete items\n- **Plan Consistency Check**: Whether it matches the implementation plan\n- **Summary**: Verification Passed/Verification Failed + specific reasons\n\n**Important**: If any check fails, you MUST write \"Verification Failed\" in the \"Summary\" section.`,\n\n 'prompt.plan': `You are a senior technical lead. Please complete requirements analysis and solution design in one go.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}\n- Description:\n{description}{supplement}\n\n## Output Requirements\nPlease read the project's CLAUDE.md first to understand the architecture, then proceed with analysis and design.\n\nPlease write the complete implementation plan to {planDir}/01-plan.md, including:\n\n### Part 1: Requirements Analysis\n1. **Requirements Overview** — Summarize the requirements goal concisely\n2. **Feature Breakdown** — List specific features to implement\n3. **Impact Analysis** — Which modules/files may be affected\n4. **Non-functional Requirements** — Performance, security, compatibility considerations\n5. **Risks and Dependencies** — Potential risks and external dependencies\n\n### Part 2: System Design\n1. **Solution Overview** — Overall design approach\n2. **Files and Modules Involved** — List of files to create/modify\n3. **Data Model Changes** — Database or model layer changes\n4. **API Design** — API interface definitions\n5. **Detailed Implementation Steps** — Step-by-step implementation plan\n\n### Part 3: Implementation Todolist\n- [ ] Step 1: Specific description\n- [ ] Step 2: Specific description\n...\n\nEnsure the Todolist is detailed enough that each step can be independently executed and verified.\nOnly output document content, no other explanations. Do not modify any code files.`,\n\n 'prompt.build': `You are a software engineer. Please complete code changes according to the implementation plan.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}\n\nPlease read first:\n- {planDir}/01-plan.md (Complete implementation plan including requirements analysis, system design and Todolist)\n- CLAUDE.md (Project Architecture and Code Standards)\n\n## Implementation Requirements\n1. Strictly follow the Todolist in 01-plan.md, completing items one by one\n2. After completing each item, update its checkbox status in 01-plan.md (- [ ] → - [x])\n3. Strictly follow code standards in CLAUDE.md ({codeStyleDescription})\n4. Don't over-engineer, only implement what's required in the plan\n5. Ensure code security, avoid OWASP Top 10 vulnerabilities`,\n\n 'prompt.rePlan': `You are a senior technical lead. The previous implementation plan was not approved. Please modify the plan based on review feedback.\n\n## Issue Information\n- IID: #{iid}\n- Title: {title}\n- Description:\n{description}{supplement}\n\n## Review Feedback History ({historyCount} rounds)\n{feedbackLines}\n\nPlease read first:\n- {planDir}/01-plan.md (Current implementation plan)\n- {planDir}/review-feedback.md (Complete review feedback history)\n- CLAUDE.md (Project Architecture)\n\n## Output Requirements\nPlease modify {planDir}/01-plan.md incorporating all rounds of review feedback, maintaining the same document structure.\nFocus on the latest round of feedback while ensuring issues raised in previous rounds are also resolved.\nOnly output document content, no other explanations. Do not modify any code files.`,\n\n 'prompt.rePlanRound': '### Round {round} ({timestamp})\\n{feedback}',\n\n 'prompt.e2eSuffix.title': '## E2E UI Verification (Enabled)',\n 'prompt.e2eSuffix.intro': 'E2E UI auto-verification is enabled for this change. Please perform the following additional steps:',\n 'prompt.e2eSuffix.previewNote': '**Preview environment is running (managed by the system, no manual startup needed):**',\n 'prompt.e2eSuffix.backend': 'Backend',\n 'prompt.e2eSuffix.frontend': 'Frontend',\n\n // Conflict resolution\n 'conflict.startComment': '🔧 **Merge Conflict Resolution Started**\\n\\nAttempting to rebase branch `{branch}` onto latest `{baseBranch}`...',\n 'conflict.noConflictComment': '✅ **Rebase Successful, No Conflicts**\\n\\nBranch `{branch}` has been successfully rebased onto latest `{baseBranch}`, no conflict resolution needed.',\n 'conflict.resolvedComment': '✅ **Merge Conflict Resolution Completed**\\n\\nBranch `{branch}` has been successfully rebased onto latest `{baseBranch}`, all conflicts have been automatically resolved and verified.',\n 'conflict.failedComment': '❌ **Merge Conflict Resolution Failed**\\n\\n{error}\\n\\nYou can retry with `@issue-auto fix-conflict`.',\n 'conflict.mrResolvedComment': '✅ **Merge conflicts have been automatically resolved**\\n\\nThe source branch of this MR has been successfully rebased onto the latest target branch, conflicts have been automatically resolved. Please re-review the changes.',\n 'conflict.startedMsg': '🔧 Conflict resolution started, please wait...',\n 'conflict.invalidState': 'Current state does not allow conflict resolution (current: {state}). Only allowed when Completed or after conflict resolution failure.',\n 'conflict.noMr': 'Issue #{iid} has no associated MR, cannot perform conflict resolution.',\n\n // Auto-update messages\n 'update.checking': 'Checking for updates...',\n 'update.available': 'New version available: v{latestVersion} (current: v{currentVersion})',\n 'update.upToDate': 'Already up to date (v{currentVersion})',\n 'update.draining': 'Waiting for active issues to complete...',\n 'update.updating': 'Updating to v{version}...',\n 'update.completed': 'Update completed, service will restart automatically',\n 'update.failed': 'Update failed: {error}',\n\n 'prompt.conflictResolve': `You are a senior software engineer handling merge conflicts during a Git rebase operation.\n\n## Context\n- Issue IID: #{iid}\n- Branch: \\`{branch}\\` is being rebased onto \\`{baseBranch}\\`\n- Conflicting files:\n{conflictFilesList}\n\n## Task\nPlease resolve the conflicts in each file listed above:\n\n1. Open each conflicting file and carefully read the conflict markers (<<<<<<< HEAD / ======= / >>>>>>> ...)\n2. Understand the intent of both sides:\n - HEAD (current branch) changes\n - Incoming branch changes\n3. Correctly merge the code, ensuring:\n - Meaningful changes from both sides are preserved\n - All conflict markers are completely removed (<<<<<<<, =======, >>>>>>>)\n - The merged code is logically complete, compilable, and runnable\n4. If a conflict involves structural changes (e.g., function signature changes), ensure all references are updated accordingly\n\n## Important\n- Do not leave any conflict markers\n- Do not introduce new bugs\n- Maintain consistent code style\n- Only modify conflicting files, do not make additional code changes`,\n\n // Distill (Knowledge Distillation)\n 'distill.diaryCreated': '📝 Experience diary recorded for Issue #{iid} ({outcome})',\n 'distill.started': '🧪 Knowledge distillation started...',\n 'distill.completed': '✅ Knowledge distillation complete — Memories: {memoryActions}, Rules: {ruleActions}, Vectors: {vectorIndexed}',\n 'distill.failed': '❌ Knowledge distillation failed: {error}',\n 'distill.runEmpty': 'No diary data available for distillation',\n 'distill.noUndistilled': 'No undistilled diaries (minimum {threshold} required)',\n 'distill.statusTitle': '📊 **Knowledge Distillation Status**',\n 'distill.statusDiaries': 'Diaries: {total} (undistilled: {undistilled})',\n 'distill.statusMemories': 'Memories: {count}',\n 'distill.statusRules': 'Rules: {count}',\n 'distill.statusVectors': 'Vector index: {count}',\n 'distill.statusLastRun': 'Last distillation: {time}',\n 'distill.statusNeverRun': 'Last distillation: never',\n 'distill.triggerSuccess': '🧪 Knowledge distillation triggered, please wait...',\n\n // Build fix mode suffix (verify-fix loop)\n 'prompt.buildFixSuffix': `\n\n## \\u26a0\\ufe0f Fix Mode (Iteration {iteration})\n\n**Important**: The previous verification found the following issues. Please fix them in this iteration:\n\n{failures}\n\n### Fix Requirements\n1. Carefully read the specific error messages in the verification report\n2. Fix all issues causing lint/build/test failures\n3. Complete all incomplete Todolist items (- [ ] \\u2192 - [x]), especially adding unit tests\n4. Do not introduce new problems\n5. After fixing, ensure {lintCommand} and {buildCommand} and {testFilesCommand} all pass\n\n### Original Verification Report Summary\n\\`\\`\\`\n{rawReport}\n\\`\\`\\`\n`,\n\n // Plan mode fallback (for runners without native plan mode support)\n 'prompt.planModeFallback': `🏗️ **You are a technical architect conducting solution planning.**\n\nYour goal is to produce a well-considered implementation plan, not to write code directly. Think like a senior architect reviewing requirements:\n\n## Your Approach\n1. **Research thoroughly** — Read project code, CLAUDE.md, and related modules to understand the existing architecture and constraints\n2. **Analyze systematically** — Map out features, impact scope, and inter-module dependencies\n3. **Design with rationale** — Propose a clear technical approach, explaining \"why\" not just \"what\"\n4. **Anticipate risks** — Identify edge cases, potential issues, and compatibility with existing code\n5. **Document your findings** — Write structured plan documents with your analysis\n\n## Constraint\nThis phase is analysis and documentation only. You MUST use file-writing tools to save your plan to the specified path, but do not modify project code files, and do not run build, test, or deploy commands. A separate implementation phase will execute your plan.`,\n\n // --- E2E Runner ---\n 'e2e.runnerCreated': 'E2E verify phases will use dedicated AI runner ({mode})',\n 'e2e.runnerFallback': 'E2E AI runner binary ({binary}) not installed, falling back to main runner',\n};\n","export type Locale = 'zh-CN' | 'en';\n\ntype MessageMap = Record<string, string>;\n\nconst locales = new Map<Locale, MessageMap>();\nlet currentLocale: Locale = 'zh-CN';\n\nexport function setLocale(locale: Locale): void {\n currentLocale = locale;\n}\n\nexport function getLocale(): Locale {\n return currentLocale;\n}\n\nexport function registerLocale(locale: Locale, messages: MessageMap): void {\n locales.set(locale, messages);\n}\n\nexport function t(key: string, params?: Record<string, string | number>): string {\n const messages = locales.get(currentLocale) ?? locales.get('zh-CN');\n if (!messages) return key;\n let text = messages[key];\n if (text === undefined) {\n const fallback = locales.get('zh-CN');\n text = fallback?.[key] ?? key;\n }\n if (params) {\n for (const [k, v] of Object.entries(params)) {\n text = text.replaceAll(`{${k}}`, String(v));\n }\n }\n return text;\n}\n\nimport { zhCN } from './locales/zh-CN.js';\nimport { en } from './locales/en.js';\n\nregisterLocale('zh-CN', zhCN);\nregisterLocale('en', en);\n"],"mappings":"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","names":[]}
package/dist/cli.js CHANGED
@@ -12,12 +12,12 @@ import {
12
12
  } from "./chunk-B7XUZJOK.js";
13
13
  import {
14
14
  resolveConfigFilePath
15
- } from "./chunk-MV2CADMB.js";
15
+ } from "./chunk-FWEW5E3B.js";
16
16
  import {
17
17
  resolveDisplayHost
18
18
  } from "./chunk-AKXDQH25.js";
19
19
  import "./chunk-TN2SYADO.js";
20
- import "./chunk-7FLKETBC.js";
20
+ import "./chunk-4LFNFRCL.js";
21
21
  import "./chunk-GF2RRYHB.js";
22
22
 
23
23
  // src/cli/index.ts
@@ -87,11 +87,11 @@ var defaults = getCliDefaults();
87
87
  var program = new Command();
88
88
  program.name("issue-auto-finish").description("Issue Auto-Finish: AI-powered issue resolution daemon").version(pkg.version, "-v, --version");
89
89
  program.command("init").description("Launch the interactive web setup wizard").option("-p, --port <port>", "Port for the setup wizard", "3456").option("-c, --config <path>", "Config file path to generate").action(async (opts) => {
90
- const { initCommand } = await import("./init-D2BQIVVD.js");
90
+ const { initCommand } = await import("./init-TDKDC6YP.js");
91
91
  await initCommand({ port: parseInt(opts.port, 10), config: opts.config });
92
92
  });
93
93
  program.command("start").description("Start the issue-auto-finish daemon service").option("-c, --config <path>", "Path to .env config file").option("-d, --daemon", "Run as a background daemon").action(async (opts) => {
94
- const { startCommand } = await import("./start-46GW453L.js");
94
+ const { startCommand } = await import("./start-27GRO4DP.js");
95
95
  await startCommand({ config: opts.config, daemon: opts.daemon });
96
96
  });
97
97
  program.command("stop").description("Stop the running service").option("-p, --port <port>", "Web UI port", defaults.port).option("-H, --host <host>", "Service host", defaults.host).option("-f, --force", "Force kill via SIGKILL").action(async (opts) => {
@@ -103,7 +103,7 @@ program.command("stop").description("Stop the running service").option("-p, --po
103
103
  });
104
104
  });
105
105
  program.command("restart").description("Restart the service (stop + start)").option("-c, --config <path>", "Path to .env config file").option("-p, --port <port>", "Web UI port", defaults.port).option("-H, --host <host>", "Service host", defaults.host).option("-d, --daemon", "Restart as a background daemon").action(async (opts) => {
106
- const { restartCommand } = await import("./restart-KFRHCALK.js");
106
+ const { restartCommand } = await import("./restart-RNXGTDWZ.js");
107
107
  await restartCommand({
108
108
  config: opts.config,
109
109
  host: opts.host,
@@ -112,11 +112,11 @@ program.command("restart").description("Restart the service (stop + start)").opt
112
112
  });
113
113
  });
114
114
  program.command("doctor").description("Check environment dependencies").action(async () => {
115
- const { doctorCommand } = await import("./doctor-P2ZH6PFX.js");
115
+ const { doctorCommand } = await import("./doctor-37JNBGDN.js");
116
116
  await doctorCommand();
117
117
  });
118
118
  program.command("analyze").description("Analyze target repository and generate knowledge.json").option("-d, --dir <path>", "Project directory to analyze (defaults to PROJECT_WORK_DIR)").option("-o, --output <path>", "Output path for knowledge.json").option("-f, --force", "Overwrite existing knowledge.json").action(async (opts) => {
119
- const { analyzeCommand } = await import("./analyze-ZITN3CSH.js");
119
+ const { analyzeCommand } = await import("./analyze-SXXPE5XL.js");
120
120
  await analyzeCommand({ dir: opts.dir, output: opts.output, force: opts.force });
121
121
  });
122
122
  program.command("status").description("Show service status").option("-p, --port <port>", "Web UI port to query", defaults.port).option("-H, --host <host>", "Service host to query", defaults.host).option("--json", "Output raw JSON").action(async (opts) => {
@@ -249,7 +249,7 @@ program.command("issues").description("List tracked issues").option("-p, --port
249
249
  });
250
250
  });
251
251
  program.command("braindump").description("Batch braindump: split ideas into tasks and execute in parallel").option("-f, --file <path>", "Read input from file").option("-t, --target <branch>", "Target branch for merging").option("-c, --concurrency <n>", "Max concurrent tasks").option("--runner <mode>", "Default AI runner mode (claude-internal, cursor-agent, codebuddy)").option("--auto", "Skip confirmation and execute immediately").option("-p, --port <port>", "Service port (proxy to running daemon)", defaults.port).option("-H, --host <host>", "Service host", defaults.host).action(async (opts) => {
252
- const { braindumpCommand } = await import("./braindump-LQU65XND.js");
252
+ const { braindumpCommand } = await import("./braindump-4E5SDMSZ.js");
253
253
  await braindumpCommand({
254
254
  file: opts.file,
255
255
  target: opts.target,
@@ -4,10 +4,10 @@ import {
4
4
  reloadConfig,
5
5
  resetDotenvCache,
6
6
  resolveConfigFilePath
7
- } from "./chunk-MV2CADMB.js";
7
+ } from "./chunk-FWEW5E3B.js";
8
8
  import "./chunk-AKXDQH25.js";
9
9
  import "./chunk-TN2SYADO.js";
10
- import "./chunk-7FLKETBC.js";
10
+ import "./chunk-4LFNFRCL.js";
11
11
  import "./chunk-GF2RRYHB.js";
12
12
  export {
13
13
  ConfigValidationError,
@@ -16,4 +16,4 @@ export {
16
16
  resetDotenvCache,
17
17
  resolveConfigFilePath
18
18
  };
19
- //# sourceMappingURL=config-C7AKWCPA.js.map
19
+ //# sourceMappingURL=config-QLINHCHD.js.map
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DependencyChecker
3
- } from "./chunk-3V3GQCB7.js";
4
- import "./chunk-KWODU7HB.js";
3
+ } from "./chunk-HDFNMVRQ.js";
4
+ import "./chunk-YCYVNRLF.js";
5
5
  import {
6
6
  resolveDataDir
7
7
  } from "./chunk-TN2SYADO.js";
@@ -98,4 +98,4 @@ async function doctorCommand() {
98
98
  export {
99
99
  doctorCommand
100
100
  };
101
- //# sourceMappingURL=doctor-P2ZH6PFX.js.map
101
+ //# sourceMappingURL=doctor-37JNBGDN.js.map
@@ -0,0 +1,13 @@
1
+ import { AppError } from './BaseError.js';
2
+ /**
3
+ * 用户主动中止/重做阶段时抛出,中断 PhaseLoopStep 循环。
4
+ *
5
+ * 在 PipelineOrchestrator 的 catch 块中被特殊处理,
6
+ * 不会进入 handleFailure 路径。
7
+ */
8
+ export declare class PhaseAbortedError extends AppError {
9
+ readonly phaseName: string;
10
+ readonly action: 'abort' | 'redo';
11
+ constructor(phaseName: string, action: 'abort' | 'redo');
12
+ }
13
+ //# sourceMappingURL=PhaseAbortedError.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PhaseAbortedError.d.ts","sourceRoot":"","sources":["../../src/errors/PhaseAbortedError.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;;;GAKG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;gBAE7B,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM;CAKxD"}
@@ -4,6 +4,7 @@ export { AIExecutionError } from './AIExecutionError.js';
4
4
  export { IssueNotFoundError, BatchNotFoundError, SessionNotFoundError, TaskNotFoundError } from './NotFoundError.js';
5
5
  export { InvalidPhaseError, InvalidStateError, PortExhaustionError, SessionLimitError } from './InvalidOperationError.js';
6
6
  export { ServiceShutdownError } from './ShutdownError.js';
7
+ export { PhaseAbortedError } from './PhaseAbortedError.js';
7
8
  export { AIOutputParseError } from './ParseError.js';
8
9
  export { PhaseNotRegisteredError, RunnerNotRegisteredError, PipelineNotFoundError, UnregisteredPhasesError, } from './RegistryError.js';
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1H,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/errors/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACrH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC1H,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EACL,uBAAuB,EACvB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,oBAAoB,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { EventEmitter } from 'node:events';
2
- export type EventType = 'issue:created' | 'issue:stateChanged' | 'issue:failed' | 'issue:deleted' | 'issue:resetForRetry' | 'issue:restarted' | 'issue:retryFromPhase' | 'poll:tick' | 'heartbeat' | 'agent:output' | 'pipeline:progress' | 'review:requested' | 'review:approved' | 'review:rejected' | 'conflict:started' | 'conflict:resolved' | 'conflict:failed' | 'update:checking' | 'update:available' | 'update:downloading' | 'update:completed' | 'update:failed' | 'braindump:created' | 'braindump:split:done' | 'braindump:confirmed' | 'braindump:task:started' | 'braindump:task:completed' | 'braindump:task:merging' | 'braindump:task:merged' | 'braindump:task:failed' | 'braindump:completed' | 'braindump:failed' | 'distill:diary:created' | 'distill:started' | 'distill:memory:updated' | 'distill:rule:generated' | 'distill:completed' | 'distill:failed' | 'verify:loopStarted' | 'verify:iterationComplete' | 'verify:loopExhausted' | 'release:gateRequested' | 'preview:reaped';
2
+ export type EventType = 'issue:created' | 'issue:stateChanged' | 'issue:failed' | 'issue:deleted' | 'issue:resetForRetry' | 'issue:restarted' | 'issue:retryFromPhase' | 'poll:tick' | 'heartbeat' | 'agent:output' | 'pipeline:progress' | 'review:requested' | 'review:approved' | 'review:rejected' | 'conflict:started' | 'conflict:resolved' | 'conflict:failed' | 'update:checking' | 'update:available' | 'update:downloading' | 'update:completed' | 'update:failed' | 'braindump:created' | 'braindump:split:done' | 'braindump:confirmed' | 'braindump:task:started' | 'braindump:task:completed' | 'braindump:task:merging' | 'braindump:task:merged' | 'braindump:task:failed' | 'braindump:completed' | 'braindump:failed' | 'distill:diary:created' | 'distill:started' | 'distill:memory:updated' | 'distill:rule:generated' | 'distill:completed' | 'distill:failed' | 'verify:loopStarted' | 'verify:iterationComplete' | 'verify:loopExhausted' | 'release:gateRequested' | 'uat:gateRequested' | 'uat:completed' | 'uat:failed' | 'issue:paused' | 'issue:continued' | 'issue:redone' | 'preview:reaped';
3
3
  export interface EventPayload {
4
4
  type: EventType;
5
5
  data: unknown;