prjct-cli 0.11.5 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +81 -25
- package/bin/dev.js +1 -1
- package/bin/generate-views.js +209 -0
- package/bin/migrate-to-json.js +742 -0
- package/bin/prjct +5 -5
- package/bin/serve.js +226 -50
- package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
- package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
- package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
- package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
- package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
- package/core/agentic/agent-router.ts +137 -0
- package/core/agentic/chain-of-thought.ts +228 -0
- package/core/agentic/command-executor/command-executor.ts +384 -0
- package/core/agentic/command-executor/index.ts +16 -0
- package/core/agentic/command-executor/status-signal.ts +38 -0
- package/core/agentic/command-executor/types.ts +79 -0
- package/core/agentic/command-executor.ts +8 -0
- package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
- package/core/agentic/context-filter.ts +365 -0
- package/core/agentic/ground-truth/index.ts +76 -0
- package/core/agentic/ground-truth/types.ts +33 -0
- package/core/agentic/ground-truth/utils.ts +48 -0
- package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
- package/core/agentic/ground-truth/verifiers/done.ts +75 -0
- package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
- package/core/agentic/ground-truth/verifiers/index.ts +37 -0
- package/core/agentic/ground-truth/verifiers/init.ts +52 -0
- package/core/agentic/ground-truth/verifiers/now.ts +57 -0
- package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
- package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
- package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
- package/core/agentic/ground-truth/verifiers.ts +6 -0
- package/core/agentic/ground-truth.ts +8 -0
- package/core/agentic/loop-detector/error-analysis.ts +97 -0
- package/core/agentic/loop-detector/hallucination.ts +71 -0
- package/core/agentic/loop-detector/index.ts +41 -0
- package/core/agentic/loop-detector/loop-detector.ts +222 -0
- package/core/agentic/loop-detector/types.ts +66 -0
- package/core/agentic/loop-detector.ts +8 -0
- package/core/agentic/memory-system/history.ts +53 -0
- package/core/agentic/memory-system/index.ts +192 -0
- package/core/agentic/memory-system/patterns.ts +156 -0
- package/core/agentic/memory-system/semantic-memories.ts +277 -0
- package/core/agentic/memory-system/session.ts +21 -0
- package/core/agentic/memory-system/types.ts +159 -0
- package/core/agentic/memory-system.ts +8 -0
- package/core/agentic/parallel-tools.ts +165 -0
- package/core/agentic/plan-mode/approval.ts +57 -0
- package/core/agentic/plan-mode/constants.ts +44 -0
- package/core/agentic/plan-mode/index.ts +28 -0
- package/core/agentic/plan-mode/plan-mode.ts +406 -0
- package/core/agentic/plan-mode/types.ts +193 -0
- package/core/agentic/plan-mode.ts +8 -0
- package/core/agentic/prompt-builder.ts +566 -0
- package/core/agentic/response-templates.ts +164 -0
- package/core/agentic/semantic-compression.ts +273 -0
- package/core/agentic/services.ts +206 -0
- package/core/agentic/smart-context.ts +476 -0
- package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
- package/core/agentic/think-blocks.ts +202 -0
- package/core/agentic/tool-registry.ts +119 -0
- package/core/agentic/validation-rules.ts +313 -0
- package/core/agents/index.ts +28 -0
- package/core/agents/performance.ts +444 -0
- package/core/agents/types.ts +126 -0
- package/core/bus/{index.js → index.ts} +57 -61
- package/core/command-registry/categories.ts +23 -0
- package/core/command-registry/commands.ts +15 -0
- package/core/command-registry/core-commands.ts +319 -0
- package/core/command-registry/index.ts +158 -0
- package/core/command-registry/optional-commands.ts +119 -0
- package/core/command-registry/setup-commands.ts +53 -0
- package/core/command-registry/types.ts +59 -0
- package/core/command-registry.ts +9 -0
- package/core/commands/analysis.ts +298 -0
- package/core/commands/analytics.ts +288 -0
- package/core/commands/base.ts +273 -0
- package/core/commands/index.ts +211 -0
- package/core/commands/maintenance.ts +226 -0
- package/core/commands/planning.ts +311 -0
- package/core/commands/setup.ts +309 -0
- package/core/commands/shipping.ts +188 -0
- package/core/commands/types.ts +183 -0
- package/core/commands/workflow.ts +226 -0
- package/core/commands.ts +11 -0
- package/core/constants/formats.ts +187 -0
- package/core/constants/index.ts +7 -0
- package/core/{context-sync.js → context-sync.ts} +59 -26
- package/core/data/agents-manager.ts +76 -0
- package/core/data/analysis-manager.ts +83 -0
- package/core/data/base-manager.ts +156 -0
- package/core/data/ideas-manager.ts +81 -0
- package/core/data/index.ts +32 -0
- package/core/data/outcomes-manager.ts +96 -0
- package/core/data/project-manager.ts +75 -0
- package/core/data/roadmap-manager.ts +118 -0
- package/core/data/shipped-manager.ts +65 -0
- package/core/data/state-manager.ts +214 -0
- package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
- package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
- package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
- package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
- package/core/domain/{analyzer.js → analyzer.ts} +91 -85
- package/core/domain/{architect-session.js → architect-session.ts} +49 -34
- package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
- package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
- package/core/domain/{product-standards.js → product-standards.ts} +40 -26
- package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
- package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
- package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
- package/core/domain/task-stack/index.ts +19 -0
- package/core/domain/task-stack/parser.ts +86 -0
- package/core/domain/task-stack/storage.ts +123 -0
- package/core/domain/task-stack/task-stack.ts +340 -0
- package/core/domain/task-stack/types.ts +51 -0
- package/core/domain/task-stack.ts +8 -0
- package/core/{index.js → index.ts} +61 -18
- package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
- package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
- package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
- package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
- package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
- package/core/infrastructure/command-installer/global-config.ts +106 -0
- package/core/infrastructure/command-installer/index.ts +25 -0
- package/core/infrastructure/command-installer/types.ts +41 -0
- package/core/infrastructure/command-installer.ts +8 -0
- package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
- package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
- package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
- package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
- package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
- package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
- package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
- package/core/infrastructure/legacy-installer-detector.ts +7 -0
- package/core/infrastructure/migrator/file-operations.ts +125 -0
- package/core/infrastructure/migrator/index.ts +288 -0
- package/core/infrastructure/migrator/project-scanner.ts +89 -0
- package/core/infrastructure/migrator/reports.ts +117 -0
- package/core/infrastructure/migrator/types.ts +124 -0
- package/core/infrastructure/migrator/validation.ts +94 -0
- package/core/infrastructure/migrator/version-migration.ts +117 -0
- package/core/infrastructure/migrator.ts +10 -0
- package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
- package/core/infrastructure/session-manager/index.ts +23 -0
- package/core/infrastructure/session-manager/migration.ts +88 -0
- package/core/infrastructure/session-manager/session-manager.ts +307 -0
- package/core/infrastructure/session-manager/types.ts +45 -0
- package/core/infrastructure/session-manager.ts +8 -0
- package/core/infrastructure/{setup.js → setup.ts} +29 -21
- package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
- package/core/outcomes/analyzer.ts +333 -0
- package/core/outcomes/index.ts +34 -0
- package/core/outcomes/recorder.ts +194 -0
- package/core/outcomes/types.ts +145 -0
- package/core/plugin/{hooks.js → hooks.ts} +56 -58
- package/core/plugin/{index.js → index.ts} +19 -8
- package/core/plugin/{loader.js → loader.ts} +87 -69
- package/core/plugin/{registry.js → registry.ts} +49 -45
- package/core/plugins/{webhook.js → webhook.ts} +43 -27
- package/core/schemas/agents.ts +27 -0
- package/core/schemas/analysis.ts +41 -0
- package/core/schemas/ideas.ts +83 -0
- package/core/schemas/index.ts +73 -0
- package/core/schemas/outcomes.ts +22 -0
- package/core/schemas/project.ts +26 -0
- package/core/schemas/roadmap.ts +90 -0
- package/core/schemas/shipped.ts +82 -0
- package/core/schemas/state.ts +107 -0
- package/core/session/index.ts +17 -0
- package/core/session/{metrics.js → metrics.ts} +64 -46
- package/core/session/{index.js → session-manager.ts} +51 -117
- package/core/session/types.ts +29 -0
- package/core/session/utils.ts +57 -0
- package/core/state/index.ts +25 -0
- package/core/state/manager.ts +376 -0
- package/core/state/types.ts +185 -0
- package/core/tsconfig.json +22 -0
- package/core/types/index.ts +506 -0
- package/core/utils/{animations.js → animations.ts} +74 -28
- package/core/utils/{branding.js → branding.ts} +29 -4
- package/core/utils/{date-helper.js → date-helper.ts} +31 -74
- package/core/utils/file-helper.ts +262 -0
- package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
- package/core/utils/{logger.js → logger.ts} +24 -12
- package/core/utils/{output.js → output.ts} +25 -13
- package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
- package/core/utils/{session-helper.js → session-helper.ts} +79 -66
- package/core/utils/{version.js → version.ts} +23 -31
- package/core/view-generator.ts +536 -0
- package/package.json +23 -17
- package/packages/shared/.turbo/turbo-build.log +14 -0
- package/packages/shared/dist/index.d.ts +8 -613
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +4110 -118
- package/packages/shared/dist/schemas.d.ts +408 -0
- package/packages/shared/dist/schemas.d.ts.map +1 -0
- package/packages/shared/dist/types.d.ts +144 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/unified.d.ts +139 -0
- package/packages/shared/dist/unified.d.ts.map +1 -0
- package/packages/shared/dist/utils.d.ts +60 -0
- package/packages/shared/dist/utils.d.ts.map +1 -0
- package/packages/shared/package.json +4 -4
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/unified.ts +174 -0
- package/packages/web/app/api/claude/sessions/route.ts +1 -1
- package/packages/web/app/api/claude/status/route.ts +1 -1
- package/packages/web/app/api/migrate/route.ts +46 -0
- package/packages/web/app/api/projects/[id]/route.ts +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
- package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
- package/packages/web/app/api/projects/route.ts +1 -1
- package/packages/web/app/api/settings/route.ts +97 -0
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
- package/packages/web/app/globals.css +38 -0
- package/packages/web/app/layout.tsx +10 -2
- package/packages/web/app/page.tsx +9 -224
- package/packages/web/app/project/[id]/page.tsx +191 -63
- package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
- package/packages/web/app/project/[id]/stats/page.tsx +204 -163
- package/packages/web/app/settings/page.tsx +222 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
- package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
- package/packages/web/components/ActivityTimeline/index.ts +2 -0
- package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
- package/packages/web/components/AgentsCard/index.ts +2 -0
- package/packages/web/components/AppSidebar/AppSidebar.tsx +190 -0
- package/packages/web/components/AppSidebar/index.ts +1 -0
- package/packages/web/components/BackLink/BackLink.tsx +18 -0
- package/packages/web/components/BackLink/BackLink.types.ts +5 -0
- package/packages/web/components/BackLink/index.ts +2 -0
- package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
- package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
- package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
- package/packages/web/components/BentoCard/index.ts +2 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
- package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
- package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
- package/packages/web/components/BentoGrid/index.ts +2 -0
- package/packages/web/components/CommandButton/index.ts +1 -0
- package/packages/web/components/ConnectionStatus/index.ts +1 -0
- package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
- package/packages/web/components/DashboardContent/index.ts +1 -0
- package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
- package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
- package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
- package/packages/web/components/DateGroup/index.ts +2 -0
- package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
- package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
- package/packages/web/components/EmptyState/index.ts +2 -0
- package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
- package/packages/web/components/EventRow/EventRow.tsx +49 -0
- package/packages/web/components/EventRow/EventRow.types.ts +7 -0
- package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
- package/packages/web/components/EventRow/index.ts +2 -0
- package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
- package/packages/web/components/ExpandButton/index.ts +2 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
- package/packages/web/components/HealthGradientBackground/index.ts +2 -0
- package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
- package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
- package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
- package/packages/web/components/HeroSection/hooks/index.ts +2 -0
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
- package/packages/web/components/HeroSection/index.ts +2 -0
- package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
- package/packages/web/components/IdeasCard/index.ts +2 -0
- package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
- package/packages/web/components/InsightMessage/index.ts +2 -0
- package/packages/web/components/Logo/index.ts +1 -0
- package/packages/web/components/MarkdownContent/index.ts +1 -0
- package/packages/web/components/NowCard/NowCard.tsx +93 -0
- package/packages/web/components/NowCard/NowCard.types.ts +15 -0
- package/packages/web/components/NowCard/index.ts +2 -0
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
- package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
- package/packages/web/components/ProgressRing/index.ts +2 -0
- package/packages/web/components/ProjectAvatar/index.ts +1 -0
- package/packages/web/components/Providers/index.ts +1 -0
- package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
- package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
- package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
- package/packages/web/components/QueueCard/index.ts +2 -0
- package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
- package/packages/web/components/ShipsCard/index.ts +2 -0
- package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
- package/packages/web/components/SparklineChart/index.ts +2 -0
- package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
- package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
- package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
- package/packages/web/components/StreakCard/index.ts +2 -0
- package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
- package/packages/web/components/TasksCounter/index.ts +2 -0
- package/packages/web/components/TechStackBadges/index.ts +1 -0
- package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
- package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
- package/packages/web/components/TerminalTabs/index.ts +1 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
- package/packages/web/components/VelocityBadge/index.ts +2 -0
- package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
- package/packages/web/components/VelocityCard/index.ts +2 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
- package/packages/web/components/WeeklySparkline/index.ts +2 -0
- package/packages/web/components/ui/input.tsx +21 -0
- package/packages/web/context/TerminalTabsContext.tsx +46 -1
- package/packages/web/hooks/useClaudeTerminal.ts +71 -21
- package/packages/web/hooks/useProjectStats.ts +55 -0
- package/packages/web/hooks/useProjects.ts +6 -6
- package/packages/web/lib/actions/projects.ts +15 -0
- package/packages/web/lib/json-loader.ts +630 -0
- package/packages/web/lib/services/index.ts +9 -0
- package/packages/web/lib/services/migration.server.ts +600 -0
- package/packages/web/lib/services/projects.server.ts +52 -0
- package/packages/web/lib/services/stats.server.ts +264 -0
- package/packages/web/lib/unified-loader.ts +396 -0
- package/packages/web/package.json +10 -7
- package/packages/web/server.ts +58 -8
- package/templates/commands/done.md +76 -32
- package/templates/commands/feature.md +121 -47
- package/templates/commands/idea.md +81 -8
- package/templates/commands/now.md +41 -17
- package/templates/commands/ship.md +64 -25
- package/templates/commands/sync.md +28 -3
- package/core/agentic/agent-router.js +0 -140
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -417
- package/core/agentic/context-filter.js +0 -354
- package/core/agentic/ground-truth.js +0 -591
- package/core/agentic/loop-detector.js +0 -406
- package/core/agentic/memory-system.js +0 -845
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -352
- package/core/agentic/response-templates.js +0 -290
- package/core/agentic/semantic-compression.js +0 -517
- package/core/agentic/think-blocks.js +0 -657
- package/core/agentic/tool-registry.js +0 -184
- package/core/agentic/validation-rules.js +0 -380
- package/core/command-registry.js +0 -698
- package/core/commands.js +0 -2237
- package/core/domain/task-stack.js +0 -497
- package/core/infrastructure/legacy-installer-detector.js +0 -546
- package/core/infrastructure/migrator.js +0 -796
- package/core/infrastructure/session-manager.js +0 -390
- package/core/utils/file-helper.js +0 -329
- package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
- package/packages/web/app/api/stats/route.ts +0 -38
- package/packages/web/components/AppSidebar.tsx +0 -113
- package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
- package/packages/web/components/stats/AgentsCard.tsx +0 -56
- package/packages/web/components/stats/BentoCard.tsx +0 -88
- package/packages/web/components/stats/HeroSection.tsx +0 -172
- package/packages/web/components/stats/NowCard.tsx +0 -71
- package/packages/web/components/stats/QueueCard.tsx +0 -58
- package/packages/web/components/stats/VelocityCard.tsx +0 -60
- package/packages/web/components/stats/index.ts +0 -17
- package/packages/web/hooks/useStats.ts +0 -28
- /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
- /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
- /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
- /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
- /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
- /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
- /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
|
@@ -1,23 +1,45 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AgentValidator - Validates agents before and after generation
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
4
|
* Ensures agents are useful and not generic
|
|
5
5
|
* Compares with existing agents before generating
|
|
6
|
-
*
|
|
6
|
+
*
|
|
7
7
|
* @version 1.0.0
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
interface AgentConfig {
|
|
11
|
+
expertise?: string
|
|
12
|
+
domain?: string
|
|
13
|
+
projectContext?: Record<string, unknown>
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface Agent {
|
|
17
|
+
name: string
|
|
18
|
+
content?: string
|
|
19
|
+
skills?: string[]
|
|
20
|
+
domain?: string
|
|
21
|
+
role?: string
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
interface ValidationResult {
|
|
25
|
+
valid: boolean
|
|
26
|
+
issues: string[]
|
|
27
|
+
warnings: string[]
|
|
28
|
+
similarAgent?: Agent | null
|
|
29
|
+
usefulness?: number
|
|
30
|
+
}
|
|
31
|
+
|
|
10
32
|
class AgentValidator {
|
|
11
33
|
/**
|
|
12
34
|
* Validate if agent should be generated
|
|
13
|
-
* @param {string} agentName - Proposed agent name
|
|
14
|
-
* @param {Object} config - Agent configuration
|
|
15
|
-
* @param {Array<Object>} existingAgents - Existing agents
|
|
16
|
-
* @returns {Object} Validation result
|
|
17
35
|
*/
|
|
18
|
-
validateBeforeGeneration(
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
validateBeforeGeneration(
|
|
37
|
+
agentName: string,
|
|
38
|
+
config: AgentConfig,
|
|
39
|
+
existingAgents: Agent[] = []
|
|
40
|
+
): ValidationResult {
|
|
41
|
+
const issues: string[] = []
|
|
42
|
+
const warnings: string[] = []
|
|
21
43
|
|
|
22
44
|
// Check if similar agent exists
|
|
23
45
|
const similar = this.findSimilarAgent(agentName, config, existingAgents)
|
|
@@ -44,18 +66,16 @@ class AgentValidator {
|
|
|
44
66
|
valid: issues.length === 0,
|
|
45
67
|
issues,
|
|
46
68
|
warnings,
|
|
47
|
-
similarAgent: similar
|
|
69
|
+
similarAgent: similar,
|
|
48
70
|
}
|
|
49
71
|
}
|
|
50
72
|
|
|
51
73
|
/**
|
|
52
74
|
* Validate agent after generation
|
|
53
|
-
* @param {Object} agent - Generated agent
|
|
54
|
-
* @returns {Object} Validation result
|
|
55
75
|
*/
|
|
56
|
-
validateAfterGeneration(agent) {
|
|
57
|
-
const issues = []
|
|
58
|
-
const warnings = []
|
|
76
|
+
validateAfterGeneration(agent: Agent): ValidationResult {
|
|
77
|
+
const issues: string[] = []
|
|
78
|
+
const warnings: string[] = []
|
|
59
79
|
|
|
60
80
|
// Check if agent has content
|
|
61
81
|
if (!agent.content || agent.content.length < 100) {
|
|
@@ -82,14 +102,14 @@ class AgentValidator {
|
|
|
82
102
|
valid: issues.length === 0,
|
|
83
103
|
issues,
|
|
84
104
|
warnings,
|
|
85
|
-
usefulness
|
|
105
|
+
usefulness,
|
|
86
106
|
}
|
|
87
107
|
}
|
|
88
108
|
|
|
89
109
|
/**
|
|
90
110
|
* Find similar existing agent
|
|
91
111
|
*/
|
|
92
|
-
findSimilarAgent(agentName, config, existingAgents) {
|
|
112
|
+
findSimilarAgent(agentName: string, config: AgentConfig, existingAgents: Agent[]): Agent | null {
|
|
93
113
|
for (const existing of existingAgents) {
|
|
94
114
|
// Check name similarity
|
|
95
115
|
if (this.namesSimilar(agentName, existing.name)) {
|
|
@@ -112,7 +132,7 @@ class AgentValidator {
|
|
|
112
132
|
/**
|
|
113
133
|
* Check if agent names are similar
|
|
114
134
|
*/
|
|
115
|
-
namesSimilar(name1, name2) {
|
|
135
|
+
namesSimilar(name1: string, name2: string): boolean {
|
|
116
136
|
const n1 = name1.toLowerCase()
|
|
117
137
|
const n2 = name2.toLowerCase()
|
|
118
138
|
|
|
@@ -125,7 +145,7 @@ class AgentValidator {
|
|
|
125
145
|
// Check word overlap
|
|
126
146
|
const words1 = new Set(n1.split('-'))
|
|
127
147
|
const words2 = new Set(n2.split('-'))
|
|
128
|
-
const intersection = new Set([...words1].filter(w => words2.has(w)))
|
|
148
|
+
const intersection = new Set([...words1].filter((w) => words2.has(w)))
|
|
129
149
|
const union = new Set([...words1, ...words2])
|
|
130
150
|
|
|
131
151
|
return intersection.size / union.size > 0.5
|
|
@@ -134,7 +154,7 @@ class AgentValidator {
|
|
|
134
154
|
/**
|
|
135
155
|
* Calculate skill overlap between config and existing agent
|
|
136
156
|
*/
|
|
137
|
-
calculateSkillOverlap(config, existingAgent) {
|
|
157
|
+
calculateSkillOverlap(config: AgentConfig, existingAgent: Agent): number {
|
|
138
158
|
if (!existingAgent.skills || existingAgent.skills.length === 0) {
|
|
139
159
|
return 0
|
|
140
160
|
}
|
|
@@ -146,10 +166,10 @@ class AgentValidator {
|
|
|
146
166
|
}
|
|
147
167
|
|
|
148
168
|
// Calculate overlap
|
|
149
|
-
const existingSet = new Set(existingAgent.skills.map(s => s.toLowerCase()))
|
|
150
|
-
const configSet = new Set(configSkills.map(s => s.toLowerCase()))
|
|
169
|
+
const existingSet = new Set(existingAgent.skills.map((s) => s.toLowerCase()))
|
|
170
|
+
const configSet = new Set(configSkills.map((s) => s.toLowerCase()))
|
|
151
171
|
|
|
152
|
-
const intersection = new Set([...existingSet].filter(s => configSet.has(s)))
|
|
172
|
+
const intersection = new Set([...existingSet].filter((s) => configSet.has(s)))
|
|
153
173
|
const union = new Set([...existingSet, ...configSet])
|
|
154
174
|
|
|
155
175
|
return intersection.size / union.size
|
|
@@ -158,27 +178,41 @@ class AgentValidator {
|
|
|
158
178
|
/**
|
|
159
179
|
* Extract skills from text
|
|
160
180
|
*/
|
|
161
|
-
extractSkillsFromText(text) {
|
|
181
|
+
extractSkillsFromText(text: string): string[] {
|
|
162
182
|
// Common technology keywords
|
|
163
183
|
const techKeywords = [
|
|
164
|
-
'React',
|
|
165
|
-
'
|
|
166
|
-
'
|
|
167
|
-
'
|
|
168
|
-
'
|
|
169
|
-
'
|
|
170
|
-
'
|
|
184
|
+
'React',
|
|
185
|
+
'Vue',
|
|
186
|
+
'Angular',
|
|
187
|
+
'Svelte',
|
|
188
|
+
'Next.js',
|
|
189
|
+
'Nuxt',
|
|
190
|
+
'SvelteKit',
|
|
191
|
+
'TypeScript',
|
|
192
|
+
'JavaScript',
|
|
193
|
+
'Node.js',
|
|
194
|
+
'Express',
|
|
195
|
+
'Fastify',
|
|
196
|
+
'Python',
|
|
197
|
+
'Django',
|
|
198
|
+
'Flask',
|
|
199
|
+
'FastAPI',
|
|
200
|
+
'Go',
|
|
201
|
+
'Rust',
|
|
202
|
+
'Ruby',
|
|
203
|
+
'Rails',
|
|
204
|
+
'PostgreSQL',
|
|
205
|
+
'MySQL',
|
|
206
|
+
'MongoDB',
|
|
171
207
|
]
|
|
172
208
|
|
|
173
|
-
return techKeywords.filter(tech =>
|
|
174
|
-
text.toLowerCase().includes(tech.toLowerCase())
|
|
175
|
-
)
|
|
209
|
+
return techKeywords.filter((tech) => text.toLowerCase().includes(tech.toLowerCase()))
|
|
176
210
|
}
|
|
177
211
|
|
|
178
212
|
/**
|
|
179
213
|
* Calculate agent usefulness score
|
|
180
214
|
*/
|
|
181
|
-
calculateUsefulness(agent) {
|
|
215
|
+
calculateUsefulness(agent: Agent): number {
|
|
182
216
|
let score = 0
|
|
183
217
|
|
|
184
218
|
// Has skills
|
|
@@ -213,5 +247,4 @@ class AgentValidator {
|
|
|
213
247
|
}
|
|
214
248
|
}
|
|
215
249
|
|
|
216
|
-
|
|
217
|
-
|
|
250
|
+
export default AgentValidator
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
const fs = require('fs').promises
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const { promisify } = require('util')
|
|
4
|
-
const { exec: execCallback } = require('child_process')
|
|
5
|
-
const exec = promisify(execCallback)
|
|
6
|
-
|
|
7
1
|
/**
|
|
8
2
|
* CodebaseAnalyzer - Provides helpers for project analysis
|
|
9
3
|
*
|
|
@@ -15,26 +9,56 @@ const exec = promisify(execCallback)
|
|
|
15
9
|
*
|
|
16
10
|
* @version 0.6.0 - Fully agentic refactor
|
|
17
11
|
*/
|
|
12
|
+
|
|
13
|
+
import fs from 'fs/promises'
|
|
14
|
+
import path from 'path'
|
|
15
|
+
import { promisify } from 'util'
|
|
16
|
+
import { exec as execCallback } from 'child_process'
|
|
17
|
+
|
|
18
|
+
const exec = promisify(execCallback)
|
|
19
|
+
|
|
20
|
+
interface PackageJson {
|
|
21
|
+
name?: string
|
|
22
|
+
version?: string
|
|
23
|
+
dependencies?: Record<string, string>
|
|
24
|
+
devDependencies?: Record<string, string>
|
|
25
|
+
scripts?: Record<string, string>
|
|
26
|
+
[key: string]: unknown
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface ComposerJson {
|
|
30
|
+
name?: string
|
|
31
|
+
require?: Record<string, string>
|
|
32
|
+
'require-dev'?: Record<string, string>
|
|
33
|
+
[key: string]: unknown
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface GitStats {
|
|
37
|
+
totalCommits: number
|
|
38
|
+
contributors: number
|
|
39
|
+
age: string
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface FileExtensions {
|
|
43
|
+
[extension: string]: number
|
|
44
|
+
}
|
|
45
|
+
|
|
18
46
|
class CodebaseAnalyzer {
|
|
19
|
-
|
|
20
|
-
this.projectPath = null
|
|
21
|
-
}
|
|
47
|
+
projectPath: string | null = null
|
|
22
48
|
|
|
23
49
|
/**
|
|
24
50
|
* Initialize analyzer for a project
|
|
25
|
-
* @param {string} projectPath - Project path
|
|
26
51
|
*/
|
|
27
|
-
init(projectPath = process.cwd()) {
|
|
52
|
+
init(projectPath: string = process.cwd()): void {
|
|
28
53
|
this.projectPath = projectPath
|
|
29
54
|
}
|
|
30
55
|
|
|
31
56
|
/**
|
|
32
57
|
* Read package.json if it exists
|
|
33
|
-
* @returns {Promise<Object|null>}
|
|
34
58
|
*/
|
|
35
|
-
async readPackageJson() {
|
|
59
|
+
async readPackageJson(): Promise<PackageJson | null> {
|
|
36
60
|
try {
|
|
37
|
-
const packagePath = path.join(this.projectPath
|
|
61
|
+
const packagePath = path.join(this.projectPath!, 'package.json')
|
|
38
62
|
const content = await fs.readFile(packagePath, 'utf-8')
|
|
39
63
|
return JSON.parse(content)
|
|
40
64
|
} catch {
|
|
@@ -44,11 +68,10 @@ class CodebaseAnalyzer {
|
|
|
44
68
|
|
|
45
69
|
/**
|
|
46
70
|
* Read Cargo.toml if it exists
|
|
47
|
-
* @returns {Promise<string|null>}
|
|
48
71
|
*/
|
|
49
|
-
async readCargoToml() {
|
|
72
|
+
async readCargoToml(): Promise<string | null> {
|
|
50
73
|
try {
|
|
51
|
-
const cargoPath = path.join(this.projectPath
|
|
74
|
+
const cargoPath = path.join(this.projectPath!, 'Cargo.toml')
|
|
52
75
|
return await fs.readFile(cargoPath, 'utf-8')
|
|
53
76
|
} catch {
|
|
54
77
|
return null
|
|
@@ -57,11 +80,10 @@ class CodebaseAnalyzer {
|
|
|
57
80
|
|
|
58
81
|
/**
|
|
59
82
|
* Read requirements.txt if it exists
|
|
60
|
-
* @returns {Promise<string|null>}
|
|
61
83
|
*/
|
|
62
|
-
async readRequirements() {
|
|
84
|
+
async readRequirements(): Promise<string | null> {
|
|
63
85
|
try {
|
|
64
|
-
const reqPath = path.join(this.projectPath
|
|
86
|
+
const reqPath = path.join(this.projectPath!, 'requirements.txt')
|
|
65
87
|
return await fs.readFile(reqPath, 'utf-8')
|
|
66
88
|
} catch {
|
|
67
89
|
return null
|
|
@@ -70,11 +92,10 @@ class CodebaseAnalyzer {
|
|
|
70
92
|
|
|
71
93
|
/**
|
|
72
94
|
* Read go.mod if it exists
|
|
73
|
-
* @returns {Promise<string|null>}
|
|
74
95
|
*/
|
|
75
|
-
async readGoMod() {
|
|
96
|
+
async readGoMod(): Promise<string | null> {
|
|
76
97
|
try {
|
|
77
|
-
const goModPath = path.join(this.projectPath
|
|
98
|
+
const goModPath = path.join(this.projectPath!, 'go.mod')
|
|
78
99
|
return await fs.readFile(goModPath, 'utf-8')
|
|
79
100
|
} catch {
|
|
80
101
|
return null
|
|
@@ -83,11 +104,10 @@ class CodebaseAnalyzer {
|
|
|
83
104
|
|
|
84
105
|
/**
|
|
85
106
|
* Read Gemfile if it exists (Ruby)
|
|
86
|
-
* @returns {Promise<string|null>}
|
|
87
107
|
*/
|
|
88
|
-
async readGemfile() {
|
|
108
|
+
async readGemfile(): Promise<string | null> {
|
|
89
109
|
try {
|
|
90
|
-
const gemfilePath = path.join(this.projectPath
|
|
110
|
+
const gemfilePath = path.join(this.projectPath!, 'Gemfile')
|
|
91
111
|
return await fs.readFile(gemfilePath, 'utf-8')
|
|
92
112
|
} catch {
|
|
93
113
|
return null
|
|
@@ -96,11 +116,10 @@ class CodebaseAnalyzer {
|
|
|
96
116
|
|
|
97
117
|
/**
|
|
98
118
|
* Read mix.exs if it exists (Elixir)
|
|
99
|
-
* @returns {Promise<string|null>}
|
|
100
119
|
*/
|
|
101
|
-
async readMixExs() {
|
|
120
|
+
async readMixExs(): Promise<string | null> {
|
|
102
121
|
try {
|
|
103
|
-
const mixPath = path.join(this.projectPath
|
|
122
|
+
const mixPath = path.join(this.projectPath!, 'mix.exs')
|
|
104
123
|
return await fs.readFile(mixPath, 'utf-8')
|
|
105
124
|
} catch {
|
|
106
125
|
return null
|
|
@@ -109,11 +128,10 @@ class CodebaseAnalyzer {
|
|
|
109
128
|
|
|
110
129
|
/**
|
|
111
130
|
* Read pom.xml if it exists (Java/Maven)
|
|
112
|
-
* @returns {Promise<string|null>}
|
|
113
131
|
*/
|
|
114
|
-
async readPomXml() {
|
|
132
|
+
async readPomXml(): Promise<string | null> {
|
|
115
133
|
try {
|
|
116
|
-
const pomPath = path.join(this.projectPath
|
|
134
|
+
const pomPath = path.join(this.projectPath!, 'pom.xml')
|
|
117
135
|
return await fs.readFile(pomPath, 'utf-8')
|
|
118
136
|
} catch {
|
|
119
137
|
return null
|
|
@@ -122,11 +140,10 @@ class CodebaseAnalyzer {
|
|
|
122
140
|
|
|
123
141
|
/**
|
|
124
142
|
* Read composer.json if it exists (PHP)
|
|
125
|
-
* @returns {Promise<Object|null>}
|
|
126
143
|
*/
|
|
127
|
-
async readComposerJson() {
|
|
144
|
+
async readComposerJson(): Promise<ComposerJson | null> {
|
|
128
145
|
try {
|
|
129
|
-
const composerPath = path.join(this.projectPath
|
|
146
|
+
const composerPath = path.join(this.projectPath!, 'composer.json')
|
|
130
147
|
const content = await fs.readFile(composerPath, 'utf-8')
|
|
131
148
|
return JSON.parse(content)
|
|
132
149
|
} catch {
|
|
@@ -136,11 +153,10 @@ class CodebaseAnalyzer {
|
|
|
136
153
|
|
|
137
154
|
/**
|
|
138
155
|
* Read pyproject.toml if it exists (Python)
|
|
139
|
-
* @returns {Promise<string|null>}
|
|
140
156
|
*/
|
|
141
|
-
async readPyprojectToml() {
|
|
157
|
+
async readPyprojectToml(): Promise<string | null> {
|
|
142
158
|
try {
|
|
143
|
-
const pyprojectPath = path.join(this.projectPath
|
|
159
|
+
const pyprojectPath = path.join(this.projectPath!, 'pyproject.toml')
|
|
144
160
|
return await fs.readFile(pyprojectPath, 'utf-8')
|
|
145
161
|
} catch {
|
|
146
162
|
return null
|
|
@@ -150,21 +166,24 @@ class CodebaseAnalyzer {
|
|
|
150
166
|
/**
|
|
151
167
|
* Get all file extensions in project with counts
|
|
152
168
|
* I/O PURO - Solo cuenta, no interpreta
|
|
153
|
-
* @returns {Promise<Object>} - {'.js': 45, '.ts': 23, ...}
|
|
154
169
|
*/
|
|
155
|
-
async getFileExtensions() {
|
|
170
|
+
async getFileExtensions(): Promise<FileExtensions> {
|
|
156
171
|
try {
|
|
157
172
|
const { stdout } = await exec(
|
|
158
173
|
'find . -type f ! -path "*/node_modules/*" ! -path "*/.git/*" ! -path "*/dist/*" ! -path "*/.next/*" | sed "s/.*\\./\\./" | sort | uniq -c | sort -rn',
|
|
159
|
-
{ cwd: this.projectPath }
|
|
174
|
+
{ cwd: this.projectPath! }
|
|
160
175
|
)
|
|
161
|
-
const extensions = {}
|
|
162
|
-
stdout
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
176
|
+
const extensions: FileExtensions = {}
|
|
177
|
+
stdout
|
|
178
|
+
.trim()
|
|
179
|
+
.split('\n')
|
|
180
|
+
.filter(Boolean)
|
|
181
|
+
.forEach((line) => {
|
|
182
|
+
const match = line.trim().match(/^\s*(\d+)\s+(\.\w+)$/)
|
|
183
|
+
if (match) {
|
|
184
|
+
extensions[match[2]] = parseInt(match[1])
|
|
185
|
+
}
|
|
186
|
+
})
|
|
168
187
|
return extensions
|
|
169
188
|
} catch {
|
|
170
189
|
return {}
|
|
@@ -174,11 +193,10 @@ class CodebaseAnalyzer {
|
|
|
174
193
|
/**
|
|
175
194
|
* List all config files in project root
|
|
176
195
|
* I/O PURO - Solo lista, no categoriza
|
|
177
|
-
* @returns {Promise<string[]>}
|
|
178
196
|
*/
|
|
179
|
-
async listConfigFiles() {
|
|
197
|
+
async listConfigFiles(): Promise<string[]> {
|
|
180
198
|
try {
|
|
181
|
-
const entries = await fs.readdir(this.projectPath)
|
|
199
|
+
const entries = await fs.readdir(this.projectPath!)
|
|
182
200
|
const configPatterns = [
|
|
183
201
|
/^package\.json$/,
|
|
184
202
|
/^Cargo\.toml$/,
|
|
@@ -195,9 +213,7 @@ class CodebaseAnalyzer {
|
|
|
195
213
|
/^docker-compose.*\.ya?ml$/,
|
|
196
214
|
/^\.env.*$/,
|
|
197
215
|
]
|
|
198
|
-
return entries.filter(entry =>
|
|
199
|
-
configPatterns.some(pattern => pattern.test(entry))
|
|
200
|
-
)
|
|
216
|
+
return entries.filter((entry) => configPatterns.some((pattern) => pattern.test(entry)))
|
|
201
217
|
} catch {
|
|
202
218
|
return []
|
|
203
219
|
}
|
|
@@ -205,11 +221,10 @@ class CodebaseAnalyzer {
|
|
|
205
221
|
|
|
206
222
|
/**
|
|
207
223
|
* List all directories in project root
|
|
208
|
-
* @returns {Promise<string[]>}
|
|
209
224
|
*/
|
|
210
|
-
async listDirectories() {
|
|
225
|
+
async listDirectories(): Promise<string[]> {
|
|
211
226
|
try {
|
|
212
|
-
const entries = await fs.readdir(this.projectPath
|
|
227
|
+
const entries = await fs.readdir(this.projectPath!, { withFileTypes: true })
|
|
213
228
|
return entries
|
|
214
229
|
.filter((entry) => entry.isDirectory())
|
|
215
230
|
.map((entry) => entry.name)
|
|
@@ -221,13 +236,11 @@ class CodebaseAnalyzer {
|
|
|
221
236
|
|
|
222
237
|
/**
|
|
223
238
|
* Get git log (last N commits)
|
|
224
|
-
* @param {number} limit - Number of commits
|
|
225
|
-
* @returns {Promise<string>}
|
|
226
239
|
*/
|
|
227
|
-
async getGitLog(limit = 50) {
|
|
240
|
+
async getGitLog(limit: number = 50): Promise<string> {
|
|
228
241
|
try {
|
|
229
242
|
const { stdout } = await exec(`git log -n ${limit} --pretty=format:"%h|%an|%ar|%s"`, {
|
|
230
|
-
cwd: this.projectPath
|
|
243
|
+
cwd: this.projectPath!,
|
|
231
244
|
})
|
|
232
245
|
return stdout
|
|
233
246
|
} catch {
|
|
@@ -237,22 +250,20 @@ class CodebaseAnalyzer {
|
|
|
237
250
|
|
|
238
251
|
/**
|
|
239
252
|
* Get git statistics
|
|
240
|
-
* @returns {Promise<Object>}
|
|
241
253
|
*/
|
|
242
|
-
async getGitStats() {
|
|
254
|
+
async getGitStats(): Promise<GitStats> {
|
|
243
255
|
try {
|
|
244
256
|
const { stdout: totalCommits } = await exec('git rev-list --count HEAD', {
|
|
245
|
-
cwd: this.projectPath
|
|
257
|
+
cwd: this.projectPath!,
|
|
246
258
|
})
|
|
247
259
|
|
|
248
260
|
const { stdout: contributors } = await exec('git log --format="%an" | sort -u | wc -l', {
|
|
249
|
-
cwd: this.projectPath
|
|
261
|
+
cwd: this.projectPath!,
|
|
250
262
|
})
|
|
251
263
|
|
|
252
|
-
const { stdout: firstCommit } = await exec(
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
)
|
|
264
|
+
const { stdout: firstCommit } = await exec('git log --reverse --pretty=format:"%ar" | head -1', {
|
|
265
|
+
cwd: this.projectPath!,
|
|
266
|
+
})
|
|
256
267
|
|
|
257
268
|
return {
|
|
258
269
|
totalCommits: parseInt(totalCommits.trim()) || 0,
|
|
@@ -270,13 +281,12 @@ class CodebaseAnalyzer {
|
|
|
270
281
|
|
|
271
282
|
/**
|
|
272
283
|
* Count total files (excluding common ignore patterns)
|
|
273
|
-
* @returns {Promise<number>}
|
|
274
284
|
*/
|
|
275
|
-
async countFiles() {
|
|
285
|
+
async countFiles(): Promise<number> {
|
|
276
286
|
try {
|
|
277
287
|
const { stdout } = await exec(
|
|
278
288
|
'find . -type f ! -path "*/node_modules/*" ! -path "*/.git/*" ! -path "*/dist/*" | wc -l',
|
|
279
|
-
{ cwd: this.projectPath }
|
|
289
|
+
{ cwd: this.projectPath! }
|
|
280
290
|
)
|
|
281
291
|
return parseInt(stdout.trim()) || 0
|
|
282
292
|
} catch {
|
|
@@ -286,12 +296,10 @@ class CodebaseAnalyzer {
|
|
|
286
296
|
|
|
287
297
|
/**
|
|
288
298
|
* Check if file exists
|
|
289
|
-
* @param {string} filename - Filename to check
|
|
290
|
-
* @returns {Promise<boolean>}
|
|
291
299
|
*/
|
|
292
|
-
async fileExists(filename) {
|
|
300
|
+
async fileExists(filename: string): Promise<boolean> {
|
|
293
301
|
try {
|
|
294
|
-
await fs.access(path.join(this.projectPath
|
|
302
|
+
await fs.access(path.join(this.projectPath!, filename))
|
|
295
303
|
return true
|
|
296
304
|
} catch {
|
|
297
305
|
return false
|
|
@@ -300,12 +308,10 @@ class CodebaseAnalyzer {
|
|
|
300
308
|
|
|
301
309
|
/**
|
|
302
310
|
* Read any file in the project
|
|
303
|
-
* @param {string} relativePath - Path relative to project root
|
|
304
|
-
* @returns {Promise<string|null>}
|
|
305
311
|
*/
|
|
306
|
-
async readFile(relativePath) {
|
|
312
|
+
async readFile(relativePath: string): Promise<string | null> {
|
|
307
313
|
try {
|
|
308
|
-
const fullPath = path.join(this.projectPath
|
|
314
|
+
const fullPath = path.join(this.projectPath!, relativePath)
|
|
309
315
|
return await fs.readFile(fullPath, 'utf-8')
|
|
310
316
|
} catch {
|
|
311
317
|
return null
|
|
@@ -314,14 +320,12 @@ class CodebaseAnalyzer {
|
|
|
314
320
|
|
|
315
321
|
/**
|
|
316
322
|
* Find files matching a pattern
|
|
317
|
-
* @param {string} pattern - Glob pattern
|
|
318
|
-
* @returns {Promise<string[]>}
|
|
319
323
|
*/
|
|
320
|
-
async findFiles(pattern) {
|
|
324
|
+
async findFiles(pattern: string): Promise<string[]> {
|
|
321
325
|
try {
|
|
322
326
|
const { stdout } = await exec(
|
|
323
327
|
`find . -type f -name "${pattern}" ! -path "*/node_modules/*" ! -path "*/.git/*"`,
|
|
324
|
-
{ cwd: this.projectPath }
|
|
328
|
+
{ cwd: this.projectPath! }
|
|
325
329
|
)
|
|
326
330
|
return stdout.trim().split('\n').filter(Boolean)
|
|
327
331
|
} catch {
|
|
@@ -330,4 +334,6 @@ class CodebaseAnalyzer {
|
|
|
330
334
|
}
|
|
331
335
|
}
|
|
332
336
|
|
|
333
|
-
|
|
337
|
+
const analyzer = new CodebaseAnalyzer()
|
|
338
|
+
export default analyzer
|
|
339
|
+
export { CodebaseAnalyzer }
|