patchwork-os 0.2.0-beta.0 → 0.2.0-beta.2
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 +4 -1
- package/deploy/deploy-dashboard.sh +25 -1
- package/deploy/macos/README.md +153 -0
- package/deploy/macos/com.patchwork.bridge.plist.template +54 -0
- package/deploy/macos/com.patchwork.tunnel.plist.template +76 -0
- package/deploy/macos/install-mac-bridge.sh +244 -0
- package/deploy/macos/uninstall-mac-bridge.sh +22 -0
- package/dist/analyticsAggregator.d.ts +5 -1
- package/dist/analyticsAggregator.js +15 -4
- package/dist/analyticsAggregator.js.map +1 -1
- package/dist/analyticsPrefs.d.ts +11 -0
- package/dist/analyticsPrefs.js +33 -0
- package/dist/analyticsPrefs.js.map +1 -1
- package/dist/approvalHttp.d.ts +14 -0
- package/dist/approvalHttp.js +172 -1
- package/dist/approvalHttp.js.map +1 -1
- package/dist/approvalQueue.d.ts +27 -2
- package/dist/approvalQueue.js +44 -7
- package/dist/approvalQueue.js.map +1 -1
- package/dist/automation.d.ts +34 -3
- package/dist/automation.js +85 -10
- package/dist/automation.js.map +1 -1
- package/dist/bridge.js +39 -27
- package/dist/bridge.js.map +1 -1
- package/dist/claudeDriver.d.ts +0 -16
- package/dist/claudeDriver.js +19 -20
- package/dist/claudeDriver.js.map +1 -1
- package/dist/claudeMdPatch.d.ts +9 -3
- package/dist/claudeMdPatch.js +79 -13
- package/dist/claudeMdPatch.js.map +1 -1
- package/dist/claudeOrchestrator.d.ts +12 -0
- package/dist/claudeOrchestrator.js +7 -2
- package/dist/claudeOrchestrator.js.map +1 -1
- package/dist/commands/marketplace.d.ts +15 -10
- package/dist/commands/marketplace.js +27 -115
- package/dist/commands/marketplace.js.map +1 -1
- package/dist/commands/recipe.js +10 -1
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commitIssueLinkLog.d.ts +8 -0
- package/dist/commitIssueLinkLog.js +53 -1
- package/dist/commitIssueLinkLog.js.map +1 -1
- package/dist/config.d.ts +11 -3
- package/dist/config.js +32 -2
- package/dist/config.js.map +1 -1
- package/dist/connectorRoutes.js +63 -372
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/baseConnector.js +25 -3
- package/dist/connectors/baseConnector.js.map +1 -1
- package/dist/connectors/jira.js +18 -1
- package/dist/connectors/jira.js.map +1 -1
- package/dist/drivers/claude/subprocess.d.ts +12 -2
- package/dist/drivers/claude/subprocess.js +79 -6
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/gemini/api.d.ts +18 -0
- package/dist/drivers/gemini/api.js +29 -0
- package/dist/drivers/gemini/api.js.map +1 -0
- package/dist/drivers/gemini/index.d.ts +22 -0
- package/dist/drivers/gemini/index.js +240 -129
- package/dist/drivers/gemini/index.js.map +1 -1
- package/dist/drivers/index.d.ts +3 -1
- package/dist/drivers/index.js +9 -1
- package/dist/drivers/index.js.map +1 -1
- package/dist/drivers/local/index.d.ts +43 -0
- package/dist/drivers/local/index.js +140 -0
- package/dist/drivers/local/index.js.map +1 -0
- package/dist/drivers/openai/index.js +30 -2
- package/dist/drivers/openai/index.js.map +1 -1
- package/dist/extensionClient.d.ts +8 -0
- package/dist/extensionClient.js +24 -2
- package/dist/extensionClient.js.map +1 -1
- package/dist/fp/automationInterpreter.d.ts +9 -1
- package/dist/fp/automationInterpreter.js +151 -34
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/automationProgram.d.ts +30 -0
- package/dist/fp/automationProgram.js.map +1 -1
- package/dist/fp/automationState.d.ts +23 -4
- package/dist/fp/automationState.js +28 -4
- package/dist/fp/automationState.js.map +1 -1
- package/dist/fp/interpreterContext.d.ts +66 -1
- package/dist/fp/interpreterContext.js +140 -1
- package/dist/fp/interpreterContext.js.map +1 -1
- package/dist/fp/policyParser.js +29 -1
- package/dist/fp/policyParser.js.map +1 -1
- package/dist/httpErrorResponse.d.ts +36 -0
- package/dist/httpErrorResponse.js +46 -0
- package/dist/httpErrorResponse.js.map +1 -0
- package/dist/inboxRoutes.js +90 -11
- package/dist/inboxRoutes.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/oauth.d.ts +22 -0
- package/dist/oauth.js +46 -0
- package/dist/oauth.js.map +1 -1
- package/dist/oauthRoutes.js +3 -8
- package/dist/oauthRoutes.js.map +1 -1
- package/dist/patchworkConfig.d.ts +30 -1
- package/dist/patchworkConfig.js +99 -4
- package/dist/patchworkConfig.js.map +1 -1
- package/dist/preToolUseHook.js +7 -1
- package/dist/preToolUseHook.js.map +1 -1
- package/dist/prompts.js +4 -0
- package/dist/prompts.js.map +1 -1
- package/dist/recipeOrchestration.js +13 -3
- package/dist/recipeOrchestration.js.map +1 -1
- package/dist/recipeRoutes.d.ts +5 -0
- package/dist/recipeRoutes.js +57 -33
- package/dist/recipeRoutes.js.map +1 -1
- package/dist/recipes/agentExecutor.d.ts +10 -1
- package/dist/recipes/agentExecutor.js +5 -4
- package/dist/recipes/agentExecutor.js.map +1 -1
- package/dist/recipes/scheduler.d.ts +7 -0
- package/dist/recipes/scheduler.js +30 -13
- package/dist/recipes/scheduler.js.map +1 -1
- package/dist/recipes/schema.d.ts +6 -0
- package/dist/recipes/tools/file.js +5 -2
- package/dist/recipes/tools/file.js.map +1 -1
- package/dist/recipes/tools/gmail.js +18 -1
- package/dist/recipes/tools/gmail.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +32 -2
- package/dist/recipes/yamlRunner.js +71 -6
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/recipesHttp.d.ts +17 -1
- package/dist/recipesHttp.js +68 -4
- package/dist/recipesHttp.js.map +1 -1
- package/dist/server.d.ts +52 -1
- package/dist/server.js +427 -248
- package/dist/server.js.map +1 -1
- package/dist/streamableHttp.d.ts +9 -4
- package/dist/streamableHttp.js +17 -9
- package/dist/streamableHttp.js.map +1 -1
- package/dist/tools/openInBrowser.js +6 -1
- package/dist/tools/openInBrowser.js.map +1 -1
- package/dist/tools/runCommand.js +5 -0
- package/dist/tools/runCommand.js.map +1 -1
- package/dist/tools/terminal.js +4 -0
- package/dist/tools/terminal.js.map +1 -1
- package/dist/tools/utils.d.ts +4 -0
- package/dist/tools/utils.js +62 -0
- package/dist/tools/utils.js.map +1 -1
- package/package.json +2 -2
- package/scripts/start-all.sh +4 -2
- package/templates/recipes/approval-queue-ui-test.yaml +205 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Gemini API driver — Google exposes an OpenAI-compatible chat-completions
|
|
4
|
+
* endpoint at https://generativelanguage.googleapis.com/v1beta/openai/, so
|
|
5
|
+
* the existing OpenAIApiDriver streaming + tool-handling can be reused with
|
|
6
|
+
* just a different baseURL + default model + key source. Same trick as Grok.
|
|
7
|
+
*
|
|
8
|
+
* Auth: GEMINI_API_KEY environment variable (the bridge auto-injects the
|
|
9
|
+
* dashboard-saved `apiKeys.google` value into GEMINI_API_KEY at startup —
|
|
10
|
+
* see config.ts:487).
|
|
11
|
+
*
|
|
12
|
+
* Install: npm install openai (reuses OpenAI SDK with custom baseURL)
|
|
13
|
+
*/
|
|
14
|
+
export declare class GeminiApiDriver extends OpenAIApiDriver {
|
|
15
|
+
readonly name = "gemini-api";
|
|
16
|
+
constructor(log: (msg: string) => void);
|
|
17
|
+
protected apiKey(): string | undefined;
|
|
18
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Gemini API driver — Google exposes an OpenAI-compatible chat-completions
|
|
4
|
+
* endpoint at https://generativelanguage.googleapis.com/v1beta/openai/, so
|
|
5
|
+
* the existing OpenAIApiDriver streaming + tool-handling can be reused with
|
|
6
|
+
* just a different baseURL + default model + key source. Same trick as Grok.
|
|
7
|
+
*
|
|
8
|
+
* Auth: GEMINI_API_KEY environment variable (the bridge auto-injects the
|
|
9
|
+
* dashboard-saved `apiKeys.google` value into GEMINI_API_KEY at startup —
|
|
10
|
+
* see config.ts:487).
|
|
11
|
+
*
|
|
12
|
+
* Install: npm install openai (reuses OpenAI SDK with custom baseURL)
|
|
13
|
+
*/
|
|
14
|
+
export class GeminiApiDriver extends OpenAIApiDriver {
|
|
15
|
+
name = "gemini-api";
|
|
16
|
+
constructor(log) {
|
|
17
|
+
if (!process.env.GEMINI_API_KEY) {
|
|
18
|
+
throw new Error("GeminiApiDriver requires GEMINI_API_KEY environment variable");
|
|
19
|
+
}
|
|
20
|
+
super(log, {
|
|
21
|
+
baseURL: "https://generativelanguage.googleapis.com/v1beta/openai/",
|
|
22
|
+
defaultModel: "gemini-2.5-pro",
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
apiKey() {
|
|
26
|
+
return process.env.GEMINI_API_KEY;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/drivers/gemini/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,eAAgB,SAAQ,eAAe;IAChC,IAAI,GAAG,YAAY,CAAC;IAEtC,YAAY,GAA0B;QACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,8DAA8D,CAC/D,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,GAAG,EAAE;YACT,OAAO,EAAE,0DAA0D;YACnE,YAAY,EAAE,gBAAgB;SAC/B,CAAC,CAAC;IACL,CAAC;IAEkB,MAAM;QACvB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACpC,CAAC;CACF"}
|
|
@@ -9,10 +9,32 @@ export declare class GeminiSubprocessDriver implements ProviderDriver {
|
|
|
9
9
|
private readonly log;
|
|
10
10
|
private readonly bridgeMcp?;
|
|
11
11
|
readonly name = "gemini";
|
|
12
|
+
/**
|
|
13
|
+
* Process-wide serialization for `~/.gemini/settings.json` mutation. Two
|
|
14
|
+
* concurrent `run()` invocations would otherwise race:
|
|
15
|
+
*
|
|
16
|
+
* A reads file (originalContent = X)
|
|
17
|
+
* A writes A's-token
|
|
18
|
+
* B reads file (originalContent = A's-token) ← B captures wrong baseline
|
|
19
|
+
* B writes B's-token
|
|
20
|
+
* A's child starts, reads settings — sees B's-token (uses wrong creds)
|
|
21
|
+
* A finishes, restores to X (wipes B's token mid-flight)
|
|
22
|
+
* B's child reads settings — sees X (no MCP config)
|
|
23
|
+
* B finishes, restores to A's-token (token leaks past run)
|
|
24
|
+
*
|
|
25
|
+
* The settings file is global to ~/.gemini/, so per-call isolation requires
|
|
26
|
+
* either Gemini-CLI's `--settings <path>` (not universal across versions)
|
|
27
|
+
* or a strict mutex across the whole run() lifetime. We take the mutex
|
|
28
|
+
* approach — Gemini subprocess runs are slow (seconds-to-minutes) and the
|
|
29
|
+
* operator-driven concurrency level is already low, so the throughput
|
|
30
|
+
* cost is acceptable for cross-version correctness.
|
|
31
|
+
*/
|
|
32
|
+
private static settingsMutex;
|
|
12
33
|
constructor(binary: string, log: (msg: string) => void, bridgeMcp?: (() => {
|
|
13
34
|
url: string;
|
|
14
35
|
authToken: string;
|
|
15
36
|
} | undefined) | undefined);
|
|
16
37
|
run(input: ProviderTaskInput): Promise<ProviderTaskResult>;
|
|
38
|
+
private _runLocked;
|
|
17
39
|
runOutcome(input: ProviderTaskInput): Promise<import("../types.js").ProviderTaskOutcome>;
|
|
18
40
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
-
import { chmodSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { chmodSync, existsSync, readFileSync, unlinkSync, writeFileSync, } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { isAbsolute, join, resolve } from "node:path";
|
|
5
5
|
import { sanitizeEnv } from "../claude/envSanitizer.js";
|
|
@@ -21,27 +21,99 @@ export class GeminiSubprocessDriver {
|
|
|
21
21
|
log;
|
|
22
22
|
bridgeMcp;
|
|
23
23
|
name = "gemini";
|
|
24
|
+
/**
|
|
25
|
+
* Process-wide serialization for `~/.gemini/settings.json` mutation. Two
|
|
26
|
+
* concurrent `run()` invocations would otherwise race:
|
|
27
|
+
*
|
|
28
|
+
* A reads file (originalContent = X)
|
|
29
|
+
* A writes A's-token
|
|
30
|
+
* B reads file (originalContent = A's-token) ← B captures wrong baseline
|
|
31
|
+
* B writes B's-token
|
|
32
|
+
* A's child starts, reads settings — sees B's-token (uses wrong creds)
|
|
33
|
+
* A finishes, restores to X (wipes B's token mid-flight)
|
|
34
|
+
* B's child reads settings — sees X (no MCP config)
|
|
35
|
+
* B finishes, restores to A's-token (token leaks past run)
|
|
36
|
+
*
|
|
37
|
+
* The settings file is global to ~/.gemini/, so per-call isolation requires
|
|
38
|
+
* either Gemini-CLI's `--settings <path>` (not universal across versions)
|
|
39
|
+
* or a strict mutex across the whole run() lifetime. We take the mutex
|
|
40
|
+
* approach — Gemini subprocess runs are slow (seconds-to-minutes) and the
|
|
41
|
+
* operator-driven concurrency level is already low, so the throughput
|
|
42
|
+
* cost is acceptable for cross-version correctness.
|
|
43
|
+
*/
|
|
44
|
+
static settingsMutex = Promise.resolve();
|
|
24
45
|
constructor(binary, log, bridgeMcp) {
|
|
25
46
|
this.binary = binary;
|
|
26
47
|
this.log = log;
|
|
27
48
|
this.bridgeMcp = bridgeMcp;
|
|
28
49
|
}
|
|
29
50
|
async run(input) {
|
|
51
|
+
// Resolve bridgeMcp ONCE per run() and pass the result down. The
|
|
52
|
+
// closure may be cheap today, but calling it twice (once at the lock
|
|
53
|
+
// gate, once inside _runLocked) opens a TOCTOU window: if the value
|
|
54
|
+
// ever flips falsy→truthy between the two calls, the gate skips the
|
|
55
|
+
// mutex but _runLocked writes settings.json without a lock.
|
|
56
|
+
const mcp = this.bridgeMcp?.();
|
|
57
|
+
if (mcp) {
|
|
58
|
+
// If we're going to mutate ~/.gemini/settings.json, wait for any prior
|
|
59
|
+
// Gemini run holding the same file to finish first.
|
|
60
|
+
const prior = GeminiSubprocessDriver.settingsMutex;
|
|
61
|
+
let releaseLock;
|
|
62
|
+
const ourLock = new Promise((resolve) => {
|
|
63
|
+
releaseLock = resolve;
|
|
64
|
+
});
|
|
65
|
+
GeminiSubprocessDriver.settingsMutex = ourLock;
|
|
66
|
+
try {
|
|
67
|
+
await prior;
|
|
68
|
+
return await this._runLocked(input, mcp);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
releaseLock();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// No mcp injection → no settings file write → no mutex needed.
|
|
75
|
+
return this._runLocked(input, undefined);
|
|
76
|
+
}
|
|
77
|
+
async _runLocked(input, mcp) {
|
|
30
78
|
const opts = input.providerOptions ?? {};
|
|
31
79
|
const approvalMode = typeof opts.approvalMode === "string" ? opts.approvalMode : "yolo";
|
|
32
80
|
// Inject bridge MCP into ~/.gemini/settings.json before spawning so the
|
|
33
|
-
// subprocess can call bridge tools. Gemini CLI reads settings.json at
|
|
34
|
-
|
|
81
|
+
// subprocess can call bridge tools. Gemini CLI reads settings.json at
|
|
82
|
+
// startup. We snapshot whatever was there before (or remember "absent")
|
|
83
|
+
// and restore it in a finally block at the end of run() — the bearer
|
|
84
|
+
// token must NOT outlive this single invocation in a shared-home file.
|
|
85
|
+
//
|
|
86
|
+
// URL is rewritten to 127.0.0.1:<port> for the spawned subprocess: the
|
|
87
|
+
// bridge may be bound 0.0.0.0 with a public --issuer-url, but the local
|
|
88
|
+
// child should always dial loopback so neither the URL nor the token
|
|
89
|
+
// ever leave this machine.
|
|
90
|
+
let settingsCleanup = null;
|
|
35
91
|
if (mcp) {
|
|
36
92
|
const settingsFile = join(homedir(), ".gemini", "settings.json");
|
|
37
93
|
try {
|
|
94
|
+
let originalContent = null;
|
|
38
95
|
let settings = {};
|
|
39
96
|
if (existsSync(settingsFile)) {
|
|
40
|
-
|
|
97
|
+
originalContent = readFileSync(settingsFile, "utf-8");
|
|
98
|
+
settings = JSON.parse(originalContent);
|
|
41
99
|
}
|
|
42
100
|
const mcpServers = (settings.mcpServers ?? {});
|
|
101
|
+
const previousBridgeEntry = Object.hasOwn(mcpServers, "claude-ide-bridge")
|
|
102
|
+
? mcpServers["claude-ide-bridge"]
|
|
103
|
+
: undefined;
|
|
104
|
+
const localUrl = (() => {
|
|
105
|
+
try {
|
|
106
|
+
const u = new URL(mcp.url);
|
|
107
|
+
// Force loopback — keeps token off the wire even if bridge bound 0.0.0.0
|
|
108
|
+
u.hostname = "127.0.0.1";
|
|
109
|
+
return u.toString();
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return mcp.url;
|
|
113
|
+
}
|
|
114
|
+
})();
|
|
43
115
|
mcpServers["claude-ide-bridge"] = {
|
|
44
|
-
url:
|
|
116
|
+
url: localUrl,
|
|
45
117
|
headers: { Authorization: `Bearer ${mcp.authToken}` },
|
|
46
118
|
};
|
|
47
119
|
settings.mcpServers = mcpServers;
|
|
@@ -49,159 +121,198 @@ export class GeminiSubprocessDriver {
|
|
|
49
121
|
mode: 0o600,
|
|
50
122
|
});
|
|
51
123
|
chmodSync(settingsFile, 0o600);
|
|
124
|
+
// Schedule restoration. If the original file existed, write back its
|
|
125
|
+
// exact bytes; if the bridge entry was absent, remove the key. If the
|
|
126
|
+
// file did not exist before, delete it. Best-effort; logged on failure.
|
|
127
|
+
settingsCleanup = () => {
|
|
128
|
+
try {
|
|
129
|
+
if (originalContent === null) {
|
|
130
|
+
// File was created by us — try to remove. Tolerate ENOENT.
|
|
131
|
+
try {
|
|
132
|
+
unlinkSync(settingsFile);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
/* ignore */
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const parsed = JSON.parse(originalContent);
|
|
140
|
+
if (previousBridgeEntry === undefined) {
|
|
141
|
+
const restoredServers = (parsed.mcpServers ?? {});
|
|
142
|
+
if (Object.hasOwn(restoredServers, "claude-ide-bridge")) {
|
|
143
|
+
delete restoredServers["claude-ide-bridge"];
|
|
144
|
+
}
|
|
145
|
+
parsed.mcpServers = restoredServers;
|
|
146
|
+
}
|
|
147
|
+
writeFileSync(settingsFile, JSON.stringify(parsed, null, 2), {
|
|
148
|
+
mode: 0o600,
|
|
149
|
+
});
|
|
150
|
+
chmodSync(settingsFile, 0o600);
|
|
151
|
+
}
|
|
152
|
+
catch (err) {
|
|
153
|
+
this.log(`[GeminiSubprocessDriver] WARN: could not restore ~/.gemini/settings.json: ${err instanceof Error ? err.message : String(err)}`);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
52
156
|
}
|
|
53
157
|
catch (err) {
|
|
54
158
|
this.log(`[GeminiSubprocessDriver] WARN: could not update ~/.gemini/settings.json: ${err instanceof Error ? err.message : String(err)}`);
|
|
55
159
|
}
|
|
56
160
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
// Strip MCP_* and CLAUDECODE vars; preserve GEMINI_API_KEY + GOOGLE_* vars
|
|
75
|
-
const env = sanitizeEnv(process.env);
|
|
76
|
-
// Also strip Claude-specific auth vars that could confuse Gemini
|
|
77
|
-
for (const key of Object.keys(env)) {
|
|
78
|
-
if (key.startsWith("ANTHROPIC_") || key === "CLAUDE_API_KEY") {
|
|
79
|
-
delete env[key];
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
this.log(`[GeminiSubprocessDriver] spawning: ${this.binary} -p <prompt> (workspace: ${input.workspace})`);
|
|
83
|
-
const child = spawn(this.binary, args, {
|
|
84
|
-
cwd: homedir(),
|
|
85
|
-
env,
|
|
86
|
-
signal: input.signal,
|
|
87
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
88
|
-
});
|
|
89
|
-
// unref() so the bridge can exit without waiting for the subprocess,
|
|
90
|
-
// but keep detached=false so the subprocess dies cleanly with the bridge
|
|
91
|
-
// rather than getting SIGPIPE when the pipe closes mid-run.
|
|
92
|
-
child.unref();
|
|
93
|
-
let lineBuf = "";
|
|
94
|
-
let accumulated = "";
|
|
95
|
-
let outputBytesSent = 0;
|
|
96
|
-
let firstAssistantAt;
|
|
97
|
-
let doneFromResult = false;
|
|
98
|
-
let resultSuccess = true;
|
|
99
|
-
child.stdout.setEncoding("utf-8");
|
|
100
|
-
child.stdout.on("data", (chunk) => {
|
|
101
|
-
const { lines, remainder } = splitLines(lineBuf, chunk);
|
|
102
|
-
lineBuf = remainder;
|
|
103
|
-
for (const line of lines) {
|
|
104
|
-
if (line.trim() === "")
|
|
105
|
-
continue;
|
|
106
|
-
let event;
|
|
107
|
-
try {
|
|
108
|
-
event = JSON.parse(line);
|
|
161
|
+
try {
|
|
162
|
+
const args = [
|
|
163
|
+
"-p",
|
|
164
|
+
input.prompt,
|
|
165
|
+
"--output-format",
|
|
166
|
+
"stream-json",
|
|
167
|
+
"--approval-mode",
|
|
168
|
+
approvalMode,
|
|
169
|
+
];
|
|
170
|
+
if (input.model)
|
|
171
|
+
args.push("-m", input.model);
|
|
172
|
+
// contextFiles: pass as --include-directories; normalize relative paths against workspace
|
|
173
|
+
for (const f of input.contextFiles ?? []) {
|
|
174
|
+
if (typeof f === "string" && f.length > 0 && !f.startsWith("-")) {
|
|
175
|
+
const abs = isAbsolute(f) ? f : resolve(input.workspace, f);
|
|
176
|
+
args.push("--include-directories", abs);
|
|
109
177
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
178
|
+
}
|
|
179
|
+
// Strip MCP_* and CLAUDECODE vars; preserve GEMINI_API_KEY + GOOGLE_* vars
|
|
180
|
+
const env = sanitizeEnv(process.env);
|
|
181
|
+
// Also strip Claude-specific auth vars that could confuse Gemini
|
|
182
|
+
for (const key of Object.keys(env)) {
|
|
183
|
+
if (key.startsWith("ANTHROPIC_") || key === "CLAUDE_API_KEY") {
|
|
184
|
+
delete env[key];
|
|
113
185
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
186
|
+
}
|
|
187
|
+
this.log(`[GeminiSubprocessDriver] spawning: ${this.binary} -p <prompt> (workspace: ${input.workspace})`);
|
|
188
|
+
const child = spawn(this.binary, args, {
|
|
189
|
+
cwd: homedir(),
|
|
190
|
+
env,
|
|
191
|
+
signal: input.signal,
|
|
192
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
193
|
+
});
|
|
194
|
+
// unref() so the bridge can exit without waiting for the subprocess,
|
|
195
|
+
// but keep detached=false so the subprocess dies cleanly with the bridge
|
|
196
|
+
// rather than getting SIGPIPE when the pipe closes mid-run.
|
|
197
|
+
child.unref();
|
|
198
|
+
let lineBuf = "";
|
|
199
|
+
let accumulated = "";
|
|
200
|
+
let outputBytesSent = 0;
|
|
201
|
+
let firstAssistantAt;
|
|
202
|
+
let doneFromResult = false;
|
|
203
|
+
let resultSuccess = true;
|
|
204
|
+
child.stdout.setEncoding("utf-8");
|
|
205
|
+
child.stdout.on("data", (chunk) => {
|
|
206
|
+
const { lines, remainder } = splitLines(lineBuf, chunk);
|
|
207
|
+
lineBuf = remainder;
|
|
208
|
+
for (const line of lines) {
|
|
209
|
+
if (line.trim() === "")
|
|
210
|
+
continue;
|
|
211
|
+
let event;
|
|
212
|
+
try {
|
|
213
|
+
event = JSON.parse(line);
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
// Non-JSON stderr/warning lines — skip (Gemini prints "YOLO mode..." to stdout)
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
if (event.type === "message" &&
|
|
220
|
+
event.role === "assistant" &&
|
|
221
|
+
event.content) {
|
|
222
|
+
if (firstAssistantAt === undefined)
|
|
223
|
+
firstAssistantAt = Date.now();
|
|
224
|
+
const text = event.content;
|
|
225
|
+
accumulated += text;
|
|
226
|
+
if (outputBytesSent < OUTPUT_CAP) {
|
|
227
|
+
const send = text.slice(0, OUTPUT_CAP - outputBytesSent);
|
|
228
|
+
if (send.length > 0) {
|
|
229
|
+
input.onChunk?.(send);
|
|
230
|
+
outputBytesSent += send.length;
|
|
231
|
+
}
|
|
126
232
|
}
|
|
127
233
|
}
|
|
234
|
+
else if (event.type === "result") {
|
|
235
|
+
doneFromResult = true;
|
|
236
|
+
resultSuccess = event.status === "success";
|
|
237
|
+
}
|
|
128
238
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
239
|
+
});
|
|
240
|
+
let stderr = "";
|
|
241
|
+
child.stderr.setEncoding("utf-8");
|
|
242
|
+
child.stderr.on("data", (chunk) => {
|
|
243
|
+
if (stderr.length < OUTPUT_CAP) {
|
|
244
|
+
stderr += chunk;
|
|
245
|
+
if (stderr.length > OUTPUT_CAP)
|
|
246
|
+
stderr = stderr.slice(0, OUTPUT_CAP);
|
|
132
247
|
}
|
|
248
|
+
});
|
|
249
|
+
const start = Date.now();
|
|
250
|
+
const stderrTailOf = (s) => s.length > 0 ? scrubSecrets(s.slice(-2048)) : undefined;
|
|
251
|
+
const startupMsOf = () => firstAssistantAt !== undefined ? firstAssistantAt - start : undefined;
|
|
252
|
+
let startupTimedOut = false;
|
|
253
|
+
const startupHandle = input.startupTimeoutMs
|
|
254
|
+
? setTimeout(() => {
|
|
255
|
+
if (firstAssistantAt === undefined && !doneFromResult) {
|
|
256
|
+
startupTimedOut = true;
|
|
257
|
+
child.kill();
|
|
258
|
+
}
|
|
259
|
+
}, input.startupTimeoutMs)
|
|
260
|
+
: null;
|
|
261
|
+
let exitCode;
|
|
262
|
+
try {
|
|
263
|
+
exitCode = await new Promise((resolve, reject) => {
|
|
264
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
265
|
+
child.on("error", reject);
|
|
266
|
+
});
|
|
133
267
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
let startupTimedOut = false;
|
|
148
|
-
const startupHandle = input.startupTimeoutMs
|
|
149
|
-
? setTimeout(() => {
|
|
150
|
-
if (firstAssistantAt === undefined && !doneFromResult) {
|
|
151
|
-
startupTimedOut = true;
|
|
152
|
-
child.kill();
|
|
268
|
+
catch (err) {
|
|
269
|
+
if (startupHandle)
|
|
270
|
+
clearTimeout(startupHandle);
|
|
271
|
+
const isAbort = (err instanceof Error && err.name === "AbortError") ||
|
|
272
|
+
input.signal.aborted;
|
|
273
|
+
if (isAbort) {
|
|
274
|
+
return {
|
|
275
|
+
text: accumulated.slice(0, OUTPUT_CAP),
|
|
276
|
+
durationMs: Date.now() - start,
|
|
277
|
+
wasAborted: true,
|
|
278
|
+
startupMs: startupMsOf(),
|
|
279
|
+
stderrTail: stderrTailOf(stderr),
|
|
280
|
+
};
|
|
153
281
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
let exitCode;
|
|
157
|
-
try {
|
|
158
|
-
exitCode = await new Promise((resolve, reject) => {
|
|
159
|
-
child.on("close", (code) => resolve(code ?? 0));
|
|
160
|
-
child.on("error", reject);
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
catch (err) {
|
|
282
|
+
throw err;
|
|
283
|
+
}
|
|
164
284
|
if (startupHandle)
|
|
165
285
|
clearTimeout(startupHandle);
|
|
166
|
-
|
|
167
|
-
input.signal.aborted;
|
|
168
|
-
if (isAbort) {
|
|
286
|
+
if (startupTimedOut) {
|
|
169
287
|
return {
|
|
170
288
|
text: accumulated.slice(0, OUTPUT_CAP),
|
|
171
289
|
durationMs: Date.now() - start,
|
|
172
290
|
wasAborted: true,
|
|
173
|
-
|
|
291
|
+
startupTimedOut: true,
|
|
174
292
|
stderrTail: stderrTailOf(stderr),
|
|
175
293
|
};
|
|
176
294
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
295
|
+
const effectiveExitCode = doneFromResult
|
|
296
|
+
? resultSuccess
|
|
297
|
+
? 0
|
|
298
|
+
: 1
|
|
299
|
+
: exitCode;
|
|
300
|
+
if (effectiveExitCode !== 0 && stderr) {
|
|
301
|
+
this.log(`[GeminiSubprocessDriver] stderr: ${stderr.slice(0, 500)}`);
|
|
302
|
+
}
|
|
182
303
|
return {
|
|
183
304
|
text: accumulated.slice(0, OUTPUT_CAP),
|
|
305
|
+
exitCode: effectiveExitCode,
|
|
184
306
|
durationMs: Date.now() - start,
|
|
185
|
-
wasAborted: true,
|
|
186
|
-
startupTimedOut: true,
|
|
187
307
|
stderrTail: stderrTailOf(stderr),
|
|
308
|
+
startupMs: startupMsOf(),
|
|
188
309
|
};
|
|
189
310
|
}
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
: exitCode;
|
|
195
|
-
if (effectiveExitCode !== 0 && stderr) {
|
|
196
|
-
this.log(`[GeminiSubprocessDriver] stderr: ${stderr.slice(0, 500)}`);
|
|
311
|
+
finally {
|
|
312
|
+
// Always restore ~/.gemini/settings.json — bridge bearer token must
|
|
313
|
+
// not survive in this shared-home file past one invocation.
|
|
314
|
+
settingsCleanup?.();
|
|
197
315
|
}
|
|
198
|
-
return {
|
|
199
|
-
text: accumulated.slice(0, OUTPUT_CAP),
|
|
200
|
-
exitCode: effectiveExitCode,
|
|
201
|
-
durationMs: Date.now() - start,
|
|
202
|
-
stderrTail: stderrTailOf(stderr),
|
|
203
|
-
startupMs: startupMsOf(),
|
|
204
|
-
};
|
|
205
316
|
}
|
|
206
317
|
async runOutcome(input) {
|
|
207
318
|
return toProviderTaskOutcome(await this.run(input));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/gemini/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/gemini/index.ts"],"names":[],"mappings":"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"}
|
package/dist/drivers/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ProviderDriver } from "./types.js";
|
|
2
|
-
export type DriverMode = "subprocess" | "api" | "openai" | "grok" | "gemini" | "none";
|
|
2
|
+
export type DriverMode = "subprocess" | "api" | "openai" | "grok" | "gemini" | "gemini-api" | "local" | "none";
|
|
3
3
|
export interface DriverFactoryOpts {
|
|
4
4
|
binary: string;
|
|
5
5
|
antBinary: string;
|
|
@@ -16,8 +16,10 @@ export interface DriverFactoryOpts {
|
|
|
16
16
|
export declare function createDriver(mode: DriverMode, opts: DriverFactoryOpts, log: (msg: string) => void): ProviderDriver | null;
|
|
17
17
|
export { ApiDriver } from "./claude/api.js";
|
|
18
18
|
export { SubprocessDriver } from "./claude/subprocess.js";
|
|
19
|
+
export { GeminiApiDriver } from "./gemini/api.js";
|
|
19
20
|
export { GeminiSubprocessDriver } from "./gemini/index.js";
|
|
20
21
|
export { GrokApiDriver } from "./grok/index.js";
|
|
22
|
+
export { LocalApiDriver } from "./local/index.js";
|
|
21
23
|
export { OpenAIApiDriver } from "./openai/index.js";
|
|
22
24
|
export type { ProviderDriver, ProviderTaskInput, ProviderTaskOutcome, ProviderTaskResult, } from "./types.js";
|
|
23
25
|
export { toProviderTaskOutcome } from "./types.js";
|
package/dist/drivers/index.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { ApiDriver } from "./claude/api.js";
|
|
2
2
|
import { SubprocessDriver } from "./claude/subprocess.js";
|
|
3
|
+
import { GeminiApiDriver } from "./gemini/api.js";
|
|
3
4
|
import { GeminiSubprocessDriver } from "./gemini/index.js";
|
|
4
5
|
import { GrokApiDriver } from "./grok/index.js";
|
|
6
|
+
import { LocalApiDriver } from "./local/index.js";
|
|
5
7
|
import { OpenAIApiDriver } from "./openai/index.js";
|
|
6
8
|
/**
|
|
7
9
|
* Create the appropriate driver from a mode string.
|
|
@@ -11,7 +13,7 @@ export function createDriver(mode, opts, log) {
|
|
|
11
13
|
if (mode === "none")
|
|
12
14
|
return null;
|
|
13
15
|
if (mode === "subprocess")
|
|
14
|
-
return new SubprocessDriver(opts.binary, opts.antBinary, log);
|
|
16
|
+
return new SubprocessDriver(opts.binary, opts.antBinary, log, opts.bridgeMcp);
|
|
15
17
|
if (mode === "api")
|
|
16
18
|
return new ApiDriver(log);
|
|
17
19
|
if (mode === "openai")
|
|
@@ -20,12 +22,18 @@ export function createDriver(mode, opts, log) {
|
|
|
20
22
|
return new GrokApiDriver(log);
|
|
21
23
|
if (mode === "gemini")
|
|
22
24
|
return new GeminiSubprocessDriver(opts.binary === "claude" ? "gemini" : opts.binary, log, opts.bridgeMcp);
|
|
25
|
+
if (mode === "gemini-api")
|
|
26
|
+
return new GeminiApiDriver(log);
|
|
27
|
+
if (mode === "local")
|
|
28
|
+
return new LocalApiDriver(log);
|
|
23
29
|
throw new Error(`Unknown driver mode: ${mode}`);
|
|
24
30
|
}
|
|
25
31
|
export { ApiDriver } from "./claude/api.js";
|
|
26
32
|
export { SubprocessDriver } from "./claude/subprocess.js";
|
|
33
|
+
export { GeminiApiDriver } from "./gemini/api.js";
|
|
27
34
|
export { GeminiSubprocessDriver } from "./gemini/index.js";
|
|
28
35
|
export { GrokApiDriver } from "./grok/index.js";
|
|
36
|
+
export { LocalApiDriver } from "./local/index.js";
|
|
29
37
|
export { OpenAIApiDriver } from "./openai/index.js";
|
|
30
38
|
export { toProviderTaskOutcome } from "./types.js";
|
|
31
39
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drivers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/drivers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAoBpD;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAgB,EAChB,IAAuB,EACvB,GAA0B;IAE1B,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,IAAI,KAAK,YAAY;QACvB,OAAO,IAAI,gBAAgB,CACzB,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,SAAS,EACd,GAAG,EACH,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;IAC9C,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IACvD,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,IAAI,KAAK,QAAQ;QACnB,OAAO,IAAI,sBAAsB,CAC/B,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,EACjD,GAAG,EACH,IAAI,CAAC,SAAS,CACf,CAAC;IACJ,IAAI,IAAI,KAAK,YAAY;QAAE,OAAO,IAAI,eAAe,CAAC,GAAG,CAAC,CAAC;IAC3D,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC;IACrD,MAAM,IAAI,KAAK,CAAC,wBAAwB,IAAI,EAAE,CAAC,CAAC;AAClD,CAAC;AAED,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
|