@hncode/hncode 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +38 -38
- package/src/config.js +10 -3
- package/src/session-hub.js +37 -0
- package/src/settings-schema.js +2 -0
- package/src/tools/edit.js +88 -161
- package/src/tools/fetch-url.js +118 -5
- package/src/tools/read.js +11 -1
- package/src/tools/web-search.js +139 -88
- package/src/tui.js +330 -142
- package/src/web.js +47 -1
package/src/web.js
CHANGED
|
@@ -270,7 +270,53 @@ attachWebSocket(server, {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
// --- API ------------------------------------------------------------------
|
|
273
|
-
if (p === '/api/state')
|
|
273
|
+
if (p === '/api/state') {
|
|
274
|
+
// WHAT TO SEND, decided by the caller.
|
|
275
|
+
//
|
|
276
|
+
// `/api/state` used to answer with one fixed shape: every row, every tool result, the whole
|
|
277
|
+
// transcript. That is what a browser wants and the wrong answer for a script asking "what did the
|
|
278
|
+
// last turn do", which pays for the entire session to read the last few rows.
|
|
279
|
+
//
|
|
280
|
+
// ?detail=full every row, tool results included (the default: unchanged behaviour)
|
|
281
|
+
// ?detail=summary drop tool RESULTS, keep the "Used Bash (cmd)" rows and the assistant text
|
|
282
|
+
// ?detail=minimal assistant and user text only — no tool rows at all
|
|
283
|
+
// ?turn=last only the most recent turn (a turn starts at a user message)
|
|
284
|
+
// ?turn=<n> only turn n, counting from 1
|
|
285
|
+
// ?limit=<n> at most n rows, taken from the end
|
|
286
|
+
//
|
|
287
|
+
// All of them compose, so `/api/state?detail=summary&turn=last` is one request for "what just
|
|
288
|
+
// happened, and with which tools" without the payload of the results themselves.
|
|
289
|
+
const detail = String(url.searchParams.get('detail') || 'full');
|
|
290
|
+
const turn = url.searchParams.get('turn');
|
|
291
|
+
const limit = Number(url.searchParams.get('limit'));
|
|
292
|
+
const snap = hub.snapshot();
|
|
293
|
+
let rows = snap.rows;
|
|
294
|
+
// A turn begins at a user message; splitting on those is what makes "the last turn" mean the same
|
|
295
|
+
// thing here as it does in the transcript.
|
|
296
|
+
if (turn === 'last' || (turn && /^\d+$/.test(turn))) {
|
|
297
|
+
const starts = [];
|
|
298
|
+
rows.forEach((r, idx) => { if (r.role === 'user') starts.push(idx); });
|
|
299
|
+
const which = turn === 'last' ? starts.length - 1 : Number(turn) - 1;
|
|
300
|
+
if (which >= 0 && which < starts.length) {
|
|
301
|
+
const from = starts[which];
|
|
302
|
+
const to = which + 1 < starts.length ? starts[which + 1] : rows.length;
|
|
303
|
+
rows = rows.slice(from, to);
|
|
304
|
+
} else {
|
|
305
|
+
rows = []; // no such turn: an empty list is the honest answer
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
if (detail === 'summary' || detail === 'minimal') {
|
|
309
|
+
// `summary` keeps the tool ROWS but clears their output: the caller wants to know which tools
|
|
310
|
+
// ran, not what they printed. `minimal` drops the rows entirely.
|
|
311
|
+
rows = rows.filter((r) => r.role !== 'tool' || detail === 'summary');
|
|
312
|
+
if (detail === 'summary') {
|
|
313
|
+
rows = rows.map((r) => (r.role === 'tool' ? { ...r, text: '', liveOutput: '', diff: undefined } : r));
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
// Any row carrying a `card` is an interactive prompt; those are never trimmed by `minimal`.
|
|
317
|
+
if (Number.isFinite(limit) && limit > 0) rows = rows.slice(-Math.floor(limit));
|
|
318
|
+
return json(res, 200, { ok: true, ...snap, rows, hidden: snap.totalRows - rows.length, detail, turn: turn || null });
|
|
319
|
+
}
|
|
274
320
|
|
|
275
321
|
// The session list for the left rail. `listSavedSessions` already powers the
|
|
276
322
|
// daemon's landing page, so a session page shows the same names in the same
|