prjct-cli 0.11.5 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +81 -25
- package/bin/dev.js +1 -1
- package/bin/generate-views.js +209 -0
- package/bin/migrate-to-json.js +742 -0
- package/bin/prjct +5 -5
- package/bin/serve.js +226 -50
- package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
- package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
- package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
- package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
- package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
- package/core/agentic/agent-router.ts +137 -0
- package/core/agentic/chain-of-thought.ts +228 -0
- package/core/agentic/command-executor/command-executor.ts +384 -0
- package/core/agentic/command-executor/index.ts +16 -0
- package/core/agentic/command-executor/status-signal.ts +38 -0
- package/core/agentic/command-executor/types.ts +79 -0
- package/core/agentic/command-executor.ts +8 -0
- package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
- package/core/agentic/context-filter.ts +365 -0
- package/core/agentic/ground-truth/index.ts +76 -0
- package/core/agentic/ground-truth/types.ts +33 -0
- package/core/agentic/ground-truth/utils.ts +48 -0
- package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
- package/core/agentic/ground-truth/verifiers/done.ts +75 -0
- package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
- package/core/agentic/ground-truth/verifiers/index.ts +37 -0
- package/core/agentic/ground-truth/verifiers/init.ts +52 -0
- package/core/agentic/ground-truth/verifiers/now.ts +57 -0
- package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
- package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
- package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
- package/core/agentic/ground-truth/verifiers.ts +6 -0
- package/core/agentic/ground-truth.ts +8 -0
- package/core/agentic/loop-detector/error-analysis.ts +97 -0
- package/core/agentic/loop-detector/hallucination.ts +71 -0
- package/core/agentic/loop-detector/index.ts +41 -0
- package/core/agentic/loop-detector/loop-detector.ts +222 -0
- package/core/agentic/loop-detector/types.ts +66 -0
- package/core/agentic/loop-detector.ts +8 -0
- package/core/agentic/memory-system/history.ts +53 -0
- package/core/agentic/memory-system/index.ts +192 -0
- package/core/agentic/memory-system/patterns.ts +156 -0
- package/core/agentic/memory-system/semantic-memories.ts +277 -0
- package/core/agentic/memory-system/session.ts +21 -0
- package/core/agentic/memory-system/types.ts +159 -0
- package/core/agentic/memory-system.ts +8 -0
- package/core/agentic/parallel-tools.ts +165 -0
- package/core/agentic/plan-mode/approval.ts +57 -0
- package/core/agentic/plan-mode/constants.ts +44 -0
- package/core/agentic/plan-mode/index.ts +28 -0
- package/core/agentic/plan-mode/plan-mode.ts +406 -0
- package/core/agentic/plan-mode/types.ts +193 -0
- package/core/agentic/plan-mode.ts +8 -0
- package/core/agentic/prompt-builder.ts +566 -0
- package/core/agentic/response-templates.ts +164 -0
- package/core/agentic/semantic-compression.ts +273 -0
- package/core/agentic/services.ts +206 -0
- package/core/agentic/smart-context.ts +476 -0
- package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
- package/core/agentic/think-blocks.ts +202 -0
- package/core/agentic/tool-registry.ts +119 -0
- package/core/agentic/validation-rules.ts +313 -0
- package/core/agents/index.ts +28 -0
- package/core/agents/performance.ts +444 -0
- package/core/agents/types.ts +126 -0
- package/core/bus/{index.js → index.ts} +57 -61
- package/core/command-registry/categories.ts +23 -0
- package/core/command-registry/commands.ts +15 -0
- package/core/command-registry/core-commands.ts +319 -0
- package/core/command-registry/index.ts +158 -0
- package/core/command-registry/optional-commands.ts +119 -0
- package/core/command-registry/setup-commands.ts +53 -0
- package/core/command-registry/types.ts +59 -0
- package/core/command-registry.ts +9 -0
- package/core/commands/analysis.ts +298 -0
- package/core/commands/analytics.ts +288 -0
- package/core/commands/base.ts +273 -0
- package/core/commands/index.ts +211 -0
- package/core/commands/maintenance.ts +226 -0
- package/core/commands/planning.ts +311 -0
- package/core/commands/setup.ts +309 -0
- package/core/commands/shipping.ts +188 -0
- package/core/commands/types.ts +183 -0
- package/core/commands/workflow.ts +226 -0
- package/core/commands.ts +11 -0
- package/core/constants/formats.ts +187 -0
- package/core/constants/index.ts +7 -0
- package/core/{context-sync.js → context-sync.ts} +59 -26
- package/core/data/agents-manager.ts +76 -0
- package/core/data/analysis-manager.ts +83 -0
- package/core/data/base-manager.ts +156 -0
- package/core/data/ideas-manager.ts +81 -0
- package/core/data/index.ts +32 -0
- package/core/data/outcomes-manager.ts +96 -0
- package/core/data/project-manager.ts +75 -0
- package/core/data/roadmap-manager.ts +118 -0
- package/core/data/shipped-manager.ts +65 -0
- package/core/data/state-manager.ts +214 -0
- package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
- package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
- package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
- package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
- package/core/domain/{analyzer.js → analyzer.ts} +91 -85
- package/core/domain/{architect-session.js → architect-session.ts} +49 -34
- package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
- package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
- package/core/domain/{product-standards.js → product-standards.ts} +40 -26
- package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
- package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
- package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
- package/core/domain/task-stack/index.ts +19 -0
- package/core/domain/task-stack/parser.ts +86 -0
- package/core/domain/task-stack/storage.ts +123 -0
- package/core/domain/task-stack/task-stack.ts +340 -0
- package/core/domain/task-stack/types.ts +51 -0
- package/core/domain/task-stack.ts +8 -0
- package/core/{index.js → index.ts} +61 -18
- package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
- package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
- package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
- package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
- package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
- package/core/infrastructure/command-installer/global-config.ts +106 -0
- package/core/infrastructure/command-installer/index.ts +25 -0
- package/core/infrastructure/command-installer/types.ts +41 -0
- package/core/infrastructure/command-installer.ts +8 -0
- package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
- package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
- package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
- package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
- package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
- package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
- package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
- package/core/infrastructure/legacy-installer-detector.ts +7 -0
- package/core/infrastructure/migrator/file-operations.ts +125 -0
- package/core/infrastructure/migrator/index.ts +288 -0
- package/core/infrastructure/migrator/project-scanner.ts +89 -0
- package/core/infrastructure/migrator/reports.ts +117 -0
- package/core/infrastructure/migrator/types.ts +124 -0
- package/core/infrastructure/migrator/validation.ts +94 -0
- package/core/infrastructure/migrator/version-migration.ts +117 -0
- package/core/infrastructure/migrator.ts +10 -0
- package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
- package/core/infrastructure/session-manager/index.ts +23 -0
- package/core/infrastructure/session-manager/migration.ts +88 -0
- package/core/infrastructure/session-manager/session-manager.ts +307 -0
- package/core/infrastructure/session-manager/types.ts +45 -0
- package/core/infrastructure/session-manager.ts +8 -0
- package/core/infrastructure/{setup.js → setup.ts} +29 -21
- package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
- package/core/outcomes/analyzer.ts +333 -0
- package/core/outcomes/index.ts +34 -0
- package/core/outcomes/recorder.ts +194 -0
- package/core/outcomes/types.ts +145 -0
- package/core/plugin/{hooks.js → hooks.ts} +56 -58
- package/core/plugin/{index.js → index.ts} +19 -8
- package/core/plugin/{loader.js → loader.ts} +87 -69
- package/core/plugin/{registry.js → registry.ts} +49 -45
- package/core/plugins/{webhook.js → webhook.ts} +43 -27
- package/core/schemas/agents.ts +27 -0
- package/core/schemas/analysis.ts +41 -0
- package/core/schemas/ideas.ts +83 -0
- package/core/schemas/index.ts +73 -0
- package/core/schemas/outcomes.ts +22 -0
- package/core/schemas/project.ts +26 -0
- package/core/schemas/roadmap.ts +90 -0
- package/core/schemas/shipped.ts +82 -0
- package/core/schemas/state.ts +107 -0
- package/core/session/index.ts +17 -0
- package/core/session/{metrics.js → metrics.ts} +64 -46
- package/core/session/{index.js → session-manager.ts} +51 -117
- package/core/session/types.ts +29 -0
- package/core/session/utils.ts +57 -0
- package/core/state/index.ts +25 -0
- package/core/state/manager.ts +376 -0
- package/core/state/types.ts +185 -0
- package/core/tsconfig.json +22 -0
- package/core/types/index.ts +506 -0
- package/core/utils/{animations.js → animations.ts} +74 -28
- package/core/utils/{branding.js → branding.ts} +29 -4
- package/core/utils/{date-helper.js → date-helper.ts} +31 -74
- package/core/utils/file-helper.ts +262 -0
- package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
- package/core/utils/{logger.js → logger.ts} +24 -12
- package/core/utils/{output.js → output.ts} +25 -13
- package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
- package/core/utils/{session-helper.js → session-helper.ts} +79 -66
- package/core/utils/{version.js → version.ts} +23 -31
- package/core/view-generator.ts +536 -0
- package/package.json +23 -17
- package/packages/shared/.turbo/turbo-build.log +14 -0
- package/packages/shared/dist/index.d.ts +8 -613
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +4110 -118
- package/packages/shared/dist/schemas.d.ts +408 -0
- package/packages/shared/dist/schemas.d.ts.map +1 -0
- package/packages/shared/dist/types.d.ts +144 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/unified.d.ts +139 -0
- package/packages/shared/dist/unified.d.ts.map +1 -0
- package/packages/shared/dist/utils.d.ts +60 -0
- package/packages/shared/dist/utils.d.ts.map +1 -0
- package/packages/shared/package.json +4 -4
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/unified.ts +174 -0
- package/packages/web/app/api/claude/sessions/route.ts +1 -1
- package/packages/web/app/api/claude/status/route.ts +1 -1
- package/packages/web/app/api/migrate/route.ts +46 -0
- package/packages/web/app/api/projects/[id]/route.ts +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
- package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
- package/packages/web/app/api/projects/route.ts +1 -1
- package/packages/web/app/api/settings/route.ts +97 -0
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
- package/packages/web/app/globals.css +38 -0
- package/packages/web/app/layout.tsx +10 -2
- package/packages/web/app/page.tsx +9 -224
- package/packages/web/app/project/[id]/page.tsx +191 -63
- package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
- package/packages/web/app/project/[id]/stats/page.tsx +204 -163
- package/packages/web/app/settings/page.tsx +222 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
- package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
- package/packages/web/components/ActivityTimeline/index.ts +2 -0
- package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
- package/packages/web/components/AgentsCard/index.ts +2 -0
- package/packages/web/components/AppSidebar/AppSidebar.tsx +190 -0
- package/packages/web/components/AppSidebar/index.ts +1 -0
- package/packages/web/components/BackLink/BackLink.tsx +18 -0
- package/packages/web/components/BackLink/BackLink.types.ts +5 -0
- package/packages/web/components/BackLink/index.ts +2 -0
- package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
- package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
- package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
- package/packages/web/components/BentoCard/index.ts +2 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
- package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
- package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
- package/packages/web/components/BentoGrid/index.ts +2 -0
- package/packages/web/components/CommandButton/index.ts +1 -0
- package/packages/web/components/ConnectionStatus/index.ts +1 -0
- package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
- package/packages/web/components/DashboardContent/index.ts +1 -0
- package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
- package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
- package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
- package/packages/web/components/DateGroup/index.ts +2 -0
- package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
- package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
- package/packages/web/components/EmptyState/index.ts +2 -0
- package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
- package/packages/web/components/EventRow/EventRow.tsx +49 -0
- package/packages/web/components/EventRow/EventRow.types.ts +7 -0
- package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
- package/packages/web/components/EventRow/index.ts +2 -0
- package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
- package/packages/web/components/ExpandButton/index.ts +2 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
- package/packages/web/components/HealthGradientBackground/index.ts +2 -0
- package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
- package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
- package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
- package/packages/web/components/HeroSection/hooks/index.ts +2 -0
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
- package/packages/web/components/HeroSection/index.ts +2 -0
- package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
- package/packages/web/components/IdeasCard/index.ts +2 -0
- package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
- package/packages/web/components/InsightMessage/index.ts +2 -0
- package/packages/web/components/Logo/index.ts +1 -0
- package/packages/web/components/MarkdownContent/index.ts +1 -0
- package/packages/web/components/NowCard/NowCard.tsx +93 -0
- package/packages/web/components/NowCard/NowCard.types.ts +15 -0
- package/packages/web/components/NowCard/index.ts +2 -0
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
- package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
- package/packages/web/components/ProgressRing/index.ts +2 -0
- package/packages/web/components/ProjectAvatar/index.ts +1 -0
- package/packages/web/components/Providers/index.ts +1 -0
- package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
- package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
- package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
- package/packages/web/components/QueueCard/index.ts +2 -0
- package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
- package/packages/web/components/ShipsCard/index.ts +2 -0
- package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
- package/packages/web/components/SparklineChart/index.ts +2 -0
- package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
- package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
- package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
- package/packages/web/components/StreakCard/index.ts +2 -0
- package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
- package/packages/web/components/TasksCounter/index.ts +2 -0
- package/packages/web/components/TechStackBadges/index.ts +1 -0
- package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
- package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
- package/packages/web/components/TerminalTabs/index.ts +1 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
- package/packages/web/components/VelocityBadge/index.ts +2 -0
- package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
- package/packages/web/components/VelocityCard/index.ts +2 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
- package/packages/web/components/WeeklySparkline/index.ts +2 -0
- package/packages/web/components/ui/input.tsx +21 -0
- package/packages/web/context/TerminalTabsContext.tsx +46 -1
- package/packages/web/hooks/useClaudeTerminal.ts +71 -21
- package/packages/web/hooks/useProjectStats.ts +55 -0
- package/packages/web/hooks/useProjects.ts +6 -6
- package/packages/web/lib/actions/projects.ts +15 -0
- package/packages/web/lib/json-loader.ts +630 -0
- package/packages/web/lib/services/index.ts +9 -0
- package/packages/web/lib/services/migration.server.ts +600 -0
- package/packages/web/lib/services/projects.server.ts +52 -0
- package/packages/web/lib/services/stats.server.ts +264 -0
- package/packages/web/lib/unified-loader.ts +396 -0
- package/packages/web/package.json +10 -7
- package/packages/web/server.ts +58 -8
- package/templates/commands/done.md +76 -32
- package/templates/commands/feature.md +121 -47
- package/templates/commands/idea.md +81 -8
- package/templates/commands/now.md +41 -17
- package/templates/commands/ship.md +64 -25
- package/templates/commands/sync.md +28 -3
- package/core/agentic/agent-router.js +0 -140
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -417
- package/core/agentic/context-filter.js +0 -354
- package/core/agentic/ground-truth.js +0 -591
- package/core/agentic/loop-detector.js +0 -406
- package/core/agentic/memory-system.js +0 -845
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -352
- package/core/agentic/response-templates.js +0 -290
- package/core/agentic/semantic-compression.js +0 -517
- package/core/agentic/think-blocks.js +0 -657
- package/core/agentic/tool-registry.js +0 -184
- package/core/agentic/validation-rules.js +0 -380
- package/core/command-registry.js +0 -698
- package/core/commands.js +0 -2237
- package/core/domain/task-stack.js +0 -497
- package/core/infrastructure/legacy-installer-detector.js +0 -546
- package/core/infrastructure/migrator.js +0 -796
- package/core/infrastructure/session-manager.js +0 -390
- package/core/utils/file-helper.js +0 -329
- package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
- package/packages/web/app/api/stats/route.ts +0 -38
- package/packages/web/components/AppSidebar.tsx +0 -113
- package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
- package/packages/web/components/stats/AgentsCard.tsx +0 -56
- package/packages/web/components/stats/BentoCard.tsx +0 -88
- package/packages/web/components/stats/HeroSection.tsx +0 -172
- package/packages/web/components/stats/NowCard.tsx +0 -71
- package/packages/web/components/stats/QueueCard.tsx +0 -58
- package/packages/web/components/stats/VelocityCard.tsx +0 -60
- package/packages/web/components/stats/index.ts +0 -17
- package/packages/web/hooks/useStats.ts +0 -28
- /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
- /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
- /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
- /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
- /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
- /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
- /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detection - Legacy Installation Detection
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'fs/promises'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
import os from 'os'
|
|
8
|
+
import { execSync } from 'child_process'
|
|
9
|
+
|
|
10
|
+
export const legacyInstallDir = path.join(os.homedir(), '.prjct-cli')
|
|
11
|
+
export const npmGlobalProjectsDir = path.join(os.homedir(), '.prjct-cli', 'projects')
|
|
12
|
+
export const isWindows = process.platform === 'win32'
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Check if legacy curl installation exists
|
|
16
|
+
*/
|
|
17
|
+
export async function hasLegacyInstallation(): Promise<boolean> {
|
|
18
|
+
try {
|
|
19
|
+
const stat = await fs.stat(legacyInstallDir)
|
|
20
|
+
if (!stat.isDirectory()) return false
|
|
21
|
+
|
|
22
|
+
// Check for .git directory (indicates curl install)
|
|
23
|
+
try {
|
|
24
|
+
await fs.access(path.join(legacyInstallDir, '.git'))
|
|
25
|
+
return true
|
|
26
|
+
} catch {
|
|
27
|
+
// No .git, check for other legacy indicators
|
|
28
|
+
const entries = await fs.readdir(legacyInstallDir)
|
|
29
|
+
|
|
30
|
+
// Legacy has: bin/, core/, templates/, scripts/, package.json
|
|
31
|
+
const legacyFiles = ['bin', 'core', 'templates', 'scripts', 'package.json']
|
|
32
|
+
const hasLegacyFiles = legacyFiles.every((file) => entries.includes(file))
|
|
33
|
+
|
|
34
|
+
if (hasLegacyFiles) {
|
|
35
|
+
return true
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Only has projects/ and config/ = already migrated
|
|
39
|
+
const onlyDataDirs = entries.every((entry) => ['projects', 'config'].includes(entry))
|
|
40
|
+
return !onlyDataDirs
|
|
41
|
+
}
|
|
42
|
+
} catch {
|
|
43
|
+
return false
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Get npm global installation path
|
|
49
|
+
*/
|
|
50
|
+
export function getNpmGlobalPath(): string {
|
|
51
|
+
try {
|
|
52
|
+
const npmRoot = execSync('npm root -g', { encoding: 'utf8' }).trim()
|
|
53
|
+
return path.join(npmRoot, 'prjct-cli')
|
|
54
|
+
} catch {
|
|
55
|
+
// Fallback to common locations
|
|
56
|
+
const nodePath = process.execPath
|
|
57
|
+
const nodeDir = path.dirname(path.dirname(nodePath))
|
|
58
|
+
return path.join(nodeDir, 'lib', 'node_modules', 'prjct-cli')
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Check if user has npm global installation
|
|
64
|
+
*/
|
|
65
|
+
export async function hasNpmInstallation(): Promise<boolean> {
|
|
66
|
+
try {
|
|
67
|
+
execSync('npm list -g prjct-cli', { stdio: 'ignore' })
|
|
68
|
+
return true
|
|
69
|
+
} catch {
|
|
70
|
+
return false
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get version of legacy installation
|
|
76
|
+
*/
|
|
77
|
+
export async function getLegacyVersion(): Promise<string | null> {
|
|
78
|
+
try {
|
|
79
|
+
const packageJsonPath = path.join(legacyInstallDir, 'package.json')
|
|
80
|
+
const content = await fs.readFile(packageJsonPath, 'utf8')
|
|
81
|
+
const pkg = JSON.parse(content)
|
|
82
|
+
return pkg.version || 'unknown'
|
|
83
|
+
} catch {
|
|
84
|
+
return null
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Quick check - silent, returns true if cleanup needed
|
|
90
|
+
*/
|
|
91
|
+
export async function needsCleanup(): Promise<boolean> {
|
|
92
|
+
const hasLegacy = await hasLegacyInstallation()
|
|
93
|
+
const hasNpm = await hasNpmInstallation()
|
|
94
|
+
return hasLegacy && hasNpm
|
|
95
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy Installer Detector
|
|
3
|
+
*
|
|
4
|
+
* Detects and cleans up legacy curl-based installations from ~/.prjct-cli/
|
|
5
|
+
*
|
|
6
|
+
* @version 0.8.8
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {
|
|
10
|
+
legacyInstallDir,
|
|
11
|
+
npmGlobalProjectsDir,
|
|
12
|
+
isWindows,
|
|
13
|
+
hasLegacyInstallation,
|
|
14
|
+
getNpmGlobalPath,
|
|
15
|
+
hasNpmInstallation,
|
|
16
|
+
getLegacyVersion,
|
|
17
|
+
needsCleanup,
|
|
18
|
+
} from './detection'
|
|
19
|
+
|
|
20
|
+
import { migrateProjectsData } from './migration'
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
cleanupLegacyInstallation,
|
|
24
|
+
cleanupLegacyPATH,
|
|
25
|
+
cleanupLegacySymlinks,
|
|
26
|
+
getShellConfigFiles,
|
|
27
|
+
} from './cleanup'
|
|
28
|
+
|
|
29
|
+
import type { CleanupReport, CleanupOptions } from './types'
|
|
30
|
+
import { CYAN, GREEN, YELLOW, RED, DIM, NC } from './types'
|
|
31
|
+
|
|
32
|
+
class LegacyInstallerDetector {
|
|
33
|
+
legacyInstallDir = legacyInstallDir
|
|
34
|
+
npmGlobalProjectsDir = npmGlobalProjectsDir
|
|
35
|
+
isWindows = isWindows
|
|
36
|
+
|
|
37
|
+
hasLegacyInstallation = hasLegacyInstallation
|
|
38
|
+
getNpmGlobalPath = getNpmGlobalPath
|
|
39
|
+
hasNpmInstallation = hasNpmInstallation
|
|
40
|
+
getLegacyVersion = getLegacyVersion
|
|
41
|
+
needsCleanup = needsCleanup
|
|
42
|
+
migrateProjectsData = migrateProjectsData
|
|
43
|
+
cleanupLegacyInstallation = cleanupLegacyInstallation
|
|
44
|
+
cleanupLegacyPATH = cleanupLegacyPATH
|
|
45
|
+
cleanupLegacySymlinks = cleanupLegacySymlinks
|
|
46
|
+
getShellConfigFiles = getShellConfigFiles
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Perform complete legacy cleanup
|
|
50
|
+
*/
|
|
51
|
+
async performCleanup(options: CleanupOptions = {}): Promise<CleanupReport> {
|
|
52
|
+
const { verbose = true } = options
|
|
53
|
+
|
|
54
|
+
const report: CleanupReport = {
|
|
55
|
+
success: false,
|
|
56
|
+
legacyVersion: null,
|
|
57
|
+
hasNpm: false,
|
|
58
|
+
steps: {
|
|
59
|
+
projectsMigrated: 0,
|
|
60
|
+
installationCleaned: false,
|
|
61
|
+
pathCleaned: false,
|
|
62
|
+
symlinksCleaned: false,
|
|
63
|
+
},
|
|
64
|
+
messages: [],
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
const hasLegacy = await hasLegacyInstallation()
|
|
69
|
+
|
|
70
|
+
if (!hasLegacy) {
|
|
71
|
+
report.success = true
|
|
72
|
+
report.messages.push('No legacy installation found')
|
|
73
|
+
return report
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
report.legacyVersion = await getLegacyVersion()
|
|
77
|
+
report.hasNpm = await hasNpmInstallation()
|
|
78
|
+
|
|
79
|
+
if (verbose) {
|
|
80
|
+
console.log('')
|
|
81
|
+
console.log(`${YELLOW}----------------------------------------${NC}`)
|
|
82
|
+
console.log(`${YELLOW}Legacy curl installation detected${NC}`)
|
|
83
|
+
console.log(`${YELLOW}----------------------------------------${NC}`)
|
|
84
|
+
console.log('')
|
|
85
|
+
console.log(` ${DIM}Version: ${report.legacyVersion || 'unknown'}${NC}`)
|
|
86
|
+
console.log(` ${DIM}Location: ~/.prjct-cli/${NC}`)
|
|
87
|
+
console.log('')
|
|
88
|
+
|
|
89
|
+
if (!report.hasNpm) {
|
|
90
|
+
console.log(`${RED}npm global installation not found${NC}`)
|
|
91
|
+
console.log('')
|
|
92
|
+
console.log(`${CYAN}Install prjct-cli via npm first:${NC}`)
|
|
93
|
+
console.log(` ${GREEN}npm install -g prjct-cli${NC}`)
|
|
94
|
+
console.log('')
|
|
95
|
+
return report
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
console.log(`${CYAN}Migrating to npm installation...${NC}`)
|
|
99
|
+
console.log('')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Step 1: Migrate projects data
|
|
103
|
+
if (verbose) console.log(` ${DIM}Migrating projects data...${NC}`)
|
|
104
|
+
const projectsMigration = await migrateProjectsData()
|
|
105
|
+
report.steps.projectsMigrated = projectsMigration.projectsMigrated
|
|
106
|
+
report.messages.push(projectsMigration.message)
|
|
107
|
+
if (verbose) {
|
|
108
|
+
const icon = projectsMigration.success ? `${GREEN}✓${NC}` : `${RED}✗${NC}`
|
|
109
|
+
console.log(` ${icon} ${projectsMigration.message}`)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// Step 2: Clean legacy installation
|
|
113
|
+
if (verbose) console.log(` ${DIM}Removing legacy files...${NC}`)
|
|
114
|
+
const installCleanup = await cleanupLegacyInstallation()
|
|
115
|
+
report.steps.installationCleaned = installCleanup.success
|
|
116
|
+
report.messages.push(installCleanup.message)
|
|
117
|
+
if (verbose) {
|
|
118
|
+
const icon = installCleanup.success ? `${GREEN}✓${NC}` : `${RED}✗${NC}`
|
|
119
|
+
console.log(` ${icon} ${installCleanup.message}`)
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Step 3: Clean PATH entries
|
|
123
|
+
if (verbose) console.log(` ${DIM}Cleaning shell PATH...${NC}`)
|
|
124
|
+
const pathCleanup = await cleanupLegacyPATH()
|
|
125
|
+
report.steps.pathCleaned = pathCleanup.success
|
|
126
|
+
report.messages.push(pathCleanup.message)
|
|
127
|
+
if (verbose) {
|
|
128
|
+
const icon = pathCleanup.success ? `${GREEN}✓${NC}` : `${RED}✗${NC}`
|
|
129
|
+
console.log(` ${icon} ${pathCleanup.message}`)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Step 4: Clean symlinks
|
|
133
|
+
if (verbose) console.log(` ${DIM}Cleaning symlinks...${NC}`)
|
|
134
|
+
const symlinkCleanup = await cleanupLegacySymlinks()
|
|
135
|
+
report.steps.symlinksCleaned = symlinkCleanup.success
|
|
136
|
+
report.messages.push(symlinkCleanup.message)
|
|
137
|
+
if (verbose) {
|
|
138
|
+
const icon = symlinkCleanup.success ? `${GREEN}✓${NC}` : `${RED}✗${NC}`
|
|
139
|
+
console.log(` ${icon} ${symlinkCleanup.message}`)
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (verbose) {
|
|
143
|
+
console.log('')
|
|
144
|
+
console.log(`${GREEN}Migration complete!${NC}`)
|
|
145
|
+
console.log('')
|
|
146
|
+
console.log(`${DIM}Next steps:${NC}`)
|
|
147
|
+
if (pathCleanup.filesModified && pathCleanup.filesModified > 0) {
|
|
148
|
+
console.log(` ${CYAN}1. Reload your shell:${NC}`)
|
|
149
|
+
console.log(` source ~/.zshrc ${DIM}(or ~/.bashrc)${NC}`)
|
|
150
|
+
console.log('')
|
|
151
|
+
}
|
|
152
|
+
const stepNum = pathCleanup.filesModified && pathCleanup.filesModified > 0 ? '2' : '1'
|
|
153
|
+
console.log(` ${CYAN}${stepNum}. Verify installation:${NC}`)
|
|
154
|
+
console.log(` which prjct ${DIM}(should show npm path)${NC}`)
|
|
155
|
+
console.log(` prjct --version`)
|
|
156
|
+
console.log('')
|
|
157
|
+
console.log(`${YELLOW}----------------------------------------${NC}`)
|
|
158
|
+
console.log('')
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
report.success = true
|
|
162
|
+
return report
|
|
163
|
+
} catch (error) {
|
|
164
|
+
report.messages.push(`Cleanup failed: ${(error as Error).message}`)
|
|
165
|
+
return report
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const legacyInstallerDetector = new LegacyInstallerDetector()
|
|
171
|
+
export default legacyInstallerDetector
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration - Project Data Migration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'fs/promises'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
import { legacyInstallDir, npmGlobalProjectsDir } from './detection'
|
|
8
|
+
import type { MigrationResult } from './types'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Copy directory recursively
|
|
12
|
+
*/
|
|
13
|
+
async function copyDirectory(source: string, destination: string): Promise<void> {
|
|
14
|
+
await fs.mkdir(destination, { recursive: true })
|
|
15
|
+
|
|
16
|
+
const entries = await fs.readdir(source, { withFileTypes: true })
|
|
17
|
+
|
|
18
|
+
for (const entry of entries) {
|
|
19
|
+
const sourcePath = path.join(source, entry.name)
|
|
20
|
+
const destPath = path.join(destination, entry.name)
|
|
21
|
+
|
|
22
|
+
if (entry.isDirectory()) {
|
|
23
|
+
await copyDirectory(sourcePath, destPath)
|
|
24
|
+
} else {
|
|
25
|
+
await fs.copyFile(sourcePath, destPath)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Migrate projects data from legacy location to npm location
|
|
32
|
+
*/
|
|
33
|
+
export async function migrateProjectsData(): Promise<MigrationResult> {
|
|
34
|
+
const result: MigrationResult = {
|
|
35
|
+
success: false,
|
|
36
|
+
projectsMigrated: 0,
|
|
37
|
+
message: '',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
const legacyProjectsDir = path.join(legacyInstallDir, 'projects')
|
|
42
|
+
|
|
43
|
+
// Check if legacy projects directory exists
|
|
44
|
+
try {
|
|
45
|
+
await fs.access(legacyProjectsDir)
|
|
46
|
+
} catch {
|
|
47
|
+
result.success = true
|
|
48
|
+
result.message = 'No projects data to migrate'
|
|
49
|
+
return result
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Ensure npm global projects directory exists
|
|
53
|
+
await fs.mkdir(npmGlobalProjectsDir, { recursive: true })
|
|
54
|
+
|
|
55
|
+
// Read all project directories
|
|
56
|
+
const projectDirs = await fs.readdir(legacyProjectsDir, { withFileTypes: true })
|
|
57
|
+
|
|
58
|
+
for (const entry of projectDirs) {
|
|
59
|
+
if (!entry.isDirectory()) continue
|
|
60
|
+
|
|
61
|
+
const legacyProjectPath = path.join(legacyProjectsDir, entry.name)
|
|
62
|
+
const npmProjectPath = path.join(npmGlobalProjectsDir, entry.name)
|
|
63
|
+
|
|
64
|
+
// Check if project already exists in npm location
|
|
65
|
+
try {
|
|
66
|
+
await fs.access(npmProjectPath)
|
|
67
|
+
// Already exists, skip
|
|
68
|
+
continue
|
|
69
|
+
} catch {
|
|
70
|
+
// Doesn't exist, copy it
|
|
71
|
+
await copyDirectory(legacyProjectPath, npmProjectPath)
|
|
72
|
+
result.projectsMigrated++
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
result.success = true
|
|
77
|
+
result.message =
|
|
78
|
+
result.projectsMigrated > 0
|
|
79
|
+
? `Migrated ${result.projectsMigrated} project(s) to npm global location`
|
|
80
|
+
: 'All projects already in npm location'
|
|
81
|
+
|
|
82
|
+
return result
|
|
83
|
+
} catch (error) {
|
|
84
|
+
result.message = `Migration failed: ${(error as Error).message}`
|
|
85
|
+
return result
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Legacy Installer Detector Types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Colors
|
|
6
|
+
export const CYAN = '\x1b[36m'
|
|
7
|
+
export const GREEN = '\x1b[32m'
|
|
8
|
+
export const YELLOW = '\x1b[33m'
|
|
9
|
+
export const RED = '\x1b[31m'
|
|
10
|
+
export const DIM = '\x1b[2m'
|
|
11
|
+
export const NC = '\x1b[0m'
|
|
12
|
+
|
|
13
|
+
export interface CleanupSteps {
|
|
14
|
+
projectsMigrated: number
|
|
15
|
+
installationCleaned: boolean
|
|
16
|
+
pathCleaned: boolean
|
|
17
|
+
symlinksCleaned: boolean
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface CleanupReport {
|
|
21
|
+
success: boolean
|
|
22
|
+
legacyVersion: string | null
|
|
23
|
+
hasNpm: boolean
|
|
24
|
+
steps: CleanupSteps
|
|
25
|
+
messages: string[]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface MigrationResult {
|
|
29
|
+
success: boolean
|
|
30
|
+
projectsMigrated: number
|
|
31
|
+
message: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface CleanupResult {
|
|
35
|
+
success: boolean
|
|
36
|
+
message: string
|
|
37
|
+
filesModified?: number
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CleanupOptions {
|
|
41
|
+
verbose?: boolean
|
|
42
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Operations
|
|
3
|
+
* Handles file copying and mapping for migrations.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import fs from 'fs/promises'
|
|
7
|
+
import path from 'path'
|
|
8
|
+
import type { FileMapping, MigrationStats, LayerCounts } from './types'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Copy a directory recursively
|
|
12
|
+
*/
|
|
13
|
+
export async function copyDirectory(source: string, destination: string): Promise<number> {
|
|
14
|
+
let fileCount = 0
|
|
15
|
+
|
|
16
|
+
await fs.mkdir(destination, { recursive: true })
|
|
17
|
+
|
|
18
|
+
const entries = await fs.readdir(source, { withFileTypes: true })
|
|
19
|
+
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
const sourcePath = path.join(source, entry.name)
|
|
22
|
+
const destPath = path.join(destination, entry.name)
|
|
23
|
+
|
|
24
|
+
if (entry.isDirectory()) {
|
|
25
|
+
fileCount += await copyDirectory(sourcePath, destPath)
|
|
26
|
+
} else {
|
|
27
|
+
await fs.copyFile(sourcePath, destPath)
|
|
28
|
+
fileCount++
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return fileCount
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Map legacy flat structure to new layered structure
|
|
37
|
+
*/
|
|
38
|
+
export function mapLegacyFile(filename: string): FileMapping {
|
|
39
|
+
if (filename === 'now.md' || filename === 'next.md' || filename === 'context.md') {
|
|
40
|
+
return { layer: 'core', filename }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (filename === 'shipped.md' || filename === 'metrics.md') {
|
|
44
|
+
return { layer: 'progress', filename }
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (filename === 'ideas.md' || filename === 'roadmap.md') {
|
|
48
|
+
return { layer: 'planning', filename }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (
|
|
52
|
+
filename === 'memory.jsonl' ||
|
|
53
|
+
filename === 'context.jsonl' ||
|
|
54
|
+
filename === 'decisions.jsonl'
|
|
55
|
+
) {
|
|
56
|
+
return { layer: 'memory', filename }
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (filename === 'repo-summary.md') {
|
|
60
|
+
return { layer: 'analysis', filename }
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return { layer: '.', filename }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Migrate files from legacy structure to new layered structure
|
|
68
|
+
*/
|
|
69
|
+
export async function migrateFiles(legacyPath: string, globalPath: string): Promise<MigrationStats> {
|
|
70
|
+
let fileCount = 0
|
|
71
|
+
const layerCounts: LayerCounts = {
|
|
72
|
+
core: 0,
|
|
73
|
+
progress: 0,
|
|
74
|
+
planning: 0,
|
|
75
|
+
analysis: 0,
|
|
76
|
+
memory: 0,
|
|
77
|
+
other: 0,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const validLayers = ['core', 'progress', 'planning', 'analysis', 'memory', 'sessions']
|
|
81
|
+
const entries = await fs.readdir(legacyPath, { withFileTypes: true })
|
|
82
|
+
|
|
83
|
+
for (const entry of entries) {
|
|
84
|
+
const sourcePath = path.join(legacyPath, entry.name)
|
|
85
|
+
|
|
86
|
+
if (entry.name === 'prjct.config.json' || entry.name.endsWith('.old')) {
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (entry.isDirectory()) {
|
|
91
|
+
if (validLayers.includes(entry.name)) {
|
|
92
|
+
const destPath = path.join(globalPath, entry.name)
|
|
93
|
+
const count = await copyDirectory(sourcePath, destPath)
|
|
94
|
+
fileCount += count
|
|
95
|
+
if (Object.prototype.hasOwnProperty.call(layerCounts, entry.name)) {
|
|
96
|
+
layerCounts[entry.name as keyof LayerCounts] += count
|
|
97
|
+
} else {
|
|
98
|
+
layerCounts.other += count
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
const destPath = path.join(globalPath, 'planning', entry.name)
|
|
102
|
+
const count = await copyDirectory(sourcePath, destPath)
|
|
103
|
+
fileCount += count
|
|
104
|
+
layerCounts.planning += count
|
|
105
|
+
}
|
|
106
|
+
} else {
|
|
107
|
+
const mapping = mapLegacyFile(entry.name)
|
|
108
|
+
const destPath = path.join(globalPath, mapping.layer, mapping.filename)
|
|
109
|
+
|
|
110
|
+
await fs.mkdir(path.dirname(destPath), { recursive: true })
|
|
111
|
+
|
|
112
|
+
await fs.copyFile(sourcePath, destPath)
|
|
113
|
+
fileCount++
|
|
114
|
+
|
|
115
|
+
if (mapping.layer === '.') {
|
|
116
|
+
layerCounts.other++
|
|
117
|
+
} else {
|
|
118
|
+
layerCounts[mapping.layer as keyof LayerCounts] =
|
|
119
|
+
(layerCounts[mapping.layer as keyof LayerCounts] || 0) + 1
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return { fileCount, layerCounts }
|
|
125
|
+
}
|