@oratis/lisa 0.5.0 → 0.8.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 (133) hide show
  1. package/README.md +5 -0
  2. package/dist/autostart/install.d.ts +28 -0
  3. package/dist/autostart/install.d.ts.map +1 -0
  4. package/dist/autostart/install.js +180 -0
  5. package/dist/autostart/install.js.map +1 -0
  6. package/dist/cli.js +49 -1
  7. package/dist/cli.js.map +1 -1
  8. package/dist/heartbeat/install.d.ts.map +1 -1
  9. package/dist/heartbeat/install.js +1 -43
  10. package/dist/heartbeat/install.js.map +1 -1
  11. package/dist/heartbeat/runner.d.ts.map +1 -1
  12. package/dist/heartbeat/runner.js +11 -0
  13. package/dist/heartbeat/runner.js.map +1 -1
  14. package/dist/idle/runner.d.ts +12 -0
  15. package/dist/idle/runner.d.ts.map +1 -1
  16. package/dist/idle/runner.js +33 -2
  17. package/dist/idle/runner.js.map +1 -1
  18. package/dist/integrations/aider/observer.d.ts +48 -0
  19. package/dist/integrations/aider/observer.d.ts.map +1 -0
  20. package/dist/integrations/aider/observer.js +196 -0
  21. package/dist/integrations/aider/observer.js.map +1 -0
  22. package/dist/integrations/comparisons.d.ts +23 -0
  23. package/dist/integrations/comparisons.d.ts.map +1 -0
  24. package/dist/integrations/comparisons.js +47 -0
  25. package/dist/integrations/comparisons.js.map +1 -0
  26. package/dist/integrations/dispatch-ledger.d.ts +51 -0
  27. package/dist/integrations/dispatch-ledger.d.ts.map +1 -0
  28. package/dist/integrations/dispatch-ledger.js +106 -0
  29. package/dist/integrations/dispatch-ledger.js.map +1 -0
  30. package/dist/integrations/github-pr/observer.d.ts +85 -0
  31. package/dist/integrations/github-pr/observer.d.ts.map +1 -0
  32. package/dist/integrations/github-pr/observer.js +261 -0
  33. package/dist/integrations/github-pr/observer.js.map +1 -0
  34. package/dist/integrations/hub.d.ts.map +1 -1
  35. package/dist/integrations/hub.js +10 -0
  36. package/dist/integrations/hub.js.map +1 -1
  37. package/dist/integrations/opencode/observer.d.ts +74 -0
  38. package/dist/integrations/opencode/observer.d.ts.map +1 -0
  39. package/dist/integrations/opencode/observer.js +207 -0
  40. package/dist/integrations/opencode/observer.js.map +1 -0
  41. package/dist/integrations/registry.d.ts.map +1 -1
  42. package/dist/integrations/registry.js +3 -1
  43. package/dist/integrations/registry.js.map +1 -1
  44. package/dist/integrations/scheduled-dispatch.d.ts +42 -0
  45. package/dist/integrations/scheduled-dispatch.d.ts.map +1 -0
  46. package/dist/integrations/scheduled-dispatch.js +140 -0
  47. package/dist/integrations/scheduled-dispatch.js.map +1 -0
  48. package/dist/launchd.d.ts +18 -0
  49. package/dist/launchd.d.ts.map +1 -0
  50. package/dist/launchd.js +60 -0
  51. package/dist/launchd.js.map +1 -0
  52. package/dist/orchestrator/journal.d.ts +46 -0
  53. package/dist/orchestrator/journal.d.ts.map +1 -0
  54. package/dist/orchestrator/journal.js +82 -0
  55. package/dist/orchestrator/journal.js.map +1 -0
  56. package/dist/orchestrator/recap.d.ts +38 -0
  57. package/dist/orchestrator/recap.d.ts.map +1 -0
  58. package/dist/orchestrator/recap.js +134 -0
  59. package/dist/orchestrator/recap.js.map +1 -0
  60. package/dist/screen_advisor/engine.d.ts +79 -0
  61. package/dist/screen_advisor/engine.d.ts.map +1 -0
  62. package/dist/screen_advisor/engine.js +128 -0
  63. package/dist/screen_advisor/engine.js.map +1 -0
  64. package/dist/soul/birth.d.ts.map +1 -1
  65. package/dist/soul/birth.js +8 -0
  66. package/dist/soul/birth.js.map +1 -1
  67. package/dist/soul/lock.d.ts +7 -4
  68. package/dist/soul/lock.d.ts.map +1 -1
  69. package/dist/soul/lock.js +33 -9
  70. package/dist/soul/lock.js.map +1 -1
  71. package/dist/tools/agent_recap.d.ts +21 -0
  72. package/dist/tools/agent_recap.d.ts.map +1 -0
  73. package/dist/tools/agent_recap.js +43 -0
  74. package/dist/tools/agent_recap.js.map +1 -0
  75. package/dist/tools/compare_agents.d.ts +16 -0
  76. package/dist/tools/compare_agents.d.ts.map +1 -0
  77. package/dist/tools/compare_agents.js +145 -0
  78. package/dist/tools/compare_agents.js.map +1 -0
  79. package/dist/tools/dispatch_agent.d.ts +13 -0
  80. package/dist/tools/dispatch_agent.d.ts.map +1 -1
  81. package/dist/tools/dispatch_agent.js +49 -37
  82. package/dist/tools/dispatch_agent.js.map +1 -1
  83. package/dist/tools/exec-util.d.ts +18 -0
  84. package/dist/tools/exec-util.d.ts.map +1 -0
  85. package/dist/tools/exec-util.js +72 -0
  86. package/dist/tools/exec-util.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/pr_status.d.ts +31 -0
  96. package/dist/tools/pr_status.d.ts.map +1 -0
  97. package/dist/tools/pr_status.js +90 -0
  98. package/dist/tools/pr_status.js.map +1 -0
  99. package/dist/tools/registry.d.ts.map +1 -1
  100. package/dist/tools/registry.js +26 -0
  101. package/dist/tools/registry.js.map +1 -1
  102. package/dist/tools/repo_digest.d.ts +33 -0
  103. package/dist/tools/repo_digest.d.ts.map +1 -0
  104. package/dist/tools/repo_digest.js +113 -0
  105. package/dist/tools/repo_digest.js.map +1 -0
  106. package/dist/tools/review_diff.d.ts +28 -0
  107. package/dist/tools/review_diff.d.ts.map +1 -0
  108. package/dist/tools/review_diff.js +68 -0
  109. package/dist/tools/review_diff.js.map +1 -0
  110. package/dist/tools/run_checks.d.ts +15 -0
  111. package/dist/tools/run_checks.d.ts.map +1 -0
  112. package/dist/tools/run_checks.js +117 -0
  113. package/dist/tools/run_checks.js.map +1 -0
  114. package/dist/tools/scheduled_dispatch.d.ts +27 -0
  115. package/dist/tools/scheduled_dispatch.d.ts.map +1 -0
  116. package/dist/tools/scheduled_dispatch.js +57 -0
  117. package/dist/tools/scheduled_dispatch.js.map +1 -0
  118. package/dist/tools/signal_agent.d.ts +36 -0
  119. package/dist/tools/signal_agent.d.ts.map +1 -0
  120. package/dist/tools/signal_agent.js +140 -0
  121. package/dist/tools/signal_agent.js.map +1 -0
  122. package/dist/web/island.d.ts +1 -1
  123. package/dist/web/island.d.ts.map +1 -1
  124. package/dist/web/island.js +139 -27
  125. package/dist/web/island.js.map +1 -1
  126. package/dist/web/lisa-html.d.ts +1 -1
  127. package/dist/web/lisa-html.d.ts.map +1 -1
  128. package/dist/web/lisa-html.js +132 -4
  129. package/dist/web/lisa-html.js.map +1 -1
  130. package/dist/web/server.d.ts.map +1 -1
  131. package/dist/web/server.js +190 -0
  132. package/dist/web/server.js.map +1 -1
  133. package/package.json +1 -1
