prjct-cli 0.11.5 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +81 -25
- package/bin/dev.js +1 -1
- package/bin/generate-views.js +209 -0
- package/bin/migrate-to-json.js +742 -0
- package/bin/prjct +5 -5
- package/bin/serve.js +226 -50
- package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
- package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
- package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
- package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
- package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
- package/core/agentic/agent-router.ts +137 -0
- package/core/agentic/chain-of-thought.ts +228 -0
- package/core/agentic/command-executor/command-executor.ts +384 -0
- package/core/agentic/command-executor/index.ts +16 -0
- package/core/agentic/command-executor/status-signal.ts +38 -0
- package/core/agentic/command-executor/types.ts +79 -0
- package/core/agentic/command-executor.ts +8 -0
- package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
- package/core/agentic/context-filter.ts +365 -0
- package/core/agentic/ground-truth/index.ts +76 -0
- package/core/agentic/ground-truth/types.ts +33 -0
- package/core/agentic/ground-truth/utils.ts +48 -0
- package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
- package/core/agentic/ground-truth/verifiers/done.ts +75 -0
- package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
- package/core/agentic/ground-truth/verifiers/index.ts +37 -0
- package/core/agentic/ground-truth/verifiers/init.ts +52 -0
- package/core/agentic/ground-truth/verifiers/now.ts +57 -0
- package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
- package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
- package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
- package/core/agentic/ground-truth/verifiers.ts +6 -0
- package/core/agentic/ground-truth.ts +8 -0
- package/core/agentic/loop-detector/error-analysis.ts +97 -0
- package/core/agentic/loop-detector/hallucination.ts +71 -0
- package/core/agentic/loop-detector/index.ts +41 -0
- package/core/agentic/loop-detector/loop-detector.ts +222 -0
- package/core/agentic/loop-detector/types.ts +66 -0
- package/core/agentic/loop-detector.ts +8 -0
- package/core/agentic/memory-system/history.ts +53 -0
- package/core/agentic/memory-system/index.ts +192 -0
- package/core/agentic/memory-system/patterns.ts +156 -0
- package/core/agentic/memory-system/semantic-memories.ts +277 -0
- package/core/agentic/memory-system/session.ts +21 -0
- package/core/agentic/memory-system/types.ts +159 -0
- package/core/agentic/memory-system.ts +8 -0
- package/core/agentic/parallel-tools.ts +165 -0
- package/core/agentic/plan-mode/approval.ts +57 -0
- package/core/agentic/plan-mode/constants.ts +44 -0
- package/core/agentic/plan-mode/index.ts +28 -0
- package/core/agentic/plan-mode/plan-mode.ts +406 -0
- package/core/agentic/plan-mode/types.ts +193 -0
- package/core/agentic/plan-mode.ts +8 -0
- package/core/agentic/prompt-builder.ts +566 -0
- package/core/agentic/response-templates.ts +164 -0
- package/core/agentic/semantic-compression.ts +273 -0
- package/core/agentic/services.ts +206 -0
- package/core/agentic/smart-context.ts +476 -0
- package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
- package/core/agentic/think-blocks.ts +202 -0
- package/core/agentic/tool-registry.ts +119 -0
- package/core/agentic/validation-rules.ts +313 -0
- package/core/agents/index.ts +28 -0
- package/core/agents/performance.ts +444 -0
- package/core/agents/types.ts +126 -0
- package/core/bus/{index.js → index.ts} +57 -61
- package/core/command-registry/categories.ts +23 -0
- package/core/command-registry/commands.ts +15 -0
- package/core/command-registry/core-commands.ts +319 -0
- package/core/command-registry/index.ts +158 -0
- package/core/command-registry/optional-commands.ts +119 -0
- package/core/command-registry/setup-commands.ts +53 -0
- package/core/command-registry/types.ts +59 -0
- package/core/command-registry.ts +9 -0
- package/core/commands/analysis.ts +298 -0
- package/core/commands/analytics.ts +288 -0
- package/core/commands/base.ts +273 -0
- package/core/commands/index.ts +211 -0
- package/core/commands/maintenance.ts +226 -0
- package/core/commands/planning.ts +311 -0
- package/core/commands/setup.ts +309 -0
- package/core/commands/shipping.ts +188 -0
- package/core/commands/types.ts +183 -0
- package/core/commands/workflow.ts +226 -0
- package/core/commands.ts +11 -0
- package/core/constants/formats.ts +187 -0
- package/core/constants/index.ts +7 -0
- package/core/{context-sync.js → context-sync.ts} +59 -26
- package/core/data/agents-manager.ts +76 -0
- package/core/data/analysis-manager.ts +83 -0
- package/core/data/base-manager.ts +156 -0
- package/core/data/ideas-manager.ts +81 -0
- package/core/data/index.ts +32 -0
- package/core/data/outcomes-manager.ts +96 -0
- package/core/data/project-manager.ts +75 -0
- package/core/data/roadmap-manager.ts +118 -0
- package/core/data/shipped-manager.ts +65 -0
- package/core/data/state-manager.ts +214 -0
- package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
- package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
- package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
- package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
- package/core/domain/{analyzer.js → analyzer.ts} +91 -85
- package/core/domain/{architect-session.js → architect-session.ts} +49 -34
- package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
- package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
- package/core/domain/{product-standards.js → product-standards.ts} +40 -26
- package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
- package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
- package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
- package/core/domain/task-stack/index.ts +19 -0
- package/core/domain/task-stack/parser.ts +86 -0
- package/core/domain/task-stack/storage.ts +123 -0
- package/core/domain/task-stack/task-stack.ts +340 -0
- package/core/domain/task-stack/types.ts +51 -0
- package/core/domain/task-stack.ts +8 -0
- package/core/{index.js → index.ts} +61 -18
- package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
- package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
- package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
- package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
- package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
- package/core/infrastructure/command-installer/global-config.ts +106 -0
- package/core/infrastructure/command-installer/index.ts +25 -0
- package/core/infrastructure/command-installer/types.ts +41 -0
- package/core/infrastructure/command-installer.ts +8 -0
- package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
- package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
- package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
- package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
- package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
- package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
- package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
- package/core/infrastructure/legacy-installer-detector.ts +7 -0
- package/core/infrastructure/migrator/file-operations.ts +125 -0
- package/core/infrastructure/migrator/index.ts +288 -0
- package/core/infrastructure/migrator/project-scanner.ts +89 -0
- package/core/infrastructure/migrator/reports.ts +117 -0
- package/core/infrastructure/migrator/types.ts +124 -0
- package/core/infrastructure/migrator/validation.ts +94 -0
- package/core/infrastructure/migrator/version-migration.ts +117 -0
- package/core/infrastructure/migrator.ts +10 -0
- package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
- package/core/infrastructure/session-manager/index.ts +23 -0
- package/core/infrastructure/session-manager/migration.ts +88 -0
- package/core/infrastructure/session-manager/session-manager.ts +307 -0
- package/core/infrastructure/session-manager/types.ts +45 -0
- package/core/infrastructure/session-manager.ts +8 -0
- package/core/infrastructure/{setup.js → setup.ts} +29 -21
- package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
- package/core/outcomes/analyzer.ts +333 -0
- package/core/outcomes/index.ts +34 -0
- package/core/outcomes/recorder.ts +194 -0
- package/core/outcomes/types.ts +145 -0
- package/core/plugin/{hooks.js → hooks.ts} +56 -58
- package/core/plugin/{index.js → index.ts} +19 -8
- package/core/plugin/{loader.js → loader.ts} +87 -69
- package/core/plugin/{registry.js → registry.ts} +49 -45
- package/core/plugins/{webhook.js → webhook.ts} +43 -27
- package/core/schemas/agents.ts +27 -0
- package/core/schemas/analysis.ts +41 -0
- package/core/schemas/ideas.ts +83 -0
- package/core/schemas/index.ts +73 -0
- package/core/schemas/outcomes.ts +22 -0
- package/core/schemas/project.ts +26 -0
- package/core/schemas/roadmap.ts +90 -0
- package/core/schemas/shipped.ts +82 -0
- package/core/schemas/state.ts +107 -0
- package/core/session/index.ts +17 -0
- package/core/session/{metrics.js → metrics.ts} +64 -46
- package/core/session/{index.js → session-manager.ts} +51 -117
- package/core/session/types.ts +29 -0
- package/core/session/utils.ts +57 -0
- package/core/state/index.ts +25 -0
- package/core/state/manager.ts +376 -0
- package/core/state/types.ts +185 -0
- package/core/tsconfig.json +22 -0
- package/core/types/index.ts +506 -0
- package/core/utils/{animations.js → animations.ts} +74 -28
- package/core/utils/{branding.js → branding.ts} +29 -4
- package/core/utils/{date-helper.js → date-helper.ts} +31 -74
- package/core/utils/file-helper.ts +262 -0
- package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
- package/core/utils/{logger.js → logger.ts} +24 -12
- package/core/utils/{output.js → output.ts} +25 -13
- package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
- package/core/utils/{session-helper.js → session-helper.ts} +79 -66
- package/core/utils/{version.js → version.ts} +23 -31
- package/core/view-generator.ts +536 -0
- package/package.json +23 -17
- package/packages/shared/.turbo/turbo-build.log +14 -0
- package/packages/shared/dist/index.d.ts +8 -613
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +4110 -118
- package/packages/shared/dist/schemas.d.ts +408 -0
- package/packages/shared/dist/schemas.d.ts.map +1 -0
- package/packages/shared/dist/types.d.ts +144 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/unified.d.ts +139 -0
- package/packages/shared/dist/unified.d.ts.map +1 -0
- package/packages/shared/dist/utils.d.ts +60 -0
- package/packages/shared/dist/utils.d.ts.map +1 -0
- package/packages/shared/package.json +4 -4
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/unified.ts +174 -0
- package/packages/web/app/api/claude/sessions/route.ts +1 -1
- package/packages/web/app/api/claude/status/route.ts +1 -1
- package/packages/web/app/api/migrate/route.ts +46 -0
- package/packages/web/app/api/projects/[id]/route.ts +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
- package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
- package/packages/web/app/api/projects/route.ts +1 -1
- package/packages/web/app/api/settings/route.ts +97 -0
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
- package/packages/web/app/globals.css +38 -0
- package/packages/web/app/layout.tsx +10 -2
- package/packages/web/app/page.tsx +9 -224
- package/packages/web/app/project/[id]/page.tsx +191 -63
- package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
- package/packages/web/app/project/[id]/stats/page.tsx +204 -163
- package/packages/web/app/settings/page.tsx +222 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
- package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
- package/packages/web/components/ActivityTimeline/index.ts +2 -0
- package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
- package/packages/web/components/AgentsCard/index.ts +2 -0
- package/packages/web/components/AppSidebar/AppSidebar.tsx +190 -0
- package/packages/web/components/AppSidebar/index.ts +1 -0
- package/packages/web/components/BackLink/BackLink.tsx +18 -0
- package/packages/web/components/BackLink/BackLink.types.ts +5 -0
- package/packages/web/components/BackLink/index.ts +2 -0
- package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
- package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
- package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
- package/packages/web/components/BentoCard/index.ts +2 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
- package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
- package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
- package/packages/web/components/BentoGrid/index.ts +2 -0
- package/packages/web/components/CommandButton/index.ts +1 -0
- package/packages/web/components/ConnectionStatus/index.ts +1 -0
- package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
- package/packages/web/components/DashboardContent/index.ts +1 -0
- package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
- package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
- package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
- package/packages/web/components/DateGroup/index.ts +2 -0
- package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
- package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
- package/packages/web/components/EmptyState/index.ts +2 -0
- package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
- package/packages/web/components/EventRow/EventRow.tsx +49 -0
- package/packages/web/components/EventRow/EventRow.types.ts +7 -0
- package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
- package/packages/web/components/EventRow/index.ts +2 -0
- package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
- package/packages/web/components/ExpandButton/index.ts +2 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
- package/packages/web/components/HealthGradientBackground/index.ts +2 -0
- package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
- package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
- package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
- package/packages/web/components/HeroSection/hooks/index.ts +2 -0
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
- package/packages/web/components/HeroSection/index.ts +2 -0
- package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
- package/packages/web/components/IdeasCard/index.ts +2 -0
- package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
- package/packages/web/components/InsightMessage/index.ts +2 -0
- package/packages/web/components/Logo/index.ts +1 -0
- package/packages/web/components/MarkdownContent/index.ts +1 -0
- package/packages/web/components/NowCard/NowCard.tsx +93 -0
- package/packages/web/components/NowCard/NowCard.types.ts +15 -0
- package/packages/web/components/NowCard/index.ts +2 -0
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
- package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
- package/packages/web/components/ProgressRing/index.ts +2 -0
- package/packages/web/components/ProjectAvatar/index.ts +1 -0
- package/packages/web/components/Providers/index.ts +1 -0
- package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
- package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
- package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
- package/packages/web/components/QueueCard/index.ts +2 -0
- package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
- package/packages/web/components/ShipsCard/index.ts +2 -0
- package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
- package/packages/web/components/SparklineChart/index.ts +2 -0
- package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
- package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
- package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
- package/packages/web/components/StreakCard/index.ts +2 -0
- package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
- package/packages/web/components/TasksCounter/index.ts +2 -0
- package/packages/web/components/TechStackBadges/index.ts +1 -0
- package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
- package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
- package/packages/web/components/TerminalTabs/index.ts +1 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
- package/packages/web/components/VelocityBadge/index.ts +2 -0
- package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
- package/packages/web/components/VelocityCard/index.ts +2 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
- package/packages/web/components/WeeklySparkline/index.ts +2 -0
- package/packages/web/components/ui/input.tsx +21 -0
- package/packages/web/context/TerminalTabsContext.tsx +46 -1
- package/packages/web/hooks/useClaudeTerminal.ts +71 -21
- package/packages/web/hooks/useProjectStats.ts +55 -0
- package/packages/web/hooks/useProjects.ts +6 -6
- package/packages/web/lib/actions/projects.ts +15 -0
- package/packages/web/lib/json-loader.ts +630 -0
- package/packages/web/lib/services/index.ts +9 -0
- package/packages/web/lib/services/migration.server.ts +600 -0
- package/packages/web/lib/services/projects.server.ts +52 -0
- package/packages/web/lib/services/stats.server.ts +264 -0
- package/packages/web/lib/unified-loader.ts +396 -0
- package/packages/web/package.json +10 -7
- package/packages/web/server.ts +58 -8
- package/templates/commands/done.md +76 -32
- package/templates/commands/feature.md +121 -47
- package/templates/commands/idea.md +81 -8
- package/templates/commands/now.md +41 -17
- package/templates/commands/ship.md +64 -25
- package/templates/commands/sync.md +28 -3
- package/core/agentic/agent-router.js +0 -140
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -417
- package/core/agentic/context-filter.js +0 -354
- package/core/agentic/ground-truth.js +0 -591
- package/core/agentic/loop-detector.js +0 -406
- package/core/agentic/memory-system.js +0 -845
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -352
- package/core/agentic/response-templates.js +0 -290
- package/core/agentic/semantic-compression.js +0 -517
- package/core/agentic/think-blocks.js +0 -657
- package/core/agentic/tool-registry.js +0 -184
- package/core/agentic/validation-rules.js +0 -380
- package/core/command-registry.js +0 -698
- package/core/commands.js +0 -2237
- package/core/domain/task-stack.js +0 -497
- package/core/infrastructure/legacy-installer-detector.js +0 -546
- package/core/infrastructure/migrator.js +0 -796
- package/core/infrastructure/session-manager.js +0 -390
- package/core/utils/file-helper.js +0 -329
- package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
- package/packages/web/app/api/stats/route.ts +0 -38
- package/packages/web/components/AppSidebar.tsx +0 -113
- package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
- package/packages/web/components/stats/AgentsCard.tsx +0 -56
- package/packages/web/components/stats/BentoCard.tsx +0 -88
- package/packages/web/components/stats/HeroSection.tsx +0 -172
- package/packages/web/components/stats/NowCard.tsx +0 -71
- package/packages/web/components/stats/QueueCard.tsx +0 -58
- package/packages/web/components/stats/VelocityCard.tsx +0 -60
- package/packages/web/components/stats/index.ts +0 -17
- package/packages/web/hooks/useStats.ts +0 -28
- /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
- /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
- /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
- /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
- /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
- /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
- /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Think Blocks
|
|
3
|
+
* Dynamic reasoning blocks for complex decisions
|
|
4
|
+
*
|
|
5
|
+
* @module agentic/think-blocks
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
interface Context {
|
|
10
|
+
params: Record<string, unknown>
|
|
11
|
+
[key: string]: unknown
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface State {
|
|
15
|
+
now?: string | null
|
|
16
|
+
analysis?: string | null
|
|
17
|
+
codePatterns?: string | null
|
|
18
|
+
[key: string]: unknown
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface ThinkTrigger {
|
|
22
|
+
type: string
|
|
23
|
+
reason: string
|
|
24
|
+
priority: 'high' | 'medium' | 'low'
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface ThinkBlock {
|
|
28
|
+
trigger: ThinkTrigger
|
|
29
|
+
commandName: string
|
|
30
|
+
conclusions: string[]
|
|
31
|
+
plan: string[]
|
|
32
|
+
confidence: number
|
|
33
|
+
generatedAt: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Detect if a think block is needed
|
|
38
|
+
*/
|
|
39
|
+
function detectTrigger(commandName: string, context: Context, state: State): ThinkTrigger | null {
|
|
40
|
+
// High-priority triggers (always think)
|
|
41
|
+
const highPriorityCommands = ['ship', 'cleanup', 'migrate']
|
|
42
|
+
if (highPriorityCommands.includes(commandName)) {
|
|
43
|
+
return {
|
|
44
|
+
type: 'critical_command',
|
|
45
|
+
reason: `${commandName} is a critical command requiring careful planning`,
|
|
46
|
+
priority: 'high',
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check for complex task
|
|
51
|
+
const taskDescription = (context.params.task as string) || (context.params.description as string) || ''
|
|
52
|
+
if (taskDescription.length > 100) {
|
|
53
|
+
return {
|
|
54
|
+
type: 'complex_task',
|
|
55
|
+
reason: 'Task description is complex, requiring analysis',
|
|
56
|
+
priority: 'medium',
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Check for existing task (potential conflict)
|
|
61
|
+
if (state.now && !state.now.includes('No current task') && commandName === 'now') {
|
|
62
|
+
return {
|
|
63
|
+
type: 'task_conflict',
|
|
64
|
+
reason: 'Already has active task, need to decide how to handle',
|
|
65
|
+
priority: 'medium',
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Check if analysis exists (context-aware)
|
|
70
|
+
if (!state.analysis && ['feature', 'spec', 'design'].includes(commandName)) {
|
|
71
|
+
return {
|
|
72
|
+
type: 'missing_context',
|
|
73
|
+
reason: 'No project analysis available, may need /p:sync first',
|
|
74
|
+
priority: 'low',
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Check for code patterns
|
|
79
|
+
if (!state.codePatterns && ['now', 'build', 'fix'].includes(commandName)) {
|
|
80
|
+
return {
|
|
81
|
+
type: 'missing_patterns',
|
|
82
|
+
reason: 'No code patterns detected, may produce inconsistent code',
|
|
83
|
+
priority: 'low',
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return null
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Generate a think block
|
|
92
|
+
*/
|
|
93
|
+
async function generate(
|
|
94
|
+
trigger: ThinkTrigger,
|
|
95
|
+
commandName: string,
|
|
96
|
+
context: Context,
|
|
97
|
+
state: State
|
|
98
|
+
): Promise<ThinkBlock> {
|
|
99
|
+
const conclusions: string[] = []
|
|
100
|
+
const plan: string[] = []
|
|
101
|
+
let confidence = 0.8
|
|
102
|
+
|
|
103
|
+
switch (trigger.type) {
|
|
104
|
+
case 'critical_command':
|
|
105
|
+
conclusions.push(`${commandName} requires careful execution`)
|
|
106
|
+
conclusions.push('Will verify state before proceeding')
|
|
107
|
+
plan.push('Check current state')
|
|
108
|
+
plan.push('Verify prerequisites')
|
|
109
|
+
plan.push('Execute with confirmation')
|
|
110
|
+
plan.push('Verify results')
|
|
111
|
+
confidence = 0.9
|
|
112
|
+
break
|
|
113
|
+
|
|
114
|
+
case 'complex_task':
|
|
115
|
+
conclusions.push('Task appears complex, breaking down')
|
|
116
|
+
conclusions.push('Will analyze dependencies first')
|
|
117
|
+
plan.push('Parse task requirements')
|
|
118
|
+
plan.push('Identify affected components')
|
|
119
|
+
plan.push('Create execution plan')
|
|
120
|
+
plan.push('Execute incrementally')
|
|
121
|
+
confidence = 0.7
|
|
122
|
+
break
|
|
123
|
+
|
|
124
|
+
case 'task_conflict':
|
|
125
|
+
conclusions.push('Existing task detected')
|
|
126
|
+
conclusions.push('Should complete or pause current task first')
|
|
127
|
+
plan.push('Check current task status')
|
|
128
|
+
plan.push('Decide: complete, pause, or replace')
|
|
129
|
+
plan.push('Update task state')
|
|
130
|
+
plan.push('Proceed with new task')
|
|
131
|
+
confidence = 0.6
|
|
132
|
+
break
|
|
133
|
+
|
|
134
|
+
case 'missing_context':
|
|
135
|
+
conclusions.push('Project analysis not available')
|
|
136
|
+
conclusions.push('May produce less optimal results')
|
|
137
|
+
plan.push('Proceed with available context')
|
|
138
|
+
plan.push('Note recommendation to run /p:sync')
|
|
139
|
+
confidence = 0.5
|
|
140
|
+
break
|
|
141
|
+
|
|
142
|
+
case 'missing_patterns':
|
|
143
|
+
conclusions.push('Code patterns not detected')
|
|
144
|
+
conclusions.push('Will use best-effort pattern matching')
|
|
145
|
+
plan.push('Read existing code for patterns')
|
|
146
|
+
plan.push('Match detected style')
|
|
147
|
+
plan.push('Generate consistent code')
|
|
148
|
+
confidence = 0.6
|
|
149
|
+
break
|
|
150
|
+
|
|
151
|
+
default:
|
|
152
|
+
conclusions.push('Standard execution path')
|
|
153
|
+
plan.push('Execute command as specified')
|
|
154
|
+
confidence = 0.8
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return {
|
|
158
|
+
trigger,
|
|
159
|
+
commandName,
|
|
160
|
+
conclusions,
|
|
161
|
+
plan,
|
|
162
|
+
confidence,
|
|
163
|
+
generatedAt: new Date().toISOString(),
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Format think block for display
|
|
169
|
+
*/
|
|
170
|
+
function format(thinkBlock: ThinkBlock | null, verbose: boolean = false): string {
|
|
171
|
+
if (!thinkBlock) {
|
|
172
|
+
return ''
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const lines: string[] = []
|
|
176
|
+
|
|
177
|
+
if (verbose) {
|
|
178
|
+
lines.push(`🧠 Think Block: ${thinkBlock.commandName}`)
|
|
179
|
+
lines.push(`Trigger: ${thinkBlock.trigger.type} (${thinkBlock.trigger.priority})`)
|
|
180
|
+
lines.push(`Reason: ${thinkBlock.trigger.reason}`)
|
|
181
|
+
lines.push('')
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
lines.push('Conclusions:')
|
|
185
|
+
thinkBlock.conclusions.forEach((c) => {
|
|
186
|
+
lines.push(` → ${c}`)
|
|
187
|
+
})
|
|
188
|
+
|
|
189
|
+
lines.push('')
|
|
190
|
+
lines.push('Plan:')
|
|
191
|
+
thinkBlock.plan.forEach((p, i) => {
|
|
192
|
+
lines.push(` ${i + 1}. ${p}`)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
lines.push('')
|
|
196
|
+
lines.push(`Confidence: ${Math.round(thinkBlock.confidence * 100)}%`)
|
|
197
|
+
|
|
198
|
+
return lines.join('\n')
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export { detectTrigger, generate, format }
|
|
202
|
+
export default { detectTrigger, generate, format }
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Registry
|
|
3
|
+
* Maps tool names to implementations for agentic execution.
|
|
4
|
+
*
|
|
5
|
+
* @module agentic/tool-registry
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'fs/promises'
|
|
10
|
+
import { exec } from 'child_process'
|
|
11
|
+
import { promisify } from 'util'
|
|
12
|
+
|
|
13
|
+
const execAsync = promisify(exec)
|
|
14
|
+
|
|
15
|
+
type ToolFunction = (...args: unknown[]) => Promise<unknown>
|
|
16
|
+
|
|
17
|
+
interface ToolRegistry {
|
|
18
|
+
tools: Map<string, ToolFunction>
|
|
19
|
+
register(name: string, fn: ToolFunction): void
|
|
20
|
+
get(name: string): ToolFunction | undefined
|
|
21
|
+
isAllowed(name: string, allowedTools: string[]): boolean
|
|
22
|
+
list(): string[]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const toolRegistry: ToolRegistry = {
|
|
26
|
+
tools: new Map(),
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Register a tool
|
|
30
|
+
*/
|
|
31
|
+
register(name: string, fn: ToolFunction): void {
|
|
32
|
+
this.tools.set(name, fn)
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get a tool by name
|
|
37
|
+
*/
|
|
38
|
+
get(name: string): ToolFunction | undefined {
|
|
39
|
+
return this.tools.get(name)
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Check if tool is allowed for command
|
|
44
|
+
*/
|
|
45
|
+
isAllowed(name: string, allowedTools: string[]): boolean {
|
|
46
|
+
// If no restrictions, allow all
|
|
47
|
+
if (!allowedTools || allowedTools.length === 0) {
|
|
48
|
+
return true
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Check if tool name matches or starts with allowed pattern
|
|
52
|
+
return allowedTools.some((allowed) => {
|
|
53
|
+
if (allowed.endsWith('*')) {
|
|
54
|
+
return name.startsWith(allowed.slice(0, -1))
|
|
55
|
+
}
|
|
56
|
+
return name === allowed
|
|
57
|
+
})
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* List all registered tools
|
|
62
|
+
*/
|
|
63
|
+
list(): string[] {
|
|
64
|
+
return Array.from(this.tools.keys())
|
|
65
|
+
},
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Register built-in tools
|
|
69
|
+
|
|
70
|
+
// Read file
|
|
71
|
+
toolRegistry.register('Read', async (filePath: unknown): Promise<string | null> => {
|
|
72
|
+
try {
|
|
73
|
+
return await fs.readFile(filePath as string, 'utf-8')
|
|
74
|
+
} catch {
|
|
75
|
+
return null
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
// Write file
|
|
80
|
+
toolRegistry.register('Write', async (filePath: unknown, content: unknown): Promise<boolean> => {
|
|
81
|
+
try {
|
|
82
|
+
await fs.writeFile(filePath as string, content as string, 'utf-8')
|
|
83
|
+
return true
|
|
84
|
+
} catch {
|
|
85
|
+
return false
|
|
86
|
+
}
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
// Execute bash command
|
|
90
|
+
toolRegistry.register('Bash', async (command: unknown): Promise<{ stdout: string; stderr: string }> => {
|
|
91
|
+
try {
|
|
92
|
+
const { stdout, stderr } = await execAsync(command as string)
|
|
93
|
+
return { stdout, stderr }
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const err = error as { stdout?: string; stderr?: string; message?: string }
|
|
96
|
+
return {
|
|
97
|
+
stdout: err.stdout || '',
|
|
98
|
+
stderr: err.stderr || err.message || 'Command failed',
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
// Get current timestamp
|
|
104
|
+
toolRegistry.register('GetTimestamp', async (): Promise<string> => {
|
|
105
|
+
return new Date().toISOString()
|
|
106
|
+
})
|
|
107
|
+
|
|
108
|
+
// Get current date
|
|
109
|
+
toolRegistry.register('GetDate', async (): Promise<string> => {
|
|
110
|
+
return new Date().toISOString().split('T')[0]
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
// Get current datetime
|
|
114
|
+
toolRegistry.register('GetDateTime', async (): Promise<string> => {
|
|
115
|
+
return new Date().toISOString()
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
export default toolRegistry
|
|
119
|
+
export { toolRegistry }
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Rules
|
|
3
|
+
* Pre-flight validation for commands before execution
|
|
4
|
+
*
|
|
5
|
+
* @module agentic/validation-rules
|
|
6
|
+
* @version 1.0.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import fs from 'fs/promises'
|
|
10
|
+
import path from 'path'
|
|
11
|
+
import os from 'os'
|
|
12
|
+
|
|
13
|
+
interface Context {
|
|
14
|
+
projectPath: string
|
|
15
|
+
projectId?: string | null
|
|
16
|
+
paths: Record<string, string>
|
|
17
|
+
params: Record<string, unknown>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ValidationResult {
|
|
21
|
+
valid: boolean
|
|
22
|
+
errors: string[]
|
|
23
|
+
warnings: string[]
|
|
24
|
+
suggestions: string[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
type Validator = (context: Context) => Promise<ValidationResult>
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Command-specific validators
|
|
31
|
+
*/
|
|
32
|
+
const validators: Record<string, Validator> = {
|
|
33
|
+
/**
|
|
34
|
+
* Validate /p:done can execute
|
|
35
|
+
*/
|
|
36
|
+
async done(context): Promise<ValidationResult> {
|
|
37
|
+
const errors: string[] = []
|
|
38
|
+
const warnings: string[] = []
|
|
39
|
+
const suggestions: string[] = []
|
|
40
|
+
|
|
41
|
+
// Check if now.md exists and has content
|
|
42
|
+
try {
|
|
43
|
+
const nowContent = await fs.readFile(context.paths.now, 'utf-8')
|
|
44
|
+
if (!nowContent.trim() || nowContent.includes('No current task')) {
|
|
45
|
+
errors.push('No active task to complete')
|
|
46
|
+
suggestions.push('Start a task with /p:now "task description"')
|
|
47
|
+
}
|
|
48
|
+
} catch {
|
|
49
|
+
errors.push('now.md does not exist')
|
|
50
|
+
suggestions.push('Initialize project with /p:init')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return {
|
|
54
|
+
valid: errors.length === 0,
|
|
55
|
+
errors,
|
|
56
|
+
warnings,
|
|
57
|
+
suggestions,
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Validate /p:ship can execute
|
|
63
|
+
*/
|
|
64
|
+
async ship(context): Promise<ValidationResult> {
|
|
65
|
+
const errors: string[] = []
|
|
66
|
+
const warnings: string[] = []
|
|
67
|
+
const suggestions: string[] = []
|
|
68
|
+
|
|
69
|
+
// Check if now.md has content to ship
|
|
70
|
+
try {
|
|
71
|
+
const nowContent = await fs.readFile(context.paths.now, 'utf-8')
|
|
72
|
+
if (!nowContent.trim() || nowContent.includes('No current task')) {
|
|
73
|
+
warnings.push('No active task to ship')
|
|
74
|
+
}
|
|
75
|
+
} catch {
|
|
76
|
+
warnings.push('now.md does not exist')
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Check if shipped.md exists
|
|
80
|
+
try {
|
|
81
|
+
await fs.access(path.dirname(context.paths.shipped))
|
|
82
|
+
} catch {
|
|
83
|
+
warnings.push('shipped.md directory does not exist')
|
|
84
|
+
suggestions.push('Run /p:init to initialize project structure')
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
valid: errors.length === 0,
|
|
89
|
+
errors,
|
|
90
|
+
warnings,
|
|
91
|
+
suggestions,
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Validate /p:now can execute
|
|
97
|
+
*/
|
|
98
|
+
async now(context): Promise<ValidationResult> {
|
|
99
|
+
const errors: string[] = []
|
|
100
|
+
const warnings: string[] = []
|
|
101
|
+
const suggestions: string[] = []
|
|
102
|
+
|
|
103
|
+
// Check if project is initialized
|
|
104
|
+
const configPath = path.join(context.projectPath, '.prjct/prjct.config.json')
|
|
105
|
+
try {
|
|
106
|
+
await fs.access(configPath)
|
|
107
|
+
} catch {
|
|
108
|
+
errors.push('Project not initialized')
|
|
109
|
+
suggestions.push('Run /p:init to initialize')
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Check if already has a task
|
|
113
|
+
try {
|
|
114
|
+
const nowContent = await fs.readFile(context.paths.now, 'utf-8')
|
|
115
|
+
if (nowContent.trim() && !nowContent.includes('No current task')) {
|
|
116
|
+
warnings.push('Already has an active task')
|
|
117
|
+
suggestions.push('Complete it first with /p:done')
|
|
118
|
+
}
|
|
119
|
+
} catch {
|
|
120
|
+
// now.md doesn't exist - that's ok for /p:now
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return {
|
|
124
|
+
valid: errors.length === 0,
|
|
125
|
+
errors,
|
|
126
|
+
warnings,
|
|
127
|
+
suggestions,
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Validate /p:init can execute
|
|
133
|
+
*/
|
|
134
|
+
async init(context): Promise<ValidationResult> {
|
|
135
|
+
const errors: string[] = []
|
|
136
|
+
const warnings: string[] = []
|
|
137
|
+
const suggestions: string[] = []
|
|
138
|
+
|
|
139
|
+
// Check if already initialized
|
|
140
|
+
const configPath = path.join(context.projectPath, '.prjct/prjct.config.json')
|
|
141
|
+
try {
|
|
142
|
+
await fs.access(configPath)
|
|
143
|
+
warnings.push('Project already initialized')
|
|
144
|
+
suggestions.push('Use /p:sync to refresh or delete .prjct/ to reinitialize')
|
|
145
|
+
} catch {
|
|
146
|
+
// Not initialized - good
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Check if global storage is writable
|
|
150
|
+
const globalPath = path.join(os.homedir(), '.prjct-cli')
|
|
151
|
+
try {
|
|
152
|
+
await fs.mkdir(globalPath, { recursive: true })
|
|
153
|
+
} catch {
|
|
154
|
+
errors.push('Cannot create ~/.prjct-cli directory')
|
|
155
|
+
suggestions.push('Check filesystem permissions')
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return {
|
|
159
|
+
valid: errors.length === 0,
|
|
160
|
+
errors,
|
|
161
|
+
warnings,
|
|
162
|
+
suggestions,
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Validate /p:sync can execute
|
|
168
|
+
*/
|
|
169
|
+
async sync(context): Promise<ValidationResult> {
|
|
170
|
+
const errors: string[] = []
|
|
171
|
+
const warnings: string[] = []
|
|
172
|
+
const suggestions: string[] = []
|
|
173
|
+
|
|
174
|
+
// Check if project is initialized
|
|
175
|
+
const configPath = path.join(context.projectPath, '.prjct/prjct.config.json')
|
|
176
|
+
try {
|
|
177
|
+
await fs.access(configPath)
|
|
178
|
+
} catch {
|
|
179
|
+
errors.push('Project not initialized')
|
|
180
|
+
suggestions.push('Run /p:init first')
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return {
|
|
184
|
+
valid: errors.length === 0,
|
|
185
|
+
errors,
|
|
186
|
+
warnings,
|
|
187
|
+
suggestions,
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Validate /p:feature can execute
|
|
193
|
+
*/
|
|
194
|
+
async feature(context): Promise<ValidationResult> {
|
|
195
|
+
const errors: string[] = []
|
|
196
|
+
const warnings: string[] = []
|
|
197
|
+
const suggestions: string[] = []
|
|
198
|
+
|
|
199
|
+
// Check if project is initialized
|
|
200
|
+
const configPath = path.join(context.projectPath, '.prjct/prjct.config.json')
|
|
201
|
+
try {
|
|
202
|
+
await fs.access(configPath)
|
|
203
|
+
} catch {
|
|
204
|
+
errors.push('Project not initialized')
|
|
205
|
+
suggestions.push('Run /p:init first')
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Check if description provided
|
|
209
|
+
if (!context.params.description && !context.params.feature) {
|
|
210
|
+
warnings.push('No feature description provided')
|
|
211
|
+
suggestions.push('Provide a feature description')
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
valid: errors.length === 0,
|
|
216
|
+
errors,
|
|
217
|
+
warnings,
|
|
218
|
+
suggestions,
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Validate /p:idea can execute
|
|
224
|
+
*/
|
|
225
|
+
async idea(context): Promise<ValidationResult> {
|
|
226
|
+
const errors: string[] = []
|
|
227
|
+
const warnings: string[] = []
|
|
228
|
+
const suggestions: string[] = []
|
|
229
|
+
|
|
230
|
+
// Check if project is initialized
|
|
231
|
+
const configPath = path.join(context.projectPath, '.prjct/prjct.config.json')
|
|
232
|
+
try {
|
|
233
|
+
await fs.access(configPath)
|
|
234
|
+
} catch {
|
|
235
|
+
errors.push('Project not initialized')
|
|
236
|
+
suggestions.push('Run /p:init first')
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Check if idea text provided
|
|
240
|
+
if (!context.params.idea && !context.params.text) {
|
|
241
|
+
warnings.push('No idea text provided')
|
|
242
|
+
suggestions.push('Provide idea text')
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return {
|
|
246
|
+
valid: errors.length === 0,
|
|
247
|
+
errors,
|
|
248
|
+
warnings,
|
|
249
|
+
suggestions,
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Validate a command before execution
|
|
256
|
+
*/
|
|
257
|
+
async function validate(commandName: string, context: Context): Promise<ValidationResult> {
|
|
258
|
+
const validator = validators[commandName]
|
|
259
|
+
|
|
260
|
+
if (!validator) {
|
|
261
|
+
// No specific validation needed
|
|
262
|
+
return {
|
|
263
|
+
valid: true,
|
|
264
|
+
errors: [],
|
|
265
|
+
warnings: [],
|
|
266
|
+
suggestions: [],
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
try {
|
|
271
|
+
return await validator(context)
|
|
272
|
+
} catch (error) {
|
|
273
|
+
return {
|
|
274
|
+
valid: false,
|
|
275
|
+
errors: [`Validation error: ${(error as Error).message}`],
|
|
276
|
+
warnings: [],
|
|
277
|
+
suggestions: ['Check file permissions and project configuration'],
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Format validation errors for display
|
|
284
|
+
*/
|
|
285
|
+
function formatError(result: ValidationResult): string {
|
|
286
|
+
let output = ''
|
|
287
|
+
|
|
288
|
+
if (result.errors.length > 0) {
|
|
289
|
+
output += '❌ Validation Failed:\n'
|
|
290
|
+
result.errors.forEach((e) => {
|
|
291
|
+
output += ` • ${e}\n`
|
|
292
|
+
})
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (result.warnings.length > 0) {
|
|
296
|
+
output += '\n⚠️ Warnings:\n'
|
|
297
|
+
result.warnings.forEach((w) => {
|
|
298
|
+
output += ` • ${w}\n`
|
|
299
|
+
})
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (result.suggestions.length > 0) {
|
|
303
|
+
output += '\n💡 Suggestions:\n'
|
|
304
|
+
result.suggestions.forEach((s) => {
|
|
305
|
+
output += ` → ${s}\n`
|
|
306
|
+
})
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return output
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export { validate, formatError, validators }
|
|
313
|
+
export default { validate, formatError, validators }
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agents Module
|
|
3
|
+
*
|
|
4
|
+
* Agent performance tracking and intelligent routing.
|
|
5
|
+
*
|
|
6
|
+
* @example
|
|
7
|
+
* ```typescript
|
|
8
|
+
* import { agentPerformanceTracker } from './agents'
|
|
9
|
+
*
|
|
10
|
+
* // Record task completion
|
|
11
|
+
* await agentPerformanceTracker.recordTask(projectId, {
|
|
12
|
+
* agentName: 'fe',
|
|
13
|
+
* taskType: 'frontend',
|
|
14
|
+
* success: true,
|
|
15
|
+
* estimatedDuration: '2h',
|
|
16
|
+
* actualDuration: '1h 45m',
|
|
17
|
+
* qualityScore: 4,
|
|
18
|
+
* completedAt: new Date().toISOString()
|
|
19
|
+
* })
|
|
20
|
+
*
|
|
21
|
+
* // Get agent suggestion
|
|
22
|
+
* const suggestion = await agentPerformanceTracker.suggestAgent(projectId, 'frontend')
|
|
23
|
+
* // { agentName: 'fe', confidence: 0.9, reason: 'Best success rate...' }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
export { AgentPerformanceTracker, default as agentPerformanceTracker } from './performance'
|
|
28
|
+
export * from './types'
|