nolo-cli 0.11.0 → 0.12.0-alpha.10
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/{_executeModel-ZEDPX6OF.js → _executeModel-4F7VZR5U.js} +52 -50
- package/{action-AA4IJ5K2.js → action-OTOWUMPW.js} +8 -9
- package/{addContentAction-QYVO4SYP.js → addContentAction-JGBUVR7K.js} +7 -9
- package/{addDialogAgentAction-WVVKT5WQ.js → addDialogAgentAction-V6CL2UCF.js} +9 -10
- package/{agentDeleteCommand-RDPGYIWF.js → agentDeleteCommand-MMRSG6AB.js} +39 -28
- package/{agentEmailCommands-2HJJKS5F.js → agentEmailCommands-YFVKOGM7.js} +65 -62
- package/{agentListCommands-HFEVV3ZW.js → agentListCommands-2PZHIQ3I.js} +128 -31
- package/{agentMachineCommands-25ZOENJU.js → agentMachineCommands-55UUZNHF.js} +38 -26
- package/{agentPullCommand-GOL2S4W2.js → agentPullCommand-KRBRIFIY.js} +7 -7
- package/{agentRecordCommands-GTCOAM3L.js → agentRecordCommands-BTP3OAPL.js} +57 -54
- package/{agentRunCommand-YBS3JDLD.js → agentRunCommand-AA4QLRQZ.js} +60 -59
- package/{agentRunControl-K4VKNEHF.js → agentRunControl-IX4F5W2C.js} +3 -3
- package/{agentRuntimeLocal-UQBMQI2M.js → agentRuntimeLocal-QDJCBXM2.js} +31 -15
- package/{agentSlice-6EKOBCCS.js → agentSlice-6JAJOU3X.js} +8 -9
- package/{authCommand-O2OWACN4.js → authCommand-DMW336GT.js} +15 -15
- package/{authCommands-H7365TZP.js → authCommands-GH5T6RYV.js} +6 -6
- package/{chunk-E4HNJSHC.js → chunk-2BVGERJ2.js} +81 -19
- package/{chunk-LP65VRCI.js → chunk-3MI5LDDU.js} +6 -6
- package/{chunk-OPZYGHUC.js → chunk-3WGLLTK4.js} +59 -1
- package/{chunk-KJR5KAUQ.js → chunk-3XF6LCCN.js} +20 -7
- package/{chunk-PXZAAB4L.js → chunk-4LG74DRG.js} +4 -4
- package/{chunk-2FTTDCD4.js → chunk-4ON5AV72.js} +2 -1
- package/{chunk-IWX4UW2E.js → chunk-524BDL33.js} +89 -8
- package/{chunk-ISNCLGUZ.js → chunk-5NBHQD4D.js} +4 -3
- package/{chunk-ZPRK73XY.js → chunk-5S4SWV5G.js} +51 -38
- package/{chunk-EVZKZF32.js → chunk-5V524MHX.js} +195 -78
- package/{chunk-CKOJQDKR.js → chunk-7JJCGV7N.js} +146 -3
- package/{chunk-NEM67FX7.js → chunk-ARSC56DC.js} +1 -1
- package/{chunk-AFON4QUU.js → chunk-AS3ZQ3O2.js} +19 -28
- package/{chunk-4SOKXIW4.js → chunk-B4KT7RN2.js} +10 -13
- package/chunk-BYXBJQAS.js +0 -0
- package/{chunk-PXQN7IBQ.js → chunk-C3BFP57W.js} +95 -2
- package/{chunk-AEZAORLG.js → chunk-CGDQDXKZ.js} +5 -5
- package/{chunk-MQI77IRB.js → chunk-DPFWKRHG.js} +2 -2
- package/{chunk-TACHTH5D.js → chunk-EIMX5ER5.js} +18 -18
- package/{chunk-5MOUAAMK.js → chunk-FSUZIGIG.js} +197 -2578
- package/{chunk-FXXSGWAJ.js → chunk-H5Y2H2N6.js} +1 -1
- package/chunk-IKXL2HZ3.js +70 -0
- package/{chunk-QNMFBBZK.js → chunk-IVAOVLM7.js} +1 -1
- package/chunk-JFANOO7I.js +2274 -0
- package/{chunk-YPRZSPF3.js → chunk-JKWWVF2I.js} +1 -1
- package/{chunk-3NSIQZZ6.js → chunk-JU7J7EAV.js} +45 -45
- package/{chunk-X2S7JTIG.js → chunk-KWBH4RAL.js} +1280 -137
- package/{chunk-OUI3ZHYD.js → chunk-LUKQQJFL.js} +39 -2
- package/{chunk-BX6U3ETE.js → chunk-MG6BVV3T.js} +320 -102
- package/{chunk-L53FGHA4.js → chunk-MQRZ5QUH.js} +1 -1
- package/{chunk-2W2VYVI5.js → chunk-MZHSAPZP.js} +675 -177
- package/{chunk-YOCHZD7D.js → chunk-NCGFB7NN.js} +5 -3
- package/{chunk-DWGAEFJL.js → chunk-O4FOPRCP.js} +1 -1
- package/chunk-OGGHETUE.js +4900 -0
- package/{chunk-PNEW2Z3T.js → chunk-OHEKYYJF.js} +7 -7
- package/chunk-OOIN7HSO.js +146 -0
- package/{chunk-SV5MWASH.js → chunk-OPM2DE2J.js} +12 -12
- package/{chunk-5OIFWVX7.js → chunk-QJSTNKJY.js} +1 -1
- package/{chunk-C4FTUXVF.js → chunk-QLUFR47U.js} +11 -1
- package/{chunk-LAX2JSTX.js → chunk-QUHUVG6Y.js} +20 -2
- package/{chunk-D6OQHXVG.js → chunk-RQSOAMPJ.js} +22 -6
- package/{chunk-ZEYDOXHF.js → chunk-RUGEW4P7.js} +1515 -884
- package/{chunk-GBDSZATH.js → chunk-RWO5DGXI.js} +3 -3
- package/{chunk-S3GS2PRL.js → chunk-TA7VKOHU.js} +613 -70
- package/{chunk-XYZA7S7V.js → chunk-TQYYGE6G.js} +6 -6
- package/{chunk-YTBMA7NO.js → chunk-TYPHUVK5.js} +70 -8
- package/{chunk-4ZDM73SD.js → chunk-V2J635L5.js} +1 -1
- package/{chunk-C2MDQQ4O.js → chunk-VBSWHE5W.js} +1 -1
- package/{chunk-O26GI2JP.js → chunk-VKG4HXYV.js} +39 -8
- package/{chunk-IPYUUY4E.js → chunk-WPHL6ALY.js} +1 -1
- package/{chunk-7D3JY6C2.js → chunk-WVTBAALN.js} +64 -5
- package/{chunk-XFOLQLDN.js → chunk-XHQWJUW4.js} +2 -2
- package/{chunk-Q3UKJVU4.js → chunk-Y5P3ZRGC.js} +10 -10
- package/{chunk-KQQVGRA3.js → chunk-YUMYYXPI.js} +53 -183
- package/cliEnvHelpers-VYC2OPTB.js +30 -0
- package/{createAgentAutomationAction-LTI5QU35.js → createAgentAutomationAction-4NY4JLOK.js} +26 -26
- package/{createDialogAction-OJJ7L3L3.js → createDialogAction-I5WUWFJ6.js} +26 -26
- package/{createPageAction-5MXWVRGY.js → createPageAction-HFTIQ7TW.js} +26 -26
- package/{dbSlice-RQFQQVHT.js → dbSlice-J4PUZ6Y5.js} +6 -7
- package/{deleteFile-7XP5BGC7.js → deleteFile-M7UNIUOO.js} +4 -4
- package/{dialogCommands-JTJ3RPPW.js → dialogCommands-SVXRJFZS.js} +34 -23
- package/{dialogSlice-OWROKURJ.js → dialogSlice-35LA3ZRG.js} +26 -26
- package/{docCreateCommands-WJBEW2V7.js → docCreateCommands-Z7RIAYKQ.js} +34 -23
- package/{docDeleteCommands-BVEHJOY5.js → docDeleteCommands-NEYHUVZF.js} +35 -25
- package/{docReadCommands-NEWOZIJV.js → docReadCommands-I4US2SDE.js} +34 -23
- package/{docStore-3DXRYBMD.js → docStore-3CP2IO6M.js} +25 -25
- package/{docUpdateCommands-C7WHT7UU.js → docUpdateCommands-UU5HQBRP.js} +34 -23
- package/fetchMessages-KTNM7QAR.js +1 -1
- package/{getPricing-3E6UNPKL.js → getPricing-UGDJHI7M.js} +7 -3
- package/{handleSendMessageAction-B5PRR7BE.js → handleSendMessageAction-FWTLQGOZ.js} +30 -30
- package/index.js +77 -76
- package/{localDialogRead-YSKFFRTT.js → localDialogRead-2VRI24F4.js} +1 -1
- package/{machineCommands-IIIREAEK.js → machineCommands-STHZKBDJ.js} +64 -61
- package/{machineWsRunDispatch-3SIU6ILW.js → machineWsRunDispatch-7YHT4TPT.js} +56 -53
- package/{memoryCommands-O4MIPIWQ.js → memoryCommands-AFMES3LN.js} +5 -5
- package/{models-4OPOOLFS.js → models-LSCRJJ6P.js} +2 -2
- package/package.json +1 -1
- package/{read-QJNKRROM.js → read-2MIMRBZ2.js} +4 -4
- package/{readDocTool-H6X6KO6X.js → readDocTool-QHVGQHUJ.js} +1 -1
- package/{readlineWorkspace-HGP3I3OC.js → readlineWorkspace-OMRWYMB6.js} +1279 -716
- package/{removeDialogAgentAction-TCT35SOF.js → removeDialogAgentAction-XUZYQBV4.js} +13 -13
- package/{runAgentClientLoop-EFM4PTVI.js → runAgentClientLoop-FP2K33ZO.js} +47 -46
- package/{runtimeDoctorCommands-ID43Z7VX.js → runtimeDoctorCommands-QNF3J3UV.js} +6 -6
- package/{setDialogExtraReferencesAction-CGYLZMFH.js → setDialogExtraReferencesAction-PTAIFKGM.js} +9 -10
- package/{setPrimaryDialogAgentAction-F6BFQDJU.js → setPrimaryDialogAgentAction-HRFTDB44.js} +13 -13
- package/{settingSlice-2I5HMG47.js → settingSlice-VGRJUSE5.js} +7 -8
- package/{skillDiscovery-UGSQGX2U.js → skillDiscovery-6M2BZUFN.js} +3 -3
- package/{spaceCommands-MT7BWCIL.js → spaceCommands-GN73BCOB.js} +38 -29
- package/{spaceSlice-BS5TSW3W.js → spaceSlice-WTFNKOVA.js} +30 -26
- package/{streamAgentChatTurn-I3VBFNR3.js → streamAgentChatTurn-HBAQQVNK.js} +442 -130
- package/{toolApiClient-C7P7YSE4.js → toolApiClient-QI3YBNWB.js} +2 -2
- package/{tools-XSD2BOEN.js → tools-TPQYTLQZ.js} +34 -33
- package/{tuiSummaryLlmCaller-32NRHTT2.js → tuiSummaryLlmCaller-XDC7WG4K.js} +11 -7
- package/{updateCommands-VOSPKXFF.js → updateCommands-XZDOOYFH.js} +13 -5
- package/{updateDialogTitleAction-7FYNJOGP.js → updateDialogTitleAction-AWXNPUQJ.js} +30 -29
- package/chunk-AZPCASRE.js +0 -36
- package/chunk-BBYVOSU2.js +0 -792
- package/chunk-DCOA4QSN.js +0 -105
- package/chunk-UAD2WT54.js +0 -64
- package/{chunk-JK7VW2FN.js → chunk-5MIDPSSK.js} +3 -3
- package/{chunk-5CS33IBL.js → chunk-PDL2AV3E.js} +3 -3
- package/{chunk-5MMZUWSG.js → chunk-TOILAPLH.js} +5 -5
- package/{chunk-OOM6SJNR.js → chunk-TSUJOM6N.js} +6 -6
- package/{db-6QED3ZVO.js → db-HCJ5PRB5.js} +3 -3
- package/{offlineMarxistsAgentCommand-BCPJITJL.js → offlineMarxistsAgentCommand-5OOWZLJI.js} +3 -3
- package/{tableCommands-M3DJUETS.js → tableCommands-E4SQWDOX.js} +6 -6
- package/{understanding-ZOESBLF3.js → understanding-3CUQQ6SV.js} +3 -3
|
@@ -1,27 +1,36 @@
|
|
|
1
1
|
import {
|
|
2
2
|
applyChatCompletionDelta,
|
|
3
|
-
finalizeAccumulatedToolCalls,
|
|
4
3
|
flushChatCompletionStream,
|
|
4
|
+
providerHttpFailure,
|
|
5
5
|
readSseFrames,
|
|
6
|
-
throwIfChatCompletionStreamFailed
|
|
7
|
-
|
|
8
|
-
} from "./chunk-ZPRK73XY.js";
|
|
6
|
+
throwIfChatCompletionStreamFailed
|
|
7
|
+
} from "./chunk-5S4SWV5G.js";
|
|
9
8
|
import {
|
|
10
9
|
parseToolArgumentsJson
|
|
11
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-TA7VKOHU.js";
|
|
12
11
|
import {
|
|
13
12
|
createThinkParserState,
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
createToolCallAccumulator,
|
|
14
|
+
extractThinkContent,
|
|
15
|
+
finalizeAccumulatedToolCalls
|
|
16
|
+
} from "./chunk-3WGLLTK4.js";
|
|
17
|
+
import {
|
|
18
|
+
requiresBareImageUrl,
|
|
19
|
+
toBareImageUrlMessages
|
|
20
|
+
} from "./chunk-LUKQQJFL.js";
|
|
16
21
|
import {
|
|
17
22
|
buildProviderAuthHeaders,
|
|
18
|
-
buildProviderExecutionPlan
|
|
19
|
-
|
|
23
|
+
buildProviderExecutionPlan,
|
|
24
|
+
toOpenAiCompatibleMessages
|
|
25
|
+
} from "./chunk-TYPHUVK5.js";
|
|
20
26
|
import {
|
|
21
27
|
canonicalizeToolName,
|
|
22
28
|
createGlob,
|
|
23
29
|
resolveExecutableOnPath
|
|
24
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-B4KT7RN2.js";
|
|
31
|
+
import {
|
|
32
|
+
toErrorMessage
|
|
33
|
+
} from "./chunk-HNMXYYJR.js";
|
|
25
34
|
import {
|
|
26
35
|
asRecordOrEmpty
|
|
27
36
|
} from "./chunk-KX6YBIHG.js";
|
|
@@ -38,17 +47,14 @@ import {
|
|
|
38
47
|
asTrimmedLowercaseString
|
|
39
48
|
} from "./chunk-QSJ3HFEF.js";
|
|
40
49
|
import {
|
|
41
|
-
|
|
42
|
-
} from "./chunk-
|
|
50
|
+
isRecord
|
|
51
|
+
} from "./chunk-KUG52IAP.js";
|
|
43
52
|
import {
|
|
44
53
|
asTrimmedString
|
|
45
54
|
} from "./chunk-3EUW3WEO.js";
|
|
46
55
|
import {
|
|
47
56
|
asOptionalPositiveFiniteNumber
|
|
48
57
|
} from "./chunk-U6VC4MU4.js";
|
|
49
|
-
import {
|
|
50
|
-
isRecord
|
|
51
|
-
} from "./chunk-KUG52IAP.js";
|
|
52
58
|
import {
|
|
53
59
|
normalizeServerOrigin
|
|
54
60
|
} from "./chunk-CF7PE763.js";
|
|
@@ -81,9 +87,14 @@ function parseSseDataLineJson(line) {
|
|
|
81
87
|
|
|
82
88
|
// packages/agent-runtime/openAiCompatibleProvider.ts
|
|
83
89
|
function buildOpenAiCompatibleChatCompletionRequest(args) {
|
|
90
|
+
const messages = toOpenAiCompatibleMessages(args.messages);
|
|
84
91
|
const body = {
|
|
85
92
|
model: args.providerConfig.model,
|
|
86
|
-
messages:
|
|
93
|
+
messages: requiresBareImageUrl({
|
|
94
|
+
endpoint: args.providerConfig.endpoint,
|
|
95
|
+
provider: args.providerConfig.provider,
|
|
96
|
+
model: args.providerConfig.model
|
|
97
|
+
}) ? toBareImageUrlMessages(messages) : messages,
|
|
87
98
|
stream: args.stream ?? false,
|
|
88
99
|
...args.providerConfig.requestOptions,
|
|
89
100
|
...args.tools && args.tools.length > 0 ? { tools: args.tools } : {},
|
|
@@ -121,6 +132,9 @@ function parseOpenAiCompatibleChatCompletionResponse(args) {
|
|
|
121
132
|
...reasoning ? { reasoning_content: reasoning } : {},
|
|
122
133
|
...typeof choiceMessage?.reasoning_content === "string" && choiceMessage.reasoning_content ? { reasoning_content: choiceMessage.reasoning_content } : {},
|
|
123
134
|
...typeof rawFinishReason === "string" && rawFinishReason.length > 0 ? { finish_reason: rawFinishReason } : {},
|
|
135
|
+
// 非流式:拿到完整的 200 JSON body 本身就证明这次调用走完了,
|
|
136
|
+
// 不必等 finish_reason(有从不发它的上游,见 AgentRuntimeResult)。
|
|
137
|
+
stream_complete: true,
|
|
124
138
|
usage: args.data?.usage,
|
|
125
139
|
trace: args.trace
|
|
126
140
|
};
|
|
@@ -137,7 +151,7 @@ async function readOpenAiCompatibleSseCompletion(args) {
|
|
|
137
151
|
content: "",
|
|
138
152
|
reasoning: "",
|
|
139
153
|
usage: void 0,
|
|
140
|
-
accumulatedToolCalls:
|
|
154
|
+
accumulatedToolCalls: createToolCallAccumulator(),
|
|
141
155
|
thinkState: createThinkParserState(),
|
|
142
156
|
onTextDelta: args.onTextDelta,
|
|
143
157
|
onReasoningDelta: args.onReasoningDelta
|
|
@@ -152,7 +166,7 @@ async function readOpenAiCompatibleSseCompletion(args) {
|
|
|
152
166
|
content: state.content,
|
|
153
167
|
...state.reasoning ? { reasoning_content: state.reasoning } : {},
|
|
154
168
|
...tool_calls.length > 0 ? { tool_calls } : {},
|
|
155
|
-
...state.usage ? { usage: state.usage } : {},
|
|
169
|
+
...state.usage ? { usage: state.usage, stream_complete: true } : {},
|
|
156
170
|
...state.finishReason ? { finish_reason: state.finishReason } : {}
|
|
157
171
|
};
|
|
158
172
|
}
|
|
@@ -183,13 +197,12 @@ async function executeOpenAiCompatibleChatCompletion(args) {
|
|
|
183
197
|
}
|
|
184
198
|
}
|
|
185
199
|
if (!res.ok) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
}
|
|
192
|
-
throw new Error(`local provider failed: HTTP ${res.status} ${JSON.stringify(data2)}`);
|
|
200
|
+
throw providerHttpFailure({
|
|
201
|
+
label: "local provider",
|
|
202
|
+
status: res.status,
|
|
203
|
+
raw: await res.text().catch(() => ""),
|
|
204
|
+
messages: args.messages
|
|
205
|
+
});
|
|
193
206
|
}
|
|
194
207
|
const contentType = res.headers.get("content-type") ?? "";
|
|
195
208
|
const isEventStream = contentType.includes("text/event-stream");
|
|
@@ -206,6 +219,7 @@ async function executeOpenAiCompatibleChatCompletion(args) {
|
|
|
206
219
|
...streamed.tool_calls ? { tool_calls: streamed.tool_calls } : {},
|
|
207
220
|
...streamed.reasoning_content ? { reasoning_content: streamed.reasoning_content } : {},
|
|
208
221
|
...streamed.usage ? { usage: streamed.usage } : {},
|
|
222
|
+
...streamed.stream_complete ? { stream_complete: true } : {},
|
|
209
223
|
...streamed.finish_reason ? { finish_reason: streamed.finish_reason } : {},
|
|
210
224
|
trace: args.messages
|
|
211
225
|
};
|
|
@@ -389,10 +403,16 @@ function dialogMessageRecordToAgentRuntimeMessage(record) {
|
|
|
389
403
|
return {
|
|
390
404
|
role: record.role,
|
|
391
405
|
content: record.content ?? "",
|
|
406
|
+
...record.contextReference !== void 0 ? { context_reference: record.contextReference } : {},
|
|
392
407
|
...typeof record.reasoning_content === "string" ? { reasoning_content: record.reasoning_content } : {},
|
|
393
408
|
...typeof record.toolCallId === "string" ? { tool_call_id: record.toolCallId } : {},
|
|
394
409
|
...Array.isArray(record.tool_calls) ? { tool_calls: record.tool_calls } : {},
|
|
395
|
-
...typeof record.toolName === "string" ? { toolName: record.toolName } : {}
|
|
410
|
+
...typeof record.toolName === "string" ? { toolName: record.toolName } : {},
|
|
411
|
+
...(() => {
|
|
412
|
+
const raw = record.createdAt;
|
|
413
|
+
const ms = typeof raw === "number" ? raw : typeof raw === "string" ? Date.parse(raw) : NaN;
|
|
414
|
+
return Number.isFinite(ms) ? { createdAt: ms } : {};
|
|
415
|
+
})()
|
|
396
416
|
};
|
|
397
417
|
}
|
|
398
418
|
|
|
@@ -469,6 +489,7 @@ function buildDialogMessageWriteOps(args) {
|
|
|
469
489
|
dialogId: args.dialogId,
|
|
470
490
|
role: message.role,
|
|
471
491
|
content: message.content ?? "",
|
|
492
|
+
...message.context_reference !== void 0 ? { contextReference: message.context_reference } : {},
|
|
472
493
|
// 持久化思维链(reasoning):空轮/异常排查的关键证据,
|
|
473
494
|
// 回读由 dialogMessageRecordToAgentRuntimeMessage 还原。
|
|
474
495
|
...typeof message.reasoning_content === "string" ? { reasoning_content: message.reasoning_content } : {},
|
|
@@ -1338,7 +1359,7 @@ function buildSearchWorkspaceParameters(variant) {
|
|
|
1338
1359
|
const path = buildWorkspacePathProperty();
|
|
1339
1360
|
const includeIgnored = {
|
|
1340
1361
|
type: "boolean",
|
|
1341
|
-
description: "When true, search files ignored by .gitignore such as .tmp. Defaults to false
|
|
1362
|
+
description: "When true, search files ignored by .gitignore such as .tmp. Defaults to false. Build artifacts (dist/, *.tsbuildinfo, *.min.js, etc.) are always excluded regardless of this flag. .git and node_modules remain excluded."
|
|
1342
1363
|
};
|
|
1343
1364
|
const exclude = {
|
|
1344
1365
|
type: "array",
|
|
@@ -1701,6 +1722,24 @@ var EXEC_SHELL_TIMEOUT_ENV = "NOLO_EXEC_SHELL_TIMEOUT_MS";
|
|
|
1701
1722
|
var EXEC_SHELL_DETACH_ENV = "NOLO_EXEC_SHELL_DETACH_MS";
|
|
1702
1723
|
var DEFAULT_EXEC_SHELL_DETACH_MS = 12e4;
|
|
1703
1724
|
var DEFAULT_LOCAL_API_ORIGIN = "http://127.0.0.1:38123";
|
|
1725
|
+
var ALWAYS_EXCLUDED_GLOBS = [
|
|
1726
|
+
"*.tsbuildinfo",
|
|
1727
|
+
"dist/**",
|
|
1728
|
+
"build/**",
|
|
1729
|
+
"out/**",
|
|
1730
|
+
"coverage/**",
|
|
1731
|
+
".next/**",
|
|
1732
|
+
".turbo/**",
|
|
1733
|
+
"public/assets/**",
|
|
1734
|
+
"*.min.js",
|
|
1735
|
+
"*.min.css",
|
|
1736
|
+
"*.map",
|
|
1737
|
+
"*.lock",
|
|
1738
|
+
"bun.lockb",
|
|
1739
|
+
"*.ldb"
|
|
1740
|
+
];
|
|
1741
|
+
var DEFAULT_SEARCH_MAX_RESULTS = 200;
|
|
1742
|
+
var SEARCH_OUTPUT_CHAR_LIMIT = 2e4;
|
|
1704
1743
|
function readTrimmedString(value) {
|
|
1705
1744
|
return asOptionalTrimmedString(value);
|
|
1706
1745
|
}
|
|
@@ -2046,8 +2085,29 @@ function sliceReadFileContent(args) {
|
|
|
2046
2085
|
truncated: startLine > 1 || effectiveEndLine < totalLines
|
|
2047
2086
|
};
|
|
2048
2087
|
}
|
|
2049
|
-
function
|
|
2050
|
-
|
|
2088
|
+
function buildEolTolerantPattern(oldTextLf) {
|
|
2089
|
+
const escaped = oldTextLf.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
2090
|
+
const pattern = escaped.replace(/\n/g, "\\r?\\n");
|
|
2091
|
+
return new RegExp(pattern, "g");
|
|
2092
|
+
}
|
|
2093
|
+
function countAndReplaceEolTolerant(args) {
|
|
2094
|
+
const oldTextLf = normalizeEolToLf(args.oldText);
|
|
2095
|
+
const newTextLf = normalizeEolToLf(args.newText);
|
|
2096
|
+
const pattern = buildEolTolerantPattern(oldTextLf);
|
|
2097
|
+
let count = 0;
|
|
2098
|
+
const result = args.content.replace(pattern, (match) => {
|
|
2099
|
+
count++;
|
|
2100
|
+
const eol = match.includes("\r\n") ? "\r\n" : "\n";
|
|
2101
|
+
return convertEol(newTextLf, eol);
|
|
2102
|
+
});
|
|
2103
|
+
return { count, result };
|
|
2104
|
+
}
|
|
2105
|
+
function normalizeEolToLf(text) {
|
|
2106
|
+
return text.replace(/\r\n/g, "\n");
|
|
2107
|
+
}
|
|
2108
|
+
function convertEol(text, eol) {
|
|
2109
|
+
const lf = normalizeEolToLf(text);
|
|
2110
|
+
return eol === "\r\n" ? lf.replace(/\n/g, "\r\n") : lf;
|
|
2051
2111
|
}
|
|
2052
2112
|
function pluralizeReplacement(count) {
|
|
2053
2113
|
return count === 1 ? "replacement" : "replacements";
|
|
@@ -2068,8 +2128,8 @@ function requireWorkspaceGlobPattern(args) {
|
|
|
2068
2128
|
if (!pattern) throw new Error("globFiles requires a non-empty pattern.");
|
|
2069
2129
|
return pattern;
|
|
2070
2130
|
}
|
|
2071
|
-
function readWorkspaceMaxResults(args) {
|
|
2072
|
-
if (args.maxResults === void 0) return
|
|
2131
|
+
function readWorkspaceMaxResults(args, defaultValue) {
|
|
2132
|
+
if (args.maxResults === void 0) return defaultValue;
|
|
2073
2133
|
const value = Number(args.maxResults);
|
|
2074
2134
|
if (!Number.isInteger(value) || value < 1) {
|
|
2075
2135
|
throw new Error("maxResults must be a positive integer.");
|
|
@@ -2245,6 +2305,29 @@ function waitForNodeProcessExit(proc) {
|
|
|
2245
2305
|
});
|
|
2246
2306
|
});
|
|
2247
2307
|
}
|
|
2308
|
+
function isSpawnFailureError(error) {
|
|
2309
|
+
if (!error || typeof error !== "object") return false;
|
|
2310
|
+
const err = error;
|
|
2311
|
+
if (err.code === "ENOENT") return true;
|
|
2312
|
+
const message = toErrorMessage(error).toLowerCase();
|
|
2313
|
+
return message.includes("enoent") || message.includes("executable not found") || message.includes("spawn") && message.includes("not found");
|
|
2314
|
+
}
|
|
2315
|
+
function spawnFailedCommandResult(error, outputLimit) {
|
|
2316
|
+
const stderr = `spawn failed: ${toErrorMessage(error)}
|
|
2317
|
+
`;
|
|
2318
|
+
return {
|
|
2319
|
+
stdout: "",
|
|
2320
|
+
stderr,
|
|
2321
|
+
exitCode: 127,
|
|
2322
|
+
timedOut: false,
|
|
2323
|
+
spawnFailed: true,
|
|
2324
|
+
content: truncateToolOutput(
|
|
2325
|
+
[`stderr:
|
|
2326
|
+
${stderr.trim()}`, "exitCode: 127"].filter(Boolean).join("\n\n"),
|
|
2327
|
+
outputLimit
|
|
2328
|
+
)
|
|
2329
|
+
};
|
|
2330
|
+
}
|
|
2248
2331
|
function resolveRipgrepBinary(env = process.env) {
|
|
2249
2332
|
const fromEnv = asOptionalTrimmedString(env.NOLO_BUNDLED_RG);
|
|
2250
2333
|
if (fromEnv) {
|
|
@@ -2255,6 +2338,9 @@ function resolveRipgrepBinary(env = process.env) {
|
|
|
2255
2338
|
}
|
|
2256
2339
|
return resolveExecutableOnPath("rg");
|
|
2257
2340
|
}
|
|
2341
|
+
function resolveGrepBinary() {
|
|
2342
|
+
return resolveExecutableOnPath("grep");
|
|
2343
|
+
}
|
|
2258
2344
|
async function runWorkspaceCommand(args) {
|
|
2259
2345
|
const timeoutMs = asOptionalPositiveFiniteNumber(args.timeoutMs);
|
|
2260
2346
|
const detached = process.platform !== "win32";
|
|
@@ -2339,7 +2425,21 @@ async function runWorkspaceCommand(args) {
|
|
|
2339
2425
|
}
|
|
2340
2426
|
if (abortPromise) racers.push(abortPromise);
|
|
2341
2427
|
if (detachPromise) racers.push(detachPromise);
|
|
2342
|
-
|
|
2428
|
+
let raceWinner;
|
|
2429
|
+
try {
|
|
2430
|
+
raceWinner = await Promise.race(racers);
|
|
2431
|
+
} catch (error) {
|
|
2432
|
+
if (timeout) clearTimeout(timeout);
|
|
2433
|
+
if (detachTimer) clearTimeout(detachTimer);
|
|
2434
|
+
if (abortListener && args.abortSignal) {
|
|
2435
|
+
args.abortSignal.removeEventListener("abort", abortListener);
|
|
2436
|
+
}
|
|
2437
|
+
detachSignalCleanup();
|
|
2438
|
+
if (isSpawnFailureError(error)) {
|
|
2439
|
+
return spawnFailedCommandResult(error, args.outputLimit);
|
|
2440
|
+
}
|
|
2441
|
+
throw error;
|
|
2442
|
+
}
|
|
2343
2443
|
if (timeout) clearTimeout(timeout);
|
|
2344
2444
|
if (detachTimer) clearTimeout(detachTimer);
|
|
2345
2445
|
if (abortListener && args.abortSignal) {
|
|
@@ -2456,12 +2556,40 @@ async function runWorkspaceCommandLimitedLines(args) {
|
|
|
2456
2556
|
]);
|
|
2457
2557
|
} catch (error) {
|
|
2458
2558
|
const settled2 = await exitSettled;
|
|
2459
|
-
if (!settled2.ok)
|
|
2559
|
+
if (!settled2.ok) {
|
|
2560
|
+
return {
|
|
2561
|
+
stdout: "",
|
|
2562
|
+
stderr: `spawn failed: ${toErrorMessage(settled2.error)}
|
|
2563
|
+
`,
|
|
2564
|
+
exitCode: 127,
|
|
2565
|
+
limitedByMaxResults: false,
|
|
2566
|
+
spawnFailed: true
|
|
2567
|
+
};
|
|
2568
|
+
}
|
|
2569
|
+
if (isSpawnFailureError(error)) {
|
|
2570
|
+
return {
|
|
2571
|
+
stdout: "",
|
|
2572
|
+
stderr: `spawn failed: ${toErrorMessage(error)}
|
|
2573
|
+
`,
|
|
2574
|
+
exitCode: 127,
|
|
2575
|
+
limitedByMaxResults: false,
|
|
2576
|
+
spawnFailed: true
|
|
2577
|
+
};
|
|
2578
|
+
}
|
|
2460
2579
|
throw error;
|
|
2461
2580
|
}
|
|
2462
2581
|
if (!limitedByMaxResults && pending.trim()) lines.push(pending);
|
|
2463
2582
|
const settled = await exitSettled;
|
|
2464
|
-
if (!settled.ok)
|
|
2583
|
+
if (!settled.ok) {
|
|
2584
|
+
return {
|
|
2585
|
+
stdout: "",
|
|
2586
|
+
stderr: `spawn failed: ${toErrorMessage(settled.error)}
|
|
2587
|
+
`,
|
|
2588
|
+
exitCode: 127,
|
|
2589
|
+
limitedByMaxResults: false,
|
|
2590
|
+
spawnFailed: true
|
|
2591
|
+
};
|
|
2592
|
+
}
|
|
2465
2593
|
const exitCode = limitedByMaxResults ? 0 : settled.code;
|
|
2466
2594
|
const stderr = await stderrPromise;
|
|
2467
2595
|
return {
|
|
@@ -2590,13 +2718,16 @@ async function editFileTool(args) {
|
|
|
2590
2718
|
...args.confirmExternalFileAccess ? { confirmExternalFileAccess: args.confirmExternalFileAccess } : {}
|
|
2591
2719
|
});
|
|
2592
2720
|
const content = await readFile(absolutePath, "utf8");
|
|
2593
|
-
const replacementCount =
|
|
2721
|
+
const { count: replacementCount, result: nextContent } = countAndReplaceEolTolerant({
|
|
2722
|
+
content,
|
|
2723
|
+
oldText,
|
|
2724
|
+
newText
|
|
2725
|
+
});
|
|
2594
2726
|
if (replacementCount !== expectedReplacements) {
|
|
2595
2727
|
throw new Error(
|
|
2596
|
-
`editFile expected ${expectedReplacements} ${pluralizeReplacement(expectedReplacements)} but found ${replacementCount} in ${requestedPath}.`
|
|
2728
|
+
`editFile expected ${expectedReplacements} ${pluralizeReplacement(expectedReplacements)} but found ${replacementCount} in ${requestedPath} (matched after EOL normalization; verify the exact text).`
|
|
2597
2729
|
);
|
|
2598
2730
|
}
|
|
2599
|
-
const nextContent = content.split(oldText).join(newText);
|
|
2600
2731
|
await writeFile(absolutePath, nextContent, "utf8");
|
|
2601
2732
|
const relativePath = normalizeWorkspaceRelativePath({
|
|
2602
2733
|
workspaceRoot: resolve(args.workspaceRoot),
|
|
@@ -2693,7 +2824,7 @@ async function searchFilesTool(args) {
|
|
|
2693
2824
|
const parsed = parseWorkspaceToolArguments(args.call.arguments);
|
|
2694
2825
|
const query = requireWorkspaceSearchQuery(parsed);
|
|
2695
2826
|
const exclude = readWorkspaceExcludeGlobs(parsed);
|
|
2696
|
-
const maxResults = readWorkspaceMaxResults(parsed);
|
|
2827
|
+
const maxResults = readWorkspaceMaxResults(parsed, DEFAULT_SEARCH_MAX_RESULTS);
|
|
2697
2828
|
const contextLines = readWorkspaceContextLines(parsed);
|
|
2698
2829
|
const literal = parsed.literal === true;
|
|
2699
2830
|
const caseSensitive = parsed.caseSensitive === false ? false : true;
|
|
@@ -2708,8 +2839,8 @@ async function searchFilesTool(args) {
|
|
|
2708
2839
|
workspaceRoot: resolve(args.workspaceRoot),
|
|
2709
2840
|
targetPath: searchPath
|
|
2710
2841
|
});
|
|
2711
|
-
const rgBinary = resolveRipgrepBinary();
|
|
2712
|
-
const grepBinary =
|
|
2842
|
+
const rgBinary = (args.resolveRipgrepBinary ?? resolveRipgrepBinary)();
|
|
2843
|
+
const grepBinary = (args.resolveGrepBinary ?? resolveGrepBinary)();
|
|
2713
2844
|
const rgCommand = rgBinary ? [
|
|
2714
2845
|
rgBinary,
|
|
2715
2846
|
"--line-number",
|
|
@@ -2723,29 +2854,26 @@ async function searchFilesTool(args) {
|
|
|
2723
2854
|
"!node_modules",
|
|
2724
2855
|
"--glob",
|
|
2725
2856
|
"!.git",
|
|
2857
|
+
...ALWAYS_EXCLUDED_GLOBS.flatMap((g) => ["--glob", `!${g}`]),
|
|
2726
2858
|
...exclude.flatMap((excludePattern) => ["--glob", `!${excludePattern}`]),
|
|
2727
2859
|
"--",
|
|
2728
2860
|
query,
|
|
2729
2861
|
relativeSearchPath
|
|
2730
2862
|
] : null;
|
|
2731
|
-
const
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
...
|
|
2738
|
-
...contextLines !== void 0 ? ["-C", String(contextLines)] : [],
|
|
2739
|
-
"--exclude-dir=node_modules",
|
|
2740
|
-
"--exclude-dir=.git",
|
|
2741
|
-
...exclude.flatMap((excludePattern) => ["--exclude", excludePattern]),
|
|
2742
|
-
query,
|
|
2743
|
-
relativeSearchPath
|
|
2863
|
+
const grepExcludeArgs = [
|
|
2864
|
+
...ALWAYS_EXCLUDED_GLOBS.flatMap((g) => {
|
|
2865
|
+
if (!g.endsWith("/**")) return ["--exclude", g];
|
|
2866
|
+
const dir = g.replace(/\/\*\*$/, "");
|
|
2867
|
+
return dir.includes("/") ? [] : [`--exclude-dir=${dir}`];
|
|
2868
|
+
}),
|
|
2869
|
+
...exclude.flatMap((excludePattern) => ["--exclude", excludePattern])
|
|
2744
2870
|
];
|
|
2871
|
+
let searchEngine = "js";
|
|
2872
|
+
let binariesUnavailable = !rgBinary && !grepBinary;
|
|
2745
2873
|
const result = await (async () => {
|
|
2746
2874
|
if (rgCommand) {
|
|
2747
2875
|
try {
|
|
2748
|
-
|
|
2876
|
+
const rgResult = maxResults && !contextLines ? await runWorkspaceCommandLimitedLines({
|
|
2749
2877
|
workspaceRoot: args.workspaceRoot,
|
|
2750
2878
|
command: rgCommand,
|
|
2751
2879
|
maxLines: maxResults
|
|
@@ -2753,35 +2881,66 @@ async function searchFilesTool(args) {
|
|
|
2753
2881
|
workspaceRoot: args.workspaceRoot,
|
|
2754
2882
|
command: rgCommand
|
|
2755
2883
|
});
|
|
2884
|
+
if (!rgResult.spawnFailed) {
|
|
2885
|
+
searchEngine = "ripgrep";
|
|
2886
|
+
return rgResult;
|
|
2887
|
+
}
|
|
2756
2888
|
} catch {
|
|
2757
2889
|
}
|
|
2758
2890
|
}
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2891
|
+
if (grepBinary) {
|
|
2892
|
+
const grepCommand = [
|
|
2893
|
+
grepBinary,
|
|
2894
|
+
"-R",
|
|
2895
|
+
"-n",
|
|
2896
|
+
"-I",
|
|
2897
|
+
...literal ? ["-F"] : [],
|
|
2898
|
+
...caseSensitive ? [] : ["-i"],
|
|
2899
|
+
...contextLines !== void 0 ? ["-C", String(contextLines)] : [],
|
|
2900
|
+
"--exclude-dir=node_modules",
|
|
2901
|
+
"--exclude-dir=.git",
|
|
2902
|
+
...grepExcludeArgs,
|
|
2903
|
+
query,
|
|
2904
|
+
relativeSearchPath
|
|
2905
|
+
];
|
|
2906
|
+
try {
|
|
2907
|
+
const grepResult = maxResults && !contextLines ? await runWorkspaceCommandLimitedLines({
|
|
2908
|
+
workspaceRoot: args.workspaceRoot,
|
|
2909
|
+
command: grepCommand,
|
|
2910
|
+
maxLines: maxResults
|
|
2911
|
+
}) : await runWorkspaceCommand({
|
|
2912
|
+
workspaceRoot: args.workspaceRoot,
|
|
2913
|
+
command: grepCommand
|
|
2914
|
+
});
|
|
2915
|
+
if (!grepResult.spawnFailed) {
|
|
2916
|
+
searchEngine = "grep";
|
|
2917
|
+
return grepResult;
|
|
2918
|
+
}
|
|
2919
|
+
binariesUnavailable = true;
|
|
2920
|
+
} catch {
|
|
2921
|
+
binariesUnavailable = true;
|
|
2922
|
+
}
|
|
2923
|
+
} else {
|
|
2924
|
+
binariesUnavailable = true;
|
|
2775
2925
|
}
|
|
2926
|
+
return {
|
|
2927
|
+
stdout: "",
|
|
2928
|
+
stderr: "",
|
|
2929
|
+
exitCode: 0,
|
|
2930
|
+
limitedByMaxResults: false,
|
|
2931
|
+
spawnFailed: true
|
|
2932
|
+
};
|
|
2776
2933
|
})();
|
|
2777
2934
|
let outputLines = result.stdout.split(/\r?\n/).map((line) => line.trimEnd().replace(/^\.\//, "")).filter(Boolean);
|
|
2935
|
+
outputLines = dropAlwaysExcludedLines(outputLines);
|
|
2778
2936
|
let limitedByMaxResults = "limitedByMaxResults" in result && result.limitedByMaxResults === true;
|
|
2779
|
-
|
|
2937
|
+
const forceJsFallback = binariesUnavailable || result.spawnFailed === true;
|
|
2938
|
+
if (outputLines.length === 0 && (forceJsFallback || result.exitCode === 0 && (includeIgnored || !await hasRootGitignore(args.workspaceRoot)))) {
|
|
2780
2939
|
const fallback = await scanWorkspaceTextMatches({
|
|
2781
2940
|
workspaceRoot: args.workspaceRoot,
|
|
2782
2941
|
relativeSearchPath,
|
|
2783
2942
|
query,
|
|
2784
|
-
exclude,
|
|
2943
|
+
exclude: [...ALWAYS_EXCLUDED_GLOBS, ...exclude],
|
|
2785
2944
|
maxResults,
|
|
2786
2945
|
literal,
|
|
2787
2946
|
caseSensitive,
|
|
@@ -2789,6 +2948,7 @@ async function searchFilesTool(args) {
|
|
|
2789
2948
|
});
|
|
2790
2949
|
outputLines = fallback.lines;
|
|
2791
2950
|
limitedByMaxResults = fallback.limitedByMaxResults;
|
|
2951
|
+
searchEngine = "js";
|
|
2792
2952
|
}
|
|
2793
2953
|
if (contextLines && outputLines.length > 0) {
|
|
2794
2954
|
const limited = limitSearchOutputByMatches(outputLines, maxResults);
|
|
@@ -2800,8 +2960,11 @@ async function searchFilesTool(args) {
|
|
|
2800
2960
|
const match = line.match(/^(.*?):\d+:/);
|
|
2801
2961
|
return match?.[1] ? [match[1]] : [];
|
|
2802
2962
|
})));
|
|
2963
|
+
const rawContent = outputLines.join("\n");
|
|
2964
|
+
const content = truncateToolOutput(rawContent, SEARCH_OUTPUT_CHAR_LIMIT);
|
|
2965
|
+
const truncatedByByteLimit = content.length !== rawContent.length;
|
|
2803
2966
|
return {
|
|
2804
|
-
content
|
|
2967
|
+
content,
|
|
2805
2968
|
metadata: {
|
|
2806
2969
|
query,
|
|
2807
2970
|
path: requestedPath,
|
|
@@ -2814,10 +2977,12 @@ async function searchFilesTool(args) {
|
|
|
2814
2977
|
count: outputLines.length,
|
|
2815
2978
|
matchCount: matchLines.length,
|
|
2816
2979
|
matchedFiles,
|
|
2817
|
-
truncated: limitedByMaxResults,
|
|
2980
|
+
truncated: limitedByMaxResults || truncatedByByteLimit,
|
|
2818
2981
|
limitedByMaxResults,
|
|
2982
|
+
...truncatedByByteLimit ? { truncatedByByteLimit: true } : {},
|
|
2819
2983
|
...maxResults ? { maxResults } : {},
|
|
2820
2984
|
exitCode: result.exitCode,
|
|
2985
|
+
searchEngine,
|
|
2821
2986
|
...extractActivity(parsed) ? { activity: extractActivity(parsed) } : {}
|
|
2822
2987
|
}
|
|
2823
2988
|
};
|
|
@@ -2848,6 +3013,14 @@ async function filterRootGitignoredFiles(args) {
|
|
|
2848
3013
|
const globs = patterns.map((pattern) => createGlob(pattern));
|
|
2849
3014
|
return args.files.filter((file) => !globs.some((glob) => glob.match(file)));
|
|
2850
3015
|
}
|
|
3016
|
+
function dropAlwaysExcludedLines(lines) {
|
|
3017
|
+
const globs = ALWAYS_EXCLUDED_GLOBS.map((pattern) => createGlob(pattern));
|
|
3018
|
+
return lines.filter((line) => {
|
|
3019
|
+
const filePath = line.match(/^(.*?):\d+[:-]/)?.[1];
|
|
3020
|
+
if (!filePath) return true;
|
|
3021
|
+
return !globs.some((glob) => glob.match(filePath));
|
|
3022
|
+
});
|
|
3023
|
+
}
|
|
2851
3024
|
function scanWorkspaceGlobFiles(args) {
|
|
2852
3025
|
const pathPrefix = args.relativeSearchPath === "." ? "" : `${args.relativeSearchPath.replace(/\/+$/, "")}/`;
|
|
2853
3026
|
return Array.from(createGlob(args.pattern).scanSync({
|
|
@@ -2940,38 +3113,76 @@ async function globFilesTool(args) {
|
|
|
2940
3113
|
workspaceRoot: resolve(args.workspaceRoot),
|
|
2941
3114
|
targetPath: searchPath
|
|
2942
3115
|
});
|
|
2943
|
-
const command = [
|
|
2944
|
-
"rg",
|
|
2945
|
-
"--files",
|
|
2946
|
-
"--hidden",
|
|
2947
|
-
...includeIgnored ? ["--no-ignore"] : [],
|
|
2948
|
-
"--glob",
|
|
2949
|
-
pattern,
|
|
2950
|
-
"--glob",
|
|
2951
|
-
"!node_modules",
|
|
2952
|
-
"--glob",
|
|
2953
|
-
"!.git",
|
|
2954
|
-
...exclude.flatMap((excludePattern) => ["--glob", `!${excludePattern}`]),
|
|
2955
|
-
...relativeSearchPath === "." ? [] : [relativeSearchPath]
|
|
2956
|
-
];
|
|
2957
|
-
const result = await runWorkspaceCommand({
|
|
2958
|
-
workspaceRoot: args.workspaceRoot,
|
|
2959
|
-
command
|
|
2960
|
-
});
|
|
2961
3116
|
const pathPrefix = relativeSearchPath === "." ? "" : `${relativeSearchPath.replace(/\/+$/, "")}/`;
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
3117
|
+
const rgBinary = (args.resolveRipgrepBinary ?? resolveRipgrepBinary)();
|
|
3118
|
+
let searchEngine = "js";
|
|
3119
|
+
let exitCode = 0;
|
|
3120
|
+
let files = [];
|
|
3121
|
+
if (rgBinary) {
|
|
3122
|
+
const command = [
|
|
3123
|
+
rgBinary,
|
|
3124
|
+
"--files",
|
|
3125
|
+
"--hidden",
|
|
3126
|
+
...includeIgnored ? ["--no-ignore"] : [],
|
|
3127
|
+
"--glob",
|
|
3128
|
+
pattern,
|
|
3129
|
+
"--glob",
|
|
3130
|
+
"!node_modules",
|
|
3131
|
+
"--glob",
|
|
3132
|
+
"!.git",
|
|
3133
|
+
...exclude.flatMap((excludePattern) => ["--glob", `!${excludePattern}`]),
|
|
3134
|
+
...relativeSearchPath === "." ? [] : [relativeSearchPath]
|
|
3135
|
+
];
|
|
3136
|
+
const result = await runWorkspaceCommand({
|
|
3137
|
+
workspaceRoot: args.workspaceRoot,
|
|
3138
|
+
command
|
|
3139
|
+
});
|
|
3140
|
+
exitCode = result.exitCode;
|
|
3141
|
+
if (result.spawnFailed) {
|
|
3142
|
+
files = scanWorkspaceGlobFiles({
|
|
3143
|
+
workspaceRoot: args.workspaceRoot,
|
|
3144
|
+
pattern,
|
|
3145
|
+
relativeSearchPath,
|
|
3146
|
+
exclude
|
|
3147
|
+
});
|
|
3148
|
+
files = await filterRootGitignoredFiles({
|
|
3149
|
+
workspaceRoot: args.workspaceRoot,
|
|
3150
|
+
files,
|
|
3151
|
+
includeIgnored
|
|
3152
|
+
});
|
|
3153
|
+
searchEngine = "js";
|
|
3154
|
+
} else {
|
|
3155
|
+
files = result.stdout.split(/\r?\n/).map((line) => line.trim().replace(/^\.\//, "")).filter(Boolean).filter((line) => !pathPrefix || line === relativeSearchPath || line.startsWith(pathPrefix)).sort((left, right) => left.localeCompare(right));
|
|
3156
|
+
files = await filterRootGitignoredFiles({
|
|
3157
|
+
workspaceRoot: args.workspaceRoot,
|
|
3158
|
+
files,
|
|
3159
|
+
includeIgnored
|
|
3160
|
+
});
|
|
3161
|
+
if (files.length === 0 && (includeIgnored || !await hasRootGitignore(args.workspaceRoot))) {
|
|
3162
|
+
files = scanWorkspaceGlobFiles({
|
|
3163
|
+
workspaceRoot: args.workspaceRoot,
|
|
3164
|
+
pattern,
|
|
3165
|
+
relativeSearchPath,
|
|
3166
|
+
exclude
|
|
3167
|
+
});
|
|
3168
|
+
searchEngine = "js";
|
|
3169
|
+
} else {
|
|
3170
|
+
searchEngine = "ripgrep";
|
|
3171
|
+
}
|
|
3172
|
+
}
|
|
3173
|
+
} else {
|
|
2969
3174
|
files = scanWorkspaceGlobFiles({
|
|
2970
3175
|
workspaceRoot: args.workspaceRoot,
|
|
2971
3176
|
pattern,
|
|
2972
3177
|
relativeSearchPath,
|
|
2973
3178
|
exclude
|
|
2974
3179
|
});
|
|
3180
|
+
files = await filterRootGitignoredFiles({
|
|
3181
|
+
workspaceRoot: args.workspaceRoot,
|
|
3182
|
+
files,
|
|
3183
|
+
includeIgnored
|
|
3184
|
+
});
|
|
3185
|
+
searchEngine = "js";
|
|
2975
3186
|
}
|
|
2976
3187
|
const commandLimitedByMaxResults = false;
|
|
2977
3188
|
const totalCount = commandLimitedByMaxResults ? void 0 : files.length;
|
|
@@ -2992,7 +3203,8 @@ async function globFilesTool(args) {
|
|
|
2992
3203
|
truncated: limitedByMaxResults,
|
|
2993
3204
|
limitedByMaxResults,
|
|
2994
3205
|
...maxResults ? { maxResults } : {},
|
|
2995
|
-
exitCode
|
|
3206
|
+
exitCode,
|
|
3207
|
+
searchEngine,
|
|
2996
3208
|
...activity ? { activity } : {}
|
|
2997
3209
|
}
|
|
2998
3210
|
};
|
|
@@ -3196,6 +3408,10 @@ async function listProcessesTool(args) {
|
|
|
3196
3408
|
}
|
|
3197
3409
|
function createLocalWorkspaceToolExecutors(args) {
|
|
3198
3410
|
const fileAccess = args.confirmExternalFileAccess ? { confirmExternalFileAccess: args.confirmExternalFileAccess } : {};
|
|
3411
|
+
const searchBinaryResolvers = {
|
|
3412
|
+
...args.resolveRipgrepBinary ? { resolveRipgrepBinary: args.resolveRipgrepBinary } : {},
|
|
3413
|
+
...args.resolveGrepBinary ? { resolveGrepBinary: args.resolveGrepBinary } : {}
|
|
3414
|
+
};
|
|
3199
3415
|
return {
|
|
3200
3416
|
editFile: (call) => editFileTool({
|
|
3201
3417
|
call,
|
|
@@ -3205,7 +3421,8 @@ function createLocalWorkspaceToolExecutors(args) {
|
|
|
3205
3421
|
globFiles: (call) => globFilesTool({
|
|
3206
3422
|
call,
|
|
3207
3423
|
workspaceRoot: args.workspaceRoot,
|
|
3208
|
-
...fileAccess
|
|
3424
|
+
...fileAccess,
|
|
3425
|
+
...args.resolveRipgrepBinary ? { resolveRipgrepBinary: args.resolveRipgrepBinary } : {}
|
|
3209
3426
|
}),
|
|
3210
3427
|
listFiles: (call) => listFilesTool({
|
|
3211
3428
|
call,
|
|
@@ -3225,7 +3442,8 @@ function createLocalWorkspaceToolExecutors(args) {
|
|
|
3225
3442
|
searchFiles: (call) => searchFilesTool({
|
|
3226
3443
|
call,
|
|
3227
3444
|
workspaceRoot: args.workspaceRoot,
|
|
3228
|
-
...fileAccess
|
|
3445
|
+
...fileAccess,
|
|
3446
|
+
...searchBinaryResolvers
|
|
3229
3447
|
}),
|
|
3230
3448
|
captureVisualState: (call) => captureVisualStateTool({
|
|
3231
3449
|
call,
|