@ycodium-ai/agent-claude 0.2.3064 → 0.2.3072
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 +170 -9
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -22173,16 +22173,16 @@ function tokenizeShellWords(value) {
|
|
|
22173
22173
|
if (!input) return [];
|
|
22174
22174
|
const tokens = [];
|
|
22175
22175
|
let current = "";
|
|
22176
|
-
let
|
|
22176
|
+
let quote2;
|
|
22177
22177
|
let quoted = false;
|
|
22178
22178
|
for (let index = 0; index < input.length; index++) {
|
|
22179
22179
|
const char = input[index];
|
|
22180
22180
|
if (char === void 0) continue;
|
|
22181
|
-
if (
|
|
22182
|
-
if (char ===
|
|
22183
|
-
|
|
22181
|
+
if (quote2) {
|
|
22182
|
+
if (char === quote2) {
|
|
22183
|
+
quote2 = void 0;
|
|
22184
22184
|
quoted = true;
|
|
22185
|
-
} else if (char === "\\" &&
|
|
22185
|
+
} else if (char === "\\" && quote2 === '"') {
|
|
22186
22186
|
const next = input[index + 1];
|
|
22187
22187
|
if (next !== void 0 && ['"', "\\", "$", "`"].includes(next)) {
|
|
22188
22188
|
current += next;
|
|
@@ -22196,7 +22196,7 @@ function tokenizeShellWords(value) {
|
|
|
22196
22196
|
continue;
|
|
22197
22197
|
}
|
|
22198
22198
|
if (char === "'" || char === '"') {
|
|
22199
|
-
|
|
22199
|
+
quote2 = char;
|
|
22200
22200
|
quoted = true;
|
|
22201
22201
|
} else if (/\s/.test(char)) {
|
|
22202
22202
|
if (current || quoted) {
|
|
@@ -23532,6 +23532,7 @@ var makeSessionLifecycle = (deps) => {
|
|
|
23532
23532
|
await completeTurn(context, "interrupted", "Session stopped.");
|
|
23533
23533
|
}
|
|
23534
23534
|
if (closeFailure) throw closeFailure;
|
|
23535
|
+
context.cliProcess.clear();
|
|
23535
23536
|
context.promptQueue.terminate();
|
|
23536
23537
|
const streamFiber = context.streamFiber;
|
|
23537
23538
|
context.streamFiber = void 0;
|
|
@@ -23650,6 +23651,106 @@ var makeSessionLifecycle = (deps) => {
|
|
|
23650
23651
|
};
|
|
23651
23652
|
};
|
|
23652
23653
|
|
|
23654
|
+
// src/claudeProcess.ts
|
|
23655
|
+
import * as NodeEvents from "node:events";
|
|
23656
|
+
import * as NodeStream from "node:stream";
|
|
23657
|
+
import { adoptChildStdin, nodeWritableFromHandle } from "@ycodium-ai/plugin-api/process-stdin";
|
|
23658
|
+
var asError = (cause) => cause instanceof Error ? cause : new Error(String(cause));
|
|
23659
|
+
var ClaudeProcess = class extends NodeEvents.EventEmitter {
|
|
23660
|
+
stdin;
|
|
23661
|
+
stdout;
|
|
23662
|
+
killed = false;
|
|
23663
|
+
exitCode = null;
|
|
23664
|
+
handle;
|
|
23665
|
+
ended = false;
|
|
23666
|
+
constructor(host, options, stderr) {
|
|
23667
|
+
super();
|
|
23668
|
+
const env2 = {
|
|
23669
|
+
...Object.fromEntries(Object.keys(process.env).map((key) => [key, void 0])),
|
|
23670
|
+
...options.env
|
|
23671
|
+
};
|
|
23672
|
+
const ready = host.process.spawn({
|
|
23673
|
+
program: options.command,
|
|
23674
|
+
args: options.args,
|
|
23675
|
+
...options.cwd === void 0 ? {} : { cwd: options.cwd },
|
|
23676
|
+
env: env2,
|
|
23677
|
+
owner: { bindingId: host.bindingId }
|
|
23678
|
+
});
|
|
23679
|
+
this.stdin = nodeWritableFromHandle({
|
|
23680
|
+
writeStdin: (chunk) => ready.then((handle) => handle.writeStdin(chunk)),
|
|
23681
|
+
closeStdin: () => ready.then((handle) => handle.closeStdin())
|
|
23682
|
+
});
|
|
23683
|
+
this.stdout = NodeStream.Readable.from(
|
|
23684
|
+
(async function* () {
|
|
23685
|
+
const handle = await ready.catch(() => void 0);
|
|
23686
|
+
if (handle) yield* handle.stdout;
|
|
23687
|
+
})(),
|
|
23688
|
+
{ objectMode: false }
|
|
23689
|
+
);
|
|
23690
|
+
adoptChildStdin(this.stdin, {
|
|
23691
|
+
onError: (error) => {
|
|
23692
|
+
this.emit("error", error);
|
|
23693
|
+
}
|
|
23694
|
+
});
|
|
23695
|
+
this.stdout.on("error", (error) => this.emit("error", error));
|
|
23696
|
+
this.requestKill = (signal) => {
|
|
23697
|
+
void ready.then((handle) => this.ended ? void 0 : handle.kill(signal)).catch((cause) => this.emit("error", asError(cause)));
|
|
23698
|
+
};
|
|
23699
|
+
const abort = () => {
|
|
23700
|
+
this.kill("SIGTERM");
|
|
23701
|
+
};
|
|
23702
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
23703
|
+
if (options.signal.aborted) abort();
|
|
23704
|
+
void ready.then(async (handle) => {
|
|
23705
|
+
this.handle = handle;
|
|
23706
|
+
const drainStderr = (async () => {
|
|
23707
|
+
const decoder = new TextDecoder();
|
|
23708
|
+
for await (const chunk of handle.stderr) stderr(decoder.decode(chunk, { stream: true }));
|
|
23709
|
+
const tail = decoder.decode();
|
|
23710
|
+
if (tail) stderr(tail);
|
|
23711
|
+
})();
|
|
23712
|
+
void drainStderr.catch((cause) => this.emit("error", asError(cause)));
|
|
23713
|
+
try {
|
|
23714
|
+
const code = await handle.exited;
|
|
23715
|
+
this.ended = true;
|
|
23716
|
+
this.handle = void 0;
|
|
23717
|
+
this.exitCode = code;
|
|
23718
|
+
this.emit("exit", code, null);
|
|
23719
|
+
} finally {
|
|
23720
|
+
options.signal.removeEventListener("abort", abort);
|
|
23721
|
+
}
|
|
23722
|
+
}).catch((cause) => {
|
|
23723
|
+
this.ended = true;
|
|
23724
|
+
this.handle = void 0;
|
|
23725
|
+
options.signal.removeEventListener("abort", abort);
|
|
23726
|
+
this.emit("error", asError(cause));
|
|
23727
|
+
});
|
|
23728
|
+
}
|
|
23729
|
+
requestKill;
|
|
23730
|
+
kill(signal) {
|
|
23731
|
+
if (this.ended || signal !== "SIGTERM" && signal !== "SIGKILL") return false;
|
|
23732
|
+
this.killed = true;
|
|
23733
|
+
this.requestKill(signal);
|
|
23734
|
+
return true;
|
|
23735
|
+
}
|
|
23736
|
+
};
|
|
23737
|
+
function makeClaudeProcessSpawner(host, stderr) {
|
|
23738
|
+
let process2;
|
|
23739
|
+
let launch;
|
|
23740
|
+
return {
|
|
23741
|
+
spawn: (options) => {
|
|
23742
|
+
launch = options;
|
|
23743
|
+
process2 = new ClaudeProcess(host, options, stderr);
|
|
23744
|
+
return process2;
|
|
23745
|
+
},
|
|
23746
|
+
current: () => process2?.handle && launch ? { handle: process2.handle, command: launch.command, args: launch.args } : void 0,
|
|
23747
|
+
clear: () => {
|
|
23748
|
+
process2 = void 0;
|
|
23749
|
+
launch = void 0;
|
|
23750
|
+
}
|
|
23751
|
+
};
|
|
23752
|
+
}
|
|
23753
|
+
|
|
23653
23754
|
// src/readOnlyDirectories.ts
|
|
23654
23755
|
var GLOB_METACHARACTERS = /[*?[\]{}]/;
|
|
23655
23756
|
function toClaudeAbsolutePath(directory) {
|
|
@@ -23832,7 +23933,9 @@ var makeStartSession = (deps) => {
|
|
|
23832
23933
|
querySettings.permissions = { allow: [...readAllowRules] };
|
|
23833
23934
|
}
|
|
23834
23935
|
const stderrTail = createOutputTail(CLAUDE_STDERR_TAIL_CHARS);
|
|
23936
|
+
const cliProcess = makeClaudeProcessSpawner(deps.host, stderrTail.append);
|
|
23835
23937
|
const queryOptions = {
|
|
23938
|
+
spawnClaudeCodeProcess: cliProcess.spawn,
|
|
23836
23939
|
...input.cwd ? { cwd: input.cwd } : {},
|
|
23837
23940
|
...apiModelId ? { model: apiModelId } : {},
|
|
23838
23941
|
pathToClaudeCodeExecutable: claudeSdkExecutablePath,
|
|
@@ -23847,7 +23950,6 @@ var makeStartSession = (deps) => {
|
|
|
23847
23950
|
...existingResumeSessionId ? { resume: existingResumeSessionId } : {},
|
|
23848
23951
|
...newSessionId ? { sessionId: newSessionId } : {},
|
|
23849
23952
|
includePartialMessages: true,
|
|
23850
|
-
stderr: stderrTail.append,
|
|
23851
23953
|
canUseTool,
|
|
23852
23954
|
onUserDialog,
|
|
23853
23955
|
hooks: {
|
|
@@ -23878,6 +23980,7 @@ var makeStartSession = (deps) => {
|
|
|
23878
23980
|
options: queryOptions
|
|
23879
23981
|
});
|
|
23880
23982
|
} catch (cause) {
|
|
23983
|
+
cliProcess.clear();
|
|
23881
23984
|
throw new Error("Failed to start Claude runtime session.", { cause });
|
|
23882
23985
|
}
|
|
23883
23986
|
const session = {
|
|
@@ -23906,6 +24009,7 @@ var makeStartSession = (deps) => {
|
|
|
23906
24009
|
},
|
|
23907
24010
|
promptQueue,
|
|
23908
24011
|
query: queryRuntime,
|
|
24012
|
+
cliProcess,
|
|
23909
24013
|
stderrTail,
|
|
23910
24014
|
streamFiber: void 0,
|
|
23911
24015
|
startedAt,
|
|
@@ -23925,6 +24029,7 @@ var makeStartSession = (deps) => {
|
|
|
23925
24029
|
pendingUserInputs,
|
|
23926
24030
|
turns: [],
|
|
23927
24031
|
inFlightTools,
|
|
24032
|
+
openBashTools: /* @__PURE__ */ new Map(),
|
|
23928
24033
|
claudeTasks,
|
|
23929
24034
|
taskAgents,
|
|
23930
24035
|
pendingTaskModels,
|
|
@@ -24107,6 +24212,7 @@ var makeStreamEventHandler = (deps) => {
|
|
|
24107
24212
|
};
|
|
24108
24213
|
const nextFingerprint = parsedInput && Object.keys(parsedInput).length > 0 ? toolInputFingerprint(parsedInput) : void 0;
|
|
24109
24214
|
context.inFlightTools.set(event.index, nextTool);
|
|
24215
|
+
if (nextTool.toolName === "Bash") context.openBashTools.set(nextTool.itemId, nextTool);
|
|
24110
24216
|
if (!parsedInput || !nextFingerprint || tool.lastEmittedInputFingerprint === nextFingerprint) {
|
|
24111
24217
|
return;
|
|
24112
24218
|
}
|
|
@@ -24183,7 +24289,9 @@ var makeStreamEventHandler = (deps) => {
|
|
|
24183
24289
|
const inputFingerprint = Object.keys(toolInput).length > 0 ? toolInputFingerprint(toolInput) : void 0;
|
|
24184
24290
|
const parentToolUseId = message.parent_tool_use_id ?? void 0;
|
|
24185
24291
|
const owningAgentId = agentIdForParentToolUse(context.taskAgents, parentToolUseId);
|
|
24292
|
+
const stamp = await makeEventStamp();
|
|
24186
24293
|
const tool = {
|
|
24294
|
+
startedAtMs: Date.parse(stamp.createdAt),
|
|
24187
24295
|
itemId,
|
|
24188
24296
|
itemType,
|
|
24189
24297
|
toolName,
|
|
@@ -24196,7 +24304,7 @@ var makeStreamEventHandler = (deps) => {
|
|
|
24196
24304
|
...parentToolUseId ? { parentToolUseId } : {}
|
|
24197
24305
|
};
|
|
24198
24306
|
context.inFlightTools.set(index, tool);
|
|
24199
|
-
|
|
24307
|
+
if (toolName === "Bash") context.openBashTools.set(itemId, tool);
|
|
24200
24308
|
offerRuntimeEvent(context, {
|
|
24201
24309
|
type: "item.started",
|
|
24202
24310
|
...eventHeader(context, stamp),
|
|
@@ -25079,6 +25187,7 @@ var makeTurnLifecycle = (deps) => {
|
|
|
25079
25187
|
context.inFlightTools.delete(index);
|
|
25080
25188
|
}
|
|
25081
25189
|
context.inFlightTools.clear();
|
|
25190
|
+
context.openBashTools.clear();
|
|
25082
25191
|
for (const block of turnState.assistantTextBlockOrder) {
|
|
25083
25192
|
await completeAssistantTextBlock(context, block, {
|
|
25084
25193
|
force: true,
|
|
@@ -25149,6 +25258,7 @@ var makeTurnMessageHandlers = (deps) => {
|
|
|
25149
25258
|
return;
|
|
25150
25259
|
}
|
|
25151
25260
|
for (const toolResult of toolResultBlocksFromUserMessage(message)) {
|
|
25261
|
+
context.openBashTools.delete(toolResult.toolUseId);
|
|
25152
25262
|
const toolEntry = Array.from(context.inFlightTools.entries()).find(
|
|
25153
25263
|
([, tool2]) => tool2.itemId === toolResult.toolUseId
|
|
25154
25264
|
);
|
|
@@ -27594,6 +27704,54 @@ var createClaudeUsage = (input) => {
|
|
|
27594
27704
|
};
|
|
27595
27705
|
};
|
|
27596
27706
|
|
|
27707
|
+
// src/openCommands.ts
|
|
27708
|
+
import { sameArgv } from "@ycodium-ai/plugin-api/executor";
|
|
27709
|
+
var quote = (command) => "'" + command.replaceAll("'", `'"'"'`) + "'";
|
|
27710
|
+
var basename = (path) => path.split(/[\\/]/).at(-1)?.toLowerCase() ?? "";
|
|
27711
|
+
function claudeCommandMatches(command, argv) {
|
|
27712
|
+
if (argv.length !== 3 || !["bash.exe", "bash"].includes(basename(argv[0] ?? "")) || argv[1] !== "-c")
|
|
27713
|
+
return false;
|
|
27714
|
+
const script = argv[2] ?? "";
|
|
27715
|
+
const source = /^source \S+\/shell-snapshots\/snapshot-bash-\d+-[a-zA-Z0-9]+\.sh /;
|
|
27716
|
+
const prefix = source.exec(script);
|
|
27717
|
+
if (!prefix) return false;
|
|
27718
|
+
const body = script.slice(prefix[0].length);
|
|
27719
|
+
if (!body.startsWith("2>/dev/null || true && ")) return false;
|
|
27720
|
+
const evalPrefix = " && eval ";
|
|
27721
|
+
const marker = evalPrefix + quote(command) + " < /dev/null && pwd -P >| ";
|
|
27722
|
+
const index = body.indexOf(marker);
|
|
27723
|
+
if (index < 0 || body.indexOf(evalPrefix) !== index || body.indexOf(evalPrefix, index + evalPrefix.length) !== -1)
|
|
27724
|
+
return false;
|
|
27725
|
+
return /^\S+\/claude-[a-fA-F0-9]{4}-cwd$/.test(body.slice(index + marker.length));
|
|
27726
|
+
}
|
|
27727
|
+
function openCommandsOf(context) {
|
|
27728
|
+
if (!context || context.stopped || !context.turnState) return void 0;
|
|
27729
|
+
const current = context.cliProcess.current();
|
|
27730
|
+
if (!current) return void 0;
|
|
27731
|
+
const commands = [...context.openBashTools.values()].flatMap((tool) => {
|
|
27732
|
+
const command = tool.input.command;
|
|
27733
|
+
return typeof command !== "string" || tool.input.run_in_background === true ? [] : [
|
|
27734
|
+
{
|
|
27735
|
+
toolCallId: tool.itemId,
|
|
27736
|
+
startedAtMs: tool.startedAtMs,
|
|
27737
|
+
matches: (argv, _platform) => claudeCommandMatches(command, argv)
|
|
27738
|
+
}
|
|
27739
|
+
];
|
|
27740
|
+
});
|
|
27741
|
+
if (commands.length === 0) return void 0;
|
|
27742
|
+
return {
|
|
27743
|
+
rootPid: current.handle.pid,
|
|
27744
|
+
sessionProcess: (argv, platform2) => {
|
|
27745
|
+
const normalize2 = (value) => platform2 === "win32" ? value.replaceAll("\\", "/").toLowerCase() : value;
|
|
27746
|
+
const expected = normalize2(current.command);
|
|
27747
|
+
const actual = normalize2(argv[0] ?? "");
|
|
27748
|
+
const sameProgram = expected.includes("/") ? actual === expected : platform2 === "win32" ? basename(actual).replace(/\.exe$/, "") === expected.replace(/\.exe$/, "") : actual.split("/").at(-1) === expected;
|
|
27749
|
+
return sameProgram && sameArgv(argv.slice(1), current.args);
|
|
27750
|
+
},
|
|
27751
|
+
commands
|
|
27752
|
+
};
|
|
27753
|
+
}
|
|
27754
|
+
|
|
27597
27755
|
// src/claudeInstance.ts
|
|
27598
27756
|
function createClaudeAdapter(recipe, host, options) {
|
|
27599
27757
|
const boundInstanceId = options?.instanceId ?? host.instanceId ?? "claudeAgent";
|
|
@@ -27709,6 +27867,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
27709
27867
|
emitProposedPlanCompleted
|
|
27710
27868
|
});
|
|
27711
27869
|
const { startSession } = makeStartSession({
|
|
27870
|
+
host,
|
|
27712
27871
|
emitter,
|
|
27713
27872
|
recipe,
|
|
27714
27873
|
log: options?.log ?? host.log,
|
|
@@ -27768,6 +27927,7 @@ function createClaudeAdapter(recipe, host, options) {
|
|
|
27768
27927
|
setRuntimeMode,
|
|
27769
27928
|
setNativeMode,
|
|
27770
27929
|
stopSession,
|
|
27930
|
+
openCommandProcesses: async (threadId) => openCommandsOf(sessions.get(threadId)),
|
|
27771
27931
|
events: runtimeEventQueue,
|
|
27772
27932
|
dispose: async () => {
|
|
27773
27933
|
const results = await Promise.allSettled(
|
|
@@ -27818,6 +27978,7 @@ function createClaudeInstance(config, host, attachments, overrides, usageCache)
|
|
|
27818
27978
|
setNativeMode: adapter.setNativeMode,
|
|
27819
27979
|
compactContext: adapter.compactContext,
|
|
27820
27980
|
stopSession: adapter.stopSession,
|
|
27981
|
+
openCommandProcesses: adapter.openCommandProcesses,
|
|
27821
27982
|
readThread: adapter.readThread,
|
|
27822
27983
|
events: adapter.events,
|
|
27823
27984
|
dispose: adapter.dispose,
|
|
@@ -27885,7 +28046,7 @@ var executors = [
|
|
|
27885
28046
|
];
|
|
27886
28047
|
var index_default = definePlugin({
|
|
27887
28048
|
id: "agent-claude",
|
|
27888
|
-
apiVersion:
|
|
28049
|
+
apiVersion: 12,
|
|
27889
28050
|
executors,
|
|
27890
28051
|
activate(ctx) {
|
|
27891
28052
|
capturedAttachments = ctx.attachments;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/agent-claude",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3072",
|
|
4
4
|
"description": "Claude executor: Claude Code CLI via @anthropic-ai/claude-agent-sdk.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ycodium",
|
|
@@ -24,10 +24,10 @@
|
|
|
24
24
|
"@types/node": "24.12.4",
|
|
25
25
|
"esbuild": "0.28.1",
|
|
26
26
|
"vite-plus": "0.2.2",
|
|
27
|
+
"@ycodium-ai/plugin-api": "0.2.3072",
|
|
27
28
|
"ycodium-composer-tokens": "0.0.0",
|
|
28
|
-
"ycodium-
|
|
29
|
-
"
|
|
30
|
-
"ycodium-jsonl-stream": "0.0.0"
|
|
29
|
+
"ycodium-jsonl-stream": "0.0.0",
|
|
30
|
+
"ycodium-executor-testing": "0.0.0"
|
|
31
31
|
},
|
|
32
32
|
"ycodium": {
|
|
33
33
|
"plugin": "./dist/index.js",
|