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
package/bin/prjct
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* prjct CLI entry point
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* Auto-setup on first use (like Astro, Vite, etc.)
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
const { VERSION } = require('../core/utils/version')
|
|
10
|
-
const editorsConfig = require('../core/infrastructure/editors-config')
|
|
9
|
+
const { VERSION } = require('../core/utils/version.ts')
|
|
10
|
+
const editorsConfig = require('../core/infrastructure/editors-config.ts').default
|
|
11
11
|
|
|
12
12
|
// Check for special subcommands that bypass normal CLI
|
|
13
13
|
const args = process.argv.slice(2)
|
|
@@ -31,7 +31,7 @@ if (args[0] === 'dev') {
|
|
|
31
31
|
console.log('🔧 One-time setup (v' + VERSION + ')...')
|
|
32
32
|
console.log('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n')
|
|
33
33
|
|
|
34
|
-
const setup = require('../core/infrastructure/setup')
|
|
34
|
+
const setup = require('../core/infrastructure/setup.ts').default
|
|
35
35
|
await setup.run()
|
|
36
36
|
|
|
37
37
|
console.log('✓ Setup complete!\n')
|
|
@@ -42,7 +42,7 @@ if (args[0] === 'dev') {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
// Continue to main CLI logic
|
|
45
|
-
require('../core/index')
|
|
45
|
+
require('../core/index.ts')
|
|
46
46
|
})()
|
|
47
47
|
|
|
48
48
|
} // end else
|
package/bin/serve.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* prjct serve - Start the web server
|
|
@@ -6,16 +6,21 @@
|
|
|
6
6
|
* Launches the prjct web interface with Claude Code CLI integration.
|
|
7
7
|
* Uses your existing Claude subscription via PTY - no API costs!
|
|
8
8
|
*
|
|
9
|
-
*
|
|
9
|
+
* Smart dependency management:
|
|
10
|
+
* - Tracks installed version in .prjct-web-state.json
|
|
11
|
+
* - Only installs when version changes or node_modules missing
|
|
12
|
+
* - Reuses existing prjct-web server if already running on port
|
|
10
13
|
*/
|
|
11
14
|
|
|
12
|
-
const { spawn, spawnSync } = require('child_process')
|
|
15
|
+
const { spawn, spawnSync, execSync } = require('child_process')
|
|
13
16
|
const path = require('path')
|
|
14
17
|
const fs = require('fs')
|
|
15
18
|
|
|
16
19
|
const packagesDir = path.join(__dirname, '..', 'packages')
|
|
17
20
|
const sharedDir = path.join(packagesDir, 'shared')
|
|
18
21
|
const webDir = path.join(packagesDir, 'web')
|
|
22
|
+
const prjctDir = path.join(require('os').homedir(), '.prjct-cli')
|
|
23
|
+
const stateFile = path.join(prjctDir, '.prjct-web-state.json')
|
|
19
24
|
|
|
20
25
|
// Parse arguments
|
|
21
26
|
const args = process.argv.slice(2)
|
|
@@ -30,26 +35,123 @@ if (!fs.existsSync(webDir)) {
|
|
|
30
35
|
process.exit(1)
|
|
31
36
|
}
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Read the current state file
|
|
40
|
+
*/
|
|
41
|
+
function readState() {
|
|
42
|
+
try {
|
|
43
|
+
if (fs.existsSync(stateFile)) {
|
|
44
|
+
return JSON.parse(fs.readFileSync(stateFile, 'utf8'))
|
|
45
|
+
}
|
|
46
|
+
} catch {
|
|
47
|
+
// Ignore errors, return empty state
|
|
48
|
+
}
|
|
49
|
+
return {}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Write state file
|
|
54
|
+
*/
|
|
55
|
+
function writeState(state) {
|
|
56
|
+
try {
|
|
57
|
+
// Ensure ~/.prjct-cli directory exists
|
|
58
|
+
if (!fs.existsSync(prjctDir)) {
|
|
59
|
+
fs.mkdirSync(prjctDir, { recursive: true })
|
|
60
|
+
}
|
|
61
|
+
fs.writeFileSync(stateFile, JSON.stringify(state, null, 2))
|
|
62
|
+
} catch {
|
|
63
|
+
// Ignore write errors
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Get package.json version and hash of dependencies
|
|
69
|
+
*/
|
|
70
|
+
function getPackageInfo(pkgPath) {
|
|
71
|
+
try {
|
|
72
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(pkgPath, 'package.json'), 'utf8'))
|
|
73
|
+
const deps = JSON.stringify(pkg.dependencies || {}) + JSON.stringify(pkg.devDependencies || {})
|
|
74
|
+
// Simple hash of dependencies
|
|
75
|
+
let hash = 0
|
|
76
|
+
for (let i = 0; i < deps.length; i++) {
|
|
77
|
+
const char = deps.charCodeAt(i)
|
|
78
|
+
hash = ((hash << 5) - hash) + char
|
|
79
|
+
hash = hash & hash // Convert to 32bit integer
|
|
80
|
+
}
|
|
81
|
+
return { version: pkg.version, depsHash: hash.toString(16) }
|
|
82
|
+
} catch {
|
|
83
|
+
return { version: '0.0.0', depsHash: '0' }
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Check if dependencies need to be installed
|
|
89
|
+
*/
|
|
90
|
+
function needsInstall(pkgDir, stateKey) {
|
|
91
|
+
const nodeModules = path.join(pkgDir, 'node_modules')
|
|
92
|
+
|
|
93
|
+
// If node_modules doesn't exist, definitely need install
|
|
94
|
+
if (!fs.existsSync(nodeModules)) {
|
|
95
|
+
return { needed: true, reason: 'node_modules not found' }
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const state = readState()
|
|
99
|
+
const pkgInfo = getPackageInfo(pkgDir)
|
|
100
|
+
const savedInfo = state[stateKey]
|
|
101
|
+
|
|
102
|
+
// If no saved state, need install to track
|
|
103
|
+
if (!savedInfo) {
|
|
104
|
+
return { needed: true, reason: 'first time tracking' }
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// If version changed, need install
|
|
108
|
+
if (savedInfo.version !== pkgInfo.version) {
|
|
109
|
+
return { needed: true, reason: `version changed: ${savedInfo.version} → ${pkgInfo.version}` }
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// If dependencies hash changed, need install
|
|
113
|
+
if (savedInfo.depsHash !== pkgInfo.depsHash) {
|
|
114
|
+
return { needed: true, reason: 'dependencies changed' }
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return { needed: false }
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Update state after successful install
|
|
122
|
+
*/
|
|
123
|
+
function markInstalled(pkgDir, stateKey) {
|
|
124
|
+
const state = readState()
|
|
125
|
+
const pkgInfo = getPackageInfo(pkgDir)
|
|
126
|
+
state[stateKey] = {
|
|
127
|
+
version: pkgInfo.version,
|
|
128
|
+
depsHash: pkgInfo.depsHash,
|
|
129
|
+
installedAt: new Date().toISOString()
|
|
130
|
+
}
|
|
131
|
+
writeState(state)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Check if dependencies need installation
|
|
135
|
+
const sharedCheck = fs.existsSync(sharedDir) ? needsInstall(sharedDir, 'shared') : { needed: false }
|
|
136
|
+
const webCheck = needsInstall(webDir, 'web')
|
|
137
|
+
|
|
138
|
+
if (sharedCheck.needed || webCheck.needed) {
|
|
139
|
+
const reasons = []
|
|
140
|
+
if (sharedCheck.needed) reasons.push(`shared: ${sharedCheck.reason}`)
|
|
141
|
+
if (webCheck.needed) reasons.push(`web: ${webCheck.reason}`)
|
|
38
142
|
|
|
39
|
-
if (needsSharedInstall || needsWebInstall) {
|
|
40
143
|
console.log(`
|
|
41
144
|
╔═══════════════════════════════════════════════════════════╗
|
|
42
145
|
║ ║
|
|
43
|
-
║ ⚡ prjct -
|
|
146
|
+
║ ⚡ prjct - Dependency Update ║
|
|
44
147
|
║ ║
|
|
45
|
-
║
|
|
46
|
-
║ This only happens once. ║
|
|
148
|
+
║ ${reasons.join(', ').substring(0, 45).padEnd(45)} ║
|
|
47
149
|
║ ║
|
|
48
150
|
╚═══════════════════════════════════════════════════════════╝
|
|
49
151
|
`)
|
|
50
152
|
|
|
51
|
-
// Install shared dependencies first (if
|
|
52
|
-
if (
|
|
153
|
+
// Install shared dependencies first (if needed)
|
|
154
|
+
if (sharedCheck.needed) {
|
|
53
155
|
console.log('📦 Installing packages/shared dependencies...')
|
|
54
156
|
const sharedInstall = spawnSync('npm', ['install'], {
|
|
55
157
|
cwd: sharedDir,
|
|
@@ -73,10 +175,12 @@ if (needsSharedInstall || needsWebInstall) {
|
|
|
73
175
|
if (sharedBuild.status !== 0) {
|
|
74
176
|
console.error('⚠️ Warning: Failed to build shared package')
|
|
75
177
|
}
|
|
178
|
+
|
|
179
|
+
markInstalled(sharedDir, 'shared')
|
|
76
180
|
}
|
|
77
181
|
|
|
78
|
-
// Install web dependencies
|
|
79
|
-
if (
|
|
182
|
+
// Install web dependencies (if needed)
|
|
183
|
+
if (webCheck.needed) {
|
|
80
184
|
console.log('📦 Installing packages/web dependencies...')
|
|
81
185
|
const webInstall = spawnSync('npm', ['install'], {
|
|
82
186
|
cwd: webDir,
|
|
@@ -88,55 +192,133 @@ if (needsSharedInstall || needsWebInstall) {
|
|
|
88
192
|
console.error('❌ Failed to install web dependencies')
|
|
89
193
|
process.exit(1)
|
|
90
194
|
}
|
|
195
|
+
|
|
196
|
+
markInstalled(webDir, 'web')
|
|
91
197
|
}
|
|
92
198
|
|
|
93
|
-
console.log('✅ Dependencies
|
|
199
|
+
console.log('✅ Dependencies ready!\n')
|
|
200
|
+
} else {
|
|
201
|
+
console.log('✅ Dependencies up to date\n')
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Check if process on port is a prjct-web server
|
|
206
|
+
*/
|
|
207
|
+
function isPrjctWebProcess(pid) {
|
|
208
|
+
try {
|
|
209
|
+
if (process.platform === 'win32') {
|
|
210
|
+
const result = spawnSync('wmic', ['process', 'where', `processid=${pid}`, 'get', 'commandline'], {
|
|
211
|
+
shell: true,
|
|
212
|
+
encoding: 'utf8',
|
|
213
|
+
})
|
|
214
|
+
return result.stdout.includes('server.ts') || result.stdout.includes('prjct')
|
|
215
|
+
} else {
|
|
216
|
+
// macOS / Linux - check process command line
|
|
217
|
+
const result = spawnSync('ps', ['-p', pid, '-o', 'command='], {
|
|
218
|
+
shell: true,
|
|
219
|
+
encoding: 'utf8',
|
|
220
|
+
})
|
|
221
|
+
const cmd = result.stdout.trim()
|
|
222
|
+
return cmd.includes('server.ts') || cmd.includes('prjct') || cmd.includes('next')
|
|
223
|
+
}
|
|
224
|
+
} catch {
|
|
225
|
+
return false
|
|
226
|
+
}
|
|
94
227
|
}
|
|
95
228
|
|
|
96
|
-
|
|
97
|
-
|
|
229
|
+
/**
|
|
230
|
+
* Get PIDs using a port
|
|
231
|
+
*/
|
|
232
|
+
function getPortPids(portToCheck) {
|
|
98
233
|
try {
|
|
99
234
|
if (process.platform === 'win32') {
|
|
100
|
-
// Windows
|
|
101
235
|
const result = spawnSync('netstat', ['-ano'], { shell: true, encoding: 'utf8' })
|
|
236
|
+
const pids = []
|
|
102
237
|
const lines = result.stdout.split('\n')
|
|
103
238
|
for (const line of lines) {
|
|
104
|
-
if (line.includes(`:${
|
|
239
|
+
if (line.includes(`:${portToCheck}`) && line.includes('LISTENING')) {
|
|
105
240
|
const parts = line.trim().split(/\s+/)
|
|
106
241
|
const pid = parts[parts.length - 1]
|
|
107
|
-
if (pid && pid !== '0')
|
|
108
|
-
spawnSync('taskkill', ['/F', '/PID', pid], { shell: true })
|
|
109
|
-
}
|
|
242
|
+
if (pid && pid !== '0') pids.push(pid)
|
|
110
243
|
}
|
|
111
244
|
}
|
|
245
|
+
return pids
|
|
112
246
|
} else {
|
|
113
|
-
|
|
114
|
-
const result = spawnSync('lsof', ['-ti', `:${portToKill}`], {
|
|
247
|
+
const result = spawnSync('lsof', ['-ti', `:${portToCheck}`], {
|
|
115
248
|
shell: true,
|
|
116
249
|
encoding: 'utf8',
|
|
117
250
|
})
|
|
118
|
-
|
|
119
|
-
|
|
251
|
+
return result.stdout.trim().split('\n').filter(Boolean)
|
|
252
|
+
}
|
|
253
|
+
} catch {
|
|
254
|
+
return []
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Kill specific PIDs
|
|
260
|
+
*/
|
|
261
|
+
function killPids(pids) {
|
|
262
|
+
for (const pid of pids) {
|
|
263
|
+
try {
|
|
264
|
+
if (process.platform === 'win32') {
|
|
265
|
+
spawnSync('taskkill', ['/F', '/PID', pid], { shell: true })
|
|
266
|
+
} else {
|
|
120
267
|
spawnSync('kill', ['-9', pid], { shell: true })
|
|
121
268
|
}
|
|
269
|
+
} catch {
|
|
270
|
+
// Ignore individual kill errors
|
|
122
271
|
}
|
|
123
|
-
} catch {
|
|
124
|
-
// Ignore errors - port might not be in use
|
|
125
272
|
}
|
|
126
273
|
}
|
|
127
274
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
275
|
+
/**
|
|
276
|
+
* Open URL in browser
|
|
277
|
+
*/
|
|
278
|
+
function openBrowser(url) {
|
|
279
|
+
const openCmd =
|
|
280
|
+
process.platform === 'darwin'
|
|
281
|
+
? 'open'
|
|
282
|
+
: process.platform === 'win32'
|
|
283
|
+
? 'start'
|
|
284
|
+
: 'xdg-open'
|
|
285
|
+
spawn(openCmd, [url], { shell: true, detached: true }).unref()
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Check if port is in use and handle accordingly
|
|
289
|
+
const portPids = getPortPids(port)
|
|
290
|
+
let serverAlreadyRunning = false
|
|
133
291
|
|
|
134
|
-
if (
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
292
|
+
if (portPids.length > 0) {
|
|
293
|
+
// Check if it's a prjct-web server
|
|
294
|
+
const isPrjctWeb = portPids.some(pid => isPrjctWebProcess(pid))
|
|
295
|
+
|
|
296
|
+
if (isPrjctWeb) {
|
|
297
|
+
console.log(`
|
|
298
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
299
|
+
║ ║
|
|
300
|
+
║ ⚡ prjct - Server Already Running ║
|
|
301
|
+
║ ║
|
|
302
|
+
║ Found existing prjct-web on port ${port} ║
|
|
303
|
+
║ Opening browser... ║
|
|
304
|
+
║ ║
|
|
305
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
306
|
+
`)
|
|
307
|
+
openBrowser(`http://localhost:${port}`)
|
|
308
|
+
serverAlreadyRunning = true
|
|
309
|
+
} else {
|
|
310
|
+
// Not a prjct-web process, ask before killing
|
|
311
|
+
console.log(`⚠️ Port ${port} is in use by another process.`)
|
|
312
|
+
console.log(` PIDs: ${portPids.join(', ')}`)
|
|
313
|
+
console.log(` Stopping to avoid killing unrelated processes.`)
|
|
314
|
+
console.log(` Use --port=XXXX to specify a different port.`)
|
|
315
|
+
process.exit(1)
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// If server is already running, we're done - just opened browser above
|
|
320
|
+
if (serverAlreadyRunning) {
|
|
321
|
+
process.exit(0)
|
|
140
322
|
}
|
|
141
323
|
|
|
142
324
|
console.log(`
|
|
@@ -144,7 +326,7 @@ console.log(`
|
|
|
144
326
|
║ ║
|
|
145
327
|
║ ⚡ prjct - Developer Momentum ║
|
|
146
328
|
║ ║
|
|
147
|
-
║
|
|
329
|
+
║ Starting production server... ║
|
|
148
330
|
║ ║
|
|
149
331
|
║ Web: http://localhost:${port} ║
|
|
150
332
|
║ ║
|
|
@@ -153,7 +335,7 @@ console.log(`
|
|
|
153
335
|
╚═══════════════════════════════════════════════════════════╝
|
|
154
336
|
`)
|
|
155
337
|
|
|
156
|
-
// Build for production if needed (first run)
|
|
338
|
+
// Build for production if needed (first run or .next missing)
|
|
157
339
|
const nextDir = path.join(webDir, '.next')
|
|
158
340
|
if (!fs.existsSync(nextDir)) {
|
|
159
341
|
console.log('🔨 Building for production (first run)...\n')
|
|
@@ -179,13 +361,7 @@ const web = spawn('npm', ['run', 'start:prod'], {
|
|
|
179
361
|
|
|
180
362
|
// Open browser after a short delay
|
|
181
363
|
setTimeout(() => {
|
|
182
|
-
|
|
183
|
-
process.platform === 'darwin'
|
|
184
|
-
? 'open'
|
|
185
|
-
: process.platform === 'win32'
|
|
186
|
-
? 'start'
|
|
187
|
-
: 'xdg-open'
|
|
188
|
-
spawn(openCmd, [`http://localhost:${port}`], { shell: true })
|
|
364
|
+
openBrowser(`http://localhost:${port}`)
|
|
189
365
|
}, 3000)
|
|
190
366
|
|
|
191
367
|
// Handle shutdown
|
|
@@ -3,27 +3,21 @@
|
|
|
3
3
|
* P3.3: Semantic Memory Database
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
import { describe, it, expect, beforeEach, afterEach } from 'bun:test'
|
|
7
|
+
import memorySystem from '../../agentic/memory-system'
|
|
8
|
+
import fs from 'fs/promises'
|
|
9
|
+
import path from 'path'
|
|
10
|
+
import os from 'os'
|
|
10
11
|
|
|
11
|
-
// Generate unique project ID for each test run
|
|
12
12
|
let testCounter = 0
|
|
13
13
|
const getTestProjectId = () => `test-memory-${Date.now()}-${++testCounter}`
|
|
14
14
|
|
|
15
15
|
describe('MemorySystem P3.3', () => {
|
|
16
|
-
let TEST_PROJECT_ID
|
|
16
|
+
let TEST_PROJECT_ID: string
|
|
17
17
|
|
|
18
18
|
beforeEach(() => {
|
|
19
|
-
// Use unique project ID for each test to avoid data leakage
|
|
20
19
|
TEST_PROJECT_ID = getTestProjectId()
|
|
21
|
-
|
|
22
|
-
memorySystem._memories = null
|
|
23
|
-
memorySystem._memoriesLoaded = false
|
|
24
|
-
memorySystem._patterns = null
|
|
25
|
-
memorySystem._patternsLoaded = false
|
|
26
|
-
memorySystem._sessionMemory.clear()
|
|
20
|
+
memorySystem.resetState()
|
|
27
21
|
})
|
|
28
22
|
|
|
29
23
|
describe('createMemory', () => {
|
|
@@ -64,10 +58,10 @@ describe('MemorySystem P3.3', () => {
|
|
|
64
58
|
const memories = await memorySystem.getAllMemories(TEST_PROJECT_ID)
|
|
65
59
|
const memory = memories.find(m => m.id === memoryId)
|
|
66
60
|
|
|
67
|
-
expect(memory
|
|
68
|
-
expect(memory
|
|
69
|
-
expect(memory
|
|
70
|
-
expect(memory
|
|
61
|
+
expect(memory!.title).toBe('Updated Title')
|
|
62
|
+
expect(memory!.content).toBe('Updated content')
|
|
63
|
+
expect(memory!.tags).toContain('architecture')
|
|
64
|
+
expect(memory!.tags).not.toContain('code_style')
|
|
71
65
|
})
|
|
72
66
|
|
|
73
67
|
it('should return false for non-existent memory', async () => {
|
|
@@ -96,7 +90,6 @@ describe('MemorySystem P3.3', () => {
|
|
|
96
90
|
|
|
97
91
|
describe('findByTags', () => {
|
|
98
92
|
beforeEach(async () => {
|
|
99
|
-
// Create test memories
|
|
100
93
|
await memorySystem.createMemory(TEST_PROJECT_ID, {
|
|
101
94
|
title: 'Memory 1',
|
|
102
95
|
content: 'Content 1',
|
|
@@ -160,7 +153,6 @@ describe('MemorySystem P3.3', () => {
|
|
|
160
153
|
|
|
161
154
|
describe('getRelevantMemories', () => {
|
|
162
155
|
beforeEach(async () => {
|
|
163
|
-
// Create memories with different relevance
|
|
164
156
|
await memorySystem.createMemory(TEST_PROJECT_ID, {
|
|
165
157
|
title: 'Commit Style',
|
|
166
158
|
content: 'Use conventional commits',
|
|
@@ -184,7 +176,6 @@ describe('MemorySystem P3.3', () => {
|
|
|
184
176
|
const results = await memorySystem.getRelevantMemories(TEST_PROJECT_ID, context, 5)
|
|
185
177
|
|
|
186
178
|
expect(results.length).toBeGreaterThan(0)
|
|
187
|
-
// Ship command should prioritize commit_style and ship_workflow tags
|
|
188
179
|
const hasRelevantTags = results.some(m =>
|
|
189
180
|
m.tags.includes('commit_style') || m.tags.includes('ship_workflow')
|
|
190
181
|
)
|
|
@@ -195,9 +186,8 @@ describe('MemorySystem P3.3', () => {
|
|
|
195
186
|
const context = { commandName: 'ship', params: {} }
|
|
196
187
|
const results = await memorySystem.getRelevantMemories(TEST_PROJECT_ID, context, 5)
|
|
197
188
|
|
|
198
|
-
// User triggered should be ranked higher
|
|
199
189
|
const userTriggeredIndex = results.findIndex(m => m.userTriggered)
|
|
200
|
-
expect(userTriggeredIndex).toBeLessThanOrEqual(1)
|
|
190
|
+
expect(userTriggeredIndex).toBeLessThanOrEqual(1)
|
|
201
191
|
})
|
|
202
192
|
|
|
203
193
|
it('should limit results', async () => {
|
|
@@ -251,7 +241,6 @@ describe('MemorySystem P3.3', () => {
|
|
|
251
241
|
})
|
|
252
242
|
})
|
|
253
243
|
|
|
254
|
-
// Cleanup test directories after each test
|
|
255
244
|
afterEach(async () => {
|
|
256
245
|
try {
|
|
257
246
|
const testPath = path.join(os.homedir(), '.prjct-cli', 'projects', TEST_PROJECT_ID)
|
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
* P3.4: Plan Mode + Approval Flow
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import { describe, it, expect, beforeEach } from 'bun:test'
|
|
7
|
+
import planMode, {
|
|
8
|
+
PLAN_STATUS,
|
|
9
|
+
PLAN_REQUIRED_COMMANDS,
|
|
10
|
+
DESTRUCTIVE_COMMANDS,
|
|
11
|
+
PLANNING_TOOLS
|
|
12
|
+
} from '../../agentic/plan-mode'
|
|
8
13
|
|
|
9
14
|
describe('PlanMode P3.4', () => {
|
|
10
15
|
const TEST_PROJECT_ID = 'test-plan-mode'
|
|
11
16
|
|
|
12
17
|
beforeEach(() => {
|
|
13
|
-
// Clear any active plans
|
|
14
18
|
planMode.activePlans.clear()
|
|
15
19
|
})
|
|
16
20
|
|
|
@@ -136,8 +140,8 @@ describe('PlanMode P3.4', () => {
|
|
|
136
140
|
planMode.recordGatheredInfo(TEST_PROJECT_ID, { type: 'file', source: 'src/index.js', data: 'content' })
|
|
137
141
|
|
|
138
142
|
const plan = planMode.getActivePlan(TEST_PROJECT_ID)
|
|
139
|
-
expect(plan
|
|
140
|
-
expect(plan
|
|
143
|
+
expect(plan!.gatheredInfo.length).toBe(1)
|
|
144
|
+
expect(plan!.gatheredInfo[0].type).toBe('file')
|
|
141
145
|
})
|
|
142
146
|
})
|
|
143
147
|
|
|
@@ -151,7 +155,7 @@ describe('PlanMode P3.4', () => {
|
|
|
151
155
|
})
|
|
152
156
|
|
|
153
157
|
const plan = planMode.getActivePlan(TEST_PROJECT_ID)
|
|
154
|
-
expect(plan
|
|
158
|
+
expect(plan!.status).toBe(PLAN_STATUS.PENDING_APPROVAL)
|
|
155
159
|
})
|
|
156
160
|
|
|
157
161
|
it('should return formatted plan for display', () => {
|
|
@@ -162,9 +166,9 @@ describe('PlanMode P3.4', () => {
|
|
|
162
166
|
steps: [{ description: 'Step 1' }]
|
|
163
167
|
})
|
|
164
168
|
|
|
165
|
-
expect(formatted
|
|
166
|
-
expect(formatted
|
|
167
|
-
expect(formatted
|
|
169
|
+
expect(formatted!.summary).toBe('Test plan')
|
|
170
|
+
expect(formatted!.approach).toBe('Test approach')
|
|
171
|
+
expect(formatted!.requiresConfirmation).toBe(true)
|
|
168
172
|
})
|
|
169
173
|
})
|
|
170
174
|
|
|
@@ -174,9 +178,9 @@ describe('PlanMode P3.4', () => {
|
|
|
174
178
|
planMode.proposePlan(TEST_PROJECT_ID, { steps: [{ description: 'Step 1' }] })
|
|
175
179
|
const result = planMode.approvePlan(TEST_PROJECT_ID)
|
|
176
180
|
|
|
177
|
-
expect(result
|
|
181
|
+
expect(result!.approved).toBe(true)
|
|
178
182
|
const plan = planMode.getActivePlan(TEST_PROJECT_ID)
|
|
179
|
-
expect(plan
|
|
183
|
+
expect(plan!.status).toBe(PLAN_STATUS.APPROVED)
|
|
180
184
|
})
|
|
181
185
|
|
|
182
186
|
it('should convert proposed steps to executable steps', () => {
|
|
@@ -186,13 +190,12 @@ describe('PlanMode P3.4', () => {
|
|
|
186
190
|
})
|
|
187
191
|
const result = planMode.approvePlan(TEST_PROJECT_ID)
|
|
188
192
|
|
|
189
|
-
expect(result
|
|
190
|
-
expect(result
|
|
193
|
+
expect(result!.steps.length).toBe(2)
|
|
194
|
+
expect(result!.steps[0].status).toBe('pending')
|
|
191
195
|
})
|
|
192
196
|
|
|
193
197
|
it('should return null if not pending approval', () => {
|
|
194
198
|
planMode.startPlanning(TEST_PROJECT_ID, 'feature', {})
|
|
195
|
-
// Not proposed yet, so should return null
|
|
196
199
|
const result = planMode.approvePlan(TEST_PROJECT_ID)
|
|
197
200
|
|
|
198
201
|
expect(result).toBeNull()
|
|
@@ -205,8 +208,8 @@ describe('PlanMode P3.4', () => {
|
|
|
205
208
|
planMode.proposePlan(TEST_PROJECT_ID, { steps: [] })
|
|
206
209
|
const result = planMode.rejectPlan(TEST_PROJECT_ID, 'Not the right approach')
|
|
207
210
|
|
|
208
|
-
expect(result
|
|
209
|
-
expect(result
|
|
211
|
+
expect(result!.rejected).toBe(true)
|
|
212
|
+
expect(result!.reason).toBe('Not the right approach')
|
|
210
213
|
})
|
|
211
214
|
|
|
212
215
|
it('should clear active plan after rejection', () => {
|
|
@@ -233,17 +236,17 @@ describe('PlanMode P3.4', () => {
|
|
|
233
236
|
it('should start execution and return first step', () => {
|
|
234
237
|
const step = planMode.startExecution(TEST_PROJECT_ID)
|
|
235
238
|
|
|
236
|
-
expect(step
|
|
237
|
-
expect(step
|
|
238
|
-
expect(step
|
|
239
|
+
expect(step!.stepNumber).toBe(1)
|
|
240
|
+
expect(step!.totalSteps).toBe(2)
|
|
241
|
+
expect(step!.progress).toBe(0)
|
|
239
242
|
})
|
|
240
243
|
|
|
241
244
|
it('should advance to next step on completion', () => {
|
|
242
245
|
planMode.startExecution(TEST_PROJECT_ID)
|
|
243
246
|
const nextStep = planMode.completeStep(TEST_PROJECT_ID, { success: true })
|
|
244
247
|
|
|
245
|
-
expect(nextStep
|
|
246
|
-
expect(nextStep
|
|
248
|
+
expect(nextStep!.stepNumber).toBe(2)
|
|
249
|
+
expect(nextStep!.progress).toBe(50)
|
|
247
250
|
})
|
|
248
251
|
|
|
249
252
|
it('should complete plan when all steps done', () => {
|
|
@@ -251,7 +254,6 @@ describe('PlanMode P3.4', () => {
|
|
|
251
254
|
planMode.completeStep(TEST_PROJECT_ID)
|
|
252
255
|
const result = planMode.completeStep(TEST_PROJECT_ID)
|
|
253
256
|
|
|
254
|
-
// When all steps complete, getNextStep returns null and completePlan is called
|
|
255
257
|
expect(result).toBeNull()
|
|
256
258
|
expect(planMode.getActivePlan(TEST_PROJECT_ID)).toBeNull()
|
|
257
259
|
})
|
|
@@ -266,8 +268,8 @@ describe('PlanMode P3.4', () => {
|
|
|
266
268
|
|
|
267
269
|
const result = planMode.abortPlan(TEST_PROJECT_ID, 'User cancelled')
|
|
268
270
|
|
|
269
|
-
expect(result
|
|
270
|
-
expect(result
|
|
271
|
+
expect(result!.aborted).toBe(true)
|
|
272
|
+
expect(result!.reason).toBe('User cancelled')
|
|
271
273
|
expect(planMode.getActivePlan(TEST_PROJECT_ID)).toBeNull()
|
|
272
274
|
})
|
|
273
275
|
})
|
|
@@ -5,11 +5,11 @@
|
|
|
5
5
|
* OPTIMIZED: Tests updated to match compressed prompt structure
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { describe, it, expect, beforeEach } from '
|
|
9
|
-
import promptBuilder from '../../agentic/prompt-builder
|
|
8
|
+
import { describe, it, expect, beforeEach } from 'bun:test'
|
|
9
|
+
import promptBuilder from '../../agentic/prompt-builder'
|
|
10
10
|
|
|
11
11
|
describe('PromptBuilder', () => {
|
|
12
|
-
let builder
|
|
12
|
+
let builder: typeof promptBuilder
|
|
13
13
|
|
|
14
14
|
beforeEach(() => {
|
|
15
15
|
builder = promptBuilder
|
|
@@ -122,7 +122,6 @@ describe('PromptBuilder', () => {
|
|
|
122
122
|
|
|
123
123
|
const prompt = builder.build(template, context, state)
|
|
124
124
|
|
|
125
|
-
// Non-code commands should NOT include patterns section
|
|
126
125
|
expect(prompt).not.toContain('## PATTERNS')
|
|
127
126
|
})
|
|
128
127
|
})
|
|
@@ -143,7 +142,6 @@ describe('PromptBuilder', () => {
|
|
|
143
142
|
|
|
144
143
|
const prompt = builder.build(template, context, state)
|
|
145
144
|
|
|
146
|
-
// OPTIMIZED: New compressed format uses ## FILES:
|
|
147
145
|
expect(prompt).toContain('## FILES:')
|
|
148
146
|
expect(prompt).toContain('3 available')
|
|
149
147
|
expect(prompt).toContain('file1.js')
|
|
@@ -161,7 +159,6 @@ describe('PromptBuilder', () => {
|
|
|
161
159
|
|
|
162
160
|
const prompt = builder.build(template, context, state)
|
|
163
161
|
|
|
164
|
-
// OPTIMIZED: New compressed format uses ## PROJECT:
|
|
165
162
|
expect(prompt).toContain('## PROJECT:')
|
|
166
163
|
expect(prompt).toContain('/test/project')
|
|
167
164
|
})
|
|
@@ -191,7 +188,6 @@ describe('PromptBuilder', () => {
|
|
|
191
188
|
expect(prompt).toContain('TOOLS:')
|
|
192
189
|
expect(prompt).toContain('Flow')
|
|
193
190
|
expect(prompt).toContain('RULES (CRITICAL)')
|
|
194
|
-
// OPTIMIZED: New compressed format uses ## FILES:
|
|
195
191
|
expect(prompt).toContain('## FILES:')
|
|
196
192
|
})
|
|
197
193
|
|
|
@@ -206,7 +202,6 @@ describe('PromptBuilder', () => {
|
|
|
206
202
|
|
|
207
203
|
const prompt = builder.build(template, context, state)
|
|
208
204
|
|
|
209
|
-
// Optimized prompts should be under 2000 chars for simple cases
|
|
210
205
|
expect(prompt.length).toBeLessThan(2000)
|
|
211
206
|
})
|
|
212
207
|
})
|