@su-record/vibe 2.7.18 → 2.7.20

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 (345) hide show
  1. package/.env.example +37 -37
  2. package/CLAUDE.md +153 -153
  3. package/LICENSE +21 -21
  4. package/README.md +451 -449
  5. package/agents/architect-low.md +41 -41
  6. package/agents/architect-medium.md +59 -59
  7. package/agents/architect.md +80 -80
  8. package/agents/build-error-resolver.md +115 -115
  9. package/agents/compounder.md +261 -261
  10. package/agents/diagrammer.md +178 -178
  11. package/agents/docs/api-documenter.md +99 -99
  12. package/agents/docs/changelog-writer.md +93 -93
  13. package/agents/e2e-tester.md +294 -294
  14. package/agents/event/event-comms.md +78 -0
  15. package/agents/event/event-content.md +68 -0
  16. package/agents/event/event-image.md +95 -0
  17. package/agents/event/event-ops.md +84 -0
  18. package/agents/event/event-scheduler.md +69 -0
  19. package/agents/event/event-speaker.md +86 -0
  20. package/agents/explorer-low.md +42 -42
  21. package/agents/explorer-medium.md +59 -59
  22. package/agents/explorer.md +48 -48
  23. package/agents/implementer-low.md +43 -43
  24. package/agents/implementer-medium.md +52 -52
  25. package/agents/implementer.md +54 -54
  26. package/agents/junior-mentor.md +141 -141
  27. package/agents/planning/requirements-analyst.md +84 -84
  28. package/agents/planning/ux-advisor.md +83 -83
  29. package/agents/qa/acceptance-tester.md +86 -86
  30. package/agents/qa/edge-case-finder.md +93 -93
  31. package/agents/refactor-cleaner.md +143 -143
  32. package/agents/research/best-practices-agent.md +199 -199
  33. package/agents/research/codebase-patterns-agent.md +157 -157
  34. package/agents/research/framework-docs-agent.md +188 -188
  35. package/agents/research/security-advisory-agent.md +213 -213
  36. package/agents/review/architecture-reviewer.md +107 -107
  37. package/agents/review/complexity-reviewer.md +116 -116
  38. package/agents/review/data-integrity-reviewer.md +88 -88
  39. package/agents/review/git-history-reviewer.md +103 -103
  40. package/agents/review/performance-reviewer.md +86 -86
  41. package/agents/review/python-reviewer.md +150 -150
  42. package/agents/review/rails-reviewer.md +139 -139
  43. package/agents/review/react-reviewer.md +144 -144
  44. package/agents/review/security-reviewer.md +80 -80
  45. package/agents/review/simplicity-reviewer.md +140 -140
  46. package/agents/review/test-coverage-reviewer.md +116 -116
  47. package/agents/review/typescript-reviewer.md +127 -127
  48. package/agents/searcher.md +54 -54
  49. package/agents/simplifier.md +120 -120
  50. package/agents/tester.md +49 -49
  51. package/agents/ui/ui-a11y-auditor.md +93 -93
  52. package/agents/ui/ui-antipattern-detector.md +94 -94
  53. package/agents/ui/ui-dataviz-advisor.md +69 -69
  54. package/agents/ui/ui-design-system-gen.md +57 -57
  55. package/agents/ui/ui-industry-analyzer.md +49 -49
  56. package/agents/ui/ui-layout-architect.md +65 -65
  57. package/agents/ui/ui-stack-implementer.md +68 -68
  58. package/agents/ui/ux-compliance-reviewer.md +81 -81
  59. package/agents/ui-previewer.md +258 -258
  60. package/commands/vibe.analyze.md +379 -379
  61. package/commands/vibe.event.md +163 -0
  62. package/commands/vibe.review.md +607 -607
  63. package/commands/vibe.run.md +2217 -2124
  64. package/commands/vibe.spec.md +1195 -1195
  65. package/commands/vibe.spec.review.md +569 -569
  66. package/commands/vibe.trace.md +50 -0
  67. package/commands/vibe.utils.md +413 -413
  68. package/commands/vibe.verify.md +484 -484
  69. package/dist/__tests__/architecture.test.d.ts +2 -0
  70. package/dist/__tests__/architecture.test.d.ts.map +1 -0
  71. package/dist/__tests__/architecture.test.js +207 -0
  72. package/dist/__tests__/architecture.test.js.map +1 -0
  73. package/dist/cli/auth.js +3 -3
  74. package/dist/cli/auth.js.map +1 -1
  75. package/dist/cli/collaborator.js +52 -52
  76. package/dist/cli/commands/evolution.js +12 -12
  77. package/dist/cli/commands/info.d.ts.map +1 -1
  78. package/dist/cli/commands/info.js +45 -81
  79. package/dist/cli/commands/info.js.map +1 -1
  80. package/dist/cli/commands/init.js +5 -5
  81. package/dist/cli/commands/remove.js +14 -14
  82. package/dist/cli/commands/sentinel.js +27 -27
  83. package/dist/cli/commands/skills.js +5 -5
  84. package/dist/cli/commands/slack.js +10 -10
  85. package/dist/cli/commands/telegram.js +12 -12
  86. package/dist/cli/detect.d.ts.map +1 -1
  87. package/dist/cli/detect.js +55 -32
  88. package/dist/cli/detect.js.map +1 -1
  89. package/dist/cli/index.d.ts +1 -1
  90. package/dist/cli/index.d.ts.map +1 -1
  91. package/dist/cli/index.js +52 -52
  92. package/dist/cli/index.js.map +1 -1
  93. package/dist/cli/llm/claude-commands.js +16 -16
  94. package/dist/cli/llm/config.js +18 -18
  95. package/dist/cli/llm/gemini-commands.js +16 -16
  96. package/dist/cli/llm/gpt-commands.js +19 -19
  97. package/dist/cli/llm/help.js +21 -21
  98. package/dist/cli/postinstall/constants.d.ts.map +1 -1
  99. package/dist/cli/postinstall/constants.js +24 -0
  100. package/dist/cli/postinstall/constants.js.map +1 -1
  101. package/dist/cli/postinstall/cursor-agents.js +32 -32
  102. package/dist/cli/postinstall/cursor-rules.js +83 -83
  103. package/dist/cli/postinstall/cursor-skills.js +743 -743
  104. package/dist/cli/setup/Provisioner.js +42 -42
  105. package/dist/infra/lib/AutomationLevel.d.ts +48 -0
  106. package/dist/infra/lib/AutomationLevel.d.ts.map +1 -0
  107. package/dist/infra/lib/AutomationLevel.js +157 -0
  108. package/dist/infra/lib/AutomationLevel.js.map +1 -0
  109. package/dist/infra/lib/DecisionTracer.d.ts +81 -0
  110. package/dist/infra/lib/DecisionTracer.d.ts.map +1 -0
  111. package/dist/infra/lib/DecisionTracer.js +135 -0
  112. package/dist/infra/lib/DecisionTracer.js.map +1 -0
  113. package/dist/infra/lib/DeepInit.js +24 -24
  114. package/dist/infra/lib/InteractiveCheckpoint.d.ts +75 -0
  115. package/dist/infra/lib/InteractiveCheckpoint.d.ts.map +1 -0
  116. package/dist/infra/lib/InteractiveCheckpoint.js +179 -0
  117. package/dist/infra/lib/InteractiveCheckpoint.js.map +1 -0
  118. package/dist/infra/lib/IterationTracker.d.ts +44 -0
  119. package/dist/infra/lib/IterationTracker.d.ts.map +1 -1
  120. package/dist/infra/lib/IterationTracker.js +267 -12
  121. package/dist/infra/lib/IterationTracker.js.map +1 -1
  122. package/dist/infra/lib/LoopBreaker.d.ts +56 -0
  123. package/dist/infra/lib/LoopBreaker.d.ts.map +1 -0
  124. package/dist/infra/lib/LoopBreaker.js +109 -0
  125. package/dist/infra/lib/LoopBreaker.js.map +1 -0
  126. package/dist/infra/lib/PythonParser.js +108 -108
  127. package/dist/infra/lib/ReviewRace.js +96 -96
  128. package/dist/infra/lib/SkillFrontmatter.js +28 -28
  129. package/dist/infra/lib/SkillQualityGate.js +9 -9
  130. package/dist/infra/lib/SkillRepository.js +159 -159
  131. package/dist/infra/lib/UltraQA.js +99 -99
  132. package/dist/infra/lib/VerificationLoop.d.ts +105 -0
  133. package/dist/infra/lib/VerificationLoop.d.ts.map +1 -0
  134. package/dist/infra/lib/VerificationLoop.js +189 -0
  135. package/dist/infra/lib/VerificationLoop.js.map +1 -0
  136. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts +2 -0
  137. package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts.map +1 -0
  138. package/dist/infra/lib/__tests__/AutomationLevel.test.js +297 -0
  139. package/dist/infra/lib/__tests__/AutomationLevel.test.js.map +1 -0
  140. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts +2 -0
  141. package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts.map +1 -0
  142. package/dist/infra/lib/__tests__/DecisionTracer.test.js +274 -0
  143. package/dist/infra/lib/__tests__/DecisionTracer.test.js.map +1 -0
  144. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts +2 -0
  145. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts.map +1 -0
  146. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js +350 -0
  147. package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js.map +1 -0
  148. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts +2 -0
  149. package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts.map +1 -0
  150. package/dist/infra/lib/__tests__/LoopBreaker.test.js +340 -0
  151. package/dist/infra/lib/__tests__/LoopBreaker.test.js.map +1 -0
  152. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts +2 -0
  153. package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts.map +1 -0
  154. package/dist/infra/lib/__tests__/VerificationLoop.test.js +486 -0
  155. package/dist/infra/lib/__tests__/VerificationLoop.test.js.map +1 -0
  156. package/dist/infra/lib/autonomy/AuditStore.js +41 -41
  157. package/dist/infra/lib/autonomy/ConfirmationStore.js +30 -30
  158. package/dist/infra/lib/autonomy/EventOutbox.js +38 -38
  159. package/dist/infra/lib/autonomy/PolicyEngine.d.ts +3 -3
  160. package/dist/infra/lib/autonomy/PolicyEngine.js +18 -18
  161. package/dist/infra/lib/autonomy/SecuritySentinel.js +1 -1
  162. package/dist/infra/lib/autonomy/SuggestionStore.js +33 -33
  163. package/dist/infra/lib/embedding/VectorStore.js +22 -22
  164. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js +4 -0
  165. package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js.map +1 -1
  166. package/dist/infra/lib/evolution/AgentAnalyzer.js +10 -10
  167. package/dist/infra/lib/evolution/DeprecationDetector.d.ts +68 -0
  168. package/dist/infra/lib/evolution/DeprecationDetector.d.ts.map +1 -0
  169. package/dist/infra/lib/evolution/DeprecationDetector.js +207 -0
  170. package/dist/infra/lib/evolution/DeprecationDetector.js.map +1 -0
  171. package/dist/infra/lib/evolution/DescriptionOptimizer.js +21 -21
  172. package/dist/infra/lib/evolution/GenerationRegistry.js +36 -36
  173. package/dist/infra/lib/evolution/InsightStore.js +90 -90
  174. package/dist/infra/lib/evolution/ParityTester.d.ts +74 -0
  175. package/dist/infra/lib/evolution/ParityTester.d.ts.map +1 -0
  176. package/dist/infra/lib/evolution/ParityTester.js +238 -0
  177. package/dist/infra/lib/evolution/ParityTester.js.map +1 -0
  178. package/dist/infra/lib/evolution/RollbackManager.js +5 -5
  179. package/dist/infra/lib/evolution/SkillBenchmark.js +23 -23
  180. package/dist/infra/lib/evolution/SkillEvalRunner.js +50 -50
  181. package/dist/infra/lib/evolution/SkillGapDetector.js +10 -10
  182. package/dist/infra/lib/evolution/UsageTracker.js +28 -28
  183. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts +2 -0
  184. package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts.map +1 -0
  185. package/dist/infra/lib/evolution/__tests__/deprecation.test.js +251 -0
  186. package/dist/infra/lib/evolution/__tests__/deprecation.test.js.map +1 -0
  187. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts +2 -0
  188. package/dist/infra/lib/evolution/__tests__/parity.test.d.ts.map +1 -0
  189. package/dist/infra/lib/evolution/__tests__/parity.test.js +319 -0
  190. package/dist/infra/lib/evolution/__tests__/parity.test.js.map +1 -0
  191. package/dist/infra/lib/evolution/index.d.ts +4 -0
  192. package/dist/infra/lib/evolution/index.d.ts.map +1 -1
  193. package/dist/infra/lib/evolution/index.js +3 -0
  194. package/dist/infra/lib/evolution/index.js.map +1 -1
  195. package/dist/infra/lib/gemini/orchestration.js +5 -5
  196. package/dist/infra/lib/gpt/orchestration.js +4 -4
  197. package/dist/infra/lib/gpt/specializations.d.ts +1 -1
  198. package/dist/infra/lib/gpt/specializations.js +1 -1
  199. package/dist/infra/lib/memory/KnowledgeGraph.js +4 -4
  200. package/dist/infra/lib/memory/MemorySearch.js +57 -57
  201. package/dist/infra/lib/memory/MemoryStorage.js +181 -181
  202. package/dist/infra/lib/memory/ObservationStore.js +28 -28
  203. package/dist/infra/lib/memory/ReflectionStore.js +30 -30
  204. package/dist/infra/lib/memory/SessionRAGRetriever.js +7 -7
  205. package/dist/infra/lib/memory/SessionRAGStore.js +225 -225
  206. package/dist/infra/lib/memory/SessionSummarizer.js +9 -9
  207. package/dist/infra/lib/telemetry/SkillTelemetry.d.ts +6 -0
  208. package/dist/infra/lib/telemetry/SkillTelemetry.d.ts.map +1 -1
  209. package/dist/infra/lib/telemetry/SkillTelemetry.js +11 -0
  210. package/dist/infra/lib/telemetry/SkillTelemetry.js.map +1 -1
  211. package/dist/infra/orchestrator/AgentManager.js +12 -12
  212. package/dist/infra/orchestrator/AgentRegistry.js +65 -65
  213. package/dist/infra/orchestrator/BackgroundManager.d.ts.map +1 -1
  214. package/dist/infra/orchestrator/BackgroundManager.js +2 -0
  215. package/dist/infra/orchestrator/BackgroundManager.js.map +1 -1
  216. package/dist/infra/orchestrator/MultiLlmResearch.js +8 -8
  217. package/dist/infra/orchestrator/PhasePipeline.js +1 -1
  218. package/dist/infra/orchestrator/PhasePipeline.js.map +1 -1
  219. package/dist/infra/orchestrator/SwarmOrchestrator.test.js +16 -16
  220. package/dist/infra/orchestrator/parallelResearch.js +24 -24
  221. package/dist/tools/convention/analyzeComplexity.test.js +115 -115
  222. package/dist/tools/convention/validateCodeQuality.test.js +104 -104
  223. package/dist/tools/index.d.ts +16 -19
  224. package/dist/tools/index.d.ts.map +1 -1
  225. package/dist/tools/index.js +15 -27
  226. package/dist/tools/index.js.map +1 -1
  227. package/dist/tools/memory/createMemoryTimeline.js +10 -10
  228. package/dist/tools/memory/getMemoryGraph.js +12 -12
  229. package/dist/tools/memory/getSessionContext.js +9 -9
  230. package/dist/tools/memory/linkMemories.js +14 -14
  231. package/dist/tools/memory/listMemories.js +4 -4
  232. package/dist/tools/memory/recallMemory.js +4 -4
  233. package/dist/tools/memory/saveMemory.js +4 -4
  234. package/dist/tools/memory/searchMemoriesAdvanced.js +23 -23
  235. package/dist/tools/memory/startSession.js +1 -1
  236. package/dist/tools/memory/startSession.js.map +1 -1
  237. package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
  238. package/dist/tools/semantic/astGrep.test.js +6 -6
  239. package/dist/tools/spec/index.d.ts +0 -4
  240. package/dist/tools/spec/index.d.ts.map +1 -1
  241. package/dist/tools/spec/index.js +0 -4
  242. package/dist/tools/spec/index.js.map +1 -1
  243. package/dist/tools/spec/prdParser.test.js +171 -171
  244. package/dist/tools/spec/specGenerator.js +169 -169
  245. package/dist/tools/spec/traceabilityMatrix.js +64 -64
  246. package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
  247. package/hooks/gemini-hooks.json +73 -73
  248. package/hooks/hooks.json +137 -137
  249. package/hooks/scripts/code-check.js +77 -77
  250. package/hooks/scripts/context-save.js +212 -212
  251. package/hooks/scripts/evolution-engine.js +69 -0
  252. package/hooks/scripts/hud-status.js +291 -291
  253. package/hooks/scripts/keyword-detector.js +214 -214
  254. package/hooks/scripts/llm-orchestrate.js +475 -475
  255. package/hooks/scripts/post-edit.js +32 -32
  256. package/hooks/scripts/pre-tool-guard.js +125 -125
  257. package/hooks/scripts/prompt-dispatcher.js +185 -185
  258. package/hooks/scripts/sentinel-guard.js +104 -104
  259. package/hooks/scripts/session-start.js +106 -106
  260. package/hooks/scripts/skill-injector.js +83 -0
  261. package/hooks/scripts/stop-notify.js +209 -209
  262. package/hooks/scripts/utils.js +100 -100
  263. package/languages/csharp-unity.md +515 -515
  264. package/languages/gdscript-godot.md +470 -470
  265. package/languages/ruby-rails.md +489 -489
  266. package/languages/typescript-angular.md +433 -433
  267. package/languages/typescript-astro.md +416 -416
  268. package/languages/typescript-electron.md +406 -406
  269. package/languages/typescript-nestjs.md +524 -524
  270. package/languages/typescript-svelte.md +407 -407
  271. package/languages/typescript-tauri.md +365 -365
  272. package/package.json +101 -123
  273. package/skills/agents-md/SKILL.md +120 -120
  274. package/skills/arch-guard/SKILL.md +180 -180
  275. package/skills/brand-assets/SKILL.md +146 -146
  276. package/skills/capability-loop/SKILL.md +167 -167
  277. package/skills/characterization-test/SKILL.md +206 -206
  278. package/skills/commerce-patterns/SKILL.md +63 -63
  279. package/skills/commit-push-pr/SKILL.md +75 -75
  280. package/skills/context7-usage/SKILL.md +105 -105
  281. package/skills/core-capabilities/SKILL.md +13 -13
  282. package/skills/e2e-commerce/SKILL.md +61 -61
  283. package/skills/event-comms/SKILL.md +161 -0
  284. package/skills/event-ops/SKILL.md +197 -0
  285. package/skills/event-planning/SKILL.md +131 -0
  286. package/skills/exec-plan/SKILL.md +147 -147
  287. package/skills/frontend-design/SKILL.md +12 -12
  288. package/skills/git-worktree/SKILL.md +72 -72
  289. package/skills/handoff/SKILL.md +109 -109
  290. package/skills/parallel-research/SKILL.md +87 -87
  291. package/skills/priority-todos/SKILL.md +63 -63
  292. package/skills/seo-checklist/SKILL.md +57 -57
  293. package/skills/techdebt/SKILL.md +122 -122
  294. package/skills/tool-fallback/SKILL.md +103 -103
  295. package/skills/typescript-advanced-types/SKILL.md +66 -66
  296. package/skills/ui-ux-pro-max/SKILL.md +221 -221
  297. package/skills/vercel-react-best-practices/SKILL.md +59 -59
  298. package/skills/video-production/SKILL.md +51 -51
  299. package/vibe/config.json +29 -29
  300. package/vibe/constitution.md +227 -227
  301. package/vibe/rules/principles/communication-guide.md +98 -98
  302. package/vibe/rules/principles/development-philosophy.md +52 -52
  303. package/vibe/rules/principles/quick-start.md +102 -102
  304. package/vibe/rules/quality/bdd-contract-testing.md +393 -393
  305. package/vibe/rules/quality/checklist.md +276 -276
  306. package/vibe/rules/quality/performance.md +236 -236
  307. package/vibe/rules/quality/testing-strategy.md +440 -440
  308. package/vibe/rules/standards/anti-patterns.md +541 -541
  309. package/vibe/rules/standards/code-structure.md +291 -291
  310. package/vibe/rules/standards/complexity-metrics.md +313 -313
  311. package/vibe/rules/standards/git-workflow.md +237 -237
  312. package/vibe/rules/standards/naming-conventions.md +198 -198
  313. package/vibe/rules/standards/security.md +305 -305
  314. package/vibe/rules/writing/document-style.md +74 -74
  315. package/vibe/setup.sh +31 -31
  316. package/vibe/templates/constitution-template.md +252 -252
  317. package/vibe/templates/contract-backend-template.md +526 -526
  318. package/vibe/templates/contract-frontend-template.md +599 -599
  319. package/vibe/templates/feature-template.md +96 -96
  320. package/vibe/templates/spec-template.md +221 -221
  321. package/vibe/ui-ux-data/charts.csv +26 -26
  322. package/vibe/ui-ux-data/colors.csv +97 -97
  323. package/vibe/ui-ux-data/icons.csv +101 -101
  324. package/vibe/ui-ux-data/landing.csv +31 -31
  325. package/vibe/ui-ux-data/products.csv +96 -96
  326. package/vibe/ui-ux-data/react-performance.csv +45 -45
  327. package/vibe/ui-ux-data/stacks/astro.csv +54 -54
  328. package/vibe/ui-ux-data/stacks/flutter.csv +53 -53
  329. package/vibe/ui-ux-data/stacks/html-tailwind.csv +56 -56
  330. package/vibe/ui-ux-data/stacks/jetpack-compose.csv +53 -53
  331. package/vibe/ui-ux-data/stacks/nextjs.csv +53 -53
  332. package/vibe/ui-ux-data/stacks/nuxt-ui.csv +51 -51
  333. package/vibe/ui-ux-data/stacks/nuxtjs.csv +59 -59
  334. package/vibe/ui-ux-data/stacks/react-native.csv +52 -52
  335. package/vibe/ui-ux-data/stacks/react.csv +54 -54
  336. package/vibe/ui-ux-data/stacks/shadcn.csv +61 -61
  337. package/vibe/ui-ux-data/stacks/svelte.csv +54 -54
  338. package/vibe/ui-ux-data/stacks/swiftui.csv +51 -51
  339. package/vibe/ui-ux-data/stacks/vue.csv +50 -50
  340. package/vibe/ui-ux-data/styles.csv +68 -68
  341. package/vibe/ui-ux-data/typography.csv +57 -57
  342. package/vibe/ui-ux-data/ui-reasoning.csv +101 -101
  343. package/vibe/ui-ux-data/ux-guidelines.csv +99 -99
  344. package/vibe/ui-ux-data/version.json +31 -31
  345. package/vibe/ui-ux-data/web-interface.csv +31 -31
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InteractiveCheckpoint.d.ts","sourceRoot":"","sources":["../../../src/infra/lib/InteractiveCheckpoint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,cAAc,GACtB,sBAAsB,GACtB,qBAAqB,GACrB,sBAAsB,GACtB,qBAAqB,GACrB,cAAc,CAAC;AAEnB,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,2BAA2B;IAC3B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,sBAAsB;IACtB,IAAI,EAAE,cAAc,CAAC;IACrB,8BAA8B;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe;IACf,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,IAAI,EAAE,cAAc,CAAC;IACrB,0BAA0B;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,iEAAiE;IACjE,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,gBAAgB,EAAE,CAAC;CAC7B;AAED,oDAAoD;AACpD,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,MAAM,EAAE,EACtB,WAAW,EAAE,MAAM,GAClB,UAAU,CAoBZ;AAED,iEAAiE;AACjE,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,GACnF,UAAU,CA4BZ;AAED,gDAAgD;AAChD,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;CAAE,CAAC,EACtE,cAAc,EAAE,MAAM,GACrB,UAAU,CAuBZ;AAED,8CAA8C;AAC9C,wBAAgB,4BAA4B,CAC1C,eAAe,EAAE,MAAM,EACvB,kBAAkB,EAAE,MAAM,EAAE,EAC5B,SAAS,EAAE,MAAM,GAChB,UAAU,CA4BZ;AAED,uCAAuC;AACvC,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,GAChF,UAAU,CAyBZ;AAED,kDAAkD;AAClD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAkB/D;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,GAClB,gBAAgB,CAclB;AAED,yDAAyD;AACzD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CAO9E;AAED,oDAAoD;AACpD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAEhE;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAC1B,OAAO,EAAE,iBAAiB,EAC1B,MAAM,EAAE,gBAAgB,GACvB,iBAAiB,CAKnB"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * InteractiveCheckpoint — Phase 전환 시 의사결정 게이트
3
+ *
4
+ * /vibe.run 워크플로우에서 주요 지점에 체크포인트를 삽입하여
5
+ * 사용자가 방향을 확인/수정할 수 있도록 함
6
+ */
7
+ /** Create a requirements confirmation checkpoint */
8
+ export function createRequirementsCheckpoint(requirements, featureName) {
9
+ const summary = [
10
+ `Feature: ${featureName}`,
11
+ '',
12
+ 'Requirements:',
13
+ ...requirements.map((r, i) => ` ${i + 1}. ${r}`),
14
+ ].join('\n');
15
+ return {
16
+ type: 'requirements_confirm',
17
+ title: 'Requirements Confirmation',
18
+ summary,
19
+ options: [
20
+ { key: 'a', label: 'Confirm', description: 'Proceed with these requirements as stated.' },
21
+ { key: 'b', label: 'Revise', description: 'Modify or clarify requirements before proceeding.' },
22
+ { key: 'c', label: 'Abort', description: 'Cancel this workflow.' },
23
+ ],
24
+ defaultOption: 'a',
25
+ metadata: { featureName, requirementCount: requirements.length },
26
+ };
27
+ }
28
+ /** Create an architecture choice checkpoint with 3 approaches */
29
+ export function createArchitectureCheckpoint(options) {
30
+ const labels = ['Minimal', 'Clean', 'Pragmatic'];
31
+ const descriptions = ['Fastest path, minimal scope', 'Balanced design and speed', 'Comprehensive, thorough'];
32
+ const checkpointOptions = options.slice(0, 3).map((opt, i) => ({
33
+ key: String.fromCharCode(97 + i),
34
+ label: `${labels[i] ?? opt.approach} (${opt.effort})`,
35
+ description: [
36
+ opt.approach,
37
+ `Pros: ${opt.pros.join(', ')}`,
38
+ `Cons: ${opt.cons.join(', ')}`,
39
+ descriptions[i] ?? '',
40
+ ].filter(Boolean).join(' | '),
41
+ }));
42
+ const summary = options
43
+ .slice(0, 3)
44
+ .map((opt, i) => `${labels[i] ?? opt.approach}: ${opt.approach} [${opt.effort}]`)
45
+ .join('\n');
46
+ return {
47
+ type: 'architecture_choice',
48
+ title: 'Architecture Approach',
49
+ summary,
50
+ options: checkpointOptions,
51
+ defaultOption: 'b',
52
+ metadata: { approachCount: options.length },
53
+ };
54
+ }
55
+ /** Create an implementation scope checkpoint */
56
+ export function createScopeCheckpoint(files, estimatedLines) {
57
+ const actionIcon = { create: '+', modify: '~', delete: '-' };
58
+ const fileLines = files.map(f => ` [${actionIcon[f.action] ?? '?'}] ${f.path}`);
59
+ const summary = [
60
+ `Estimated lines of change: ${estimatedLines}`,
61
+ '',
62
+ 'Files:',
63
+ ...fileLines,
64
+ ].join('\n');
65
+ return {
66
+ type: 'implementation_scope',
67
+ title: 'Implementation Scope Approval',
68
+ summary,
69
+ options: [
70
+ { key: 'a', label: 'Approve', description: 'Proceed with the listed scope.' },
71
+ { key: 'b', label: 'Narrow', description: 'Reduce scope before implementation.' },
72
+ { key: 'c', label: 'Abort', description: 'Cancel implementation.' },
73
+ ],
74
+ defaultOption: 'a',
75
+ metadata: { fileCount: files.length, estimatedLines },
76
+ };
77
+ }
78
+ /** Create a verification result checkpoint */
79
+ export function createVerificationCheckpoint(achievementRate, failedRequirements, iteration) {
80
+ const ratePercent = Math.round(achievementRate * 100);
81
+ const passedCount = failedRequirements.length === 0
82
+ ? 'all'
83
+ : `some`;
84
+ const failedLines = failedRequirements.length > 0
85
+ ? ['', 'Failed requirements:', ...failedRequirements.map(r => ` - ${r}`)]
86
+ : ['', 'All requirements passed.'];
87
+ const summary = [
88
+ `Iteration: ${iteration}`,
89
+ `Achievement rate: ${ratePercent}% (${passedCount} requirements met)`,
90
+ ...failedLines,
91
+ ].join('\n');
92
+ return {
93
+ type: 'verification_result',
94
+ title: 'Verification Result Review',
95
+ summary,
96
+ options: [
97
+ { key: 'a', label: 'Continue fixing', description: 'Run another fix iteration.' },
98
+ { key: 'b', label: 'Accept as-is', description: 'Accept current state and move on.' },
99
+ { key: 'c', label: 'Abort', description: 'Stop the workflow.' },
100
+ ],
101
+ defaultOption: failedRequirements.length === 0 ? 'b' : 'a',
102
+ metadata: { achievementRate, failedCount: failedRequirements.length, iteration },
103
+ };
104
+ }
105
+ /** Create a fix strategy checkpoint */
106
+ export function createFixStrategyCheckpoint(issues) {
107
+ const criticalCount = issues.filter(i => i.severity === 'critical').length;
108
+ const warningCount = issues.filter(i => i.severity === 'warning').length;
109
+ const infoCount = issues.filter(i => i.severity === 'info').length;
110
+ const issueLines = issues.map(i => ` [${i.severity.toUpperCase()}] ${i.description}`);
111
+ const summary = [
112
+ `Issues: ${criticalCount} critical, ${warningCount} warning, ${infoCount} info`,
113
+ '',
114
+ ...issueLines,
115
+ ].join('\n');
116
+ return {
117
+ type: 'fix_strategy',
118
+ title: 'Fix Strategy Selection',
119
+ summary,
120
+ options: [
121
+ { key: 'a', label: 'Fix all', description: 'Address every issue (critical, warning, info).' },
122
+ { key: 'b', label: 'Critical only', description: 'Fix only critical issues and skip the rest.' },
123
+ { key: 'c', label: 'Accept as-is', description: 'Skip all fixes and proceed.' },
124
+ ],
125
+ defaultOption: criticalCount > 0 ? 'a' : 'c',
126
+ metadata: { criticalCount, warningCount, infoCount },
127
+ };
128
+ }
129
+ /** Format a checkpoint as readable prompt text */
130
+ export function formatCheckpoint(checkpoint) {
131
+ const divider = '─'.repeat(50);
132
+ const optionLines = checkpoint.options.map(opt => ` ${opt.key}) ${opt.label}\n ${opt.description}`);
133
+ return [
134
+ divider,
135
+ `CHECKPOINT: ${checkpoint.title}`,
136
+ divider,
137
+ checkpoint.summary,
138
+ '',
139
+ 'Options:',
140
+ ...optionLines,
141
+ '',
142
+ `Default: ${checkpoint.defaultOption}`,
143
+ divider,
144
+ ].join('\n');
145
+ }
146
+ /** Resolve a checkpoint with user's choice */
147
+ export function resolveCheckpoint(checkpoint, selectedKey) {
148
+ const validKeys = checkpoint.options.map(o => o.key);
149
+ if (!validKeys.includes(selectedKey)) {
150
+ throw new Error(`Invalid option key "${selectedKey}". Valid keys: ${validKeys.join(', ')}`);
151
+ }
152
+ return {
153
+ type: checkpoint.type,
154
+ selectedOption: selectedKey,
155
+ timestamp: new Date().toISOString(),
156
+ autoResolved: false,
157
+ };
158
+ }
159
+ /** Auto-resolve a checkpoint using the default option */
160
+ export function autoResolveCheckpoint(checkpoint) {
161
+ return {
162
+ type: checkpoint.type,
163
+ selectedOption: checkpoint.defaultOption,
164
+ timestamp: new Date().toISOString(),
165
+ autoResolved: true,
166
+ };
167
+ }
168
+ /** Create a new checkpoint history for a feature */
169
+ export function createHistory(feature) {
170
+ return { feature, results: [] };
171
+ }
172
+ /** Append a result to history (immutable — returns new history) */
173
+ export function addToHistory(history, result) {
174
+ return {
175
+ feature: history.feature,
176
+ results: [...history.results, result],
177
+ };
178
+ }
179
+ //# sourceMappingURL=InteractiveCheckpoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InteractiveCheckpoint.js","sourceRoot":"","sources":["../../../src/infra/lib/InteractiveCheckpoint.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,44 @@
1
1
  /**
2
2
  * Iteration Tracker for ULTRAWORK/Ralph Loop
3
3
  * 작업 진행 상황을 추적하고 표시
4
+ *
5
+ * Also provides disk-based progress persistence (merged from ProgressTracker).
4
6
  */
