@prmichaelsen/acp-visualizer 0.8.1 → 0.9.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.
@@ -11,13 +11,22 @@
11
11
  import { Route as rootRouteImport } from './routes/__root'
12
12
  import { Route as TasksRouteImport } from './routes/tasks'
13
13
  import { Route as SearchRouteImport } from './routes/search'
14
+ import { Route as ReportsRouteImport } from './routes/reports'
15
+ import { Route as PatternsRouteImport } from './routes/patterns'
14
16
  import { Route as MilestonesRouteImport } from './routes/milestones'
17
+ import { Route as DesignsRouteImport } from './routes/designs'
15
18
  import { Route as ActivityRouteImport } from './routes/activity'
16
19
  import { Route as IndexRouteImport } from './routes/index'
17
20
  import { Route as TasksIndexRouteImport } from './routes/tasks.index'
21
+ import { Route as ReportsIndexRouteImport } from './routes/reports.index'
22
+ import { Route as PatternsIndexRouteImport } from './routes/patterns.index'
18
23
  import { Route as MilestonesIndexRouteImport } from './routes/milestones.index'
24
+ import { Route as DesignsIndexRouteImport } from './routes/designs.index'
19
25
  import { Route as TasksTaskIdRouteImport } from './routes/tasks.$taskId'
26
+ import { Route as ReportsSlugRouteImport } from './routes/reports.$slug'
27
+ import { Route as PatternsSlugRouteImport } from './routes/patterns.$slug'
20
28
  import { Route as MilestonesMilestoneIdRouteImport } from './routes/milestones.$milestoneId'
29
+ import { Route as DesignsSlugRouteImport } from './routes/designs.$slug'
21
30
  import { Route as ApiWatchRouteImport } from './routes/api/watch'
22
31
 
