@oratis/lisa 0.7.0 → 0.9.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 (141) hide show
  1. package/dist/autostart/install.d.ts +28 -0
  2. package/dist/autostart/install.d.ts.map +1 -0
  3. package/dist/autostart/install.js +180 -0
  4. package/dist/autostart/install.js.map +1 -0
  5. package/dist/cli.js +49 -1
  6. package/dist/cli.js.map +1 -1
  7. package/dist/heartbeat/install.d.ts.map +1 -1
  8. package/dist/heartbeat/install.js +1 -43
  9. package/dist/heartbeat/install.js.map +1 -1
  10. package/dist/heartbeat/runner.d.ts.map +1 -1
  11. package/dist/heartbeat/runner.js +11 -0
  12. package/dist/heartbeat/runner.js.map +1 -1
  13. package/dist/integrations/aider/observer.d.ts +48 -0
  14. package/dist/integrations/aider/observer.d.ts.map +1 -0
  15. package/dist/integrations/aider/observer.js +196 -0
  16. package/dist/integrations/aider/observer.js.map +1 -0
  17. package/dist/integrations/comparisons.d.ts +23 -0
  18. package/dist/integrations/comparisons.d.ts.map +1 -0
  19. package/dist/integrations/comparisons.js +47 -0
  20. package/dist/integrations/comparisons.js.map +1 -0
  21. package/dist/integrations/github-pr/observer.d.ts +85 -0
  22. package/dist/integrations/github-pr/observer.d.ts.map +1 -0
  23. package/dist/integrations/github-pr/observer.js +261 -0
  24. package/dist/integrations/github-pr/observer.js.map +1 -0
  25. package/dist/integrations/hub.d.ts.map +1 -1
  26. package/dist/integrations/hub.js +10 -0
  27. package/dist/integrations/hub.js.map +1 -1
  28. package/dist/integrations/opencode/observer.d.ts +74 -0
  29. package/dist/integrations/opencode/observer.d.ts.map +1 -0
  30. package/dist/integrations/opencode/observer.js +207 -0
  31. package/dist/integrations/opencode/observer.js.map +1 -0
  32. package/dist/integrations/registry.d.ts.map +1 -1
  33. package/dist/integrations/registry.js +3 -1
  34. package/dist/integrations/registry.js.map +1 -1
  35. package/dist/integrations/scheduled-dispatch.d.ts +42 -0
  36. package/dist/integrations/scheduled-dispatch.d.ts.map +1 -0
  37. package/dist/integrations/scheduled-dispatch.js +140 -0
  38. package/dist/integrations/scheduled-dispatch.js.map +1 -0
  39. package/dist/launchd.d.ts +18 -0
  40. package/dist/launchd.d.ts.map +1 -0
  41. package/dist/launchd.js +60 -0
  42. package/dist/launchd.js.map +1 -0
  43. package/dist/mcp/config.d.ts +4 -0
  44. package/dist/mcp/config.d.ts.map +1 -1
  45. package/dist/mcp/config.js +34 -0
  46. package/dist/mcp/config.js.map +1 -1
  47. package/dist/orchestrator/journal.d.ts +46 -0
  48. package/dist/orchestrator/journal.d.ts.map +1 -0
  49. package/dist/orchestrator/journal.js +82 -0
  50. package/dist/orchestrator/journal.js.map +1 -0
  51. package/dist/orchestrator/recap.d.ts +38 -0
  52. package/dist/orchestrator/recap.d.ts.map +1 -0
  53. package/dist/orchestrator/recap.js +134 -0
  54. package/dist/orchestrator/recap.js.map +1 -0
  55. package/dist/screen_advisor/engine.d.ts +79 -0
  56. package/dist/screen_advisor/engine.d.ts.map +1 -0
  57. package/dist/screen_advisor/engine.js +128 -0
  58. package/dist/screen_advisor/engine.js.map +1 -0
  59. package/dist/soul/lock.d.ts +7 -4
  60. package/dist/soul/lock.d.ts.map +1 -1
  61. package/dist/soul/lock.js +33 -9
  62. package/dist/soul/lock.js.map +1 -1
  63. package/dist/tools/agent_recap.d.ts +21 -0
  64. package/dist/tools/agent_recap.d.ts.map +1 -0
  65. package/dist/tools/agent_recap.js +43 -0
  66. package/dist/tools/agent_recap.js.map +1 -0
  67. package/dist/tools/compare_agents.d.ts +16 -0
  68. package/dist/tools/compare_agents.d.ts.map +1 -0
  69. package/dist/tools/compare_agents.js +145 -0
  70. package/dist/tools/compare_agents.js.map +1 -0
  71. package/dist/tools/dispatch_agent.d.ts +13 -0
  72. package/dist/tools/dispatch_agent.d.ts.map +1 -1
  73. package/dist/tools/dispatch_agent.js +46 -46
  74. package/dist/tools/dispatch_agent.js.map +1 -1
  75. package/dist/tools/exec-util.d.ts +18 -0
  76. package/dist/tools/exec-util.d.ts.map +1 -0
  77. package/dist/tools/exec-util.js +72 -0
  78. package/dist/tools/exec-util.js.map +1 -0
  79. package/dist/tools/github.d.ts +34 -0
  80. package/dist/tools/github.d.ts.map +1 -0
  81. package/dist/tools/github.js +140 -0
  82. package/dist/tools/github.js.map +1 -0
  83. package/dist/tools/github_link.d.ts +36 -0
  84. package/dist/tools/github_link.d.ts.map +1 -0
  85. package/dist/tools/github_link.js +127 -0
  86. package/dist/tools/github_link.js.map +1 -0
  87. package/dist/tools/inspect_agent.d.ts +21 -0
  88. package/dist/tools/inspect_agent.d.ts.map +1 -0
  89. package/dist/tools/inspect_agent.js +87 -0
  90. package/dist/tools/inspect_agent.js.map +1 -0
  91. package/dist/tools/list_agents.d.ts +21 -0
  92. package/dist/tools/list_agents.d.ts.map +1 -0
  93. package/dist/tools/list_agents.js +88 -0
  94. package/dist/tools/list_agents.js.map +1 -0
  95. package/dist/tools/mcp.d.ts +28 -0
  96. package/dist/tools/mcp.d.ts.map +1 -0
  97. package/dist/tools/mcp.js +55 -0
  98. package/dist/tools/mcp.js.map +1 -0
  99. package/dist/tools/npm_info.d.ts +21 -0
  100. package/dist/tools/npm_info.d.ts.map +1 -0
  101. package/dist/tools/npm_info.js +102 -0
  102. package/dist/tools/npm_info.js.map +1 -0
  103. package/dist/tools/pr_status.d.ts +31 -0
  104. package/dist/tools/pr_status.d.ts.map +1 -0
  105. package/dist/tools/pr_status.js +90 -0
  106. package/dist/tools/pr_status.js.map +1 -0
  107. package/dist/tools/registry.d.ts.map +1 -1
  108. package/dist/tools/registry.js +27 -0
  109. package/dist/tools/registry.js.map +1 -1
  110. package/dist/tools/repo_digest.d.ts +33 -0
  111. package/dist/tools/repo_digest.d.ts.map +1 -0
  112. package/dist/tools/repo_digest.js +113 -0
  113. package/dist/tools/repo_digest.js.map +1 -0
  114. package/dist/tools/review_diff.d.ts +28 -0
  115. package/dist/tools/review_diff.d.ts.map +1 -0
  116. package/dist/tools/review_diff.js +68 -0
  117. package/dist/tools/review_diff.js.map +1 -0
  118. package/dist/tools/run_checks.d.ts +15 -0
  119. package/dist/tools/run_checks.d.ts.map +1 -0
  120. package/dist/tools/run_checks.js +117 -0
  121. package/dist/tools/run_checks.js.map +1 -0
  122. package/dist/tools/scheduled_dispatch.d.ts +27 -0
  123. package/dist/tools/scheduled_dispatch.d.ts.map +1 -0
  124. package/dist/tools/scheduled_dispatch.js +57 -0
  125. package/dist/tools/scheduled_dispatch.js.map +1 -0
  126. package/dist/voice/dictation.d.ts +51 -0
  127. package/dist/voice/dictation.d.ts.map +1 -0
  128. package/dist/voice/dictation.js +70 -0
  129. package/dist/voice/dictation.js.map +1 -0
  130. package/dist/web/island.d.ts +1 -1
  131. package/dist/web/island.d.ts.map +1 -1
  132. package/dist/web/island.js +84 -8
  133. package/dist/web/island.js.map +1 -1
  134. package/dist/web/lisa-html.d.ts +1 -1
  135. package/dist/web/lisa-html.d.ts.map +1 -1
  136. package/dist/web/lisa-html.js +80 -13
  137. package/dist/web/lisa-html.js.map +1 -1
  138. package/dist/web/server.d.ts.map +1 -1
  139. package/dist/web/server.js +156 -1
  140. package/dist/web/server.js.map +1 -1
  141. package/package.json +1 -1
