@p4code/cli 0.1.5 → 0.1.6
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/bin.mjs +256 -32
- package/dist/client/assets/{DiffPanel-ML_kqHo4.js → DiffPanel-CcuhH24b.js} +2 -2
- package/dist/client/assets/{FilePreviewPanel-DqEQ4wir.js → FilePreviewPanel-IupIzTGt.js} +2 -2
- package/dist/client/assets/{PreviewPanel-BwHQqsFC.js → PreviewPanel-CMRKi8Jr.js} +2 -2
- package/dist/client/assets/{angular-html-B70hXg9o.js → angular-html-D4VEGoU_.js} +2 -2
- package/dist/client/assets/{angular-ts-B2MRnnc1.js → angular-ts-DDbN_Pcg.js} +2 -2
- package/dist/client/assets/{apl-DY9W2lgD.js → apl-BH7XGSiX.js} +2 -2
- package/dist/client/assets/arrow-right-B-_6vDIF.js +2 -0
- package/dist/client/assets/{astro-CKmYmuzu.js → astro-DKjLEfvq.js} +2 -2
- package/dist/client/assets/{blade-mlm-ZlOd.js → blade-mO6atsi4.js} +2 -2
- package/dist/client/assets/{c-9y7zDOj9.js → c-drphy09y.js} +2 -2
- package/dist/client/assets/{cobol-CD87wiGp.js → cobol-Do365H-h.js} +2 -2
- package/dist/client/assets/{coffee-kgGv4P2i.js → coffee-CJ9y15YY.js} +2 -2
- package/dist/client/assets/{cpp-DpZlUxYu.js → cpp-C1FVZ39w.js} +2 -2
- package/dist/client/assets/{crystal-B0OLLlY8.js → crystal-D1Y9mCOy.js} +2 -2
- package/dist/client/assets/{css--MUQJ4o7.js → css-C1chQpfJ.js} +2 -2
- package/dist/client/assets/{edge-B9eY7KZn.js → edge-Cir90YUi.js} +2 -2
- package/dist/client/assets/{elixir-BZ2mTmkv.js → elixir-D8U_xdUO.js} +2 -2
- package/dist/client/assets/{elm-Bu95APK0.js → elm-DFyeiMH7.js} +2 -2
- package/dist/client/assets/{erb-CpKKo-fS.js → erb-C6TvSrSi.js} +2 -2
- package/dist/client/assets/{fileCommentAnnotations-DeY-XSzV.js → fileCommentAnnotations-BotL9n2H.js} +2 -2
- package/dist/client/assets/{git-rebase-BN70gFDl.js → git-rebase-C7PDtezn.js} +2 -2
- package/dist/client/assets/{glimmer-js-DM-4mIJW.js → glimmer-js-CXugsloP.js} +2 -2
- package/dist/client/assets/{glimmer-ts-DFHG1P9q.js → glimmer-ts-IiHVp7il.js} +2 -2
- package/dist/client/assets/{glsl-B4TfqZ4_.js → glsl-eBdXjOgx.js} +2 -2
- package/dist/client/assets/{graphql-DLTs8DHV.js → graphql-CBwWowq8.js} +2 -2
- package/dist/client/assets/{hack-DRRemOcq.js → hack-DoKoRNA-.js} +2 -2
- package/dist/client/assets/{haml-4MHJURGQ.js → haml-B2cA0ELm.js} +2 -2
- package/dist/client/assets/{handlebars-D7k0HQlo.js → handlebars-OQNujFnM.js} +2 -2
- package/dist/client/assets/{html-DovLLqdO.js → html-B9l55IY7.js} +2 -2
- package/dist/client/assets/{html-derivative-Dz9-s5om.js → html-derivative-C24d_8BY.js} +2 -2
- package/dist/client/assets/{http-cxnvN4kV.js → http-Ca2KxOLT.js} +2 -2
- package/dist/client/assets/{hurl-CSBBQOts.js → hurl-BuLZo6wH.js} +2 -2
- package/dist/client/assets/index-B-nUm8w7.js +664 -0
- package/dist/client/assets/{index-oFUAtVw2.css → index-DfKhU-QO.css} +1 -1
- package/dist/client/assets/{java-DIz7GrNg.js → java-BEVFbCvA.js} +2 -2
- package/dist/client/assets/{javascript-MSaRoKWU.js → javascript-AWDSrR1H.js} +2 -2
- package/dist/client/assets/{jinja-DI8yd0V9.js → jinja-CFK-VDc5.js} +2 -2
- package/dist/client/assets/{jison-sGqXSFug.js → jison-CSmyyQ0V.js} +2 -2
- package/dist/client/assets/{json-C_w_LNS4.js → json-D0qpEJUc.js} +2 -2
- package/dist/client/assets/{jsx-V5NNKrjP.js → jsx-smdyqdvA.js} +2 -2
- package/dist/client/assets/{julia-BGVYDOsa.js → julia-DWo_5QH9.js} +2 -2
- package/dist/client/assets/{just-D-04ksOT.js → just-74GGYpCk.js} +2 -2
- package/dist/client/assets/{latex-BEsliWgq.js → latex-d8vfKbSv.js} +2 -2
- package/dist/client/assets/{liquid-DNUeMt2o.js → liquid-CsWNZJPs.js} +2 -2
- package/dist/client/assets/{lua--TgilFGl.js → lua-x3z7TbKl.js} +2 -2
- package/dist/client/assets/{marko-DxDDGF4_.js → marko-CJyhwQKw.js} +2 -2
- package/dist/client/assets/{mdc-DzjvIH05.js → mdc-CtbrrOYL.js} +2 -2
- package/dist/client/assets/{nginx-BqVTMZgm.js → nginx-CY-uw8dq.js} +2 -2
- package/dist/client/assets/{nim-Co2BGNef.js → nim-DqT4w7rK.js} +2 -2
- package/dist/client/assets/{perl-Ba8Q7XkF.js → perl-CE3_DH1L.js} +2 -2
- package/dist/client/assets/{php-Bfbmd1-m.js → php-Zxsq1XMP.js} +2 -2
- package/dist/client/assets/{pug-be-1Xvfl.js → pug-DnCImvlN.js} +2 -2
- package/dist/client/assets/{qml-D7icULiU.js → qml-DLfoubjW.js} +2 -2
- package/dist/client/assets/{r-Cph7TJQ-.js → r-BtfLsgk8.js} +2 -2
- package/dist/client/assets/{razor-CjLyUAnD.js → razor-CzAGh9fe.js} +2 -2
- package/dist/client/assets/{regexp-BdlWyepz.js → regexp-Bw17HBbP.js} +2 -2
- package/dist/client/assets/{rst-DEpJb2t7.js → rst-DhRr0i5h.js} +2 -2
- package/dist/client/assets/{ruby-C_x4mzoE.js → ruby-BnQcHU-H.js} +2 -2
- package/dist/client/assets/{sas-Bz4iLdau.js → sas-mMUu1htl.js} +2 -2
- package/dist/client/assets/{scss-CwgGUhGr.js → scss-0_lOQ1qp.js} +2 -2
- package/dist/client/assets/{shellscript-CHr9xiaE.js → shellscript-BAdG8zJQ.js} +2 -2
- package/dist/client/assets/{shellsession-11TeKCPG.js → shellsession-upfFHc_2.js} +2 -2
- package/dist/client/assets/{soy-BLILGuwU.js → soy-Dzncl5z6.js} +2 -2
- package/dist/client/assets/{sql-KbVEV8JC.js → sql-Ca2FgbAh.js} +2 -2
- package/dist/client/assets/{stata-XDGn9IyV.js → stata-D8IymSlL.js} +2 -2
- package/dist/client/assets/{surrealql-BkijSB1h.js → surrealql-CZsXvHAi.js} +2 -2
- package/dist/client/assets/{svelte-S0qXpcmK.js → svelte-nM61Il-m.js} +2 -2
- package/dist/client/assets/{templ-Bpai32u4.js → templ-DzjlBYVo.js} +2 -2
- package/dist/client/assets/{tex-BqM5PBWs.js → tex-BPwIdn9G.js} +2 -2
- package/dist/client/assets/{textarea-CUI7U2B2.js → textarea-DhTMBBxg.js} +2 -2
- package/dist/client/assets/{ts-tags-ChsaUtvn.js → ts-tags-BL9D6Ojm.js} +2 -2
- package/dist/client/assets/{tsx-Bw54IsTH.js → tsx-AKDVGVPx.js} +2 -2
- package/dist/client/assets/{twig-BOAKWhe6.js → twig-B79f_Jz8.js} +2 -2
- package/dist/client/assets/{typescript-vJRDqHfC.js → typescript-BsyojNKj.js} +2 -2
- package/dist/client/assets/{vue-CtHSR0DM.js → vue-BTqtDJT-.js} +2 -2
- package/dist/client/assets/{vue-html-KPDmQoqc.js → vue-html-B_UfyILk.js} +2 -2
- package/dist/client/assets/{vue-vine-BSN6OPd2.js → vue-vine-B8EK-Iln.js} +2 -2
- package/dist/client/assets/{xml-8bohM9Or.js → xml-Do-3lCfL.js} +2 -2
- package/dist/client/assets/{xsl-D-jqs0Dv.js → xsl-CwgwYGXC.js} +2 -2
- package/dist/client/assets/{yaml-CzI494Jo.js → yaml-C4XlY-p5.js} +2 -2
- package/dist/client/index.html +3 -3
- package/package.json +1 -1
- package/dist/client/assets/arrow-right-Bdq-W9Bm.js +0 -2
- package/dist/client/assets/index-BXFHdiV7.js +0 -664
package/dist/bin.mjs
CHANGED
|
@@ -233,7 +233,7 @@ const make$73 = () => {
|
|
|
233
233
|
const layer$69 = Layer.sync(NetService, make$73);
|
|
234
234
|
//#endregion
|
|
235
235
|
//#region package.json
|
|
236
|
-
var version = "0.1.
|
|
236
|
+
var version = "0.1.6";
|
|
237
237
|
//#endregion
|
|
238
238
|
//#region src/config.ts
|
|
239
239
|
/**
|
|
@@ -5634,11 +5634,22 @@ const ClaudeSettings = makeProviderSettingsSchema({
|
|
|
5634
5634
|
placeholder: "e.g. --chrome",
|
|
5635
5635
|
clearWhenEmpty: "omit"
|
|
5636
5636
|
}
|
|
5637
|
+
})),
|
|
5638
|
+
/**
|
|
5639
|
+
* The SDK preset system prompt omits the interactive CLI's terminal-tone
|
|
5640
|
+
* sections, so the model tends to open a turn with a tool call instead of
|
|
5641
|
+
* saying what it is about to do. This appends that instruction back.
|
|
5642
|
+
*/
|
|
5643
|
+
narrateBeforeTools: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(true)), Schema$1.annotateKey({
|
|
5644
|
+
title: "Explain before tool calls",
|
|
5645
|
+
description: "Ask Claude to write one short sentence before its first tool call in a turn.",
|
|
5646
|
+
providerSettingsForm: { control: "switch" }
|
|
5637
5647
|
}))
|
|
5638
5648
|
}, { order: [
|
|
5639
5649
|
"binaryPath",
|
|
5640
5650
|
"homePath",
|
|
5641
|
-
"launchArgs"
|
|
5651
|
+
"launchArgs",
|
|
5652
|
+
"narrateBeforeTools"
|
|
5642
5653
|
] });
|
|
5643
5654
|
const CursorSettings = makeProviderSettingsSchema({
|
|
5644
5655
|
enabled: Schema$1.Boolean.pipe(Schema$1.withDecodingDefault(Effect.succeed(false)), Schema$1.annotateKey({ providerSettingsForm: { hidden: true } })),
|
|
@@ -5827,7 +5838,8 @@ const ClaudeSettingsPatch = Schema$1.Struct({
|
|
|
5827
5838
|
binaryPath: Schema$1.optionalKey(TrimmedString),
|
|
5828
5839
|
homePath: Schema$1.optionalKey(TrimmedString),
|
|
5829
5840
|
customModels: Schema$1.optionalKey(Schema$1.Array(Schema$1.String)),
|
|
5830
|
-
launchArgs: Schema$1.optionalKey(TrimmedString)
|
|
5841
|
+
launchArgs: Schema$1.optionalKey(TrimmedString),
|
|
5842
|
+
narrateBeforeTools: Schema$1.optionalKey(Schema$1.Boolean)
|
|
5831
5843
|
});
|
|
5832
5844
|
const CursorSettingsPatch = Schema$1.Struct({
|
|
5833
5845
|
enabled: Schema$1.optionalKey(Schema$1.Boolean),
|
|
@@ -46471,6 +46483,177 @@ function parseCliArgs(args, options) {
|
|
|
46471
46483
|
};
|
|
46472
46484
|
}
|
|
46473
46485
|
//#endregion
|
|
46486
|
+
//#region ../../packages/shared/src/toolCategory.ts
|
|
46487
|
+
const TOOL_CATEGORY_TITLES = {
|
|
46488
|
+
file_read: "File read",
|
|
46489
|
+
file_search: "File search",
|
|
46490
|
+
file_change: "File change",
|
|
46491
|
+
command: "Command run",
|
|
46492
|
+
mcp_tool: "MCP tool call",
|
|
46493
|
+
subagent: "Subagent task",
|
|
46494
|
+
web_search: "Web search",
|
|
46495
|
+
image_view: "Image view",
|
|
46496
|
+
tool: "Tool call"
|
|
46497
|
+
};
|
|
46498
|
+
/** Exact tool names, lowercased, matched before the substring heuristics below. */
|
|
46499
|
+
const FILE_READ_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
46500
|
+
"read",
|
|
46501
|
+
"readfile",
|
|
46502
|
+
"read_file",
|
|
46503
|
+
"view",
|
|
46504
|
+
"viewfile",
|
|
46505
|
+
"view_file",
|
|
46506
|
+
"notebookread",
|
|
46507
|
+
"notebook_read",
|
|
46508
|
+
"openfile",
|
|
46509
|
+
"open_file"
|
|
46510
|
+
]);
|
|
46511
|
+
const FILE_SEARCH_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
46512
|
+
"grep",
|
|
46513
|
+
"glob",
|
|
46514
|
+
"search",
|
|
46515
|
+
"filesearch",
|
|
46516
|
+
"file_search",
|
|
46517
|
+
"codebasesearch",
|
|
46518
|
+
"codebase_search",
|
|
46519
|
+
"listdir",
|
|
46520
|
+
"list_dir",
|
|
46521
|
+
"list_directory",
|
|
46522
|
+
"ls"
|
|
46523
|
+
]);
|
|
46524
|
+
const FILE_CHANGE_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
46525
|
+
"edit",
|
|
46526
|
+
"write",
|
|
46527
|
+
"multiedit",
|
|
46528
|
+
"multi_edit",
|
|
46529
|
+
"notebookedit",
|
|
46530
|
+
"notebook_edit",
|
|
46531
|
+
"applypatch",
|
|
46532
|
+
"apply_patch",
|
|
46533
|
+
"patch",
|
|
46534
|
+
"createfile",
|
|
46535
|
+
"create_file",
|
|
46536
|
+
"strreplace",
|
|
46537
|
+
"str_replace",
|
|
46538
|
+
"deletefile",
|
|
46539
|
+
"delete_file"
|
|
46540
|
+
]);
|
|
46541
|
+
const COMMAND_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
46542
|
+
"bash",
|
|
46543
|
+
"shell",
|
|
46544
|
+
"terminal",
|
|
46545
|
+
"exec",
|
|
46546
|
+
"execute",
|
|
46547
|
+
"execcommand",
|
|
46548
|
+
"exec_command",
|
|
46549
|
+
"runcommand",
|
|
46550
|
+
"run_command",
|
|
46551
|
+
"local_shell"
|
|
46552
|
+
]);
|
|
46553
|
+
const SUBAGENT_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
46554
|
+
"task",
|
|
46555
|
+
"agent",
|
|
46556
|
+
"subagent",
|
|
46557
|
+
"sub_agent"
|
|
46558
|
+
]);
|
|
46559
|
+
/** Shell builtins that say nothing about what the command as a whole does. */
|
|
46560
|
+
const NEUTRAL_SHELL_COMMANDS = /* @__PURE__ */ new Set([
|
|
46561
|
+
"cd",
|
|
46562
|
+
"echo",
|
|
46563
|
+
"printf",
|
|
46564
|
+
"pwd",
|
|
46565
|
+
"true",
|
|
46566
|
+
"false",
|
|
46567
|
+
"time"
|
|
46568
|
+
]);
|
|
46569
|
+
/** `sed`/`awk` are stream editors (`sed -i` rewrites files), so they stay commands. */
|
|
46570
|
+
const FILE_READ_SHELL_COMMANDS = /* @__PURE__ */ new Set([
|
|
46571
|
+
"cat",
|
|
46572
|
+
"head",
|
|
46573
|
+
"tail",
|
|
46574
|
+
"less",
|
|
46575
|
+
"more",
|
|
46576
|
+
"bat",
|
|
46577
|
+
"nl",
|
|
46578
|
+
"jq",
|
|
46579
|
+
"wc"
|
|
46580
|
+
]);
|
|
46581
|
+
const FILE_SEARCH_SHELL_COMMANDS = /* @__PURE__ */ new Set([
|
|
46582
|
+
"grep",
|
|
46583
|
+
"egrep",
|
|
46584
|
+
"fgrep",
|
|
46585
|
+
"rg",
|
|
46586
|
+
"ag",
|
|
46587
|
+
"ack",
|
|
46588
|
+
"find",
|
|
46589
|
+
"fd",
|
|
46590
|
+
"ls",
|
|
46591
|
+
"tree",
|
|
46592
|
+
"which"
|
|
46593
|
+
]);
|
|
46594
|
+
const SHELL_SEGMENT_SEPARATOR = /\|\||&&|;|\||\n/u;
|
|
46595
|
+
const LEADING_ENV_ASSIGNMENT = /^[A-Za-z_][A-Za-z0-9_]*=\S*\s+/u;
|
|
46596
|
+
const REDIRECT_TARGET = /\d?>>?\s*(?<target>[^\s|;&]+)/gu;
|
|
46597
|
+
/** Redirect targets that discard output instead of writing a file. */
|
|
46598
|
+
const DISCARDED_REDIRECT_TARGETS = /* @__PURE__ */ new Set([
|
|
46599
|
+
"/dev/null",
|
|
46600
|
+
"&1",
|
|
46601
|
+
"&2"
|
|
46602
|
+
]);
|
|
46603
|
+
function toolCategoryTitle(category) {
|
|
46604
|
+
return TOOL_CATEGORY_TITLES[category];
|
|
46605
|
+
}
|
|
46606
|
+
function readCommandInput(toolInput) {
|
|
46607
|
+
const raw = toolInput?.command ?? toolInput?.cmd;
|
|
46608
|
+
if (typeof raw !== "string") return;
|
|
46609
|
+
const trimmed = raw.trim();
|
|
46610
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
46611
|
+
}
|
|
46612
|
+
/** `cat x > y` reads and writes; only the write matters for the row heading. */
|
|
46613
|
+
function redirectsToFile(segment) {
|
|
46614
|
+
for (const match of segment.matchAll(REDIRECT_TARGET)) {
|
|
46615
|
+
const target = match.groups?.target;
|
|
46616
|
+
if (target && !DISCARDED_REDIRECT_TARGETS.has(target)) return true;
|
|
46617
|
+
}
|
|
46618
|
+
return false;
|
|
46619
|
+
}
|
|
46620
|
+
function classifyShellSegment(segment) {
|
|
46621
|
+
if (redirectsToFile(segment)) return "command";
|
|
46622
|
+
const head = segment.trim().replace(LEADING_ENV_ASSIGNMENT, "").split(/\s+/u)[0]?.replace(/^.*\//u, "").toLowerCase();
|
|
46623
|
+
if (!head || NEUTRAL_SHELL_COMMANDS.has(head)) return;
|
|
46624
|
+
if (FILE_READ_SHELL_COMMANDS.has(head)) return "file_read";
|
|
46625
|
+
if (FILE_SEARCH_SHELL_COMMANDS.has(head)) return "file_search";
|
|
46626
|
+
return "command";
|
|
46627
|
+
}
|
|
46628
|
+
/**
|
|
46629
|
+
* A shell call only counts as a read or a search when every non-neutral segment
|
|
46630
|
+
* agrees; anything unrecognized (or write-ish) keeps the whole call a command.
|
|
46631
|
+
* Quoted separators split segments too, which can only downgrade to "command".
|
|
46632
|
+
*/
|
|
46633
|
+
function classifyShellCommand(command) {
|
|
46634
|
+
const categories = command.split(SHELL_SEGMENT_SEPARATOR).map(classifyShellSegment).filter((category) => category !== void 0);
|
|
46635
|
+
if (categories.length === 0 || categories.includes("command")) return "command";
|
|
46636
|
+
return categories.includes("file_search") ? "file_search" : "file_read";
|
|
46637
|
+
}
|
|
46638
|
+
function classifyToolCategory(input) {
|
|
46639
|
+
const normalized = input.toolName.trim().toLowerCase();
|
|
46640
|
+
if (normalized.startsWith("mcp__") || normalized.includes("mcp")) return "mcp_tool";
|
|
46641
|
+
if (SUBAGENT_TOOL_NAMES.has(normalized) || normalized.includes("agent")) return "subagent";
|
|
46642
|
+
if (FILE_READ_TOOL_NAMES.has(normalized)) return "file_read";
|
|
46643
|
+
if (FILE_SEARCH_TOOL_NAMES.has(normalized)) return "file_search";
|
|
46644
|
+
if (FILE_CHANGE_TOOL_NAMES.has(normalized)) return "file_change";
|
|
46645
|
+
if (COMMAND_TOOL_NAMES.has(normalized) || normalized.includes("bash") || normalized.includes("shell") || normalized.includes("terminal") || normalized.includes("command")) {
|
|
46646
|
+
const command = readCommandInput(input.toolInput);
|
|
46647
|
+
return command ? classifyShellCommand(command) : "command";
|
|
46648
|
+
}
|
|
46649
|
+
if (normalized.includes("websearch") || normalized.includes("web_search")) return "web_search";
|
|
46650
|
+
if (normalized.includes("edit") || normalized.includes("write") || normalized.includes("patch") || normalized.includes("replace") || normalized.includes("create") || normalized.includes("delete")) return "file_change";
|
|
46651
|
+
if (normalized.includes("read") || normalized.includes("view")) return "file_read";
|
|
46652
|
+
if (normalized.includes("grep") || normalized.includes("glob")) return "file_search";
|
|
46653
|
+
if (normalized.includes("image")) return "image_view";
|
|
46654
|
+
return "tool";
|
|
46655
|
+
}
|
|
46656
|
+
//#endregion
|
|
46474
46657
|
//#region src/provider/askUserQuestionAnswers.ts
|
|
46475
46658
|
/**
|
|
46476
46659
|
* What separates the options of one multi-select answer.
|
|
@@ -47043,17 +47226,17 @@ function summarizeToolRequest(toolName, input) {
|
|
|
47043
47226
|
if (serialized.length <= TOOL_SUMMARY_MAX_LENGTH) return `${toolName}: ${serialized}`;
|
|
47044
47227
|
return `${toolName}: ${serialized.slice(0, TOOL_SUMMARY_MAX_LENGTH - 3)}...`;
|
|
47045
47228
|
}
|
|
47046
|
-
|
|
47047
|
-
|
|
47048
|
-
|
|
47049
|
-
|
|
47050
|
-
|
|
47051
|
-
|
|
47052
|
-
|
|
47053
|
-
|
|
47054
|
-
|
|
47055
|
-
|
|
47056
|
-
}
|
|
47229
|
+
/**
|
|
47230
|
+
* Heading for a tool row. Derived from the tool name plus its input so a `Read`
|
|
47231
|
+
* reads as "File read" instead of a bare "Tool call", and a `Bash` that only
|
|
47232
|
+
* inspects a file (`sed -n 1,20p src/x.ts`) reads as "File read" instead of
|
|
47233
|
+
* "Command run". Recomputed as streamed input arrives.
|
|
47234
|
+
*/
|
|
47235
|
+
function titleForTool(toolName, toolInput) {
|
|
47236
|
+
return toolCategoryTitle(classifyToolCategory({
|
|
47237
|
+
toolName,
|
|
47238
|
+
toolInput
|
|
47239
|
+
}));
|
|
47057
47240
|
}
|
|
47058
47241
|
const SUPPORTED_CLAUDE_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
47059
47242
|
"image/gif",
|
|
@@ -47061,6 +47244,12 @@ const SUPPORTED_CLAUDE_IMAGE_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
|
47061
47244
|
"image/png",
|
|
47062
47245
|
"image/webp"
|
|
47063
47246
|
]);
|
|
47247
|
+
/**
|
|
47248
|
+
* Appended to the preset system prompt when `narrateBeforeTools` is on. The SDK
|
|
47249
|
+
* preset drops the interactive CLI's terminal-tone sections, so without this the
|
|
47250
|
+
* model opens a turn with a tool call rather than a line saying what it is doing.
|
|
47251
|
+
*/
|
|
47252
|
+
const NARRATE_BEFORE_TOOLS_PROMPT = "Before your first tool call in a turn, write one short sentence saying what you are about to do. Keep it to a single line and skip it when you are answering without tools.";
|
|
47064
47253
|
const CLAUDE_SETTING_SOURCES = [
|
|
47065
47254
|
"user",
|
|
47066
47255
|
"project",
|
|
@@ -47786,6 +47975,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
47786
47975
|
});
|
|
47787
47976
|
const updatedAt = yield* nowIso;
|
|
47788
47977
|
context.turnState = void 0;
|
|
47978
|
+
context.steeredMessages.clear();
|
|
47789
47979
|
context.session = {
|
|
47790
47980
|
...context.session,
|
|
47791
47981
|
status: "ready",
|
|
@@ -47832,6 +48022,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
47832
48022
|
const updatedAt = yield* nowIso;
|
|
47833
48023
|
context.turnState = turnState;
|
|
47834
48024
|
context.interruptRequested = false;
|
|
48025
|
+
context.steeredMessages.clear();
|
|
47835
48026
|
context.session = {
|
|
47836
48027
|
...context.session,
|
|
47837
48028
|
status: "running",
|
|
@@ -47853,24 +48044,49 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
47853
48044
|
/**
|
|
47854
48045
|
* Start the queued sendTurn, if the session has gone idle.
|
|
47855
48046
|
*
|
|
47856
|
-
* Runs after every turn completion.
|
|
47857
|
-
*
|
|
47858
|
-
*
|
|
47859
|
-
*
|
|
47860
|
-
* so it starts as a single turn.
|
|
48047
|
+
* Runs after every turn completion. What waits here are the steers Stop took
|
|
48048
|
+
* back from the CLI before they ran (see `reclaimSteeredMessages`); they are
|
|
48049
|
+
* already merged into one request, so they start as a single turn the moment
|
|
48050
|
+
* the interrupted loop ends.
|
|
47861
48051
|
*/
|
|
47862
48052
|
const drainPendingTurns = Effect.fn("drainPendingTurns")(function* (context) {
|
|
47863
48053
|
if (context.stopped || context.turnState !== void 0) return;
|
|
47864
48054
|
const pending = context.pendingTurnRequest;
|
|
47865
48055
|
if (pending === void 0) return;
|
|
47866
48056
|
context.pendingTurnRequest = void 0;
|
|
47867
|
-
yield*
|
|
47868
|
-
yield* beginTurn(context, pending.turnId, pending.modelSelection?.model);
|
|
48057
|
+
yield* beginTurn(context, pending.turnId, context.session.model);
|
|
47869
48058
|
yield* Queue.offer(context.promptQueue, {
|
|
47870
48059
|
type: "message",
|
|
47871
48060
|
message: pending.message
|
|
47872
48061
|
}).pipe(Effect.ignore);
|
|
47873
48062
|
});
|
|
48063
|
+
/**
|
|
48064
|
+
* Take back the steers the CLI has not started yet, so Stop still runs them.
|
|
48065
|
+
*
|
|
48066
|
+
* A steer sits in the CLI's async-message queue until the agent loop reaches
|
|
48067
|
+
* its next boundary. `cancelAsyncMessage` answers true only while it is still
|
|
48068
|
+
* waiting there: those never reached the model and become the next turn
|
|
48069
|
+
* together, while an already-dequeued one is part of the turn being stopped
|
|
48070
|
+
* and must not run a second time.
|
|
48071
|
+
*/
|
|
48072
|
+
const reclaimSteeredMessages = Effect.fn("reclaimSteeredMessages")(function* (context) {
|
|
48073
|
+
const steered = Array.from(context.steeredMessages);
|
|
48074
|
+
context.steeredMessages.clear();
|
|
48075
|
+
const cancelAsyncMessage = context.query.cancelAsyncMessage;
|
|
48076
|
+
if (steered.length === 0 || cancelAsyncMessage === void 0) return;
|
|
48077
|
+
const reclaimed = [];
|
|
48078
|
+
for (const [messageUuid, message] of steered) if (yield* Effect.tryPromise({
|
|
48079
|
+
try: () => cancelAsyncMessage(messageUuid),
|
|
48080
|
+
catch: (cause) => toRequestError$1(context.session.threadId, "turn/cancelAsyncMessage", cause)
|
|
48081
|
+
}).pipe(Effect.catchCause((cause) => Effect.logWarning("claude steer cancel failed", { cause }).pipe(Effect.as(false))))) reclaimed.push(message);
|
|
48082
|
+
if (reclaimed.length === 0) return;
|
|
48083
|
+
const merged = reclaimed.reduce((left, right) => mergeUserMessages(left, right));
|
|
48084
|
+
const pending = context.pendingTurnRequest;
|
|
48085
|
+
context.pendingTurnRequest = {
|
|
48086
|
+
turnId: pending?.turnId ?? TurnId.make(yield* randomUUIDv4),
|
|
48087
|
+
message: pending ? mergeUserMessages(pending.message, merged) : merged
|
|
48088
|
+
};
|
|
48089
|
+
});
|
|
47874
48090
|
const handleStreamEvent = Effect.fn("handleStreamEvent")(function* (context, message) {
|
|
47875
48091
|
if (message.type !== "stream_event") return;
|
|
47876
48092
|
const { event } = message;
|
|
@@ -47921,11 +48137,13 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
47921
48137
|
const partialInputJson = tool.partialInputJson + event.delta.partial_json;
|
|
47922
48138
|
const parsedInput = tryParseJsonRecord(partialInputJson);
|
|
47923
48139
|
const detail = parsedInput ? summarizeToolRequest(tool.toolName, parsedInput) : tool.detail;
|
|
48140
|
+
const title = parsedInput ? titleForTool(tool.toolName, parsedInput) : tool.title;
|
|
47924
48141
|
let nextTool = {
|
|
47925
48142
|
...tool,
|
|
47926
48143
|
partialInputJson,
|
|
47927
48144
|
...parsedInput ? { input: parsedInput } : {},
|
|
47928
|
-
...detail ? { detail } : {}
|
|
48145
|
+
...detail ? { detail } : {},
|
|
48146
|
+
title
|
|
47929
48147
|
};
|
|
47930
48148
|
const nextFingerprint = parsedInput && Object.keys(parsedInput).length > 0 ? toolInputFingerprint(parsedInput) : void 0;
|
|
47931
48149
|
context.inFlightTools.set(event.index, nextTool);
|
|
@@ -47998,7 +48216,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
47998
48216
|
itemId,
|
|
47999
48217
|
itemType,
|
|
48000
48218
|
toolName,
|
|
48001
|
-
title: titleForTool(
|
|
48219
|
+
title: titleForTool(toolName, toolInput),
|
|
48002
48220
|
detail,
|
|
48003
48221
|
input: toolInput,
|
|
48004
48222
|
partialInputJson: "",
|
|
@@ -48864,7 +49082,8 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
48864
49082
|
pathToClaudeCodeExecutable: claudeBinaryPath,
|
|
48865
49083
|
systemPrompt: {
|
|
48866
49084
|
type: "preset",
|
|
48867
|
-
preset: "claude_code"
|
|
49085
|
+
preset: "claude_code",
|
|
49086
|
+
...claudeSettings.narrateBeforeTools ? { append: NARRATE_BEFORE_TOOLS_PROMPT } : {}
|
|
48868
49087
|
},
|
|
48869
49088
|
settingSources: [...CLAUDE_SETTING_SOURCES],
|
|
48870
49089
|
...effectiveEffort ? { effort: effectiveEffort } : {},
|
|
@@ -48906,6 +49125,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
48906
49125
|
"claude.query.include_partial_messages": true,
|
|
48907
49126
|
"claude.query.additional_directories": input.cwd ? [input.cwd] : [],
|
|
48908
49127
|
"claude.query.setting_sources": [...CLAUDE_SETTING_SOURCES],
|
|
49128
|
+
"claude.query.narrate_before_tools": claudeSettings.narrateBeforeTools,
|
|
48909
49129
|
"claude.query.settings_json": encodeJsonStringForDiagnostics$2(settings) ?? "",
|
|
48910
49130
|
"claude.query.extra_args_json": encodeJsonStringForDiagnostics$2(extraArgs) ?? "",
|
|
48911
49131
|
"claude.query.path_to_executable": claudeBinaryPath
|
|
@@ -48956,6 +49176,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
48956
49176
|
claudeTasks,
|
|
48957
49177
|
turnState: void 0,
|
|
48958
49178
|
pendingTurnRequest: void 0,
|
|
49179
|
+
steeredMessages: /* @__PURE__ */ new Map(),
|
|
48959
49180
|
lastKnownContextWindow: initialContextWindow,
|
|
48960
49181
|
lastKnownTokenUsage: void 0,
|
|
48961
49182
|
lastKnownTotalProcessedTokens: void 0,
|
|
@@ -49024,17 +49245,19 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
49024
49245
|
boundInstanceId
|
|
49025
49246
|
});
|
|
49026
49247
|
if (context.turnState) {
|
|
49027
|
-
const
|
|
49028
|
-
const
|
|
49029
|
-
|
|
49030
|
-
|
|
49031
|
-
message: pending ? mergeUserMessages(pending.message, message) : message,
|
|
49032
|
-
modelSelection,
|
|
49033
|
-
interactionMode: input.interactionMode
|
|
49248
|
+
const steerUuid = yield* randomUUIDv4;
|
|
49249
|
+
const steered = {
|
|
49250
|
+
...message,
|
|
49251
|
+
uuid: steerUuid
|
|
49034
49252
|
};
|
|
49253
|
+
context.steeredMessages.set(steerUuid, steered);
|
|
49254
|
+
yield* Queue.offer(context.promptQueue, {
|
|
49255
|
+
type: "message",
|
|
49256
|
+
message: steered
|
|
49257
|
+
}).pipe(Effect.mapError((cause) => toRequestError$1(input.threadId, "turn/start", cause)));
|
|
49035
49258
|
return {
|
|
49036
49259
|
threadId: context.session.threadId,
|
|
49037
|
-
turnId,
|
|
49260
|
+
turnId: context.turnState.turnId,
|
|
49038
49261
|
...context.session.resumeCursor !== void 0 ? { resumeCursor: context.session.resumeCursor } : {}
|
|
49039
49262
|
};
|
|
49040
49263
|
}
|
|
@@ -49054,6 +49277,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
|
|
|
49054
49277
|
const interruptTurn = Effect.fn("interruptTurn")(function* (threadId, _turnId) {
|
|
49055
49278
|
const context = yield* requireSession(threadId);
|
|
49056
49279
|
context.interruptRequested = true;
|
|
49280
|
+
yield* reclaimSteeredMessages(context);
|
|
49057
49281
|
yield* Effect.tryPromise({
|
|
49058
49282
|
try: () => context.query.interrupt(),
|
|
49059
49283
|
catch: (cause) => toRequestError$1(threadId, "turn/interrupt", cause)
|