@tekmidian/pai 1.0.3 → 1.0.4
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/.claude-plugin/plugin.json +1 -1
- package/dist/{auto-route-B7Yu6Uam.mjs → auto-route-21GdHL70.mjs} +1 -1
- package/dist/{auto-route-CjjQqU1o.mjs → auto-route-C3S2W3Bc.mjs} +1 -1
- package/dist/{budget-Dod6rnA9.mjs → budget-BrloTOZW.mjs} +1 -1
- package/dist/{chain-7n9Gx56r.mjs → chain-D7PFur8Y.mjs} +2 -2
- package/dist/cli/index.mjs +70 -180
- package/dist/{cockpit-actions-DR9X514g.mjs → cockpit-actions-BfRMr2sm.mjs} +6 -6
- package/dist/{cockpit-actions-BBHeyEZI.mjs → cockpit-actions-OodH_vx_.mjs} +20 -18
- package/dist/{cockpit-memory--dnShXBA.mjs → cockpit-memory-teG9M8bG.mjs} +6 -6
- package/dist/config/defaults/config.yaml +6 -0
- package/dist/{controls-CPoeudou.mjs → controls-JLm6g0yP.mjs} +7 -5
- package/dist/daemon/index.mjs +18 -18
- package/dist/{daemon-DKdBNKfa.mjs → daemon-DeYImF1F.mjs} +18 -18
- package/dist/daemon-mcp/index.mjs +18 -18
- package/dist/{daemon-DPAo6WTa.mjs → daemon-nXanenDM.mjs} +21 -17
- package/dist/{detect-9CZNO0yf.mjs → detect-BLKsUOgG.mjs} +2 -2
- package/dist/{detect-D1ziFFfA.mjs → detect-Rrimh0xc.mjs} +3 -3
- package/dist/{embed-pass-DIWjA68P.mjs → embed-pass-e64AwDCa.mjs} +1 -1
- package/dist/{endreason-C577xIQz.mjs → endreason-BC-v05H_.mjs} +17 -3
- package/dist/{factory-DjAAsqr_.mjs → factory-B7nv75rC.mjs} +2 -2
- package/dist/{factory-Bsib-qDG.mjs → factory-Bs9imVMq.mjs} +2 -2
- package/dist/{fallback-DFlItw1Z.mjs → fallback-CBWpp2F2.mjs} +227 -5
- package/dist/{health-Dnym-qcT.mjs → health-C4FQmkJn.mjs} +2 -2
- package/dist/{helpers-BD6V-p9w.mjs → helpers-DSNK_1KP.mjs} +2 -2
- package/dist/{helpers-CMGjy_0N.mjs → helpers-Dz7mjTSw.mjs} +3 -3
- package/dist/hooks/capture-all-events.mjs +21 -2
- package/dist/hooks/capture-tool-output.mjs +21 -2
- package/dist/hooks/worker-pool-host.mjs +52 -9
- package/dist/hooks/worker-status-line.mjs +34 -6
- package/dist/{indexer-backend-Cll7le4P.mjs → indexer-backend-BdjeL4P8.mjs} +31 -228
- package/dist/{ipc-client-CaiGJnSM.mjs → ipc-client-CnYEF31R.mjs} +1 -1
- package/dist/{ipc-client-ZRmDKd5Z.mjs → ipc-client-DN7EvoVo.mjs} +1 -1
- package/dist/{kill-tree-EWYaEk5v.mjs → kill-tree-DleMNZX3.mjs} +2 -2
- package/dist/{kill-tree-BG7dRVtp.mjs → kill-tree-SV6hrIa3.mjs} +2 -2
- package/dist/{launch-Jh5NVeNe.mjs → launch-Di7N-J5X.mjs} +2 -2
- package/dist/{launch-CXVlZjHt.mjs → launch-DlZTKE3u.mjs} +2 -2
- package/dist/{main-config-ops-BEMpuhDz.mjs → main-config-ops-kTXR8Pyv.mjs} +1 -1
- package/dist/{main-resolver-3Ns1HPmS.mjs → main-resolver-yp_puSSb.mjs} +5 -5
- package/dist/{model-inventory-BFVSNFT3.mjs → model-inventory-h6Z9fN_o.mjs} +1 -1
- package/dist/{models-add-C1QIc1DA.mjs → models-add-TVni3A7V.mjs} +19 -19
- package/dist/{pane-audit-DKQt71s4.mjs → pane-audit-Lqy9N_Ki.mjs} +23 -5
- package/dist/{planner-BmFACdLa.mjs → planner-j77ndkBf.mjs} +11 -11
- package/dist/{postgres-BdBNkL_l.mjs → postgres-BK4FP9Zg.mjs} +1 -1
- package/dist/{postgres-C6ti4haA.mjs → postgres-DNIOQijl.mjs} +17 -7
- package/dist/{project-setup-jvfONJTQ.mjs → project-setup-CBRtFFh0.mjs} +15 -235
- package/dist/{providers-CblTFrhz.mjs → providers-C9QC0TtO.mjs} +2 -2
- package/dist/{providers-BeDiVEb-.mjs → providers-FvCLzFge.mjs} +2 -2
- package/dist/{query-feedback-BRfPtqki.mjs → query-feedback-DN52N9C5.mjs} +1 -1
- package/dist/{render-CoMvwMPs.mjs → render-B35bQTE-.mjs} +2 -2
- package/dist/{render-BYmQkuLd.mjs → render-C84BqQRC.mjs} +2 -2
- package/dist/{root-Xglu0OPD.mjs → root-C4oXlXS_.mjs} +7 -7
- package/dist/{root-FtJsxYnm.mjs → root-DD1xx_Vu.mjs} +12 -12
- package/dist/route-table-FEfDuhIV.mjs +15 -0
- package/dist/{routing-BAAST9vT.mjs → routing-DmkheCRH.mjs} +126 -8
- package/dist/{routing-CENt4HH1.mjs → routing-f2zulGwD.mjs} +1 -1
- package/dist/{run-CSC7mgPf.mjs → run-BwZKBJZZ.mjs} +25 -11
- package/dist/{scan-C_Y5W9py.mjs → scan-BBGvU5EB.mjs} +2 -2
- package/dist/{session-BeqAbNPd.mjs → session-BAhtXdxj.mjs} +11 -11
- package/dist/{session-8iqQDkqb.mjs → session-Dn5OJXlg.mjs} +20 -20
- package/dist/{session-scan-BJI_ZO8M.mjs → session-scan-B57dNuA4.mjs} +1 -1
- package/dist/{session-scan-W-gbwJHM.mjs → session-scan-DUn10MBd.mjs} +2 -2
- package/dist/session-usage-CPvXvSkw.mjs +222 -0
- package/dist/{sources-ESUkZaWv.mjs → sources-CiE3rZek.mjs} +1 -1
- package/dist/{viewer-CqozWW39.mjs → viewer-DEySE4c_.mjs} +6 -6
- package/dist/{viewer-mDXUNHNy.mjs → viewer-wfKnvnrI.mjs} +5 -5
- package/dist/{worker-config-DESkIjMF.mjs → worker-config-CO5FXLAT.mjs} +18 -18
- package/dist/{worker-config-CJhEMk19.mjs → worker-config-eY5Qy4vl.mjs} +318 -21
- package/dist/{zettelkasten-BzMm8REH.mjs → zettelkasten-_h_tUm2T.mjs} +1 -1
- package/dist/{zettelkasten-B_rRRRvD.mjs → zettelkasten-tpCRBYvH.mjs} +2 -2
- package/docs/cockpit.md +1 -0
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/pai-plugin.json +1 -1
- package/plugins/context-preservation/plugin.json +1 -1
- package/plugins/core/plugin.json +1 -1
- package/plugins/creative/plugin.json +1 -1
- package/plugins/observability/plugin.json +1 -1
- package/plugins/productivity/plugin.json +1 -1
- package/plugins/semantic-search/plugin.json +1 -1
- package/plugins/ui/plugin.json +1 -1
- package/plugins/zettelkasten/plugin.json +1 -1
- package/src/hooks/ts/capture-all-events.ts +15 -3
- package/src/hooks/ts/lib/raw-capture.ts +7 -0
- package/src/hooks/ts/post-tool-use/capture-tool-output.ts +13 -3
- package/dist/route-table-B7zpoypi.mjs +0 -15
|
@@ -2,11 +2,233 @@ import { l as claudeHomeDir, t as aibrokerHomeDir } from "./runtime-paths-WsO9sJ
|
|
|
2
2
|
import { F as writeWorkersSection, N as resolveModelCapability, P as resolveProviderKey, c as WorkersConfigError, j as readWorkersSection } from "./config-XpZWOYOG.mjs";
|
|
3
3
|
import { D as readJsonStrict, O as writeJsonAtomic } from "./config-Bu1_vbY8.mjs";
|
|
4
4
|
import { u as workersLogDir } from "./paths-CHifubDh.mjs";
|
|
5
|
-
import { _ as resolveTarget } from "./routing-
|
|
5
|
+
import { _ as resolveTarget } from "./routing-DmkheCRH.mjs";
|
|
6
|
+
import { yt as psTable } from "./controls-JLm6g0yP.mjs";
|
|
6
7
|
import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
7
|
-
import { join } from "node:path";
|
|
8
|
-
import { execFileSync } from "node:child_process";
|
|
8
|
+
import { isAbsolute, join, relative } from "node:path";
|
|
9
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
9
11
|
|
|
12
|
+
//#region src/workers/hang-probe.ts
|
|
13
|
+
/**
|
|
14
|
+
* hang-probe.ts — `pai worker test-run -- <command>`: runs a test command and, when it goes silent,
|
|
15
|
+
* tells the model WHERE it is stuck.
|
|
16
|
+
*
|
|
17
|
+
* A synchronous infinite loop blocks Node's event loop, so the test runner cannot even report its own
|
|
18
|
+
* timeout and the model sees nothing. Node's `--report-on-signal` does not help: it is serviced by the
|
|
19
|
+
* event loop (measured: a `while(true){}` process never writes the report). The child therefore runs with a
|
|
20
|
+
* preloaded watchdog (NODE_OPTIONS --require): a worker thread per process that, when a trigger file appears,
|
|
21
|
+
* attaches the inspector to the main thread, pauses it (V8 interrupts a running loop) and writes the call
|
|
22
|
+
* frames. After the command was silent for the idle threshold the wrapper triggers every node process under
|
|
23
|
+
* it and maps the frames to the worktree's files. The worker guard rewrites test commands into this wrapper
|
|
24
|
+
* (see wrapTestCommand).
|
|
25
|
+
*/
|
|
26
|
+
/** Marker line every diagnosis carries; the loop guard keys on it. */
|
|
27
|
+
const HANG_MARKER = "[pai hang probe]";
|
|
28
|
+
const DEFAULT_IDLE_SECS = 60;
|
|
29
|
+
/** Seconds of the first `timeout N` in the command, else null. */
|
|
30
|
+
function timeoutSecs(command) {
|
|
31
|
+
const m = /\b(?:g?timeout)\s+(?:-[ks]\s+\S+\s+|-\S+\s+)*(\d+(?:\.\d+)?)([smhd]?)\b/.exec(command);
|
|
32
|
+
if (!m) return null;
|
|
33
|
+
return Number(m[1]) * {
|
|
34
|
+
"": 1,
|
|
35
|
+
s: 1,
|
|
36
|
+
m: 60,
|
|
37
|
+
h: 3600,
|
|
38
|
+
d: 86400
|
|
39
|
+
}[m[2]];
|
|
40
|
+
}
|
|
41
|
+
function killQuiet(pid, sig) {
|
|
42
|
+
try {
|
|
43
|
+
process.kill(pid, sig);
|
|
44
|
+
} catch {}
|
|
45
|
+
}
|
|
46
|
+
function rmQuiet(f) {
|
|
47
|
+
try {
|
|
48
|
+
unlinkSync(f);
|
|
49
|
+
} catch {}
|
|
50
|
+
}
|
|
51
|
+
const shq = (s) => `'${s.replace(/'/g, `'\\''`)}'`;
|
|
52
|
+
/** The command line test-run executes: the decoded --cmd-b64 payload, else the words after `--`, each shell-quoted. */
|
|
53
|
+
function commandToRun(cmdB64, words) {
|
|
54
|
+
if (cmdB64) return Buffer.from(cmdB64, "base64").toString("utf8");
|
|
55
|
+
return words.map(shq).join(" ");
|
|
56
|
+
}
|
|
57
|
+
/** Call frames of one probed process, user code only, files relative to cwd. */
|
|
58
|
+
function userFrames(frames, cwd) {
|
|
59
|
+
const out = [];
|
|
60
|
+
for (const f of frames) {
|
|
61
|
+
let file = f.url;
|
|
62
|
+
if (file.startsWith("file://")) try {
|
|
63
|
+
file = fileURLToPath(file);
|
|
64
|
+
} catch {
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (!file || file.startsWith("node:") || file.includes("node_modules") || !isAbsolute(file)) continue;
|
|
68
|
+
const rel = relative(cwd, file);
|
|
69
|
+
if (rel.startsWith("..")) continue;
|
|
70
|
+
out.push({
|
|
71
|
+
fn: f.functionName || "(anonymous)",
|
|
72
|
+
file: rel,
|
|
73
|
+
line: f.lineNumber + 1
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
/** The model-facing diagnosis for the reports taken after `idleSecs` of silence. */
|
|
79
|
+
function diagnose(probed, cwd, idleSecs) {
|
|
80
|
+
const stuck = probed.map((r) => userFrames(r, cwd)).find((f) => f.length > 0);
|
|
81
|
+
if (stuck) {
|
|
82
|
+
const [top, ...rest] = stuck;
|
|
83
|
+
const via = rest[0] ? ` (called from ${rest[0].file}:${rest[0].line} ${rest[0].fn}())` : "";
|
|
84
|
+
return `${HANG_MARKER} test run hung with no output for ${idleSecs} s; the main thread is stuck in ${top.file}:${top.line} ${top.fn}()${via}. A synchronous loop that never ends blocks the runner's own timeout. Fix that loop; rerunning unchanged will hang again.\n` + stuck.slice(0, 6).map((f) => ` at ${f.fn} (${f.file}:${f.line})`).join("\n");
|
|
85
|
+
}
|
|
86
|
+
return `${HANG_MARKER} test run printed nothing for ${idleSecs} s and the main thread is idle in the event loop: it is waiting (async), not spinning. A test awaits a promise, timer, process or socket that never completes (vitest's own per-test timeout ends it unless the test raised it). Find the await and give it an end; rerunning unchanged will wait again.`;
|
|
87
|
+
}
|
|
88
|
+
function listProcs() {
|
|
89
|
+
try {
|
|
90
|
+
return psTable("pid=,ppid=,command=").split("\n").flatMap((l) => {
|
|
91
|
+
const m = /^\s*(\d+)\s+(\d+)\s+(.*)$/.exec(l);
|
|
92
|
+
return m ? [{
|
|
93
|
+
pid: Number(m[1]),
|
|
94
|
+
ppid: Number(m[2]),
|
|
95
|
+
cmd: m[3]
|
|
96
|
+
}] : [];
|
|
97
|
+
});
|
|
98
|
+
} catch {
|
|
99
|
+
return [];
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Pids of node processes below `root`. */
|
|
103
|
+
function nodeDescendants(root, procs = listProcs()) {
|
|
104
|
+
const seen = new Set([root]);
|
|
105
|
+
for (let grew = true; grew;) {
|
|
106
|
+
grew = false;
|
|
107
|
+
for (const p of procs) if (!seen.has(p.pid) && seen.has(p.ppid)) seen.add(p.pid), grew = true;
|
|
108
|
+
}
|
|
109
|
+
return procs.filter((p) => p.pid !== root && seen.has(p.pid) && /(?:^|\/)node(?:\s|$)/.test(p.cmd)).map((p) => p.pid);
|
|
110
|
+
}
|
|
111
|
+
/** Runs the command, passes its output through, probes once when it goes silent. Resolves to the exit code. */
|
|
112
|
+
async function runProbed(o) {
|
|
113
|
+
const out = o.out ?? ((s) => process.stdout.write(s));
|
|
114
|
+
const err = o.err ?? ((s) => process.stderr.write(s));
|
|
115
|
+
mkdirSync(o.reportDir, { recursive: true });
|
|
116
|
+
const t = timeoutSecs(o.command);
|
|
117
|
+
const idle = Math.max(2, Math.min(o.idleSecs ?? DEFAULT_IDLE_SECS, t !== null ? t - 8 : Infinity));
|
|
118
|
+
const preload = join(o.reportDir, "preload.cjs");
|
|
119
|
+
writeFileSync(preload, PRELOAD_SOURCE);
|
|
120
|
+
const env = {
|
|
121
|
+
...process.env,
|
|
122
|
+
PAI_HANG_PROBE_DIR: o.reportDir,
|
|
123
|
+
NODE_OPTIONS: `${process.env.NODE_OPTIONS ?? ""} --require=${preload}`.trim()
|
|
124
|
+
};
|
|
125
|
+
const child = spawn("bash", ["-c", o.command], {
|
|
126
|
+
cwd: o.cwd,
|
|
127
|
+
env,
|
|
128
|
+
stdio: [
|
|
129
|
+
"ignore",
|
|
130
|
+
"pipe",
|
|
131
|
+
"pipe"
|
|
132
|
+
]
|
|
133
|
+
});
|
|
134
|
+
let last = Date.now();
|
|
135
|
+
let probing = false;
|
|
136
|
+
let announcedIdle = false;
|
|
137
|
+
let spun = false;
|
|
138
|
+
let pending = Promise.resolve();
|
|
139
|
+
child.stdout.on("data", (d) => (last = Date.now(), out(d.toString())));
|
|
140
|
+
child.stderr.on("data", (d) => (last = Date.now(), err(d.toString())));
|
|
141
|
+
const timer = setInterval(() => {
|
|
142
|
+
if (probing || spun || Date.now() - last < idle * 1e3 || !child.pid) return;
|
|
143
|
+
probing = true;
|
|
144
|
+
const pids = nodeDescendants(child.pid);
|
|
145
|
+
for (const p of pids) writeFileSync(join(o.reportDir, `probe-${p}`), "");
|
|
146
|
+
pending = collectFrames(o.reportDir, pids, 3e3).then((frames) => {
|
|
147
|
+
for (const p of pids) rmQuiet(join(o.reportDir, `probe-${p}`));
|
|
148
|
+
const stuck = frames.some((f) => userFrames(f, o.cwd).length > 0);
|
|
149
|
+
if (stuck || !announcedIdle) err(`\n${diagnose(frames, o.cwd, idle)}\n`);
|
|
150
|
+
announcedIdle = true;
|
|
151
|
+
probing = false;
|
|
152
|
+
if (stuck) {
|
|
153
|
+
spun = true;
|
|
154
|
+
for (const p of [...pids, child.pid]) killQuiet(p, "SIGTERM");
|
|
155
|
+
setTimeout(() => pids.forEach((p) => killQuiet(p, "SIGKILL")), 2e3).unref();
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}, 1e3);
|
|
159
|
+
return await new Promise((resolve) => {
|
|
160
|
+
child.on("close", (code, sig) => {
|
|
161
|
+
clearInterval(timer);
|
|
162
|
+
pending.then(() => resolve(spun ? 124 : code ?? (sig ? 128 + (sig === "SIGKILL" ? 9 : 15) : 1)));
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
/** Frames each probed pid reported (empty list: its main thread was idle); pids that never answered are left out. */
|
|
167
|
+
async function collectFrames(dir, pids, waitMs) {
|
|
168
|
+
const got = /* @__PURE__ */ new Map();
|
|
169
|
+
for (const end = Date.now() + waitMs; Date.now() < end && got.size < pids.length;) {
|
|
170
|
+
for (const p of pids) {
|
|
171
|
+
const f = join(dir, `frames-${p}.json`);
|
|
172
|
+
if (got.has(p) || !existsSync(f)) continue;
|
|
173
|
+
try {
|
|
174
|
+
got.set(p, JSON.parse(readFileSync(f, "utf8")).frames);
|
|
175
|
+
unlinkSync(f);
|
|
176
|
+
} catch {}
|
|
177
|
+
}
|
|
178
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
179
|
+
}
|
|
180
|
+
return [...got.values()];
|
|
181
|
+
}
|
|
182
|
+
/** Preloaded into every node process of the test run (CommonJS, so it also loads under --require). */
|
|
183
|
+
const PRELOAD_SOURCE = `"use strict";
|
|
184
|
+
const { Worker, isMainThread } = require("node:worker_threads");
|
|
185
|
+
if (isMainThread) {
|
|
186
|
+
const code = \`
|
|
187
|
+
const { existsSync, unlinkSync, writeFileSync, renameSync } = require("node:fs");
|
|
188
|
+
const { Session } = require("node:inspector");
|
|
189
|
+
const { workerData } = require("node:worker_threads");
|
|
190
|
+
const trigger = workerData.dir + "/probe-" + workerData.pid;
|
|
191
|
+
const done = (frames) => {
|
|
192
|
+
const tmp = workerData.dir + "/tmp-" + workerData.pid;
|
|
193
|
+
writeFileSync(tmp, JSON.stringify({ frames }));
|
|
194
|
+
renameSync(tmp, workerData.dir + "/frames-" + workerData.pid + ".json");
|
|
195
|
+
};
|
|
196
|
+
setInterval(() => {
|
|
197
|
+
if (!existsSync(trigger)) return;
|
|
198
|
+
try { unlinkSync(trigger); } catch {}
|
|
199
|
+
const s = new Session();
|
|
200
|
+
s.connectToMainThread();
|
|
201
|
+
let answered = false;
|
|
202
|
+
const urls = {}, maps = {};
|
|
203
|
+
s.on("Debugger.scriptParsed", (m) => { urls[m.params.scriptId] = m.params.url; maps[m.params.scriptId] = m.params.sourceMapURL; });
|
|
204
|
+
// transformed code (vite-node, tsx) has shifted lines: map back through its inline source map
|
|
205
|
+
const where = (f) => {
|
|
206
|
+
const id = f.location.scriptId;
|
|
207
|
+
let url = urls[id] || f.url, line = f.location.lineNumber;
|
|
208
|
+
const m = /^data:[^,]*;base64,(.*)$/.exec(maps[id] || "");
|
|
209
|
+
if (m) try {
|
|
210
|
+
const e = new (require("node:module").SourceMap)(JSON.parse(Buffer.from(m[1], "base64").toString())).findEntry(line, f.location.columnNumber || 0);
|
|
211
|
+
if (e && e.originalSource) { url = new URL(e.originalSource, url).href; line = e.originalLine; }
|
|
212
|
+
} catch {}
|
|
213
|
+
return { functionName: f.functionName, url, lineNumber: line };
|
|
214
|
+
};
|
|
215
|
+
s.on("Debugger.paused", (m) => {
|
|
216
|
+
answered = true;
|
|
217
|
+
done(m.params.callFrames.map(where));
|
|
218
|
+
s.post("Debugger.resume", () => s.post("Debugger.disable", () => s.disconnect()));
|
|
219
|
+
});
|
|
220
|
+
s.post("Debugger.enable", () => s.post("Debugger.pause"));
|
|
221
|
+
// an idle event loop runs no JS to pause in
|
|
222
|
+
setTimeout(() => { if (!answered) { done([]); s.post("Debugger.disable", () => s.disconnect()); } }, 800);
|
|
223
|
+
}, 200);
|
|
224
|
+
\`;
|
|
225
|
+
try {
|
|
226
|
+
new Worker(code, { eval: true, workerData: { dir: process.env.PAI_HANG_PROBE_DIR, pid: process.pid } }).unref();
|
|
227
|
+
} catch {}
|
|
228
|
+
}
|
|
229
|
+
`;
|
|
230
|
+
|
|
231
|
+
//#endregion
|
|
10
232
|
//#region src/workers/fallback.ts
|
|
11
233
|
/**
|
|
12
234
|
* fallback.ts — machine-wide Claude Code fallback to a worker provider.
|
|
@@ -271,5 +493,5 @@ function fallbackStatusText(s) {
|
|
|
271
493
|
}
|
|
272
494
|
|
|
273
495
|
//#endregion
|
|
274
|
-
export { fallbackStatusText as i, fallbackOn as n, fallbackStatus as r, fallbackOff as t };
|
|
275
|
-
//# sourceMappingURL=fallback-
|
|
496
|
+
export { DEFAULT_IDLE_SECS as a, fallbackStatusText as i, fallbackOn as n, commandToRun as o, fallbackStatus as r, runProbed as s, fallbackOff as t };
|
|
497
|
+
//# sourceMappingURL=fallback-CBWpp2F2.mjs.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { g as paiHomePath } from "./runtime-paths-WsO9sJFc.mjs";
|
|
2
2
|
import { t as ANTHROPIC_NATIVE } from "./config-XpZWOYOG.mjs";
|
|
3
|
-
import { A as budgetSkipReason, D as budgetExceeded, E as budgetCache, M as budgetWall } from "./routing-
|
|
3
|
+
import { A as budgetSkipReason, D as budgetExceeded, E as budgetCache, M as budgetWall } from "./routing-DmkheCRH.mjs";
|
|
4
4
|
import { n as tierProviderNames, t as isLocalCandidate } from "./local-candidate-DLdwQt0s.mjs";
|
|
5
5
|
import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { Chalk } from "chalk";
|
|
@@ -311,4 +311,4 @@ function saveBudgetSnapshot(map, now = Date.now()) {
|
|
|
311
311
|
|
|
312
312
|
//#endregion
|
|
313
313
|
export { colorEnabled as a, renderCommandHelp as c, renderOverview as d, renderTable as f, saveBudgetSnapshot as i, renderMarkdown as l, usageLine as m, readBudget as n, makeStyle as o, suggest as p, readBudgetSnapshot as r, mdCommand as s, providerHealth as t, renderMore as u };
|
|
314
|
-
//# sourceMappingURL=health-
|
|
314
|
+
//# sourceMappingURL=health-C4FQmkJn.mjs.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as getRegistryBackend } from "./factory-
|
|
1
|
+
import { i as getRegistryBackend } from "./factory-B7nv75rC.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/cli/impl/project/helpers.ts
|
|
4
4
|
/**
|
|
@@ -66,4 +66,4 @@ async function upsertTag(tagName) {
|
|
|
66
66
|
|
|
67
67
|
//#endregion
|
|
68
68
|
export { getSessionCount as a, upsertTag as c, getProjectTags as i, getProject as n, requireProject as o, getProjectAliases as r, resolveIdentifier as s, getLastSessionDate as t };
|
|
69
|
-
//# sourceMappingURL=helpers-
|
|
69
|
+
//# sourceMappingURL=helpers-DSNK_1KP.mjs.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./config-Bu1_vbY8.mjs";
|
|
2
2
|
import "./helpers-CRuBUas3.mjs";
|
|
3
|
-
import "./factory-
|
|
4
|
-
import "./postgres-
|
|
3
|
+
import "./factory-B7nv75rC.mjs";
|
|
4
|
+
import "./postgres-DNIOQijl.mjs";
|
|
5
5
|
import "./embedding-gate-6rZrWRXa.mjs";
|
|
6
6
|
import "./embeddings-BVq3esBF.mjs";
|
|
7
7
|
import "./router-CQSc3lk3.mjs";
|
|
8
|
-
import { a as getSessionCount, c as upsertTag, i as getProjectTags, n as getProject, o as requireProject, r as getProjectAliases, s as resolveIdentifier, t as getLastSessionDate } from "./helpers-
|
|
8
|
+
import { a as getSessionCount, c as upsertTag, i as getProjectTags, n as getProject, o as requireProject, r as getProjectAliases, s as resolveIdentifier, t as getLastSessionDate } from "./helpers-DSNK_1KP.mjs";
|
|
9
9
|
|
|
10
10
|
export { getProject };
|
|
@@ -7738,8 +7738,18 @@ function maskSecrets(text) {
|
|
|
7738
7738
|
return text.split("\n").map((l) => SECRET_LINE.test(l) ? MASKED_LINE : l).join("\n");
|
|
7739
7739
|
}
|
|
7740
7740
|
|
|
7741
|
+
// src/utils/hash.ts
|
|
7742
|
+
import { createHash } from "node:crypto";
|
|
7743
|
+
function sha256(content) {
|
|
7744
|
+
return createHash("sha256").update(content).digest("hex");
|
|
7745
|
+
}
|
|
7746
|
+
|
|
7741
7747
|
// src/hooks/ts/lib/raw-capture.ts
|
|
7742
7748
|
var RAW_CAPTURE_MAX_BYTES = 10 * 1024 * 1024;
|
|
7749
|
+
function captureEventId(parts) {
|
|
7750
|
+
const joined = `${parts.sessionId ?? ""}|${parts.toolUseId ?? ""}|${parts.event ?? ""}|${parts.ts ?? ""}`;
|
|
7751
|
+
return sha256(joined).slice(0, 16);
|
|
7752
|
+
}
|
|
7743
7753
|
function redactDeep(value) {
|
|
7744
7754
|
if (typeof value === "string") return maskSecrets(value);
|
|
7745
7755
|
if (Array.isArray(value)) return value.map(redactDeep);
|
|
@@ -7855,13 +7865,22 @@ async function main() {
|
|
|
7855
7865
|
setAgentForSession(sessionId, agentName);
|
|
7856
7866
|
}
|
|
7857
7867
|
}
|
|
7868
|
+
const timestamp = Date.now();
|
|
7858
7869
|
let event = {
|
|
7859
7870
|
source_app: agentName,
|
|
7860
7871
|
session_id: hookData.session_id || "main",
|
|
7861
7872
|
hook_event_type: eventType,
|
|
7862
7873
|
payload: redactDeep(hookData),
|
|
7863
|
-
timestamp
|
|
7864
|
-
timestamp_local: getLocalTimestamp()
|
|
7874
|
+
timestamp,
|
|
7875
|
+
timestamp_local: getLocalTimestamp(),
|
|
7876
|
+
source: "hook",
|
|
7877
|
+
fidelity: "observed",
|
|
7878
|
+
eventId: captureEventId({
|
|
7879
|
+
sessionId: hookData.session_id,
|
|
7880
|
+
toolUseId: hookData.tool_use_id,
|
|
7881
|
+
event: eventType,
|
|
7882
|
+
ts: String(timestamp)
|
|
7883
|
+
})
|
|
7865
7884
|
};
|
|
7866
7885
|
if (isAgentSpawningCall(hookData.tool_name, hookData.tool_input)) {
|
|
7867
7886
|
event = enrichEventWithAgentMetadata(
|
|
@@ -155,8 +155,18 @@ function maskSecrets(text) {
|
|
|
155
155
|
return text.split("\n").map((l) => SECRET_LINE.test(l) ? MASKED_LINE : l).join("\n");
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
+
// src/utils/hash.ts
|
|
159
|
+
import { createHash } from "node:crypto";
|
|
160
|
+
function sha256(content) {
|
|
161
|
+
return createHash("sha256").update(content).digest("hex");
|
|
162
|
+
}
|
|
163
|
+
|
|
158
164
|
// src/hooks/ts/lib/raw-capture.ts
|
|
159
165
|
var RAW_CAPTURE_MAX_BYTES = 10 * 1024 * 1024;
|
|
166
|
+
function captureEventId(parts) {
|
|
167
|
+
const joined = `${parts.sessionId ?? ""}|${parts.toolUseId ?? ""}|${parts.event ?? ""}|${parts.ts ?? ""}`;
|
|
168
|
+
return sha256(joined).slice(0, 16);
|
|
169
|
+
}
|
|
160
170
|
function redactDeep(value) {
|
|
161
171
|
if (typeof value === "string") return maskSecrets(value);
|
|
162
172
|
if (Array.isArray(value)) return value.map(redactDeep);
|
|
@@ -202,12 +212,21 @@ async function main() {
|
|
|
202
212
|
const yearMonth = today.substring(0, 7);
|
|
203
213
|
const dateDir = join3(CAPTURE_DIR, yearMonth);
|
|
204
214
|
const captureFile = join3(dateDir, `${today}_tool-outputs.jsonl`);
|
|
215
|
+
const timestamp = data.timestamp || now.toISOString();
|
|
205
216
|
const captureEntry = JSON.stringify({
|
|
206
|
-
timestamp
|
|
217
|
+
timestamp,
|
|
207
218
|
tool: data.tool_name,
|
|
208
219
|
input: redactDeep(data.tool_input),
|
|
209
220
|
output: redactDeep(data.tool_response),
|
|
210
|
-
session: data.session_id
|
|
221
|
+
session: data.session_id,
|
|
222
|
+
source: "hook",
|
|
223
|
+
fidelity: "observed",
|
|
224
|
+
eventId: captureEventId({
|
|
225
|
+
sessionId: data.session_id,
|
|
226
|
+
toolUseId: data.tool_use_id,
|
|
227
|
+
event: "PostToolUse",
|
|
228
|
+
ts: timestamp
|
|
229
|
+
})
|
|
211
230
|
}) + "\n";
|
|
212
231
|
appendRawCapture(captureFile, dateDir, captureEntry);
|
|
213
232
|
process.exit(0);
|
|
@@ -20935,6 +20935,17 @@ var init_kg_triples = __esm({
|
|
|
20935
20935
|
async function ensureObservationTables(pool) {
|
|
20936
20936
|
if (_tablesEnsured) return;
|
|
20937
20937
|
await pool.query(SCHEMA_SQL);
|
|
20938
|
+
const colCheck = await pool.query(
|
|
20939
|
+
`SELECT column_name FROM information_schema.columns
|
|
20940
|
+
WHERE table_name = 'pai_observations' AND column_name IN ('source', 'fidelity')`
|
|
20941
|
+
);
|
|
20942
|
+
const existing = new Set(colCheck.rows.map((r) => r.column_name));
|
|
20943
|
+
if (!existing.has("source")) {
|
|
20944
|
+
await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS source TEXT");
|
|
20945
|
+
}
|
|
20946
|
+
if (!existing.has("fidelity")) {
|
|
20947
|
+
await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS fidelity TEXT");
|
|
20948
|
+
}
|
|
20938
20949
|
_tablesEnsured = true;
|
|
20939
20950
|
}
|
|
20940
20951
|
async function ensureSkillTelemetryTable(pool) {
|
|
@@ -20962,8 +20973,9 @@ async function storeObservation(pool, obs) {
|
|
|
20962
20973
|
const result = await pool.query(
|
|
20963
20974
|
`INSERT INTO pai_observations
|
|
20964
20975
|
(session_id, project_id, project_slug, type, title, narrative,
|
|
20965
|
-
tool_name, tool_input_summary, files_read, files_modified, concepts, content_hash
|
|
20966
|
-
|
|
20976
|
+
tool_name, tool_input_summary, files_read, files_modified, concepts, content_hash,
|
|
20977
|
+
source, fidelity)
|
|
20978
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::jsonb, $10::jsonb, $11::jsonb, $12, $13, $14)
|
|
20967
20979
|
RETURNING id`,
|
|
20968
20980
|
[
|
|
20969
20981
|
obs.session_id,
|
|
@@ -20977,7 +20989,9 @@ async function storeObservation(pool, obs) {
|
|
|
20977
20989
|
JSON.stringify(obs.files_read),
|
|
20978
20990
|
JSON.stringify(obs.files_modified),
|
|
20979
20991
|
JSON.stringify(obs.concepts),
|
|
20980
|
-
hash
|
|
20992
|
+
hash,
|
|
20993
|
+
obs.source ?? null,
|
|
20994
|
+
obs.fidelity ?? null
|
|
20981
20995
|
]
|
|
20982
20996
|
);
|
|
20983
20997
|
return result.rows[0]?.id ?? null;
|
|
@@ -21019,7 +21033,7 @@ async function queryObservations(pool, opts = {}) {
|
|
|
21019
21033
|
`SELECT id, session_id, project_id, project_slug, type, title, narrative,
|
|
21020
21034
|
tool_name, tool_input_summary,
|
|
21021
21035
|
files_read, files_modified, concepts,
|
|
21022
|
-
content_hash, created_at
|
|
21036
|
+
content_hash, source, fidelity, created_at
|
|
21023
21037
|
FROM pai_observations
|
|
21024
21038
|
${where}
|
|
21025
21039
|
ORDER BY created_at DESC
|
|
@@ -21034,7 +21048,7 @@ async function queryRecentObservations(pool, projectId, limit) {
|
|
|
21034
21048
|
`SELECT id, session_id, project_id, project_slug, type, title, narrative,
|
|
21035
21049
|
tool_name, tool_input_summary,
|
|
21036
21050
|
files_read, files_modified, concepts,
|
|
21037
|
-
content_hash, created_at
|
|
21051
|
+
content_hash, source, fidelity, created_at
|
|
21038
21052
|
FROM pai_observations
|
|
21039
21053
|
WHERE project_id = $1
|
|
21040
21054
|
ORDER BY created_at DESC
|
|
@@ -21049,7 +21063,7 @@ async function querySessionObservations(pool, sessionId) {
|
|
|
21049
21063
|
`SELECT id, session_id, project_id, project_slug, type, title, narrative,
|
|
21050
21064
|
tool_name, tool_input_summary,
|
|
21051
21065
|
files_read, files_modified, concepts,
|
|
21052
|
-
content_hash, created_at
|
|
21066
|
+
content_hash, source, fidelity, created_at
|
|
21053
21067
|
FROM pai_observations
|
|
21054
21068
|
WHERE session_id = $1
|
|
21055
21069
|
ORDER BY created_at ASC`,
|
|
@@ -21219,6 +21233,8 @@ CREATE TABLE IF NOT EXISTS pai_observations (
|
|
|
21219
21233
|
files_modified JSONB DEFAULT '[]'::jsonb,
|
|
21220
21234
|
concepts JSONB DEFAULT '[]'::jsonb,
|
|
21221
21235
|
content_hash TEXT,
|
|
21236
|
+
source TEXT,
|
|
21237
|
+
fidelity TEXT,
|
|
21222
21238
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
21223
21239
|
);
|
|
21224
21240
|
|
|
@@ -27711,6 +27727,16 @@ var init_route_table = __esm({
|
|
|
27711
27727
|
}
|
|
27712
27728
|
});
|
|
27713
27729
|
|
|
27730
|
+
// src/router/cockpit-auth.ts
|
|
27731
|
+
var init_cockpit_auth = __esm({
|
|
27732
|
+
"src/router/cockpit-auth.ts"() {
|
|
27733
|
+
"use strict";
|
|
27734
|
+
init_pai_home();
|
|
27735
|
+
init_loopback();
|
|
27736
|
+
init_timeouts();
|
|
27737
|
+
}
|
|
27738
|
+
});
|
|
27739
|
+
|
|
27714
27740
|
// src/router/router.ts
|
|
27715
27741
|
var routerPort;
|
|
27716
27742
|
var init_router2 = __esm({
|
|
@@ -27730,6 +27756,7 @@ var init_router2 = __esm({
|
|
|
27730
27756
|
init_local_instances();
|
|
27731
27757
|
init_route_table();
|
|
27732
27758
|
init_loopback_guard();
|
|
27759
|
+
init_cockpit_auth();
|
|
27733
27760
|
routerPort = () => loadConfig().router.port;
|
|
27734
27761
|
}
|
|
27735
27762
|
});
|
|
@@ -28014,6 +28041,13 @@ function requestKill(logDir2, ledger, id, by = callerDescription(), forced = fal
|
|
|
28014
28041
|
writeFileAtomic(killMarkerPath(logDir2, id), JSON.stringify(req));
|
|
28015
28042
|
appendLedger(ledger, "WORKER-KILL", { id, by, pid: req.pid, ppid: req.ppid, cwd: req.cwd, ...forced ? { forced: 1 } : {}, ...reason ? { reason } : {} });
|
|
28016
28043
|
}
|
|
28044
|
+
function peekMarker(logDir2, id) {
|
|
28045
|
+
try {
|
|
28046
|
+
return JSON.parse(readFileSync36(killMarkerPath(logDir2, id), "utf8"));
|
|
28047
|
+
} catch {
|
|
28048
|
+
return null;
|
|
28049
|
+
}
|
|
28050
|
+
}
|
|
28017
28051
|
function readMarker(logDir2, id) {
|
|
28018
28052
|
const p = killMarkerPath(logDir2, id);
|
|
28019
28053
|
if (!existsSync36(p)) return null;
|
|
@@ -28047,8 +28081,11 @@ function parentInfo() {
|
|
|
28047
28081
|
function decideEndReason(a) {
|
|
28048
28082
|
if (a.timedOut) return { reason: "deadline" };
|
|
28049
28083
|
if (a.loopStopped) return { reason: "loop-stopped" };
|
|
28050
|
-
|
|
28051
|
-
|
|
28084
|
+
const marker = a.signal || peekMarker(a.logDir, a.id)?.by === "pane audit" ? readMarker(a.logDir, a.id) : null;
|
|
28085
|
+
if (!a.signal && !marker) return { reason: "exit" };
|
|
28086
|
+
if (!a.signal && marker) {
|
|
28087
|
+
return { reason: "pai-worker-kill", by: marker.by, note: `killed by ${marker.by}${marker.reason ? `: ${marker.reason}` : ""}`, ...marker.reason ? { killReason: marker.reason } : {}, forced: true };
|
|
28088
|
+
}
|
|
28052
28089
|
if (marker) {
|
|
28053
28090
|
return {
|
|
28054
28091
|
reason: "pai-worker-kill",
|
|
@@ -30957,6 +30994,7 @@ function fireDeadline(logDir2, status, ledger, limit) {
|
|
|
30957
30994
|
status.last = what;
|
|
30958
30995
|
saveStatus(logDir2, status);
|
|
30959
30996
|
appendLedger(ledger, "WORKER-DEADLINE", { id: status.id, minutes: limit.minutes, waitedMin: waited });
|
|
30997
|
+
appendStopEvent(logDir2, status.id, { killed_by: "deadline", forced: false, reason: `${what} (timer: --max-minutes/--deadline, armed at spawn)` });
|
|
30960
30998
|
void killTree(logDir2, status.id, { skipRoot: true, by: "deadline", reason: `parent worker ${what}` }).catch(() => void 0);
|
|
30961
30999
|
}
|
|
30962
31000
|
function trackBlocked(logDir2, status, limit) {
|
|
@@ -31032,6 +31070,10 @@ async function finaliseRun(f) {
|
|
|
31032
31070
|
}
|
|
31033
31071
|
const end = decideEndReason({ logDir: logDir2, id: wid, timedOut: f.timedOut !== void 0, loopStopped: !!loopStop });
|
|
31034
31072
|
status.endReason = end.reason;
|
|
31073
|
+
if (end.reason === "pai-worker-kill" && !f.timedOut && end.killReason && !succeeded) {
|
|
31074
|
+
status.last = shortText(end.killReason, 90);
|
|
31075
|
+
report = { ...report ?? {}, result: report?.result ?? "-", why: end.killReason, notes: [end.killReason, report?.notes ?? f.fallbackText].filter(Boolean).join("\n") };
|
|
31076
|
+
}
|
|
31035
31077
|
status.claimsContinue = report?.result === "~";
|
|
31036
31078
|
saveStatus(logDir2, status);
|
|
31037
31079
|
appendLedger(ledger, "WORKER-END", { id: wid, ...f.end, rc, secs: f.secs, ...endFields(end) });
|
|
@@ -31658,7 +31700,8 @@ async function openOwnedPane(o) {
|
|
|
31658
31700
|
let pidWaiter = null;
|
|
31659
31701
|
let ended = false;
|
|
31660
31702
|
let startedAt = 0;
|
|
31661
|
-
const
|
|
31703
|
+
const openedAt = Date.now();
|
|
31704
|
+
const record = (extra = {}) => writeJson(recordPath(o.id), { id: o.id, kind: o.kind, caller: process.pid, wrapper: wrapper || void 0, session, openedMs: openedAt, startedMs: startedAt || openedAt, ...extra });
|
|
31662
31705
|
const settle = (code, signal) => {
|
|
31663
31706
|
if (ended) return;
|
|
31664
31707
|
ended = true;
|
|
@@ -10565,6 +10565,7 @@ var init_pane_audit = __esm({
|
|
|
10565
10565
|
init_ledger();
|
|
10566
10566
|
init_paths();
|
|
10567
10567
|
init_kill_tree();
|
|
10568
|
+
init_endreason();
|
|
10568
10569
|
init_status();
|
|
10569
10570
|
init_plan_status();
|
|
10570
10571
|
init_pane_run();
|
|
@@ -18041,6 +18042,17 @@ var init_kg_triples = __esm({
|
|
|
18041
18042
|
async function ensureObservationTables(pool) {
|
|
18042
18043
|
if (_tablesEnsured) return;
|
|
18043
18044
|
await pool.query(SCHEMA_SQL);
|
|
18045
|
+
const colCheck = await pool.query(
|
|
18046
|
+
`SELECT column_name FROM information_schema.columns
|
|
18047
|
+
WHERE table_name = 'pai_observations' AND column_name IN ('source', 'fidelity')`
|
|
18048
|
+
);
|
|
18049
|
+
const existing = new Set(colCheck.rows.map((r) => r.column_name));
|
|
18050
|
+
if (!existing.has("source")) {
|
|
18051
|
+
await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS source TEXT");
|
|
18052
|
+
}
|
|
18053
|
+
if (!existing.has("fidelity")) {
|
|
18054
|
+
await pool.query("ALTER TABLE pai_observations ADD COLUMN IF NOT EXISTS fidelity TEXT");
|
|
18055
|
+
}
|
|
18044
18056
|
_tablesEnsured = true;
|
|
18045
18057
|
}
|
|
18046
18058
|
async function ensureSkillTelemetryTable(pool) {
|
|
@@ -18068,8 +18080,9 @@ async function storeObservation(pool, obs) {
|
|
|
18068
18080
|
const result = await pool.query(
|
|
18069
18081
|
`INSERT INTO pai_observations
|
|
18070
18082
|
(session_id, project_id, project_slug, type, title, narrative,
|
|
18071
|
-
tool_name, tool_input_summary, files_read, files_modified, concepts, content_hash
|
|
18072
|
-
|
|
18083
|
+
tool_name, tool_input_summary, files_read, files_modified, concepts, content_hash,
|
|
18084
|
+
source, fidelity)
|
|
18085
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9::jsonb, $10::jsonb, $11::jsonb, $12, $13, $14)
|
|
18073
18086
|
RETURNING id`,
|
|
18074
18087
|
[
|
|
18075
18088
|
obs.session_id,
|
|
@@ -18083,7 +18096,9 @@ async function storeObservation(pool, obs) {
|
|
|
18083
18096
|
JSON.stringify(obs.files_read),
|
|
18084
18097
|
JSON.stringify(obs.files_modified),
|
|
18085
18098
|
JSON.stringify(obs.concepts),
|
|
18086
|
-
hash
|
|
18099
|
+
hash,
|
|
18100
|
+
obs.source ?? null,
|
|
18101
|
+
obs.fidelity ?? null
|
|
18087
18102
|
]
|
|
18088
18103
|
);
|
|
18089
18104
|
return result.rows[0]?.id ?? null;
|
|
@@ -18125,7 +18140,7 @@ async function queryObservations(pool, opts = {}) {
|
|
|
18125
18140
|
`SELECT id, session_id, project_id, project_slug, type, title, narrative,
|
|
18126
18141
|
tool_name, tool_input_summary,
|
|
18127
18142
|
files_read, files_modified, concepts,
|
|
18128
|
-
content_hash, created_at
|
|
18143
|
+
content_hash, source, fidelity, created_at
|
|
18129
18144
|
FROM pai_observations
|
|
18130
18145
|
${where}
|
|
18131
18146
|
ORDER BY created_at DESC
|
|
@@ -18140,7 +18155,7 @@ async function queryRecentObservations(pool, projectId, limit) {
|
|
|
18140
18155
|
`SELECT id, session_id, project_id, project_slug, type, title, narrative,
|
|
18141
18156
|
tool_name, tool_input_summary,
|
|
18142
18157
|
files_read, files_modified, concepts,
|
|
18143
|
-
content_hash, created_at
|
|
18158
|
+
content_hash, source, fidelity, created_at
|
|
18144
18159
|
FROM pai_observations
|
|
18145
18160
|
WHERE project_id = $1
|
|
18146
18161
|
ORDER BY created_at DESC
|
|
@@ -18155,7 +18170,7 @@ async function querySessionObservations(pool, sessionId) {
|
|
|
18155
18170
|
`SELECT id, session_id, project_id, project_slug, type, title, narrative,
|
|
18156
18171
|
tool_name, tool_input_summary,
|
|
18157
18172
|
files_read, files_modified, concepts,
|
|
18158
|
-
content_hash, created_at
|
|
18173
|
+
content_hash, source, fidelity, created_at
|
|
18159
18174
|
FROM pai_observations
|
|
18160
18175
|
WHERE session_id = $1
|
|
18161
18176
|
ORDER BY created_at ASC`,
|
|
@@ -18325,6 +18340,8 @@ CREATE TABLE IF NOT EXISTS pai_observations (
|
|
|
18325
18340
|
files_modified JSONB DEFAULT '[]'::jsonb,
|
|
18326
18341
|
concepts JSONB DEFAULT '[]'::jsonb,
|
|
18327
18342
|
content_hash TEXT,
|
|
18343
|
+
source TEXT,
|
|
18344
|
+
fidelity TEXT,
|
|
18328
18345
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
18329
18346
|
);
|
|
18330
18347
|
|
|
@@ -24629,6 +24646,16 @@ var init_loopback_guard = __esm({
|
|
|
24629
24646
|
}
|
|
24630
24647
|
});
|
|
24631
24648
|
|
|
24649
|
+
// src/router/cockpit-auth.ts
|
|
24650
|
+
var init_cockpit_auth = __esm({
|
|
24651
|
+
"src/router/cockpit-auth.ts"() {
|
|
24652
|
+
"use strict";
|
|
24653
|
+
init_pai_home();
|
|
24654
|
+
init_loopback();
|
|
24655
|
+
init_timeouts();
|
|
24656
|
+
}
|
|
24657
|
+
});
|
|
24658
|
+
|
|
24632
24659
|
// src/router/router.ts
|
|
24633
24660
|
var init_router2 = __esm({
|
|
24634
24661
|
"src/router/router.ts"() {
|
|
@@ -24647,6 +24674,7 @@ var init_router2 = __esm({
|
|
|
24647
24674
|
init_local_instances();
|
|
24648
24675
|
init_route_table();
|
|
24649
24676
|
init_loopback_guard();
|
|
24677
|
+
init_cockpit_auth();
|
|
24650
24678
|
}
|
|
24651
24679
|
});
|
|
24652
24680
|
|