nolo-cli 0.33.0-alpha.2 → 0.33.0-alpha.21

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 (118) hide show
  1. package/{_executeModel-RWPVI3YV.js → _executeModel-XKWVTZAY.js} +35 -34
  2. package/{action-SMLG6OTB.js → action-Q4KO7DDW.js} +4 -4
  3. package/{addContentAction-SFO244QN.js → addContentAction-FRXDZKSI.js} +3 -3
  4. package/{addDialogAgentAction-W44ZCEHB.js → addDialogAgentAction-XL5G3LPR.js} +2 -2
  5. package/{agentDeleteCommand-KU2RXQPP.js → agentDeleteCommand-ZU4H6F6M.js} +19 -18
  6. package/{agentEmailCommands-MPCMDENS.js → agentEmailCommands-6ULFXW4A.js} +41 -40
  7. package/{agentListCommands-EPD4N6FX.js → agentListCommands-VN7WCW7Z.js} +21 -20
  8. package/{agentMachineCommands-AF7C3YRT.js → agentMachineCommands-5PALVQBD.js} +21 -20
  9. package/{agentPullCommand-YH5GEBK4.js → agentPullCommand-TSWAJPS2.js} +1 -1
  10. package/{agentRecordCommands-EYE6MZZG.js → agentRecordCommands-XEB66KRX.js} +40 -39
  11. package/{agentRunCommand-LL22SGTN.js → agentRunCommand-OJX27NII.js} +42 -41
  12. package/{agentRuntimeLocal-JX34G47Z.js → agentRuntimeLocal-UWDOE55A.js} +20 -19
  13. package/{agentSlice-TNMFQQOV.js → agentSlice-SZRRJ3ZX.js} +5 -5
  14. package/{appDeleteCommands-43K5VXQB.js → appDeleteCommands-R63PZAY7.js} +20 -19
  15. package/{appDeployCommands-FEEJSVDZ.js → appDeployCommands-VNRT54YO.js} +20 -19
  16. package/{appDeployStatusCommands-H76CG45R.js → appDeployStatusCommands-6IPTKLEM.js} +20 -19
  17. package/{appGetCommands-MDZYFTYZ.js → appGetCommands-JPFVMVAI.js} +20 -19
  18. package/{appListCommands-TUJJXPWG.js → appListCommands-B3SLTPII.js} +20 -19
  19. package/{authCommand-T7UK4CWS.js → authCommand-EX5G5PF4.js} +12 -11
  20. package/{authCommands-EAPFGNHN.js → authCommands-VR6Q6GU2.js} +4 -4
  21. package/{chatQueueReduxAdapter-LVQXC4ZY.js → chatQueueReduxAdapter-IEX32ZVP.js} +15 -14
  22. package/{chunk-2H3XIBY4.js → chunk-2CNX3CJE.js} +4 -82
  23. package/{chunk-MPZJVZDC.js → chunk-2UDMTJOM.js} +9 -9
  24. package/{chunk-WHD6BG7M.js → chunk-37LDAHQN.js} +20 -18
  25. package/{chunk-2UECQ7RE.js → chunk-3AOLVADY.js} +1 -1
  26. package/{chunk-HUCT7HID.js → chunk-42IF53CR.js} +1 -1
  27. package/{chunk-AAGCMVFT.js → chunk-46JSKTPF.js} +189 -38
  28. package/{chunk-3WXRAHCG.js → chunk-6MSSX7FI.js} +1 -1
  29. package/{chunk-57QJXIB6.js → chunk-6YH4UR3E.js} +3 -3
  30. package/{chunk-HDKRSRYU.js → chunk-7BNPRRDS.js} +150 -29
  31. package/{chunk-FMEVI5TG.js → chunk-7CH6U3FL.js} +1 -1
  32. package/{chunk-OR2HNLVO.js → chunk-7EPNNOL4.js} +6 -6
  33. package/{chunk-PREQU5QV.js → chunk-7OGIWPNK.js} +1 -1
  34. package/{chunk-DFUPZE6V.js → chunk-7SLMYTSF.js} +1 -1
  35. package/{chunk-3GZXL6FM.js → chunk-AOWETAXX.js} +1 -1
  36. package/{chunk-2IVEXF7P.js → chunk-BHILFABL.js} +1 -1
  37. package/{chunk-TFPUAELY.js → chunk-DDET6246.js} +1 -1
  38. package/{chunk-ZURFOV5J.js → chunk-DMT4NJXR.js} +1 -1
  39. package/{chunk-RAZOLMJR.js → chunk-EQ6HOWEJ.js} +2 -2
  40. package/{chunk-6HYVJV7B.js → chunk-ESHYE7WU.js} +2 -1
  41. package/{chunk-JZ5AMMXU.js → chunk-FH7VUJN5.js} +2 -2
  42. package/{chunk-I6N2UVVY.js → chunk-FV63ICZC.js} +1 -1
  43. package/{chunk-U4TRT5V4.js → chunk-GEPHJJW4.js} +1 -1
  44. package/{chunk-VH2F7ZB6.js → chunk-GTEHJWXU.js} +1 -1
  45. package/{chunk-AOXVOC6D.js → chunk-HCOIKLSH.js} +2 -2
  46. package/{chunk-GTYM4HKV.js → chunk-IEHZHWN7.js} +2 -2
  47. package/{chunk-2QTEYCR7.js → chunk-JFUW3UTO.js} +1 -1
  48. package/{chunk-73GINUCW.js → chunk-JL2PUYVS.js} +102 -23
  49. package/{chunk-37V5LNEQ.js → chunk-KIL7V27H.js} +1 -1
  50. package/{chunk-JTSGWTYZ.js → chunk-KMMQFY5O.js} +1 -1
  51. package/{chunk-UK5JGQVU.js → chunk-KZB5SNYH.js} +9 -14
  52. package/{chunk-XCCGU6QB.js → chunk-L5XKDBSH.js} +1 -1
  53. package/{chunk-DPMBNHOJ.js → chunk-LAZTMWIU.js} +1 -1
  54. package/{chunk-M4NC7NF6.js → chunk-LJGEEYGC.js} +2 -2
  55. package/{chunk-B2BSG6QQ.js → chunk-LLKHGZME.js} +4 -4
  56. package/{chunk-7E72JMBB.js → chunk-N2WDGMD5.js} +45 -4
  57. package/{chunk-Q5ITEGIN.js → chunk-N4XRDM26.js} +1 -1
  58. package/{chunk-AFV4FOT2.js → chunk-OQVRTSZ5.js} +4 -91
  59. package/{chunk-3VAQHAXT.js → chunk-PU47HKTF.js} +11 -11
  60. package/{chunk-CLP2K7U4.js → chunk-QKCMP3LU.js} +2 -2
  61. package/{chunk-JZPBVBIY.js → chunk-QTZD6HBK.js} +18 -8
  62. package/{chunk-LOD75GOS.js → chunk-REOW4YJX.js} +80 -1099
  63. package/{chunk-6SXC35F4.js → chunk-RO3AEN3L.js} +5 -5
  64. package/{chunk-5CS33IBL.js → chunk-RQFO3CAF.js} +8 -9
  65. package/{chunk-GMXWYXAF.js → chunk-SBPGB6TF.js} +3 -3
  66. package/{chunk-FSSX3XRY.js → chunk-U2FRXKC7.js} +1 -1
  67. package/{chunk-NUO3QFWD.js → chunk-UNHKVD2N.js} +1 -1
  68. package/{chunk-GE6IWA5N.js → chunk-UNZDCI3O.js} +126 -1
  69. package/{chunk-JMPYDFHY.js → chunk-V44VE7R4.js} +2 -2
  70. package/{chunk-IL545V3E.js → chunk-V4MT7AEN.js} +1 -1
  71. package/{chunk-FXFGNOT2.js → chunk-VFVCYIRQ.js} +1 -1
  72. package/chunk-VIRTYWWE.js +97 -0
  73. package/{chunk-ZJMME4DS.js → chunk-XS543SNR.js} +5 -5
  74. package/{chunk-O6GEBMIY.js → chunk-XTSVOICC.js} +195 -47
  75. package/{chunk-6PO2SYCS.js → chunk-YH3FPBG6.js} +1569 -204
  76. package/{chunk-WLH5BAKX.js → chunk-YYTTDOWA.js} +2 -2
  77. package/{chunk-5SBK2MTI.js → chunk-ZKUATCEY.js} +20 -69
  78. package/{codingSkills-DY5MINPG.js → codingSkills-5VOV3JVB.js} +2 -2
  79. package/{createAgentAutomationAction-INQT23LX.js → createAgentAutomationAction-72NNXELT.js} +16 -15
  80. package/{createDialogAction-LDCPDI73.js → createDialogAction-3CJ2GXNO.js} +18 -17
  81. package/{createPageAction-5YXOG2M4.js → createPageAction-HZHQGQO6.js} +16 -15
  82. package/{dbSlice-3SD5L5H2.js → dbSlice-2YD2PZER.js} +2 -2
  83. package/{dialogCommands-CHJO47AX.js → dialogCommands-2BF4ZSWH.js} +18 -17
  84. package/{dialogSlice-DOWKOILN.js → dialogSlice-5R4O4377.js} +15 -14
  85. package/{docCreateCommands-OVZARUFX.js → docCreateCommands-HMZUBFGL.js} +19 -18
  86. package/{docDeleteCommands-E2XJ62LD.js → docDeleteCommands-DFR7GCOR.js} +19 -18
  87. package/{docReadCommands-I7OSREPJ.js → docReadCommands-YM7RDUAZ.js} +19 -18
  88. package/{docStore-UAWSKZ2Y.js → docStore-A4SRW2DJ.js} +17 -16
  89. package/{docUpdateCommands-X4Z26VJM.js → docUpdateCommands-TTQBD7IU.js} +19 -18
  90. package/{getPricing-L2ENXWHV.js → getPricing-J4VXWR5B.js} +3 -3
  91. package/{handleSendMessageAction-C3TSDWKH.js → handleSendMessageAction-CIFBZCI2.js} +15 -14
  92. package/index.js +70 -70
  93. package/{localRuntimeAuthority-E3R24J4T.js → localRuntimeAuthority-S77B5QVB.js} +6 -2
  94. package/{localRuntimeDb-DDZCJFQZ.js → localRuntimeDb-N3H3HQ7G.js} +1 -1
  95. package/{machineCommands-BUOIYJAD.js → machineCommands-QSW4JKR2.js} +40 -39
  96. package/{machineInfo-M6KB6HZN.js → machineInfo-66ZFUMLE.js} +1 -1
  97. package/{machineWsRunDispatch-7CRWAA6O.js → machineWsRunDispatch-X3ZC7DZJ.js} +39 -38
  98. package/{models-OX2S5C6Q.js → models-SQFOI4FI.js} +2 -2
  99. package/package.json +1 -1
  100. package/{read-6G73BMEY.js → read-526GJR3R.js} +1 -1
  101. package/{readDocTool-DK4EI2GA.js → readDocTool-JNEZUOSM.js} +1 -1
  102. package/{readlineWorkspace-ZDWEASJV.js → readlineWorkspace-J2ARMEUC.js} +2701 -2083
  103. package/{removeDialogAgentAction-E7H557UO.js → removeDialogAgentAction-NPMEFEJW.js} +4 -4
  104. package/{runAgentClientLoop-U7HYA3O5.js → runAgentClientLoop-5I2R74NR.js} +31 -30
  105. package/{runtimeDoctorCommands-KIKM6BIO.js → runtimeDoctorCommands-KHGQKT3B.js} +3 -3
  106. package/{setDialogExtraReferencesAction-RMMGBR5F.js → setDialogExtraReferencesAction-ZZ6QWAG2.js} +3 -3
  107. package/{setPrimaryDialogAgentAction-FWBKKLVA.js → setPrimaryDialogAgentAction-BG72QA6S.js} +4 -4
  108. package/{settingSlice-73PV4KG4.js → settingSlice-JCCLCXZB.js} +3 -3
  109. package/{skillDiscovery-KLLKXPUO.js → skillDiscovery-AYBKAG6X.js} +3 -3
  110. package/{spaceCommands-GEWZXGHM.js → spaceCommands-EZYMMJJH.js} +18 -17
  111. package/{spaceSlice-B6MOVY4N.js → spaceSlice-TL2FR4AF.js} +16 -15
  112. package/{streamAgentChatTurn-T527EQTT.js → streamAgentChatTurn-UDYSE2ES.js} +45 -54
  113. package/{switchDialogAgentAction-US6QNL3N.js → switchDialogAgentAction-YPGPM2LL.js} +2 -2
  114. package/{tableCommands-QE47K72R.js → tableCommands-64FZBAI3.js} +1 -1
  115. package/{tools-XMWCVMPM.js → tools-KWYWDJ77.js} +25 -24
  116. package/{tuiSummaryLlmCaller-NCAJSVSD.js → tuiSummaryLlmCaller-WUVAOIYU.js} +9 -8
  117. package/{updateCommands-AK2RDOFR.js → updateCommands-MNDUIKN7.js} +2 -2
  118. package/{updateDialogTitleAction-XPJZRJEL.js → updateDialogTitleAction-NQCOEOLF.js} +16 -15
