patchwork-os 0.2.0-alpha.2 → 0.2.0-alpha.3
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/dist/claudeDriver.d.ts +3 -1
- package/dist/claudeDriver.js +48 -0
- package/dist/claudeDriver.js.map +1 -1
- package/dist/config.d.ts +2 -2
- package/dist/config.js +5 -2
- package/dist/config.js.map +1 -1
- package/dist/connectors/gmail.js +14 -0
- package/dist/connectors/gmail.js.map +1 -1
- package/dist/connectors/linear.d.ts +67 -0
- package/dist/connectors/linear.js +198 -0
- package/dist/connectors/linear.js.map +1 -0
- package/dist/connectors/sentry.d.ts +47 -0
- package/dist/connectors/sentry.js +204 -0
- package/dist/connectors/sentry.js.map +1 -0
- package/dist/drivers/claude/api.d.ts +11 -0
- package/dist/drivers/claude/api.js +54 -0
- package/dist/drivers/claude/api.js.map +1 -0
- package/dist/drivers/claude/envSanitizer.d.ts +7 -0
- package/dist/drivers/claude/envSanitizer.js +18 -0
- package/dist/drivers/claude/envSanitizer.js.map +1 -0
- package/dist/drivers/claude/streamParser.d.ts +38 -0
- package/dist/drivers/claude/streamParser.js +34 -0
- package/dist/drivers/claude/streamParser.js.map +1 -0
- package/dist/drivers/claude/subprocess.d.ts +19 -0
- package/dist/drivers/claude/subprocess.js +216 -0
- package/dist/drivers/claude/subprocess.js.map +1 -0
- package/dist/drivers/claude/subprocessSettings.d.ts +9 -0
- package/dist/drivers/claude/subprocessSettings.js +55 -0
- package/dist/drivers/claude/subprocessSettings.js.map +1 -0
- package/dist/drivers/gemini/index.d.ts +14 -0
- package/dist/drivers/gemini/index.js +176 -0
- package/dist/drivers/gemini/index.js.map +1 -0
- package/dist/drivers/grok/index.d.ts +11 -0
- package/dist/drivers/grok/index.js +22 -0
- package/dist/drivers/grok/index.js.map +1 -0
- package/dist/drivers/index.d.ts +18 -0
- package/dist/drivers/index.js +31 -0
- package/dist/drivers/index.js.map +1 -0
- package/dist/drivers/openai/index.d.ts +24 -0
- package/dist/drivers/openai/index.js +110 -0
- package/dist/drivers/openai/index.js.map +1 -0
- package/dist/drivers/types.d.ts +72 -0
- package/dist/drivers/types.js +30 -0
- package/dist/drivers/types.js.map +1 -0
- package/dist/recipes/yamlRunner.js +65 -0
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/server.js +92 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/ctxGetTaskContext.d.ts +4 -1
- package/dist/tools/ctxGetTaskContext.js +45 -2
- package/dist/tools/ctxGetTaskContext.js.map +1 -1
- package/dist/tools/fetchLinearIssue.d.ts +112 -0
- package/dist/tools/fetchLinearIssue.js +129 -0
- package/dist/tools/fetchLinearIssue.js.map +1 -0
- package/dist/tools/fetchSentryIssue.d.ts +143 -0
- package/dist/tools/fetchSentryIssue.js +150 -0
- package/dist/tools/fetchSentryIssue.js.map +1 -0
- package/dist/tools/index.js +4 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +2 -2
- package/templates/recipes/morning-brief.yaml +9 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { toProviderTaskOutcome } from "../types.js";
|
|
3
|
+
import { sanitizeEnv } from "./envSanitizer.js";
|
|
4
|
+
import { parseStreamLine, splitLines } from "./streamParser.js";
|
|
5
|
+
import { createSubprocessSettings } from "./subprocessSettings.js";
|
|
6
|
+
const OUTPUT_CAP = 50 * 1024; // 50KB
|
|
7
|
+
/**
|
|
8
|
+
* Scrub secrets from a string before storing or surfacing it.
|
|
9
|
+
*/
|
|
10
|
+
export function scrubSecrets(text) {
|
|
11
|
+
return text
|
|
12
|
+
.replace(/sk-ant-[A-Za-z0-9_-]{20,}/g, "[REDACTED_API_KEY]")
|
|
13
|
+
.replace(/Bearer\s+[A-Za-z0-9._-]{16,}/gi, "Bearer [REDACTED]")
|
|
14
|
+
.replace(/\btoken[=:]\s*[A-Za-z0-9._-]{16,}/gi, "token=[REDACTED]");
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Claude subprocess driver — spawns `claude -p` with stream-json output.
|
|
18
|
+
* Claude-specific providerOptions: { effort, fallbackModel, maxBudgetUsd, useAnt }
|
|
19
|
+
*/
|
|
20
|
+
export class SubprocessDriver {
|
|
21
|
+
binary;
|
|
22
|
+
antBinary;
|
|
23
|
+
log;
|
|
24
|
+
name = "subprocess";
|
|
25
|
+
settings;
|
|
26
|
+
constructor(binary, antBinary, log) {
|
|
27
|
+
this.binary = binary;
|
|
28
|
+
this.antBinary = antBinary;
|
|
29
|
+
this.log = log;
|
|
30
|
+
this.settings = createSubprocessSettings(log);
|
|
31
|
+
this.settings.write();
|
|
32
|
+
}
|
|
33
|
+
async run(input) {
|
|
34
|
+
const opts = input.providerOptions ?? {};
|
|
35
|
+
const useAnt = opts.useAnt === true;
|
|
36
|
+
const effort = typeof opts.effort === "string" ? opts.effort : undefined;
|
|
37
|
+
const fallbackModel = typeof opts.fallbackModel === "string" ? opts.fallbackModel : undefined;
|
|
38
|
+
const maxBudgetUsd = typeof opts.maxBudgetUsd === "number" ? opts.maxBudgetUsd : undefined;
|
|
39
|
+
const effectiveBinary = useAnt ? this.antBinary : this.binary;
|
|
40
|
+
// Re-write before each run — /tmp may be cleared on long-running servers.
|
|
41
|
+
this.settings.write();
|
|
42
|
+
const args = [
|
|
43
|
+
"-p",
|
|
44
|
+
input.prompt,
|
|
45
|
+
"--strict-mcp-config",
|
|
46
|
+
"--settings",
|
|
47
|
+
this.settings.path,
|
|
48
|
+
"--output-format",
|
|
49
|
+
"stream-json",
|
|
50
|
+
"--verbose",
|
|
51
|
+
"--include-partial-messages",
|
|
52
|
+
"--no-session-persistence",
|
|
53
|
+
];
|
|
54
|
+
if (input.model)
|
|
55
|
+
args.push("--model", input.model);
|
|
56
|
+
if (effort)
|
|
57
|
+
args.push("--effort", effort);
|
|
58
|
+
if (input.systemPrompt)
|
|
59
|
+
args.push("--system-prompt", input.systemPrompt);
|
|
60
|
+
if (fallbackModel)
|
|
61
|
+
args.push("--fallback-model", fallbackModel);
|
|
62
|
+
if (maxBudgetUsd !== undefined)
|
|
63
|
+
args.push("--max-budget-usd", String(maxBudgetUsd));
|
|
64
|
+
// Always skip permissions: headless subprocesses can't respond to prompts.
|
|
65
|
+
args.push("--dangerously-skip-permissions");
|
|
66
|
+
for (const f of input.contextFiles ?? []) {
|
|
67
|
+
if (typeof f === "string" && f.length > 0 && !f.startsWith("-")) {
|
|
68
|
+
args.push("--add-dir", f);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const env = sanitizeEnv(process.env);
|
|
72
|
+
this.log(`[SubprocessDriver] spawning: ${effectiveBinary} -p <prompt> (workspace: ${input.workspace})`);
|
|
73
|
+
const child = spawn(effectiveBinary, args, {
|
|
74
|
+
cwd: input.workspace,
|
|
75
|
+
env,
|
|
76
|
+
signal: input.signal,
|
|
77
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
78
|
+
// setsid() — prevents subprocess from opening /dev/tty for interactive prompts.
|
|
79
|
+
detached: true,
|
|
80
|
+
});
|
|
81
|
+
let lineBuf = "";
|
|
82
|
+
let accumulated = "";
|
|
83
|
+
let outputBytesSent = 0;
|
|
84
|
+
let firstAssistantAt;
|
|
85
|
+
let doneFromResult = false;
|
|
86
|
+
let resultText = "";
|
|
87
|
+
let resultIsError = false;
|
|
88
|
+
child.stdout.setEncoding("utf-8");
|
|
89
|
+
child.stdout.on("data", (chunk) => {
|
|
90
|
+
const { lines, remainder } = splitLines(lineBuf, chunk);
|
|
91
|
+
lineBuf = remainder;
|
|
92
|
+
for (const line of lines) {
|
|
93
|
+
if (line.trim() === "")
|
|
94
|
+
continue;
|
|
95
|
+
const parsed = parseStreamLine(line);
|
|
96
|
+
if (parsed.kind === "raw") {
|
|
97
|
+
accumulated += parsed.text;
|
|
98
|
+
if (outputBytesSent < OUTPUT_CAP) {
|
|
99
|
+
const send = parsed.text.slice(0, OUTPUT_CAP - outputBytesSent);
|
|
100
|
+
if (send.length > 0) {
|
|
101
|
+
input.onChunk?.(send);
|
|
102
|
+
outputBytesSent += send.length;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const { event, text } = parsed;
|
|
108
|
+
if (event.type === "assistant") {
|
|
109
|
+
if (firstAssistantAt === undefined)
|
|
110
|
+
firstAssistantAt = Date.now();
|
|
111
|
+
if (text.length > 0) {
|
|
112
|
+
accumulated += text;
|
|
113
|
+
if (outputBytesSent < OUTPUT_CAP) {
|
|
114
|
+
const send = text.slice(0, OUTPUT_CAP - outputBytesSent);
|
|
115
|
+
if (send.length > 0) {
|
|
116
|
+
input.onChunk?.(send);
|
|
117
|
+
outputBytesSent += send.length;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else if (event.type === "result") {
|
|
123
|
+
doneFromResult = true;
|
|
124
|
+
resultIsError = event.is_error === true;
|
|
125
|
+
resultText = text || accumulated;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
let stderr = "";
|
|
130
|
+
child.stderr.setEncoding("utf-8");
|
|
131
|
+
child.stderr.on("data", (chunk) => {
|
|
132
|
+
if (stderr.length < OUTPUT_CAP) {
|
|
133
|
+
stderr += chunk;
|
|
134
|
+
if (stderr.length > OUTPUT_CAP)
|
|
135
|
+
stderr = stderr.slice(0, OUTPUT_CAP);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
const start = Date.now();
|
|
139
|
+
const stderrTailOf = (s) => s.length > 0 ? scrubSecrets(s.slice(-2048)) : undefined;
|
|
140
|
+
const startupMsOf = () => firstAssistantAt !== undefined ? firstAssistantAt - start : undefined;
|
|
141
|
+
let startupTimedOut = false;
|
|
142
|
+
const startupHandle = input.startupTimeoutMs
|
|
143
|
+
? setTimeout(() => {
|
|
144
|
+
if (firstAssistantAt === undefined && !doneFromResult) {
|
|
145
|
+
startupTimedOut = true;
|
|
146
|
+
child.kill();
|
|
147
|
+
}
|
|
148
|
+
}, input.startupTimeoutMs)
|
|
149
|
+
: null;
|
|
150
|
+
let exitCode;
|
|
151
|
+
try {
|
|
152
|
+
exitCode = await new Promise((resolve, reject) => {
|
|
153
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
154
|
+
child.on("error", reject);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
catch (err) {
|
|
158
|
+
if (startupHandle)
|
|
159
|
+
clearTimeout(startupHandle);
|
|
160
|
+
if (doneFromResult) {
|
|
161
|
+
return {
|
|
162
|
+
text: resultText.slice(0, OUTPUT_CAP),
|
|
163
|
+
exitCode: resultIsError ? 1 : 0,
|
|
164
|
+
durationMs: Date.now() - start,
|
|
165
|
+
stderrTail: stderrTailOf(stderr),
|
|
166
|
+
startupMs: startupMsOf(),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
const isAbort = (err instanceof Error && err.name === "AbortError") ||
|
|
170
|
+
input.signal.aborted;
|
|
171
|
+
if (isAbort) {
|
|
172
|
+
return {
|
|
173
|
+
text: accumulated.slice(0, OUTPUT_CAP),
|
|
174
|
+
exitCode: -1,
|
|
175
|
+
durationMs: Date.now() - start,
|
|
176
|
+
stderrTail: stderrTailOf(stderr),
|
|
177
|
+
wasAborted: true,
|
|
178
|
+
startupMs: startupMsOf(),
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
throw err;
|
|
182
|
+
}
|
|
183
|
+
if (startupHandle)
|
|
184
|
+
clearTimeout(startupHandle);
|
|
185
|
+
const effectiveExitCode = doneFromResult
|
|
186
|
+
? resultIsError
|
|
187
|
+
? 1
|
|
188
|
+
: 0
|
|
189
|
+
: exitCode;
|
|
190
|
+
const finalText = doneFromResult ? resultText : accumulated;
|
|
191
|
+
if (startupTimedOut) {
|
|
192
|
+
return {
|
|
193
|
+
text: accumulated.slice(0, OUTPUT_CAP),
|
|
194
|
+
exitCode: -1,
|
|
195
|
+
durationMs: Date.now() - start,
|
|
196
|
+
stderrTail: stderrTailOf(stderr),
|
|
197
|
+
wasAborted: true,
|
|
198
|
+
startupTimedOut: true,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
if (effectiveExitCode !== 0 && stderr) {
|
|
202
|
+
this.log(`[SubprocessDriver] stderr: ${stderr.slice(0, 500)}`);
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
text: finalText.slice(0, OUTPUT_CAP),
|
|
206
|
+
exitCode: effectiveExitCode,
|
|
207
|
+
durationMs: Date.now() - start,
|
|
208
|
+
stderrTail: stderrTailOf(stderr),
|
|
209
|
+
startupMs: startupMsOf(),
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
async runOutcome(input) {
|
|
213
|
+
return toProviderTaskOutcome(await this.run(input));
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=subprocess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subprocess.js","sourceRoot":"","sources":["../../../src/drivers/claude/subprocess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write a minimal subprocess settings file that suppresses hooks and denies
|
|
3
|
+
* destructive operations. Uses --settings instead of --bare to preserve OAuth
|
|
4
|
+
* auth flows (--bare sets CLAUDE_CODE_SIMPLE=1 which skips OAuth).
|
|
5
|
+
*/
|
|
6
|
+
export declare function createSubprocessSettings(log: (msg: string) => void): {
|
|
7
|
+
path: string;
|
|
8
|
+
write: () => void;
|
|
9
|
+
};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
/** Deny list applied to all bridge-spawned subprocess tasks. */
|
|
5
|
+
const DENY_LIST = [
|
|
6
|
+
// Publishing / release
|
|
7
|
+
"Bash(npm publish*)",
|
|
8
|
+
"Bash(npm version*)",
|
|
9
|
+
"Bash(yarn publish*)",
|
|
10
|
+
"Bash(pnpm publish*)",
|
|
11
|
+
"Bash(npx semantic-release*)",
|
|
12
|
+
"Bash(npx release-it*)",
|
|
13
|
+
// Git remote / tagging
|
|
14
|
+
"Bash(git push*)",
|
|
15
|
+
"Bash(git tag*)",
|
|
16
|
+
"Bash(gh release*)",
|
|
17
|
+
// Destructive git operations
|
|
18
|
+
"Bash(git reset --hard*)",
|
|
19
|
+
"Bash(git clean -f*)",
|
|
20
|
+
// Filesystem destruction
|
|
21
|
+
"Bash(rm -rf *)",
|
|
22
|
+
"Bash(rm -rf/*)",
|
|
23
|
+
// Privilege escalation
|
|
24
|
+
"Bash(sudo *)",
|
|
25
|
+
"Bash(chmod 777*)",
|
|
26
|
+
// Arbitrary code execution
|
|
27
|
+
"Bash(eval *)",
|
|
28
|
+
"Bash(curl *|*)",
|
|
29
|
+
"Bash(wget *|*)",
|
|
30
|
+
// Process termination
|
|
31
|
+
"Bash(kill -9 *)",
|
|
32
|
+
"Bash(pkill *)",
|
|
33
|
+
];
|
|
34
|
+
const SETTINGS_CONTENT = JSON.stringify({
|
|
35
|
+
hooks: {},
|
|
36
|
+
permissions: { deny: DENY_LIST },
|
|
37
|
+
});
|
|
38
|
+
/**
|
|
39
|
+
* Write a minimal subprocess settings file that suppresses hooks and denies
|
|
40
|
+
* destructive operations. Uses --settings instead of --bare to preserve OAuth
|
|
41
|
+
* auth flows (--bare sets CLAUDE_CODE_SIMPLE=1 which skips OAuth).
|
|
42
|
+
*/
|
|
43
|
+
export function createSubprocessSettings(log) {
|
|
44
|
+
const path = join(tmpdir(), `claude-ide-bridge-subprocess-settings-${process.pid}.json`);
|
|
45
|
+
const write = () => {
|
|
46
|
+
try {
|
|
47
|
+
writeFileSync(path, SETTINGS_CONTENT, "utf-8");
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
log(`[SubprocessSettings] WARN: could not write settings file at ${path}: ${err instanceof Error ? err.message : String(err)} — subprocess hooks may fire`);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
return { path, write };
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=subprocessSettings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subprocessSettings.js","sourceRoot":"","sources":["../../../src/drivers/claude/subprocessSettings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,gEAAgE;AAChE,MAAM,SAAS,GAAG;IAChB,uBAAuB;IACvB,oBAAoB;IACpB,oBAAoB;IACpB,qBAAqB;IACrB,qBAAqB;IACrB,6BAA6B;IAC7B,uBAAuB;IACvB,uBAAuB;IACvB,iBAAiB;IACjB,gBAAgB;IAChB,mBAAmB;IACnB,6BAA6B;IAC7B,yBAAyB;IACzB,qBAAqB;IACrB,yBAAyB;IACzB,gBAAgB;IAChB,gBAAgB;IAChB,uBAAuB;IACvB,cAAc;IACd,kBAAkB;IAClB,2BAA2B;IAC3B,cAAc;IACd,gBAAgB;IAChB,gBAAgB;IAChB,sBAAsB;IACtB,iBAAiB;IACjB,eAAe;CAChB,CAAC;AAEF,MAAM,gBAAgB,GAAG,IAAI,CAAC,SAAS,CAAC;IACtC,KAAK,EAAE,EAAE;IACT,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;CACjC,CAAC,CAAC;AAEH;;;;GAIG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAA0B;IAIjE,MAAM,IAAI,GAAG,IAAI,CACf,MAAM,EAAE,EACR,yCAAyC,OAAO,CAAC,GAAG,OAAO,CAC5D,CAAC;IACF,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,CAAC;YACH,aAAa,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CACD,+DAA+D,IAAI,KAAK,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,8BAA8B,CACvJ,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;IACF,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ProviderDriver, ProviderTaskInput, ProviderTaskResult } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* GeminiSubprocessDriver — spawns `gemini -p` with --output-format stream-json.
|
|
4
|
+
* Auth: GEMINI_API_KEY env var (or gcloud ADC / Vertex if configured in ~/.gemini/settings.json).
|
|
5
|
+
* providerOptions: { approvalMode?: "yolo" | "auto_edit" | "default" | "plan" }
|
|
6
|
+
*/
|
|
7
|
+
export declare class GeminiSubprocessDriver implements ProviderDriver {
|
|
8
|
+
private readonly binary;
|
|
9
|
+
private readonly log;
|
|
10
|
+
readonly name = "gemini";
|
|
11
|
+
constructor(binary: string, log: (msg: string) => void);
|
|
12
|
+
run(input: ProviderTaskInput): Promise<ProviderTaskResult>;
|
|
13
|
+
runOutcome(input: ProviderTaskInput): Promise<import("../types.js").ProviderTaskOutcome>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { sanitizeEnv } from "../claude/envSanitizer.js";
|
|
3
|
+
import { splitLines } from "../claude/streamParser.js";
|
|
4
|
+
import { toProviderTaskOutcome } from "../types.js";
|
|
5
|
+
const OUTPUT_CAP = 50 * 1024;
|
|
6
|
+
function scrubSecrets(text) {
|
|
7
|
+
return text
|
|
8
|
+
.replace(/AIza[A-Za-z0-9_-]{35}/g, "[REDACTED_API_KEY]")
|
|
9
|
+
.replace(/Bearer\s+[A-Za-z0-9._-]{16,}/gi, "Bearer [REDACTED]");
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* GeminiSubprocessDriver — spawns `gemini -p` with --output-format stream-json.
|
|
13
|
+
* Auth: GEMINI_API_KEY env var (or gcloud ADC / Vertex if configured in ~/.gemini/settings.json).
|
|
14
|
+
* providerOptions: { approvalMode?: "yolo" | "auto_edit" | "default" | "plan" }
|
|
15
|
+
*/
|
|
16
|
+
export class GeminiSubprocessDriver {
|
|
17
|
+
binary;
|
|
18
|
+
log;
|
|
19
|
+
name = "gemini";
|
|
20
|
+
constructor(binary, log) {
|
|
21
|
+
this.binary = binary;
|
|
22
|
+
this.log = log;
|
|
23
|
+
}
|
|
24
|
+
async run(input) {
|
|
25
|
+
const opts = input.providerOptions ?? {};
|
|
26
|
+
const approvalMode = typeof opts.approvalMode === "string" ? opts.approvalMode : "yolo";
|
|
27
|
+
const args = [
|
|
28
|
+
"-p",
|
|
29
|
+
input.prompt,
|
|
30
|
+
"--output-format",
|
|
31
|
+
"stream-json",
|
|
32
|
+
"--approval-mode",
|
|
33
|
+
approvalMode,
|
|
34
|
+
];
|
|
35
|
+
if (input.model)
|
|
36
|
+
args.push("-m", input.model);
|
|
37
|
+
// contextFiles: pass as --include-directories for directory paths
|
|
38
|
+
for (const f of input.contextFiles ?? []) {
|
|
39
|
+
if (typeof f === "string" && f.length > 0 && !f.startsWith("-")) {
|
|
40
|
+
args.push("--include-directories", f);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Strip MCP_* and CLAUDECODE vars; preserve GEMINI_API_KEY + GOOGLE_* vars
|
|
44
|
+
const env = sanitizeEnv(process.env);
|
|
45
|
+
// Also strip Claude-specific auth vars that could confuse Gemini
|
|
46
|
+
for (const key of Object.keys(env)) {
|
|
47
|
+
if (key.startsWith("ANTHROPIC_") || key === "CLAUDE_API_KEY") {
|
|
48
|
+
delete env[key];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.log(`[GeminiSubprocessDriver] spawning: ${this.binary} -p <prompt> (workspace: ${input.workspace})`);
|
|
52
|
+
const child = spawn(this.binary, args, {
|
|
53
|
+
cwd: input.workspace,
|
|
54
|
+
env,
|
|
55
|
+
signal: input.signal,
|
|
56
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
57
|
+
detached: true,
|
|
58
|
+
});
|
|
59
|
+
let lineBuf = "";
|
|
60
|
+
let accumulated = "";
|
|
61
|
+
let outputBytesSent = 0;
|
|
62
|
+
let firstAssistantAt;
|
|
63
|
+
let doneFromResult = false;
|
|
64
|
+
let resultSuccess = true;
|
|
65
|
+
child.stdout.setEncoding("utf-8");
|
|
66
|
+
child.stdout.on("data", (chunk) => {
|
|
67
|
+
const { lines, remainder } = splitLines(lineBuf, chunk);
|
|
68
|
+
lineBuf = remainder;
|
|
69
|
+
for (const line of lines) {
|
|
70
|
+
if (line.trim() === "")
|
|
71
|
+
continue;
|
|
72
|
+
let event;
|
|
73
|
+
try {
|
|
74
|
+
event = JSON.parse(line);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Non-JSON stderr/warning lines — skip (Gemini prints "YOLO mode..." to stdout)
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
if (event.type === "message" &&
|
|
81
|
+
event.role === "assistant" &&
|
|
82
|
+
event.content) {
|
|
83
|
+
if (firstAssistantAt === undefined)
|
|
84
|
+
firstAssistantAt = Date.now();
|
|
85
|
+
const text = event.content;
|
|
86
|
+
accumulated += text;
|
|
87
|
+
if (outputBytesSent < OUTPUT_CAP) {
|
|
88
|
+
const send = text.slice(0, OUTPUT_CAP - outputBytesSent);
|
|
89
|
+
if (send.length > 0) {
|
|
90
|
+
input.onChunk?.(send);
|
|
91
|
+
outputBytesSent += send.length;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
else if (event.type === "result") {
|
|
96
|
+
doneFromResult = true;
|
|
97
|
+
resultSuccess = event.status === "success";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
let stderr = "";
|
|
102
|
+
child.stderr.setEncoding("utf-8");
|
|
103
|
+
child.stderr.on("data", (chunk) => {
|
|
104
|
+
if (stderr.length < OUTPUT_CAP) {
|
|
105
|
+
stderr += chunk;
|
|
106
|
+
if (stderr.length > OUTPUT_CAP)
|
|
107
|
+
stderr = stderr.slice(0, OUTPUT_CAP);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
const start = Date.now();
|
|
111
|
+
const stderrTailOf = (s) => s.length > 0 ? scrubSecrets(s.slice(-2048)) : undefined;
|
|
112
|
+
const startupMsOf = () => firstAssistantAt !== undefined ? firstAssistantAt - start : undefined;
|
|
113
|
+
let startupTimedOut = false;
|
|
114
|
+
const startupHandle = input.startupTimeoutMs
|
|
115
|
+
? setTimeout(() => {
|
|
116
|
+
if (firstAssistantAt === undefined && !doneFromResult) {
|
|
117
|
+
startupTimedOut = true;
|
|
118
|
+
child.kill();
|
|
119
|
+
}
|
|
120
|
+
}, input.startupTimeoutMs)
|
|
121
|
+
: null;
|
|
122
|
+
let exitCode;
|
|
123
|
+
try {
|
|
124
|
+
exitCode = await new Promise((resolve, reject) => {
|
|
125
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
126
|
+
child.on("error", reject);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
catch (err) {
|
|
130
|
+
if (startupHandle)
|
|
131
|
+
clearTimeout(startupHandle);
|
|
132
|
+
const isAbort = (err instanceof Error && err.name === "AbortError") ||
|
|
133
|
+
input.signal.aborted;
|
|
134
|
+
if (isAbort) {
|
|
135
|
+
return {
|
|
136
|
+
text: accumulated.slice(0, OUTPUT_CAP),
|
|
137
|
+
durationMs: Date.now() - start,
|
|
138
|
+
wasAborted: true,
|
|
139
|
+
startupMs: startupMsOf(),
|
|
140
|
+
stderrTail: stderrTailOf(stderr),
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
throw err;
|
|
144
|
+
}
|
|
145
|
+
if (startupHandle)
|
|
146
|
+
clearTimeout(startupHandle);
|
|
147
|
+
if (startupTimedOut) {
|
|
148
|
+
return {
|
|
149
|
+
text: accumulated.slice(0, OUTPUT_CAP),
|
|
150
|
+
durationMs: Date.now() - start,
|
|
151
|
+
wasAborted: true,
|
|
152
|
+
startupTimedOut: true,
|
|
153
|
+
stderrTail: stderrTailOf(stderr),
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
const effectiveExitCode = doneFromResult
|
|
157
|
+
? resultSuccess
|
|
158
|
+
? 0
|
|
159
|
+
: 1
|
|
160
|
+
: exitCode;
|
|
161
|
+
if (effectiveExitCode !== 0 && stderr) {
|
|
162
|
+
this.log(`[GeminiSubprocessDriver] stderr: ${stderr.slice(0, 500)}`);
|
|
163
|
+
}
|
|
164
|
+
return {
|
|
165
|
+
text: accumulated.slice(0, OUTPUT_CAP),
|
|
166
|
+
exitCode: effectiveExitCode,
|
|
167
|
+
durationMs: Date.now() - start,
|
|
168
|
+
stderrTail: stderrTailOf(stderr),
|
|
169
|
+
startupMs: startupMsOf(),
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
async runOutcome(input) {
|
|
173
|
+
return toProviderTaskOutcome(await this.run(input));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/gemini/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Grok driver — xAI's API is OpenAI-compatible at https://api.x.ai/v1.
|
|
4
|
+
* Requires XAI_API_KEY environment variable.
|
|
5
|
+
* Install: npm install openai (reuses OpenAI SDK with custom baseURL)
|
|
6
|
+
*/
|
|
7
|
+
export declare class GrokApiDriver extends OpenAIApiDriver {
|
|
8
|
+
readonly name = "grok";
|
|
9
|
+
constructor(log: (msg: string) => void);
|
|
10
|
+
protected apiKey(): string | undefined;
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Grok driver — xAI's API is OpenAI-compatible at https://api.x.ai/v1.
|
|
4
|
+
* Requires XAI_API_KEY environment variable.
|
|
5
|
+
* Install: npm install openai (reuses OpenAI SDK with custom baseURL)
|
|
6
|
+
*/
|
|
7
|
+
export class GrokApiDriver extends OpenAIApiDriver {
|
|
8
|
+
name = "grok";
|
|
9
|
+
constructor(log) {
|
|
10
|
+
if (!process.env.XAI_API_KEY) {
|
|
11
|
+
throw new Error("GrokApiDriver requires XAI_API_KEY environment variable");
|
|
12
|
+
}
|
|
13
|
+
super(log, {
|
|
14
|
+
baseURL: "https://api.x.ai/v1",
|
|
15
|
+
defaultModel: "grok-2-latest",
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
apiKey() {
|
|
19
|
+
return process.env.XAI_API_KEY;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/grok/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD;;;;GAIG;AACH,MAAM,OAAO,aAAc,SAAQ,eAAe;IAC9B,IAAI,GAAG,MAAM,CAAC;IAEhC,YAAY,GAA0B;QACpC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,yDAAyD,CAC1D,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,GAAG,EAAE;YACT,OAAO,EAAE,qBAAqB;YAC9B,YAAY,EAAE,eAAe;SAC9B,CAAC,CAAC;IACL,CAAC;IAEkB,MAAM;QACvB,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;IACjC,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ProviderDriver } from "./types.js";
|
|
2
|
+
export type DriverMode = "subprocess" | "api" | "openai" | "grok" | "gemini" | "none";
|
|
3
|
+
export interface DriverFactoryOpts {
|
|
4
|
+
binary: string;
|
|
5
|
+
antBinary: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Create the appropriate driver from a mode string.
|
|
9
|
+
* Returns null for "none" (orchestration disabled).
|
|
10
|
+
*/
|
|
11
|
+
export declare function createDriver(mode: DriverMode, opts: DriverFactoryOpts, log: (msg: string) => void): ProviderDriver | null;
|
|
12
|
+
export { ApiDriver } from "./claude/api.js";
|
|
13
|
+
export { SubprocessDriver } from "./claude/subprocess.js";
|
|
14
|
+
export { GeminiSubprocessDriver } from "./gemini/index.js";
|
|
15
|
+
export { GrokApiDriver } from "./grok/index.js";
|
|
16
|
+
export { OpenAIApiDriver } from "./openai/index.js";
|
|
17
|
+
export type { ProviderDriver, ProviderTaskInput, ProviderTaskOutcome, ProviderTaskResult, } from "./types.js";
|
|
18
|
+
export { toProviderTaskOutcome } from "./types.js";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ApiDriver } from "./claude/api.js";
|
|
2
|
+
import { SubprocessDriver } from "./claude/subprocess.js";
|
|
3
|
+
import { GeminiSubprocessDriver } from "./gemini/index.js";
|
|
4
|
+
import { GrokApiDriver } from "./grok/index.js";
|
|
5
|
+
import { OpenAIApiDriver } from "./openai/index.js";
|
|
6
|
+
/**
|
|
7
|
+
* Create the appropriate driver from a mode string.
|
|
8
|
+
* Returns null for "none" (orchestration disabled).
|
|
9
|
+
*/
|
|
10
|
+
export function createDriver(mode, opts, log) {
|
|
11
|
+
if (mode === "none")
|
|
12
|
+
return null;
|
|
13
|
+
if (mode === "subprocess")
|
|
14
|
+
return new SubprocessDriver(opts.binary, opts.antBinary, log);
|
|
15
|
+
if (mode === "api")
|
|
16
|
+
return new ApiDriver(log);
|
|
17
|
+
if (mode === "openai")
|
|
18
|
+
return new OpenAIApiDriver(log);
|
|
19
|
+
if (mode === "grok")
|
|
20
|
+
return new GrokApiDriver(log);
|
|
21
|
+
if (mode === "gemini")
|
|
22
|
+
return new GeminiSubprocessDriver(opts.binary === "claude" ? "gemini" : opts.binary, log);
|
|
23
|
+
throw new Error(`Unknown driver mode: ${mode}`);
|
|
24
|
+
}
|
|
25
|
+
export { ApiDriver } from "./claude/api.js";
|
|
26
|
+
export { SubprocessDriver } from "./claude/subprocess.js";
|
|
27
|
+
export { GeminiSubprocessDriver } from "./gemini/index.js";
|
|
28
|
+
export { GrokApiDriver } from "./grok/index.js";
|
|
29
|
+
export { OpenAIApiDriver } from "./openai/index.js";
|
|
30
|
+
export { toProviderTaskOutcome } from "./types.js";
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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;AAgBpD;;;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,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAChE,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,CACJ,CAAC;IACJ,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,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { ProviderDriver, ProviderTaskInput, ProviderTaskResult } from "../types.js";
|
|
2
|
+
export interface OpenAIDriverOpts {
|
|
3
|
+
/** Override API base URL — used by Grok and other OpenAI-compatible endpoints. */
|
|
4
|
+
baseURL?: string;
|
|
5
|
+
/** Default model when input.model is not set. */
|
|
6
|
+
defaultModel?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* OpenAI API driver — streams via chat.completions.create.
|
|
10
|
+
* Dynamic import: openai package is an optional peer dep (not in package.json).
|
|
11
|
+
* Install: npm install openai
|
|
12
|
+
*
|
|
13
|
+
* Limitation: single-turn only — no agentic tool-use loop.
|
|
14
|
+
* providerOptions: { maxTokens?: number, temperature?: number }
|
|
15
|
+
*/
|
|
16
|
+
export declare class OpenAIApiDriver implements ProviderDriver {
|
|
17
|
+
private readonly log;
|
|
18
|
+
private readonly opts;
|
|
19
|
+
readonly name: string;
|
|
20
|
+
constructor(log: (msg: string) => void, opts?: OpenAIDriverOpts);
|
|
21
|
+
run(input: ProviderTaskInput): Promise<ProviderTaskResult>;
|
|
22
|
+
/** Override in subclasses to use a different env var. */
|
|
23
|
+
protected apiKey(): string | undefined;
|
|
24
|
+
}
|