@@ -0,0 +1,42 @@
1
+ export type ScheduledAgent = "claude" | "codex" | "opencode" | "aider";
2
+ export interface ScheduledDispatch {
3
+ id: string;
4
+ agent: ScheduledAgent;
5
+ task: string;
6
+ cwd: string;
7
+ /** "every:30m" | "every:2h" | "every:1d" | "daily:09:00" */
8
+ schedule: string;
9
+ maxRuns: number;
10
+ runs: number;
11
+ lastRunAt?: number;
12
+ createdAt: number;
13
+ }
14
+ export declare const DEFAULT_MAX_RUNS = 30;
15
+ export declare function loadScheduled(): Promise<ScheduledDispatch[]>;
16
+ export declare function addScheduled(e: Omit<ScheduledDispatch, "id" | "runs" | "createdAt"> & {
17
+ createdAt?: number;
18
+ }): Promise<ScheduledDispatch>;
19
+ export declare function removeScheduled(id: string): Promise<boolean>;
20
+ /** Persist run bookkeeping after a fire. */
21
+ export declare function markRan(id: string, when: number): Promise<void>;
22
+ export declare function isValidSchedule(schedule: string): boolean;
23
+ /**
24
+ * Is this entry due to fire at `now`? Pure + testable.
25
+ * - capped: false once runs >= maxRuns
26
+ * - every:N — due when now - lastRunAt >= interval (or never run)
27
+ * - daily:HH:MM — due when now is past today's HH:MM and it hasn't run since
28
+ */
29
+ export declare function isDue(e: ScheduledDispatch, now: number): boolean;
30
+ /**
31
+ * Fire every due entry via the injected `launch` (dependency-injected so this
32
+ * module stays free of the tools layer and is testable). Marks each fired entry
33
+ * regardless of launch success, so a broken entry burns its run budget rather
34
+ * than retrying every tick. Returns one summary line per fire.
35
+ */
36
+ export declare function fireDue(now: number, launch: (e: ScheduledDispatch) => Promise<{
37
+ pid?: number;
38
+ error?: string;
39
+ }>): Promise<string[]>;
40
+ /** Human description of an entry for listing. */
41
+ export declare function describeScheduled(e: ScheduledDispatch): string;
42
+ //# sourceMappingURL=scheduled-dispatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-dispatch.d.ts","sourceRoot":"","sources":["../../src/integrations/scheduled-dispatch.ts"],"names":[],"mappings":"AAeA,MAAM,MAAM,cAAc,GAAG,QAAQ,GAAG,OAAO,GAAG,UAAU,GAAG,OAAO,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,4DAA4D;IAC5D,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAGD,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAMnC,wBAAsB,aAAa,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAQlE;AAMD,wBAAsB,YAAY,CAChC,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,CAAC,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E,OAAO,CAAC,iBAAiB,CAAC,CAW5B;AAED,wBAAsB,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMlE;AAED,4CAA4C;AAC5C,wBAAsB,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOrE;AAqBD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,CAAC,EAAE,iBAAiB,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAoBhE;AAED;;;;;GAKG;AACH,wBAAsB,OAAO,CAC3B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1E,OAAO,CAAC,MAAM,EAAE,CAAC,CAenB;AAED,iDAAiD;AACjD,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAI9D"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Scheduled dispatches — a small persisted store of "launch agent X in repo Y
3
+ * with task Z on schedule S". The heartbeat runner checks it each tick and
4
+ * fires the due ones (see fireDueScheduledDispatches, called from the runner).
5
+ *
6
+ * Safety: this auto-launches autonomous agents unattended at heartbeat cadence,
7
+ * so each entry carries a maxRuns cap (default 30) and records its run count;
8
+ * once spent it's inert until the user removes/re-adds it.
9
+ */
10
+ import { randomUUID } from "node:crypto";
11
+ import path from "node:path";
12
+ import { readFile } from "node:fs/promises";
13
+ import { atomicWrite } from "../fs-utils.js";
14
+ import { LISA_HOME } from "../paths.js";
15
+ const FILE = path.join(LISA_HOME, "scheduled-dispatches.json");
16
+ export const DEFAULT_MAX_RUNS = 30;
17
+ export async function loadScheduled() {
18
+ try {
19
+ const raw = await readFile(FILE, "utf8");
20
+ const store = JSON.parse(raw);
21
+ return Array.isArray(store.entries) ? store.entries : [];
22
+ }
23
+ catch {
24
+ return [];
25
+ }
26
+ }
27
+ async function saveScheduled(entries) {
28
+ await atomicWrite(FILE, JSON.stringify({ entries }, null, 2));
29
+ }
30
+ export async function addScheduled(e) {
31
+ const entries = await loadScheduled();
32
+ const entry = {
33
+ ...e,
34
+ id: randomUUID().slice(0, 8),
35
+ runs: 0,
36
+ createdAt: e.createdAt ?? Date.now(),
37
+ };
38
+ entries.push(entry);
39
+ await saveScheduled(entries);
40
+ return entry;
41
+ }
42
+ export async function removeScheduled(id) {
43
+ const entries = await loadScheduled();
44
+ const next = entries.filter((e) => e.id !== id && !e.id.startsWith(id));
45
+ if (next.length === entries.length)
46
+ return false;
47
+ await saveScheduled(next);
48
+ return true;
49
+ }
50
+ /** Persist run bookkeeping after a fire. */
51
+ export async function markRan(id, when) {
52
+ const entries = await loadScheduled();
53
+ const e = entries.find((x) => x.id === id);
54
+ if (!e)
55
+ return;
56
+ e.runs += 1;
57
+ e.lastRunAt = when;
58
+ await saveScheduled(entries);
59
+ }
60
+ /** Parse "every:<N><m|h|d>" → interval ms, or null if not that form. */
61
+ function parseEvery(schedule) {
62
+ const m = schedule.match(/^every:(\d+)([mhd])$/i);
63
+ if (!m)
64
+ return null;
65
+ const n = parseInt(m[1], 10);
66
+ const unit = m[2].toLowerCase();
67
+ return n * (unit === "m" ? 60_000 : unit === "h" ? 3_600_000 : 86_400_000);
68
+ }
69
+ /** Parse "daily:HH:MM" → {h, m}, or null. */
70
+ function parseDaily(schedule) {
71
+ const m = schedule.match(/^daily:(\d{1,2}):(\d{2})$/i);
72
+ if (!m)
73
+ return null;
74
+ const h = parseInt(m[1], 10);
75
+ const min = parseInt(m[2], 10);
76
+ if (h > 23 || min > 59)
77
+ return null;
78
+ return { h, m: min };
79
+ }
80
+ export function isValidSchedule(schedule) {
81
+ return parseEvery(schedule) !== null || parseDaily(schedule) !== null;
82
+ }
83
+ /**
84
+ * Is this entry due to fire at `now`? Pure + testable.
85
+ * - capped: false once runs >= maxRuns
86
+ * - every:N — due when now - lastRunAt >= interval (or never run)
87
+ * - daily:HH:MM — due when now is past today's HH:MM and it hasn't run since
88
+ */
89
+ export function isDue(e, now) {
90
+ if (e.runs >= e.maxRuns)
91
+ return false;
92
+ const everyMs = parseEvery(e.schedule);
93
+ if (everyMs !== null) {
94
+ if (e.lastRunAt == null)
95
+ return true;
96
+ return now - e.lastRunAt >= everyMs;
97
+ }
98
+ const daily = parseDaily(e.schedule);
99
+ if (daily) {
100
+ const target = new Date(now);
101
+ target.setHours(daily.h, daily.m, 0, 0);
102
+ const targetMs = target.getTime();
103
+ if (now < targetMs)
104
+ return false; // today's time hasn't arrived
105
+ // Past today's target: due unless we already ran at/after it.
106
+ return e.lastRunAt == null || e.lastRunAt < targetMs;
107
+ }
108
+ return false; // unparseable schedule never fires
109
+ }
110
+ /**
111
+ * Fire every due entry via the injected `launch` (dependency-injected so this
112
+ * module stays free of the tools layer and is testable). Marks each fired entry
113
+ * regardless of launch success, so a broken entry burns its run budget rather
114
+ * than retrying every tick. Returns one summary line per fire.
115
+ */
116
+ export async function fireDue(now, launch) {
117
+ const entries = await loadScheduled();
118
+ const fired = [];
119
+ for (const e of entries) {
120
+ if (!isDue(e, now))
121
+ continue;
122
+ let result;
123
+ try {
124
+ result = await launch(e);
125
+ }
126
+ catch (err) {
127
+ result = { error: err.message };
128
+ }
129
+ await markRan(e.id, now);
130
+ fired.push(`${e.agent} in ${e.cwd} — ${result.error ? "FAILED: " + result.error : "pid " + result.pid}`);
131
+ }
132
+ return fired;
133
+ }
134
+ /** Human description of an entry for listing. */
135
+ export function describeScheduled(e) {
136
+ const last = e.lastRunAt ? new Date(e.lastRunAt).toISOString().slice(0, 16).replace("T", " ") : "never";
137
+ const task = e.task.length > 60 ? e.task.slice(0, 57) + "…" : e.task;
138
+ return `• ${e.id} ${e.agent} @ ${e.schedule} (${e.runs}/${e.maxRuns} runs, last ${last})\n ${e.cwd}\n "${task}"`;
139
+ }
140
+ //# sourceMappingURL=scheduled-dispatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduled-dispatch.js","sourceRoot":"","sources":["../../src/integrations/scheduled-dispatch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /** Escape a string for inclusion as XML text/attribute content in a plist. */
2
+ export declare function escapeXml(s: string): string;
3
+ /** Run a command, resolving stdout on exit 0 and rejecting otherwise. */
4
+ export declare function runCmd(cmd: string, args: string[]): Promise<string>;
5
+ /**
6
+ * Best-effort path to the `lisa` binary, used for the human-readable
7
+ * instructions line and the Linux service snippet. May return a "node <path>"
8
+ * form when only the local dist build is available.
9
+ */
10
+ export declare function resolveLisaBin(): Promise<string>;
11
+ /**
12
+ * Resolve the displayed binary into launchd ProgramArguments slots (one argv
13
+ * element per array entry). A "node <path>" form is split into two slots with
14
+ * an absolute node path so launchd — which has no shell and a minimal PATH —
15
+ * can exec it.
16
+ */
17
+ export declare function resolveLisaArgv(displayedBin: string): Promise<string[]>;
18
+ //# sourceMappingURL=launchd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launchd.d.ts","sourceRoot":"","sources":["../src/launchd.ts"],"names":[],"mappings":"AAQA,8EAA8E;AAC9E,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAI3C;AAED,yEAAyE;AACzE,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAcnE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,CAYtD;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAO7E"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Shared launchd / process helpers used by both the heartbeat scheduler and
3
+ * the login autostart installer. Kept dependency-free (node built-ins only).
4
+ */
5
+ import fs from "node:fs/promises";
6
+ import path from "node:path";
7
+ import { spawn } from "node:child_process";
8
+ /** Escape a string for inclusion as XML text/attribute content in a plist. */
9
+ export function escapeXml(s) {
10
+ return s.replace(/[<>&"']/g, (c) => ({ "<": "&lt;", ">": "&gt;", "&": "&amp;", '"': "&quot;", "'": "&apos;" }[c]));
11
+ }
12
+ /** Run a command, resolving stdout on exit 0 and rejecting otherwise. */
13
+ export function runCmd(cmd, args) {
14
+ return new Promise((resolve, reject) => {
15
+ const child = spawn(cmd, args);
16
+ let stdout = "";
17
+ let stderr = "";
18
+ child.stdout.on("data", (b) => (stdout += b.toString("utf8")));
19
+ child.stderr.on("data", (b) => (stderr += b.toString("utf8")));
20
+ child.on("error", reject);
21
+ child.on("close", (code) => code === 0
22
+ ? resolve(stdout)
23
+ : reject(new Error(`${cmd} exited ${code}: ${stderr.trim()}`)));
24
+ });
25
+ }
26
+ /**
27
+ * Best-effort path to the `lisa` binary, used for the human-readable
28
+ * instructions line and the Linux service snippet. May return a "node <path>"
29
+ * form when only the local dist build is available.
30
+ */
31
+ export async function resolveLisaBin() {
32
+ try {
33
+ const out = await runCmd("which", ["lisa"]);
34
+ const trimmed = out.trim();
35
+ if (trimmed)
36
+ return trimmed;
37
+ }
38
+ catch { }
39
+ const here = path.resolve(process.cwd(), "dist", "cli.js");
40
+ try {
41
+ await fs.access(here);
42
+ return `node ${here}`;
43
+ }
44
+ catch { }
45
+ return "lisa";
46
+ }
47
+ /**
48
+ * Resolve the displayed binary into launchd ProgramArguments slots (one argv
49
+ * element per array entry). A "node <path>" form is split into two slots with
50
+ * an absolute node path so launchd — which has no shell and a minimal PATH —
51
+ * can exec it.
52
+ */
53
+ export async function resolveLisaArgv(displayedBin) {
54
+ if (displayedBin.startsWith("node ")) {
55
+ const nodePath = (await runCmd("which", ["node"]).catch(() => "node")).trim() || "node";
56
+ return [nodePath, displayedBin.slice("node ".length)];
57
+ }
58
+ return [displayedBin];
59
+ }
60
+ //# sourceMappingURL=launchd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launchd.js","sourceRoot":"","sources":["../src/launchd.ts"],"names":[],"mappings":"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"}
@@ -11,4 +11,8 @@ export interface McpConfig {
11
11
  }
12
12
  export declare function loadMcpConfig(): Promise<McpServerSpec[]>;
13
13
  export declare const MCP_CONFIG_PATH: string;
14
+ /** Add or replace a server in mcp.json (upsert by name). Returns the spec. */
15
+ export declare function saveMcpServer(name: string, spec: Omit<McpServerSpec, "name">): Promise<void>;
16
+ /** Remove a server from mcp.json. Returns false if it wasn't there. */
17
+ export declare function deleteMcpServer(name: string): Promise<boolean>;
14
18
  //# sourceMappingURL=config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAID,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB9D;AAED,eAAO,MAAM,eAAe,QAAc,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAID,wBAAsB,aAAa,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB9D;AAED,eAAO,MAAM,eAAe,QAAc,CAAC;AAE3C,8EAA8E;AAC9E,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,uEAAuE;AACvE,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYpE"}
@@ -25,4 +25,38 @@ export async function loadMcpConfig() {
25
25
  }));
