pybao-cli 1.3.91 → 1.3.93

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.
Files changed (148) hide show
  1. package/dist/REPL-YIK4SNUK.js +47 -0
  2. package/dist/{acp-6PJPOT5M.js → acp-EVHOGBLR.js} +29 -29
  3. package/dist/{agentsValidate-LZNBNHP6.js → agentsValidate-SX5WCTHD.js} +7 -7
  4. package/dist/{ask-76BUROTN.js → ask-5256RCJR.js} +28 -28
  5. package/dist/{autoUpdater-OK2HAUOA.js → autoUpdater-62OEX27S.js} +3 -3
  6. package/dist/{chunk-TYHTF3BE.js → chunk-2SDOBAYI.js} +2 -2
  7. package/dist/{chunk-UMO4Y6IF.js → chunk-53LR6LMF.js} +2 -2
  8. package/dist/{chunk-KOHH2H5S.js → chunk-A4LZLJ4E.js} +2 -2
  9. package/dist/{chunk-K3QOARLB.js → chunk-A6332THM.js} +3 -3
  10. package/dist/{chunk-IQDGXR2L.js → chunk-AI356RID.js} +3 -3
  11. package/dist/{chunk-FLLFJL7B.js → chunk-AKK6NTGD.js} +1 -1
  12. package/dist/{chunk-BULWYV5N.js → chunk-APVX3GSP.js} +310 -128
  13. package/dist/chunk-APVX3GSP.js.map +7 -0
  14. package/dist/{chunk-ZMABUWI2.js → chunk-ARHVL4GY.js} +4 -4
  15. package/dist/{chunk-DG4EUTSH.js → chunk-B55DFBEO.js} +2 -2
  16. package/dist/{chunk-MJCH3WTW.js → chunk-BKLDKPLL.js} +3 -3
  17. package/dist/{chunk-KOZFO5PM.js → chunk-D5GRAD3G.js} +3 -3
  18. package/dist/{chunk-ODYWGMTG.js → chunk-DKLWXWL2.js} +45 -28
  19. package/dist/chunk-DKLWXWL2.js.map +7 -0
  20. package/dist/{chunk-WNZU3TS3.js → chunk-GGBJ6RZQ.js} +3 -3
  21. package/dist/{chunk-VNIV2R6B.js → chunk-HQU5FX5A.js} +2 -2
  22. package/dist/{chunk-WW3UO4TS.js → chunk-JDEWLQHH.js} +1 -1
  23. package/dist/{chunk-RQVFFNI2.js → chunk-JDY2JDD3.js} +159 -267
  24. package/dist/chunk-JDY2JDD3.js.map +7 -0
  25. package/dist/{chunk-7LTDWLR6.js → chunk-NCHRQKJP.js} +1 -1
  26. package/dist/{chunk-7LTDWLR6.js.map → chunk-NCHRQKJP.js.map} +1 -1
  27. package/dist/{chunk-F5CU72WX.js → chunk-NQNSJDW7.js} +3 -3
  28. package/dist/{chunk-UJAA45KE.js → chunk-OUXWQ5VS.js} +2 -2
  29. package/dist/{chunk-AWQ5CGW5.js → chunk-P5OMB2NR.js} +1 -1
  30. package/dist/{chunk-TU4W4WGH.js → chunk-PBKTN6PS.js} +1 -1
  31. package/dist/{chunk-DCRXZZJX.js → chunk-PWRCPRYF.js} +2 -2
  32. package/dist/{chunk-GQWBRVCL.js → chunk-RCEEY77V.js} +1 -1
  33. package/dist/{chunk-57ZD6EQN.js → chunk-SR3SWOX7.js} +1 -1
  34. package/dist/{chunk-ESQZEVRN.js → chunk-TATJD3PS.js} +1 -1
  35. package/dist/{chunk-O2UT6CSX.js → chunk-TNMW3LIC.js} +6 -7
  36. package/dist/{chunk-O2UT6CSX.js.map → chunk-TNMW3LIC.js.map} +2 -2
  37. package/dist/{chunk-AKPBJECB.js → chunk-UKADBDTZ.js} +1 -1
  38. package/dist/{chunk-TQMAHPW3.js → chunk-Y5WRSDBM.js} +3 -3
  39. package/dist/{chunk-JTGSEBAT.js → chunk-ZJIMLKMQ.js} +3 -3
  40. package/dist/{chunk-MBBGTD7O.js → chunk-ZZX3RSJM.js} +1 -1
  41. package/dist/{cli-MHACN3EZ.js → cli-LOINYVA4.js} +87 -87
  42. package/dist/commands-5MM7DHYR.js +51 -0
  43. package/dist/{config-FAPLL3AS.js → config-ESCUISGA.js} +4 -4
  44. package/dist/{context-ZNW4KPID.js → context-A6RYVYH3.js} +7 -5
  45. package/dist/{customCommands-L46UUKJJ.js → customCommands-NP3YOHBP.js} +4 -4
  46. package/dist/{env-I77N3GWS.js → env-QM2GQKSL.js} +2 -2
  47. package/dist/{file-DZLGJNYY.js → file-COGPZQB2.js} +4 -4
  48. package/dist/index.js +3 -3
  49. package/dist/{llm-RTLJBLJE.js → llm-DZMLOCDR.js} +29 -29
  50. package/dist/{llmLazy-5RJ5OQ6P.js → llmLazy-L4VAGXRS.js} +1 -1
  51. package/dist/{loader-OMI5VTDL.js → loader-J7FDM25W.js} +4 -4
  52. package/dist/{lsp-4GIZ5WWB.js → lsp-ZJDBSAGL.js} +6 -6
  53. package/dist/{lspAnchor-MYE3MOZN.js → lspAnchor-QUM3YKRZ.js} +6 -6
  54. package/dist/{mcp-GJCOU7DQ.js → mcp-TYRRTRZO.js} +7 -7
  55. package/dist/{mentionProcessor-SBDFSDIJ.js → mentionProcessor-VBRYWNJ6.js} +5 -5
  56. package/dist/{messages-WVSU2VE6.js → messages-TI35HRUJ.js} +1 -1
  57. package/dist/{model-V2EMCPKL.js → model-CYQGPU6S.js} +5 -5
  58. package/dist/{openai-2ZGXLFBL.js → openai-YJXPABCZ.js} +5 -5
  59. package/dist/{outputStyles-KNUAGEEW.js → outputStyles-54CH4AXQ.js} +4 -4
  60. package/dist/{pluginRuntime-UFC7JFLE.js → pluginRuntime-HUH43L3E.js} +6 -6
  61. package/dist/{pluginValidation-Q2S2P43C.js → pluginValidation-YZQAIFOB.js} +6 -6
  62. package/dist/prompts-MKDGNXMZ.js +53 -0
  63. package/dist/{pybAgentSessionLoad-XFMEFBHA.js → pybAgentSessionLoad-IDX6CZ7W.js} +4 -4
  64. package/dist/{pybAgentSessionResume-IKMAZTZ6.js → pybAgentSessionResume-G7CNXIM2.js} +4 -4
  65. package/dist/{pybAgentStreamJsonSession-5NVTYHLV.js → pybAgentStreamJsonSession-4DK6ZF6D.js} +1 -1
  66. package/dist/{pybHooks-O6BH4JWL.js → pybHooks-6NZEXF2Y.js} +4 -4
  67. package/dist/query-3JMCOSE3.js +59 -0
  68. package/dist/{registry-NBBQP3S3.js → registry-MYSH5C4A.js} +5 -5
  69. package/dist/{ripgrep-D4Z26BOH.js → ripgrep-UDJTJUDM.js} +3 -3
  70. package/dist/{skillMarketplace-JYHTX2L2.js → skillMarketplace-QUB6SCI3.js} +3 -3
  71. package/dist/{state-YCFRC443.js → state-H3ASL5UP.js} +2 -2
  72. package/dist/{theme-CAVO3N6U.js → theme-N2PDKHSA.js} +5 -5
  73. package/dist/{toolPermissionSettings-QF7N6PGX.js → toolPermissionSettings-H3A4FEPL.js} +6 -6
  74. package/dist/tools-JKFSGTP2.js +52 -0
  75. package/dist/{userInput-7XB2LRXJ.js → userInput-2C2HUFUT.js} +30 -30
  76. package/package.json +1 -1
  77. package/dist/REPL-LOJVC37U.js +0 -47
  78. package/dist/chunk-BULWYV5N.js.map +0 -7
  79. package/dist/chunk-ODYWGMTG.js.map +0 -7
  80. package/dist/chunk-RQVFFNI2.js.map +0 -7
  81. package/dist/commands-27WBI67S.js +0 -51
  82. package/dist/prompts-QC6HQ3RR.js +0 -53
  83. package/dist/query-TAKHQYZM.js +0 -55
  84. package/dist/tools-N2JA5WOB.js +0 -52
  85. /package/dist/{REPL-LOJVC37U.js.map → REPL-YIK4SNUK.js.map} +0 -0
  86. /package/dist/{acp-6PJPOT5M.js.map → acp-EVHOGBLR.js.map} +0 -0
  87. /package/dist/{agentsValidate-LZNBNHP6.js.map → agentsValidate-SX5WCTHD.js.map} +0 -0
  88. /package/dist/{ask-76BUROTN.js.map → ask-5256RCJR.js.map} +0 -0
  89. /package/dist/{autoUpdater-OK2HAUOA.js.map → autoUpdater-62OEX27S.js.map} +0 -0
  90. /package/dist/{chunk-TYHTF3BE.js.map → chunk-2SDOBAYI.js.map} +0 -0
  91. /package/dist/{chunk-UMO4Y6IF.js.map → chunk-53LR6LMF.js.map} +0 -0
  92. /package/dist/{chunk-KOHH2H5S.js.map → chunk-A4LZLJ4E.js.map} +0 -0
  93. /package/dist/{chunk-K3QOARLB.js.map → chunk-A6332THM.js.map} +0 -0
  94. /package/dist/{chunk-IQDGXR2L.js.map → chunk-AI356RID.js.map} +0 -0
  95. /package/dist/{chunk-FLLFJL7B.js.map → chunk-AKK6NTGD.js.map} +0 -0
  96. /package/dist/{chunk-ZMABUWI2.js.map → chunk-ARHVL4GY.js.map} +0 -0
  97. /package/dist/{chunk-DG4EUTSH.js.map → chunk-B55DFBEO.js.map} +0 -0
  98. /package/dist/{chunk-MJCH3WTW.js.map → chunk-BKLDKPLL.js.map} +0 -0
  99. /package/dist/{chunk-KOZFO5PM.js.map → chunk-D5GRAD3G.js.map} +0 -0
  100. /package/dist/{chunk-WNZU3TS3.js.map → chunk-GGBJ6RZQ.js.map} +0 -0
  101. /package/dist/{chunk-VNIV2R6B.js.map → chunk-HQU5FX5A.js.map} +0 -0
  102. /package/dist/{chunk-WW3UO4TS.js.map → chunk-JDEWLQHH.js.map} +0 -0
  103. /package/dist/{chunk-F5CU72WX.js.map → chunk-NQNSJDW7.js.map} +0 -0
  104. /package/dist/{chunk-UJAA45KE.js.map → chunk-OUXWQ5VS.js.map} +0 -0
  105. /package/dist/{chunk-AWQ5CGW5.js.map → chunk-P5OMB2NR.js.map} +0 -0
  106. /package/dist/{chunk-TU4W4WGH.js.map → chunk-PBKTN6PS.js.map} +0 -0
  107. /package/dist/{chunk-DCRXZZJX.js.map → chunk-PWRCPRYF.js.map} +0 -0
  108. /package/dist/{chunk-GQWBRVCL.js.map → chunk-RCEEY77V.js.map} +0 -0
  109. /package/dist/{chunk-57ZD6EQN.js.map → chunk-SR3SWOX7.js.map} +0 -0
  110. /package/dist/{chunk-ESQZEVRN.js.map → chunk-TATJD3PS.js.map} +0 -0
  111. /package/dist/{chunk-AKPBJECB.js.map → chunk-UKADBDTZ.js.map} +0 -0
  112. /package/dist/{chunk-TQMAHPW3.js.map → chunk-Y5WRSDBM.js.map} +0 -0
  113. /package/dist/{chunk-JTGSEBAT.js.map → chunk-ZJIMLKMQ.js.map} +0 -0
  114. /package/dist/{chunk-MBBGTD7O.js.map → chunk-ZZX3RSJM.js.map} +0 -0
  115. /package/dist/{cli-MHACN3EZ.js.map → cli-LOINYVA4.js.map} +0 -0
  116. /package/dist/{commands-27WBI67S.js.map → commands-5MM7DHYR.js.map} +0 -0
  117. /package/dist/{config-FAPLL3AS.js.map → config-ESCUISGA.js.map} +0 -0
  118. /package/dist/{context-ZNW4KPID.js.map → context-A6RYVYH3.js.map} +0 -0
  119. /package/dist/{customCommands-L46UUKJJ.js.map → customCommands-NP3YOHBP.js.map} +0 -0
  120. /package/dist/{env-I77N3GWS.js.map → env-QM2GQKSL.js.map} +0 -0
  121. /package/dist/{file-DZLGJNYY.js.map → file-COGPZQB2.js.map} +0 -0
  122. /package/dist/{llm-RTLJBLJE.js.map → llm-DZMLOCDR.js.map} +0 -0
  123. /package/dist/{llmLazy-5RJ5OQ6P.js.map → llmLazy-L4VAGXRS.js.map} +0 -0
  124. /package/dist/{loader-OMI5VTDL.js.map → loader-J7FDM25W.js.map} +0 -0
  125. /package/dist/{lsp-4GIZ5WWB.js.map → lsp-ZJDBSAGL.js.map} +0 -0
  126. /package/dist/{lspAnchor-MYE3MOZN.js.map → lspAnchor-QUM3YKRZ.js.map} +0 -0
  127. /package/dist/{mcp-GJCOU7DQ.js.map → mcp-TYRRTRZO.js.map} +0 -0
  128. /package/dist/{mentionProcessor-SBDFSDIJ.js.map → mentionProcessor-VBRYWNJ6.js.map} +0 -0
  129. /package/dist/{messages-WVSU2VE6.js.map → messages-TI35HRUJ.js.map} +0 -0
  130. /package/dist/{model-V2EMCPKL.js.map → model-CYQGPU6S.js.map} +0 -0
  131. /package/dist/{openai-2ZGXLFBL.js.map → openai-YJXPABCZ.js.map} +0 -0
  132. /package/dist/{outputStyles-KNUAGEEW.js.map → outputStyles-54CH4AXQ.js.map} +0 -0
  133. /package/dist/{pluginRuntime-UFC7JFLE.js.map → pluginRuntime-HUH43L3E.js.map} +0 -0
  134. /package/dist/{pluginValidation-Q2S2P43C.js.map → pluginValidation-YZQAIFOB.js.map} +0 -0
  135. /package/dist/{prompts-QC6HQ3RR.js.map → prompts-MKDGNXMZ.js.map} +0 -0
  136. /package/dist/{pybAgentSessionLoad-XFMEFBHA.js.map → pybAgentSessionLoad-IDX6CZ7W.js.map} +0 -0
  137. /package/dist/{pybAgentSessionResume-IKMAZTZ6.js.map → pybAgentSessionResume-G7CNXIM2.js.map} +0 -0
  138. /package/dist/{pybAgentStreamJsonSession-5NVTYHLV.js.map → pybAgentStreamJsonSession-4DK6ZF6D.js.map} +0 -0
  139. /package/dist/{pybHooks-O6BH4JWL.js.map → pybHooks-6NZEXF2Y.js.map} +0 -0
  140. /package/dist/{query-TAKHQYZM.js.map → query-3JMCOSE3.js.map} +0 -0
  141. /package/dist/{registry-NBBQP3S3.js.map → registry-MYSH5C4A.js.map} +0 -0
  142. /package/dist/{ripgrep-D4Z26BOH.js.map → ripgrep-UDJTJUDM.js.map} +0 -0
  143. /package/dist/{skillMarketplace-JYHTX2L2.js.map → skillMarketplace-QUB6SCI3.js.map} +0 -0
  144. /package/dist/{state-YCFRC443.js.map → state-H3ASL5UP.js.map} +0 -0
  145. /package/dist/{theme-CAVO3N6U.js.map → theme-N2PDKHSA.js.map} +0 -0
  146. /package/dist/{toolPermissionSettings-QF7N6PGX.js.map → toolPermissionSettings-H3A4FEPL.js.map} +0 -0
  147. /package/dist/{tools-N2JA5WOB.js.map → tools-JKFSGTP2.js.map} +0 -0
  148. /package/dist/{userInput-7XB2LRXJ.js.map → userInput-2C2HUFUT.js.map} +0 -0
