prjct-cli 0.11.5 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +58 -0
- package/README.md +81 -25
- package/bin/dev.js +1 -1
- package/bin/generate-views.js +209 -0
- package/bin/migrate-to-json.js +742 -0
- package/bin/prjct +5 -5
- package/bin/serve.js +226 -50
- package/core/__tests__/agentic/{memory-system.test.js → memory-system.test.ts} +12 -23
- package/core/__tests__/agentic/{plan-mode.test.js → plan-mode.test.ts} +26 -24
- package/core/__tests__/agentic/{prompt-builder.test.js → prompt-builder.test.ts} +3 -8
- package/core/__tests__/utils/{date-helper.test.js → date-helper.test.ts} +19 -30
- package/core/__tests__/utils/{output.test.js → output.test.ts} +12 -24
- package/core/agentic/agent-router.ts +137 -0
- package/core/agentic/chain-of-thought.ts +228 -0
- package/core/agentic/command-executor/command-executor.ts +384 -0
- package/core/agentic/command-executor/index.ts +16 -0
- package/core/agentic/command-executor/status-signal.ts +38 -0
- package/core/agentic/command-executor/types.ts +79 -0
- package/core/agentic/command-executor.ts +8 -0
- package/core/agentic/{context-builder.js → context-builder.ts} +92 -81
- package/core/agentic/context-filter.ts +365 -0
- package/core/agentic/ground-truth/index.ts +76 -0
- package/core/agentic/ground-truth/types.ts +33 -0
- package/core/agentic/ground-truth/utils.ts +48 -0
- package/core/agentic/ground-truth/verifiers/analyze.ts +54 -0
- package/core/agentic/ground-truth/verifiers/done.ts +75 -0
- package/core/agentic/ground-truth/verifiers/feature.ts +70 -0
- package/core/agentic/ground-truth/verifiers/index.ts +37 -0
- package/core/agentic/ground-truth/verifiers/init.ts +52 -0
- package/core/agentic/ground-truth/verifiers/now.ts +57 -0
- package/core/agentic/ground-truth/verifiers/ship.ts +85 -0
- package/core/agentic/ground-truth/verifiers/spec.ts +45 -0
- package/core/agentic/ground-truth/verifiers/sync.ts +47 -0
- package/core/agentic/ground-truth/verifiers.ts +6 -0
- package/core/agentic/ground-truth.ts +8 -0
- package/core/agentic/loop-detector/error-analysis.ts +97 -0
- package/core/agentic/loop-detector/hallucination.ts +71 -0
- package/core/agentic/loop-detector/index.ts +41 -0
- package/core/agentic/loop-detector/loop-detector.ts +222 -0
- package/core/agentic/loop-detector/types.ts +66 -0
- package/core/agentic/loop-detector.ts +8 -0
- package/core/agentic/memory-system/history.ts +53 -0
- package/core/agentic/memory-system/index.ts +192 -0
- package/core/agentic/memory-system/patterns.ts +156 -0
- package/core/agentic/memory-system/semantic-memories.ts +277 -0
- package/core/agentic/memory-system/session.ts +21 -0
- package/core/agentic/memory-system/types.ts +159 -0
- package/core/agentic/memory-system.ts +8 -0
- package/core/agentic/parallel-tools.ts +165 -0
- package/core/agentic/plan-mode/approval.ts +57 -0
- package/core/agentic/plan-mode/constants.ts +44 -0
- package/core/agentic/plan-mode/index.ts +28 -0
- package/core/agentic/plan-mode/plan-mode.ts +406 -0
- package/core/agentic/plan-mode/types.ts +193 -0
- package/core/agentic/plan-mode.ts +8 -0
- package/core/agentic/prompt-builder.ts +566 -0
- package/core/agentic/response-templates.ts +164 -0
- package/core/agentic/semantic-compression.ts +273 -0
- package/core/agentic/services.ts +206 -0
- package/core/agentic/smart-context.ts +476 -0
- package/core/agentic/{template-loader.js → template-loader.ts} +27 -16
- package/core/agentic/think-blocks.ts +202 -0
- package/core/agentic/tool-registry.ts +119 -0
- package/core/agentic/validation-rules.ts +313 -0
- package/core/agents/index.ts +28 -0
- package/core/agents/performance.ts +444 -0
- package/core/agents/types.ts +126 -0
- package/core/bus/{index.js → index.ts} +57 -61
- package/core/command-registry/categories.ts +23 -0
- package/core/command-registry/commands.ts +15 -0
- package/core/command-registry/core-commands.ts +319 -0
- package/core/command-registry/index.ts +158 -0
- package/core/command-registry/optional-commands.ts +119 -0
- package/core/command-registry/setup-commands.ts +53 -0
- package/core/command-registry/types.ts +59 -0
- package/core/command-registry.ts +9 -0
- package/core/commands/analysis.ts +298 -0
- package/core/commands/analytics.ts +288 -0
- package/core/commands/base.ts +273 -0
- package/core/commands/index.ts +211 -0
- package/core/commands/maintenance.ts +226 -0
- package/core/commands/planning.ts +311 -0
- package/core/commands/setup.ts +309 -0
- package/core/commands/shipping.ts +188 -0
- package/core/commands/types.ts +183 -0
- package/core/commands/workflow.ts +226 -0
- package/core/commands.ts +11 -0
- package/core/constants/formats.ts +187 -0
- package/core/constants/index.ts +7 -0
- package/core/{context-sync.js → context-sync.ts} +59 -26
- package/core/data/agents-manager.ts +76 -0
- package/core/data/analysis-manager.ts +83 -0
- package/core/data/base-manager.ts +156 -0
- package/core/data/ideas-manager.ts +81 -0
- package/core/data/index.ts +32 -0
- package/core/data/outcomes-manager.ts +96 -0
- package/core/data/project-manager.ts +75 -0
- package/core/data/roadmap-manager.ts +118 -0
- package/core/data/shipped-manager.ts +65 -0
- package/core/data/state-manager.ts +214 -0
- package/core/domain/{agent-generator.js → agent-generator.ts} +77 -57
- package/core/domain/{agent-loader.js → agent-loader.ts} +65 -56
- package/core/domain/{agent-matcher.js → agent-matcher.ts} +51 -24
- package/core/domain/{agent-validator.js → agent-validator.ts} +70 -37
- package/core/domain/{analyzer.js → analyzer.ts} +91 -85
- package/core/domain/{architect-session.js → architect-session.ts} +49 -34
- package/core/domain/{architecture-generator.js → architecture-generator.ts} +25 -13
- package/core/domain/{context-estimator.js → context-estimator.ts} +57 -36
- package/core/domain/{product-standards.js → product-standards.ts} +40 -26
- package/core/domain/{smart-cache.js → smart-cache.ts} +39 -30
- package/core/domain/{snapshot-manager.js → snapshot-manager.ts} +103 -100
- package/core/domain/{task-analyzer.js → task-analyzer.ts} +82 -43
- package/core/domain/task-stack/index.ts +19 -0
- package/core/domain/task-stack/parser.ts +86 -0
- package/core/domain/task-stack/storage.ts +123 -0
- package/core/domain/task-stack/task-stack.ts +340 -0
- package/core/domain/task-stack/types.ts +51 -0
- package/core/domain/task-stack.ts +8 -0
- package/core/{index.js → index.ts} +61 -18
- package/core/infrastructure/{agent-detector.js → agent-detector.ts} +55 -19
- package/core/infrastructure/agents/{claude-agent.js → claude-agent.ts} +61 -21
- package/core/infrastructure/{author-detector.js → author-detector.ts} +42 -49
- package/core/infrastructure/{capability-installer.js → capability-installer.ts} +51 -27
- package/core/infrastructure/{command-installer.js → command-installer/command-installer.ts} +43 -144
- package/core/infrastructure/command-installer/global-config.ts +106 -0
- package/core/infrastructure/command-installer/index.ts +25 -0
- package/core/infrastructure/command-installer/types.ts +41 -0
- package/core/infrastructure/command-installer.ts +8 -0
- package/core/infrastructure/{config-manager.js → config-manager.ts} +60 -80
- package/core/infrastructure/{editors-config.js → editors-config.ts} +33 -31
- package/core/infrastructure/legacy-installer-detector/cleanup.ts +216 -0
- package/core/infrastructure/legacy-installer-detector/detection.ts +95 -0
- package/core/infrastructure/legacy-installer-detector/index.ts +171 -0
- package/core/infrastructure/legacy-installer-detector/migration.ts +87 -0
- package/core/infrastructure/legacy-installer-detector/types.ts +42 -0
- package/core/infrastructure/legacy-installer-detector.ts +7 -0
- package/core/infrastructure/migrator/file-operations.ts +125 -0
- package/core/infrastructure/migrator/index.ts +288 -0
- package/core/infrastructure/migrator/project-scanner.ts +89 -0
- package/core/infrastructure/migrator/reports.ts +117 -0
- package/core/infrastructure/migrator/types.ts +124 -0
- package/core/infrastructure/migrator/validation.ts +94 -0
- package/core/infrastructure/migrator/version-migration.ts +117 -0
- package/core/infrastructure/migrator.ts +10 -0
- package/core/infrastructure/{path-manager.js → path-manager.ts} +51 -91
- package/core/infrastructure/session-manager/index.ts +23 -0
- package/core/infrastructure/session-manager/migration.ts +88 -0
- package/core/infrastructure/session-manager/session-manager.ts +307 -0
- package/core/infrastructure/session-manager/types.ts +45 -0
- package/core/infrastructure/session-manager.ts +8 -0
- package/core/infrastructure/{setup.js → setup.ts} +29 -21
- package/core/infrastructure/{update-checker.js → update-checker.ts} +40 -18
- package/core/outcomes/analyzer.ts +333 -0
- package/core/outcomes/index.ts +34 -0
- package/core/outcomes/recorder.ts +194 -0
- package/core/outcomes/types.ts +145 -0
- package/core/plugin/{hooks.js → hooks.ts} +56 -58
- package/core/plugin/{index.js → index.ts} +19 -8
- package/core/plugin/{loader.js → loader.ts} +87 -69
- package/core/plugin/{registry.js → registry.ts} +49 -45
- package/core/plugins/{webhook.js → webhook.ts} +43 -27
- package/core/schemas/agents.ts +27 -0
- package/core/schemas/analysis.ts +41 -0
- package/core/schemas/ideas.ts +83 -0
- package/core/schemas/index.ts +73 -0
- package/core/schemas/outcomes.ts +22 -0
- package/core/schemas/project.ts +26 -0
- package/core/schemas/roadmap.ts +90 -0
- package/core/schemas/shipped.ts +82 -0
- package/core/schemas/state.ts +107 -0
- package/core/session/index.ts +17 -0
- package/core/session/{metrics.js → metrics.ts} +64 -46
- package/core/session/{index.js → session-manager.ts} +51 -117
- package/core/session/types.ts +29 -0
- package/core/session/utils.ts +57 -0
- package/core/state/index.ts +25 -0
- package/core/state/manager.ts +376 -0
- package/core/state/types.ts +185 -0
- package/core/tsconfig.json +22 -0
- package/core/types/index.ts +506 -0
- package/core/utils/{animations.js → animations.ts} +74 -28
- package/core/utils/{branding.js → branding.ts} +29 -4
- package/core/utils/{date-helper.js → date-helper.ts} +31 -74
- package/core/utils/file-helper.ts +262 -0
- package/core/utils/{jsonl-helper.js → jsonl-helper.ts} +71 -107
- package/core/utils/{logger.js → logger.ts} +24 -12
- package/core/utils/{output.js → output.ts} +25 -13
- package/core/utils/{project-capabilities.js → project-capabilities.ts} +31 -18
- package/core/utils/{session-helper.js → session-helper.ts} +79 -66
- package/core/utils/{version.js → version.ts} +23 -31
- package/core/view-generator.ts +536 -0
- package/package.json +23 -17
- package/packages/shared/.turbo/turbo-build.log +14 -0
- package/packages/shared/dist/index.d.ts +8 -613
- package/packages/shared/dist/index.d.ts.map +1 -0
- package/packages/shared/dist/index.js +4110 -118
- package/packages/shared/dist/schemas.d.ts +408 -0
- package/packages/shared/dist/schemas.d.ts.map +1 -0
- package/packages/shared/dist/types.d.ts +144 -0
- package/packages/shared/dist/types.d.ts.map +1 -0
- package/packages/shared/dist/unified.d.ts +139 -0
- package/packages/shared/dist/unified.d.ts.map +1 -0
- package/packages/shared/dist/utils.d.ts +60 -0
- package/packages/shared/dist/utils.d.ts.map +1 -0
- package/packages/shared/package.json +4 -4
- package/packages/shared/src/index.ts +1 -0
- package/packages/shared/src/unified.ts +174 -0
- package/packages/web/app/api/claude/sessions/route.ts +1 -1
- package/packages/web/app/api/claude/status/route.ts +1 -1
- package/packages/web/app/api/migrate/route.ts +46 -0
- package/packages/web/app/api/projects/[id]/route.ts +1 -1
- package/packages/web/app/api/projects/[id]/stats/route.ts +30 -2
- package/packages/web/app/api/projects/[id]/status/route.ts +1 -1
- package/packages/web/app/api/projects/route.ts +1 -1
- package/packages/web/app/api/settings/route.ts +97 -0
- package/packages/web/app/api/v2/projects/[id]/unified/route.ts +57 -0
- package/packages/web/app/globals.css +38 -0
- package/packages/web/app/layout.tsx +10 -2
- package/packages/web/app/page.tsx +9 -224
- package/packages/web/app/project/[id]/page.tsx +191 -63
- package/packages/web/app/project/[id]/stats/loading.tsx +43 -0
- package/packages/web/app/project/[id]/stats/page.tsx +204 -163
- package/packages/web/app/settings/page.tsx +222 -2
- package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +2 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +50 -0
- package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +8 -0
- package/packages/web/components/ActivityTimeline/hooks/index.ts +2 -0
- package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +9 -0
- package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +23 -0
- package/packages/web/components/ActivityTimeline/index.ts +2 -0
- package/packages/web/components/AgentsCard/AgentsCard.tsx +63 -0
- package/packages/web/components/AgentsCard/AgentsCard.types.ts +13 -0
- package/packages/web/components/AgentsCard/index.ts +2 -0
- package/packages/web/components/AppSidebar/AppSidebar.tsx +190 -0
- package/packages/web/components/AppSidebar/index.ts +1 -0
- package/packages/web/components/BackLink/BackLink.tsx +18 -0
- package/packages/web/components/BackLink/BackLink.types.ts +5 -0
- package/packages/web/components/BackLink/index.ts +2 -0
- package/packages/web/components/BentoCard/BentoCard.constants.ts +16 -0
- package/packages/web/components/BentoCard/BentoCard.tsx +47 -0
- package/packages/web/components/BentoCard/BentoCard.types.ts +15 -0
- package/packages/web/components/BentoCard/index.ts +2 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +9 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +18 -0
- package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +5 -0
- package/packages/web/components/BentoCardSkeleton/index.ts +2 -0
- package/packages/web/components/{stats → BentoGrid}/BentoGrid.tsx +4 -8
- package/packages/web/components/BentoGrid/BentoGrid.types.ts +4 -0
- package/packages/web/components/BentoGrid/index.ts +2 -0
- package/packages/web/components/CommandButton/index.ts +1 -0
- package/packages/web/components/ConnectionStatus/index.ts +1 -0
- package/packages/web/components/DashboardContent/DashboardContent.tsx +254 -0
- package/packages/web/components/DashboardContent/index.ts +1 -0
- package/packages/web/components/DateGroup/DateGroup.tsx +18 -0
- package/packages/web/components/DateGroup/DateGroup.types.ts +6 -0
- package/packages/web/components/DateGroup/DateGroup.utils.ts +11 -0
- package/packages/web/components/DateGroup/index.ts +2 -0
- package/packages/web/components/{stats → EmptyState}/EmptyState.tsx +1 -10
- package/packages/web/components/EmptyState/EmptyState.types.ts +10 -0
- package/packages/web/components/EmptyState/index.ts +2 -0
- package/packages/web/components/EventRow/EventRow.constants.ts +10 -0
- package/packages/web/components/EventRow/EventRow.tsx +49 -0
- package/packages/web/components/EventRow/EventRow.types.ts +7 -0
- package/packages/web/components/EventRow/EventRow.utils.ts +49 -0
- package/packages/web/components/EventRow/index.ts +2 -0
- package/packages/web/components/ExpandButton/ExpandButton.tsx +18 -0
- package/packages/web/components/ExpandButton/ExpandButton.types.ts +6 -0
- package/packages/web/components/ExpandButton/index.ts +2 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +14 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +5 -0
- package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +13 -0
- package/packages/web/components/HealthGradientBackground/index.ts +2 -0
- package/packages/web/components/HeroSection/HeroSection.tsx +55 -0
- package/packages/web/components/HeroSection/HeroSection.types.ts +14 -0
- package/packages/web/components/HeroSection/HeroSection.utils.ts +7 -0
- package/packages/web/components/HeroSection/hooks/index.ts +2 -0
- package/packages/web/components/HeroSection/hooks/useCountUp.ts +45 -0
- package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +18 -0
- package/packages/web/components/HeroSection/index.ts +2 -0
- package/packages/web/components/{stats → IdeasCard}/IdeasCard.tsx +3 -14
- package/packages/web/components/IdeasCard/IdeasCard.types.ts +9 -0
- package/packages/web/components/IdeasCard/index.ts +2 -0
- package/packages/web/components/InsightMessage/InsightMessage.tsx +9 -0
- package/packages/web/components/InsightMessage/InsightMessage.types.ts +3 -0
- package/packages/web/components/InsightMessage/index.ts +2 -0
- package/packages/web/components/Logo/index.ts +1 -0
- package/packages/web/components/MarkdownContent/index.ts +1 -0
- package/packages/web/components/NowCard/NowCard.tsx +93 -0
- package/packages/web/components/NowCard/NowCard.types.ts +15 -0
- package/packages/web/components/NowCard/index.ts +2 -0
- package/packages/web/components/ProgressRing/ProgressRing.constants.ts +20 -0
- package/packages/web/components/{stats → ProgressRing}/ProgressRing.tsx +4 -27
- package/packages/web/components/ProgressRing/ProgressRing.types.ts +11 -0
- package/packages/web/components/ProgressRing/index.ts +2 -0
- package/packages/web/components/ProjectAvatar/index.ts +1 -0
- package/packages/web/components/Providers/index.ts +1 -0
- package/packages/web/components/QueueCard/QueueCard.tsx +72 -0
- package/packages/web/components/QueueCard/QueueCard.types.ts +11 -0
- package/packages/web/components/QueueCard/QueueCard.utils.ts +12 -0
- package/packages/web/components/QueueCard/index.ts +2 -0
- package/packages/web/components/{stats → RoadmapCard}/RoadmapCard.tsx +3 -23
- package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +15 -0
- package/packages/web/components/RoadmapCard/index.ts +2 -0
- package/packages/web/components/{stats → ShipsCard}/ShipsCard.tsx +4 -22
- package/packages/web/components/ShipsCard/ShipsCard.types.ts +12 -0
- package/packages/web/components/ShipsCard/ShipsCard.utils.ts +4 -0
- package/packages/web/components/ShipsCard/index.ts +2 -0
- package/packages/web/components/{stats → SparklineChart}/SparklineChart.tsx +1 -7
- package/packages/web/components/SparklineChart/SparklineChart.types.ts +6 -0
- package/packages/web/components/SparklineChart/index.ts +2 -0
- package/packages/web/components/StreakCard/StreakCard.constants.ts +2 -0
- package/packages/web/components/{stats → StreakCard}/StreakCard.tsx +5 -11
- package/packages/web/components/StreakCard/StreakCard.types.ts +4 -0
- package/packages/web/components/StreakCard/index.ts +2 -0
- package/packages/web/components/TasksCounter/TasksCounter.tsx +14 -0
- package/packages/web/components/TasksCounter/TasksCounter.types.ts +3 -0
- package/packages/web/components/TasksCounter/index.ts +2 -0
- package/packages/web/components/TechStackBadges/index.ts +1 -0
- package/packages/web/components/{TerminalTab.tsx → TerminalTabs/TerminalTab.tsx} +11 -0
- package/packages/web/components/{TerminalTabs.tsx → TerminalTabs/TerminalTabs.tsx} +29 -28
- package/packages/web/components/TerminalTabs/index.ts +1 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.tsx +27 -0
- package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +3 -0
- package/packages/web/components/VelocityBadge/index.ts +2 -0
- package/packages/web/components/VelocityCard/VelocityCard.tsx +71 -0
- package/packages/web/components/VelocityCard/VelocityCard.types.ts +7 -0
- package/packages/web/components/VelocityCard/index.ts +2 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +13 -0
- package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +3 -0
- package/packages/web/components/WeeklySparkline/index.ts +2 -0
- package/packages/web/components/ui/input.tsx +21 -0
- package/packages/web/context/TerminalTabsContext.tsx +46 -1
- package/packages/web/hooks/useClaudeTerminal.ts +71 -21
- package/packages/web/hooks/useProjectStats.ts +55 -0
- package/packages/web/hooks/useProjects.ts +6 -6
- package/packages/web/lib/actions/projects.ts +15 -0
- package/packages/web/lib/json-loader.ts +630 -0
- package/packages/web/lib/services/index.ts +9 -0
- package/packages/web/lib/services/migration.server.ts +600 -0
- package/packages/web/lib/services/projects.server.ts +52 -0
- package/packages/web/lib/services/stats.server.ts +264 -0
- package/packages/web/lib/unified-loader.ts +396 -0
- package/packages/web/package.json +10 -7
- package/packages/web/server.ts +58 -8
- package/templates/commands/done.md +76 -32
- package/templates/commands/feature.md +121 -47
- package/templates/commands/idea.md +81 -8
- package/templates/commands/now.md +41 -17
- package/templates/commands/ship.md +64 -25
- package/templates/commands/sync.md +28 -3
- package/core/agentic/agent-router.js +0 -140
- package/core/agentic/chain-of-thought.js +0 -578
- package/core/agentic/command-executor.js +0 -417
- package/core/agentic/context-filter.js +0 -354
- package/core/agentic/ground-truth.js +0 -591
- package/core/agentic/loop-detector.js +0 -406
- package/core/agentic/memory-system.js +0 -845
- package/core/agentic/parallel-tools.js +0 -366
- package/core/agentic/plan-mode.js +0 -572
- package/core/agentic/prompt-builder.js +0 -352
- package/core/agentic/response-templates.js +0 -290
- package/core/agentic/semantic-compression.js +0 -517
- package/core/agentic/think-blocks.js +0 -657
- package/core/agentic/tool-registry.js +0 -184
- package/core/agentic/validation-rules.js +0 -380
- package/core/command-registry.js +0 -698
- package/core/commands.js +0 -2237
- package/core/domain/task-stack.js +0 -497
- package/core/infrastructure/legacy-installer-detector.js +0 -546
- package/core/infrastructure/migrator.js +0 -796
- package/core/infrastructure/session-manager.js +0 -390
- package/core/utils/file-helper.js +0 -329
- package/packages/web/app/api/projects/[id]/delete/route.ts +0 -21
- package/packages/web/app/api/stats/route.ts +0 -38
- package/packages/web/components/AppSidebar.tsx +0 -113
- package/packages/web/components/stats/ActivityTimeline.tsx +0 -201
- package/packages/web/components/stats/AgentsCard.tsx +0 -56
- package/packages/web/components/stats/BentoCard.tsx +0 -88
- package/packages/web/components/stats/HeroSection.tsx +0 -172
- package/packages/web/components/stats/NowCard.tsx +0 -71
- package/packages/web/components/stats/QueueCard.tsx +0 -58
- package/packages/web/components/stats/VelocityCard.tsx +0 -60
- package/packages/web/components/stats/index.ts +0 -17
- package/packages/web/hooks/useStats.ts +0 -28
- /package/packages/web/components/{CommandButton.tsx → CommandButton/CommandButton.tsx} +0 -0
- /package/packages/web/components/{ConnectionStatus.tsx → ConnectionStatus/ConnectionStatus.tsx} +0 -0
- /package/packages/web/components/{Logo.tsx → Logo/Logo.tsx} +0 -0
- /package/packages/web/components/{MarkdownContent.tsx → MarkdownContent/MarkdownContent.tsx} +0 -0
- /package/packages/web/components/{ProjectAvatar.tsx → ProjectAvatar/ProjectAvatar.tsx} +0 -0
- /package/packages/web/components/{providers.tsx → Providers/Providers.tsx} +0 -0
- /package/packages/web/components/{TechStackBadges.tsx → TechStackBadges/TechStackBadges.tsx} +0 -0
|
@@ -1,37 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SessionManager
|
|
3
|
-
*
|
|
4
|
-
* Tracks work sessions with metrics, timeline, and duration.
|
|
5
|
-
* Inspired by OpenCode's session system but simplified.
|
|
6
|
-
*
|
|
7
|
-
* Storage: ~/.prjct-cli/projects/{projectId}/sessions/
|
|
8
|
-
*
|
|
9
|
-
* @version 1.0.0
|
|
2
|
+
* SessionManager Class
|
|
3
|
+
* Core session management functionality
|
|
10
4
|
*/
|
|
11
5
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
class SessionManager {
|
|
34
|
-
constructor(projectPath) {
|
|
6
|
+
import fs from 'fs/promises'
|
|
7
|
+
import path from 'path'
|
|
8
|
+
import { exec } from 'child_process'
|
|
9
|
+
import { promisify } from 'util'
|
|
10
|
+
import pathManager from '../infrastructure/path-manager'
|
|
11
|
+
import configManager from '../infrastructure/config-manager'
|
|
12
|
+
import { emit } from '../bus'
|
|
13
|
+
import type { Session, SessionMetrics } from './types'
|
|
14
|
+
import { generateId, calculateDuration, formatDuration } from './utils'
|
|
15
|
+
|
|
16
|
+
const execAsync = promisify(exec)
|
|
17
|
+
|
|
18
|
+
export class SessionManager {
|
|
19
|
+
private projectPath: string
|
|
20
|
+
private projectId: string | null
|
|
21
|
+
private sessionDir: string | null
|
|
22
|
+
private initialized: boolean
|
|
23
|
+
|
|
24
|
+
constructor(projectPath: string) {
|
|
35
25
|
this.projectPath = projectPath
|
|
36
26
|
this.projectId = null
|
|
37
27
|
this.sessionDir = null
|
|
@@ -41,7 +31,7 @@ class SessionManager {
|
|
|
41
31
|
/**
|
|
42
32
|
* Initialize session manager for project
|
|
43
33
|
*/
|
|
44
|
-
async initialize() {
|
|
34
|
+
async initialize(): Promise<void> {
|
|
45
35
|
this.projectId = await configManager.getProjectId(this.projectPath)
|
|
46
36
|
if (!this.projectId) {
|
|
47
37
|
throw new Error('No prjct project found. Run /p:init first.')
|
|
@@ -57,23 +47,17 @@ class SessionManager {
|
|
|
57
47
|
/**
|
|
58
48
|
* Generate unique session ID
|
|
59
49
|
*/
|
|
60
|
-
generateId() {
|
|
61
|
-
|
|
62
|
-
let id = 'sess_'
|
|
63
|
-
for (let i = 0; i < 8; i++) {
|
|
64
|
-
id += chars.charAt(Math.floor(Math.random() * chars.length))
|
|
65
|
-
}
|
|
66
|
-
return id
|
|
50
|
+
generateId(): string {
|
|
51
|
+
return generateId()
|
|
67
52
|
}
|
|
68
53
|
|
|
69
54
|
/**
|
|
70
55
|
* Get current active session
|
|
71
|
-
* @returns {Promise<Session|null>}
|
|
72
56
|
*/
|
|
73
|
-
async getCurrent() {
|
|
57
|
+
async getCurrent(): Promise<Session | null> {
|
|
74
58
|
if (!this.initialized) await this.initialize()
|
|
75
59
|
|
|
76
|
-
const currentPath = path.join(this.sessionDir
|
|
60
|
+
const currentPath = path.join(this.sessionDir!, 'current.json')
|
|
77
61
|
try {
|
|
78
62
|
const content = await fs.readFile(currentPath, 'utf-8')
|
|
79
63
|
return JSON.parse(content)
|
|
@@ -84,10 +68,8 @@ class SessionManager {
|
|
|
84
68
|
|
|
85
69
|
/**
|
|
86
70
|
* Create a new session
|
|
87
|
-
* @param {string} task - Task description
|
|
88
|
-
* @returns {Promise<Session>}
|
|
89
71
|
*/
|
|
90
|
-
async create(task) {
|
|
72
|
+
async create(task: string): Promise<Session> {
|
|
91
73
|
if (!this.initialized) await this.initialize()
|
|
92
74
|
|
|
93
75
|
// Check if there's already an active session
|
|
@@ -97,9 +79,9 @@ class SessionManager {
|
|
|
97
79
|
}
|
|
98
80
|
|
|
99
81
|
const now = new Date().toISOString()
|
|
100
|
-
const session = {
|
|
82
|
+
const session: Session = {
|
|
101
83
|
id: this.generateId(),
|
|
102
|
-
projectId: this.projectId
|
|
84
|
+
projectId: this.projectId!,
|
|
103
85
|
task,
|
|
104
86
|
status: 'active',
|
|
105
87
|
startedAt: now,
|
|
@@ -136,10 +118,8 @@ class SessionManager {
|
|
|
136
118
|
|
|
137
119
|
/**
|
|
138
120
|
* Resume a paused session or continue active session
|
|
139
|
-
* @param {string} [task] - Optional new task (creates new session if provided)
|
|
140
|
-
* @returns {Promise<Session>}
|
|
141
121
|
*/
|
|
142
|
-
async resume(task = null) {
|
|
122
|
+
async resume(task: string | null = null): Promise<Session> {
|
|
143
123
|
if (!this.initialized) await this.initialize()
|
|
144
124
|
|
|
145
125
|
const current = await this.getCurrent()
|
|
@@ -182,9 +162,8 @@ class SessionManager {
|
|
|
182
162
|
|
|
183
163
|
/**
|
|
184
164
|
* Pause current session
|
|
185
|
-
* @returns {Promise<Session>}
|
|
186
165
|
*/
|
|
187
|
-
async pause() {
|
|
166
|
+
async pause(): Promise<Session> {
|
|
188
167
|
if (!this.initialized) await this.initialize()
|
|
189
168
|
|
|
190
169
|
const current = await this.getCurrent()
|
|
@@ -199,7 +178,7 @@ class SessionManager {
|
|
|
199
178
|
const now = new Date().toISOString()
|
|
200
179
|
current.status = 'paused'
|
|
201
180
|
current.pausedAt = now
|
|
202
|
-
current.duration =
|
|
181
|
+
current.duration = calculateDuration(current)
|
|
203
182
|
current.timeline.push({ type: 'pause', at: now })
|
|
204
183
|
|
|
205
184
|
await this.saveCurrent(current)
|
|
@@ -218,9 +197,8 @@ class SessionManager {
|
|
|
218
197
|
|
|
219
198
|
/**
|
|
220
199
|
* Complete current session
|
|
221
|
-
* @returns {Promise<Session>}
|
|
222
200
|
*/
|
|
223
|
-
async complete() {
|
|
201
|
+
async complete(): Promise<Session> {
|
|
224
202
|
if (!this.initialized) await this.initialize()
|
|
225
203
|
|
|
226
204
|
const current = await this.getCurrent()
|
|
@@ -231,7 +209,7 @@ class SessionManager {
|
|
|
231
209
|
const now = new Date().toISOString()
|
|
232
210
|
current.status = 'completed'
|
|
233
211
|
current.completedAt = now
|
|
234
|
-
current.duration =
|
|
212
|
+
current.duration = calculateDuration(current)
|
|
235
213
|
current.metrics = await this.calculateMetrics(current)
|
|
236
214
|
current.timeline.push({ type: 'complete', at: now })
|
|
237
215
|
|
|
@@ -263,45 +241,18 @@ class SessionManager {
|
|
|
263
241
|
|
|
264
242
|
/**
|
|
265
243
|
* Calculate total duration in seconds
|
|
266
|
-
* @param {Session} session
|
|
267
|
-
* @returns {number}
|
|
268
244
|
*/
|
|
269
|
-
calculateDuration(session) {
|
|
270
|
-
|
|
271
|
-
let lastStart = null
|
|
272
|
-
|
|
273
|
-
for (const event of session.timeline) {
|
|
274
|
-
if (event.type === 'start' || event.type === 'resume') {
|
|
275
|
-
lastStart = new Date(event.at)
|
|
276
|
-
} else if (event.type === 'pause' || event.type === 'complete') {
|
|
277
|
-
if (lastStart) {
|
|
278
|
-
totalMs += new Date(event.at) - lastStart
|
|
279
|
-
lastStart = null
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// If still active, count from last start to now
|
|
285
|
-
if (lastStart && session.status === 'active') {
|
|
286
|
-
totalMs += Date.now() - lastStart
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
return Math.round(totalMs / 1000)
|
|
245
|
+
calculateDuration(session: Session): number {
|
|
246
|
+
return calculateDuration(session)
|
|
290
247
|
}
|
|
291
248
|
|
|
292
249
|
/**
|
|
293
250
|
* Calculate metrics for session
|
|
294
|
-
* @param {Session} session
|
|
295
|
-
* @returns {Promise<Object>}
|
|
296
251
|
*/
|
|
297
|
-
async calculateMetrics(session) {
|
|
252
|
+
async calculateMetrics(session: Session): Promise<SessionMetrics> {
|
|
298
253
|
const metrics = { ...session.metrics }
|
|
299
254
|
|
|
300
255
|
try {
|
|
301
|
-
const { exec } = require('child_process')
|
|
302
|
-
const { promisify } = require('util')
|
|
303
|
-
const execAsync = promisify(exec)
|
|
304
|
-
|
|
305
256
|
// Get git stats since session start
|
|
306
257
|
const since = session.startedAt.split('T')[0]
|
|
307
258
|
|
|
@@ -337,18 +288,17 @@ class SessionManager {
|
|
|
337
288
|
|
|
338
289
|
/**
|
|
339
290
|
* Save current session
|
|
340
|
-
* @param {Session} session
|
|
341
291
|
*/
|
|
342
|
-
async saveCurrent(session) {
|
|
343
|
-
const currentPath = path.join(this.sessionDir
|
|
292
|
+
async saveCurrent(session: Session): Promise<void> {
|
|
293
|
+
const currentPath = path.join(this.sessionDir!, 'current.json')
|
|
344
294
|
await fs.writeFile(currentPath, JSON.stringify(session, null, 2))
|
|
345
295
|
}
|
|
346
296
|
|
|
347
297
|
/**
|
|
348
298
|
* Clear current session file
|
|
349
299
|
*/
|
|
350
|
-
async clearCurrent() {
|
|
351
|
-
const currentPath = path.join(this.sessionDir
|
|
300
|
+
async clearCurrent(): Promise<void> {
|
|
301
|
+
const currentPath = path.join(this.sessionDir!, 'current.json')
|
|
352
302
|
try {
|
|
353
303
|
await fs.unlink(currentPath)
|
|
354
304
|
} catch {
|
|
@@ -358,12 +308,11 @@ class SessionManager {
|
|
|
358
308
|
|
|
359
309
|
/**
|
|
360
310
|
* Archive completed session
|
|
361
|
-
* @param {Session} session
|
|
362
311
|
*/
|
|
363
|
-
async archive(session) {
|
|
364
|
-
const date = new Date(session.completedAt)
|
|
312
|
+
async archive(session: Session): Promise<void> {
|
|
313
|
+
const date = new Date(session.completedAt!)
|
|
365
314
|
const yearMonth = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}`
|
|
366
|
-
const archiveDir = path.join(this.sessionDir
|
|
315
|
+
const archiveDir = path.join(this.sessionDir!, 'archive', yearMonth)
|
|
367
316
|
|
|
368
317
|
await fs.mkdir(archiveDir, { recursive: true })
|
|
369
318
|
|
|
@@ -373,14 +322,12 @@ class SessionManager {
|
|
|
373
322
|
|
|
374
323
|
/**
|
|
375
324
|
* Get session history
|
|
376
|
-
* @param {number} limit - Max sessions to return
|
|
377
|
-
* @returns {Promise<Session[]>}
|
|
378
325
|
*/
|
|
379
|
-
async getHistory(limit = 10) {
|
|
326
|
+
async getHistory(limit: number = 10): Promise<Session[]> {
|
|
380
327
|
if (!this.initialized) await this.initialize()
|
|
381
328
|
|
|
382
|
-
const sessions = []
|
|
383
|
-
const archiveDir = path.join(this.sessionDir
|
|
329
|
+
const sessions: Session[] = []
|
|
330
|
+
const archiveDir = path.join(this.sessionDir!, 'archive')
|
|
384
331
|
|
|
385
332
|
try {
|
|
386
333
|
const months = await fs.readdir(archiveDir)
|
|
@@ -409,11 +356,9 @@ class SessionManager {
|
|
|
409
356
|
|
|
410
357
|
/**
|
|
411
358
|
* Log event to memory
|
|
412
|
-
* @param {string} action
|
|
413
|
-
* @param {Object} data
|
|
414
359
|
*/
|
|
415
|
-
async logEvent(action, data) {
|
|
416
|
-
const globalPath = pathManager.getGlobalProjectPath(this.projectId)
|
|
360
|
+
async logEvent(action: string, data: Record<string, unknown>): Promise<void> {
|
|
361
|
+
const globalPath = pathManager.getGlobalProjectPath(this.projectId!)
|
|
417
362
|
const memoryPath = path.join(globalPath, 'memory', 'context.jsonl')
|
|
418
363
|
|
|
419
364
|
const entry = JSON.stringify({
|
|
@@ -431,19 +376,8 @@ class SessionManager {
|
|
|
431
376
|
|
|
432
377
|
/**
|
|
433
378
|
* Format duration as human readable
|
|
434
|
-
* @param {number} seconds
|
|
435
|
-
* @returns {string}
|
|
436
379
|
*/
|
|
437
|
-
static formatDuration(seconds) {
|
|
438
|
-
|
|
439
|
-
if (seconds < 3600) return `${Math.round(seconds / 60)}m`
|
|
440
|
-
|
|
441
|
-
const hours = Math.floor(seconds / 3600)
|
|
442
|
-
const minutes = Math.round((seconds % 3600) / 60)
|
|
443
|
-
|
|
444
|
-
if (minutes === 0) return `${hours}h`
|
|
445
|
-
return `${hours}h ${minutes}m`
|
|
380
|
+
static formatDuration(seconds: number): string {
|
|
381
|
+
return formatDuration(seconds)
|
|
446
382
|
}
|
|
447
383
|
}
|
|
448
|
-
|
|
449
|
-
module.exports = SessionManager
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Types
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export interface SessionMetrics {
|
|
6
|
+
filesChanged: number
|
|
7
|
+
linesAdded: number
|
|
8
|
+
linesRemoved: number
|
|
9
|
+
commits: number
|
|
10
|
+
snapshots: string[]
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface TimelineEvent {
|
|
14
|
+
type: 'start' | 'pause' | 'resume' | 'complete'
|
|
15
|
+
at: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface Session {
|
|
19
|
+
id: string
|
|
20
|
+
projectId: string
|
|
21
|
+
task: string
|
|
22
|
+
status: 'active' | 'paused' | 'completed'
|
|
23
|
+
startedAt: string
|
|
24
|
+
pausedAt: string | null
|
|
25
|
+
completedAt: string | null
|
|
26
|
+
duration: number
|
|
27
|
+
metrics: SessionMetrics
|
|
28
|
+
timeline: TimelineEvent[]
|
|
29
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session Utilities
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Session, TimelineEvent } from './types'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generate unique session ID
|
|
9
|
+
*/
|
|
10
|
+
export function generateId(): string {
|
|
11
|
+
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'
|
|
12
|
+
let id = 'sess_'
|
|
13
|
+
for (let i = 0; i < 8; i++) {
|
|
14
|
+
id += chars.charAt(Math.floor(Math.random() * chars.length))
|
|
15
|
+
}
|
|
16
|
+
return id
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Calculate total duration in seconds
|
|
21
|
+
*/
|
|
22
|
+
export function calculateDuration(session: Session): number {
|
|
23
|
+
let totalMs = 0
|
|
24
|
+
let lastStart: Date | null = null
|
|
25
|
+
|
|
26
|
+
for (const event of session.timeline) {
|
|
27
|
+
if (event.type === 'start' || event.type === 'resume') {
|
|
28
|
+
lastStart = new Date(event.at)
|
|
29
|
+
} else if (event.type === 'pause' || event.type === 'complete') {
|
|
30
|
+
if (lastStart) {
|
|
31
|
+
totalMs += new Date(event.at).getTime() - lastStart.getTime()
|
|
32
|
+
lastStart = null
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// If still active, count from last start to now
|
|
38
|
+
if (lastStart && session.status === 'active') {
|
|
39
|
+
totalMs += Date.now() - lastStart.getTime()
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return Math.round(totalMs / 1000)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Format duration as human readable
|
|
47
|
+
*/
|
|
48
|
+
export function formatDuration(seconds: number): string {
|
|
49
|
+
if (seconds < 60) return `${seconds}s`
|
|
50
|
+
if (seconds < 3600) return `${Math.round(seconds / 60)}m`
|
|
51
|
+
|
|
52
|
+
const hours = Math.floor(seconds / 3600)
|
|
53
|
+
const minutes = Math.round((seconds % 3600) / 60)
|
|
54
|
+
|
|
55
|
+
if (minutes === 0) return `${hours}h`
|
|
56
|
+
return `${hours}h ${minutes}m`
|
|
57
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* State Module
|
|
3
|
+
*
|
|
4
|
+
* Unified project state management.
|
|
5
|
+
* Single source of truth replacing scattered file reads.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import stateManager from './state'
|
|
10
|
+
*
|
|
11
|
+
* // Read state
|
|
12
|
+
* const state = await stateManager.read(projectId)
|
|
13
|
+
*
|
|
14
|
+
* // Update state
|
|
15
|
+
* await stateManager.startTask(projectId, { id: 'task_1', description: 'auth' })
|
|
16
|
+
* await stateManager.completeTask(projectId, '2h 15m')
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import stateManager from './manager'
|
|
21
|
+
|
|
22
|
+
export { StateManager } from './manager'
|
|
23
|
+
export { stateManager }
|
|
24
|
+
export default stateManager
|
|
25
|
+
export * from './types'
|