prjct-cli 0.11.4 → 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 +72 -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 +246 -54
- 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.ts +405 -0
- 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} +99 -89
- 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} +35 -18
- 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} +62 -23
- 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 +203 -403
- 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/BentoGrid/BentoGrid.tsx +18 -0
- 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/EmptyState/EmptyState.tsx +58 -0
- 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/IdeasCard/IdeasCard.tsx +48 -0
- 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/ProgressRing/ProgressRing.tsx +51 -0
- 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/RoadmapCard/RoadmapCard.tsx +77 -0
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/ShipsCard/ShipsCard.tsx +52 -0
- 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/SparklineChart/SparklineChart.tsx +38 -0
- 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/StreakCard/StreakCard.tsx +53 -0
- 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/components/ui/tooltip.tsx +2 -2
- 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/next-env.d.ts +1 -1
- package/packages/web/package.json +10 -6
- 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 -128
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -421
- 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 -850
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -338
- 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 -799
- 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/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,476 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart Context Compression
|
|
3
|
+
*
|
|
4
|
+
* Intelligently filters context based on task type.
|
|
5
|
+
* Reduces prompt size by 40-70% while maintaining relevance.
|
|
6
|
+
*
|
|
7
|
+
* @module agentic/smart-context
|
|
8
|
+
* @version 1.0
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import stateManager from '../state'
|
|
12
|
+
import { agentPerformanceTracker } from '../agents'
|
|
13
|
+
import { outcomeAnalyzer } from '../outcomes'
|
|
14
|
+
import type { ProjectState } from '../state/types'
|
|
15
|
+
import type { TaskType } from '../agents/types'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Context domain for filtering.
|
|
19
|
+
*/
|
|
20
|
+
export type ContextDomain = 'frontend' | 'backend' | 'devops' | 'docs' | 'testing' | 'general'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Full context available before filtering.
|
|
24
|
+
*/
|
|
25
|
+
export interface FullContext {
|
|
26
|
+
/** Project state */
|
|
27
|
+
state: ProjectState | null
|
|
28
|
+
|
|
29
|
+
/** Available agents */
|
|
30
|
+
agents: AgentInfo[]
|
|
31
|
+
|
|
32
|
+
/** Roadmap features */
|
|
33
|
+
roadmap: FeatureInfo[]
|
|
34
|
+
|
|
35
|
+
/** Detected patterns */
|
|
36
|
+
patterns: PatternInfo[]
|
|
37
|
+
|
|
38
|
+
/** Tech stack info */
|
|
39
|
+
stack: StackInfo
|
|
40
|
+
|
|
41
|
+
/** File list */
|
|
42
|
+
files: string[]
|
|
43
|
+
|
|
44
|
+
/** Project path */
|
|
45
|
+
projectPath: string
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Filtered context optimized for a task domain.
|
|
50
|
+
*/
|
|
51
|
+
export interface FilteredContext {
|
|
52
|
+
/** Filtered agents (domain-relevant only) */
|
|
53
|
+
agents: AgentInfo[]
|
|
54
|
+
|
|
55
|
+
/** Filtered roadmap (related features only) */
|
|
56
|
+
roadmap: FeatureInfo[]
|
|
57
|
+
|
|
58
|
+
/** Filtered patterns (domain-relevant only) */
|
|
59
|
+
patterns: PatternInfo[]
|
|
60
|
+
|
|
61
|
+
/** Filtered stack info */
|
|
62
|
+
stack: Partial<StackInfo>
|
|
63
|
+
|
|
64
|
+
/** Filtered files */
|
|
65
|
+
files: string[]
|
|
66
|
+
|
|
67
|
+
/** Filtering metrics */
|
|
68
|
+
metrics: FilterMetrics
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Agent info for context.
|
|
73
|
+
*/
|
|
74
|
+
export interface AgentInfo {
|
|
75
|
+
name: string
|
|
76
|
+
domain: ContextDomain
|
|
77
|
+
skills: string[]
|
|
78
|
+
successRate?: number
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Feature info for context.
|
|
83
|
+
*/
|
|
84
|
+
export interface FeatureInfo {
|
|
85
|
+
id: string
|
|
86
|
+
name: string
|
|
87
|
+
relatedTo: ContextDomain[]
|
|
88
|
+
status: string
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Pattern info for context.
|
|
93
|
+
*/
|
|
94
|
+
export interface PatternInfo {
|
|
95
|
+
description: string
|
|
96
|
+
domain: ContextDomain
|
|
97
|
+
confidence: number
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Stack info for context.
|
|
102
|
+
*/
|
|
103
|
+
export interface StackInfo {
|
|
104
|
+
frontend: string[]
|
|
105
|
+
backend: string[]
|
|
106
|
+
devops: string[]
|
|
107
|
+
database: string[]
|
|
108
|
+
testing: string[]
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Filtering metrics.
|
|
113
|
+
*/
|
|
114
|
+
export interface FilterMetrics {
|
|
115
|
+
originalSize: number
|
|
116
|
+
filteredSize: number
|
|
117
|
+
reductionPercent: number
|
|
118
|
+
domain: ContextDomain
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Domain detection result.
|
|
123
|
+
*/
|
|
124
|
+
interface DomainAnalysis {
|
|
125
|
+
primary: ContextDomain
|
|
126
|
+
secondary: ContextDomain[]
|
|
127
|
+
confidence: number
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* SmartContext - Intelligent context filtering.
|
|
132
|
+
*/
|
|
133
|
+
class SmartContext {
|
|
134
|
+
/**
|
|
135
|
+
* Detect the domain of a task from its description.
|
|
136
|
+
*/
|
|
137
|
+
detectDomain(taskDescription: string): DomainAnalysis {
|
|
138
|
+
const lower = taskDescription.toLowerCase()
|
|
139
|
+
|
|
140
|
+
// Frontend indicators
|
|
141
|
+
const frontendKeywords = [
|
|
142
|
+
'ui', 'component', 'react', 'vue', 'angular', 'css', 'style',
|
|
143
|
+
'button', 'form', 'modal', 'layout', 'responsive', 'animation',
|
|
144
|
+
'dom', 'html', 'frontend', 'fe', 'client', 'browser', 'jsx', 'tsx'
|
|
145
|
+
]
|
|
146
|
+
|
|
147
|
+
// Backend indicators
|
|
148
|
+
const backendKeywords = [
|
|
149
|
+
'api', 'server', 'database', 'db', 'endpoint', 'route', 'handler',
|
|
150
|
+
'controller', 'service', 'repository', 'model', 'query', 'backend',
|
|
151
|
+
'be', 'rest', 'graphql', 'prisma', 'sql', 'redis', 'auth'
|
|
152
|
+
]
|
|
153
|
+
|
|
154
|
+
// DevOps indicators
|
|
155
|
+
const devopsKeywords = [
|
|
156
|
+
'deploy', 'docker', 'kubernetes', 'k8s', 'ci', 'cd', 'pipeline',
|
|
157
|
+
'terraform', 'ansible', 'aws', 'gcp', 'azure', 'config', 'nginx',
|
|
158
|
+
'devops', 'infrastructure', 'monitoring', 'logging', 'build'
|
|
159
|
+
]
|
|
160
|
+
|
|
161
|
+
// Docs indicators
|
|
162
|
+
const docsKeywords = [
|
|
163
|
+
'document', 'docs', 'readme', 'changelog', 'comment', 'jsdoc',
|
|
164
|
+
'tutorial', 'guide', 'explain', 'describe', 'markdown'
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
// Testing indicators
|
|
168
|
+
const testingKeywords = [
|
|
169
|
+
'test', 'spec', 'jest', 'vitest', 'mocha', 'cypress', 'playwright',
|
|
170
|
+
'e2e', 'unit', 'integration', 'coverage', 'mock', 'fixture'
|
|
171
|
+
]
|
|
172
|
+
|
|
173
|
+
// Count matches
|
|
174
|
+
const scores: Record<ContextDomain, number> = {
|
|
175
|
+
frontend: frontendKeywords.filter(k => lower.includes(k)).length,
|
|
176
|
+
backend: backendKeywords.filter(k => lower.includes(k)).length,
|
|
177
|
+
devops: devopsKeywords.filter(k => lower.includes(k)).length,
|
|
178
|
+
docs: docsKeywords.filter(k => lower.includes(k)).length,
|
|
179
|
+
testing: testingKeywords.filter(k => lower.includes(k)).length,
|
|
180
|
+
general: 0,
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Find primary and secondary domains
|
|
184
|
+
const sorted = Object.entries(scores)
|
|
185
|
+
.filter(([_, score]) => score > 0)
|
|
186
|
+
.sort((a, b) => b[1] - a[1])
|
|
187
|
+
|
|
188
|
+
if (sorted.length === 0) {
|
|
189
|
+
return { primary: 'general', secondary: [], confidence: 0.5 }
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const primary = sorted[0][0] as ContextDomain
|
|
193
|
+
const primaryScore = sorted[0][1]
|
|
194
|
+
const secondary = sorted.slice(1, 3).map(([domain]) => domain as ContextDomain)
|
|
195
|
+
|
|
196
|
+
// Calculate confidence based on score gap
|
|
197
|
+
const totalScore = sorted.reduce((sum, [_, score]) => sum + score, 0)
|
|
198
|
+
const confidence = totalScore > 0 ? Math.min(0.95, primaryScore / totalScore + 0.3) : 0.5
|
|
199
|
+
|
|
200
|
+
return { primary, secondary, confidence }
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Filter context for a specific task type.
|
|
205
|
+
*/
|
|
206
|
+
async filterForTask(
|
|
207
|
+
fullContext: FullContext,
|
|
208
|
+
taskDescription: string,
|
|
209
|
+
projectId: string
|
|
210
|
+
): Promise<FilteredContext> {
|
|
211
|
+
const domainAnalysis = this.detectDomain(taskDescription)
|
|
212
|
+
const { primary: taskDomain, secondary } = domainAnalysis
|
|
213
|
+
|
|
214
|
+
// Include primary and secondary domains
|
|
215
|
+
const relevantDomains = [taskDomain, ...secondary, 'general']
|
|
216
|
+
|
|
217
|
+
// Filter agents
|
|
218
|
+
const filteredAgents = fullContext.agents.filter(
|
|
219
|
+
agent => relevantDomains.includes(agent.domain)
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
// Enrich with performance data
|
|
223
|
+
for (const agent of filteredAgents) {
|
|
224
|
+
const perf = await agentPerformanceTracker.getAgentPerformance(
|
|
225
|
+
projectId,
|
|
226
|
+
agent.name
|
|
227
|
+
)
|
|
228
|
+
if (perf) {
|
|
229
|
+
agent.successRate = perf.successRate
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Filter roadmap
|
|
234
|
+
const filteredRoadmap = fullContext.roadmap.filter(
|
|
235
|
+
feature => feature.relatedTo.some(domain => relevantDomains.includes(domain))
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
// Filter patterns
|
|
239
|
+
const filteredPatterns = fullContext.patterns.filter(
|
|
240
|
+
pattern => relevantDomains.includes(pattern.domain)
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
// Get relevant patterns from outcomes
|
|
244
|
+
try {
|
|
245
|
+
const outcomePatterns = await outcomeAnalyzer.detectPatterns(projectId)
|
|
246
|
+
for (const pattern of outcomePatterns.slice(0, 3)) {
|
|
247
|
+
filteredPatterns.push({
|
|
248
|
+
description: pattern.description,
|
|
249
|
+
domain: taskDomain,
|
|
250
|
+
confidence: pattern.confidence,
|
|
251
|
+
})
|
|
252
|
+
}
|
|
253
|
+
} catch {
|
|
254
|
+
// Outcomes not available
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// Filter stack
|
|
258
|
+
const filteredStack: Partial<StackInfo> = {}
|
|
259
|
+
if (relevantDomains.includes('frontend')) {
|
|
260
|
+
filteredStack.frontend = fullContext.stack.frontend
|
|
261
|
+
}
|
|
262
|
+
if (relevantDomains.includes('backend')) {
|
|
263
|
+
filteredStack.backend = fullContext.stack.backend
|
|
264
|
+
filteredStack.database = fullContext.stack.database
|
|
265
|
+
}
|
|
266
|
+
if (relevantDomains.includes('devops')) {
|
|
267
|
+
filteredStack.devops = fullContext.stack.devops
|
|
268
|
+
}
|
|
269
|
+
if (relevantDomains.includes('testing')) {
|
|
270
|
+
filteredStack.testing = fullContext.stack.testing
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Filter files by domain patterns
|
|
274
|
+
const filteredFiles = this.filterFiles(fullContext.files, taskDomain)
|
|
275
|
+
|
|
276
|
+
// Calculate metrics
|
|
277
|
+
const originalSize = this.estimateSize(fullContext)
|
|
278
|
+
const filteredSize = this.estimateSize({
|
|
279
|
+
agents: filteredAgents,
|
|
280
|
+
roadmap: filteredRoadmap,
|
|
281
|
+
patterns: filteredPatterns,
|
|
282
|
+
stack: filteredStack,
|
|
283
|
+
files: filteredFiles,
|
|
284
|
+
})
|
|
285
|
+
|
|
286
|
+
return {
|
|
287
|
+
agents: filteredAgents,
|
|
288
|
+
roadmap: filteredRoadmap,
|
|
289
|
+
patterns: filteredPatterns,
|
|
290
|
+
stack: filteredStack,
|
|
291
|
+
files: filteredFiles,
|
|
292
|
+
metrics: {
|
|
293
|
+
originalSize,
|
|
294
|
+
filteredSize,
|
|
295
|
+
reductionPercent: Math.round((1 - filteredSize / originalSize) * 100),
|
|
296
|
+
domain: taskDomain,
|
|
297
|
+
},
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Filter files by domain.
|
|
303
|
+
*/
|
|
304
|
+
private filterFiles(files: string[], domain: ContextDomain): string[] {
|
|
305
|
+
const patterns: Record<ContextDomain, RegExp[]> = {
|
|
306
|
+
frontend: [
|
|
307
|
+
/\.(tsx?|jsx?|vue|svelte)$/,
|
|
308
|
+
/components?\//i,
|
|
309
|
+
/pages?\//i,
|
|
310
|
+
/views?\//i,
|
|
311
|
+
/styles?\//i,
|
|
312
|
+
/hooks?\//i,
|
|
313
|
+
],
|
|
314
|
+
backend: [
|
|
315
|
+
/\.(ts|js|py|go|rs|java)$/,
|
|
316
|
+
/api\//i,
|
|
317
|
+
/routes?\//i,
|
|
318
|
+
/controllers?\//i,
|
|
319
|
+
/services?\//i,
|
|
320
|
+
/models?\//i,
|
|
321
|
+
/handlers?\//i,
|
|
322
|
+
],
|
|
323
|
+
devops: [
|
|
324
|
+
/\.(ya?ml|toml|dockerfile|tf)$/i,
|
|
325
|
+
/docker/i,
|
|
326
|
+
/\.github\//i,
|
|
327
|
+
/deploy/i,
|
|
328
|
+
/infra/i,
|
|
329
|
+
/k8s/i,
|
|
330
|
+
],
|
|
331
|
+
docs: [
|
|
332
|
+
/\.(md|mdx|rst|txt)$/i,
|
|
333
|
+
/docs?\//i,
|
|
334
|
+
/readme/i,
|
|
335
|
+
/changelog/i,
|
|
336
|
+
],
|
|
337
|
+
testing: [
|
|
338
|
+
/\.(test|spec)\./i,
|
|
339
|
+
/tests?\//i,
|
|
340
|
+
/__tests__\//i,
|
|
341
|
+
/e2e\//i,
|
|
342
|
+
/fixtures?\//i,
|
|
343
|
+
],
|
|
344
|
+
general: [],
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const domainPatterns = patterns[domain]
|
|
348
|
+
if (domainPatterns.length === 0) {
|
|
349
|
+
return files // Return all for general domain
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Always include config files
|
|
353
|
+
const configPatterns = [
|
|
354
|
+
/package\.json$/,
|
|
355
|
+
/tsconfig\.json$/,
|
|
356
|
+
/\.config\.(ts|js)$/,
|
|
357
|
+
]
|
|
358
|
+
|
|
359
|
+
return files.filter(file => {
|
|
360
|
+
// Include if matches domain patterns
|
|
361
|
+
if (domainPatterns.some(p => p.test(file))) {
|
|
362
|
+
return true
|
|
363
|
+
}
|
|
364
|
+
// Include config files
|
|
365
|
+
if (configPatterns.some(p => p.test(file))) {
|
|
366
|
+
return true
|
|
367
|
+
}
|
|
368
|
+
return false
|
|
369
|
+
})
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Estimate context size in approximate tokens.
|
|
374
|
+
*/
|
|
375
|
+
private estimateSize(context: Partial<{
|
|
376
|
+
agents: unknown[]
|
|
377
|
+
roadmap: unknown[]
|
|
378
|
+
patterns: unknown[]
|
|
379
|
+
stack: unknown
|
|
380
|
+
files: string[]
|
|
381
|
+
state: unknown
|
|
382
|
+
}>): number {
|
|
383
|
+
let size = 0
|
|
384
|
+
|
|
385
|
+
// Rough estimates: each item ~50 tokens, files ~10 tokens each
|
|
386
|
+
size += (context.agents?.length || 0) * 50
|
|
387
|
+
size += (context.roadmap?.length || 0) * 50
|
|
388
|
+
size += (context.patterns?.length || 0) * 30
|
|
389
|
+
size += context.stack ? 100 : 0
|
|
390
|
+
size += (context.files?.length || 0) * 10
|
|
391
|
+
size += context.state ? 200 : 0
|
|
392
|
+
|
|
393
|
+
return Math.max(100, size)
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Convert TaskType to ContextDomain.
|
|
398
|
+
*/
|
|
399
|
+
taskTypeToContextDomain(taskType: TaskType): ContextDomain {
|
|
400
|
+
const mapping: Record<TaskType, ContextDomain> = {
|
|
401
|
+
frontend: 'frontend',
|
|
402
|
+
backend: 'backend',
|
|
403
|
+
devops: 'devops',
|
|
404
|
+
database: 'backend',
|
|
405
|
+
testing: 'testing',
|
|
406
|
+
documentation: 'docs',
|
|
407
|
+
refactoring: 'general',
|
|
408
|
+
bugfix: 'general',
|
|
409
|
+
feature: 'general',
|
|
410
|
+
design: 'frontend',
|
|
411
|
+
other: 'general',
|
|
412
|
+
}
|
|
413
|
+
return mapping[taskType]
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Get recommended context for a task based on history.
|
|
418
|
+
*/
|
|
419
|
+
async getRecommendedContext(
|
|
420
|
+
projectId: string,
|
|
421
|
+
taskDescription: string
|
|
422
|
+
): Promise<{
|
|
423
|
+
domain: ContextDomain
|
|
424
|
+
suggestedAgent: string | null
|
|
425
|
+
estimatedDuration: string | null
|
|
426
|
+
patterns: string[]
|
|
427
|
+
}> {
|
|
428
|
+
const domainAnalysis = this.detectDomain(taskDescription)
|
|
429
|
+
const taskType = this.contextDomainToTaskType(domainAnalysis.primary)
|
|
430
|
+
|
|
431
|
+
// Get agent suggestion
|
|
432
|
+
const agentSuggestion = await agentPerformanceTracker.suggestAgent(
|
|
433
|
+
projectId,
|
|
434
|
+
taskType
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
// Get duration estimate
|
|
438
|
+
const durationEstimate = await outcomeAnalyzer.suggestEstimate(
|
|
439
|
+
projectId,
|
|
440
|
+
taskType
|
|
441
|
+
)
|
|
442
|
+
|
|
443
|
+
// Get relevant patterns
|
|
444
|
+
const patterns = await outcomeAnalyzer.detectPatterns(projectId)
|
|
445
|
+
const relevantPatterns = patterns
|
|
446
|
+
.slice(0, 3)
|
|
447
|
+
.map(p => p.description)
|
|
448
|
+
|
|
449
|
+
return {
|
|
450
|
+
domain: domainAnalysis.primary,
|
|
451
|
+
suggestedAgent: agentSuggestion?.agentName || null,
|
|
452
|
+
estimatedDuration: durationEstimate,
|
|
453
|
+
patterns: relevantPatterns,
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Convert ContextDomain to TaskType.
|
|
459
|
+
*/
|
|
460
|
+
private contextDomainToTaskType(domain: ContextDomain): TaskType {
|
|
461
|
+
const mapping: Record<ContextDomain, TaskType> = {
|
|
462
|
+
frontend: 'frontend',
|
|
463
|
+
backend: 'backend',
|
|
464
|
+
devops: 'devops',
|
|
465
|
+
docs: 'documentation',
|
|
466
|
+
testing: 'testing',
|
|
467
|
+
general: 'other',
|
|
468
|
+
}
|
|
469
|
+
return mapping[domain]
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
// Singleton instance
|
|
474
|
+
const smartContext = new SmartContext()
|
|
475
|
+
export default smartContext
|
|
476
|
+
export { SmartContext }
|
|
@@ -1,13 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Template Loader
|
|
3
|
-
* Loads command templates with frontmatter
|
|
4
|
-
*
|
|
3
|
+
* Loads and parses command templates with frontmatter.
|
|
4
|
+
*
|
|
5
|
+
* @module agentic/template-loader
|
|
6
|
+
* @version 1.0.0
|
|
5
7
|
*/
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
import fs from 'fs/promises'
|
|
10
|
+
import path from 'path'
|
|
9
11
|
|
|
12
|
+
interface Frontmatter {
|
|
13
|
+
name?: string
|
|
14
|
+
description?: string
|
|
15
|
+
'allowed-tools'?: string[]
|
|
16
|
+
[key: string]: string | string[] | undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface ParsedTemplate {
|
|
20
|
+
frontmatter: Frontmatter
|
|
21
|
+
content: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Loads command templates from templates/commands/ with caching.
|
|
26
|
+
* Parses YAML-like frontmatter for metadata extraction.
|
|
27
|
+
*/
|
|
10
28
|
class TemplateLoader {
|
|
29
|
+
templatesDir: string
|
|
30
|
+
cache: Map<string, ParsedTemplate>
|
|
31
|
+
|
|
11
32
|
constructor() {
|
|
12
33
|
this.templatesDir = path.join(__dirname, '..', '..', 'templates', 'commands')
|
|
13
34
|
this.cache = new Map()
|
|
@@ -15,13 +36,11 @@ class TemplateLoader {
|
|
|
15
36
|
|
|
16
37
|
/**
|
|
17
38
|
* Load template with frontmatter
|
|
18
|
-
* @param {string} commandName - Command name (e.g., 'now', 'done', 'ship')
|
|
19
|
-
* @returns {Promise<{frontmatter: Object, content: string}>}
|
|
20
39
|
*/
|
|
21
|
-
async load(commandName) {
|
|
40
|
+
async load(commandName: string): Promise<ParsedTemplate> {
|
|
22
41
|
// Check cache first
|
|
23
42
|
if (this.cache.has(commandName)) {
|
|
24
|
-
return this.cache.get(commandName)
|
|
43
|
+
return this.cache.get(commandName)!
|
|
25
44
|
}
|
|
26
45
|
|
|
27
46
|
const templatePath = path.join(this.templatesDir, `${commandName}.md`)
|
|
@@ -34,17 +53,15 @@ class TemplateLoader {
|
|
|
34
53
|
this.cache.set(commandName, parsed)
|
|
35
54
|
|
|
36
55
|
return parsed
|
|
37
|
-
} catch
|
|
56
|
+
} catch {
|
|
38
57
|
throw new Error(`Template not found: ${commandName}.md`)
|
|
39
58
|
}
|
|
40
59
|
}
|
|
41
60
|
|
|
42
61
|
/**
|
|
43
62
|
* Parse frontmatter from markdown
|
|
44
|
-
* @param {string} content - Raw markdown content
|
|
45
|
-
* @returns {Object} Parsed template with frontmatter and content
|
|
46
63
|
*/
|
|
47
|
-
parseFrontmatter(content) {
|
|
64
|
+
parseFrontmatter(content: string): ParsedTemplate {
|
|
48
65
|
const frontmatterRegex = /^---\n([\s\S]+?)\n---\n([\s\S]*)$/
|
|
49
66
|
const match = content.match(frontmatterRegex)
|
|
50
67
|
|
|
@@ -56,7 +73,7 @@ class TemplateLoader {
|
|
|
56
73
|
}
|
|
57
74
|
|
|
58
75
|
const [, frontmatterText, mainContent] = match
|
|
59
|
-
const frontmatter = {}
|
|
76
|
+
const frontmatter: Frontmatter = {}
|
|
60
77
|
|
|
61
78
|
// Parse frontmatter lines
|
|
62
79
|
frontmatterText.split('\n').forEach((line) => {
|
|
@@ -85,10 +102,8 @@ class TemplateLoader {
|
|
|
85
102
|
|
|
86
103
|
/**
|
|
87
104
|
* Get allowed tools for a command
|
|
88
|
-
* @param {string} commandName - Command name
|
|
89
|
-
* @returns {Promise<string[]>}
|
|
90
105
|
*/
|
|
91
|
-
async getAllowedTools(commandName) {
|
|
106
|
+
async getAllowedTools(commandName: string): Promise<string[]> {
|
|
92
107
|
const template = await this.load(commandName)
|
|
93
108
|
return template.frontmatter['allowed-tools'] || []
|
|
94
109
|
}
|
|
@@ -96,9 +111,11 @@ class TemplateLoader {
|
|
|
96
111
|
/**
|
|
97
112
|
* Clear cache (useful for testing)
|
|
98
113
|
*/
|
|
99
|
-
clearCache() {
|
|
114
|
+
clearCache(): void {
|
|
100
115
|
this.cache.clear()
|
|
101
116
|
}
|
|
102
117
|
}
|
|
103
118
|
|
|
104
|
-
|
|
119
|
+
const templateLoader = new TemplateLoader()
|
|
120
|
+
export default templateLoader
|
|
121
|
+
export { TemplateLoader }
|