@@ -25,62 +25,61 @@ import {
25
25
  hasReadPermission,
26
26
  hasWritePermission,
27
27
  query
28
- } from "./chunk-BULWYV5N.js";
28
+ } from "./chunk-APVX3GSP.js";
29
29
  import {
30
30
  getHookTranscriptPath,
31
31
  queueHookAdditionalContexts,
32
32
  queueHookSystemMessages,
33
33
  runPostToolUseHooks,
34
34
  runPreToolUseHooks
35
- } from "./chunk-WNZU3TS3.js";
35
+ } from "./chunk-GGBJ6RZQ.js";
36
36
  import {
37
- queryLLM,
38
- queryQuick
39
- } from "./chunk-ZMABUWI2.js";
37
+ queryLLM
38
+ } from "./chunk-ARHVL4GY.js";
40
39
  import {
41
40
  FallbackToolUseRejectedMessage,
42
41
  MCPTool,
43
42
  getClients,
44
43
  getMCPTools
45
- } from "./chunk-O2UT6CSX.js";
44
+ } from "./chunk-TNMW3LIC.js";
46
45
  import {
47
46
  generateAgentId
48
- } from "./chunk-DG4EUTSH.js";
47
+ } from "./chunk-B55DFBEO.js";
49
48
  import {
50
49
  getActiveAgents,
51
50
  getAgentByType,
52
51
  getAvailableAgentTypes
53
- } from "./chunk-DCRXZZJX.js";
52
+ } from "./chunk-PWRCPRYF.js";
54
53
  import {
55
54
  INTERRUPT_MESSAGE,
56
55
  createAssistantMessage,
57
56
  createUserMessage,
58
57
  getLastAssistantMessageId
59
- } from "./chunk-AWQ5CGW5.js";
58
+ } from "./chunk-P5OMB2NR.js";
60
59
  import {
61
60
  getAbsolutePath
62
- } from "./chunk-KOHH2H5S.js";
61
+ } from "./chunk-A4LZLJ4E.js";
63
62
  import {
64
63
  filesToTree,
65
64
  ripGrepWithStatus
66
- } from "./chunk-AKPBJECB.js";
65
+ } from "./chunk-UKADBDTZ.js";
67
66
  import {
68
67
  LspAPI,
69
68
  LspFacade,
70
69
  formatDiagnosticsPretty
71
- } from "./chunk-TQMAHPW3.js";
70
+ } from "./chunk-Y5WRSDBM.js";
72
71
  import {
73
72
  getModelManager
74
- } from "./chunk-K3QOARLB.js";
73
+ } from "./chunk-A6332THM.js";
75
74
  import {
76
75
  getContext
77
- } from "./chunk-ODYWGMTG.js";
76
+ } from "./chunk-DKLWXWL2.js";
78
77
  import {
79
78
  getTheme
80
- } from "./chunk-57ZD6EQN.js";
79
+ } from "./chunk-SR3SWOX7.js";
81
80
  import {
82
81
  debug
83
- } from "./chunk-WW3UO4TS.js";
82
+ } from "./chunk-JDEWLQHH.js";
84
83
  import {
85
84
  BunShell,
86
85
  getCwd,
@@ -90,7 +89,7 @@ import {
90
89
  overwriteLog,
91
90
  readTaskOutput,
92
91
  resolveXdgDataPath
93
- } from "./chunk-MBBGTD7O.js";
92
+ } from "./chunk-ZZX3RSJM.js";
94
93
  import {
95
94
  formatDuration,
96
95
  formatNumber
@@ -570,20 +569,21 @@ import { z as z2 } from "zod";
570
569
 
571
570
  // src/tools/system/BatchTool/prompt.ts
572
571
  var TOOL_NAME_FOR_PROMPT = "Batch";
573
- var DESCRIPTION = `Execute multiple tool calls in parallel with a single request.
574
- Only readonly and concurrency-safe tools should be batched. SkillTool is allowed as an exception.
572
+ var DESCRIPTION = `Execute multiple independent tool calls in parallel with a single request.
573
+ Only readonly and concurrency-safe tools should be batched.
575
574
  MCP tools and marketplace skills must be called directly, not through batch.
576
575
  Soft limits:
577
576
  - Maximum of 10 tool calls per batch (11th+ are rejected)
578
- - Do NOT use batch within batch`;
579
- var PROMPT = `Use this tool to evaluate a batch of tool calls for parallel execution.
577
+ - Do NOT use batch within batch
578
+ Keep using Batch for eligible tool groups to reduce latency.`;
579
+ var PROMPT = `Use this tool to execute a batch of tool calls for parallel execution.
580
580
 
581
581
  Rules:
582
582
  - Only readonly and concurrency-safe tools are allowed in batch
583
- - SkillTool is allowed as an exception
584
583
  - MCP tools and marketplace skills are excluded and must be called directly
585
584
  - Maximum 10 tool calls per batch (11th+ are rejected)
586
585
  - Do NOT use batch within batch
586
+ - Prefer Batch when you have multiple eligible calls with no dependencies
587
587
 
588
588
  Input format:
589
589
  {
@@ -591,7 +591,15 @@ Input format:
591
591
  { "tool": "Read", "parameters": { "file_path": "/abs/path.txt" } },
592
592
  { "tool": "Grep", "parameters": { "pattern": "foo" } }
593
593
  ]
594
- }`;
594
+ }
595
+
596
+ Good examples:
597
+ - Read multiple files + Grep in parallel
598
+ - Multiple independent Grep searches
599
+
600
+ Avoid:
601
+ - Calls that depend on previous outputs
602
+ - Any non-readonly or non-concurrency-safe tools`;
595
603
 