@@ -0,0 +1,21 @@
1
+ /**
2
+ * inspect_agent (vibe-coding) — the deep view of ONE observed session, where
3
+ * list_agents is the one-line-each roster. Full structural activity for the
4
+ * matched session: state + reason, branch, turn count, every tool it has run,
5
+ * every file it has touched, last command, pending permission, error, tokens.
6
+ *
7
+ * PRIVACY: structural metadata only — never conversation content (file PATHS
8
+ * and tool NAMES, not contents). For what a repo actually changed, use
9
+ * repo_digest / review_diff against its cwd.
10
+ */
11
+ import type { ToolDefinition } from "../types.js";
12
+ import type { AgentSession } from "../integrations/types.js";
13
+ interface InspectInput {
14
+ /** Session id (or a prefix), or a project name, to inspect. */
15
+ target: string;
16
+ }
17
+ /** Pure: full structural detail for one session. Exported for tests. */
18
+ export declare function formatDetail(s: AgentSession, now: number): string;
19
+ export declare const inspectAgentTool: ToolDefinition<InspectInput, string>;
20
+ export {};
21
+ //# sourceMappingURL=inspect_agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect_agent.d.ts","sourceRoot":"","sources":["../../src/tools/inspect_agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAE7D,UAAU,YAAY;IACpB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAUD,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAmBjE;AAYD,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,YAAY,EAAE,MAAM,CAoCjE,CAAC"}
@@ -0,0 +1,87 @@
1
+ import { getCurrentHub } from "../integrations/current-hub.js";
2
+ function ago(ms, now) {
3
+ const s = Math.max(0, Math.floor((now - ms) / 1000));
4
+ if (s < 60)
5
+ return `${s}s ago`;
6
+ const m = Math.floor(s / 60);
7
+ if (m < 60)
8
+ return `${m}m ago`;
9
+ return `${Math.floor(m / 60)}h ago`;
10
+ }
11
+ /** Pure: full structural detail for one session. Exported for tests. */
12
+ export function formatDetail(s, now) {
13
+ const a = s.activity;
14
+ const lines = [];
15
+ lines.push(`${s.project} · ${s.agent} · ${s.sessionId}`);
16
+ lines.push(` state: ${s.state}${s.stateReason ? ` (${s.stateReason})` : ""} · last active ${ago(s.lastMtime, now)}`);
17
+ if (s.cwd)
18
+ lines.push(` cwd: ${s.cwd}`);
19
+ if (a?.gitBranch)
20
+ lines.push(` branch: ${a.gitBranch}`);
21
+ if (typeof a?.turnCount === "number")
22
+ lines.push(` turns: ${a.turnCount}`);
23
+ if (a?.pendingPermission)
24
+ lines.push(` ⏳ waiting on permission: ${a.pendingPermission}`);
25
+ if (a?.lastCommandName)
26
+ lines.push(` last command: ${a.lastCommandName}`);
27
+ if (a?.lastTools && a.lastTools.length)
28
+ lines.push(` tools: ${a.lastTools.join(" → ")}`);
29
+ if (a?.filesTouched && a.filesTouched.length) {
30
+ lines.push(` files touched (${a.filesTouched.length}):`);
31
+ for (const f of a.filesTouched.slice(0, 15))
32
+ lines.push(` ${f}`);
33
+ if (a.filesTouched.length > 15)
34
+ lines.push(` … +${a.filesTouched.length - 15} more`);
35
+ }
36
+ if (a?.tokens)
37
+ lines.push(` tokens: ${a.tokens.input} in / ${a.tokens.output} out`);
38
+ if (a?.lastError)
39
+ lines.push(` error: ${a.lastError}`);
40
+ return lines.join("\n");
41
+ }
42
+ function matches(s, target) {
43
+ const t = target.toLowerCase();
44
+ return (s.sessionId.toLowerCase().startsWith(t) ||
45
+ s.sessionId.toLowerCase() === t ||
46
+ s.project.toLowerCase() === t ||
47
+ s.project.toLowerCase().includes(t));
48
+ }
49
+ export const inspectAgentTool = {
50
+ name: "inspect_agent",
51
+ description: "Deep-dive one observed agent session (by session id / prefix, or project name): its full " +
52
+ "structural activity — state + reason, git branch, turn count, every tool it ran, all files it " +
53
+ "touched, last command, pending permission, errors, token usage. Use when the user asks 'what is " +
54
+ "<session/project> doing in detail'. list_agents is the roster; this is one session. Structural " +
55
+ "metadata only — never conversation content.",
56
+ inputSchema: {
57
+ type: "object",
58
+ properties: {
59
+ target: { type: "string", description: "Session id (or prefix) or project name to inspect." },
60
+ },
61
+ required: ["target"],
62
+ additionalProperties: false,
63
+ },
64
+ async execute(input) {
65
+ const hub = getCurrentHub();
66
+ if (!hub)
67
+ return "(agent monitoring isn't active — start the web server with `lisa serve --web`)";
68
+ const target = (input.target ?? "").trim();
69
+ if (!target)
70
+ return "(give a session id or project name to inspect)";
71
+ const now = Date.now();
72
+ const all = hub.list();
73
+ const hits = all.filter((s) => matches(s, target));
74
+ if (hits.length === 0) {
75
+ const names = all.map((s) => `${s.project} (${s.sessionId.slice(0, 8)})`).slice(0, 10).join(", ");
76
+ return `(no observed session matches "${target}". Active: ${names || "none"})`;
77
+ }
78
+ if (hits.length > 1) {
79
+ // Disambiguate, but still detail the most recently active one.
80
+ hits.sort((a, b) => b.lastMtime - a.lastMtime);
81
+ const head = `(${hits.length} match "${target}"; showing the most recent — narrow by session id)\n`;
82
+ return head + formatDetail(hits[0], now);
83
+ }
84
+ return formatDetail(hits[0], now);
85
+ },
86
+ };
87
+ //# sourceMappingURL=inspect_agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspect_agent.js","sourceRoot":"","sources":["../../src/tools/inspect_agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * list_agents (orchestrator OBSERVE — read side) — enumerate the CLI agent
3
+ * sessions LISA is watching (Claude Code, Codex, …) with their structural
4
+ * activity, so she can answer "what are my agents doing right now?" in chat.
5
+ *
6
+ * Fills the gap between:
7
+ * - advise_now — only the relevance-gated *summary* ("10 active, nothing notable")
8
+ * - signal_agent — only LISA's OWN dispatched agents (the user's manual sessions
9
+ * are observed but unreachable there)
10
+ * The sidebar/island already show this data; this exposes it to the chat agent.
11
+ *
12
+ * PRIVACY: structural metadata only — state, project, git branch, tool/command
13
+ * NAMES, file PATHS, counts, error strings. Never a prompt, a reply, or full
14
+ * command arguments. Same boundary the parser privacy tests assert.
15
+ */
16
+ import type { ToolDefinition } from "../types.js";
17
+ import type { AgentSession } from "../integrations/types.js";
18
+ /** One session → a readable, structural-only line. Pure, for display + tests. */
19
+ export declare function formatSessionLine(s: AgentSession, now: number): string;
20
+ export declare const listAgentsTool: ToolDefinition<Record<string, never>, string>;
21
+ //# sourceMappingURL=list_agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_agents.d.ts","sourceRoot":"","sources":["../../src/tools/list_agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAoB7D,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAiBtE;AAED,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CA2BxE,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * list_agents (orchestrator OBSERVE — read side) — enumerate the CLI agent
3
+ * sessions LISA is watching (Claude Code, Codex, …) with their structural
4
+ * activity, so she can answer "what are my agents doing right now?" in chat.
5
+ *
6
+ * Fills the gap between:
7
+ * - advise_now — only the relevance-gated *summary* ("10 active, nothing notable")
8
+ * - signal_agent — only LISA's OWN dispatched agents (the user's manual sessions
9
+ * are observed but unreachable there)
10
+ * The sidebar/island already show this data; this exposes it to the chat agent.
11
+ *
12
+ * PRIVACY: structural metadata only — state, project, git branch, tool/command
13
+ * NAMES, file PATHS, counts, error strings. Never a prompt, a reply, or full
14
+ * command arguments. Same boundary the parser privacy tests assert.
15
+ */
16
+ import { getCurrentHub } from "../integrations/current-hub.js";
17
+ const STATE_RANK = {
18
+ error: 0,
19
+ waiting: 1,
20
+ working: 2,
21
+ done: 3,
22
+ idle: 4,
23
+ unknown: 5,
24
+ };
25
+ function ago(ms, now) {
26
+ const d = Math.max(0, now - ms);
27
+ const s = Math.floor(d / 1000);
28
+ if (s < 60)
29
+ return `${s}s`;
30
+ const m = Math.floor(s / 60);
31
+ if (m < 60)
32
+ return `${m}m`;
33
+ return `${Math.floor(m / 60)}h`;
34
+ }
35
+ /** One session → a readable, structural-only line. Pure, for display + tests. */
36
+ export function formatSessionLine(s, now) {
37
+ const a = s.activity;
38
+ const bits = [];
39
+ if (a?.gitBranch)
40
+ bits.push(`@${a.gitBranch}`);
41
+ if (a?.pendingPermission)
42
+ bits.push(`⏳ needs permission: ${a.pendingPermission}`);
43
+ else if (a?.lastCommandName)
44
+ bits.push(`$ ${a.lastCommandName}`);
45
+ else if (a?.lastTools && a.lastTools.length)
46
+ bits.push(a.lastTools.slice(-3).join("→"));
47
+ if (a?.lastError)
48
+ bits.push(`error: ${a.lastError}`);
49
+ if (a?.filesTouched && a.filesTouched.length) {
50
+ const f = a.filesTouched
51
+ .slice(-2)
52
+ .map((p) => p.split("/").pop() ?? p)
53
+ .join(", ");
54
+ bits.push(`files: ${f}`);
55
+ }
56
+ const detail = bits.length ? " · " + bits.join(" · ") : "";
57
+ return `• [${s.state}] ${s.project} (${s.agent}, ${ago(s.lastMtime, now)} ago)${detail}`;
58
+ }
59
+ export const listAgentsTool = {
60
+ name: "list_agents",
61
+ description: "List the CLI agent sessions LISA is observing right now (Claude Code, Codex, …) with their " +
62
+ "structural activity: state (working/waiting/error/idle), project, git branch, last tool/command " +
63
+ "NAME, files touched, pending permission, errors. Use when the user asks what their agents are " +
64
+ "doing, what's running, or 'what is <agent> up to'. Structural metadata only — never conversation " +
65
+ "content; to see what a repo actually changed, read its `git log`. For LISA's OWN dispatched " +
66
+ "agents (start/stop) use signal_agent; for a relevance-gated summary use advise_now.",
67
+ inputSchema: { type: "object", properties: {}, additionalProperties: false },
68
+ async execute() {
69
+ const hub = getCurrentHub();
70
+ if (!hub) {
71
+ return "(agent monitoring isn't active — start the web server with `lisa serve --web`)";
72
+ }
73
+ const now = Date.now();
74
+ const sessions = hub.list();
75
+ if (sessions.length === 0)
76
+ return "(no agents are active right now)";
77
+ const sorted = sessions.slice().sort((a, b) => {
78
+ const ra = STATE_RANK[a.state] ?? 9;
79
+ const rb = STATE_RANK[b.state] ?? 9;
80
+ if (ra !== rb)
81
+ return ra - rb;
82
+ return b.lastMtime - a.lastMtime;
83
+ });
84
+ const head = `${sessions.length} agent session(s) observed (structural activity only):`;
85
+ return [head, ...sorted.map((s) => formatSessionLine(s, now))].join("\n");
86
+ },
87
+ };
88
+ //# sourceMappingURL=list_agents.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list_agents.js","sourceRoot":"","sources":["../../src/tools/list_agents.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * pr_status (vibe-coding) — when many agents open many PRs, which are green,
3
+ * which need review, which are failing? Wraps `gh pr list` to surface each open
4
+ * PR's CI rollup + review decision in one glance. Read-only.
5
+ */
6
+ import type { ToolDefinition } from "../types.js";
7
+ interface PrStatusInput {
8
+ cwd?: string;
9
+ /** Only your own PRs (gh --author @me). Default false = all open PRs. */
10
+ mine?: boolean;
11
+ }
12
+ interface RollupItem {
13
+ conclusion?: string | null;
14
+ status?: string | null;
15
+ state?: string | null;
16
+ }
17
+ interface PR {
18
+ number: number;
19
+ title: string;
20
+ headRefName: string;
21
+ isDraft: boolean;
22
+ reviewDecision?: string | null;
23
+ statusCheckRollup?: RollupItem[] | null;
24
+ }
25
+ /** Pure: reduce a PR's check rollup to one of ✓ / ✗ / ⏳ / – . */
26
+ export declare function summarizeChecks(rollup: RollupItem[] | null | undefined): string;
27
+ /** Pure: one PR → a readable line. Exported for tests. */
28
+ export declare function formatPR(pr: PR): string;
29
+ export declare const prStatusTool: ToolDefinition<PrStatusInput, string>;
30
+ export {};
31
+ //# sourceMappingURL=pr_status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr_status.d.ts","sourceRoot":"","sources":["../../src/tools/pr_status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,UAAU,aAAa;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,UAAU,UAAU;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AACD,UAAU,EAAE;IACV,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,iBAAiB,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;CACzC;AAED,iEAAiE;AACjE,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAkB/E;AAWD,0DAA0D;AAC1D,wBAAgB,QAAQ,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAIvC;AAED,eAAO,MAAM,YAAY,EAAE,cAAc,CAAC,aAAa,EAAE,MAAM,CA2C9D,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { runIn, isDir, gitRoot } from "./exec-util.js";
2
+ /** Pure: reduce a PR's check rollup to one of ✓ / ✗ / ⏳ / – . */
3
+ export function summarizeChecks(rollup) {
4
+ if (!rollup || rollup.length === 0)
5
+ return "–";
6
+ let fail = false;
7
+ let pending = false;
8
+ for (const c of rollup) {
9
+ const concl = (c.conclusion ?? "").toUpperCase();
10
+ const state = (c.state ?? "").toUpperCase();
11
+ if (["FAILURE", "ERROR", "CANCELLED", "TIMED_OUT", "ACTION_REQUIRED"].includes(concl) || ["FAILURE", "ERROR"].includes(state)) {
12
+ fail = true;
13
+ }
14
+ else if (concl === "SUCCESS" || state === "SUCCESS") {
15
+ // ok
16
+ }
17
+ else {
18
+ pending = true; // queued / in_progress / pending / expected
19
+ }
20
+ }
21
+ if (fail)
22
+ return "✗";
23
+ if (pending)
24
+ return "⏳";
25
+ return "✓";
26
+ }
27
+ function reviewLabel(d) {
28
+ switch ((d ?? "").toUpperCase()) {
29
+ case "APPROVED": return "approved";
30
+ case "CHANGES_REQUESTED": return "changes requested";
31
+ case "REVIEW_REQUIRED": return "needs review";
32
+ default: return "no review";
33
+ }
34
+ }
35
+ /** Pure: one PR → a readable line. Exported for tests. */
36
+ export function formatPR(pr) {
37
+ const draft = pr.isDraft ? " (draft)" : "";
38
+ const title = pr.title.length > 60 ? pr.title.slice(0, 57) + "…" : pr.title;
39
+ return `#${pr.number} ${summarizeChecks(pr.statusCheckRollup)} CI · ${reviewLabel(pr.reviewDecision)} · ${title}${draft} [${pr.headRefName}]`;
40
+ }
41
+ export const prStatusTool = {
42
+ name: "pr_status",
43
+ description: "List the repo's open pull requests with each one's CI status (✓/✗/⏳) and review decision " +
44
+ "(approved / changes requested / needs review). Use when the user asks which PRs are green, " +
45
+ "ready to merge, failing, or waiting on review — handy when several agents have opened PRs. " +
46
+ "Read-only; needs the `gh` CLI (authenticated). mine:true limits to your own PRs.",
47
+ inputSchema: {
48
+ type: "object",
49
+ properties: {
50
+ cwd: { type: "string", description: "Absolute path inside the repo. Defaults to the current directory." },
51
+ mine: { type: "boolean", description: "Only your own PRs (default false = all open)." },
52
+ },
53
+ additionalProperties: false,
54
+ },
55
+ async execute(input, ctx) {
56
+ const cwd = input.cwd && input.cwd.startsWith("/") ? input.cwd : ctx.cwd;
57
+ if (!(await isDir(cwd)))
58
+ return `(not a directory: ${cwd})`;
59
+ const root = (await gitRoot(cwd, ctx.signal)) ?? cwd;
60
+ const args = [
61
+ "pr", "list", "--state", "open", "--limit", "30",
62
+ "--json", "number,title,headRefName,isDraft,reviewDecision,statusCheckRollup",
63
+ ];
64
+ if (input.mine)
65
+ args.push("--author", "@me");
66
+ const r = await runIn(root, "gh", args, { timeoutMs: 20000, signal: ctx.signal, maxBytes: 200_000 });
67
+ if (r.spawnError)
68
+ return "(the `gh` CLI isn't installed — needed for PR status. Install: https://cli.github.com)";
69
+ if (r.code !== 0) {
70
+ const e = r.stderr.trim();
71
+ if (/auth|login/i.test(e))
72
+ return "(`gh` isn't authenticated — run `gh auth login`)";
73
+ return `(gh pr list failed: ${e.slice(0, 200) || "is this a GitHub repo?"})`;
74
+ }
75
+ let prs;
76
+ try {
77
+ prs = JSON.parse(r.stdout);
78
+ }
79
+ catch {
80
+ return "(couldn't parse gh output)";
81
+ }
82
+ if (prs.length === 0)
83
+ return "(no open PRs)";
84
+ // failing first, then pending, then the rest
85
+ const rank = (p) => { const s = summarizeChecks(p.statusCheckRollup); return s === "✗" ? 0 : s === "⏳" ? 1 : 2; };
86
+ prs.sort((a, b) => rank(a) - rank(b) || a.number - b.number);
87
+ return `${prs.length} open PR(s):\n` + prs.map(formatPR).join("\n");
88
+ },
89
+ };
90
+ //# sourceMappingURL=pr_status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pr_status.js","sourceRoot":"","sources":["../../src/tools/pr_status.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AA8BlD,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,mBAAwB,GAAG,cAAc,EAAE,CAuClF;AAED,eAAO,MAAM,oBAAoB,aAS/B,CAAC;AAEH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAExE"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAwClD,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;CAC1B;AAED,wBAAgB,iBAAiB,CAAC,IAAI,GAAE,mBAAwB,GAAG,cAAc,EAAE,CAoDlF;AAED,eAAO,MAAM,oBAAoB,aAU/B,CAAC;AAEH,wBAAgB,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAExE"}
@@ -1,5 +1,17 @@
1
1
  import { memoryTool } from "../memory/tool.js";
