@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.
- package/package.json +1 -1
- package/src/components/DocumentDetail.tsx +100 -0
- package/src/components/DocumentList.tsx +90 -0
- package/src/components/Header.tsx +23 -6
- package/src/components/MilestoneKanban.tsx +14 -8
- package/src/components/MilestonePreview.tsx +162 -0
- package/src/components/MilestoneTable.tsx +18 -8
- package/src/components/MilestoneTree.tsx +19 -13
- package/src/components/PreviewButton.tsx +33 -0
- package/src/components/PriorityBadge.tsx +20 -0
- package/src/components/SidePanel.tsx +45 -0
- package/src/components/Sidebar.tsx +11 -8
- package/src/components/TaskList.tsx +9 -5
- package/src/components/TaskPreview.tsx +147 -0
- package/src/contexts/SidePanelContext.tsx +50 -0
- package/src/lib/types.ts +8 -0
- package/src/lib/useTheme.ts +27 -0
- package/src/lib/yaml-loader.ts +49 -13
- package/src/routeTree.gen.ts +211 -0
- package/src/routes/__root.tsx +14 -9
- package/src/routes/designs.$slug.tsx +18 -0
- package/src/routes/designs.index.tsx +10 -0
- package/src/routes/designs.tsx +9 -0
- package/src/routes/milestones.$milestoneId.tsx +6 -0
- package/src/routes/patterns.$slug.tsx +18 -0
- package/src/routes/patterns.index.tsx +10 -0
- package/src/routes/patterns.tsx +9 -0
- package/src/routes/reports.$slug.tsx +18 -0
- package/src/routes/reports.index.tsx +10 -0
- package/src/routes/reports.tsx +9 -0
- package/src/routes/tasks.$taskId.tsx +11 -1
- package/src/services/markdown.service.ts +102 -0
- package/src/styles.css +2 -2
|
@@ -115,6 +115,108 @@ async function fetchMarkdownFromGitHub(
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
// ---------- listAgentDirectory ----------
|
|
119
|
+
|
|
120
|
+
export type AgentFile = {
|
|
121
|
+
name: string
|
|
122
|
+
/** Relative path from project root, e.g. "agent/design/local.foo.md" */
|
|
123
|
+
relativePath: string
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export type ListDirResult =
|
|
127
|
+
| { ok: true; files: AgentFile[] }
|
|
128
|
+
| { ok: false; files: []; error: string }
|
|
129
|
+
|
|
130
|
+
export const listAgentDirectory = createServerFn({ method: 'GET' })
|
|
131
|
+
.inputValidator((input: { dirPath: string; github?: { owner: string; repo: string; branch?: string; token?: string } }) => input)
|
|
132
|
+
.handler(async ({ data: input }): Promise<ListDirResult> => {
|
|
133
|
+
if (input.github) {
|
|
134
|
+
return listDirFromGitHub(input.dirPath, input.github)
|
|
135
|
+
}
|
|
136
|
+
return listDirFromDisk(input.dirPath)
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
async function listDirFromDisk(dirPath: string): Promise<ListDirResult> {
|
|
140
|
+
try {
|
|
141
|
+
const fs = await import('fs')
|
|
142
|
+
const path = await import('path')
|
|
143
|
+
|
|
144
|
+
const basePath = getBasePath()
|
|
145
|
+
const fullDir = path.resolve(basePath, dirPath)
|
|
146
|
+
|
|
147
|
+
if (!fs.existsSync(fullDir)) {
|
|
148
|
+
return { ok: false, files: [], error: `Directory not found: ${dirPath}` }
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const entries = fs.readdirSync(fullDir)
|
|
152
|
+
const files: AgentFile[] = entries
|
|
153
|
+
.filter((f: string) => f.endsWith('.md') && !f.includes('template'))
|
|
154
|
+
.sort()
|
|
155
|
+
.map((f: string) => ({
|
|
156
|
+
name: f.replace(/\.md$/, ''),
|
|
157
|
+
relativePath: `${dirPath}/${f}`,
|
|
158
|
+
}))
|
|
159
|
+
|
|
160
|
+
return { ok: true, files }
|
|
161
|
+
} catch (err: any) {
|
|
162
|
+
return { ok: false, files: [], error: `Failed to list directory: ${dirPath}` }
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
async function listDirFromGitHub(
|
|
167
|
+
dirPath: string,
|
|
168
|
+
github: { owner: string; repo: string; branch?: string; token?: string },
|
|
169
|
+
): Promise<ListDirResult> {
|
|
170
|
+
try {
|
|
171
|
+
let branch = github.branch
|
|
172
|
+
if (!branch) {
|
|
173
|
+
try {
|
|
174
|
+
const metaRes = await fetch(`https://api.github.com/repos/${github.owner}/${github.repo}`, {
|
|
175
|
+
headers: github.token ? { Authorization: `token ${github.token}` } : {},
|
|
176
|
+
})
|
|
177
|
+
if (metaRes.ok) {
|
|
178
|
+
const meta = (await metaRes.json()) as { default_branch?: string }
|
|
179
|
+
branch = meta.default_branch || 'main'
|
|
180
|
+
} else {
|
|
181
|
+
branch = 'main'
|
|
182
|
+
}
|
|
183
|
+
} catch {
|
|
184
|
+
branch = 'main'
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
const url = `https://api.github.com/repos/${github.owner}/${github.repo}/contents/${dirPath}?ref=${branch}`
|
|
189
|
+
const headers: Record<string, string> = {
|
|
190
|
+
Accept: 'application/vnd.github.v3+json',
|
|
191
|
+
}
|
|
192
|
+
if (github.token) {
|
|
193
|
+
headers['Authorization'] = `token ${github.token}`
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const response = await fetch(url, { headers })
|
|
197
|
+
|
|
198
|
+
if (!response.ok) {
|
|
199
|
+
if (response.status === 404) {
|
|
200
|
+
return { ok: true, files: [] }
|
|
201
|
+
}
|
|
202
|
+
return { ok: false, files: [], error: `GitHub returned ${response.status}` }
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
const entries = (await response.json()) as Array<{ name: string; path: string; type: string }>
|
|
206
|
+
const files: AgentFile[] = entries
|
|
207
|
+
.filter((e) => e.name.endsWith('.md') && !e.name.includes('template'))
|
|
208
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
|
209
|
+
.map((e) => ({
|
|
210
|
+
name: e.name.replace(/\.md$/, ''),
|
|
211
|
+
relativePath: e.path,
|
|
212
|
+
}))
|
|
213
|
+
|
|
214
|
+
return { ok: true, files }
|
|
215
|
+
} catch (err) {
|
|
216
|
+
return { ok: false, files: [], error: `Failed to list directory from GitHub` }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
118
220
|
// ---------- resolveMilestoneFile ----------
|
|
119
221
|
|
|
120
222
|
export const resolveMilestoneFile = createServerFn({ method: 'GET' })
|
package/src/styles.css
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
@import "highlight.js/styles/github-dark.css";
|
|
4
4
|
|
|
5
5
|
html {
|
|
6
|
-
@apply bg-gray-950;
|
|
6
|
+
@apply bg-white dark:bg-gray-950;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
body {
|
|
10
|
-
@apply m-0 bg-gray-950 min-h-screen text-gray-100;
|
|
10
|
+
@apply m-0 bg-white dark:bg-gray-950 min-h-screen text-gray-900 dark:text-gray-100;
|
|
11
11
|
font-family: "Inter", system-ui, -apple-system, sans-serif;
|
|
12
12
|
-webkit-font-smoothing: antialiased;
|
|
13
13
|
-moz-osx-font-smoothing: grayscale;
|