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
|
@@ -1,352 +0,0 @@
|
|
|
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
|
-
* @module agentic/prompt-builder
|
|
7
|
-
* @version 4.1
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
const fs = require('fs')
|
|
11
|
-
const path = require('path')
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Builds prompts for Claude using templates, context, and learned patterns.
|
|
15
|
-
* Supports plan mode, think blocks, and quality checklists.
|
|
16
|
-
*/
|
|
17
|
-
class PromptBuilder {
|
|
18
|
-
constructor() {
|
|
19
|
-
/** @type {Object<string, string>|null} */
|
|
20
|
-
this._checklistsCache = null
|
|
21
|
-
/** @type {string|null} */
|
|
22
|
-
this._checklistRoutingCache = null
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Load quality checklists from templates/checklists/
|
|
27
|
-
*
|
|
28
|
-
* @returns {Object<string, string>} Map of checklist name to content
|
|
29
|
-
*/
|
|
30
|
-
loadChecklists() {
|
|
31
|
-
if (this._checklistsCache) return this._checklistsCache
|
|
32
|
-
|
|
33
|
-
const checklistsDir = path.join(__dirname, '..', '..', 'templates', 'checklists')
|
|
34
|
-
const checklists = {}
|
|
35
|
-
|
|
36
|
-
try {
|
|
37
|
-
if (fs.existsSync(checklistsDir)) {
|
|
38
|
-
const files = fs.readdirSync(checklistsDir).filter(f => f.endsWith('.md'))
|
|
39
|
-
for (const file of files) {
|
|
40
|
-
const name = file.replace('.md', '')
|
|
41
|
-
const content = fs.readFileSync(path.join(checklistsDir, file), 'utf-8')
|
|
42
|
-
checklists[name] = content
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
} catch (err) {
|
|
46
|
-
// Silent fail - checklists are optional enhancement
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
this._checklistsCache = checklists
|
|
50
|
-
return checklists
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Load checklist routing template for Claude to decide which checklists apply
|
|
55
|
-
*
|
|
56
|
-
* @returns {string|null} Routing template content or null if not found
|
|
57
|
-
*/
|
|
58
|
-
loadChecklistRouting() {
|
|
59
|
-
if (this._checklistRoutingCache) return this._checklistRoutingCache
|
|
60
|
-
|
|
61
|
-
const routingPath = path.join(__dirname, '..', '..', 'templates', 'agentic', 'checklist-routing.md')
|
|
62
|
-
|
|
63
|
-
try {
|
|
64
|
-
if (fs.existsSync(routingPath)) {
|
|
65
|
-
this._checklistRoutingCache = fs.readFileSync(routingPath, 'utf-8')
|
|
66
|
-
}
|
|
67
|
-
} catch (err) {
|
|
68
|
-
// Silent fail
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return this._checklistRoutingCache || null
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Build a complete prompt for Claude from template, context, and enhancements
|
|
75
|
-
*
|
|
76
|
-
* @param {Object} template - Template with frontmatter and content
|
|
77
|
-
* @param {Object} context - Project context (projectPath, projectId, files, params)
|
|
78
|
-
* @param {Object} state - Current prjct state (now, next, analysis, etc.)
|
|
79
|
-
* @param {Object|null} [agent] - Specialized agent config (name, role, skills)
|
|
80
|
-
* @param {Object|null} [learnedPatterns] - User preferences from memory system
|
|
81
|
-
* @param {Object|null} [thinkBlock] - Reasoning block (plan, conclusions, confidence)
|
|
82
|
-
* @param {Array|null} [relevantMemories] - Past decisions from semantic database
|
|
83
|
-
* @param {Object|null} [planInfo] - Plan mode status (isPlanning, requiresApproval)
|
|
84
|
-
* @returns {string} Complete prompt ready for Claude
|
|
85
|
-
*/
|
|
86
|
-
build(template, context, state, agent = null, learnedPatterns = null, thinkBlock = null, relevantMemories = null, planInfo = null) {
|
|
87
|
-
const parts = []
|
|
88
|
-
|
|
89
|
-
// Store context for use in helper methods
|
|
90
|
-
this._currentContext = context
|
|
91
|
-
|
|
92
|
-
// Agent assignment (CONDITIONAL - only for code-modifying commands)
|
|
93
|
-
// Commands like done, ship, recap, next don't need specialized agents
|
|
94
|
-
const commandName = template.frontmatter?.name?.replace('p:', '') || ''
|
|
95
|
-
const agentCommands = ['now', 'build', 'feature', 'design', 'fix', 'bug', 'test', 'work', 'cleanup', 'spec']
|
|
96
|
-
const needsAgent = agentCommands.includes(commandName)
|
|
97
|
-
|
|
98
|
-
if (agent && needsAgent) {
|
|
99
|
-
// COMPRESSED: Only essential agent info (500 bytes vs 3-5KB)
|
|
100
|
-
parts.push(`# AGENT: ${agent.name}\n`)
|
|
101
|
-
if (agent.role) parts.push(`Role: ${agent.role}\n`)
|
|
102
|
-
if (agent.skills?.length) parts.push(`Skills: ${agent.skills.join(', ')}\n`)
|
|
103
|
-
parts.push(`\nApply specialized expertise. Read agent file for details if needed.\n\n`)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Core instruction (concise)
|
|
107
|
-
parts.push(`TASK: ${template.frontmatter.description}\n`)
|
|
108
|
-
|
|
109
|
-
// Tools (inline)
|
|
110
|
-
if (template.frontmatter['allowed-tools']) {
|
|
111
|
-
parts.push(`TOOLS: ${template.frontmatter['allowed-tools'].join(', ')}\n`)
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Critical parameters only
|
|
115
|
-
if (context.params?.task || context.params?.description) {
|
|
116
|
-
parts.push(`INPUT: ${context.params.task || context.params.description}\n`)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
parts.push('\n---\n')
|
|
120
|
-
|
|
121
|
-
// Template (only the flow section, skip verbose explanations)
|
|
122
|
-
const flowMatch = template.content.match(/## Flow([\s\S]*?)(?=##|$)/)
|
|
123
|
-
if (flowMatch) {
|
|
124
|
-
parts.push(flowMatch[0])
|
|
125
|
-
} else {
|
|
126
|
-
// Fallback to full template if no flow section
|
|
127
|
-
parts.push(template.content)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Current state (only if exists and relevant)
|
|
131
|
-
const relevantState = this.filterRelevantState(state)
|
|
132
|
-
if (relevantState) {
|
|
133
|
-
parts.push('\n## PRJCT STATE (Project Management Data)\n')
|
|
134
|
-
parts.push(relevantState)
|
|
135
|
-
parts.push('\n')
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// COMPRESSED: File list (5 files vs 20, saves ~400 bytes)
|
|
139
|
-
if (context.files?.length > 0) {
|
|
140
|
-
const top5 = context.files.slice(0, 5).join(', ')
|
|
141
|
-
parts.push(`\n## FILES: ${context.files.length} available. Top: ${top5}\n`)
|
|
142
|
-
parts.push('Read BEFORE modifying. Use Glob/Grep to find more.\n\n')
|
|
143
|
-
} else if (context.projectPath) {
|
|
144
|
-
parts.push(`\n## PROJECT: ${context.projectPath}\nRead files before modifying.\n\n`)
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// OPTIMIZED: Only include patterns for code-modifying commands
|
|
148
|
-
// Commands like done, ship, recap, next don't need full patterns
|
|
149
|
-
const codeCommands = ['now', 'build', 'feature', 'design', 'cleanup', 'fix', 'bug', 'test', 'init', 'spec', 'work']
|
|
150
|
-
const needsPatterns = codeCommands.includes(commandName)
|
|
151
|
-
|
|
152
|
-
// Include code patterns analysis for code-modifying commands
|
|
153
|
-
// COMPRESSED: Extract only conventions and anti-patterns (800 bytes max vs 6KB)
|
|
154
|
-
const codePatternsContent = state?.codePatterns || ''
|
|
155
|
-
if (needsPatterns && codePatternsContent && codePatternsContent.trim()) {
|
|
156
|
-
const patternSummary = this.extractPatternSummary(codePatternsContent)
|
|
157
|
-
if (patternSummary) {
|
|
158
|
-
parts.push('\n## CODE PATTERNS\n')
|
|
159
|
-
parts.push(patternSummary)
|
|
160
|
-
parts.push('\nFull patterns: Read analysis/patterns.md\n')
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const analysisContent = state?.analysis || ''
|
|
165
|
-
if (needsPatterns && analysisContent && analysisContent.trim()) {
|
|
166
|
-
// Extract stack info compactly
|
|
167
|
-
const stackMatch = analysisContent.match(/Stack[:\s]+([^\n]+)/i) ||
|
|
168
|
-
analysisContent.match(/Technology[:\s]+([^\n]+)/i)
|
|
169
|
-
const stack = stackMatch ? stackMatch[1].trim() : 'detected'
|
|
170
|
-
|
|
171
|
-
parts.push(`\n## STACK\nStack: ${stack}\n`)
|
|
172
|
-
if (!codePatternsContent) {
|
|
173
|
-
parts.push('Read analysis/repo-summary.md + similar files before coding. Match patterns exactly.\n')
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// CRITICAL: Compressed rules (replaces 78 lines with 12)
|
|
178
|
-
parts.push(this.buildCriticalRules());
|
|
179
|
-
|
|
180
|
-
// P1.1: Learned Patterns (avoid asking user questions we already know)
|
|
181
|
-
if (learnedPatterns && Object.keys(learnedPatterns).some(k => learnedPatterns[k])) {
|
|
182
|
-
parts.push('\n## LEARNED PATTERNS (use these, do NOT ask user)\n')
|
|
183
|
-
for (const [key, value] of Object.entries(learnedPatterns)) {
|
|
184
|
-
if (value) {
|
|
185
|
-
parts.push(`- ${key}: ${value}\n`)
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// P3.1: Think Block (reasoning before action)
|
|
191
|
-
if (thinkBlock && thinkBlock.plan && thinkBlock.plan.length > 0) {
|
|
192
|
-
parts.push('\n## THINK FIRST (reasoning from analysis)\n')
|
|
193
|
-
if (thinkBlock.conclusions && thinkBlock.conclusions.length > 0) {
|
|
194
|
-
parts.push('Conclusions:\n')
|
|
195
|
-
thinkBlock.conclusions.forEach(c => parts.push(` → ${c}\n`))
|
|
196
|
-
}
|
|
197
|
-
parts.push('Plan:\n')
|
|
198
|
-
thinkBlock.plan.forEach((p, i) => parts.push(` ${i + 1}. ${p}\n`))
|
|
199
|
-
parts.push(`Confidence: ${Math.round((thinkBlock.confidence || 0.5) * 100)}%\n`)
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// P3.3: Relevant Memories (context from past decisions)
|
|
203
|
-
if (relevantMemories && relevantMemories.length > 0) {
|
|
204
|
-
parts.push('\n## RELEVANT MEMORIES (apply these learnings)\n')
|
|
205
|
-
for (const memory of relevantMemories) {
|
|
206
|
-
parts.push(`- **${memory.title}**: ${memory.content}\n`)
|
|
207
|
-
if (memory.tags && memory.tags.length > 0) {
|
|
208
|
-
parts.push(` Tags: ${memory.tags.join(', ')}\n`)
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// P3.4: Plan Mode (OPTIMIZED: 30 lines → 5 lines)
|
|
214
|
-
if (planInfo?.isPlanning) {
|
|
215
|
-
parts.push(`\n## PLAN MODE\nRead-only. Gather info → Analyze → Propose plan → Wait for approval.\n`)
|
|
216
|
-
if (planInfo.allowedTools) parts.push(`Tools: ${planInfo.allowedTools.join(', ')}\n`)
|
|
217
|
-
}
|
|
218
|
-
if (planInfo?.requiresApproval) {
|
|
219
|
-
parts.push(`\n## APPROVAL REQUIRED\nShow changes, list affected files, ask for confirmation.\n`)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// P4.1: Quality Checklists (Claude decides which to apply)
|
|
223
|
-
// Only for code-modifying commands that benefit from quality gates
|
|
224
|
-
const checklistCommands = ['now', 'build', 'feature', 'design', 'fix', 'bug', 'cleanup', 'spec', 'work']
|
|
225
|
-
if (checklistCommands.includes(commandName)) {
|
|
226
|
-
const routing = this.loadChecklistRouting()
|
|
227
|
-
const checklists = this.loadChecklists()
|
|
228
|
-
|
|
229
|
-
if (routing && Object.keys(checklists).length > 0) {
|
|
230
|
-
parts.push('\n## QUALITY CHECKLISTS\n')
|
|
231
|
-
parts.push('Apply relevant checklists based on task. Read checklist-routing.md for guidance.\n')
|
|
232
|
-
parts.push(`Available: ${Object.keys(checklists).join(', ')}\n`)
|
|
233
|
-
parts.push('Path: templates/checklists/{name}.md\n')
|
|
234
|
-
parts.push('Use Read tool to load checklists you determine are relevant.\n')
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Simple execution directive
|
|
239
|
-
parts.push('\nEXECUTE: Follow flow. Use tools. Decide.\n')
|
|
240
|
-
|
|
241
|
-
return parts.join('')
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/**
|
|
245
|
-
* Filter state data to include only relevant portions for the prompt
|
|
246
|
-
*
|
|
247
|
-
* @param {Object} state - Full prjct state object
|
|
248
|
-
* @returns {string|null} Formatted relevant state or null if empty
|
|
249
|
-
*/
|
|
250
|
-
filterRelevantState(state) {
|
|
251
|
-
if (!state || Object.keys(state).length === 0) return null
|
|
252
|
-
|
|
253
|
-
const relevant = []
|
|
254
|
-
for (const [key, content] of Object.entries(state)) {
|
|
255
|
-
if (content && content.trim()) {
|
|
256
|
-
// Include full content for critical files (now, next, context, patterns)
|
|
257
|
-
const criticalFiles = ['now', 'next', 'context', 'analysis', 'codePatterns']
|
|
258
|
-
if (criticalFiles.includes(key)) {
|
|
259
|
-
// Include full content for critical files (up to 2000 chars)
|
|
260
|
-
const display = content.length > 2000
|
|
261
|
-
? content.substring(0, 2000) + '\n... (truncated)'
|
|
262
|
-
: content
|
|
263
|
-
relevant.push(`### ${key}\n${display}`)
|
|
264
|
-
} else if (content.length < 1000) {
|
|
265
|
-
// Include full content for small files
|
|
266
|
-
relevant.push(`### ${key}\n${content}`)
|
|
267
|
-
} else {
|
|
268
|
-
// Truncate large files but show more context
|
|
269
|
-
relevant.push(`### ${key}\n${content.substring(0, 500)}... (truncated, use Read tool for full content)`)
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return relevant.length > 0 ? relevant.join('\n\n') : null
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Build an analysis prompt for pre-action investigation tasks
|
|
279
|
-
*
|
|
280
|
-
* @param {string} analysisType - Type of analysis (e.g., 'patterns', 'stack')
|
|
281
|
-
* @param {Object} context - Project context with projectPath and projectId
|
|
282
|
-
* @returns {string} Analysis prompt
|
|
283
|
-
*/
|
|
284
|
-
buildAnalysis(analysisType, context) {
|
|
285
|
-
const parts = []
|
|
286
|
-
|
|
287
|
-
parts.push(`# Analyze: ${analysisType}\n\n`)
|
|
288
|
-
parts.push('Read the project context and provide your analysis.\n')
|
|
289
|
-
parts.push('No predetermined patterns - decide based on what you find.\n\n')
|
|
290
|
-
|
|
291
|
-
parts.push('## Project Context\n')
|
|
292
|
-
parts.push(`- Path: ${context.projectPath}\n`)
|
|
293
|
-
parts.push(`- ID: ${context.projectId}\n\n`)
|
|
294
|
-
|
|
295
|
-
return parts.join('')
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
/**
|
|
299
|
-
* Extract compressed pattern summary (conventions + high-priority anti-patterns)
|
|
300
|
-
*
|
|
301
|
-
* @param {string} content - Full patterns file content
|
|
302
|
-
* @returns {string|null} Compressed summary (max 800 bytes) or null
|
|
303
|
-
*/
|
|
304
|
-
extractPatternSummary(content) {
|
|
305
|
-
if (!content) return null
|
|
306
|
-
|
|
307
|
-
const parts = []
|
|
308
|
-
|
|
309
|
-
// Extract conventions section
|
|
310
|
-
const conventionsMatch = content.match(/## Conventions[\s\S]*?(?=##|$)/i)
|
|
311
|
-
if (conventionsMatch) {
|
|
312
|
-
// Compress to key lines only
|
|
313
|
-
const conventions = conventionsMatch[0]
|
|
314
|
-
.split('\n')
|
|
315
|
-
.filter(line => line.includes(':') || line.startsWith('-'))
|
|
316
|
-
.slice(0, 6)
|
|
317
|
-
.join('\n')
|
|
318
|
-
if (conventions) parts.push(conventions)
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Extract high priority anti-patterns only
|
|
322
|
-
const antiPatternsMatch = content.match(/### High Priority[\s\S]*?(?=###|##|$)/i)
|
|
323
|
-
if (antiPatternsMatch) {
|
|
324
|
-
const antiPatterns = antiPatternsMatch[0].substring(0, 300)
|
|
325
|
-
parts.push('\nAvoid:\n' + antiPatterns)
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
const result = parts.join('\n').substring(0, 800)
|
|
329
|
-
return result || null
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Build critical anti-hallucination rules section
|
|
334
|
-
*
|
|
335
|
-
* @returns {string} Formatted rules block
|
|
336
|
-
*/
|
|
337
|
-
buildCriticalRules() {
|
|
338
|
-
const fileCount = this._currentContext?.files?.length || this._currentContext?.filteredSize || 0
|
|
339
|
-
return `
|
|
340
|
-
## RULES (CRITICAL)
|
|
341
|
-
1. **READ FIRST**: Use Read tool BEFORE modifying any file. Never assume code structure.
|
|
342
|
-
2. **MATCH PATTERNS**: Follow existing style, architecture, naming, imports exactly.
|
|
343
|
-
3. **NO HALLUCINATIONS**: Don't invent files, functions, or paths. If unsure, READ first.
|
|
344
|
-
4. **GIT SAFETY**: Never use checkout/reset --hard/clean. Always check status first.
|
|
345
|
-
5. **VERIFY**: After writing, confirm code matches project patterns.
|
|
346
|
-
Context: ${fileCount} files available. Read what you need.
|
|
347
|
-
`;
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
module.exports = new PromptBuilder()
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Response Templates
|
|
3
|
-
* Minimal output templates for all commands
|
|
4
|
-
* Rule: < 4 lines, always actionable
|
|
5
|
-
*
|
|
6
|
-
* OPTIMIZATION (P0.3): Minimal Output
|
|
7
|
-
* - Concise responses (< 4 lines)
|
|
8
|
-
* - Always suggest next action
|
|
9
|
-
* - Use symbols for status, not words
|
|
10
|
-
*
|
|
11
|
-
* Source: Claude Code, Kiro patterns
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Format duration from milliseconds or ISO strings
|
|
16
|
-
* @param {number|string|Date} start - Start time
|
|
17
|
-
* @param {number|string|Date} end - End time (defaults to now)
|
|
18
|
-
* @returns {string} Human-readable duration
|
|
19
|
-
*/
|
|
20
|
-
function formatDuration(start, end = new Date()) {
|
|
21
|
-
const startMs = new Date(start).getTime()
|
|
22
|
-
const endMs = new Date(end).getTime()
|
|
23
|
-
const diffMs = endMs - startMs
|
|
24
|
-
|
|
25
|
-
const hours = Math.floor(diffMs / (1000 * 60 * 60))
|
|
26
|
-
const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60))
|
|
27
|
-
|
|
28
|
-
if (hours > 0) {
|
|
29
|
-
return `${hours}h ${minutes}m`
|
|
30
|
-
}
|
|
31
|
-
return `${minutes}m`
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Truncate text to max length with ellipsis
|
|
36
|
-
* @param {string} text - Text to truncate
|
|
37
|
-
* @param {number} maxLength - Maximum length
|
|
38
|
-
* @returns {string}
|
|
39
|
-
*/
|
|
40
|
-
function truncate(text, maxLength = 40) {
|
|
41
|
-
if (!text) return ''
|
|
42
|
-
if (text.length <= maxLength) return text
|
|
43
|
-
return text.substring(0, maxLength - 3) + '...'
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Response templates for each command
|
|
48
|
-
* Each template is a function that returns minimal formatted output
|
|
49
|
-
*/
|
|
50
|
-
const templates = {
|
|
51
|
-
/**
|
|
52
|
-
* /p:done - Task completed
|
|
53
|
-
*/
|
|
54
|
-
done: ({ task, duration, nextTask }) => {
|
|
55
|
-
let output = `✓ '${truncate(task)}' (${duration})`
|
|
56
|
-
if (nextTask) {
|
|
57
|
-
output += `\n→ Next: '${truncate(nextTask)}'`
|
|
58
|
-
}
|
|
59
|
-
output += '\n\n/p:ship to release'
|
|
60
|
-
return output
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* /p:now - Current task set/shown
|
|
65
|
-
*/
|
|
66
|
-
now: ({ task, started, isNew }) => {
|
|
67
|
-
if (!task) {
|
|
68
|
-
return `No active task\n→ /p:now "task" to start`
|
|
69
|
-
}
|
|
70
|
-
if (isNew) {
|
|
71
|
-
return `🎯 Started: '${truncate(task)}'\n→ /p:done when complete`
|
|
72
|
-
}
|
|
73
|
-
return `🎯 Working on: '${truncate(task)}'\n⏱️ ${started || 'just now'}\n→ /p:done when complete`
|
|
74
|
-
},
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* /p:next - Priority queue
|
|
78
|
-
*/
|
|
79
|
-
next: ({ tasks, total }) => {
|
|
80
|
-
if (!tasks || tasks.length === 0) {
|
|
81
|
-
return `Queue empty\n→ /p:feature or /p:idea to add`
|
|
82
|
-
}
|
|
83
|
-
const top3 = tasks.slice(0, 3).map((t, i) =>
|
|
84
|
-
`${i + 1}. ${truncate(t.name, 35)}`
|
|
85
|
-
).join('\n')
|
|
86
|
-
const more = total > 3 ? `\n+${total - 3} more` : ''
|
|
87
|
-
return `${top3}${more}\n\n/p:now 1 to start`
|
|
88
|
-
},
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* /p:ship - Feature shipped
|
|
92
|
-
*/
|
|
93
|
-
ship: ({ feature, agent, duration, version }) => {
|
|
94
|
-
let output = `🚀 Shipped: '${truncate(feature)}'`
|
|
95
|
-
if (agent) output += ` (${agent})`
|
|
96
|
-
if (duration) output += ` | ${duration}`
|
|
97
|
-
if (version) output += ` | v${version}`
|
|
98
|
-
output += '\n→ /compact recommended'
|
|
99
|
-
return output
|
|
100
|
-
},
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* /p:idea - Idea captured
|
|
104
|
-
*/
|
|
105
|
-
idea: ({ idea, addedToQueue }) => {
|
|
106
|
-
let output = `💡 Captured: '${truncate(idea)}'`
|
|
107
|
-
if (addedToQueue) {
|
|
108
|
-
output += '\n→ Added to queue'
|
|
109
|
-
}
|
|
110
|
-
output += '\n\n/p:next to see queue'
|
|
111
|
-
return output
|
|
112
|
-
},
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* /p:feature - Feature added
|
|
116
|
-
*/
|
|
117
|
-
feature: ({ feature, tasks, impact, effort }) => {
|
|
118
|
-
let output = `📋 Feature: '${truncate(feature)}'`
|
|
119
|
-
if (tasks) output += ` (${tasks} tasks)`
|
|
120
|
-
if (impact) output += `\nImpact: ${impact}`
|
|
121
|
-
if (effort) output += ` | Effort: ${effort}`
|
|
122
|
-
output += '\n\n/p:now to start'
|
|
123
|
-
return output
|
|
124
|
-
},
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* /p:bug - Bug reported
|
|
128
|
-
*/
|
|
129
|
-
bug: ({ description, priority, addedAt }) => {
|
|
130
|
-
const priorityIcon = {
|
|
131
|
-
'critical': '🔴',
|
|
132
|
-
'high': '🟠',
|
|
133
|
-
'medium': '🟡',
|
|
134
|
-
'low': '🟢'
|
|
135
|
-
}[priority] || '🟡'
|
|
136
|
-
|
|
137
|
-
let output = `${priorityIcon} Bug: '${truncate(description)}'\nPriority: ${priority}`
|
|
138
|
-
if (addedAt) {
|
|
139
|
-
output += ` | Added: ${addedAt}`
|
|
140
|
-
}
|
|
141
|
-
output += '\n\n/p:now to fix'
|
|
142
|
-
return output
|
|
143
|
-
},
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* /p:pause - Task paused
|
|
147
|
-
*/
|
|
148
|
-
pause: ({ task, duration }) => {
|
|
149
|
-
return `⏸️ Paused: '${truncate(task)}' (${duration})\n→ /p:resume to continue`
|
|
150
|
-
},
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* /p:resume - Task resumed
|
|
154
|
-
*/
|
|
155
|
-
resume: ({ task, pausedFor }) => {
|
|
156
|
-
return `▶️ Resumed: '${truncate(task)}'\nPaused for: ${pausedFor}\n→ /p:done when complete`
|
|
157
|
-
},
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* /p:recap - Project overview
|
|
161
|
-
*/
|
|
162
|
-
recap: ({ shipped, inProgress, queued, momentum }) => {
|
|
163
|
-
const momentumIcon = {
|
|
164
|
-
'high': '🔥',
|
|
165
|
-
'medium': '✨',
|
|
166
|
-
'low': '💤'
|
|
167
|
-
}[momentum] || '✨'
|
|
168
|
-
|
|
169
|
-
return `${momentumIcon} ${shipped} shipped | ${inProgress ? '1 active' : '0 active'} | ${queued} queued`
|
|
170
|
-
},
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* /p:progress - Progress metrics
|
|
174
|
-
*/
|
|
175
|
-
progress: ({ period, shipped, velocity, trend }) => {
|
|
176
|
-
const trendIcon = trend > 0 ? '↑' : trend < 0 ? '↓' : '→'
|
|
177
|
-
return `📊 ${period}: ${shipped} shipped\nVelocity: ${velocity}/week ${trendIcon}`
|
|
178
|
-
},
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* /p:analyze - Analysis complete
|
|
182
|
-
*/
|
|
183
|
-
analyze: ({ stack, files, agents }) => {
|
|
184
|
-
return `🔍 Analyzed: ${stack}\n${files} files | ${agents} agents generated\n\n/p:sync to update`
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
/**
|
|
188
|
-
* /p:sync - Sync complete
|
|
189
|
-
*/
|
|
190
|
-
sync: ({ updated, agents }) => {
|
|
191
|
-
return `🔄 Synced: ${updated} files updated\n${agents} agents refreshed`
|
|
192
|
-
},
|
|
193
|
-
|
|
194
|
-
/**
|
|
195
|
-
* /p:help - Help shown
|
|
196
|
-
*/
|
|
197
|
-
help: ({ context, suggestions }) => {
|
|
198
|
-
const sugs = suggestions.slice(0, 3).map(s => `• ${s}`).join('\n')
|
|
199
|
-
return `📚 ${context}\n\n${sugs}`
|
|
200
|
-
},
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* /p:suggest - Suggestions
|
|
204
|
-
*/
|
|
205
|
-
suggest: ({ urgency, suggestion, command }) => {
|
|
206
|
-
const urgencyIcon = {
|
|
207
|
-
'high': '🔥',
|
|
208
|
-
'medium': '💡',
|
|
209
|
-
'low': '✨'
|
|
210
|
-
}[urgency] || '💡'
|
|
211
|
-
|
|
212
|
-
return `${urgencyIcon} ${suggestion}\n→ ${command}`
|
|
213
|
-
},
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* /p:spec - Spec created/updated
|
|
217
|
-
*/
|
|
218
|
-
spec: ({ name, status, tasks, requirements, isNew }) => {
|
|
219
|
-
let output = isNew
|
|
220
|
-
? `📋 Created spec: '${truncate(name)}'`
|
|
221
|
-
: `📋 Updated spec: '${truncate(name)}'`
|
|
222
|
-
|
|
223
|
-
if (requirements) output += `\n${requirements} requirements`
|
|
224
|
-
if (tasks) output += ` | ${tasks} tasks`
|
|
225
|
-
if (status) output += ` | Status: ${status}`
|
|
226
|
-
|
|
227
|
-
output += '\n\n→ Review and approve to start'
|
|
228
|
-
return output
|
|
229
|
-
},
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Generic success response
|
|
233
|
-
*/
|
|
234
|
-
success: ({ message, nextAction }) => {
|
|
235
|
-
let output = `✓ ${message}`
|
|
236
|
-
if (nextAction) {
|
|
237
|
-
output += `\n→ ${nextAction}`
|
|
238
|
-
}
|
|
239
|
-
return output
|
|
240
|
-
},
|
|
241
|
-
|
|
242
|
-
/**
|
|
243
|
-
* Generic error response
|
|
244
|
-
*/
|
|
245
|
-
error: ({ error, suggestion }) => {
|
|
246
|
-
let output = `❌ ${error}`
|
|
247
|
-
if (suggestion) {
|
|
248
|
-
output += `\n→ ${suggestion}`
|
|
249
|
-
}
|
|
250
|
-
return output
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Format a response using the appropriate template
|
|
256
|
-
*
|
|
257
|
-
* @param {string} commandName - Command name
|
|
258
|
-
* @param {Object} data - Data for the template
|
|
259
|
-
* @returns {string} Formatted response
|
|
260
|
-
*/
|
|
261
|
-
function format(commandName, data) {
|
|
262
|
-
const template = templates[commandName]
|
|
263
|
-
if (!template) {
|
|
264
|
-
// Fallback to generic success/error
|
|
265
|
-
if (data.error) {
|
|
266
|
-
return templates.error(data)
|
|
267
|
-
}
|
|
268
|
-
return templates.success(data)
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return template(data)
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/**
|
|
275
|
-
* Check if response exceeds recommended length
|
|
276
|
-
* @param {string} response - Response text
|
|
277
|
-
* @returns {boolean} True if too long
|
|
278
|
-
*/
|
|
279
|
-
function isTooLong(response) {
|
|
280
|
-
const lines = response.split('\n').filter(l => l.trim())
|
|
281
|
-
return lines.length > 4
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
module.exports = {
|
|
285
|
-
format,
|
|
286
|
-
templates,
|
|
287
|
-
formatDuration,
|
|
288
|
-
truncate,
|
|
289
|
-
isTooLong
|
|
290
|
-
}
|