198fbb7980
- 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
77 lines
3.3 KiB
JavaScript
77 lines
3.3 KiB
JavaScript
/**
|
|
* @file Tests server/compat-sqlite.js, the node:sqlite stand-in a plugin
|
|
* install runs on (better-sqlite3 has no native build there): every
|
|
* better-sqlite3 API the server uses — `function`, `pluck`, `readonly` /
|
|
* `fileMustExist` — and a real `server/db.js` boot in a child process with
|
|
* better-sqlite3 blocked, since the rest of the suite only ever runs on
|
|
* better-sqlite3 and a missing method there crashes the dashboard at start.
|
|
* @author Nguyễn Ngọc Trí Vĩ <vinnt@smartgift.vn>
|
|
*/
|
|
|
|
const { describe, it, after } = require("node:test");
|
|
const assert = require("node:assert/strict");
|
|
const fs = require("fs");
|
|
const os = require("os");
|
|
const path = require("path");
|
|
const { spawnSync } = require("child_process");
|
|
const Database = require("../compat-sqlite");
|
|
|
|
const TMP = fs.mkdtempSync(path.join(os.tmpdir(), "agenthub-compat-"));
|
|
after(() => fs.rmSync(TMP, { recursive: true, force: true }));
|
|
|
|
describe("compat-sqlite", () => {
|
|
it("registers a SQL function like better-sqlite3's db.function", () => {
|
|
const db = new Database(":memory:");
|
|
db.function("twice", { deterministic: true }, (s) => `${s}${s}`);
|
|
db.function("one", () => 1);
|
|
assert.equal(db.prepare("SELECT twice('ab') AS v, one() AS o").get().v, "abab");
|
|
db.close();
|
|
});
|
|
|
|
it("pluck() returns the first column from get, all and iterate", () => {
|
|
const db = new Database(":memory:");
|
|
db.exec("CREATE TABLE t (a, b); INSERT INTO t VALUES (1, 'x'), (2, 'y');");
|
|
const s = db.prepare("SELECT a, b FROM t ORDER BY a").pluck();
|
|
assert.equal(s.get(), 1);
|
|
assert.deepEqual(s.all(), [1, 2]);
|
|
assert.deepEqual([...s.iterate()], [1, 2]);
|
|
assert.equal(db.prepare("SELECT a FROM t WHERE a = 9").pluck().get(), undefined);
|
|
db.close();
|
|
});
|
|
|
|
it("boots server/db.js and its trim/sweep paths with better-sqlite3 unavailable", () => {
|
|
const block = path.join(TMP, "no-bs3.js");
|
|
fs.writeFileSync(
|
|
block,
|
|
`const M = require("module"); const load = M._load;
|
|
M._load = function (r, ...a) { if (r === "better-sqlite3") throw new Error("blocked"); return load.call(this, r, ...a); };`
|
|
);
|
|
const script = `
|
|
const { db, Database } = require("./server/db");
|
|
if (Database !== require("./server/compat-sqlite")) throw new Error("not on compat");
|
|
const big = JSON.stringify({ tool_input: { content: "x".repeat(20000) } });
|
|
db.prepare("INSERT INTO sessions (id) VALUES ('s1')").run();
|
|
db.prepare("INSERT INTO events (session_id, event_type, tool_name, data) VALUES ('s1', 'PreToolUse', 'Write', ?)").run(big);
|
|
require("./server/lib/event-payload").sweepEventPayloads(db).then((r) => {
|
|
const len = db.prepare("SELECT length(trim_event_data(?)) AS n").get(big).n;
|
|
console.log(JSON.stringify({ swept: r.rows >= 0, trimmedShorter: len < big.length }));
|
|
process.exit(0);
|
|
});`;
|
|
const r = spawnSync(process.execPath, ["-r", block, "-e", script], {
|
|
cwd: path.join(__dirname, "..", ".."),
|
|
env: {
|
|
...process.env,
|
|
DASHBOARD_DB_PATH: path.join(TMP, "boot.db"),
|
|
AGENTHUB_PRICING_SYNC: "0",
|
|
},
|
|
encoding: "utf8",
|
|
timeout: 60_000,
|
|
});
|
|
assert.equal(r.status, 0, r.stderr);
|
|
assert.deepEqual(JSON.parse(r.stdout.trim().split("\n").pop()), {
|
|
swept: true,
|
|
trimmedShorter: true,
|
|
});
|
|
});
|
|
});
|