@oratis/lisa 0.3.1 → 0.5.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.
Files changed (70) hide show
  1. package/dist/advisor/detectors.d.ts +25 -0
  2. package/dist/advisor/detectors.d.ts.map +1 -0
  3. package/dist/advisor/detectors.js +161 -0
  4. package/dist/advisor/detectors.js.map +1 -0
  5. package/dist/advisor/engine.d.ts +41 -0
  6. package/dist/advisor/engine.d.ts.map +1 -0
  7. package/dist/advisor/engine.js +156 -0
  8. package/dist/advisor/engine.js.map +1 -0
  9. package/dist/advisor/types.d.ts +68 -0
  10. package/dist/advisor/types.d.ts.map +1 -0
  11. package/dist/advisor/types.js +19 -0
  12. package/dist/advisor/types.js.map +1 -0
  13. package/dist/integrations/claude-code/observer.d.ts +19 -0
  14. package/dist/integrations/claude-code/observer.d.ts.map +1 -0
  15. package/dist/integrations/claude-code/observer.js +59 -0
  16. package/dist/integrations/claude-code/observer.js.map +1 -0
  17. package/dist/integrations/claude-code/parser.d.ts +2 -0
  18. package/dist/integrations/claude-code/parser.d.ts.map +1 -1
  19. package/dist/integrations/claude-code/parser.js +153 -0
  20. package/dist/integrations/claude-code/parser.js.map +1 -1
  21. package/dist/integrations/claude-code/watcher.d.ts +9 -0
  22. package/dist/integrations/claude-code/watcher.d.ts.map +1 -1
  23. package/dist/integrations/claude-code/watcher.js +25 -4
  24. package/dist/integrations/claude-code/watcher.js.map +1 -1
  25. package/dist/integrations/codex/observer.d.ts +48 -0
  26. package/dist/integrations/codex/observer.d.ts.map +1 -0
  27. package/dist/integrations/codex/observer.js +213 -0
  28. package/dist/integrations/codex/observer.js.map +1 -0
  29. package/dist/integrations/current-hub.d.ts +13 -0
  30. package/dist/integrations/current-hub.d.ts.map +1 -0
  31. package/dist/integrations/current-hub.js +17 -0
  32. package/dist/integrations/current-hub.js.map +1 -0
  33. package/dist/integrations/hub.d.ts +45 -0
  34. package/dist/integrations/hub.d.ts.map +1 -0
  35. package/dist/integrations/hub.js +110 -0
  36. package/dist/integrations/hub.js.map +1 -0
  37. package/dist/integrations/registry.d.ts +15 -0
  38. package/dist/integrations/registry.d.ts.map +1 -0
  39. package/dist/integrations/registry.js +38 -0
  40. package/dist/integrations/registry.js.map +1 -0
  41. package/dist/integrations/types.d.ts +90 -0
  42. package/dist/integrations/types.d.ts.map +1 -0
  43. package/dist/integrations/types.js +12 -0
  44. package/dist/integrations/types.js.map +1 -0
  45. package/dist/tools/advise_now.d.ts +11 -0
  46. package/dist/tools/advise_now.d.ts.map +1 -0
  47. package/dist/tools/advise_now.js +34 -0
  48. package/dist/tools/advise_now.js.map +1 -0
  49. package/dist/tools/dispatch_agent.d.ts +38 -0
  50. package/dist/tools/dispatch_agent.d.ts.map +1 -0
  51. package/dist/tools/dispatch_agent.js +145 -0
  52. package/dist/tools/dispatch_agent.js.map +1 -0
  53. package/dist/tools/registry.d.ts.map +1 -1
  54. package/dist/tools/registry.js.map +1 -1
  55. package/dist/vision/capture.d.ts +44 -0
  56. package/dist/vision/capture.d.ts.map +1 -0
  57. package/dist/vision/capture.js +86 -0
  58. package/dist/vision/capture.js.map +1 -0
  59. package/dist/web/island.d.ts +1 -1
  60. package/dist/web/island.d.ts.map +1 -1
  61. package/dist/web/island.js +43 -0
  62. package/dist/web/island.js.map +1 -1
  63. package/dist/web/lisa-html.d.ts +1 -1
  64. package/dist/web/lisa-html.d.ts.map +1 -1
  65. package/dist/web/lisa-html.js +61 -4
  66. package/dist/web/lisa-html.js.map +1 -1
  67. package/dist/web/server.d.ts.map +1 -1
  68. package/dist/web/server.js +112 -17
  69. package/dist/web/server.js.map +1 -1
  70. package/package.json +1 -1
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Advisor detectors — pure functions: an AdvisorInput snapshot in, candidate
3
+ * Suggestions out. No I/O, no state mutation, fully testable. The engine
4
+ * (engine.ts) is what scores + throttles + dedupes them.
5
+ *
6
+ * Every detector works from STRUCTURAL signals only (state, cwd, the Tier-2
7
+ * SessionActivity) — never conversation content.
8
+ */
9
+ import type { AdvisorInput, Suggestion } from "./types.js";
10
+ export declare const STUCK_MS: number;
11
+ export declare const COST_SPIKE_TOKENS = 1500000;
12
+ /** Pending permission → urgent, actionable. */
13
+ export declare function detectPermission(input: AdvisorInput): Suggestion[];
14
+ export declare function detectStuck(input: AdvisorInput): Suggestion[];
15
+ /** Two+ active sessions sharing a cwd (or an overlapping touched file). */
16
+ export declare function detectConflict(input: AdvisorInput): Suggestion[];
17
+ /** Combined token usage across active sessions above the spike threshold. */
18
+ export declare function detectCostSpike(input: AdvisorInput): Suggestion[];
19
+ /** A session that finished a turn and is awaiting you (end_turn / done). */
20
+ export declare function detectReady(input: AdvisorInput): Suggestion[];
21
+ /** Nothing running but standing chores exist. */
22
+ export declare function detectIdleCapacity(input: AdvisorInput): Suggestion[];
23
+ /** Run every detector and concatenate their candidates. */
24
+ export declare function runAllDetectors(input: AdvisorInput): Suggestion[];
25
+ //# sourceMappingURL=detectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../../src/advisor/detectors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAA+B,MAAM,YAAY,CAAC;AAGxF,eAAO,MAAM,QAAQ,QAAc,CAAC;AACpC,eAAO,MAAM,iBAAiB,UAAY,CAAC;AAoB3C,+CAA+C;AAC/C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CAkBlE;AAoBD,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CAyC7D;AAED,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CA2BhE;AAED,6EAA6E;AAC7E,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CA6BjE;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CAqB7D;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CAiBpE;AAED,2DAA2D;AAC3D,wBAAgB,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,UAAU,EAAE,CASjE"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Advisor detectors — pure functions: an AdvisorInput snapshot in, candidate
3
+ * Suggestions out. No I/O, no state mutation, fully testable. The engine
4
+ * (engine.ts) is what scores + throttles + dedupes them.
5
+ *
6
+ * Every detector works from STRUCTURAL signals only (state, cwd, the Tier-2
7
+ * SessionActivity) — never conversation content.
8
+ */
9
+ // Thresholds (ms). Tuned to "a human would want this flagged".
10
+ export const STUCK_MS = 10 * 60_000; // waiting/error with no change for 10 min
11
+ export const COST_SPIKE_TOKENS = 1_500_000; // combined tokens across active sessions
12
+ function mk(id, category, urgency, text, conditionHash, now, action) {
13
+ return { id, category, urgency, text, conditionHash, ts: now, action, score: 0 };
14
+ }
15
+ function basename(p) {
16
+ if (!p)
17
+ return "";
18
+ const parts = p.split("/");
19
+ return parts[parts.length - 1] || p;
20
+ }
21
+ /** Pending permission → urgent, actionable. */
22
+ export function detectPermission(input) {
23
+ const out = [];
24
+ for (const s of input.sessions) {
25
+ const pend = s.activity?.pendingPermission;
26
+ if (!pend)
27
+ continue;
28
+ out.push(mk(`permission:${s.agent}:${s.sessionId}`, "stuck", "urgent", `${s.project} wants to run ${pend} — approve?`, `permission:${pend}`, input.now, { label: "Approve", kind: "approve", arg: s.sessionId }));
29
+ }
30
+ return out;
31
+ }
32
+ /**
33
+ * "Stuck" = a session that looks like it needs attention but isn't making
34
+ * progress. The trap (and the v1 noise bug) is that a `waiting` session is
35
+ * USUALLY fine — Claude finished its turn (end_turn) and is just idle waiting
36
+ * for the user. That's not stuck, it's normal, and flagging every >10min idle
37
+ * session buries the real signal.
38
+ *
39
+ * So a session counts as stuck only when:
40
+ * - state is `error` (something actually broke), OR
41
+ * - state is `waiting` with a reason that means "blocked / not cleanly
42
+ * finished" — i.e. NOT end_turn/stop_sequence/max_tokens (clean stops,
43
+ * surfaced quietly by detectReady instead).
44
+ * AND it's been quiet for ≥ STUCK_MS. If more than COLLAPSE_THRESHOLD qualify,
45
+ * emit ONE rolled-up line so the digest stays scannable.
46
+ */
47
+ const CLEAN_STOP_REASONS = new Set(["end_turn", "stop_sequence", "max_tokens"]);
48
+ const COLLAPSE_THRESHOLD = 3;
49
+ export function detectStuck(input) {
50
+ const stuck = input.sessions.filter((s) => {
51
+ if (s.activity?.pendingPermission)
52
+ return false; // detectPermission owns these
53
+ if (input.now - s.lastMtime < STUCK_MS)
54
+ return false;
55
+ if (s.state === "error")
56
+ return true;
57
+ if (s.state === "waiting")
58
+ return !CLEAN_STOP_REASONS.has(s.stateReason);
59
+ return false;
60
+ });
61
+ if (stuck.length === 0)
62
+ return [];
63
+ if (stuck.length > COLLAPSE_THRESHOLD) {
64
+ const errs = stuck.filter((s) => s.state === "error").length;
65
+ const detail = errs > 0 ? ` (${errs} errored)` : "";
66
+ return [
67
+ mk(`stuck-many:${stuck.length}`, "stuck", "notice", `${stuck.length} agent sessions look stuck or stalled${detail} — want the list?`, `stuck-many:${stuck.length}:${errs}`, input.now, { label: "List", kind: "look", arg: "stuck" }),
68
+ ];
69
+ }
70
+ return stuck.map((s) => {
71
+ const mins = Math.round((input.now - s.lastMtime) / 60_000);
72
+ const cmd = s.activity?.lastCommandName;
73
+ const why = s.state === "error" ? "errored" : "has stalled";
74
+ const on = cmd ? ` on \`${cmd}\`` : "";
75
+ return mk(`stuck:${s.agent}:${s.sessionId}`, "stuck", "notice", `${s.project} ${why}${on} (idle ${mins}m) — want me to look, or cancel it?`, `stuck:${s.state}:${s.stateReason}:${cmd ?? ""}`, input.now, { label: "Look", kind: "look", arg: s.sessionId });
76
+ });
77
+ }
78
+ /** Two+ active sessions sharing a cwd (or an overlapping touched file). */
79
+ export function detectConflict(input) {
80
+ const out = [];
81
+ const byCwd = new Map();
82
+ for (const s of input.sessions) {
83
+ if (!s.cwd)
84
+ continue;
85
+ if (s.state !== "working" && s.state !== "waiting")
86
+ continue;
87
+ const arr = byCwd.get(s.cwd) ?? [];
88
+ arr.push(s);
89
+ byCwd.set(s.cwd, arr);
90
+ }
91
+ for (const [cwd, group] of byCwd) {
92
+ if (group.length < 2)
93
+ continue;
94
+ const agents = [...new Set(group.map((g) => g.agent))];
95
+ const label = basename(cwd);
96
+ out.push(mk(`conflict:${cwd}`, "conflict", "notice", `${group.length} agents (${agents.join(", ")}) are both working in ${label} — high risk of clobbering. Serialize?`, `conflict:${group.map((g) => g.sessionId).sort().join(",")}`, input.now, { label: "Serialize", kind: "serialize", arg: cwd }));
97
+ }
98
+ return out;
99
+ }
100
+ /** Combined token usage across active sessions above the spike threshold. */
101
+ export function detectCostSpike(input) {
102
+ let total = 0;
103
+ let topSession = null;
104
+ let topTokens = 0;
105
+ for (const s of input.sessions) {
106
+ const t = s.activity?.tokens;
107
+ if (!t)
108
+ continue;
109
+ const sum = (t.input ?? 0) + (t.output ?? 0);
110
+ total += sum;
111
+ if (sum > topTokens) {
112
+ topTokens = sum;
113
+ topSession = s;
114
+ }
115
+ }
116
+ if (total < COST_SPIKE_TOKENS)
117
+ return [];
118
+ const millions = (total / 1_000_000).toFixed(1);
119
+ const pct = total > 0 ? Math.round((topTokens / total) * 100) : 0;
120
+ const who = topSession ? ` — ${topSession.project} is ${pct}% of it` : "";
121
+ return [
122
+ mk(`cost:${Math.round(total / 100_000)}`, // bucketed so it re-fires per ~100k step
123
+ "cost_spike", "notice", `Active agents are at ${millions}M tokens${who}.`, `cost:${Math.round(total / 500_000)}`, input.now, topSession ? { label: "Look", kind: "look", arg: topSession.sessionId } : undefined),
124
+ ];
125
+ }
126
+ /** A session that finished a turn and is awaiting you (end_turn / done). */
127
+ export function detectReady(input) {
128
+ const out = [];
129
+ for (const s of input.sessions) {
130
+ const ready = s.state === "done" ||
131
+ (s.state === "waiting" && s.stateReason === "end_turn");
132
+ if (!ready)
133
+ continue;
134
+ if (s.activity?.lastError)
135
+ continue; // erroring isn't "ready"
136
+ out.push(mk(`ready:${s.agent}:${s.sessionId}`, "ready", "info", `${s.project} finished and is waiting for you.`, `ready:${s.lastMtime}`, input.now, { label: "Open", kind: "open", arg: s.cwd ?? s.sessionId }));
137
+ }
138
+ return out;
139
+ }
140
+ /** Nothing running but standing chores exist. */
141
+ export function detectIdleCapacity(input) {
142
+ const active = input.sessions.some((s) => s.state === "working" || s.state === "waiting");
143
+ const pending = input.pendingDesireCount ?? 0;
144
+ if (active || pending <= 0)
145
+ return [];
146
+ return [
147
+ mk("idle-capacity", "idle", "info", `Nothing's running and you have ${pending} standing ${pending === 1 ? "task" : "tasks"} — want me to dispatch them?`, `idle:${pending}`, input.now, { label: "Dispatch", kind: "dispatch", arg: String(pending) }),
148
+ ];
149
+ }
150
+ /** Run every detector and concatenate their candidates. */
151
+ export function runAllDetectors(input) {
152
+ return [
153
+ ...detectPermission(input),
154
+ ...detectStuck(input),
155
+ ...detectConflict(input),
156
+ ...detectCostSpike(input),
157
+ ...detectReady(input),
158
+ ...detectIdleCapacity(input),
159
+ ];
160
+ }
161
+ //# sourceMappingURL=detectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectors.js","sourceRoot":"","sources":["../../src/advisor/detectors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,0CAA0C;AAC/E,MAAM,CAAC,MAAM,iBAAiB,GAAG,SAAS,CAAC,CAAC,yCAAyC;AAErF,SAAS,EAAE,CACT,EAAU,EACV,QAA4B,EAC5B,OAAgB,EAChB,IAAY,EACZ,aAAqB,EACrB,GAAW,EACX,MAA6B;IAE7B,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AACnF,CAAC;AAED,SAAS,QAAQ,CAAC,CAAU;IAC1B,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AACtC,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,gBAAgB,CAAC,KAAmB;IAClD,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,iBAAiB,CAAC;QAC3C,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,GAAG,CAAC,IAAI,CACN,EAAE,CACA,cAAc,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,EACtC,OAAO,EACP,QAAQ,EACR,GAAG,CAAC,CAAC,OAAO,iBAAiB,IAAI,aAAa,EAC9C,cAAc,IAAI,EAAE,EACpB,KAAK,CAAC,GAAG,EACT,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,CACxD,CACF,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,eAAe,EAAE,YAAY,CAAC,CAAC,CAAC;AAChF,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,MAAM,UAAU,WAAW,CAAC,KAAmB;IAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACxC,IAAI,CAAC,CAAC,QAAQ,EAAE,iBAAiB;YAAE,OAAO,KAAK,CAAC,CAAC,8BAA8B;QAC/E,IAAI,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,GAAG,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrD,IAAI,CAAC,CAAC,KAAK,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACzE,OAAO,KAAK,CAAC;IACf,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,IAAI,KAAK,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,MAAM,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,OAAO;YACL,EAAE,CACA,cAAc,KAAK,CAAC,MAAM,EAAE,EAC5B,OAAO,EACP,QAAQ,EACR,GAAG,KAAK,CAAC,MAAM,wCAAwC,MAAM,mBAAmB,EAChF,cAAc,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,EACpC,KAAK,CAAC,GAAG,EACT,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,CAC9C;SACF,CAAC;IACJ,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,GAAG,MAAM,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,eAAe,CAAC;QACxC,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC;QAC5D,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,OAAO,EAAE,CACP,SAAS,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,EACjC,OAAO,EACP,QAAQ,EACR,GAAG,CAAC,CAAC,OAAO,IAAI,GAAG,GAAG,EAAE,UAAU,IAAI,qCAAqC,EAC3E,SAAS,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,WAAW,IAAI,GAAG,IAAI,EAAE,EAAE,EAChD,KAAK,CAAC,GAAG,EACT,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,SAAS,EAAE,CAClD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,cAAc,CAAC,KAAmB;IAChD,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,IAAI,GAAG,EAA0B,CAAC;IAChD,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,CAAC,CAAC,GAAG;YAAE,SAAS;QACrB,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS;YAAE,SAAS;QAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACnC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACZ,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxB,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC;QACjC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAC/B,MAAM,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACvD,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC5B,GAAG,CAAC,IAAI,CACN,EAAE,CACA,YAAY,GAAG,EAAE,EACjB,UAAU,EACV,QAAQ,EACR,GAAG,KAAK,CAAC,MAAM,YAAY,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,yBAAyB,KAAK,wCAAwC,EAClH,YAAY,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAC5D,KAAK,CAAC,GAAG,EACT,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,EAAE,CACpD,CACF,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,UAAU,GAAwB,IAAI,CAAC;IAC3C,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC7B,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QAC7C,KAAK,IAAI,GAAG,CAAC;QACb,IAAI,GAAG,GAAG,SAAS,EAAE,CAAC;YACpB,SAAS,GAAG,GAAG,CAAC;YAChB,UAAU,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,IAAI,KAAK,GAAG,iBAAiB;QAAE,OAAO,EAAE,CAAC;IACzC,MAAM,QAAQ,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,GAAG,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClE,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,UAAU,CAAC,OAAO,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,OAAO;QACL,EAAE,CACA,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,EAAE,EAAE,yCAAyC;QAChF,YAAY,EACZ,QAAQ,EACR,wBAAwB,QAAQ,WAAW,GAAG,GAAG,EACjD,QAAQ,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC,EAAE,EACrC,KAAK,CAAC,GAAG,EACT,UAAU,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CACpF;KACF,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,WAAW,CAAC,KAAmB;IAC7C,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC/B,MAAM,KAAK,GACT,CAAC,CAAC,KAAK,KAAK,MAAM;YAClB,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS;YAAE,SAAS,CAAC,yBAAyB;QAC9D,GAAG,CAAC,IAAI,CACN,EAAE,CACA,SAAS,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,SAAS,EAAE,EACjC,OAAO,EACP,MAAM,EACN,GAAG,CAAC,CAAC,OAAO,mCAAmC,EAC/C,SAAS,CAAC,CAAC,SAAS,EAAE,EACtB,KAAK,CAAC,GAAG,EACT,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,EAAE,CAC3D,CACF,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,iDAAiD;AACjD,MAAM,UAAU,kBAAkB,CAAC,KAAmB;IACpD,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAChC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CACtD,CAAC;IACF,MAAM,OAAO,GAAG,KAAK,CAAC,kBAAkB,IAAI,CAAC,CAAC;IAC9C,IAAI,MAAM,IAAI,OAAO,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,OAAO;QACL,EAAE,CACA,eAAe,EACf,MAAM,EACN,MAAM,EACN,kCAAkC,OAAO,aAAa,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,8BAA8B,EACpH,QAAQ,OAAO,EAAE,EACjB,KAAK,CAAC,GAAG,EACT,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAC9D;KACF,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,eAAe,CAAC,KAAmB;IACjD,OAAO;QACL,GAAG,gBAAgB,CAAC,KAAK,CAAC;QAC1B,GAAG,WAAW,CAAC,KAAK,CAAC;QACrB,GAAG,cAAc,CAAC,KAAK,CAAC;QACxB,GAAG,eAAe,CAAC,KAAK,CAAC;QACzB,GAAG,WAAW,CAAC,KAAK,CAAC;QACrB,GAAG,kBAAkB,CAAC,KAAK,CAAC;KAC7B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Advisor engine — the anti-annoyance brain.
3
+ *
4
+ * Pure decision core: given this run's candidate suggestions + the persisted
5
+ * advisor state + the clock, decide which clear the relevance bar AND the
6
+ * throttle AND dedup, and which get suppressed (journaled, not shown). The
7
+ * caller does the I/O (load/save state, surface the survivors).
8
+ *
9
+ * See docs/ORCHESTRATOR_PLAN.md §5b.3 for the anti-annoyance contract.
10
+ */
11
+ import { type AdvisorDecision, type AdvisorInput, type AdvisorState, type Suggestion, type SuggestionCategory } from "./types.js";
12
+ export declare const ADVISOR_STATE_PATH: string;
13
+ /** Relevance score = urgency × actionability × dismissal-decay. */
14
+ export declare function scoreSuggestion(s: Suggestion, state: AdvisorState): number;
15
+ /**
16
+ * Pure decision. Returns the surface/suppress split AND the next state to
17
+ * persist. Does not touch disk.
18
+ */
19
+ export declare function decide(candidates: Suggestion[], state: AdvisorState, now: number): {
20
+ decision: AdvisorDecision;
21
+ nextState: AdvisorState;
22
+ };
23
+ /** Record a user dismissal so the category fades over time. */
24
+ export declare function applyDismissal(state: AdvisorState, id: string, category: SuggestionCategory): AdvisorState;
25
+ export declare function loadAdvisorState(p?: string): Promise<AdvisorState>;
26
+ export declare function saveAdvisorState(state: AdvisorState, p?: string): Promise<void>;
27
+ /**
28
+ * Full advise cycle: detect → decide → persist. Returns the suggestions to
29
+ * surface. Uses the soul lock so a heartbeat advise can't race a manual one.
30
+ */
31
+ export declare function advise(input: AdvisorInput, statePath?: string): Promise<AdvisorDecision>;
32
+ /**
33
+ * On-demand ("pull") advice: run the detectors against the current snapshot
34
+ * and return everything above the bar, sorted — WITHOUT the throttle/dedup
35
+ * (the user explicitly asked, so don't suppress) and WITHOUT mutating state.
36
+ * Used by the advise_now tool.
37
+ */
38
+ export declare function adviseNow(input: AdvisorInput, state?: AdvisorState): Suggestion[];
39
+ /** Render surfaced suggestions into one digest card (markdown-ish text). */
40
+ export declare function formatDigest(suggestions: Suggestion[]): string;
41
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../src/advisor/engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,UAAU,EACf,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAC;AAQpB,eAAO,MAAM,kBAAkB,QAA6C,CAAC;AAE7E,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,CAO1E;AAUD;;;GAGG;AACH,wBAAgB,MAAM,CACpB,UAAU,EAAE,UAAU,EAAE,EACxB,KAAK,EAAE,YAAY,EACnB,GAAG,EAAE,MAAM,GACV;IAAE,QAAQ,EAAE,eAAe,CAAC;IAAC,SAAS,EAAE,YAAY,CAAA;CAAE,CAgDxD;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,CAC5B,KAAK,EAAE,YAAY,EACnB,EAAE,EAAE,MAAM,EACV,QAAQ,EAAE,kBAAkB,GAC3B,YAAY,CASd;AAID,wBAAsB,gBAAgB,CACpC,CAAC,GAAE,MAA2B,GAC7B,OAAO,CAAC,YAAY,CAAC,CAQvB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,YAAY,EACnB,CAAC,GAAE,MAA2B,GAC7B,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;GAGG;AACH,wBAAsB,MAAM,CAC1B,KAAK,EAAE,YAAY,EACnB,SAAS,GAAE,MAA2B,GACrC,OAAO,CAAC,eAAe,CAAC,CAQ1B;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,KAAK,GAAE,YAAkC,GAAG,UAAU,EAAE,CAMtG;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAQ9D"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Advisor engine — the anti-annoyance brain.
3
+ *
4
+ * Pure decision core: given this run's candidate suggestions + the persisted
5
+ * advisor state + the clock, decide which clear the relevance bar AND the
6
+ * throttle AND dedup, and which get suppressed (journaled, not shown). The
7
+ * caller does the I/O (load/save state, surface the survivors).
8
+ *
9
+ * See docs/ORCHESTRATOR_PLAN.md §5b.3 for the anti-annoyance contract.
10
+ */
11
+ import fsp from "node:fs/promises";
12
+ import path from "node:path";
13
+ import { LISA_HOME } from "../paths.js";
14
+ import { atomicWrite } from "../fs-utils.js";
15
+ import { withFileLock } from "../soul/lock.js";
16
+ import { runAllDetectors } from "./detectors.js";
17
+ import { emptyAdvisorState, } from "./types.js";
18
+ // Tunables.
19
+ const URGENCY_WEIGHT = { info: 1, notice: 2, urgent: 4 };
20
+ const MIN_SCORE = 1.5; // relevance bar: below this → journal, not user
21
+ const DIGEST_THROTTLE_MS = 3 * 60 * 60_000; // ≤1 non-urgent digest / 3h
22
+ const RE_ARM_MS = 24 * 60 * 60_000; // a standing condition can re-surface daily
23
+ export const ADVISOR_STATE_PATH = path.join(LISA_HOME, "advisor-state.json");
24
+ /** Relevance score = urgency × actionability × dismissal-decay. */
25
+ export function scoreSuggestion(s, state) {
26
+ const urgency = URGENCY_WEIGHT[s.urgency];
27
+ const actionability = s.action ? 1 : 0.5;
28
+ const catDismissals = state.categoryDismissals[s.category] ?? 0;
29
+ // Each dismissal of this category halves its pull (learns to shut up).
30
+ const decay = 1 / (1 + catDismissals * 1.0);
31
+ return urgency * actionability * decay;
32
+ }
33
+ /** Has this exact condition been surfaced recently (→ suppress as dup)? */
34
+ function isDuplicate(s, state, now) {
35
+ const prev = state.surfaced[s.id];
36
+ if (!prev)
37
+ return false;
38
+ if (prev.conditionHash !== s.conditionHash)
39
+ return false; // condition changed → fresh
40
+ return now - prev.ts < RE_ARM_MS;
41
+ }
42
+ /**
43
+ * Pure decision. Returns the surface/suppress split AND the next state to
44
+ * persist. Does not touch disk.
45
+ */
46
+ export function decide(candidates, state, now) {
47
+ const surface = [];
48
+ const suppressed = [];
49
+ // Score everything first.
50
+ for (const c of candidates)
51
+ c.score = scoreSuggestion(c, state);
52
+ const withinThrottle = now - state.lastDigestAt < DIGEST_THROTTLE_MS;
53
+ let surfacedAnyNonUrgent = false;
54
+ for (const c of candidates) {
55
+ // Dedup: same condition seen recently → suppress.
56
+ if (isDuplicate(c, state, now)) {
57
+ suppressed.push(c);
58
+ continue;
59
+ }
60
+ if (c.urgency === "urgent") {
61
+ // Urgent bypasses the bar + throttle — but still deduped above.
62
+ surface.push(c);
63
+ continue;
64
+ }
65
+ // Non-urgent must clear the relevance bar…
66
+ if (c.score < MIN_SCORE) {
67
+ suppressed.push(c);
68
+ continue;
69
+ }
70
+ // …and the digest throttle.
71
+ if (withinThrottle) {
72
+ suppressed.push(c);
73
+ continue;
74
+ }
75
+ surface.push(c);
76
+ surfacedAnyNonUrgent = true;
77
+ }
78
+ // Build next state: record what we surfaced + advance the digest clock.
79
+ const nextState = {
80
+ ...state,
81
+ surfaced: { ...state.surfaced },
82
+ };
83
+ for (const s of surface) {
84
+ nextState.surfaced[s.id] = { ts: now, conditionHash: s.conditionHash };
85
+ }
86
+ if (surfacedAnyNonUrgent)
87
+ nextState.lastDigestAt = now;
88
+ // Sort surfaced by score desc so the digest leads with what matters.
89
+ surface.sort((a, b) => b.score - a.score);
90
+ return { decision: { surface, suppressed }, nextState };
91
+ }
92
+ /** Record a user dismissal so the category fades over time. */
93
+ export function applyDismissal(state, id, category) {
94
+ return {
95
+ ...state,
96
+ dismissals: { ...state.dismissals, [id]: (state.dismissals[id] ?? 0) + 1 },
97
+ categoryDismissals: {
98
+ ...state.categoryDismissals,
99
+ [category]: (state.categoryDismissals[category] ?? 0) + 1,
100
+ },
101
+ };
102
+ }
103
+ // ── I/O ─────────────────────────────────────────────────────────────────
104
+ export async function loadAdvisorState(p = ADVISOR_STATE_PATH) {
105
+ try {
106
+ const raw = await fsp.readFile(p, "utf8");
107
+ const parsed = JSON.parse(raw);
108
+ return { ...emptyAdvisorState(), ...parsed };
109
+ }
110
+ catch {
111
+ return emptyAdvisorState();
112
+ }
113
+ }
114
+ export async function saveAdvisorState(state, p = ADVISOR_STATE_PATH) {
115
+ await atomicWrite(p, JSON.stringify(state, null, 2));
116
+ }
117
+ /**
118
+ * Full advise cycle: detect → decide → persist. Returns the suggestions to
119
+ * surface. Uses the soul lock so a heartbeat advise can't race a manual one.
120
+ */
121
+ export async function advise(input, statePath = ADVISOR_STATE_PATH) {
122
+ return withFileLock(statePath + ".lock", async () => {
123
+ const state = await loadAdvisorState(statePath);
124
+ const candidates = runAllDetectors(input);
125
+ const { decision, nextState } = decide(candidates, state, input.now);
126
+ await saveAdvisorState(nextState, statePath);
127
+ return decision;
128
+ });
129
+ }
130
+ /**
131
+ * On-demand ("pull") advice: run the detectors against the current snapshot
132
+ * and return everything above the bar, sorted — WITHOUT the throttle/dedup
133
+ * (the user explicitly asked, so don't suppress) and WITHOUT mutating state.
134
+ * Used by the advise_now tool.
135
+ */
136
+ export function adviseNow(input, state = emptyAdvisorState()) {
137
+ const cands = runAllDetectors(input);
138
+ for (const c of cands)
139
+ c.score = scoreSuggestion(c, state);
140
+ return cands
141
+ .filter((c) => c.urgency === "urgent" || c.score >= MIN_SCORE)
142
+ .sort((a, b) => b.score - a.score);
143
+ }
144
+ /** Render surfaced suggestions into one digest card (markdown-ish text). */
145
+ export function formatDigest(suggestions) {
146
+ if (suggestions.length === 0)
147
+ return "";
148
+ if (suggestions.length === 1)
149
+ return suggestions[0].text;
150
+ const lines = suggestions.map((s) => {
151
+ const mark = s.urgency === "urgent" ? "⚠ " : "• ";
152
+ return mark + s.text;
153
+ });
154
+ return "A few things across your agents:\n" + lines.join("\n");
155
+ }
156
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/advisor/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Advisor (L5 ADVISE) — types.
3
+ *
4
+ * The advisor turns cross-agent observation into periodic, proactive
5
+ * suggestions. Its one hard problem is not being annoying, so everything is
6
+ * organized around the relevance bar + throttle + dedup (see engine.ts).
7
+ *
8
+ * See docs/ORCHESTRATOR_PLAN.md §5b.
9
+ */
10
+ import type { AgentSession } from "../integrations/types.js";
11
+ export type SuggestionCategory = "stuck" | "conflict" | "repeated_failure" | "cost_spike" | "ready" | "idle";
12
+ /** How loudly a suggestion wants to be surfaced. */
13
+ export type Urgency = "info" | "notice" | "urgent";
14
+ /** A concrete action LISA can offer to take. A suggestion without one is
15
+ * considered non-actionable and won't clear the relevance bar. */
16
+ export interface SuggestedAction {
17
+ label: string;
18
+ kind: "approve" | "cancel" | "open" | "serialize" | "look" | "dispatch";
19
+ /** Opaque arg the action handler needs (sessionId, cwd, …). */
20
+ arg?: string;
21
+ }
22
+ export interface Suggestion {
23
+ /** Stable dedup key — same underlying condition → same id. */
24
+ id: string;
25
+ category: SuggestionCategory;
26
+ urgency: Urgency;
27
+ /** One-line, user-facing. Structural — no conversation content. */
28
+ text: string;
29
+ action?: SuggestedAction;
30
+ /** Computed relevance score (urgency × novelty × actionability). */
31
+ score: number;
32
+ /** A hash of the underlying condition; re-surface only when it changes. */
33
+ conditionHash: string;
34
+ /** When this was generated (epoch ms). */
35
+ ts: number;
36
+ }
37
+ /** Persisted advisor memory (~/.lisa/advisor-state.json). */
38
+ export interface AdvisorState {
39
+ /** id → last time we surfaced it + the condition hash then. */
40
+ surfaced: Record<string, {
41
+ ts: number;
42
+ conditionHash: string;
43
+ }>;
44
+ /** id → number of times the user dismissed it (down-weights category). */
45
+ dismissals: Record<string, number>;
46
+ /** category → dismissal count, for learning what to stop saying. */
47
+ categoryDismissals: Partial<Record<SuggestionCategory, number>>;
48
+ /** last time ANY non-urgent digest was surfaced (throttle). */
49
+ lastDigestAt: number;
50
+ /** rolling memory of (command → error count) for repeated-failure detection. */
51
+ errorCommandCounts: Record<string, number>;
52
+ }
53
+ export declare function emptyAdvisorState(): AdvisorState;
54
+ /** Input snapshot for the detectors. */
55
+ export interface AdvisorInput {
56
+ sessions: AgentSession[];
57
+ now: number;
58
+ /** Count of actionable desires with nothing running (drives "idle"). */
59
+ pendingDesireCount?: number;
60
+ }
61
+ /** What the engine decided to do with this run's candidates. */
62
+ export interface AdvisorDecision {
63
+ /** Cleared the bar + throttle/dedup → surface to the user. */
64
+ surface: Suggestion[];
65
+ /** Generated but suppressed (logged to journal, not shown). */
66
+ suppressed: Suggestion[];
67
+ }
68
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/advisor/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAC1B,OAAO,GACP,UAAU,GACV,kBAAkB,GAClB,YAAY,GACZ,OAAO,GACP,MAAM,CAAC;AAEX,oDAAoD;AACpD,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEnD;mEACmE;AACnE,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,GAAG,UAAU,CAAC;IACxE,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,8DAA8D;IAC9D,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,oEAAoE;IACpE,KAAK,EAAE,MAAM,CAAC;IACd,2EAA2E;IAC3E,aAAa,EAAE,MAAM,CAAC;IACtB,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,6DAA6D;AAC7D,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,0EAA0E;IAC1E,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,oEAAoE;IACpE,kBAAkB,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAC;IAChE,+DAA+D;IAC/D,YAAY,EAAE,MAAM,CAAC;IACrB,gFAAgF;IAChF,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,wBAAgB,iBAAiB,IAAI,YAAY,CAQhD;AAED,wCAAwC;AACxC,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,gEAAgE;AAChE,MAAM,WAAW,eAAe;IAC9B,8DAA8D;IAC9D,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,+DAA+D;IAC/D,UAAU,EAAE,UAAU,EAAE,CAAC;CAC1B"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Advisor (L5 ADVISE) — types.
3
+ *
4
+ * The advisor turns cross-agent observation into periodic, proactive
5
+ * suggestions. Its one hard problem is not being annoying, so everything is
6
+ * organized around the relevance bar + throttle + dedup (see engine.ts).
7
+ *
8
+ * See docs/ORCHESTRATOR_PLAN.md §5b.
9
+ */
10
+ export function emptyAdvisorState() {
11
+ return {
12
+ surfaced: {},
13
+ dismissals: {},
14
+ categoryDismissals: {},
15
+ lastDigestAt: 0,
16
+ errorCommandCounts: {},
17
+ };
18
+ }
19
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/advisor/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAsDH,MAAM,UAAU,iBAAiB;IAC/B,OAAO;QACL,QAAQ,EAAE,EAAE;QACZ,UAAU,EAAE,EAAE;QACd,kBAAkB,EAAE,EAAE;QACtB,YAAY,EAAE,CAAC;QACf,kBAAkB,EAAE,EAAE;KACvB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Claude Code AgentObserver — adapts the existing ClaudeCodeWatcher to the
3
+ * normalized cross-agent interface and registers it in the integration
4
+ * registry.
5
+ *
6
+ * The watcher itself is unchanged (it's well-tested); this is a thin
7
+ * normalization layer: ClaudeSessionInfo → AgentSession. Activity (Tier 2)
8
+ * is attached when the watcher provides it.
9
+ */
10
+ import type { AgentIntegrationConfig, AgentObserver, AgentSession } from "../types.js";
11
+ export declare class ClaudeCodeObserver implements AgentObserver {
12
+ readonly agent = "claude-code";
13
+ private watcher;
14
+ constructor(cfg: AgentIntegrationConfig);
15
+ start(emit: (s: AgentSession) => void): Promise<void>;
16
+ list(): AgentSession[];
17
+ stop(): Promise<void>;
18
+ }
19
+ //# sourceMappingURL=observer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer.d.ts","sourceRoot":"","sources":["../../../src/integrations/claude-code/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,sBAAsB,EACtB,aAAa,EACb,YAAY,EACb,MAAM,aAAa,CAAC;AAerB,qBAAa,kBAAmB,YAAW,aAAa;IACtD,QAAQ,CAAC,KAAK,iBAAiB;IAC/B,OAAO,CAAC,OAAO,CAAoB;gBAEvB,GAAG,EAAE,sBAAsB;IAWjC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAc3D,IAAI,IAAI,YAAY,EAAE;IAIhB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAG5B"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Claude Code AgentObserver — adapts the existing ClaudeCodeWatcher to the
3
+ * normalized cross-agent interface and registers it in the integration
4
+ * registry.
5
+ *
6
+ * The watcher itself is unchanged (it's well-tested); this is a thin
7
+ * normalization layer: ClaudeSessionInfo → AgentSession. Activity (Tier 2)
8
+ * is attached when the watcher provides it.
9
+ */
10
+ import { ClaudeCodeWatcher } from "./watcher.js";
11
+ import { registerIntegration } from "../registry.js";
12
+ function toAgentSession(info) {
13
+ return {
14
+ agent: "claude-code",
15
+ sessionId: info.sessionId,
16
+ project: info.projectLabel,
17
+ cwd: info.cwd,
18
+ state: info.state,
19
+ stateReason: info.stateReason,
20
+ lastMtime: info.lastMtime,
21
+ activity: info.activity,
22
+ };
23
+ }
24
+ export class ClaudeCodeObserver {
25
+ agent = "claude-code";
26
+ watcher;
27
+ constructor(cfg) {
28
+ // Tier 2: compute structural activity when visibility is "activity" or
29
+ // "intent". At "metadata"/"off" we stay metadata-only (cheaper, and the
30
+ // privacy-minimal default).
31
+ const computeActivity = cfg.visibility === "activity" || cfg.visibility === "intent";
32
+ this.watcher = new ClaudeCodeWatcher({
33
+ log: (m) => console.error(m),
34
+ computeActivity,
35
+ });
36
+ }
37
+ async start(emit) {
38
+ // The watcher's "update" payload is a lightweight ClaudeSessionUpdate
39
+ // (no lastMtime/activity), so we re-derive the full session from the
40
+ // current snapshot by sessionId. listActive() includes the just-updated
41
+ // session (its mtime is current), so the lookup succeeds.
42
+ this.watcher.on("update", (payload) => {
43
+ const info = this.watcher
44
+ .listActive()
45
+ .find((s) => s.sessionId === payload.sessionId);
46
+ if (info)
47
+ emit(toAgentSession(info));
48
+ });
49
+ await this.watcher.start();
50
+ }
51
+ list() {
52
+ return this.watcher.listActive().map(toAgentSession);
53
+ }
54
+ async stop() {
55
+ this.watcher.stop();
56
+ }
57
+ }
58
+ registerIntegration("claude-code", (cfg) => new ClaudeCodeObserver(cfg));
59
+ //# sourceMappingURL=observer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observer.js","sourceRoot":"","sources":["../../../src/integrations/claude-code/observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,iBAAiB,EAA0B,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAOrD,SAAS,cAAc,CAAC,IAAuB;IAC7C,OAAO;QACL,KAAK,EAAE,aAAa;QACpB,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,OAAO,EAAE,IAAI,CAAC,YAAY;QAC1B,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,kBAAkB;IACpB,KAAK,GAAG,aAAa,CAAC;IACvB,OAAO,CAAoB;IAEnC,YAAY,GAA2B;QACrC,uEAAuE;QACvE,wEAAwE;QACxE,4BAA4B;QAC5B,MAAM,eAAe,GAAG,GAAG,CAAC,UAAU,KAAK,UAAU,IAAI,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC;QACrF,IAAI,CAAC,OAAO,GAAG,IAAI,iBAAiB,CAAC;YACnC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5B,eAAe;SAChB,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAA+B;QACzC,sEAAsE;QACtE,qEAAqE;QACrE,wEAAwE;QACxE,0DAA0D;QAC1D,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAA8B,EAAE,EAAE;YAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO;iBACtB,UAAU,EAAE;iBACZ,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;YAClD,IAAI,IAAI;gBAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;CACF;AAED,mBAAmB,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC"}
@@ -39,6 +39,7 @@
39
39
  * take the LAST complete line). File deletion mid-parse returns
40
40
  * "unknown".
41
41
  */
42
+ import type { SessionActivity } from "../types.js";
42
43
  export type ClaudeSessionState = "working" | "waiting" | "error" | "unknown";
43
44
  export interface SessionStateInfo {
44
45
  state: ClaudeSessionState;
@@ -53,4 +54,5 @@ export interface SessionStateInfo {
53
54
  cwd?: string;
54
55
  }
55
56
  export declare function parseSessionState(filePath: string): Promise<SessionStateInfo>;
57
+ export declare function parseSessionActivity(filePath: string): Promise<SessionActivity | undefined>;
56
58
  //# sourceMappingURL=parser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/integrations/claude-code/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAIH,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAgBD,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoDnF"}
1
+ {"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../src/integrations/claude-code/parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,kBAAkB,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,iEAAiE;IACjE,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAgBD,wBAAsB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoDnF;AAwID,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CA+GtC"}