prjct-cli 0.18.1 → 0.19.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.
Files changed (245) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/CLAUDE.md +74 -211
  3. package/core/agentic/prompt-builder.ts +3 -7
  4. package/core/command-registry/optional-commands.ts +0 -20
  5. package/core/infrastructure/command-installer/command-installer.ts +8 -1
  6. package/core/infrastructure/command-installer/global-config.ts +31 -1
  7. package/core/infrastructure/command-installer/index.ts +1 -1
  8. package/core/infrastructure/setup.ts +3 -0
  9. package/package.json +3 -17
  10. package/templates/agentic/subagent-generation.md +8 -6
  11. package/templates/commands/done.md +57 -258
  12. package/templates/commands/now.md +72 -277
  13. package/templates/commands/ship.md +55 -261
  14. package/templates/commands/sync.md +7 -7
  15. package/templates/commands/test.md +328 -21
  16. package/templates/global/CLAUDE.md +40 -205
  17. package/templates/global/docs/agents.md +88 -0
  18. package/templates/global/docs/architecture.md +103 -0
  19. package/templates/global/docs/commands.md +98 -0
  20. package/templates/global/docs/validation.md +95 -0
  21. package/templates/mcp-config.json +36 -0
  22. package/bin/dev.js +0 -216
  23. package/bin/serve.js +0 -361
  24. package/packages/web/README.md +0 -36
  25. package/packages/web/app/api/claude/sessions/route.ts +0 -44
  26. package/packages/web/app/api/claude/status/route.ts +0 -34
  27. package/packages/web/app/api/projects/[id]/icon/route.ts +0 -33
  28. package/packages/web/app/api/projects/[id]/momentum/route.ts +0 -257
  29. package/packages/web/app/api/projects/[id]/route.ts +0 -29
  30. package/packages/web/app/api/projects/[id]/stats/route.ts +0 -41
  31. package/packages/web/app/api/projects/[id]/status/route.ts +0 -21
  32. package/packages/web/app/api/projects/route.ts +0 -16
  33. package/packages/web/app/api/sessions/current/route.ts +0 -132
  34. package/packages/web/app/api/sessions/history/route.ts +0 -204
  35. package/packages/web/app/error.tsx +0 -34
  36. package/packages/web/app/favicon.ico +0 -0
  37. package/packages/web/app/globals.css +0 -198
  38. package/packages/web/app/layout.tsx +0 -53
  39. package/packages/web/app/loading.tsx +0 -7
  40. package/packages/web/app/not-found.tsx +0 -25
  41. package/packages/web/app/page.tsx +0 -12
  42. package/packages/web/app/project/[id]/code/layout.tsx +0 -18
  43. package/packages/web/app/project/[id]/code/page.tsx +0 -408
  44. package/packages/web/app/project/[id]/error.tsx +0 -41
  45. package/packages/web/app/project/[id]/loading.tsx +0 -9
  46. package/packages/web/app/project/[id]/not-found.tsx +0 -27
  47. package/packages/web/app/project/[id]/page.tsx +0 -384
  48. package/packages/web/app/project/[id]/reports/page.tsx +0 -59
  49. package/packages/web/app/project/[id]/reports/print/page.tsx +0 -58
  50. package/packages/web/app/sessions/page.tsx +0 -165
  51. package/packages/web/app/settings/page.tsx +0 -151
  52. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +0 -2
  53. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +0 -49
  54. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +0 -8
  55. package/packages/web/components/ActivityTimeline/hooks/index.ts +0 -2
  56. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +0 -9
  57. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +0 -23
  58. package/packages/web/components/ActivityTimeline/index.ts +0 -2
  59. package/packages/web/components/AgentsCard/AgentsCard.tsx +0 -93
  60. package/packages/web/components/AgentsCard/AgentsCard.types.ts +0 -14
  61. package/packages/web/components/AgentsCard/index.ts +0 -2
  62. package/packages/web/components/AppSidebar/AppSidebar.tsx +0 -316
  63. package/packages/web/components/AppSidebar/index.ts +0 -1
  64. package/packages/web/components/BackLink/BackLink.tsx +0 -18
  65. package/packages/web/components/BackLink/BackLink.types.ts +0 -5
  66. package/packages/web/components/BackLink/index.ts +0 -2
  67. package/packages/web/components/BentoCard/BentoCard.constants.ts +0 -16
  68. package/packages/web/components/BentoCard/BentoCard.tsx +0 -48
  69. package/packages/web/components/BentoCard/BentoCard.types.ts +0 -15
  70. package/packages/web/components/BentoCard/index.ts +0 -2
  71. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +0 -9
  72. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +0 -18
  73. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +0 -5
  74. package/packages/web/components/BentoCardSkeleton/index.ts +0 -2
  75. package/packages/web/components/BentoGrid/BentoGrid.tsx +0 -18
  76. package/packages/web/components/BentoGrid/BentoGrid.types.ts +0 -4
  77. package/packages/web/components/BentoGrid/index.ts +0 -2
  78. package/packages/web/components/BlockersCard/BlockersCard.tsx +0 -75
  79. package/packages/web/components/BlockersCard/BlockersCard.types.ts +0 -12
  80. package/packages/web/components/BlockersCard/index.ts +0 -2
  81. package/packages/web/components/CommandBar/CommandBar.tsx +0 -67
  82. package/packages/web/components/CommandBar/index.ts +0 -1
  83. package/packages/web/components/CommandButton/CommandButton.tsx +0 -46
  84. package/packages/web/components/CommandButton/index.ts +0 -1
  85. package/packages/web/components/ConnectionStatus/ConnectionStatus.tsx +0 -29
  86. package/packages/web/components/ConnectionStatus/index.ts +0 -1
  87. package/packages/web/components/DashboardContent/DashboardContent.tsx +0 -284
  88. package/packages/web/components/DashboardContent/index.ts +0 -1
  89. package/packages/web/components/DateGroup/DateGroup.tsx +0 -18
  90. package/packages/web/components/DateGroup/DateGroup.types.ts +0 -6
  91. package/packages/web/components/DateGroup/DateGroup.utils.ts +0 -11
  92. package/packages/web/components/DateGroup/index.ts +0 -2
  93. package/packages/web/components/EmptyState/EmptyState.tsx +0 -76
  94. package/packages/web/components/EmptyState/EmptyState.types.ts +0 -11
  95. package/packages/web/components/EmptyState/index.ts +0 -2
  96. package/packages/web/components/EventRow/EventRow.constants.ts +0 -10
  97. package/packages/web/components/EventRow/EventRow.tsx +0 -49
  98. package/packages/web/components/EventRow/EventRow.types.ts +0 -7
  99. package/packages/web/components/EventRow/EventRow.utils.ts +0 -49
  100. package/packages/web/components/EventRow/index.ts +0 -2
  101. package/packages/web/components/ExpandButton/ExpandButton.tsx +0 -18
  102. package/packages/web/components/ExpandButton/ExpandButton.types.ts +0 -6
  103. package/packages/web/components/ExpandButton/index.ts +0 -2
  104. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +0 -14
  105. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +0 -5
  106. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +0 -13
  107. package/packages/web/components/HealthGradientBackground/index.ts +0 -2
  108. package/packages/web/components/HeroSection/HeroSection.tsx +0 -92
  109. package/packages/web/components/HeroSection/HeroSection.types.ts +0 -14
  110. package/packages/web/components/HeroSection/HeroSection.utils.ts +0 -11
  111. package/packages/web/components/HeroSection/hooks/index.ts +0 -2
  112. package/packages/web/components/HeroSection/hooks/useCountUp.ts +0 -45
  113. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +0 -18
  114. package/packages/web/components/HeroSection/index.ts +0 -2
  115. package/packages/web/components/IdeasCard/IdeasCard.tsx +0 -115
  116. package/packages/web/components/IdeasCard/IdeasCard.types.ts +0 -10
  117. package/packages/web/components/IdeasCard/index.ts +0 -2
  118. package/packages/web/components/InsightMessage/InsightMessage.tsx +0 -9
  119. package/packages/web/components/InsightMessage/InsightMessage.types.ts +0 -3
  120. package/packages/web/components/InsightMessage/index.ts +0 -2
  121. package/packages/web/components/Logo/Logo.tsx +0 -65
  122. package/packages/web/components/Logo/index.ts +0 -1
  123. package/packages/web/components/MarkdownContent/MarkdownContent.tsx +0 -123
  124. package/packages/web/components/MarkdownContent/index.ts +0 -1
  125. package/packages/web/components/MasonryGrid/MasonryGrid.tsx +0 -18
  126. package/packages/web/components/MasonryGrid/index.ts +0 -1
  127. package/packages/web/components/MomentumWidget/MomentumWidget.tsx +0 -119
  128. package/packages/web/components/MomentumWidget/MomentumWidget.types.ts +0 -16
  129. package/packages/web/components/MomentumWidget/index.ts +0 -2
  130. package/packages/web/components/NowCard/NowCard.tsx +0 -118
  131. package/packages/web/components/NowCard/NowCard.types.ts +0 -16
  132. package/packages/web/components/NowCard/index.ts +0 -2
  133. package/packages/web/components/PageHeader/PageHeader.tsx +0 -24
  134. package/packages/web/components/PageHeader/index.ts +0 -1
  135. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +0 -20
  136. package/packages/web/components/ProgressRing/ProgressRing.tsx +0 -51
  137. package/packages/web/components/ProgressRing/ProgressRing.types.ts +0 -11
  138. package/packages/web/components/ProgressRing/index.ts +0 -2
  139. package/packages/web/components/ProjectAvatar/ProjectAvatar.tsx +0 -54
  140. package/packages/web/components/ProjectAvatar/index.ts +0 -1
  141. package/packages/web/components/ProjectColorDot/ProjectColorDot.tsx +0 -37
  142. package/packages/web/components/ProjectColorDot/index.ts +0 -1
  143. package/packages/web/components/ProjectSelectorModal/ProjectSelectorModal.tsx +0 -104
  144. package/packages/web/components/ProjectSelectorModal/index.ts +0 -1
  145. package/packages/web/components/Providers/Providers.tsx +0 -48
  146. package/packages/web/components/Providers/index.ts +0 -1
  147. package/packages/web/components/QueueCard/QueueCard.tsx +0 -125
  148. package/packages/web/components/QueueCard/QueueCard.types.ts +0 -12
  149. package/packages/web/components/QueueCard/QueueCard.utils.ts +0 -12
  150. package/packages/web/components/QueueCard/index.ts +0 -2
  151. package/packages/web/components/RecoverCard/RecoverCard.tsx +0 -72
  152. package/packages/web/components/RecoverCard/RecoverCard.types.ts +0 -16
  153. package/packages/web/components/RecoverCard/index.ts +0 -2
  154. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +0 -145
  155. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +0 -16
  156. package/packages/web/components/RoadmapCard/index.ts +0 -2
  157. package/packages/web/components/ShipsCard/ShipsCard.tsx +0 -95
  158. package/packages/web/components/ShipsCard/ShipsCard.types.ts +0 -14
  159. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +0 -4
  160. package/packages/web/components/ShipsCard/index.ts +0 -2
  161. package/packages/web/components/SparklineChart/SparklineChart.tsx +0 -40
  162. package/packages/web/components/SparklineChart/SparklineChart.types.ts +0 -6
  163. package/packages/web/components/SparklineChart/index.ts +0 -2
  164. package/packages/web/components/StatsMasonry/StatsMasonry.tsx +0 -95
  165. package/packages/web/components/StatsMasonry/index.ts +0 -1
  166. package/packages/web/components/StreakCard/StreakCard.constants.ts +0 -2
  167. package/packages/web/components/StreakCard/StreakCard.tsx +0 -55
  168. package/packages/web/components/StreakCard/StreakCard.types.ts +0 -4
  169. package/packages/web/components/StreakCard/index.ts +0 -2
  170. package/packages/web/components/TasksCounter/TasksCounter.tsx +0 -14
  171. package/packages/web/components/TasksCounter/TasksCounter.types.ts +0 -3
  172. package/packages/web/components/TasksCounter/index.ts +0 -2
  173. package/packages/web/components/TechStackBadges/TechStackBadges.tsx +0 -28
  174. package/packages/web/components/TechStackBadges/index.ts +0 -1
  175. package/packages/web/components/TerminalDock/DockToggleTab.tsx +0 -29
  176. package/packages/web/components/TerminalDock/TerminalDock.tsx +0 -386
  177. package/packages/web/components/TerminalDock/TerminalDockTab.tsx +0 -130
  178. package/packages/web/components/TerminalDock/TerminalTabBar.tsx +0 -142
  179. package/packages/web/components/TerminalDock/index.ts +0 -2
  180. package/packages/web/components/TerminalTabs/TerminalTab.tsx +0 -95
  181. package/packages/web/components/TerminalTabs/TerminalTabs.tsx +0 -211
  182. package/packages/web/components/TerminalTabs/index.ts +0 -1
  183. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +0 -32
  184. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +0 -3
  185. package/packages/web/components/VelocityBadge/index.ts +0 -2
  186. package/packages/web/components/VelocityCard/VelocityCard.tsx +0 -73
  187. package/packages/web/components/VelocityCard/VelocityCard.types.ts +0 -7
  188. package/packages/web/components/VelocityCard/index.ts +0 -2
  189. package/packages/web/components/WeeklyReports/PrintableReport.tsx +0 -259
  190. package/packages/web/components/WeeklyReports/ReportPreviewCard.tsx +0 -187
  191. package/packages/web/components/WeeklyReports/WeekCalendar.tsx +0 -288
  192. package/packages/web/components/WeeklyReports/WeeklyReports.tsx +0 -149
  193. package/packages/web/components/WeeklyReports/index.ts +0 -4
  194. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +0 -25
  195. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +0 -4
  196. package/packages/web/components/WeeklySparkline/index.ts +0 -2
  197. package/packages/web/components/charts/SessionsChart.tsx +0 -175
  198. package/packages/web/components/ui/alert-dialog.tsx +0 -157
  199. package/packages/web/components/ui/badge.tsx +0 -46
  200. package/packages/web/components/ui/button.tsx +0 -60
  201. package/packages/web/components/ui/card.tsx +0 -92
  202. package/packages/web/components/ui/chart.tsx +0 -385
  203. package/packages/web/components/ui/dialog.tsx +0 -143
  204. package/packages/web/components/ui/drawer.tsx +0 -135
  205. package/packages/web/components/ui/dropdown-menu.tsx +0 -257
  206. package/packages/web/components/ui/input.tsx +0 -21
  207. package/packages/web/components/ui/scroll-area.tsx +0 -58
  208. package/packages/web/components/ui/select.tsx +0 -187
  209. package/packages/web/components/ui/sheet.tsx +0 -139
  210. package/packages/web/components/ui/tabs.tsx +0 -66
  211. package/packages/web/components/ui/tooltip.tsx +0 -61
  212. package/packages/web/components.json +0 -22
  213. package/packages/web/context/GlobalTerminalContext.tsx +0 -538
  214. package/packages/web/context/TerminalContext.tsx +0 -45
  215. package/packages/web/context/TerminalTabsContext.tsx +0 -181
  216. package/packages/web/eslint.config.mjs +0 -18
  217. package/packages/web/hooks/useClaudeTerminal.ts +0 -425
  218. package/packages/web/hooks/useProjectStats.ts +0 -93
  219. package/packages/web/hooks/useProjects.ts +0 -73
  220. package/packages/web/lib/actions/projects.ts +0 -15
  221. package/packages/web/lib/commands.ts +0 -81
  222. package/packages/web/lib/format.ts +0 -23
  223. package/packages/web/lib/generate-week-report.ts +0 -285
  224. package/packages/web/lib/parse-prjct-files.ts +0 -1123
  225. package/packages/web/lib/project-colors.ts +0 -58
  226. package/packages/web/lib/projects.ts +0 -506
  227. package/packages/web/lib/pty.ts +0 -101
  228. package/packages/web/lib/query-config.ts +0 -44
  229. package/packages/web/lib/services/index.ts +0 -9
  230. package/packages/web/lib/services/projects.server.ts +0 -66
  231. package/packages/web/lib/services/stats.server.ts +0 -562
  232. package/packages/web/lib/unified-loader.ts +0 -396
  233. package/packages/web/lib/utils.ts +0 -6
  234. package/packages/web/next-env.d.ts +0 -6
  235. package/packages/web/next.config.ts +0 -7
  236. package/packages/web/package.json +0 -57
  237. package/packages/web/postcss.config.mjs +0 -7
  238. package/packages/web/public/file.svg +0 -1
  239. package/packages/web/public/globe.svg +0 -1
  240. package/packages/web/public/next.svg +0 -1
  241. package/packages/web/public/vercel.svg +0 -1
  242. package/packages/web/public/window.svg +0 -1
  243. package/packages/web/server.ts +0 -312
  244. package/packages/web/tsconfig.json +0 -34
  245. package/templates/commands/serve.md +0 -121
