xtrm-tools 0.5.22 → 0.5.24
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 +127 -82
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/hooks/xtrm-logger.mjs +8 -1
- package/package.json +1 -1
package/cli/dist/index.cjs
CHANGED
|
@@ -56907,6 +56907,84 @@ function createDocsCommand() {
|
|
|
56907
56907
|
var import_node_child_process8 = require("child_process");
|
|
56908
56908
|
var import_node_fs5 = require("fs");
|
|
56909
56909
|
var import_node_path6 = require("path");
|
|
56910
|
+
var KIND_LABELS = {
|
|
56911
|
+
"hook.edit_gate.allow": { label: "EDIT+", color: kleur_default.green },
|
|
56912
|
+
"hook.edit_gate.block": { label: "EDIT-", color: kleur_default.red },
|
|
56913
|
+
"hook.commit_gate.allow": { label: "CMIT+", color: kleur_default.green },
|
|
56914
|
+
"hook.commit_gate.block": { label: "CMIT-", color: kleur_default.red },
|
|
56915
|
+
"hook.stop_gate.allow": { label: "STOP+", color: kleur_default.green },
|
|
56916
|
+
"hook.stop_gate.block": { label: "STOP-", color: kleur_default.red },
|
|
56917
|
+
"hook.memory_gate.acked": { label: "MEMO+", color: kleur_default.green },
|
|
56918
|
+
"hook.memory_gate.triggered": { label: "MEMO-", color: kleur_default.yellow },
|
|
56919
|
+
"hook.worktree_boundary.block": { label: "WTRE-", color: kleur_default.red },
|
|
56920
|
+
"bd.claimed": { label: "CLMD ", color: kleur_default.cyan },
|
|
56921
|
+
"bd.closed": { label: "CLSD ", color: kleur_default.green },
|
|
56922
|
+
"bd.auto_committed": { label: "ACMT+", color: kleur_default.cyan }
|
|
56923
|
+
};
|
|
56924
|
+
function getLabel(kind, outcome) {
|
|
56925
|
+
const def = KIND_LABELS[kind];
|
|
56926
|
+
if (!def) {
|
|
56927
|
+
const short = (kind.split(".").pop() ?? "UNKN").slice(0, 4).toUpperCase();
|
|
56928
|
+
const label = `${short}${outcome === "block" ? "-" : "+"}`.padEnd(5);
|
|
56929
|
+
return outcome === "block" ? kleur_default.red(label) : kleur_default.green(label);
|
|
56930
|
+
}
|
|
56931
|
+
if (kind === "bd.auto_committed") {
|
|
56932
|
+
return outcome === "block" ? kleur_default.red("ACMT-") : kleur_default.cyan("ACMT+");
|
|
56933
|
+
}
|
|
56934
|
+
return def.color(def.label);
|
|
56935
|
+
}
|
|
56936
|
+
var SESSION_COLORS = [
|
|
56937
|
+
kleur_default.blue,
|
|
56938
|
+
kleur_default.green,
|
|
56939
|
+
kleur_default.yellow,
|
|
56940
|
+
kleur_default.cyan,
|
|
56941
|
+
kleur_default.magenta
|
|
56942
|
+
];
|
|
56943
|
+
function buildSessionColorMap(events) {
|
|
56944
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
56945
|
+
for (const ev of events) {
|
|
56946
|
+
if (!map2.has(ev.session_id)) {
|
|
56947
|
+
map2.set(ev.session_id, SESSION_COLORS[map2.size % SESSION_COLORS.length]);
|
|
56948
|
+
}
|
|
56949
|
+
}
|
|
56950
|
+
return map2;
|
|
56951
|
+
}
|
|
56952
|
+
function extendSessionColorMap(map2, events) {
|
|
56953
|
+
for (const ev of events) {
|
|
56954
|
+
if (!map2.has(ev.session_id)) {
|
|
56955
|
+
map2.set(ev.session_id, SESSION_COLORS[map2.size % SESSION_COLORS.length]);
|
|
56956
|
+
}
|
|
56957
|
+
}
|
|
56958
|
+
}
|
|
56959
|
+
function fmtTime(created_at) {
|
|
56960
|
+
try {
|
|
56961
|
+
const d = new Date(created_at);
|
|
56962
|
+
if (isNaN(d.getTime())) return created_at.slice(11, 19) || "??:??:??";
|
|
56963
|
+
return d.toLocaleTimeString("en-GB", { hour12: false });
|
|
56964
|
+
} catch {
|
|
56965
|
+
return created_at.slice(11, 19) || "??:??:??";
|
|
56966
|
+
}
|
|
56967
|
+
}
|
|
56968
|
+
function buildDetail(event) {
|
|
56969
|
+
const parts = [];
|
|
56970
|
+
if (event.tool_name) parts.push(kleur_default.dim(`tool=${event.tool_name}`));
|
|
56971
|
+
if (event.issue_id) parts.push(kleur_default.yellow(`issue=${event.issue_id}`));
|
|
56972
|
+
if (event.worktree) parts.push(kleur_default.dim(`wt=${event.worktree}`));
|
|
56973
|
+
return parts.join(" ") || kleur_default.dim("\u2014");
|
|
56974
|
+
}
|
|
56975
|
+
function formatEventLine(event, colorMap) {
|
|
56976
|
+
const time3 = kleur_default.dim(fmtTime(event.created_at));
|
|
56977
|
+
const colorFn = colorMap.get(event.session_id) ?? kleur_default.white;
|
|
56978
|
+
const session = colorFn(event.session_id.slice(0, 8));
|
|
56979
|
+
const label = getLabel(event.kind, event.outcome);
|
|
56980
|
+
const detail = buildDetail(event);
|
|
56981
|
+
return `${time3} ${session} ${label} ${detail}`;
|
|
56982
|
+
}
|
|
56983
|
+
function printHeader() {
|
|
56984
|
+
const h = kleur_default.dim;
|
|
56985
|
+
console.log(` ${h("TIME ")} ${h("SESSION ")} ${h("LABEL")} ${h("DETAIL")}`);
|
|
56986
|
+
console.log(` ${kleur_default.dim("\u2500".repeat(72))}`);
|
|
56987
|
+
}
|
|
56910
56988
|
function findProjectRoot(cwd) {
|
|
56911
56989
|
let dir = cwd;
|
|
56912
56990
|
for (let i = 0; i < 10; i++) {
|
|
@@ -56921,8 +56999,7 @@ function parseBdTable(output, columns2) {
|
|
|
56921
56999
|
const lines = output.split("\n").map((l) => l.trim()).filter(Boolean);
|
|
56922
57000
|
const sepIdx = lines.findIndex((l) => /^[-+\s]+$/.test(l) && l.includes("-"));
|
|
56923
57001
|
if (sepIdx < 1) return [];
|
|
56924
|
-
|
|
56925
|
-
return dataLines.map((line) => {
|
|
57002
|
+
return lines.slice(sepIdx + 1).filter((l) => !l.startsWith("(")).map((line) => {
|
|
56926
57003
|
const cells = line.split("|").map((c) => c.trim());
|
|
56927
57004
|
const row = {};
|
|
56928
57005
|
columns2.forEach((col2, i) => {
|
|
@@ -56931,20 +57008,34 @@ function parseBdTable(output, columns2) {
|
|
|
56931
57008
|
return row;
|
|
56932
57009
|
});
|
|
56933
57010
|
}
|
|
56934
|
-
|
|
56935
|
-
|
|
56936
|
-
|
|
56937
|
-
|
|
56938
|
-
const sql = `SELECT ${
|
|
56939
|
-
|
|
57011
|
+
var COLS = "seq, id, created_at, runtime, session_id, worktree, layer, kind, outcome, tool_name, issue_id";
|
|
57012
|
+
var COL_NAMES = ["seq", "id", "created_at", "runtime", "session_id", "worktree", "layer", "kind", "outcome", "tool_name", "issue_id"];
|
|
57013
|
+
var ADD_SEQ_SQL = `ALTER TABLE xtrm_events ADD COLUMN seq INT NOT NULL AUTO_INCREMENT, ADD UNIQUE KEY uk_seq (seq)`;
|
|
57014
|
+
function queryEvents(cwd, where, limit) {
|
|
57015
|
+
const sql = `SELECT ${COLS} FROM xtrm_events${where ? ` WHERE ${where}` : ""} ORDER BY seq ASC LIMIT ${limit}`;
|
|
57016
|
+
let result = (0, import_node_child_process8.spawnSync)("bd", ["sql", sql], {
|
|
56940
57017
|
cwd,
|
|
56941
57018
|
stdio: ["pipe", "pipe", "pipe"],
|
|
56942
57019
|
encoding: "utf8",
|
|
56943
57020
|
timeout: 8e3
|
|
56944
57021
|
});
|
|
57022
|
+
if (result.status !== 0) {
|
|
57023
|
+
(0, import_node_child_process8.spawnSync)("bd", ["sql", ADD_SEQ_SQL], {
|
|
57024
|
+
cwd,
|
|
57025
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
57026
|
+
encoding: "utf8",
|
|
57027
|
+
timeout: 5e3
|
|
57028
|
+
});
|
|
57029
|
+
result = (0, import_node_child_process8.spawnSync)("bd", ["sql", sql], {
|
|
57030
|
+
cwd,
|
|
57031
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
57032
|
+
encoding: "utf8",
|
|
57033
|
+
timeout: 8e3
|
|
57034
|
+
});
|
|
57035
|
+
}
|
|
56945
57036
|
if (result.status !== 0) return [];
|
|
56946
|
-
|
|
56947
|
-
|
|
57037
|
+
return parseBdTable(result.stdout, COL_NAMES).map((r) => ({
|
|
57038
|
+
seq: parseInt(r.seq, 10) || 0,
|
|
56948
57039
|
id: r.id,
|
|
56949
57040
|
created_at: r.created_at,
|
|
56950
57041
|
runtime: r.runtime,
|
|
@@ -56957,52 +57048,9 @@ function queryEvents(cwd, whereExtra, limit) {
|
|
|
56957
57048
|
issue_id: r.issue_id === "<nil>" || !r.issue_id ? null : r.issue_id
|
|
56958
57049
|
}));
|
|
56959
57050
|
}
|
|
56960
|
-
function
|
|
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) {
|
|
57051
|
+
function buildWhere(opts, baseClause) {
|
|
57002
57052
|
const clauses = [];
|
|
57003
|
-
if (
|
|
57004
|
-
clauses.push(`created_at >= '${sinceTs}'`);
|
|
57005
|
-
}
|
|
57053
|
+
if (baseClause) clauses.push(baseClause);
|
|
57006
57054
|
if (opts.session) {
|
|
57007
57055
|
const s = opts.session.replace(/'/g, "''");
|
|
57008
57056
|
clauses.push(`session_id LIKE '${s}%'`);
|
|
@@ -57013,37 +57061,34 @@ function buildWhereClause(opts, sinceTs) {
|
|
|
57013
57061
|
}
|
|
57014
57062
|
return clauses.join(" AND ");
|
|
57015
57063
|
}
|
|
57016
|
-
function
|
|
57017
|
-
const seenIds = /* @__PURE__ */ new Set();
|
|
57018
|
-
let lastTs = null;
|
|
57064
|
+
function follow(cwd, opts) {
|
|
57019
57065
|
const fiveMinsAgo = new Date(Date.now() - 5 * 60 * 1e3).toISOString().replace("T", " ").slice(0, 19);
|
|
57020
|
-
const
|
|
57021
|
-
const
|
|
57066
|
+
const initial = queryEvents(cwd, buildWhere(opts, `created_at >= '${fiveMinsAgo}'`), 200);
|
|
57067
|
+
const colorMap = buildSessionColorMap(initial);
|
|
57068
|
+
let lastSeq = 0;
|
|
57022
57069
|
if (initial.length > 0) {
|
|
57023
57070
|
for (const ev of initial) {
|
|
57024
|
-
|
|
57025
|
-
if (!lastTs || ev.created_at > lastTs) lastTs = ev.created_at;
|
|
57071
|
+
if (ev.seq > lastSeq) lastSeq = ev.seq;
|
|
57026
57072
|
if (opts.json) {
|
|
57027
57073
|
console.log(JSON.stringify(ev));
|
|
57028
57074
|
} else {
|
|
57029
|
-
|
|
57075
|
+
console.log(" " + formatEventLine(ev, colorMap));
|
|
57030
57076
|
}
|
|
57031
57077
|
}
|
|
57032
|
-
} else {
|
|
57033
|
-
|
|
57078
|
+
} else if (!opts.json) {
|
|
57079
|
+
console.log(kleur_default.dim(" (no recent events \u2014 waiting for new ones)\n"));
|
|
57034
57080
|
}
|
|
57035
57081
|
const interval = setInterval(() => {
|
|
57036
|
-
const
|
|
57037
|
-
|
|
57038
|
-
|
|
57039
|
-
|
|
57040
|
-
|
|
57041
|
-
|
|
57042
|
-
|
|
57043
|
-
|
|
57044
|
-
|
|
57045
|
-
|
|
57046
|
-
printEvent(ev);
|
|
57082
|
+
const events = queryEvents(cwd, buildWhere(opts, `seq > ${lastSeq}`), 50);
|
|
57083
|
+
if (events.length > 0) {
|
|
57084
|
+
extendSessionColorMap(colorMap, events);
|
|
57085
|
+
for (const ev of events) {
|
|
57086
|
+
if (ev.seq > lastSeq) lastSeq = ev.seq;
|
|
57087
|
+
if (opts.json) {
|
|
57088
|
+
console.log(JSON.stringify(ev));
|
|
57089
|
+
} else {
|
|
57090
|
+
console.log(" " + formatEventLine(ev, colorMap));
|
|
57091
|
+
}
|
|
57047
57092
|
}
|
|
57048
57093
|
}
|
|
57049
57094
|
}, 2e3);
|
|
@@ -57054,7 +57099,7 @@ function watch(cwd, opts) {
|
|
|
57054
57099
|
});
|
|
57055
57100
|
}
|
|
57056
57101
|
function createDebugCommand() {
|
|
57057
|
-
return new Command("debug").description("Watch xtrm hook and bd lifecycle events in real time").option("--all", "Show full history
|
|
57102
|
+
return new Command("debug").description("Watch xtrm hook and bd lifecycle events in real time").option("-f, --follow", "Follow new events (default when no other mode set)", false).option("--all", "Show full history and exit", 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
57103
|
const cwd = process.cwd();
|
|
57059
57104
|
const root = findProjectRoot(cwd);
|
|
57060
57105
|
if (!root) {
|
|
@@ -57067,31 +57112,31 @@ function createDebugCommand() {
|
|
|
57067
57112
|
if (opts.all) {
|
|
57068
57113
|
console.log(kleur_default.dim(" Showing full history\n"));
|
|
57069
57114
|
} else {
|
|
57070
|
-
console.log(kleur_default.dim("
|
|
57115
|
+
console.log(kleur_default.dim(" Following events \u2014 Ctrl+C to stop\n"));
|
|
57071
57116
|
}
|
|
57072
57117
|
printHeader();
|
|
57073
57118
|
}
|
|
57074
57119
|
if (opts.all) {
|
|
57075
|
-
const
|
|
57076
|
-
const events = queryEvents(root, where, 200);
|
|
57120
|
+
const events = queryEvents(root, buildWhere(opts, ""), 200);
|
|
57077
57121
|
if (events.length === 0) {
|
|
57078
57122
|
if (!opts.json) {
|
|
57079
57123
|
console.log(kleur_default.dim("\n No events recorded yet."));
|
|
57080
57124
|
console.log(kleur_default.dim(" Events appear here as hooks fire and bd lifecycle runs.\n"));
|
|
57081
57125
|
}
|
|
57082
57126
|
} else {
|
|
57127
|
+
const colorMap = buildSessionColorMap(events);
|
|
57083
57128
|
for (const ev of events) {
|
|
57084
57129
|
if (opts.json) {
|
|
57085
57130
|
console.log(JSON.stringify(ev));
|
|
57086
57131
|
} else {
|
|
57087
|
-
|
|
57132
|
+
console.log(" " + formatEventLine(ev, colorMap));
|
|
57088
57133
|
}
|
|
57089
57134
|
}
|
|
57090
57135
|
if (!opts.json) console.log("");
|
|
57091
57136
|
}
|
|
57092
57137
|
return;
|
|
57093
57138
|
}
|
|
57094
|
-
|
|
57139
|
+
follow(root, opts);
|
|
57095
57140
|
});
|
|
57096
57141
|
}
|
|
57097
57142
|
|