llm-deep-trace 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/LICENSE +21 -0
- package/README.md +159 -0
- package/bin/llm-deep-trace.js +24 -0
- package/next.config.ts +8 -0
- package/package.json +56 -0
- package/postcss.config.mjs +5 -0
- package/public/banner-v2.png +0 -0
- package/public/file.svg +1 -0
- package/public/globe.svg +1 -0
- package/public/logo.png +0 -0
- package/public/next.svg +1 -0
- package/public/vercel.svg +1 -0
- package/public/window.svg +1 -0
- package/src/app/api/agent-config/route.ts +31 -0
- package/src/app/api/all-sessions/route.ts +9 -0
- package/src/app/api/analytics/route.ts +379 -0
- package/src/app/api/detect-agents/route.ts +170 -0
- package/src/app/api/image/route.ts +73 -0
- package/src/app/api/search/route.ts +28 -0
- package/src/app/api/session-by-key/route.ts +21 -0
- package/src/app/api/sessions/[sessionId]/messages/route.ts +46 -0
- package/src/app/api/sse/route.ts +86 -0
- package/src/app/favicon.ico +0 -0
- package/src/app/globals.css +3518 -0
- package/src/app/icon.svg +4 -0
- package/src/app/layout.tsx +20 -0
- package/src/app/page.tsx +5 -0
- package/src/components/AnalyticsDashboard.tsx +393 -0
- package/src/components/App.tsx +243 -0
- package/src/components/CopyButton.tsx +42 -0
- package/src/components/Logo.tsx +20 -0
- package/src/components/MainPanel.tsx +1128 -0
- package/src/components/MessageRenderer.tsx +983 -0
- package/src/components/SessionTree.tsx +505 -0
- package/src/components/SettingsPanel.tsx +160 -0
- package/src/components/SetupView.tsx +206 -0
- package/src/components/Sidebar.tsx +714 -0
- package/src/components/ThemeToggle.tsx +54 -0
- package/src/lib/client-utils.ts +360 -0
- package/src/lib/normalizers.ts +371 -0
- package/src/lib/sessions.ts +1223 -0
- package/src/lib/store.ts +518 -0
- package/src/lib/types.ts +112 -0
- package/src/lib/useSSE.ts +81 -0
- package/tsconfig.json +34 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 llm-deep-trace contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="public/banner-v2.png" width="900" alt="llm-deep-trace" />
|
|
3
|
+
<br/><br/>
|
|
4
|
+
<p>Browse, search, and analyze every conversation your agents have ever had.<br/>All local. No accounts. No cloud.</p>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What it is
|
|
10
|
+
|
|
11
|
+
You use coding agents. They leave behind session logs. Those logs are gold — decisions made, code written, reasoning traced, subagents spawned. But they're just JSONL files buried in `~/.claude/` or `~/.kimi/`.
|
|
12
|
+
|
|
13
|
+
llm-deep-trace turns those files into a proper interface: threaded conversations, subagent trees, a conversation map, analytics, live tail, and full-text search across everything.
|
|
14
|
+
|
|
15
|
+
It runs entirely on your machine. It reads your local files. That's it.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Supported agents
|
|
20
|
+
|
|
21
|
+
| Agent | Sessions | Subagents | Notes |
|
|
22
|
+
|---|---|---|---|
|
|
23
|
+
| **Claude Code** (Anthropic) | ✓ | ✓ | Full support incl. agent teams |
|
|
24
|
+
| **Codex** | ✓ | — | |
|
|
25
|
+
| **Kimi** | ✓ | — | Think-block rendering |
|
|
26
|
+
| **Gemini CLI** (Google) | ✓ | — | |
|
|
27
|
+
| **OpenClaw** | ✓ | ✓ | |
|
|
28
|
+
| **Cursor** | ✓ | — | Partial — some metadata missing |
|
|
29
|
+
| **Aider** | ✓ | — | Chat history format |
|
|
30
|
+
| **Continue.dev** | ✓ | — | |
|
|
31
|
+
| **GitHub Copilot** | ✓ | — | |
|
|
32
|
+
| **Factory Droid** | ✓ | — | |
|
|
33
|
+
| **OpenCode** | ✓ | — | |
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Quick start
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
git clone https://github.com/userFRM/llm-deep-trace
|
|
41
|
+
cd llm-deep-trace
|
|
42
|
+
npm install
|
|
43
|
+
npm run dev
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Open [http://localhost:3000](http://localhost:3000). No config needed — it finds your sessions automatically.
|
|
47
|
+
|
|
48
|
+
**Requirements:** Node.js 18+
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
**Session browser**
|
|
55
|
+
- All providers in one sidebar, grouped and searchable
|
|
56
|
+
- Parent sessions show subagent count; click to expand the tree
|
|
57
|
+
- Expand all / collapse all, archive sessions you don't need
|
|
58
|
+
|
|
59
|
+
**Conversation view**
|
|
60
|
+
- User messages as bubbles, assistant responses as cards
|
|
61
|
+
- Tool call blocks collapsed by default, color-coded by type (bash, edit, web, browser, message, spawn)
|
|
62
|
+
- Thinking blocks (Claude extended thinking, Kimi reasoning) as expandable cards
|
|
63
|
+
- Inline image thumbnails with click-to-lightbox
|
|
64
|
+
- Ctrl+F find with match counter and highlights
|
|
65
|
+
- Skip preamble toggle — jump straight to the actual work
|
|
66
|
+
|
|
67
|
+
**Subagent tree + conversation map**
|
|
68
|
+
- React Flow visualization of the full session graph
|
|
69
|
+
- Click any node to navigate to that session
|
|
70
|
+
- Reset view, zoom capped at 75%, padding scales with graph size
|
|
71
|
+
|
|
72
|
+
**Live tail**
|
|
73
|
+
- Follow an active session in real time (3s poll)
|
|
74
|
+
- Green pulsing indicator while tailing
|
|
75
|
+
|
|
76
|
+
**Analytics**
|
|
77
|
+
- Sessions per day, stacked by provider
|
|
78
|
+
- Provider breakdown, top tools used, token totals
|
|
79
|
+
- Session length distribution
|
|
80
|
+
|
|
81
|
+
**Search**
|
|
82
|
+
- Full-text search across all sessions and all providers
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Running remotely
|
|
87
|
+
|
|
88
|
+
llm-deep-trace reads files from the machine it runs on. If your agent sessions live on a remote server (VPS, home lab, cloud box), you have a few options:
|
|
89
|
+
|
|
90
|
+
**SSH tunnel** — forward the port to your local machine:
|
|
91
|
+
```bash
|
|
92
|
+
ssh -L 3000:localhost:3000 user@your-server
|
|
93
|
+
# then open http://localhost:3000 locally
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Tailscale** — start the server bound to your Tailscale IP:
|
|
97
|
+
```bash
|
|
98
|
+
npx next start --hostname <tailscale-ip> --port 3000
|
|
99
|
+
# accessible at http://<tailscale-ip>:3000 from any device on your Tailscale network
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**VPS / cloud** — same as SSH tunnel, or bind to a private network interface. Do not expose port 3000 to the public internet — there's no auth.
|
|
103
|
+
|
|
104
|
+
In all cases: the app runs on the machine where your `~/.claude/`, `~/.kimi/`, etc. directories live.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## How to ship it (for contributors)
|
|
109
|
+
|
|
110
|
+
Right now: clone and run locally. That's the intended workflow for a local devtool.
|
|
111
|
+
|
|
112
|
+
Planned:
|
|
113
|
+
- `npm install -g llm-deep-trace` + `llm-deep-trace` CLI command
|
|
114
|
+
- Homebrew tap for Mac users who prefer it
|
|
115
|
+
- Docker one-liner for the server crowd
|
|
116
|
+
|
|
117
|
+
PRs welcome on any of these.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Limitations
|
|
122
|
+
|
|
123
|
+
Being straight with you:
|
|
124
|
+
|
|
125
|
+
- **Read-only.** Browse and analyze — you can't resume or fork sessions from here yet. jazzyalex/agent-sessions does this for Codex and Claude Code.
|
|
126
|
+
- **Local files only.** Reads `~/.claude/`, `~/.kimi/`, etc. on the machine it runs on. Remote sessions not supported.
|
|
127
|
+
- **Cursor / Aider / Continue** support is partial. Session formats vary and some metadata is missing.
|
|
128
|
+
- **No mobile UI.** Built for desktop browsers.
|
|
129
|
+
- **Requires Node.js 18+.** Not a zero-dep install.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## vs alternatives
|
|
134
|
+
|
|
135
|
+
[**jazzyalex/agent-sessions**](https://github.com/jazzyalex/agent-sessions) — the closest thing. Native macOS Swift app (macOS 14+), v2.11.2, actively maintained. Supports 7 agents: Codex, Claude Code, Gemini, Copilot, Factory Droid, OpenCode, OpenClaw. Has unified search, analytics, rate limits tracker, image browser, Homebrew install, and — notably — **session resume** (reopen a session directly in your terminal). If you're on a Mac and want a native app, it's worth looking at.
|
|
136
|
+
|
|
137
|
+
Where llm-deep-trace is different:
|
|
138
|
+
- **Cross-platform** — runs on Mac, Linux, Windows; anything with Node.js. Not macOS-only.
|
|
139
|
+
- **More agents** — 11 vs 7 (adds Kimi, Aider, Continue.dev, Cursor)
|
|
140
|
+
- **Subagent tree** — React Flow visualization of parent → child agent relationships
|
|
141
|
+
- **Conversation map** — full session graph, click-to-navigate
|
|
142
|
+
- **Web-based** — no install, no signing, no notarization; just `npm run dev`
|
|
143
|
+
|
|
144
|
+
What they have that we don't (yet):
|
|
145
|
+
- Session resume (reopen past sessions in the terminal)
|
|
146
|
+
- Real-time rate limits tracker
|
|
147
|
+
- Native performance + Homebrew cask + auto-updates
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Tech stack
|
|
152
|
+
|
|
153
|
+
Next.js 16 · React 19 · TypeScript · React Flow · Zustand · highlight.js · Marked
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## License
|
|
158
|
+
|
|
159
|
+
MIT
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
const { execSync, spawn } = require("child_process");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fs = require("fs");
|
|
6
|
+
|
|
7
|
+
const pkgDir = path.join(__dirname, "..");
|
|
8
|
+
const nextDir = path.join(pkgDir, ".next");
|
|
9
|
+
const port = process.env.PORT || "8340";
|
|
10
|
+
const host = process.env.HOST || "0.0.0.0";
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(nextDir)) {
|
|
13
|
+
console.log("llm-deep-trace: first run — building (this takes ~30s)...");
|
|
14
|
+
execSync("npx next build", { cwd: pkgDir, stdio: "inherit" });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const child = spawn(
|
|
18
|
+
"npx",
|
|
19
|
+
["next", "start", "--hostname", host, "--port", port],
|
|
20
|
+
{ cwd: pkgDir, stdio: "inherit" }
|
|
21
|
+
);
|
|
22
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
23
|
+
process.on("SIGINT", () => child.kill("SIGINT"));
|
|
24
|
+
process.on("SIGTERM", () => child.kill("SIGTERM"));
|
package/next.config.ts
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "llm-deep-trace",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The session browser for coding agents — Claude Code, Codex, Kimi, Gemini CLI, OpenClaw, Cursor, Aider, and more.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"claude-code",
|
|
7
|
+
"codex",
|
|
8
|
+
"kimi",
|
|
9
|
+
"gemini",
|
|
10
|
+
"ai-agents",
|
|
11
|
+
"llm",
|
|
12
|
+
"session-browser",
|
|
13
|
+
"devtools"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/userFRM/llm-deep-trace",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/userFRM/llm-deep-trace"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "next dev",
|
|
23
|
+
"build": "next build",
|
|
24
|
+
"start": "next start",
|
|
25
|
+
"lint": "eslint"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@xyflow/react": "^12.10.1",
|
|
29
|
+
"highlight.js": "^11.11.1",
|
|
30
|
+
"marked": "^17.0.3",
|
|
31
|
+
"next": "16.1.6",
|
|
32
|
+
"react": "19.2.3",
|
|
33
|
+
"react-dom": "19.2.3",
|
|
34
|
+
"zustand": "^5.0.11"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/node": "^20",
|
|
38
|
+
"@types/react": "^19",
|
|
39
|
+
"@types/react-dom": "^19",
|
|
40
|
+
"eslint": "^9",
|
|
41
|
+
"eslint-config-next": "16.1.6",
|
|
42
|
+
"typescript": "^5"
|
|
43
|
+
},
|
|
44
|
+
"bin": {
|
|
45
|
+
"llm-deep-trace": "bin/llm-deep-trace.js"
|
|
46
|
+
},
|
|
47
|
+
"files": [
|
|
48
|
+
"bin/",
|
|
49
|
+
"src/",
|
|
50
|
+
"public/",
|
|
51
|
+
"next.config.ts",
|
|
52
|
+
"tsconfig.json",
|
|
53
|
+
"postcss.config.mjs",
|
|
54
|
+
"tailwind.config.ts"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
Binary file
|
package/public/file.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.5 13.5V5.41a1 1 0 0 0-.3-.7L9.8.29A1 1 0 0 0 9.08 0H1.5v13.5A2.5 2.5 0 0 0 4 16h8a2.5 2.5 0 0 0 2.5-2.5m-1.5 0v-7H8v-5H3v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1M9.5 5V2.12L12.38 5zM5.13 5h-.62v1.25h2.12V5zm-.62 3h7.12v1.25H4.5zm.62 3h-.62v1.25h7.12V11z" clip-rule="evenodd" fill="#666" fill-rule="evenodd"/></svg>
|
package/public/globe.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><g clip-path="url(#a)"><path fill-rule="evenodd" clip-rule="evenodd" d="M10.27 14.1a6.5 6.5 0 0 0 3.67-3.45q-1.24.21-2.7.34-.31 1.83-.97 3.1M8 16A8 8 0 1 0 8 0a8 8 0 0 0 0 16m.48-1.52a7 7 0 0 1-.96 0H7.5a4 4 0 0 1-.84-1.32q-.38-.89-.63-2.08a40 40 0 0 0 3.92 0q-.25 1.2-.63 2.08a4 4 0 0 1-.84 1.31zm2.94-4.76q1.66-.15 2.95-.43a7 7 0 0 0 0-2.58q-1.3-.27-2.95-.43a18 18 0 0 1 0 3.44m-1.27-3.54a17 17 0 0 1 0 3.64 39 39 0 0 1-4.3 0 17 17 0 0 1 0-3.64 39 39 0 0 1 4.3 0m1.1-1.17q1.45.13 2.69.34a6.5 6.5 0 0 0-3.67-3.44q.65 1.26.98 3.1M8.48 1.5l.01.02q.41.37.84 1.31.38.89.63 2.08a40 40 0 0 0-3.92 0q.25-1.2.63-2.08a4 4 0 0 1 .85-1.32 7 7 0 0 1 .96 0m-2.75.4a6.5 6.5 0 0 0-3.67 3.44 29 29 0 0 1 2.7-.34q.31-1.83.97-3.1M4.58 6.28q-1.66.16-2.95.43a7 7 0 0 0 0 2.58q1.3.27 2.95.43a18 18 0 0 1 0-3.44m.17 4.71q-1.45-.12-2.69-.34a6.5 6.5 0 0 0 3.67 3.44q-.65-1.27-.98-3.1" fill="#666"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h16v16H0z"/></clipPath></defs></svg>
|
package/public/logo.png
ADDED
|
Binary file
|
package/public/next.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1155 1000"><path d="m577.3 0 577.4 1000H0z" fill="#fff"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="none" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.5h13v10a1 1 0 0 1-1 1h-11a1 1 0 0 1-1-1zM0 1h16v11.5a2.5 2.5 0 0 1-2.5 2.5h-11A2.5 2.5 0 0 1 0 12.5zm3.75 4.5a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5M7 4.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0m1.75.75a.75.75 0 1 0 0-1.5.75.75 0 0 0 0 1.5" fill="#666"/></svg>
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { NextResponse, NextRequest } from "next/server";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
|
|
5
|
+
const HOME = process.env.HOME || "/root";
|
|
6
|
+
const CONFIG_PATH = path.join(HOME, ".llm-deep-trace.json");
|
|
7
|
+
|
|
8
|
+
export async function GET() {
|
|
9
|
+
try {
|
|
10
|
+
if (fs.existsSync(CONFIG_PATH)) {
|
|
11
|
+
return NextResponse.json(JSON.parse(fs.readFileSync(CONFIG_PATH, "utf8")));
|
|
12
|
+
}
|
|
13
|
+
} catch { /* ignore */ }
|
|
14
|
+
return NextResponse.json({});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function POST(req: NextRequest) {
|
|
18
|
+
try {
|
|
19
|
+
const body = await req.json();
|
|
20
|
+
// body: { [agentId]: { binaryPath?: string; sessionsDir?: string } }
|
|
21
|
+
let existing: Record<string, unknown> = {};
|
|
22
|
+
try {
|
|
23
|
+
if (fs.existsSync(CONFIG_PATH)) existing = JSON.parse(fs.readFileSync(CONFIG_PATH, "utf8"));
|
|
24
|
+
} catch { /* ignore */ }
|
|
25
|
+
const merged = { ...existing, ...body };
|
|
26
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(merged, null, 2), "utf8");
|
|
27
|
+
return NextResponse.json({ ok: true });
|
|
28
|
+
} catch (e) {
|
|
29
|
+
return NextResponse.json({ error: String(e) }, { status: 500 });
|
|
30
|
+
}
|
|
31
|
+
}
|