@meetopenbot/claude-code 0.1.2 → 0.1.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/index.js +166 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// runtime.ts
|
|
2
|
+
import { existsSync as existsSync2, readlinkSync as readlinkSync2, statSync as statSync2 } from "node:fs";
|
|
3
|
+
|
|
1
4
|
// node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
2
5
|
import { createRequire as $S } from "node:module";
|
|
3
6
|
import { execFile as E6$ } from "child_process";
|
|
@@ -19425,6 +19428,131 @@ var buildApiKeyWidget = (agentId, threadId, reason) => uiWidget({
|
|
|
19425
19428
|
var toolCallWidgetId = (toolUseId) => `claude_code_tool_${toolUseId}`;
|
|
19426
19429
|
var truncate = (s2, max) => s2.length > max ? `${s2.slice(0, max)}
|
|
19427
19430
|
\u2026` : s2;
|
|
19431
|
+
var MAX_STDERR_CHARS = 4e3;
|
|
19432
|
+
var MAX_ERROR_CHARS = 12e3;
|
|
19433
|
+
var asSystemError = (value) => value && typeof value === "object" ? value : void 0;
|
|
19434
|
+
var spawnFailureHint = (code, executablePath) => {
|
|
19435
|
+
switch (code) {
|
|
19436
|
+
case "EACCES":
|
|
19437
|
+
return executablePath ? `Permission denied executing "${executablePath}". Check chmod +x and macOS quarantine (xattr -d com.apple.quarantine "${executablePath}").` : "Permission denied executing the Claude Code binary.";
|
|
19438
|
+
case "EPERM":
|
|
19439
|
+
return "Operation not permitted when launching Claude Code. Common under sandboxed runtimes or restricted security policies.";
|
|
19440
|
+
case "ENOENT":
|
|
19441
|
+
return executablePath ? `No such file at "${executablePath}", or a required runtime/interpreter is missing.` : "Claude Code executable or required runtime not found.";
|
|
19442
|
+
case "ENOTDIR":
|
|
19443
|
+
case "ELOOP":
|
|
19444
|
+
return "Invalid executable path \u2014 a path component is not a directory or is a symlink loop.";
|
|
19445
|
+
default:
|
|
19446
|
+
return void 0;
|
|
19447
|
+
}
|
|
19448
|
+
};
|
|
19449
|
+
var describePathAccess = (label, path) => {
|
|
19450
|
+
try {
|
|
19451
|
+
if (!existsSync2(path)) return `${label}: missing (${path})`;
|
|
19452
|
+
const st = statSync2(path);
|
|
19453
|
+
const lines = [
|
|
19454
|
+
`${label}: ${path}`,
|
|
19455
|
+
`exists: yes`,
|
|
19456
|
+
`type: ${st.isDirectory() ? "directory" : st.isFile() ? "file" : "other"}`
|
|
19457
|
+
];
|
|
19458
|
+
if (st.isFile()) {
|
|
19459
|
+
lines.push(`size: ${st.size} bytes`);
|
|
19460
|
+
lines.push(`mode: ${(st.mode & 511).toString(8)}`);
|
|
19461
|
+
lines.push(`executable bit: ${(st.mode & 73) !== 0 ? "yes" : "no"}`);
|
|
19462
|
+
}
|
|
19463
|
+
try {
|
|
19464
|
+
const target = readlinkSync2(path);
|
|
19465
|
+
lines.push(`symlink target: ${target}`);
|
|
19466
|
+
lines.push(`target exists: ${existsSync2(target) ? "yes" : "no"}`);
|
|
19467
|
+
} catch {
|
|
19468
|
+
}
|
|
19469
|
+
return lines.join("\n");
|
|
19470
|
+
} catch (inspectError) {
|
|
19471
|
+
return `${label}: could not inspect (${path}): ${inspectError instanceof Error ? inspectError.message : String(inspectError)}`;
|
|
19472
|
+
}
|
|
19473
|
+
};
|
|
19474
|
+
var launchFailureHintsFromInspection = (executableDetails, workingDirDetails, executablePath) => {
|
|
19475
|
+
const hints = [];
|
|
19476
|
+
if (workingDirDetails?.includes("missing")) {
|
|
19477
|
+
hints.push("Working directory does not exist. Create it or remove the cwd override from config.");
|
|
19478
|
+
}
|
|
19479
|
+
if (executableDetails?.includes("executable bit: no")) {
|
|
19480
|
+
const hint = spawnFailureHint("EACCES", executablePath);
|
|
19481
|
+
if (hint) hints.push(hint);
|
|
19482
|
+
}
|
|
19483
|
+
if (executableDetails?.includes("target exists: no")) {
|
|
19484
|
+
hints.push("Executable symlink target is missing. Reinstall Claude Code or point executablePath at a valid binary.");
|
|
19485
|
+
}
|
|
19486
|
+
if (executableDetails?.includes("missing")) {
|
|
19487
|
+
const hint = spawnFailureHint("ENOENT", executablePath);
|
|
19488
|
+
if (hint) hints.push(hint);
|
|
19489
|
+
}
|
|
19490
|
+
if (hints.length === 0) {
|
|
19491
|
+
hints.push(
|
|
19492
|
+
"The Claude Code process could not be started. Verify executablePath, working directory permissions, and that OpenBot can spawn child processes in this environment."
|
|
19493
|
+
);
|
|
19494
|
+
}
|
|
19495
|
+
return hints;
|
|
19496
|
+
};
|
|
19497
|
+
var formatClaudeCodeError = (error, context, stderrChunks) => {
|
|
19498
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
19499
|
+
const parts = [err.message];
|
|
19500
|
+
const causeLines = [];
|
|
19501
|
+
let current = err.cause;
|
|
19502
|
+
while (current) {
|
|
19503
|
+
if (current instanceof Error) {
|
|
19504
|
+
causeLines.push(current.message);
|
|
19505
|
+
const sys2 = asSystemError(current);
|
|
19506
|
+
if (sys2?.code) causeLines.push(` code: ${sys2.code}`);
|
|
19507
|
+
if (sys2?.errno !== void 0) causeLines.push(` errno: ${sys2.errno}`);
|
|
19508
|
+
if (sys2?.syscall) causeLines.push(` syscall: ${sys2.syscall}`);
|
|
19509
|
+
if (sys2?.path) causeLines.push(` path: ${sys2.path}`);
|
|
19510
|
+
current = current.cause;
|
|
19511
|
+
} else {
|
|
19512
|
+
causeLines.push(String(current));
|
|
19513
|
+
break;
|
|
19514
|
+
}
|
|
19515
|
+
}
|
|
19516
|
+
if (causeLines.length > 0) parts.push(`Cause:
|
|
19517
|
+
${causeLines.join("\n")}`);
|
|
19518
|
+
const sys = asSystemError(err.cause) ?? asSystemError(err);
|
|
19519
|
+
const hint = spawnFailureHint(sys?.code, context.executablePath);
|
|
19520
|
+
if (hint) parts.push(hint);
|
|
19521
|
+
const isLaunchFailure = err.message.includes("failed to launch") || err.message.includes("not found") || err.message.includes("Failed to spawn") || err.message.includes("exited with code") || err.message.includes("terminated by signal");
|
|
19522
|
+
if (isLaunchFailure) {
|
|
19523
|
+
const executableDetails = context.executablePath ? describePathAccess("Executable", context.executablePath) : "Executable: using SDK bundled binary (no executablePath override).";
|
|
19524
|
+
const workingDirDetails = context.workingDir ? describePathAccess("Working directory", context.workingDir) : void 0;
|
|
19525
|
+
parts.push(`Launch diagnostics:
|
|
19526
|
+
${executableDetails}`);
|
|
19527
|
+
if (workingDirDetails) parts.push(workingDirDetails);
|
|
19528
|
+
if (err.message.includes("failed to launch")) {
|
|
19529
|
+
for (const launchHint of launchFailureHintsFromInspection(
|
|
19530
|
+
executableDetails,
|
|
19531
|
+
workingDirDetails,
|
|
19532
|
+
context.executablePath
|
|
19533
|
+
)) {
|
|
19534
|
+
parts.push(launchHint);
|
|
19535
|
+
}
|
|
19536
|
+
}
|
|
19537
|
+
}
|
|
19538
|
+
const stderr = stderrChunks.join("").trim();
|
|
19539
|
+
if (stderr) parts.push(`Process stderr:
|
|
19540
|
+
${truncate(stderr, MAX_STDERR_CHARS)}`);
|
|
19541
|
+
return truncate(parts.join("\n\n"), MAX_ERROR_CHARS);
|
|
19542
|
+
};
|
|
19543
|
+
var formatResultError = (message) => {
|
|
19544
|
+
if (message.type !== "result" || message.subtype === "success") return "";
|
|
19545
|
+
const record = asRecord(message);
|
|
19546
|
+
const parts = [`subtype: ${message.subtype}`];
|
|
19547
|
+
const result = record.result;
|
|
19548
|
+
if (typeof result === "string" && result) parts.push(`result: ${result}`);
|
|
19549
|
+
const errors = record.errors;
|
|
19550
|
+
if (Array.isArray(errors) && errors.length > 0) {
|
|
19551
|
+
parts.push(`errors:
|
|
19552
|
+
${errors.map((entry) => `- ${String(entry)}`).join("\n")}`);
|
|
19553
|
+
}
|
|
19554
|
+
return parts.join("\n");
|
|
19555
|
+
};
|
|
19428
19556
|
var formatJsonForWidget = (value, maxLen) => {
|
|
19429
19557
|
try {
|
|
19430
19558
|
return truncate(JSON.stringify(value, null, 2), maxLen);
|
|
@@ -19432,6 +19560,15 @@ var formatJsonForWidget = (value, maxLen) => {
|
|
|
19432
19560
|
return truncate(String(value), maxLen);
|
|
19433
19561
|
}
|
|
19434
19562
|
};
|
|
19563
|
+
var formatToolInputBody = (input, maxLen = 8e3) => `Input:
|
|
19564
|
+
${formatJsonForWidget(input, maxLen)}`;
|
|
19565
|
+
var formatToolResultBody = (input, output) => {
|
|
19566
|
+
const inputSection = formatJsonForWidget(input, 4e3);
|
|
19567
|
+
const parts = [`Input:
|
|
19568
|
+
${inputSection}`, `Output:
|
|
19569
|
+
${output}`];
|
|
19570
|
+
return parts.join("\n\n");
|
|
19571
|
+
};
|
|
19435
19572
|
var formatToolResultPayload = (content, isError) => {
|
|
19436
19573
|
let body;
|
|
19437
19574
|
if (typeof content === "string") {
|
|
@@ -19487,6 +19624,7 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19487
19624
|
system,
|
|
19488
19625
|
permissionMode = "default",
|
|
19489
19626
|
cwd,
|
|
19627
|
+
executablePath,
|
|
19490
19628
|
allowedTools,
|
|
19491
19629
|
storage
|
|
19492
19630
|
} = options;
|
|
@@ -19499,12 +19637,21 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19499
19637
|
const threadId = event.meta?.threadId || context.state.threadId;
|
|
19500
19638
|
const resumeId = readPersistedSessionId(context.state);
|
|
19501
19639
|
const workingDir = cwd ?? context.state.channelDetails?.cwd;
|
|
19640
|
+
const stderrChunks = [];
|
|
19641
|
+
const launchContext = {
|
|
19642
|
+
executablePath,
|
|
19643
|
+
workingDir
|
|
19644
|
+
};
|
|
19502
19645
|
const sdkOptions = {
|
|
19503
19646
|
model,
|
|
19504
19647
|
permissionMode,
|
|
19648
|
+
stderr: (data) => {
|
|
19649
|
+
stderrChunks.push(data);
|
|
19650
|
+
},
|
|
19505
19651
|
...system ? { systemPrompt: { type: "preset", preset: "claude_code", append: system } } : {},
|
|
19506
19652
|
...resumeId ? { resume: resumeId } : {},
|
|
19507
19653
|
...workingDir ? { cwd: workingDir } : {},
|
|
19654
|
+
...executablePath ? { pathToClaudeCodeExecutable: executablePath } : {},
|
|
19508
19655
|
...allowedTools ? { allowedTools } : {}
|
|
19509
19656
|
};
|
|
19510
19657
|
try {
|
|
@@ -19550,8 +19697,8 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19550
19697
|
kind: "message",
|
|
19551
19698
|
widgetId: toolCallWidgetId(tool.toolUseId),
|
|
19552
19699
|
title: toolTitleByUseId.get(tool.toolUseId)?.title ?? "",
|
|
19553
|
-
description:
|
|
19554
|
-
body:
|
|
19700
|
+
description: "",
|
|
19701
|
+
body: formatToolInputBody(tool.input),
|
|
19555
19702
|
display: "collapsed",
|
|
19556
19703
|
metadata: {
|
|
19557
19704
|
type: "claude_tool",
|
|
@@ -19597,8 +19744,11 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19597
19744
|
kind: "message",
|
|
19598
19745
|
widgetId: toolCallWidgetId(res.toolUseId),
|
|
19599
19746
|
title: toolTitleByUseId.get(res.toolUseId)?.title ?? "",
|
|
19600
|
-
description:
|
|
19601
|
-
body
|
|
19747
|
+
description: "",
|
|
19748
|
+
body: formatToolResultBody(
|
|
19749
|
+
toolTitleByUseId.get(res.toolUseId)?.input,
|
|
19750
|
+
body
|
|
19751
|
+
),
|
|
19602
19752
|
display: "collapsed",
|
|
19603
19753
|
...state ? { state } : {},
|
|
19604
19754
|
metadata: {
|
|
@@ -19620,10 +19770,12 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19620
19770
|
yield buildApiKeyWidget(context.state.agentId, threadId, subtype);
|
|
19621
19771
|
return;
|
|
19622
19772
|
}
|
|
19773
|
+
const details = formatResultError(message);
|
|
19623
19774
|
yield agentOutput({
|
|
19624
19775
|
agentId: context.state.agentId,
|
|
19625
19776
|
threadId,
|
|
19626
|
-
content: `[claude-code] run ended with error:
|
|
19777
|
+
content: details ? `[claude-code] run ended with error:
|
|
19778
|
+
${details}` : `[claude-code] run ended with error: ${subtype}`
|
|
19627
19779
|
});
|
|
19628
19780
|
}
|
|
19629
19781
|
}
|
|
@@ -19631,7 +19783,7 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19631
19783
|
await persistSessionId(context.state, storage, lastSessionId);
|
|
19632
19784
|
}
|
|
19633
19785
|
} catch (error) {
|
|
19634
|
-
const errorMessage = error
|
|
19786
|
+
const errorMessage = formatClaudeCodeError(error, launchContext, stderrChunks);
|
|
19635
19787
|
if (isAuthErrorMessage(errorMessage)) {
|
|
19636
19788
|
yield buildApiKeyWidget(context.state.agentId, threadId, errorMessage);
|
|
19637
19789
|
return;
|
|
@@ -19639,7 +19791,8 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19639
19791
|
yield agentOutput({
|
|
19640
19792
|
agentId: context.state.agentId,
|
|
19641
19793
|
threadId,
|
|
19642
|
-
content: `[claude-code] error:
|
|
19794
|
+
content: `[claude-code] error:
|
|
19795
|
+
${errorMessage}`
|
|
19643
19796
|
});
|
|
19644
19797
|
}
|
|
19645
19798
|
});
|
|
@@ -19710,15 +19863,21 @@ var claudeCodePlugin = {
|
|
|
19710
19863
|
description: "How the SDK handles tool permission prompts: default | acceptEdits | bypassPermissions | plan | dontAsk | auto.",
|
|
19711
19864
|
default: "default",
|
|
19712
19865
|
enum: ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"]
|
|
19866
|
+
},
|
|
19867
|
+
executablePath: {
|
|
19868
|
+
type: "string",
|
|
19869
|
+
description: "Path to the Claude Code CLI executable. When unset, the SDK uses its bundled binary."
|
|
19713
19870
|
}
|
|
19714
19871
|
}
|
|
19715
19872
|
},
|
|
19716
19873
|
factory: ({ agentDetails, config, storage }) => {
|
|
19717
19874
|
const model = typeof config.model === "string" && config.model ? config.model : "sonnet";
|
|
19718
19875
|
const permissionMode = typeof config.permissionMode === "string" && config.permissionMode ? config.permissionMode : "default";
|
|
19876
|
+
const executablePath = typeof config.executablePath === "string" && config.executablePath ? config.executablePath : void 0;
|
|
19719
19877
|
return claudeCodeRuntime({
|
|
19720
19878
|
model,
|
|
19721
19879
|
permissionMode,
|
|
19880
|
+
executablePath,
|
|
19722
19881
|
system: agentDetails.instructions || CLAUDE_CODE_SYSTEM_PROMPT,
|
|
19723
19882
|
storage
|
|
19724
19883
|
});
|