spiracha 2.0.0 → 2.2.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/AGENTS.md +27 -12
- package/README.md +42 -19
- package/apps/ui/AGENTS.md +18 -10
- package/apps/ui/README.md +36 -11
- package/apps/ui/src/components/analytics-breakdowns.tsx +106 -0
- package/apps/ui/src/components/antigravity-conversations-table.tsx +51 -11
- package/apps/ui/src/components/antigravity-workspaces-table.tsx +1 -1
- package/apps/ui/src/components/app-shell.tsx +46 -3
- package/apps/ui/src/components/breadcrumbs.tsx +21 -3
- package/apps/ui/src/components/claude-code-sessions-table.tsx +42 -6
- package/apps/ui/src/components/claude-code-workspaces-table.tsx +3 -1
- package/apps/ui/src/components/cursor-threads-table.tsx +10 -47
- package/apps/ui/src/components/data-table.tsx +23 -5
- package/apps/ui/src/components/delete-confirm-dialog.tsx +4 -3
- package/apps/ui/src/components/export-dialog.tsx +79 -74
- package/apps/ui/src/components/grok-sessions-table.tsx +146 -0
- package/apps/ui/src/components/grok-workspaces-table.tsx +53 -0
- package/apps/ui/src/components/kiro-sessions-table.tsx +40 -4
- package/apps/ui/src/components/opencode-sessions-table.tsx +40 -4
- package/apps/ui/src/components/page-header.tsx +15 -9
- package/apps/ui/src/components/projects-table.tsx +4 -1
- package/apps/ui/src/components/qoder-sessions-table.tsx +23 -2
- package/apps/ui/src/components/qoder-workspaces-table.tsx +5 -1
- package/apps/ui/src/components/route-error-panel.tsx +13 -0
- package/apps/ui/src/components/selection-actions-toolbar.tsx +80 -0
- package/apps/ui/src/components/thread-goals-panel.tsx +50 -0
- package/apps/ui/src/components/thread-tools-panel.tsx +142 -0
- package/apps/ui/src/components/threads-table.tsx +13 -47
- package/apps/ui/src/components/transcript-view.tsx +148 -52
- package/apps/ui/src/components/ui/select.tsx +1 -1
- package/apps/ui/src/lib/antigravity-conversation-state.ts +17 -4
- package/apps/ui/src/lib/antigravity-server.ts +209 -11
- package/apps/ui/src/lib/antigravity-transcript-events.ts +57 -73
- package/apps/ui/src/lib/claude-code-queries.ts +8 -0
- package/apps/ui/src/lib/claude-code-server.ts +185 -7
- package/apps/ui/src/lib/claude-code-transcript-events.ts +8 -1
- package/apps/ui/src/lib/codex-queries.ts +16 -0
- package/apps/ui/src/lib/codex-server.ts +134 -52
- package/apps/ui/src/lib/cursor-server.ts +68 -53
- package/apps/ui/src/lib/cursor-transcript-events.ts +11 -86
- package/apps/ui/src/lib/delete-batch.ts +52 -0
- package/apps/ui/src/lib/error-presentation.ts +43 -0
- package/apps/ui/src/lib/export-mutation.ts +20 -0
- package/apps/ui/src/lib/export-options.ts +15 -0
- package/apps/ui/src/lib/formatters.ts +3 -5
- package/apps/ui/src/lib/grok-queries.ts +22 -0
- package/apps/ui/src/lib/grok-server.ts +168 -0
- package/apps/ui/src/lib/grok-transcript-events.ts +149 -0
- package/apps/ui/src/lib/kiro-server.ts +97 -7
- package/apps/ui/src/lib/mutation-error.ts +15 -0
- package/apps/ui/src/lib/opencode-server.ts +96 -7
- package/apps/ui/src/lib/path-utils.ts +1 -1
- package/apps/ui/src/lib/qoder-queries.ts +15 -0
- package/apps/ui/src/lib/qoder-server.ts +67 -11
- package/apps/ui/src/lib/qoder-transcript-events.ts +1 -1
- package/apps/ui/src/lib/route-search.ts +114 -0
- package/apps/ui/src/lib/route-state-reset.tsx +10 -0
- package/apps/ui/src/lib/settings-server.ts +33 -0
- package/apps/ui/src/lib/settings-store.tsx +82 -38
- package/apps/ui/src/lib/settings.ts +65 -0
- package/apps/ui/src/lib/source-session-export-server.ts +86 -3
- package/apps/ui/src/lib/thread-metadata.ts +22 -0
- package/apps/ui/src/lib/thread-transcript-load.ts +15 -0
- package/apps/ui/src/lib/thread-transcript-stats.ts +10 -1
- package/apps/ui/src/lib/workspace-delete-navigation.ts +20 -0
- package/apps/ui/src/routeTree.gen.ts +341 -234
- package/apps/ui/src/routes/__root.tsx +12 -15
- package/apps/ui/src/routes/analytics.tsx +10 -61
- package/apps/ui/src/routes/antigravity-conversations.$conversationId.tsx +149 -29
- package/apps/ui/src/routes/antigravity.$workspaceKey.tsx +262 -42
- package/apps/ui/src/routes/antigravity.index.tsx +2 -2
- package/apps/ui/src/routes/api.v1.conversations.$source.$id.ts +4 -0
- package/apps/ui/src/routes/api.v1.conversations.delete.ts +12 -0
- package/apps/ui/src/routes/api.v1.conversations.export.ts +12 -0
- package/apps/ui/src/routes/claude-code-sessions.$sessionId.tsx +168 -28
- package/apps/ui/src/routes/claude-code.$workspaceKey.tsx +179 -45
- package/apps/ui/src/routes/claude-code.index.tsx +2 -2
- package/apps/ui/src/routes/codex.$project.tsx +33 -31
- package/apps/ui/src/routes/codex.index.tsx +5 -10
- package/apps/ui/src/routes/cursor-threads.$composerId.tsx +31 -18
- package/apps/ui/src/routes/cursor.$workspaceKey.tsx +44 -28
- package/apps/ui/src/routes/cursor.index.tsx +5 -2
- package/apps/ui/src/routes/grok-sessions.$sessionId.tsx +401 -0
- package/apps/ui/src/routes/grok.$workspaceKey.tsx +295 -0
- package/apps/ui/src/routes/grok.index.tsx +48 -0
- package/apps/ui/src/routes/index.tsx +2 -18
- package/apps/ui/src/routes/kiro-sessions.$sessionId.tsx +91 -27
- package/apps/ui/src/routes/kiro.$workspaceKey.tsx +213 -51
- package/apps/ui/src/routes/kiro.index.tsx +2 -2
- package/apps/ui/src/routes/opencode-sessions.$sessionId.tsx +108 -29
- package/apps/ui/src/routes/opencode.$workspaceKey.tsx +231 -55
- package/apps/ui/src/routes/opencode.index.tsx +6 -2
- package/apps/ui/src/routes/qoder-sessions.$sessionId.tsx +19 -15
- package/apps/ui/src/routes/qoder.$workspaceKey.tsx +89 -48
- package/apps/ui/src/routes/qoder.index.tsx +2 -2
- package/apps/ui/src/routes/threads.$threadId.tsx +620 -105
- package/apps/ui/vite.config.ts +22 -12
- package/bin/spiracha.ts +28 -1
- package/package.json +37 -27
- package/src/client.ts +183 -5
- package/src/lib/antigravity-db.ts +424 -94
- package/src/lib/antigravity-exporter-types.ts +3 -0
- package/src/lib/antigravity-keychain.ts +7 -8
- package/src/lib/antigravity-projects.ts +201 -0
- package/src/lib/antigravity-transcript-phase.ts +47 -0
- package/src/lib/claude-code-db.ts +534 -42
- package/src/lib/claude-code-exporter-types.ts +5 -0
- package/src/lib/claude-code-transcript-phase.ts +60 -1
- package/src/lib/claude-code-transcript.ts +8 -5
- package/src/lib/codex-analytics.ts +32 -5
- package/src/lib/codex-browser-db.ts +540 -137
- package/src/lib/codex-browser-export.ts +18 -27
- package/src/lib/codex-browser-types.ts +21 -1
- package/src/lib/codex-thread-cache.ts +106 -23
- package/src/lib/codex-thread-parser.ts +149 -55
- package/src/lib/codex-thread-recovery.ts +38 -11
- package/src/lib/codex-transcript-filter.ts +31 -0
- package/src/lib/codex-transcript-renderer.ts +87 -79
- package/src/lib/concurrency.ts +56 -3
- package/src/lib/conversation-api.ts +410 -27
- package/src/lib/conversation-data/adapter-helpers.ts +25 -3
- package/src/lib/conversation-data/antigravity-adapter.ts +70 -26
- package/src/lib/conversation-data/claude-code-adapter.ts +69 -12
- package/src/lib/conversation-data/codex-adapter.ts +108 -73
- package/src/lib/conversation-data/cursor-adapter.ts +77 -29
- package/src/lib/conversation-data/grok-adapter.ts +223 -0
- package/src/lib/conversation-data/index.ts +105 -11
- package/src/lib/conversation-data/kiro-adapter.ts +59 -12
- package/src/lib/conversation-data/message-selector.ts +2 -5
- package/src/lib/conversation-data/opencode-adapter.ts +67 -17
- package/src/lib/conversation-data/path-match.ts +1 -13
- package/src/lib/conversation-data/qoder-adapter.ts +67 -37
- package/src/lib/conversation-data/types.ts +43 -0
- package/src/lib/conversation-zip-export.ts +75 -0
- package/src/lib/cursor-db.ts +68 -28
- package/src/lib/cursor-id.ts +17 -0
- package/src/lib/cursor-recovery.ts +146 -35
- package/src/lib/cursor-transcript-phase.ts +40 -0
- package/src/lib/cursor-transcript.ts +21 -5
- package/src/lib/grok-db.ts +1068 -0
- package/src/lib/grok-exporter-types.ts +110 -0
- package/src/lib/grok-transcript-phase.ts +61 -0
- package/src/lib/grok-transcript.ts +167 -0
- package/src/lib/kiro-db.ts +187 -43
- package/src/lib/kiro-transcript.ts +0 -4
- package/src/lib/model-label.ts +11 -3
- package/src/lib/opencode-db.ts +599 -60
- package/src/lib/opencode-think-tags.ts +17 -3
- package/src/lib/opencode-transcript.ts +8 -5
- package/src/lib/portable-path.ts +9 -0
- package/src/lib/qoder-acp-client.ts +11 -2
- package/src/lib/qoder-db.ts +51 -17
- package/src/lib/qoder-transcript-phase.ts +64 -0
- package/src/lib/qoder-transcript.ts +30 -2
- package/src/lib/shared.ts +63 -15
- package/src/lib/sqlite-error.ts +31 -5
- package/src/lib/transcript-load-limiter.ts +87 -0
- package/src/lib/ui-cache.ts +185 -24
- package/src/lib/ui-export-archive.ts +58 -39
- package/src/lib/ui-export-files.ts +75 -15
- package/src/lib/ui-export-zip.ts +40 -0
- package/apps/ui/package.json +0 -65
package/AGENTS.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
This repo is a Bun-first local app for browsing, exporting, and exposing agent conversation history from Codex, Claude Code, Kiro, Qoder, Cursor, Antigravity, and OpenCode.
|
|
5
|
+
This repo is a Bun-first local app for browsing, exporting, and exposing agent conversation history from Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, and OpenCode.
|
|
6
6
|
|
|
7
7
|
The command-line exporter, MCP server, and Codex plugin were removed in the 2.0 hard cut. Do not add bridge commands, compatibility aliases, or deprecated entrypoints back. New client workflows should use the stable HTTP API exposed by the UI server or the stable `spiracha/client` package export.
|
|
8
8
|
|
|
@@ -52,10 +52,14 @@ Codex browser/export modules:
|
|
|
52
52
|
- project/thread browsing queries, delete flows, dashboard summaries, DB path resolution
|
|
53
53
|
- `src/lib/codex-browser-export.ts`
|
|
54
54
|
- UI-facing thread download rendering
|
|
55
|
+
- `src/lib/codex-browser-types.ts`
|
|
56
|
+
- Codex browser query and presentation contracts
|
|
55
57
|
- `src/lib/codex-thread-types.ts`
|
|
56
58
|
- Codex DB row and transcript rendering types
|
|
57
59
|
- `src/lib/codex-transcript-renderer.ts`
|
|
58
60
|
- Markdown/plain text rendering for Codex session files
|
|
61
|
+
- `src/lib/codex-transcript-filter.ts`
|
|
62
|
+
- centralized hidden bootstrap and transcript-text filtering
|
|
59
63
|
- `src/lib/codex-thread-parser.ts`
|
|
60
64
|
- structured Codex event parsing used by analytics and the UI
|
|
61
65
|
- `src/lib/codex-analytics.ts`
|
|
@@ -66,29 +70,35 @@ Codex browser/export modules:
|
|
|
66
70
|
- Codex project recovery helpers
|
|
67
71
|
|
|
68
72
|
Source-specific browser/export modules:
|
|
69
|
-
- `src/lib/claude-code-db.ts`, `src/lib/claude-code-transcript-phase.ts`, `src/lib/claude-code-transcript.ts`
|
|
70
|
-
- `src/lib/
|
|
71
|
-
- `src/lib/
|
|
72
|
-
- `src/lib/
|
|
73
|
-
- `src/lib/
|
|
74
|
-
- `src/lib/
|
|
73
|
+
- `src/lib/claude-code-db.ts`, `src/lib/claude-code-exporter-types.ts`, `src/lib/claude-code-transcript-phase.ts`, `src/lib/claude-code-transcript.ts`
|
|
74
|
+
- `src/lib/grok-db.ts`, `src/lib/grok-exporter-types.ts`, `src/lib/grok-transcript-phase.ts`, `src/lib/grok-transcript.ts`
|
|
75
|
+
- `src/lib/kiro-db.ts`, `src/lib/kiro-exporter-types.ts`, `src/lib/kiro-transcript-phase.ts`, `src/lib/kiro-transcript.ts`
|
|
76
|
+
- `src/lib/qoder-db.ts`, `src/lib/qoder-acp-client.ts`, `src/lib/qoder-exporter-types.ts`, `src/lib/qoder-transcript-phase.ts`, `src/lib/qoder-transcript.ts`
|
|
77
|
+
- `src/lib/cursor-db.ts`, `src/lib/cursor-exporter-types.ts`, `src/lib/cursor-recovery.ts`, `src/lib/cursor-transcript-phase.ts`, `src/lib/cursor-transcript.ts`
|
|
78
|
+
- `src/lib/antigravity-db.ts`, `src/lib/antigravity-exporter-types.ts`, `src/lib/antigravity-keychain.ts`, `src/lib/antigravity-projects.ts`, `src/lib/antigravity-transcript-phase.ts`
|
|
79
|
+
- `src/lib/opencode-db.ts`, `src/lib/opencode-exporter-types.ts`, `src/lib/opencode-transcript-phase.ts`, `src/lib/opencode-think-tags.ts`, `src/lib/opencode-transcript.ts`
|
|
75
80
|
|
|
76
81
|
Shared utilities:
|
|
77
82
|
- `src/lib/concurrency.ts`
|
|
78
83
|
- `src/lib/model-label.ts`
|
|
79
84
|
- `src/lib/path-transforms.ts`
|
|
85
|
+
- `src/lib/portable-path.ts`
|
|
80
86
|
- `src/lib/shared.ts`
|
|
81
87
|
- `src/lib/sqlite-error.ts`
|
|
82
88
|
- `src/lib/sqlite-retry.ts`
|
|
83
89
|
- `src/lib/ui-cache.ts`
|
|
84
90
|
- `src/lib/ui-export-archive.ts`
|
|
85
91
|
- `src/lib/ui-export-files.ts`
|
|
92
|
+
- `src/lib/ui-export-zip.ts`
|
|
93
|
+
- `src/lib/conversation-zip-export.ts`
|
|
94
|
+
- `src/lib/transcript-load-limiter.ts`
|
|
95
|
+
- `src/coverage-check.ts`
|
|
86
96
|
|
|
87
|
-
UI
|
|
97
|
+
UI source tree:
|
|
88
98
|
- `apps/ui/`
|
|
89
99
|
- TanStack Start browser UI
|
|
90
100
|
- API routes live under `apps/ui/src/routes/api.v1.*.ts`
|
|
91
|
-
- source routes include `/threads/$threadId`, `/claude-code-sessions/$sessionId`, `/kiro-sessions/$sessionId`, `/qoder-sessions/$sessionId`, `/cursor-threads/$composerId`, `/antigravity-conversations/$conversationId`, and `/opencode-sessions/$sessionId`
|
|
101
|
+
- source routes include `/threads/$threadId`, `/claude-code-sessions/$sessionId`, `/grok-sessions/$sessionId`, `/kiro-sessions/$sessionId`, `/qoder-sessions/$sessionId`, `/cursor-threads/$composerId`, `/antigravity-conversations/$conversationId`, and `/opencode-sessions/$sessionId`
|
|
92
102
|
|
|
93
103
|
## Stable API Contract
|
|
94
104
|
|
|
@@ -105,6 +115,9 @@ The local UI server exposes:
|
|
|
105
115
|
- `POST /api/v1/conversation-query`
|
|
106
116
|
- `GET /api/v1/conversations/:source/:id`
|
|
107
117
|
- `GET /api/v1/conversations/:source/:id/export`
|
|
118
|
+
- `DELETE /api/v1/conversations/:source/:id`
|
|
119
|
+
- `POST /api/v1/conversations/delete`
|
|
120
|
+
- `POST /api/v1/conversations/export`
|
|
108
121
|
- `GET /api/v1/resolve?ref=<url-or-deeplink>`
|
|
109
122
|
|
|
110
123
|
Defaults:
|
|
@@ -126,8 +139,9 @@ Current tests cover:
|
|
|
126
139
|
- Cursor recovery/prune behavior
|
|
127
140
|
- Antigravity discovery, transcript parsing, Keychain state, and artifact export rendering
|
|
128
141
|
- OpenCode MiniMax `<think>` tag extraction, including code-literal preservation
|
|
129
|
-
- UI component and adapter behavior through the Vitest suite wrapped by `src/ui-
|
|
142
|
+
- UI component and adapter behavior through the Vitest suite wrapped by `src/ui-suite.test.ts`
|
|
130
143
|
- package manifest hard-cut guarantees through `src/package-manifest.test.ts`
|
|
144
|
+
- a 90% line-coverage gate for both the root Bun suite and UI Vitest suite, with function and hotspot reporting
|
|
131
145
|
|
|
132
146
|
When changing risky areas:
|
|
133
147
|
- Stable API changes: update `src/lib/conversation-api.test.ts` and focused tests under `src/lib/conversation-data/`.
|
|
@@ -147,13 +161,14 @@ rtk bun run build
|
|
|
147
161
|
rtk bun run coverage
|
|
148
162
|
rtk bun start
|
|
149
163
|
rtk bun run ui:preview
|
|
150
|
-
rtk bun run
|
|
164
|
+
rtk bun run test:ui
|
|
151
165
|
```
|
|
152
166
|
|
|
153
167
|
## Notes
|
|
154
168
|
|
|
155
169
|
- Keep root-package source modules imported by the UI available through `@spiracha/lib/*`.
|
|
156
|
-
- The
|
|
170
|
+
- The repository has one package manifest. Keep UI runtime dependencies needed by packaged `bunx spiracha` in root `dependencies` and build/test-only tooling in root `devDependencies`.
|
|
171
|
+
- Root-owned UI Vite commands use `apps/ui` as their internal working directory and run through `bun --bun` because TanStack and server functions depend on that application root and Bun-only modules like `bun:sqlite`. Do not add a nested manifest to achieve this. UI Vitest commands use the normal Node runtime.
|
|
157
172
|
- TanStack Start server functions should use `.validator(...)`, not deprecated `.inputValidator(...)`.
|
|
158
173
|
- API routes should use route-level `server.handlers`.
|
|
159
174
|
- Keep `*-transcript-phase.ts` modules browser-safe; UI client adapters import them directly.
|
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
[](LICENSE.md)
|
|
8
8
|
[](https://bun.sh)
|
|
9
9
|
|
|
10
|
-
Spiracha is a local TanStack Start
|
|
10
|
+
Spiracha is a Bun package with a local TanStack Start UI and a direct data client for browsing and exporting agent conversation history from Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, and OpenCode.
|
|
11
11
|
|
|
12
12
|
The legacy CLI, MCP server, and Codex plugin surfaces have been removed in the 2.0 hard cut. Spiracha now exposes the UI and a stable local data API; client-specific workflows such as review collection belong in the client that calls the API.
|
|
13
13
|
|
|
@@ -24,17 +24,20 @@ Spiracha asks Vite for port 3000 and automatically uses the next available port
|
|
|
24
24
|
For repository development:
|
|
25
25
|
|
|
26
26
|
```bash
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
bun install
|
|
28
|
+
bun start
|
|
29
29
|
```
|
|
30
30
|
|
|
31
31
|
Open the local URL printed by Vite.
|
|
32
32
|
|
|
33
|
+
Spiracha requires Bun 1.3.14 or newer. Set `PORT` to request a different starting port, for example `PORT=4100 bunx spiracha`; the launcher uses the next available port if that one is occupied.
|
|
34
|
+
|
|
33
35
|
## What It Does
|
|
34
36
|
|
|
35
|
-
- Browse local conversations across Codex, Claude Code, Kiro, Qoder, Cursor, Antigravity, and OpenCode.
|
|
36
|
-
-
|
|
37
|
-
-
|
|
37
|
+
- Browse local conversations across Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, and OpenCode.
|
|
38
|
+
- Search Codex projects from the app shell, with results delegated to the shareable `/codex?q=...` inventory filter.
|
|
39
|
+
- Inspect source-specific detail pages with transcript, tool, reasoning, metadata, raw event, export, and delete flows where supported by the source. Codex thread detail includes a tool-focused activity view plus recorded goals and sandbox policy.
|
|
40
|
+
- Export transcripts from the UI as Markdown, text, or zip bundles with source-specific commentary/final-answer filtering. The last submitted export choices persist across dialog openings; canceled drafts do not.
|
|
38
41
|
- Expose a stable API for local clients that need normalized conversation metadata and message payloads.
|
|
39
42
|
- Resolve Spiracha UI links and native source links into normalized `{ source, id }` references for cross-thread context lookup.
|
|
40
43
|
|
|
@@ -54,11 +57,16 @@ GET /api/v1/conversations?cwd=/absolute/project&include_messages=true
|
|
|
54
57
|
POST /api/v1/conversation-query
|
|
55
58
|
GET /api/v1/conversations/:source/:id
|
|
56
59
|
GET /api/v1/conversations/:source/:id/export
|
|
60
|
+
DELETE /api/v1/conversations/:source/:id
|
|
61
|
+
POST /api/v1/conversations/delete
|
|
62
|
+
POST /api/v1/conversations/export
|
|
57
63
|
GET /api/v1/resolve?ref=<url-or-deeplink>
|
|
58
64
|
```
|
|
59
65
|
|
|
60
66
|
The default list selector is `last_final_answer`, which keeps `fgh --collect` style clients fast and small. Use `message_selector=all` when a client needs the full normalized thread.
|
|
61
67
|
|
|
68
|
+
Batch delete requires an explicit source and ID list. It returns `deletedIds`, `missingIds`, and a result for each requested ID, so partial success is represented in a `200` response body. Batch export also requires an explicit source and ID list, but is atomic: any missing ID returns an error instead of a partial archive.
|
|
69
|
+
|
|
62
70
|
Example:
|
|
63
71
|
|
|
64
72
|
```bash
|
|
@@ -90,13 +98,13 @@ Response envelope:
|
|
|
90
98
|
}
|
|
91
99
|
],
|
|
92
100
|
"meta": {
|
|
93
|
-
"
|
|
101
|
+
"has_next": false,
|
|
94
102
|
"next_cursor": null
|
|
95
103
|
}
|
|
96
104
|
}
|
|
97
105
|
```
|
|
98
106
|
|
|
99
|
-
For
|
|
107
|
+
For direct access from Bun scripts and CLIs, use the public client export. Local mode reads the source data without starting the TanStack server:
|
|
100
108
|
|
|
101
109
|
```ts
|
|
102
110
|
import { createConversationClient } from "spiracha/client";
|
|
@@ -109,12 +117,16 @@ const page = await client.listConversations({
|
|
|
109
117
|
});
|
|
110
118
|
```
|
|
111
119
|
|
|
120
|
+
Library and CLI use is quiet by default. Set `SPIRACHA_TRANSCRIPT_LOAD_LOGS=1` or
|
|
121
|
+
`SPIRACHA_OPENCODE_DB_LOGS=1` only when diagnosing loader or OpenCode database timing.
|
|
122
|
+
|
|
112
123
|
## Source Locations
|
|
113
124
|
|
|
114
125
|
| Source | Default location | Primary override |
|
|
115
126
|
| --- | --- | --- |
|
|
116
127
|
| Codex | shared Codex DB probe list | `SPIRACHA_CODEX_DB` |
|
|
117
128
|
| Claude Code | `~/.claude/projects` | `SPIRACHA_CLAUDE_CODE_PROJECTS_DIR` |
|
|
129
|
+
| Grok | `~/.grok/sessions` | `SPIRACHA_GROK_SESSIONS_DIR` |
|
|
118
130
|
| Kiro | `~/Library/Application Support/Kiro/User/globalStorage/kiro.kiroagent/workspace-sessions` | `SPIRACHA_KIRO_WORKSPACE_SESSIONS_DIR` |
|
|
119
131
|
| Qoder | `~/Library/Application Support/Qoder/User/globalStorage/state.vscdb` and `~/Library/Application Support/Qoder/User/workspaceStorage` | `SPIRACHA_QODER_GLOBAL_STATE_DB`, `SPIRACHA_QODER_WORKSPACE_STORAGE_DIR` |
|
|
120
132
|
| Cursor | `~/Library/Application Support/Cursor/User` on macOS | `SPIRACHA_CURSOR_USER_DIR`, `SPIRACHA_CURSOR_PROJECTS_DIR` |
|
|
@@ -122,27 +134,38 @@ const page = await client.listConversations({
|
|
|
122
134
|
| OpenCode | `${XDG_DATA_HOME:-~/.local/share}/opencode/opencode.db` | `SPIRACHA_OPENCODE_DB` |
|
|
123
135
|
| UI exports | OS temp directory under `spiracha-ui-exports` | `SPIRACHA_UI_EXPORT_DIR` |
|
|
124
136
|
|
|
137
|
+
### Qoder live ACP hydration
|
|
138
|
+
|
|
139
|
+
Qoder detail/export reads first use persisted state and CLI transcript files. When those do not contain assistant messages and Qoder is running, Spiracha can connect to Qoder's local JSON-RPC ACP Unix socket, issue `initialize` and `session/load`, and collect the streamed session updates. The default socket is the Qoder `SharedClientCache/qoder.sock`; override it with `SPIRACHA_QODER_SOCKET_PATH` (or the legacy environment spelling `SPIRACHA_QODER_SOCKET`). Connection failures and timeouts fall back to the persisted transcript rather than preventing the session from loading.
|
|
140
|
+
|
|
125
141
|
## UI Routes
|
|
126
142
|
|
|
127
143
|
- `/codex` and `/codex/$project` for Codex inventory and project threads.
|
|
128
144
|
- `/threads/$threadId` for Codex thread detail.
|
|
129
|
-
- `/claude-code`, `/kiro`, `/qoder`, `/cursor`, `/antigravity`, and `/opencode` for source inventories.
|
|
130
|
-
- Source detail routes include `/claude-code-sessions/$sessionId`, `/kiro-sessions/$sessionId`, `/qoder-sessions/$sessionId`, `/cursor-threads/$composerId`, `/antigravity-conversations/$conversationId`, and `/opencode-sessions/$sessionId`.
|
|
131
|
-
- `/analytics` for Codex token and tool-
|
|
145
|
+
- `/claude-code`, `/grok`, `/kiro`, `/qoder`, `/cursor`, `/antigravity`, and `/opencode` for source inventories.
|
|
146
|
+
- Source detail routes include `/claude-code-sessions/$sessionId`, `/grok-sessions/$sessionId`, `/kiro-sessions/$sessionId`, `/qoder-sessions/$sessionId`, `/cursor-threads/$composerId`, `/antigravity-conversations/$conversationId`, and `/opencode-sessions/$sessionId`.
|
|
147
|
+
- `/analytics` for project-scoped Codex token totals, average and median thread size, archive counts, tool usage, model tokens, client sources, and reasoning-effort breakdowns.
|
|
148
|
+
- `/settings` for transcript path conversion and username redaction. Export dialogs remember their own last submitted options.
|
|
132
149
|
|
|
133
150
|
## Development
|
|
134
151
|
|
|
135
152
|
```bash
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
153
|
+
bun test
|
|
154
|
+
bun run lint
|
|
155
|
+
bun run typecheck
|
|
156
|
+
bun run build
|
|
157
|
+
bun run coverage
|
|
158
|
+
bun start
|
|
159
|
+
bun run test:ui
|
|
143
160
|
```
|
|
144
161
|
|
|
145
|
-
|
|
162
|
+
`bun run coverage` enforces at least 90% line coverage independently for the root Bun suite and the UI Vitest suite, and reports function coverage and per-file hotspots for follow-up.
|
|
163
|
+
|
|
164
|
+
Run one root test file with `bun test src/lib/shared.test.ts`. Run one UI test file with `bun run test:ui --run apps/ui/src/components/export-dialog.vitest.tsx`.
|
|
165
|
+
|
|
166
|
+
Spiracha has one package manifest. The `apps/ui` directory remains a source boundary, but all UI and direct-client commands and dependencies are owned at the repository root. Root-owned Vite commands use `apps/ui` as their internal working directory and run through `bun --bun` because TanStack server functions import Bun-only modules such as `bun:sqlite`; Vitest uses its normal Node runtime.
|
|
167
|
+
|
|
168
|
+
TanStack Router generates `apps/ui/src/routeTree.gen.ts` during development/build. Do not edit it manually; after adding or renaming route files, run `bun run build` (or start the dev server) and include the generated update.
|
|
146
169
|
|
|
147
170
|
## Breaking Consequences
|
|
148
171
|
|
package/apps/ui/AGENTS.md
CHANGED
|
@@ -2,22 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
This
|
|
5
|
+
This directory is the local browser UI source tree for Spiracha. It reads Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, and OpenCode local data through TanStack Start server functions and shared root-package helpers.
|
|
6
6
|
|
|
7
7
|
## Commands
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
rtk bun
|
|
10
|
+
rtk bun start
|
|
11
11
|
rtk bun run build
|
|
12
|
-
rtk bun run test
|
|
12
|
+
rtk bun run test:ui
|
|
13
13
|
rtk bun run typecheck
|
|
14
14
|
rtk bun run coverage
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
+
Run these commands from the repository root. There is intentionally no nested UI package manifest.
|
|
18
|
+
|
|
17
19
|
Important:
|
|
18
20
|
|
|
19
|
-
- `
|
|
20
|
-
-
|
|
21
|
+
- `start`, `build`, and `ui:preview` run Vite through `bun --bun ...` on purpose. Do not switch them back to Node execution, because the server functions import Bun-only modules such as `bun:sqlite`.
|
|
22
|
+
- Those root-owned Vite scripts use `apps/ui` as their internal working directory because TanStack Start derives part of its dev-server plan from the process working directory.
|
|
23
|
+
- Keep UI runtime dependencies needed by the packaged `bunx spiracha` launcher in the root `dependencies`. Keep build and test tooling in the root `devDependencies`.
|
|
24
|
+
- Keep Vitest on its normal Node runtime; forcing it through `bun --bun` breaks test-environment module and global behavior.
|
|
21
25
|
|
|
22
26
|
## Routing
|
|
23
27
|
|
|
@@ -29,12 +33,13 @@ Important:
|
|
|
29
33
|
- Codex project inventory and project-thread search use route search params. `/codex` and `/codex/$project` use `q`.
|
|
30
34
|
- Codex analytics uses the `project` route search param so filtered analytics links can be bookmarked and reloaded.
|
|
31
35
|
- Claude Code session detail lives at `/claude-code-sessions/$sessionId`.
|
|
36
|
+
- Grok session detail lives at `/grok-sessions/$sessionId`.
|
|
32
37
|
- Kiro session detail lives at `/kiro-sessions/$sessionId`.
|
|
33
38
|
- Qoder session detail lives at `/qoder-sessions/$sessionId`.
|
|
34
39
|
- Cursor thread detail lives at `/cursor-threads/$composerId`.
|
|
35
40
|
- Antigravity conversation detail lives at `/antigravity-conversations/$conversationId`.
|
|
36
41
|
- OpenCode session detail lives at `/opencode-sessions/$sessionId`.
|
|
37
|
-
- Keep the Codex, Claude Code, Kiro, Qoder, Cursor, Antigravity, and OpenCode list/detail pages aligned around the same table-driven index/detail pattern when adding new source integrations.
|
|
42
|
+
- Keep the Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, and OpenCode list/detail pages aligned around the same table-driven index/detail pattern when adding new source integrations.
|
|
38
43
|
|
|
39
44
|
## Shared Data Layer
|
|
40
45
|
|
|
@@ -48,6 +53,9 @@ The UI depends on root-package helpers via `@spiracha/*` path aliases:
|
|
|
48
53
|
- `@spiracha/lib/claude-code-db`
|
|
49
54
|
- `@spiracha/lib/claude-code-transcript-phase`
|
|
50
55
|
- `@spiracha/lib/claude-code-transcript`
|
|
56
|
+
- `@spiracha/lib/grok-db`
|
|
57
|
+
- `@spiracha/lib/grok-transcript-phase`
|
|
58
|
+
- `@spiracha/lib/grok-transcript`
|
|
51
59
|
- `@spiracha/lib/kiro-db`
|
|
52
60
|
- `@spiracha/lib/kiro-transcript-phase`
|
|
53
61
|
- `@spiracha/lib/kiro-transcript`
|
|
@@ -73,10 +81,10 @@ The `*-transcript-phase` helpers are intentionally browser-safe and may be impor
|
|
|
73
81
|
|
|
74
82
|
Use the existing layers consistently:
|
|
75
83
|
|
|
76
|
-
- TanStack Start server functions in `src/lib/codex-server.ts`, `src/lib/claude-code-server.ts`, `src/lib/kiro-server.ts`, `src/lib/qoder-server.ts`, `src/lib/cursor-server.ts`, `src/lib/antigravity-server.ts`, and `src/lib/opencode-server.ts`
|
|
84
|
+
- TanStack Start server functions in `src/lib/codex-server.ts`, `src/lib/claude-code-server.ts`, `src/lib/grok-server.ts`, `src/lib/kiro-server.ts`, `src/lib/qoder-server.ts`, `src/lib/cursor-server.ts`, `src/lib/antigravity-server.ts`, and `src/lib/opencode-server.ts`
|
|
77
85
|
- Use for any browser-triggered read/write that needs Bun-only modules, DB access, filesystem access, Keychain access, or shared root-package helpers.
|
|
78
86
|
- Use `.validator(...)` for input validation. Do not add new `.inputValidator(...)` calls.
|
|
79
|
-
- TanStack Query query options in `src/lib/codex-queries.ts`, `src/lib/claude-code-queries.ts`, `src/lib/kiro-queries.ts`, `src/lib/qoder-queries.ts`, `src/lib/cursor-queries.ts`, `src/lib/antigravity-queries.ts`, and `src/lib/opencode-queries.ts`
|
|
87
|
+
- TanStack Query query options in `src/lib/codex-queries.ts`, `src/lib/claude-code-queries.ts`, `src/lib/grok-queries.ts`, `src/lib/kiro-queries.ts`, `src/lib/qoder-queries.ts`, `src/lib/cursor-queries.ts`, `src/lib/antigravity-queries.ts`, and `src/lib/opencode-queries.ts`
|
|
80
88
|
- Use for client-side fetching, caching, retries, and invalidation of server-function results.
|
|
81
89
|
- Shared root-package helpers under `@spiracha/lib/*`
|
|
82
90
|
- Extend these when the behavior should stay shared between the UI and the stable data API.
|
|
@@ -103,7 +111,7 @@ For URL-backed route state, use `src/lib/route-search.ts` instead of ad hoc pars
|
|
|
103
111
|
- UI component tests live under `src/**/*.vitest.tsx`.
|
|
104
112
|
- Source-specific transcript adapter tests live next to their adapter files under `src/lib/*.vitest.ts`.
|
|
105
113
|
- Route search parsing tests live next to the helper in `src/lib/route-search.vitest.ts`.
|
|
106
|
-
- The root package wraps this Vitest suite from `src/ui-
|
|
114
|
+
- The root package wraps this Vitest suite from `src/ui-suite.test.ts` so `rtk bun test` exercises both the Bun suite and the UI suite.
|
|
107
115
|
|
|
108
116
|
## Design
|
|
109
117
|
|
|
@@ -113,5 +121,5 @@ For URL-backed route state, use `src/lib/route-search.ts` instead of ad hoc pars
|
|
|
113
121
|
## Constraints
|
|
114
122
|
|
|
115
123
|
- Do not add a second database.
|
|
116
|
-
- Do not duplicate transcript parsing or export rendering in
|
|
124
|
+
- Do not duplicate transcript parsing or export rendering in the UI source tree.
|
|
117
125
|
- Use the shared root-package helpers instead.
|
package/apps/ui/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Spiracha UI
|
|
2
2
|
|
|
3
|
-
The browser UI for browsing local Codex, Claude Code, Kiro, Qoder, Cursor, Antigravity, and OpenCode history, inspecting transcript details, exporting chats, and analyzing Codex usage patterns.
|
|
3
|
+
The browser UI for browsing local Codex, Claude Code, Grok, Kiro, Qoder, Cursor, Antigravity, and OpenCode history, inspecting transcript details, exporting chats, and analyzing Codex usage patterns.
|
|
4
4
|
|
|
5
5
|
## Stack
|
|
6
6
|
|
|
@@ -17,10 +17,13 @@ The browser UI for browsing local Codex, Claude Code, Kiro, Qoder, Cursor, Antig
|
|
|
17
17
|
|
|
18
18
|
- lists derived Codex projects from the Codex SQLite database
|
|
19
19
|
- lists Codex threads within a project in chronological order
|
|
20
|
-
- shows Codex thread timelines, tool
|
|
21
|
-
-
|
|
20
|
+
- shows Codex thread timelines, a dedicated tool activity and definition view, recorded goals, readable sandbox policy, metadata, and raw event context
|
|
21
|
+
- searches Codex projects from the app shell through the URL-backed `/codex?q=...` inventory filter
|
|
22
|
+
- exports Codex, Claude Code, Grok, Kiro, Qoder, Cursor, and OpenCode sessions or threads as Markdown, plain text, or optional zip archives with optional metadata, commentary, and tool-call inclusion; the last submitted choices persist while canceled drafts are discarded
|
|
22
23
|
- lists Claude Code workspaces and sessions from local `~/.claude/projects` JSONL files
|
|
23
24
|
- shows dedicated Claude Code session detail pages with reasoning, tool calls, token metadata, and export actions
|
|
25
|
+
- lists Grok workspaces and sessions from local Grok session archives
|
|
26
|
+
- shows dedicated Grok session detail pages with compacted-history recovery, tool calls, metadata, export, and delete actions
|
|
24
27
|
- lists Kiro workspaces and sessions from local Kiro workspace session files
|
|
25
28
|
- shows dedicated Kiro session detail pages with image attachments, prompt logs, execution-derived tool calls, metadata, and export actions
|
|
26
29
|
- lists Qoder workspaces and sessions from local Qoder history and checkpoint storage
|
|
@@ -33,26 +36,26 @@ The browser UI for browsing local Codex, Claude Code, Kiro, Qoder, Cursor, Antig
|
|
|
33
36
|
- unlocks Antigravity transcript export through macOS Keychain and exports conversations or artifacts as Markdown
|
|
34
37
|
- lists OpenCode workspaces and sessions from the local OpenCode SQLite database
|
|
35
38
|
- shows dedicated OpenCode session detail pages with reasoning, tool parts, MiniMax `<think>` blocks, token metadata, and export actions
|
|
36
|
-
- shows dashboard and
|
|
39
|
+
- shows dashboard and project-scoped Codex analytics for token totals, average and median thread size, archive counts, tool usage, model tokens, client sources, and reasoning effort
|
|
37
40
|
- keeps Codex inventory search and analytics project filters in URL search params for reloadable and shareable views
|
|
38
41
|
- keeps source-specific commentary hidden by default while preserving final answers, with matching export filtering for Claude Code, Kiro, Qoder, and OpenCode
|
|
39
42
|
|
|
40
43
|
## Commands
|
|
41
44
|
|
|
42
45
|
```bash
|
|
43
|
-
rtk bun
|
|
46
|
+
rtk bun start
|
|
44
47
|
rtk bun run build
|
|
45
|
-
rtk bun run test
|
|
48
|
+
rtk bun run test:ui
|
|
46
49
|
rtk bun run typecheck
|
|
47
50
|
```
|
|
48
51
|
|
|
49
52
|
## Runtime Note
|
|
50
53
|
|
|
51
|
-
|
|
54
|
+
Run these commands from the repository root. The UI is part of the root package and intentionally has no nested package manifest.
|
|
52
55
|
|
|
53
|
-
That is required because
|
|
56
|
+
Root-owned Vite commands use `apps/ui` as their internal working directory and run through `bun --bun`. That is required because TanStack Start derives part of its server plan from the application directory and the server functions use Bun-only modules such as `bun:sqlite`.
|
|
54
57
|
|
|
55
|
-
|
|
58
|
+
Vitest uses its normal Node runtime.
|
|
56
59
|
|
|
57
60
|
## Configuration
|
|
58
61
|
|
|
@@ -67,9 +70,17 @@ Runtime configuration is intentionally small:
|
|
|
67
70
|
- `SPIRACHA_ANALYTICS_TRANSCRIPT_CONCURRENCY`
|
|
68
71
|
- Optional positive integer for Codex analytics transcript parsing concurrency.
|
|
69
72
|
- Defaults to `8`.
|
|
73
|
+
- `SPIRACHA_TRANSCRIPT_LOAD_CONCURRENCY`
|
|
74
|
+
- Optional positive integer for detail-page transcript loading concurrency across sources.
|
|
75
|
+
- Defaults to `3` and is capped at `16` to protect the server from excessive parallel disk and database work.
|
|
76
|
+
- `SPIRACHA_TRANSCRIPT_LOAD_LOGS`
|
|
77
|
+
- Set to `1` to log transcript-loader queue and timing diagnostics. Disabled by default so library and CLI consumers stay quiet.
|
|
70
78
|
- `SPIRACHA_CLAUDE_CODE_PROJECTS_DIR`
|
|
71
79
|
- Optional absolute path to the Claude Code projects directory.
|
|
72
80
|
- If unset, Spiracha reads `${SPIRACHA_CLAUDE_CODE_DATA_DIR:-~/.claude}/projects`. `SPIRACHA_CLAUDE_CODE_DIR` and `SPIRACHA_CLAUDE_HOME` are also accepted aliases for the Claude Code data directory.
|
|
81
|
+
- `SPIRACHA_GROK_SESSIONS_DIR`
|
|
82
|
+
- Optional path to the Grok sessions directory.
|
|
83
|
+
- If unset, Spiracha reads `${SPIRACHA_GROK_HOME:-~/.grok}/sessions`. `SPIRACHA_GROK_DIR` is accepted as a Grok home-directory alias.
|
|
73
84
|
- `SPIRACHA_KIRO_WORKSPACE_SESSIONS_DIR`
|
|
74
85
|
- Optional absolute path to the Kiro workspace sessions directory.
|
|
75
86
|
- If unset, Spiracha reads `${SPIRACHA_KIRO_DATA_DIR:-~/Library/Application Support/Kiro/User/globalStorage/kiro.kiroagent}/workspace-sessions`. `SPIRACHA_KIRO_AGENT_DIR` and `SPIRACHA_KIRO_DIR` are also accepted aliases for the Kiro data directory.
|
|
@@ -82,6 +93,11 @@ Runtime configuration is intentionally small:
|
|
|
82
93
|
- `SPIRACHA_OPENCODE_DB`
|
|
83
94
|
- Optional absolute path to the OpenCode SQLite database.
|
|
84
95
|
- If unset, Spiracha reads `${SPIRACHA_OPENCODE_DATA_DIR:-${XDG_DATA_HOME:-~/.local/share}/opencode}/opencode.db`. `SPIRACHA_OPENCODE_DIR` is also accepted as an OpenCode data-directory alias.
|
|
96
|
+
- `SPIRACHA_OPENCODE_DB_CONCURRENCY`
|
|
97
|
+
- Optional positive integer for concurrent OpenCode database reads.
|
|
98
|
+
- Defaults to `2`.
|
|
99
|
+
- `SPIRACHA_OPENCODE_DB_LOGS`
|
|
100
|
+
- Set to `1` to log OpenCode database queue and timing diagnostics. Disabled by default.
|
|
85
101
|
- `SPIRACHA_CURSOR_USER_DIR`
|
|
86
102
|
- Optional absolute path to Cursor's `User` directory.
|
|
87
103
|
- If unset, Spiracha reads the platform default Cursor user-data directory.
|
|
@@ -100,6 +116,7 @@ Default source locations:
|
|
|
100
116
|
| --- | --- | --- |
|
|
101
117
|
| Codex | shared Codex DB probe list | `SPIRACHA_CODEX_DB` |
|
|
102
118
|
| Claude Code | `~/.claude/projects` | `SPIRACHA_CLAUDE_CODE_PROJECTS_DIR` |
|
|
119
|
+
| Grok | `~/.grok/sessions` | `SPIRACHA_GROK_SESSIONS_DIR`, `SPIRACHA_GROK_HOME` |
|
|
103
120
|
| Kiro | `~/Library/Application Support/Kiro/User/globalStorage/kiro.kiroagent/workspace-sessions` | `SPIRACHA_KIRO_WORKSPACE_SESSIONS_DIR` |
|
|
104
121
|
| Qoder | `~/Library/Application Support/Qoder/User/globalStorage/state.vscdb` + `~/Library/Application Support/Qoder/User/workspaceStorage` | `SPIRACHA_QODER_GLOBAL_STATE_DB`, `SPIRACHA_QODER_WORKSPACE_STORAGE_DIR` |
|
|
105
122
|
| Cursor | `~/Library/Application Support/Cursor/User` on macOS | `SPIRACHA_CURSOR_USER_DIR`, `SPIRACHA_CURSOR_PROJECTS_DIR` |
|
|
@@ -109,6 +126,8 @@ Default source locations:
|
|
|
109
126
|
|
|
110
127
|
Codex analytics cache keys are based on Codex DB row metadata instead of statting every rollout file before cache hits. That keeps large histories responsive. The tradeoff is that manual JSONL edits outside Codex do not invalidate analytics unless DB row metadata changes or the temporary UI cache is cleared.
|
|
111
128
|
|
|
129
|
+
The temporary UI cache is pruned opportunistically at read/write boundaries, with cleanup scans throttled to once per minute. Entries expire after 24 hours and the retained cache is capped at 256 MiB; recently accessed entries refresh their age so hot data survives eviction.
|
|
130
|
+
|
|
112
131
|
Transcript detail pages expose the same display controls across sources: user messages, commentary, tool calls, extra events, and raw JSON. Claude Code assistant lead-ins are classified from `stop_reason`, Kiro assistant phases are classified per user turn from session and execution files, Qoder shows local prompt history plus checkpoint file operations, and OpenCode assistant phases are classified per assistant run after stripping MiniMax `<think>` blocks into commentary. OpenCode think-tag extraction preserves literal `<think>` examples inside Markdown code spans and fenced code blocks.
|
|
113
132
|
|
|
114
133
|
## Routes
|
|
@@ -125,6 +144,12 @@ Transcript detail pages expose the same display controls across sources: user me
|
|
|
125
144
|
- Claude Code workspace session listing
|
|
126
145
|
- `/claude-code-sessions/$sessionId`
|
|
127
146
|
- Claude Code session detail and export
|
|
147
|
+
- `/grok`
|
|
148
|
+
- Grok workspace inventory and search
|
|
149
|
+
- `/grok/$workspaceKey`
|
|
150
|
+
- Grok workspace session listing
|
|
151
|
+
- `/grok-sessions/$sessionId`
|
|
152
|
+
- Grok session detail, export, and delete
|
|
128
153
|
- `/kiro`
|
|
129
154
|
- Kiro workspace inventory and search
|
|
130
155
|
- `/kiro/$workspaceKey`
|
|
@@ -160,11 +185,11 @@ Transcript detail pages expose the same display controls across sources: user me
|
|
|
160
185
|
- `/$threadId`
|
|
161
186
|
- shortcut redirect to the thread detail page for pasted Codex thread UUIDs
|
|
162
187
|
- `/analytics`
|
|
163
|
-
- Codex token
|
|
188
|
+
- project-scoped Codex token, archive, tool, model, client-source, and reasoning-effort analytics, with `project` as the route search param
|
|
164
189
|
|
|
165
190
|
## Testing
|
|
166
191
|
|
|
167
192
|
- UI component tests live under `src/**/*.vitest.tsx`.
|
|
168
193
|
- Source-specific transcript event adapter tests live under `src/lib/*.vitest.ts`.
|
|
169
194
|
- Route search parsing tests live in `src/lib/route-search.vitest.ts`.
|
|
170
|
-
- The repo root wraps this Vitest suite from `src/ui-
|
|
195
|
+
- The repo root wraps this Vitest suite from `src/ui-suite.test.ts`, so `rtk bun test` at the root covers both the Bun tests and the UI tests.
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CodexAnalytics,
|
|
3
|
+
DistributionItem,
|
|
4
|
+
ModelTokenSummary,
|
|
5
|
+
ToolUsageSummary,
|
|
6
|
+
} from '@spiracha/lib/codex-browser-types';
|
|
7
|
+
import { createColumnHelper } from '@tanstack/react-table';
|
|
8
|
+
import { formatNumber, formatTokens } from '#/lib/formatters';
|
|
9
|
+
import { DataTable } from './data-table';
|
|
10
|
+
|
|
11
|
+
const toolUsageColumnHelper = createColumnHelper<ToolUsageSummary>();
|
|
12
|
+
const toolUsageColumns = [
|
|
13
|
+
toolUsageColumnHelper.accessor('name', {
|
|
14
|
+
cell: (info) => <span className="font-mono text-sm">{info.getValue()}</span>,
|
|
15
|
+
header: 'Tool',
|
|
16
|
+
}),
|
|
17
|
+
toolUsageColumnHelper.accessor('count', {
|
|
18
|
+
cell: (info) => <span className="font-mono text-sm">{formatNumber(info.getValue())}</span>,
|
|
19
|
+
header: 'Calls',
|
|
20
|
+
}),
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
const modelColumnHelper = createColumnHelper<ModelTokenSummary>();
|
|
24
|
+
const modelColumns = [
|
|
25
|
+
modelColumnHelper.accessor('model', {
|
|
26
|
+
cell: (info) => <span className="font-mono text-sm">{info.getValue()}</span>,
|
|
27
|
+
header: 'Model',
|
|
28
|
+
}),
|
|
29
|
+
modelColumnHelper.accessor('threadCount', {
|
|
30
|
+
cell: (info) => <span className="font-mono text-sm">{formatNumber(info.getValue())}</span>,
|
|
31
|
+
header: 'Threads',
|
|
32
|
+
}),
|
|
33
|
+
modelColumnHelper.accessor('totalTokens', {
|
|
34
|
+
cell: (info) => <span className="font-mono text-sm">{formatTokens(info.getValue())}</span>,
|
|
35
|
+
header: 'Tokens',
|
|
36
|
+
}),
|
|
37
|
+
] as const;
|
|
38
|
+
|
|
39
|
+
const distributionColumnHelper = createColumnHelper<DistributionItem>();
|
|
40
|
+
const distributionColumns = [
|
|
41
|
+
distributionColumnHelper.accessor('label', {
|
|
42
|
+
cell: (info) => <span className="font-mono text-sm">{info.getValue()}</span>,
|
|
43
|
+
header: 'Value',
|
|
44
|
+
}),
|
|
45
|
+
distributionColumnHelper.accessor('count', {
|
|
46
|
+
cell: (info) => <span className="font-mono text-sm">{formatNumber(info.getValue())}</span>,
|
|
47
|
+
header: 'Threads',
|
|
48
|
+
}),
|
|
49
|
+
] as const;
|
|
50
|
+
|
|
51
|
+
type AnalyticsBreakdownsProps = Pick<CodexAnalytics, 'modelsByTokens' | 'reasoningEfforts' | 'sources' | 'toolUsage'>;
|
|
52
|
+
|
|
53
|
+
export const AnalyticsBreakdowns = ({
|
|
54
|
+
modelsByTokens,
|
|
55
|
+
reasoningEfforts,
|
|
56
|
+
sources,
|
|
57
|
+
toolUsage,
|
|
58
|
+
}: AnalyticsBreakdownsProps) => {
|
|
59
|
+
return (
|
|
60
|
+
<div className="grid gap-6 xl:grid-cols-2">
|
|
61
|
+
<section className="space-y-4">
|
|
62
|
+
<div>
|
|
63
|
+
<h3 className="font-semibold text-sm">Most frequent tool calls</h3>
|
|
64
|
+
<p className="mt-1 text-[var(--muted-foreground)] text-sm">
|
|
65
|
+
Useful for future prompt and tool optimization work.
|
|
66
|
+
</p>
|
|
67
|
+
</div>
|
|
68
|
+
<DataTable columns={toolUsageColumns} data={toolUsage} emptyMessage="No tool calls recorded." />
|
|
69
|
+
</section>
|
|
70
|
+
|
|
71
|
+
<section className="space-y-4">
|
|
72
|
+
<div>
|
|
73
|
+
<h3 className="font-semibold text-sm">Model token breakdown</h3>
|
|
74
|
+
<p className="mt-1 text-[var(--muted-foreground)] text-sm">
|
|
75
|
+
Compare model usage and token concentration within the current project scope.
|
|
76
|
+
</p>
|
|
77
|
+
</div>
|
|
78
|
+
<DataTable columns={modelColumns} data={modelsByTokens} emptyMessage="No model usage recorded." />
|
|
79
|
+
</section>
|
|
80
|
+
|
|
81
|
+
<section className="space-y-4">
|
|
82
|
+
<div>
|
|
83
|
+
<h3 className="font-semibold text-sm">Client source breakdown</h3>
|
|
84
|
+
<p className="mt-1 text-[var(--muted-foreground)] text-sm">
|
|
85
|
+
See which Codex clients created threads in the current scope.
|
|
86
|
+
</p>
|
|
87
|
+
</div>
|
|
88
|
+
<DataTable columns={distributionColumns} data={sources} emptyMessage="No client sources recorded." />
|
|
89
|
+
</section>
|
|
90
|
+
|
|
91
|
+
<section className="space-y-4">
|
|
92
|
+
<div>
|
|
93
|
+
<h3 className="font-semibold text-sm">Reasoning effort breakdown</h3>
|
|
94
|
+
<p className="mt-1 text-[var(--muted-foreground)] text-sm">
|
|
95
|
+
Compare configured reasoning effort across threads.
|
|
96
|
+
</p>
|
|
97
|
+
</div>
|
|
98
|
+
<DataTable
|
|
99
|
+
columns={distributionColumns}
|
|
100
|
+
data={reasoningEfforts}
|
|
101
|
+
emptyMessage="No reasoning effort recorded."
|
|
102
|
+
/>
|
|
103
|
+
</section>
|
|
104
|
+
</div>
|
|
105
|
+
);
|
|
106
|
+
};
|