@getforgeai/cli 0.1.0-beta.1
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/LICENSE +201 -0
- package/README.md +80 -0
- package/dist/bin/forgeai.d.ts +3 -0
- package/dist/bin/forgeai.js +8 -0
- package/dist/cli.d.ts +4 -0
- package/dist/cli.js +180 -0
- package/dist/commands/auth-login.d.ts +4 -0
- package/dist/commands/auth-login.js +202 -0
- package/dist/commands/auth-logout.d.ts +2 -0
- package/dist/commands/auth-logout.js +41 -0
- package/dist/commands/auth-status.d.ts +4 -0
- package/dist/commands/auth-status.js +81 -0
- package/dist/commands/cli-list.d.ts +4 -0
- package/dist/commands/cli-list.js +40 -0
- package/dist/commands/cli-unlink.d.ts +4 -0
- package/dist/commands/cli-unlink.js +45 -0
- package/dist/commands/config-set.d.ts +5 -0
- package/dist/commands/config-set.js +63 -0
- package/dist/commands/connect.d.ts +9 -0
- package/dist/commands/connect.js +165 -0
- package/dist/commands/disconnect.d.ts +5 -0
- package/dist/commands/disconnect.js +126 -0
- package/dist/commands/journal-clear.d.ts +2 -0
- package/dist/commands/journal-clear.js +16 -0
- package/dist/commands/journal-list.d.ts +2 -0
- package/dist/commands/journal-list.js +20 -0
- package/dist/commands/journal-status.d.ts +2 -0
- package/dist/commands/journal-status.js +18 -0
- package/dist/commands/mcp-serve.d.ts +13 -0
- package/dist/commands/mcp-serve.js +74 -0
- package/dist/commands/org-list.d.ts +4 -0
- package/dist/commands/org-list.js +56 -0
- package/dist/commands/org-unlink.d.ts +4 -0
- package/dist/commands/org-unlink.js +63 -0
- package/dist/commands/reconnect.d.ts +4 -0
- package/dist/commands/reconnect.js +46 -0
- package/dist/commands/release-open.d.ts +2 -0
- package/dist/commands/release-open.js +43 -0
- package/dist/commands/session-respond.d.ts +2 -0
- package/dist/commands/session-respond.js +29 -0
- package/dist/commands/task-open.d.ts +2 -0
- package/dist/commands/task-open.js +42 -0
- package/dist/commands/vm.d.ts +21 -0
- package/dist/commands/vm.js +122 -0
- package/dist/commands/workflow-open.d.ts +2 -0
- package/dist/commands/workflow-open.js +43 -0
- package/dist/config/config-manager.d.ts +31 -0
- package/dist/config/config-manager.js +70 -0
- package/dist/config/token-manager.d.ts +11 -0
- package/dist/config/token-manager.js +87 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +22 -0
- package/dist/lib/auth-client.d.ts +1670 -0
- package/dist/lib/auth-client.js +10 -0
- package/dist/lib/branch-manager.d.ts +79 -0
- package/dist/lib/branch-manager.js +620 -0
- package/dist/lib/clone-and-checkout.d.ts +6 -0
- package/dist/lib/clone-and-checkout.js +41 -0
- package/dist/lib/connection-manager.d.ts +58 -0
- package/dist/lib/connection-manager.js +436 -0
- package/dist/lib/daemon-entry.d.ts +2 -0
- package/dist/lib/daemon-entry.js +210 -0
- package/dist/lib/daemon.d.ts +38 -0
- package/dist/lib/daemon.js +148 -0
- package/dist/lib/event-journal.d.ts +24 -0
- package/dist/lib/event-journal.js +76 -0
- package/dist/lib/ipc-client.d.ts +10 -0
- package/dist/lib/ipc-client.js +70 -0
- package/dist/lib/ipc-server.d.ts +36 -0
- package/dist/lib/ipc-server.js +70 -0
- package/dist/lib/node-version-guard.d.ts +8 -0
- package/dist/lib/node-version-guard.js +60 -0
- package/dist/lib/open-directory.d.ts +7 -0
- package/dist/lib/open-directory.js +41 -0
- package/dist/lib/repo-manager.d.ts +29 -0
- package/dist/lib/repo-manager.js +103 -0
- package/dist/lib/resilient-emitter.d.ts +53 -0
- package/dist/lib/resilient-emitter.js +160 -0
- package/dist/lib/rest-client.d.ts +164 -0
- package/dist/lib/rest-client.js +139 -0
- package/dist/lib/skill-manager.d.ts +23 -0
- package/dist/lib/skill-manager.js +167 -0
- package/dist/lib/socket-client.d.ts +68 -0
- package/dist/lib/socket-client.js +160 -0
- package/dist/mcp/mcp-probe.d.ts +11 -0
- package/dist/mcp/mcp-probe.js +106 -0
- package/dist/mcp/mcp-response.d.ts +29 -0
- package/dist/mcp/mcp-response.js +67 -0
- package/dist/mcp/mcp-server.d.ts +19 -0
- package/dist/mcp/mcp-server.js +76 -0
- package/dist/mcp/resources/project-conventions.d.ts +4 -0
- package/dist/mcp/resources/project-conventions.js +50 -0
- package/dist/mcp/resources/task-current.d.ts +4 -0
- package/dist/mcp/resources/task-current.js +51 -0
- package/dist/mcp/tools/forge-add-group-dependency.d.ts +4 -0
- package/dist/mcp/tools/forge-add-group-dependency.js +20 -0
- package/dist/mcp/tools/forge-add-task-dependency.d.ts +4 -0
- package/dist/mcp/tools/forge-add-task-dependency.js +20 -0
- package/dist/mcp/tools/forge-ask-human.d.ts +4 -0
- package/dist/mcp/tools/forge-ask-human.js +80 -0
- package/dist/mcp/tools/forge-column-done.d.ts +4 -0
- package/dist/mcp/tools/forge-column-done.js +46 -0
- package/dist/mcp/tools/forge-complete-step.d.ts +4 -0
- package/dist/mcp/tools/forge-complete-step.js +139 -0
- package/dist/mcp/tools/forge-create-task-group.d.ts +4 -0
- package/dist/mcp/tools/forge-create-task-group.js +22 -0
- package/dist/mcp/tools/forge-create-task.d.ts +4 -0
- package/dist/mcp/tools/forge-create-task.js +28 -0
- package/dist/mcp/tools/forge-delete-task-group.d.ts +4 -0
- package/dist/mcp/tools/forge-delete-task-group.js +17 -0
- package/dist/mcp/tools/forge-delete-task.d.ts +4 -0
- package/dist/mcp/tools/forge-delete-task.js +17 -0
- package/dist/mcp/tools/forge-get-task.d.ts +4 -0
- package/dist/mcp/tools/forge-get-task.js +17 -0
- package/dist/mcp/tools/forge-merge-back.d.ts +4 -0
- package/dist/mcp/tools/forge-merge-back.js +179 -0
- package/dist/mcp/tools/forge-release-merge.d.ts +4 -0
- package/dist/mcp/tools/forge-release-merge.js +159 -0
- package/dist/mcp/tools/forge-release-notes.d.ts +4 -0
- package/dist/mcp/tools/forge-release-notes.js +51 -0
- package/dist/mcp/tools/forge-release-tag.d.ts +4 -0
- package/dist/mcp/tools/forge-release-tag.js +125 -0
- package/dist/mcp/tools/forge-remove-group-dependency.d.ts +4 -0
- package/dist/mcp/tools/forge-remove-group-dependency.js +19 -0
- package/dist/mcp/tools/forge-remove-task-dependency.d.ts +4 -0
- package/dist/mcp/tools/forge-remove-task-dependency.js +19 -0
- package/dist/mcp/tools/forge-requeue.d.ts +4 -0
- package/dist/mcp/tools/forge-requeue.js +39 -0
- package/dist/mcp/tools/forge-submit-pr.d.ts +4 -0
- package/dist/mcp/tools/forge-submit-pr.js +68 -0
- package/dist/mcp/tools/forge-update-status.d.ts +4 -0
- package/dist/mcp/tools/forge-update-status.js +77 -0
- package/dist/mcp/tools/forge-update-task-group.d.ts +4 -0
- package/dist/mcp/tools/forge-update-task-group.js +21 -0
- package/dist/mcp/tools/forge-update-task.d.ts +4 -0
- package/dist/mcp/tools/forge-update-task.js +25 -0
- package/dist/mcp/tools/forge-validate-merge.d.ts +4 -0
- package/dist/mcp/tools/forge-validate-merge.js +194 -0
- package/dist/mcp/types.d.ts +39 -0
- package/dist/mcp/types.js +8 -0
- package/dist/methodology/artifact-manager.d.ts +14 -0
- package/dist/methodology/artifact-manager.js +55 -0
- package/dist/orchestrator/agent-registry.d.ts +53 -0
- package/dist/orchestrator/agent-registry.js +96 -0
- package/dist/orchestrator/agent-spawner.d.ts +112 -0
- package/dist/orchestrator/agent-spawner.js +1518 -0
- package/dist/orchestrator/connectors/claude-code-connector.d.ts +3 -0
- package/dist/orchestrator/connectors/claude-code-connector.js +60 -0
- package/dist/orchestrator/connectors/connector.d.ts +95 -0
- package/dist/orchestrator/connectors/connector.js +25 -0
- package/dist/orchestrator/connectors/docker-connector.d.ts +14 -0
- package/dist/orchestrator/connectors/docker-connector.js +337 -0
- package/dist/orchestrator/connectors/native-vm-connector.d.ts +11 -0
- package/dist/orchestrator/connectors/native-vm-connector.js +162 -0
- package/dist/orchestrator/connectors/opencode-connector.d.ts +3 -0
- package/dist/orchestrator/connectors/opencode-connector.js +39 -0
- package/dist/orchestrator/connectors/vm-connector.d.ts +3 -0
- package/dist/orchestrator/connectors/vm-connector.js +139 -0
- package/dist/orchestrator/dispatch-queue.d.ts +43 -0
- package/dist/orchestrator/dispatch-queue.js +93 -0
- package/dist/orchestrator/resume-handler.d.ts +34 -0
- package/dist/orchestrator/resume-handler.js +159 -0
- package/dist/orchestrator/stream-batcher.d.ts +16 -0
- package/dist/orchestrator/stream-batcher.js +50 -0
- package/dist/orchestrator/stream-json-extractor.d.ts +97 -0
- package/dist/orchestrator/stream-json-extractor.js +579 -0
- package/dist/vm/claude-token-manager.d.ts +36 -0
- package/dist/vm/claude-token-manager.js +223 -0
- package/dist/vm/docker-executor.d.ts +131 -0
- package/dist/vm/docker-executor.js +360 -0
- package/dist/vm/docker-process-proxy.d.ts +31 -0
- package/dist/vm/docker-process-proxy.js +105 -0
- package/dist/vm/forge-vm-agent.d.ts +11 -0
- package/dist/vm/forge-vm-agent.js +159 -0
- package/dist/vm/git-credentials.d.ts +43 -0
- package/dist/vm/git-credentials.js +53 -0
- package/dist/vm/image-manager.d.ts +7 -0
- package/dist/vm/image-manager.js +61 -0
- package/dist/vm/log.d.ts +9 -0
- package/dist/vm/log.js +18 -0
- package/dist/vm/mcp-bridge.d.ts +63 -0
- package/dist/vm/mcp-bridge.js +243 -0
- package/dist/vm/mcp-stub.d.ts +15 -0
- package/dist/vm/mcp-stub.js +67 -0
- package/dist/vm/native-addon.d.ts +69 -0
- package/dist/vm/native-addon.js +68 -0
- package/dist/vm/provider-resolver.d.ts +7 -0
- package/dist/vm/provider-resolver.js +27 -0
- package/dist/vm/providers/lima.d.ts +17 -0
- package/dist/vm/providers/lima.js +191 -0
- package/dist/vm/providers/qemu.d.ts +28 -0
- package/dist/vm/providers/qemu.js +260 -0
- package/dist/vm/providers/vfkit.d.ts +40 -0
- package/dist/vm/providers/vfkit.js +371 -0
- package/dist/vm/providers/wsl2.d.ts +27 -0
- package/dist/vm/providers/wsl2.js +226 -0
- package/dist/vm/session-manager.d.ts +130 -0
- package/dist/vm/session-manager.js +494 -0
- package/dist/vm/session-snapshot.d.ts +31 -0
- package/dist/vm/session-snapshot.js +180 -0
- package/dist/vm/types.d.ts +73 -0
- package/dist/vm/types.js +2 -0
- package/dist/vm/vm-helper-client.d.ts +81 -0
- package/dist/vm/vm-helper-client.js +335 -0
- package/dist/vm/vm-helper.d.ts +11 -0
- package/dist/vm/vm-helper.js +156 -0
- package/dist/vm/vm-ipc-protocol.d.ts +84 -0
- package/dist/vm/vm-ipc-protocol.js +9 -0
- package/dist/vm/vm-manager-facade.d.ts +23 -0
- package/dist/vm/vm-manager-facade.js +43 -0
- package/dist/vm/vm-manager.d.ts +74 -0
- package/dist/vm/vm-manager.js +515 -0
- package/dist/vm/vm-process-proxy.d.ts +34 -0
- package/dist/vm/vm-process-proxy.js +64 -0
- package/dist/vm/vsock-bridge.d.ts +44 -0
- package/dist/vm/vsock-bridge.js +140 -0
- package/dist/vm/vsock-protocol.d.ts +98 -0
- package/dist/vm/vsock-protocol.js +57 -0
- package/package.json +65 -0
- package/rootfs/Dockerfile +50 -0
- package/rootfs/forge-mcp-relay.mjs +158 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VM Helper Process — child process entry point.
|
|
3
|
+
*
|
|
4
|
+
* Runs under node-vm (signed with com.apple.security.virtualization entitlement).
|
|
5
|
+
* Loads the native addon, creates a real SessionManager, and proxies commands
|
|
6
|
+
* from the parent CLI process over Node.js IPC.
|
|
7
|
+
*
|
|
8
|
+
* Usage: node-vm dist/vm/vm-helper.js
|
|
9
|
+
*/
|
|
10
|
+
import { initSessionManager } from "./session-manager.js";
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// Setup
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
const sm = initSessionManager();
|
|
15
|
+
/** Active agent proxies keyed by taskId — for streaming relay and kill routing */
|
|
16
|
+
const proxies = new Map();
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// IPC helpers
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
function sendResponse(reqId, value) {
|
|
21
|
+
const msg = { type: "res", reqId, ok: true, value };
|
|
22
|
+
process.send(msg);
|
|
23
|
+
}
|
|
24
|
+
function sendError(reqId, error) {
|
|
25
|
+
const msg = { type: "res", reqId, ok: false, error };
|
|
26
|
+
process.send(msg);
|
|
27
|
+
}
|
|
28
|
+
function sendEvent(event) {
|
|
29
|
+
process.send(event);
|
|
30
|
+
}
|
|
31
|
+
// Forward vmLog to parent
|
|
32
|
+
function sendLog(level, prefix, message) {
|
|
33
|
+
sendEvent({ type: "log", level, prefix, message });
|
|
34
|
+
}
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// Request dispatch
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
async function handleRequest(req) {
|
|
39
|
+
const { reqId } = req;
|
|
40
|
+
try {
|
|
41
|
+
switch (req.method) {
|
|
42
|
+
case "ensureVmRunning": {
|
|
43
|
+
await sm.ensureVmRunning();
|
|
44
|
+
sendResponse(reqId, null);
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
case "createSession": {
|
|
48
|
+
const sessionId = await sm.createSession(req.taskId);
|
|
49
|
+
sendResponse(reqId, sessionId);
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case "cloneRepo": {
|
|
53
|
+
await sm.cloneRepo(req.sessionId, req.repoUrl, req.branch, req.baseBranch);
|
|
54
|
+
sendResponse(reqId, null);
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case "spawnAgent": {
|
|
58
|
+
const proxy = await sm.spawnAgent(req.taskId, req.cmd, req.args, req.env);
|
|
59
|
+
// Store for kill routing
|
|
60
|
+
proxies.set(req.taskId, proxy);
|
|
61
|
+
// Relay stdout/stderr to parent
|
|
62
|
+
proxy.stdout.on("data", (chunk) => {
|
|
63
|
+
sendEvent({
|
|
64
|
+
type: "stream",
|
|
65
|
+
taskId: req.taskId,
|
|
66
|
+
channel: "stdout",
|
|
67
|
+
data: chunk,
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
proxy.stderr.on("data", (chunk) => {
|
|
71
|
+
sendEvent({
|
|
72
|
+
type: "stream",
|
|
73
|
+
taskId: req.taskId,
|
|
74
|
+
channel: "stderr",
|
|
75
|
+
data: chunk,
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
// Relay exit to parent
|
|
79
|
+
proxy.on("exit", (code) => {
|
|
80
|
+
sendEvent({ type: "exit", taskId: req.taskId, code });
|
|
81
|
+
proxies.delete(req.taskId);
|
|
82
|
+
});
|
|
83
|
+
sendResponse(reqId, { pid: proxy.pid, sessionId: req.taskId });
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "killAgent": {
|
|
87
|
+
await sm.killAgent(req.taskIdOrSessionId, req.signal);
|
|
88
|
+
sendResponse(reqId, null);
|
|
89
|
+
break;
|
|
90
|
+
}
|
|
91
|
+
case "destroySession": {
|
|
92
|
+
await sm.destroySession(req.taskId);
|
|
93
|
+
proxies.delete(req.taskId);
|
|
94
|
+
sendResponse(reqId, null);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case "exec": {
|
|
98
|
+
const result = await sm.exec(req.cmd, req.args, req.cwd);
|
|
99
|
+
sendResponse(reqId, result);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case "shutdown": {
|
|
103
|
+
await sm.shutdown();
|
|
104
|
+
sendResponse(reqId, null);
|
|
105
|
+
// Give response time to flush, then exit
|
|
106
|
+
setTimeout(() => process.exit(0), 500);
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
case "isVmRunning": {
|
|
110
|
+
sendResponse(reqId, sm.isVmRunning());
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
case "getAllSessions": {
|
|
114
|
+
sendResponse(reqId, sm.getAllSessions());
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case "getSessionByTaskId": {
|
|
118
|
+
sendResponse(reqId, sm.getSessionByTaskId(req.taskId) ?? null);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
default: {
|
|
122
|
+
sendError(reqId, `Unknown method: ${req.method}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
sendError(reqId, err instanceof Error ? err.message : String(err));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
// Message listener
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
process.on("message", (msg) => {
|
|
134
|
+
const m = msg;
|
|
135
|
+
if (m?.type === "req" && m.reqId && m.method) {
|
|
136
|
+
handleRequest(m).catch((err) => {
|
|
137
|
+
sendError(m.reqId, `Unhandled: ${err instanceof Error ? err.message : err}`);
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
// Graceful shutdown when parent disconnects
|
|
142
|
+
process.on("disconnect", () => {
|
|
143
|
+
sendLog("info", "vm-helper", "Parent disconnected, shutting down...");
|
|
144
|
+
sm.shutdown()
|
|
145
|
+
.catch(() => { })
|
|
146
|
+
.finally(() => process.exit(0));
|
|
147
|
+
});
|
|
148
|
+
// Prevent unhandled errors from crashing the helper
|
|
149
|
+
process.on("uncaughtException", (err) => {
|
|
150
|
+
sendLog("error", "vm-helper", `Uncaught: ${err.message}`);
|
|
151
|
+
});
|
|
152
|
+
process.on("unhandledRejection", (reason) => {
|
|
153
|
+
sendLog("error", "vm-helper", `Unhandled rejection: ${reason}`);
|
|
154
|
+
});
|
|
155
|
+
sendLog("info", "vm-helper", "Helper process started");
|
|
156
|
+
//# sourceMappingURL=vm-helper.js.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPC protocol between the main CLI process (parent) and the VM helper
|
|
3
|
+
* process (child running under node-vm with Apple Virtualization entitlements).
|
|
4
|
+
*
|
|
5
|
+
* Uses Node.js built-in IPC with `serialization: 'advanced'` (structured clone)
|
|
6
|
+
* so Buffer objects transfer natively without base64 encoding.
|
|
7
|
+
*/
|
|
8
|
+
import type { SessionState } from "./session-manager.js";
|
|
9
|
+
type IpcRequestBase = {
|
|
10
|
+
type: "req";
|
|
11
|
+
reqId: string;
|
|
12
|
+
};
|
|
13
|
+
export type IpcRequest = IpcRequestBase & ({
|
|
14
|
+
method: "ensureVmRunning";
|
|
15
|
+
} | {
|
|
16
|
+
method: "createSession";
|
|
17
|
+
taskId: string;
|
|
18
|
+
} | {
|
|
19
|
+
method: "cloneRepo";
|
|
20
|
+
sessionId: string;
|
|
21
|
+
repoUrl?: string;
|
|
22
|
+
branch?: string;
|
|
23
|
+
baseBranch?: string;
|
|
24
|
+
} | {
|
|
25
|
+
method: "spawnAgent";
|
|
26
|
+
taskId: string;
|
|
27
|
+
cmd: string;
|
|
28
|
+
args: string[];
|
|
29
|
+
env: Record<string, string>;
|
|
30
|
+
} | {
|
|
31
|
+
method: "killAgent";
|
|
32
|
+
taskIdOrSessionId: string;
|
|
33
|
+
signal?: string;
|
|
34
|
+
} | {
|
|
35
|
+
method: "destroySession";
|
|
36
|
+
taskId: string;
|
|
37
|
+
} | {
|
|
38
|
+
method: "exec";
|
|
39
|
+
cmd: string;
|
|
40
|
+
args: string[];
|
|
41
|
+
cwd?: string;
|
|
42
|
+
} | {
|
|
43
|
+
method: "shutdown";
|
|
44
|
+
} | {
|
|
45
|
+
method: "isVmRunning";
|
|
46
|
+
} | {
|
|
47
|
+
method: "getAllSessions";
|
|
48
|
+
} | {
|
|
49
|
+
method: "getSessionByTaskId";
|
|
50
|
+
taskId: string;
|
|
51
|
+
});
|
|
52
|
+
export type IpcResponse = {
|
|
53
|
+
type: "res";
|
|
54
|
+
reqId: string;
|
|
55
|
+
ok: true;
|
|
56
|
+
value: unknown;
|
|
57
|
+
} | {
|
|
58
|
+
type: "res";
|
|
59
|
+
reqId: string;
|
|
60
|
+
ok: false;
|
|
61
|
+
error: string;
|
|
62
|
+
};
|
|
63
|
+
export type IpcEvent = {
|
|
64
|
+
type: "stream";
|
|
65
|
+
taskId: string;
|
|
66
|
+
channel: "stdout" | "stderr";
|
|
67
|
+
data: Buffer;
|
|
68
|
+
} | {
|
|
69
|
+
type: "exit";
|
|
70
|
+
taskId: string;
|
|
71
|
+
code: number;
|
|
72
|
+
} | {
|
|
73
|
+
type: "log";
|
|
74
|
+
level: string;
|
|
75
|
+
prefix: string;
|
|
76
|
+
message: string;
|
|
77
|
+
};
|
|
78
|
+
export type IpcMessage = IpcRequest | IpcResponse | IpcEvent;
|
|
79
|
+
export type IpcSpawnResult = {
|
|
80
|
+
pid: number;
|
|
81
|
+
sessionId: string;
|
|
82
|
+
};
|
|
83
|
+
export type { SessionState };
|
|
84
|
+
//# sourceMappingURL=vm-ipc-protocol.d.ts.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPC protocol between the main CLI process (parent) and the VM helper
|
|
3
|
+
* process (child running under node-vm with Apple Virtualization entitlements).
|
|
4
|
+
*
|
|
5
|
+
* Uses Node.js built-in IPC with `serialization: 'advanced'` (structured clone)
|
|
6
|
+
* so Buffer objects transfer natively without base64 encoding.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=vm-ipc-protocol.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facade for the Docker-backed session manager.
|
|
3
|
+
* Consumers import getVmManager() / initVmManager() to get a SessionManager.
|
|
4
|
+
*/
|
|
5
|
+
import { type SessionManager } from "./session-manager.js";
|
|
6
|
+
export type VmManager = SessionManager;
|
|
7
|
+
/**
|
|
8
|
+
* Initialize the Docker-backed session manager.
|
|
9
|
+
* Checks Docker daemon availability before proceeding.
|
|
10
|
+
*/
|
|
11
|
+
export declare function initVmManager(): Promise<VmManager>;
|
|
12
|
+
/**
|
|
13
|
+
* Get the initialized session manager.
|
|
14
|
+
* Throws if initVmManager() hasn't been called yet.
|
|
15
|
+
*/
|
|
16
|
+
export declare function getVmManager(): VmManager;
|
|
17
|
+
/**
|
|
18
|
+
* Check if Docker-based agent execution is possible.
|
|
19
|
+
* Always returns true (Docker is expected on all platforms).
|
|
20
|
+
* Actual daemon availability is verified in initVmManager().
|
|
21
|
+
*/
|
|
22
|
+
export declare function isVmCapable(): boolean;
|
|
23
|
+
//# sourceMappingURL=vm-manager-facade.d.ts.map
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Facade for the Docker-backed session manager.
|
|
3
|
+
* Consumers import getVmManager() / initVmManager() to get a SessionManager.
|
|
4
|
+
*/
|
|
5
|
+
import { isDockerAvailable } from "./docker-executor.js";
|
|
6
|
+
import { initSessionManager, getSessionManager, } from "./session-manager.js";
|
|
7
|
+
import { vmLog } from "./log.js";
|
|
8
|
+
let initialized = false;
|
|
9
|
+
/**
|
|
10
|
+
* Initialize the Docker-backed session manager.
|
|
11
|
+
* Checks Docker daemon availability before proceeding.
|
|
12
|
+
*/
|
|
13
|
+
export async function initVmManager() {
|
|
14
|
+
if (initialized)
|
|
15
|
+
return getVmManager();
|
|
16
|
+
const available = await isDockerAvailable();
|
|
17
|
+
if (!available) {
|
|
18
|
+
throw new Error("Docker not available. Install Docker Desktop and ensure the daemon is running.");
|
|
19
|
+
}
|
|
20
|
+
vmLog.info("vm-facade", "Using Docker containers for agent execution");
|
|
21
|
+
const sm = initSessionManager();
|
|
22
|
+
initialized = true;
|
|
23
|
+
return sm;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the initialized session manager.
|
|
27
|
+
* Throws if initVmManager() hasn't been called yet.
|
|
28
|
+
*/
|
|
29
|
+
export function getVmManager() {
|
|
30
|
+
if (!initialized) {
|
|
31
|
+
throw new Error("VM manager not initialized — call initVmManager() first");
|
|
32
|
+
}
|
|
33
|
+
return getSessionManager();
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Check if Docker-based agent execution is possible.
|
|
37
|
+
* Always returns true (Docker is expected on all platforms).
|
|
38
|
+
* Actual daemon availability is verified in initVmManager().
|
|
39
|
+
*/
|
|
40
|
+
export function isVmCapable() {
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=vm-manager-facade.js.map
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { ChildProcess } from "node:child_process";
|
|
2
|
+
import type { VmProvider, VmInfo, SessionConfig, SessionFiles, SessionInfo } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* TCP bridge that runs `forge mcp` on the host and exposes it as a TCP server.
|
|
5
|
+
* Each client connection (from the VM via SSH reverse tunnel) gets its own
|
|
6
|
+
* `forge mcp` subprocess with stdio piped through TCP.
|
|
7
|
+
*/
|
|
8
|
+
declare class McpTcpBridge {
|
|
9
|
+
private context;
|
|
10
|
+
private server;
|
|
11
|
+
port: number;
|
|
12
|
+
constructor(context: {
|
|
13
|
+
taskId: string;
|
|
14
|
+
projectId: string;
|
|
15
|
+
orgId: string;
|
|
16
|
+
workflowId?: string;
|
|
17
|
+
stepId?: string;
|
|
18
|
+
});
|
|
19
|
+
start(): Promise<void>;
|
|
20
|
+
stop(): void;
|
|
21
|
+
}
|
|
22
|
+
export declare function getVmManager(): VmManager;
|
|
23
|
+
export declare function initVmManager(provider: VmProvider): VmManager;
|
|
24
|
+
export declare class VmManager {
|
|
25
|
+
private provider;
|
|
26
|
+
private sessions;
|
|
27
|
+
constructor(provider: VmProvider);
|
|
28
|
+
createSession(taskId: string, config: SessionConfig): Promise<string>;
|
|
29
|
+
bootVm(sessionId: string): Promise<VmInfo>;
|
|
30
|
+
cloneRepo(sessionId: string, repoUrl: string | undefined, branch: string | undefined, baseBranch?: string): Promise<void>;
|
|
31
|
+
prepareWorkspace(sessionId: string, files: SessionFiles): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Provision the VM with required tools after boot.
|
|
34
|
+
* Skips if image is pre-baked (claude already installed via build.sh).
|
|
35
|
+
* Fallback installs Node.js + Claude CLI if using a stock Ubuntu image.
|
|
36
|
+
*/
|
|
37
|
+
private provisionVm;
|
|
38
|
+
/**
|
|
39
|
+
* Inject Claude Code credentials into the VM.
|
|
40
|
+
* Supports:
|
|
41
|
+
* - macOS Keychain (Pro/Max subscription via OAuth)
|
|
42
|
+
* - ~/.claude/.credentials.json (Linux/manual setup)
|
|
43
|
+
* - ANTHROPIC_API_KEY env var (API key fallback — handled at spawn time)
|
|
44
|
+
*/
|
|
45
|
+
private injectClaudeCredentials;
|
|
46
|
+
/**
|
|
47
|
+
* Resolve an authenticated clone URL by extracting credentials from the host.
|
|
48
|
+
* Uses `git credential fill` which delegates to the user's credential helper
|
|
49
|
+
* (osxkeychain, wincred, credential-store, GitHub CLI, etc.).
|
|
50
|
+
*
|
|
51
|
+
* For SSH URLs, returns as-is (SSH agent forwarding handles auth).
|
|
52
|
+
* For HTTPS URLs, injects the token into the URL (ephemeral, never persisted in VM).
|
|
53
|
+
*/
|
|
54
|
+
private resolveAuthenticatedUrl;
|
|
55
|
+
spawnAgent(sessionId: string, cmd: string, args: string[], mcpContext?: {
|
|
56
|
+
taskId: string;
|
|
57
|
+
projectId: string;
|
|
58
|
+
orgId: string;
|
|
59
|
+
workflowId?: string;
|
|
60
|
+
stepId?: string;
|
|
61
|
+
}): Promise<{
|
|
62
|
+
pid: number;
|
|
63
|
+
process: ChildProcess;
|
|
64
|
+
mcpBridge?: McpTcpBridge;
|
|
65
|
+
}>;
|
|
66
|
+
stopVm(sessionId: string): Promise<void>;
|
|
67
|
+
destroySession(sessionId: string): Promise<void>;
|
|
68
|
+
getSession(taskId: string): SessionInfo | undefined;
|
|
69
|
+
getAllSessions(): SessionInfo[];
|
|
70
|
+
private findSession;
|
|
71
|
+
private findSessionOptional;
|
|
72
|
+
}
|
|
73
|
+
export {};
|
|
74
|
+
//# sourceMappingURL=vm-manager.d.ts.map
|