xtrm-tools 0.5.20 → 0.5.22
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/cli/dist/index.cjs +202 -9
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/config/hooks.json +0 -3
- package/hooks/beads-claim-sync.mjs +39 -0
- package/hooks/beads-commit-gate.mjs +26 -1
- package/hooks/beads-edit-gate.mjs +40 -6
- package/hooks/beads-memory-gate.mjs +21 -1
- package/hooks/beads-stop-gate.mjs +22 -1
- package/hooks/hooks.json +0 -4
- package/hooks/quality-check.cjs +53 -53
- package/hooks/quality-check.py +36 -36
- package/hooks/statusline.mjs +2 -1
- package/hooks/xtrm-logger.mjs +123 -0
- package/package.json +1 -1
- package/skills/sync-docs/SKILL.md +24 -1
- package/skills/sync-docs/scripts/drift_detector.py +259 -23
- package/hooks/serena-workflow-reminder.py +0 -74
package/cli/dist/index.cjs
CHANGED
|
@@ -30319,10 +30319,10 @@ var require_stringify = __commonJS({
|
|
|
30319
30319
|
replacer = null;
|
|
30320
30320
|
indent2 = EMPTY;
|
|
30321
30321
|
};
|
|
30322
|
-
var
|
|
30322
|
+
var join6 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + LF + gap : two ? two.trimRight() + LF + gap : EMPTY;
|
|
30323
30323
|
var join_content = (inside, value, gap) => {
|
|
30324
30324
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent2, true);
|
|
30325
|
-
return
|
|
30325
|
+
return join6(comment, inside, gap);
|
|
30326
30326
|
};
|
|
30327
30327
|
var array_stringify = (value, gap) => {
|
|
30328
30328
|
const deeper_gap = gap + indent2;
|
|
@@ -30333,7 +30333,7 @@ var require_stringify = __commonJS({
|
|
|
30333
30333
|
if (i !== 0) {
|
|
30334
30334
|
inside += COMMA;
|
|
30335
30335
|
}
|
|
30336
|
-
const before =
|
|
30336
|
+
const before = join6(
|
|
30337
30337
|
after_comma,
|
|
30338
30338
|
process_comments(value, BEFORE(i), deeper_gap),
|
|
30339
30339
|
deeper_gap
|
|
@@ -30343,7 +30343,7 @@ var require_stringify = __commonJS({
|
|
|
30343
30343
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
30344
30344
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
30345
30345
|
}
|
|
30346
|
-
inside +=
|
|
30346
|
+
inside += join6(
|
|
30347
30347
|
after_comma,
|
|
30348
30348
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
30349
30349
|
deeper_gap
|
|
@@ -30368,7 +30368,7 @@ var require_stringify = __commonJS({
|
|
|
30368
30368
|
inside += COMMA;
|
|
30369
30369
|
}
|
|
30370
30370
|
first = false;
|
|
30371
|
-
const before =
|
|
30371
|
+
const before = join6(
|
|
30372
30372
|
after_comma,
|
|
30373
30373
|
process_comments(value, BEFORE(key), deeper_gap),
|
|
30374
30374
|
deeper_gap
|
|
@@ -30378,7 +30378,7 @@ var require_stringify = __commonJS({
|
|
|
30378
30378
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
30379
30379
|
};
|
|
30380
30380
|
keys.forEach(iteratee);
|
|
30381
|
-
inside +=
|
|
30381
|
+
inside += join6(
|
|
30382
30382
|
after_comma,
|
|
30383
30383
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
30384
30384
|
deeper_gap
|
|
@@ -33827,8 +33827,8 @@ var init_boxen = __esm({
|
|
|
33827
33827
|
});
|
|
33828
33828
|
|
|
33829
33829
|
// src/index.ts
|
|
33830
|
-
var
|
|
33831
|
-
var
|
|
33830
|
+
var import_node_fs6 = require("fs");
|
|
33831
|
+
var import_node_path7 = require("path");
|
|
33832
33832
|
|
|
33833
33833
|
// ../node_modules/commander/esm.mjs
|
|
33834
33834
|
var import_index = __toESM(require_commander(), 1);
|
|
@@ -56903,6 +56903,198 @@ function createDocsCommand() {
|
|
|
56903
56903
|
return docs;
|
|
56904
56904
|
}
|
|
56905
56905
|
|
|
56906
|
+
// src/commands/debug.ts
|
|
56907
|
+
var import_node_child_process8 = require("child_process");
|
|
56908
|
+
var import_node_fs5 = require("fs");
|
|
56909
|
+
var import_node_path6 = require("path");
|
|
56910
|
+
function findProjectRoot(cwd) {
|
|
56911
|
+
let dir = cwd;
|
|
56912
|
+
for (let i = 0; i < 10; i++) {
|
|
56913
|
+
if ((0, import_node_fs5.existsSync)((0, import_node_path6.join)(dir, ".beads"))) return dir;
|
|
56914
|
+
const parent = (0, import_node_path6.join)(dir, "..");
|
|
56915
|
+
if (parent === dir) break;
|
|
56916
|
+
dir = parent;
|
|
56917
|
+
}
|
|
56918
|
+
return null;
|
|
56919
|
+
}
|
|
56920
|
+
function parseBdTable(output, columns2) {
|
|
56921
|
+
const lines = output.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
56922
|
+
const sepIdx = lines.findIndex((l) => /^[-+\s]+$/.test(l) && l.includes("-"));
|
|
56923
|
+
if (sepIdx < 1) return [];
|
|
56924
|
+
const dataLines = lines.slice(sepIdx + 1).filter((l) => !l.startsWith("("));
|
|
56925
|
+
return dataLines.map((line) => {
|
|
56926
|
+
const cells = line.split("|").map((c) => c.trim());
|
|
56927
|
+
const row = {};
|
|
56928
|
+
columns2.forEach((col2, i) => {
|
|
56929
|
+
row[col2] = cells[i] ?? "";
|
|
56930
|
+
});
|
|
56931
|
+
return row;
|
|
56932
|
+
});
|
|
56933
|
+
}
|
|
56934
|
+
function queryEvents(cwd, whereExtra, limit) {
|
|
56935
|
+
const cols = "id, created_at, runtime, session_id, worktree, layer, kind, outcome, tool_name, issue_id";
|
|
56936
|
+
const colNames = ["id", "created_at", "runtime", "session_id", "worktree", "layer", "kind", "outcome", "tool_name", "issue_id"];
|
|
56937
|
+
const where = whereExtra ? `WHERE ${whereExtra}` : "";
|
|
56938
|
+
const sql = `SELECT ${cols} FROM xtrm_events ${where} ORDER BY created_at ASC, id ASC LIMIT ${limit}`;
|
|
56939
|
+
const result = (0, import_node_child_process8.spawnSync)("bd", ["sql", sql], {
|
|
56940
|
+
cwd,
|
|
56941
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
56942
|
+
encoding: "utf8",
|
|
56943
|
+
timeout: 8e3
|
|
56944
|
+
});
|
|
56945
|
+
if (result.status !== 0) return [];
|
|
56946
|
+
const rows = parseBdTable(result.stdout, colNames);
|
|
56947
|
+
return rows.map((r) => ({
|
|
56948
|
+
id: r.id,
|
|
56949
|
+
created_at: r.created_at,
|
|
56950
|
+
runtime: r.runtime,
|
|
56951
|
+
session_id: r.session_id,
|
|
56952
|
+
worktree: r.worktree === "<nil>" || !r.worktree ? null : r.worktree,
|
|
56953
|
+
layer: r.layer,
|
|
56954
|
+
kind: r.kind,
|
|
56955
|
+
outcome: r.outcome,
|
|
56956
|
+
tool_name: r.tool_name === "<nil>" || !r.tool_name ? null : r.tool_name,
|
|
56957
|
+
issue_id: r.issue_id === "<nil>" || !r.issue_id ? null : r.issue_id
|
|
56958
|
+
}));
|
|
56959
|
+
}
|
|
56960
|
+
function fmtTime(created_at) {
|
|
56961
|
+
try {
|
|
56962
|
+
const d = new Date(created_at);
|
|
56963
|
+
if (isNaN(d.getTime())) return created_at.slice(11, 19) || "??:??:??";
|
|
56964
|
+
return d.toLocaleTimeString("en-GB", { hour12: false });
|
|
56965
|
+
} catch {
|
|
56966
|
+
return created_at.slice(11, 19) || "??:??:??";
|
|
56967
|
+
}
|
|
56968
|
+
}
|
|
56969
|
+
function fmtKind(kind, outcome) {
|
|
56970
|
+
const dot = outcome === "block" ? kleur_default.red("\u25CF") : kleur_default.green("\u25CB");
|
|
56971
|
+
const label = kind.padEnd(36);
|
|
56972
|
+
const colored = outcome === "block" ? kleur_default.red(label) : kleur_default.green(label);
|
|
56973
|
+
return `${dot} ${colored}`;
|
|
56974
|
+
}
|
|
56975
|
+
function fmtSession(sessionId) {
|
|
56976
|
+
const short = sessionId.length > 8 ? sessionId.slice(0, 8) : sessionId;
|
|
56977
|
+
return kleur_default.dim(short);
|
|
56978
|
+
}
|
|
56979
|
+
function fmtMeta(event) {
|
|
56980
|
+
const parts = [];
|
|
56981
|
+
if (event.tool_name) parts.push(kleur_default.cyan(event.tool_name.padEnd(10)));
|
|
56982
|
+
if (event.issue_id) parts.push(kleur_default.yellow(event.issue_id));
|
|
56983
|
+
if (event.worktree) parts.push(kleur_default.dim(`[${event.worktree}]`));
|
|
56984
|
+
return parts.join(" ") || kleur_default.dim("\u2014");
|
|
56985
|
+
}
|
|
56986
|
+
function printEvent(event) {
|
|
56987
|
+
const time3 = kleur_default.dim(`[${fmtTime(event.created_at)}]`);
|
|
56988
|
+
const session = fmtSession(event.session_id);
|
|
56989
|
+
const kind = fmtKind(event.kind, event.outcome);
|
|
56990
|
+
const meta3 = fmtMeta(event);
|
|
56991
|
+
console.log(` ${time3} ${session} ${kind} ${meta3}`);
|
|
56992
|
+
}
|
|
56993
|
+
function printHeader() {
|
|
56994
|
+
const h = kleur_default.dim;
|
|
56995
|
+
const col2 = (s, w) => s.padEnd(w);
|
|
56996
|
+
console.log(
|
|
56997
|
+
` ${h(col2("[TIME]", 10))} ${h(col2("SESSION", 10))} ${h("\u25CF/\u25CB")} ${h(col2("KIND", 37))} ${h("TOOL/ISSUE")}`
|
|
56998
|
+
);
|
|
56999
|
+
console.log(` ${kleur_default.dim("\u2500".repeat(90))}`);
|
|
57000
|
+
}
|
|
57001
|
+
function buildWhereClause(opts, sinceTs) {
|
|
57002
|
+
const clauses = [];
|
|
57003
|
+
if (sinceTs) {
|
|
57004
|
+
clauses.push(`created_at >= '${sinceTs}'`);
|
|
57005
|
+
}
|
|
57006
|
+
if (opts.session) {
|
|
57007
|
+
const s = opts.session.replace(/'/g, "''");
|
|
57008
|
+
clauses.push(`session_id LIKE '${s}%'`);
|
|
57009
|
+
}
|
|
57010
|
+
if (opts.type) {
|
|
57011
|
+
const layer = opts.type.replace(/'/g, "''");
|
|
57012
|
+
clauses.push(`layer = '${layer}'`);
|
|
57013
|
+
}
|
|
57014
|
+
return clauses.join(" AND ");
|
|
57015
|
+
}
|
|
57016
|
+
function watch(cwd, opts) {
|
|
57017
|
+
const seenIds = /* @__PURE__ */ new Set();
|
|
57018
|
+
let lastTs = null;
|
|
57019
|
+
const fiveMinsAgo = new Date(Date.now() - 5 * 60 * 1e3).toISOString().replace("T", " ").slice(0, 19);
|
|
57020
|
+
const initialWhere = buildWhereClause(opts, fiveMinsAgo);
|
|
57021
|
+
const initial = queryEvents(cwd, initialWhere, 200);
|
|
57022
|
+
if (initial.length > 0) {
|
|
57023
|
+
for (const ev of initial) {
|
|
57024
|
+
seenIds.add(ev.id);
|
|
57025
|
+
if (!lastTs || ev.created_at > lastTs) lastTs = ev.created_at;
|
|
57026
|
+
if (opts.json) {
|
|
57027
|
+
console.log(JSON.stringify(ev));
|
|
57028
|
+
} else {
|
|
57029
|
+
printEvent(ev);
|
|
57030
|
+
}
|
|
57031
|
+
}
|
|
57032
|
+
} else {
|
|
57033
|
+
if (!opts.json) console.log(kleur_default.dim(" (no recent events \u2014 waiting for new ones)\n"));
|
|
57034
|
+
}
|
|
57035
|
+
const interval = setInterval(() => {
|
|
57036
|
+
const overlapTs = lastTs ? new Date(new Date(lastTs.replace(" +0000 UTC", "Z")).getTime() - 2e3).toISOString().replace("T", " ").slice(0, 19) : new Date(Date.now() - 1e4).toISOString().replace("T", " ").slice(0, 19);
|
|
57037
|
+
const where = buildWhereClause(opts, overlapTs);
|
|
57038
|
+
const events = queryEvents(cwd, where, 50);
|
|
57039
|
+
const newEvents = events.filter((ev) => !seenIds.has(ev.id));
|
|
57040
|
+
for (const ev of newEvents) {
|
|
57041
|
+
seenIds.add(ev.id);
|
|
57042
|
+
if (!lastTs || ev.created_at > lastTs) lastTs = ev.created_at;
|
|
57043
|
+
if (opts.json) {
|
|
57044
|
+
console.log(JSON.stringify(ev));
|
|
57045
|
+
} else {
|
|
57046
|
+
printEvent(ev);
|
|
57047
|
+
}
|
|
57048
|
+
}
|
|
57049
|
+
}, 2e3);
|
|
57050
|
+
process.on("SIGINT", () => {
|
|
57051
|
+
clearInterval(interval);
|
|
57052
|
+
if (!opts.json) console.log(kleur_default.dim("\n stopped\n"));
|
|
57053
|
+
process.exit(0);
|
|
57054
|
+
});
|
|
57055
|
+
}
|
|
57056
|
+
function createDebugCommand() {
|
|
57057
|
+
return new Command("debug").description("Watch xtrm hook and bd lifecycle events in real time").option("--all", "Show full history instead of watching", false).option("--session <id>", "Filter by session ID (prefix match)").option("--type <layer>", "Filter by layer: gate | bd").option("--json", "Output raw JSON lines", false).action((opts) => {
|
|
57058
|
+
const cwd = process.cwd();
|
|
57059
|
+
const root = findProjectRoot(cwd);
|
|
57060
|
+
if (!root) {
|
|
57061
|
+
console.error(kleur_default.red("\n \u2717 No beads project found (.beads directory missing)\n"));
|
|
57062
|
+
console.error(kleur_default.dim(" Run from inside an xtrm project.\n"));
|
|
57063
|
+
process.exit(1);
|
|
57064
|
+
}
|
|
57065
|
+
if (!opts.json) {
|
|
57066
|
+
console.log(kleur_default.bold("\n xtrm event log"));
|
|
57067
|
+
if (opts.all) {
|
|
57068
|
+
console.log(kleur_default.dim(" Showing full history\n"));
|
|
57069
|
+
} else {
|
|
57070
|
+
console.log(kleur_default.dim(" Watching for events \u2014 Ctrl+C to stop\n"));
|
|
57071
|
+
}
|
|
57072
|
+
printHeader();
|
|
57073
|
+
}
|
|
57074
|
+
if (opts.all) {
|
|
57075
|
+
const where = buildWhereClause(opts, null);
|
|
57076
|
+
const events = queryEvents(root, where, 200);
|
|
57077
|
+
if (events.length === 0) {
|
|
57078
|
+
if (!opts.json) {
|
|
57079
|
+
console.log(kleur_default.dim("\n No events recorded yet."));
|
|
57080
|
+
console.log(kleur_default.dim(" Events appear here as hooks fire and bd lifecycle runs.\n"));
|
|
57081
|
+
}
|
|
57082
|
+
} else {
|
|
57083
|
+
for (const ev of events) {
|
|
57084
|
+
if (opts.json) {
|
|
57085
|
+
console.log(JSON.stringify(ev));
|
|
57086
|
+
} else {
|
|
57087
|
+
printEvent(ev);
|
|
57088
|
+
}
|
|
57089
|
+
}
|
|
57090
|
+
if (!opts.json) console.log("");
|
|
57091
|
+
}
|
|
57092
|
+
return;
|
|
57093
|
+
}
|
|
57094
|
+
watch(root, opts);
|
|
57095
|
+
});
|
|
57096
|
+
}
|
|
57097
|
+
|
|
56906
57098
|
// src/utils/banner.ts
|
|
56907
57099
|
var ART = [
|
|
56908
57100
|
" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
@@ -57075,7 +57267,7 @@ async function printBanner(version3) {
|
|
|
57075
57267
|
// src/index.ts
|
|
57076
57268
|
var version2 = "0.0.0";
|
|
57077
57269
|
try {
|
|
57078
|
-
version2 = JSON.parse((0,
|
|
57270
|
+
version2 = JSON.parse((0, import_node_fs6.readFileSync)((0, import_node_path7.resolve)(__dirname, "../package.json"), "utf8")).version;
|
|
57079
57271
|
} catch {
|
|
57080
57272
|
}
|
|
57081
57273
|
var program2 = new Command();
|
|
@@ -57101,6 +57293,7 @@ program2.addCommand(createCleanCommand());
|
|
|
57101
57293
|
program2.addCommand(createEndCommand());
|
|
57102
57294
|
program2.addCommand(createWorktreeCommand());
|
|
57103
57295
|
program2.addCommand(createDocsCommand());
|
|
57296
|
+
program2.addCommand(createDebugCommand());
|
|
57104
57297
|
program2.addCommand(createHelpCommand());
|
|
57105
57298
|
program2.action(async () => {
|
|
57106
57299
|
program2.help();
|