prjct-cli 0.18.2 → 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 (243) hide show
  1. package/CHANGELOG.md +40 -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/commands/done.md +57 -258
  11. package/templates/commands/now.md +72 -277
  12. package/templates/commands/ship.md +55 -261
  13. package/templates/commands/test.md +328 -21
  14. package/templates/global/CLAUDE.md +40 -205
  15. package/templates/global/docs/agents.md +88 -0
  16. package/templates/global/docs/architecture.md +103 -0
  17. package/templates/global/docs/commands.md +98 -0
  18. package/templates/global/docs/validation.md +95 -0
  19. package/templates/mcp-config.json +36 -0
  20. package/bin/dev.js +0 -216
  21. package/bin/serve.js +0 -361
  22. package/packages/web/README.md +0 -36
  23. package/packages/web/app/api/claude/sessions/route.ts +0 -44
  24. package/packages/web/app/api/claude/status/route.ts +0 -34
  25. package/packages/web/app/api/projects/[id]/icon/route.ts +0 -33
  26. package/packages/web/app/api/projects/[id]/momentum/route.ts +0 -257
  27. package/packages/web/app/api/projects/[id]/route.ts +0 -29
  28. package/packages/web/app/api/projects/[id]/stats/route.ts +0 -41
  29. package/packages/web/app/api/projects/[id]/status/route.ts +0 -21
  30. package/packages/web/app/api/projects/route.ts +0 -16
  31. package/packages/web/app/api/sessions/current/route.ts +0 -132
  32. package/packages/web/app/api/sessions/history/route.ts +0 -204
  33. package/packages/web/app/error.tsx +0 -34
  34. package/packages/web/app/favicon.ico +0 -0
  35. package/packages/web/app/globals.css +0 -198
  36. package/packages/web/app/layout.tsx +0 -53
  37. package/packages/web/app/loading.tsx +0 -7
  38. package/packages/web/app/not-found.tsx +0 -25
  39. package/packages/web/app/page.tsx +0 -12
  40. package/packages/web/app/project/[id]/code/layout.tsx +0 -18
  41. package/packages/web/app/project/[id]/code/page.tsx +0 -408
  42. package/packages/web/app/project/[id]/error.tsx +0 -41
  43. package/packages/web/app/project/[id]/loading.tsx +0 -9
  44. package/packages/web/app/project/[id]/not-found.tsx +0 -27
  45. package/packages/web/app/project/[id]/page.tsx +0 -384
  46. package/packages/web/app/project/[id]/reports/page.tsx +0 -59
  47. package/packages/web/app/project/[id]/reports/print/page.tsx +0 -58
  48. package/packages/web/app/sessions/page.tsx +0 -165
  49. package/packages/web/app/settings/page.tsx +0 -151
  50. package/packages/web/components/ActivityTimeline/ActivityTimeline.constants.ts +0 -2
  51. package/packages/web/components/ActivityTimeline/ActivityTimeline.tsx +0 -49
  52. package/packages/web/components/ActivityTimeline/ActivityTimeline.types.ts +0 -8
  53. package/packages/web/components/ActivityTimeline/hooks/index.ts +0 -2
  54. package/packages/web/components/ActivityTimeline/hooks/useExpandable.ts +0 -9
  55. package/packages/web/components/ActivityTimeline/hooks/useGroupedEvents.ts +0 -23
  56. package/packages/web/components/ActivityTimeline/index.ts +0 -2
  57. package/packages/web/components/AgentsCard/AgentsCard.tsx +0 -93
  58. package/packages/web/components/AgentsCard/AgentsCard.types.ts +0 -14
  59. package/packages/web/components/AgentsCard/index.ts +0 -2
  60. package/packages/web/components/AppSidebar/AppSidebar.tsx +0 -316
  61. package/packages/web/components/AppSidebar/index.ts +0 -1
  62. package/packages/web/components/BackLink/BackLink.tsx +0 -18
  63. package/packages/web/components/BackLink/BackLink.types.ts +0 -5
  64. package/packages/web/components/BackLink/index.ts +0 -2
  65. package/packages/web/components/BentoCard/BentoCard.constants.ts +0 -16
  66. package/packages/web/components/BentoCard/BentoCard.tsx +0 -48
  67. package/packages/web/components/BentoCard/BentoCard.types.ts +0 -15
  68. package/packages/web/components/BentoCard/index.ts +0 -2
  69. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.constants.ts +0 -9
  70. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.tsx +0 -18
  71. package/packages/web/components/BentoCardSkeleton/BentoCardSkeleton.types.ts +0 -5
  72. package/packages/web/components/BentoCardSkeleton/index.ts +0 -2
  73. package/packages/web/components/BentoGrid/BentoGrid.tsx +0 -18
  74. package/packages/web/components/BentoGrid/BentoGrid.types.ts +0 -4
  75. package/packages/web/components/BentoGrid/index.ts +0 -2
  76. package/packages/web/components/BlockersCard/BlockersCard.tsx +0 -75
  77. package/packages/web/components/BlockersCard/BlockersCard.types.ts +0 -12
  78. package/packages/web/components/BlockersCard/index.ts +0 -2
  79. package/packages/web/components/CommandBar/CommandBar.tsx +0 -67
  80. package/packages/web/components/CommandBar/index.ts +0 -1
  81. package/packages/web/components/CommandButton/CommandButton.tsx +0 -46
  82. package/packages/web/components/CommandButton/index.ts +0 -1
  83. package/packages/web/components/ConnectionStatus/ConnectionStatus.tsx +0 -29
  84. package/packages/web/components/ConnectionStatus/index.ts +0 -1
  85. package/packages/web/components/DashboardContent/DashboardContent.tsx +0 -284
  86. package/packages/web/components/DashboardContent/index.ts +0 -1
  87. package/packages/web/components/DateGroup/DateGroup.tsx +0 -18
  88. package/packages/web/components/DateGroup/DateGroup.types.ts +0 -6
  89. package/packages/web/components/DateGroup/DateGroup.utils.ts +0 -11
  90. package/packages/web/components/DateGroup/index.ts +0 -2
  91. package/packages/web/components/EmptyState/EmptyState.tsx +0 -76
  92. package/packages/web/components/EmptyState/EmptyState.types.ts +0 -11
  93. package/packages/web/components/EmptyState/index.ts +0 -2
  94. package/packages/web/components/EventRow/EventRow.constants.ts +0 -10
  95. package/packages/web/components/EventRow/EventRow.tsx +0 -49
  96. package/packages/web/components/EventRow/EventRow.types.ts +0 -7
  97. package/packages/web/components/EventRow/EventRow.utils.ts +0 -49
  98. package/packages/web/components/EventRow/index.ts +0 -2
  99. package/packages/web/components/ExpandButton/ExpandButton.tsx +0 -18
  100. package/packages/web/components/ExpandButton/ExpandButton.types.ts +0 -6
  101. package/packages/web/components/ExpandButton/index.ts +0 -2
  102. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.tsx +0 -14
  103. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.types.ts +0 -5
  104. package/packages/web/components/HealthGradientBackground/HealthGradientBackground.utils.ts +0 -13
  105. package/packages/web/components/HealthGradientBackground/index.ts +0 -2
  106. package/packages/web/components/HeroSection/HeroSection.tsx +0 -92
  107. package/packages/web/components/HeroSection/HeroSection.types.ts +0 -14
  108. package/packages/web/components/HeroSection/HeroSection.utils.ts +0 -11
  109. package/packages/web/components/HeroSection/hooks/index.ts +0 -2
  110. package/packages/web/components/HeroSection/hooks/useCountUp.ts +0 -45
  111. package/packages/web/components/HeroSection/hooks/useWeeklyActivity.ts +0 -18
  112. package/packages/web/components/HeroSection/index.ts +0 -2
  113. package/packages/web/components/IdeasCard/IdeasCard.tsx +0 -115
  114. package/packages/web/components/IdeasCard/IdeasCard.types.ts +0 -10
  115. package/packages/web/components/IdeasCard/index.ts +0 -2
  116. package/packages/web/components/InsightMessage/InsightMessage.tsx +0 -9
  117. package/packages/web/components/InsightMessage/InsightMessage.types.ts +0 -3
  118. package/packages/web/components/InsightMessage/index.ts +0 -2
  119. package/packages/web/components/Logo/Logo.tsx +0 -65
  120. package/packages/web/components/Logo/index.ts +0 -1
  121. package/packages/web/components/MarkdownContent/MarkdownContent.tsx +0 -123
  122. package/packages/web/components/MarkdownContent/index.ts +0 -1
  123. package/packages/web/components/MasonryGrid/MasonryGrid.tsx +0 -18
  124. package/packages/web/components/MasonryGrid/index.ts +0 -1
  125. package/packages/web/components/MomentumWidget/MomentumWidget.tsx +0 -119
  126. package/packages/web/components/MomentumWidget/MomentumWidget.types.ts +0 -16
  127. package/packages/web/components/MomentumWidget/index.ts +0 -2
  128. package/packages/web/components/NowCard/NowCard.tsx +0 -118
  129. package/packages/web/components/NowCard/NowCard.types.ts +0 -16
  130. package/packages/web/components/NowCard/index.ts +0 -2
  131. package/packages/web/components/PageHeader/PageHeader.tsx +0 -24
  132. package/packages/web/components/PageHeader/index.ts +0 -1
  133. package/packages/web/components/ProgressRing/ProgressRing.constants.ts +0 -20
  134. package/packages/web/components/ProgressRing/ProgressRing.tsx +0 -51
  135. package/packages/web/components/ProgressRing/ProgressRing.types.ts +0 -11
  136. package/packages/web/components/ProgressRing/index.ts +0 -2
  137. package/packages/web/components/ProjectAvatar/ProjectAvatar.tsx +0 -54
  138. package/packages/web/components/ProjectAvatar/index.ts +0 -1
  139. package/packages/web/components/ProjectColorDot/ProjectColorDot.tsx +0 -37
  140. package/packages/web/components/ProjectColorDot/index.ts +0 -1
  141. package/packages/web/components/ProjectSelectorModal/ProjectSelectorModal.tsx +0 -104
  142. package/packages/web/components/ProjectSelectorModal/index.ts +0 -1
  143. package/packages/web/components/Providers/Providers.tsx +0 -48
  144. package/packages/web/components/Providers/index.ts +0 -1
  145. package/packages/web/components/QueueCard/QueueCard.tsx +0 -125
  146. package/packages/web/components/QueueCard/QueueCard.types.ts +0 -12
  147. package/packages/web/components/QueueCard/QueueCard.utils.ts +0 -12
  148. package/packages/web/components/QueueCard/index.ts +0 -2
  149. package/packages/web/components/RecoverCard/RecoverCard.tsx +0 -72
  150. package/packages/web/components/RecoverCard/RecoverCard.types.ts +0 -16
  151. package/packages/web/components/RecoverCard/index.ts +0 -2
  152. package/packages/web/components/RoadmapCard/RoadmapCard.tsx +0 -145
  153. package/packages/web/components/RoadmapCard/RoadmapCard.types.ts +0 -16
  154. package/packages/web/components/RoadmapCard/index.ts +0 -2
  155. package/packages/web/components/ShipsCard/ShipsCard.tsx +0 -95
  156. package/packages/web/components/ShipsCard/ShipsCard.types.ts +0 -14
  157. package/packages/web/components/ShipsCard/ShipsCard.utils.ts +0 -4
  158. package/packages/web/components/ShipsCard/index.ts +0 -2
  159. package/packages/web/components/SparklineChart/SparklineChart.tsx +0 -40
  160. package/packages/web/components/SparklineChart/SparklineChart.types.ts +0 -6
  161. package/packages/web/components/SparklineChart/index.ts +0 -2
  162. package/packages/web/components/StatsMasonry/StatsMasonry.tsx +0 -95
  163. package/packages/web/components/StatsMasonry/index.ts +0 -1
  164. package/packages/web/components/StreakCard/StreakCard.constants.ts +0 -2
  165. package/packages/web/components/StreakCard/StreakCard.tsx +0 -55
  166. package/packages/web/components/StreakCard/StreakCard.types.ts +0 -4
  167. package/packages/web/components/StreakCard/index.ts +0 -2
  168. package/packages/web/components/TasksCounter/TasksCounter.tsx +0 -14
  169. package/packages/web/components/TasksCounter/TasksCounter.types.ts +0 -3
  170. package/packages/web/components/TasksCounter/index.ts +0 -2
  171. package/packages/web/components/TechStackBadges/TechStackBadges.tsx +0 -28
  172. package/packages/web/components/TechStackBadges/index.ts +0 -1
  173. package/packages/web/components/TerminalDock/DockToggleTab.tsx +0 -29
  174. package/packages/web/components/TerminalDock/TerminalDock.tsx +0 -386
  175. package/packages/web/components/TerminalDock/TerminalDockTab.tsx +0 -130
  176. package/packages/web/components/TerminalDock/TerminalTabBar.tsx +0 -142
  177. package/packages/web/components/TerminalDock/index.ts +0 -2
  178. package/packages/web/components/TerminalTabs/TerminalTab.tsx +0 -95
  179. package/packages/web/components/TerminalTabs/TerminalTabs.tsx +0 -211
  180. package/packages/web/components/TerminalTabs/index.ts +0 -1
  181. package/packages/web/components/VelocityBadge/VelocityBadge.tsx +0 -32
  182. package/packages/web/components/VelocityBadge/VelocityBadge.types.ts +0 -3
  183. package/packages/web/components/VelocityBadge/index.ts +0 -2
  184. package/packages/web/components/VelocityCard/VelocityCard.tsx +0 -73
  185. package/packages/web/components/VelocityCard/VelocityCard.types.ts +0 -7
  186. package/packages/web/components/VelocityCard/index.ts +0 -2
  187. package/packages/web/components/WeeklyReports/PrintableReport.tsx +0 -259
  188. package/packages/web/components/WeeklyReports/ReportPreviewCard.tsx +0 -187
  189. package/packages/web/components/WeeklyReports/WeekCalendar.tsx +0 -288
  190. package/packages/web/components/WeeklyReports/WeeklyReports.tsx +0 -149
  191. package/packages/web/components/WeeklyReports/index.ts +0 -4
  192. package/packages/web/components/WeeklySparkline/WeeklySparkline.tsx +0 -25
  193. package/packages/web/components/WeeklySparkline/WeeklySparkline.types.ts +0 -4
  194. package/packages/web/components/WeeklySparkline/index.ts +0 -2
  195. package/packages/web/components/charts/SessionsChart.tsx +0 -175
  196. package/packages/web/components/ui/alert-dialog.tsx +0 -157
  197. package/packages/web/components/ui/badge.tsx +0 -46
  198. package/packages/web/components/ui/button.tsx +0 -60
  199. package/packages/web/components/ui/card.tsx +0 -92
  200. package/packages/web/components/ui/chart.tsx +0 -385
  201. package/packages/web/components/ui/dialog.tsx +0 -143
  202. package/packages/web/components/ui/drawer.tsx +0 -135
  203. package/packages/web/components/ui/dropdown-menu.tsx +0 -257
  204. package/packages/web/components/ui/input.tsx +0 -21
  205. package/packages/web/components/ui/scroll-area.tsx +0 -58
  206. package/packages/web/components/ui/select.tsx +0 -187
  207. package/packages/web/components/ui/sheet.tsx +0 -139
  208. package/packages/web/components/ui/tabs.tsx +0 -66
  209. package/packages/web/components/ui/tooltip.tsx +0 -61
  210. package/packages/web/components.json +0 -22
  211. package/packages/web/context/GlobalTerminalContext.tsx +0 -538
  212. package/packages/web/context/TerminalContext.tsx +0 -45
  213. package/packages/web/context/TerminalTabsContext.tsx +0 -181
  214. package/packages/web/eslint.config.mjs +0 -18
  215. package/packages/web/hooks/useClaudeTerminal.ts +0 -425
  216. package/packages/web/hooks/useProjectStats.ts +0 -93
  217. package/packages/web/hooks/useProjects.ts +0 -73
  218. package/packages/web/lib/actions/projects.ts +0 -15
  219. package/packages/web/lib/commands.ts +0 -81
  220. package/packages/web/lib/format.ts +0 -23
  221. package/packages/web/lib/generate-week-report.ts +0 -285
  222. package/packages/web/lib/parse-prjct-files.ts +0 -1123
  223. package/packages/web/lib/project-colors.ts +0 -58
  224. package/packages/web/lib/projects.ts +0 -506
  225. package/packages/web/lib/pty.ts +0 -101
  226. package/packages/web/lib/query-config.ts +0 -44
  227. package/packages/web/lib/services/index.ts +0 -9
  228. package/packages/web/lib/services/projects.server.ts +0 -66
  229. package/packages/web/lib/services/stats.server.ts +0 -562
  230. package/packages/web/lib/unified-loader.ts +0 -396
  231. package/packages/web/lib/utils.ts +0 -6
  232. package/packages/web/next-env.d.ts +0 -6
  233. package/packages/web/next.config.ts +0 -7
  234. package/packages/web/package.json +0 -57
  235. package/packages/web/postcss.config.mjs +0 -7
  236. package/packages/web/public/file.svg +0 -1
  237. package/packages/web/public/globe.svg +0 -1
  238. package/packages/web/public/next.svg +0 -1
  239. package/packages/web/public/vercel.svg +0 -1
  240. package/packages/web/public/window.svg +0 -1
  241. package/packages/web/server.ts +0 -312
  242. package/packages/web/tsconfig.json +0 -34
  243. 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>