2
2
  import { memorySearchTool } from "../memory/search_tool.js";
3
+ import { adviseNowTool } from "./advise_now.js";
4
+ import { listAgentsTool } from "./list_agents.js";
5
+ import { inspectAgentTool } from "./inspect_agent.js";
6
+ import { repoDigestTool } from "./repo_digest.js";
7
+ import { reviewDiffTool } from "./review_diff.js";
8
+ import { runChecksTool } from "./run_checks.js";
9
+ import { prStatusTool } from "./pr_status.js";
10
+ import { dispatchAgentTool } from "./dispatch_agent.js";
11
+ import { scheduledDispatchTool } from "./scheduled_dispatch.js";
12
+ import { compareAgentsTool } from "./compare_agents.js";
13
+ import { signalAgentTool } from "./signal_agent.js";
14
+ import { agentRecapTool } from "./agent_recap.js";
3
15
  import { skillManageTool } from "../skills/tool.js";
4
16
  import { desireCloseTool, desireProgressTool, soulDiffTool, soulFeelTool, soulHistoryTool, soulJournalTool, soulObjectTool, soulPatchTool, soulReadTool, } from "../soul/tools.js";
5
17
  import { speakTool, transcribeTool } from "../voice/tool.js";
@@ -39,6 +51,19 @@ export function buildToolRegistry(opts = {}) {
39
51
  webFetchTool,
40
52
  webSearchTool,
41
53
  redeployTool,
54
+ // Orchestration (docs/ORCHESTRATOR_PLAN.md): observe → advise → dispatch → control.
55
+ listAgentsTool,
56
+ inspectAgentTool,
57
+ repoDigestTool,
58
+ reviewDiffTool,
59
+ runChecksTool,
60
+ prStatusTool,
61
+ adviseNowTool,
62
+ dispatchAgentTool,
63
+ scheduledDispatchTool,
64
+ compareAgentsTool,
65
+ signalAgentTool,
66
+ agentRecapTool,
42
67
  ];
