@meetopenbot/claude-code 0.1.2 → 0.1.4
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 +181 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// runtime.ts
|
|
2
|
+
import { execSync } from "node:child_process";
|
|
3
|
+
import { existsSync as existsSync2, readlinkSync as readlinkSync2, statSync as statSync2 } from "node:fs";
|
|
4
|
+
|
|
1
5
|
// node_modules/@anthropic-ai/claude-agent-sdk/sdk.mjs
|
|
2
6
|
import { createRequire as $S } from "node:module";
|
|
3
7
|
import { execFile as E6$ } from "child_process";
|
|
@@ -19425,6 +19429,131 @@ var buildApiKeyWidget = (agentId, threadId, reason) => uiWidget({
|
|
|
19425
19429
|
var toolCallWidgetId = (toolUseId) => `claude_code_tool_${toolUseId}`;
|
|
19426
19430
|
var truncate = (s2, max) => s2.length > max ? `${s2.slice(0, max)}
|
|
19427
19431
|
\u2026` : s2;
|
|
19432
|
+
var MAX_STDERR_CHARS = 4e3;
|
|
19433
|
+
var MAX_ERROR_CHARS = 12e3;
|
|
19434
|
+
var asSystemError = (value) => value && typeof value === "object" ? value : void 0;
|
|
19435
|
+
var spawnFailureHint = (code, executablePath) => {
|
|
19436
|
+
switch (code) {
|
|
19437
|
+
case "EACCES":
|
|
19438
|
+
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.";
|
|
19439
|
+
case "EPERM":
|
|
19440
|
+
return "Operation not permitted when launching Claude Code. Common under sandboxed runtimes or restricted security policies.";
|
|
19441
|
+
case "ENOENT":
|
|
19442
|
+
return executablePath ? `No such file at "${executablePath}", or a required runtime/interpreter is missing.` : "Claude Code executable or required runtime not found.";
|
|
19443
|
+
case "ENOTDIR":
|
|
19444
|
+
case "ELOOP":
|
|
19445
|
+
return "Invalid executable path \u2014 a path component is not a directory or is a symlink loop.";
|
|
19446
|
+
default:
|
|
19447
|
+
return void 0;
|
|
19448
|
+
}
|
|
19449
|
+
};
|
|
19450
|
+
var describePathAccess = (label, path) => {
|
|
19451
|
+
try {
|
|
19452
|
+
if (!existsSync2(path)) return `${label}: missing (${path})`;
|
|
19453
|
+
const st = statSync2(path);
|
|
19454
|
+
const lines = [
|
|
19455
|
+
`${label}: ${path}`,
|
|
19456
|
+
`exists: yes`,
|
|
19457
|
+
`type: ${st.isDirectory() ? "directory" : st.isFile() ? "file" : "other"}`
|
|
19458
|
+
];
|
|
19459
|
+
if (st.isFile()) {
|
|
19460
|
+
lines.push(`size: ${st.size} bytes`);
|
|
19461
|
+
lines.push(`mode: ${(st.mode & 511).toString(8)}`);
|
|
19462
|
+
lines.push(`executable bit: ${(st.mode & 73) !== 0 ? "yes" : "no"}`);
|
|
19463
|
+
}
|
|
19464
|
+
try {
|
|
19465
|
+
const target = readlinkSync2(path);
|
|
19466
|
+
lines.push(`symlink target: ${target}`);
|
|
19467
|
+
lines.push(`target exists: ${existsSync2(target) ? "yes" : "no"}`);
|
|
19468
|
+
} catch {
|
|
19469
|
+
}
|
|
19470
|
+
return lines.join("\n");
|
|
19471
|
+
} catch (inspectError) {
|
|
19472
|
+
return `${label}: could not inspect (${path}): ${inspectError instanceof Error ? inspectError.message : String(inspectError)}`;
|
|
19473
|
+
}
|
|
19474
|
+
};
|
|
19475
|
+
var launchFailureHintsFromInspection = (executableDetails, workingDirDetails, executablePath) => {
|
|
19476
|
+
const hints = [];
|
|
19477
|
+
if (workingDirDetails?.includes("missing")) {
|
|
19478
|
+
hints.push("Working directory does not exist. Create it or remove the cwd override from config.");
|
|
19479
|
+
}
|
|
19480
|
+
if (executableDetails?.includes("executable bit: no")) {
|
|
19481
|
+
const hint = spawnFailureHint("EACCES", executablePath);
|
|
19482
|
+
if (hint) hints.push(hint);
|
|
19483
|
+
}
|
|
19484
|
+
if (executableDetails?.includes("target exists: no")) {
|
|
19485
|
+
hints.push("Executable symlink target is missing. Reinstall Claude Code or point executablePath at a valid binary.");
|
|
19486
|
+
}
|
|
19487
|
+
if (executableDetails?.includes("missing")) {
|
|
19488
|
+
const hint = spawnFailureHint("ENOENT", executablePath);
|
|
19489
|
+
if (hint) hints.push(hint);
|
|
19490
|
+
}
|
|
19491
|
+
if (hints.length === 0) {
|
|
19492
|
+
hints.push(
|
|
19493
|
+
"The Claude Code process could not be started. Verify executablePath, working directory permissions, and that OpenBot can spawn child processes in this environment."
|
|
19494
|
+
);
|
|
19495
|
+
}
|
|
19496
|
+
return hints;
|
|
19497
|
+
};
|
|
19498
|
+
var formatClaudeCodeError = (error, context, stderrChunks) => {
|
|
19499
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
19500
|
+
const parts = [err.message];
|
|
19501
|
+
const causeLines = [];
|
|
19502
|
+
let current = err.cause;
|
|
19503
|
+
while (current) {
|
|
19504
|
+
if (current instanceof Error) {
|
|
19505
|
+
causeLines.push(current.message);
|
|
19506
|
+
const sys2 = asSystemError(current);
|
|
19507
|
+
if (sys2?.code) causeLines.push(` code: ${sys2.code}`);
|
|
19508
|
+
if (sys2?.errno !== void 0) causeLines.push(` errno: ${sys2.errno}`);
|
|
19509
|
+
if (sys2?.syscall) causeLines.push(` syscall: ${sys2.syscall}`);
|
|
19510
|
+
if (sys2?.path) causeLines.push(` path: ${sys2.path}`);
|
|
19511
|
+
current = current.cause;
|
|
19512
|
+
} else {
|
|
19513
|
+
causeLines.push(String(current));
|
|
19514
|
+
break;
|
|
19515
|
+
}
|
|
19516
|
+
}
|
|
19517
|
+
if (causeLines.length > 0) parts.push(`Cause:
|
|
19518
|
+
${causeLines.join("\n")}`);
|
|
19519
|
+
const sys = asSystemError(err.cause) ?? asSystemError(err);
|
|
19520
|
+
const hint = spawnFailureHint(sys?.code, context.executablePath);
|
|
19521
|
+
if (hint) parts.push(hint);
|
|
19522
|
+
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");
|
|
19523
|
+
if (isLaunchFailure) {
|
|
19524
|
+
const executableDetails = context.executablePath ? describePathAccess("Executable", context.executablePath) : "Executable: using SDK bundled binary (no executablePath override).";
|
|
19525
|
+
const workingDirDetails = context.workingDir ? describePathAccess("Working directory", context.workingDir) : void 0;
|
|
19526
|
+
parts.push(`Launch diagnostics:
|
|
19527
|
+
${executableDetails}`);
|
|
19528
|
+
if (workingDirDetails) parts.push(workingDirDetails);
|
|
19529
|
+
if (err.message.includes("failed to launch")) {
|
|
19530
|
+
for (const launchHint of launchFailureHintsFromInspection(
|
|
19531
|
+
executableDetails,
|
|
19532
|
+
workingDirDetails,
|
|
19533
|
+
context.executablePath
|
|
19534
|
+
)) {
|
|
19535
|
+
parts.push(launchHint);
|
|
19536
|
+
}
|
|
19537
|
+
}
|
|
19538
|
+
}
|
|
19539
|
+
const stderr = stderrChunks.join("").trim();
|
|
19540
|
+
if (stderr) parts.push(`Process stderr:
|
|
19541
|
+
${truncate(stderr, MAX_STDERR_CHARS)}`);
|
|
19542
|
+
return truncate(parts.join("\n\n"), MAX_ERROR_CHARS);
|
|
19543
|
+
};
|
|
19544
|
+
var formatResultError = (message) => {
|
|
19545
|
+
if (message.type !== "result" || message.subtype === "success") return "";
|
|
19546
|
+
const record = asRecord(message);
|
|
19547
|
+
const parts = [`subtype: ${message.subtype}`];
|
|
19548
|
+
const result = record.result;
|
|
19549
|
+
if (typeof result === "string" && result) parts.push(`result: ${result}`);
|
|
19550
|
+
const errors = record.errors;
|
|
19551
|
+
if (Array.isArray(errors) && errors.length > 0) {
|
|
19552
|
+
parts.push(`errors:
|
|
19553
|
+
${errors.map((entry) => `- ${String(entry)}`).join("\n")}`);
|
|
19554
|
+
}
|
|
19555
|
+
return parts.join("\n");
|
|
19556
|
+
};
|
|
19428
19557
|
var formatJsonForWidget = (value, maxLen) => {
|
|
19429
19558
|
try {
|
|
19430
19559
|
return truncate(JSON.stringify(value, null, 2), maxLen);
|
|
@@ -19432,6 +19561,15 @@ var formatJsonForWidget = (value, maxLen) => {
|
|
|
19432
19561
|
return truncate(String(value), maxLen);
|
|
19433
19562
|
}
|
|
19434
19563
|
};
|
|
19564
|
+
var formatToolInputBody = (input, maxLen = 8e3) => `Input:
|
|
19565
|
+
${formatJsonForWidget(input, maxLen)}`;
|
|
19566
|
+
var formatToolResultBody = (input, output) => {
|
|
19567
|
+
const inputSection = formatJsonForWidget(input, 4e3);
|
|
19568
|
+
const parts = [`Input:
|
|
19569
|
+
${inputSection}`, `Output:
|
|
19570
|
+
${output}`];
|
|
19571
|
+
return parts.join("\n\n");
|
|
19572
|
+
};
|
|
19435
19573
|
var formatToolResultPayload = (content, isError) => {
|
|
19436
19574
|
let body;
|
|
19437
19575
|
if (typeof content === "string") {
|
|
@@ -19481,15 +19619,28 @@ var parseToolResultBlock = (block) => {
|
|
|
19481
19619
|
}
|
|
19482
19620
|
return null;
|
|
19483
19621
|
};
|
|
19622
|
+
var findClaudeExecutable = () => {
|
|
19623
|
+
try {
|
|
19624
|
+
const command = process.platform === "win32" ? "where claude" : "which claude";
|
|
19625
|
+
const path = execSync(command, { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
|
19626
|
+
if (path && existsSync2(path)) {
|
|
19627
|
+
return path;
|
|
19628
|
+
}
|
|
19629
|
+
} catch {
|
|
19630
|
+
}
|
|
19631
|
+
return void 0;
|
|
19632
|
+
};
|
|
19484
19633
|
var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
19485
19634
|
const {
|
|
19486
19635
|
model = "sonnet",
|
|
19487
19636
|
system,
|
|
19488
19637
|
permissionMode = "default",
|
|
19489
19638
|
cwd,
|
|
19639
|
+
executablePath: executablePathOverride,
|
|
19490
19640
|
allowedTools,
|
|
19491
19641
|
storage
|
|
19492
19642
|
} = options;
|
|
19643
|
+
const executablePath = executablePathOverride || findClaudeExecutable();
|
|
19493
19644
|
builder.on("agent:invoke", async function* (event, context) {
|
|
19494
19645
|
if (!shouldHandleInvoke(event, context.state.agentId)) {
|
|
19495
19646
|
return;
|
|
@@ -19499,12 +19650,21 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19499
19650
|
const threadId = event.meta?.threadId || context.state.threadId;
|
|
19500
19651
|
const resumeId = readPersistedSessionId(context.state);
|
|
19501
19652
|
const workingDir = cwd ?? context.state.channelDetails?.cwd;
|
|
19653
|
+
const stderrChunks = [];
|
|
19654
|
+
const launchContext = {
|
|
19655
|
+
executablePath,
|
|
19656
|
+
workingDir
|
|
19657
|
+
};
|
|
19502
19658
|
const sdkOptions = {
|
|
19503
19659
|
model,
|
|
19504
19660
|
permissionMode,
|
|
19661
|
+
stderr: (data) => {
|
|
19662
|
+
stderrChunks.push(data);
|
|
19663
|
+
},
|
|
19505
19664
|
...system ? { systemPrompt: { type: "preset", preset: "claude_code", append: system } } : {},
|
|
19506
19665
|
...resumeId ? { resume: resumeId } : {},
|
|
19507
19666
|
...workingDir ? { cwd: workingDir } : {},
|
|
19667
|
+
...executablePath ? { pathToClaudeCodeExecutable: executablePath } : {},
|
|
19508
19668
|
...allowedTools ? { allowedTools } : {}
|
|
19509
19669
|
};
|
|
19510
19670
|
try {
|
|
@@ -19550,8 +19710,8 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19550
19710
|
kind: "message",
|
|
19551
19711
|
widgetId: toolCallWidgetId(tool.toolUseId),
|
|
19552
19712
|
title: toolTitleByUseId.get(tool.toolUseId)?.title ?? "",
|
|
19553
|
-
description:
|
|
19554
|
-
body:
|
|
19713
|
+
description: "",
|
|
19714
|
+
body: formatToolInputBody(tool.input),
|
|
19555
19715
|
display: "collapsed",
|
|
19556
19716
|
metadata: {
|
|
19557
19717
|
type: "claude_tool",
|
|
@@ -19597,8 +19757,11 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19597
19757
|
kind: "message",
|
|
19598
19758
|
widgetId: toolCallWidgetId(res.toolUseId),
|
|
19599
19759
|
title: toolTitleByUseId.get(res.toolUseId)?.title ?? "",
|
|
19600
|
-
description:
|
|
19601
|
-
body
|
|
19760
|
+
description: "",
|
|
19761
|
+
body: formatToolResultBody(
|
|
19762
|
+
toolTitleByUseId.get(res.toolUseId)?.input,
|
|
19763
|
+
body
|
|
19764
|
+
),
|
|
19602
19765
|
display: "collapsed",
|
|
19603
19766
|
...state ? { state } : {},
|
|
19604
19767
|
metadata: {
|
|
@@ -19620,10 +19783,12 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19620
19783
|
yield buildApiKeyWidget(context.state.agentId, threadId, subtype);
|
|
19621
19784
|
return;
|
|
19622
19785
|
}
|
|
19786
|
+
const details = formatResultError(message);
|
|
19623
19787
|
yield agentOutput({
|
|
19624
19788
|
agentId: context.state.agentId,
|
|
19625
19789
|
threadId,
|
|
19626
|
-
content: `[claude-code] run ended with error:
|
|
19790
|
+
content: details ? `[claude-code] run ended with error:
|
|
19791
|
+
${details}` : `[claude-code] run ended with error: ${subtype}`
|
|
19627
19792
|
});
|
|
19628
19793
|
}
|
|
19629
19794
|
}
|
|
@@ -19631,7 +19796,7 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19631
19796
|
await persistSessionId(context.state, storage, lastSessionId);
|
|
19632
19797
|
}
|
|
19633
19798
|
} catch (error) {
|
|
19634
|
-
const errorMessage = error
|
|
19799
|
+
const errorMessage = formatClaudeCodeError(error, launchContext, stderrChunks);
|
|
19635
19800
|
if (isAuthErrorMessage(errorMessage)) {
|
|
19636
19801
|
yield buildApiKeyWidget(context.state.agentId, threadId, errorMessage);
|
|
19637
19802
|
return;
|
|
@@ -19639,7 +19804,8 @@ var claudeCodeRuntime = (options = {}) => (builder) => {
|
|
|
19639
19804
|
yield agentOutput({
|
|
19640
19805
|
agentId: context.state.agentId,
|
|
19641
19806
|
threadId,
|
|
19642
|
-
content: `[claude-code] error:
|
|
19807
|
+
content: `[claude-code] error:
|
|
19808
|
+
${errorMessage}`
|
|
19643
19809
|
});
|
|
19644
19810
|
}
|
|
19645
19811
|
});
|
|
@@ -19708,17 +19874,23 @@ var claudeCodePlugin = {
|
|
|
19708
19874
|
permissionMode: {
|
|
19709
19875
|
type: "string",
|
|
19710
19876
|
description: "How the SDK handles tool permission prompts: default | acceptEdits | bypassPermissions | plan | dontAsk | auto.",
|
|
19711
|
-
default: "
|
|
19877
|
+
default: "bypassPermissions",
|
|
19712
19878
|
enum: ["default", "acceptEdits", "bypassPermissions", "plan", "dontAsk", "auto"]
|
|
19879
|
+
},
|
|
19880
|
+
executablePath: {
|
|
19881
|
+
type: "string",
|
|
19882
|
+
description: "Path to the Claude Code CLI executable. When unset, the plugin attempts to find it in your PATH, falling back to the SDK bundled binary."
|
|
19713
19883
|
}
|
|
19714
19884
|
}
|
|
19715
19885
|
},
|
|
19716
19886
|
factory: ({ agentDetails, config, storage }) => {
|
|
19717
19887
|
const model = typeof config.model === "string" && config.model ? config.model : "sonnet";
|
|
19718
|
-
const permissionMode = typeof config.permissionMode === "string" && config.permissionMode ? config.permissionMode : "
|
|
19888
|
+
const permissionMode = typeof config.permissionMode === "string" && config.permissionMode ? config.permissionMode : "bypassPermissions";
|
|
19889
|
+
const executablePath = typeof config.executablePath === "string" && config.executablePath ? config.executablePath : void 0;
|
|
19719
19890
|
return claudeCodeRuntime({
|
|
19720
19891
|
model,
|
|
19721
19892
|
permissionMode,
|
|
19893
|
+
executablePath,
|
|
19722
19894
|
system: agentDetails.instructions || CLAUDE_CODE_SYSTEM_PROMPT,
|
|
19723
19895
|
storage
|
|
19724
19896
|
});
|