@prmichaelsen/acp-visualizer 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -0
- package/agent/commands/acp.clarification-address.md +417 -0
- package/agent/commands/acp.clarification-capture.md +386 -0
- package/agent/commands/acp.clarification-create.md +437 -0
- package/agent/commands/acp.clarifications-research.md +326 -0
- package/agent/commands/acp.command-create.md +432 -0
- package/agent/commands/acp.design-create.md +286 -0
- package/agent/commands/acp.design-reference.md +355 -0
- package/agent/commands/acp.handoff.md +270 -0
- package/agent/commands/acp.index.md +423 -0
- package/agent/commands/acp.init.md +546 -0
- package/agent/commands/acp.package-create.md +895 -0
- package/agent/commands/acp.package-info.md +212 -0
- package/agent/commands/acp.package-install.md +539 -0
- package/agent/commands/acp.package-list.md +280 -0
- package/agent/commands/acp.package-publish.md +541 -0
- package/agent/commands/acp.package-remove.md +293 -0
- package/agent/commands/acp.package-search.md +307 -0
- package/agent/commands/acp.package-update.md +361 -0
- package/agent/commands/acp.package-validate.md +540 -0
- package/agent/commands/acp.pattern-create.md +386 -0
- package/agent/commands/acp.plan.md +587 -0
- package/agent/commands/acp.proceed.md +882 -0
- package/agent/commands/acp.project-create.md +675 -0
- package/agent/commands/acp.project-info.md +312 -0
- package/agent/commands/acp.project-list.md +226 -0
- package/agent/commands/acp.project-remove.md +379 -0
- package/agent/commands/acp.project-set.md +227 -0
- package/agent/commands/acp.project-update.md +307 -0
- package/agent/commands/acp.projects-restore.md +228 -0
- package/agent/commands/acp.projects-sync.md +347 -0
- package/agent/commands/acp.report.md +407 -0
- package/agent/commands/acp.resume.md +239 -0
- package/agent/commands/acp.sessions.md +301 -0
- package/agent/commands/acp.status.md +293 -0
- package/agent/commands/acp.sync.md +364 -0
- package/agent/commands/acp.task-create.md +500 -0
- package/agent/commands/acp.update.md +302 -0
- package/agent/commands/acp.validate.md +466 -0
- package/agent/commands/acp.version-check-for-updates.md +276 -0
- package/agent/commands/acp.version-check.md +191 -0
- package/agent/commands/acp.version-update.md +289 -0
- package/agent/commands/command.template.md +339 -0
- package/agent/commands/git.commit.md +526 -0
- package/agent/commands/git.init.md +514 -0
- package/agent/commands/tanstack-cloudflare.deploy.md +272 -0
- package/agent/commands/tanstack-cloudflare.tail.md +275 -0
- package/agent/design/.gitkeep +0 -0
- package/agent/design/design.template.md +154 -0
- package/agent/design/local.dashboard-layout-routing.md +288 -0
- package/agent/design/local.data-model-yaml-parsing.md +310 -0
- package/agent/design/local.search-filtering.md +331 -0
- package/agent/design/local.server-api-auto-refresh.md +235 -0
- package/agent/design/local.table-tree-views.md +299 -0
- package/agent/design/local.visualizer-requirements.md +349 -0
- package/agent/design/requirements.template.md +387 -0
- package/agent/index/.gitkeep +0 -0
- package/agent/index/acp.core.yaml +137 -0
- package/agent/index/local.main.template.yaml +37 -0
- package/agent/manifest.template.yaml +13 -0
- package/agent/manifest.yaml +302 -0
- package/agent/milestones/.gitkeep +0 -0
- package/agent/milestones/milestone-1-project-scaffold-data-pipeline.md +67 -0
- package/agent/milestones/milestone-1-{title}.template.md +206 -0
- package/agent/milestones/milestone-2-dashboard-views-interaction.md +79 -0
- package/agent/package.template.yaml +86 -0
- package/agent/patterns/.gitkeep +0 -0
- package/agent/patterns/bootstrap.template.md +1237 -0
- package/agent/patterns/pattern.template.md +382 -0
- package/agent/patterns/tanstack-cloudflare.acl-permissions.md +332 -0
- package/agent/patterns/tanstack-cloudflare.action-bar-item.md +416 -0
- package/agent/patterns/tanstack-cloudflare.api-route-handlers.md +401 -0
- package/agent/patterns/tanstack-cloudflare.auth-session-management.md +387 -0
- package/agent/patterns/tanstack-cloudflare.card-and-list.md +271 -0
- package/agent/patterns/tanstack-cloudflare.chat-engine.md +353 -0
- package/agent/patterns/tanstack-cloudflare.confirmation-tokens.md +346 -0
- package/agent/patterns/tanstack-cloudflare.durable-objects-websocket.md +516 -0
- package/agent/patterns/tanstack-cloudflare.email-service.md +431 -0
- package/agent/patterns/tanstack-cloudflare.expander.md +98 -0
- package/agent/patterns/tanstack-cloudflare.fcm-push.md +115 -0
- package/agent/patterns/tanstack-cloudflare.firebase-anonymous-sessions.md +441 -0
- package/agent/patterns/tanstack-cloudflare.firebase-auth.md +348 -0
- package/agent/patterns/tanstack-cloudflare.firebase-firestore.md +550 -0
- package/agent/patterns/tanstack-cloudflare.firebase-storage.md +369 -0
- package/agent/patterns/tanstack-cloudflare.form-controls.md +145 -0
- package/agent/patterns/tanstack-cloudflare.global-search-context.md +93 -0
- package/agent/patterns/tanstack-cloudflare.image-carousel.md +126 -0
- package/agent/patterns/tanstack-cloudflare.library-services.md +553 -0
- package/agent/patterns/tanstack-cloudflare.lightbox.md +169 -0
- package/agent/patterns/tanstack-cloudflare.markdown-content.md +115 -0
- package/agent/patterns/tanstack-cloudflare.mention-suggestions.md +98 -0
- package/agent/patterns/tanstack-cloudflare.modal.md +156 -0
- package/agent/patterns/tanstack-cloudflare.nextjs-to-tanstack-routing.md +461 -0
- package/agent/patterns/tanstack-cloudflare.notifications-engine.md +151 -0
- package/agent/patterns/tanstack-cloudflare.oauth-token-refresh.md +90 -0
- package/agent/patterns/tanstack-cloudflare.og-metadata.md +296 -0
- package/agent/patterns/tanstack-cloudflare.pagination.md +442 -0
- package/agent/patterns/tanstack-cloudflare.pill-input.md +220 -0
- package/agent/patterns/tanstack-cloudflare.provider-adapter.md +401 -0
- package/agent/patterns/tanstack-cloudflare.rate-limiting.md +323 -0
- package/agent/patterns/tanstack-cloudflare.scheduled-tasks.md +338 -0
- package/agent/patterns/tanstack-cloudflare.searchable-settings.md +375 -0
- package/agent/patterns/tanstack-cloudflare.slide-over.md +129 -0
- package/agent/patterns/tanstack-cloudflare.ssr-preload.md +571 -0
- package/agent/patterns/tanstack-cloudflare.third-party-api-integration.md +508 -0
- package/agent/patterns/tanstack-cloudflare.toast-system.md +142 -0
- package/agent/patterns/tanstack-cloudflare.unified-header.md +280 -0
- package/agent/patterns/tanstack-cloudflare.user-scoped-collections.md +628 -0
- package/agent/patterns/tanstack-cloudflare.websocket-manager.md +237 -0
- package/agent/patterns/tanstack-cloudflare.wrangler-configuration.md +358 -0
- package/agent/patterns/tanstack-cloudflare.zod-schema-validation.md +336 -0
- package/agent/progress.template.yaml +161 -0
- package/agent/progress.yaml +145 -0
- package/agent/schemas/package.schema.yaml +276 -0
- package/agent/scripts/acp.common.sh +1781 -0
- package/agent/scripts/acp.install.sh +333 -0
- package/agent/scripts/acp.package-create.sh +924 -0
- package/agent/scripts/acp.package-info.sh +288 -0
- package/agent/scripts/acp.package-install.sh +893 -0
- package/agent/scripts/acp.package-list.sh +311 -0
- package/agent/scripts/acp.package-publish.sh +420 -0
- package/agent/scripts/acp.package-remove.sh +348 -0
- package/agent/scripts/acp.package-search.sh +156 -0
- package/agent/scripts/acp.package-update.sh +517 -0
- package/agent/scripts/acp.package-validate.sh +1018 -0
- package/agent/scripts/acp.uninstall.sh +85 -0
- package/agent/scripts/acp.version-check-for-updates.sh +98 -0
- package/agent/scripts/acp.version-check.sh +47 -0
- package/agent/scripts/acp.version-update.sh +176 -0
- package/agent/scripts/acp.yaml-parser.sh +985 -0
- package/agent/scripts/acp.yaml-validate.sh +205 -0
- package/agent/tasks/.gitkeep +0 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-1-initialize-tanstack-start-project.md +210 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-2-implement-data-model-yaml-parser.md +294 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-3-build-server-api-data-loading.md +193 -0
- package/agent/tasks/milestone-1-project-scaffold-data-pipeline/task-4-add-auto-refresh-sse.md +262 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-10-polish-integration-testing.md +156 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-5-build-dashboard-layout-routing.md +178 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-6-build-overview-page.md +141 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-7-implement-milestone-table-view.md +153 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-8-implement-milestone-tree-view.md +174 -0
- package/agent/tasks/milestone-2-dashboard-views-interaction/task-9-implement-search-filtering.md +233 -0
- package/agent/tasks/task-1-{title}.template.md +244 -0
- package/bin/visualize.mjs +84 -0
- package/package.json +48 -0
- package/src/components/ExtraFieldsBadge.tsx +15 -0
- package/src/components/FilterBar.tsx +33 -0
- package/src/components/Header.tsx +23 -0
- package/src/components/MilestoneTable.tsx +167 -0
- package/src/components/MilestoneTree.tsx +84 -0
- package/src/components/ProgressBar.tsx +20 -0
- package/src/components/SearchInput.tsx +22 -0
- package/src/components/Sidebar.tsx +54 -0
- package/src/components/StatusBadge.tsx +23 -0
- package/src/components/StatusDot.tsx +12 -0
- package/src/components/TaskList.tsx +36 -0
- package/src/components/ViewToggle.tsx +31 -0
- package/src/lib/config.ts +8 -0
- package/src/lib/file-watcher.ts +43 -0
- package/src/lib/search.ts +48 -0
- package/src/lib/types.ts +73 -0
- package/src/lib/useAutoRefresh.ts +31 -0
- package/src/lib/useCollapse.ts +31 -0
- package/src/lib/useFilteredData.ts +55 -0
- package/src/lib/yaml-loader-real.spec.ts +47 -0
- package/src/lib/yaml-loader.spec.ts +201 -0
- package/src/lib/yaml-loader.ts +265 -0
- package/src/routeTree.gen.ts +140 -0
- package/src/router.tsx +10 -0
- package/src/routes/__root.tsx +75 -0
- package/src/routes/api/watch.ts +29 -0
- package/src/routes/index.tsx +115 -0
- package/src/routes/milestones.tsx +50 -0
- package/src/routes/search.tsx +84 -0
- package/src/routes/tasks.tsx +63 -0
- package/src/services/progress-database.service.ts +46 -0
- package/src/styles.css +25 -0
- package/tsconfig.json +24 -0
- package/vite.config.ts +16 -0
- package/vitest.config.ts +27 -0
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# Table & Tree Views
|
|
2
|
+
|
|
3
|
+
**Concept**: P0 milestone/task visualization via sortable table and expandable tree views
|
|
4
|
+
**Created**: 2026-03-14
|
|
5
|
+
**Status**: Design Specification
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
Defines the two P0 view components for visualizing milestones and tasks: a sortable, filterable **table view** using `@tanstack/react-table` and an expandable/collapsible **tree view** showing the milestone → task hierarchy. Both views share the same underlying data and filter state.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Problem Statement
|
|
16
|
+
|
|
17
|
+
Progress.yaml contains hierarchical data (project → milestones → tasks) that users need to navigate efficiently. Two complementary views are needed:
|
|
18
|
+
- **Table**: Dense, scannable, sortable — best for comparing milestones side-by-side
|
|
19
|
+
- **Tree**: Hierarchical, contextual — best for understanding milestone-task relationships and drilling into details
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Solution
|
|
24
|
+
|
|
25
|
+
Two view components that share filter/search state, switchable via a toggle in the milestones page header. Both receive `ProgressData` as input and render milestones with inline task expansion.
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Implementation
|
|
30
|
+
|
|
31
|
+
### View Toggle
|
|
32
|
+
|
|
33
|
+
```tsx
|
|
34
|
+
// app/routes/milestones.tsx
|
|
35
|
+
|
|
36
|
+
function MilestonesPage() {
|
|
37
|
+
const [view, setView] = useState<'table' | 'tree'>('table');
|
|
38
|
+
const { data } = Route.useLoaderData();
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<div>
|
|
42
|
+
<div className="flex items-center justify-between mb-4">
|
|
43
|
+
<h2 className="text-lg font-medium">Milestones</h2>
|
|
44
|
+
<ViewToggle value={view} onChange={setView} />
|
|
45
|
+
</div>
|
|
46
|
+
<FilterBar />
|
|
47
|
+
{view === 'table' ? (
|
|
48
|
+
<MilestoneTable data={data} />
|
|
49
|
+
) : (
|
|
50
|
+
<MilestoneTree data={data} />
|
|
51
|
+
)}
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### MilestoneTable
|
|
58
|
+
|
|
59
|
+
Uses `@tanstack/react-table` with the following columns:
|
|
60
|
+
|
|
61
|
+
| Column | Width | Content | Sortable |
|
|
62
|
+
|--------|-------|---------|----------|
|
|
63
|
+
| Name | flex | Milestone name | Yes |
|
|
64
|
+
| Status | 120px | StatusBadge component | Yes |
|
|
65
|
+
| Progress | 140px | ProgressBar + percentage | Yes |
|
|
66
|
+
| Tasks | 80px | `completed/total` | Yes |
|
|
67
|
+
| Started | 100px | Date string | Yes |
|
|
68
|
+
| Est. Weeks | 80px | Estimated duration | Yes |
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
// app/components/MilestoneTable.tsx
|
|
72
|
+
|
|
73
|
+
import { createColumnHelper, useReactTable, getCoreRowModel, getSortedRowModel } from '@tanstack/react-table';
|
|
74
|
+
|
|
75
|
+
const columnHelper = createColumnHelper<Milestone>();
|
|
76
|
+
|
|
77
|
+
const columns = [
|
|
78
|
+
columnHelper.accessor('name', {
|
|
79
|
+
header: 'Milestone',
|
|
80
|
+
cell: info => (
|
|
81
|
+
<Link to="/milestones/$id" params={{ id: info.row.original.id }}
|
|
82
|
+
className="text-blue-400 hover:text-blue-300">
|
|
83
|
+
{info.getValue()}
|
|
84
|
+
</Link>
|
|
85
|
+
),
|
|
86
|
+
}),
|
|
87
|
+
columnHelper.accessor('status', {
|
|
88
|
+
header: 'Status',
|
|
89
|
+
cell: info => <StatusBadge status={info.getValue()} />,
|
|
90
|
+
}),
|
|
91
|
+
columnHelper.accessor('progress', {
|
|
92
|
+
header: 'Progress',
|
|
93
|
+
cell: info => (
|
|
94
|
+
<div className="flex items-center gap-2">
|
|
95
|
+
<ProgressBar value={info.getValue()} size="sm" />
|
|
96
|
+
<span className="text-xs text-gray-400 font-mono w-8">
|
|
97
|
+
{info.getValue()}%
|
|
98
|
+
</span>
|
|
99
|
+
</div>
|
|
100
|
+
),
|
|
101
|
+
}),
|
|
102
|
+
columnHelper.display({
|
|
103
|
+
id: 'tasks',
|
|
104
|
+
header: 'Tasks',
|
|
105
|
+
cell: info => (
|
|
106
|
+
<span className="font-mono text-xs">
|
|
107
|
+
{info.row.original.tasks_completed}/{info.row.original.tasks_total}
|
|
108
|
+
</span>
|
|
109
|
+
),
|
|
110
|
+
}),
|
|
111
|
+
columnHelper.accessor('started', {
|
|
112
|
+
header: 'Started',
|
|
113
|
+
cell: info => (
|
|
114
|
+
<span className="text-xs text-gray-400">
|
|
115
|
+
{info.getValue() || '—'}
|
|
116
|
+
</span>
|
|
117
|
+
),
|
|
118
|
+
}),
|
|
119
|
+
];
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Row expansion**: Clicking a row or expansion chevron reveals the task list for that milestone inline, below the row.
|
|
123
|
+
|
|
124
|
+
### MilestoneTree
|
|
125
|
+
|
|
126
|
+
Expandable/collapsible tree structure:
|
|
127
|
+
|
|
128
|
+
```
|
|
129
|
+
▼ M1 - Core Infrastructure [████████░░] 80% ✓ 8/10 tasks
|
|
130
|
+
✓ task-1: Setup project scaffold
|
|
131
|
+
✓ task-2: Implement data model
|
|
132
|
+
● task-3: Build server API (in progress)
|
|
133
|
+
○ task-4: Add auto-refresh
|
|
134
|
+
▶ M2 - Views & Components [██░░░░░░░░] 20% ✓ 2/10 tasks
|
|
135
|
+
▶ M3 - Search & Polish [░░░░░░░░░░] 0% ○ 0/6 tasks
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```tsx
|
|
139
|
+
// app/components/MilestoneTree.tsx
|
|
140
|
+
|
|
141
|
+
function MilestoneTree({ data }: { data: ProgressData }) {
|
|
142
|
+
const [expanded, setExpanded] = useState<Set<string>>(new Set());
|
|
143
|
+
|
|
144
|
+
const toggle = (id: string) => {
|
|
145
|
+
setExpanded(prev => {
|
|
146
|
+
const next = new Set(prev);
|
|
147
|
+
next.has(id) ? next.delete(id) : next.add(id);
|
|
148
|
+
return next;
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<div className="space-y-1">
|
|
154
|
+
{data.milestones.map(milestone => (
|
|
155
|
+
<div key={milestone.id}>
|
|
156
|
+
<MilestoneTreeRow
|
|
157
|
+
milestone={milestone}
|
|
158
|
+
expanded={expanded.has(milestone.id)}
|
|
159
|
+
onToggle={() => toggle(milestone.id)}
|
|
160
|
+
/>
|
|
161
|
+
{expanded.has(milestone.id) && (
|
|
162
|
+
<TaskList tasks={data.tasks[milestone.id] || []} />
|
|
163
|
+
)}
|
|
164
|
+
</div>
|
|
165
|
+
))}
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### TaskList (Shared)
|
|
172
|
+
|
|
173
|
+
Used by both table row expansion and tree expansion:
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
// app/components/TaskList.tsx
|
|
177
|
+
|
|
178
|
+
function TaskList({ tasks }: { tasks: Task[] }) {
|
|
179
|
+
return (
|
|
180
|
+
<div className="pl-6 py-1 space-y-0.5">
|
|
181
|
+
{tasks.map(task => (
|
|
182
|
+
<div key={task.id} className="flex items-center gap-2 py-1 text-sm">
|
|
183
|
+
<StatusDot status={task.status} />
|
|
184
|
+
<span className={task.status === 'completed' ? 'text-gray-500' : 'text-gray-200'}>
|
|
185
|
+
{task.name}
|
|
186
|
+
</span>
|
|
187
|
+
{task.notes && (
|
|
188
|
+
<span className="text-xs text-gray-500 ml-auto truncate max-w-[200px]">
|
|
189
|
+
{task.notes}
|
|
190
|
+
</span>
|
|
191
|
+
)}
|
|
192
|
+
{Object.keys(task.extra).length > 0 && (
|
|
193
|
+
<ExtraFieldsBadge fields={task.extra} />
|
|
194
|
+
)}
|
|
195
|
+
</div>
|
|
196
|
+
))}
|
|
197
|
+
</div>
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Extra Fields Display
|
|
203
|
+
|
|
204
|
+
When tasks or milestones have `extra` fields from agent drift, show a subtle indicator:
|
|
205
|
+
|
|
206
|
+
```tsx
|
|
207
|
+
// app/components/ExtraFieldsBadge.tsx
|
|
208
|
+
|
|
209
|
+
function ExtraFieldsBadge({ fields }: { fields: ExtraFields }) {
|
|
210
|
+
const count = Object.keys(fields).length;
|
|
211
|
+
if (count === 0) return null;
|
|
212
|
+
|
|
213
|
+
return (
|
|
214
|
+
<Tooltip content={JSON.stringify(fields, null, 2)}>
|
|
215
|
+
<span className="text-xs text-gray-600 bg-gray-800 px-1.5 py-0.5 rounded">
|
|
216
|
+
+{count}
|
|
217
|
+
</span>
|
|
218
|
+
</Tooltip>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### Shared Filter State
|
|
224
|
+
|
|
225
|
+
Both views consume the same filter context:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
interface FilterState {
|
|
229
|
+
status: Status | 'all';
|
|
230
|
+
search: string;
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Filtering is applied before data reaches view components — filtered `ProgressData` is passed as props. See `local.search-filtering.md` for filter implementation.
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Benefits
|
|
239
|
+
|
|
240
|
+
- **Two complementary views**: Table for scanning, tree for hierarchy
|
|
241
|
+
- **Shared data/filters**: Switching views preserves filter state
|
|
242
|
+
- **Information dense**: Monospace values, compact rows, inline expansion
|
|
243
|
+
- **Extra fields visible**: Agent-added properties are discoverable via badges
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Trade-offs
|
|
248
|
+
|
|
249
|
+
- **No virtualization in P0**: Large milestone lists (50+) may have rendering cost (mitigated: most projects have <20 milestones)
|
|
250
|
+
- **Inline expansion only**: No separate task detail page in P0 (tree + expansion provides sufficient detail)
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Applicable Patterns
|
|
255
|
+
|
|
256
|
+
| Pattern | How It Applies |
|
|
257
|
+
|---------|----------------|
|
|
258
|
+
| [`tanstack-cloudflare.expander`](../patterns/tanstack-cloudflare.expander.md) | Use the `useCollapse` hook for smooth height animation on tree node expand/collapse and table row expansion. 300ms cubic-bezier transition with `overflow: hidden`. Handles the scrollHeight → 0 measurement pattern for accurate animation. Use the `thread` or `segmented` variant style for tree indentation lines. |
|
|
259
|
+
| [`tanstack-cloudflare.card-and-list`](../patterns/tanstack-cloudflare.card-and-list.md) | TaskList rendering follows the FeedList pattern: loading skeletons, empty states, consistent card styling (`bg-gray-900/50 border border-gray-800 rounded-xl`). Text hierarchy for task items follows the pattern's conventions. |
|
|
260
|
+
| [`tanstack-cloudflare.pagination`](../patterns/tanstack-cloudflare.pagination.md) | If milestone/task lists grow large, adopt Virtuoso integration for virtualized rendering. For P0, simple rendering is sufficient (<50 milestones), but the pattern's InfiniteScrollSentinel and `useRef` offset tracking provide the upgrade path. |
|
|
261
|
+
| [`tanstack-cloudflare.ssr-preload`](../patterns/tanstack-cloudflare.ssr-preload.md) | Both table and tree views receive data via `Route.useRouteContext()` from SSR `beforeLoad`. Components initialize with SSR data, skip client fetch when present. No loading spinners on initial render. |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Dependencies
|
|
266
|
+
|
|
267
|
+
- `@tanstack/react-table` — table primitives
|
|
268
|
+
- `StatusBadge`, `ProgressBar` from layout design
|
|
269
|
+
- `ProgressData` types from data model design
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Testing Strategy
|
|
274
|
+
|
|
275
|
+
- **Component tests**: Table renders correct columns, sorting works, tree expand/collapse toggles
|
|
276
|
+
- **Filter integration**: Filtered data shows correct subset in both views
|
|
277
|
+
- **Empty state**: Both views handle 0 milestones gracefully
|
|
278
|
+
- **Extra fields**: Badge renders when extra fields present, tooltip shows JSON
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
## Migration Path
|
|
283
|
+
|
|
284
|
+
N/A — greenfield project.
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Future Considerations
|
|
289
|
+
|
|
290
|
+
- **P1: Kanban view** — Third view option showing milestones as cards in status columns
|
|
291
|
+
- **P2: Gantt view** — Timeline visualization with date positioning
|
|
292
|
+
- **Virtualization**: If projects grow beyond 50 milestones, add `@tanstack/react-virtual`
|
|
293
|
+
- **Task detail page**: `milestones.$id.tasks.$taskId.tsx` for full task view with notes, history
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
**Status**: Design Specification
|
|
298
|
+
**Recommendation**: Implement after layout + server API are in place
|
|
299
|
+
**Related Documents**: local.visualizer-requirements.md, local.dashboard-layout-routing.md, local.data-model-yaml-parsing.md, tanstack-cloudflare.expander, tanstack-cloudflare.card-and-list, tanstack-cloudflare.pagination, tanstack-cloudflare.ssr-preload
|
|
@@ -0,0 +1,349 @@
|
|
|
1
|
+
# ACP Progress Visualizer
|
|
2
|
+
|
|
3
|
+
**Concept**: Browser-based read-only dashboard for visualizing progress.yaml project data
|
|
4
|
+
**Created**: 2026-03-14
|
|
5
|
+
**Status**: Design Specification
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Overview
|
|
10
|
+
|
|
11
|
+
A standalone TanStack Start application that renders ACP `progress.yaml` files as an interactive admin dashboard. The visualizer provides table, tree, kanban, and Gantt views of milestones and tasks, with search, filtering, and auto-refresh capabilities. It runs locally during development and can be deployed to Cloudflare Workers for hosted access.
|
|
12
|
+
|
|
13
|
+
The tool lives in a separate repository (`agent-context-protocol-visualizer`) and is designed for personal use by project owners who want a visual overview of their ACP project status.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Problem Statement
|
|
18
|
+
|
|
19
|
+
ACP's `progress.yaml` files grow large (1800+ lines for the core ACP project) and are difficult to navigate in a text editor. The existing text-based status commands (`@acp.status`, `@acp.report`) provide useful summaries but lack:
|
|
20
|
+
|
|
21
|
+
- Visual milestone/task hierarchy with expandable detail
|
|
22
|
+
- Filterable views (e.g., show only in-progress items)
|
|
23
|
+
- Search across milestones, tasks, and activity logs
|
|
24
|
+
- Progress charts and completion metrics
|
|
25
|
+
- A persistent dashboard that auto-updates as work progresses
|
|
26
|
+
|
|
27
|
+
Without a visual tool, project owners must mentally parse large YAML files or rely on text command output to understand project state.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Solution
|
|
32
|
+
|
|
33
|
+
Build a TanStack Start web application that:
|
|
34
|
+
|
|
35
|
+
1. Reads `progress.yaml` from the local filesystem (P0) or a GitHub repo URL (P1)
|
|
36
|
+
2. Parses YAML into structured data
|
|
37
|
+
3. Renders multiple visualization views with priority-tiered rollout
|
|
38
|
+
4. Provides search via fuse.js and status-based filtering
|
|
39
|
+
5. Auto-refreshes when the source file changes
|
|
40
|
+
|
|
41
|
+
### Alternative Approaches Considered
|
|
42
|
+
|
|
43
|
+
- **Single HTML file**: Rejected — user confirmed this will be a "heavy project" needing proper build tooling
|
|
44
|
+
- **Static site generator**: Rejected — dynamic runtime YAML loading preferred for auto-refresh
|
|
45
|
+
- **Integration into agentbase.me**: Rejected — standalone tool preferred
|
|
46
|
+
- **Monorepo subfolder in ACP core**: Rejected — ACP core is pure bash; mixing in a full JS/TS app would complicate CI and bloat the repo
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Implementation
|
|
51
|
+
|
|
52
|
+
### Architecture
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
agent-context-protocol-visualizer/
|
|
56
|
+
├── app/
|
|
57
|
+
│ ├── routes/
|
|
58
|
+
│ │ ├── __root.tsx # Root layout (sidebar, header)
|
|
59
|
+
│ │ ├── index.tsx # Dashboard home (project overview)
|
|
60
|
+
│ │ ├── milestones.tsx # Milestone views (table/tree/kanban/gantt)
|
|
61
|
+
│ │ ├── tasks.tsx # Task detail views
|
|
62
|
+
│ │ ├── activity.tsx # Recent work timeline (P1)
|
|
63
|
+
│ │ └── search.tsx # Global search results
|
|
64
|
+
│ ├── components/
|
|
65
|
+
│ │ ├── MilestoneTable.tsx # P0: @tanstack/react-table view
|
|
66
|
+
│ │ ├── MilestoneTree.tsx # P0: Expandable/collapsible tree
|
|
67
|
+
│ │ ├── MilestoneKanban.tsx # P1: Status-column kanban
|
|
68
|
+
│ │ ├── MilestoneGantt.tsx # P2: Timeline/Gantt chart
|
|
69
|
+
│ │ ├── TaskList.tsx # Expandable task list per milestone
|
|
70
|
+
│ │ ├── ProgressBar.tsx # Overall completion percentage
|
|
71
|
+
│ │ ├── StatusBadge.tsx # Color-coded status indicators
|
|
72
|
+
│ │ ├── SearchBar.tsx # Fuse.js-powered search
|
|
73
|
+
│ │ ├── FilterBar.tsx # Status filter controls
|
|
74
|
+
│ │ └── NextSteps.tsx # Next steps display
|
|
75
|
+
│ └── lib/
|
|
76
|
+
│ ├── yaml-loader.ts # YAML parsing and data normalization
|
|
77
|
+
│ ├── data-source.ts # Filesystem vs GitHub data source abstraction
|
|
78
|
+
│ └── search.ts # Fuse.js index configuration
|
|
79
|
+
├── server/
|
|
80
|
+
│ ├── routes/
|
|
81
|
+
│ │ └── api/
|
|
82
|
+
│ │ └── progress.ts # Server route: read progress.yaml from disk
|
|
83
|
+
│ └── lib/
|
|
84
|
+
│ └── file-watcher.ts # File change detection for auto-refresh
|
|
85
|
+
├── app.config.ts
|
|
86
|
+
├── package.json
|
|
87
|
+
├── tailwind.config.ts
|
|
88
|
+
└── tsconfig.json
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Data Model
|
|
92
|
+
|
|
93
|
+
The YAML is parsed into TypeScript interfaces:
|
|
94
|
+
|
|
95
|
+
```typescript
|
|
96
|
+
interface ProgressData {
|
|
97
|
+
project: ProjectMetadata;
|
|
98
|
+
milestones: Milestone[];
|
|
99
|
+
tasks: Record<string, Task[]>; // keyed by milestone_id
|
|
100
|
+
recent_work: WorkEntry[];
|
|
101
|
+
next_steps: string[];
|
|
102
|
+
notes: string[];
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
interface ProjectMetadata {
|
|
106
|
+
name: string;
|
|
107
|
+
version: string;
|
|
108
|
+
started: string;
|
|
109
|
+
status: 'in_progress' | 'completed' | 'not_started';
|
|
110
|
+
current_milestone: string;
|
|
111
|
+
description: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
interface Milestone {
|
|
115
|
+
id: string;
|
|
116
|
+
name: string;
|
|
117
|
+
status: 'completed' | 'in_progress' | 'not_started';
|
|
118
|
+
progress: number;
|
|
119
|
+
started: string | null;
|
|
120
|
+
completed: string | null;
|
|
121
|
+
estimated_weeks: string;
|
|
122
|
+
tasks_completed: number;
|
|
123
|
+
tasks_total: number;
|
|
124
|
+
notes: string;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
interface Task {
|
|
128
|
+
id: string;
|
|
129
|
+
name: string;
|
|
130
|
+
status: 'completed' | 'in_progress' | 'not_started';
|
|
131
|
+
file: string;
|
|
132
|
+
estimated_hours: string;
|
|
133
|
+
completed_date: string | null;
|
|
134
|
+
notes: string;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
interface WorkEntry {
|
|
138
|
+
date: string;
|
|
139
|
+
description: string;
|
|
140
|
+
items: string[];
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Data Loading
|
|
145
|
+
|
|
146
|
+
**P0 — Local filesystem**:
|
|
147
|
+
- TanStack Start server route reads `progress.yaml` via `fs.readFileSync`
|
|
148
|
+
- Path configurable via environment variable or CLI argument
|
|
149
|
+
- File watcher triggers SSE/WebSocket push for auto-refresh
|
|
150
|
+
|
|
151
|
+
**P1 — GitHub remote**:
|
|
152
|
+
- Fetch via GitHub API: `GET /repos/{owner}/{repo}/contents/agent/progress.yaml`
|
|
153
|
+
- Support public repos without auth; private repos require GitHub token
|
|
154
|
+
- Poll-based refresh (configurable interval)
|
|
155
|
+
|
|
156
|
+
### Tech Stack
|
|
157
|
+
|
|
158
|
+
| Layer | Technology |
|
|
159
|
+
|-------|-----------|
|
|
160
|
+
| Framework | TanStack Start (React) |
|
|
161
|
+
| Styling | Tailwind CSS |
|
|
162
|
+
| Table | @tanstack/react-table |
|
|
163
|
+
| Search | fuse.js |
|
|
164
|
+
| YAML parsing | js-yaml or yaml |
|
|
165
|
+
| Charts (P1) | recharts |
|
|
166
|
+
| Build | Vite |
|
|
167
|
+
| Deployment (P1) | Cloudflare Workers |
|
|
168
|
+
|
|
169
|
+
### Visual Design
|
|
170
|
+
|
|
171
|
+
- Minimal, compact admin dashboard (Linear/Vercel style)
|
|
172
|
+
- Monospace fonts for data values
|
|
173
|
+
- Neutral gray palette with status accent colors:
|
|
174
|
+
- Green: completed
|
|
175
|
+
- Blue: in_progress
|
|
176
|
+
- Gray: not_started
|
|
177
|
+
- Desktop-optimized layout (no mobile responsiveness unless minimal lift)
|
|
178
|
+
- High information density
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Priority Tiers
|
|
183
|
+
|
|
184
|
+
### P0 — MVP
|
|
185
|
+
|
|
186
|
+
| Feature | Description |
|
|
187
|
+
|---------|-------------|
|
|
188
|
+
| Project metadata display | Name, version, status, dates, current milestone |
|
|
189
|
+
| Milestone table view | @tanstack/react-table with sortable columns |
|
|
190
|
+
| Milestone tree view | Expandable milestones → tasks hierarchy |
|
|
191
|
+
| Task list | Expandable/collapsible tasks within each milestone |
|
|
192
|
+
| Status badges | Color-coded completed/in-progress/not-started |
|
|
193
|
+
| Overall completion % | Progress bar across all milestones |
|
|
194
|
+
| Next steps display | Rendered from next_steps array |
|
|
195
|
+
| Status filtering | Show only in-progress, completed, or not-started items |
|
|
196
|
+
| Search | Fuse.js across milestones, tasks |
|
|
197
|
+
| Local filesystem loading | Server route reads progress.yaml from disk |
|
|
198
|
+
| Auto-refresh | File watcher triggers reload on YAML change |
|
|
199
|
+
| Local dev server | `npm run dev` starts Vite dev server |
|
|
200
|
+
|
|
201
|
+
### P1 — Enhanced
|
|
202
|
+
|
|
203
|
+
| Feature | Description |
|
|
204
|
+
|---------|-------------|
|
|
205
|
+
| Kanban board view | Columns by status (not_started → in_progress → completed) |
|
|
206
|
+
| Recent work timeline | Activity feed from recent_work entries |
|
|
207
|
+
| Notes display | Project notes rendered |
|
|
208
|
+
| Burndown/velocity chart | recharts-based completion over time |
|
|
209
|
+
| GitHub remote loading | Fetch progress.yaml from public/private GitHub repos |
|
|
210
|
+
| Multi-project support | View multiple projects from ~/.acp/projects.yaml |
|
|
211
|
+
| Hosted deployment | Cloudflare Workers via wrangler deploy |
|
|
212
|
+
|
|
213
|
+
### P2 — Future
|
|
214
|
+
|
|
215
|
+
| Feature | Description |
|
|
216
|
+
|---------|-------------|
|
|
217
|
+
| Gantt/timeline view | Horizontal timeline with date-based positioning |
|
|
218
|
+
| Task dependencies | Dependency graph visualization |
|
|
219
|
+
|
|
220
|
+
### P3 — Deferred
|
|
221
|
+
|
|
222
|
+
| Feature | Description |
|
|
223
|
+
|---------|-------------|
|
|
224
|
+
| Multi-project aggregation | Cross-project overview dashboard |
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Benefits
|
|
229
|
+
|
|
230
|
+
- **Immediate visibility**: See project status at a glance instead of parsing 1800-line YAML
|
|
231
|
+
- **Searchable**: Find any milestone, task, or activity entry instantly
|
|
232
|
+
- **Filterable**: Focus on in-progress work without scrolling past completed items
|
|
233
|
+
- **Auto-updating**: Dashboard reflects progress.yaml changes in real time
|
|
234
|
+
- **Reusable patterns**: Leverages existing acp-tanstack-cloudflare patterns for deployment
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## Trade-offs
|
|
239
|
+
|
|
240
|
+
- **Separate repo**: Requires cross-repo coordination for progress.yaml schema changes (mitigated by stable schema)
|
|
241
|
+
- **Heavy stack**: Full TanStack Start app is significant infrastructure for what starts as a YAML viewer (justified by P1+ features and user's explicit preference for "proper app")
|
|
242
|
+
- **Desktop-only**: No mobile support unless trivial to add (acceptable per requirements — users develop on laptops)
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Dependencies
|
|
247
|
+
|
|
248
|
+
- TanStack Start (React)
|
|
249
|
+
- @tanstack/react-table
|
|
250
|
+
- Tailwind CSS
|
|
251
|
+
- js-yaml or yaml
|
|
252
|
+
- fuse.js
|
|
253
|
+
- recharts (P1)
|
|
254
|
+
- wrangler (P1, for Cloudflare Workers deployment)
|
|
255
|
+
- Existing `acp-tanstack-cloudflare` patterns for deployment patterns
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Testing Strategy
|
|
260
|
+
|
|
261
|
+
- **Unit tests**: YAML parsing, data normalization, search index building
|
|
262
|
+
- **Component tests**: Table rendering, tree expand/collapse, filter logic
|
|
263
|
+
- **Integration tests**: Server route reads real progress.yaml and returns correct data
|
|
264
|
+
- **E2E tests**: Full page load, search, filter, view switching
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Migration Path
|
|
269
|
+
|
|
270
|
+
No migration needed — this is a greenfield project in a new repository.
|
|
271
|
+
|
|
272
|
+
1. Create `agent-context-protocol-visualizer` repo
|
|
273
|
+
2. Initialize TanStack Start project with Tailwind
|
|
274
|
+
3. Implement P0 features
|
|
275
|
+
4. Register in `~/.acp/projects.yaml`
|
|
276
|
+
5. Create `@acp.visualize` command as an ACP package command
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Key Design Decisions
|
|
281
|
+
|
|
282
|
+
### Scope
|
|
283
|
+
|
|
284
|
+
| Decision | Choice | Rationale |
|
|
285
|
+
|---|---|---|
|
|
286
|
+
| Read/write mode | Read-only | Dashboard is for viewing, not editing YAML |
|
|
287
|
+
| Target audience | Project owner (personal use) | P0 is local dev tool, not team-facing |
|
|
288
|
+
| Standalone vs integrated | Standalone tool in separate repo | ACP core is pure bash; JS/TS app doesn't belong there |
|
|
289
|
+
| Repository | `agent-context-protocol-visualizer` | Clean separation of concerns, independent versioning |
|
|
290
|
+
|
|
291
|
+
### Architecture
|
|
292
|
+
|
|
293
|
+
| Decision | Choice | Rationale |
|
|
294
|
+
|---|---|---|
|
|
295
|
+
| Framework | TanStack Start (React) | User preference; existing patterns in acp-tanstack-cloudflare |
|
|
296
|
+
| App type | Proper app with build tooling | Will be a "heavy project" per user; not suitable for single HTML file |
|
|
297
|
+
| Data loading | Dynamic runtime YAML parsing | Supports auto-refresh and multiple data sources |
|
|
298
|
+
| Styling | Tailwind CSS, admin dashboard pattern | Minimal, compact, Linear/Vercel style |
|
|
299
|
+
|
|
300
|
+
### Views & Features
|
|
301
|
+
|
|
302
|
+
| Decision | Choice | Rationale |
|
|
303
|
+
|---|---|---|
|
|
304
|
+
| P0 views | Table + Tree | Fastest to build, most data-dense, maps to YAML structure |
|
|
305
|
+
| P1 views | Kanban | Good visual overview, moderate build effort |
|
|
306
|
+
| P2 views | Gantt/Timeline | Most complex, many milestones lack precise dates |
|
|
307
|
+
| Search library | fuse.js | User preference, lightweight fuzzy search |
|
|
308
|
+
| Task dependencies | P2 | Nice-to-have, not needed for MVP |
|
|
309
|
+
| Responsive/mobile | Desktop-only | Users develop on laptops; mobile adds complexity for no value |
|
|
310
|
+
|
|
311
|
+
### Data Sources
|
|
312
|
+
|
|
313
|
+
| Decision | Choice | Rationale |
|
|
314
|
+
|---|---|---|
|
|
315
|
+
| P0 data source | Local filesystem via server route | Simple, fast, supports file watcher auto-refresh |
|
|
316
|
+
| P1 data source | GitHub API | Enables hosted dashboard viewing remote repos |
|
|
317
|
+
| Auto-refresh | Yes, via file watcher | Real-time updates as agents modify progress.yaml |
|
|
318
|
+
|
|
319
|
+
### Hosting
|
|
320
|
+
|
|
321
|
+
| Decision | Choice | Rationale |
|
|
322
|
+
|---|---|---|
|
|
323
|
+
| P0 hosting | Local dev server | `npm run dev`, personal use |
|
|
324
|
+
| P1 hosting | Cloudflare Workers | Existing patterns, official TanStack Start support |
|
|
325
|
+
| @acp.visualize command | Yes | Shell script to start dev server and open browser |
|
|
326
|
+
| Auto-generate via @acp.report | No | Visualizer is separate, on-demand tool |
|
|
327
|
+
|
|
328
|
+
### Multi-Project
|
|
329
|
+
|
|
330
|
+
| Decision | Choice | Rationale |
|
|
331
|
+
|---|---|---|
|
|
332
|
+
| Multi-project aggregation | P3 (deferred) | Single project is P0; aggregation is low priority |
|
|
333
|
+
| Multi-project page structure | Each project gets own page | When implemented, keeps views focused |
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Future Considerations
|
|
338
|
+
|
|
339
|
+
- **@acp.visualize command**: Package command that starts the local server and opens the dashboard
|
|
340
|
+
- **progress.yaml schema documentation**: Formal schema definition to enable cross-repo validation
|
|
341
|
+
- **Dark mode toggle**: Natural extension of the admin dashboard pattern
|
|
342
|
+
- **Export to PDF/PNG**: Snapshot reports for stakeholders
|
|
343
|
+
- **WebSocket-based refresh**: Replace file polling with WebSocket push for lower latency
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
**Status**: Design Specification
|
|
348
|
+
**Recommendation**: Create new repository `agent-context-protocol-visualizer`, initialize TanStack Start project, implement P0 features
|
|
349
|
+
**Related Documents**: clarification-10-progress-visualizer.md
|