@oratis/lisa 0.8.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +123 -16
- package/README.zh-CN.md +101 -15
- package/completions/_lisa +56 -0
- package/completions/lisa.bash +35 -1
- package/completions/lisa.fish +18 -1
- package/dist/advisor/engine.d.ts +7 -0
- package/dist/advisor/engine.d.ts.map +1 -1
- package/dist/advisor/engine.js +12 -0
- package/dist/advisor/engine.js.map +1 -1
- package/dist/agent.d.ts +14 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +58 -7
- package/dist/agent.js.map +1 -1
- package/dist/agents/managed.d.ts +108 -0
- package/dist/agents/managed.d.ts.map +1 -0
- package/dist/agents/managed.js +241 -0
- package/dist/agents/managed.js.map +1 -0
- package/dist/agents/pty.d.ts +155 -0
- package/dist/agents/pty.d.ts.map +1 -0
- package/dist/agents/pty.js +299 -0
- package/dist/agents/pty.js.map +1 -0
- package/dist/approval.d.ts +13 -0
- package/dist/approval.d.ts.map +1 -1
- package/dist/approval.js +25 -2
- package/dist/approval.js.map +1 -1
- package/dist/autonomy/runs.d.ts +33 -0
- package/dist/autonomy/runs.d.ts.map +1 -0
- package/dist/autonomy/runs.js +106 -0
- package/dist/autonomy/runs.js.map +1 -0
- package/dist/channels/feishu.d.ts.map +1 -1
- package/dist/channels/feishu.js +65 -0
- package/dist/channels/feishu.js.map +1 -1
- package/dist/channels/router.d.ts +7 -0
- package/dist/channels/router.d.ts.map +1 -1
- package/dist/channels/router.js +1 -1
- package/dist/channels/router.js.map +1 -1
- package/dist/cli/agents-pty.d.ts +18 -0
- package/dist/cli/agents-pty.d.ts.map +1 -0
- package/dist/cli/agents-pty.js +182 -0
- package/dist/cli/agents-pty.js.map +1 -0
- package/dist/cli/agents.d.ts +2 -0
- package/dist/cli/agents.d.ts.map +1 -0
- package/dist/cli/agents.js +65 -0
- package/dist/cli/agents.js.map +1 -0
- package/dist/cli/consent.d.ts +2 -0
- package/dist/cli/consent.d.ts.map +1 -0
- package/dist/cli/consent.js +57 -0
- package/dist/cli/consent.js.map +1 -0
- package/dist/cli/model.d.ts +2 -0
- package/dist/cli/model.d.ts.map +1 -0
- package/dist/cli/model.js +121 -0
- package/dist/cli/model.js.map +1 -0
- package/dist/cli/sense.d.ts +2 -0
- package/dist/cli/sense.d.ts.map +1 -0
- package/dist/cli/sense.js +36 -0
- package/dist/cli/sense.js.map +1 -0
- package/dist/cli.js +117 -12
- package/dist/cli.js.map +1 -1
- package/dist/consent/blacklist.d.ts +28 -0
- package/dist/consent/blacklist.d.ts.map +1 -0
- package/dist/consent/blacklist.js +78 -0
- package/dist/consent/blacklist.js.map +1 -0
- package/dist/consent/store.d.ts +45 -0
- package/dist/consent/store.d.ts.map +1 -0
- package/dist/consent/store.js +126 -0
- package/dist/consent/store.js.map +1 -0
- package/dist/control/policy.d.ts +13 -0
- package/dist/control/policy.d.ts.map +1 -0
- package/dist/control/policy.js +57 -0
- package/dist/control/policy.js.map +1 -0
- package/dist/heartbeat/runner.d.ts.map +1 -1
- package/dist/heartbeat/runner.js +70 -14
- package/dist/heartbeat/runner.js.map +1 -1
- package/dist/idle/runner.d.ts.map +1 -1
- package/dist/idle/runner.js +87 -17
- package/dist/idle/runner.js.map +1 -1
- package/dist/integrations/aider/observer.d.ts +21 -1
- package/dist/integrations/aider/observer.d.ts.map +1 -1
- package/dist/integrations/aider/observer.js +110 -1
- package/dist/integrations/aider/observer.js.map +1 -1
- package/dist/integrations/claude-code/liveness.d.ts +10 -0
- package/dist/integrations/claude-code/liveness.d.ts.map +1 -0
- package/dist/integrations/claude-code/liveness.js +62 -0
- package/dist/integrations/claude-code/liveness.js.map +1 -0
- package/dist/integrations/claude-code/watcher.d.ts +39 -4
- package/dist/integrations/claude-code/watcher.d.ts.map +1 -1
- package/dist/integrations/claude-code/watcher.js +94 -57
- package/dist/integrations/claude-code/watcher.js.map +1 -1
- package/dist/integrations/codex/observer.d.ts +19 -6
- package/dist/integrations/codex/observer.d.ts.map +1 -1
- package/dist/integrations/codex/observer.js +228 -4
- package/dist/integrations/codex/observer.js.map +1 -1
- package/dist/integrations/dispatch-ledger.d.ts +30 -1
- package/dist/integrations/dispatch-ledger.d.ts.map +1 -1
- package/dist/integrations/dispatch-ledger.js +75 -9
- package/dist/integrations/dispatch-ledger.js.map +1 -1
- package/dist/integrations/git/branch.d.ts +11 -0
- package/dist/integrations/git/branch.d.ts.map +1 -0
- package/dist/integrations/git/branch.js +49 -0
- package/dist/integrations/git/branch.js.map +1 -0
- package/dist/integrations/git/observer.d.ts +39 -0
- package/dist/integrations/git/observer.d.ts.map +1 -0
- package/dist/integrations/git/observer.js +252 -0
- package/dist/integrations/git/observer.js.map +1 -0
- package/dist/integrations/github-pr/observer.d.ts.map +1 -1
- package/dist/integrations/github-pr/observer.js +7 -2
- package/dist/integrations/github-pr/observer.js.map +1 -1
- package/dist/integrations/hub.d.ts +8 -0
- package/dist/integrations/hub.d.ts.map +1 -1
- package/dist/integrations/hub.js +39 -1
- package/dist/integrations/hub.js.map +1 -1
- package/dist/integrations/managed/observer.d.ts +17 -0
- package/dist/integrations/managed/observer.d.ts.map +1 -0
- package/dist/integrations/managed/observer.js +46 -0
- package/dist/integrations/managed/observer.js.map +1 -0
- package/dist/integrations/opencode/observer.d.ts +53 -5
- package/dist/integrations/opencode/observer.d.ts.map +1 -1
- package/dist/integrations/opencode/observer.js +242 -20
- package/dist/integrations/opencode/observer.js.map +1 -1
- package/dist/integrations/pty/observer.d.ts +25 -0
- package/dist/integrations/pty/observer.d.ts.map +1 -0
- package/dist/integrations/pty/observer.js +48 -0
- package/dist/integrations/pty/observer.js.map +1 -0
- package/dist/integrations/registry.d.ts.map +1 -1
- package/dist/integrations/registry.js +5 -0
- package/dist/integrations/registry.js.map +1 -1
- package/dist/integrations/shell/observer.d.ts +33 -0
- package/dist/integrations/shell/observer.d.ts.map +1 -0
- package/dist/integrations/shell/observer.js +223 -0
- package/dist/integrations/shell/observer.js.map +1 -0
- package/dist/integrations/takoapi/a2a.d.ts +38 -0
- package/dist/integrations/takoapi/a2a.d.ts.map +1 -0
- package/dist/integrations/takoapi/a2a.js +70 -0
- package/dist/integrations/takoapi/a2a.js.map +1 -0
- package/dist/integrations/takoapi/ledger.d.ts +32 -0
- package/dist/integrations/takoapi/ledger.d.ts.map +1 -0
- package/dist/integrations/takoapi/ledger.js +96 -0
- package/dist/integrations/takoapi/ledger.js.map +1 -0
- package/dist/integrations/takoapi/observer.d.ts +39 -0
- package/dist/integrations/takoapi/observer.d.ts.map +1 -0
- package/dist/integrations/takoapi/observer.js +102 -0
- package/dist/integrations/takoapi/observer.js.map +1 -0
- package/dist/integrations/types.d.ts +17 -0
- package/dist/integrations/types.d.ts.map +1 -1
- package/dist/mcp/client.d.ts +5 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +1 -1
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/config.d.ts +4 -0
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/config.js +34 -0
- package/dist/mcp/config.js.map +1 -1
- package/dist/memory/embedding.d.ts +45 -0
- package/dist/memory/embedding.d.ts.map +1 -0
- package/dist/memory/embedding.js +139 -0
- package/dist/memory/embedding.js.map +1 -0
- package/dist/memory/search_tool.d.ts.map +1 -1
- package/dist/memory/search_tool.js +6 -2
- package/dist/memory/search_tool.js.map +1 -1
- package/dist/memory/vector.d.ts +14 -3
- package/dist/memory/vector.d.ts.map +1 -1
- package/dist/memory/vector.js +50 -0
- package/dist/memory/vector.js.map +1 -1
- package/dist/model/local.d.ts +43 -0
- package/dist/model/local.d.ts.map +1 -0
- package/dist/model/local.js +118 -0
- package/dist/model/local.js.map +1 -0
- package/dist/model/plan-usage.d.ts +41 -0
- package/dist/model/plan-usage.d.ts.map +1 -0
- package/dist/model/plan-usage.js +168 -0
- package/dist/model/plan-usage.js.map +1 -0
- package/dist/model/plans.d.ts +73 -0
- package/dist/model/plans.d.ts.map +1 -0
- package/dist/model/plans.js +246 -0
- package/dist/model/plans.js.map +1 -0
- package/dist/orchestrator/recent-recap.d.ts +2 -0
- package/dist/orchestrator/recent-recap.d.ts.map +1 -0
- package/dist/orchestrator/recent-recap.js +20 -0
- package/dist/orchestrator/recent-recap.js.map +1 -0
- package/dist/providers/anthropic.d.ts +1 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +10 -2
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/fallback.d.ts +23 -0
- package/dist/providers/fallback.d.ts.map +1 -0
- package/dist/providers/fallback.js +29 -0
- package/dist/providers/fallback.js.map +1 -0
- package/dist/providers/gemini.d.ts +2 -0
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +24 -10
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +4 -1
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/registry.d.ts +18 -2
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +56 -9
- package/dist/providers/registry.js.map +1 -1
- package/dist/reflect.d.ts +55 -0
- package/dist/reflect.d.ts.map +1 -1
- package/dist/reflect.js +148 -54
- package/dist/reflect.js.map +1 -1
- package/dist/sense/log.d.ts +9 -0
- package/dist/sense/log.d.ts.map +1 -0
- package/dist/sense/log.js +63 -0
- package/dist/sense/log.js.map +1 -0
- package/dist/sense/screen.d.ts +43 -0
- package/dist/sense/screen.d.ts.map +1 -0
- package/dist/sense/screen.js +107 -0
- package/dist/sense/screen.js.map +1 -0
- package/dist/sense/service.d.ts +16 -0
- package/dist/sense/service.d.ts.map +1 -0
- package/dist/sense/service.js +33 -0
- package/dist/sense/service.js.map +1 -0
- package/dist/sense/types.d.ts +35 -0
- package/dist/sense/types.d.ts.map +1 -0
- package/dist/sense/types.js +11 -0
- package/dist/sense/types.js.map +1 -0
- package/dist/sense/voice.d.ts +28 -0
- package/dist/sense/voice.d.ts.map +1 -0
- package/dist/sense/voice.js +64 -0
- package/dist/sense/voice.js.map +1 -0
- package/dist/soul/git.d.ts.map +1 -1
- package/dist/soul/git.js +35 -16
- package/dist/soul/git.js.map +1 -1
- package/dist/soul/store.d.ts +22 -0
- package/dist/soul/store.d.ts.map +1 -1
- package/dist/soul/store.js +69 -14
- package/dist/soul/store.js.map +1 -1
- package/dist/soul/summary.d.ts +10 -0
- package/dist/soul/summary.d.ts.map +1 -0
- package/dist/soul/summary.js +57 -0
- package/dist/soul/summary.js.map +1 -0
- package/dist/soul/tools.d.ts.map +1 -1
- package/dist/soul/tools.js +13 -24
- package/dist/soul/tools.js.map +1 -1
- package/dist/soul/types.d.ts +9 -0
- package/dist/soul/types.d.ts.map +1 -1
- package/dist/soul/types.js.map +1 -1
- package/dist/subagent.d.ts +7 -0
- package/dist/subagent.d.ts.map +1 -1
- package/dist/subagent.js +3 -1
- package/dist/subagent.js.map +1 -1
- package/dist/tools/dispatch_agent.d.ts +13 -1
- package/dist/tools/dispatch_agent.d.ts.map +1 -1
- package/dist/tools/dispatch_agent.js +56 -12
- package/dist/tools/dispatch_agent.js.map +1 -1
- package/dist/tools/dispatch_status.d.ts +22 -0
- package/dist/tools/dispatch_status.d.ts.map +1 -0
- package/dist/tools/dispatch_status.js +57 -0
- package/dist/tools/dispatch_status.js.map +1 -0
- package/dist/tools/github.d.ts +34 -0
- package/dist/tools/github.d.ts.map +1 -0
- package/dist/tools/github.js +140 -0
- package/dist/tools/github.js.map +1 -0
- package/dist/tools/github_link.d.ts +36 -0
- package/dist/tools/github_link.d.ts.map +1 -0
- package/dist/tools/github_link.js +127 -0
- package/dist/tools/github_link.js.map +1 -0
- package/dist/tools/mcp.d.ts +28 -0
- package/dist/tools/mcp.d.ts.map +1 -0
- package/dist/tools/mcp.js +55 -0
- package/dist/tools/mcp.js.map +1 -0
- package/dist/tools/npm_info.d.ts +21 -0
- package/dist/tools/npm_info.d.ts.map +1 -0
- package/dist/tools/npm_info.js +102 -0
- package/dist/tools/npm_info.js.map +1 -0
- package/dist/tools/registry.d.ts +29 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +75 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/run_on_plan.d.ts +46 -0
- package/dist/tools/run_on_plan.d.ts.map +1 -0
- package/dist/tools/run_on_plan.js +89 -0
- package/dist/tools/run_on_plan.js.map +1 -0
- package/dist/tools/takoapi.d.ts +60 -0
- package/dist/tools/takoapi.d.ts.map +1 -0
- package/dist/tools/takoapi.js +181 -0
- package/dist/tools/takoapi.js.map +1 -0
- package/dist/tools/validate.d.ts +22 -0
- package/dist/tools/validate.d.ts.map +1 -0
- package/dist/tools/validate.js +50 -0
- package/dist/tools/validate.js.map +1 -0
- package/dist/voice/dictation.d.ts +51 -0
- package/dist/voice/dictation.d.ts.map +1 -0
- package/dist/voice/dictation.js +70 -0
- package/dist/voice/dictation.js.map +1 -0
- package/dist/web/agent-roster.d.ts +56 -0
- package/dist/web/agent-roster.d.ts.map +1 -0
- package/dist/web/agent-roster.js +109 -0
- package/dist/web/agent-roster.js.map +1 -0
- package/dist/web/devices.d.ts +27 -0
- package/dist/web/devices.d.ts.map +1 -0
- package/dist/web/devices.js +113 -0
- package/dist/web/devices.js.map +1 -0
- package/dist/web/island.d.ts +5 -1
- package/dist/web/island.d.ts.map +1 -1
- package/dist/web/island.js +427 -67
- package/dist/web/island.js.map +1 -1
- package/dist/web/lisa-client.d.ts +20 -0
- package/dist/web/lisa-client.d.ts.map +1 -0
- package/dist/web/lisa-client.js +1323 -0
- package/dist/web/lisa-client.js.map +1 -0
- package/dist/web/lisa-css.d.ts +13 -0
- package/dist/web/lisa-css.d.ts.map +1 -0
- package/dist/web/lisa-css.js +1163 -0
- package/dist/web/lisa-css.js.map +1 -0
- package/dist/web/lisa-html.d.ts +1 -1
- package/dist/web/lisa-html.d.ts.map +1 -1
- package/dist/web/lisa-html.js +16 -2091
- package/dist/web/lisa-html.js.map +1 -1
- package/dist/web/push.d.ts +76 -0
- package/dist/web/push.d.ts.map +1 -0
- package/dist/web/push.js +163 -0
- package/dist/web/push.js.map +1 -0
- package/dist/web/server.d.ts +19 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +898 -65
- package/dist/web/server.js.map +1 -1
- package/package.json +5 -2
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
* codex → codex exec "<task>"
|
|
8
8
|
* opencode → opencode run "<task>"
|
|
9
9
|
* aider → aider --message "<task>" --yes
|
|
10
|
+
* copilot → copilot -p "<task>"
|
|
10
11
|
*
|
|
11
12
|
* The agent is spawned detached so it keeps running independently; it then
|
|
12
13
|
* shows up in the orchestrator hub via its normal session file (the same
|
|
@@ -21,15 +22,18 @@
|
|
|
21
22
|
* surface (same lesson as the iMessage argv fix).
|
|
22
23
|
*/
|
|
23
24
|
import { spawn } from "node:child_process";
|
|
25
|
+
import fs from "node:fs";
|
|
26
|
+
import path from "node:path";
|
|
27
|
+
import crypto from "node:crypto";
|
|
24
28
|
import { getCurrentHub } from "../integrations/current-hub.js";
|
|
25
|
-
import { recordDispatch } from "../integrations/dispatch-ledger.js";
|
|
29
|
+
import { recordDispatch, dispatchLogDir } from "../integrations/dispatch-ledger.js";
|
|
26
30
|
/**
|
|
27
31
|
* L4 COORDINATE: is another agent already actively working in this cwd?
|
|
28
32
|
* Launching a second agent into the same directory is the #1 way multi-agent
|
|
29
33
|
* setups clobber a repo, so dispatch refuses by default (overridable with
|
|
30
34
|
* force). Returns the conflicting session's label, or null if clear.
|
|
31
35
|
*/
|
|
32
|
-
function activeAgentInCwd(cwd) {
|
|
36
|
+
export function activeAgentInCwd(cwd) {
|
|
33
37
|
const hub = getCurrentHub();
|
|
34
38
|
if (!hub)
|
|
35
39
|
return null; // no monitor → can't check; allow
|
|
@@ -49,6 +53,8 @@ export function buildDispatchArgv(agent, task) {
|
|
|
49
53
|
return { cmd: "opencode", args: ["run", task] };
|
|
50
54
|
case "aider":
|
|
51
55
|
return { cmd: "aider", args: ["--message", task, "--yes"] };
|
|
56
|
+
case "copilot":
|
|
57
|
+
return { cmd: "copilot", args: ["-p", task] };
|
|
52
58
|
default: {
|
|
53
59
|
// exhaustiveness guard
|
|
54
60
|
const _never = agent;
|
|
@@ -63,13 +69,45 @@ export function buildDispatchArgv(agent, task) {
|
|
|
63
69
|
*/
|
|
64
70
|
export async function launchAgent(agent, task, cwd, log) {
|
|
65
71
|
const { cmd, args } = buildDispatchArgv(agent, task);
|
|
72
|
+
// Capture the agent's stdout+stderr so dispatch isn't fire-and-forget: LISA
|
|
73
|
+
// can read back what the agent SHE launched produced (D1 feedback). Detached
|
|
74
|
+
// + a real file fd keeps capturing after LISA's own process exits. Reading a
|
|
75
|
+
// self-dispatched agent's own output is hers to read — distinct from the
|
|
76
|
+
// observers, which deliberately never read another session's content.
|
|
77
|
+
const startedAt = Date.now();
|
|
78
|
+
let logPath;
|
|
79
|
+
let outFd;
|
|
80
|
+
try {
|
|
81
|
+
fs.mkdirSync(dispatchLogDir(), { recursive: true });
|
|
82
|
+
logPath = path.join(dispatchLogDir(), `${agent}-${startedAt.toString(36)}-${crypto.randomBytes(3).toString("hex")}.log`);
|
|
83
|
+
outFd = fs.openSync(logPath, "a");
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
logPath = undefined;
|
|
87
|
+
outFd = undefined;
|
|
88
|
+
}
|
|
66
89
|
let child;
|
|
67
90
|
try {
|
|
68
|
-
child = spawn(cmd, args, {
|
|
91
|
+
child = spawn(cmd, args, {
|
|
92
|
+
cwd,
|
|
93
|
+
detached: true,
|
|
94
|
+
stdio: outFd !== undefined ? ["ignore", outFd, outFd] : "ignore",
|
|
95
|
+
});
|
|
69
96
|
}
|
|
70
97
|
catch (err) {
|
|
98
|
+
if (outFd !== undefined)
|
|
99
|
+
try {
|
|
100
|
+
fs.closeSync(outFd);
|
|
101
|
+
}
|
|
102
|
+
catch { /* ignore */ }
|
|
71
103
|
return { error: `Failed to launch ${agent}: ${err.message}. Is "${cmd}" installed and on PATH?`, cmd };
|
|
72
104
|
}
|
|
105
|
+
// The child dup'd the fd for its stdio; close our copy.
|
|
106
|
+
if (outFd !== undefined)
|
|
107
|
+
try {
|
|
108
|
+
fs.closeSync(outFd);
|
|
109
|
+
}
|
|
110
|
+
catch { /* ignore */ }
|
|
73
111
|
const launchError = await new Promise((resolve) => {
|
|
74
112
|
let settled = false;
|
|
75
113
|
child.once("error", (e) => {
|
|
@@ -85,23 +123,30 @@ export async function launchAgent(agent, task, cwd, log) {
|
|
|
85
123
|
resolve(null);
|
|
86
124
|
}, 150);
|
|
87
125
|
});
|
|
88
|
-
if (launchError)
|
|
126
|
+
if (launchError) {
|
|
127
|
+
if (logPath)
|
|
128
|
+
try {
|
|
129
|
+
fs.unlinkSync(logPath);
|
|
130
|
+
}
|
|
131
|
+
catch { /* ignore */ }
|
|
89
132
|
return { error: launchError, cmd };
|
|
133
|
+
}
|
|
90
134
|
const pid = child.pid;
|
|
91
135
|
child.unref();
|
|
136
|
+
let id;
|
|
92
137
|
if (typeof pid === "number") {
|
|
93
138
|
try {
|
|
94
|
-
recordDispatch({ agent, pid, cwd, task });
|
|
139
|
+
id = recordDispatch({ agent, pid, cwd, task, logPath, now: startedAt }).id;
|
|
95
140
|
}
|
|
96
141
|
catch (err) {
|
|
97
142
|
log?.(`[dispatch] ledger write failed (non-fatal): ${err.message}`);
|
|
98
143
|
}
|
|
99
144
|
}
|
|
100
|
-
return { pid, cmd };
|
|
145
|
+
return { pid, cmd, id, logPath };
|
|
101
146
|
}
|
|
102
147
|
export const dispatchAgentTool = {
|
|
103
148
|
name: "dispatch_agent",
|
|
104
|
-
description: "Launch another CLI coding agent (claude, codex, opencode, aider) to work on a task " +
|
|
149
|
+
description: "Launch another CLI coding agent (claude, codex, opencode, aider, copilot) to work on a task " +
|
|
105
150
|
"autonomously in a given directory. The agent runs in the background and appears in " +
|
|
106
151
|
"the agent session monitor. Use when the user asks you to hand work to another agent, " +
|
|
107
152
|
"or to pursue a desire by dispatching one. Returns a handle; it does NOT wait for the " +
|
|
@@ -112,7 +157,7 @@ export const dispatchAgentTool = {
|
|
|
112
157
|
properties: {
|
|
113
158
|
agent: {
|
|
114
159
|
type: "string",
|
|
115
|
-
enum: ["claude", "codex", "opencode", "aider"],
|
|
160
|
+
enum: ["claude", "codex", "opencode", "aider", "copilot"],
|
|
116
161
|
description: "Which CLI agent to launch.",
|
|
117
162
|
},
|
|
118
163
|
task: {
|
|
@@ -144,14 +189,13 @@ export const dispatchAgentTool = {
|
|
|
144
189
|
`Wait for it to finish, pick a different directory, or pass force:true to override.`);
|
|
145
190
|
}
|
|
146
191
|
}
|
|
147
|
-
const { pid, error } = await launchAgent(input.agent, input.task, cwd, ctx.log);
|
|
192
|
+
const { pid, error, id } = await launchAgent(input.agent, input.task, cwd, ctx.log);
|
|
148
193
|
if (error)
|
|
149
194
|
return error;
|
|
150
195
|
ctx.log(`[dispatch] launched ${input.agent} (pid ${pid}) in ${cwd}: ${input.task.slice(0, 80)}`);
|
|
151
196
|
return (`Launched ${input.agent} (pid ${pid}) in ${cwd}.\n` +
|
|
152
|
-
`
|
|
153
|
-
`
|
|
154
|
-
`or signal_agent to list/cancel it.`);
|
|
197
|
+
`Running autonomously — I won't block on it. Check whether it finished and read ` +
|
|
198
|
+
`its output with dispatch_status${id ? ` (id ${id})` : ""}; signal_agent lists/cancels it.`);
|
|
155
199
|
},
|
|
156
200
|
};
|
|
157
201
|
//# sourceMappingURL=dispatch_agent.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch_agent.js","sourceRoot":"","sources":["../../src/tools/dispatch_agent.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"dispatch_agent.js","sourceRoot":"","sources":["../../src/tools/dispatch_agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dispatch_status (L3 DISPATCH — feedback half of the command loop, D1).
|
|
3
|
+
*
|
|
4
|
+
* dispatch_agent launches agents detached and fire-and-forget; this closes the
|
|
5
|
+
* loop on the READ side: for each agent LISA dispatched, report whether it's
|
|
6
|
+
* still running or has finished, and show the tail of its captured output — so
|
|
7
|
+
* Lisa (and the user) can actually see what the delegated agent produced.
|
|
8
|
+
*
|
|
9
|
+
* This reads the output of an agent LISA HERSELF launched (captured to a log by
|
|
10
|
+
* dispatch_agent). That's hers to read — distinct from the observers, which
|
|
11
|
+
* deliberately never read another session's content. It's read-only: no spawn,
|
|
12
|
+
* no signal. (Mid-run approval-relay / steering is a separate, harder piece —
|
|
13
|
+
* it needs a control surface each headless CLI doesn't currently expose.)
|
|
14
|
+
*/
|
|
15
|
+
import type { ToolDefinition } from "../types.js";
|
|
16
|
+
interface DispatchStatusInput {
|
|
17
|
+
/** A dispatch id or pid; omit to list all recent dispatches. */
|
|
18
|
+
id?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const dispatchStatusTool: ToolDefinition<DispatchStatusInput, string>;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=dispatch_status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch_status.d.ts","sourceRoot":"","sources":["../../src/tools/dispatch_status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,UAAU,mBAAmB;IAC3B,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AA0BD,eAAO,MAAM,kBAAkB,EAAE,cAAc,CAAC,mBAAmB,EAAE,MAAM,CA8B1E,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { isAlive, listRecentDispatches, readDispatchOutput, } from "../integrations/dispatch-ledger.js";
|
|
2
|
+
function fmtAge(sec) {
|
|
3
|
+
if (sec < 60)
|
|
4
|
+
return `${sec}s`;
|
|
5
|
+
if (sec < 3600)
|
|
6
|
+
return `${Math.round(sec / 60)}m`;
|
|
7
|
+
return `${Math.round(sec / 3600)}h`;
|
|
8
|
+
}
|
|
9
|
+
function indent(text) {
|
|
10
|
+
return text
|
|
11
|
+
.split("\n")
|
|
12
|
+
.map((l) => ` | ${l}`)
|
|
13
|
+
.join("\n");
|
|
14
|
+
}
|
|
15
|
+
function render(e, now, maxBytes) {
|
|
16
|
+
const live = isAlive(e.pid);
|
|
17
|
+
const age = Math.max(0, Math.round((now - e.startedAt) / 1000));
|
|
18
|
+
const head = `${live ? "▶ running" : "✓ finished"} · ${e.agent} (pid ${e.pid}, ${fmtAge(age)} ago) · id ${e.id}\n` +
|
|
19
|
+
` task: ${e.task.slice(0, 100)}`;
|
|
20
|
+
const out = readDispatchOutput(e, maxBytes).trim();
|
|
21
|
+
if (!out)
|
|
22
|
+
return `${head}\n (no output captured${e.logPath ? " yet" : ""})`;
|
|
23
|
+
return `${head}\n output (tail):\n${indent(out)}`;
|
|
24
|
+
}
|
|
25
|
+
export const dispatchStatusTool = {
|
|
26
|
+
name: "dispatch_status",
|
|
27
|
+
description: "Check on the CLI agents you dispatched (dispatch_agent): whether each is still running or has " +
|
|
28
|
+
"finished, and the tail of its captured output — so dispatching isn't fire-and-forget. Pass `id` " +
|
|
29
|
+
"(a dispatch id or pid) for one agent's fuller output, or omit to list all recent dispatches. Read-only.",
|
|
30
|
+
inputSchema: {
|
|
31
|
+
type: "object",
|
|
32
|
+
properties: {
|
|
33
|
+
id: {
|
|
34
|
+
type: "string",
|
|
35
|
+
description: "A dispatch id (from dispatch_agent) or pid; omit to list all recent dispatches.",
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
},
|
|
40
|
+
async execute(input) {
|
|
41
|
+
const all = listRecentDispatches();
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
if (input.id) {
|
|
44
|
+
const e = all.find((x) => x.id === input.id || String(x.pid) === input.id);
|
|
45
|
+
if (!e)
|
|
46
|
+
return `No dispatch found for "${input.id}". (It may have aged out, or was never dispatched by me.)`;
|
|
47
|
+
return render(e, now, 4000);
|
|
48
|
+
}
|
|
49
|
+
if (all.length === 0)
|
|
50
|
+
return "No dispatched agents on record.";
|
|
51
|
+
return all
|
|
52
|
+
.sort((a, b) => b.startedAt - a.startedAt)
|
|
53
|
+
.map((e) => render(e, now, 600))
|
|
54
|
+
.join("\n\n");
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=dispatch_status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dispatch_status.js","sourceRoot":"","sources":["../../src/tools/dispatch_status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* github (integration) — a gh-CLI-backed tool covering the GitHub operations a
|
|
3
|
+
* coding agent / orchestrator actually needs beyond pr_status (list+CI) and
|
|
4
|
+
* github_link (URLs): issues (list/view/create/comment), PRs (view/create/
|
|
5
|
+
* comment/merge), CI runs (list/view), releases. One tool, action-dispatched.
|
|
6
|
+
*
|
|
7
|
+
* Read actions are safe; create/comment/merge are write actions (gated by the
|
|
8
|
+
* host approval layer like any mutating tool). Needs `gh` authenticated.
|
|
9
|
+
*/
|
|
10
|
+
import type { ToolDefinition } from "../types.js";
|
|
11
|
+
type GithubAction = "issue_list" | "issue_view" | "issue_create" | "issue_comment" | "pr_view" | "pr_create" | "pr_comment" | "pr_merge" | "run_list" | "run_view" | "release_list";
|
|
12
|
+
interface GithubInput {
|
|
13
|
+
action: GithubAction;
|
|
14
|
+
cwd?: string;
|
|
15
|
+
/** Issue / PR / run number (issue_view, pr_view, *_comment, pr_merge, run_view). */
|
|
16
|
+
number?: number;
|
|
17
|
+
title?: string;
|
|
18
|
+
body?: string;
|
|
19
|
+
/** pr_create base branch. */
|
|
20
|
+
base?: string;
|
|
21
|
+
/** issue_list / pr filter state. */
|
|
22
|
+
state?: "open" | "closed" | "all";
|
|
23
|
+
/** pr_merge method. Default squash. */
|
|
24
|
+
merge_method?: "squash" | "merge" | "rebase";
|
|
25
|
+
}
|
|
26
|
+
/** Build the gh argv for an action (without the leading "gh"). Pure + tested. */
|
|
27
|
+
export declare function buildGhArgs(input: GithubInput): {
|
|
28
|
+
args: string[];
|
|
29
|
+
} | {
|
|
30
|
+
error: string;
|
|
31
|
+
};
|
|
32
|
+
export declare const githubTool: ToolDefinition<GithubInput, string>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=github.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../../src/tools/github.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,KAAK,YAAY,GACb,YAAY,GAAG,YAAY,GAAG,cAAc,GAAG,eAAe,GAC9D,SAAS,GAAG,WAAW,GAAG,YAAY,GAAG,UAAU,GACnD,UAAU,GAAG,UAAU,GAAG,cAAc,CAAC;AAE7C,UAAU,WAAW;IACnB,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6BAA6B;IAC7B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IAClC,uCAAuC;IACvC,YAAY,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;CAC9C;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA8CtF;AAsBD,eAAO,MAAM,UAAU,EAAE,cAAc,CAAC,WAAW,EAAE,MAAM,CA8C1D,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { runIn, isDir, gitRoot } from "./exec-util.js";
|
|
2
|
+
/** Build the gh argv for an action (without the leading "gh"). Pure + tested. */
|
|
3
|
+
export function buildGhArgs(input) {
|
|
4
|
+
const need = (v, name) => v == null || v === "" ? `${input.action} needs ${name}` : null;
|
|
5
|
+
switch (input.action) {
|
|
6
|
+
case "issue_list":
|
|
7
|
+
return { args: ["issue", "list", "--state", input.state ?? "open", "--limit", "30", "--json", "number,title,state,author,labels"] };
|
|
8
|
+
case "issue_view": {
|
|
9
|
+
const e = need(input.number, "a number");
|
|
10
|
+
if (e)
|
|
11
|
+
return { error: e };
|
|
12
|
+
return { args: ["issue", "view", String(input.number), "--comments"] };
|
|
13
|
+
}
|
|
14
|
+
case "issue_create": {
|
|
15
|
+
const e = need(input.title, "a title");
|
|
16
|
+
if (e)
|
|
17
|
+
return { error: e };
|
|
18
|
+
return { args: ["issue", "create", "--title", input.title, "--body", input.body ?? ""] };
|
|
19
|
+
}
|
|
20
|
+
case "issue_comment": {
|
|
21
|
+
const e = need(input.number, "a number") || need(input.body, "a body");
|
|
22
|
+
if (e)
|
|
23
|
+
return { error: e };
|
|
24
|
+
return { args: ["issue", "comment", String(input.number), "--body", input.body] };
|
|
25
|
+
}
|
|
26
|
+
case "pr_view": {
|
|
27
|
+
const e = need(input.number, "a number");
|
|
28
|
+
if (e)
|
|
29
|
+
return { error: e };
|
|
30
|
+
return { args: ["pr", "view", String(input.number), "--comments"] };
|
|
31
|
+
}
|
|
32
|
+
case "pr_create": {
|
|
33
|
+
const e = need(input.title, "a title");
|
|
34
|
+
if (e)
|
|
35
|
+
return { error: e };
|
|
36
|
+
const args = ["pr", "create", "--title", input.title, "--body", input.body ?? ""];
|
|
37
|
+
if (input.base)
|
|
38
|
+
args.push("--base", input.base);
|
|
39
|
+
return { args };
|
|
40
|
+
}
|
|
41
|
+
case "pr_comment": {
|
|
42
|
+
const e = need(input.number, "a number") || need(input.body, "a body");
|
|
43
|
+
if (e)
|
|
44
|
+
return { error: e };
|
|
45
|
+
return { args: ["pr", "comment", String(input.number), "--body", input.body] };
|
|
46
|
+
}
|
|
47
|
+
case "pr_merge": {
|
|
48
|
+
const e = need(input.number, "a number");
|
|
49
|
+
if (e)
|
|
50
|
+
return { error: e };
|
|
51
|
+
return { args: ["pr", "merge", String(input.number), `--${input.merge_method ?? "squash"}`, "--delete-branch"] };
|
|
52
|
+
}
|
|
53
|
+
case "run_list":
|
|
54
|
+
return { args: ["run", "list", "--limit", "15", "--json", "databaseId,name,status,conclusion,headBranch,event"] };
|
|
55
|
+
case "run_view": {
|
|
56
|
+
const e = need(input.number, "a run id (number)");
|
|
57
|
+
if (e)
|
|
58
|
+
return { error: e };
|
|
59
|
+
return { args: ["run", "view", String(input.number)] };
|
|
60
|
+
}
|
|
61
|
+
case "release_list":
|
|
62
|
+
return { args: ["release", "list", "--limit", "10"] };
|
|
63
|
+
default:
|
|
64
|
+
return { error: `unknown action: ${input.action}` };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Compact a gh --json issue/PR/run array into readable lines. */
|
|
68
|
+
function formatJsonList(action, raw) {
|
|
69
|
+
let arr;
|
|
70
|
+
try {
|
|
71
|
+
arr = JSON.parse(raw);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return raw.trim();
|
|
75
|
+
}
|
|
76
|
+
if (!Array.isArray(arr) || arr.length === 0)
|
|
77
|
+
return "(none)";
|
|
78
|
+
if (action === "issue_list") {
|
|
79
|
+
return arr.map((i) => {
|
|
80
|
+
const labels = (i.labels ?? []).map((l) => l.name).join(", ");
|
|
81
|
+
return `#${i.number} [${i.state}] ${i.title}${labels ? ` (${labels})` : ""} — @${i.author?.login ?? "?"}`;
|
|
82
|
+
}).join("\n");
|
|
83
|
+
}
|
|
84
|
+
if (action === "run_list") {
|
|
85
|
+
return arr.map((r) => {
|
|
86
|
+
const s = r.conclusion || r.status || "?";
|
|
87
|
+
return `${r.databaseId} ${s} · ${r.name} · ${r.headBranch} (${r.event})`;
|
|
88
|
+
}).join("\n");
|
|
89
|
+
}
|
|
90
|
+
return raw.trim();
|
|
91
|
+
}
|
|
92
|
+
export const githubTool = {
|
|
93
|
+
name: "github",
|
|
94
|
+
description: "GitHub operations via gh: issues (issue_list / issue_view / issue_create / issue_comment), " +
|
|
95
|
+
"PRs (pr_view / pr_create / pr_comment / pr_merge), CI (run_list / run_view), releases " +
|
|
96
|
+
"(release_list). For listing open PRs with CI use pr_status; for URLs use github_link. " +
|
|
97
|
+
"create/comment/merge are write actions. Needs `gh` authenticated.",
|
|
98
|
+
inputSchema: {
|
|
99
|
+
type: "object",
|
|
100
|
+
properties: {
|
|
101
|
+
action: {
|
|
102
|
+
type: "string",
|
|
103
|
+
enum: ["issue_list", "issue_view", "issue_create", "issue_comment", "pr_view", "pr_create", "pr_comment", "pr_merge", "run_list", "run_view", "release_list"],
|
|
104
|
+
},
|
|
105
|
+
cwd: { type: "string", description: "Absolute path inside the repo. Defaults to the current directory." },
|
|
106
|
+
number: { type: "integer", description: "Issue / PR number, or run id (per action)." },
|
|
107
|
+
title: { type: "string", description: "For issue_create / pr_create." },
|
|
108
|
+
body: { type: "string", description: "Body for create/comment actions." },
|
|
109
|
+
base: { type: "string", description: "Base branch for pr_create." },
|
|
110
|
+
state: { type: "string", enum: ["open", "closed", "all"], description: "Filter for issue_list (default open)." },
|
|
111
|
+
merge_method: { type: "string", enum: ["squash", "merge", "rebase"], description: "For pr_merge (default squash)." },
|
|
112
|
+
},
|
|
113
|
+
required: ["action"],
|
|
114
|
+
additionalProperties: false,
|
|
115
|
+
},
|
|
116
|
+
async execute(input, ctx) {
|
|
117
|
+
const cwd = input.cwd && input.cwd.startsWith("/") ? input.cwd : ctx.cwd;
|
|
118
|
+
if (!(await isDir(cwd)))
|
|
119
|
+
return `(not a directory: ${cwd})`;
|
|
120
|
+
const root = (await gitRoot(cwd, ctx.signal)) ?? cwd;
|
|
121
|
+
const built = buildGhArgs(input);
|
|
122
|
+
if ("error" in built)
|
|
123
|
+
return `(${built.error})`;
|
|
124
|
+
const r = await runIn(root, "gh", built.args, { timeoutMs: 30000, signal: ctx.signal, maxBytes: 200_000 });
|
|
125
|
+
if (r.spawnError)
|
|
126
|
+
return "(the `gh` CLI isn't installed — needed for GitHub operations. https://cli.github.com)";
|
|
127
|
+
if (r.code !== 0) {
|
|
128
|
+
const e = r.stderr.trim();
|
|
129
|
+
if (/auth|login/i.test(e))
|
|
130
|
+
return "(`gh` isn't authenticated — run `gh auth login`)";
|
|
131
|
+
return `(gh ${input.action} failed: ${e.slice(0, 250) || "unknown error"})`;
|
|
132
|
+
}
|
|
133
|
+
const out = r.stdout.trim();
|
|
134
|
+
if (input.action === "issue_list" || input.action === "run_list") {
|
|
135
|
+
return formatJsonList(input.action, r.stdout) || "(none)";
|
|
136
|
+
}
|
|
137
|
+
return out || "(done)";
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=github.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github.js","sourceRoot":"","sources":["../../src/tools/github.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ToolDefinition } from "../types.js";
|
|
2
|
+
interface GithubLinkInput {
|
|
3
|
+
/** What to link: repo (default), branch, commit, file, pr, issue. */
|
|
4
|
+
target?: "repo" | "branch" | "commit" | "file" | "pr" | "issue";
|
|
5
|
+
cwd?: string;
|
|
6
|
+
/** Branch name or commit sha; defaults to the current branch/HEAD. */
|
|
7
|
+
ref?: string;
|
|
8
|
+
/** For target:file — path (absolute or repo-relative). */
|
|
9
|
+
path?: string;
|
|
10
|
+
start_line?: number;
|
|
11
|
+
end_line?: number;
|
|
12
|
+
/** For target:pr/issue — the number. */
|
|
13
|
+
number?: number;
|
|
14
|
+
/** Also open the URL in the default browser. */
|
|
15
|
+
open?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface Remote {
|
|
18
|
+
host: string;
|
|
19
|
+
owner: string;
|
|
20
|
+
repo: string;
|
|
21
|
+
}
|
|
22
|
+
/** Parse a git remote URL (scp or https/ssh) into host/owner/repo. Pure. */
|
|
23
|
+
export declare function parseRemote(url: string): Remote | null;
|
|
24
|
+
/** Build a GitHub URL for the given target. Pure + tested. */
|
|
25
|
+
export declare function buildUrl(r: Remote, target: NonNullable<GithubLinkInput["target"]>, opts?: {
|
|
26
|
+
ref?: string;
|
|
27
|
+
path?: string;
|
|
28
|
+
startLine?: number;
|
|
29
|
+
endLine?: number;
|
|
30
|
+
number?: number;
|
|
31
|
+
}): string | {
|
|
32
|
+
error: string;
|
|
33
|
+
};
|
|
34
|
+
export declare const githubLinkTool: ToolDefinition<GithubLinkInput, string>;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=github_link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github_link.d.ts","sourceRoot":"","sources":["../../src/tools/github_link.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,UAAU,eAAe;IACvB,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAED,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAatD;AAED,8DAA8D;AAC9D,wBAAgB,QAAQ,CACtB,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,EAC9C,IAAI,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAChG,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,CA2B5B;AAED,eAAO,MAAM,cAAc,EAAE,cAAc,CAAC,eAAe,EAAE,MAAM,CAgElE,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* github_link (vibe-coding) — turn the local git context into a shareable
|
|
3
|
+
* GitHub URL: the repo, a branch, a commit, a file (optionally with a line
|
|
4
|
+
* range), or a PR / issue. So when LISA references "src/web/server.ts:120" or
|
|
5
|
+
* "PR #58" she can hand you a clickable link instead of a path.
|
|
6
|
+
*
|
|
7
|
+
* URL building is pure git (parses `origin`), so it needs no gh. `open:true`
|
|
8
|
+
* best-effort opens it in your browser.
|
|
9
|
+
*/
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { runIn, isDir, gitRoot } from "./exec-util.js";
|
|
12
|
+
/** Parse a git remote URL (scp or https/ssh) into host/owner/repo. Pure. */
|
|
13
|
+
export function parseRemote(url) {
|
|
14
|
+
let s = url.trim().replace(/\.git$/i, "").replace(/\/$/, "");
|
|
15
|
+
// scp-like: git@github.com:owner/repo (also ssh://git@github.com/owner/repo)
|
|
16
|
+
let m = s.match(/^(?:ssh:\/\/)?[^@\s]*@([^:/]+)[:/](.+)$/i);
|
|
17
|
+
if (!m) {
|
|
18
|
+
// url: https://github.com/owner/repo
|
|
19
|
+
m = s.match(/^https?:\/\/(?:[^@/]+@)?([^/]+)\/(.+)$/i);
|
|
20
|
+
}
|
|
21
|
+
if (!m)
|
|
22
|
+
return null;
|
|
23
|
+
const host = m[1];
|
|
24
|
+
const parts = m[2].split("/").filter(Boolean);
|
|
25
|
+
if (parts.length < 2)
|
|
26
|
+
return null;
|
|
27
|
+
return { host, owner: parts[0], repo: parts[1] };
|
|
28
|
+
}
|
|
29
|
+
/** Build a GitHub URL for the given target. Pure + tested. */
|
|
30
|
+
export function buildUrl(r, target, opts = {}) {
|
|
31
|
+
const base = `https://${r.host}/${r.owner}/${r.repo}`;
|
|
32
|
+
switch (target) {
|
|
33
|
+
case "repo":
|
|
34
|
+
return base;
|
|
35
|
+
case "branch":
|
|
36
|
+
return opts.ref ? `${base}/tree/${encodeURIComponent(opts.ref)}` : base;
|
|
37
|
+
case "commit":
|
|
38
|
+
return opts.ref ? `${base}/commit/${opts.ref}` : { error: "commit needs a ref/sha" };
|
|
39
|
+
case "file": {
|
|
40
|
+
if (!opts.path)
|
|
41
|
+
return { error: "file needs a path" };
|
|
42
|
+
const ref = opts.ref || "HEAD";
|
|
43
|
+
const cleanPath = opts.path.split("/").map(encodeURIComponent).join("/").replace(/^\//, "");
|
|
44
|
+
let url = `${base}/blob/${encodeURIComponent(ref)}/${cleanPath}`;
|
|
45
|
+
if (opts.startLine) {
|
|
46
|
+
url += `#L${opts.startLine}`;
|
|
47
|
+
if (opts.endLine && opts.endLine !== opts.startLine)
|
|
48
|
+
url += `-L${opts.endLine}`;
|
|
49
|
+
}
|
|
50
|
+
return url;
|
|
51
|
+
}
|
|
52
|
+
case "pr":
|
|
53
|
+
return opts.number ? `${base}/pull/${opts.number}` : { error: "pr needs a number" };
|
|
54
|
+
case "issue":
|
|
55
|
+
return opts.number ? `${base}/issues/${opts.number}` : { error: "issue needs a number" };
|
|
56
|
+
default:
|
|
57
|
+
return { error: `unknown target: ${target}` };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
export const githubLinkTool = {
|
|
61
|
+
name: "github_link",
|
|
62
|
+
description: "Build a shareable GitHub URL from the local git repo: target 'repo' (default), 'branch', " +
|
|
63
|
+
"'commit', 'file' (path + optional start_line/end_line), 'pr' or 'issue' (number). Defaults the " +
|
|
64
|
+
"ref to the current branch / HEAD. Use to give the user a clickable link to a file/line, commit, " +
|
|
65
|
+
"branch, or PR you're referencing. open:true also opens it in the browser. Needs a GitHub `origin` " +
|
|
66
|
+
"remote; no gh required.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: "object",
|
|
69
|
+
properties: {
|
|
70
|
+
target: { type: "string", enum: ["repo", "branch", "commit", "file", "pr", "issue"] },
|
|
71
|
+
cwd: { type: "string", description: "Absolute path inside the repo. Defaults to the current directory." },
|
|
72
|
+
ref: { type: "string", description: "Branch name or commit sha. Defaults to the current branch (for file/branch) or HEAD." },
|
|
73
|
+
path: { type: "string", description: "For target:file — absolute or repo-relative file path." },
|
|
74
|
+
start_line: { type: "integer", minimum: 1 },
|
|
75
|
+
end_line: { type: "integer", minimum: 1 },
|
|
76
|
+
number: { type: "integer", minimum: 1, description: "For target:pr or issue." },
|
|
77
|
+
open: { type: "boolean", description: "Also open the URL in the default browser." },
|
|
78
|
+
},
|
|
79
|
+
additionalProperties: false,
|
|
80
|
+
},
|
|
81
|
+
async execute(input, ctx) {
|
|
82
|
+
const cwd = input.cwd && input.cwd.startsWith("/") ? input.cwd : ctx.cwd;
|
|
83
|
+
if (!(await isDir(cwd)))
|
|
84
|
+
return `(not a directory: ${cwd})`;
|
|
85
|
+
const root = await gitRoot(cwd, ctx.signal);
|
|
86
|
+
if (!root)
|
|
87
|
+
return `(not a git repo: ${cwd})`;
|
|
88
|
+
const remoteR = await runIn(root, "git", ["-C", root, "remote", "get-url", "origin"], { timeoutMs: 5000, signal: ctx.signal });
|
|
89
|
+
if (remoteR.code !== 0)
|
|
90
|
+
return "(no `origin` remote on this repo)";
|
|
91
|
+
const remote = parseRemote(remoteR.stdout);
|
|
92
|
+
if (!remote)
|
|
93
|
+
return `(couldn't parse a GitHub URL from origin: ${remoteR.stdout.trim().slice(0, 120)})`;
|
|
94
|
+
const target = input.target ?? "repo";
|
|
95
|
+
// Resolve a default ref for branch/file when none given.
|
|
96
|
+
let ref = input.ref;
|
|
97
|
+
if (!ref && (target === "branch" || target === "file")) {
|
|
98
|
+
const b = await runIn(root, "git", ["-C", root, "rev-parse", "--abbrev-ref", "HEAD"], { timeoutMs: 5000, signal: ctx.signal });
|
|
99
|
+
if (b.code === 0)
|
|
100
|
+
ref = b.stdout.trim();
|
|
101
|
+
}
|
|
102
|
+
if (!ref && target === "commit") {
|
|
103
|
+
const h = await runIn(root, "git", ["-C", root, "rev-parse", "HEAD"], { timeoutMs: 5000, signal: ctx.signal });
|
|
104
|
+
if (h.code === 0)
|
|
105
|
+
ref = h.stdout.trim();
|
|
106
|
+
}
|
|
107
|
+
// For file: make the path repo-relative.
|
|
108
|
+
let filePath = input.path;
|
|
109
|
+
if (target === "file" && filePath) {
|
|
110
|
+
if (filePath.startsWith("/"))
|
|
111
|
+
filePath = path.relative(root, filePath);
|
|
112
|
+
if (filePath.startsWith(".."))
|
|
113
|
+
return `(file is outside the repo: ${input.path})`;
|
|
114
|
+
}
|
|
115
|
+
const built = buildUrl(remote, target, { ref, path: filePath, startLine: input.start_line, endLine: input.end_line, number: input.number });
|
|
116
|
+
if (typeof built !== "string")
|
|
117
|
+
return `(${built.error})`;
|
|
118
|
+
if (input.open) {
|
|
119
|
+
const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
120
|
+
const args = process.platform === "win32" ? ["/c", "start", built] : [built];
|
|
121
|
+
runIn(root, opener, args, { timeoutMs: 5000, signal: ctx.signal }).catch(() => { });
|
|
122
|
+
return `${built}\n(opened in browser)`;
|
|
123
|
+
}
|
|
124
|
+
return built;
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=github_link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"github_link.js","sourceRoot":"","sources":["../../src/tools/github_link.ts"],"names":[],"mappings":"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"}
|