@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.
- package/.env.example +37 -37
- package/CLAUDE.md +153 -153
- package/LICENSE +21 -21
- package/README.md +451 -449
- package/agents/architect-low.md +41 -41
- package/agents/architect-medium.md +59 -59
- package/agents/architect.md +80 -80
- package/agents/build-error-resolver.md +115 -115
- package/agents/compounder.md +261 -261
- package/agents/diagrammer.md +178 -178
- package/agents/docs/api-documenter.md +99 -99
- package/agents/docs/changelog-writer.md +93 -93
- package/agents/e2e-tester.md +294 -294
- package/agents/event/event-comms.md +78 -0
- package/agents/event/event-content.md +68 -0
- package/agents/event/event-image.md +95 -0
- package/agents/event/event-ops.md +84 -0
- package/agents/event/event-scheduler.md +69 -0
- package/agents/event/event-speaker.md +86 -0
- package/agents/explorer-low.md +42 -42
- package/agents/explorer-medium.md +59 -59
- package/agents/explorer.md +48 -48
- package/agents/implementer-low.md +43 -43
- package/agents/implementer-medium.md +52 -52
- package/agents/implementer.md +54 -54
- package/agents/junior-mentor.md +141 -141
- package/agents/planning/requirements-analyst.md +84 -84
- package/agents/planning/ux-advisor.md +83 -83
- package/agents/qa/acceptance-tester.md +86 -86
- package/agents/qa/edge-case-finder.md +93 -93
- package/agents/refactor-cleaner.md +143 -143
- package/agents/research/best-practices-agent.md +199 -199
- package/agents/research/codebase-patterns-agent.md +157 -157
- package/agents/research/framework-docs-agent.md +188 -188
- package/agents/research/security-advisory-agent.md +213 -213
- package/agents/review/architecture-reviewer.md +107 -107
- package/agents/review/complexity-reviewer.md +116 -116
- package/agents/review/data-integrity-reviewer.md +88 -88
- package/agents/review/git-history-reviewer.md +103 -103
- package/agents/review/performance-reviewer.md +86 -86
- package/agents/review/python-reviewer.md +150 -150
- package/agents/review/rails-reviewer.md +139 -139
- package/agents/review/react-reviewer.md +144 -144
- package/agents/review/security-reviewer.md +80 -80
- package/agents/review/simplicity-reviewer.md +140 -140
- package/agents/review/test-coverage-reviewer.md +116 -116
- package/agents/review/typescript-reviewer.md +127 -127
- package/agents/searcher.md +54 -54
- package/agents/simplifier.md +120 -120
- package/agents/tester.md +49 -49
- package/agents/ui/ui-a11y-auditor.md +93 -93
- package/agents/ui/ui-antipattern-detector.md +94 -94
- package/agents/ui/ui-dataviz-advisor.md +69 -69
- package/agents/ui/ui-design-system-gen.md +57 -57
- package/agents/ui/ui-industry-analyzer.md +49 -49
- package/agents/ui/ui-layout-architect.md +65 -65
- package/agents/ui/ui-stack-implementer.md +68 -68
- package/agents/ui/ux-compliance-reviewer.md +81 -81
- package/agents/ui-previewer.md +258 -258
- package/commands/vibe.analyze.md +379 -379
- package/commands/vibe.event.md +163 -0
- package/commands/vibe.review.md +607 -607
- package/commands/vibe.run.md +2217 -2124
- package/commands/vibe.spec.md +1195 -1195
- package/commands/vibe.spec.review.md +569 -569
- package/commands/vibe.trace.md +50 -0
- package/commands/vibe.utils.md +413 -413
- package/commands/vibe.verify.md +484 -484
- package/dist/__tests__/architecture.test.d.ts +2 -0
- package/dist/__tests__/architecture.test.d.ts.map +1 -0
- package/dist/__tests__/architecture.test.js +207 -0
- package/dist/__tests__/architecture.test.js.map +1 -0
- package/dist/cli/auth.js +3 -3
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/collaborator.js +52 -52
- package/dist/cli/commands/evolution.js +12 -12
- package/dist/cli/commands/info.d.ts.map +1 -1
- package/dist/cli/commands/info.js +45 -81
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/init.js +5 -5
- package/dist/cli/commands/remove.js +14 -14
- package/dist/cli/commands/sentinel.js +27 -27
- package/dist/cli/commands/skills.js +5 -5
- package/dist/cli/commands/slack.js +10 -10
- package/dist/cli/commands/telegram.js +12 -12
- package/dist/cli/detect.d.ts.map +1 -1
- package/dist/cli/detect.js +55 -32
- package/dist/cli/detect.js.map +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +52 -52
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/llm/claude-commands.js +16 -16
- package/dist/cli/llm/config.js +18 -18
- package/dist/cli/llm/gemini-commands.js +16 -16
- package/dist/cli/llm/gpt-commands.js +19 -19
- package/dist/cli/llm/help.js +21 -21
- package/dist/cli/postinstall/constants.d.ts.map +1 -1
- package/dist/cli/postinstall/constants.js +24 -0
- package/dist/cli/postinstall/constants.js.map +1 -1
- package/dist/cli/postinstall/cursor-agents.js +32 -32
- package/dist/cli/postinstall/cursor-rules.js +83 -83
- package/dist/cli/postinstall/cursor-skills.js +743 -743
- package/dist/cli/setup/Provisioner.js +42 -42
- package/dist/infra/lib/AutomationLevel.d.ts +48 -0
- package/dist/infra/lib/AutomationLevel.d.ts.map +1 -0
- package/dist/infra/lib/AutomationLevel.js +157 -0
- package/dist/infra/lib/AutomationLevel.js.map +1 -0
- package/dist/infra/lib/DecisionTracer.d.ts +81 -0
- package/dist/infra/lib/DecisionTracer.d.ts.map +1 -0
- package/dist/infra/lib/DecisionTracer.js +135 -0
- package/dist/infra/lib/DecisionTracer.js.map +1 -0
- package/dist/infra/lib/DeepInit.js +24 -24
- package/dist/infra/lib/InteractiveCheckpoint.d.ts +75 -0
- package/dist/infra/lib/InteractiveCheckpoint.d.ts.map +1 -0
- package/dist/infra/lib/InteractiveCheckpoint.js +179 -0
- package/dist/infra/lib/InteractiveCheckpoint.js.map +1 -0
- package/dist/infra/lib/IterationTracker.d.ts +44 -0
- package/dist/infra/lib/IterationTracker.d.ts.map +1 -1
- package/dist/infra/lib/IterationTracker.js +267 -12
- package/dist/infra/lib/IterationTracker.js.map +1 -1
- package/dist/infra/lib/LoopBreaker.d.ts +56 -0
- package/dist/infra/lib/LoopBreaker.d.ts.map +1 -0
- package/dist/infra/lib/LoopBreaker.js +109 -0
- package/dist/infra/lib/LoopBreaker.js.map +1 -0
- package/dist/infra/lib/PythonParser.js +108 -108
- package/dist/infra/lib/ReviewRace.js +96 -96
- package/dist/infra/lib/SkillFrontmatter.js +28 -28
- package/dist/infra/lib/SkillQualityGate.js +9 -9
- package/dist/infra/lib/SkillRepository.js +159 -159
- package/dist/infra/lib/UltraQA.js +99 -99
- package/dist/infra/lib/VerificationLoop.d.ts +105 -0
- package/dist/infra/lib/VerificationLoop.d.ts.map +1 -0
- package/dist/infra/lib/VerificationLoop.js +189 -0
- package/dist/infra/lib/VerificationLoop.js.map +1 -0
- package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts +2 -0
- package/dist/infra/lib/__tests__/AutomationLevel.test.d.ts.map +1 -0
- package/dist/infra/lib/__tests__/AutomationLevel.test.js +297 -0
- package/dist/infra/lib/__tests__/AutomationLevel.test.js.map +1 -0
- package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts +2 -0
- package/dist/infra/lib/__tests__/DecisionTracer.test.d.ts.map +1 -0
- package/dist/infra/lib/__tests__/DecisionTracer.test.js +274 -0
- package/dist/infra/lib/__tests__/DecisionTracer.test.js.map +1 -0
- package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts +2 -0
- package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.d.ts.map +1 -0
- package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js +350 -0
- package/dist/infra/lib/__tests__/InteractiveCheckpoint.test.js.map +1 -0
- package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts +2 -0
- package/dist/infra/lib/__tests__/LoopBreaker.test.d.ts.map +1 -0
- package/dist/infra/lib/__tests__/LoopBreaker.test.js +340 -0
- package/dist/infra/lib/__tests__/LoopBreaker.test.js.map +1 -0
- package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts +2 -0
- package/dist/infra/lib/__tests__/VerificationLoop.test.d.ts.map +1 -0
- package/dist/infra/lib/__tests__/VerificationLoop.test.js +486 -0
- package/dist/infra/lib/__tests__/VerificationLoop.test.js.map +1 -0
- package/dist/infra/lib/autonomy/AuditStore.js +41 -41
- package/dist/infra/lib/autonomy/ConfirmationStore.js +30 -30
- package/dist/infra/lib/autonomy/EventOutbox.js +38 -38
- package/dist/infra/lib/autonomy/PolicyEngine.d.ts +3 -3
- package/dist/infra/lib/autonomy/PolicyEngine.js +18 -18
- package/dist/infra/lib/autonomy/SecuritySentinel.js +1 -1
- package/dist/infra/lib/autonomy/SuggestionStore.js +33 -33
- package/dist/infra/lib/embedding/VectorStore.js +22 -22
- package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js +4 -0
- package/dist/infra/lib/embedding/__tests__/EmbeddingProvider.test.js.map +1 -1
- package/dist/infra/lib/evolution/AgentAnalyzer.js +10 -10
- package/dist/infra/lib/evolution/DeprecationDetector.d.ts +68 -0
- package/dist/infra/lib/evolution/DeprecationDetector.d.ts.map +1 -0
- package/dist/infra/lib/evolution/DeprecationDetector.js +207 -0
- package/dist/infra/lib/evolution/DeprecationDetector.js.map +1 -0
- package/dist/infra/lib/evolution/DescriptionOptimizer.js +21 -21
- package/dist/infra/lib/evolution/GenerationRegistry.js +36 -36
- package/dist/infra/lib/evolution/InsightStore.js +90 -90
- package/dist/infra/lib/evolution/ParityTester.d.ts +74 -0
- package/dist/infra/lib/evolution/ParityTester.d.ts.map +1 -0
- package/dist/infra/lib/evolution/ParityTester.js +238 -0
- package/dist/infra/lib/evolution/ParityTester.js.map +1 -0
- package/dist/infra/lib/evolution/RollbackManager.js +5 -5
- package/dist/infra/lib/evolution/SkillBenchmark.js +23 -23
- package/dist/infra/lib/evolution/SkillEvalRunner.js +50 -50
- package/dist/infra/lib/evolution/SkillGapDetector.js +10 -10
- package/dist/infra/lib/evolution/UsageTracker.js +28 -28
- package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts +2 -0
- package/dist/infra/lib/evolution/__tests__/deprecation.test.d.ts.map +1 -0
- package/dist/infra/lib/evolution/__tests__/deprecation.test.js +251 -0
- package/dist/infra/lib/evolution/__tests__/deprecation.test.js.map +1 -0
- package/dist/infra/lib/evolution/__tests__/parity.test.d.ts +2 -0
- package/dist/infra/lib/evolution/__tests__/parity.test.d.ts.map +1 -0
- package/dist/infra/lib/evolution/__tests__/parity.test.js +319 -0
- package/dist/infra/lib/evolution/__tests__/parity.test.js.map +1 -0
- package/dist/infra/lib/evolution/index.d.ts +4 -0
- package/dist/infra/lib/evolution/index.d.ts.map +1 -1
- package/dist/infra/lib/evolution/index.js +3 -0
- package/dist/infra/lib/evolution/index.js.map +1 -1
- package/dist/infra/lib/gemini/orchestration.js +5 -5
- package/dist/infra/lib/gpt/orchestration.js +4 -4
- package/dist/infra/lib/gpt/specializations.d.ts +1 -1
- package/dist/infra/lib/gpt/specializations.js +1 -1
- package/dist/infra/lib/memory/KnowledgeGraph.js +4 -4
- package/dist/infra/lib/memory/MemorySearch.js +57 -57
- package/dist/infra/lib/memory/MemoryStorage.js +181 -181
- package/dist/infra/lib/memory/ObservationStore.js +28 -28
- package/dist/infra/lib/memory/ReflectionStore.js +30 -30
- package/dist/infra/lib/memory/SessionRAGRetriever.js +7 -7
- package/dist/infra/lib/memory/SessionRAGStore.js +225 -225
- package/dist/infra/lib/memory/SessionSummarizer.js +9 -9
- package/dist/infra/lib/telemetry/SkillTelemetry.d.ts +6 -0
- package/dist/infra/lib/telemetry/SkillTelemetry.d.ts.map +1 -1
- package/dist/infra/lib/telemetry/SkillTelemetry.js +11 -0
- package/dist/infra/lib/telemetry/SkillTelemetry.js.map +1 -1
- package/dist/infra/orchestrator/AgentManager.js +12 -12
- package/dist/infra/orchestrator/AgentRegistry.js +65 -65
- package/dist/infra/orchestrator/BackgroundManager.d.ts.map +1 -1
- package/dist/infra/orchestrator/BackgroundManager.js +2 -0
- package/dist/infra/orchestrator/BackgroundManager.js.map +1 -1
- package/dist/infra/orchestrator/MultiLlmResearch.js +8 -8
- package/dist/infra/orchestrator/PhasePipeline.js +1 -1
- package/dist/infra/orchestrator/PhasePipeline.js.map +1 -1
- package/dist/infra/orchestrator/SwarmOrchestrator.test.js +16 -16
- package/dist/infra/orchestrator/parallelResearch.js +24 -24
- package/dist/tools/convention/analyzeComplexity.test.js +115 -115
- package/dist/tools/convention/validateCodeQuality.test.js +104 -104
- package/dist/tools/index.d.ts +16 -19
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +15 -27
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/memory/createMemoryTimeline.js +10 -10
- package/dist/tools/memory/getMemoryGraph.js +12 -12
- package/dist/tools/memory/getSessionContext.js +9 -9
- package/dist/tools/memory/linkMemories.js +14 -14
- package/dist/tools/memory/listMemories.js +4 -4
- package/dist/tools/memory/recallMemory.js +4 -4
- package/dist/tools/memory/saveMemory.js +4 -4
- package/dist/tools/memory/searchMemoriesAdvanced.js +23 -23
- package/dist/tools/memory/startSession.js +1 -1
- package/dist/tools/memory/startSession.js.map +1 -1
- package/dist/tools/semantic/analyzeDependencyGraph.js +12 -12
- package/dist/tools/semantic/astGrep.test.js +6 -6
- package/dist/tools/spec/index.d.ts +0 -4
- package/dist/tools/spec/index.d.ts.map +1 -1
- package/dist/tools/spec/index.js +0 -4
- package/dist/tools/spec/index.js.map +1 -1
- package/dist/tools/spec/prdParser.test.js +171 -171
- package/dist/tools/spec/specGenerator.js +169 -169
- package/dist/tools/spec/traceabilityMatrix.js +64 -64
- package/dist/tools/spec/traceabilityMatrix.test.js +28 -28
- package/hooks/gemini-hooks.json +73 -73
- package/hooks/hooks.json +137 -137
- package/hooks/scripts/code-check.js +77 -77
- package/hooks/scripts/context-save.js +212 -212
- package/hooks/scripts/evolution-engine.js +69 -0
- package/hooks/scripts/hud-status.js +291 -291
- package/hooks/scripts/keyword-detector.js +214 -214
- package/hooks/scripts/llm-orchestrate.js +475 -475
- package/hooks/scripts/post-edit.js +32 -32
- package/hooks/scripts/pre-tool-guard.js +125 -125
- package/hooks/scripts/prompt-dispatcher.js +185 -185
- package/hooks/scripts/sentinel-guard.js +104 -104
- package/hooks/scripts/session-start.js +106 -106
- package/hooks/scripts/skill-injector.js +83 -0
- package/hooks/scripts/stop-notify.js +209 -209
- package/hooks/scripts/utils.js +100 -100
- package/languages/csharp-unity.md +515 -515
- package/languages/gdscript-godot.md +470 -470
- package/languages/ruby-rails.md +489 -489
- package/languages/typescript-angular.md +433 -433
- package/languages/typescript-astro.md +416 -416
- package/languages/typescript-electron.md +406 -406
- package/languages/typescript-nestjs.md +524 -524
- package/languages/typescript-svelte.md +407 -407
- package/languages/typescript-tauri.md +365 -365
- package/package.json +101 -123
- package/skills/agents-md/SKILL.md +120 -120
- package/skills/arch-guard/SKILL.md +180 -180
- package/skills/brand-assets/SKILL.md +146 -146
- package/skills/capability-loop/SKILL.md +167 -167
- package/skills/characterization-test/SKILL.md +206 -206
- package/skills/commerce-patterns/SKILL.md +63 -63
- package/skills/commit-push-pr/SKILL.md +75 -75
- package/skills/context7-usage/SKILL.md +105 -105
- package/skills/core-capabilities/SKILL.md +13 -13
- package/skills/e2e-commerce/SKILL.md +61 -61
- package/skills/event-comms/SKILL.md +161 -0
- package/skills/event-ops/SKILL.md +197 -0
- package/skills/event-planning/SKILL.md +131 -0
- package/skills/exec-plan/SKILL.md +147 -147
- package/skills/frontend-design/SKILL.md +12 -12
- package/skills/git-worktree/SKILL.md +72 -72
- package/skills/handoff/SKILL.md +109 -109
- package/skills/parallel-research/SKILL.md +87 -87
- package/skills/priority-todos/SKILL.md +63 -63
- package/skills/seo-checklist/SKILL.md +57 -57
- package/skills/techdebt/SKILL.md +122 -122
- package/skills/tool-fallback/SKILL.md +103 -103
- package/skills/typescript-advanced-types/SKILL.md +66 -66
- package/skills/ui-ux-pro-max/SKILL.md +221 -221
- package/skills/vercel-react-best-practices/SKILL.md +59 -59
- package/skills/video-production/SKILL.md +51 -51
- package/vibe/config.json +29 -29
- package/vibe/constitution.md +227 -227
- package/vibe/rules/principles/communication-guide.md +98 -98
- package/vibe/rules/principles/development-philosophy.md +52 -52
- package/vibe/rules/principles/quick-start.md +102 -102
- package/vibe/rules/quality/bdd-contract-testing.md +393 -393
- package/vibe/rules/quality/checklist.md +276 -276
- package/vibe/rules/quality/performance.md +236 -236
- package/vibe/rules/quality/testing-strategy.md +440 -440
- package/vibe/rules/standards/anti-patterns.md +541 -541
- package/vibe/rules/standards/code-structure.md +291 -291
- package/vibe/rules/standards/complexity-metrics.md +313 -313
- package/vibe/rules/standards/git-workflow.md +237 -237
- package/vibe/rules/standards/naming-conventions.md +198 -198
- package/vibe/rules/standards/security.md +305 -305
- package/vibe/rules/writing/document-style.md +74 -74
- package/vibe/setup.sh +31 -31
- package/vibe/templates/constitution-template.md +252 -252
- package/vibe/templates/contract-backend-template.md +526 -526
- package/vibe/templates/contract-frontend-template.md +599 -599
- package/vibe/templates/feature-template.md +96 -96
- package/vibe/templates/spec-template.md +221 -221
- package/vibe/ui-ux-data/charts.csv +26 -26
- package/vibe/ui-ux-data/colors.csv +97 -97
- package/vibe/ui-ux-data/icons.csv +101 -101
- package/vibe/ui-ux-data/landing.csv +31 -31
- package/vibe/ui-ux-data/products.csv +96 -96
- package/vibe/ui-ux-data/react-performance.csv +45 -45
- package/vibe/ui-ux-data/stacks/astro.csv +54 -54
- package/vibe/ui-ux-data/stacks/flutter.csv +53 -53
- package/vibe/ui-ux-data/stacks/html-tailwind.csv +56 -56
- package/vibe/ui-ux-data/stacks/jetpack-compose.csv +53 -53
- package/vibe/ui-ux-data/stacks/nextjs.csv +53 -53
- package/vibe/ui-ux-data/stacks/nuxt-ui.csv +51 -51
- package/vibe/ui-ux-data/stacks/nuxtjs.csv +59 -59
- package/vibe/ui-ux-data/stacks/react-native.csv +52 -52
- package/vibe/ui-ux-data/stacks/react.csv +54 -54
- package/vibe/ui-ux-data/stacks/shadcn.csv +61 -61
- package/vibe/ui-ux-data/stacks/svelte.csv +54 -54
- package/vibe/ui-ux-data/stacks/swiftui.csv +51 -51
- package/vibe/ui-ux-data/stacks/vue.csv +50 -50
- package/vibe/ui-ux-data/styles.csv +68 -68
- package/vibe/ui-ux-data/typography.csv +57 -57
- package/vibe/ui-ux-data/ui-reasoning.csv +101 -101
- package/vibe/ui-ux-data/ux-guidelines.csv +99 -99
- package/vibe/ui-ux-data/version.json +31 -31
- 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
|
|
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
|
|
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
|
/**
|