@@ -1,396 +0,0 @@
1
- /**
2
- * Unified Loader
3
- *
4
- * Loads project data from the new unified state modules.
5
- * Provides faster access than parsing markdown files.
6
- */
7
-
8
- import { promises as fs } from 'fs'
9
- import { join } from 'path'
10
- import { homedir } from 'os'
11
-
12
- const GLOBAL_STORAGE = join(homedir(), '.prjct-cli', 'projects')
13
-
14
- /**
15
- * Project state from state.json
16
- */
17
- export interface ProjectState {
18
- projectId: string
19
- currentTask: CurrentTask | null
20
- queue: QueuedTask[]
21
- activeFeature: ActiveFeature | null
22
- stats: PerformanceStats
23
- recentActivity: RecentActivity[]
24
- lastSync: string
25
- version: number
26
- }
27
-
28
- export interface CurrentTask {
29
- id: string
30
- description: string
31
- startedAt: string
32
- agent?: string
33
- agentConfidence?: number
34
- estimatedDuration?: string
35
- featureId?: string
36
- pausedAt?: string
37
- pauseReason?: string
38
- }
39
-
40
- export interface QueuedTask {
41
- id: string
42
- description: string
43
- priority: 'low' | 'medium' | 'high' | 'critical'
44
- featureId?: string
45
- estimatedDuration?: string
46
- tags?: string[]
47
- createdAt: string
48
- blockedReason?: string
49
- }
50
-
51
- export interface ActiveFeature {
52
- id: string
53
- name: string
54
- status: 'planned' | 'in_progress' | 'completed' | 'shipped'
55
- tasksCompleted: number
56
- tasksRemaining: number
57
- estimatedEffort?: string
58
- actualEffort?: string
59
- startedAt: string
60
- }
61
-
62
- export interface PerformanceStats {
63
- tasksToday: number
64
- tasksThisWeek: number
65
- avgDuration: string
66
- velocity: string
67
- estimateAccuracy: number
68
- streak: number
69
- }
70
-
71
- export interface RecentActivity {
72
- type: 'task_completed' | 'feature_shipped' | 'idea_captured' | 'session_started'
73
- description: string
74
- timestamp: string
75
- duration?: string
76
- }
77
-
78
- /**
79
- * Outcome summary from analyzer
80
- */
81
- export interface OutcomeSummary {
82
- totalOutcomes: number
83
- avgQualityScore: number
84
- estimateAccuracy: number
85
- topBlockers: string[]
86
- topAgents: string[]
87
- patternsDetected: string[]
88
- }
89
-
90
- /**
91
- * Agent performance data
92
- */
93
- export interface AgentPerformance {
94
- agentName: string
95
- taskType: string
96
- tasksCompleted: number
97
- successRate: number
98
- avgDuration: string
99
- estimateAccuracy: number
100
- improving: boolean
101
- lastUpdated: string
102
- bestFor: string[]
103
- avoidFor: string[]
104
- }
105
-
106
- /**
107
- * Insights computed from all data
108
- */
109
- export interface ProjectInsights {
110
- healthScore: number
111
- estimateAccuracy: number
112
- topBlockers: string[]
113
- patternsDetected: string[]
114
- recommendations: string[]
115
- }
116
-
117
- /**
118
- * Unified response combining all data
119
- */
120
- export interface UnifiedProjectData {
121
- state: ProjectState | null
122
- outcomes: OutcomeSummary | null
123
- agentPerformance: AgentPerformance[]
124
- insights: ProjectInsights
125
- // Legacy fallback data
126
- legacyFallback: boolean
127
- }
128
-
129
- const DEFAULT_STATE: ProjectState = {
130
- projectId: '',
131
- currentTask: null,
132
- queue: [],
133
- activeFeature: null,
134
- stats: {
135
- tasksToday: 0,
136
- tasksThisWeek: 0,
137
- avgDuration: '0h',
138
- velocity: '0',
139
- estimateAccuracy: 0,
140
- streak: 0,
141
- },
142
- recentActivity: [],
143
- lastSync: new Date().toISOString(),
144
- version: 1,
145
- }
146
-
147
- /**
148
- * Read state.json for a project
149
- */
150
- async function readState(projectId: string): Promise<ProjectState | null> {
151
- const statePath = join(GLOBAL_STORAGE, projectId, 'core', 'state.json')
152
- try {
153
- const content = await fs.readFile(statePath, 'utf-8')
154
- return JSON.parse(content) as ProjectState
155
- } catch {
156
- return null
157
- }
158
- }
159
-
160
- /**
161
- * Read outcomes summary
162
- */
163
- async function readOutcomes(projectId: string): Promise<OutcomeSummary | null> {
164
- const outcomesPath = join(GLOBAL_STORAGE, projectId, 'outcomes', 'outcomes.jsonl')
165
- try {
166
- const content = await fs.readFile(outcomesPath, 'utf-8')
167
- const outcomes = content
168
- .trim()
169
- .split('\n')
170
- .filter(line => line.trim())
171
- .map(line => JSON.parse(line))
172
-
173
- if (outcomes.length === 0) return null
174
-
175
- // Calculate summary
176
- const avgQuality = outcomes.reduce((sum: number, o: { qualityScore: number }) =>
177
- sum + o.qualityScore, 0) / outcomes.length
178
-
179
- // Count accurate estimates (within 20%)
180
- const accurateCount = outcomes.filter((o: { variance: string; estimatedDuration: string }) => {
181
- if (!o.variance) return false
182
- const variance = parseVariance(o.variance)
183
- const estimated = parseDuration(o.estimatedDuration)
184
- if (estimated === 0) return false
185
- return Math.abs(variance) / estimated <= 0.2
186
- }).length
187
-
188
- // Count blockers
189
- const blockerCounts = new Map<string, number>()
190
- for (const outcome of outcomes) {
191
- for (const blocker of outcome.blockers || []) {
192
- blockerCounts.set(blocker, (blockerCounts.get(blocker) || 0) + 1)
193
- }
194
- }
195
- const topBlockers = [...blockerCounts.entries()]
196
- .sort((a, b) => b[1] - a[1])
197
- .slice(0, 5)
198
- .map(([blocker]) => blocker)
199
-
200
- // Count agents
201
- const agentCounts = new Map<string, number>()
202
- for (const outcome of outcomes) {
203
- if (outcome.agentUsed) {
204
- agentCounts.set(outcome.agentUsed, (agentCounts.get(outcome.agentUsed) || 0) + 1)
205
- }
206
- }
207
- const topAgents = [...agentCounts.entries()]
208
- .sort((a, b) => b[1] - a[1])
209
- .slice(0, 3)
210
- .map(([agent]) => agent)
211
-
212
- // Detect patterns
213
- const patterns: string[] = []
214
- const underestimated = outcomes.filter((o: { variance: string }) => {
215
- const variance = parseVariance(o.variance)
216
- return variance > 0
217
- })
218
- if (underestimated.length / outcomes.length > 0.6) {
219
- patterns.push('Tasks consistently take longer than estimated')
220
- }
221
-
222
- return {
223
- totalOutcomes: outcomes.length,
224
- avgQualityScore: Math.round(avgQuality * 10) / 10,
225
- estimateAccuracy: Math.round((accurateCount / outcomes.length) * 100),
226
- topBlockers,
227
- topAgents,
228
- patternsDetected: patterns,
229
- }
230
- } catch {
231
- return null
232
- }
233
- }
234
-
235
- /**
236
- * Read agent performance data
237
- */
238
- async function readAgentPerformance(projectId: string): Promise<AgentPerformance[]> {
239
- const perfPath = join(GLOBAL_STORAGE, projectId, 'analysis', 'agent-performance.json')
240
- try {
241
- const content = await fs.readFile(perfPath, 'utf-8')
242
- const data = JSON.parse(content)
243
- return data.agents || []
244
- } catch {
245
- return []
246
- }
247
- }
248
-
249
- /**
250
- * Compute insights from all data
251
- */
252
- function computeInsights(
253
- state: ProjectState | null,
254
- outcomes: OutcomeSummary | null,
255
- agentPerformance: AgentPerformance[]
256
- ): ProjectInsights {
257
- let healthScore = 50 // Base score
258
-
259
- // Adjust for state
260
- if (state) {
261
- // Has current task = +10
262
- if (state.currentTask) healthScore += 10
263
-
264
- // Velocity bonus (max +20)
265
- const velocity = parseFloat(state.stats.velocity) || 0
266
- healthScore += Math.min(20, velocity * 5)
267
-
268
- // Streak bonus (max +15)
269
- healthScore += Math.min(15, state.stats.streak * 3)
270
-
271
- // Queue size penalty (too many = -5)
272
- if (state.queue.length > 15) healthScore -= 5
273
- }
274
-
275
- // Adjust for outcomes
276
- if (outcomes) {
277
- // Estimate accuracy bonus (max +15)
278
- healthScore += Math.round(outcomes.estimateAccuracy * 0.15)
279
-
280
- // Quality score bonus (max +10)
281
- healthScore += Math.round(outcomes.avgQualityScore * 2)
282
-
283
- // Blockers penalty
284
- healthScore -= outcomes.topBlockers.length * 2
285
- }
286
-
287
- // Adjust for agent performance
288
- if (agentPerformance.length > 0) {
289
- const avgSuccess = agentPerformance.reduce((sum, a) => sum + a.successRate, 0) / agentPerformance.length
290
- healthScore += Math.round(avgSuccess * 0.1)
291
- }
292
-
293
- // Clamp to 0-100
294
- healthScore = Math.max(0, Math.min(100, healthScore))
295
-
296
- // Build recommendations
297
- const recommendations: string[] = []
298
-
299
- if (!state?.currentTask) {
300
- recommendations.push('Start a task with /p:now to maintain momentum')
301
- }
302
-
303
- if (state && state.queue.length > 10) {
304
- recommendations.push('Queue is large - consider prioritizing or archiving tasks')
305
- }
306
-
307
- if (outcomes && outcomes.estimateAccuracy < 50) {
308
- recommendations.push('Estimate accuracy is low - try adding 30% buffer to estimates')
309
- }
310
-
311
- if (agentPerformance.length === 0) {
312
- recommendations.push('No agent performance data yet - track outcomes with /p:done')
313
- }
314
-
315
- const improving = agentPerformance.filter(a => a.improving)
316
- if (improving.length > 0) {
317
- recommendations.push(`${improving.map(a => a.agentName).join(', ')} improving - great progress!`)
318
- }
319
-
320
- return {
321
- healthScore,
322
- estimateAccuracy: outcomes?.estimateAccuracy || 0,
323
- topBlockers: outcomes?.topBlockers || [],
324
- patternsDetected: outcomes?.patternsDetected || [],
325
- recommendations: recommendations.slice(0, 4),
326
- }
327
- }
328
-
329
- /**
330
- * Parse variance string to minutes
331
- */
332
- function parseVariance(variance: string): number {
333
- const match = variance.match(/^([+-])(\d+)([mh])$/)
334
- if (!match) return 0
335
-
336
- const sign = match[1] === '-' ? -1 : 1
337
- const value = parseInt(match[2], 10)
338
- const unit = match[3]
339
-
340
- return sign * (unit === 'h' ? value * 60 : value)
341
- }
342
-
343
- /**
344
- * Parse duration string to minutes
345
- */
346
- function parseDuration(duration: string): number {
347
- let minutes = 0
348
-
349
- const hourMatch = duration.match(/(\d+)h/)
350
- if (hourMatch) {
351
- minutes += parseInt(hourMatch[1], 10) * 60
352
- }
353
-
354
- const minMatch = duration.match(/(\d+)m/)
355
- if (minMatch) {
356
- minutes += parseInt(minMatch[1], 10)
357
- }
358
-
359
- return minutes
360
- }
361
-
362
- /**
363
- * Load unified project data
364
- */
365
- export async function loadUnifiedProjectData(projectId: string): Promise<UnifiedProjectData> {
366
- // Try to read from new unified state
367
- const [state, outcomes, agentPerformance] = await Promise.all([
368
- readState(projectId),
369
- readOutcomes(projectId),
370
- readAgentPerformance(projectId),
371
- ])
372
-
373
- // Compute insights
374
- const insights = computeInsights(state, outcomes, agentPerformance)
375
-
376
- return {
377
- state,
378
- outcomes,
379
- agentPerformance,
380
- insights,
381
- legacyFallback: state === null,
382
- }
383
- }
384
-
385
- /**
386
- * Check if unified state exists for a project
387
- */
388
- export async function hasUnifiedState(projectId: string): Promise<boolean> {
389
- const statePath = join(GLOBAL_STORAGE, projectId, 'core', 'state.json')
390
- try {
391
- await fs.access(statePath)
392
- return true
393
- } catch {
394
- return false
395
- }
396
- }
@@ -1,6 +0,0 @@
1
- import { clsx, type ClassValue } from "clsx"
2
- import { twMerge } from "tailwind-merge"
3
-
4
- export function cn(...inputs: ClassValue[]) {
5
- return twMerge(clsx(inputs))
6
- }
@@ -1,6 +0,0 @@
1
- /// <reference types="next" />
2
- /// <reference types="next/image-types/global" />
3
- import "./.next/types/routes.d.ts";
4
-
5
- // NOTE: This file should not be edited
6
- // see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
@@ -1,7 +0,0 @@
1
- import type { NextConfig } from "next";
2
-
3
- const nextConfig: NextConfig = {
4
- /* config options here */
5
- };
6
-
7
- export default nextConfig;
@@ -1,57 +0,0 @@
1
- {
2
- "name": "web",
3
- "version": "0.1.0",
4
- "private": true,
5
- "scripts": {
6
- "dev": "NODE_ENV=development PORT=9471 bun server.ts",
7
- "build": "bun next build",
8
- "start": "NODE_ENV=production PORT=9472 node --import tsx server.ts",
9
- "lint": "eslint"
10
- },
11
- "dependencies": {
12
- "@radix-ui/react-alert-dialog": "^1.1.15",
13
- "@radix-ui/react-dialog": "^1.1.15",
14
- "@radix-ui/react-dropdown-menu": "^2.1.16",
15
- "@radix-ui/react-scroll-area": "^1.2.10",
16
- "@radix-ui/react-select": "^2.2.6",
17
- "@radix-ui/react-slot": "^1.2.4",
18
- "@radix-ui/react-tabs": "^1.1.13",
19
- "@radix-ui/react-tooltip": "^1.2.8",
20
- "@tanstack/react-query": "^5.90.12",
21
- "@types/mime-types": "^3.0.1",
22
- "@xterm/addon-fit": "^0.10.0",
23
- "@xterm/addon-web-links": "^0.11.0",
24
- "@xterm/xterm": "^5.5.0",
25
- "class-variance-authority": "^0.7.1",
26
- "clsx": "^2.1.1",
27
- "lucide-react": "^0.556.0",
28
- "mime-types": "^3.0.2",
29
- "next": "16.0.7",
30
- "next-themes": "^0.4.6",
31
- "node-pty": "^1.0.0",
32
- "react": "19.2.0",
33
- "react-dom": "19.2.0",
34
- "react-markdown": "^10.1.0",
35
- "react-resizable-panels": "^3.0.6",
36
- "recharts": "^3.5.1",
37
- "remark-gfm": "^4.0.1",
38
- "tailwind-merge": "^3.4.0",
39
- "vaul": "^1.1.2",
40
- "ws": "^8.18.3",
41
- "zod": "^4.1.13"
42
- },
43
- "devDependencies": {
44
- "@tailwindcss/postcss": "^4",
45
- "@types/bun": "latest",
46
- "tsx": "^4.21.0",
47
- "@types/node": "^20",
48
- "@types/react": "^19",
49
- "@types/react-dom": "^19",
50
- "@types/ws": "^8.18.0",
51
- "eslint": "^9",
52
- "eslint-config-next": "16.0.7",
53
- "tailwindcss": "^4",
54
- "tw-animate-css": "^1.4.0",
55
- "typescript": "^5"
56
- }
57
- }
@@ -1,7 +0,0 @@
1
- const config = {
2
- plugins: {
3
- "@tailwindcss/postcss": {},
4
- },
5
- };
6
-
7
- export default config;
@@ -1 +0,0 @@
1
- <svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
@@ -1 +0,0 @@
1
- <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
@@ -1 +0,0 @@
1
- <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
@@ -1 +0,0 @@
1
- <svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>