archbyte 0.6.1 → 0.7.1
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 -62
- package/dist/agents/index.js +2 -0
- package/dist/agents/observability/adapters/archbyte.d.ts +3 -0
- package/dist/agents/observability/adapters/archbyte.js +104 -0
- package/dist/agents/observability/adapters/claude-transcripts.d.ts +31 -0
- package/dist/agents/observability/adapters/claude-transcripts.js +692 -0
- package/dist/agents/observability/reader.d.ts +7 -0
- package/dist/agents/observability/reader.js +86 -0
- package/dist/agents/observability/types.d.ts +125 -0
- package/dist/agents/observability/types.js +3 -0
- package/dist/agents/observability/writer.d.ts +9 -0
- package/dist/agents/observability/writer.js +100 -0
- package/dist/agents/pipeline/index.d.ts +1 -1
- package/dist/agents/pipeline/index.js +85 -3
- package/dist/agents/pipeline/types.d.ts +2 -0
- package/dist/agents/prompt-data.js +9 -0
- package/dist/cli/analyze.js +81 -1
- package/dist/cli/config.js +21 -1
- package/dist/server/src/index.js +301 -13
- package/package.json +1 -1
- package/ui/dist/assets/index-ClEznf0G.js +85 -0
- package/ui/dist/assets/{index-BQouokNH.css → index-FuWCQecR.css} +1 -1
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-CWGPRsWP.js +0 -72
package/README.md
CHANGED
|
@@ -5,11 +5,8 @@ AI-powered architecture visualization for your codebase. Analyzes code, generate
|
|
|
5
5
|
## Quick Start
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Run (auto-configures on first use)
|
|
12
|
-
archbyte run
|
|
8
|
+
# Run directly — no install required
|
|
9
|
+
npx archbyte run
|
|
13
10
|
```
|
|
14
11
|
|
|
15
12
|
On first run, ArchByte walks you through sign-in and provider setup interactively. Your API keys stay on your machine — ArchByte never stores or transmits your provider credentials.
|
|
@@ -19,8 +16,17 @@ On first run, ArchByte walks you through sign-in and provider setup interactivel
|
|
|
19
16
|
Prefer to configure each step separately:
|
|
20
17
|
|
|
21
18
|
```bash
|
|
22
|
-
archbyte login # Sign in or create a free account
|
|
23
|
-
archbyte init # Configure your AI provider (BYOK)
|
|
19
|
+
npx archbyte login # Sign in or create a free account
|
|
20
|
+
npx archbyte init # Configure your AI provider (BYOK)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Global install (optional)
|
|
24
|
+
|
|
25
|
+
If you prefer a persistent install:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install -g archbyte
|
|
29
|
+
archbyte run
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
### Setup with Claude Code
|
|
@@ -65,11 +71,11 @@ Run `/archbyte-help` in Claude Code to see all commands.
|
|
|
65
71
|
Sign in or create a free account. Shows an interactive provider picker (GitHub, Google, Email & Password).
|
|
66
72
|
|
|
67
73
|
```bash
|
|
68
|
-
archbyte login # interactive provider picker
|
|
69
|
-
archbyte login --github # sign in with GitHub
|
|
70
|
-
archbyte login --google # sign in with Google
|
|
71
|
-
archbyte login --email # sign in with email and password
|
|
72
|
-
archbyte login --token JWT # login with a pre-existing JWT token
|
|
74
|
+
npx archbyte login # interactive provider picker
|
|
75
|
+
npx archbyte login --github # sign in with GitHub
|
|
76
|
+
npx archbyte login --google # sign in with Google
|
|
77
|
+
npx archbyte login --email # sign in with email and password
|
|
78
|
+
npx archbyte login --token JWT # login with a pre-existing JWT token
|
|
73
79
|
```
|
|
74
80
|
|
|
75
81
|
Multiple accounts are supported. If already logged in, you'll be prompted to add a different account.
|
|
@@ -79,9 +85,9 @@ Multiple accounts are supported. If already logged in, you'll be prompted to add
|
|
|
79
85
|
Sign out of ArchByte.
|
|
80
86
|
|
|
81
87
|
```bash
|
|
82
|
-
archbyte logout # logout active account
|
|
83
|
-
archbyte logout user@co.com # logout specific account
|
|
84
|
-
archbyte logout --all # logout all accounts
|
|
88
|
+
npx archbyte logout # logout active account
|
|
89
|
+
npx archbyte logout user@co.com # logout specific account
|
|
90
|
+
npx archbyte logout --all # logout all accounts
|
|
85
91
|
```
|
|
86
92
|
|
|
87
93
|
### `archbyte accounts`
|
|
@@ -89,9 +95,9 @@ archbyte logout --all # logout all accounts
|
|
|
89
95
|
List and manage logged-in accounts.
|
|
90
96
|
|
|
91
97
|
```bash
|
|
92
|
-
archbyte accounts # list all accounts
|
|
93
|
-
archbyte accounts switch # interactive account switcher
|
|
94
|
-
archbyte accounts switch user@co.com # switch to specific account
|
|
98
|
+
npx archbyte accounts # list all accounts
|
|
99
|
+
npx archbyte accounts switch # interactive account switcher
|
|
100
|
+
npx archbyte accounts switch user@co.com # switch to specific account
|
|
95
101
|
```
|
|
96
102
|
|
|
97
103
|
### `archbyte status`
|
|
@@ -99,7 +105,7 @@ archbyte accounts switch user@co.com # switch to specific account
|
|
|
99
105
|
Show account status, tier, and usage.
|
|
100
106
|
|
|
101
107
|
```bash
|
|
102
|
-
archbyte status
|
|
108
|
+
npx archbyte status
|
|
103
109
|
```
|
|
104
110
|
|
|
105
111
|
### `archbyte init`
|
|
@@ -107,54 +113,54 @@ archbyte status
|
|
|
107
113
|
Scaffold an `archbyte.yaml` config and `.archbyte/` directory.
|
|
108
114
|
|
|
109
115
|
```bash
|
|
110
|
-
archbyte init
|
|
111
|
-
archbyte init --force # overwrite existing
|
|
116
|
+
npx archbyte init
|
|
117
|
+
npx archbyte init --force # overwrite existing
|
|
112
118
|
```
|
|
113
119
|
|
|
114
120
|
> **Why this matters:** Without a config, every team member picks their own rules and thresholds. `init` gives your project a single source of truth for architecture governance from day one.
|
|
115
121
|
>
|
|
116
|
-
> *Example:* You join a new monorepo and want to enforce "no direct DB calls from the frontend." Run `archbyte init`, edit the generated `archbyte.yaml` to add that custom rule, and commit it — now every contributor shares the same guardrails.
|
|
122
|
+
> *Example:* You join a new monorepo and want to enforce "no direct DB calls from the frontend." Run `npx archbyte init`, edit the generated `archbyte.yaml` to add that custom rule, and commit it — now every contributor shares the same guardrails.
|
|
117
123
|
|
|
118
124
|
### `archbyte generate`
|
|
119
125
|
|
|
120
126
|
Convert analysis JSON into an architecture diagram.
|
|
121
127
|
|
|
122
128
|
```bash
|
|
123
|
-
archbyte generate
|
|
124
|
-
archbyte generate --input path/to/analysis.json --output path/to/arch.json
|
|
125
|
-
archbyte generate --verbose
|
|
129
|
+
npx archbyte generate
|
|
130
|
+
npx archbyte generate --input path/to/analysis.json --output path/to/arch.json
|
|
131
|
+
npx archbyte generate --verbose
|
|
126
132
|
```
|
|
127
133
|
|
|
128
134
|
Merges with existing diagram to preserve user-adjusted node positions.
|
|
129
135
|
|
|
130
136
|
> **Why this matters:** Raw analysis JSON is data — a positioned architecture diagram is *understanding*. Generate turns a flat list of components and dependencies into a spatial map you can actually reason about.
|
|
131
137
|
>
|
|
132
|
-
> *Example:* After an AI analysis finds 40 components and 120 dependencies, `archbyte generate` lays them out by layer so you instantly see that your "AuthService" sits in the wrong tier. Re-running after code changes merges new nodes in without losing the positions you manually adjusted last sprint.
|
|
138
|
+
> *Example:* After an AI analysis finds 40 components and 120 dependencies, `npx archbyte generate` lays them out by layer so you instantly see that your "AuthService" sits in the wrong tier. Re-running after code changes merges new nodes in without losing the positions you manually adjusted last sprint.
|
|
133
139
|
|
|
134
140
|
### `archbyte serve`
|
|
135
141
|
|
|
136
142
|
Start the HTTP server with the interactive visualization UI.
|
|
137
143
|
|
|
138
144
|
```bash
|
|
139
|
-
archbyte serve # default port 3847
|
|
140
|
-
archbyte serve --port 8080
|
|
141
|
-
archbyte serve --diagram path/to/architecture.json
|
|
145
|
+
npx archbyte serve # default port 3847
|
|
146
|
+
npx archbyte serve --port 8080
|
|
147
|
+
npx archbyte serve --diagram path/to/architecture.json
|
|
142
148
|
```
|
|
143
149
|
|
|
144
150
|
Features: real-time SSE updates, drag-and-drop nodes, environment filtering, flow animation, dependency highlighting, export to PNG/SVG.
|
|
145
151
|
|
|
146
152
|
> **Why this matters:** Architecture diagrams on a wiki go stale the moment they're drawn. A live, interactive diagram that updates in real-time means you're always looking at the truth, not a six-month-old Confluence page.
|
|
147
153
|
>
|
|
148
|
-
> *Example:* During an incident review, run `archbyte serve` and drag the failing service to the center. Click it to highlight all upstream dependencies — now the whole team can see which services are affected and trace the blast radius visually instead of grep-ing through YAML manifests.
|
|
154
|
+
> *Example:* During an incident review, run `npx archbyte serve` and drag the failing service to the center. Click it to highlight all upstream dependencies — now the whole team can see which services are affected and trace the blast radius visually instead of grep-ing through YAML manifests.
|
|
149
155
|
|
|
150
156
|
### `archbyte validate`
|
|
151
157
|
|
|
152
158
|
Run architecture fitness function rules.
|
|
153
159
|
|
|
154
160
|
```bash
|
|
155
|
-
archbyte validate
|
|
156
|
-
archbyte validate --ci # JSON output, exit code 1 on errors
|
|
157
|
-
archbyte validate --watch # re-validate on file changes
|
|
161
|
+
npx archbyte validate
|
|
162
|
+
npx archbyte validate --ci # JSON output, exit code 1 on errors
|
|
163
|
+
npx archbyte validate --watch # re-validate on file changes
|
|
158
164
|
```
|
|
159
165
|
|
|
160
166
|
**Built-in rules:**
|
|
@@ -185,54 +191,54 @@ rules:
|
|
|
185
191
|
|
|
186
192
|
> **Why this matters:** Code review catches syntax and logic bugs, but architectural violations slip through because no human reviewer holds the entire dependency graph in their head. Validate acts as an automated architect that never misses a rule.
|
|
187
193
|
>
|
|
188
|
-
> *Example:* A junior developer adds a direct import from a React component to a Postgres client library. `archbyte validate --ci` in your GitHub Actions pipeline catches the layer bypass (`presentation -> data`) and fails the build *before* the PR is merged — no manual review needed.
|
|
194
|
+
> *Example:* A junior developer adds a direct import from a React component to a Postgres client library. `npx archbyte validate --ci` in your GitHub Actions pipeline catches the layer bypass (`presentation -> data`) and fails the build *before* the PR is merged — no manual review needed.
|
|
189
195
|
|
|
190
196
|
### `archbyte stats`
|
|
191
197
|
|
|
192
198
|
Architecture health dashboard.
|
|
193
199
|
|
|
194
200
|
```bash
|
|
195
|
-
archbyte stats
|
|
196
|
-
archbyte stats --diagram path/to/architecture.json
|
|
201
|
+
npx archbyte stats
|
|
202
|
+
npx archbyte stats --diagram path/to/architecture.json
|
|
197
203
|
```
|
|
198
204
|
|
|
199
205
|
Shows: component counts, layer distribution, connection density, hub detection, orphan detection, layer violations.
|
|
200
206
|
|
|
201
207
|
> **Why this matters:** "How healthy is our architecture?" is usually answered with gut feelings. Stats turns that into numbers you can track over time and discuss objectively in sprint retros.
|
|
202
208
|
>
|
|
203
|
-
> *Example:* You run `archbyte stats` and discover your `ApiGateway` has 14 connections — more than double the threshold. That's a hub risk: if it goes down, 14 services are affected. You bring this to the team meeting with hard data instead of a hunch, and the team agrees to split it into domain-specific gateways.
|
|
209
|
+
> *Example:* You run `npx archbyte stats` and discover your `ApiGateway` has 14 connections — more than double the threshold. That's a hub risk: if it goes down, 14 services are affected. You bring this to the team meeting with hard data instead of a hunch, and the team agrees to split it into domain-specific gateways.
|
|
204
210
|
|
|
205
211
|
### `archbyte export`
|
|
206
212
|
|
|
207
213
|
Export to various formats.
|
|
208
214
|
|
|
209
215
|
```bash
|
|
210
|
-
archbyte export # mermaid to stdout
|
|
211
|
-
archbyte export --format plantuml
|
|
212
|
-
archbyte export --format dot # Graphviz
|
|
213
|
-
archbyte export --format markdown
|
|
214
|
-
archbyte export --format json
|
|
215
|
-
archbyte export --output docs/architecture.mmd
|
|
216
|
+
npx archbyte export # mermaid to stdout
|
|
217
|
+
npx archbyte export --format plantuml
|
|
218
|
+
npx archbyte export --format dot # Graphviz
|
|
219
|
+
npx archbyte export --format markdown
|
|
220
|
+
npx archbyte export --format json
|
|
221
|
+
npx archbyte export --output docs/architecture.mmd
|
|
216
222
|
```
|
|
217
223
|
|
|
218
224
|
> **Why this matters:** Your architecture diagram shouldn't be locked inside one tool. Export lets you embed it in PRs, design docs, ADRs, or any toolchain your team already uses.
|
|
219
225
|
>
|
|
220
|
-
> *Example:* Before each release, you run `archbyte export --format mermaid --output docs/architecture.mmd` and commit it. GitHub renders the Mermaid diagram inline in your repo — anyone browsing the codebase sees an always-current architecture map without installing anything.
|
|
226
|
+
> *Example:* Before each release, you run `npx archbyte export --format mermaid --output docs/architecture.mmd` and commit it. GitHub renders the Mermaid diagram inline in your repo — anyone browsing the codebase sees an always-current architecture map without installing anything.
|
|
221
227
|
|
|
222
228
|
### `archbyte diff`
|
|
223
229
|
|
|
224
230
|
Compare architecture snapshots and detect drift.
|
|
225
231
|
|
|
226
232
|
```bash
|
|
227
|
-
archbyte diff --baseline .archbyte/baseline.json
|
|
228
|
-
archbyte diff --baseline old.json --current new.json
|
|
233
|
+
npx archbyte diff --baseline .archbyte/baseline.json
|
|
234
|
+
npx archbyte diff --baseline old.json --current new.json
|
|
229
235
|
```
|
|
230
236
|
|
|
231
237
|
Reports added/removed components, added/removed connections, density change, new/resolved violations. Exit code 1 on new errors.
|
|
232
238
|
|
|
233
239
|
> **Why this matters:** Architecture erosion happens one commit at a time. By the time someone notices, the codebase has drifted far from its intended design. Diff catches drift early by comparing snapshots and surfacing exactly what changed.
|
|
234
240
|
>
|
|
235
|
-
> *Example:* You save a baseline after your v2.0 release with `cp .archbyte/architecture.json .archbyte/baseline.json`. Two months later, run `archbyte diff --baseline .archbyte/baseline.json` and discover 3 new circular dependencies and a removed service boundary. You can now decide whether to accept the drift or fix it — before it compounds further.
|
|
241
|
+
> *Example:* You save a baseline after your v2.0 release with `cp .archbyte/architecture.json .archbyte/baseline.json`. Two months later, run `npx archbyte diff --baseline .archbyte/baseline.json` and discover 3 new circular dependencies and a removed service boundary. You can now decide whether to accept the drift or fix it — before it compounds further.
|
|
236
242
|
|
|
237
243
|
### `archbyte patrol`
|
|
238
244
|
|
|
@@ -241,11 +247,11 @@ Continuous architecture health monitoring — runs the validation pipeline on a
|
|
|
241
247
|
Inspired by [Gastown's](https://github.com/steveyegge/gastown) patrol loop pattern.
|
|
242
248
|
|
|
243
249
|
```bash
|
|
244
|
-
archbyte patrol # default 5m interval
|
|
245
|
-
archbyte patrol --interval 30s # 30 second cycles
|
|
246
|
-
archbyte patrol --interval 1h # hourly
|
|
247
|
-
archbyte patrol --on-violation json # JSON output for piping
|
|
248
|
-
archbyte patrol --history # view patrol history dashboard
|
|
250
|
+
npx archbyte patrol # default 5m interval
|
|
251
|
+
npx archbyte patrol --interval 30s # 30 second cycles
|
|
252
|
+
npx archbyte patrol --interval 1h # hourly
|
|
253
|
+
npx archbyte patrol --on-violation json # JSON output for piping
|
|
254
|
+
npx archbyte patrol --history # view patrol history dashboard
|
|
249
255
|
```
|
|
250
256
|
|
|
251
257
|
**Options:**
|
|
@@ -263,19 +269,19 @@ The patrol daemon:
|
|
|
263
269
|
|
|
264
270
|
> **Why this matters:** Validate catches violations at a point in time; Patrol catches them *over time*. Running continuously, it detects the moment a violation appears and tells you when violations get resolved — giving you a living health timeline for your architecture.
|
|
265
271
|
>
|
|
266
|
-
> *Example:* You start `archbyte patrol --interval 5m` in a tmux session during a refactoring sprint. Mid-afternoon, it flags a new circular dependency introduced in the latest commit. You fix it immediately instead of discovering it three weeks later in a failing CI pipeline. At the end of the sprint, `archbyte patrol --history` shows the team a sparkline proving architecture health improved from 72% to 95%.
|
|
272
|
+
> *Example:* You start `npx archbyte patrol --interval 5m` in a tmux session during a refactoring sprint. Mid-afternoon, it flags a new circular dependency introduced in the latest commit. You fix it immediately instead of discovering it three weeks later in a failing CI pipeline. At the end of the sprint, `npx archbyte patrol --history` shows the team a sparkline proving architecture health improved from 72% to 95%.
|
|
267
273
|
|
|
268
274
|
### `archbyte workflow`
|
|
269
275
|
|
|
270
276
|
Composable multi-step architecture pipelines with dependency tracking and resume-on-failure. Inspired by Gastown's MEOW (Molecular Expression of Work) system.
|
|
271
277
|
|
|
272
278
|
```bash
|
|
273
|
-
archbyte workflow --list # list available workflows
|
|
274
|
-
archbyte workflow --run full-analysis # run a workflow
|
|
275
|
-
archbyte workflow --show ci-check # show step details
|
|
276
|
-
archbyte workflow --status # show progress bars
|
|
277
|
-
archbyte workflow --create "my-pipeline" # scaffold a custom workflow
|
|
278
|
-
archbyte workflow --reset # clear all state
|
|
279
|
+
npx archbyte workflow --list # list available workflows
|
|
280
|
+
npx archbyte workflow --run full-analysis # run a workflow
|
|
281
|
+
npx archbyte workflow --show ci-check # show step details
|
|
282
|
+
npx archbyte workflow --status # show progress bars
|
|
283
|
+
npx archbyte workflow --create "my-pipeline" # scaffold a custom workflow
|
|
284
|
+
npx archbyte workflow --reset # clear all state
|
|
279
285
|
```
|
|
280
286
|
|
|
281
287
|
**Built-in workflows:**
|
|
@@ -314,7 +320,7 @@ Workflows **resume on failure** — completed steps are skipped when you re-run.
|
|
|
314
320
|
|
|
315
321
|
> **Why this matters:** Running `generate`, then `validate`, then `stats`, then `export` manually is tedious and error-prone. Workflows chain them into a single reproducible pipeline — and if step 3 fails, you re-run and it skips the already-completed steps instead of starting from scratch.
|
|
316
322
|
>
|
|
317
|
-
> *Example:* You add a `ci-check` workflow to your GitHub Actions. On every PR, it runs `archbyte workflow --run ci-check`, which validates architecture rules in CI mode and exits non-zero on violations. No manual steps, no forgotten checks. For bigger releases, `archbyte workflow --run full-analysis` runs the entire generate-validate-stats-export pipeline in one command and produces a Mermaid diagram committed to `docs/`.
|
|
323
|
+
> *Example:* You add a `ci-check` workflow to your GitHub Actions. On every PR, it runs `npx archbyte workflow --run ci-check`, which validates architecture rules in CI mode and exits non-zero on violations. No manual steps, no forgotten checks. For bigger releases, `npx archbyte workflow --run full-analysis` runs the entire generate-validate-stats-export pipeline in one command and produces a Mermaid diagram committed to `docs/`.
|
|
318
324
|
|
|
319
325
|
## Keyboard Shortcuts (UI)
|
|
320
326
|
|
|
@@ -328,8 +334,8 @@ Workflows **resume on failure** — completed steps are skipped when you re-run.
|
|
|
328
334
|
|
|
329
335
|
## Requirements
|
|
330
336
|
|
|
331
|
-
- Node.js >= 18
|
|
332
|
-
- Claude Code (for `/archbyte-analyze`)
|
|
337
|
+
- Node.js >= 18 (for `npx archbyte`)
|
|
338
|
+
- Claude Code (for `/archbyte-analyze` slash commands)
|
|
333
339
|
|
|
334
340
|
## License
|
|
335
341
|
|
package/dist/agents/index.js
CHANGED
|
@@ -53,6 +53,7 @@ export async function loadPremiumAgents() {
|
|
|
53
53
|
import("./premium/migration-planner.js"),
|
|
54
54
|
import("./premium/api-contract-verifier.js"),
|
|
55
55
|
import("./premium/drift-detector.js"),
|
|
56
|
+
import("./premium/infra-agent-auditor.js"),
|
|
56
57
|
]);
|
|
57
58
|
return [
|
|
58
59
|
mods[0].securityAuditor,
|
|
@@ -62,6 +63,7 @@ export async function loadPremiumAgents() {
|
|
|
62
63
|
mods[4].migrationPlanner,
|
|
63
64
|
mods[5].apiContractVerifier,
|
|
64
65
|
mods[6].driftDetector,
|
|
66
|
+
mods[7].infraAgentAuditor,
|
|
65
67
|
];
|
|
66
68
|
}
|
|
67
69
|
catch {
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
// Archbyte Adapter — reads .archbyte/runs/ + session.json + metadata.json
|
|
2
|
+
// Converts archbyte pipeline run data into AgentSession for the Sessions panel
|
|
3
|
+
import { readFile, readdir } from "fs/promises";
|
|
4
|
+
import { existsSync, readFileSync } from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
/** Read a text file if it exists, return null otherwise */
|
|
7
|
+
async function readOptional(filePath) {
|
|
8
|
+
if (!existsSync(filePath))
|
|
9
|
+
return null;
|
|
10
|
+
try {
|
|
11
|
+
return await readFile(filePath, "utf-8");
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
/** Read and parse a JSON file, return null on failure */
|
|
18
|
+
function readJsonSync(filePath) {
|
|
19
|
+
if (!existsSync(filePath))
|
|
20
|
+
return null;
|
|
21
|
+
try {
|
|
22
|
+
return JSON.parse(readFileSync(filePath, "utf-8"));
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Import a .archbyte/ directory into AgentSession(s) */
|
|
29
|
+
export async function importArchbyte(archbyteDir) {
|
|
30
|
+
const runsDir = path.join(archbyteDir, "runs");
|
|
31
|
+
if (!existsSync(runsDir))
|
|
32
|
+
return [];
|
|
33
|
+
// Read run subdirectories
|
|
34
|
+
let entries;
|
|
35
|
+
try {
|
|
36
|
+
const dirEntries = await readdir(runsDir, { withFileTypes: true });
|
|
37
|
+
entries = dirEntries.filter(e => e.isDirectory()).map(e => e.name).sort();
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
if (entries.length === 0)
|
|
43
|
+
return [];
|
|
44
|
+
// Read session.json for session-level metadata
|
|
45
|
+
const session = readJsonSync(path.join(archbyteDir, "session.json"));
|
|
46
|
+
const metadata = readJsonSync(path.join(archbyteDir, "metadata.json"));
|
|
47
|
+
const sessionId = session?.sessionId ?? `archbyte-${path.basename(path.dirname(archbyteDir))}`;
|
|
48
|
+
// Build runs from subdirectories
|
|
49
|
+
const runs = [];
|
|
50
|
+
for (const dirName of entries) {
|
|
51
|
+
const runPath = path.join(runsDir, dirName);
|
|
52
|
+
const meta = readJsonSync(path.join(runPath, "meta.json"));
|
|
53
|
+
if (!meta)
|
|
54
|
+
continue;
|
|
55
|
+
const prompt = await readOptional(path.join(runPath, "prompt.md"));
|
|
56
|
+
const output = await readOptional(path.join(runPath, "output.md"));
|
|
57
|
+
runs.push({
|
|
58
|
+
...meta,
|
|
59
|
+
artifacts: {
|
|
60
|
+
...(prompt ? { prompt } : {}),
|
|
61
|
+
...(output ? { output } : {}),
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if (runs.length === 0)
|
|
66
|
+
return [];
|
|
67
|
+
// Derive session summary
|
|
68
|
+
const totalElapsed = session?.totalElapsedSeconds ?? runs.reduce((s, r) => s + (r.elapsedSeconds ?? 0), 0);
|
|
69
|
+
const totalTokens = session?.totalTokens ?? {
|
|
70
|
+
input: runs.reduce((s, r) => s + (r.tokens?.input ?? 0), 0),
|
|
71
|
+
output: runs.reduce((s, r) => s + (r.tokens?.output ?? 0), 0),
|
|
72
|
+
};
|
|
73
|
+
const phases = [...new Set(runs.map(r => r.phase))];
|
|
74
|
+
const models = [...new Set(runs.map(r => r.model))];
|
|
75
|
+
const successfulRuns = runs.filter(r => r.status === "success").length;
|
|
76
|
+
const failedRuns = runs.filter(r => r.status === "error").length;
|
|
77
|
+
const skippedRuns = runs.filter(r => r.status === "skipped").length;
|
|
78
|
+
const firstRun = runs[0];
|
|
79
|
+
const lastRun = runs[runs.length - 1];
|
|
80
|
+
const startedAt = session?.startedAt ?? firstRun.startedAt;
|
|
81
|
+
const completedAt = session?.completedAt ?? lastRun.completedAt ?? lastRun.startedAt;
|
|
82
|
+
const status = failedRuns > 0 ? "partial" : "success";
|
|
83
|
+
return [{
|
|
84
|
+
sessionId,
|
|
85
|
+
startedAt,
|
|
86
|
+
completedAt,
|
|
87
|
+
status: session?.status ?? status,
|
|
88
|
+
source: "archbyte",
|
|
89
|
+
projectMeta: {
|
|
90
|
+
mode: session?.mode ?? metadata?.mode ?? "pipeline",
|
|
91
|
+
},
|
|
92
|
+
summary: {
|
|
93
|
+
totalRuns: runs.length,
|
|
94
|
+
successfulRuns,
|
|
95
|
+
failedRuns,
|
|
96
|
+
skippedRuns,
|
|
97
|
+
totalElapsedSeconds: totalElapsed,
|
|
98
|
+
totalTokens,
|
|
99
|
+
phases,
|
|
100
|
+
models,
|
|
101
|
+
},
|
|
102
|
+
runs,
|
|
103
|
+
}];
|
|
104
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AgentSession } from "../types.js";
|
|
2
|
+
/** Invalidate cached index entries. Call with a path to invalidate one file, or no args to clear all. */
|
|
3
|
+
export declare function invalidateIndexCache(filePath?: string): void;
|
|
4
|
+
export declare function getClaudeProjectsDir(): string;
|
|
5
|
+
export declare function encodeProjectPath(cwd: string): string;
|
|
6
|
+
export declare function getProjectTranscriptDir(cwd: string): string | null;
|
|
7
|
+
export type SessionCategory = "implementation" | "exploration" | "conversation" | "pipeline";
|
|
8
|
+
export interface SessionIndexEntry {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
startedAt: string;
|
|
11
|
+
completedAt?: string;
|
|
12
|
+
status: "success" | "partial";
|
|
13
|
+
runCount: number;
|
|
14
|
+
phases: string[];
|
|
15
|
+
source: string;
|
|
16
|
+
model?: string;
|
|
17
|
+
version?: string;
|
|
18
|
+
gitBranch?: string;
|
|
19
|
+
subagentCount?: number;
|
|
20
|
+
category?: SessionCategory;
|
|
21
|
+
label?: string;
|
|
22
|
+
touchedDirs?: string[];
|
|
23
|
+
eventCount?: number;
|
|
24
|
+
dirMetrics?: Record<string, {
|
|
25
|
+
reads: number;
|
|
26
|
+
writes: number;
|
|
27
|
+
}>;
|
|
28
|
+
estimatedCost?: number;
|
|
29
|
+
}
|
|
30
|
+
export declare function scanTranscriptIndex(projectDir: string): Promise<SessionIndexEntry[]>;
|
|
31
|
+
export declare function importClaudeTranscript(projectDir: string, sessionId: string): Promise<AgentSession | null>;
|