23
32
  const TasksRoute = TasksRouteImport.update({
@@ -30,11 +39,26 @@ const SearchRoute = SearchRouteImport.update({
30
39
  path: '/search',
31
40
  getParentRoute: () => rootRouteImport,
32
41
  } as any)
42
+ const ReportsRoute = ReportsRouteImport.update({
43
+ id: '/reports',
44
+ path: '/reports',
45
+ getParentRoute: () => rootRouteImport,
46
+ } as any)
47
+ const PatternsRoute = PatternsRouteImport.update({
48
+ id: '/patterns',
49
+ path: '/patterns',
50
+ getParentRoute: () => rootRouteImport,
51
+ } as any)
33
52
  const MilestonesRoute = MilestonesRouteImport.update({
34
53
  id: '/milestones',
35
54
  path: '/milestones',
36
55
  getParentRoute: () => rootRouteImport,
37
56
  } as any)
57
+ const DesignsRoute = DesignsRouteImport.update({
58
+ id: '/designs',
59
+ path: '/designs',
60
+ getParentRoute: () => rootRouteImport,
61
+ } as any)
38
62
  const ActivityRoute = ActivityRouteImport.update({
39
63
  id: '/activity',
40
64
  path: '/activity',
@@ -50,21 +74,51 @@ const TasksIndexRoute = TasksIndexRouteImport.update({
50
74
  path: '/',
51
75
  getParentRoute: () => TasksRoute,
52
76
  } as any)
77
+ const ReportsIndexRoute = ReportsIndexRouteImport.update({
78
+ id: '/',
79
+ path: '/',
80
+ getParentRoute: () => ReportsRoute,
81
+ } as any)
82
+ const PatternsIndexRoute = PatternsIndexRouteImport.update({
83
+ id: '/',
84
+ path: '/',
85
+ getParentRoute: () => PatternsRoute,
86
+ } as any)
53
87
  const MilestonesIndexRoute = MilestonesIndexRouteImport.update({
54
88
  id: '/',
55
89
  path: '/',
56
90
  getParentRoute: () => MilestonesRoute,
57
91
  } as any)
92
+ const DesignsIndexRoute = DesignsIndexRouteImport.update({
93
+ id: '/',
94
+ path: '/',
95
+ getParentRoute: () => DesignsRoute,
96
+ } as any)
58
97
  const TasksTaskIdRoute = TasksTaskIdRouteImport.update({
59
98
  id: '/$taskId',
60
99
  path: '/$taskId',
61
100
  getParentRoute: () => TasksRoute,
62
101
  } as any)
102
+ const ReportsSlugRoute = ReportsSlugRouteImport.update({
103
+ id: '/$slug',
104
+ path: '/$slug',
105
+ getParentRoute: () => ReportsRoute,
106
+ } as any)
107
+ const PatternsSlugRoute = PatternsSlugRouteImport.update({
108
+ id: '/$slug',
109
+ path: '/$slug',
110
+ getParentRoute: () => PatternsRoute,
111
+ } as any)
63
112
  const MilestonesMilestoneIdRoute = MilestonesMilestoneIdRouteImport.update({
64
113
  id: '/$milestoneId',
65
114
  path: '/$milestoneId',
66
115
  getParentRoute: () => MilestonesRoute,
67
116
  } as any)
117
+ const DesignsSlugRoute = DesignsSlugRouteImport.update({
118
+ id: '/$slug',
119
+ path: '/$slug',
120
+ getParentRoute: () => DesignsRoute,
121
+ } as any)
68
122
  const ApiWatchRoute = ApiWatchRouteImport.update({
69
123
  id: '/api/watch',
70
124
  path: '/api/watch',
@@ -74,13 +128,22 @@ const ApiWatchRoute = ApiWatchRouteImport.update({
74
128
  export interface FileRoutesByFullPath {
75
129
  '/': typeof IndexRoute
76
130
  '/activity': typeof ActivityRoute
131
+ '/designs': typeof DesignsRouteWithChildren
77
132
  '/milestones': typeof MilestonesRouteWithChildren
133
+ '/patterns': typeof PatternsRouteWithChildren
134
+ '/reports': typeof ReportsRouteWithChildren
78
135
  '/search': typeof SearchRoute
79
136
  '/tasks': typeof TasksRouteWithChildren
80
137
  '/api/watch': typeof ApiWatchRoute
138
+ '/designs/$slug': typeof DesignsSlugRoute
81
139
  '/milestones/$milestoneId': typeof MilestonesMilestoneIdRoute
140
+ '/patterns/$slug': typeof PatternsSlugRoute
141
+ '/reports/$slug': typeof ReportsSlugRoute
82
142
  '/tasks/$taskId': typeof TasksTaskIdRoute
143
+ '/designs/': typeof DesignsIndexRoute
83
144
  '/milestones/': typeof MilestonesIndexRoute
145
+ '/patterns/': typeof PatternsIndexRoute
146
+ '/reports/': typeof ReportsIndexRoute
84
147
  '/tasks/': typeof TasksIndexRoute
85
148
  }
86
149
  export interface FileRoutesByTo {
@@ -88,22 +151,37 @@ export interface FileRoutesByTo {
88
151
  '/activity': typeof ActivityRoute
89
152
  '/search': typeof SearchRoute
90
153
  '/api/watch': typeof ApiWatchRoute
154
+ '/designs/$slug': typeof DesignsSlugRoute
91
155
  '/milestones/$milestoneId': typeof MilestonesMilestoneIdRoute
156
+ '/patterns/$slug': typeof PatternsSlugRoute
157
+ '/reports/$slug': typeof ReportsSlugRoute
92
158
  '/tasks/$taskId': typeof TasksTaskIdRoute
159
+ '/designs': typeof DesignsIndexRoute
93
160
  '/milestones': typeof MilestonesIndexRoute
161
+ '/patterns': typeof PatternsIndexRoute
162
+ '/reports': typeof ReportsIndexRoute
94
163
  '/tasks': typeof TasksIndexRoute
95
164
  }
96
165
  export interface FileRoutesById {
97
166
  __root__: typeof rootRouteImport
98
167
  '/': typeof IndexRoute
99
168
  '/activity': typeof ActivityRoute
169
+ '/designs': typeof DesignsRouteWithChildren
100
170
  '/milestones': typeof MilestonesRouteWithChildren
171
+ '/patterns': typeof PatternsRouteWithChildren
172
+ '/reports': typeof ReportsRouteWithChildren
101
173
  '/search': typeof SearchRoute
102
174
  '/tasks': typeof TasksRouteWithChildren
103
175
  '/api/watch': typeof ApiWatchRoute
176
+ '/designs/$slug': typeof DesignsSlugRoute
104
177
  '/milestones/$milestoneId': typeof MilestonesMilestoneIdRoute
178
+ '/patterns/$slug': typeof PatternsSlugRoute
179
+ '/reports/$slug': typeof ReportsSlugRoute
105
180
  '/tasks/$taskId': typeof TasksTaskIdRoute
181
+ '/designs/': typeof DesignsIndexRoute
106
182
  '/milestones/': typeof MilestonesIndexRoute
183
+ '/patterns/': typeof PatternsIndexRoute
184
+ '/reports/': typeof ReportsIndexRoute
107
185
  '/tasks/': typeof TasksIndexRoute
108
186
  }
109
187
  export interface FileRouteTypes {
@@ -111,13 +189,22 @@ export interface FileRouteTypes {
111
189
  fullPaths:
112
190
  | '/'
113
191
  | '/activity'
192
+ | '/designs'
114
193
  | '/milestones'
194
+ | '/patterns'
195
+ | '/reports'
115
196
  | '/search'
116
197
  | '/tasks'
117
198
  | '/api/watch'
199
+ | '/designs/$slug'
118
200
  | '/milestones/$milestoneId'
201
+ | '/patterns/$slug'
202
+ | '/reports/$slug'
119
203
  | '/tasks/$taskId'
204
+ | '/designs/'
120
205
  | '/milestones/'
206
+ | '/patterns/'
207
+ | '/reports/'
121
208
  | '/tasks/'
122
209
  fileRoutesByTo: FileRoutesByTo
123
210
  to:
@@ -125,28 +212,46 @@ export interface FileRouteTypes {
125
212
  | '/activity'
126
213
  | '/search'
127
214
  | '/api/watch'
215
+ | '/designs/$slug'
128
216
  | '/milestones/$milestoneId'
217
+ | '/patterns/$slug'
218
+ | '/reports/$slug'
129
219
  | '/tasks/$taskId'
220
+ | '/designs'
130
221
  | '/milestones'
222
+ | '/patterns'
223
+ | '/reports'
131
224
  | '/tasks'
132
225
  id:
133
226
  | '__root__'
134
227
  | '/'
135
228
  | '/activity'
229
+ | '/designs'
136
230
  | '/milestones'
231
+ | '/patterns'
232
+ | '/reports'
137
233
  | '/search'
138
234
  | '/tasks'
139
235
  | '/api/watch'
236
+ | '/designs/$slug'
140
237
  | '/milestones/$milestoneId'
238
+ | '/patterns/$slug'
239
+ | '/reports/$slug'
141
240
  | '/tasks/$taskId'
241
+ | '/designs/'
142
242
  | '/milestones/'
243
+ | '/patterns/'
244
+ | '/reports/'
143
245
  | '/tasks/'
144
246
  fileRoutesById: FileRoutesById
145
247
  }
146
248
  export interface RootRouteChildren {
147
249
  IndexRoute: typeof IndexRoute
148
250
  ActivityRoute: typeof ActivityRoute
251
+ DesignsRoute: typeof DesignsRouteWithChildren
149
252
  MilestonesRoute: typeof MilestonesRouteWithChildren
253
+ PatternsRoute: typeof PatternsRouteWithChildren
254
+ ReportsRoute: typeof ReportsRouteWithChildren
150
255
  SearchRoute: typeof SearchRoute
151
256
  TasksRoute: typeof TasksRouteWithChildren
152
257
  ApiWatchRoute: typeof ApiWatchRoute
@@ -168,6 +273,20 @@ declare module '@tanstack/react-router' {
168
273
  preLoaderRoute: typeof SearchRouteImport
169
274
  parentRoute: typeof rootRouteImport
170
275
  }
276
+ '/reports': {
277
+ id: '/reports'
278
+ path: '/reports'
279
+ fullPath: '/reports'
280
+ preLoaderRoute: typeof ReportsRouteImport
281
+ parentRoute: typeof rootRouteImport
282
+ }
283
+ '/patterns': {
284
+ id: '/patterns'
285
+ path: '/patterns'
286
+ fullPath: '/patterns'
287
+ preLoaderRoute: typeof PatternsRouteImport
288
+ parentRoute: typeof rootRouteImport
289
+ }
171
290
  '/milestones': {
172
291
  id: '/milestones'
173
292
  path: '/milestones'
@@ -175,6 +294,13 @@ declare module '@tanstack/react-router' {
175
294
  preLoaderRoute: typeof MilestonesRouteImport
176
295
  parentRoute: typeof rootRouteImport
177
296
  }
297
+ '/designs': {
298
+ id: '/designs'
299
+ path: '/designs'
300
+ fullPath: '/designs'
301
+ preLoaderRoute: typeof DesignsRouteImport
302
+ parentRoute: typeof rootRouteImport
303
+ }
178
304
  '/activity': {
179
305
  id: '/activity'
180
306
  path: '/activity'
@@ -196,6 +322,20 @@ declare module '@tanstack/react-router' {
196
322
  preLoaderRoute: typeof TasksIndexRouteImport
197
323
  parentRoute: typeof TasksRoute
198
324
  }
325
+ '/reports/': {
326
+ id: '/reports/'
327
+ path: '/'
328
+ fullPath: '/reports/'
329
+ preLoaderRoute: typeof ReportsIndexRouteImport
330
+ parentRoute: typeof ReportsRoute
331
+ }
332
+ '/patterns/': {
333
+ id: '/patterns/'
334
+ path: '/'
335
+ fullPath: '/patterns/'
336
+ preLoaderRoute: typeof PatternsIndexRouteImport
337
+ parentRoute: typeof PatternsRoute
338
+ }
199
339
  '/milestones/': {
200
340
  id: '/milestones/'
201
341
  path: '/'
@@ -203,6 +343,13 @@ declare module '@tanstack/react-router' {
203
343
  preLoaderRoute: typeof MilestonesIndexRouteImport
204
344
  parentRoute: typeof MilestonesRoute
205
345
  }
346
+ '/designs/': {
347
+ id: '/designs/'
348
+ path: '/'
349
+ fullPath: '/designs/'
350
+ preLoaderRoute: typeof DesignsIndexRouteImport
351
+ parentRoute: typeof DesignsRoute
352
+ }
206
353
  '/tasks/$taskId': {
207
354
  id: '/tasks/$taskId'
208
355
  path: '/$taskId'
@@ -210,6 +357,20 @@ declare module '@tanstack/react-router' {
210
357
  preLoaderRoute: typeof TasksTaskIdRouteImport
211
358
  parentRoute: typeof TasksRoute
212
359
  }
360
+ '/reports/$slug': {
361
+ id: '/reports/$slug'
362
+ path: '/$slug'
363
+ fullPath: '/reports/$slug'
364
+ preLoaderRoute: typeof ReportsSlugRouteImport
365
+ parentRoute: typeof ReportsRoute
366
+ }
367
+ '/patterns/$slug': {
368
+ id: '/patterns/$slug'
369
+ path: '/$slug'
370
+ fullPath: '/patterns/$slug'
371
+ preLoaderRoute: typeof PatternsSlugRouteImport
372
+ parentRoute: typeof PatternsRoute
373
+ }
213
374
  '/milestones/$milestoneId': {
214
375
  id: '/milestones/$milestoneId'
215
376
  path: '/$milestoneId'
@@ -217,6 +378,13 @@ declare module '@tanstack/react-router' {
217
378
  preLoaderRoute: typeof MilestonesMilestoneIdRouteImport
218
379
  parentRoute: typeof MilestonesRoute
219
380
  }
381
+ '/designs/$slug': {
382
+ id: '/designs/$slug'
383
+ path: '/$slug'
384
+ fullPath: '/designs/$slug'
385
+ preLoaderRoute: typeof DesignsSlugRouteImport
386
+ parentRoute: typeof DesignsRoute
387
+ }
220
388
  '/api/watch': {
221
389
  id: '/api/watch'
222
390
  path: '/api/watch'
@@ -227,6 +395,19 @@ declare module '@tanstack/react-router' {
227
395
  }
228
396
  }
229
397
 
398
+ interface DesignsRouteChildren {
399
+ DesignsSlugRoute: typeof DesignsSlugRoute
400
+ DesignsIndexRoute: typeof DesignsIndexRoute
401
+ }
402
+
403
+ const DesignsRouteChildren: DesignsRouteChildren = {
404
+ DesignsSlugRoute: DesignsSlugRoute,
405
+ DesignsIndexRoute: DesignsIndexRoute,
406
+ }
407
+
408
+ const DesignsRouteWithChildren =
409
+ DesignsRoute._addFileChildren(DesignsRouteChildren)
410
+
230
411
  interface MilestonesRouteChildren {
231
412
  MilestonesMilestoneIdRoute: typeof MilestonesMilestoneIdRoute
232
413
  MilestonesIndexRoute: typeof MilestonesIndexRoute
@@ -241,6 +422,33 @@ const MilestonesRouteWithChildren = MilestonesRoute._addFileChildren(
241
422
  MilestonesRouteChildren,
242
423
  )
243
424
 
425
+ interface PatternsRouteChildren {
426
+ PatternsSlugRoute: typeof PatternsSlugRoute
427
+ PatternsIndexRoute: typeof PatternsIndexRoute
428
+ }
429
+
430
+ const PatternsRouteChildren: PatternsRouteChildren = {
431
+ PatternsSlugRoute: PatternsSlugRoute,
432
+ PatternsIndexRoute: PatternsIndexRoute,
433
+ }
434
+
435
+ const PatternsRouteWithChildren = PatternsRoute._addFileChildren(
436
+ PatternsRouteChildren,
437
+ )
438
+
439
+ interface ReportsRouteChildren {
440
+ ReportsSlugRoute: typeof ReportsSlugRoute
441
+ ReportsIndexRoute: typeof ReportsIndexRoute
442
+ }
443
+
444
+ const ReportsRouteChildren: ReportsRouteChildren = {
445
+ ReportsSlugRoute: ReportsSlugRoute,
446
+ ReportsIndexRoute: ReportsIndexRoute,
447
+ }
448
+
449
+ const ReportsRouteWithChildren =
450
+ ReportsRoute._addFileChildren(ReportsRouteChildren)
451
+
244
452
  interface TasksRouteChildren {
245
453
  TasksTaskIdRoute: typeof TasksTaskIdRoute
246
454
  TasksIndexRoute: typeof TasksIndexRoute
@@ -256,7 +464,10 @@ const TasksRouteWithChildren = TasksRoute._addFileChildren(TasksRouteChildren)
256
464
  const rootRouteChildren: RootRouteChildren = {
257
465
  IndexRoute: IndexRoute,
258
466
  ActivityRoute: ActivityRoute,
467
+ DesignsRoute: DesignsRouteWithChildren,
259
468
  MilestonesRoute: MilestonesRouteWithChildren,
469
+ PatternsRoute: PatternsRouteWithChildren,
470
+ ReportsRoute: ReportsRouteWithChildren,
260
471
  SearchRoute: SearchRoute,
261
472
  TasksRoute: TasksRouteWithChildren,
262
473
  ApiWatchRoute: ApiWatchRoute,
@@ -3,12 +3,14 @@ import { useState, useCallback, useEffect } from 'react'
3
3
  import { useAutoRefresh } from '../lib/useAutoRefresh'
4
4
  import { Sidebar } from '../components/Sidebar'
5
5
  import { Header } from '../components/Header'
6
+ import { SidePanel } from '../components/SidePanel'
6
7
  import { getProgressData } from '../services/progress-database.service'
7
8
  import { listProjects, getProjectProgressPath } from '../services/projects.service'
8
9
  import { fetchGitHubProgress } from '../services/github.service'
9
10
  import type { ProgressData } from '../lib/types'
10
11
  import type { AcpProject } from '../services/projects.service'
11
12
  import { ProgressProvider } from '../contexts/ProgressContext'
13
+ import { SidePanelProvider } from '../contexts/SidePanelContext'
12
14
 
13
15
  import appCss from '../styles.css?url'
14
16
 
@@ -63,8 +65,8 @@ function NotFound() {
63
65
  return (
64
66
  <div className="flex items-center justify-center h-full">
65
67
  <div className="text-center">
66
- <h2 className="text-xl font-semibold text-gray-200 mb-2">Page Not Found</h2>
67
- <p className="text-sm text-gray-400">
68
+ <h2 className="text-xl font-semibold text-gray-800 dark:text-gray-200 mb-2">Page Not Found</h2>
69
+ <p className="text-sm text-gray-600 dark:text-gray-400">
68
70
  The page you're looking for doesn't exist.
69
71
  </p>
70
72
  </div>
@@ -154,7 +156,7 @@ function RootLayout() {
154
156
  return (
155
157
  <>
156
158
  <AutoRefresh />
157
- <div className="flex h-screen bg-gray-950 text-gray-100">
159
+ <div className="flex h-screen bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100">
158
160
  <Sidebar
159
161
  projects={context.projects}
160
162
  currentProject={currentProject}
@@ -162,12 +164,15 @@ function RootLayout() {
162
164
  onGitHubLoad={handleGitHubLoad}
163
165
  />
164
166
  <ProgressProvider data={progressData}>
165
- <div className="flex-1 flex flex-col overflow-hidden">
166
- <Header data={progressData} />
167
- <main className="flex-1 overflow-auto">
168
- <Outlet />
169
- </main>
170
- </div>
167
+ <SidePanelProvider>
168
+ <div className="flex-1 flex flex-col overflow-hidden">
169
+ <Header data={progressData} />
170
+ <main className="flex-1 overflow-auto bg-gray-50 dark:bg-gray-900">
171
+ <Outlet />
172
+ </main>
173
+ </div>
174
+ <SidePanel />
175
+ </SidePanelProvider>
171
176
  </ProgressProvider>
172
177
  </div>
173
178
  </>
@@ -0,0 +1,18 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+ import { DocumentDetail } from '../components/DocumentDetail'
3
+
4
+ export const Route = createFileRoute('/designs/$slug')({
5
+ component: DesignDetailPage,
6
+ })
7
+
8
+ function DesignDetailPage() {
9
+ const { slug } = Route.useParams()
10
+ return (
11
+ <DocumentDetail
12
+ slug={slug}
13
+ dirPath="agent/design"
14
+ sectionLabel="Designs"
15
+ sectionHref="/designs"
16
+ />
17
+ )
18
+ }
@@ -0,0 +1,10 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+ import { DocumentList } from '../components/DocumentList'
3
+
4
+ export const Route = createFileRoute('/designs/')({
5
+ component: DesignsPage,
6
+ })
7
+
8
+ function DesignsPage() {
9
+ return <DocumentList title="Designs" dirPath="agent/design" baseTo="/designs" />
10
+ }
@@ -0,0 +1,9 @@
1
+ import { createFileRoute, Outlet } from '@tanstack/react-router'
2
+
3
+ export const Route = createFileRoute('/designs')({
4
+ component: DesignsLayout,
5
+ })
6
+
7
+ function DesignsLayout() {
8
+ return <Outlet />
9
+ }
@@ -5,6 +5,7 @@ import { Breadcrumb } from '../components/Breadcrumb'
5
5
  import { DetailHeader } from '../components/DetailHeader'
6
6
  import { ProgressBar } from '../components/ProgressBar'
7
7
  import { StatusDot } from '../components/StatusDot'
8
+ import { PriorityBadge } from '../components/PriorityBadge'
8
9
  import { MarkdownContent, buildLinkMap } from '../components/MarkdownContent'
9
10
  import { getMarkdownContent, resolveMilestoneFile } from '../services/markdown.service'
10
11
  import type { MarkdownResult, ResolveFileResult } from '../services/markdown.service'
@@ -105,6 +106,10 @@ function MilestoneDetailPage() {
105
106
  <span className="text-xs text-gray-500">{milestone.progress}%</span>
106
107
  </div>
107
108
 
109
+ <div className="flex items-center gap-2 mb-4">
110
+ <PriorityBadge priority={milestone.priority} />
111
+ </div>
112
+
108
113
  <DetailHeader status={milestone.status} fields={fields} />
109
114
 
110
115
  {milestone.notes && (
@@ -140,6 +145,7 @@ function MilestoneDetailPage() {
140
145
  <span className={task.status === 'completed' ? 'text-gray-500' : 'text-gray-200'}>
141
146
  {task.name}
142
147
  </span>
148
+ <PriorityBadge priority={task.priority} />
143
149
  {task.estimated_hours && (
144
150
  <span className="text-xs text-gray-600 ml-auto">{task.estimated_hours}h</span>
145
151
  )}
@@ -0,0 +1,18 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+ import { DocumentDetail } from '../components/DocumentDetail'
3
+
4
+ export const Route = createFileRoute('/patterns/$slug')({
5
+ component: PatternDetailPage,
6
+ })
7
+
8
+ function PatternDetailPage() {
9
+ const { slug } = Route.useParams()
10
+ return (
11
+ <DocumentDetail
12
+ slug={slug}
13
+ dirPath="agent/patterns"
14
+ sectionLabel="Patterns"
15
+ sectionHref="/patterns"
16
+ />
17
+ )
18
+ }
@@ -0,0 +1,10 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+ import { DocumentList } from '../components/DocumentList'
3
+
4
+ export const Route = createFileRoute('/patterns/')({
5
+ component: PatternsPage,
6
+ })
7
+
8
+ function PatternsPage() {
9
+ return <DocumentList title="Patterns" dirPath="agent/patterns" baseTo="/patterns" />
10
+ }
@@ -0,0 +1,9 @@
1
+ import { createFileRoute, Outlet } from '@tanstack/react-router'
2
+
3
+ export const Route = createFileRoute('/patterns')({
4
+ component: PatternsLayout,
5
+ })
6
+
7
+ function PatternsLayout() {
8
+ return <Outlet />
9
+ }
@@ -0,0 +1,18 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+ import { DocumentDetail } from '../components/DocumentDetail'
3
+
4
+ export const Route = createFileRoute('/reports/$slug')({
5
+ component: ReportDetailPage,
6
+ })
7
+
8
+ function ReportDetailPage() {
9
+ const { slug } = Route.useParams()
10
+ return (
11
+ <DocumentDetail
12
+ slug={slug}
13
+ dirPath="agent/reports"
14
+ sectionLabel="Reports"
15
+ sectionHref="/reports"
16
+ />
17
+ )
18
+ }
@@ -0,0 +1,10 @@
1
+ import { createFileRoute } from '@tanstack/react-router'
2
+ import { DocumentList } from '../components/DocumentList'
3
+
4
+ export const Route = createFileRoute('/reports/')({
5
+ component: ReportsPage,
6
+ })
7
+
8
+ function ReportsPage() {
9
+ return <DocumentList title="Reports" dirPath="agent/reports" baseTo="/reports" />
10
+ }
@@ -0,0 +1,9 @@
1
+ import { createFileRoute, Outlet } from '@tanstack/react-router'
2
+
3
+ export const Route = createFileRoute('/reports')({
4
+ component: ReportsLayout,
5
+ })
6
+
7
+ function ReportsLayout() {
8
+ return <Outlet />
9
+ }
@@ -3,6 +3,7 @@ import { useState, useEffect, useMemo } from 'react'
3
3
  import { useProgressData } from '../contexts/ProgressContext'
4
4
  import { Breadcrumb } from '../components/Breadcrumb'
5
5
  import { DetailHeader } from '../components/DetailHeader'
6
+ import { PriorityBadge } from '../components/PriorityBadge'
6
7
  import { MarkdownContent, buildLinkMap } from '../components/MarkdownContent'
7
8
  import { getMarkdownContent } from '../services/markdown.service'
8
9
  import { resolveTaskFile } from '../services/markdown.service'
@@ -94,8 +95,13 @@ function TaskDetailPage() {
94
95
  )
95
96
  }
96
97
 
98
+ const hoursDisplay = task.actual_hours != null
99
+ ? `Est: ${task.estimated_hours}h | Actual: ${task.actual_hours}h`
100
+ : `${task.estimated_hours}h`
101
+
97
102
  const fields = [
98
- { label: 'Est', value: `${task.estimated_hours}h` },
103
+ { label: 'Est', value: hoursDisplay },
104
+ ...(task.started ? [{ label: 'Started', value: task.started }] : []),
99
105
  ...(task.completed_date ? [{ label: 'Completed', value: task.completed_date }] : []),
100
106
  {
101
107
  label: 'Milestone',
@@ -123,6 +129,10 @@ function TaskDetailPage() {
123
129
 
124
130
  <h1 className="text-xl font-semibold text-gray-100 mb-3">{task.name}</h1>
125
131
 
132
+ <div className="flex items-center gap-2 mb-4">
133
+ <PriorityBadge priority={task.priority} />
134
+ </div>
135
+
126
136
  <DetailHeader status={task.status} fields={fields} />
127
137
 
128
138
  {task.notes && (