prjct-cli 0.11.5 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +81 -25
- package/bin/dev.js +1 -1
- package/bin/generate-views.js +209 -0
- package/bin/migrate-to-json.js +742 -0
- package/bin/prjct +5 -5
- package/bin/serve.js +226 -50
- package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
- package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
- package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
- package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
- package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
- package/core/agentic/agent-router.ts +137 -0
- package/core/agentic/chain-of-thought.ts +228 -0
- package/core/agentic/command-executor/command-executor.ts +384 -0
- package/core/agentic/command-executor/index.ts +16 -0
- package/core/agentic/command-executor/status-signal.ts +38 -0
- package/core/agentic/command-executor/types.ts +79 -0
- package/core/agentic/command-executor.ts +8 -0
- package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
- package/core/agentic/context-filter.ts +365 -0
- package/core/agentic/ground-truth/index.ts +76 -0
- package/core/agentic/ground-truth/types.ts +33 -0
- package/core/agentic/ground-truth/utils.ts +48 -0
- package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
- package/core/agentic/ground-truth/verifiers/done.ts +75 -0
- package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
- package/core/agentic/ground-truth/verifiers/index.ts +37 -0
- package/core/agentic/ground-truth/verifiers/init.ts +52 -0
- package/core/agentic/ground-truth/verifiers/now.ts +57 -0
- package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
- package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
- package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
- package/core/agentic/ground-truth/verifiers.ts +6 -0
- package/core/agentic/ground-truth.ts +8 -0
- package/core/agentic/loop-detector/error-analysis.ts +97 -0
- package/core/agentic/loop-detector/hallucination.ts +71 -0
- package/core/agentic/loop-detector/index.ts +41 -0
- package/core/agentic/loop-detector/loop-detector.ts +222 -0
- package/core/agentic/loop-detector/types.ts +66 -0
- package/core/agentic/loop-detector.ts +8 -0
- package/core/agentic/memory-system/history.ts +53 -0
- package/core/agentic/memory-system/index.ts +192 -0
- package/core/agentic/memory-system/patterns.ts +156 -0
- package/core/agentic/memory-system/semantic-memories.ts +277 -0
- package/core/agentic/memory-system/session.ts +21 -0
- package/core/agentic/memory-system/types.ts +159 -0
- package/core/agentic/memory-system.ts +8 -0
- package/core/agentic/parallel-tools.ts +165 -0
- package/core/agentic/plan-mode/approval.ts +57 -0
- package/core/agentic/plan-mode/constants.ts +44 -0
- package/core/agentic/plan-mode/index.ts +28 -0
- package/core/agentic/plan-mode/plan-mode.ts +406 -0
- package/core/agentic/plan-mode/types.ts +193 -0
- package/core/agentic/plan-mode.ts +8 -0
- package/core/agentic/prompt-builder.ts +566 -0
- package/core/agentic/response-templates.ts +164 -0
- package/core/agentic/semantic-compression.ts +273 -0
- package/core/agentic/services.ts +206 -0
- package/core/agentic/smart-context.ts +476 -0
- package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
- package/core/agentic/think-blocks.ts +202 -0
- package/core/agentic/tool-registry.ts +119 -0
- package/core/agentic/validation-rules.ts +313 -0
- package/core/agents/index.ts +28 -0
- package/core/agents/performance.ts +444 -0
- package/core/agents/types.ts +126 -0
- package/core/bus/{index.js → index.ts} +57 -61
- package/core/command-registry/categories.ts +23 -0
- package/core/command-registry/commands.ts +15 -0
- package/core/command-registry/core-commands.ts +319 -0
- package/core/command-registry/index.ts +158 -0
- package/core/command-registry/optional-commands.ts +119 -0
- package/core/command-registry/setup-commands.ts +53 -0
- package/core/command-registry/types.ts +59 -0
- package/core/command-registry.ts +9 -0
- package/core/commands/analysis.ts +298 -0
- package/core/commands/analytics.ts +288 -0
- package/core/commands/base.ts +273 -0
- package/core/commands/index.ts +211 -0
- package/core/commands/maintenance.ts +226 -0
- package/core/commands/planning.ts +311 -0
- package/core/commands/setup.ts +309 -0
- package/core/commands/shipping.ts +188 -0
- package/core/commands/types.ts +183 -0
- package/core/commands/workflow.ts +226 -0
- package/core/commands.ts +11 -0
- package/core/constants/formats.ts +187 -0
- package/core/constants/index.ts +7 -0
- package/core/{context-sync.js → context-sync.ts} +59 -26
- package/core/data/agents-manager.ts +76 -0
- package/core/data/analysis-manager.ts +83 -0
- package/core/data/base-manager.ts +156 -0
- package/core/data/ideas-manager.ts +81 -0
- package/core/data/index.ts +32 -0
- package/core/data/outcomes-manager.ts +96 -0
- package/core/data/project-manager.ts +75 -0
- package/core/data/roadmap-manager.ts +118 -0
- package/core/data/shipped-manager.ts +65 -0
- package/core/data/state-manager.ts +214 -0
- package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
- package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
- package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
- package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
- package/core/domain/{analyzer.js → analyzer.ts} +91 -85
- package/core/domain/{architect-session.js → architect-session.ts} +49 -34
- package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
- package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
- package/core/domain/{product-standards.js → product-standards.ts} +40 -26
- package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
- package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
- package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
- package/core/domain/task-stack/index.ts +19 -0
- package/core/domain/task-stack/parser.ts +86 -0
- package/core/domain/task-stack/storage.ts +123 -0
- package/core/domain/task-stack/task-stack.ts +340 -0
- package/core/domain/task-stack/types.ts +51 -0
- package/core/domain/task-stack.ts +8 -0
- package/core/{index.js → index.ts} +61 -18
- package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
- package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
- package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
- package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
- package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
- package/core/infrastructure/command-installer/global-config.ts +106 -0
- package/core/infrastructure/command-installer/index.ts +25 -0
- package/core/infrastructure/command-installer/types.ts +41 -0
- package/core/infrastructure/command-installer.ts +8 -0
- package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
- package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
- package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
- package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
- package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
- package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
- package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
- package/core/infrastructure/legacy-installer-detector.ts +7 -0
- package/core/infrastructure/migrator/file-operations.ts +125 -0
- package/core/infrastructure/migrator/index.ts +288 -0
- package/core/infrastructure/migrator/project-scanner.ts +89 -0
- package/core/infrastructure/migrator/reports.ts +117 -0
- package/core/infrastructure/migrator/types.ts +124 -0
- package/core/infrastructure/migrator/validation.ts +94 -0
- package/core/infrastructure/migrator/version-migration.ts +117 -0
- package/core/infrastructure/migrator.ts +10 -0
- package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
- package/core/infrastructure/session-manager/index.ts +23 -0
- package/core/infrastructure/session-manager/migration.ts +88 -0
- package/core/infrastructure/session-manager/session-manager.ts +307 -0
- package/core/infrastructure/session-manager/types.ts +45 -0
- package/core/infrastructure/session-manager.ts +8 -0
- package/core/infrastructure/{setup.js → setup.ts} +29 -21
- package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
- package/core/outcomes/analyzer.ts +333 -0
- package/core/outcomes/index.ts +34 -0
- package/core/outcomes/recorder.ts +194 -0
- package/core/outcomes/types.ts +145 -0
- package/core/plugin/{hooks.js → hooks.ts} +56 -58
- package/core/plugin/{index.js → index.ts} +19 -8
- package/core/plugin/{loader.js → loader.ts} +87 -69
- package/core/plugin/{registry.js → registry.ts} +49 -45
- package/core/plugins/{webhook.js → webhook.ts} +43 -27
- package/core/schemas/agents.ts +27 -0
- package/core/schemas/analysis.ts +41 -0
- package/core/schemas/ideas.ts +83 -0
- package/core/schemas/index.ts +73 -0
- package/core/schemas/outcomes.ts +22 -0
- package/core/schemas/project.ts +26 -0
- package/core/schemas/roadmap.ts +90 -0
- package/core/schemas/shipped.ts +82 -0
- package/core/schemas/state.ts +107 -0
- package/core/session/index.ts +17 -0
- package/core/session/{metrics.js → metrics.ts} +64 -46
- package/core/session/{index.js → session-manager.ts} +51 -117
- package/core/session/types.ts +29 -0
- package/core/session/utils.ts +57 -0
- package/core/state/index.ts +25 -0
- package/core/state/manager.ts +376 -0
- package/core/state/types.ts +185 -0
- package/core/tsconfig.json +22 -0
- package/core/types/index.ts +506 -0
- package/core/utils/{animations.js → animations.ts} +74 -28
- package/core/utils/{branding.js → branding.ts} +29 -4
- package/core/utils/{date-helper.js → date-helper.ts} +31 -74
- package/core/utils/file-helper.ts +262 -0
- package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
- package/core/utils/{logger.js → logger.ts} +24 -12
- package/core/utils/{output.js → output.ts} +25 -13
- package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
- package/core/utils/{session-helper.js → session-helper.ts} +79 -66
- package/core/utils/{version.js → version.ts} +23 -31
- package/core/view-generator.ts +536 -0
- package/package.json +23 -17
- package/packages/shared/.turbo/turbo-build.log +14 -0
- package/packages/shared/dist/index.d.ts +8 -613
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +4110 -118
- package/packages/shared/dist/schemas.d.ts +408 -0
- package/packages/shared/dist/schemas.d.ts.map +1 -0
- package/packages/shared/dist/types.d.ts +144 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/unified.d.ts +139 -0
- package/packages/shared/dist/unified.d.ts.map +1 -0
- package/packages/shared/dist/utils.d.ts +60 -0
- package/packages/shared/dist/utils.d.ts.map +1 -0
- package/packages/shared/package.json +4 -4
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/unified.ts +174 -0
- package/packages/web/app/api/claude/sessions/route.ts +1 -1
- package/packages/web/app/api/claude/status/route.ts +1 -1
- package/packages/web/app/api/migrate/route.ts +46 -0
- package/packages/web/app/api/projects/[id]/route.ts +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
- package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
- package/packages/web/app/api/projects/route.ts +1 -1
- package/packages/web/app/api/settings/route.ts +97 -0
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
- package/packages/web/app/globals.css +38 -0
- package/packages/web/app/layout.tsx +10 -2
- package/packages/web/app/page.tsx +9 -224
- package/packages/web/app/project/[id]/page.tsx +191 -63
- package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
- package/packages/web/app/project/[id]/stats/page.tsx +204 -163
- package/packages/web/app/settings/page.tsx +222 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
- package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
- package/packages/web/components/ActivityTimeline/index.ts +2 -0
- package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
- package/packages/web/components/AgentsCard/index.ts +2 -0
- package/packages/web/components/AppSidebar/AppSidebar.tsx +134 -0
- package/packages/web/components/AppSidebar/index.ts +1 -0
- package/packages/web/components/BackLink/BackLink.tsx +18 -0
- package/packages/web/components/BackLink/BackLink.types.ts +5 -0
- package/packages/web/components/BackLink/index.ts +2 -0
- package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
- package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
- package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
- package/packages/web/components/BentoCard/index.ts +2 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
- package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
- package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
- package/packages/web/components/BentoGrid/index.ts +2 -0
- package/packages/web/components/CommandButton/index.ts +1 -0
- package/packages/web/components/ConnectionStatus/index.ts +1 -0
- package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
- package/packages/web/components/DashboardContent/index.ts +1 -0
- package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
- package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
- package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
- package/packages/web/components/DateGroup/index.ts +2 -0
- package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
- package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
- package/packages/web/components/EmptyState/index.ts +2 -0
- package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
- package/packages/web/components/EventRow/EventRow.tsx +49 -0
- package/packages/web/components/EventRow/EventRow.types.ts +7 -0
- package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
- package/packages/web/components/EventRow/index.ts +2 -0
- package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
- package/packages/web/components/ExpandButton/index.ts +2 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
- package/packages/web/components/HealthGradientBackground/index.ts +2 -0
- package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
- package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
- package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
- package/packages/web/components/HeroSection/hooks/index.ts +2 -0
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
- package/packages/web/components/HeroSection/index.ts +2 -0
- package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
- package/packages/web/components/IdeasCard/index.ts +2 -0
- package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
- package/packages/web/components/InsightMessage/index.ts +2 -0
- package/packages/web/components/Logo/index.ts +1 -0
- package/packages/web/components/MarkdownContent/index.ts +1 -0
- package/packages/web/components/NowCard/NowCard.tsx +93 -0
- package/packages/web/components/NowCard/NowCard.types.ts +15 -0
- package/packages/web/components/NowCard/index.ts +2 -0
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
- package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
- package/packages/web/components/ProgressRing/index.ts +2 -0
- package/packages/web/components/ProjectAvatar/index.ts +1 -0
- package/packages/web/components/Providers/index.ts +1 -0
- package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
- package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
- package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
- package/packages/web/components/QueueCard/index.ts +2 -0
- package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
- package/packages/web/components/ShipsCard/index.ts +2 -0
- package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
- package/packages/web/components/SparklineChart/index.ts +2 -0
- package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
- package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
- package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
- package/packages/web/components/StreakCard/index.ts +2 -0
- package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
- package/packages/web/components/TasksCounter/index.ts +2 -0
- package/packages/web/components/TechStackBadges/index.ts +1 -0
- package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
- package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
- package/packages/web/components/TerminalTabs/index.ts +1 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
- package/packages/web/components/VelocityBadge/index.ts +2 -0
- package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
- package/packages/web/components/VelocityCard/index.ts +2 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
- package/packages/web/components/WeeklySparkline/index.ts +2 -0
- package/packages/web/components/ui/input.tsx +21 -0
- package/packages/web/context/TerminalTabsContext.tsx +46 -1
- package/packages/web/hooks/useClaudeTerminal.ts +71 -21
- package/packages/web/hooks/useProjectStats.ts +55 -0
- package/packages/web/hooks/useProjects.ts +6 -6
- package/packages/web/lib/actions/projects.ts +15 -0
- package/packages/web/lib/json-loader.ts +630 -0
- package/packages/web/lib/services/index.ts +9 -0
- package/packages/web/lib/services/migration.server.ts +598 -0
- package/packages/web/lib/services/projects.server.ts +52 -0
- package/packages/web/lib/services/stats.server.ts +264 -0
- package/packages/web/lib/unified-loader.ts +396 -0
- package/packages/web/package.json +10 -7
- package/packages/web/server.ts +36 -6
- package/templates/commands/done.md +76 -32
- package/templates/commands/feature.md +121 -47
- package/templates/commands/idea.md +81 -8
- package/templates/commands/now.md +41 -17
- package/templates/commands/ship.md +64 -25
- package/templates/commands/sync.md +28 -3
- package/core/agentic/agent-router.js +0 -140
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -417
- package/core/agentic/context-filter.js +0 -354
- package/core/agentic/ground-truth.js +0 -591
- package/core/agentic/loop-detector.js +0 -406
- package/core/agentic/memory-system.js +0 -845
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -352
- package/core/agentic/response-templates.js +0 -290
- package/core/agentic/semantic-compression.js +0 -517
- package/core/agentic/think-blocks.js +0 -657
- package/core/agentic/tool-registry.js +0 -184
- package/core/agentic/validation-rules.js +0 -380
- package/core/command-registry.js +0 -698
- package/core/commands.js +0 -2237
- package/core/domain/task-stack.js +0 -497
- package/core/infrastructure/legacy-installer-detector.js +0 -546
- package/core/infrastructure/migrator.js +0 -796
- package/core/infrastructure/session-manager.js +0 -390
- package/core/utils/file-helper.js +0 -329
- package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
- package/packages/web/app/api/stats/route.ts +0 -38
- package/packages/web/components/AppSidebar.tsx +0 -113
- package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
- package/packages/web/components/stats/AgentsCard.tsx +0 -56
- package/packages/web/components/stats/BentoCard.tsx +0 -88
- package/packages/web/components/stats/HeroSection.tsx +0 -172
- package/packages/web/components/stats/NowCard.tsx +0 -71
- package/packages/web/components/stats/QueueCard.tsx +0 -58
- package/packages/web/components/stats/VelocityCard.tsx +0 -60
- package/packages/web/components/stats/index.ts +0 -17
- package/packages/web/hooks/useStats.ts +0 -28
- /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
- /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
- /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
- /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
- /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
- /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
- /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
const fs = require('fs').promises
|
|
2
|
-
const pathManager = require('./path-manager')
|
|
3
|
-
const { VERSION } = require('../utils/version')
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
2
|
* ConfigManager - Manages prjct.config.json files
|
|
7
3
|
*
|
|
@@ -13,14 +9,43 @@ const { VERSION } = require('../utils/version')
|
|
|
13
9
|
*
|
|
14
10
|
* @version 0.2.1
|
|
15
11
|
*/
|
|
12
|
+
|
|
13
|
+
import fs from 'fs/promises'
|
|
14
|
+
import path from 'path'
|
|
15
|
+
import pathManager from './path-manager'
|
|
16
|
+
import { VERSION } from '../utils/version'
|
|
17
|
+
|
|
18
|
+
interface Author {
|
|
19
|
+
name: string
|
|
20
|
+
email: string
|
|
21
|
+
github: string
|
|
22
|
+
firstContribution?: string
|
|
23
|
+
lastActivity?: string
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface LocalConfig {
|
|
27
|
+
projectId: string
|
|
28
|
+
dataPath: string
|
|
29
|
+
authors?: Author[]
|
|
30
|
+
author?: Author
|
|
31
|
+
version?: string
|
|
32
|
+
created?: string
|
|
33
|
+
lastSync?: string
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
interface GlobalConfig {
|
|
37
|
+
projectId: string
|
|
38
|
+
authors: Author[]
|
|
39
|
+
version: string
|
|
40
|
+
created?: string
|
|
41
|
+
lastSync: string
|
|
42
|
+
}
|
|
43
|
+
|
|
16
44
|
class ConfigManager {
|
|
17
45
|
/**
|
|
18
46
|
* Read the project configuration file
|
|
19
|
-
*
|
|
20
|
-
* @param {string} projectPath - Path to the project
|
|
21
|
-
* @returns {Promise<Object|null>} - Configuration object or null if not found
|
|
22
47
|
*/
|
|
23
|
-
async readConfig(projectPath) {
|
|
48
|
+
async readConfig(projectPath: string): Promise<LocalConfig | null> {
|
|
24
49
|
try {
|
|
25
50
|
const configPath = pathManager.getLocalConfigPath(projectPath)
|
|
26
51
|
const content = await fs.readFile(configPath, 'utf-8')
|
|
@@ -32,12 +57,8 @@ class ConfigManager {
|
|
|
32
57
|
|
|
33
58
|
/**
|
|
34
59
|
* Write the project configuration file
|
|
35
|
-
*
|
|
36
|
-
* @param {string} projectPath - Path to the project
|
|
37
|
-
* @param {Object} config - Configuration object
|
|
38
|
-
* @returns {Promise<void>}
|
|
39
60
|
*/
|
|
40
|
-
async writeConfig(projectPath, config) {
|
|
61
|
+
async writeConfig(projectPath: string, config: LocalConfig): Promise<void> {
|
|
41
62
|
const configPath = pathManager.getLocalConfigPath(projectPath)
|
|
42
63
|
const configDir = pathManager.getLegacyPrjctPath(projectPath)
|
|
43
64
|
|
|
@@ -50,11 +71,8 @@ class ConfigManager {
|
|
|
50
71
|
/**
|
|
51
72
|
* Read the global project configuration file
|
|
52
73
|
* Contains authors array and other system data
|
|
53
|
-
*
|
|
54
|
-
* @param {string} projectId - Project identifier
|
|
55
|
-
* @returns {Promise<Object|null>} - Configuration object or null if not found
|
|
56
74
|
*/
|
|
57
|
-
async readGlobalConfig(projectId) {
|
|
75
|
+
async readGlobalConfig(projectId: string): Promise<GlobalConfig | null> {
|
|
58
76
|
try {
|
|
59
77
|
const configPath = pathManager.getGlobalProjectConfigPath(projectId)
|
|
60
78
|
const content = await fs.readFile(configPath, 'utf-8')
|
|
@@ -66,12 +84,8 @@ class ConfigManager {
|
|
|
66
84
|
|
|
67
85
|
/**
|
|
68
86
|
* Write the global project configuration file
|
|
69
|
-
*
|
|
70
|
-
* @param {string} projectId - Project identifier
|
|
71
|
-
* @param {Object} config - Configuration object
|
|
72
|
-
* @returns {Promise<void>}
|
|
73
87
|
*/
|
|
74
|
-
async writeGlobalConfig(projectId, config) {
|
|
88
|
+
async writeGlobalConfig(projectId: string, config: GlobalConfig): Promise<void> {
|
|
75
89
|
const configPath = pathManager.getGlobalProjectConfigPath(projectId)
|
|
76
90
|
const configDir = pathManager.getGlobalProjectPath(projectId)
|
|
77
91
|
|
|
@@ -83,11 +97,8 @@ class ConfigManager {
|
|
|
83
97
|
|
|
84
98
|
/**
|
|
85
99
|
* Ensure global config exists, create if not
|
|
86
|
-
*
|
|
87
|
-
* @param {string} projectId - Project identifier
|
|
88
|
-
* @returns {Promise<Object>} - Global configuration
|
|
89
100
|
*/
|
|
90
|
-
async ensureGlobalConfig(projectId) {
|
|
101
|
+
async ensureGlobalConfig(projectId: string): Promise<GlobalConfig> {
|
|
91
102
|
let globalConfig = await this.readGlobalConfig(projectId)
|
|
92
103
|
|
|
93
104
|
if (!globalConfig) {
|
|
@@ -106,25 +117,24 @@ class ConfigManager {
|
|
|
106
117
|
|
|
107
118
|
/**
|
|
108
119
|
* Create a new project configuration
|
|
109
|
-
*
|
|
110
|
-
* @param {string} projectPath - Path to the project
|
|
111
|
-
* @param {Object} author - Author information {name, email, github}
|
|
112
|
-
* @returns {Promise<Object>} - Created configuration
|
|
113
120
|
*/
|
|
114
|
-
async createConfig(
|
|
121
|
+
async createConfig(
|
|
122
|
+
projectPath: string,
|
|
123
|
+
author: { name?: string; email?: string; github?: string }
|
|
124
|
+
): Promise<LocalConfig> {
|
|
115
125
|
const projectId = pathManager.generateProjectId(projectPath)
|
|
116
126
|
const globalPath = pathManager.getGlobalProjectPath(projectId)
|
|
117
127
|
const displayPath = pathManager.getDisplayPath(globalPath)
|
|
118
128
|
const now = new Date().toISOString()
|
|
119
129
|
|
|
120
|
-
const localConfig = {
|
|
130
|
+
const localConfig: LocalConfig = {
|
|
121
131
|
projectId,
|
|
122
132
|
dataPath: displayPath,
|
|
123
133
|
}
|
|
124
134
|
|
|
125
135
|
await this.writeConfig(projectPath, localConfig)
|
|
126
136
|
|
|
127
|
-
const globalConfig = {
|
|
137
|
+
const globalConfig: GlobalConfig = {
|
|
128
138
|
projectId,
|
|
129
139
|
authors: [
|
|
130
140
|
{
|
|
@@ -147,11 +157,8 @@ class ConfigManager {
|
|
|
147
157
|
|
|
148
158
|
/**
|
|
149
159
|
* Update the lastSync timestamp in global config
|
|
150
|
-
*
|
|
151
|
-
* @param {string} projectPath - Path to the project
|
|
152
|
-
* @returns {Promise<void>}
|
|
153
160
|
*/
|
|
154
|
-
async updateLastSync(projectPath) {
|
|
161
|
+
async updateLastSync(projectPath: string): Promise<void> {
|
|
155
162
|
const projectId = await this.getProjectId(projectPath)
|
|
156
163
|
const globalConfig = await this.readGlobalConfig(projectId)
|
|
157
164
|
if (globalConfig) {
|
|
@@ -164,11 +171,8 @@ class ConfigManager {
|
|
|
164
171
|
* Validate a local configuration object
|
|
165
172
|
* Local config only contains project metadata (projectId, dataPath)
|
|
166
173
|
* All system data (version, created, lastSync, authors) is in global config
|
|
167
|
-
*
|
|
168
|
-
* @param {Object} config - Configuration to validate
|
|
169
|
-
* @returns {boolean} - True if valid
|
|
170
174
|
*/
|
|
171
|
-
validateConfig(config) {
|
|
175
|
+
validateConfig(config: LocalConfig | null): boolean {
|
|
172
176
|
if (!config) return false
|
|
173
177
|
if (!config.projectId) return false
|
|
174
178
|
if (!config.dataPath) return false
|
|
@@ -181,11 +185,8 @@ class ConfigManager {
|
|
|
181
185
|
* Migration is needed if:
|
|
182
186
|
* - Has legacy .prjct/ structure
|
|
183
187
|
* - AND either no config exists OR files not yet in global location
|
|
184
|
-
*
|
|
185
|
-
* @param {string} projectPath - Path to the project
|
|
186
|
-
* @returns {Promise<boolean>} - True if migration needed
|
|
187
188
|
*/
|
|
188
|
-
async needsMigration(projectPath) {
|
|
189
|
+
async needsMigration(projectPath: string): Promise<boolean> {
|
|
189
190
|
const hasLegacy = await pathManager.hasLegacyStructure(projectPath)
|
|
190
191
|
if (!hasLegacy) return false
|
|
191
192
|
|
|
@@ -197,8 +198,6 @@ class ConfigManager {
|
|
|
197
198
|
if (!config || !config.projectId) return true
|
|
198
199
|
|
|
199
200
|
const globalPath = pathManager.getGlobalProjectPath(config.projectId)
|
|
200
|
-
const fs = require('fs').promises
|
|
201
|
-
const path = require('path')
|
|
202
201
|
|
|
203
202
|
try {
|
|
204
203
|
const coreFiles = await fs.readdir(path.join(globalPath, 'core'))
|
|
@@ -210,11 +209,8 @@ class ConfigManager {
|
|
|
210
209
|
|
|
211
210
|
/**
|
|
212
211
|
* Get the project ID from config, or generate it if config doesn't exist
|
|
213
|
-
*
|
|
214
|
-
* @param {string} projectPath - Path to the project
|
|
215
|
-
* @returns {Promise<string>} - Project ID
|
|
216
212
|
*/
|
|
217
|
-
async getProjectId(projectPath) {
|
|
213
|
+
async getProjectId(projectPath: string): Promise<string> {
|
|
218
214
|
const config = await this.readConfig(projectPath)
|
|
219
215
|
if (config && config.projectId) {
|
|
220
216
|
return config.projectId
|
|
@@ -225,12 +221,8 @@ class ConfigManager {
|
|
|
225
221
|
/**
|
|
226
222
|
* Find an author in the authors array by github username
|
|
227
223
|
* Reads from GLOBAL config
|
|
228
|
-
*
|
|
229
|
-
* @param {string} projectId - Project identifier
|
|
230
|
-
* @param {string} githubUsername - GitHub username to search for
|
|
231
|
-
* @returns {Promise<Object|null>} - Author object or null if not found
|
|
232
224
|
*/
|
|
233
|
-
async findAuthor(projectId, githubUsername) {
|
|
225
|
+
async findAuthor(projectId: string, githubUsername: string): Promise<Author | null> {
|
|
234
226
|
const globalConfig = await this.readGlobalConfig(projectId)
|
|
235
227
|
if (!globalConfig || !globalConfig.authors) return null
|
|
236
228
|
|
|
@@ -240,12 +232,11 @@ class ConfigManager {
|
|
|
240
232
|
/**
|
|
241
233
|
* Add a new author to the authors array
|
|
242
234
|
* Writes to GLOBAL config
|
|
243
|
-
*
|
|
244
|
-
* @param {string} projectId - Project identifier
|
|
245
|
-
* @param {Object} author - Author information {name, email, github}
|
|
246
|
-
* @returns {Promise<void>}
|
|
247
235
|
*/
|
|
248
|
-
async addAuthor(
|
|
236
|
+
async addAuthor(
|
|
237
|
+
projectId: string,
|
|
238
|
+
author: { name?: string; email?: string; github?: string }
|
|
239
|
+
): Promise<void> {
|
|
249
240
|
const globalConfig = await this.ensureGlobalConfig(projectId)
|
|
250
241
|
|
|
251
242
|
const exists = globalConfig.authors.some((a) => a.github === author.github)
|
|
@@ -267,12 +258,8 @@ class ConfigManager {
|
|
|
267
258
|
/**
|
|
268
259
|
* Update author's last activity timestamp
|
|
269
260
|
* Updates GLOBAL config
|
|
270
|
-
*
|
|
271
|
-
* @param {string} projectId - Project identifier
|
|
272
|
-
* @param {string} githubUsername - GitHub username
|
|
273
|
-
* @returns {Promise<void>}
|
|
274
261
|
*/
|
|
275
|
-
async updateAuthorActivity(projectId, githubUsername) {
|
|
262
|
+
async updateAuthorActivity(projectId: string, githubUsername: string): Promise<void> {
|
|
276
263
|
const globalConfig = await this.readGlobalConfig(projectId)
|
|
277
264
|
if (!globalConfig || !globalConfig.authors) return
|
|
278
265
|
|
|
@@ -286,12 +273,10 @@ class ConfigManager {
|
|
|
286
273
|
|
|
287
274
|
/**
|
|
288
275
|
* Get current author for session (detect or get from global config)
|
|
289
|
-
*
|
|
290
|
-
* @param {string} projectPath - Path to the project
|
|
291
|
-
* @returns {Promise<string>} - GitHub username of current author
|
|
292
276
|
*/
|
|
293
|
-
async getCurrentAuthor(projectPath) {
|
|
294
|
-
|
|
277
|
+
async getCurrentAuthor(projectPath: string): Promise<string> {
|
|
278
|
+
// Dynamic import to avoid circular dependency
|
|
279
|
+
const authorDetector = (await import('./author-detector')).default
|
|
295
280
|
const author = await authorDetector.detect()
|
|
296
281
|
|
|
297
282
|
const projectId = await this.getProjectId(projectPath)
|
|
@@ -302,11 +287,8 @@ class ConfigManager {
|
|
|
302
287
|
|
|
303
288
|
/**
|
|
304
289
|
* Check if config exists and is valid
|
|
305
|
-
*
|
|
306
|
-
* @param {string} projectPath - Path to the project
|
|
307
|
-
* @returns {Promise<boolean>} - True if valid config exists
|
|
308
290
|
*/
|
|
309
|
-
async isConfigured(projectPath) {
|
|
291
|
+
async isConfigured(projectPath: string): Promise<boolean> {
|
|
310
292
|
const config = await this.readConfig(projectPath)
|
|
311
293
|
return this.validateConfig(config)
|
|
312
294
|
}
|
|
@@ -314,11 +296,8 @@ class ConfigManager {
|
|
|
314
296
|
/**
|
|
315
297
|
* Get configuration with defaults
|
|
316
298
|
* Returns LOCAL config only (projectId, dataPath)
|
|
317
|
-
*
|
|
318
|
-
* @param {string} projectPath - Path to the project
|
|
319
|
-
* @returns {Promise<Object>} - Configuration with defaults
|
|
320
299
|
*/
|
|
321
|
-
async getConfigWithDefaults(projectPath) {
|
|
300
|
+
async getConfigWithDefaults(projectPath: string): Promise<LocalConfig> {
|
|
322
301
|
const config = await this.readConfig(projectPath)
|
|
323
302
|
if (config) {
|
|
324
303
|
return config
|
|
@@ -332,4 +311,5 @@ class ConfigManager {
|
|
|
332
311
|
}
|
|
333
312
|
}
|
|
334
313
|
|
|
335
|
-
|
|
314
|
+
const configManager = new ConfigManager()
|
|
315
|
+
export default configManager
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
const fs = require('fs').promises
|
|
2
|
-
const path = require('path')
|
|
3
|
-
const os = require('os')
|
|
4
|
-
|
|
5
1
|
/**
|
|
6
2
|
* EditorsConfig - Manages Claude installation tracking
|
|
7
3
|
*
|
|
@@ -12,7 +8,23 @@ const os = require('os')
|
|
|
12
8
|
*
|
|
13
9
|
* @version 0.5.0
|
|
14
10
|
*/
|
|
11
|
+
|
|
12
|
+
import fs from 'fs/promises'
|
|
13
|
+
import path from 'path'
|
|
14
|
+
import os from 'os'
|
|
15
|
+
|
|
16
|
+
interface EditorConfig {
|
|
17
|
+
version: string
|
|
18
|
+
editor: string
|
|
19
|
+
lastInstall: string
|
|
20
|
+
path: string
|
|
21
|
+
}
|
|
22
|
+
|
|
15
23
|
class EditorsConfig {
|
|
24
|
+
homeDir: string
|
|
25
|
+
configDir: string
|
|
26
|
+
configFile: string
|
|
27
|
+
|
|
16
28
|
constructor() {
|
|
17
29
|
this.homeDir = os.homedir()
|
|
18
30
|
this.configDir = path.join(this.homeDir, '.prjct-cli', 'config')
|
|
@@ -22,42 +34,38 @@ class EditorsConfig {
|
|
|
22
34
|
/**
|
|
23
35
|
* Ensure config directory exists
|
|
24
36
|
*/
|
|
25
|
-
async ensureConfigDir() {
|
|
37
|
+
async ensureConfigDir(): Promise<void> {
|
|
26
38
|
try {
|
|
27
39
|
await fs.mkdir(this.configDir, { recursive: true })
|
|
28
40
|
} catch (error) {
|
|
29
|
-
console.error('[editors-config] Error creating config directory:', error.message)
|
|
41
|
+
console.error('[editors-config] Error creating config directory:', (error as Error).message)
|
|
30
42
|
}
|
|
31
43
|
}
|
|
32
44
|
|
|
33
45
|
/**
|
|
34
46
|
* Load installation configuration
|
|
35
|
-
* @returns {Promise<Object|null>} Configuration object or null if not found
|
|
36
47
|
*/
|
|
37
|
-
async loadConfig() {
|
|
48
|
+
async loadConfig(): Promise<EditorConfig | null> {
|
|
38
49
|
try {
|
|
39
50
|
const content = await fs.readFile(this.configFile, 'utf-8')
|
|
40
51
|
return JSON.parse(content)
|
|
41
52
|
} catch (error) {
|
|
42
|
-
if (error.code === 'ENOENT') {
|
|
53
|
+
if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
|
|
43
54
|
return null
|
|
44
55
|
}
|
|
45
|
-
console.error('[editors-config] Error loading config:', error.message)
|
|
56
|
+
console.error('[editors-config] Error loading config:', (error as Error).message)
|
|
46
57
|
return null
|
|
47
58
|
}
|
|
48
59
|
}
|
|
49
60
|
|
|
50
61
|
/**
|
|
51
62
|
* Save installation configuration
|
|
52
|
-
* @param {string} version - Current prjct-cli version
|
|
53
|
-
* @param {string} claudePath - Path to Claude commands directory
|
|
54
|
-
* @returns {Promise<boolean>} Success status
|
|
55
63
|
*/
|
|
56
|
-
async saveConfig(version, claudePath) {
|
|
64
|
+
async saveConfig(version: string, claudePath: string): Promise<boolean> {
|
|
57
65
|
try {
|
|
58
66
|
await this.ensureConfigDir()
|
|
59
67
|
|
|
60
|
-
const config = {
|
|
68
|
+
const config: EditorConfig = {
|
|
61
69
|
version,
|
|
62
70
|
editor: 'claude',
|
|
63
71
|
lastInstall: new Date().toISOString(),
|
|
@@ -68,36 +76,31 @@ class EditorsConfig {
|
|
|
68
76
|
|
|
69
77
|
return true
|
|
70
78
|
} catch (error) {
|
|
71
|
-
console.error('[editors-config] Error saving config:', error.message)
|
|
79
|
+
console.error('[editors-config] Error saving config:', (error as Error).message)
|
|
72
80
|
return false
|
|
73
81
|
}
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
/**
|
|
77
85
|
* Get last installed version
|
|
78
|
-
* @returns {Promise<string|null>} Version string or null
|
|
79
86
|
*/
|
|
80
|
-
async getLastVersion() {
|
|
87
|
+
async getLastVersion(): Promise<string | null> {
|
|
81
88
|
const config = await this.loadConfig()
|
|
82
89
|
return config ? config.version : null
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
/**
|
|
86
93
|
* Check if version has changed since last install
|
|
87
|
-
* @param {string} currentVersion - Current version to compare
|
|
88
|
-
* @returns {Promise<boolean>} True if version has changed
|
|
89
94
|
*/
|
|
90
|
-
async hasVersionChanged(currentVersion) {
|
|
95
|
+
async hasVersionChanged(currentVersion: string): Promise<boolean> {
|
|
91
96
|
const lastVersion = await this.getLastVersion()
|
|
92
97
|
return lastVersion !== null && lastVersion !== currentVersion
|
|
93
98
|
}
|
|
94
99
|
|
|
95
100
|
/**
|
|
96
101
|
* Update version in configuration
|
|
97
|
-
* @param {string} version - New version to save
|
|
98
|
-
* @returns {Promise<boolean>} Success status
|
|
99
102
|
*/
|
|
100
|
-
async updateVersion(version) {
|
|
103
|
+
async updateVersion(version: string): Promise<boolean> {
|
|
101
104
|
try {
|
|
102
105
|
const config = await this.loadConfig()
|
|
103
106
|
if (!config) {
|
|
@@ -111,16 +114,15 @@ class EditorsConfig {
|
|
|
111
114
|
|
|
112
115
|
return true
|
|
113
116
|
} catch (error) {
|
|
114
|
-
console.error('[editors-config] Error updating version:', error.message)
|
|
117
|
+
console.error('[editors-config] Error updating version:', (error as Error).message)
|
|
115
118
|
return false
|
|
116
119
|
}
|
|
117
120
|
}
|
|
118
121
|
|
|
119
122
|
/**
|
|
120
123
|
* Check if config file exists
|
|
121
|
-
* @returns {Promise<boolean>} True if config exists
|
|
122
124
|
*/
|
|
123
|
-
async configExists() {
|
|
125
|
+
async configExists(): Promise<boolean> {
|
|
124
126
|
try {
|
|
125
127
|
await fs.access(this.configFile)
|
|
126
128
|
return true
|
|
@@ -132,9 +134,8 @@ class EditorsConfig {
|
|
|
132
134
|
/**
|
|
133
135
|
* Delete configuration file
|
|
134
136
|
* Used during uninstallation to clean up tracking data
|
|
135
|
-
* @returns {Promise<boolean>} Success status
|
|
136
137
|
*/
|
|
137
|
-
async deleteConfig() {
|
|
138
|
+
async deleteConfig(): Promise<boolean> {
|
|
138
139
|
try {
|
|
139
140
|
const exists = await this.configExists()
|
|
140
141
|
if (exists) {
|
|
@@ -142,10 +143,11 @@ class EditorsConfig {
|
|
|
142
143
|
}
|
|
143
144
|
return true
|
|
144
145
|
} catch (error) {
|
|
145
|
-
console.error('[editors-config] Error deleting config:', error.message)
|
|
146
|
+
console.error('[editors-config] Error deleting config:', (error as Error).message)
|
|
146
147
|
return false
|
|
147
148
|
}
|
|
148
149
|
}
|
|
149
150
|
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
+
const editorsConfig = new EditorsConfig()
|
|
153
|
+
export default editorsConfig
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cleanup - Legacy Installation Cleanup
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import fs from 'fs/promises'
|
|
6
|
+
import path from 'path'
|
|
7
|
+
import os from 'os'
|
|
8
|
+
import { legacyInstallDir, isWindows } from './detection'
|
|
9
|
+
import type { CleanupResult } from './types'
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Get platform-specific shell config files
|
|
13
|
+
*/
|
|
14
|
+
export function getShellConfigFiles(): string[] {
|
|
15
|
+
if (isWindows) {
|
|
16
|
+
const profilePaths: string[] = []
|
|
17
|
+
|
|
18
|
+
if (process.env.USERPROFILE) {
|
|
19
|
+
profilePaths.push(
|
|
20
|
+
path.join(
|
|
21
|
+
process.env.USERPROFILE,
|
|
22
|
+
'Documents',
|
|
23
|
+
'PowerShell',
|
|
24
|
+
'Microsoft.PowerShell_profile.ps1'
|
|
25
|
+
),
|
|
26
|
+
path.join(
|
|
27
|
+
process.env.USERPROFILE,
|
|
28
|
+
'Documents',
|
|
29
|
+
'WindowsPowerShell',
|
|
30
|
+
'Microsoft.PowerShell_profile.ps1'
|
|
31
|
+
)
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return profilePaths
|
|
36
|
+
} else {
|
|
37
|
+
return [
|
|
38
|
+
path.join(os.homedir(), '.zshrc'),
|
|
39
|
+
path.join(os.homedir(), '.bashrc'),
|
|
40
|
+
path.join(os.homedir(), '.profile'),
|
|
41
|
+
path.join(os.homedir(), '.bash_profile'),
|
|
42
|
+
]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Remove legacy installation files (keep projects data)
|
|
48
|
+
*/
|
|
49
|
+
export async function cleanupLegacyInstallation(): Promise<CleanupResult> {
|
|
50
|
+
const result: CleanupResult = {
|
|
51
|
+
success: false,
|
|
52
|
+
message: '',
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
const dirsToRemove = [
|
|
57
|
+
'bin',
|
|
58
|
+
'core',
|
|
59
|
+
'templates',
|
|
60
|
+
'scripts',
|
|
61
|
+
'node_modules',
|
|
62
|
+
'.git',
|
|
63
|
+
'__tests__',
|
|
64
|
+
'website',
|
|
65
|
+
'docs',
|
|
66
|
+
'.github',
|
|
67
|
+
]
|
|
68
|
+
const filesToRemove = [
|
|
69
|
+
'package.json',
|
|
70
|
+
'package-lock.json',
|
|
71
|
+
'README.md',
|
|
72
|
+
'LICENSE',
|
|
73
|
+
'CHANGELOG.md',
|
|
74
|
+
'CLAUDE.md',
|
|
75
|
+
'CONTRIBUTING.md',
|
|
76
|
+
'MIGRATION.md',
|
|
77
|
+
'TESTING.md',
|
|
78
|
+
'.gitignore',
|
|
79
|
+
'.eslintrc.js',
|
|
80
|
+
'.prettierrc',
|
|
81
|
+
'vitest.config.js',
|
|
82
|
+
'vitest.workspace.js',
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
let removedItems = 0
|
|
86
|
+
|
|
87
|
+
for (const dir of dirsToRemove) {
|
|
88
|
+
const dirPath = path.join(legacyInstallDir, dir)
|
|
89
|
+
try {
|
|
90
|
+
await fs.rm(dirPath, { recursive: true, force: true })
|
|
91
|
+
removedItems++
|
|
92
|
+
} catch {
|
|
93
|
+
// Directory doesn't exist
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
for (const file of filesToRemove) {
|
|
98
|
+
const filePath = path.join(legacyInstallDir, file)
|
|
99
|
+
try {
|
|
100
|
+
await fs.unlink(filePath)
|
|
101
|
+
removedItems++
|
|
102
|
+
} catch {
|
|
103
|
+
// File doesn't exist
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
result.success = true
|
|
108
|
+
result.message = `Removed ${removedItems} legacy installation items`
|
|
109
|
+
return result
|
|
110
|
+
} catch (error) {
|
|
111
|
+
result.message = `Cleanup failed: ${(error as Error).message}`
|
|
112
|
+
return result
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Clean up legacy PATH entries from shell config files
|
|
118
|
+
*/
|
|
119
|
+
export async function cleanupLegacyPATH(): Promise<CleanupResult> {
|
|
120
|
+
const result: CleanupResult = {
|
|
121
|
+
success: false,
|
|
122
|
+
message: '',
|
|
123
|
+
filesModified: 0,
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
try {
|
|
127
|
+
const shellConfigs = getShellConfigFiles()
|
|
128
|
+
|
|
129
|
+
for (const configFile of shellConfigs) {
|
|
130
|
+
try {
|
|
131
|
+
const content = await fs.readFile(configFile, 'utf8')
|
|
132
|
+
|
|
133
|
+
if (!content.includes('.prjct-cli/bin')) {
|
|
134
|
+
continue
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const lines = content.split('\n')
|
|
138
|
+
const filteredLines = lines.filter((line) => {
|
|
139
|
+
return !line.includes('.prjct-cli/bin') && !line.includes('# prjct/cli')
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const cleanedLines: string[] = []
|
|
143
|
+
for (let i = 0; i < filteredLines.length; i++) {
|
|
144
|
+
const line = filteredLines[i]
|
|
145
|
+
const prevLine = filteredLines[i - 1]
|
|
146
|
+
|
|
147
|
+
if (line.trim() === '' && prevLine && prevLine.trim() === '') {
|
|
148
|
+
continue
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
cleanedLines.push(line)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
await fs.writeFile(configFile, cleanedLines.join('\n'), 'utf8')
|
|
155
|
+
result.filesModified!++
|
|
156
|
+
} catch {
|
|
157
|
+
// File doesn't exist or can't read
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
result.success = true
|
|
162
|
+
result.message =
|
|
163
|
+
result.filesModified! > 0
|
|
164
|
+
? `Cleaned PATH from ${result.filesModified} shell config(s)`
|
|
165
|
+
: 'No legacy PATH entries found'
|
|
166
|
+
|
|
167
|
+
return result
|
|
168
|
+
} catch (error) {
|
|
169
|
+
result.message = `PATH cleanup failed: ${(error as Error).message}`
|
|
170
|
+
return result
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Clean up legacy symlinks
|
|
176
|
+
*/
|
|
177
|
+
export async function cleanupLegacySymlinks(): Promise<CleanupResult> {
|
|
178
|
+
const result: CleanupResult = {
|
|
179
|
+
success: false,
|
|
180
|
+
message: '',
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (isWindows) {
|
|
184
|
+
result.success = true
|
|
185
|
+
result.message = 'No symlinks on Windows'
|
|
186
|
+
return result
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
const symlinkPath = path.join(os.homedir(), '.local', 'bin', 'prjct')
|
|
191
|
+
|
|
192
|
+
try {
|
|
193
|
+
const stat = await fs.lstat(symlinkPath)
|
|
194
|
+
|
|
195
|
+
if (stat.isSymbolicLink()) {
|
|
196
|
+
const target = await fs.readlink(symlinkPath)
|
|
197
|
+
|
|
198
|
+
if (target.includes('.prjct-cli')) {
|
|
199
|
+
await fs.unlink(symlinkPath)
|
|
200
|
+
result.success = true
|
|
201
|
+
result.message = 'Removed legacy symlink'
|
|
202
|
+
return result
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
} catch {
|
|
206
|
+
// Symlink doesn't exist
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
result.success = true
|
|
210
|
+
result.message = 'No legacy symlinks found'
|
|
211
|
+
return result
|
|
212
|
+
} catch (error) {
|
|
213
|
+
result.message = `Symlink cleanup failed: ${(error as Error).message}`
|
|
214
|
+
return result
|
|
215
|
+
}
|
|
216
|
+
}
|