26
26
  }
27
27
  export const MCP_CONFIG_PATH = CONFIG_PATH;
28
+ /** Add or replace a server in mcp.json (upsert by name). Returns the spec. */
29
+ export async function saveMcpServer(name, spec) {
30
+ let config = { mcpServers: {} };
31
+ if (await pathExists(CONFIG_PATH)) {
32
+ try {
33
+ config = JSON.parse(await fs.readFile(CONFIG_PATH, "utf8"));
34
+ }
35
+ catch {
36
+ // start fresh on a corrupt file rather than lose the add
37
+ }
38
+ }
39
+ if (!config.mcpServers)
40
+ config.mcpServers = {};
41
+ config.mcpServers[name] = spec;
42
+ await fs.mkdir(path.dirname(CONFIG_PATH), { recursive: true });
43
+ await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
44
+ }
45
+ /** Remove a server from mcp.json. Returns false if it wasn't there. */
46
+ export async function deleteMcpServer(name) {
47
+ if (!(await pathExists(CONFIG_PATH)))
48
+ return false;
49
+ let config;
50
+ try {
51
+ config = JSON.parse(await fs.readFile(CONFIG_PATH, "utf8"));
52
+ }
53
+ catch {
54
+ return false;
55
+ }
56
+ if (!config.mcpServers || !(name in config.mcpServers))
57
+ return false;
58
+ delete config.mcpServers[name];
59
+ await fs.writeFile(CONFIG_PATH, JSON.stringify(config, null, 2));
60
+ return true;
61
+ }
28
62
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAe5C,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAChD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACnD,IAAI,MAAiB,CAAC;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAc,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,WAAW,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;IACxC,OAAO,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACpD,IAAI;QACJ,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,IAAI;QAC7B,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,KAAK;KACrC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/mcp/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Orchestrator journal (L6) — a small temporal record of agent activity.
3
+ *
4
+ * The hub (L1) only holds a *live snapshot*; once a session goes idle/done it
5
+ * falls out of `hub.list()`. The advisor (L5) surfaces relevance-gated alerts.
6
+ * Neither answers "what actually happened across all my agents while I was
7
+ * away?" — which needs a record over *time*, including sessions that have since
8
+ * ended. This journal is that record: every meaningful state transition the hub
9
+ * emits is appended to a capped ring buffer, from which recap.ts synthesizes a
10
+ * cross-agent "while you were away" digest.
11
+ *
12
+ * In-memory + capped (no growth): a recap covers the current server's uptime,
13
+ * which is exactly the window the user was away *for*. PRIVACY: stores only the
14
+ * same structural metadata the hub emits (agent, project, state, tool/file
15
+ * names, error strings) — never prompts, replies, or file contents.
16
+ */
17
+ import type { AgentSession, AgentSessionState } from "../integrations/types.js";
18
+ export interface AgentEvent {
19
+ agent: string;
20
+ sessionId: string;
21
+ project: string;
22
+ cwd?: string;
23
+ state: AgentSessionState;
24
+ stateReason: string;
25
+ /** Epoch ms of the transition. */
26
+ at: number;
27
+ /** Compact structural activity summary (tool · file · $cmd), if any. */
28
+ activity?: string;
29
+ /** Short error string when the session errored. */
30
+ error?: string;
31
+ }
32
+ /** Compact, structural one-liner from a session's Tier-2 activity. */
33
+ export declare function summarizeActivity(s: AgentSession): string | undefined;
34
+ /**
35
+ * Append a transition. Consecutive events for the same session with the same
36
+ * state + reason are collapsed (we only record *changes*), so a session that
37
+ * sits in "working" for an hour produces one entry, not hundreds.
38
+ */
39
+ export declare function recordEvent(s: AgentSession, now?: number): AgentEvent | null;
40
+ /** All recorded events (oldest → newest). */
41
+ export declare function allEvents(): AgentEvent[];
42
+ /** Events at or after `sinceMs` (epoch ms), oldest → newest. */
43
+ export declare function eventsSince(sinceMs: number): AgentEvent[];
44
+ /** Test hook — wipe the buffer. */
45
+ export declare function _resetJournalForTest(): void;
46
+ //# sourceMappingURL=journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/orchestrator/journal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEhF,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,iBAAiB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,sEAAsE;AACtE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAYrE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,GAAE,MAAmB,GAAG,UAAU,GAAG,IAAI,CA0BxF;AAED,6CAA6C;AAC7C,wBAAgB,SAAS,IAAI,UAAU,EAAE,CAExC;AAED,gEAAgE;AAChE,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAEzD;AAED,mCAAmC;AACnC,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Orchestrator journal (L6) — a small temporal record of agent activity.
3
+ *
4
+ * The hub (L1) only holds a *live snapshot*; once a session goes idle/done it
5
+ * falls out of `hub.list()`. The advisor (L5) surfaces relevance-gated alerts.
6
+ * Neither answers "what actually happened across all my agents while I was
7
+ * away?" — which needs a record over *time*, including sessions that have since
8
+ * ended. This journal is that record: every meaningful state transition the hub
9
+ * emits is appended to a capped ring buffer, from which recap.ts synthesizes a
10
+ * cross-agent "while you were away" digest.
11
+ *
12
+ * In-memory + capped (no growth): a recap covers the current server's uptime,
13
+ * which is exactly the window the user was away *for*. PRIVACY: stores only the
14
+ * same structural metadata the hub emits (agent, project, state, tool/file
15
+ * names, error strings) — never prompts, replies, or file contents.
16
+ */
17
+ const MAX_EVENTS = 400;
18
+ const events = [];
19
+ /** Compact, structural one-liner from a session's Tier-2 activity. */
20
+ export function summarizeActivity(s) {
21
+ const a = s.activity;
22
+ if (!a)
23
+ return undefined;
24
+ const bits = [];
25
+ const tool = a.lastTools?.length ? a.lastTools[a.lastTools.length - 1] : "";
26
+ if (tool)
27
+ bits.push(tool);
28
+ if (a.lastCommandName)
29
+ bits.push("$" + a.lastCommandName);
30
+ const file = a.filesTouched?.length
31
+ ? a.filesTouched[a.filesTouched.length - 1].split("/").pop()
32
+ : "";
33
+ if (file)
34
+ bits.push(file);
35
+ return bits.length ? bits.join(" · ") : undefined;
36
+ }
37
+ /**
38
+ * Append a transition. Consecutive events for the same session with the same
39
+ * state + reason are collapsed (we only record *changes*), so a session that
40
+ * sits in "working" for an hour produces one entry, not hundreds.
41
+ */
42
+ export function recordEvent(s, now = Date.now()) {
43
+ // Find the most recent event for this session.
44
+ let prev;
45
+ for (let i = events.length - 1; i >= 0; i--) {
46
+ if (events[i].sessionId === s.sessionId) {
47
+ prev = events[i];
48
+ break;
49
+ }
50
+ }
51
+ if (prev && prev.state === s.state && prev.stateReason === s.stateReason) {
52
+ return null; // no real transition
53
+ }
54
+ const ev = {
55
+ agent: s.agent,
56
+ sessionId: s.sessionId,
57
+ project: s.project,
58
+ cwd: s.cwd,
59
+ state: s.state,
60
+ stateReason: s.stateReason,
61
+ at: Number.isFinite(s.lastMtime) && s.lastMtime > 0 ? s.lastMtime : now,
62
+ activity: summarizeActivity(s),
63
+ error: s.activity?.lastError,
64
+ };
65
+ events.push(ev);
66
+ if (events.length > MAX_EVENTS)
67
+ events.splice(0, events.length - MAX_EVENTS);
68
+ return ev;
69
+ }
70
+ /** All recorded events (oldest → newest). */
71
+ export function allEvents() {
72
+ return events.slice();
73
+ }
74
+ /** Events at or after `sinceMs` (epoch ms), oldest → newest. */
75
+ export function eventsSince(sinceMs) {
76
+ return events.filter((e) => e.at >= sinceMs);
77
+ }
78
+ /** Test hook — wipe the buffer. */
79
+ export function _resetJournalForTest() {
80
+ events.length = 0;
81
+ }
82
+ //# sourceMappingURL=journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/orchestrator/journal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Recap (L6) — synthesize the orchestrator journal into a cross-agent
3
+ * "while you were away" digest. Deterministic (no LLM): given the journal
4
+ * events in a time window, group by project, tally how each session ended,
5
+ * and surface the notable moments (errors, finishes, merged PRs, blocks).
6
+ *
7
+ * This is the narrative counterpart to the advisor's alerts and list_agents'
8
+ * roster: it answers "what happened, across everything, since I left?"
9
+ */
10
+ import type { AgentEvent } from "./journal.js";
11
+ export interface ProjectRecap {
12
+ project: string;
13
+ agents: string[];
14
+ /** Distinct sessions seen in the window. */
15
+ sessions: number;
16
+ finished: number;
17
+ errored: number;
18
+ active: number;
19
+ /** Up to a few file basenames touched. */
20
+ files: string[];
21
+ /** Human-readable notable lines for this project. */
22
+ notable: string[];
23
+ }
24
+ export interface Recap {
25
+ sinceMs: number;
26
+ now: number;
27
+ /** Distinct sessions that had any event in the window. */
28
+ totalSessions: number;
29
+ totalEvents: number;
30
+ projects: ProjectRecap[];
31
+ /** One-line headline. */
32
+ headline: string;
33
+ }
34
+ /** Build the structured recap from journal events in [sinceMs, now]. Pure. */
35
+ export declare function buildRecap(events: AgentEvent[], sinceMs: number, now: number): Recap;
36
+ /** Render the recap as a readable multi-line digest. Pure. */
37
+ export declare function formatRecap(recap: Recap): string;
38
+ //# sourceMappingURL=recap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recap.d.ts","sourceRoot":"","sources":["../../src/orchestrator/recap.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG/C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4CAA4C;IAC5C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,qDAAqD;IACrD,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,KAAK;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAoBD,8EAA8E;AAC9E,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,KAAK,CA6GpF;AAED,8DAA8D;AAC9D,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAShD"}