prjct-cli 0.11.5 → 0.12.0
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 +134 -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 +598 -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 +36 -6
- 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
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Tests for centralized date operations and formatting
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, setSystemTime } from 'bun:test'
|
|
7
|
+
import {
|
|
7
8
|
formatDate,
|
|
8
9
|
formatMonth,
|
|
9
10
|
getTodayKey,
|
|
@@ -20,7 +21,7 @@ const {
|
|
|
20
21
|
calculateDuration,
|
|
21
22
|
getStartOfDay,
|
|
22
23
|
getEndOfDay,
|
|
23
|
-
}
|
|
24
|
+
} from '../../utils/date-helper'
|
|
24
25
|
|
|
25
26
|
describe('DateHelper', () => {
|
|
26
27
|
describe('formatDate', () => {
|
|
@@ -64,12 +65,9 @@ describe('DateHelper', () => {
|
|
|
64
65
|
|
|
65
66
|
describe('getTodayKey', () => {
|
|
66
67
|
it('should return today in YYYY-MM-DD format', () => {
|
|
67
|
-
|
|
68
|
-
vi.setSystemTime(new Date(2025, 5, 15)) // June 15, 2025
|
|
69
|
-
|
|
68
|
+
setSystemTime(new Date(2025, 5, 15)) // June 15, 2025
|
|
70
69
|
expect(getTodayKey()).toBe('2025-06-15')
|
|
71
|
-
|
|
72
|
-
vi.useRealTimers()
|
|
70
|
+
setSystemTime()
|
|
73
71
|
})
|
|
74
72
|
})
|
|
75
73
|
|
|
@@ -93,14 +91,12 @@ describe('DateHelper', () => {
|
|
|
93
91
|
it('should pad month values', () => {
|
|
94
92
|
const date = new Date(2025, 0, 15) // Jan 15, 2025
|
|
95
93
|
const result = getYearMonthDay(date)
|
|
96
|
-
|
|
97
94
|
expect(result.month).toBe('01')
|
|
98
95
|
})
|
|
99
96
|
|
|
100
97
|
it('should pad day values', () => {
|
|
101
98
|
const date = new Date(2025, 5, 7) // June 7, 2025
|
|
102
99
|
const result = getYearMonthDay(date)
|
|
103
|
-
|
|
104
100
|
expect(result.day).toBe('07')
|
|
105
101
|
})
|
|
106
102
|
})
|
|
@@ -122,12 +118,9 @@ describe('DateHelper', () => {
|
|
|
122
118
|
|
|
123
119
|
describe('getTimestamp', () => {
|
|
124
120
|
it('should return ISO timestamp', () => {
|
|
125
|
-
|
|
126
|
-
vi.setSystemTime(new Date('2025-10-04T14:30:00.000Z'))
|
|
127
|
-
|
|
121
|
+
setSystemTime(new Date('2025-10-04T14:30:00.000Z'))
|
|
128
122
|
expect(getTimestamp()).toBe('2025-10-04T14:30:00.000Z')
|
|
129
|
-
|
|
130
|
-
vi.useRealTimers()
|
|
123
|
+
setSystemTime()
|
|
131
124
|
})
|
|
132
125
|
|
|
133
126
|
it('should include milliseconds', () => {
|
|
@@ -138,12 +131,11 @@ describe('DateHelper', () => {
|
|
|
138
131
|
|
|
139
132
|
describe('getDaysAgo', () => {
|
|
140
133
|
beforeEach(() => {
|
|
141
|
-
|
|
142
|
-
vi.setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
|
|
134
|
+
setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
|
|
143
135
|
})
|
|
144
136
|
|
|
145
137
|
afterEach(() => {
|
|
146
|
-
|
|
138
|
+
setSystemTime()
|
|
147
139
|
})
|
|
148
140
|
|
|
149
141
|
it('should calculate past dates correctly', () => {
|
|
@@ -164,12 +156,11 @@ describe('DateHelper', () => {
|
|
|
164
156
|
|
|
165
157
|
describe('getDaysFromNow', () => {
|
|
166
158
|
beforeEach(() => {
|
|
167
|
-
|
|
168
|
-
vi.setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
|
|
159
|
+
setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
|
|
169
160
|
})
|
|
170
161
|
|
|
171
162
|
afterEach(() => {
|
|
172
|
-
|
|
163
|
+
setSystemTime()
|
|
173
164
|
})
|
|
174
165
|
|
|
175
166
|
it('should calculate future dates correctly', () => {
|
|
@@ -241,12 +232,11 @@ describe('DateHelper', () => {
|
|
|
241
232
|
|
|
242
233
|
describe('isToday', () => {
|
|
243
234
|
beforeEach(() => {
|
|
244
|
-
|
|
245
|
-
vi.setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
|
|
235
|
+
setSystemTime(new Date(2025, 9, 15)) // Oct 15, 2025
|
|
246
236
|
})
|
|
247
237
|
|
|
248
238
|
afterEach(() => {
|
|
249
|
-
|
|
239
|
+
setSystemTime()
|
|
250
240
|
})
|
|
251
241
|
|
|
252
242
|
it('should return true for today', () => {
|
|
@@ -272,12 +262,11 @@ describe('DateHelper', () => {
|
|
|
272
262
|
|
|
273
263
|
describe('isWithinLastDays', () => {
|
|
274
264
|
beforeEach(() => {
|
|
275
|
-
|
|
276
|
-
vi.setSystemTime(new Date(2025, 9, 15, 12, 0, 0)) // Oct 15, 2025 at noon
|
|
265
|
+
setSystemTime(new Date(2025, 9, 15, 12, 0, 0)) // Oct 15, 2025 at noon
|
|
277
266
|
})
|
|
278
267
|
|
|
279
268
|
afterEach(() => {
|
|
280
|
-
|
|
269
|
+
setSystemTime()
|
|
281
270
|
})
|
|
282
271
|
|
|
283
272
|
it('should return true for dates within range', () => {
|
|
@@ -296,7 +285,8 @@ describe('DateHelper', () => {
|
|
|
296
285
|
})
|
|
297
286
|
|
|
298
287
|
it('should include boundary date', () => {
|
|
299
|
-
|
|
288
|
+
// Oct 8 at noon is exactly 7 days before Oct 15 at noon
|
|
289
|
+
const boundary = new Date(2025, 9, 8, 12, 0, 0)
|
|
300
290
|
expect(isWithinLastDays(boundary, 7)).toBe(true)
|
|
301
291
|
})
|
|
302
292
|
})
|
|
@@ -339,13 +329,12 @@ describe('DateHelper', () => {
|
|
|
339
329
|
})
|
|
340
330
|
|
|
341
331
|
it('should default to now if no end date', () => {
|
|
342
|
-
|
|
343
|
-
vi.setSystemTime(new Date('2025-10-15T12:00:00.000Z'))
|
|
332
|
+
setSystemTime(new Date('2025-10-15T12:00:00.000Z'))
|
|
344
333
|
|
|
345
334
|
const start = new Date('2025-10-15T10:00:00.000Z')
|
|
346
335
|
expect(calculateDuration(start)).toBe('2h 0m')
|
|
347
336
|
|
|
348
|
-
|
|
337
|
+
setSystemTime()
|
|
349
338
|
})
|
|
350
339
|
|
|
351
340
|
it('should handle short durations', () => {
|
|
@@ -3,18 +3,16 @@
|
|
|
3
3
|
* Minimal output system for prjct-cli
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach, spyOn } from 'bun:test'
|
|
7
|
+
import out from '../../utils/output'
|
|
7
8
|
|
|
8
9
|
describe('Output Module', () => {
|
|
9
|
-
let consoleLogSpy
|
|
10
|
-
let stdoutWriteSpy
|
|
10
|
+
let consoleLogSpy: ReturnType<typeof spyOn>
|
|
11
|
+
let stdoutWriteSpy: ReturnType<typeof spyOn>
|
|
11
12
|
|
|
12
13
|
beforeEach(() => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// Mock process.stdout.write
|
|
16
|
-
stdoutWriteSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => {})
|
|
17
|
-
// Ensure spinner is stopped before each test
|
|
14
|
+
consoleLogSpy = spyOn(console, 'log').mockImplementation(() => {})
|
|
15
|
+
stdoutWriteSpy = spyOn(process.stdout, 'write').mockImplementation(() => true)
|
|
18
16
|
out.stop()
|
|
19
17
|
})
|
|
20
18
|
|
|
@@ -39,7 +37,6 @@ describe('Output Module', () => {
|
|
|
39
37
|
out.done(longMessage)
|
|
40
38
|
|
|
41
39
|
const output = consoleLogSpy.mock.calls[0][0]
|
|
42
|
-
// Should be truncated to ~65 chars + checkmark
|
|
43
40
|
expect(output.length).toBeLessThan(80)
|
|
44
41
|
})
|
|
45
42
|
|
|
@@ -90,20 +87,16 @@ describe('Output Module', () => {
|
|
|
90
87
|
})
|
|
91
88
|
|
|
92
89
|
describe('spin()', () => {
|
|
93
|
-
it('should start spinner with message', () => {
|
|
94
|
-
vi.useFakeTimers()
|
|
95
|
-
|
|
90
|
+
it('should start spinner with message', async () => {
|
|
96
91
|
out.spin('loading')
|
|
97
92
|
|
|
98
|
-
|
|
99
|
-
vi.advanceTimersByTime(100)
|
|
93
|
+
await new Promise(resolve => setTimeout(resolve, 150))
|
|
100
94
|
|
|
101
95
|
expect(stdoutWriteSpy).toHaveBeenCalled()
|
|
102
96
|
const output = stdoutWriteSpy.mock.calls[0][0]
|
|
103
97
|
expect(output).toContain('loading')
|
|
104
98
|
|
|
105
99
|
out.stop()
|
|
106
|
-
vi.useRealTimers()
|
|
107
100
|
})
|
|
108
101
|
|
|
109
102
|
it('should return self for chaining', () => {
|
|
@@ -114,19 +107,14 @@ describe('Output Module', () => {
|
|
|
114
107
|
})
|
|
115
108
|
|
|
116
109
|
describe('stop()', () => {
|
|
117
|
-
it('should stop spinner and clear line', () => {
|
|
118
|
-
vi.useFakeTimers()
|
|
119
|
-
|
|
110
|
+
it('should stop spinner and clear line', async () => {
|
|
120
111
|
out.spin('loading')
|
|
121
|
-
|
|
112
|
+
await new Promise(resolve => setTimeout(resolve, 150))
|
|
122
113
|
|
|
123
114
|
stdoutWriteSpy.mockClear()
|
|
124
115
|
out.stop()
|
|
125
116
|
|
|
126
|
-
// Should write clearing spaces
|
|
127
117
|
expect(stdoutWriteSpy).toHaveBeenCalled()
|
|
128
|
-
|
|
129
|
-
vi.useRealTimers()
|
|
130
118
|
})
|
|
131
119
|
|
|
132
120
|
it('should be safe to call multiple times', () => {
|
|
@@ -151,8 +139,8 @@ describe('Output Module', () => {
|
|
|
151
139
|
})
|
|
152
140
|
|
|
153
141
|
it('should handle null/undefined messages', () => {
|
|
154
|
-
expect(() => out.done(null)).not.toThrow()
|
|
155
|
-
expect(() => out.done(undefined)).not.toThrow()
|
|
142
|
+
expect(() => out.done(null as unknown as string)).not.toThrow()
|
|
143
|
+
expect(() => out.done(undefined as unknown as string)).not.toThrow()
|
|
156
144
|
})
|
|
157
145
|
|
|
158
146
|
it('should handle messages with special characters', () => {
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Router
|
|
3
|
+
* Orchestrates agent loading and context building for Claude delegation.
|
|
4
|
+
*
|
|
5
|
+
* @module agentic/agent-router
|
|
6
|
+
* @version 2.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'fs/promises'
|
|
10
|
+
import path from 'path'
|
|
11
|
+
import configManager from '../infrastructure/config-manager'
|
|
12
|
+
import pathManager from '../infrastructure/path-manager'
|
|
13
|
+
|
|
14
|
+
interface Agent {
|
|
15
|
+
name: string
|
|
16
|
+
content: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface AssignmentContext {
|
|
20
|
+
task: string
|
|
21
|
+
availableAgents: string[]
|
|
22
|
+
projectPath: string
|
|
23
|
+
projectId: string | null
|
|
24
|
+
_template: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Routes tasks to specialized agents based on Claude's decisions.
|
|
29
|
+
* Handles agent loading, context building, and usage logging.
|
|
30
|
+
*/
|
|
31
|
+
class AgentRouter {
|
|
32
|
+
projectId: string | null = null
|
|
33
|
+
agentsPath: string | null = null
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Initialize router with project context
|
|
37
|
+
*/
|
|
38
|
+
async initialize(projectPath: string): Promise<void> {
|
|
39
|
+
this.projectId = await configManager.getProjectId(projectPath)
|
|
40
|
+
this.agentsPath = pathManager.getPath(this.projectId!, 'agents')
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Load all available agents from project
|
|
45
|
+
*/
|
|
46
|
+
async loadAvailableAgents(): Promise<Agent[]> {
|
|
47
|
+
try {
|
|
48
|
+
const files = await fs.readdir(this.agentsPath!)
|
|
49
|
+
const agents: Agent[] = []
|
|
50
|
+
|
|
51
|
+
for (const file of files) {
|
|
52
|
+
if (file.endsWith('.md')) {
|
|
53
|
+
const name = file.replace('.md', '')
|
|
54
|
+
const content = await fs.readFile(path.join(this.agentsPath!, file), 'utf-8')
|
|
55
|
+
agents.push({ name, content })
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return agents
|
|
60
|
+
} catch {
|
|
61
|
+
return []
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get list of available agent names
|
|
67
|
+
*/
|
|
68
|
+
async getAgentNames(): Promise<string[]> {
|
|
69
|
+
const agents = await this.loadAvailableAgents()
|
|
70
|
+
return agents.map((a) => a.name)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Load a specific agent by name
|
|
75
|
+
*/
|
|
76
|
+
async loadAgent(name: string): Promise<Agent | null> {
|
|
77
|
+
try {
|
|
78
|
+
const filePath = path.join(this.agentsPath!, `${name}.md`)
|
|
79
|
+
const content = await fs.readFile(filePath, 'utf-8')
|
|
80
|
+
return { name, content }
|
|
81
|
+
} catch {
|
|
82
|
+
return null
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Build context for Claude to decide agent assignment
|
|
88
|
+
*/
|
|
89
|
+
async buildAssignmentContext(
|
|
90
|
+
task: string | { description?: string },
|
|
91
|
+
projectPath: string
|
|
92
|
+
): Promise<AssignmentContext> {
|
|
93
|
+
const agents = await this.getAgentNames()
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
task: typeof task === 'string' ? task : task.description || '',
|
|
97
|
+
availableAgents: agents,
|
|
98
|
+
projectPath,
|
|
99
|
+
projectId: this.projectId,
|
|
100
|
+
// Claude reads this and decides via template
|
|
101
|
+
_template: 'templates/agent-assignment.md',
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Log agent usage to JSONL file
|
|
107
|
+
*/
|
|
108
|
+
async logUsage(
|
|
109
|
+
task: string | { description?: string },
|
|
110
|
+
agent: string | { name?: string },
|
|
111
|
+
_projectPath: string
|
|
112
|
+
): Promise<void> {
|
|
113
|
+
try {
|
|
114
|
+
const logPath = path.join(
|
|
115
|
+
process.env.HOME || '',
|
|
116
|
+
'.prjct-cli',
|
|
117
|
+
'projects',
|
|
118
|
+
this.projectId || '',
|
|
119
|
+
'agent-usage.jsonl'
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
const entry =
|
|
123
|
+
JSON.stringify({
|
|
124
|
+
timestamp: new Date().toISOString(),
|
|
125
|
+
task: typeof task === 'string' ? task : task.description,
|
|
126
|
+
agent: typeof agent === 'string' ? agent : agent.name,
|
|
127
|
+
projectId: this.projectId,
|
|
128
|
+
}) + '\n'
|
|
129
|
+
|
|
130
|
+
await fs.appendFile(logPath, entry)
|
|
131
|
+
} catch {
|
|
132
|
+
// Silent fail for logging
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export default AgentRouter
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chain of Thought Reasoning
|
|
3
|
+
* Implements step-by-step reasoning for complex commands
|
|
4
|
+
*
|
|
5
|
+
* @module agentic/chain-of-thought
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
interface Context {
|
|
10
|
+
projectId?: string | null
|
|
11
|
+
projectPath: string
|
|
12
|
+
params: Record<string, unknown>
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
interface State {
|
|
16
|
+
now?: string | null
|
|
17
|
+
next?: string | null
|
|
18
|
+
shipped?: string | null
|
|
19
|
+
analysis?: string | null
|
|
20
|
+
[key: string]: unknown
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface ReasoningStep {
|
|
24
|
+
step: string
|
|
25
|
+
passed: boolean
|
|
26
|
+
details?: string
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ReasoningResult {
|
|
30
|
+
commandName: string
|
|
31
|
+
reasoning: {
|
|
32
|
+
steps: ReasoningStep[]
|
|
33
|
+
allPassed: boolean
|
|
34
|
+
criticalIssues: string[]
|
|
35
|
+
} | null
|
|
36
|
+
plan: string[]
|
|
37
|
+
confidence: number
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Commands that require chain of thought reasoning
|
|
42
|
+
*/
|
|
43
|
+
const REASONING_REQUIRED_COMMANDS = ['ship', 'feature', 'spec', 'cleanup', 'migrate']
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check if command requires reasoning
|
|
47
|
+
*/
|
|
48
|
+
function requiresReasoning(commandName: string): boolean {
|
|
49
|
+
return REASONING_REQUIRED_COMMANDS.includes(commandName)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Reason through a command before execution
|
|
54
|
+
*/
|
|
55
|
+
async function reason(commandName: string, context: Context, state: State): Promise<ReasoningResult> {
|
|
56
|
+
const steps: ReasoningStep[] = []
|
|
57
|
+
const plan: string[] = []
|
|
58
|
+
const criticalIssues: string[] = []
|
|
59
|
+
|
|
60
|
+
switch (commandName) {
|
|
61
|
+
case 'ship':
|
|
62
|
+
// Check prerequisites
|
|
63
|
+
if (state.now && !state.now.includes('No current task')) {
|
|
64
|
+
steps.push({ step: 'Has active task', passed: true })
|
|
65
|
+
} else {
|
|
66
|
+
steps.push({ step: 'Has active task', passed: false, details: 'No active task to ship' })
|
|
67
|
+
criticalIssues.push('No active task')
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Check if there's content to ship
|
|
71
|
+
if (state.shipped) {
|
|
72
|
+
steps.push({ step: 'Shipped log accessible', passed: true })
|
|
73
|
+
} else {
|
|
74
|
+
steps.push({ step: 'Shipped log accessible', passed: false, details: 'shipped.md not found' })
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Plan
|
|
78
|
+
plan.push('Read current task from now.md')
|
|
79
|
+
plan.push('Calculate duration')
|
|
80
|
+
plan.push('Append to shipped.md')
|
|
81
|
+
plan.push('Clear now.md')
|
|
82
|
+
plan.push('Update metrics')
|
|
83
|
+
break
|
|
84
|
+
|
|
85
|
+
case 'feature':
|
|
86
|
+
// Check if description provided
|
|
87
|
+
if (context.params.description || context.params.feature) {
|
|
88
|
+
steps.push({ step: 'Has feature description', passed: true })
|
|
89
|
+
} else {
|
|
90
|
+
steps.push({ step: 'Has feature description', passed: false, details: 'No description provided' })
|
|
91
|
+
criticalIssues.push('Missing feature description')
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Check roadmap accessibility
|
|
95
|
+
if (state.analysis) {
|
|
96
|
+
steps.push({ step: 'Project analyzed', passed: true })
|
|
97
|
+
} else {
|
|
98
|
+
steps.push({ step: 'Project analyzed', passed: false, details: 'Run /p:sync first' })
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Plan
|
|
102
|
+
plan.push('Parse feature description')
|
|
103
|
+
plan.push('Generate tasks breakdown')
|
|
104
|
+
plan.push('Add to roadmap.md')
|
|
105
|
+
plan.push('Add tasks to next.md')
|
|
106
|
+
plan.push('Suggest starting first task')
|
|
107
|
+
break
|
|
108
|
+
|
|
109
|
+
case 'spec':
|
|
110
|
+
// Check if feature name provided
|
|
111
|
+
if (context.params.feature || context.params.name) {
|
|
112
|
+
steps.push({ step: 'Has spec name', passed: true })
|
|
113
|
+
} else {
|
|
114
|
+
steps.push({ step: 'Has spec name', passed: false, details: 'No spec name provided' })
|
|
115
|
+
criticalIssues.push('Missing spec name')
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Plan
|
|
119
|
+
plan.push('Generate spec template')
|
|
120
|
+
plan.push('Analyze requirements')
|
|
121
|
+
plan.push('Create spec file')
|
|
122
|
+
plan.push('Link to roadmap')
|
|
123
|
+
break
|
|
124
|
+
|
|
125
|
+
case 'cleanup':
|
|
126
|
+
// Check for analysis
|
|
127
|
+
if (state.analysis) {
|
|
128
|
+
steps.push({ step: 'Has code analysis', passed: true })
|
|
129
|
+
} else {
|
|
130
|
+
steps.push({ step: 'Has code analysis', passed: false, details: 'Run /p:analyze first' })
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Plan
|
|
134
|
+
plan.push('Scan for unused code')
|
|
135
|
+
plan.push('Identify dead imports')
|
|
136
|
+
plan.push('List files to clean')
|
|
137
|
+
plan.push('Show preview')
|
|
138
|
+
plan.push('Wait for approval')
|
|
139
|
+
plan.push('Execute cleanup')
|
|
140
|
+
break
|
|
141
|
+
|
|
142
|
+
case 'migrate':
|
|
143
|
+
// Always warn for migrate
|
|
144
|
+
steps.push({
|
|
145
|
+
step: 'Migration safety check',
|
|
146
|
+
passed: true,
|
|
147
|
+
details: 'Will require manual approval',
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
// Plan
|
|
151
|
+
plan.push('Analyze current state')
|
|
152
|
+
plan.push('Generate migration plan')
|
|
153
|
+
plan.push('Show affected files')
|
|
154
|
+
plan.push('Request approval')
|
|
155
|
+
plan.push('Execute migration')
|
|
156
|
+
plan.push('Verify results')
|
|
157
|
+
break
|
|
158
|
+
|
|
159
|
+
default:
|
|
160
|
+
// Generic plan
|
|
161
|
+
plan.push('Execute command')
|
|
162
|
+
break
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Calculate confidence
|
|
166
|
+
const passedSteps = steps.filter((s) => s.passed).length
|
|
167
|
+
const totalSteps = steps.length
|
|
168
|
+
const confidence = totalSteps > 0 ? passedSteps / totalSteps : 1
|
|
169
|
+
|
|
170
|
+
return {
|
|
171
|
+
commandName,
|
|
172
|
+
reasoning:
|
|
173
|
+
steps.length > 0
|
|
174
|
+
? {
|
|
175
|
+
steps,
|
|
176
|
+
allPassed: criticalIssues.length === 0,
|
|
177
|
+
criticalIssues,
|
|
178
|
+
}
|
|
179
|
+
: null,
|
|
180
|
+
plan,
|
|
181
|
+
confidence,
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Format reasoning plan for display
|
|
187
|
+
*/
|
|
188
|
+
function formatPlan(result: ReasoningResult): string {
|
|
189
|
+
const lines: string[] = []
|
|
190
|
+
|
|
191
|
+
lines.push(`📋 Chain of Thought: ${result.commandName}`)
|
|
192
|
+
lines.push('')
|
|
193
|
+
|
|
194
|
+
if (result.reasoning) {
|
|
195
|
+
lines.push('Steps:')
|
|
196
|
+
result.reasoning.steps.forEach((step) => {
|
|
197
|
+
const icon = step.passed ? '✅' : '❌'
|
|
198
|
+
lines.push(` ${icon} ${step.step}`)
|
|
199
|
+
if (step.details) {
|
|
200
|
+
lines.push(` ${step.details}`)
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
lines.push('')
|
|
204
|
+
|
|
205
|
+
if (result.reasoning.criticalIssues.length > 0) {
|
|
206
|
+
lines.push('Critical Issues:')
|
|
207
|
+
result.reasoning.criticalIssues.forEach((issue) => {
|
|
208
|
+
lines.push(` ⚠️ ${issue}`)
|
|
209
|
+
})
|
|
210
|
+
lines.push('')
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (result.plan.length > 0) {
|
|
215
|
+
lines.push('Plan:')
|
|
216
|
+
result.plan.forEach((step, i) => {
|
|
217
|
+
lines.push(` ${i + 1}. ${step}`)
|
|
218
|
+
})
|
|
219
|
+
lines.push('')
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
lines.push(`Confidence: ${Math.round(result.confidence * 100)}%`)
|
|
223
|
+
|
|
224
|
+
return lines.join('\n')
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export { requiresReasoning, reason, formatPlan, REASONING_REQUIRED_COMMANDS }
|
|
228
|
+
export default { requiresReasoning, reason, formatPlan }
|