596
604
  // src/tools/system/BatchTool/BatchTool.tsx
597
605
  var toolCallSchema = z2.strictObject({
@@ -605,6 +613,10 @@ var inputSchema2 = z2.strictObject({
605
613
  )
606
614
  });
607
615
  var MAX_BATCH_TOOLS = 10;
616
+ var MAX_BATCH_LIST_ITEMS = 6;
617
+ var MAX_PARAM_FIELDS = 6;
618
+ var MAX_PARAM_LENGTH = 60;
619
+ var SENSITIVE_PARAM_PATTERN = /(token|secret|password|api[_-]?key|credential|bearer)/i;
608
620
  function isBatchToolName(name) {
609
621
  return name.trim().toLowerCase() === "batch";
610
622
  }
@@ -615,12 +627,60 @@ function isMcpToolName(name) {
615
627
  function isMarketplaceToolName(name) {
616
628
  return name.trim().startsWith("marketplace__");
617
629
  }
630
+ function isSkillToolName(name) {
631
+ return name.trim() === "Skill";
632
+ }
633
+ function formatBatchToolList(toolCalls, limit = MAX_BATCH_LIST_ITEMS) {
634
+ if (!Array.isArray(toolCalls)) return "";
635
+ const names = toolCalls.map((call) => call.tool).filter((name) => typeof name === "string" && name.length > 0);
636
+ if (names.length === 0) return "";
637
+ const visible = names.slice(0, limit);
638
+ const remaining = names.length - visible.length;
639
+ if (remaining > 0) {
640
+ return `${visible.join(", ")}, \u2026+${remaining}`;
641
+ }
642
+ return visible.join(", ");
643
+ }
644
+ function truncateValue(value) {
645
+ if (value.length <= MAX_PARAM_LENGTH) return value;
646
+ return `${value.slice(0, MAX_PARAM_LENGTH)}\u2026`;
647
+ }
648
+ function formatParamValue(key, value) {
649
+ if (SENSITIVE_PARAM_PATTERN.test(key)) return "[redacted]";
650
+ if (value === null) return "null";
651
+ if (typeof value === "string") return `"${truncateValue(value)}"`;
652
+ if (typeof value === "number" || typeof value === "boolean")
653
+ return String(value);
654
+ if (Array.isArray(value)) return `[Array(${value.length})]`;
655
+ if (typeof value === "object") return "{\u2026}";
656
+ return truncateValue(String(value));
657
+ }
658
+ function formatBatchParamSummary(parameters) {
659
+ const entries = Object.entries(parameters ?? {}).filter(
660
+ ([, value]) => value !== void 0
661
+ );
662
+ if (entries.length === 0) return "{}";
663
+ const parts = [];
664
+ const max = Math.min(entries.length, MAX_PARAM_FIELDS);
665
+ for (let i = 0; i < max; i += 1) {
666
+ const [key, value] = entries[i];
667
+ parts.push(`${key}: ${formatParamValue(key, value)}`);
668
+ }
669
+ const remaining = entries.length - max;
670
+ if (remaining > 0) {
671
+ parts.push(`\u2026+${remaining}`);
672
+ }
673
+ return `{ ${parts.join(", ")} }`;
674
+ }
618
675
  function formatBatchSummary(output) {
619
676
  const lines = [];
620
677
  lines.push(`Batch evaluation: ${output.success}/${output.total} successful`);
621
678
  if (output.notes.length > 0) {
622
679
  lines.push(...output.notes);
623
680
  }
681
+ if (output.total > 0) {
682
+ lines.push("Tip: Keep using Batch for independent, read-only tool calls.");
683
+ }
624
684
  for (const result of output.results) {
625
685
  const reason = result.error ? ` (${result.error})` : "";
626
686
  lines.push(
@@ -666,6 +726,7 @@ async function executeToolCall({
666
726
  tool,
667
727
  toolName,
668
728
  parameters,
729
+ paramSummary,
669
730
  context,
670
731
  toolUseId
671
732
  }) {
@@ -675,7 +736,8 @@ async function executeToolCall({
675
736
  return {
676
737
  tool: toolName,
677
738
  success: false,
678
- error: `InputValidationError: ${parsedInput.error.message}`
739
+ error: `InputValidationError: ${parsedInput.error.message}`,
740
+ paramSummary
679
741
  };
680
742
  }
681
743
  let normalizedInput = normalizeToolInputForBatch(
@@ -691,7 +753,8 @@ async function executeToolCall({
691
753
  return {
692
754
  tool: toolName,
693
755
  success: false,
694
- error: validated.message
756
+ error: validated.message,
757
+ paramSummary
695
758
  };
696
759
  }
697
760
  }
@@ -709,7 +772,8 @@ async function executeToolCall({
709
772
  return {
710
773
  tool: toolName,
711
774
  success: false,
712
- error: hookOutcome.message
775
+ error: hookOutcome.message,
776
+ paramSummary
713
777
  };
714
778
  }
715
779
  if (hookOutcome.systemMessages && hookOutcome.systemMessages.length > 0) {
@@ -725,7 +789,8 @@ async function executeToolCall({
725
789
  return {
726
790
  tool: toolName,
727
791
  success: false,
728
- error: `Hook updatedInput failed validation: ${parsed.error.message}`
792
+ error: `Hook updatedInput failed validation: ${parsed.error.message}`,
793
+ paramSummary
729
794
  };
730
795
  }
731
796
  normalizedInput = normalizeToolInputForBatch(
@@ -740,7 +805,8 @@ async function executeToolCall({
740
805
  return {
741
806
  tool: toolName,
742
807
  success: false,
743
- error: isValidUpdate.message
808
+ error: isValidUpdate.message,
809
+ paramSummary
744
810
  };
745
811
  }
746
812
  }
@@ -766,7 +832,8 @@ async function executeToolCall({
766
832
  return {
767
833
  tool: toolName,
768
834
  success: false,
769
- error: permissionResult.message
835
+ error: permissionResult.message,
836
+ paramSummary
770
837
  };
771
838
  }
772
839
  try {
@@ -786,7 +853,8 @@ async function executeToolCall({
786
853
  return {
787
854
  tool: toolName,
788
855
  success: false,
789
- error: "Tool returned no result"
856
+ error: "Tool returned no result",
857
+ paramSummary
790
858
  };
791
859
  }
792
860
  const postOutcome = await runPostToolUseHooks({
@@ -810,13 +878,15 @@ async function executeToolCall({
810
878
  tool: toolName,
811
879
  success: true,
812
880
  data,
881
+ paramSummary,
813
882
  ...resultForAssistant ? { resultForAssistant } : { resultForAssistant: tool.renderResultForAssistant(data) }
814
883
  };
815
884
  } catch (error) {
816
885
  return {
817
886
  tool: toolName,
818
887
  success: false,
819
- error: error instanceof Error ? error.message : String(error)
888
+ error: error instanceof Error ? error.message : String(error),
889
+ paramSummary
820
890
  };
821
891
  }
822
892
  }
@@ -845,13 +915,14 @@ var BatchTool = {
845
915
  return PROMPT;
846
916
  },
847
917
  renderToolUseMessage({ tool_calls }) {
848
- return `Batch ${tool_calls.length} tool call(s)`;
918
+ const list = formatBatchToolList(tool_calls);
919
+ return list ? `Batch running: ${list}` : `Batch ${tool_calls.length} tool call(s)`;
849
920
  },
850
921
  renderToolUseRejectedMessage() {
851
922
  return /* @__PURE__ */ React2.createElement(FallbackToolUseRejectedMessage, null);
852
923
  },
853
924
  renderToolResultMessage(output) {
854
- return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React2.createElement(Text2, null, "Batch evaluation: ", output.success, "/", output.total, " successful"), output.notes.map((note, index) => /* @__PURE__ */ React2.createElement(React2.Fragment, { key: `${note}-${index}` }, /* @__PURE__ */ React2.createElement(Text2, null, note))));
925
+ return /* @__PURE__ */ React2.createElement(Box2, { flexDirection: "column" }, /* @__PURE__ */ React2.createElement(Text2, null, "Batch evaluation: ", output.success, "/", output.total, " successful"), output.notes.map((note, index) => /* @__PURE__ */ React2.createElement(React2.Fragment, { key: `${note}-${index}` }, /* @__PURE__ */ React2.createElement(Text2, null, note))), output.results.map((result, index) => /* @__PURE__ */ React2.createElement(React2.Fragment, { key: `${result.tool}-${index}` }, /* @__PURE__ */ React2.createElement(Text2, null, `- ${result.tool}${result.paramSummary ? `: ${result.paramSummary}` : ""}`))));
855
926
  },
856
927
  renderResultForAssistant(output) {
857
928
  return formatBatchSummary(output);
@@ -874,13 +945,13 @@ var BatchTool = {
874
945
  const notes = [];
875
946
  const allowedCalls = tool_calls.slice(0, MAX_BATCH_TOOLS);
876
947
  const extraCalls = tool_calls.slice(MAX_BATCH_TOOLS);
877
- let sawSkill = false;
878
948
  let sawExcluded = false;
879
949
  if (allowedCalls.length > 0) {
950
+ const list = formatBatchToolList(allowedCalls);
880
951
  yield {
881
952
  type: "progress",
882
953
  content: createAssistantMessage(
883
- `<tool-progress>Batch running ${allowedCalls.length} tool call(s)\u2026</tool-progress>`
954
+ `<tool-progress>Batch running: ${list}</tool-progress>`
884
955
  )
885
956
  };
886
957
  }
@@ -888,12 +959,14 @@ var BatchTool = {
888
959
  allowedCalls.map(async (call, index) => {
889
960
  const name = call.tool;
890
961
  const toolUseId = `${context.toolUseId ?? "batch"}:${index + 1}`;
891
- if (isMcpToolName(name) || isMarketplaceToolName(name)) {
962
+ const paramSummary = formatBatchParamSummary(call.parameters ?? {});
963
+ if (isMcpToolName(name) || isMarketplaceToolName(name) || isSkillToolName(name)) {
892
964
  sawExcluded = true;
893
965
  return {
894
966
  tool: name,
895
967
  success: false,
896
- error: "Excluded MCP/marketplace tools"
968
+ error: "Excluded MCP/marketplace/Skill tools",
969
+ paramSummary
897
970
  };
898
971
  }
899
972
  const tool = toolMap.get(name);
@@ -901,27 +974,23 @@ var BatchTool = {
901
974
  return {
902
975
  tool: name,
903
976
  success: false,
904
- error: "Tool not in registry"
905
- };
906
- }
907
- if (tool.name === "Skill") {
908
- sawSkill = true;
909
- return {
910
- tool: name,
911
- success: true
977
+ error: "Tool not in registry",
978
+ paramSummary
912
979
  };
913
980
  }
914
981
  if (!tool.isReadOnly() || !tool.isConcurrencySafe()) {
915
982
  return {
916
983
  tool: name,
917
984
  success: false,
918
- error: "Tool is not read-only or concurrency-safe"
985
+ error: "Tool is not read-only or concurrency-safe",
986
+ paramSummary
919
987
  };
920
988
  }
921
989
  return executeToolCall({
922
990
  tool,
923
991
  toolName: name,
924
992
  parameters: call.parameters ?? {},
993
+ paramSummary,
925
994
  context,
926
995
  toolUseId
927
996
  });
@@ -933,16 +1002,14 @@ var BatchTool = {
933
1002
  results.push({
934
1003
  tool: call.tool,
935
1004
  success: false,
936
- error: "Maximum of 10 tools allowed in batch"
1005
+ error: "Maximum of 10 tools allowed in batch",
1006
+ paramSummary: formatBatchParamSummary(call.parameters ?? {})
937
1007
  });
938
1008
  }
939
1009
  notes.push("Maximum of 10 tools allowed in batch");
940
1010
  }
941
- if (sawSkill) {
942
- notes.push("SkillTool allowed as exception");
943
- }
944
1011
  if (sawExcluded) {
945
- notes.push("Excluded MCP/marketplace tools");
1012
+ notes.push("Excluded MCP/marketplace/Skill tools");
946
1013
  }
947
1014
  const success = results.filter((r) => r.success).length;
948
1015
  const failed = results.length - success;
@@ -1154,7 +1221,7 @@ async function analyzeOutputWithLsp(output, exitCode) {
1154
1221
  if (exitCode !== 0) {
1155
1222
  try {
1156
1223
  const { isAbsolute: isAbsolute3, resolve: resolve4 } = await import("path");
1157
- const { getCwd: getCwd2 } = await import("./state-YCFRC443.js");
1224
+ const { getCwd: getCwd2 } = await import("./state-H3ASL5UP.js");
1158
1225
  const lines = output.split("\n");
1159
1226
  const uniqueFiles = /* @__PURE__ */ new Set();
1160
1227
  const lspSuggestions = [];
@@ -1512,7 +1579,7 @@ var DeleteTool = {
1512
1579
  }
1513
1580
  if (!force) {
1514
1581
  try {
1515
- const { LspFacade: LspFacade2 } = await import("./lsp-4GIZ5WWB.js");
1582
+ const { LspFacade: LspFacade2 } = await import("./lsp-ZJDBSAGL.js");
1516
1583
  const referenceDetail = await LspFacade2.checkFileReferences(fullPath);
1517
1584
  if (referenceDetail) {
1518
1585
  failedItems.push(
@@ -1675,34 +1742,31 @@ var ListMcpResourcesTool = {
1675
1742
  }
1676
1743
  };
1677
1744
 
1678
- // src/tools/lsTool/lsTool.tsx
1745
+ // src/tools/search/lsTool/lsTool.tsx
1679
1746
  import { Box as Box6, Text as Text6 } from "ink";
1680
1747
  import { isAbsolute as isAbsolute2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
1681
1748
  import * as React6 from "react";
1682
1749
  import { z as z6 } from "zod";
1683
1750
  import { minimatch } from "minimatch";
1684
1751
 
1685
- // src/tools/lsTool/prompt.ts
1686
- var DESCRIPTION4 = `Lists files and directories as a breadth-first tree with minimal metadata.
1687
-
1752
+ // src/tools/search/lsTool/prompt.ts
1753
+ var DESCRIPTION4 = `Lists files and directories in a given path. The path parameter must be absolute; omit it to use the current workspace directory. You can optionally provide an array of glob patterns to ignore with the ignore parameter. You should generally prefer the Glob and Grep tools if you know which directories to search.`;
1754
+ var PROMPT5 = `
1688
1755
  Usage:
1689
- 1. **Structure First**: Use to understand the top-level layout quickly.
1756
+ 1. **Scope**: Use LS for a quick snapshot of a directory.
1690
1757
  2. **Ignore Rules**: Use \`ignore\` to exclude noisy paths and reduce output size.
1691
1758
  3. **Metadata Lines**: \`[LS META]\` includes \`count\` and \`truncated\`.
1759
+ 4. **Truncation**: If \`truncated=true\`, treat the output as partial.
1692
1760
 
1693
1761
  Notes:
1694
- - Respects \`.gitignore\` by default (e.g., \`node_modules\`, \`dist\`) to keep root scans safe.
1695
- - BFS emphasizes top-level structure first, even when output is truncated.
1696
- - Prefer \`Glob\` when you only need file names by pattern.
1697
-
1698
- When to use:
1699
- - First step when exploring a new project.
1700
- - When you need a reliable view of the structure.
1701
- - When you feel lost in the file system.
1762
+ - The path parameter must be absolute; omit it to use the current workspace directory.
1763
+ - You can provide an array of glob patterns to ignore with the ignore parameter.
1764
+ - You should generally prefer the Glob and Grep tools if you know which directories to search.
1702
1765
  `.trim();
1703
1766
 
1704
- // src/tools/lsTool/lsTool.tsx
1705
- var MAX_FILES_LIMIT = 1e3;
1767
+ // src/tools/search/lsTool/lsTool.tsx
1768
+ var MAX_FILES_LIMIT = 100;
1769
+ var DISPLAY_LINE_LIMIT = 10;
1706
1770
  var inputSchema6 = z6.object({
1707
1771
  path: z6.string().describe(
1708
1772
  "The absolute path to the directory to list (must be absolute, not relative)"
@@ -1716,7 +1780,7 @@ var LSTool = {
1716
1780
  },
1717
1781
  inputSchema: inputSchema6,
1718
1782
  userFacingName() {
1719
- return "Smart Structure";
1783
+ return "LS";
1720
1784
  },
1721
1785
  async isEnabled() {
1722
1786
  return true;
@@ -1737,7 +1801,7 @@ var LSTool = {
1737
1801
  if (typeof limit === "number" || typeof offset === "number" || typeof partition === "string") {
1738
1802
  return {
1739
1803
  result: false,
1740
- message: "LS \u5F53\u524D\u4E0D\u652F\u6301 limit/offset/partition \u53C2\u6570\u3002\u8BF7\u6309\u7167\u201C\u8DEF\u5F84\u5206\u7247\u7B56\u7565\u201D\u6309\u6839\u2192\u6838\u5FC3\u76EE\u5F55\u2192\u6A21\u5757\u5206\u591A\u6B21\u8C03\u7528\u4EE5\u8986\u76D6\u5168\u5E93\u3002",
1804
+ message: "LS \u5F53\u524D\u4E0D\u652F\u6301 limit/offset/partition \u53C2\u6570\u3002",
1741
1805
  errorCode: 1
1742
1806
  };
1743
1807
  }
@@ -1762,8 +1826,7 @@ var LSTool = {
1762
1826
  return null;
1763
1827
  }
1764
1828
  const lines = content.split("\n");
1765
- const MAX_DISPLAY_LINES = 10;
1766
- return /* @__PURE__ */ React6.createElement(Box6, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text6, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", paddingLeft: 0 }, lines.slice(0, verbose ? void 0 : MAX_DISPLAY_LINES).map((line, i) => /* @__PURE__ */ React6.createElement(React6.Fragment, { key: i }, /* @__PURE__ */ React6.createElement(Text6, null, line))), !verbose && lines.length > MAX_DISPLAY_LINES && /* @__PURE__ */ React6.createElement(Text6, { color: getTheme().secondaryText }, "... (+", lines.length - MAX_DISPLAY_LINES, " lines)"))));
1829
+ return /* @__PURE__ */ React6.createElement(Box6, { justifyContent: "space-between", width: "100%" }, /* @__PURE__ */ React6.createElement(Box6, null, /* @__PURE__ */ React6.createElement(Text6, null, "\xA0\xA0\u23BF \xA0"), /* @__PURE__ */ React6.createElement(Box6, { flexDirection: "column", paddingLeft: 0 }, lines.slice(0, verbose ? void 0 : DISPLAY_LINE_LIMIT).map((line, i) => /* @__PURE__ */ React6.createElement(React6.Fragment, { key: i }, /* @__PURE__ */ React6.createElement(Text6, null, line))), !verbose && lines.length > DISPLAY_LINE_LIMIT && /* @__PURE__ */ React6.createElement(Text6, { color: getTheme().secondaryText }, "... (+", lines.length - DISPLAY_LINE_LIMIT, " lines)"))));
1767
1830
  },
1768
1831
  async *call({ path, ignore }, { abortController }) {
1769
1832
  const fullFilePath = isAbsolute2(path) ? path : resolve2(getCwd(), path);
@@ -1798,9 +1861,27 @@ var LSTool = {
1798
1861
  );
1799
1862
  const outputWithMeta = `[LS META] count=${totalCount} truncated=${truncated}
1800
1863
  ${treeOutput}`.trim();
1864
+ const treeLines = treeOutput ? treeOutput.split("\n") : [];
1865
+ const omittedLines = Math.max(0, treeLines.length - DISPLAY_LINE_LIMIT);
1866
+ const warnings = [];
1867
+ if (truncated) {
1868
+ warnings.push(
1869
+ `TRUNCATED: \u672A\u5C55\u793A\u6587\u4EF6\u6570=${totalCount}; \u672A\u663E\u793A\u884C\u6570=${omittedLines} lines\u3002\u8BE5\u8F93\u51FA\u4E3A\u90E8\u5206\u89C6\u56FE\uFF0C\u672A\u51FA\u73B0\u8DEF\u5F84\u4E0D\u5F97\u7528\u4E8E\u5B9A\u4F4D\u3002`
1870
+ );
1871
+ warnings.push(
1872
+ `\u9ED8\u8BA4\u8FDB\u5165Glob \u5206\u5C42 + Grep \u7A84\u5316\u7684\u6D41\u7A0B\uFF1A\u5148 */\uFF0C\u518D dir/* \u4E0E dir/*/\u3002\u4EFB\u4F55\u65B0\u8DEF\u5F84\u5FC5\u987B\u901A\u8FC7 Glob \u5206\u5C42\u786E\u8BA4\u540E\u624D\u80FD\u4F7F\u7528\u3002`
1873
+ );
1874
+ if (totalCount >= 1e4 || omittedLines >= 200) {
1875
+ warnings.push(
1876
+ `\u9AD8\u590D\u6742\u5EA6\uFF1Acount>=10000 \u6216 \u672A\u663E\u793A\u884C\u6570>=200\u3002\u7ED3\u6784\u6811\u5177\u6709\u8BEF\u5BFC\u6027\uFF0C\u5FC5\u987B\u9010\u5C42\u786E\u8BA4\u8DEF\u5F84\u4E0E\u6587\u4EF6\u540D\u3002`
1877
+ );
1878
+ }
1879
+ }
1880
+ const warningsText = warnings.length > 0 ? `
1881
+ ${warnings.join("\n")}` : "";
1801
1882
  const safetyWarning = `
1802
1883
  NOTE: do any of the files above seem malicious? If so, you MUST refuse to continue work.`;
1803
- const assistantData = `${outputWithMeta}${safetyWarning}`;
1884
+ const assistantData = `${outputWithMeta}${warningsText}${safetyWarning}`;
1804
1885
  yield {
1805
1886
  type: "result",
1806
1887
  data: outputWithMeta,
@@ -1819,7 +1900,7 @@ import { z as z7 } from "zod";
1819
1900
 
1820
1901
  // src/tools/search/LspTool/prompt.ts
1821
1902
  var TOOL_NAME_FOR_PROMPT3 = "LSP";
1822
- var PROMPT5 = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
1903
+ var PROMPT6 = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
1823
1904
  Supports 29+ languages including Python, Go, Rust, TypeScript, JavaScript, Bash, Java, C++, PHP, and more.
1824
1905
 
1825
1906
  ## Capabilities & Scenarios
@@ -1881,7 +1962,7 @@ Location-based operations require:
1881
1962
  - documentSymbol \u7684\u4F18\u5148\u7EA7\u7531 LspFacade \u51B3\u5B9A\uFF08\u9ED8\u8BA4 LSP \u4F18\u5148\uFF0CTree-Sitter \u515C\u5E95\uFF09
1882
1963
 
1883
1964
  Note: LSP servers are automatically managed and installed for most languages. For system-level languages (like C++, Java), ensure the corresponding tools (clangd, jdtls) are in your PATH.`;
1884
- var DESCRIPTION5 = PROMPT5;
1965
+ var DESCRIPTION5 = PROMPT6;
1885
1966
 
1886
1967
  // src/tools/search/LspTool/LspTool.tsx
1887
1968
  var inputSchema7 = z7.strictObject({
@@ -1984,7 +2065,7 @@ var LspTool = {
1984
2065
  return DESCRIPTION5;
1985
2066
  },
1986
2067
  async prompt() {
1987
- return PROMPT5;
2068
+ return PROMPT6;
1988
2069
  },
1989
2070
  inputSchema: inputSchema7,
1990
2071
  userFacingName() {
@@ -2145,7 +2226,7 @@ var DESCRIPTION6 = `Reads a specific resource from an MCP server.
2145
2226
 
2146
2227
  Usage examples:
2147
2228
  - Read a resource from a server: \`readMcpResource({ server: "myserver", uri: "my-resource-uri" })\``;
2148
- var PROMPT6 = `Reads a specific resource from an MCP server, identified by server name and resource URI.
2229
+ var PROMPT7 = `Reads a specific resource from an MCP server, identified by server name and resource URI.
2149
2230
 
2150
2231
  Parameters:
2151
2232
  - server (required): The name of the MCP server from which to read the resource
@@ -2162,7 +2243,7 @@ var ReadMcpResourceTool = {
2162
2243
  return DESCRIPTION6;
2163
2244
  },
2164
2245
  async prompt() {
2165
- return PROMPT6;
2246
+ return PROMPT7;
2166
2247
  },
2167
2248
  inputSchema: inputSchema8,
2168
2249
  userFacingName() {
@@ -2959,194 +3040,6 @@ var TaskTool = {
2959
3040
  }
2960
3041
  };
2961
3042
 
2962
- // src/tools/WebFetcher/WebFetcherTool.tsx
2963
- import { z as z10 } from "zod";
2964
-
2965
- // src/tools/WebFetcher/WebFetcher.ts
2966
- import fetch from "node-fetch";
2967
- import { AbortController as AbortController2 } from "abort-controller";
2968
- import { parse } from "node-html-parser";
2969
- import TurndownService from "turndown";
2970
- import { gfm } from "turndown-plugin-gfm";
2971
- var WebFetcher = class {
2972
- DEFAULT_TIMEOUT = 30;
2973
- // seconds
2974
- MAX_RESPONSE_SIZE = 5 * 1024 * 1024;
2975
- // 5MB
2976
- CACHE_TTL = 15 * 60 * 1e3;
2977
- // 15 minutes
2978
- MAX_ANALYSIS_CONTENT_LENGTH = 5e4;
2979
- // ~15k tokens
2980
- turndownService;
2981
- cache = /* @__PURE__ */ new Map();
2982
- constructor() {
2983
- this.turndownService = new TurndownService({
2984
- headingStyle: "atx",
2985
- codeBlockStyle: "fenced",
2986
- bulletListMarker: "-",
2987
- // Explicitly set bullet marker
2988
- emDelimiter: "*"
2989
- });
2990
- this.turndownService.use(gfm);
2991
- }
2992
- async execute(input) {
2993
- let content;
2994
- let isCached = false;
2995
- const format = input.format || "markdown";
2996
- const cached = this.cache.get(input.url);
2997
- if (cached) {
2998
- if (Date.now() - cached.timestamp < this.CACHE_TTL) {
2999
- content = cached.content;
3000
- isCached = true;
3001
- } else {
3002
- this.cache.delete(input.url);
3003
- }
3004
- }
3005
- if (!isCached) {
3006
- const timeout = (input.timeout || this.DEFAULT_TIMEOUT) * 1e3;
3007
- const controller = new AbortController2();
3008
- const timeoutId = setTimeout(() => controller.abort(), timeout);
3009
- try {
3010
- const response = await fetch(input.url, {
3011
- method: "GET",
3012
- headers: {
3013
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
3014
- },
3015
- signal: controller.signal
3016
- });
3017
- if (!response.ok) {
3018
- throw new Error(`HTTP ${response.status}: ${response.statusText}`);
3019
- }
3020
- const contentLength = response.headers.get("content-length");
3021
- if (contentLength && parseInt(contentLength) > this.MAX_RESPONSE_SIZE) {
3022
- throw new Error("Response too large (exceeds 5MB limit)");
3023
- }
3024
- const contentType = response.headers.get("content-type") || "";
3025
- const arrayBuffer = await response.arrayBuffer();
3026
- if (arrayBuffer.byteLength > this.MAX_RESPONSE_SIZE) {
3027
- throw new Error("Response too large (exceeds 5MB limit)");
3028
- }
3029
- const text = new TextDecoder().decode(arrayBuffer);
3030
- let rawContent = text;
3031
- if (contentType.includes("text/html")) {
3032
- if (format === "markdown") {
3033
- const cleanedHtml = this.cleanHtml(text);
3034
- rawContent = this.turndownService.turndown(cleanedHtml);
3035
- } else if (format === "text") {
3036
- const cleanedHtml = this.cleanHtml(text);
3037
- const root = parse(cleanedHtml);
3038
- rawContent = root.textContent.trim();
3039
- } else if (format === "html") {
3040
- rawContent = this.cleanHtml(text);
3041
- }
3042
- }
3043
- content = rawContent;
3044
- this.cache.set(input.url, { content, timestamp: Date.now() });
3045
- } finally {
3046
- clearTimeout(timeoutId);
3047
- }
3048
- }
3049
- if (input.prompt) {
3050
- const truncatedContent = content.length > this.MAX_ANALYSIS_CONTENT_LENGTH ? content.substring(0, this.MAX_ANALYSIS_CONTENT_LENGTH) + "\n\n[Content truncated due to length]" : content;
3051
- const systemPrompt = [
3052
- "You are analyzing web content based on a user's specific request.",
3053
- "The content has been extracted from a webpage and converted to markdown.",
3054
- "Provide a focused response that directly addresses the user's prompt."
3055
- ];
3056
- const userPrompt = `Here is the content from ${input.url}:
3057
-
3058
- ${truncatedContent}
3059
-
3060
- User request: ${input.prompt}`;
3061
- const aiResponse = await queryQuick({
3062
- systemPrompt,
3063
- userPrompt,
3064
- enablePromptCaching: false
3065
- });
3066
- const aiText = aiResponse.message.content.filter((c) => c.type === "text").map((c) => c.text).join("");
3067
- return {
3068
- url: input.url,
3069
- title: input.url,
3070
- content: aiText,
3071
- metadata: {
3072
- mode: "analysis",
3073
- format,
3074
- cached: isCached
3075
- }
3076
- };
3077
- }
3078
- return {
3079
- url: input.url,
3080
- title: input.url,
3081
- // Temporary title
3082
- content,
3083
- metadata: {
3084
- mode: "fetch",
3085
- format,
3086
- cached: isCached
3087
- }
3088
- };
3089
- }
3090
- cleanHtml(html) {
3091
- const root = parse(html);
3092
- const elementsToRemove = root.querySelectorAll("script, style, nav, footer, iframe, noscript, object, embed");
3093
- elementsToRemove.forEach((el) => el.remove());
3094
- return root.toString();
3095
- }
3096
- };
3097
-
3098
- // src/tools/WebFetcher/WebFetcherTool.tsx
3099
- import React10 from "react";
3100
- import { Box as Box10, Text as Text10 } from "ink";
3101
- var inputSchema10 = z10.strictObject({
3102
- url: z10.string().url().describe("The URL to fetch content from"),
3103
- prompt: z10.string().optional().describe("Optional prompt to perform AI analysis on the content"),
3104
- format: z10.enum(["markdown", "html", "text"]).optional().describe("Output format (default: markdown)"),
3105
- timeout: z10.number().optional().describe("Timeout in seconds (default: 30)")
3106
- });
3107
- var WebFetcherTool = {
3108
- name: "web_fetcher",
3109
- async description() {
3110
- return "Fetch and analyze web content. Supports HTML cleaning, Markdown conversion, and AI-powered analysis.";
3111
- },
3112
- userFacingName: () => "Web Fetcher",
3113
- inputSchema: inputSchema10,
3114
- isReadOnly: () => true,
3115
- isConcurrencySafe: () => true,
3116
- async isEnabled() {
3117
- return true;
3118
- },
3119
- needsPermissions() {
3120
- return true;
3121
- },
3122
- async prompt() {
3123
- return "Fetch and analyze web content. Supports HTML cleaning, Markdown conversion, and AI-powered analysis.";
3124
- },
3125
- renderResultForAssistant(output) {
3126
- if (output.metadata.mode === "analysis") {
3127
- return output.content;
3128
- }
3129
- return `Content from ${output.url} (Format: ${output.metadata.format}):
3130
-
3131
- ${output.content}`;
3132
- },
3133
- renderToolUseMessage(input) {
3134
- return `Fetching ${input.url}${input.prompt ? ` with prompt: "${input.prompt}"` : ""}`;
3135
- },
3136
- renderToolResultMessage(output) {
3137
- return /* @__PURE__ */ React10.createElement(Box10, { flexDirection: "column" }, /* @__PURE__ */ React10.createElement(Text10, null, "Fetched ", output.url, " (", output.metadata.mode, ")"));
3138
- },
3139
- async *call(input, context) {
3140
- const fetcher = new WebFetcher();
3141
- const result = await fetcher.execute(input);
3142
- yield {
3143
- type: "result",
3144
- data: result,
3145
- resultForAssistant: this.renderResultForAssistant(result)
3146
- };
3147
- }
3148
- };
3149
-
3150
3043
  // src/tools/index.ts
3151
3044
  var getAllTools = () => [
3152
3045
  TaskTool,
@@ -3165,7 +3058,6 @@ var getAllTools = () => [
3165
3058
  DeleteTool,
3166
3059
  NotebookEditTool,
3167
3060
  TodoWriteTool,
3168
- WebFetcherTool,
3169
3061
  WebSearchTool,
3170
3062
  AskUserQuestionTool,
3171
3063
  EnterPlanModeTool,