@oratis/lisa 0.3.0 → 0.4.0
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/README.md +34 -5
- package/README.zh-CN.md +34 -5
- package/dist/advisor/detectors.d.ts +25 -0
- package/dist/advisor/detectors.d.ts.map +1 -0
- package/dist/advisor/detectors.js +161 -0
- package/dist/advisor/detectors.js.map +1 -0
- package/dist/advisor/engine.d.ts +41 -0
- package/dist/advisor/engine.d.ts.map +1 -0
- package/dist/advisor/engine.js +156 -0
- package/dist/advisor/engine.js.map +1 -0
- package/dist/advisor/types.d.ts +68 -0
- package/dist/advisor/types.d.ts.map +1 -0
- package/dist/advisor/types.js +19 -0
- package/dist/advisor/types.js.map +1 -0
- package/dist/channels/imessage.d.ts +16 -0
- package/dist/channels/imessage.d.ts.map +1 -1
- package/dist/channels/imessage.js +29 -8
- package/dist/channels/imessage.js.map +1 -1
- package/dist/heartbeat/config.d.ts +10 -0
- package/dist/heartbeat/config.d.ts.map +1 -1
- package/dist/heartbeat/config.js +8 -2
- package/dist/heartbeat/config.js.map +1 -1
- package/dist/heartbeat/runner.d.ts.map +1 -1
- package/dist/heartbeat/runner.js +30 -0
- package/dist/heartbeat/runner.js.map +1 -1
- package/dist/integrations/claude-code/observer.d.ts +19 -0
- package/dist/integrations/claude-code/observer.d.ts.map +1 -0
- package/dist/integrations/claude-code/observer.js +59 -0
- package/dist/integrations/claude-code/observer.js.map +1 -0
- package/dist/integrations/claude-code/parser.d.ts +2 -0
- package/dist/integrations/claude-code/parser.d.ts.map +1 -1
- package/dist/integrations/claude-code/parser.js +153 -0
- package/dist/integrations/claude-code/parser.js.map +1 -1
- package/dist/integrations/claude-code/watcher.d.ts +9 -0
- package/dist/integrations/claude-code/watcher.d.ts.map +1 -1
- package/dist/integrations/claude-code/watcher.js +25 -4
- package/dist/integrations/claude-code/watcher.js.map +1 -1
- package/dist/integrations/codex/observer.d.ts +48 -0
- package/dist/integrations/codex/observer.d.ts.map +1 -0
- package/dist/integrations/codex/observer.js +213 -0
- package/dist/integrations/codex/observer.js.map +1 -0
- package/dist/integrations/current-hub.d.ts +13 -0
- package/dist/integrations/current-hub.d.ts.map +1 -0
- package/dist/integrations/current-hub.js +17 -0
- package/dist/integrations/current-hub.js.map +1 -0
- package/dist/integrations/hub.d.ts +45 -0
- package/dist/integrations/hub.d.ts.map +1 -0
- package/dist/integrations/hub.js +110 -0
- package/dist/integrations/hub.js.map +1 -0
- package/dist/integrations/registry.d.ts +15 -0
- package/dist/integrations/registry.d.ts.map +1 -0
- package/dist/integrations/registry.js +38 -0
- package/dist/integrations/registry.js.map +1 -0
- package/dist/integrations/types.d.ts +90 -0
- package/dist/integrations/types.d.ts.map +1 -0
- package/dist/integrations/types.js +12 -0
- package/dist/integrations/types.js.map +1 -0
- package/dist/memory/vector.d.ts +5 -1
- package/dist/memory/vector.d.ts.map +1 -1
- package/dist/memory/vector.js +58 -1
- package/dist/memory/vector.js.map +1 -1
- package/dist/soul/lock.d.ts +38 -0
- package/dist/soul/lock.d.ts.map +1 -0
- package/dist/soul/lock.js +103 -0
- package/dist/soul/lock.js.map +1 -0
- package/dist/soul/paths.d.ts.map +1 -1
- package/dist/soul/paths.js +12 -6
- package/dist/soul/paths.js.map +1 -1
- package/dist/soul/slug.d.ts +40 -0
- package/dist/soul/slug.d.ts.map +1 -0
- package/dist/soul/slug.js +78 -0
- package/dist/soul/slug.js.map +1 -0
- package/dist/soul/store.d.ts +12 -1
- package/dist/soul/store.d.ts.map +1 -1
- package/dist/soul/store.js +40 -23
- package/dist/soul/store.js.map +1 -1
- package/dist/soul/tools.d.ts.map +1 -1
- package/dist/soul/tools.js +10 -3
- package/dist/soul/tools.js.map +1 -1
- package/dist/tools/advise_now.d.ts +11 -0
- package/dist/tools/advise_now.d.ts.map +1 -0
- package/dist/tools/advise_now.js +34 -0
- package/dist/tools/advise_now.js.map +1 -0
- package/dist/tools/dispatch_agent.d.ts +38 -0
- package/dist/tools/dispatch_agent.d.ts.map +1 -0
- package/dist/tools/dispatch_agent.js +145 -0
- package/dist/tools/dispatch_agent.js.map +1 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/web_fetch.d.ts +10 -0
- package/dist/tools/web_fetch.d.ts.map +1 -1
- package/dist/tools/web_fetch.js +48 -16
- package/dist/tools/web_fetch.js.map +1 -1
- package/dist/web/island.d.ts +1 -1
- package/dist/web/island.d.ts.map +1 -1
- package/dist/web/island.js +69 -5
- package/dist/web/island.js.map +1 -1
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +79 -16
- package/dist/web/server.js.map +1 -1
- package/package.json +3 -1
|
@@ -39,7 +39,7 @@ import fsp from "node:fs/promises";
|
|
|
39
39
|
import path from "node:path";
|
|
40
40
|
import os from "node:os";
|
|
41
41
|
import { EventEmitter } from "node:events";
|
|
42
|
-
import { parseSessionState } from "./parser.js";
|
|
42
|
+
import { parseSessionState, parseSessionActivity } from "./parser.js";
|
|
43
43
|
const CLAUDE_HOME = process.env.CLAUDE_HOME ?? path.join(os.homedir(), ".claude");
|
|
44
44
|
const PROJECTS_DIR = path.join(CLAUDE_HOME, "projects");
|
|
45
45
|
const DEBOUNCE_MS = 200;
|
|
@@ -76,10 +76,14 @@ export class ClaudeCodeWatcher extends EventEmitter {
|
|
|
76
76
|
repollTimer = null;
|
|
77
77
|
pendingChanges = new Map();
|
|
78
78
|
log;
|
|
79
|
+
computeActivity;
|
|
79
80
|
started = false;
|
|
80
81
|
constructor(opts = {}) {
|
|
81
82
|
super();
|
|
82
83
|
this.log = opts.log ?? (() => { });
|
|
84
|
+
// O2: only extract Tier-2 structural activity when asked (visibility ≥
|
|
85
|
+
// "activity"). Default off preserves the metadata-only behavior.
|
|
86
|
+
this.computeActivity = opts.computeActivity ?? false;
|
|
83
87
|
this.setMaxListeners(32);
|
|
84
88
|
}
|
|
85
89
|
/** Begin watching. Idempotent. Survives ~/.claude/projects not existing yet. */
|
|
@@ -151,7 +155,10 @@ export class ClaudeCodeWatcher extends EventEmitter {
|
|
|
151
155
|
if (!st.isFile())
|
|
152
156
|
return;
|
|
153
157
|
const parsed = await parseSessionState(filePath);
|
|
154
|
-
const
|
|
158
|
+
const activity = this.computeActivity
|
|
159
|
+
? await parseSessionActivity(filePath)
|
|
160
|
+
: undefined;
|
|
161
|
+
const info = this.makeInfo(filePath, st.mtimeMs, st.size, parsed.state, parsed.reason, parsed.cwd, activity);
|
|
155
162
|
this.sessions.set(filePath, info);
|
|
156
163
|
}
|
|
157
164
|
catch {
|
|
@@ -225,7 +232,10 @@ export class ClaudeCodeWatcher extends EventEmitter {
|
|
|
225
232
|
return;
|
|
226
233
|
const prev = this.sessions.get(fullPath);
|
|
227
234
|
const parsed = await parseSessionState(fullPath);
|
|
228
|
-
const
|
|
235
|
+
const activity = this.computeActivity
|
|
236
|
+
? await parseSessionActivity(fullPath)
|
|
237
|
+
: undefined;
|
|
238
|
+
const info = this.makeInfo(fullPath, st.mtimeMs, st.size, parsed.state, parsed.reason, parsed.cwd, activity);
|
|
229
239
|
this.sessions.set(fullPath, info);
|
|
230
240
|
if (!prev) {
|
|
231
241
|
this.emitUpdate("new", info);
|
|
@@ -256,7 +266,7 @@ export class ClaudeCodeWatcher extends EventEmitter {
|
|
|
256
266
|
};
|
|
257
267
|
this.emit("update", payload);
|
|
258
268
|
}
|
|
259
|
-
makeInfo(filePath, mtimeMs, size, state, stateReason, cwd) {
|
|
269
|
+
makeInfo(filePath, mtimeMs, size, state, stateReason, cwd, activity) {
|
|
260
270
|
const sessionId = path.basename(filePath, ".jsonl");
|
|
261
271
|
const projectEncoded = path.basename(path.dirname(filePath));
|
|
262
272
|
// Staleness heuristic: any "working" session whose jsonl hasn't
|
|
@@ -285,6 +295,16 @@ export class ClaudeCodeWatcher extends EventEmitter {
|
|
|
285
295
|
finalState = "waiting";
|
|
286
296
|
finalReason = stateReason === "tool_use" ? "permission" : "idle";
|
|
287
297
|
}
|
|
298
|
+
// When the session is blocked on a permission decision, surface which
|
|
299
|
+
// tool it's waiting on (the most recent tool name) — drives the advisor's
|
|
300
|
+
// "Codex wants to run X — approve?" prompts.
|
|
301
|
+
let finalActivity = activity;
|
|
302
|
+
if (finalActivity && finalReason === "permission" && finalActivity.lastTools.length) {
|
|
303
|
+
finalActivity = {
|
|
304
|
+
...finalActivity,
|
|
305
|
+
pendingPermission: finalActivity.lastTools[finalActivity.lastTools.length - 1],
|
|
306
|
+
};
|
|
307
|
+
}
|
|
288
308
|
return {
|
|
289
309
|
projectEncoded,
|
|
290
310
|
projectLabel: decodeProjectLabel(projectEncoded),
|
|
@@ -294,6 +314,7 @@ export class ClaudeCodeWatcher extends EventEmitter {
|
|
|
294
314
|
state: finalState,
|
|
295
315
|
stateReason: finalReason,
|
|
296
316
|
cwd,
|
|
317
|
+
activity: finalActivity,
|
|
297
318
|
};
|
|
298
319
|
}
|
|
299
320
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/integrations/claude-code/watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,GAAG,MAAM,kBAAkB,CAAC;AACnC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAA2B,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/integrations/claude-code/watcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,GAAG,MAAM,kBAAkB,CAAC;AACnC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAA2B,MAAM,aAAa,CAAC;AAG/F,MAAM,WAAW,GAAS,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AACxF,MAAM,YAAY,GAAQ,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;AAC7D,MAAM,WAAW,GAAS,GAAG,CAAC;AAC9B,MAAM,gBAAgB,GAAI,EAAE,GAAG,MAAM,CAAC;AACtC,MAAM,UAAU,GAAU,EAAE,CAAC;AAE7B;;;;;;;;;;;;;;;GAeG;AACH,MAAM,gCAAgC,GAAG,KAAK,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,KAAK,CAAC;AAgDjC,MAAM,OAAO,iBAAkB,SAAQ,YAAY;IACzC,QAAQ,GAAG,IAAI,GAAG,EAA6B,CAAC,CAAC,kBAAkB;IACnE,OAAO,GAAwB,IAAI,CAAC;IACpC,UAAU,GAA0B,IAAI,CAAC;IACzC,WAAW,GAA0B,IAAI,CAAC;IAC1C,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC1C,GAAG,CAAM;IACT,eAAe,CAAU;IAClC,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,OAAiD,EAAE;QAC7D,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAClC,uEAAuE;QACvE,iEAAiE;QACjE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,eAAe,IAAI,KAAK,CAAC;QACrD,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;IAC3B,CAAC;IAED,gFAAgF;IAChF,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;QACzB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC3B,IAAI,CAAC,eAAe,EAAE,CAAC;IACzB,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,IAAI,CAAC,UAAU;YAAE,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,IAAI,CAAC,WAAW;YAAE,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACtD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;YAAE,YAAY,CAAC,CAAC,CAAC,CAAC;QAC9D,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;IAC9B,CAAC;IAED,kEAAkE;IAClE,UAAU;QACR,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC;QAC7C,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;aAC/B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,MAAM,CAAC;aACpC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;aACzC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAC1B,CAAC;IAED,oEAAoE;IAE5D,KAAK,CAAC,WAAW;QACvB,IAAI,WAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,WAAW,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAChD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,GAAG,GAA4B,CAAC;YACvC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACxB,IAAI,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO;QACT,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;YAC9B,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;gBAAE,SAAS;YAClC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;YACjD,IAAI,YAAY,GAAa,EAAE,CAAC;YAChC,IAAI,CAAC;gBACH,YAAY,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAChD,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;YACD,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;gBAC7B,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC;oBAAE,SAAS;gBACpC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;gBACvC,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,QAAQ,CAAC,IAAI,kBAAkB,CAAC,CAAC;IAChF,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,QAAgB;QAC3C,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;gBAAE,OAAO;YACzB,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe;gBACnC,CAAC,CAAC,MAAM,oBAAoB,CAAC,QAAQ,CAAC;gBACtC,CAAC,CAAC,SAAS,CAAC;YACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,EAC7B,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAC9E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACpC,CAAC;QAAC,MAAM,CAAC;YACP,qDAAqD;QACvD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,6DAA6D;YAC7D,+DAA+D;YAC/D,IAAI,CAAC,aAAa,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC;YACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC,KAAK,CACrB,YAAY,EACZ,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,EACtC,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE;gBACvB,IAAI,QAAQ;oBAAE,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC7C,CAAC,CACF,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBAC/B,IAAI,CAAC,GAAG,CAAC,gCAAgC,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC;gBACpE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;gBACtB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;gBACpB,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,GAAG,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,mCAAoC,GAAa,CAAC,OAAO,YAAY,CAAC,CAAC;YAChF,IAAI,CAAC,aAAa,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAEO,aAAa;QACnB,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC7C,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,KAAK,IAAI,CAAC,aAAa,EAAE,CAAC;QAC5B,CAAC,EAAE,MAAM,CAAC,CAAC;IACb,CAAC;IAED;;;;OAIG;IACK,aAAa,CAAC,QAAgB;QACpC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,OAAO;QACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC/C,IAAI,QAAQ;YAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CACrB,IAAI,EACJ,UAAU,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACjC,KAAK,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC,EAAE,WAAW,CAAC,CAChB,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,QAAgB;QACjC,IAAI,EAAY,CAAC;QACjB,IAAI,CAAC;YACH,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,0EAA0E;YAC1E,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC/B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;YAAE,OAAO;QAEzB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe;YACnC,CAAC,CAAC,MAAM,oBAAoB,CAAC,QAAQ,CAAC;YACtC,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,EAC7B,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9E,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAElC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,SAAS,CAAC;QACpE,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;QAC/C,IAAI,IAAI,EAAE,CAAC;YACT,0DAA0D;YAC1D,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,YAAY,EAAE,CAAC;YACxB,2DAA2D;YAC3D,gEAAgE;YAChE,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;IAEO,UAAU,CAAC,KAA0C,EAAE,IAAuB;QACpF,MAAM,OAAO,GAAwB;YACnC,KAAK;YACL,cAAc,EAAE,IAAI,CAAC,cAAc;YACnC,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SAC7B,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;IAEO,QAAQ,CACd,QAAgB,EAChB,OAAe,EACf,IAAY,EACZ,KAAyB,EACzB,WAAmB,EACnB,GAAuB,EACvB,QAA0B;QAE1B,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACpD,MAAM,cAAc,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7D,gEAAgE;QAChE,6DAA6D;QAC7D,qDAAqD;QACrD,EAAE;QACF,4DAA4D;QAC5D,iEAAiE;QACjE,kEAAkE;QAClE,gEAAgE;QAChE,+DAA+D;QAC/D,mDAAmD;QACnD,iEAAiE;QACjE,+DAA+D;QAC/D,0DAA0D;QAC1D,EAAE;QACF,kEAAkE;QAClE,kEAAkE;QAClE,oEAAoE;QACpE,kEAAkE;QAClE,kBAAkB;QAClB,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC;QACnC,IAAI,UAAU,GAAG,KAAK,CAAC;QACvB,IAAI,WAAW,GAAG,WAAW,CAAC;QAC9B,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,gCAAgC,EAAE,CAAC;YACrE,UAAU,GAAG,SAAS,CAAC;YACvB,WAAW,GAAG,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;QACnE,CAAC;QACD,sEAAsE;QACtE,0EAA0E;QAC1E,6CAA6C;QAC7C,IAAI,aAAa,GAAG,QAAQ,CAAC;QAC7B,IAAI,aAAa,IAAI,WAAW,KAAK,YAAY,IAAI,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACpF,aAAa,GAAG;gBACd,GAAG,aAAa;gBAChB,iBAAiB,EAAE,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;aAC/E,CAAC;QACJ,CAAC;QACD,OAAO;YACL,cAAc;YACd,YAAY,EAAE,kBAAkB,CAAC,cAAc,CAAC;YAChD,SAAS;YACT,SAAS,EAAE,OAAO;YAClB,IAAI;YACJ,KAAK,EAAE,UAAU;YACjB,WAAW,EAAE,WAAW;YACxB,GAAG;YACH,QAAQ,EAAE,aAAa;SACxB,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACK,eAAe;QACrB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE;YAClC,KAAK,IAAI,CAAC,YAAY,EAAE,CAAC;QAC3B,CAAC,EAAE,kBAAkB,CAAC,CAAC;QACvB,+DAA+D;QAC/D,6DAA6D;QAC7D,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK;YAAE,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;IACvD,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,gBAAgB,CAAC;QAC7C,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;aAC5C,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC;QAClD,KAAK,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;YAC1C,IAAI,EAAY,CAAC;YACjB,IAAI,CAAC;gBACH,EAAE,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS,CAAC,mDAAmD;YAC/D,CAAC;YACD,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;gBAAE,SAAS;YAC3B,MAAM,MAAM,GAAG,MAAM,iBAAiB,CAAC,QAAQ,CAAC,CAAC;YACjD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,EAC7B,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;YACpE,4DAA4D;YAC5D,2DAA2D;YAC3D,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC;gBACvE,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAClC,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;YACzC,CAAC;QACH,CAAC;IACH,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAC7C,MAAM,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IACnC,IAAI,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,OAAO,CAAC;IAC1C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Codex CLI observer — proves the integration registry generalizes
|
|
3
|
+
* beyond Claude Code.
|
|
4
|
+
*
|
|
5
|
+
* Codex persists each session as JSONL at
|
|
6
|
+
* $CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl (CODEX_HOME ~ ~/.codex)
|
|
7
|
+
* — the same file-tailing shape as Claude Code, so this adapter mirrors that
|
|
8
|
+
* watcher's structure: scan + fs.watch the sessions tree, derive state from
|
|
9
|
+
* each file's tail, normalize to AgentSession.
|
|
10
|
+
*
|
|
11
|
+
* PRIVACY: identical contract to claude-code — only structural metadata
|
|
12
|
+
* (entry `type`/`role`, error flags, file mtime). Never message content.
|
|
13
|
+
*
|
|
14
|
+
* NOTE: Codex's exact rollout schema varies by version; the state parse is
|
|
15
|
+
* deliberately tolerant (unknown shapes → "unknown") and the integration is
|
|
16
|
+
* DISABLED by default (opt in via ~/.lisa/agents.json). It graceful-no-ops
|
|
17
|
+
* when $CODEX_HOME/sessions is absent.
|
|
18
|
+
*/
|
|
19
|
+
import { EventEmitter } from "node:events";
|
|
20
|
+
import type { AgentIntegrationConfig, AgentObserver, AgentSession, AgentSessionState } from "../types.js";
|
|
21
|
+
export declare class CodexObserver extends EventEmitter implements AgentObserver {
|
|
22
|
+
readonly agent = "codex";
|
|
23
|
+
private sessionsRoot;
|
|
24
|
+
private sessions;
|
|
25
|
+
private watcher;
|
|
26
|
+
private pending;
|
|
27
|
+
private emitFn;
|
|
28
|
+
constructor(cfg: AgentIntegrationConfig);
|
|
29
|
+
start(emit: (s: AgentSession) => void): Promise<void>;
|
|
30
|
+
list(): AgentSession[];
|
|
31
|
+
stop(): Promise<void>;
|
|
32
|
+
private scan;
|
|
33
|
+
private attach;
|
|
34
|
+
private record;
|
|
35
|
+
}
|
|
36
|
+
/** Recursively collect rollout-*.jsonl under root. Empty array if absent. */
|
|
37
|
+
export declare function walkRollouts(root: string): Promise<string[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Tolerant state derivation from a Codex rollout tail. Codex schema differs
|
|
40
|
+
* by version; we look for the last entry's role/type and any error flag.
|
|
41
|
+
* Unknown shapes → "unknown". Structural fields only.
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseCodexState(filePath: string): Promise<{
|
|
44
|
+
state: AgentSessionState;
|
|
45
|
+
reason: string;
|
|
46
|
+
cwd?: string;
|
|
47
|
+
}>;
|
|
48
|
+
//# sourceMappingURL=observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.d.ts","sourceRoot":"","sources":["../../../src/integrations/codex/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,sBAAsB,EACtB,aAAa,EACb,YAAY,EACZ,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAgBrB,qBAAa,aAAc,SAAQ,YAAa,YAAW,aAAa;IACtE,QAAQ,CAAC,KAAK,WAAW;IACzB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,MAAM,CAA4C;gBAE9C,GAAG,EAAE,sBAAsB;IAQjC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3D,IAAI,IAAI,YAAY,EAAE;IAShB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAQb,IAAI;IAKlB,OAAO,CAAC,MAAM;YAiCA,MAAM;CAiBrB;AAcD,6EAA6E;AAC7E,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAiBlE;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;IAAE,KAAK,EAAE,iBAAiB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAkDrE"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Codex CLI observer — proves the integration registry generalizes
|
|
3
|
+
* beyond Claude Code.
|
|
4
|
+
*
|
|
5
|
+
* Codex persists each session as JSONL at
|
|
6
|
+
* $CODEX_HOME/sessions/YYYY/MM/DD/rollout-*.jsonl (CODEX_HOME ~ ~/.codex)
|
|
7
|
+
* — the same file-tailing shape as Claude Code, so this adapter mirrors that
|
|
8
|
+
* watcher's structure: scan + fs.watch the sessions tree, derive state from
|
|
9
|
+
* each file's tail, normalize to AgentSession.
|
|
10
|
+
*
|
|
11
|
+
* PRIVACY: identical contract to claude-code — only structural metadata
|
|
12
|
+
* (entry `type`/`role`, error flags, file mtime). Never message content.
|
|
13
|
+
*
|
|
14
|
+
* NOTE: Codex's exact rollout schema varies by version; the state parse is
|
|
15
|
+
* deliberately tolerant (unknown shapes → "unknown") and the integration is
|
|
16
|
+
* DISABLED by default (opt in via ~/.lisa/agents.json). It graceful-no-ops
|
|
17
|
+
* when $CODEX_HOME/sessions is absent.
|
|
18
|
+
*/
|
|
19
|
+
import fs from "node:fs";
|
|
20
|
+
import fsp from "node:fs/promises";
|
|
21
|
+
import path from "node:path";
|
|
22
|
+
import os from "node:os";
|
|
23
|
+
import { EventEmitter } from "node:events";
|
|
24
|
+
import { registerIntegration } from "../registry.js";
|
|
25
|
+
const ACTIVE_WINDOW_MS = 30 * 60_000;
|
|
26
|
+
const MAX_LISTED = 10;
|
|
27
|
+
const DEBOUNCE_MS = 300;
|
|
28
|
+
const TAIL_BYTES = 32 * 1024;
|
|
29
|
+
export class CodexObserver extends EventEmitter {
|
|
30
|
+
agent = "codex";
|
|
31
|
+
sessionsRoot;
|
|
32
|
+
sessions = new Map();
|
|
33
|
+
watcher = null;
|
|
34
|
+
pending = new Map();
|
|
35
|
+
emitFn = null;
|
|
36
|
+
constructor(cfg) {
|
|
37
|
+
super();
|
|
38
|
+
const home = cfg.home
|
|
39
|
+
? cfg.home.replace(/^~/, os.homedir())
|
|
40
|
+
: process.env.CODEX_HOME ?? path.join(os.homedir(), ".codex");
|
|
41
|
+
this.sessionsRoot = path.join(home, "sessions");
|
|
42
|
+
}
|
|
43
|
+
async start(emit) {
|
|
44
|
+
this.emitFn = emit;
|
|
45
|
+
await this.scan();
|
|
46
|
+
this.attach();
|
|
47
|
+
}
|
|
48
|
+
list() {
|
|
49
|
+
const cutoff = Date.now() - ACTIVE_WINDOW_MS;
|
|
50
|
+
return [...this.sessions.values()]
|
|
51
|
+
.filter((s) => s.lastMtime >= cutoff)
|
|
52
|
+
.sort((a, b) => b.lastMtime - a.lastMtime)
|
|
53
|
+
.slice(0, MAX_LISTED)
|
|
54
|
+
.map(toAgentSession);
|
|
55
|
+
}
|
|
56
|
+
async stop() {
|
|
57
|
+
this.watcher?.close();
|
|
58
|
+
this.watcher = null;
|
|
59
|
+
for (const t of this.pending.values())
|
|
60
|
+
clearTimeout(t);
|
|
61
|
+
this.pending.clear();
|
|
62
|
+
}
|
|
63
|
+
// ── internals ──
|
|
64
|
+
async scan() {
|
|
65
|
+
const files = await walkRollouts(this.sessionsRoot);
|
|
66
|
+
for (const f of files)
|
|
67
|
+
await this.record(f);
|
|
68
|
+
}
|
|
69
|
+
attach() {
|
|
70
|
+
try {
|
|
71
|
+
this.watcher = fs.watch(this.sessionsRoot, { recursive: true, persistent: false }, (_e, filename) => {
|
|
72
|
+
if (!filename)
|
|
73
|
+
return;
|
|
74
|
+
const base = path.basename(filename);
|
|
75
|
+
if (!base.startsWith("rollout-") || !base.endsWith(".jsonl"))
|
|
76
|
+
return;
|
|
77
|
+
const full = path.join(this.sessionsRoot, filename);
|
|
78
|
+
const prev = this.pending.get(full);
|
|
79
|
+
if (prev)
|
|
80
|
+
clearTimeout(prev);
|
|
81
|
+
this.pending.set(full, setTimeout(() => {
|
|
82
|
+
this.pending.delete(full);
|
|
83
|
+
void this.record(full).then(() => {
|
|
84
|
+
const info = this.sessions.get(full);
|
|
85
|
+
if (info && this.emitFn)
|
|
86
|
+
this.emitFn(toAgentSession(info));
|
|
87
|
+
});
|
|
88
|
+
}, DEBOUNCE_MS));
|
|
89
|
+
});
|
|
90
|
+
this.watcher.on("error", () => {
|
|
91
|
+
this.watcher?.close();
|
|
92
|
+
this.watcher = null;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
// sessions dir absent / unwatchable → graceful no-op (Codex not installed)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
async record(full) {
|
|
100
|
+
try {
|
|
101
|
+
const st = await fsp.stat(full);
|
|
102
|
+
if (!st.isFile())
|
|
103
|
+
return;
|
|
104
|
+
const { state, reason, cwd } = await parseCodexState(full);
|
|
105
|
+
this.sessions.set(full, {
|
|
106
|
+
sessionId: path.basename(full, ".jsonl").replace(/^rollout-/, ""),
|
|
107
|
+
project: cwd ? path.basename(cwd) : path.basename(path.dirname(full)),
|
|
108
|
+
cwd,
|
|
109
|
+
lastMtime: st.mtimeMs,
|
|
110
|
+
state,
|
|
111
|
+
stateReason: reason,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
this.sessions.delete(full);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function toAgentSession(i) {
|
|
120
|
+
return {
|
|
121
|
+
agent: "codex",
|
|
122
|
+
sessionId: i.sessionId,
|
|
123
|
+
project: i.project,
|
|
124
|
+
cwd: i.cwd,
|
|
125
|
+
state: i.state,
|
|
126
|
+
stateReason: i.stateReason,
|
|
127
|
+
lastMtime: i.lastMtime,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
/** Recursively collect rollout-*.jsonl under root. Empty array if absent. */
|
|
131
|
+
export async function walkRollouts(root) {
|
|
132
|
+
const out = [];
|
|
133
|
+
async function rec(dir) {
|
|
134
|
+
let entries;
|
|
135
|
+
try {
|
|
136
|
+
entries = await fsp.readdir(dir, { withFileTypes: true });
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
for (const e of entries) {
|
|
142
|
+
const full = path.join(dir, e.name);
|
|
143
|
+
if (e.isDirectory())
|
|
144
|
+
await rec(full);
|
|
145
|
+
else if (e.name.startsWith("rollout-") && e.name.endsWith(".jsonl"))
|
|
146
|
+
out.push(full);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
await rec(root);
|
|
150
|
+
return out;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Tolerant state derivation from a Codex rollout tail. Codex schema differs
|
|
154
|
+
* by version; we look for the last entry's role/type and any error flag.
|
|
155
|
+
* Unknown shapes → "unknown". Structural fields only.
|
|
156
|
+
*/
|
|
157
|
+
export async function parseCodexState(filePath) {
|
|
158
|
+
let tail;
|
|
159
|
+
let size;
|
|
160
|
+
try {
|
|
161
|
+
const st = await fsp.stat(filePath);
|
|
162
|
+
size = st.size;
|
|
163
|
+
if (size === 0)
|
|
164
|
+
return { state: "unknown", reason: "empty" };
|
|
165
|
+
const fd = await fsp.open(filePath, "r");
|
|
166
|
+
try {
|
|
167
|
+
const len = Math.min(TAIL_BYTES, size);
|
|
168
|
+
const buf = Buffer.alloc(len);
|
|
169
|
+
await fd.read(buf, 0, len, size - len);
|
|
170
|
+
tail = buf.toString("utf8");
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
await fd.close();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
return { state: "unknown", reason: "read-failed" };
|
|
178
|
+
}
|
|
179
|
+
const lines = tail.split("\n").filter(Boolean);
|
|
180
|
+
if (size > TAIL_BYTES && lines.length)
|
|
181
|
+
lines.shift();
|
|
182
|
+
let cwd;
|
|
183
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
184
|
+
let e;
|
|
185
|
+
try {
|
|
186
|
+
e = JSON.parse(lines[i]);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (!cwd && typeof e.cwd === "string")
|
|
192
|
+
cwd = e.cwd;
|
|
193
|
+
if (e.is_error === true || e.error === true)
|
|
194
|
+
return { state: "error", reason: "is_error", cwd };
|
|
195
|
+
const type = typeof e.type === "string" ? e.type : undefined;
|
|
196
|
+
const role = typeof e.role === "string"
|
|
197
|
+
? e.role
|
|
198
|
+
: typeof e.message?.role === "string"
|
|
199
|
+
? (e.message.role)
|
|
200
|
+
: undefined;
|
|
201
|
+
// Heuristic: last meaningful entry from the assistant → it just spoke
|
|
202
|
+
// (waiting for the user); from the user / a tool call → working.
|
|
203
|
+
if (role === "assistant" || type === "assistant" || type === "response") {
|
|
204
|
+
return { state: "waiting", reason: "assistant", cwd };
|
|
205
|
+
}
|
|
206
|
+
if (role === "user" || type === "user" || type === "function_call" || type === "tool_use") {
|
|
207
|
+
return { state: "working", reason: type ?? role ?? "user", cwd };
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return { state: "unknown", reason: "no-decision", cwd };
|
|
211
|
+
}
|
|
212
|
+
registerIntegration("codex", (cfg) => new CodexObserver(cfg));
|
|
213
|
+
//# sourceMappingURL=observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.js","sourceRoot":"","sources":["../../../src/integrations/codex/observer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide handle to the live OrchestratorHub.
|
|
3
|
+
*
|
|
4
|
+
* The hub's session state lives in memory in the web-server process. The
|
|
5
|
+
* advise_now tool (which runs in that same process during a chat turn) and
|
|
6
|
+
* the server's periodic advisor tick both need it, so we expose it as a
|
|
7
|
+
* tiny singleton the server sets at startup. Null until the server starts
|
|
8
|
+
* (e.g. CLI-only runs) — callers must handle that.
|
|
9
|
+
*/
|
|
10
|
+
import type { OrchestratorHub } from "./hub.js";
|
|
11
|
+
export declare function setCurrentHub(hub: OrchestratorHub | null): void;
|
|
12
|
+
export declare function getCurrentHub(): OrchestratorHub | null;
|
|
13
|
+
//# sourceMappingURL=current-hub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-hub.d.ts","sourceRoot":"","sources":["../../src/integrations/current-hub.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhD,wBAAgB,aAAa,CAAC,GAAG,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI,CAE/D;AAED,wBAAgB,aAAa,IAAI,eAAe,GAAG,IAAI,CAEtD"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process-wide handle to the live OrchestratorHub.
|
|
3
|
+
*
|
|
4
|
+
* The hub's session state lives in memory in the web-server process. The
|
|
5
|
+
* advise_now tool (which runs in that same process during a chat turn) and
|
|
6
|
+
* the server's periodic advisor tick both need it, so we expose it as a
|
|
7
|
+
* tiny singleton the server sets at startup. Null until the server starts
|
|
8
|
+
* (e.g. CLI-only runs) — callers must handle that.
|
|
9
|
+
*/
|
|
10
|
+
let current = null;
|
|
11
|
+
export function setCurrentHub(hub) {
|
|
12
|
+
current = hub;
|
|
13
|
+
}
|
|
14
|
+
export function getCurrentHub() {
|
|
15
|
+
return current;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=current-hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"current-hub.js","sourceRoot":"","sources":["../../src/integrations/current-hub.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,IAAI,OAAO,GAA2B,IAAI,CAAC;AAE3C,MAAM,UAAU,aAAa,CAAC,GAA2B;IACvD,OAAO,GAAG,GAAG,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrchestratorHub — the one thing the web server talks to for cross-agent
|
|
3
|
+
* session state. Owns every registered AgentObserver, merges their sessions
|
|
4
|
+
* into one normalized list, and re-emits a single "update" event.
|
|
5
|
+
*
|
|
6
|
+
* Replaces the bare single-purpose ClaudeCodeWatcher wiring in server.ts:
|
|
7
|
+
* instead of one watcher, the hub fans out over all enabled integrations.
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from "node:events";
|
|
10
|
+
import type { AgentIntegrationConfig, AgentSession, VisibilityTier } from "./types.js";
|
|
11
|
+
export interface OrchestratorConfig {
|
|
12
|
+
/** Per-integration config, keyed by integration name. */
|
|
13
|
+
integrations: Record<string, AgentIntegrationConfig>;
|
|
14
|
+
/** Global visibility tier; integrations may override per-entry. */
|
|
15
|
+
visibility: VisibilityTier;
|
|
16
|
+
}
|
|
17
|
+
/** Default config when ~/.lisa/agents.json is absent: just Claude Code, at
|
|
18
|
+
* the "activity" tier (Tier 2 — structural, no conversation content). */
|
|
19
|
+
export declare const DEFAULT_ORCHESTRATOR_CONFIG: OrchestratorConfig;
|
|
20
|
+
type Log = (msg: string) => void;
|
|
21
|
+
export declare class OrchestratorHub extends EventEmitter {
|
|
22
|
+
private observers;
|
|
23
|
+
private readonly cfg;
|
|
24
|
+
private readonly log;
|
|
25
|
+
private started;
|
|
26
|
+
private readonly registerBuiltins;
|
|
27
|
+
constructor(cfg: OrchestratorConfig, opts?: {
|
|
28
|
+
log?: Log;
|
|
29
|
+
registerBuiltins?: boolean;
|
|
30
|
+
});
|
|
31
|
+
/** Instantiate + start every enabled integration. Idempotent. */
|
|
32
|
+
start(): Promise<void>;
|
|
33
|
+
stop(): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Merged snapshot across all observers. Sorted by recency (newest first)
|
|
36
|
+
* so the UI + advisor see a single ranked stream.
|
|
37
|
+
*/
|
|
38
|
+
list(): AgentSession[];
|
|
39
|
+
/** Sessions for one agent kind. */
|
|
40
|
+
listByAgent(agent: string): AgentSession[];
|
|
41
|
+
}
|
|
42
|
+
/** Load ~/.lisa/agents.json, falling back to the default config. */
|
|
43
|
+
export declare function loadOrchestratorConfig(path: string): Promise<OrchestratorConfig>;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=hub.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../src/integrations/hub.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EACV,sBAAsB,EAEtB,YAAY,EACZ,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACrD,mEAAmE;IACnE,UAAU,EAAE,cAAc,CAAC;CAC5B;AAED;0EAC0E;AAC1E,eAAO,MAAM,2BAA2B,EAAE,kBAQzC,CAAC;AAEF,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;AAEjC,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAqB;IACzC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAM;IAC1B,OAAO,CAAC,OAAO,CAAS;IAExB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAE/B,GAAG,EAAE,kBAAkB,EAAE,IAAI,GAAE;QAAE,GAAG,CAAC,EAAE,GAAG,CAAC;QAAC,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAO;IAUzF,iEAAiE;IAC3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAM3B;;;OAGG;IACH,IAAI,IAAI,YAAY,EAAE;IAYtB,mCAAmC;IACnC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE;CAG3C;AAED,oEAAoE;AACpE,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,kBAAkB,CAAC,CAiB7B"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OrchestratorHub — the one thing the web server talks to for cross-agent
|
|
3
|
+
* session state. Owns every registered AgentObserver, merges their sessions
|
|
4
|
+
* into one normalized list, and re-emits a single "update" event.
|
|
5
|
+
*
|
|
6
|
+
* Replaces the bare single-purpose ClaudeCodeWatcher wiring in server.ts:
|
|
7
|
+
* instead of one watcher, the hub fans out over all enabled integrations.
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from "node:events";
|
|
10
|
+
import { makeIntegration, registerBuiltinIntegrations } from "./registry.js";
|
|
11
|
+
/** Default config when ~/.lisa/agents.json is absent: just Claude Code, at
|
|
12
|
+
* the "activity" tier (Tier 2 — structural, no conversation content). */
|
|
13
|
+
export const DEFAULT_ORCHESTRATOR_CONFIG = {
|
|
14
|
+
integrations: {
|
|
15
|
+
"claude-code": { enabled: true },
|
|
16
|
+
// Available but off by default — enable in ~/.lisa/agents.json once you
|
|
17
|
+
// use Codex. Graceful no-op if ~/.codex/sessions is absent anyway.
|
|
18
|
+
codex: { enabled: false },
|
|
19
|
+
},
|
|
20
|
+
visibility: "activity",
|
|
21
|
+
};
|
|
22
|
+
export class OrchestratorHub extends EventEmitter {
|
|
23
|
+
observers = [];
|
|
24
|
+
cfg;
|
|
25
|
+
log;
|
|
26
|
+
started = false;
|
|
27
|
+
registerBuiltins;
|
|
28
|
+
constructor(cfg, opts = {}) {
|
|
29
|
+
super();
|
|
30
|
+
this.cfg = cfg;
|
|
31
|
+
this.log = opts.log ?? (() => { });
|
|
32
|
+
// Tests pre-register fake observers and set this false so start() doesn't
|
|
33
|
+
// pull in (and clobber with) the real builtin adapters.
|
|
34
|
+
this.registerBuiltins = opts.registerBuiltins ?? true;
|
|
35
|
+
this.setMaxListeners(64);
|
|
36
|
+
}
|
|
37
|
+
/** Instantiate + start every enabled integration. Idempotent. */
|
|
38
|
+
async start() {
|
|
39
|
+
if (this.started)
|
|
40
|
+
return;
|
|
41
|
+
this.started = true;
|
|
42
|
+
if (this.registerBuiltins)
|
|
43
|
+
await registerBuiltinIntegrations();
|
|
44
|
+
for (const [name, entry] of Object.entries(this.cfg.integrations)) {
|
|
45
|
+
if (entry.enabled === false)
|
|
46
|
+
continue;
|
|
47
|
+
// Resolve the effective visibility for this integration.
|
|
48
|
+
const visibility = entry.visibility ?? this.cfg.visibility;
|
|
49
|
+
try {
|
|
50
|
+
const obs = await makeIntegration(name, { ...entry, visibility });
|
|
51
|
+
await obs.start((session) => {
|
|
52
|
+
this.emit("update", session);
|
|
53
|
+
});
|
|
54
|
+
this.observers.push(obs);
|
|
55
|
+
this.log(`[orchestrator] integration "${name}" started (visibility=${visibility})`);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
// A bad/unknown integration must not take down the others.
|
|
59
|
+
this.log(`[orchestrator] integration "${name}" failed: ${err.message}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async stop() {
|
|
64
|
+
this.started = false;
|
|
65
|
+
await Promise.all(this.observers.map((o) => o.stop().catch(() => { })));
|
|
66
|
+
this.observers = [];
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Merged snapshot across all observers. Sorted by recency (newest first)
|
|
70
|
+
* so the UI + advisor see a single ranked stream.
|
|
71
|
+
*/
|
|
72
|
+
list() {
|
|
73
|
+
const all = [];
|
|
74
|
+
for (const o of this.observers) {
|
|
75
|
+
try {
|
|
76
|
+
all.push(...o.list());
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// one flaky observer shouldn't break the merge
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return all.sort((a, b) => b.lastMtime - a.lastMtime);
|
|
83
|
+
}
|
|
84
|
+
/** Sessions for one agent kind. */
|
|
85
|
+
listByAgent(agent) {
|
|
86
|
+
return this.list().filter((s) => s.agent === agent);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Load ~/.lisa/agents.json, falling back to the default config. */
|
|
90
|
+
export async function loadOrchestratorConfig(path) {
|
|
91
|
+
const fs = await import("node:fs/promises");
|
|
92
|
+
let raw;
|
|
93
|
+
try {
|
|
94
|
+
raw = await fs.readFile(path, "utf8");
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return DEFAULT_ORCHESTRATOR_CONFIG;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const parsed = JSON.parse(raw);
|
|
101
|
+
return {
|
|
102
|
+
integrations: parsed.integrations ?? DEFAULT_ORCHESTRATOR_CONFIG.integrations,
|
|
103
|
+
visibility: parsed.visibility ?? DEFAULT_ORCHESTRATOR_CONFIG.visibility,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return DEFAULT_ORCHESTRATOR_CONFIG;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=hub.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hub.js","sourceRoot":"","sources":["../../src/integrations/hub.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Integration registry — mirrors src/channels/registry.ts.
|
|
3
|
+
*
|
|
4
|
+
* Each agent adapter calls registerIntegration() at module-load time; the
|
|
5
|
+
* hub looks them up by name. Keeps adapters decoupled and lets community
|
|
6
|
+
* adapters slot in by importing one more module.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentIntegrationConfig, AgentObserver, AgentObserverFactory } from "./types.js";
|
|
9
|
+
export declare function registerIntegration(name: string, factory: AgentObserverFactory): void;
|
|
10
|
+
export declare function makeIntegration(name: string, cfg: AgentIntegrationConfig): Promise<AgentObserver>;
|
|
11
|
+
export declare function listAvailableIntegrations(): string[];
|
|
12
|
+
/** Test hook — clear the registry between unit tests. */
|
|
13
|
+
export declare function _resetIntegrationsForTest(): void;
|
|
14
|
+
export declare function registerBuiltinIntegrations(): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/integrations/registry.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EACV,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAIpB,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,IAAI,CAEN;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,sBAAsB,GAC1B,OAAO,CAAC,aAAa,CAAC,CAUxB;AAED,wBAAgB,yBAAyB,IAAI,MAAM,EAAE,CAEpD;AAED,yDAAyD;AACzD,wBAAgB,yBAAyB,IAAI,IAAI,CAGhD;AAKD,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAMjE"}
|