prjct-cli 0.11.5 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +81 -25
- package/bin/dev.js +1 -1
- package/bin/generate-views.js +209 -0
- package/bin/migrate-to-json.js +742 -0
- package/bin/prjct +5 -5
- package/bin/serve.js +226 -50
- package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
- package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
- package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
- package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
- package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
- package/core/agentic/agent-router.ts +137 -0
- package/core/agentic/chain-of-thought.ts +228 -0
- package/core/agentic/command-executor/command-executor.ts +384 -0
- package/core/agentic/command-executor/index.ts +16 -0
- package/core/agentic/command-executor/status-signal.ts +38 -0
- package/core/agentic/command-executor/types.ts +79 -0
- package/core/agentic/command-executor.ts +8 -0
- package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
- package/core/agentic/context-filter.ts +365 -0
- package/core/agentic/ground-truth/index.ts +76 -0
- package/core/agentic/ground-truth/types.ts +33 -0
- package/core/agentic/ground-truth/utils.ts +48 -0
- package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
- package/core/agentic/ground-truth/verifiers/done.ts +75 -0
- package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
- package/core/agentic/ground-truth/verifiers/index.ts +37 -0
- package/core/agentic/ground-truth/verifiers/init.ts +52 -0
- package/core/agentic/ground-truth/verifiers/now.ts +57 -0
- package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
- package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
- package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
- package/core/agentic/ground-truth/verifiers.ts +6 -0
- package/core/agentic/ground-truth.ts +8 -0
- package/core/agentic/loop-detector/error-analysis.ts +97 -0
- package/core/agentic/loop-detector/hallucination.ts +71 -0
- package/core/agentic/loop-detector/index.ts +41 -0
- package/core/agentic/loop-detector/loop-detector.ts +222 -0
- package/core/agentic/loop-detector/types.ts +66 -0
- package/core/agentic/loop-detector.ts +8 -0
- package/core/agentic/memory-system/history.ts +53 -0
- package/core/agentic/memory-system/index.ts +192 -0
- package/core/agentic/memory-system/patterns.ts +156 -0
- package/core/agentic/memory-system/semantic-memories.ts +277 -0
- package/core/agentic/memory-system/session.ts +21 -0
- package/core/agentic/memory-system/types.ts +159 -0
- package/core/agentic/memory-system.ts +8 -0
- package/core/agentic/parallel-tools.ts +165 -0
- package/core/agentic/plan-mode/approval.ts +57 -0
- package/core/agentic/plan-mode/constants.ts +44 -0
- package/core/agentic/plan-mode/index.ts +28 -0
- package/core/agentic/plan-mode/plan-mode.ts +406 -0
- package/core/agentic/plan-mode/types.ts +193 -0
- package/core/agentic/plan-mode.ts +8 -0
- package/core/agentic/prompt-builder.ts +566 -0
- package/core/agentic/response-templates.ts +164 -0
- package/core/agentic/semantic-compression.ts +273 -0
- package/core/agentic/services.ts +206 -0
- package/core/agentic/smart-context.ts +476 -0
- package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
- package/core/agentic/think-blocks.ts +202 -0
- package/core/agentic/tool-registry.ts +119 -0
- package/core/agentic/validation-rules.ts +313 -0
- package/core/agents/index.ts +28 -0
- package/core/agents/performance.ts +444 -0
- package/core/agents/types.ts +126 -0
- package/core/bus/{index.js → index.ts} +57 -61
- package/core/command-registry/categories.ts +23 -0
- package/core/command-registry/commands.ts +15 -0
- package/core/command-registry/core-commands.ts +319 -0
- package/core/command-registry/index.ts +158 -0
- package/core/command-registry/optional-commands.ts +119 -0
- package/core/command-registry/setup-commands.ts +53 -0
- package/core/command-registry/types.ts +59 -0
- package/core/command-registry.ts +9 -0
- package/core/commands/analysis.ts +298 -0
- package/core/commands/analytics.ts +288 -0
- package/core/commands/base.ts +273 -0
- package/core/commands/index.ts +211 -0
- package/core/commands/maintenance.ts +226 -0
- package/core/commands/planning.ts +311 -0
- package/core/commands/setup.ts +309 -0
- package/core/commands/shipping.ts +188 -0
- package/core/commands/types.ts +183 -0
- package/core/commands/workflow.ts +226 -0
- package/core/commands.ts +11 -0
- package/core/constants/formats.ts +187 -0
- package/core/constants/index.ts +7 -0
- package/core/{context-sync.js → context-sync.ts} +59 -26
- package/core/data/agents-manager.ts +76 -0
- package/core/data/analysis-manager.ts +83 -0
- package/core/data/base-manager.ts +156 -0
- package/core/data/ideas-manager.ts +81 -0
- package/core/data/index.ts +32 -0
- package/core/data/outcomes-manager.ts +96 -0
- package/core/data/project-manager.ts +75 -0
- package/core/data/roadmap-manager.ts +118 -0
- package/core/data/shipped-manager.ts +65 -0
- package/core/data/state-manager.ts +214 -0
- package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
- package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
- package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
- package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
- package/core/domain/{analyzer.js → analyzer.ts} +91 -85
- package/core/domain/{architect-session.js → architect-session.ts} +49 -34
- package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
- package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
- package/core/domain/{product-standards.js → product-standards.ts} +40 -26
- package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
- package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
- package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
- package/core/domain/task-stack/index.ts +19 -0
- package/core/domain/task-stack/parser.ts +86 -0
- package/core/domain/task-stack/storage.ts +123 -0
- package/core/domain/task-stack/task-stack.ts +340 -0
- package/core/domain/task-stack/types.ts +51 -0
- package/core/domain/task-stack.ts +8 -0
- package/core/{index.js → index.ts} +61 -18
- package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
- package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
- package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
- package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
- package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
- package/core/infrastructure/command-installer/global-config.ts +106 -0
- package/core/infrastructure/command-installer/index.ts +25 -0
- package/core/infrastructure/command-installer/types.ts +41 -0
- package/core/infrastructure/command-installer.ts +8 -0
- package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
- package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
- package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
- package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
- package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
- package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
- package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
- package/core/infrastructure/legacy-installer-detector.ts +7 -0
- package/core/infrastructure/migrator/file-operations.ts +125 -0
- package/core/infrastructure/migrator/index.ts +288 -0
- package/core/infrastructure/migrator/project-scanner.ts +89 -0
- package/core/infrastructure/migrator/reports.ts +117 -0
- package/core/infrastructure/migrator/types.ts +124 -0
- package/core/infrastructure/migrator/validation.ts +94 -0
- package/core/infrastructure/migrator/version-migration.ts +117 -0
- package/core/infrastructure/migrator.ts +10 -0
- package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
- package/core/infrastructure/session-manager/index.ts +23 -0
- package/core/infrastructure/session-manager/migration.ts +88 -0
- package/core/infrastructure/session-manager/session-manager.ts +307 -0
- package/core/infrastructure/session-manager/types.ts +45 -0
- package/core/infrastructure/session-manager.ts +8 -0
- package/core/infrastructure/{setup.js → setup.ts} +29 -21
- package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
- package/core/outcomes/analyzer.ts +333 -0
- package/core/outcomes/index.ts +34 -0
- package/core/outcomes/recorder.ts +194 -0
- package/core/outcomes/types.ts +145 -0
- package/core/plugin/{hooks.js → hooks.ts} +56 -58
- package/core/plugin/{index.js → index.ts} +19 -8
- package/core/plugin/{loader.js → loader.ts} +87 -69
- package/core/plugin/{registry.js → registry.ts} +49 -45
- package/core/plugins/{webhook.js → webhook.ts} +43 -27
- package/core/schemas/agents.ts +27 -0
- package/core/schemas/analysis.ts +41 -0
- package/core/schemas/ideas.ts +83 -0
- package/core/schemas/index.ts +73 -0
- package/core/schemas/outcomes.ts +22 -0
- package/core/schemas/project.ts +26 -0
- package/core/schemas/roadmap.ts +90 -0
- package/core/schemas/shipped.ts +82 -0
- package/core/schemas/state.ts +107 -0
- package/core/session/index.ts +17 -0
- package/core/session/{metrics.js → metrics.ts} +64 -46
- package/core/session/{index.js → session-manager.ts} +51 -117
- package/core/session/types.ts +29 -0
- package/core/session/utils.ts +57 -0
- package/core/state/index.ts +25 -0
- package/core/state/manager.ts +376 -0
- package/core/state/types.ts +185 -0
- package/core/tsconfig.json +22 -0
- package/core/types/index.ts +506 -0
- package/core/utils/{animations.js → animations.ts} +74 -28
- package/core/utils/{branding.js → branding.ts} +29 -4
- package/core/utils/{date-helper.js → date-helper.ts} +31 -74
- package/core/utils/file-helper.ts +262 -0
- package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
- package/core/utils/{logger.js → logger.ts} +24 -12
- package/core/utils/{output.js → output.ts} +25 -13
- package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
- package/core/utils/{session-helper.js → session-helper.ts} +79 -66
- package/core/utils/{version.js → version.ts} +23 -31
- package/core/view-generator.ts +536 -0
- package/package.json +23 -17
- package/packages/shared/.turbo/turbo-build.log +14 -0
- package/packages/shared/dist/index.d.ts +8 -613
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +4110 -118
- package/packages/shared/dist/schemas.d.ts +408 -0
- package/packages/shared/dist/schemas.d.ts.map +1 -0
- package/packages/shared/dist/types.d.ts +144 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/unified.d.ts +139 -0
- package/packages/shared/dist/unified.d.ts.map +1 -0
- package/packages/shared/dist/utils.d.ts +60 -0
- package/packages/shared/dist/utils.d.ts.map +1 -0
- package/packages/shared/package.json +4 -4
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/unified.ts +174 -0
- package/packages/web/app/api/claude/sessions/route.ts +1 -1
- package/packages/web/app/api/claude/status/route.ts +1 -1
- package/packages/web/app/api/migrate/route.ts +46 -0
- package/packages/web/app/api/projects/[id]/route.ts +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
- package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
- package/packages/web/app/api/projects/route.ts +1 -1
- package/packages/web/app/api/settings/route.ts +97 -0
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
- package/packages/web/app/globals.css +38 -0
- package/packages/web/app/layout.tsx +10 -2
- package/packages/web/app/page.tsx +9 -224
- package/packages/web/app/project/[id]/page.tsx +191 -63
- package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
- package/packages/web/app/project/[id]/stats/page.tsx +204 -163
- package/packages/web/app/settings/page.tsx +222 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
- package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
- package/packages/web/components/ActivityTimeline/index.ts +2 -0
- package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
- package/packages/web/components/AgentsCard/index.ts +2 -0
- package/packages/web/components/AppSidebar/AppSidebar.tsx +134 -0
- package/packages/web/components/AppSidebar/index.ts +1 -0
- package/packages/web/components/BackLink/BackLink.tsx +18 -0
- package/packages/web/components/BackLink/BackLink.types.ts +5 -0
- package/packages/web/components/BackLink/index.ts +2 -0
- package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
- package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
- package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
- package/packages/web/components/BentoCard/index.ts +2 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
- package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
- package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
- package/packages/web/components/BentoGrid/index.ts +2 -0
- package/packages/web/components/CommandButton/index.ts +1 -0
- package/packages/web/components/ConnectionStatus/index.ts +1 -0
- package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
- package/packages/web/components/DashboardContent/index.ts +1 -0
- package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
- package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
- package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
- package/packages/web/components/DateGroup/index.ts +2 -0
- package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
- package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
- package/packages/web/components/EmptyState/index.ts +2 -0
- package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
- package/packages/web/components/EventRow/EventRow.tsx +49 -0
- package/packages/web/components/EventRow/EventRow.types.ts +7 -0
- package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
- package/packages/web/components/EventRow/index.ts +2 -0
- package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
- package/packages/web/components/ExpandButton/index.ts +2 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
- package/packages/web/components/HealthGradientBackground/index.ts +2 -0
- package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
- package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
- package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
- package/packages/web/components/HeroSection/hooks/index.ts +2 -0
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
- package/packages/web/components/HeroSection/index.ts +2 -0
- package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
- package/packages/web/components/IdeasCard/index.ts +2 -0
- package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
- package/packages/web/components/InsightMessage/index.ts +2 -0
- package/packages/web/components/Logo/index.ts +1 -0
- package/packages/web/components/MarkdownContent/index.ts +1 -0
- package/packages/web/components/NowCard/NowCard.tsx +93 -0
- package/packages/web/components/NowCard/NowCard.types.ts +15 -0
- package/packages/web/components/NowCard/index.ts +2 -0
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
- package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
- package/packages/web/components/ProgressRing/index.ts +2 -0
- package/packages/web/components/ProjectAvatar/index.ts +1 -0
- package/packages/web/components/Providers/index.ts +1 -0
- package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
- package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
- package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
- package/packages/web/components/QueueCard/index.ts +2 -0
- package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
- package/packages/web/components/ShipsCard/index.ts +2 -0
- package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
- package/packages/web/components/SparklineChart/index.ts +2 -0
- package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
- package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
- package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
- package/packages/web/components/StreakCard/index.ts +2 -0
- package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
- package/packages/web/components/TasksCounter/index.ts +2 -0
- package/packages/web/components/TechStackBadges/index.ts +1 -0
- package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
- package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
- package/packages/web/components/TerminalTabs/index.ts +1 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
- package/packages/web/components/VelocityBadge/index.ts +2 -0
- package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
- package/packages/web/components/VelocityCard/index.ts +2 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
- package/packages/web/components/WeeklySparkline/index.ts +2 -0
- package/packages/web/components/ui/input.tsx +21 -0
- package/packages/web/context/TerminalTabsContext.tsx +46 -1
- package/packages/web/hooks/useClaudeTerminal.ts +71 -21
- package/packages/web/hooks/useProjectStats.ts +55 -0
- package/packages/web/hooks/useProjects.ts +6 -6
- package/packages/web/lib/actions/projects.ts +15 -0
- package/packages/web/lib/json-loader.ts +630 -0
- package/packages/web/lib/services/index.ts +9 -0
- package/packages/web/lib/services/migration.server.ts +598 -0
- package/packages/web/lib/services/projects.server.ts +52 -0
- package/packages/web/lib/services/stats.server.ts +264 -0
- package/packages/web/lib/unified-loader.ts +396 -0
- package/packages/web/package.json +10 -7
- package/packages/web/server.ts +36 -6
- package/templates/commands/done.md +76 -32
- package/templates/commands/feature.md +121 -47
- package/templates/commands/idea.md +81 -8
- package/templates/commands/now.md +41 -17
- package/templates/commands/ship.md +64 -25
- package/templates/commands/sync.md +28 -3
- package/core/agentic/agent-router.js +0 -140
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -417
- package/core/agentic/context-filter.js +0 -354
- package/core/agentic/ground-truth.js +0 -591
- package/core/agentic/loop-detector.js +0 -406
- package/core/agentic/memory-system.js +0 -845
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -352
- package/core/agentic/response-templates.js +0 -290
- package/core/agentic/semantic-compression.js +0 -517
- package/core/agentic/think-blocks.js +0 -657
- package/core/agentic/tool-registry.js +0 -184
- package/core/agentic/validation-rules.js +0 -380
- package/core/command-registry.js +0 -698
- package/core/commands.js +0 -2237
- package/core/domain/task-stack.js +0 -497
- package/core/infrastructure/legacy-installer-detector.js +0 -546
- package/core/infrastructure/migrator.js +0 -796
- package/core/infrastructure/session-manager.js +0 -390
- package/core/utils/file-helper.js +0 -329
- package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
- package/packages/web/app/api/stats/route.ts +0 -38
- package/packages/web/components/AppSidebar.tsx +0 -113
- package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
- package/packages/web/components/stats/AgentsCard.tsx +0 -56
- package/packages/web/components/stats/BentoCard.tsx +0 -88
- package/packages/web/components/stats/HeroSection.tsx +0 -172
- package/packages/web/components/stats/NowCard.tsx +0 -71
- package/packages/web/components/stats/QueueCard.tsx +0 -58
- package/packages/web/components/stats/VelocityCard.tsx +0 -60
- package/packages/web/components/stats/index.ts +0 -17
- package/packages/web/hooks/useStats.ts +0 -28
- /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
- /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
- /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
- /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
- /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
- /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
- /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
|
@@ -1,16 +1,55 @@
|
|
|
1
|
-
const fs = require('fs').promises
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const os = require('os')
|
|
4
|
-
const AgentLoader = require('./agent-loader')
|
|
5
|
-
const log = require('../utils/logger')
|
|
6
|
-
|
|
7
1
|
/**
|
|
8
2
|
* AgentGenerator - Universal Dynamic Agent Generation
|
|
9
3
|
* Optimized for minimal context usage
|
|
10
4
|
* @version 1.0.0
|
|
11
5
|
*/
|
|
6
|
+
|
|
7
|
+
import fs from 'fs/promises'
|
|
8
|
+
import path from 'path'
|
|
9
|
+
import os from 'os'
|
|
10
|
+
import AgentLoader from './agent-loader'
|
|
11
|
+
import log from '../utils/logger'
|
|
12
|
+
|
|
13
|
+
interface AgentConfig {
|
|
14
|
+
role?: string
|
|
15
|
+
domain?: string
|
|
16
|
+
projectContext?: Record<string, unknown> | string
|
|
17
|
+
expertise?: string
|
|
18
|
+
contextFilter?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface TechSummary {
|
|
22
|
+
languages: string[]
|
|
23
|
+
frameworks: string[]
|
|
24
|
+
buildTools: string[]
|
|
25
|
+
testFrameworks: string[]
|
|
26
|
+
databases: string[]
|
|
27
|
+
tools: string[]
|
|
28
|
+
allDependencies: string[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface GenerateContext {
|
|
32
|
+
detectedTech: TechSummary
|
|
33
|
+
analysisSummary?: string
|
|
34
|
+
projectPath?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface Agent {
|
|
38
|
+
name: string
|
|
39
|
+
content?: string
|
|
40
|
+
path?: string
|
|
41
|
+
role?: string | null
|
|
42
|
+
domain?: string
|
|
43
|
+
skills?: string[]
|
|
44
|
+
modified?: Date
|
|
45
|
+
}
|
|
46
|
+
|
|
12
47
|
class AgentGenerator {
|
|
13
|
-
|
|
48
|
+
projectId: string | null
|
|
49
|
+
outputDir: string
|
|
50
|
+
loader: AgentLoader
|
|
51
|
+
|
|
52
|
+
constructor(projectId: string | null = null) {
|
|
14
53
|
this.projectId = projectId
|
|
15
54
|
this.outputDir = projectId
|
|
16
55
|
? path.join(os.homedir(), '.prjct-cli', 'projects', projectId, 'agents')
|
|
@@ -22,7 +61,7 @@ class AgentGenerator {
|
|
|
22
61
|
* Generate specialized agent with deep expertise
|
|
23
62
|
* Universal - works with ANY technology stack
|
|
24
63
|
*/
|
|
25
|
-
async generateDynamicAgent(agentName, config) {
|
|
64
|
+
async generateDynamicAgent(agentName: string, config: AgentConfig): Promise<{ name: string }> {
|
|
26
65
|
log.debug(`Generating ${agentName} agent...`)
|
|
27
66
|
await fs.mkdir(this.outputDir, { recursive: true })
|
|
28
67
|
|
|
@@ -41,60 +80,52 @@ class AgentGenerator {
|
|
|
41
80
|
* Claude decides what agents are needed based on actual project tech
|
|
42
81
|
* NO HARDCODED LISTS - reads analysis and decides
|
|
43
82
|
*/
|
|
44
|
-
async generateAgentsFromTech(context) {
|
|
45
|
-
const { detectedTech
|
|
46
|
-
const agents = []
|
|
47
|
-
|
|
83
|
+
async generateAgentsFromTech(context: GenerateContext): Promise<Array<{ name: string }>> {
|
|
84
|
+
const { detectedTech } = context
|
|
85
|
+
const agents: string[] = []
|
|
86
|
+
|
|
48
87
|
// Read agent generation template - Claude will use this to decide
|
|
49
88
|
const templatePath = path.join(__dirname, '../../templates/agents/AGENTS.md')
|
|
50
|
-
let agentTemplate = ''
|
|
51
89
|
try {
|
|
52
|
-
|
|
90
|
+
await fs.readFile(templatePath, 'utf-8')
|
|
53
91
|
} catch {
|
|
54
92
|
// Fallback if template doesn't exist
|
|
55
|
-
agentTemplate = 'Generate agents based on detected technologies'
|
|
56
93
|
}
|
|
57
|
-
|
|
94
|
+
|
|
58
95
|
// Build context for Claude to decide
|
|
59
|
-
|
|
60
|
-
const techSummary = {
|
|
96
|
+
const techSummary: TechSummary = {
|
|
61
97
|
languages: detectedTech.languages || [],
|
|
62
98
|
frameworks: detectedTech.frameworks || [],
|
|
63
99
|
buildTools: detectedTech.buildTools || [],
|
|
64
100
|
testFrameworks: detectedTech.testFrameworks || [],
|
|
65
101
|
databases: detectedTech.databases || [],
|
|
66
102
|
tools: detectedTech.tools || [],
|
|
67
|
-
allDependencies: detectedTech.allDependencies || []
|
|
103
|
+
allDependencies: detectedTech.allDependencies || [],
|
|
68
104
|
}
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
// But this should be replaced with Claude decision-making
|
|
72
|
-
// TODO: Make this fully agentic by having Claude read the template and decide
|
|
73
|
-
|
|
74
|
-
// Temporary: Generate agents for detected domains (agentic, not hardcoded)
|
|
75
|
-
// Claude will eventually decide this based on template
|
|
105
|
+
|
|
106
|
+
// Generate agents for detected domains
|
|
76
107
|
if (techSummary.languages.length > 0 || techSummary.frameworks.length > 0) {
|
|
77
|
-
// Generate a general development agent
|
|
78
108
|
await this.generateDynamicAgent('developer', {
|
|
79
109
|
role: 'Development Specialist',
|
|
80
110
|
domain: 'general',
|
|
81
|
-
projectContext: techSummary
|
|
111
|
+
projectContext: techSummary,
|
|
82
112
|
})
|
|
83
113
|
agents.push('developer')
|
|
84
114
|
}
|
|
85
|
-
|
|
86
|
-
return agents.map(name => ({ name }))
|
|
115
|
+
|
|
116
|
+
return agents.map((name) => ({ name }))
|
|
87
117
|
}
|
|
88
118
|
|
|
89
119
|
/**
|
|
90
120
|
* Build comprehensive agent prompt
|
|
91
121
|
*/
|
|
92
|
-
buildAgentPrompt(agentName, config) {
|
|
93
|
-
const domain = config.domain || 'general'
|
|
94
|
-
|
|
95
|
-
const projectContext =
|
|
96
|
-
|
|
97
|
-
|
|
122
|
+
buildAgentPrompt(agentName: string, config: AgentConfig): string {
|
|
123
|
+
const domain = config.domain || 'general'
|
|
124
|
+
|
|
125
|
+
const projectContext =
|
|
126
|
+
typeof config.projectContext === 'object'
|
|
127
|
+
? JSON.stringify(config.projectContext || {}, null, 2)
|
|
128
|
+
: config.projectContext || 'No specific project context provided.'
|
|
98
129
|
|
|
99
130
|
return `# AGENT: ${agentName.toUpperCase()}
|
|
100
131
|
Role: ${config.role || agentName}
|
|
@@ -133,16 +164,14 @@ ${config.contextFilter || 'Only relevant files'}
|
|
|
133
164
|
- Do not assume a specific stack until you see the code.
|
|
134
165
|
- Optimize for production.
|
|
135
166
|
- No explanations unless asked.
|
|
136
|
-
|
|
167
|
+
`
|
|
137
168
|
}
|
|
138
169
|
|
|
139
170
|
/**
|
|
140
171
|
* Remove agents that are no longer needed
|
|
141
|
-
* @param {Array} requiredAgents - List of agents that should exist
|
|
142
|
-
* @returns {Promise<Array>} List of removed agents
|
|
143
172
|
*/
|
|
144
|
-
async cleanupObsoleteAgents(requiredAgents) {
|
|
145
|
-
const removed = []
|
|
173
|
+
async cleanupObsoleteAgents(requiredAgents: string[]): Promise<string[]> {
|
|
174
|
+
const removed: string[] = []
|
|
146
175
|
|
|
147
176
|
try {
|
|
148
177
|
const files = await fs.readdir(this.outputDir)
|
|
@@ -159,7 +188,7 @@ ${config.contextFilter || 'Only relevant files'}
|
|
|
159
188
|
}
|
|
160
189
|
}
|
|
161
190
|
} catch (error) {
|
|
162
|
-
log.error('Agent cleanup failed:', error.message)
|
|
191
|
+
log.error('Agent cleanup failed:', (error as Error).message)
|
|
163
192
|
}
|
|
164
193
|
|
|
165
194
|
return removed
|
|
@@ -167,14 +196,11 @@ ${config.contextFilter || 'Only relevant files'}
|
|
|
167
196
|
|
|
168
197
|
/**
|
|
169
198
|
* List all existing agents
|
|
170
|
-
* @returns {Promise<Array>} List of agent names
|
|
171
199
|
*/
|
|
172
|
-
async listAgents() {
|
|
200
|
+
async listAgents(): Promise<string[]> {
|
|
173
201
|
try {
|
|
174
202
|
const files = await fs.readdir(this.outputDir)
|
|
175
|
-
return files
|
|
176
|
-
.filter((f) => f.endsWith('.md') && !f.startsWith('.'))
|
|
177
|
-
.map((f) => f.replace('.md', ''))
|
|
203
|
+
return files.filter((f) => f.endsWith('.md') && !f.startsWith('.')).map((f) => f.replace('.md', ''))
|
|
178
204
|
} catch {
|
|
179
205
|
return []
|
|
180
206
|
}
|
|
@@ -182,30 +208,24 @@ ${config.contextFilter || 'Only relevant files'}
|
|
|
182
208
|
|
|
183
209
|
/**
|
|
184
210
|
* Load an agent from its file
|
|
185
|
-
* CRITICAL: This is how agents are actually used in prompts
|
|
186
|
-
* @param {string} agentName - Name of the agent (without .md extension)
|
|
187
|
-
* @returns {Promise<Object|null>} - Agent object with name, content, role, domain, skills, or null if not found
|
|
188
211
|
*/
|
|
189
|
-
async loadAgent(agentName) {
|
|
212
|
+
async loadAgent(agentName: string): Promise<Agent | null> {
|
|
190
213
|
return await this.loader.loadAgent(agentName)
|
|
191
214
|
}
|
|
192
215
|
|
|
193
216
|
/**
|
|
194
217
|
* Load all agents for the project
|
|
195
|
-
* @returns {Promise<Array<Object>>} - Array of agent objects
|
|
196
218
|
*/
|
|
197
|
-
async loadAllAgents() {
|
|
219
|
+
async loadAllAgents(): Promise<Agent[]> {
|
|
198
220
|
return await this.loader.loadAllAgents()
|
|
199
221
|
}
|
|
200
222
|
|
|
201
223
|
/**
|
|
202
224
|
* Check if an agent exists
|
|
203
|
-
* @param {string} agentName - Name of the agent
|
|
204
|
-
* @returns {Promise<boolean>} - True if agent file exists
|
|
205
225
|
*/
|
|
206
|
-
async agentExists(agentName) {
|
|
226
|
+
async agentExists(agentName: string): Promise<boolean> {
|
|
207
227
|
return await this.loader.agentExists(agentName)
|
|
208
228
|
}
|
|
209
229
|
}
|
|
210
230
|
|
|
211
|
-
|
|
231
|
+
export default AgentGenerator
|
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AgentLoader - Loads agents from project files
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* CRITICAL: This ensures agents generated for a project are actually USED
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* @version 1.0.0
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
import fs from 'fs/promises'
|
|
10
|
+
import path from 'path'
|
|
11
|
+
import os from 'os'
|
|
12
|
+
|
|
13
|
+
interface Agent {
|
|
14
|
+
name: string
|
|
15
|
+
content: string
|
|
16
|
+
path: string
|
|
17
|
+
role: string | null
|
|
18
|
+
domain: string
|
|
19
|
+
skills: string[]
|
|
20
|
+
modified: Date
|
|
21
|
+
}
|
|
12
22
|
|
|
13
23
|
class AgentLoader {
|
|
14
|
-
|
|
24
|
+
projectId: string | null
|
|
25
|
+
agentsDir: string
|
|
26
|
+
cache: Map<string, Agent>
|
|
27
|
+
|
|
28
|
+
constructor(projectId: string | null = null) {
|
|
15
29
|
this.projectId = projectId
|
|
16
30
|
this.agentsDir = projectId
|
|
17
31
|
? path.join(os.homedir(), '.prjct-cli', 'projects', projectId, 'agents')
|
|
@@ -21,14 +35,12 @@ class AgentLoader {
|
|
|
21
35
|
|
|
22
36
|
/**
|
|
23
37
|
* Load an agent from its file
|
|
24
|
-
* @param {string} agentName - Name of the agent (without .md extension)
|
|
25
|
-
* @returns {Promise<Object|null>} - Agent object with name and content, or null if not found
|
|
26
38
|
*/
|
|
27
|
-
async loadAgent(agentName) {
|
|
39
|
+
async loadAgent(agentName: string): Promise<Agent | null> {
|
|
28
40
|
// Check cache first
|
|
29
41
|
const cacheKey = `${this.projectId || 'global'}-${agentName}`
|
|
30
42
|
if (this.cache.has(cacheKey)) {
|
|
31
|
-
return this.cache.get(cacheKey)
|
|
43
|
+
return this.cache.get(cacheKey)!
|
|
32
44
|
}
|
|
33
45
|
|
|
34
46
|
try {
|
|
@@ -36,18 +48,14 @@ class AgentLoader {
|
|
|
36
48
|
const content = await fs.readFile(agentPath, 'utf-8')
|
|
37
49
|
|
|
38
50
|
// Parse agent metadata from content
|
|
39
|
-
const agent = {
|
|
51
|
+
const agent: Agent = {
|
|
40
52
|
name: agentName,
|
|
41
53
|
content,
|
|
42
54
|
path: agentPath,
|
|
43
|
-
// Extract role if present in content
|
|
44
55
|
role: this.extractRole(content),
|
|
45
|
-
// Extract domain if present
|
|
46
56
|
domain: this.extractDomain(content),
|
|
47
|
-
// Extract skills/technologies mentioned
|
|
48
57
|
skills: this.extractSkills(content),
|
|
49
|
-
|
|
50
|
-
modified: (await fs.stat(agentPath)).mtime
|
|
58
|
+
modified: (await fs.stat(agentPath)).mtime,
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
// Cache it
|
|
@@ -55,7 +63,7 @@ class AgentLoader {
|
|
|
55
63
|
|
|
56
64
|
return agent
|
|
57
65
|
} catch (error) {
|
|
58
|
-
if (error.code === 'ENOENT') {
|
|
66
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
59
67
|
return null // Agent file doesn't exist
|
|
60
68
|
}
|
|
61
69
|
throw error
|
|
@@ -64,14 +72,13 @@ class AgentLoader {
|
|
|
64
72
|
|
|
65
73
|
/**
|
|
66
74
|
* Load all agents for the project
|
|
67
|
-
* @returns {Promise<Array<Object>>} - Array of agent objects
|
|
68
75
|
*/
|
|
69
|
-
async loadAllAgents() {
|
|
76
|
+
async loadAllAgents(): Promise<Agent[]> {
|
|
70
77
|
try {
|
|
71
78
|
const files = await fs.readdir(this.agentsDir)
|
|
72
|
-
const agentFiles = files.filter(f => f.endsWith('.md') && !f.startsWith('.'))
|
|
79
|
+
const agentFiles = files.filter((f) => f.endsWith('.md') && !f.startsWith('.'))
|
|
73
80
|
|
|
74
|
-
const agents = []
|
|
81
|
+
const agents: Agent[] = []
|
|
75
82
|
for (const file of agentFiles) {
|
|
76
83
|
const agentName = file.replace('.md', '')
|
|
77
84
|
const agent = await this.loadAgent(agentName)
|
|
@@ -82,7 +89,7 @@ class AgentLoader {
|
|
|
82
89
|
|
|
83
90
|
return agents
|
|
84
91
|
} catch (error) {
|
|
85
|
-
if (error.code === 'ENOENT') {
|
|
92
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
86
93
|
return [] // Agents directory doesn't exist yet
|
|
87
94
|
}
|
|
88
95
|
throw error
|
|
@@ -91,10 +98,8 @@ class AgentLoader {
|
|
|
91
98
|
|
|
92
99
|
/**
|
|
93
100
|
* Check if an agent exists
|
|
94
|
-
* @param {string} agentName - Name of the agent
|
|
95
|
-
* @returns {Promise<boolean>} - True if agent file exists
|
|
96
101
|
*/
|
|
97
|
-
async agentExists(agentName) {
|
|
102
|
+
async agentExists(agentName: string): Promise<boolean> {
|
|
98
103
|
try {
|
|
99
104
|
const agentPath = path.join(this.agentsDir, `${agentName}.md`)
|
|
100
105
|
await fs.access(agentPath)
|
|
@@ -107,58 +112,64 @@ class AgentLoader {
|
|
|
107
112
|
/**
|
|
108
113
|
* Clear cache (useful after agent updates)
|
|
109
114
|
*/
|
|
110
|
-
clearCache() {
|
|
115
|
+
clearCache(): void {
|
|
111
116
|
this.cache.clear()
|
|
112
117
|
}
|
|
113
118
|
|
|
114
119
|
/**
|
|
115
120
|
* Extract role from agent content
|
|
116
|
-
* @private
|
|
117
121
|
*/
|
|
118
|
-
extractRole(content) {
|
|
122
|
+
private extractRole(content: string): string | null {
|
|
119
123
|
const roleMatch = content.match(/Role:\s*(.+)/i)
|
|
120
124
|
return roleMatch ? roleMatch[1].trim() : null
|
|
121
125
|
}
|
|
122
126
|
|
|
123
127
|
/**
|
|
124
128
|
* Extract domain from agent content
|
|
125
|
-
* @private
|
|
126
129
|
*/
|
|
127
|
-
extractDomain(content) {
|
|
130
|
+
private extractDomain(content: string): string {
|
|
128
131
|
const domainMatch = content.match(/DOMAIN AUTHORITY[\s\S]*?the\s+(\w+)\s+domain/i)
|
|
129
132
|
if (domainMatch) {
|
|
130
133
|
return domainMatch[1].toLowerCase()
|
|
131
134
|
}
|
|
132
|
-
|
|
133
|
-
// Fallback: try to detect from agent name
|
|
134
|
-
const name = this.projectId ? '' : ''
|
|
135
|
-
if (name.includes('frontend')) return 'frontend'
|
|
136
|
-
if (name.includes('backend')) return 'backend'
|
|
137
|
-
if (name.includes('database')) return 'database'
|
|
138
|
-
if (name.includes('devops')) return 'devops'
|
|
139
|
-
if (name.includes('qa')) return 'qa'
|
|
140
|
-
if (name.includes('architect')) return 'architecture'
|
|
141
|
-
|
|
135
|
+
|
|
142
136
|
return 'general'
|
|
143
137
|
}
|
|
144
138
|
|
|
145
139
|
/**
|
|
146
140
|
* Extract skills/technologies mentioned in agent content
|
|
147
|
-
* @private
|
|
148
141
|
*/
|
|
149
|
-
extractSkills(content) {
|
|
150
|
-
const skills = []
|
|
151
|
-
|
|
142
|
+
private extractSkills(content: string): string[] {
|
|
143
|
+
const skills: string[] = []
|
|
144
|
+
|
|
152
145
|
// Look for common technology mentions
|
|
153
146
|
const techKeywords = [
|
|
154
|
-
'React',
|
|
155
|
-
'
|
|
156
|
-
'
|
|
157
|
-
'
|
|
158
|
-
'
|
|
159
|
-
'
|
|
160
|
-
'
|
|
161
|
-
'
|
|
147
|
+
'React',
|
|
148
|
+
'Vue',
|
|
149
|
+
'Angular',
|
|
150
|
+
'Svelte',
|
|
151
|
+
'Next.js',
|
|
152
|
+
'Nuxt',
|
|
153
|
+
'SvelteKit',
|
|
154
|
+
'TypeScript',
|
|
155
|
+
'JavaScript',
|
|
156
|
+
'Node.js',
|
|
157
|
+
'Express',
|
|
158
|
+
'Fastify',
|
|
159
|
+
'Python',
|
|
160
|
+
'Django',
|
|
161
|
+
'Flask',
|
|
162
|
+
'FastAPI',
|
|
163
|
+
'Go',
|
|
164
|
+
'Rust',
|
|
165
|
+
'Ruby',
|
|
166
|
+
'Rails',
|
|
167
|
+
'PostgreSQL',
|
|
168
|
+
'MySQL',
|
|
169
|
+
'MongoDB',
|
|
170
|
+
'Docker',
|
|
171
|
+
'Kubernetes',
|
|
172
|
+
'Terraform',
|
|
162
173
|
]
|
|
163
174
|
|
|
164
175
|
for (const tech of techKeywords) {
|
|
@@ -172,12 +183,10 @@ class AgentLoader {
|
|
|
172
183
|
|
|
173
184
|
/**
|
|
174
185
|
* Get agents directory path
|
|
175
|
-
* @returns {string} - Path to agents directory
|
|
176
186
|
*/
|
|
177
|
-
getAgentsDir() {
|
|
187
|
+
getAgentsDir(): string {
|
|
178
188
|
return this.agentsDir
|
|
179
189
|
}
|
|
180
190
|
}
|
|
181
191
|
|
|
182
|
-
|
|
183
|
-
|
|
192
|
+
export default AgentLoader
|
|
@@ -9,21 +9,47 @@
|
|
|
9
9
|
* @version 2.0.0
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
import fs from 'fs/promises'
|
|
13
|
+
import path from 'path'
|
|
14
|
+
|
|
15
|
+
interface Agent {
|
|
16
|
+
name: string
|
|
17
|
+
domain?: string
|
|
18
|
+
content?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface Task {
|
|
22
|
+
description?: string
|
|
23
|
+
type?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface HistoryEntry {
|
|
27
|
+
timestamp: string
|
|
28
|
+
agent: string
|
|
29
|
+
task: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface FormattedAgent {
|
|
33
|
+
name: string
|
|
34
|
+
domain: string
|
|
35
|
+
hasContent: boolean
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface FormattedTask {
|
|
39
|
+
description: string
|
|
40
|
+
type: string
|
|
41
|
+
}
|
|
14
42
|
|
|
15
43
|
class AgentMatcher {
|
|
16
|
-
|
|
17
|
-
this.historyPath = null
|
|
18
|
-
}
|
|
44
|
+
historyPath: string | null = null
|
|
19
45
|
|
|
20
46
|
/**
|
|
21
47
|
* Set history path for logging
|
|
22
48
|
* ORCHESTRATION: Path setup only
|
|
23
49
|
*/
|
|
24
|
-
setHistoryPath(projectId) {
|
|
50
|
+
setHistoryPath(projectId: string): void {
|
|
25
51
|
this.historyPath = path.join(
|
|
26
|
-
process.env.HOME,
|
|
52
|
+
process.env.HOME || '',
|
|
27
53
|
'.prjct-cli',
|
|
28
54
|
'projects',
|
|
29
55
|
projectId,
|
|
@@ -35,11 +61,11 @@ class AgentMatcher {
|
|
|
35
61
|
* Format agents for Claude
|
|
36
62
|
* ORCHESTRATION: Data formatting only
|
|
37
63
|
*/
|
|
38
|
-
formatAgentsForTemplate(agents) {
|
|
39
|
-
return agents.map(a => ({
|
|
64
|
+
formatAgentsForTemplate(agents: Agent[]): FormattedAgent[] {
|
|
65
|
+
return agents.map((a) => ({
|
|
40
66
|
name: a.name,
|
|
41
67
|
domain: a.domain || 'general',
|
|
42
|
-
hasContent: !!a.content
|
|
68
|
+
hasContent: !!a.content,
|
|
43
69
|
}))
|
|
44
70
|
}
|
|
45
71
|
|
|
@@ -47,10 +73,10 @@ class AgentMatcher {
|
|
|
47
73
|
* Format task for Claude
|
|
48
74
|
* ORCHESTRATION: Data formatting only
|
|
49
75
|
*/
|
|
50
|
-
formatTaskForTemplate(task) {
|
|
76
|
+
formatTaskForTemplate(task: string | Task): FormattedTask {
|
|
51
77
|
return {
|
|
52
|
-
description: typeof task === 'string' ? task : task.description,
|
|
53
|
-
type: task.type || 'unknown'
|
|
78
|
+
description: typeof task === 'string' ? task : task.description || '',
|
|
79
|
+
type: typeof task === 'string' ? 'unknown' : task.type || 'unknown',
|
|
54
80
|
}
|
|
55
81
|
}
|
|
56
82
|
|
|
@@ -58,15 +84,16 @@ class AgentMatcher {
|
|
|
58
84
|
* Record agent usage
|
|
59
85
|
* ORCHESTRATION: File I/O only
|
|
60
86
|
*/
|
|
61
|
-
async recordUsage(agent, task) {
|
|
87
|
+
async recordUsage(agent: string | Agent, task: string | Task): Promise<void> {
|
|
62
88
|
if (!this.historyPath) return
|
|
63
89
|
|
|
64
90
|
try {
|
|
65
|
-
const entry =
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
91
|
+
const entry =
|
|
92
|
+
JSON.stringify({
|
|
93
|
+
timestamp: new Date().toISOString(),
|
|
94
|
+
agent: typeof agent === 'string' ? agent : agent.name,
|
|
95
|
+
task: typeof task === 'string' ? task : task.description,
|
|
96
|
+
}) + '\n'
|
|
70
97
|
|
|
71
98
|
await fs.appendFile(this.historyPath, entry)
|
|
72
99
|
} catch {
|
|
@@ -78,7 +105,7 @@ class AgentMatcher {
|
|
|
78
105
|
* Load usage history
|
|
79
106
|
* ORCHESTRATION: File I/O only
|
|
80
107
|
*/
|
|
81
|
-
async loadHistory() {
|
|
108
|
+
async loadHistory(): Promise<HistoryEntry[]> {
|
|
82
109
|
if (!this.historyPath) return []
|
|
83
110
|
|
|
84
111
|
try {
|
|
@@ -86,18 +113,18 @@ class AgentMatcher {
|
|
|
86
113
|
return content
|
|
87
114
|
.split('\n')
|
|
88
115
|
.filter(Boolean)
|
|
89
|
-
.map(line => {
|
|
116
|
+
.map((line) => {
|
|
90
117
|
try {
|
|
91
|
-
return JSON.parse(line)
|
|
118
|
+
return JSON.parse(line) as HistoryEntry
|
|
92
119
|
} catch {
|
|
93
120
|
return null
|
|
94
121
|
}
|
|
95
122
|
})
|
|
96
|
-
.filter(
|
|
123
|
+
.filter((entry): entry is HistoryEntry => entry !== null)
|
|
97
124
|
} catch {
|
|
98
125
|
return []
|
|
99
126
|
}
|
|
100
127
|
}
|
|
101
128
|
}
|
|
102
129
|
|
|
103
|
-
|
|
130
|
+
export default AgentMatcher
|