@@ -7,14 +7,30 @@ import {
7
7
  providerHttpFailure,
8
8
  readSseFrames,
9
9
  throwIfChatCompletionStreamFailed
10
- } from "./chunk-RAZOLMJR.js";
10
+ } from "./chunk-EQ6HOWEJ.js";
11
11
  import {
12
12
  sanitizeForOutbound
13
13
  } from "./chunk-T27IEBNQ.js";
14
14
  import {
15
- parseToolArgumentsJson,
16
- resolveHistoricalToolContentCap
17
- } from "./chunk-6PO2SYCS.js";
15
+ buildExecShellToolDefinition,
16
+ buildWorkspaceShellCommand,
17
+ buildWorkspaceShellEscapeBlockedResult,
18
+ createGlob,
19
+ deriveLabel,
20
+ evaluateExecShellDestructiveGuard,
21
+ extractActivity,
22
+ findWorkspaceShellEscapeToken,
23
+ getProcessRegistry,
24
+ invokeCapability,
25
+ isSpawnFailureError,
26
+ readNodeStream,
27
+ resolveExecutableOnPath,
28
+ resolveHistoricalToolContentCap,
29
+ runWorkspaceCommand,
30
+ spawnToWebStreams,
31
+ truncateToolOutput,
32
+ waitForNodeProcessExit
33
+ } from "./chunk-YH3FPBG6.js";
18
34
  import {
19
35
  createThinkParserState,
20
36
  createToolCallAccumulator,
@@ -25,7 +41,7 @@ import {
25
41
  import {
26
42
  requiresBareImageUrl,
27
43
  toBareImageUrlMessages
28
- } from "./chunk-5SBK2MTI.js";
44
+ } from "./chunk-ZKUATCEY.js";
29
45
  import {
30
46
  convertMessagesToResponsesInput,
31
47
  extractReasoningFromResponseOutput,
@@ -39,7 +55,7 @@ import {
39
55
  import {
40
56
  buildProviderAuthHeaders,
41
57
  buildProviderExecutionPlan
42
- } from "./chunk-AFV4FOT2.js";
58
+ } from "./chunk-OQVRTSZ5.js";
43
59
  import {
44
60
  NOLO_WORKSPACE_TOOL_NAMES,
45
61
  buildNoloWorkspaceCommandArgs,
@@ -64,24 +80,15 @@ import {
64
80
  dialogMessageKey,
65
81
  dialogMessageRange
66
82
  } from "./chunk-KMSZPTM6.js";
67
- import {
68
- asOptionalFiniteNumber
69
- } from "./chunk-WWC7I6TA.js";
70
83
  import {
71
84
  asTrimmedNonEmptyStringArray
72
85
  } from "./chunk-I42VC5KR.js";
73
- import {
74
- asTrimmedLowercaseString
75
- } from "./chunk-QSJ3HFEF.js";
76
86
  import {
77
87
  asTrimmedString
78
88
  } from "./chunk-3EUW3WEO.js";
79
89
  import {
80
90
  asOptionalPositiveFiniteNumber
81
91
  } from "./chunk-U6VC4MU4.js";
82
- import {
83
- isRecord
84
- } from "./chunk-KUG52IAP.js";
85
92
  import {
86
93
  normalizeServerOrigin
87
94
  } from "./chunk-CF7PE763.js";
@@ -1033,219 +1040,6 @@ function createHybridRecordStore(deps) {
1033
1040
  };
1034
1041
  }
1035
1042
 
1036
- // packages/agent-runtime/shellCommandPolicy.ts
1037
- var DESTRUCTIVE_NEGATION_PATTERNS = [
1038
- "\u522B\u5220",
1039
- "\u522B\u5220\u9664",
1040
- "\u4E0D\u8981\u5220",
1041
- "\u4E0D\u8981\u5220\u9664",
1042
- "\u522B\u4E71\u5220",
1043
- "\u522B\u52A8",
1044
- "\u4E0D\u8981\u52A8",
1045
- "\u4E0D\u8981\u6E05\u7406",
1046
- "\u4E0D\u8981\u6E05\u7A7A",
1047
- "\u4E0D\u8981\u91CD\u7F6E",
1048
- "don't delete",
1049
- "do not delete",
1050
- "don't remove",
1051
- "do not remove",
1052
- "without deleting"
1053
- ];
1054
- var EXPLICIT_DESTRUCTIVE_REQUEST_PATTERNS = [
1055
- "\u5220\u9664",
1056
- "\u5220\u6389",
1057
- "\u79FB\u9664",
1058
- "\u6E05\u7406",
1059
- "\u6E05\u7A7A",
1060
- "\u91CD\u7F6E",
1061
- "drop",
1062
- "delete",
1063
- "remove",
1064
- "erase",
1065
- "clean up",
1066
- "reset"
1067
- ];
1068
- var SHELL_DESTRUCTIVE_PATTERNS = [
1069
- /\brm\s+(-[^\n\r]*\s+)?/i,
1070
- /\bremove-item\b/i,
1071
- /\bdel\s+\/?[a-z]*\s+/i,
1072
- /\berase\s+/i,
1073
- /\brmdir\s+/i,
1074
- /\brd\s+\/s\b/i,
1075
- /\bgit\s+reset\s+(--hard\b|--merge\b|--keep\b)/i,
1076
- /\bgit\s+clean\s+-[^\n\r]*f/i,
1077
- /\bgit\s+checkout\s+--\b/i,
1078
- /\bgit\s+restore\s+--source=/i
1079
- ];
1080
- var SHELL_STRING_EXECUTION_PATTERNS = [
1081
- /\b(?:ba|da|z|k)?sh\b/i,
1082
- /\beval\b/i,
1083
- /\bexec\b/i,
1084
- /\bxargs\b/i,
1085
- /\bsource\s/i,
1086
- /\b(?:node|deno|bun)\s+(?:-\S+\s+)*(?:-e|--eval)\b/i,
1087
- /\bpython[\d.]*\s+(?:-\S+\s+)*-c\b/i,
1088
- /\b(?:perl|ruby)\s+(?:-\S+\s+)*-e\b/i
1089
- ];
1090
- var stripQuotedSegments = (text) => {
1091
- let out = "";
1092
- let i = 0;
1093
- while (i < text.length) {
1094
- const ch = text[i];
1095
- if (ch === "\\") {
1096
- out += text.slice(i, i + 2);
1097
- i += 2;
1098
- } else if (ch === "'") {
1099
- const end = text.indexOf("'", i + 1);
1100
- if (end === -1) return out + text.slice(i);
1101
- out += "''";
1102
- i = end + 1;
1103
- } else if (ch === '"') {
1104
- let j = i + 1;
1105
- while (j < text.length && text[j] !== '"') {
1106
- j += text[j] === "\\" ? 2 : 1;
1107
- }
1108
- if (j >= text.length) return out + text.slice(i);
1109
- out += '""';
1110
- i = j + 1;
1111
- } else {
1112
- out += ch;
1113
- i += 1;
1114
- }
1115
- }
1116
- return out;
1117
- };
1118
- var normalizeUserInput = (value) => asTrimmedLowercaseString(value);
1119
- var containsAny = (text, patterns) => patterns.some((pattern) => text.includes(pattern));
1120
- var hasExplicitDestructivePermission = (userInput) => {
1121
- const normalized = normalizeUserInput(userInput);
1122
- if (!normalized) return false;
1123
- if (containsAny(normalized, DESTRUCTIVE_NEGATION_PATTERNS)) return false;
1124
- return containsAny(normalized, EXPLICIT_DESTRUCTIVE_REQUEST_PATTERNS);
1125
- };
1126
- var SHELL_COMMAND_ARG_ALIASES = [
1127
- "command",
1128
- "runCommand",
1129
- "run_command",
1130
- "terminalCommand",
1131
- "terminal_command",
1132
- "runInBash",
1133
- "run_in_bash",
1134
- "executeCommand",
1135
- "execute_command",
1136
- "execShell",
1137
- "bash",
1138
- "cmd"
1139
- ];
1140
- var resolveShellCommandArg = (args) => {
1141
- if (!args) return void 0;
1142
- for (const key of SHELL_COMMAND_ARG_ALIASES) {
1143
- const value = args[key];
1144
- if (value != null) return value;
1145
- }
1146
- return void 0;
1147
- };
1148
- var buildCombinedShellInput = (args) => {
1149
- const command = resolveShellCommandArg(args);
1150
- return [
1151
- typeof command === "string" ? command : "",
1152
- typeof args.input === "string" ? args.input : ""
1153
- ].filter(Boolean).join("\n");
1154
- };
1155
- function resolveScannableShellInput(args) {
1156
- const combined = buildCombinedShellInput(args);
1157
- if (!combined.trim()) return void 0;
1158
- return SHELL_STRING_EXECUTION_PATTERNS.some(
1159
- (pattern) => pattern.test(combined)
1160
- ) ? combined : stripQuotedSegments(combined);
1161
- }
1162
- function isDestructiveShellCommand(args) {
1163
- const scannable = resolveScannableShellInput(args);
1164
- if (scannable === void 0) return false;
1165
- return SHELL_DESTRUCTIVE_PATTERNS.some((pattern) => pattern.test(scannable));
1166
- }
1167
- var LONG_RUNNING_COMMAND_PATTERNS = [
1168
- /\b(run|npm|yarn|pnpm|bun|npx)\s+(run\s+)?(dev|serve|start|watch)\b/i,
1169
- /(^|[\s=&|;])--watch\b/i,
1170
- /\bvite\b.*\b(dev|serve)\b/i,
1171
- /\bwebpack\b.*(?:--watch|serve)\b/i,
1172
- /\bnodemon\b/i,
1173
- /\bgatsby\b.*\b(develop|serve)\b/i,
1174
- /\bnext\b.*\b(dev|start)\b/i,
1175
- /\belectron\b.*\bdev\b/i,
1176
- /\bforever\b/i,
1177
- /\bpm2\b.*\bstart\b/i
1178
- ];
1179
- function isLongRunningShellCommand(args) {
1180
- const scannable = resolveScannableShellInput(args);
1181
- if (scannable === void 0) return false;
1182
- return LONG_RUNNING_COMMAND_PATTERNS.some((pattern) => pattern.test(scannable));
1183
- }
1184
- var IMMEDIATE_DETACH_COMMAND_PATTERNS = [
1185
- /\btail\s+(?:-\S*[fF]\S*|--follow)\b/,
1186
- /\bwatch\s+\S/,
1187
- /\bwhile\s+(?:true|:|\[\s*true\s*\])\s*;\s*do\b/
1188
- ];
1189
- var IMMEDIATE_DETACH_SLEEP_THRESHOLD_SECONDS = 5;
1190
- var SLEEP_PREFIX_PATTERN = /^(?:[A-Za-z_][A-Za-z0-9_]*=\S*\s+)*(?:nohup\s+|time\s+)*sleep\s+(\S+)/;
1191
- function parseSleepDurationSeconds(token) {
1192
- const match = /^(\d+(?:\.\d+)?)(s|m|h|d)?$/i.exec(token);
1193
- if (!match) return void 0;
1194
- const value = Number(match[1]);
1195
- if (!Number.isFinite(value)) return void 0;
1196
- const unit = (match[2] ?? "s").toLowerCase();
1197
- const factor = unit === "m" ? 60 : unit === "h" ? 3600 : unit === "d" ? 86400 : 1;
1198
- return value * factor;
1199
- }
1200
- function isLongSleepCommand(scannable) {
1201
- const match = SLEEP_PREFIX_PATTERN.exec(scannable.trim());
1202
- if (!match) return false;
1203
- const durationToken = match[1] ?? "";
1204
- if (/^inf(inity)?$/i.test(durationToken)) return true;
1205
- const seconds = parseSleepDurationSeconds(durationToken);
1206
- if (seconds === void 0) return true;
1207
- return seconds > IMMEDIATE_DETACH_SLEEP_THRESHOLD_SECONDS;
1208
- }
1209
- function isImmediateDetachShellCommand(args) {
1210
- const scannable = resolveScannableShellInput(args);
1211
- if (scannable === void 0) return false;
1212
- return isLongSleepCommand(scannable) || LONG_RUNNING_COMMAND_PATTERNS.some((pattern) => pattern.test(scannable)) || IMMEDIATE_DETACH_COMMAND_PATTERNS.some(
1213
- (pattern) => pattern.test(scannable)
1214
- );
1215
- }
1216
- function evaluateShellCommandPolicy(args) {
1217
- if (isDestructiveShellCommand(args) && !hasExplicitDestructivePermission(args.userInput)) {
1218
- return {
1219
- verdict: "forbidden",
1220
- permissionDecision: "ask",
1221
- code: "destructive_action_requires_confirmation",
1222
- reason: "\u5F53\u524D\u8FD0\u884C\u9ED8\u8BA4\u7981\u6B62\u81EA\u52A8\u6267\u884C\u53EF\u80FD\u5220\u9664\u7528\u6237\u5185\u5BB9\u7684 shell \u547D\u4EE4\u3002\u53EA\u6709\u5F53\u7528\u6237\u5728\u5F53\u524D\u8BF7\u6C42\u91CC\u660E\u786E\u8981\u6C42\u5220\u9664/\u6E05\u7406\u65F6\uFF0C\u624D\u80FD\u7EE7\u7EED\uFF1B\u5426\u5219\u8BF7\u505C\u6B62\u5E76\u5148\u8BF4\u660E\u9650\u5236\u3002",
1223
- permissionRequest: {
1224
- id: "permission-shell-destructive-action",
1225
- tool: "execShell",
1226
- action: "destructive_shell_command",
1227
- title: "\u786E\u8BA4\u6267\u884C\u7834\u574F\u6027 shell \u547D\u4EE4",
1228
- body: "\u8BE5\u547D\u4EE4\u53EF\u80FD\u5220\u9664\u6216\u91CD\u7F6E\u7528\u6237\u5185\u5BB9\uFF0C\u9700\u8981\u7528\u6237\u660E\u786E\u786E\u8BA4\u540E\u624D\u80FD\u6267\u884C\u3002",
1229
- suggestedRule: {
1230
- scope: "once",
1231
- pattern: { capability: "destructive_action", target: "shell_command" }
1232
- }
1233
- },
1234
- policy: {
1235
- capability: "destructive_action",
1236
- target: "shell_command",
1237
- detail: "execShell destructive command"
1238
- }
1239
- };
1240
- }
1241
- const longRunningHint = isLongRunningShellCommand(args);
1242
- return {
1243
- verdict: "allowed",
1244
- permissionDecision: "allow",
1245
- ...longRunningHint ? { longRunningHint: true } : {}
1246
- };
1247
- }
1248
-
1249
1043
  // packages/agent-runtime/localToolPolicy.ts
1250
1044
  var NEVER_LOCAL_TOOLS = /* @__PURE__ */ new Set([
1251
1045
  "deleteSpaces",
@@ -1290,20 +1084,6 @@ function normalizeLocalToolName(toolName) {
1290
1084
  String(toolName ?? "").replace(/^functions\./, "").trim()
1291
1085
  );
1292
1086
  }
1293
- function parseShellCommandPayload(rawArguments) {
1294
- return parseToolArgumentsJson(rawArguments);
1295
- }
1296
- function toDisplayCommand(command) {
1297
- if (typeof command === "string") {
1298
- const trimmed = command.trim();
1299
- return trimmed ? trimmed : void 0;
1300
- }
1301
- if (Array.isArray(command)) {
1302
- const joined = command.map((item) => typeof item === "string" ? item : String(item)).filter((item) => item.length > 0).join(" ").trim();
1303
- return joined ? joined : void 0;
1304
- }
1305
- return void 0;
1306
- }
1307
1087
  function isRestrictedLocalToolMode(env) {
1308
1088
  return env.NOLO_LOCAL_TOOL_MODE === "restricted";
1309
1089
  }
@@ -1353,7 +1133,6 @@ function resolveLocalToolPolicy(args) {
1353
1133
  reason: `${toolName} is not enabled for local runtime runs. The agent must declare the tool in its manifest; in restricted mode (NOLO_LOCAL_TOOL_MODE=restricted) non-default tools also require adding to NOLO_LOCAL_ALLOWED_TOOLS (e.g. NOLO_LOCAL_ALLOWED_TOOLS=someCustomTool) and restarting the session so the env var loads.`
1354
1134
  };
1355
1135
  }
1356
- var ABORT_AWARE_LOCAL_TOOLS = /* @__PURE__ */ new Set(["execShell", "controlAgentRun"]);
1357
1136
  async function executeLocalToolWithPolicy(args) {
1358
1137
  const decision = resolveLocalToolPolicy({
1359
1138
  env: args.env,
@@ -1365,66 +1144,37 @@ async function executeLocalToolWithPolicy(args) {
1365
1144
  if (!executor) {
1366
1145
  throw new Error(`${decision.toolName} is allowed by policy but no local executor is registered.`);
1367
1146
  }
1368
- const effectiveExecutor = args.abortSignal && ABORT_AWARE_LOCAL_TOOLS.has(decision.toolName) && args.executors ? (call) => executor(call, {
1369
- abortSignal: args.abortSignal,
1370
- detachMs: args.detachMs
1371
- }) : executor;
1372
- const guardEnabled = args.enableDestructiveShellGuard !== false;
1373
- if (decision.toolName === "execShell" && !args.confirmed && guardEnabled) {
1374
- const parsed = parseShellCommandPayload(args.call.arguments);
1375
- const rawCommand = resolveShellCommandArg(parsed);
1376
- if (isDestructiveShellCommand({ command: rawCommand, input: parsed.input })) {
1377
- const command = toDisplayCommand(rawCommand);
1378
- const request = {
1379
- id: "permission-shell-destructive-action",
1380
- tool: "execShell",
1381
- action: "destructive_shell_command",
1382
- title: "\u786E\u8BA4\u6267\u884C\u7834\u574F\u6027 shell \u547D\u4EE4",
1383
- body: "\u8BE5\u547D\u4EE4\u53EF\u80FD\u5220\u9664\u6216\u91CD\u7F6E\u7528\u6237\u5185\u5BB9\uFF0C\u9700\u8981\u7528\u6237\u660E\u786E\u786E\u8BA4\u540E\u624D\u80FD\u6267\u884C\u3002",
1384
- ...command ? { command } : {},
1385
- suggestedRule: {
1386
- scope: "once",
1387
- pattern: { capability: "destructive_action", target: "shell_command" }
1388
- }
1389
- };
1390
- const buildBlockedError = (reason) => {
1391
- const error = new Error(reason);
1392
- error.code = "destructive_action_requires_confirmation";
1393
- error.policy = {
1394
- capability: "destructive_action",
1395
- target: "shell_command",
1396
- detail: "execShell destructive command"
1397
- };
1398
- error.permissionRequest = request;
1399
- return error;
1400
- };
1401
- if (!args.confirmDestructiveAction) {
1402
- if (args.blockDestructiveWithoutConfirmation) {
1403
- throw buildBlockedError(
1404
- "destructive shell command blocked: no confirmation channel available"
1405
- );
1406
- }
1407
- return effectiveExecutor({
1408
- ...args.call,
1409
- name: decision.toolName
1410
- });
1411
- }
1412
- const confirmed = await args.confirmDestructiveAction(request);
1413
- if (!confirmed) {
1414
- throw buildBlockedError(
1415
- "destructive shell command blocked: user declined confirmation"
1416
- );
1147
+ const opts = {
1148
+ ...args.abortSignal ? { abortSignal: args.abortSignal } : {},
1149
+ ...args.detachMs !== void 0 ? { detachMs: args.detachMs } : {},
1150
+ ...args.confirmed !== void 0 ? { confirmed: args.confirmed } : {},
1151
+ ...args.enableDestructiveShellGuard !== void 0 ? { enableDestructiveShellGuard: args.enableDestructiveShellGuard } : {},
1152
+ ...args.confirmDestructiveAction ? { confirmDestructiveAction: args.confirmDestructiveAction } : {},
1153
+ ...args.blockDestructiveWithoutConfirmation !== void 0 ? { blockDestructiveWithoutConfirmation: args.blockDestructiveWithoutConfirmation } : {}
1154
+ };
1155
+ if (decision.toolName === "execShell") {
1156
+ let parsedInput = args.call.arguments;
1157
+ if (typeof parsedInput === "string") {
1158
+ try {
1159
+ parsedInput = JSON.parse(parsedInput);
1160
+ } catch {
1161
+ parsedInput = { command: parsedInput };
1417
1162
  }
1418
1163
  }
1164
+ await evaluateExecShellDestructiveGuard(parsedInput, opts);
1165
+ opts.confirmed = true;
1419
1166
  }
1420
- return effectiveExecutor({
1421
- ...args.call,
1422
- name: decision.toolName
1423
- });
1167
+ return executor(
1168
+ {
1169
+ ...args.call,
1170
+ name: decision.toolName
1171
+ },
1172
+ opts
1173
+ );
1424
1174
  }
1425
1175
 
1426
1176
  // packages/agent-runtime/localWorkspaceTools.ts
1427
- import { existsSync as existsSync2 } from "node:fs";
1177
+ import { existsSync } from "node:fs";
1428
1178
  import { createHash } from "node:crypto";
1429
1179
  import { mkdir, readdir, readFile, stat, writeFile } from "node:fs/promises";
1430
1180
  import { dirname, relative, resolve, sep } from "node:path";
@@ -1462,244 +1212,6 @@ function isLineRangeCovered(request, covered) {
1462
1212
  return open > request.endLine;
1463
1213
  }
1464
1214
 
1465
- // packages/agent-runtime/runtimeCompat.ts
1466
- import { existsSync, readdirSync, statSync } from "node:fs";
1467
- import { join } from "node:path";
1468
- import { spawn } from "node:child_process";
1469
- var IS_WINDOWS = process.platform === "win32";
1470
- function isExecutableFile(candidate) {
1471
- if (!existsSync(candidate)) return false;
1472
- try {
1473
- return statSync(candidate).isFile();
1474
- } catch {
1475
- return false;
1476
- }
1477
- }
1478
- function resolveExecutableOnPath(name) {
1479
- if (IS_WINDOWS && !/\.[a-z]+$/i.test(name)) {
1480
- const exts = (process.env.PATHEXT || ".EXE;.CMD;.BAT").split(";").filter(Boolean);
1481
- for (const ext of exts) {
1482
- const found = resolveExecutableOnPath(name + ext);
1483
- if (found) return found;
1484
- }
1485
- return null;
1486
- }
1487
- const pathEnv = process.env.PATH ?? "";
1488
- const sep2 = pathEnv.includes(";") && IS_WINDOWS ? ";" : ":";
1489
- const pathDirs = pathEnv.split(sep2).filter(Boolean);
1490
- const fallbackDirs = IS_WINDOWS ? [] : [
1491
- "/opt/homebrew/bin",
1492
- "/usr/local/bin",
1493
- "/usr/bin",
1494
- "/bin",
1495
- `${process.env.HOME ?? ""}/.local/bin`
1496
- ].filter(Boolean);
1497
- for (const dir of [...pathDirs, ...fallbackDirs]) {
1498
- const candidate = join(dir, name);
1499
- if (isExecutableFile(candidate)) return candidate;
1500
- }
1501
- return null;
1502
- }
1503
- function createGlob(pattern) {
1504
- const regex = globToRegExp(pattern);
1505
- return {
1506
- match(path) {
1507
- return regex.test(path);
1508
- },
1509
- scanSync(opts) {
1510
- const dot = opts.dot ?? false;
1511
- const results = [];
1512
- walkDir(opts.cwd, "", dot, results);
1513
- return results.filter((rel) => regex.test(rel));
1514
- }
1515
- };
1516
- }
1517
- function walkDir(dir, prefix, dot, out) {
1518
- let entries;
1519
- try {
1520
- entries = readdirSync(dir, { withFileTypes: true, encoding: "utf8" });
1521
- } catch {
1522
- return;
1523
- }
1524
- for (const entry of entries) {
1525
- const name = String(entry.name);
1526
- if (!dot && name.startsWith(".")) continue;
1527
- const rel = prefix ? `${prefix}/${name}` : name;
1528
- const full = join(dir, name);
1529
- if (entry.isDirectory()) {
1530
- walkDir(full, rel, dot, out);
1531
- } else if (entry.isFile()) {
1532
- out.push(rel);
1533
- }
1534
- }
1535
- }
1536
- function globToRegExp(pattern) {
1537
- const trailingDir = pattern.endsWith("/");
1538
- const src = trailingDir ? pattern.slice(0, -1) : pattern;
1539
- const anchored = src.startsWith("/");
1540
- const body = anchored ? src.slice(1) : src;
1541
- let regex = "^";
1542
- if (!anchored) regex += "(?:.*/)?";
1543
- regex += convertBody(body);
1544
- if (trailingDir) {
1545
- regex += "(?:/.*)?";
1546
- }
1547
- regex += "$";
1548
- return new RegExp(regex);
1549
- }
1550
- function convertBody(p) {
1551
- let out = "";
1552
- let i = 0;
1553
- while (i < p.length) {
1554
- const c = p[i];
1555
- if (c === "*") {
1556
- if (p[i + 1] === "*") {
1557
- i += 2;
1558
- if (p[i] === "/") {
1559
- out += "(?:.*/)?";
1560
- i += 1;
1561
- } else {
1562
- out += ".*";
1563
- }
1564
- } else {
1565
- out += "[^/]*";
1566
- i += 1;
1567
- }
1568
- } else if (c === "?") {
1569
- out += "[^/]";
1570
- i += 1;
1571
- } else if (c === "[") {
1572
- out += "[";
1573
- i += 1;
1574
- if (p[i] === "!") {
1575
- out += "^";
1576
- i += 1;
1577
- }
1578
- while (i < p.length && p[i] !== "]") {
1579
- out += p[i] === "\\" ? "\\\\" : p[i];
1580
- i += 1;
1581
- }
1582
- if (p[i] === "]") {
1583
- out += "]";
1584
- i += 1;
1585
- }
1586
- } else if (c === "{") {
1587
- let depth = 1;
1588
- let j = i + 1;
1589
- let bodyStr = "";
1590
- while (j < p.length && depth > 0) {
1591
- if (p[j] === "{") depth += 1;
1592
- else if (p[j] === "}") depth -= 1;
1593
- if (depth > 0) bodyStr += p[j];
1594
- j += 1;
1595
- }
1596
- const alts = bodyStr.split(",").map((alt) => convertBody(alt));
1597
- out += `(?:${alts.join("|")})`;
1598
- i = j;
1599
- } else {
1600
- out += escapeRegexChar(c);
1601
- i += 1;
1602
- }
1603
- }
1604
- return out;
1605
- }
1606
- function escapeRegexChar(c) {
1607
- if ("\\^$.|+()".includes(c)) {
1608
- return `\\${c}`;
1609
- }
1610
- return c;
1611
- }
1612
- function spawnToWebStreams(options) {
1613
- const [command, ...args] = options.cmd;
1614
- const child = spawn(command, args, {
1615
- env: options.env,
1616
- stdio: ["ignore", "pipe", "pipe"]
1617
- });
1618
- const exited = new Promise((resolve2) => {
1619
- child.on("exit", (code) => resolve2(code ?? 1));
1620
- child.on("error", () => resolve2(127));
1621
- });
1622
- const toWeb = (stream) => {
1623
- if (!stream) return null;
1624
- return stream.toWeb?.() ?? new ReadableStream({
1625
- start(controller) {
1626
- stream.on("data", (chunk) => controller.enqueue(new Uint8Array(chunk)));
1627
- stream.on("end", () => controller.close());
1628
- stream.on("error", (e) => controller.error(e));
1629
- }
1630
- });
1631
- };
1632
- return {
1633
- stdout: toWeb(child.stdout),
1634
- stderr: toWeb(child.stderr),
1635
- exited
1636
- };
1637
- }
1638
-
1639
- // packages/agent-runtime/processRegistry.ts
1640
- var ProcessRegistry = class {
1641
- processes = /* @__PURE__ */ new Map();
1642
- add(proc) {
1643
- this.processes.set(proc.pid, {
1644
- pid: proc.pid,
1645
- pgid: proc.pgid,
1646
- command: proc.command,
1647
- label: proc.label,
1648
- startedAt: Date.now(),
1649
- status: "running",
1650
- persist: proc.persist ?? false
1651
- });
1652
- }
1653
- list() {
1654
- return Array.from(this.processes.values()).map((proc) => ({ ...proc }));
1655
- }
1656
- get(pid) {
1657
- const item = this.processes.get(pid);
1658
- return item ? { ...item } : void 0;
1659
- }
1660
- kill(pid, signal = "SIGTERM") {
1661
- const item = this.processes.get(pid);
1662
- if (!item) return false;
1663
- if (item.status === "running") {
1664
- try {
1665
- process.kill(-item.pgid, signal);
1666
- } catch {
1667
- }
1668
- item.status = "stopped";
1669
- return true;
1670
- }
1671
- return false;
1672
- }
1673
- stopAll(signal = "SIGTERM", opts) {
1674
- for (const item of this.processes.values()) {
1675
- if (item.status === "running" && (opts?.includePersist || !item.persist)) {
1676
- try {
1677
- process.kill(-item.pgid, signal);
1678
- } catch {
1679
- }
1680
- item.status = "stopped";
1681
- }
1682
- }
1683
- }
1684
- markExited(pid, exitCode) {
1685
- const item = this.processes.get(pid);
1686
- if (item && item.status === "running") {
1687
- item.exitCode = exitCode;
1688
- item.status = exitCode === 0 ? "exited" : "failed";
1689
- }
1690
- }
1691
- clear() {
1692
- this.processes.clear();
1693
- }
1694
- };
1695
- var registry = null;
1696
- function getProcessRegistry() {
1697
- if (!registry) {
1698
- registry = new ProcessRegistry();
1699
- }
1700
- return registry;
1701
- }
1702
-
1703
1215
  // packages/agent-runtime/localWorkspaceToolDefs.ts
1704
1216
  var WORKSPACE_TOOL_NAMES = [
1705
1217
  "listFiles",
@@ -1723,15 +1235,6 @@ var REMOVED_WORKSPACE_TOOL_NAMES = /* @__PURE__ */ new Set([
1723
1235
  "gitCommit",
1724
1236
  "commitWorkspace"
1725
1237
  ]);
1726
- function tokenizeShellPrefix(command) {
1727
- const tokens = [];
1728
- const pattern = /"([^"]*)"|'([^']*)'|([^\s"'|;&<>]+)/g;
1729
- let match;
1730
- while (match = pattern.exec(command)) {
1731
- tokens.push(match[1] ?? match[2] ?? match[3] ?? "");
1732
- }
1733
- return tokens;
1734
- }
1735
1238
  function buildWorkspacePathProperty() {
1736
1239
  return {
1737
1240
  type: "string",
@@ -2105,26 +1608,7 @@ function buildCaptureVisualStateTool() {
2105
1608
  };
2106
1609
  }
2107
1610
  function buildExecShellTool(toolName) {
2108
- return {
2109
- type: "function",
2110
- function: {
2111
- name: toolName,
2112
- description: `Execute a shell command from the workspace root. Prefer one compound command (e.g. 'git status && git diff --stat') to perform complete verification in one step instead of multiple small roundtrips. Do not cd into guessed paths; commands already run from the workspace root. Commands block until exit. Long-running commands (sleep over ${IMMEDIATE_DETACH_SLEEP_THRESHOLD_SECONDS}s, dev servers, watchers) automatically detach to background returning {detached: true, pid, label}; for persistent services, prefer launchProcess.`,
2113
- parameters: {
2114
- type: "object",
2115
- properties: {
2116
- command: {
2117
- type: "string",
2118
- description: "Shell command to run (non-empty)."
2119
- },
2120
- cmd: {
2121
- type: "string",
2122
- description: "Compatibility alias for command."
2123
- }
2124
- }
2125
- }
2126
- }
2127
- };
1611
+ return buildExecShellToolDefinition(toolName);
2128
1612
  }
2129
1613
  function buildLaunchProcessTool() {
2130
1614
  return {
@@ -2166,73 +1650,6 @@ function buildListProcessesTool() {
2166
1650
  }
2167
1651
  };
2168
1652
  }
2169
- function wrapPowerShellCommand(command) {
2170
- return [
2171
- "[Console]::InputEncoding=[System.Text.Encoding]::UTF8",
2172
- "[Console]::OutputEncoding=[System.Text.Encoding]::UTF8",
2173
- "$OutputEncoding=[System.Text.Encoding]::UTF8",
2174
- "$PSStyle.OutputRendering='PlainText'",
2175
- command
2176
- ].join("; ");
2177
- }
2178
- function findPowerShellExecutable() {
2179
- return resolveExecutableOnPath("pwsh") || resolveExecutableOnPath("powershell.exe") || resolveExecutableOnPath("powershell");
2180
- }
2181
- function buildPowerShellCommand(command) {
2182
- const executable = findPowerShellExecutable();
2183
- if (!executable) throw new Error("PowerShell is not available on this machine.");
2184
- return [
2185
- executable,
2186
- "-NoLogo",
2187
- "-NoProfile",
2188
- "-NonInteractive",
2189
- "-ExecutionPolicy",
2190
- "Bypass",
2191
- "-Command",
2192
- wrapPowerShellCommand(command)
2193
- ];
2194
- }
2195
- function buildBashCommand(command) {
2196
- const executable = resolveExecutableOnPath("bash") || resolveExecutableOnPath("sh");
2197
- if (!executable) throw new Error("bash/sh is not available on this machine.");
2198
- return [executable, "-lc", command];
2199
- }
2200
- function buildWorkspaceShellCommand(args) {
2201
- if (args.shell === "powershell") return buildPowerShellCommand(args.command);
2202
- if (args.shell === "bash") return buildBashCommand(args.command);
2203
- return process.platform === "win32" ? buildPowerShellCommand(args.command) : buildBashCommand(args.command);
2204
- }
2205
- function findWorkspaceShellEscapeToken(command) {
2206
- const tokens = tokenizeShellPrefix(command);
2207
- for (const token of tokens) {
2208
- if (token === ".." || token.startsWith("../") || token.startsWith("..\\") || token.includes("/../") || token.includes("\\..\\")) {
2209
- return token;
2210
- }
2211
- if (token === "~" || token.startsWith("~/") || token.startsWith("~\\")) {
2212
- return token;
2213
- }
2214
- if (token === "/" || token.startsWith("/") || /^[A-Za-z]:[\\/]/.test(token) || token.startsWith("\\\\")) {
2215
- return token;
2216
- }
2217
- }
2218
- return null;
2219
- }
2220
- function buildWorkspaceShellEscapeBlockedResult(args) {
2221
- return {
2222
- content: [
2223
- "workspace_shell_escape_blocked",
2224
- `blockedToken: ${args.token}`,
2225
- `command: ${args.command}`,
2226
- "Use paths relative to the authorized folder only.",
2227
- "exitCode: 126"
2228
- ].join("\n"),
2229
- metadata: {
2230
- exitCode: 126,
2231
- workspaceShellEscapeBlocked: true,
2232
- blockedToken: args.token
2233
- }
2234
- };
2235
- }
2236
1653
  function buildWorkspaceToolDefinition(toolName, args) {
2237
1654
  if (toolName === "listFiles") {
2238
1655
  return buildListWorkspaceFilesTool({
@@ -2277,9 +1694,6 @@ function filterDeclaredWorkspaceToolNames(args) {
2277
1694
  }
2278
1695
 
2279
1696
  // packages/agent-runtime/localWorkspaceTools.ts
2280
- var EXEC_SHELL_TIMEOUT_ENV = "NOLO_EXEC_SHELL_TIMEOUT_MS";
2281
- var EXEC_SHELL_DETACH_ENV = "NOLO_EXEC_SHELL_DETACH_MS";
2282
- var DEFAULT_EXEC_SHELL_DETACH_MS = 12e4;
2283
1697
  var DEFAULT_LOCAL_API_ORIGIN = "http://127.0.0.1:38123";
2284
1698
  var ALWAYS_EXCLUDED_GLOBS = [
2285
1699
  "*.tsbuildinfo",
@@ -2312,168 +1726,6 @@ function readBoolean(parsed, key) {
2312
1726
  }
2313
1727
  return void 0;
2314
1728
  }
2315
- function resolveExecShellTimeoutMs(override) {
2316
- const fromOverride = asOptionalPositiveFiniteNumber(override);
2317
- if (fromOverride !== void 0) return fromOverride;
2318
- const raw = process.env[EXEC_SHELL_TIMEOUT_ENV];
2319
- if (raw === void 0) return void 0;
2320
- return asOptionalPositiveFiniteNumber(Number(raw));
2321
- }
2322
- function resolveDetachMs(override) {
2323
- if (typeof override === "number" && Number.isFinite(override) && override >= 0) {
2324
- return override;
2325
- }
2326
- const raw = process.env[EXEC_SHELL_DETACH_ENV];
2327
- if (raw === void 0) return DEFAULT_EXEC_SHELL_DETACH_MS;
2328
- const parsed = asOptionalPositiveFiniteNumber(Number(raw));
2329
- return parsed === void 0 ? DEFAULT_EXEC_SHELL_DETACH_MS : parsed;
2330
- }
2331
- function extractInteractiveGhAuthCommand(command) {
2332
- const tokens = tokenizeShellPrefix(command);
2333
- if (tokens[0] !== "gh" || tokens[1] !== "auth") return null;
2334
- const subcommand = tokens[2];
2335
- if (subcommand !== "login" && subcommand !== "refresh") return null;
2336
- if (tokens.includes("--help")) return null;
2337
- const result = ["gh", "auth", subcommand];
2338
- for (let index = 3; index < tokens.length; index += 1) {
2339
- const token = tokens[index];
2340
- if (!token) continue;
2341
- if (token === "-h" || token === "--hostname" || token === "-s" || token === "--scopes" || token === "--remove-scopes" || token === "-r") {
2342
- const value = tokens[index + 1];
2343
- if (value) {
2344
- result.push(token, value);
2345
- index += 1;
2346
- }
2347
- continue;
2348
- }
2349
- if (token === "--clipboard" || token === "-c" || token === "--insecure-storage" || token === "--reset-scopes") {
2350
- result.push(token);
2351
- continue;
2352
- }
2353
- if (token.startsWith("--hostname=") || token.startsWith("--scopes=") || token.startsWith("--remove-scopes=")) {
2354
- result.push(token);
2355
- continue;
2356
- }
2357
- }
2358
- return result.join(" ");
2359
- }
2360
- function splitShellWords(command) {
2361
- return tokenizeShellPrefix(command);
2362
- }
2363
- function buildInteractiveCommandBlockedResult(command) {
2364
- const argv = splitShellWords(command);
2365
- return {
2366
- content: [
2367
- "action_gate: handoff",
2368
- `command: ${command}`,
2369
- "Run this in the current TUI terminal, then resume the agent turn.",
2370
- "exitCode: 130"
2371
- ].join("\n"),
2372
- metadata: {
2373
- exitCode: 130,
2374
- timedOut: false,
2375
- actionGate: {
2376
- id: `gate-${Date.now().toString(36)}-terminal-handoff`,
2377
- kind: "handoff",
2378
- title: "This command requires an interactive terminal.",
2379
- body: "Complete it in the terminal, then nolo will continue.",
2380
- payload: {
2381
- command: argv,
2382
- displayCommand: command
2383
- }
2384
- },
2385
- reason: "interactive-command-requires-terminal"
2386
- }
2387
- };
2388
- }
2389
- function extractActivityRefs(rawRefs) {
2390
- if (!Array.isArray(rawRefs)) return void 0;
2391
- const refs = rawRefs.flatMap((entry) => {
2392
- if (!isRecord(entry)) return [];
2393
- if (entry.type === "file") {
2394
- const path = readTrimmedString(entry.path);
2395
- return path ? [{ type: "file", path }] : [];
2396
- }
2397
- if (entry.type === "terminal") {
2398
- const id = readTrimmedString(entry.id);
2399
- const label = readTrimmedString(entry.label);
2400
- return id || label ? [{ type: "terminal", ...id ? { id } : {}, ...label ? { label } : {} }] : [];
2401
- }
2402
- if (entry.type === "url") {
2403
- const url = readTrimmedString(entry.url);
2404
- const label = readTrimmedString(entry.label);
2405
- return url ? [{ type: "url", url, ...label ? { label } : {} }] : [];
2406
- }
2407
- return [];
2408
- });
2409
- return refs.length ? refs : void 0;
2410
- }
2411
- function extractActivityAction(rawAction) {
2412
- if (!isRecord(rawAction)) return void 0;
2413
- const title = readTrimmedString(rawAction.title);
2414
- if (!title) return void 0;
2415
- const kind = readTrimmedString(rawAction.kind);
2416
- const detail = readTrimmedString(rawAction.detail);
2417
- const refs = extractActivityRefs(rawAction.refs);
2418
- return {
2419
- title,
2420
- ...kind ? { kind } : {},
2421
- ...detail ? { detail } : {},
2422
- ...refs ? { refs } : {}
2423
- };
2424
- }
2425
- function extractActivityPhase(rawPhase) {
2426
- if (!isRecord(rawPhase)) return void 0;
2427
- const title = readTrimmedString(rawPhase.title);
2428
- if (!title) return void 0;
2429
- const id = readTrimmedString(rawPhase.id) || title.toLowerCase().replace(/\s+/g, "-");
2430
- const index = asOptionalFiniteNumber(rawPhase.index);
2431
- const total = asOptionalFiniteNumber(rawPhase.total);
2432
- const status = rawPhase.status === "pending" || rawPhase.status === "running" || rawPhase.status === "success" || rawPhase.status === "failed" ? rawPhase.status : void 0;
2433
- return {
2434
- id,
2435
- title,
2436
- ...index !== void 0 ? { index } : {},
2437
- ...total !== void 0 ? { total } : {},
2438
- ...status ? { status } : {}
2439
- };
2440
- }
2441
- function extractActivityPlan(rawPlan) {
2442
- if (!isRecord(rawPlan)) return void 0;
2443
- if (!Array.isArray(rawPlan.phases)) return void 0;
2444
- const phases = rawPlan.phases.flatMap((entry, index) => {
2445
- const phase = extractActivityPhase(entry);
2446
- if (!phase) return [];
2447
- return [{
2448
- id: phase.id,
2449
- title: phase.title,
2450
- index: phase.index ?? index + 1,
2451
- ...phase.status ? { status: phase.status } : {}
2452
- }];
2453
- });
2454
- if (phases.length === 0) return void 0;
2455
- const title = readTrimmedString(rawPlan.title);
2456
- return {
2457
- ...title ? { title } : {},
2458
- phases
2459
- };
2460
- }
2461
- function extractActivity(parsed) {
2462
- const raw = parsed._activity;
2463
- if (!isRecord(raw)) return void 0;
2464
- const nestedAction = extractActivityAction(raw.action);
2465
- const legacyAction = extractActivityAction(raw);
2466
- const action = nestedAction || legacyAction;
2467
- const phase = extractActivityPhase(raw.phase);
2468
- const plan = extractActivityPlan(raw.plan);
2469
- if (!action && !plan) return void 0;
2470
- return {
2471
- ...action ? action : {},
2472
- ...phase ? { phase } : {},
2473
- ...nestedAction ? { action: nestedAction } : {},
2474
- ...plan ? { plan } : {}
2475
- };
2476
- }
2477
1729
  function buildLocalWorkspaceToolset(args) {
2478
1730
  const exposeShellTools = args.exposeShellTools === true;
2479
1731
  if (args.useDeclaredToolNamesOnly) {
@@ -2929,22 +2181,6 @@ async function runWorkspacePackageScript(args) {
2929
2181
  }
2930
2182
  };
2931
2183
  }
2932
- function truncateToolOutput(value, limit = 2e4) {
2933
- if (value.length <= limit) return value;
2934
- const approxMarkerLen = 40;
2935
- if (limit <= approxMarkerLen) return value.slice(0, limit);
2936
- const remaining = limit - approxMarkerLen;
2937
- const headSize = Math.floor(remaining * 0.3);
2938
- const tailSize = remaining - headSize;
2939
- const head = value.slice(0, headSize);
2940
- const tail = value.slice(-tailSize);
2941
- const actualRemoved = value.length - headSize - tailSize;
2942
- return `${head}
2943
-
2944
- [... truncated ${actualRemoved} chars ...]
2945
-
2946
- ${tail}`;
2947
- }
2948
2184
  function parseLastJsonObject(text) {
2949
2185
  const trimmed = text.trim();
2950
2186
  for (let index = trimmed.lastIndexOf("{"); index >= 0; index = trimmed.lastIndexOf("{", index - 1)) {
@@ -2956,57 +2192,11 @@ function parseLastJsonObject(text) {
2956
2192
  }
2957
2193
  return null;
2958
2194
  }
2959
- function readNodeStream(stream) {
2960
- if (!stream) return Promise.resolve("");
2961
- return new Promise((resolveRead, rejectRead) => {
2962
- const chunks = [];
2963
- stream.on("data", (chunk) => {
2964
- chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
2965
- });
2966
- stream.on("error", rejectRead);
2967
- stream.on("end", () => resolveRead(Buffer.concat(chunks).toString("utf8")));
2968
- });
2969
- }
2970
- function waitForNodeProcessExit(proc) {
2971
- return new Promise((resolveExit, rejectExit) => {
2972
- proc.once("error", rejectExit);
2973
- proc.once("close", (code, signal) => {
2974
- if (typeof code === "number") {
2975
- resolveExit(code);
2976
- return;
2977
- }
2978
- resolveExit(signal ? 1 : 0);
2979
- });
2980
- });
2981
- }
2982
- function isSpawnFailureError(error) {
2983
- if (!error || typeof error !== "object") return false;
2984
- const err = error;
2985
- if (err.code === "ENOENT") return true;
2986
- const message = toErrorMessage(error).toLowerCase();
2987
- return message.includes("enoent") || message.includes("executable not found") || message.includes("spawn") && message.includes("not found");
2988
- }
2989
- function spawnFailedCommandResult(error, outputLimit) {
2990
- const stderr = `spawn failed: ${toErrorMessage(error)}
2991
- `;
2992
- return {
2993
- stdout: "",
2994
- stderr,
2995
- exitCode: 127,
2996
- timedOut: false,
2997
- spawnFailed: true,
2998
- content: truncateToolOutput(
2999
- [`stderr:
3000
- ${stderr.trim()}`, "exitCode: 127"].filter(Boolean).join("\n\n"),
3001
- outputLimit
3002
- )
3003
- };
3004
- }
3005
2195
  function resolveRipgrepBinary(env = process.env) {
3006
2196
  const fromEnv = asOptionalTrimmedString(env.NOLO_BUNDLED_RG);
3007
2197
  if (fromEnv) {
3008
2198
  try {
3009
- if (existsSync2(fromEnv)) return fromEnv;
2199
+ if (existsSync(fromEnv)) return fromEnv;
3010
2200
  } catch {
3011
2201
  }
3012
2202
  }
@@ -3015,178 +2205,6 @@ function resolveRipgrepBinary(env = process.env) {
3015
2205
  function resolveGrepBinary() {
3016
2206
  return resolveExecutableOnPath("grep");
3017
2207
  }
3018
- async function runWorkspaceCommand(args) {
3019
- const timeoutMs = asOptionalPositiveFiniteNumber(args.timeoutMs);
3020
- const detached = process.platform !== "win32";
3021
- const command = [
3022
- ...args.commandPrefix ?? [],
3023
- ...args.command
3024
- ];
3025
- const proc = spawnChildProcess(command[0] ?? "", command.slice(1), {
3026
- cwd: resolve(args.workspaceRoot),
3027
- stdio: [
3028
- args.stdin === void 0 ? "ignore" : "pipe",
3029
- "pipe",
3030
- "pipe"
3031
- ],
3032
- detached
3033
- });
3034
- if (args.stdin !== void 0 && proc.stdin) {
3035
- proc.stdin.write(args.stdin);
3036
- proc.stdin.end();
3037
- }
3038
- const exitPromise = waitForNodeProcessExit(proc);
3039
- const cleanupChildOnHostSignal = (signal) => {
3040
- if (typeof proc.pid === "number") {
3041
- try {
3042
- process.kill(-proc.pid, signal);
3043
- } catch {
3044
- }
3045
- }
3046
- };
3047
- if (detached) {
3048
- process.once("SIGHUP", cleanupChildOnHostSignal);
3049
- process.once("SIGTERM", cleanupChildOnHostSignal);
3050
- process.once("SIGINT", cleanupChildOnHostSignal);
3051
- }
3052
- const detachSignalCleanup = () => {
3053
- if (!detached) return;
3054
- process.removeListener("SIGHUP", cleanupChildOnHostSignal);
3055
- process.removeListener("SIGTERM", cleanupChildOnHostSignal);
3056
- process.removeListener("SIGINT", cleanupChildOnHostSignal);
3057
- };
3058
- exitPromise.then(detachSignalCleanup, detachSignalCleanup);
3059
- const stdoutPromise = readNodeStream(proc.stdout);
3060
- const stderrPromise = readNodeStream(proc.stderr);
3061
- const killChild = (signal) => {
3062
- if (detached && typeof proc.pid === "number") {
3063
- try {
3064
- process.kill(-proc.pid, signal);
3065
- return;
3066
- } catch {
3067
- }
3068
- }
3069
- try {
3070
- proc.kill(signal);
3071
- } catch {
3072
- }
3073
- };
3074
- let timeout;
3075
- let detachTimer;
3076
- const timeoutResult = Symbol("timeout");
3077
- const abortResult = Symbol("abort");
3078
- const detachResult = Symbol("detach");
3079
- let abortListener;
3080
- const abortPromise = args.abortSignal ? new Promise((resolveAbort) => {
3081
- if (args.abortSignal.aborted) {
3082
- resolveAbort(abortResult);
3083
- return;
3084
- }
3085
- abortListener = () => resolveAbort(abortResult);
3086
- args.abortSignal.addEventListener("abort", abortListener, { once: true });
3087
- }) : null;
3088
- const effectiveDetachMs = resolveDetachMs(args.detachMs);
3089
- const detachPromise = new Promise((r) => {
3090
- detachTimer = setTimeout(() => r(detachResult), effectiveDetachMs);
3091
- });
3092
- const racers = [exitPromise];
3093
- if (timeoutMs) {
3094
- racers.push(
3095
- new Promise((resolveTimeout) => {
3096
- timeout = setTimeout(() => resolveTimeout(timeoutResult), timeoutMs);
3097
- })
3098
- );
3099
- }
3100
- if (abortPromise) racers.push(abortPromise);
3101
- racers.push(detachPromise);
3102
- let raceWinner;
3103
- try {
3104
- raceWinner = await Promise.race(racers);
3105
- } catch (error) {
3106
- if (timeout) clearTimeout(timeout);
3107
- if (detachTimer) clearTimeout(detachTimer);
3108
- if (abortListener && args.abortSignal) {
3109
- args.abortSignal.removeEventListener("abort", abortListener);
3110
- }
3111
- detachSignalCleanup();
3112
- if (isSpawnFailureError(error)) {
3113
- return spawnFailedCommandResult(error, args.outputLimit);
3114
- }
3115
- throw error;
3116
- }
3117
- if (timeout) clearTimeout(timeout);
3118
- if (detachTimer) clearTimeout(detachTimer);
3119
- if (abortListener && args.abortSignal) {
3120
- args.abortSignal.removeEventListener("abort", abortListener);
3121
- }
3122
- const timedOut = raceWinner === timeoutResult;
3123
- const aborted = raceWinner === abortResult;
3124
- const didDetach = raceWinner === detachResult;
3125
- if (timedOut || aborted) {
3126
- killChild("SIGTERM");
3127
- await Promise.race([
3128
- exitPromise.catch(() => 124),
3129
- new Promise((resolveKill) => setTimeout(resolveKill, 500))
3130
- ]);
3131
- killChild("SIGKILL");
3132
- }
3133
- if (didDetach) {
3134
- exitPromise.catch(() => {
3135
- });
3136
- const pid = typeof proc.pid === "number" ? proc.pid : 0;
3137
- const label = deriveLabel(args.command.join(" "));
3138
- const pgid = pid;
3139
- const registry2 = getProcessRegistry();
3140
- registry2.add({ pid, pgid, command: args.command.join(" "), label });
3141
- proc.on("close", (code) => {
3142
- detachSignalCleanup();
3143
- registry2.markExited(pid, code ?? 1);
3144
- });
3145
- const immediate = effectiveDetachMs === 0;
3146
- const reason = immediate ? `command looks long-running; moved to background immediately (pid=${pid}, label=${label})` : `command detached to background after ${effectiveDetachMs}ms (pid=${pid}, label=${label})`;
3147
- return {
3148
- stdout: "",
3149
- stderr: `${reason}
3150
- Use listProcesses to inspect or stop it.`,
3151
- exitCode: 0,
3152
- timedOut: false,
3153
- detached: true,
3154
- pid,
3155
- label,
3156
- content: JSON.stringify({
3157
- detached: true,
3158
- pid,
3159
- label,
3160
- status: "running",
3161
- ...immediate ? { reason: "long-running-command" } : {}
3162
- })
3163
- };
3164
- }
3165
- const [stdout, rawStderr] = await Promise.all([
3166
- stdoutPromise,
3167
- stderrPromise
3168
- ]);
3169
- const exitCode = aborted ? 130 : timedOut ? 124 : Number(raceWinner);
3170
- const stderr = aborted ? `${rawStderr.trim() ? `${rawStderr.trim()}
3171
- ` : ""}command aborted by signal
3172
- ` : timedOut ? `${rawStderr.trim() ? `${rawStderr.trim()}
3173
- ` : ""}command timed out after ${timeoutMs ?? "unknown"}ms
3174
- ` : rawStderr;
3175
- return {
3176
- stdout,
3177
- stderr,
3178
- exitCode,
3179
- timedOut,
3180
- aborted,
3181
- content: truncateToolOutput([
3182
- stdout.trim() ? `stdout:
3183
- ${stdout.trim()}` : "",
3184
- stderr.trim() ? `stderr:
3185
- ${stderr.trim()}` : "",
3186
- `exitCode: ${exitCode}`
3187
- ].filter(Boolean).join("\n\n"), args.outputLimit)
3188
- };
3189
- }
3190
2208
  async function runWorkspaceCommandLimitedLines(args) {
3191
2209
  const command = [
3192
2210
  ...args.commandPrefix ?? [],
@@ -4045,63 +3063,24 @@ async function captureVisualStateTool(args) {
4045
3063
  };
4046
3064
  }
4047
3065
  async function execShellTool(args) {
4048
- const parsed = parseWorkspaceToolArguments(args.call.arguments);
4049
- const command = requireShellCommand(parsed, args.call.name);
4050
- if (args.restrictToWorkspace) {
4051
- const escapeToken = findWorkspaceShellEscapeToken(command);
4052
- if (escapeToken) {
4053
- return buildWorkspaceShellEscapeBlockedResult({ command, token: escapeToken });
4054
- }
4055
- }
4056
- const interactiveAuthCommand = extractInteractiveGhAuthCommand(command);
4057
- if (interactiveAuthCommand) {
4058
- const activity2 = extractActivity(parsed);
4059
- const blocked = buildInteractiveCommandBlockedResult(interactiveAuthCommand);
4060
- return {
4061
- ...blocked,
4062
- metadata: {
4063
- ...blocked.metadata,
4064
- ...activity2 ? { activity: activity2 } : {}
4065
- }
4066
- };
4067
- }
4068
- const result = await runWorkspaceCommand({
4069
- workspaceRoot: args.workspaceRoot,
4070
- command: buildWorkspaceShellCommand({
4071
- toolName: args.call.name,
4072
- command,
4073
- shell: parsed.shell
4074
- }),
4075
- timeoutMs: resolveExecShellTimeoutMs(args.commandTimeoutMs),
4076
- outputLimit: args.commandOutputLimit,
4077
- commandPrefix: args.commandPrefix,
4078
- abortSignal: args.abortSignal,
4079
- // Commands that clearly never exit (long sleeps, tail -f, watch, dev
4080
- // servers, infinite loops) are promoted to background immediately so the
4081
- // turn — and the user's conversation — keeps going. Everything else keeps
4082
- // the caller/env detach grace window.
4083
- detachMs: isImmediateDetachShellCommand({ command }) ? 0 : args.detachMs
4084
- });
4085
- const activity = extractActivity(parsed);
4086
- return {
4087
- content: result.content,
4088
- metadata: {
4089
- command,
4090
- exitCode: result.exitCode,
4091
- timedOut: result.timedOut,
4092
- ...result.aborted ? { aborted: true } : {},
4093
- ...result.detached ? { detached: true, pid: result.pid, label: result.label, status: "running" } : {},
4094
- ...activity ? { activity } : {}
3066
+ return invokeCapability(
3067
+ "execShell",
3068
+ args.call.arguments,
3069
+ {
3070
+ workspaceRoot: args.workspaceRoot,
3071
+ commandTimeoutMs: args.commandTimeoutMs,
3072
+ commandOutputLimit: args.commandOutputLimit,
3073
+ commandPrefix: args.commandPrefix,
3074
+ restrictToWorkspace: args.restrictToWorkspace,
3075
+ abortSignal: args.abortSignal,
3076
+ detachMs: args.detachMs,
3077
+ confirmed: args.confirmed,
3078
+ enableDestructiveShellGuard: args.enableDestructiveShellGuard,
3079
+ confirmDestructiveAction: args.confirmDestructiveAction,
3080
+ blockDestructiveWithoutConfirmation: args.blockDestructiveWithoutConfirmation,
3081
+ onInvoke: args.onInvoke
4095
3082
  }
4096
- };
4097
- }
4098
- function deriveLabel(command) {
4099
- const trimmed = command.trim();
4100
- if (!trimmed) return "process";
4101
- const tokens = trimmed.split(/\s+/);
4102
- const lastToken = tokens[tokens.length - 1] ?? trimmed;
4103
- const labelCandidate = lastToken.split(/[/\\]/).pop() || lastToken;
4104
- return labelCandidate || trimmed;
3083
+ );
4105
3084
  }
4106
3085
  async function launchProcessTool(args) {
4107
3086
  const parsed = parseWorkspaceToolArguments(args.call.arguments);
@@ -4138,8 +3117,8 @@ async function launchProcessTool(args) {
4138
3117
  };
4139
3118
  }
4140
3119
  const pgid = detached ? pid : pid;
4141
- const registry2 = getProcessRegistry();
4142
- registry2.add({ pid, pgid, command, label, persist });
3120
+ const registry = getProcessRegistry();
3121
+ registry.add({ pid, pgid, command, label, persist });
4143
3122
  const cleanupChildOnHostSignal = (signal) => {
4144
3123
  try {
4145
3124
  if (detached) {
@@ -4161,7 +3140,7 @@ async function launchProcessTool(args) {
4161
3140
  process.removeListener("SIGTERM", cleanupChildOnHostSignal);
4162
3141
  process.removeListener("SIGINT", cleanupChildOnHostSignal);
4163
3142
  }
4164
- registry2.markExited(pid, code ?? 1);
3143
+ registry.markExited(pid, code ?? 1);
4165
3144
  });
4166
3145
  const activity = extractActivity(parsed);
4167
3146
  const resultData = { pid, label, status: "running" };
@@ -4241,7 +3220,12 @@ function createLocalWorkspaceToolExecutors(args) {
4241
3220
  commandPrefix: args.commandPrefix,
4242
3221
  restrictToWorkspace: args.restrictShellToWorkspace,
4243
3222
  abortSignal: opts?.abortSignal ?? args.abortSignal,
4244
- detachMs: opts?.detachMs ?? args.detachMs
3223
+ detachMs: opts?.detachMs ?? args.detachMs,
3224
+ confirmed: opts?.confirmed,
3225
+ enableDestructiveShellGuard: opts?.enableDestructiveShellGuard,
3226
+ confirmDestructiveAction: opts?.confirmDestructiveAction,
3227
+ blockDestructiveWithoutConfirmation: opts?.blockDestructiveWithoutConfirmation,
3228
+ onInvoke: opts?.onInvoke
4245
3229
  }),
4246
3230
  launchProcess: (call) => launchProcessTool({
4247
3231
  call,
@@ -4280,11 +3264,11 @@ async function readNoloProcessStream(readable) {
4280
3264
  async function runNoloWorkspaceCliTool(call, args) {
4281
3265
  const cliArgs = buildNoloWorkspaceCommandArgs(call);
4282
3266
  const bunSpawn = globalThis.Bun?.spawn;
4283
- const spawn2 = args.spawn ?? (typeof bunSpawn === "function" ? bunSpawn : nodeSpawnFallback);
3267
+ const spawn = args.spawn ?? (typeof bunSpawn === "function" ? bunSpawn : nodeSpawnFallback);
4284
3268
  const execPath = args.processExecPath ?? process.execPath;
4285
3269
  const entrypoint = args.cliEntrypoint;
4286
3270
  const cmd = entrypoint && entrypoint !== execPath ? [execPath, entrypoint, ...cliArgs] : [execPath, ...cliArgs];
4287
- const proc = spawn2({
3271
+ const proc = spawn({
4288
3272
  cmd,
4289
3273
  stdout: "pipe",
4290
3274
  stderr: "pipe",
@@ -4386,10 +3370,10 @@ function buildLoadSkillExecutor(args) {
4386
3370
  metadata: { loadSkill: true, resolved: false }
4387
3371
  };
4388
3372
  }
4389
- const { resolveSkillByName } = await import("./skillDiscovery-KLLKXPUO.js");
3373
+ const { resolveSkillByName } = await import("./skillDiscovery-AYBKAG6X.js");
4390
3374
  const resolved = resolveSkillByName(args.cwd, name);
4391
3375
  if (!resolved) {
4392
- const { resolveCodingBuiltinSlug, buildCodingSkillContentBySlug } = await import("./codingSkills-DY5MINPG.js");
3376
+ const { resolveCodingBuiltinSlug, buildCodingSkillContentBySlug } = await import("./codingSkills-5VOV3JVB.js");
4393
3377
  const builtinSlug = resolveCodingBuiltinSlug(name);
4394
3378
  if (builtinSlug) {
4395
3379
  const body = buildCodingSkillContentBySlug(builtinSlug);
@@ -4424,7 +3408,7 @@ ${body}`,
4424
3408
  };
4425
3409
  }
4426
3410
  async function formatUnknownSkillMessage(cwd, requestedName) {
4427
- const { discoverSkills } = await import("./skillDiscovery-KLLKXPUO.js");
3411
+ const { discoverSkills } = await import("./skillDiscovery-AYBKAG6X.js");
4428
3412
  let available = [];
4429
3413
  try {
4430
3414
  available = discoverSkills(cwd).map((s) => s.name);
@@ -4456,13 +3440,10 @@ export {
4456
3440
  shouldCacheHybridRemoteRecord,
4457
3441
  parseSyncServersEnv,
4458
3442
  createHybridRecordStore,
4459
- isDestructiveShellCommand,
4460
- evaluateShellCommandPolicy,
4461
3443
  resolveLocalToolPolicy,
4462
3444
  executeLocalToolWithPolicy,
4463
3445
  filterRetainedLedgerRecords,
4464
3446
  isLineRangeCovered,
4465
- getProcessRegistry,
4466
3447
  buildLocalWorkspaceToolset,
4467
3448
  buildLocalWorkspacePolicyToolNames,
4468
3449
  buildLocalWorkspaceOpenAiTools,