fix: event-loop freezes, plugin-install boot crash, tmux attach/scrollbar, Codex transcripts

- GET /api/workflows: one LEAD() window pass in a read worker (read-pool.js,
  workflow-stats.js); idx_events_session restored, idx_events_tool added
- compat-sqlite gains function/pluck/readonly so a plugin install without a
  better-sqlite3 build boots again; antigravity-usage uses db.js's Database
- install-hooks adds no checkout hooks while the agenthub plugin is enabled
  (events were doubled)
- terminal attach runs the live tmux server's own binary; the pane scrollbar
  gets a visible 2-column style, and claude panes start with
  CLAUDE_CODE_DISABLE_ALTERNATE_SCREEN=1 so tmux keeps history to scroll
- Codex sessions' conversation in GET /api/sessions/:id/transcript
- Codex/Antigravity sessions claimed by their workspace without hooks
- UI-audit follow-ups, docs and OpenAPI
This commit is contained in:
2026-10-05 17:01:05 +07:00
parent 442f133930
commit 198fbb7980
78 changed files with 2716 additions and 873 deletions
+8 -2
View File
@@ -39,8 +39,10 @@
const fs = require("node:fs");
const path = require("node:path");
const Database = require("better-sqlite3");
const { db, stmts } = require("../db");
// The driver db.js chose: better-sqlite3 has no build in a plugin install
// (installed without scripts), and only db.js falls back to node:sqlite.
const { db, stmts, Database } = require("../db");
const { claimToolSessions } = require("./dashboard-runs");
const { getAgyCliDir } = require("./antigravity-home");
const pricingSync = require("./pricing-sync");
@@ -56,6 +58,9 @@ const NOT_AGYS = /SQLITE_NOTADB|SQLITE_CORRUPT|no such table/;
* a Buffer. Throws on a malformed buffer.
*/
function pbFields(buf) {
// node:sqlite hands a BLOB over as a plain Uint8Array, whose toString()
// ignores its encoding — model names and file URIs would decode as "1,2,3".
if (!Buffer.isBuffer(buf)) buf = Buffer.from(buf.buffer, buf.byteOffset, buf.byteLength);
const out = [];
let i = 0;
const varint = () => {
@@ -359,6 +364,7 @@ function writeSession(f, conv, now) {
lastWrite,
JSON.stringify({ source: "antigravity-conversation" })
);
claimToolSessions(id); // its workspace, before the broadcast
// Every usage row of an Antigravity session is this module's: rewritten whole.
clearUsage.run(id);
for (const [m, t] of Object.entries(conv.usage)) {