patchwork-os 0.2.0-beta.10 → 0.2.0-beta.10.canary.101
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/bridge.js +17 -10
- package/dist/bridge.js.map +1 -1
- package/dist/commands/connect.d.ts +47 -0
- package/dist/commands/connect.js +419 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/recipe.d.ts +45 -4
- package/dist/commands/recipe.js +141 -4
- package/dist/commands/recipe.js.map +1 -1
- package/dist/commands/task.d.ts +25 -0
- package/dist/commands/task.js +61 -41
- package/dist/commands/task.js.map +1 -1
- package/dist/commands/tracesExport.d.ts +15 -1
- package/dist/commands/tracesExport.js +39 -5
- package/dist/commands/tracesExport.js.map +1 -1
- package/dist/connectorRoutes.js +556 -0
- package/dist/connectorRoutes.js.map +1 -1
- package/dist/connectors/connectorRegistry.d.ts +0 -3
- package/dist/connectors/connectorRegistry.js +8 -8
- package/dist/connectors/connectorRegistry.js.map +1 -1
- package/dist/connectors/datadog.js +8 -1
- package/dist/connectors/datadog.js.map +1 -1
- package/dist/connectors/jira.js +7 -2
- package/dist/connectors/jira.js.map +1 -1
- package/dist/connectors/mcpClient.js +37 -23
- package/dist/connectors/mcpClient.js.map +1 -1
- package/dist/connectors/notion.d.ts +1 -1
- package/dist/connectors/notion.js +13 -4
- package/dist/connectors/notion.js.map +1 -1
- package/dist/connectors/redis.js +10 -2
- package/dist/connectors/redis.js.map +1 -1
- package/dist/connectors/snowflake.js +18 -0
- package/dist/connectors/snowflake.js.map +1 -1
- package/dist/decisionReplay.d.ts +8 -6
- package/dist/decisionReplay.js +35 -11
- package/dist/decisionReplay.js.map +1 -1
- package/dist/drivers/claude/api.js +28 -5
- package/dist/drivers/claude/api.js.map +1 -1
- package/dist/drivers/claude/subprocess.js +47 -13
- package/dist/drivers/claude/subprocess.js.map +1 -1
- package/dist/drivers/local/index.d.ts +2 -17
- package/dist/drivers/local/index.js +5 -92
- package/dist/drivers/local/index.js.map +1 -1
- package/dist/fp/automationInterpreter.js +57 -12
- package/dist/fp/automationInterpreter.js.map +1 -1
- package/dist/fp/policyParser.js +5 -1
- package/dist/fp/policyParser.js.map +1 -1
- package/dist/index.js +154 -83
- package/dist/index.js.map +1 -1
- package/dist/localEndpointGuard.d.ts +25 -0
- package/dist/localEndpointGuard.js +101 -0
- package/dist/localEndpointGuard.js.map +1 -0
- package/dist/orchestrator/childBridgeClient.d.ts +5 -0
- package/dist/orchestrator/childBridgeClient.js +28 -1
- package/dist/orchestrator/childBridgeClient.js.map +1 -1
- package/dist/orchestrator/orchestratorBridge.d.ts +33 -0
- package/dist/orchestrator/orchestratorBridge.js +70 -9
- package/dist/orchestrator/orchestratorBridge.js.map +1 -1
- package/dist/recipes/chainedRunner.js +14 -4
- package/dist/recipes/chainedRunner.js.map +1 -1
- package/dist/recipes/compiler.js +9 -5
- package/dist/recipes/compiler.js.map +1 -1
- package/dist/recipes/dependencyGraph.d.ts +9 -0
- package/dist/recipes/dependencyGraph.js +19 -2
- package/dist/recipes/dependencyGraph.js.map +1 -1
- package/dist/recipes/githubInstallSource.d.ts +9 -2
- package/dist/recipes/githubInstallSource.js +36 -6
- package/dist/recipes/githubInstallSource.js.map +1 -1
- package/dist/recipes/idempotencyKey.d.ts +23 -3
- package/dist/recipes/idempotencyKey.js +57 -4
- package/dist/recipes/idempotencyKey.js.map +1 -1
- package/dist/recipes/installer.js +10 -1
- package/dist/recipes/installer.js.map +1 -1
- package/dist/recipes/parser.js +28 -1
- package/dist/recipes/parser.js.map +1 -1
- package/dist/recipes/schema.d.ts +29 -2
- package/dist/recipes/schemaGenerator.js +16 -2
- package/dist/recipes/schemaGenerator.js.map +1 -1
- package/dist/recipes/toolRegistry.js +13 -4
- package/dist/recipes/toolRegistry.js.map +1 -1
- package/dist/recipes/tools/airtable.d.ts +15 -0
- package/dist/recipes/tools/airtable.js +239 -0
- package/dist/recipes/tools/airtable.js.map +1 -0
- package/dist/recipes/tools/circleci.d.ts +10 -0
- package/dist/recipes/tools/circleci.js +203 -0
- package/dist/recipes/tools/circleci.js.map +1 -0
- package/dist/recipes/tools/grafana.d.ts +11 -0
- package/dist/recipes/tools/grafana.js +215 -0
- package/dist/recipes/tools/grafana.js.map +1 -0
- package/dist/recipes/tools/index.d.ts +11 -0
- package/dist/recipes/tools/index.js +11 -0
- package/dist/recipes/tools/index.js.map +1 -1
- package/dist/recipes/tools/pipedrive.d.ts +16 -0
- package/dist/recipes/tools/pipedrive.js +233 -0
- package/dist/recipes/tools/pipedrive.js.map +1 -0
- package/dist/recipes/tools/posthog.d.ts +16 -0
- package/dist/recipes/tools/posthog.js +218 -0
- package/dist/recipes/tools/posthog.js.map +1 -0
- package/dist/recipes/tools/resend.d.ts +8 -0
- package/dist/recipes/tools/resend.js +152 -0
- package/dist/recipes/tools/resend.js.map +1 -0
- package/dist/recipes/tools/sendgrid.d.ts +9 -0
- package/dist/recipes/tools/sendgrid.js +174 -0
- package/dist/recipes/tools/sendgrid.js.map +1 -0
- package/dist/recipes/tools/shopify.d.ts +16 -0
- package/dist/recipes/tools/shopify.js +265 -0
- package/dist/recipes/tools/shopify.js.map +1 -0
- package/dist/recipes/tools/todoist.d.ts +15 -0
- package/dist/recipes/tools/todoist.js +227 -0
- package/dist/recipes/tools/todoist.js.map +1 -0
- package/dist/recipes/tools/twilio.d.ts +11 -0
- package/dist/recipes/tools/twilio.js +179 -0
- package/dist/recipes/tools/twilio.js.map +1 -0
- package/dist/recipes/tools/vercel.d.ts +9 -0
- package/dist/recipes/tools/vercel.js +145 -0
- package/dist/recipes/tools/vercel.js.map +1 -0
- package/dist/recipes/validation.js +112 -0
- package/dist/recipes/validation.js.map +1 -1
- package/dist/recipes/yamlRunner.d.ts +3 -0
- package/dist/recipes/yamlRunner.js +112 -29
- package/dist/recipes/yamlRunner.js.map +1 -1
- package/dist/schemas/recipe.v1.json +2 -2
- package/dist/telemetry.js +20 -9
- package/dist/telemetry.js.map +1 -1
- package/dist/tools/getGitStatus.js +6 -1
- package/dist/tools/getGitStatus.js.map +1 -1
- package/dist/tools/getToolCapabilities.js +39 -4
- package/dist/tools/getToolCapabilities.js.map +1 -1
- package/dist/tools/github/composite.d.ts +1 -1
- package/dist/tools/github/composite.js +7 -7
- package/dist/tools/github/composite.js.map +1 -1
- package/dist/tools/github/pr.d.ts +6 -6
- package/dist/tools/github/pr.js +18 -11
- package/dist/tools/github/pr.js.map +1 -1
- package/dist/tools/index.js +14 -10
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/previewEdit.js +16 -1
- package/dist/tools/previewEdit.js.map +1 -1
- package/dist/tools/searchAndReplace.js +4 -5
- package/dist/tools/searchAndReplace.js.map +1 -1
- package/dist/tools/searchTools.d.ts +26 -0
- package/dist/tools/searchTools.js +42 -2
- package/dist/tools/searchTools.js.map +1 -1
- package/dist/tools/transaction.d.ts +9 -1
- package/dist/tools/transaction.js +59 -4
- package/dist/tools/transaction.js.map +1 -1
- package/dist/tools/utils.d.ts +15 -0
- package/dist/tools/utils.js +19 -0
- package/dist/tools/utils.js.map +1 -1
- package/dist/transport.js +23 -0
- package/dist/transport.js.map +1 -1
- package/package.json +1 -1
package/dist/decisionReplay.js
CHANGED
|
@@ -17,14 +17,37 @@
|
|
|
17
17
|
* the rule match is tool-name-only. Noted in the result via `incomplete`.
|
|
18
18
|
*/
|
|
19
19
|
import { evaluateRules, loadCcPermissions } from "./ccPermissions.js";
|
|
20
|
+
/**
|
|
21
|
+
* Decide whether two decisions are equivalent for replay purposes.
|
|
22
|
+
*
|
|
23
|
+
* A `replay` of "none" (no current rule matched) is treated as unchanged when
|
|
24
|
+
* the original was "allow" or "deny" — absence of an explicit rule defaults to
|
|
25
|
+
* the same effective outcome the user already saw, so it is not a real flip.
|
|
26
|
+
*/
|
|
27
|
+
function isUnchanged(original, replay) {
|
|
28
|
+
return (replay === original ||
|
|
29
|
+
(replay === "none" && original === "allow") ||
|
|
30
|
+
(replay === "none" && original === "deny"));
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Bucket a CHANGED row by its NEW (replay) outcome. Keyed purely off the replay
|
|
34
|
+
* direction so every changed row maps to exactly one bucket and the three
|
|
35
|
+
* bucket counts always sum to changedCount:
|
|
36
|
+
* - replay "allow" → now_allowed
|
|
37
|
+
* - replay "ask" → now_asked
|
|
38
|
+
* - replay "deny"/"none" → now_denied (effectively blocked)
|
|
39
|
+
*
|
|
40
|
+
* Returns undefined for unchanged rows (no bucket).
|
|
41
|
+
*/
|
|
20
42
|
function changeKind(original, replay) {
|
|
21
|
-
if (
|
|
43
|
+
if (isUnchanged(original, replay))
|
|
44
|
+
return undefined;
|
|
45
|
+
if (replay === "allow")
|
|
22
46
|
return "now_allowed";
|
|
23
|
-
if (
|
|
24
|
-
return "now_denied";
|
|
25
|
-
if (replay === "ask" && original !== "ask")
|
|
47
|
+
if (replay === "ask")
|
|
26
48
|
return "now_asked";
|
|
27
|
-
|
|
49
|
+
// A changed row whose replay is "deny" or "none" is effectively now blocked.
|
|
50
|
+
return "now_denied";
|
|
28
51
|
}
|
|
29
52
|
export function computeDecisionReplay(activityLog, opts) {
|
|
30
53
|
const { workspace, sinceMs = 0, limit = 500 } = opts;
|
|
@@ -60,9 +83,8 @@ export function computeDecisionReplay(activityLog, opts) {
|
|
|
60
83
|
}
|
|
61
84
|
const incomplete = specifier === undefined;
|
|
62
85
|
const replay = evaluateRules(toolName, specifier, rules);
|
|
63
|
-
const unchanged =
|
|
64
|
-
|
|
65
|
-
(replay === "none" && originalDecision === "deny");
|
|
86
|
+
const unchanged = isUnchanged(originalDecision, replay);
|
|
87
|
+
const kind = changeKind(originalDecision, replay);
|
|
66
88
|
rows.push({
|
|
67
89
|
timestamp: entry.timestamp,
|
|
68
90
|
toolName,
|
|
@@ -70,15 +92,14 @@ export function computeDecisionReplay(activityLog, opts) {
|
|
|
70
92
|
originalDecision,
|
|
71
93
|
replayDecision: replay,
|
|
72
94
|
unchanged,
|
|
73
|
-
...(
|
|
74
|
-
changeKind: changeKind(originalDecision, replay),
|
|
75
|
-
}),
|
|
95
|
+
...(kind !== undefined && { changeKind: kind }),
|
|
76
96
|
...(incomplete && { incomplete: true }),
|
|
77
97
|
});
|
|
78
98
|
}
|
|
79
99
|
let changedCount = 0;
|
|
80
100
|
let nowAllowedCount = 0;
|
|
81
101
|
let nowDeniedCount = 0;
|
|
102
|
+
let nowAskedCount = 0;
|
|
82
103
|
for (const r of rows) {
|
|
83
104
|
if (r.unchanged)
|
|
84
105
|
continue;
|
|
@@ -87,6 +108,8 @@ export function computeDecisionReplay(activityLog, opts) {
|
|
|
87
108
|
nowAllowedCount++;
|
|
88
109
|
else if (r.changeKind === "now_denied")
|
|
89
110
|
nowDeniedCount++;
|
|
111
|
+
else if (r.changeKind === "now_asked")
|
|
112
|
+
nowAskedCount++;
|
|
90
113
|
}
|
|
91
114
|
return {
|
|
92
115
|
rows,
|
|
@@ -95,6 +118,7 @@ export function computeDecisionReplay(activityLog, opts) {
|
|
|
95
118
|
changedCount,
|
|
96
119
|
nowAllowedCount,
|
|
97
120
|
nowDeniedCount,
|
|
121
|
+
nowAskedCount,
|
|
98
122
|
workspace,
|
|
99
123
|
};
|
|
100
124
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decisionReplay.js","sourceRoot":"","sources":["../src/decisionReplay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"decisionReplay.js","sourceRoot":"","sources":["../src/decisionReplay.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,11 +32,34 @@ export class ApiDriver {
|
|
|
32
32
|
.join("\n")}\n--- END CONTEXT FILE LIST ---`
|
|
33
33
|
: "";
|
|
34
34
|
this.log("[ApiDriver] sending request to Anthropic API");
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
35
|
+
// ProviderDriver contract (types.ts): run() must resolve, never reject —
|
|
36
|
+
// swallow auth/429/network/abort errors into the result. messages.create
|
|
37
|
+
// rejects on all of these, so wrap it and translate into an errorMessage
|
|
38
|
+
// (or wasAborted for an abort/cancellation), mirroring OpenAIApiDriver.run.
|
|
39
|
+
let message;
|
|
40
|
+
try {
|
|
41
|
+
message = await client.messages.create({
|
|
42
|
+
model: input.model ?? "claude-haiku-4-5-20251001",
|
|
43
|
+
max_tokens: 4096,
|
|
44
|
+
messages: [{ role: "user", content: input.prompt + contextNote }],
|
|
45
|
+
}, { signal: input.signal });
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
const isAbort = (err instanceof Error && err.name === "AbortError") ||
|
|
49
|
+
input.signal.aborted;
|
|
50
|
+
if (isAbort) {
|
|
51
|
+
return {
|
|
52
|
+
text: "",
|
|
53
|
+
durationMs: Date.now() - start,
|
|
54
|
+
wasAborted: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
text: "",
|
|
59
|
+
durationMs: Date.now() - start,
|
|
60
|
+
errorMessage: err instanceof Error ? err.message : String(err),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
40
63
|
// biome-ignore lint/suspicious/noExplicitAny: message is from dynamically imported optional dep
|
|
41
64
|
const content = message.content;
|
|
42
65
|
let text = "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/drivers/claude/api.ts"],"names":[],"mappings":"AAMA,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7B;;;GAGG;AACH,MAAM,OAAO,SAAS;IAGS;IAFpB,IAAI,GAAG,KAAK,CAAC;IAEtB,YAA6B,GAA0B;QAA1B,QAAG,GAAH,GAAG,CAAuB;QACrD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,2DAA2D,CAC5D,CAAC;QACJ,CAAC;IACH,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAwB;QAChC,kFAAkF;QAClF,IAAI,aAA4B,CAAC;QACjC,IAAI,CAAC;YACH,6DAA6D;YAC7D,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,mBAA0B,CAAC,CAAC;YACrD,6DAA6D;YAC7D,aAAa,GAAI,GAAW,CAAC,OAAO,IAAI,GAAG,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAEzB,MAAM,WAAW,GACf,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;YACjD,CAAC,CAAC,0EAA0E,KAAK,CAAC,YAAY;iBACzF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;iBAC3D,IAAI,CAAC,IAAI,CAAC,iCAAiC;YAChD,CAAC,CAAC,EAAE,CAAC;QAET,IAAI,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAEzD,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/drivers/claude/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,35 @@ import { sanitizeEnv } from "./envSanitizer.js";
|
|
|
9
9
|
import { parseStreamLine, splitLines } from "./streamParser.js";
|
|
10
10
|
import { createSubprocessSettings } from "./subprocessSettings.js";
|
|
11
11
|
const OUTPUT_CAP = 50 * 1024; // 50KB
|
|
12
|
+
/**
|
|
13
|
+
* Truncate `text` to at most `cap` UTF-8 bytes without splitting a multi-byte
|
|
14
|
+
* codepoint mid-sequence. `String.slice(0, cap)` operates on UTF-16 code
|
|
15
|
+
* units, so a 50K cap can store ~50K code points but emit up to ~200KB of
|
|
16
|
+
* UTF-8 wire bytes for CJK / emoji content — and may produce a lone surrogate
|
|
17
|
+
* at the boundary. `Buffer.toString("utf8")` substitutes U+FFFD for incomplete
|
|
18
|
+
* trailing sequences instead.
|
|
19
|
+
*/
|
|
20
|
+
function truncateUtf8Bytes(text, cap) {
|
|
21
|
+
const buf = Buffer.from(text, "utf8");
|
|
22
|
+
if (buf.length <= cap)
|
|
23
|
+
return text;
|
|
24
|
+
return buf.subarray(0, cap).toString("utf8");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Truncate `text` so it adds at most `remaining` UTF-8 bytes to the stream and
|
|
28
|
+
* never splits a multi-byte codepoint mid-sequence. Returns the safely-
|
|
29
|
+
* truncated slice plus its actual byte length so the running byte total can be
|
|
30
|
+
* advanced correctly.
|
|
31
|
+
*/
|
|
32
|
+
function truncateToBytes(text, remaining) {
|
|
33
|
+
const buf = Buffer.from(text, "utf8");
|
|
34
|
+
if (buf.length <= remaining)
|
|
35
|
+
return { send: text, bytes: buf.length };
|
|
36
|
+
// Buffer.toString("utf8") substitutes U+FFFD for incomplete trailing
|
|
37
|
+
// sequences, which is the correct UTF-8 truncation behavior.
|
|
38
|
+
const sliced = buf.subarray(0, remaining).toString("utf8");
|
|
39
|
+
return { send: sliced, bytes: Buffer.byteLength(sliced, "utf8") };
|
|
40
|
+
}
|
|
12
41
|
/**
|
|
13
42
|
* Write a single-server MCP config to a 0600 temp file, return the path.
|
|
14
43
|
* Caller passes path via `--mcp-config <path>` to claude -p.
|
|
@@ -188,10 +217,10 @@ export class SubprocessDriver {
|
|
|
188
217
|
if (parsed.kind === "raw") {
|
|
189
218
|
accumulated += parsed.text;
|
|
190
219
|
if (outputBytesSent < OUTPUT_CAP) {
|
|
191
|
-
const send = parsed.text
|
|
192
|
-
if (
|
|
220
|
+
const { send, bytes } = truncateToBytes(parsed.text, OUTPUT_CAP - outputBytesSent);
|
|
221
|
+
if (bytes > 0) {
|
|
193
222
|
input.onChunk?.(send);
|
|
194
|
-
outputBytesSent +=
|
|
223
|
+
outputBytesSent += bytes;
|
|
195
224
|
}
|
|
196
225
|
}
|
|
197
226
|
continue;
|
|
@@ -203,10 +232,10 @@ export class SubprocessDriver {
|
|
|
203
232
|
if (text.length > 0) {
|
|
204
233
|
accumulated += text;
|
|
205
234
|
if (outputBytesSent < OUTPUT_CAP) {
|
|
206
|
-
const send = text
|
|
207
|
-
if (
|
|
235
|
+
const { send, bytes } = truncateToBytes(text, OUTPUT_CAP - outputBytesSent);
|
|
236
|
+
if (bytes > 0) {
|
|
208
237
|
input.onChunk?.(send);
|
|
209
|
-
outputBytesSent +=
|
|
238
|
+
outputBytesSent += bytes;
|
|
210
239
|
}
|
|
211
240
|
}
|
|
212
241
|
}
|
|
@@ -221,10 +250,15 @@ export class SubprocessDriver {
|
|
|
221
250
|
let stderr = "";
|
|
222
251
|
child.stderr.setEncoding("utf-8");
|
|
223
252
|
child.stderr.on("data", (chunk) => {
|
|
224
|
-
|
|
253
|
+
// Apply the same byte-budget cap to stderr to prevent unbounded memory
|
|
254
|
+
// growth on multi-byte UTF-8 output. Counting via Buffer.byteLength /
|
|
255
|
+
// truncateUtf8Bytes keeps the cap a true byte budget rather than a
|
|
256
|
+
// UTF-16 code-unit budget.
|
|
257
|
+
if (Buffer.byteLength(stderr, "utf8") < OUTPUT_CAP) {
|
|
225
258
|
stderr += chunk;
|
|
226
|
-
if (stderr
|
|
227
|
-
stderr = stderr
|
|
259
|
+
if (Buffer.byteLength(stderr, "utf8") > OUTPUT_CAP) {
|
|
260
|
+
stderr = truncateUtf8Bytes(stderr, OUTPUT_CAP);
|
|
261
|
+
}
|
|
228
262
|
}
|
|
229
263
|
});
|
|
230
264
|
const start = Date.now();
|
|
@@ -251,7 +285,7 @@ export class SubprocessDriver {
|
|
|
251
285
|
clearTimeout(startupHandle);
|
|
252
286
|
if (doneFromResult) {
|
|
253
287
|
return {
|
|
254
|
-
text: resultText
|
|
288
|
+
text: truncateUtf8Bytes(resultText, OUTPUT_CAP),
|
|
255
289
|
exitCode: resultIsError ? 1 : 0,
|
|
256
290
|
durationMs: Date.now() - start,
|
|
257
291
|
stderrTail: stderrTailOf(stderr),
|
|
@@ -262,7 +296,7 @@ export class SubprocessDriver {
|
|
|
262
296
|
input.signal.aborted;
|
|
263
297
|
if (isAbort) {
|
|
264
298
|
return {
|
|
265
|
-
text: accumulated
|
|
299
|
+
text: truncateUtf8Bytes(accumulated, OUTPUT_CAP),
|
|
266
300
|
exitCode: -1,
|
|
267
301
|
durationMs: Date.now() - start,
|
|
268
302
|
stderrTail: stderrTailOf(stderr),
|
|
@@ -282,7 +316,7 @@ export class SubprocessDriver {
|
|
|
282
316
|
const finalText = doneFromResult ? resultText : accumulated;
|
|
283
317
|
if (startupTimedOut) {
|
|
284
318
|
return {
|
|
285
|
-
text: accumulated
|
|
319
|
+
text: truncateUtf8Bytes(accumulated, OUTPUT_CAP),
|
|
286
320
|
exitCode: -1,
|
|
287
321
|
durationMs: Date.now() - start,
|
|
288
322
|
stderrTail: stderrTailOf(stderr),
|
|
@@ -294,7 +328,7 @@ export class SubprocessDriver {
|
|
|
294
328
|
this.log(`[SubprocessDriver] stderr: ${stderr.slice(0, 500)}`);
|
|
295
329
|
}
|
|
296
330
|
return {
|
|
297
|
-
text: finalText
|
|
331
|
+
text: truncateUtf8Bytes(finalText, OUTPUT_CAP),
|
|
298
332
|
exitCode: effectiveExitCode,
|
|
299
333
|
durationMs: Date.now() - start,
|
|
300
334
|
stderrTail: stderrTailOf(stderr),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subprocess.js","sourceRoot":"","sources":["../../../src/drivers/claude/subprocess.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"subprocess.js","sourceRoot":"","sources":["../../../src/drivers/claude/subprocess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO;AAErC;;;;;;;GAOG;AACH,SAAS,iBAAiB,CAAC,IAAY,EAAE,GAAW;IAClD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,IAAI,CAAC;IACnC,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,SAAS,eAAe,CACtB,IAAY,EACZ,SAAiB;IAEjB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,IAAI,GAAG,CAAC,MAAM,IAAI,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC;IACtE,qEAAqE;IACrE,6DAA6D;IAC7D,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;AACpE,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,SAAS,kBAAkB,CAAC,IAAwC;IAClE,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACnC,4EAA4E;IAC5E,0EAA0E;IAC1E,wEAAwE;IACxE,2DAA2D;IAC3D,MAAM,MAAM,GAAG;QACb,UAAU,EAAE;YACV,SAAS,EAAE;gBACT,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,aAAa,CAAC,mBAAmB,CAAC;gBAC3C,IAAI,EAAE,CAAC,MAAM,CAAC;aACf;SACF;KACF,CAAC;IACF,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI;SACR,OAAO,CAAC,4BAA4B,EAAE,oBAAoB,CAAC;SAC3D,OAAO,CAAC,gCAAgC,EAAE,mBAAmB,CAAC;SAC9D,OAAO,CAAC,qCAAqC,EAAE,kBAAkB,CAAC,CAAC;AACxE,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,gBAAgB;IAKR;IACA;IACA;IACA;IAPV,IAAI,GAAG,YAAY,CAAC;IACZ,QAAQ,CAA8C;IAEvE,YACmB,MAAc,EACd,SAAiB,EACjB,GAA0B,EAC1B,SAEJ;QALI,WAAM,GAAN,MAAM,CAAQ;QACd,cAAS,GAAT,SAAS,CAAQ;QACjB,QAAG,GAAH,GAAG,CAAuB;QAC1B,cAAS,GAAT,SAAS,CAEb;QAEb,IAAI,CAAC,QAAQ,GAAG,wBAAwB,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAwB;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,eAAe,IAAI,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,KAAK,IAAI,CAAC;QACpC,MAAM,MAAM,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QACzE,MAAM,aAAa,GACjB,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1E,MAAM,YAAY,GAChB,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC;QAExE,qEAAqE;QACrE,uEAAuE;QACvE,8DAA8D;QAC9D,MAAM,eAAe,GAAG,aAAa,CACnC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CACtC,CAAC;QACF,0EAA0E;QAC1E,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAEtB,0EAA0E;QAC1E,qEAAqE;QACrE,qEAAqE;QACrE,qEAAqE;QACrE,eAAe;QACf,IAAI,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CACb,wEAAwE,CACzE,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC;QAC1C,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QAEvD,MAAM,IAAI,GAAG;YACX,IAAI;YACJ,KAAK,CAAC,MAAM;YACZ,uEAAuE;YACvE,8DAA8D;YAC9D,oEAAoE;YACpE,sEAAsE;YACtE,qBAAqB;YACrB,YAAY;YACZ,IAAI,CAAC,QAAQ,CAAC,IAAI;YAClB,iBAAiB;YACjB,aAAa;YACb,WAAW;YACX,4BAA4B;YAC5B,0BAA0B;SAC3B,CAAC;QAEF,uEAAuE;QACvE,2EAA2E;QAC3E,IAAI,SAAS,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CACN,4IAA4I,CAC7I,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,EAAE,CAAC;YACR,MAAM,aAAa,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;YAC9C,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,aAAa,CAAC,CAAC;QAC3C,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACrE,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9D,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,aAAa,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,YAAY,KAAK,SAAS;YAC5B,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC;QACtD,2EAA2E;QAC3E,IAAI,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC5C,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC;YACzC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChE,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;YAC5B,CAAC;QACH,CAAC;QAED,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAErC,IAAI,CAAC,GAAG,CACN,gCAAgC,eAAe,4BAA4B,KAAK,CAAC,SAAS,GAAG,CAC9F,CAAC;QAEF,MAAM,KAAK,GAAG,KAAK,CAAC,eAAe,EAAE,IAAI,EAAE;YACzC,GAAG,EAAE,KAAK,CAAC,SAAS;YACpB,GAAG;YACH,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;YACjC,gFAAgF;YAChF,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QACH,2EAA2E;QAC3E,uEAAuE;QACvE,qEAAqE;QACrE,sEAAsE;QACtE,gEAAgE;QAChE,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACtC,KAAK,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,GAAG,EAAE,CAAC;QACjB,IAAI,WAAW,GAAG,EAAE,CAAC;QACrB,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,IAAI,gBAAoC,CAAC;QACzC,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,UAAU,GAAG,EAAE,CAAC;QACpB,IAAI,aAAa,GAAG,KAAK,CAAC;QAE1B,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACxD,OAAO,GAAG,SAAS,CAAC;YAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;oBAAE,SAAS;gBAEjC,MAAM,MAAM,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;gBACrC,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;oBAC1B,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC;oBAC3B,IAAI,eAAe,GAAG,UAAU,EAAE,CAAC;wBACjC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,eAAe,CACrC,MAAM,CAAC,IAAI,EACX,UAAU,GAAG,eAAe,CAC7B,CAAC;wBACF,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;4BACd,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;4BACtB,eAAe,IAAI,KAAK,CAAC;wBAC3B,CAAC;oBACH,CAAC;oBACD,SAAS;gBACX,CAAC;gBAED,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC;gBAC/B,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;oBAC/B,IAAI,gBAAgB,KAAK,SAAS;wBAAE,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAClE,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACpB,WAAW,IAAI,IAAI,CAAC;wBACpB,IAAI,eAAe,GAAG,UAAU,EAAE,CAAC;4BACjC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,eAAe,CACrC,IAAI,EACJ,UAAU,GAAG,eAAe,CAC7B,CAAC;4BACF,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gCACd,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC;gCACtB,eAAe,IAAI,KAAK,CAAC;4BAC3B,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;qBAAM,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACnC,cAAc,GAAG,IAAI,CAAC;oBACtB,aAAa,GAAG,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC;oBACxC,UAAU,GAAG,IAAI,IAAI,WAAW,CAAC;gBACnC,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACxC,uEAAuE;YACvE,sEAAsE;YACtE,mEAAmE;YACnE,2BAA2B;YAC3B,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;gBACnD,MAAM,IAAI,KAAK,CAAC;gBAChB,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC;oBACnD,MAAM,GAAG,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,MAAM,YAAY,GAAG,CAAC,CAAS,EAAsB,EAAE,CACrD,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC1D,MAAM,WAAW,GAAG,GAAuB,EAAE,CAC3C,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,gBAAgB,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAExE,IAAI,eAAe,GAAG,KAAK,CAAC;QAC5B,MAAM,aAAa,GAAG,KAAK,CAAC,gBAAgB;YAC1C,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,gBAAgB,KAAK,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;oBACtD,eAAe,GAAG,IAAI,CAAC;oBACvB,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC,EAAE,KAAK,CAAC,gBAAgB,CAAC;YAC5B,CAAC,CAAC,IAAI,CAAC;QAET,IAAI,QAAgB,CAAC;QACrB,IAAI,CAAC;YACH,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACvD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC;gBAChD,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,aAAa;gBAAE,YAAY,CAAC,aAAa,CAAC,CAAC;YAC/C,IAAI,cAAc,EAAE,CAAC;gBACnB,OAAO;oBACL,IAAI,EAAE,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC;oBAC/C,QAAQ,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC/B,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,UAAU,EAAE,YAAY,CAAC,MAAM,CAAC;oBAChC,SAAS,EAAE,WAAW,EAAE;iBACzB,CAAC;YACJ,CAAC;YACD,MAAM,OAAO,GACX,CAAC,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC;gBACnD,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC;YACvB,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO;oBACL,IAAI,EAAE,iBAAiB,CAAC,WAAW,EAAE,UAAU,CAAC;oBAChD,QAAQ,EAAE,CAAC,CAAC;oBACZ,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;oBAC9B,UAAU,EAAE,YAAY,CAAC,MAAM,CAAC;oBAChC,UAAU,EAAE,IAAI;oBAChB,SAAS,EAAE,WAAW,EAAE;iBACzB,CAAC;YACJ,CAAC;YACD,MAAM,GAAG,CAAC;QACZ,CAAC;QACD,IAAI,aAAa;YAAE,YAAY,CAAC,aAAa,CAAC,CAAC;QAE/C,MAAM,iBAAiB,GAAG,cAAc;YACtC,CAAC,CAAC,aAAa;gBACb,CAAC,CAAC,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,QAAQ,CAAC;QACb,MAAM,SAAS,GAAG,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC;QAE5D,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO;gBACL,IAAI,EAAE,iBAAiB,CAAC,WAAW,EAAE,UAAU,CAAC;gBAChD,QAAQ,EAAE,CAAC,CAAC;gBACZ,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;gBAC9B,UAAU,EAAE,YAAY,CAAC,MAAM,CAAC;gBAChC,UAAU,EAAE,IAAI;gBAChB,eAAe,EAAE,IAAI;aACtB,CAAC;QACJ,CAAC;QAED,IAAI,iBAAiB,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,8BAA8B,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,OAAO;YACL,IAAI,EAAE,iBAAiB,CAAC,SAAS,EAAE,UAAU,CAAC;YAC9C,QAAQ,EAAE,iBAAiB;YAC3B,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;YAC9B,UAAU,EAAE,YAAY,CAAC,MAAM,CAAC;YAChC,SAAS,EAAE,WAAW,EAAE;SACzB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,KAAwB;QACvC,OAAO,qBAAqB,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACtD,CAAC;CACF"}
|
|
@@ -1,21 +1,6 @@
|
|
|
1
|
+
import { isLoopbackOrPrivateEndpoint } from "../../localEndpointGuard.js";
|
|
1
2
|
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
-
|
|
3
|
-
* Reject any LOCAL_ENDPOINT that doesn't resolve to loopback or RFC1918
|
|
4
|
-
* private space. The local driver streams the user prompt + context-file
|
|
5
|
-
* paths to whatever URL is set; if a malicious recipe (or a user pasting
|
|
6
|
-
* a phishy "free local LLM" link) sets `LOCAL_ENDPOINT=https://attacker/v1`,
|
|
7
|
-
* everything the local driver receives gets exfiltrated.
|
|
8
|
-
*
|
|
9
|
-
* Rule: hostname must be one of
|
|
10
|
-
* - localhost / 127.0.0.1 / ::1
|
|
11
|
-
* - RFC1918 private space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
|
|
12
|
-
* - link-local (169.254.0.0/16, fe80::/10)
|
|
13
|
-
* - .local mDNS / .lan / .home / .internal suffixes
|
|
14
|
-
*
|
|
15
|
-
* To opt out (e.g. authorized remote inference cluster), the operator can
|
|
16
|
-
* set LOCAL_ENDPOINT_ALLOW_REMOTE=1 — explicit override, audited via env.
|
|
17
|
-
*/
|
|
18
|
-
export declare function isLoopbackOrPrivateEndpoint(rawUrl: string): boolean;
|
|
3
|
+
export { isLoopbackOrPrivateEndpoint };
|
|
19
4
|
/**
|
|
20
5
|
* Local LLM driver — Ollama, LM Studio, vLLM, llama.cpp server, and most
|
|
21
6
|
* other self-hosted runtimes expose an OpenAI-compatible chat-completions
|
|
@@ -1,96 +1,9 @@
|
|
|
1
|
+
import { isLoopbackOrPrivateEndpoint } from "../../localEndpointGuard.js";
|
|
1
2
|
import { OpenAIApiDriver } from "../openai/index.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* a phishy "free local LLM" link) sets `LOCAL_ENDPOINT=https://attacker/v1`,
|
|
7
|
-
* everything the local driver receives gets exfiltrated.
|
|
8
|
-
*
|
|
9
|
-
* Rule: hostname must be one of
|
|
10
|
-
* - localhost / 127.0.0.1 / ::1
|
|
11
|
-
* - RFC1918 private space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
|
|
12
|
-
* - link-local (169.254.0.0/16, fe80::/10)
|
|
13
|
-
* - .local mDNS / .lan / .home / .internal suffixes
|
|
14
|
-
*
|
|
15
|
-
* To opt out (e.g. authorized remote inference cluster), the operator can
|
|
16
|
-
* set LOCAL_ENDPOINT_ALLOW_REMOTE=1 — explicit override, audited via env.
|
|
17
|
-
*/
|
|
18
|
-
export function isLoopbackOrPrivateEndpoint(rawUrl) {
|
|
19
|
-
let host;
|
|
20
|
-
let wasBracketed = false;
|
|
21
|
-
try {
|
|
22
|
-
host = new URL(rawUrl).hostname.toLowerCase();
|
|
23
|
-
}
|
|
24
|
-
catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
if (!host)
|
|
28
|
-
return false;
|
|
29
|
-
// Strip IPv6 brackets if any
|
|
30
|
-
if (host.startsWith("[") && host.endsWith("]")) {
|
|
31
|
-
host = host.slice(1, -1);
|
|
32
|
-
wasBracketed = true;
|
|
33
|
-
}
|
|
34
|
-
if (host === "localhost" || host === "127.0.0.1" || host === "::1") {
|
|
35
|
-
return true;
|
|
36
|
-
}
|
|
37
|
-
// IPv4 RFC1918 + link-local + 127/8 (check first — strict literal match)
|
|
38
|
-
const v4 = host.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/);
|
|
39
|
-
if (v4) {
|
|
40
|
-
const a = Number(v4[1]);
|
|
41
|
-
const b = Number(v4[2]);
|
|
42
|
-
if (a === 10)
|
|
43
|
-
return true;
|
|
44
|
-
if (a === 127)
|
|
45
|
-
return true;
|
|
46
|
-
if (a === 169 && b === 254)
|
|
47
|
-
return true;
|
|
48
|
-
if (a === 172 && b >= 16 && b <= 31)
|
|
49
|
-
return true;
|
|
50
|
-
if (a === 192 && b === 168)
|
|
51
|
-
return true;
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
// IPv6 ranges — only when the input looked like an IPv6 literal (was
|
|
55
|
-
// bracketed in the URL, or matches an IPv6 syntactic shape). Without this
|
|
56
|
-
// gate, a hostname like `fc-services.example.com` or `fe8a-test` would
|
|
57
|
-
// match the legacy `startsWith("fc")` / `startsWith("fe8")` checks and
|
|
58
|
-
// bypass the validator. RFC3986 allows IPv6 literals only inside `[…]`,
|
|
59
|
-
// so requiring the brackets is the conservative path.
|
|
60
|
-
if (wasBracketed || /^[0-9a-f:]+$/.test(host)) {
|
|
61
|
-
if (host.startsWith("fe8") ||
|
|
62
|
-
host.startsWith("fe9") ||
|
|
63
|
-
host.startsWith("fea") ||
|
|
64
|
-
host.startsWith("feb")) {
|
|
65
|
-
return true; // link-local fe80::/10
|
|
66
|
-
}
|
|
67
|
-
if (host.startsWith("fc") || host.startsWith("fd")) {
|
|
68
|
-
return true; // unique-local fc00::/7
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// mDNS / common LAN suffixes — checked LAST and require a leading dot
|
|
72
|
-
// boundary so attacker-registered public domains like `evil.com.local`
|
|
73
|
-
// don't slip through (`.local` and `.lan` are not reserved TLDs at the
|
|
74
|
-
// DNS resolver level — only RFC6762 reserves them for mDNS, but public
|
|
75
|
-
// resolvers will happily look them up).
|
|
76
|
-
//
|
|
77
|
-
// The trade-off: a host literally named `printer.local` (single label
|
|
78
|
-
// before `.local`) is the legitimate mDNS form and matches; a host like
|
|
79
|
-
// `evil.com.local` (two-or-more labels before `.local`) is only the
|
|
80
|
-
// mDNS form by accident and is the bypass we're rejecting.
|
|
81
|
-
for (const suffix of [".local", ".lan", ".home", ".internal"]) {
|
|
82
|
-
if (host.endsWith(suffix)) {
|
|
83
|
-
const labels = host.split(".");
|
|
84
|
-
// 2 labels exactly: `<name>.local` — legitimate mDNS shape.
|
|
85
|
-
if (labels.length === 2)
|
|
86
|
-
return true;
|
|
87
|
-
// More labels: ambiguous — refuse by default. Operator can opt out
|
|
88
|
-
// via LOCAL_ENDPOINT_ALLOW_REMOTE for legitimate multi-label
|
|
89
|
-
// internal DNS zones (e.g. `service.team.internal`).
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
return false;
|
|
93
|
-
}
|
|
3
|
+
// Re-export so existing importers (`import { isLoopbackOrPrivateEndpoint }
|
|
4
|
+
// from ".../drivers/local/index.js"`) keep working after the predicate moved
|
|
5
|
+
// to the shared `src/localEndpointGuard.ts` module.
|
|
6
|
+
export { isLoopbackOrPrivateEndpoint };
|
|
94
7
|
/**
|
|
95
8
|
* Local LLM driver — Ollama, LM Studio, vLLM, llama.cpp server, and most
|
|
96
9
|
* other self-hosted runtimes expose an OpenAI-compatible chat-completions
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/drivers/local/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,2EAA2E;AAC3E,6EAA6E;AAC7E,oDAAoD;AACpD,OAAO,EAAE,2BAA2B,EAAE,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,cAAe,SAAQ,eAAe;IAC/B,IAAI,GAAG,OAAO,CAAC;IAEjC,YAAY,GAA0B;QACpC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;QAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,8FAA8F,CAC/F,CAAC;QACJ,CAAC;QACD,IACE,OAAO,CAAC,GAAG,CAAC,2BAA2B,KAAK,GAAG;YAC/C,CAAC,2BAA2B,CAAC,OAAO,CAAC,EACrC,CAAC;YACD,MAAM,IAAI,KAAK,CACb,mCAAmC,OAAO,gCAAgC;gBACxE,yEAAyE;gBACzE,uEAAuE;gBACvE,iDAAiD,CACpD,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,GAAG,EAAE;YACT,OAAO;YACP,mEAAmE;YACnE,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,UAAU;SACpD,CAAC,CAAC;IACL,CAAC;IAEkB,MAAM;QACvB,mEAAmE;QACnE,6DAA6D;QAC7D,OAAO,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,QAAQ,CAAC;IAC/C,CAAC;CACF"}
|
|
@@ -225,6 +225,27 @@ function buildFinalPrompt(promptTemplate, hookType, eventData, nonce) {
|
|
|
225
225
|
}
|
|
226
226
|
return truncatePrompt(meta + resolved);
|
|
227
227
|
}
|
|
228
|
+
/**
|
|
229
|
+
* Resolve `{{placeholder}}` tokens in a WithCooldown key against the live
|
|
230
|
+
* `eventData` at interpret time. Lets a hook scope its cooldown bucket per
|
|
231
|
+
* dynamic value — e.g. `recipesave:{{file}}` cools down only the saved file,
|
|
232
|
+
* not every recipe. Keys without any `{{…}}` token pass through unchanged, so
|
|
233
|
+
* every other hook's cooldown behaviour is untouched.
|
|
234
|
+
*
|
|
235
|
+
* Sanitised to a stable map-key shape: control chars stripped, length capped,
|
|
236
|
+
* unresolved placeholders collapse to `*` so a missing value still produces a
|
|
237
|
+
* deterministic bucket (rather than leaking the raw `{{file}}` literal).
|
|
238
|
+
*/
|
|
239
|
+
function resolveCooldownKey(key, eventData) {
|
|
240
|
+
if (!key.includes("{{"))
|
|
241
|
+
return key;
|
|
242
|
+
return key.replace(/\{\{(\w+)\}\}/g, (_m, name) => {
|
|
243
|
+
const val = eventData[name];
|
|
244
|
+
if (val === undefined || val === "")
|
|
245
|
+
return "*";
|
|
246
|
+
return val.replace(/[\x00-\x1F\x7F]/g, "").slice(0, 256);
|
|
247
|
+
});
|
|
248
|
+
}
|
|
228
249
|
// ── Interpreter ───────────────────────────────────────────────────────────────
|
|
229
250
|
async function interpret(program, ctx, acc) {
|
|
230
251
|
switch (program._tag) {
|
|
@@ -463,15 +484,19 @@ async function interpret(program, ctx, acc) {
|
|
|
463
484
|
return current;
|
|
464
485
|
}
|
|
465
486
|
case "WithCooldown": {
|
|
466
|
-
|
|
487
|
+
// Resolve any `{{placeholder}}` in the cooldown key against the live
|
|
488
|
+
// event so a per-file hook (e.g. onRecipeSave → `recipesave:{{file}}`)
|
|
489
|
+
// gets its OWN cooldown bucket. Static keys pass through unchanged.
|
|
490
|
+
const cooldownKey = resolveCooldownKey(program.key, ctx.eventData);
|
|
491
|
+
if (isOnCooldown(acc.state, cooldownKey, ctx.now, program.cooldownMs)) {
|
|
467
492
|
const hookLabel = program.program._tag === "Hook"
|
|
468
493
|
? program.program.hookType
|
|
469
|
-
:
|
|
494
|
+
: cooldownKey;
|
|
470
495
|
return {
|
|
471
496
|
...acc,
|
|
472
497
|
skipped: [
|
|
473
498
|
...acc.skipped,
|
|
474
|
-
{ reason: `cooldown:${
|
|
499
|
+
{ reason: `cooldown:${cooldownKey}`, hook: hookLabel },
|
|
475
500
|
],
|
|
476
501
|
};
|
|
477
502
|
}
|
|
@@ -495,11 +520,11 @@ async function interpret(program, ctx, acc) {
|
|
|
495
520
|
}
|
|
496
521
|
if (newTaskIds.length > 0) {
|
|
497
522
|
const lastTaskId = newTaskIds[newTaskIds.length - 1] ?? "";
|
|
498
|
-
const newState = recordTrigger(innerAcc.state,
|
|
523
|
+
const newState = recordTrigger(innerAcc.state, cooldownKey, lastTaskId, ctx.now);
|
|
499
524
|
return { ...innerAcc, state: newState };
|
|
500
525
|
}
|
|
501
526
|
if (webhookFired) {
|
|
502
|
-
const newState = recordTrigger(innerAcc.state,
|
|
527
|
+
const newState = recordTrigger(innerAcc.state, cooldownKey, "webhook", ctx.now);
|
|
503
528
|
return { ...innerAcc, state: newState };
|
|
504
529
|
}
|
|
505
530
|
return innerAcc;
|
|
@@ -554,8 +579,17 @@ async function interpret(program, ctx, acc) {
|
|
|
554
579
|
if (attempt < program.maxRetries) {
|
|
555
580
|
const nextAttempt = attempt + 1;
|
|
556
581
|
const nextRetryAt = ctx.now + program.retryDelayMs;
|
|
557
|
-
// Schedule retry: re-run the
|
|
558
|
-
// fires.
|
|
582
|
+
// Schedule retry: re-run the WithRetry NODE (not just its wrapped
|
|
583
|
+
// child) when the timer fires. Re-entering the WithRetry case is
|
|
584
|
+
// what lets each successive failure re-check `attempt < maxRetries`
|
|
585
|
+
// and schedule the next retry — running only `program.program`
|
|
586
|
+
// capped retries at 1 because the inner program never re-enters
|
|
587
|
+
// this branch. The interpret() result already carries the
|
|
588
|
+
// pendingRetries bookkeeping the node performs (record on
|
|
589
|
+
// re-schedule, clear on success/exhaustion), so the retry returns
|
|
590
|
+
// it as-is rather than force-clearing.
|
|
591
|
+
//
|
|
592
|
+
// The work runs INSIDE AutomationHooks' mutation lock
|
|
559
593
|
// (`runRetryUnderLock`) so:
|
|
560
594
|
// 1. Read of live state is atomic w.r.t. concurrent _runInterpreter
|
|
561
595
|
// calls — the retry sees their cooldown / dedup / rateLimit
|
|
@@ -563,15 +597,14 @@ async function interpret(program, ctx, acc) {
|
|
|
563
597
|
// 2. Write of post-retry state is atomic w.r.t. the same chain,
|
|
564
598
|
// so the retry's effects can't be lost to a concurrent run
|
|
565
599
|
// that started between scheduling and merge.
|
|
566
|
-
// 3.
|
|
567
|
-
// pendingRetries entry is dropped even if the inner
|
|
600
|
+
// 3. The catch clears the pendingRetries entry even if the inner
|
|
568
601
|
// interpret() throws (otherwise the retry leaks the entry
|
|
569
602
|
// forever).
|
|
570
603
|
//
|
|
571
604
|
// TestBackend records the call but does not actually fire the timer.
|
|
572
605
|
// Tests that exercise retry dispatch synchronously override
|
|
573
606
|
// `scheduleRetry`.
|
|
574
|
-
const
|
|
607
|
+
const retryProgram = program;
|
|
575
608
|
const retrySnapshot = innerAcc.state;
|
|
576
609
|
const liveStateFn = ctx.getLiveState;
|
|
577
610
|
const runUnderLock = ctx.runRetryUnderLock;
|
|
@@ -584,8 +617,12 @@ async function interpret(program, ctx, acc) {
|
|
|
584
617
|
state: live,
|
|
585
618
|
now: Date.now(),
|
|
586
619
|
};
|
|
587
|
-
|
|
588
|
-
|
|
620
|
+
// Re-enter the WithRetry node so a repeated failure can
|
|
621
|
+
// schedule the next attempt (up to maxRetries). The node
|
|
622
|
+
// owns the pendingRetries lifecycle — return its state
|
|
623
|
+
// directly so a re-scheduled attempt isn't force-cleared.
|
|
624
|
+
const retryResult = await interpret(retryProgram, retryCtx, emptyAcc(live));
|
|
625
|
+
return retryResult.state;
|
|
589
626
|
}
|
|
590
627
|
catch (e) {
|
|
591
628
|
const m = e instanceof Error ? e.message : String(e);
|
|
@@ -612,6 +649,14 @@ async function interpret(program, ctx, acc) {
|
|
|
612
649
|
const newState = recordPendingRetry(innerAcc.state, program.key, nextAttempt, nextRetryAt, "");
|
|
613
650
|
return { ...innerAcc, state: newState };
|
|
614
651
|
}
|
|
652
|
+
// Retries exhausted (attempt >= maxRetries): the inner program still
|
|
653
|
+
// failed but no further retry is scheduled. Drop the pendingRetries
|
|
654
|
+
// entry so it doesn't leak and block a future, unrelated retry for
|
|
655
|
+
// the same key.
|
|
656
|
+
return {
|
|
657
|
+
...innerAcc,
|
|
658
|
+
state: clearPendingRetry(innerAcc.state, program.key),
|
|
659
|
+
};
|
|
615
660
|
}
|
|
616
661
|
return innerAcc;
|
|
617
662
|
}
|