prjct-cli 0.11.5 → 0.12.1
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/CHANGELOG.md +58 -0
- package/README.md +81 -25
- package/bin/dev.js +1 -1
- package/bin/generate-views.js +209 -0
- package/bin/migrate-to-json.js +742 -0
- package/bin/prjct +5 -5
- package/bin/serve.js +226 -50
- package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
- package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
- package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
- package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
- package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
- package/core/agentic/agent-router.ts +137 -0
- package/core/agentic/chain-of-thought.ts +228 -0
- package/core/agentic/command-executor/command-executor.ts +384 -0
- package/core/agentic/command-executor/index.ts +16 -0
- package/core/agentic/command-executor/status-signal.ts +38 -0
- package/core/agentic/command-executor/types.ts +79 -0
- package/core/agentic/command-executor.ts +8 -0
- package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
- package/core/agentic/context-filter.ts +365 -0
- package/core/agentic/ground-truth/index.ts +76 -0
- package/core/agentic/ground-truth/types.ts +33 -0
- package/core/agentic/ground-truth/utils.ts +48 -0
- package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
- package/core/agentic/ground-truth/verifiers/done.ts +75 -0
- package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
- package/core/agentic/ground-truth/verifiers/index.ts +37 -0
- package/core/agentic/ground-truth/verifiers/init.ts +52 -0
- package/core/agentic/ground-truth/verifiers/now.ts +57 -0
- package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
- package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
- package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
- package/core/agentic/ground-truth/verifiers.ts +6 -0
- package/core/agentic/ground-truth.ts +8 -0
- package/core/agentic/loop-detector/error-analysis.ts +97 -0
- package/core/agentic/loop-detector/hallucination.ts +71 -0
- package/core/agentic/loop-detector/index.ts +41 -0
- package/core/agentic/loop-detector/loop-detector.ts +222 -0
- package/core/agentic/loop-detector/types.ts +66 -0
- package/core/agentic/loop-detector.ts +8 -0
- package/core/agentic/memory-system/history.ts +53 -0
- package/core/agentic/memory-system/index.ts +192 -0
- package/core/agentic/memory-system/patterns.ts +156 -0
- package/core/agentic/memory-system/semantic-memories.ts +277 -0
- package/core/agentic/memory-system/session.ts +21 -0
- package/core/agentic/memory-system/types.ts +159 -0
- package/core/agentic/memory-system.ts +8 -0
- package/core/agentic/parallel-tools.ts +165 -0
- package/core/agentic/plan-mode/approval.ts +57 -0
- package/core/agentic/plan-mode/constants.ts +44 -0
- package/core/agentic/plan-mode/index.ts +28 -0
- package/core/agentic/plan-mode/plan-mode.ts +406 -0
- package/core/agentic/plan-mode/types.ts +193 -0
- package/core/agentic/plan-mode.ts +8 -0
- package/core/agentic/prompt-builder.ts +566 -0
- package/core/agentic/response-templates.ts +164 -0
- package/core/agentic/semantic-compression.ts +273 -0
- package/core/agentic/services.ts +206 -0
- package/core/agentic/smart-context.ts +476 -0
- package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
- package/core/agentic/think-blocks.ts +202 -0
- package/core/agentic/tool-registry.ts +119 -0
- package/core/agentic/validation-rules.ts +313 -0
- package/core/agents/index.ts +28 -0
- package/core/agents/performance.ts +444 -0
- package/core/agents/types.ts +126 -0
- package/core/bus/{index.js → index.ts} +57 -61
- package/core/command-registry/categories.ts +23 -0
- package/core/command-registry/commands.ts +15 -0
- package/core/command-registry/core-commands.ts +319 -0
- package/core/command-registry/index.ts +158 -0
- package/core/command-registry/optional-commands.ts +119 -0
- package/core/command-registry/setup-commands.ts +53 -0
- package/core/command-registry/types.ts +59 -0
- package/core/command-registry.ts +9 -0
- package/core/commands/analysis.ts +298 -0
- package/core/commands/analytics.ts +288 -0
- package/core/commands/base.ts +273 -0
- package/core/commands/index.ts +211 -0
- package/core/commands/maintenance.ts +226 -0
- package/core/commands/planning.ts +311 -0
- package/core/commands/setup.ts +309 -0
- package/core/commands/shipping.ts +188 -0
- package/core/commands/types.ts +183 -0
- package/core/commands/workflow.ts +226 -0
- package/core/commands.ts +11 -0
- package/core/constants/formats.ts +187 -0
- package/core/constants/index.ts +7 -0
- package/core/{context-sync.js → context-sync.ts} +59 -26
- package/core/data/agents-manager.ts +76 -0
- package/core/data/analysis-manager.ts +83 -0
- package/core/data/base-manager.ts +156 -0
- package/core/data/ideas-manager.ts +81 -0
- package/core/data/index.ts +32 -0
- package/core/data/outcomes-manager.ts +96 -0
- package/core/data/project-manager.ts +75 -0
- package/core/data/roadmap-manager.ts +118 -0
- package/core/data/shipped-manager.ts +65 -0
- package/core/data/state-manager.ts +214 -0
- package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
- package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
- package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
- package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
- package/core/domain/{analyzer.js → analyzer.ts} +91 -85
- package/core/domain/{architect-session.js → architect-session.ts} +49 -34
- package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
- package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
- package/core/domain/{product-standards.js → product-standards.ts} +40 -26
- package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
- package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
- package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
- package/core/domain/task-stack/index.ts +19 -0
- package/core/domain/task-stack/parser.ts +86 -0
- package/core/domain/task-stack/storage.ts +123 -0
- package/core/domain/task-stack/task-stack.ts +340 -0
- package/core/domain/task-stack/types.ts +51 -0
- package/core/domain/task-stack.ts +8 -0
- package/core/{index.js → index.ts} +61 -18
- package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
- package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
- package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
- package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
- package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
- package/core/infrastructure/command-installer/global-config.ts +106 -0
- package/core/infrastructure/command-installer/index.ts +25 -0
- package/core/infrastructure/command-installer/types.ts +41 -0
- package/core/infrastructure/command-installer.ts +8 -0
- package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
- package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
- package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
- package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
- package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
- package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
- package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
- package/core/infrastructure/legacy-installer-detector.ts +7 -0
- package/core/infrastructure/migrator/file-operations.ts +125 -0
- package/core/infrastructure/migrator/index.ts +288 -0
- package/core/infrastructure/migrator/project-scanner.ts +89 -0
- package/core/infrastructure/migrator/reports.ts +117 -0
- package/core/infrastructure/migrator/types.ts +124 -0
- package/core/infrastructure/migrator/validation.ts +94 -0
- package/core/infrastructure/migrator/version-migration.ts +117 -0
- package/core/infrastructure/migrator.ts +10 -0
- package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
- package/core/infrastructure/session-manager/index.ts +23 -0
- package/core/infrastructure/session-manager/migration.ts +88 -0
- package/core/infrastructure/session-manager/session-manager.ts +307 -0
- package/core/infrastructure/session-manager/types.ts +45 -0
- package/core/infrastructure/session-manager.ts +8 -0
- package/core/infrastructure/{setup.js → setup.ts} +29 -21
- package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
- package/core/outcomes/analyzer.ts +333 -0
- package/core/outcomes/index.ts +34 -0
- package/core/outcomes/recorder.ts +194 -0
- package/core/outcomes/types.ts +145 -0
- package/core/plugin/{hooks.js → hooks.ts} +56 -58
- package/core/plugin/{index.js → index.ts} +19 -8
- package/core/plugin/{loader.js → loader.ts} +87 -69
- package/core/plugin/{registry.js → registry.ts} +49 -45
- package/core/plugins/{webhook.js → webhook.ts} +43 -27
- package/core/schemas/agents.ts +27 -0
- package/core/schemas/analysis.ts +41 -0
- package/core/schemas/ideas.ts +83 -0
- package/core/schemas/index.ts +73 -0
- package/core/schemas/outcomes.ts +22 -0
- package/core/schemas/project.ts +26 -0
- package/core/schemas/roadmap.ts +90 -0
- package/core/schemas/shipped.ts +82 -0
- package/core/schemas/state.ts +107 -0
- package/core/session/index.ts +17 -0
- package/core/session/{metrics.js → metrics.ts} +64 -46
- package/core/session/{index.js → session-manager.ts} +51 -117
- package/core/session/types.ts +29 -0
- package/core/session/utils.ts +57 -0
- package/core/state/index.ts +25 -0
- package/core/state/manager.ts +376 -0
- package/core/state/types.ts +185 -0
- package/core/tsconfig.json +22 -0
- package/core/types/index.ts +506 -0
- package/core/utils/{animations.js → animations.ts} +74 -28
- package/core/utils/{branding.js → branding.ts} +29 -4
- package/core/utils/{date-helper.js → date-helper.ts} +31 -74
- package/core/utils/file-helper.ts +262 -0
- package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
- package/core/utils/{logger.js → logger.ts} +24 -12
- package/core/utils/{output.js → output.ts} +25 -13
- package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
- package/core/utils/{session-helper.js → session-helper.ts} +79 -66
- package/core/utils/{version.js → version.ts} +23 -31
- package/core/view-generator.ts +536 -0
- package/package.json +23 -17
- package/packages/shared/.turbo/turbo-build.log +14 -0
- package/packages/shared/dist/index.d.ts +8 -613
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +4110 -118
- package/packages/shared/dist/schemas.d.ts +408 -0
- package/packages/shared/dist/schemas.d.ts.map +1 -0
- package/packages/shared/dist/types.d.ts +144 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/unified.d.ts +139 -0
- package/packages/shared/dist/unified.d.ts.map +1 -0
- package/packages/shared/dist/utils.d.ts +60 -0
- package/packages/shared/dist/utils.d.ts.map +1 -0
- package/packages/shared/package.json +4 -4
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/unified.ts +174 -0
- package/packages/web/app/api/claude/sessions/route.ts +1 -1
- package/packages/web/app/api/claude/status/route.ts +1 -1
- package/packages/web/app/api/migrate/route.ts +46 -0
- package/packages/web/app/api/projects/[id]/route.ts +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
- package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
- package/packages/web/app/api/projects/route.ts +1 -1
- package/packages/web/app/api/settings/route.ts +97 -0
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
- package/packages/web/app/globals.css +38 -0
- package/packages/web/app/layout.tsx +10 -2
- package/packages/web/app/page.tsx +9 -224
- package/packages/web/app/project/[id]/page.tsx +191 -63
- package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
- package/packages/web/app/project/[id]/stats/page.tsx +204 -163
- package/packages/web/app/settings/page.tsx +222 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
- package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
- package/packages/web/components/ActivityTimeline/index.ts +2 -0
- package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
- package/packages/web/components/AgentsCard/index.ts +2 -0
- package/packages/web/components/AppSidebar/AppSidebar.tsx +190 -0
- package/packages/web/components/AppSidebar/index.ts +1 -0
- package/packages/web/components/BackLink/BackLink.tsx +18 -0
- package/packages/web/components/BackLink/BackLink.types.ts +5 -0
- package/packages/web/components/BackLink/index.ts +2 -0
- package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
- package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
- package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
- package/packages/web/components/BentoCard/index.ts +2 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
- package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
- package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
- package/packages/web/components/BentoGrid/index.ts +2 -0
- package/packages/web/components/CommandButton/index.ts +1 -0
- package/packages/web/components/ConnectionStatus/index.ts +1 -0
- package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
- package/packages/web/components/DashboardContent/index.ts +1 -0
- package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
- package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
- package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
- package/packages/web/components/DateGroup/index.ts +2 -0
- package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
- package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
- package/packages/web/components/EmptyState/index.ts +2 -0
- package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
- package/packages/web/components/EventRow/EventRow.tsx +49 -0
- package/packages/web/components/EventRow/EventRow.types.ts +7 -0
- package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
- package/packages/web/components/EventRow/index.ts +2 -0
- package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
- package/packages/web/components/ExpandButton/index.ts +2 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
- package/packages/web/components/HealthGradientBackground/index.ts +2 -0
- package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
- package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
- package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
- package/packages/web/components/HeroSection/hooks/index.ts +2 -0
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
- package/packages/web/components/HeroSection/index.ts +2 -0
- package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
- package/packages/web/components/IdeasCard/index.ts +2 -0
- package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
- package/packages/web/components/InsightMessage/index.ts +2 -0
- package/packages/web/components/Logo/index.ts +1 -0
- package/packages/web/components/MarkdownContent/index.ts +1 -0
- package/packages/web/components/NowCard/NowCard.tsx +93 -0
- package/packages/web/components/NowCard/NowCard.types.ts +15 -0
- package/packages/web/components/NowCard/index.ts +2 -0
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
- package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
- package/packages/web/components/ProgressRing/index.ts +2 -0
- package/packages/web/components/ProjectAvatar/index.ts +1 -0
- package/packages/web/components/Providers/index.ts +1 -0
- package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
- package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
- package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
- package/packages/web/components/QueueCard/index.ts +2 -0
- package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
- package/packages/web/components/ShipsCard/index.ts +2 -0
- package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
- package/packages/web/components/SparklineChart/index.ts +2 -0
- package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
- package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
- package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
- package/packages/web/components/StreakCard/index.ts +2 -0
- package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
- package/packages/web/components/TasksCounter/index.ts +2 -0
- package/packages/web/components/TechStackBadges/index.ts +1 -0
- package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
- package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
- package/packages/web/components/TerminalTabs/index.ts +1 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
- package/packages/web/components/VelocityBadge/index.ts +2 -0
- package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
- package/packages/web/components/VelocityCard/index.ts +2 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
- package/packages/web/components/WeeklySparkline/index.ts +2 -0
- package/packages/web/components/ui/input.tsx +21 -0
- package/packages/web/context/TerminalTabsContext.tsx +46 -1
- package/packages/web/hooks/useClaudeTerminal.ts +71 -21
- package/packages/web/hooks/useProjectStats.ts +55 -0
- package/packages/web/hooks/useProjects.ts +6 -6
- package/packages/web/lib/actions/projects.ts +15 -0
- package/packages/web/lib/json-loader.ts +630 -0
- package/packages/web/lib/services/index.ts +9 -0
- package/packages/web/lib/services/migration.server.ts +600 -0
- package/packages/web/lib/services/projects.server.ts +52 -0
- package/packages/web/lib/services/stats.server.ts +264 -0
- package/packages/web/lib/unified-loader.ts +396 -0
- package/packages/web/package.json +10 -7
- package/packages/web/server.ts +58 -8
- package/templates/commands/done.md +76 -32
- package/templates/commands/feature.md +121 -47
- package/templates/commands/idea.md +81 -8
- package/templates/commands/now.md +41 -17
- package/templates/commands/ship.md +64 -25
- package/templates/commands/sync.md +28 -3
- package/core/agentic/agent-router.js +0 -140
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -417
- package/core/agentic/context-filter.js +0 -354
- package/core/agentic/ground-truth.js +0 -591
- package/core/agentic/loop-detector.js +0 -406
- package/core/agentic/memory-system.js +0 -845
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -352
- package/core/agentic/response-templates.js +0 -290
- package/core/agentic/semantic-compression.js +0 -517
- package/core/agentic/think-blocks.js +0 -657
- package/core/agentic/tool-registry.js +0 -184
- package/core/agentic/validation-rules.js +0 -380
- package/core/command-registry.js +0 -698
- package/core/commands.js +0 -2237
- package/core/domain/task-stack.js +0 -497
- package/core/infrastructure/legacy-installer-detector.js +0 -546
- package/core/infrastructure/migrator.js +0 -796
- package/core/infrastructure/session-manager.js +0 -390
- package/core/utils/file-helper.js +0 -329
- package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
- package/packages/web/app/api/stats/route.ts +0 -38
- package/packages/web/components/AppSidebar.tsx +0 -113
- package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
- package/packages/web/components/stats/AgentsCard.tsx +0 -56
- package/packages/web/components/stats/BentoCard.tsx +0 -88
- package/packages/web/components/stats/HeroSection.tsx +0 -172
- package/packages/web/components/stats/NowCard.tsx +0 -71
- package/packages/web/components/stats/QueueCard.tsx +0 -58
- package/packages/web/components/stats/VelocityCard.tsx +0 -60
- package/packages/web/components/stats/index.ts +0 -17
- package/packages/web/hooks/useStats.ts +0 -28
- /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
- /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
- /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
- /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
- /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
- /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
- /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Builder
|
|
3
|
+
* Builds prompts for Claude based on templates and context.
|
|
4
|
+
* Claude decides what to do - NO if/else logic here.
|
|
5
|
+
*
|
|
6
|
+
* Auto-injects unified state, learned patterns, and performance stats.
|
|
7
|
+
*
|
|
8
|
+
* @module agentic/prompt-builder
|
|
9
|
+
* @version 5.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import fs from 'fs'
|
|
13
|
+
import path from 'path'
|
|
14
|
+
import stateManager from '../state'
|
|
15
|
+
import { outcomeAnalyzer } from '../outcomes'
|
|
16
|
+
import type { ProjectState } from '../state/types'
|
|
17
|
+
import type { DetectedPattern } from '../outcomes/analyzer'
|
|
18
|
+
|
|
19
|
+
interface Frontmatter {
|
|
20
|
+
name?: string
|
|
21
|
+
description?: string
|
|
22
|
+
'allowed-tools'?: string[]
|
|
23
|
+
[key: string]: unknown
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface Template {
|
|
27
|
+
frontmatter: Frontmatter
|
|
28
|
+
content: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface Agent {
|
|
32
|
+
name: string
|
|
33
|
+
role?: string
|
|
34
|
+
skills?: string[]
|
|
35
|
+
[key: string]: unknown
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface Context {
|
|
39
|
+
files?: string[]
|
|
40
|
+
filteredSize?: number
|
|
41
|
+
[key: string]: unknown
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface State {
|
|
45
|
+
codePatterns?: string
|
|
46
|
+
analysis?: string
|
|
47
|
+
[key: string]: unknown
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
interface LearnedPatterns {
|
|
51
|
+
[key: string]: string | null
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
interface ThinkBlock {
|
|
55
|
+
plan?: string[]
|
|
56
|
+
conclusions?: string[]
|
|
57
|
+
confidence?: number
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface Memory {
|
|
61
|
+
title: string
|
|
62
|
+
content: string
|
|
63
|
+
tags?: string[]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface PlanInfo {
|
|
67
|
+
isPlanning?: boolean
|
|
68
|
+
requiresApproval?: boolean
|
|
69
|
+
allowedTools?: string[]
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Builds prompts for Claude using templates, context, and learned patterns.
|
|
74
|
+
* Supports plan mode, think blocks, and quality checklists.
|
|
75
|
+
* Auto-injects unified state and performance insights.
|
|
76
|
+
*/
|
|
77
|
+
class PromptBuilder {
|
|
78
|
+
private _checklistsCache: Record<string, string> | null = null
|
|
79
|
+
private _checklistRoutingCache: string | null = null
|
|
80
|
+
private _currentContext: Context | null = null
|
|
81
|
+
private _stateCache: Map<string, { state: ProjectState; timestamp: number }> = new Map()
|
|
82
|
+
private _stateCacheTTL = 5000 // 5 seconds
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Load quality checklists from templates/checklists/
|
|
86
|
+
*/
|
|
87
|
+
loadChecklists(): Record<string, string> {
|
|
88
|
+
if (this._checklistsCache) return this._checklistsCache
|
|
89
|
+
|
|
90
|
+
const checklistsDir = path.join(__dirname, '..', '..', 'templates', 'checklists')
|
|
91
|
+
const checklists: Record<string, string> = {}
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
if (fs.existsSync(checklistsDir)) {
|
|
95
|
+
const files = fs.readdirSync(checklistsDir).filter((f) => f.endsWith('.md'))
|
|
96
|
+
for (const file of files) {
|
|
97
|
+
const name = file.replace('.md', '')
|
|
98
|
+
const content = fs.readFileSync(path.join(checklistsDir, file), 'utf-8')
|
|
99
|
+
checklists[name] = content
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} catch {
|
|
103
|
+
// Silent fail - checklists are optional enhancement
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
this._checklistsCache = checklists
|
|
107
|
+
return checklists
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get unified project state with caching.
|
|
112
|
+
*/
|
|
113
|
+
async getProjectState(projectId: string): Promise<ProjectState | null> {
|
|
114
|
+
if (!projectId) return null
|
|
115
|
+
|
|
116
|
+
const cached = this._stateCache.get(projectId)
|
|
117
|
+
if (cached && Date.now() - cached.timestamp < this._stateCacheTTL) {
|
|
118
|
+
return cached.state
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
const state = await stateManager.read(projectId)
|
|
123
|
+
this._stateCache.set(projectId, { state, timestamp: Date.now() })
|
|
124
|
+
return state
|
|
125
|
+
} catch {
|
|
126
|
+
return null
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Build auto-injected context from unified state.
|
|
132
|
+
* This is automatically added to every prompt.
|
|
133
|
+
*/
|
|
134
|
+
async buildInjectedContext(projectId: string): Promise<string | null> {
|
|
135
|
+
if (!projectId) return null
|
|
136
|
+
|
|
137
|
+
const state = await this.getProjectState(projectId)
|
|
138
|
+
if (!state) return null
|
|
139
|
+
|
|
140
|
+
const parts: string[] = []
|
|
141
|
+
|
|
142
|
+
// Current state
|
|
143
|
+
parts.push('## AUTO-INJECTED CONTEXT')
|
|
144
|
+
parts.push('')
|
|
145
|
+
|
|
146
|
+
// Current task
|
|
147
|
+
if (state.currentTask) {
|
|
148
|
+
const elapsed = this.calculateElapsed(state.currentTask.startedAt)
|
|
149
|
+
parts.push(`**Current Task**: ${state.currentTask.description}`)
|
|
150
|
+
parts.push(`- Started: ${elapsed} ago`)
|
|
151
|
+
if (state.currentTask.agent) {
|
|
152
|
+
parts.push(`- Agent: ${state.currentTask.agent}`)
|
|
153
|
+
}
|
|
154
|
+
if (state.currentTask.pausedAt) {
|
|
155
|
+
parts.push(`- Status: PAUSED (${state.currentTask.pauseReason || 'no reason'})`)
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
parts.push('**Current Task**: None')
|
|
159
|
+
}
|
|
160
|
+
parts.push('')
|
|
161
|
+
|
|
162
|
+
// Active feature
|
|
163
|
+
if (state.activeFeature) {
|
|
164
|
+
const progress = state.activeFeature.tasksCompleted + state.activeFeature.tasksRemaining
|
|
165
|
+
const pct = progress > 0
|
|
166
|
+
? Math.round((state.activeFeature.tasksCompleted / progress) * 100)
|
|
167
|
+
: 0
|
|
168
|
+
parts.push(`**Feature**: ${state.activeFeature.name} (${pct}% complete)`)
|
|
169
|
+
parts.push(`- Tasks: ${state.activeFeature.tasksCompleted}/${progress}`)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Queue summary
|
|
173
|
+
if (state.queue.length > 0) {
|
|
174
|
+
parts.push(`**Queue**: ${state.queue.length} tasks pending`)
|
|
175
|
+
const top3 = state.queue.slice(0, 3)
|
|
176
|
+
for (const task of top3) {
|
|
177
|
+
parts.push(`- [${task.priority}] ${task.description}`)
|
|
178
|
+
}
|
|
179
|
+
if (state.queue.length > 3) {
|
|
180
|
+
parts.push(`- ... and ${state.queue.length - 3} more`)
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
parts.push('')
|
|
184
|
+
|
|
185
|
+
// Performance stats
|
|
186
|
+
if (state.stats.tasksToday > 0 || state.stats.streak > 0) {
|
|
187
|
+
parts.push('**Performance**')
|
|
188
|
+
parts.push(`- Today: ${state.stats.tasksToday} tasks`)
|
|
189
|
+
parts.push(`- Velocity: ${state.stats.velocity}`)
|
|
190
|
+
parts.push(`- Estimate accuracy: ${state.stats.estimateAccuracy}%`)
|
|
191
|
+
if (state.stats.streak > 1) {
|
|
192
|
+
parts.push(`- Streak: ${state.stats.streak} days`)
|
|
193
|
+
}
|
|
194
|
+
parts.push('')
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Get detected patterns from outcomes
|
|
198
|
+
try {
|
|
199
|
+
const patterns = await outcomeAnalyzer.detectPatterns(projectId)
|
|
200
|
+
if (patterns.length > 0) {
|
|
201
|
+
parts.push('**Learned Patterns**')
|
|
202
|
+
for (const pattern of patterns.slice(0, 3)) {
|
|
203
|
+
parts.push(`- ${pattern.description}`)
|
|
204
|
+
if (pattern.suggestedAction) {
|
|
205
|
+
parts.push(` → ${pattern.suggestedAction}`)
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
parts.push('')
|
|
209
|
+
}
|
|
210
|
+
} catch {
|
|
211
|
+
// Outcomes not available yet
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Recent activity
|
|
215
|
+
if (state.recentActivity.length > 0) {
|
|
216
|
+
parts.push('**Recent Activity**')
|
|
217
|
+
for (const activity of state.recentActivity.slice(0, 3)) {
|
|
218
|
+
const ago = this.calculateElapsed(activity.timestamp)
|
|
219
|
+
parts.push(`- ${activity.type}: ${activity.description} (${ago} ago)`)
|
|
220
|
+
}
|
|
221
|
+
parts.push('')
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
parts.push('---')
|
|
225
|
+
parts.push('')
|
|
226
|
+
|
|
227
|
+
return parts.join('\n')
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Calculate elapsed time from ISO timestamp.
|
|
232
|
+
*/
|
|
233
|
+
private calculateElapsed(isoTimestamp: string): string {
|
|
234
|
+
const start = new Date(isoTimestamp).getTime()
|
|
235
|
+
const now = Date.now()
|
|
236
|
+
const diffMs = now - start
|
|
237
|
+
|
|
238
|
+
const minutes = Math.floor(diffMs / 60000)
|
|
239
|
+
const hours = Math.floor(minutes / 60)
|
|
240
|
+
const days = Math.floor(hours / 24)
|
|
241
|
+
|
|
242
|
+
if (days > 0) return `${days}d ${hours % 24}h`
|
|
243
|
+
if (hours > 0) return `${hours}h ${minutes % 60}m`
|
|
244
|
+
return `${minutes}m`
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Load checklist routing template for Claude to decide which checklists apply
|
|
249
|
+
*/
|
|
250
|
+
loadChecklistRouting(): string | null {
|
|
251
|
+
if (this._checklistRoutingCache) return this._checklistRoutingCache
|
|
252
|
+
|
|
253
|
+
const routingPath = path.join(__dirname, '..', '..', 'templates', 'agentic', 'checklist-routing.md')
|
|
254
|
+
|
|
255
|
+
try {
|
|
256
|
+
if (fs.existsSync(routingPath)) {
|
|
257
|
+
this._checklistRoutingCache = fs.readFileSync(routingPath, 'utf-8')
|
|
258
|
+
}
|
|
259
|
+
} catch {
|
|
260
|
+
// Silent fail
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return this._checklistRoutingCache || null
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Build a complete prompt with auto-injected context.
|
|
268
|
+
* This is the preferred method - automatically includes state and insights.
|
|
269
|
+
*/
|
|
270
|
+
async buildWithInjection(
|
|
271
|
+
template: Template,
|
|
272
|
+
context: Context & { projectId?: string },
|
|
273
|
+
state: State,
|
|
274
|
+
agent: Agent | null = null,
|
|
275
|
+
learnedPatterns: LearnedPatterns | null = null,
|
|
276
|
+
thinkBlock: ThinkBlock | null = null,
|
|
277
|
+
relevantMemories: Memory[] | null = null,
|
|
278
|
+
planInfo: PlanInfo | null = null
|
|
279
|
+
): Promise<string> {
|
|
280
|
+
const parts: string[] = []
|
|
281
|
+
|
|
282
|
+
// Auto-inject unified context first
|
|
283
|
+
if (context.projectId) {
|
|
284
|
+
const injected = await this.buildInjectedContext(context.projectId)
|
|
285
|
+
if (injected) {
|
|
286
|
+
parts.push(injected)
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Build the rest using existing method
|
|
291
|
+
const basePrompt = this.build(
|
|
292
|
+
template,
|
|
293
|
+
context,
|
|
294
|
+
state,
|
|
295
|
+
agent,
|
|
296
|
+
learnedPatterns,
|
|
297
|
+
thinkBlock,
|
|
298
|
+
relevantMemories,
|
|
299
|
+
planInfo
|
|
300
|
+
)
|
|
301
|
+
|
|
302
|
+
parts.push(basePrompt)
|
|
303
|
+
|
|
304
|
+
return parts.join('')
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Build a complete prompt for Claude from template, context, and enhancements
|
|
309
|
+
* @deprecated Use buildWithInjection for auto-injected context
|
|
310
|
+
*/
|
|
311
|
+
build(
|
|
312
|
+
template: Template,
|
|
313
|
+
context: Context,
|
|
314
|
+
state: State,
|
|
315
|
+
agent: Agent | null = null,
|
|
316
|
+
learnedPatterns: LearnedPatterns | null = null,
|
|
317
|
+
thinkBlock: ThinkBlock | null = null,
|
|
318
|
+
relevantMemories: Memory[] | null = null,
|
|
319
|
+
planInfo: PlanInfo | null = null
|
|
320
|
+
): string {
|
|
321
|
+
const parts: string[] = []
|
|
322
|
+
|
|
323
|
+
// Store context for use in helper methods
|
|
324
|
+
this._currentContext = context
|
|
325
|
+
|
|
326
|
+
// Agent assignment (CONDITIONAL - only for code-modifying commands)
|
|
327
|
+
const commandName = template.frontmatter?.name?.replace('p:', '') || ''
|
|
328
|
+
const agentCommands = ['now', 'build', 'feature', 'design', 'fix', 'bug', 'test', 'work', 'cleanup', 'spec']
|
|
329
|
+
const needsAgent = agentCommands.includes(commandName)
|
|
330
|
+
|
|
331
|
+
if (agent && needsAgent) {
|
|
332
|
+
parts.push(`# AGENT: ${agent.name}\n`)
|
|
333
|
+
if (agent.role) parts.push(`Role: ${agent.role}\n`)
|
|
334
|
+
if (agent.skills?.length) parts.push(`Skills: ${agent.skills.join(', ')}\n`)
|
|
335
|
+
parts.push(`\nApply specialized expertise. Read agent file for details if needed.\n\n`)
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Core instruction (concise)
|
|
339
|
+
parts.push(`TASK: ${template.frontmatter.description}\n`)
|
|
340
|
+
|
|
341
|
+
// Tools (inline)
|
|
342
|
+
if (template.frontmatter['allowed-tools']) {
|
|
343
|
+
parts.push(`TOOLS: ${template.frontmatter['allowed-tools'].join(', ')}\n`)
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// Critical parameters only
|
|
347
|
+
const params = context as { params?: { task?: string; description?: string } }
|
|
348
|
+
if (params.params?.task || params.params?.description) {
|
|
349
|
+
parts.push(`INPUT: ${params.params.task || params.params.description}\n`)
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
parts.push('\n---\n')
|
|
353
|
+
|
|
354
|
+
// Template (only the flow section, skip verbose explanations)
|
|
355
|
+
const flowMatch = template.content.match(/## Flow([\s\S]*?)(?=##|$)/)
|
|
356
|
+
if (flowMatch) {
|
|
357
|
+
parts.push(flowMatch[0])
|
|
358
|
+
} else {
|
|
359
|
+
parts.push(template.content)
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
// Current state (only if exists and relevant)
|
|
363
|
+
const relevantState = this.filterRelevantState(state)
|
|
364
|
+
if (relevantState) {
|
|
365
|
+
parts.push('\n## PRJCT STATE (Project Management Data)\n')
|
|
366
|
+
parts.push(relevantState)
|
|
367
|
+
parts.push('\n')
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// COMPRESSED: File list
|
|
371
|
+
const files = context.files || []
|
|
372
|
+
if (files.length > 0) {
|
|
373
|
+
const top5 = files.slice(0, 5).join(', ')
|
|
374
|
+
parts.push(`\n## FILES: ${files.length} available. Top: ${top5}\n`)
|
|
375
|
+
parts.push('Read BEFORE modifying. Use Glob/Grep to find more.\n\n')
|
|
376
|
+
} else if ((context as { projectPath?: string }).projectPath) {
|
|
377
|
+
parts.push(`\n## PROJECT: ${(context as { projectPath: string }).projectPath}\nRead files before modifying.\n\n`)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// OPTIMIZED: Only include patterns for code-modifying commands
|
|
381
|
+
const codeCommands = ['now', 'build', 'feature', 'design', 'cleanup', 'fix', 'bug', 'test', 'init', 'spec', 'work']
|
|
382
|
+
const needsPatterns = codeCommands.includes(commandName)
|
|
383
|
+
|
|
384
|
+
// Include code patterns analysis for code-modifying commands
|
|
385
|
+
const codePatternsContent = state?.codePatterns || ''
|
|
386
|
+
if (needsPatterns && codePatternsContent && codePatternsContent.trim()) {
|
|
387
|
+
const patternSummary = this.extractPatternSummary(codePatternsContent)
|
|
388
|
+
if (patternSummary) {
|
|
389
|
+
parts.push('\n## CODE PATTERNS\n')
|
|
390
|
+
parts.push(patternSummary)
|
|
391
|
+
parts.push('\nFull patterns: Read analysis/patterns.md\n')
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const analysisContent = state?.analysis || ''
|
|
396
|
+
if (needsPatterns && analysisContent && analysisContent.trim()) {
|
|
397
|
+
const stackMatch =
|
|
398
|
+
analysisContent.match(/Stack[:\s]+([^\n]+)/i) || analysisContent.match(/Technology[:\s]+([^\n]+)/i)
|
|
399
|
+
const stack = stackMatch ? stackMatch[1].trim() : 'detected'
|
|
400
|
+
|
|
401
|
+
parts.push(`\n## STACK\nStack: ${stack}\n`)
|
|
402
|
+
if (!codePatternsContent) {
|
|
403
|
+
parts.push('Read analysis/repo-summary.md + similar files before coding. Match patterns exactly.\n')
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// CRITICAL: Compressed rules
|
|
408
|
+
parts.push(this.buildCriticalRules())
|
|
409
|
+
|
|
410
|
+
// P1.1: Learned Patterns
|
|
411
|
+
if (learnedPatterns && Object.keys(learnedPatterns).some((k) => learnedPatterns[k])) {
|
|
412
|
+
parts.push('\n## LEARNED PATTERNS (use these, do NOT ask user)\n')
|
|
413
|
+
for (const [key, value] of Object.entries(learnedPatterns)) {
|
|
414
|
+
if (value) {
|
|
415
|
+
parts.push(`- ${key}: ${value}\n`)
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
// P3.1: Think Block
|
|
421
|
+
if (thinkBlock && thinkBlock.plan && thinkBlock.plan.length > 0) {
|
|
422
|
+
parts.push('\n## THINK FIRST (reasoning from analysis)\n')
|
|
423
|
+
if (thinkBlock.conclusions && thinkBlock.conclusions.length > 0) {
|
|
424
|
+
parts.push('Conclusions:\n')
|
|
425
|
+
thinkBlock.conclusions.forEach((c) => parts.push(` → ${c}\n`))
|
|
426
|
+
}
|
|
427
|
+
parts.push('Plan:\n')
|
|
428
|
+
thinkBlock.plan.forEach((p, i) => parts.push(` ${i + 1}. ${p}\n`))
|
|
429
|
+
parts.push(`Confidence: ${Math.round((thinkBlock.confidence || 0.5) * 100)}%\n`)
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// P3.3: Relevant Memories
|
|
433
|
+
if (relevantMemories && relevantMemories.length > 0) {
|
|
434
|
+
parts.push('\n## RELEVANT MEMORIES (apply these learnings)\n')
|
|
435
|
+
for (const memory of relevantMemories) {
|
|
436
|
+
parts.push(`- **${memory.title}**: ${memory.content}\n`)
|
|
437
|
+
if (memory.tags && memory.tags.length > 0) {
|
|
438
|
+
parts.push(` Tags: ${memory.tags.join(', ')}\n`)
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// P3.4: Plan Mode
|
|
444
|
+
if (planInfo?.isPlanning) {
|
|
445
|
+
parts.push(`\n## PLAN MODE\nRead-only. Gather info → Analyze → Propose plan → Wait for approval.\n`)
|
|
446
|
+
if (planInfo.allowedTools) parts.push(`Tools: ${planInfo.allowedTools.join(', ')}\n`)
|
|
447
|
+
}
|
|
448
|
+
if (planInfo?.requiresApproval) {
|
|
449
|
+
parts.push(`\n## APPROVAL REQUIRED\nShow changes, list affected files, ask for confirmation.\n`)
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// P4.1: Quality Checklists
|
|
453
|
+
const checklistCommands = ['now', 'build', 'feature', 'design', 'fix', 'bug', 'cleanup', 'spec', 'work']
|
|
454
|
+
if (checklistCommands.includes(commandName)) {
|
|
455
|
+
const routing = this.loadChecklistRouting()
|
|
456
|
+
const checklists = this.loadChecklists()
|
|
457
|
+
|
|
458
|
+
if (routing && Object.keys(checklists).length > 0) {
|
|
459
|
+
parts.push('\n## QUALITY CHECKLISTS\n')
|
|
460
|
+
parts.push('Apply relevant checklists based on task. Read checklist-routing.md for guidance.\n')
|
|
461
|
+
parts.push(`Available: ${Object.keys(checklists).join(', ')}\n`)
|
|
462
|
+
parts.push('Path: templates/checklists/{name}.md\n')
|
|
463
|
+
parts.push('Use Read tool to load checklists you determine are relevant.\n')
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// Simple execution directive
|
|
468
|
+
parts.push('\nEXECUTE: Follow flow. Use tools. Decide.\n')
|
|
469
|
+
|
|
470
|
+
return parts.join('')
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Filter state data to include only relevant portions for the prompt
|
|
475
|
+
*/
|
|
476
|
+
filterRelevantState(state: State): string | null {
|
|
477
|
+
if (!state || Object.keys(state).length === 0) return null
|
|
478
|
+
|
|
479
|
+
const relevant: string[] = []
|
|
480
|
+
for (const [key, content] of Object.entries(state)) {
|
|
481
|
+
if (content && (content as string).trim()) {
|
|
482
|
+
const criticalFiles = ['now', 'next', 'context', 'analysis', 'codePatterns']
|
|
483
|
+
if (criticalFiles.includes(key)) {
|
|
484
|
+
const display =
|
|
485
|
+
(content as string).length > 2000
|
|
486
|
+
? (content as string).substring(0, 2000) + '\n... (truncated)'
|
|
487
|
+
: content
|
|
488
|
+
relevant.push(`### ${key}\n${display}`)
|
|
489
|
+
} else if ((content as string).length < 1000) {
|
|
490
|
+
relevant.push(`### ${key}\n${content}`)
|
|
491
|
+
} else {
|
|
492
|
+
relevant.push(
|
|
493
|
+
`### ${key}\n${(content as string).substring(0, 500)}... (truncated, use Read tool for full content)`
|
|
494
|
+
)
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return relevant.length > 0 ? relevant.join('\n\n') : null
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Build an analysis prompt for pre-action investigation tasks
|
|
504
|
+
*/
|
|
505
|
+
buildAnalysis(analysisType: string, context: { projectPath: string; projectId?: string }): string {
|
|
506
|
+
const parts: string[] = []
|
|
507
|
+
|
|
508
|
+
parts.push(`# Analyze: ${analysisType}\n\n`)
|
|
509
|
+
parts.push('Read the project context and provide your analysis.\n')
|
|
510
|
+
parts.push('No predetermined patterns - decide based on what you find.\n\n')
|
|
511
|
+
|
|
512
|
+
parts.push('## Project Context\n')
|
|
513
|
+
parts.push(`- Path: ${context.projectPath}\n`)
|
|
514
|
+
parts.push(`- ID: ${context.projectId}\n\n`)
|
|
515
|
+
|
|
516
|
+
return parts.join('')
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Extract compressed pattern summary
|
|
521
|
+
*/
|
|
522
|
+
extractPatternSummary(content: string): string | null {
|
|
523
|
+
if (!content) return null
|
|
524
|
+
|
|
525
|
+
const parts: string[] = []
|
|
526
|
+
|
|
527
|
+
const conventionsMatch = content.match(/## Conventions[\s\S]*?(?=##|$)/i)
|
|
528
|
+
if (conventionsMatch) {
|
|
529
|
+
const conventions = conventionsMatch[0]
|
|
530
|
+
.split('\n')
|
|
531
|
+
.filter((line) => line.includes(':') || line.startsWith('-'))
|
|
532
|
+
.slice(0, 6)
|
|
533
|
+
.join('\n')
|
|
534
|
+
if (conventions) parts.push(conventions)
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
const antiPatternsMatch = content.match(/### High Priority[\s\S]*?(?=###|##|$)/i)
|
|
538
|
+
if (antiPatternsMatch) {
|
|
539
|
+
const antiPatterns = antiPatternsMatch[0].substring(0, 300)
|
|
540
|
+
parts.push('\nAvoid:\n' + antiPatterns)
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
const result = parts.join('\n').substring(0, 800)
|
|
544
|
+
return result || null
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
/**
|
|
548
|
+
* Build critical anti-hallucination rules section
|
|
549
|
+
*/
|
|
550
|
+
buildCriticalRules(): string {
|
|
551
|
+
const fileCount = this._currentContext?.files?.length || this._currentContext?.filteredSize || 0
|
|
552
|
+
return `
|
|
553
|
+
## RULES (CRITICAL)
|
|
554
|
+
1. **READ FIRST**: Use Read tool BEFORE modifying any file. Never assume code structure.
|
|
555
|
+
2. **MATCH PATTERNS**: Follow existing style, architecture, naming, imports exactly.
|
|
556
|
+
3. **NO HALLUCINATIONS**: Don't invent files, functions, or paths. If unsure, READ first.
|
|
557
|
+
4. **GIT SAFETY**: Never use checkout/reset --hard/clean. Always check status first.
|
|
558
|
+
5. **VERIFY**: After writing, confirm code matches project patterns.
|
|
559
|
+
Context: ${fileCount} files available. Read what you need.
|
|
560
|
+
`
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
const promptBuilder = new PromptBuilder()
|
|
565
|
+
export default promptBuilder
|
|
566
|
+
export { PromptBuilder }
|