7
+ import { LoopBreaker } from './LoopBreaker.js';
8
+ export interface PhaseInfo {
9
+ id: number;
10
+ name: string;
11
+ status: 'pending' | 'in_progress' | 'completed' | 'blocked';
12
+ startedAt?: string;
13
+ completedAt?: string;
14
+ blockers?: string[];
15
+ }
16
+ export interface ProgressState {
17
+ feature: string;
18
+ spec: string;
19
+ status: 'pending' | 'in_progress' | 'blocked' | 'completed';
20
+ currentPhase: number;
21
+ totalPhases: number;
22
+ phases: PhaseInfo[];
23
+ completedTasks: string[];
24
+ pendingTasks: string[];
25
+ blockers: string[];
26
+ lastCommit?: string;
27
+ lastUpdated: string;
28
+ startedAt: string;
29
+ sessionCount: number;
30
+ }
31
+ export declare function getProgressPath(projectRoot: string): string;
32
+ export declare function loadProgress(projectRoot: string): ProgressState | null;
33
+ export declare function saveProgress(projectRoot: string, progress: ProgressState): void;
34
+ export declare function initProgress(projectRoot: string, feature: string, spec: string, phases: string[]): ProgressState;
35
+ export declare function updatePhase(projectRoot: string, phaseNumber: number, status: PhaseInfo['status'], blockers?: string[]): ProgressState | null;
36
+ export declare function completeTask(projectRoot: string, task: string): ProgressState | null;
37
+ export declare function recordCommit(projectRoot: string, commitHash: string): ProgressState | null;
38
+ export declare function incrementSession(projectRoot: string): ProgressState | null;
39
+ export declare function formatProgressState(progress: ProgressState): string;
40
+ export declare function getProgressSummary(projectRoot: string): string | null;
41
+ export declare function writeProgressText(projectRoot: string): void;
5
42
  export interface PhaseProgress {
6
43
  phaseNumber: number;
7
44
  phaseName: string;
@@ -29,14 +66,17 @@ export interface IterationState {
29
66
  export declare function startIteration(featureName: string, phaseNames: string[], isUltrawork?: boolean, maxRetries?: number, pipelineEnabled?: boolean): IterationState;
30
67
  /**
31
68
  * Phase 시작
69
+ * Records an iteration with LoopBreaker; returns null if the loop limit is hit.
32
70
  */
33
71
  export declare function startPhase(phaseNumber: number): PhaseProgress | null;
34
72
  /**
35
73
  * Phase 완료
74
+ * Resets the consecutive error counter in LoopBreaker on success.
36
75
  */
37
76
  export declare function completePhase(phaseNumber: number): PhaseProgress | null;
38
77
  /**
39
78
  * Phase 실패 (재시도 가능)
79
+ * Records an error with LoopBreaker; forces canRetry=false when the error limit is hit.
40
80
  */
41
81
  export declare function failPhase(phaseNumber: number, error: string): {
42
82
  canRetry: boolean;
@@ -50,6 +90,10 @@ export declare function completeIteration(): IterationState | null;
50
90
  * 현재 상태 조회
51
91
  */
52
92
  export declare function getCurrentState(): IterationState | null;
93
+ /**
94
+ * Returns the current LoopBreaker instance for external inspection.
95
+ */
96
+ export declare function getIterationLoopBreaker(): LoopBreaker;
53
97
  /**
54
98
  * 진행 상황 포맷팅 (터미널 출력용)
55
99
  */
@@ -1 +1 @@
1
- {"version":3,"file":"IterationTracker.d.ts","sourceRoot":"","sources":["../../../src/infra/lib/IterationTracker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,UAAU,CAAC;IACxE,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,sBAAsB;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAKD;;GAEG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAAE,EACpB,WAAW,GAAE,OAAe,EAC5B,UAAU,GAAE,MAAU,EACtB,eAAe,GAAE,OAAe,GAC/B,cAAc,CAkBhB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAWpE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAUvE;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,aAAa,CAAA;CAAE,GAAG,IAAI,CAahH;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAQzD;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,cAAc,GAAG,IAAI,CAEvD;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,GAAE,cAA8B,GAAG,MAAM,CAwB5E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAMpG;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAEpF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAgBrE;AAgBD;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAalH;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB/D"}
1
+ {"version":3,"file":"IterationTracker.d.ts","sourceRoot":"","sources":["../../../src/infra/lib/IterationTracker.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,252 @@
1
1
  /**
2
2
  * Iteration Tracker for ULTRAWORK/Ralph Loop
3
3
  * 작업 진행 상황을 추적하고 표시
4
+ *
5
+ * Also provides disk-based progress persistence (merged from ProgressTracker).
4
6
  */
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ import { LoopBreaker } from './LoopBreaker.js';
10
+ const DEFAULT_PROGRESS = {
11
+ feature: '',
12
+ spec: '',
13
+ status: 'pending',
14
+ currentPhase: 0,
15
+ totalPhases: 0,
16
+ phases: [],
17
+ completedTasks: [],
18
+ pendingTasks: [],
19
+ blockers: [],
20
+ lastUpdated: new Date().toISOString(),
21
+ startedAt: new Date().toISOString(),
22
+ sessionCount: 0,
23
+ };
24
+ export function getProgressPath(projectRoot) {
25
+ return path.join(projectRoot, '.claude', 'vibe', 'progress.json');
26
+ }
27
+ export function loadProgress(projectRoot) {
28
+ const progressPath = getProgressPath(projectRoot);
29
+ try {
30
+ if (fs.existsSync(progressPath)) {
31
+ const content = fs.readFileSync(progressPath, 'utf-8');
32
+ return JSON.parse(content);
33
+ }
34
+ }
35
+ catch {
36
+ // Ignore parse errors
37
+ }
38
+ return null;
39
+ }
40
+ export function saveProgress(projectRoot, progress) {
41
+ const progressPath = getProgressPath(projectRoot);
42
+ const coreDir = path.dirname(progressPath);
43
+ if (!fs.existsSync(coreDir)) {
44
+ fs.mkdirSync(coreDir, { recursive: true });
45
+ }
46
+ progress.lastUpdated = new Date().toISOString();
47
+ fs.writeFileSync(progressPath, JSON.stringify(progress, null, 2));
48
+ }
49
+ export function initProgress(projectRoot, feature, spec, phases) {
50
+ const progress = {
51
+ ...DEFAULT_PROGRESS,
52
+ feature,
53
+ spec,
54
+ status: 'in_progress',
55
+ currentPhase: 1,
56
+ totalPhases: phases.length,
57
+ phases: phases.map((name, idx) => ({
58
+ id: idx + 1,
59
+ name,
60
+ status: idx === 0 ? 'in_progress' : 'pending',
61
+ startedAt: idx === 0 ? new Date().toISOString() : undefined,
62
+ })),
63
+ pendingTasks: phases.slice(1),
64
+ startedAt: new Date().toISOString(),
65
+ sessionCount: 1,
66
+ };
67
+ saveProgress(projectRoot, progress);
68
+ return progress;
69
+ }
70
+ export function updatePhase(projectRoot, phaseNumber, status, blockers) {
71
+ const progress = loadProgress(projectRoot);
72
+ if (!progress)
73
+ return null;
74
+ const phase = progress.phases.find(p => p.id === phaseNumber);
75
+ if (phase) {
76
+ phase.status = status;
77
+ if (status === 'in_progress') {
78
+ phase.startedAt = new Date().toISOString();
79
+ progress.currentPhase = phaseNumber;
80
+ }
81
+ else if (status === 'completed') {
82
+ phase.completedAt = new Date().toISOString();
83
+ progress.completedTasks.push(phase.name);
84
+ progress.pendingTasks = progress.pendingTasks.filter(t => t !== phase.name);
85
+ const nextPhase = progress.phases.find(p => p.id === phaseNumber + 1);
86
+ if (nextPhase) {
87
+ nextPhase.status = 'in_progress';
88
+ nextPhase.startedAt = new Date().toISOString();
89
+ progress.currentPhase = nextPhase.id;
90
+ }
91
+ else {
92
+ progress.status = 'completed';
93
+ }
94
+ }
95
+ else if (status === 'blocked') {
96
+ phase.blockers = blockers;
97
+ progress.blockers = blockers || [];
98
+ progress.status = 'blocked';
99
+ }
100
+ }
101
+ saveProgress(projectRoot, progress);
102
+ return progress;
103
+ }
104
+ export function completeTask(projectRoot, task) {
105
+ const progress = loadProgress(projectRoot);
106
+ if (!progress)
107
+ return null;
108
+ if (!progress.completedTasks.includes(task)) {
109
+ progress.completedTasks.push(task);
110
+ }
111
+ progress.pendingTasks = progress.pendingTasks.filter(t => t !== task);
112
+ saveProgress(projectRoot, progress);
113
+ return progress;
114
+ }
115
+ export function recordCommit(projectRoot, commitHash) {
116
+ const progress = loadProgress(projectRoot);
117
+ if (!progress)
118
+ return null;
119
+ progress.lastCommit = commitHash;
120
+ saveProgress(projectRoot, progress);
121
+ return progress;
122
+ }
123
+ export function incrementSession(projectRoot) {
124
+ const progress = loadProgress(projectRoot);
125
+ if (!progress)
126
+ return null;
127
+ progress.sessionCount++;
128
+ saveProgress(projectRoot, progress);
129
+ return progress;
130
+ }
131
+ export function formatProgressState(progress) {
132
+ const lines = [];
133
+ const statusIcon = {
134
+ pending: '⏳',
135
+ in_progress: '🔨',
136
+ blocked: '🚫',
137
+ completed: '✅',
138
+ }[progress.status];
139
+ lines.push(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
140
+ lines.push(`${statusIcon} Feature: ${progress.feature}`);
141
+ lines.push(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
142
+ lines.push(`Status: ${progress.status.toUpperCase()}`);
143
+ lines.push(`Phase: ${progress.currentPhase}/${progress.totalPhases}`);
144
+ lines.push(`Sessions: ${progress.sessionCount}`);
145
+ lines.push(``);
146
+ lines.push(`Phases:`);
147
+ for (const phase of progress.phases) {
148
+ const icon = {
149
+ pending: '○',
150
+ in_progress: '●',
151
+ completed: '✓',
152
+ blocked: '✗',
153
+ }[phase.status];
154
+ lines.push(` ${icon} ${phase.id}. ${phase.name}`);
155
+ }
156
+ if (progress.completedTasks.length > 0) {
157
+ lines.push(``);
158
+ lines.push(`Completed: ${progress.completedTasks.length} tasks`);
159
+ }
160
+ if (progress.blockers.length > 0) {
161
+ lines.push(``);
162
+ lines.push(`Blockers:`);
163
+ for (const blocker of progress.blockers) {
164
+ lines.push(` - ${blocker}`);
165
+ }
166
+ }
167
+ if (progress.lastCommit) {
168
+ lines.push(``);
169
+ lines.push(`Last commit: ${progress.lastCommit}`);
170
+ }
171
+ lines.push(`━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
172
+ return lines.join('\n');
173
+ }
174
+ export function getProgressSummary(projectRoot) {
175
+ const progress = loadProgress(projectRoot);
176
+ if (!progress || progress.status === 'completed')
177
+ return null;
178
+ const currentPhase = progress.phases.find(p => p.id === progress.currentPhase);
179
+ const phaseName = currentPhase?.name || 'Unknown';
180
+ return `Active feature: "${progress.feature}" - Phase ${progress.currentPhase}/${progress.totalPhases} (${phaseName})`;
181
+ }
182
+ export function writeProgressText(projectRoot) {
183
+ const progress = loadProgress(projectRoot);
184
+ if (!progress)
185
+ return;
186
+ const progressTextPath = path.join(projectRoot, '.claude', 'vibe', 'claude-progress.txt');
187
+ const lines = [];
188
+ lines.push(`# Progress: ${progress.feature}`);
189
+ lines.push(`Updated: ${new Date().toISOString()}`);
190
+ lines.push(`Status: ${progress.status.toUpperCase()}`);
191
+ lines.push(`Session: ${progress.sessionCount}`);
192
+ lines.push('');
193
+ lines.push('## Phases');
194
+ for (const phase of progress.phases) {
195
+ const icon = { pending: '[ ]', in_progress: '[>]', completed: '[x]', blocked: '[!]' }[phase.status];
196
+ lines.push(`${icon} Phase ${phase.id}: ${phase.name}`);
197
+ if (phase.blockers?.length) {
198
+ for (const b of phase.blockers) {
199
+ lines.push(` BLOCKED: ${b}`);
200
+ }
201
+ }
202
+ }
203
+ if (progress.completedTasks.length > 0) {
204
+ lines.push('');
205
+ lines.push('## Completed');
206
+ for (const task of progress.completedTasks) {
207
+ lines.push(`- ${task}`);
208
+ }
209
+ }
210
+ if (progress.pendingTasks.length > 0) {
211
+ lines.push('');
212
+ lines.push('## Remaining');
213
+ for (const task of progress.pendingTasks) {
214
+ lines.push(`- ${task}`);
215
+ }
216
+ }
217
+ if (progress.blockers.length > 0) {
218
+ lines.push('');
219
+ lines.push('## Blockers');
220
+ for (const blocker of progress.blockers) {
221
+ lines.push(`- ${blocker}`);
222
+ }
223
+ }
224
+ if (progress.lastCommit) {
225
+ lines.push('');
226
+ lines.push(`## Last Commit: ${progress.lastCommit}`);
227
+ }
228
+ const coreDir = path.dirname(progressTextPath);
229
+ if (!fs.existsSync(coreDir)) {
230
+ fs.mkdirSync(coreDir, { recursive: true });
231
+ }
232
+ fs.writeFileSync(progressTextPath, lines.join('\n') + '\n');
233
+ }
5
234
  // 전역 상태 (세션 내 유지)
6
235
  let currentState = null;
236
+ // Module-level LoopBreaker instance (lazy init per startIteration call)
237
+ let _loopBreaker = null;
238
+ function getLoopBreaker() {
239
+ if (!_loopBreaker) {
240
+ _loopBreaker = new LoopBreaker();
241
+ }
242
+ return _loopBreaker;
243
+ }
7
244
  /**
8
245
  * 새 작업 시작
9
246
  */
10
247
  export function startIteration(featureName, phaseNames, isUltrawork = false, maxRetries = 3, pipelineEnabled = false) {
248
+ // Reset LoopBreaker for the new iteration
249
+ _loopBreaker = new LoopBreaker();
11
250
  currentState = {
12
251
  featureName,
13
252
  totalPhases: phaseNames.length,
@@ -27,11 +266,16 @@ export function startIteration(featureName, phaseNames, isUltrawork = false, max
27
266
  }
28
267
  /**
29
268
  * Phase 시작
269
+ * Records an iteration with LoopBreaker; returns null if the loop limit is hit.
30
270
  */
31
271
  export function startPhase(phaseNumber) {
32
272
  if (!currentState || phaseNumber < 1 || phaseNumber > currentState.totalPhases) {
33
273
  return null;
34
274
  }
275
+ const breakResult = getLoopBreaker().recordIteration();
276
+ if (breakResult.shouldBreak) {
277
+ return null;
278
+ }
35
279
  const phase = currentState.phases[phaseNumber - 1];
36
280
  phase.status = 'in_progress';
37
281
  phase.startTime = new Date();
@@ -40,11 +284,13 @@ export function startPhase(phaseNumber) {
40
284
  }
41
285
  /**
42
286
  * Phase 완료
287
+ * Resets the consecutive error counter in LoopBreaker on success.
43
288
  */
44
289
  export function completePhase(phaseNumber) {
45
290
  if (!currentState || phaseNumber < 1 || phaseNumber > currentState.totalPhases) {
46
291
  return null;
47
292
  }
293
+ getLoopBreaker().recordSuccess();
48
294
  const phase = currentState.phases[phaseNumber - 1];
49
295
  phase.status = 'completed';
50
296
  phase.endTime = new Date();
@@ -52,15 +298,18 @@ export function completePhase(phaseNumber) {
52
298
  }
53
299
  /**
54
300
  * Phase 실패 (재시도 가능)
301
+ * Records an error with LoopBreaker; forces canRetry=false when the error limit is hit.
55
302
  */
56
303
  export function failPhase(phaseNumber, error) {
57
304
  if (!currentState || phaseNumber < 1 || phaseNumber > currentState.totalPhases) {
58
305
  return null;
59
306
  }
307
+ const breakResult = getLoopBreaker().recordError();
60
308
  const phase = currentState.phases[phaseNumber - 1];
61
309
  phase.retryCount += 1;
62
310
  phase.error = error;
63
- const canRetry = phase.retryCount < currentState.maxRetries;
311
+ const withinRetries = phase.retryCount < currentState.maxRetries;
312
+ const canRetry = withinRetries && !breakResult.shouldBreak;
64
313
  phase.status = canRetry ? 'retrying' : 'failed';
65
314
  return { canRetry, phase };
66
315
  }
@@ -81,6 +330,12 @@ export function completeIteration() {
81
330
  export function getCurrentState() {
82
331
  return currentState;
83
332
  }
333
+ /**
334
+ * Returns the current LoopBreaker instance for external inspection.
335
+ */
336
+ export function getIterationLoopBreaker() {
337
+ return getLoopBreaker();
338
+ }
84
339
  /**
85
340
  * 진행 상황 포맷팅 (터미널 출력용)
86
341
  */
@@ -108,10 +363,10 @@ export function formatProgress(state = currentState) {
108
363
  * Phase 시작 배너
109
364
  */
110
365
  export function formatPhaseStart(phaseNumber, phaseName, totalPhases) {
111
- return `
112
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
113
- 🏔️ BOULDER ROLLING... Phase ${phaseNumber}/${totalPhases}
114
- ${phaseName}
366
+ return `
367
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
368
+ 🏔️ BOULDER ROLLING... Phase ${phaseNumber}/${totalPhases}
369
+ ${phaseName}
115
370
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`.trim();
116
371
  }
117
372
  /**
@@ -129,13 +384,13 @@ export function formatIterationComplete(state) {
129
384
  : 0;
130
385
  const totalRetries = state.phases.reduce((sum, p) => sum + p.retryCount, 0);
131
386
  const retryInfo = totalRetries > 0 ? ` (${totalRetries} retries)` : '';
132
- return `
133
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
134
- 🎉 BOULDER REACHED THE TOP!
135
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
136
- Feature: ${state.featureName}
137
- Phases: ${state.totalPhases}/${state.totalPhases} complete${retryInfo}
138
- Time: ${duration}s
387
+ return `
388
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
389
+ 🎉 BOULDER REACHED THE TOP!
390
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
391
+ Feature: ${state.featureName}
392
+ Phases: ${state.totalPhases}/${state.totalPhases} complete${retryInfo}
393
+ Time: ${duration}s
139
394
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`.trim();
140
395
  }
141
396
  /**