feat(trace-workbench): reveal the session's jsonl in the file manager
POST /api/sessions/:id/reveal resolves the file server-side (execFile, argv array — no shell) and opens the platform file manager; the header button shows the full path on hover.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env node
|
||||
const { execFile } = require('node:child_process')
|
||||
const fs = require('node:fs')
|
||||
const http = require('node:http')
|
||||
const path = require('node:path')
|
||||
@@ -167,6 +168,15 @@ function summarize(file) {
|
||||
}
|
||||
}
|
||||
|
||||
// Reveal a file in the OS file manager. The path always comes from
|
||||
// findSessionFile (never from the request), and execFile takes an argv array —
|
||||
// no shell, no injection surface.
|
||||
function revealInFileManager(file) {
|
||||
if (process.platform === 'darwin') execFile('open', ['-R', file], () => {})
|
||||
else if (process.platform === 'win32') execFile('explorer', [`/select,${file}`], () => {})
|
||||
else execFile('xdg-open', [path.dirname(file)], () => {})
|
||||
}
|
||||
|
||||
function findSessionFile(id) {
|
||||
const files = walkJsonl(SESSIONS_ROOT)
|
||||
const byName = files.find(file => path.basename(file, '.jsonl') === id)
|
||||
@@ -433,6 +443,13 @@ const server = http.createServer(async (req, res) => {
|
||||
if (req.method === 'GET') return send(res, 200, { feedback: readFeedback(id) })
|
||||
if (req.method === 'POST') return send(res, 200, { feedback: appendFeedback(id, await readJsonBody(req)) })
|
||||
}
|
||||
if (req.method === 'POST' && suffix.endsWith('/reveal')) {
|
||||
const id = suffix.slice(0, -'/reveal'.length)
|
||||
const file = findSessionFile(id)
|
||||
if (!file) return send(res, 404, { error: `session not found: ${id}` })
|
||||
revealInFileManager(file)
|
||||
return send(res, 200, { ok: true, path: file })
|
||||
}
|
||||
if (req.method === 'POST' && suffix.endsWith('/messages')) {
|
||||
return send(res, 501, {
|
||||
error: 'Live interaction is not connected yet. This prototype is reading persisted JSONL replay data.',
|
||||
|
||||
Reference in New Issue
Block a user