43
68
  if (opts.includeVoice) {
44
69
  tools.push(speakTool, transcribeTool);
@@ -64,6 +89,7 @@ export const READ_ONLY_TOOL_NAMES = new Set([
64
89
  "soul_diff",
65
90
  "web_fetch",
66
91
  "web_search",
92
+ "agent_recap",
67
93
  ]);
68
94
  export function readOnlySubset(tools) {
69
95
  return tools.filter((t) => READ_ONLY_TOOL_NAMES.has(t.name));
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,eAAe,EACf,cAAc,EACd,aAAa,EACb,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAavC,MAAM,UAAU,iBAAiB,CAAC,OAA4B,EAAE;IAC9D,MAAM,KAAK,GAAqB;QAC9B,QAA0B;QAC1B,SAA2B;QAC3B,QAA0B;QAC1B,cAAgC;QAChC,QAA0B;QAC1B,QAA0B;QAC1B,MAAwB;QACxB,eAAiC;QACjC,UAA4B;QAC5B,gBAAkC;QAClC,WAA6B;QAC7B,aAA+B;QAC/B,eAAiC;QACjC,YAA8B;QAC9B,YAA8B;QAC9B,eAAiC;QACjC,YAA8B;QAC9B,cAAgC;QAChC,kBAAoC;QACpC,eAAiC;QACjC,YAA8B;QAC9B,aAA+B;QAC/B,YAA8B;QAC9B,oFAAoF;QACpF,cAAgC;QAChC,gBAAkC;QAClC,cAAgC;QAChC,cAAgC;QAChC,aAA+B;QAC/B,YAA8B;QAC9B,aAA+B;QAC/B,iBAAmC;QACnC,qBAAuC;QACvC,iBAAmC;QACnC,eAAiC;QACjC,cAAgC;KACjC,CAAC;IACF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,SAA2B,EAAE,cAAgC,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBAAE,SAAS,CAAC,2CAA2C;YAC3E,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACnB,CAAC;IACH,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IAC1C,MAAM;IACN,MAAM;IACN,IAAI;IACJ,eAAe;IACf,cAAc;IACd,WAAW;IACX,WAAW;IACX,YAAY;IACZ,aAAa;CACd,CAAC,CAAC;AAEH,MAAM,UAAU,cAAc,CAAC,KAAuB;IACpD,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * repo_digest (vibe-coding) — "what actually changed?" across the repos your
3
+ * agents are working in. The orchestrator only sees structural activity (tool
4
+ * names, file paths); git is the source of truth for *what was produced*. This
5
+ * wraps git so LISA can answer "what did Claude Code do today" with real
6
+ * commits + working-tree state, per repo.
7
+ *
8
+ * Reads the user's own git repos (content they've asked LISA to look at) — this
9
+ * is separate from the orchestrator's no-conversation-content privacy rule.
10
+ */
11
+ import type { ToolDefinition } from "../types.js";
12
+ interface RepoDigestInput {
13
+ /** Repo path. Omit to digest every repo with an observed agent session. */
14
+ cwd?: string;
15
+ /** git --since value. Default "1 day ago". */
16
+ since?: string;
17
+ }
18
+ export interface RepoDigest {
19
+ root: string;
20
+ branch: string;
21
+ commits: string[];
22
+ dirtyFiles: number;
23
+ diffStat: string;
24
+ ahead: number;
25
+ behind: number;
26
+ since: string;
27
+ error?: string;
28
+ }
29
+ /** Pure: render one repo's digest. Exported for tests. */
30
+ export declare function formatDigest(d: RepoDigest): string;
31
+ export declare const repoDigestTool: ToolDefinition<RepoDigestInput, string>;
32
+ export {};
33
+ //# sourceMappingURL=repo_digest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo_digest.d.ts","sourceRoot":"","sources":["../../src/tools/repo_digest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAIlD,UAAU,eAAe;IACvB,2EAA2E;IAC3E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8CAA8C;IAC9C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAqBlD;AAoDD,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,eAAe,EAAE,MAAM,CAkClE,CAAC"}
@@ -0,0 +1,113 @@
1
+ import { getCurrentHub } from "../integrations/current-hub.js";
2
+ import { runIn, isDir, gitRoot } from "./exec-util.js";
3
+ /** Pure: render one repo's digest. Exported for tests. */
4
+ export function formatDigest(d) {
5
+ const name = d.root.split("/").pop() || d.root;
6
+ if (d.error)
7
+ return `▸ ${name} — ${d.error}`;
8
+ const lines = [];
9
+ const sync = d.ahead || d.behind
10
+ ? ` (${d.ahead ? "↑" + d.ahead : ""}${d.behind ? "↓" + d.behind : ""} vs upstream)`
11
+ : "";
12
+ lines.push(`▸ ${name} @ ${d.branch}${sync}`);
13
+ if (d.commits.length) {
14
+ lines.push(` commits since ${d.since}:`);
15
+ for (const c of d.commits)
16
+ lines.push(` ${c}`);
17
+ }
18
+ else {
19
+ lines.push(` no commits since ${d.since}`);
20
+ }
21
+ if (d.dirtyFiles > 0) {
22
+ lines.push(` uncommitted: ${d.dirtyFiles} file(s)${d.diffStat ? " · " + d.diffStat : ""}`);
23
+ }
24
+ else {
25
+ lines.push(` working tree clean`);
26
+ }
27
+ return lines.join("\n");
28
+ }
29
+ async function digestRepo(cwd, since, signal) {
30
+ const root = await gitRoot(cwd, signal);
31
+ const base = { root: root ?? cwd, branch: "?", commits: [], dirtyFiles: 0, diffStat: "", ahead: 0, behind: 0, since };
32
+ if (!root)
33
+ return { ...base, error: "not a git repo" };
34
+ const git = (args) => runIn(root, "git", ["-C", root, ...args], { timeoutMs: 8000, signal });
35
+ const branch = await git(["rev-parse", "--abbrev-ref", "HEAD"]);
36
+ base.branch = branch.code === 0 ? branch.stdout.trim() || "?" : "?";
37
+ // Commits across all refs in the window (covers agent worktrees/branches).
38
+ const log = await git(["log", "--all", "--oneline", "--no-decorate", `--since=${since}`, "-n", "25"]);
39
+ if (log.code === 0) {
40
+ base.commits = log.stdout.split("\n").map((l) => l.trim()).filter(Boolean);
41
+ }
42
+ const status = await git(["status", "--porcelain"]);
43
+ if (status.code === 0) {
44
+ base.dirtyFiles = status.stdout.split("\n").filter((l) => l.trim()).length;
45
+ }
46
+ if (base.dirtyFiles > 0) {
47
+ const ds = await git(["diff", "--shortstat"]);
48
+ if (ds.code === 0)
49
+ base.diffStat = ds.stdout.trim();
50
+ }
51
+ const ab = await git(["rev-list", "--left-right", "--count", "@{upstream}...HEAD"]);
52
+ if (ab.code === 0) {
53
+ const m = ab.stdout.trim().split(/\s+/);
54
+ base.behind = parseInt(m[0] ?? "0", 10) || 0;
55
+ base.ahead = parseInt(m[1] ?? "0", 10) || 0;
56
+ }
57
+ return base;
58
+ }
59
+ /** Collect distinct git roots from the observed agent sessions' cwds. */
60
+ async function observedRepoRoots(signal) {
61
+ const hub = getCurrentHub();
62
+ if (!hub)
63
+ return [];
64
+ const cwds = Array.from(new Set(hub.list().map((s) => s.cwd).filter((c) => !!c && c.startsWith("/"))));
65
+ const roots = new Set();
66
+ for (const c of cwds) {
67
+ const r = await gitRoot(c, signal);
68
+ if (r)
69
+ roots.add(r);
70
+ if (roots.size >= 8)
71
+ break;
72
+ }
73
+ return Array.from(roots);
74
+ }
75
+ export const repoDigestTool = {
76
+ name: "repo_digest",
77
+ description: "Summarise what actually changed in a git repo (or, with no cwd, every repo your agents are " +
78
+ "working in): recent commits in a time window, current branch, uncommitted file count + diff " +
79
+ "stat, and ahead/behind vs upstream. Use to answer 'what did <agent> / I do today', 'what's the " +
80
+ "state of <repo>', or before reviewing/merging. Reads git only (no writes). Pair with review_diff " +
81
+ "to see the actual changes and run_checks to verify them.",
82
+ inputSchema: {
83
+ type: "object",
84
+ properties: {
85
+ cwd: { type: "string", description: "Absolute path inside the repo. Omit to digest all repos with an active agent session." },
86
+ since: { type: "string", description: 'git --since window, e.g. "1 day ago", "today", "3 hours ago". Default "1 day ago".' },
87
+ },
88
+ additionalProperties: false,
89
+ },
90
+ async execute(input, ctx) {
91
+ const since = input.since?.trim() || "1 day ago";
92
+ let roots;
93
+ if (input.cwd) {
94
+ if (!(await isDir(input.cwd)))
95
+ return `(not a directory: ${input.cwd})`;
96
+ roots = [input.cwd];
97
+ }
98
+ else {
99
+ roots = await observedRepoRoots(ctx.signal);
100
+ if (roots.length === 0) {
101
+ // Fall back to the current working directory's repo.
102
+ const r = await gitRoot(ctx.cwd, ctx.signal);
103
+ if (r)
104
+ roots = [r];
105
+ }
106
+ }
107
+ if (roots.length === 0)
108
+ return "(no git repos to digest — no active agent sessions and cwd isn't a repo)";
109
+ const digests = await Promise.all(roots.map((r) => digestRepo(r, since, ctx.signal)));
110
+ return digests.map(formatDigest).join("\n\n");
111
+ },
112
+ };
113
+ //# sourceMappingURL=repo_digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo_digest.js","sourceRoot":"","sources":["../../src/tools/repo_digest.ts"],"names":[],"mappings":"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"}