@iaforged/context-code 2.1.6 → 2.1.7

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 (409) hide show
  1. package/dist/src/Task.js +1 -1
  2. package/dist/src/commands/add-dir/add-dir.js +1 -1
  3. package/dist/src/commands/add-dir/validation.js +1 -1
  4. package/dist/src/constants/oauth.js +1 -1
  5. package/dist/src/context/mailbox.js +1 -1
  6. package/dist/src/context/voice.js +1 -1
  7. package/dist/src/hooks/useTerminalSize.js +1 -1
  8. package/dist/src/ink/Ansi.js +1 -1
  9. package/dist/src/ink/clearTerminal.js +1 -1
  10. package/dist/src/ink/colorize.js +1 -1
  11. package/dist/src/ink/components/App.js +1 -1
  12. package/dist/src/ink/components/Button.js +1 -1
  13. package/dist/src/ink/components/ClockContext.js +1 -1
  14. package/dist/src/ink/components/CursorDeclarationContext.js +1 -1
  15. package/dist/src/ink/components/Link.js +1 -1
  16. package/dist/src/ink/components/StdinContext.js +1 -1
  17. package/dist/src/ink/components/TerminalFocusContext.js +1 -1
  18. package/dist/src/ink/dom.js +1 -1
  19. package/dist/src/ink/events/keyboard-event.js +1 -1
  20. package/dist/src/ink/hit-test.js +1 -1
  21. package/dist/src/ink/hooks/use-animation-frame.js +1 -1
  22. package/dist/src/ink/hooks/use-app.js +1 -1
  23. package/dist/src/ink/hooks/use-input.js +1 -1
  24. package/dist/src/ink/hooks/use-interval.js +1 -1
  25. package/dist/src/ink/hooks/use-selection.js +1 -1
  26. package/dist/src/ink/hooks/use-tab-status.js +1 -1
  27. package/dist/src/ink/hooks/use-terminal-focus.js +1 -1
  28. package/dist/src/ink/hooks/use-terminal-title.js +1 -1
  29. package/dist/src/ink/hooks/use-terminal-viewport.js +1 -1
  30. package/dist/src/ink/ink.js +1 -1
  31. package/dist/src/ink/layout/yoga.js +1 -1
  32. package/dist/src/ink/line-width-cache.js +1 -1
  33. package/dist/src/ink/log-update.js +1 -1
  34. package/dist/src/ink/measure-text.js +1 -1
  35. package/dist/src/ink/output.js +1 -1
  36. package/dist/src/ink/parse-keypress.js +1 -1
  37. package/dist/src/ink/reconciler.js +1 -1
  38. package/dist/src/ink/render-border.js +1 -1
  39. package/dist/src/ink/render-node-to-output.js +1 -1
  40. package/dist/src/ink/render-to-screen.js +1 -1
  41. package/dist/src/ink/renderer.js +1 -1
  42. package/dist/src/ink/root.js +1 -1
  43. package/dist/src/ink/screen.js +1 -1
  44. package/dist/src/ink/searchHighlight.js +1 -1
  45. package/dist/src/ink/selection.js +1 -1
  46. package/dist/src/ink/squash-text-nodes.js +1 -1
  47. package/dist/src/ink/stringWidth.js +1 -1
  48. package/dist/src/ink/tabstops.js +1 -1
  49. package/dist/src/ink/terminal.js +1 -1
  50. package/dist/src/ink/termio/osc.js +1 -1
  51. package/dist/src/ink/termio/parser.js +1 -1
  52. package/dist/src/ink/termio/tokenize.js +1 -1
  53. package/dist/src/ink/useTerminalNotification.js +1 -1
  54. package/dist/src/ink/warn.js +1 -1
  55. package/dist/src/ink/widest-line.js +1 -1
  56. package/dist/src/ink/wrap-text.js +1 -1
  57. package/dist/src/ink/wrapAnsi.js +1 -1
  58. package/dist/src/native-ts/yoga-layout/index.js +1 -1
  59. package/dist/src/schemas/hooks.js +1 -1
  60. package/dist/src/services/SessionMemory/sessionMemoryUtils.js +1 -1
  61. package/dist/src/services/api/client.js +1 -1
  62. package/dist/src/services/api/dumpPrompts.js +1 -1
  63. package/dist/src/services/api/errorUtils.js +1 -1
  64. package/dist/src/services/api/promptCacheBreakDetection.js +1 -1
  65. package/dist/src/services/api/withRetry.js +1 -1
  66. package/dist/src/services/autoDream/consolidationLock.js +1 -1
  67. package/dist/src/services/mcp/elicitationHandler.js +1 -1
  68. package/dist/src/services/mcp/mcpStringUtils.js +1 -1
  69. package/dist/src/services/mcp/oauthPort.js +1 -1
  70. package/dist/src/services/mcp/vscodeSdkMcp.js +1 -1
  71. package/dist/src/services/oauth/client.js +1 -1
  72. package/dist/src/services/oauth/getOauthProfile.js +1 -1
  73. package/dist/src/services/objetivo/types.js +1 -1
  74. package/dist/src/services/rateLimitMocking.js +1 -1
  75. package/dist/src/services/remoteManagedSettings/syncCacheState.js +1 -1
  76. package/dist/src/skills/bundledSkills.js +1 -1
  77. package/dist/src/tasks/DreamTask/DreamTask.js +1 -1
  78. package/dist/src/tools/AgentTool/agentMemory.js +1 -1
  79. package/dist/src/tools/AgentTool/forkSubagent.js +1 -1
  80. package/dist/src/tools/BashTool/BashToolResultMessage.js +1 -1
  81. package/dist/src/tools/BashTool/UI.js +1 -1
  82. package/dist/src/tools/BashTool/sedEditParser.js +1 -1
  83. package/dist/src/tools/BashTool/utils.js +1 -1
  84. package/dist/src/tools/FileReadTool/imageProcessor.js +1 -1
  85. package/dist/src/tools/FileReadTool/prompt.js +1 -1
  86. package/dist/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +1 -1
  87. package/dist/src/tools/ListMcpResourcesTool/UI.js +1 -1
  88. package/dist/src/tools/MCPTool/MCPTool.js +1 -1
  89. package/dist/src/tools/MCPTool/UI.js +1 -1
  90. package/dist/src/tools/McpAuthTool/McpAuthTool.js +1 -1
  91. package/dist/src/tools/NotebookEditTool/prompt.js +1 -1
  92. package/dist/src/tools/PowerShellTool/PowerShellTool.js +1 -1
  93. package/dist/src/tools/PowerShellTool/UI.js +1 -1
  94. package/dist/src/tools/PowerShellTool/gitSafety.js +1 -1
  95. package/dist/src/tools/PowerShellTool/modeValidation.js +1 -1
  96. package/dist/src/tools/PowerShellTool/pathValidation.js +1 -1
  97. package/dist/src/tools/PowerShellTool/powershellPermissions.js +1 -1
  98. package/dist/src/tools/PowerShellTool/powershellSecurity.js +1 -1
  99. package/dist/src/tools/PowerShellTool/prompt.js +1 -1
  100. package/dist/src/tools/PowerShellTool/readOnlyValidation.js +1 -1
  101. package/dist/src/tools/REPLTool/constants.js +1 -1
  102. package/dist/src/tools/REPLTool/primitiveTools.js +1 -1
  103. package/dist/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +1 -1
  104. package/dist/src/tools/ReadMcpResourceTool/UI.js +1 -1
  105. package/dist/src/tools/ScheduleCronTool/prompt.js +1 -1
  106. package/dist/src/tools/SkillTool/prompt.js +1 -1
  107. package/dist/src/tools/TodoWriteTool/TodoWriteTool.js +1 -1
  108. package/dist/src/tools/ToolSearchTool/prompt.js +1 -1
  109. package/dist/src/tools/WebSearchTool/prompt.js +1 -1
  110. package/dist/src/tools/shared/gitOperationTracking.js +1 -1
  111. package/dist/src/types/permissions.js +1 -1
  112. package/dist/src/utils/Cursor.js +1 -1
  113. package/dist/src/utils/QueryGuard.js +1 -1
  114. package/dist/src/utils/Shell.js +1 -1
  115. package/dist/src/utils/ShellCommand.js +1 -1
  116. package/dist/src/utils/activityManager.js +1 -1
  117. package/dist/src/utils/advisor.js +1 -1
  118. package/dist/src/utils/appleTerminalBackup.js +1 -1
  119. package/dist/src/utils/argumentSubstitution.js +1 -1
  120. package/dist/src/utils/authFileDescriptor.js +1 -1
  121. package/dist/src/utils/autoUpdater.js +1 -1
  122. package/dist/src/utils/background/remote/preconditions.js +1 -1
  123. package/dist/src/utils/background/remote/remoteSession.js +1 -1
  124. package/dist/src/utils/bash/ShellSnapshot.js +1 -1
  125. package/dist/src/utils/bash/ast.js +1 -1
  126. package/dist/src/utils/bash/bashParser.js +1 -1
  127. package/dist/src/utils/bash/bashPipeCommand.js +1 -1
  128. package/dist/src/utils/bash/parser.js +1 -1
  129. package/dist/src/utils/bash/shellQuote.js +1 -1
  130. package/dist/src/utils/bash/shellQuoting.js +1 -1
  131. package/dist/src/utils/billing.js +1 -1
  132. package/dist/src/utils/caCerts.js +1 -1
  133. package/dist/src/utils/claudeInChrome/common.js +1 -1
  134. package/dist/src/utils/claudeInChrome/setupPortable.js +1 -1
  135. package/dist/src/utils/claudemd.js +1 -1
  136. package/dist/src/utils/collapseBackgroundBashNotifications.js +1 -1
  137. package/dist/src/utils/collapseReadSearch.js +1 -1
  138. package/dist/src/utils/completionCache.js +1 -1
  139. package/dist/src/utils/computerUse/common.js +1 -1
  140. package/dist/src/utils/concurrentSessions.js +1 -1
  141. package/dist/src/utils/context.js +1 -1
  142. package/dist/src/utils/cron.js +1 -1
  143. package/dist/src/utils/cronTasks.js +1 -1
  144. package/dist/src/utils/cwd.js +1 -1
  145. package/dist/src/utils/debug.js +1 -1
  146. package/dist/src/utils/debugFilter.js +1 -1
  147. package/dist/src/utils/detectRepository.js +1 -1
  148. package/dist/src/utils/diagLogs.js +1 -1
  149. package/dist/src/utils/diff.js +1 -1
  150. package/dist/src/utils/directMemberMessage.js +1 -1
  151. package/dist/src/utils/doctorDiagnostic.js +1 -1
  152. package/dist/src/utils/dxt/helpers.js +1 -1
  153. package/dist/src/utils/dxt/zip.js +1 -1
  154. package/dist/src/utils/earlyInput.js +1 -1
  155. package/dist/src/utils/editor.js +1 -1
  156. package/dist/src/utils/effort.js +1 -1
  157. package/dist/src/utils/embeddedTools.js +1 -1
  158. package/dist/src/utils/envDynamic.js +1 -1
  159. package/dist/src/utils/envUtils.js +1 -1
  160. package/dist/src/utils/execFileNoThrowPortable.js +1 -1
  161. package/dist/src/utils/execSyncWrapper.js +1 -1
  162. package/dist/src/utils/exportRenderer.js +1 -1
  163. package/dist/src/utils/extraUsage.js +1 -1
  164. package/dist/src/utils/fastMode.js +1 -1
  165. package/dist/src/utils/fileOperationAnalytics.js +1 -1
  166. package/dist/src/utils/fileRead.js +1 -1
  167. package/dist/src/utils/findExecutable.js +1 -1
  168. package/dist/src/utils/format.js +1 -1
  169. package/dist/src/utils/frontmatterParser.js +1 -1
  170. package/dist/src/utils/fsOperations.js +1 -1
  171. package/dist/src/utils/fullscreen.js +1 -1
  172. package/dist/src/utils/genericProcessUtils.js +1 -1
  173. package/dist/src/utils/getWorktreePaths.js +1 -1
  174. package/dist/src/utils/git/gitConfigParser.js +1 -1
  175. package/dist/src/utils/git/gitFilesystem.js +1 -1
  176. package/dist/src/utils/git/gitignore.js +1 -1
  177. package/dist/src/utils/gitDiff.js +1 -1
  178. package/dist/src/utils/gitSettings.js +1 -1
  179. package/dist/src/utils/glob.js +1 -1
  180. package/dist/src/utils/gracefulShutdown.js +1 -1
  181. package/dist/src/utils/groupToolUses.js +1 -1
  182. package/dist/src/utils/handlePromptSubmit.js +1 -1
  183. package/dist/src/utils/hash.js +1 -1
  184. package/dist/src/utils/hooks/fileChangedWatcher.js +1 -1
  185. package/dist/src/utils/hooks/hooksSettings.js +1 -1
  186. package/dist/src/utils/hooks/registerSkillHooks.js +1 -1
  187. package/dist/src/utils/hooks/sessionHooks.js +1 -1
  188. package/dist/src/utils/http.js +1 -1
  189. package/dist/src/utils/hyperlink.js +1 -1
  190. package/dist/src/utils/ide.js +1 -1
  191. package/dist/src/utils/idePathConversion.js +1 -1
  192. package/dist/src/utils/imagePaste.js +1 -1
  193. package/dist/src/utils/imageResizer.js +1 -1
  194. package/dist/src/utils/imageStore.js +1 -1
  195. package/dist/src/utils/inProcessTeammateHelpers.js +1 -1
  196. package/dist/src/utils/ink.js +1 -1
  197. package/dist/src/utils/jetbrains.js +1 -1
  198. package/dist/src/utils/json.js +1 -1
  199. package/dist/src/utils/listSessionsImpl.js +1 -1
  200. package/dist/src/utils/localInstaller.js +1 -1
  201. package/dist/src/utils/lockfile.js +1 -1
  202. package/dist/src/utils/logoV2Utils.js +1 -1
  203. package/dist/src/utils/markdown.js +1 -1
  204. package/dist/src/utils/mcp/dateTimeParser.js +1 -1
  205. package/dist/src/utils/mcpOutputStorage.js +1 -1
  206. package/dist/src/utils/mcpValidation.js +1 -1
  207. package/dist/src/utils/memoize.js +1 -1
  208. package/dist/src/utils/memory/types.js +1 -1
  209. package/dist/src/utils/memoryFileDetection.js +1 -1
  210. package/dist/src/utils/messageQueueManager.js +1 -1
  211. package/dist/src/utils/messages/mappers.js +1 -1
  212. package/dist/src/utils/messages/systemInit.js +1 -1
  213. package/dist/src/utils/model/antModels.js +1 -1
  214. package/dist/src/utils/model/check1mAccess.js +1 -1
  215. package/dist/src/utils/model/contextWindowUpgradeCheck.js +1 -1
  216. package/dist/src/utils/model/model.js +1 -1
  217. package/dist/src/utils/model/modelAllowlist.js +1 -1
  218. package/dist/src/utils/model/modelCapabilities.js +1 -1
  219. package/dist/src/utils/model/modelOptions.js +1 -1
  220. package/dist/src/utils/model/modelStrings.js +1 -1
  221. package/dist/src/utils/model/providerModels.js +1 -1
  222. package/dist/src/utils/model/providerProfiles.js +1 -1
  223. package/dist/src/utils/model/providerProfilesDb.js +1 -1
  224. package/dist/src/utils/model/providerSwitch.js +1 -1
  225. package/dist/src/utils/model/providers.js +1 -1
  226. package/dist/src/utils/modelCost.js +1 -1
  227. package/dist/src/utils/modifiers.js +1 -1
  228. package/dist/src/utils/mtls.js +1 -1
  229. package/dist/src/utils/nativeInstaller/download.js +1 -1
  230. package/dist/src/utils/nativeInstaller/installer.js +1 -1
  231. package/dist/src/utils/nativeInstaller/packageManagers.js +1 -1
  232. package/dist/src/utils/nativeInstaller/pidLock.js +1 -1
  233. package/dist/src/utils/notebook.js +1 -1
  234. package/dist/src/utils/pasteStore.js +1 -1
  235. package/dist/src/utils/path.js +1 -1
  236. package/dist/src/utils/permissions/PermissionMode.js +1 -1
  237. package/dist/src/utils/permissions/PermissionPromptToolResultSchema.js +1 -1
  238. package/dist/src/utils/permissions/PermissionUpdate.js +1 -1
  239. package/dist/src/utils/permissions/PermissionUpdateSchema.js +1 -1
  240. package/dist/src/utils/permissions/autoModeState.js +1 -1
  241. package/dist/src/utils/permissions/bypassPermissionsKillswitch.js +1 -1
  242. package/dist/src/utils/permissions/filesystem.js +1 -1
  243. package/dist/src/utils/permissions/getNextPermissionMode.js +1 -1
  244. package/dist/src/utils/permissions/pathValidation.js +1 -1
  245. package/dist/src/utils/permissions/permissionRuleParser.js +1 -1
  246. package/dist/src/utils/permissions/permissionsDb.js +1 -1
  247. package/dist/src/utils/permissions/permissionsLoader.js +1 -1
  248. package/dist/src/utils/permissions/shellRuleMatching.js +1 -1
  249. package/dist/src/utils/planModeV2.js +1 -1
  250. package/dist/src/utils/plans.js +1 -1
  251. package/dist/src/utils/platform.js +1 -1
  252. package/dist/src/utils/plugins/addDirPluginSettings.js +1 -1
  253. package/dist/src/utils/plugins/cacheUtils.js +1 -1
  254. package/dist/src/utils/plugins/dependencyResolver.js +1 -1
  255. package/dist/src/utils/plugins/fetchTelemetry.js +1 -1
  256. package/dist/src/utils/plugins/gitAvailability.js +1 -1
  257. package/dist/src/utils/plugins/hintRecommendation.js +1 -1
  258. package/dist/src/utils/plugins/installedPluginsManager.js +1 -1
  259. package/dist/src/utils/plugins/loadPluginAgents.js +1 -1
  260. package/dist/src/utils/plugins/loadPluginCommands.js +1 -1
  261. package/dist/src/utils/plugins/loadPluginHooks.js +1 -1
  262. package/dist/src/utils/plugins/loadPluginOutputStyles.js +1 -1
  263. package/dist/src/utils/plugins/lspPluginIntegration.js +1 -1
  264. package/dist/src/utils/plugins/lspRecommendation.js +1 -1
  265. package/dist/src/utils/plugins/managedPlugins.js +1 -1
  266. package/dist/src/utils/plugins/marketplaceHelpers.js +1 -1
  267. package/dist/src/utils/plugins/marketplaceManager.js +1 -1
  268. package/dist/src/utils/plugins/mcpPluginIntegration.js +1 -1
  269. package/dist/src/utils/plugins/mcpbHandler.js +1 -1
  270. package/dist/src/utils/plugins/officialMarketplaceGcs.js +1 -1
  271. package/dist/src/utils/plugins/officialMarketplaceStartupCheck.js +1 -1
  272. package/dist/src/utils/plugins/orphanedPluginFilter.js +1 -1
  273. package/dist/src/utils/plugins/performStartupChecks.js +1 -1
  274. package/dist/src/utils/plugins/pluginAutoupdate.js +1 -1
  275. package/dist/src/utils/plugins/pluginBlocklist.js +1 -1
  276. package/dist/src/utils/plugins/pluginDirectories.js +1 -1
  277. package/dist/src/utils/plugins/pluginFlagging.js +1 -1
  278. package/dist/src/utils/plugins/pluginInstallationHelpers.js +1 -1
  279. package/dist/src/utils/plugins/pluginLoader.js +1 -1
  280. package/dist/src/utils/plugins/pluginOptionsStorage.js +1 -1
  281. package/dist/src/utils/plugins/pluginPolicy.js +1 -1
  282. package/dist/src/utils/plugins/pluginStartupCheck.js +1 -1
  283. package/dist/src/utils/plugins/pluginVersioning.js +1 -1
  284. package/dist/src/utils/plugins/reconciler.js +1 -1
  285. package/dist/src/utils/plugins/refresh.js +1 -1
  286. package/dist/src/utils/plugins/schemas.js +1 -1
  287. package/dist/src/utils/plugins/walkPluginMarkdown.js +1 -1
  288. package/dist/src/utils/plugins/zipCache.js +1 -1
  289. package/dist/src/utils/powershell/parser.js +1 -1
  290. package/dist/src/utils/processUserInput/processBashCommand.js +1 -1
  291. package/dist/src/utils/processUserInput/processSlashCommand.js +1 -1
  292. package/dist/src/utils/processUserInput/processTextPrompt.js +1 -1
  293. package/dist/src/utils/processUserInput/processUserInput.js +1 -1
  294. package/dist/src/utils/profilerBase.js +1 -1
  295. package/dist/src/utils/promptCategory.js +1 -1
  296. package/dist/src/utils/promptEditor.js +1 -1
  297. package/dist/src/utils/promptShellExecution.js +1 -1
  298. package/dist/src/utils/proxy.js +1 -1
  299. package/dist/src/utils/queryHelpers.js +1 -1
  300. package/dist/src/utils/queryProfiler.js +1 -1
  301. package/dist/src/utils/queueProcessor.js +1 -1
  302. package/dist/src/utils/readFileInRange.js +1 -1
  303. package/dist/src/utils/releaseNotes.js +1 -1
  304. package/dist/src/utils/renderOptions.js +1 -1
  305. package/dist/src/utils/ripgrep.js +1 -1
  306. package/dist/src/utils/sandbox/sandbox-adapter.js +1 -1
  307. package/dist/src/utils/sdkEventQueue.js +1 -1
  308. package/dist/src/utils/secureStorage/index.js +1 -1
  309. package/dist/src/utils/secureStorage/macOsKeychainHelpers.js +1 -1
  310. package/dist/src/utils/secureStorage/macOsKeychainStorage.js +1 -1
  311. package/dist/src/utils/secureStorage/plainTextStorage.js +1 -1
  312. package/dist/src/utils/secureStorage/sqliteStorage.js +1 -1
  313. package/dist/src/utils/sessionEnvironment.js +1 -1
  314. package/dist/src/utils/sessionIngressAuth.js +1 -1
  315. package/dist/src/utils/sessionRestore.js +1 -1
  316. package/dist/src/utils/sessionStart.js +1 -1
  317. package/dist/src/utils/sessionTitle.js +1 -1
  318. package/dist/src/utils/settings/managedPath.js +1 -1
  319. package/dist/src/utils/settings/mdm/rawRead.js +1 -1
  320. package/dist/src/utils/settings/mdm/settings.js +1 -1
  321. package/dist/src/utils/settings/permissionValidation.js +1 -1
  322. package/dist/src/utils/settings/pluginOnlyPolicy.js +1 -1
  323. package/dist/src/utils/settings/schemaOutput.js +1 -1
  324. package/dist/src/utils/settings/settings.js +1 -1
  325. package/dist/src/utils/settings/types.js +1 -1
  326. package/dist/src/utils/settings/validateEditTool.js +1 -1
  327. package/dist/src/utils/settings/validation.js +1 -1
  328. package/dist/src/utils/shell/bashProvider.js +1 -1
  329. package/dist/src/utils/shell/powershellDetection.js +1 -1
  330. package/dist/src/utils/shell/powershellProvider.js +1 -1
  331. package/dist/src/utils/shell/readOnlyCommandValidation.js +1 -1
  332. package/dist/src/utils/shell/resolveDefaultShell.js +1 -1
  333. package/dist/src/utils/shell/shellToolUtils.js +1 -1
  334. package/dist/src/utils/shell/specPrefix.js +1 -1
  335. package/dist/src/utils/shellConfig.js +1 -1
  336. package/dist/src/utils/sideQuestion.js +1 -1
  337. package/dist/src/utils/skills/skillChangeDetector.js +1 -1
  338. package/dist/src/utils/slashCommandParsing.js +1 -1
  339. package/dist/src/utils/sliceAnsi.js +1 -1
  340. package/dist/src/utils/slowOperations.js +1 -1
  341. package/dist/src/utils/standaloneAgent.js +1 -1
  342. package/dist/src/utils/startupProfiler.js +1 -1
  343. package/dist/src/utils/staticRender.js +1 -1
  344. package/dist/src/utils/status.js +1 -1
  345. package/dist/src/utils/statusNoticeDefinitions.js +1 -1
  346. package/dist/src/utils/suggestions/commandSuggestions.js +1 -1
  347. package/dist/src/utils/suggestions/directoryCompletion.js +1 -1
  348. package/dist/src/utils/suggestions/shellHistoryCompletion.js +1 -1
  349. package/dist/src/utils/suggestions/skillUsageTracking.js +1 -1
  350. package/dist/src/utils/suggestions/slackChannelSuggestions.js +1 -1
  351. package/dist/src/utils/swarm/backends/detection.js +1 -1
  352. package/dist/src/utils/swarm/permissionSync.js +1 -1
  353. package/dist/src/utils/swarm/reconnection.js +1 -1
  354. package/dist/src/utils/swarm/spawnUtils.js +91 -1
  355. package/dist/src/utils/swarm/teammateInit.js +1 -1
  356. package/dist/src/utils/systemDirectories.js +1 -1
  357. package/dist/src/utils/systemPrompt.js +1 -1
  358. package/dist/src/utils/systemTheme.js +1 -1
  359. package/dist/src/utils/task/TaskOutput.js +1 -1
  360. package/dist/src/utils/task/diskOutput.js +1 -1
  361. package/dist/src/utils/tasks.js +1 -1
  362. package/dist/src/utils/teamDiscovery.js +1 -1
  363. package/dist/src/utils/teamMemoryOps.js +1 -1
  364. package/dist/src/utils/teammateMailbox.js +1 -1
  365. package/dist/src/utils/telemetry/betaSessionTracing.js +1 -1
  366. package/dist/src/utils/telemetry/bigqueryExporter.js +1 -1
  367. package/dist/src/utils/telemetry/events.js +1 -1
  368. package/dist/src/utils/telemetry/instrumentation.js +1 -1
  369. package/dist/src/utils/telemetry/logger.js +1 -1
  370. package/dist/src/utils/telemetry/perfettoTracing.js +1 -1
  371. package/dist/src/utils/telemetry/pluginTelemetry.js +1 -1
  372. package/dist/src/utils/telemetry/sessionTracing.js +1 -1
  373. package/dist/src/utils/telemetryAttributes.js +1 -1
  374. package/dist/src/utils/teleport/api.js +1 -1
  375. package/dist/src/utils/teleport/environments.js +1 -1
  376. package/dist/src/utils/teleport/gitBundle.js +1 -1
  377. package/dist/src/utils/teleport.js +1 -1
  378. package/dist/src/utils/tempfile.js +1 -1
  379. package/dist/src/utils/terminal.js +1 -1
  380. package/dist/src/utils/terminalPanel.js +1 -1
  381. package/dist/src/utils/textHighlighting.js +1 -1
  382. package/dist/src/utils/theme.js +1 -1
  383. package/dist/src/utils/themes/bootstrap.js +1 -1
  384. package/dist/src/utils/themes/loader.js +1 -1
  385. package/dist/src/utils/thinking.js +1 -1
  386. package/dist/src/utils/tmuxSocket.js +1 -1
  387. package/dist/src/utils/tokens.js +1 -1
  388. package/dist/src/utils/toolPool.js +1 -1
  389. package/dist/src/utils/toolResultStorage.js +1 -1
  390. package/dist/src/utils/transcriptSearch.js +1 -1
  391. package/dist/src/utils/truncate.js +1 -1
  392. package/dist/src/utils/ultraplan/keyword.js +1 -1
  393. package/dist/src/utils/unaryLogging.js +1 -1
  394. package/dist/src/utils/undercover.js +1 -1
  395. package/dist/src/utils/user.js +1 -1
  396. package/dist/src/utils/userPromptKeywords.js +1 -1
  397. package/dist/src/utils/which.js +1 -1
  398. package/dist/src/utils/windowsPaths.js +1 -1
  399. package/dist/src/utils/worktree.js +1 -1
  400. package/dist/src/utils/zodToJsonSchema.js +1 -1
  401. package/dist/src/vim/operators.js +1 -1
  402. package/dist/src/vim/textObjects.js +1 -1
  403. package/dist/src/vim/transitions.js +1 -1
  404. package/dist/src/voice/voiceModeEnabled.js +1 -1
  405. package/dist/src/webapp/auth.js +1 -1
  406. package/dist/src/webapp/tunnel.js +1 -1
  407. package/dist/src/whatsapp/bridge.js +1 -1
  408. package/dist/src/whatsapp/mirror.js +1 -1
  409. package/package.json +1 -1
@@ -1 +1 @@
1
- import{feature as e}from"../../recovery/bunBundleShim.js";import{randomUUID as t}from"crypto";import{getIsNonInteractiveSession as o}from"../../bootstrap/state.js";import{FORK_BOILERPLATE_TAG as r,FORK_DIRECTIVE_PREFIX as n}from"../../constants/xml.js";import{isCoordinatorMode as s}from"../../coordinator/coordinatorMode.js";import{logForDebugging as i}from"../../utils/debug.js";import{createUserMessage as a}from"../../utils/messages.js";export function isForkSubagentEnabled(){return!!e("FORK_SUBAGENT")&&(!s()&&!o())}export const FORK_SUBAGENT_TYPE="fork";export const FORK_AGENT={agentType:"fork",whenToUse:"Implicit fork — inherits full conversation context. Not selectable via subagent_type; triggered by omitting subagent_type when the fork experiment is active.",tools:["*"],maxTurns:200,model:"inherit",permissionMode:"bubble",source:"built-in",baseDir:"built-in",getSystemPrompt:()=>""};export function isInForkChild(e){return e.some(e=>{if("user"!==e.type)return!1;const t=e.message.content;return!!Array.isArray(t)&&t.some(e=>"text"===e.type&&e.text.includes(`<${r}>`))})}export function buildForkedMessages(e,o){const r={...o,uuid:t(),message:{...o.message,content:[...o.message.content]}},n=o.message.content.filter(e=>"tool_use"===e.type);if(0===n.length)return i(`No tool_use blocks found in assistant message for fork directive: ${e.slice(0,50)}...`,{level:"error"}),[a({content:[{type:"text",text:buildChildMessage(e)}]})];const s=n.map(e=>({type:"tool_result",tool_use_id:e.id,content:[{type:"text",text:"Fork started — processing in background"}]}));return[r,a({content:[...s,{type:"text",text:buildChildMessage(e)}]})]}export function buildChildMessage(e){return`<${r}>\nSTOP. READ THIS FIRST.\n\nYou are a forked worker process. You are NOT the main agent.\n\nRULES (non-negotiable):\n1. Your system prompt says "default to forking." IGNORE IT — that's for the parent. You ARE the fork. Do NOT spawn sub-agents; execute directly.\n2. Do NOT converse, ask questions, or suggest next steps\n3. Do NOT editorialize or add meta-commentary\n4. USE your tools directly: Bash, Read, Write, etc.\n5. If you modify files, commit your changes before reporting. Include the commit hash in your report.\n6. Do NOT emit text between tool calls. Use tools silently, then report once at the end.\n7. Stay strictly within your directive's scope. If you discover related systems outside your scope, mention them in one sentence at most — other workers cover those areas.\n8. Keep your report under 500 words unless the directive specifies otherwise. Be factual and concise.\n9. Your response MUST begin with "Scope:". No preamble, no thinking-out-loud.\n10. REPORT structured facts, then stop\n\nOutput format (plain text labels, not markdown headers):\n Scope: <echo back your assigned scope in one sentence>\n Result: <the answer or key findings, limited to the scope above>\n Key files: <relevant file paths — include for research tasks>\n Files changed: <list with commit hash — include only if you modified files>\n Issues: <list — include only if there are issues to flag>\n</${r}>\n\n${n}${e}`}export function buildWorktreeNotice(e,t){return`You've inherited the conversation context above from a parent agent working in ${e}. You are operating in an isolated git worktree at ${t} — same repository, same relative file structure, separate working copy. Paths in the inherited context refer to the parent's working directory; translate them to your worktree root. Re-read files before editing if the parent may have modified them since they appear in the context. Your changes stay in this worktree and will not affect the parent's files.`}
1
+ import{feature as e}from"bun:bundle";import{randomUUID as t}from"crypto";import{getIsNonInteractiveSession as o}from"../../bootstrap/state.js";import{FORK_BOILERPLATE_TAG as r,FORK_DIRECTIVE_PREFIX as n}from"../../constants/xml.js";import{isCoordinatorMode as s}from"../../coordinator/coordinatorMode.js";import{logForDebugging as i}from"../../utils/debug.js";import{createUserMessage as a}from"../../utils/messages.js";export function isForkSubagentEnabled(){return!!e("FORK_SUBAGENT")&&!s()&&!o()}export const FORK_SUBAGENT_TYPE="fork";export const FORK_AGENT={agentType:"fork",whenToUse:"Implicit fork — inherits full conversation context. Not selectable via subagent_type; triggered by omitting subagent_type when the fork experiment is active.",tools:["*"],maxTurns:200,model:"inherit",permissionMode:"bubble",source:"built-in",baseDir:"built-in",getSystemPrompt:()=>""};export function isInForkChild(e){return e.some(e=>{if("user"!==e.type)return!1;const t=e.message.content;return!!Array.isArray(t)&&t.some(e=>"text"===e.type&&e.text.includes(`<${r}>`))})}export function buildForkedMessages(e,o){const r={...o,uuid:t(),message:{...o.message,content:[...o.message.content]}},n=o.message.content.filter(e=>"tool_use"===e.type);if(0===n.length)return i(`No tool_use blocks found in assistant message for fork directive: ${e.slice(0,50)}...`,{level:"error"}),[a({content:[{type:"text",text:buildChildMessage(e)}]})];const s=n.map(e=>({type:"tool_result",tool_use_id:e.id,content:[{type:"text",text:"Fork started — processing in background"}]}));return[r,a({content:[...s,{type:"text",text:buildChildMessage(e)}]})]}export function buildChildMessage(e){return`<${r}>\nSTOP. READ THIS FIRST.\n\nYou are a forked worker process. You are NOT the main agent.\n\nRULES (non-negotiable):\n1. Your system prompt says "default to forking." IGNORE IT — that's for the parent. You ARE the fork. Do NOT spawn sub-agents; execute directly.\n2. Do NOT converse, ask questions, or suggest next steps\n3. Do NOT editorialize or add meta-commentary\n4. USE your tools directly: Bash, Read, Write, etc.\n5. If you modify files, commit your changes before reporting. Include the commit hash in your report.\n6. Do NOT emit text between tool calls. Use tools silently, then report once at the end.\n7. Stay strictly within your directive's scope. If you discover related systems outside your scope, mention them in one sentence at most — other workers cover those areas.\n8. Keep your report under 500 words unless the directive specifies otherwise. Be factual and concise.\n9. Your response MUST begin with "Scope:". No preamble, no thinking-out-loud.\n10. REPORT structured facts, then stop\n\nOutput format (plain text labels, not markdown headers):\n Scope: <echo back your assigned scope in one sentence>\n Result: <the answer or key findings, limited to the scope above>\n Key files: <relevant file paths — include for research tasks>\n Files changed: <list with commit hash — include only if you modified files>\n Issues: <list — include only if there are issues to flag>\n</${r}>\n\n${n}${e}`}export function buildWorktreeNotice(e,t){return`You've inherited the conversation context above from a parent agent working in ${e}. You are operating in an isolated git worktree at ${t} — same repository, same relative file structure, separate working copy. Paths in the inherited context refer to the parent's working directory; translate them to your worktree root. Re-read files before editing if the parent may have modified them since they appear in the context. Your changes stay in this worktree and will not affect the parent's files.`}
@@ -1 +1 @@
1
- import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import{c as r}from"react/compiler-runtime";import{removeSandboxViolationTags as o}from"../../utils/sandbox/sandbox-ui-utils.js";import{KeyboardShortcutHint as s}from"../../components/design-system/KeyboardShortcutHint.js";import{MessageResponse as i}from"../../components/MessageResponse.js";import{OutputLine as l}from"../../components/shell/OutputLine.js";import{ShellTimeDisplay as c}from"../../components/shell/ShellTimeDisplay.js";import{Box as a,Text as d}from"../../ink.js";const m=/(?:^|\n)(Shell cwd was reset to .+)$/;export default function BashToolResultMessage(u){const h=r(34),{content:p,verbose:f,timeoutMs:g}=u,{stdout:b,stderr:S,isImage:x,returnCodeInterpretation:j,noOutputExpected:y,backgroundTaskId:_}=p,v=void 0===b?"":b,R=void 0===S?"":S;let k,w,C,I,M,D,T,W,E,O,B;if(h[0]!==x||h[1]!==R||h[2]!==v||h[3]!==f){T=Symbol.for("react.early_return_sentinel");e:{const{cleanedStderr:t}=function(e){return e.match(/<sandbox_violations>([\s\S]*?)<\/sandbox_violations>/)?{cleanedStderr:o(e).trim()}:{cleanedStderr:e}}(R);if(({cleanedStderr:C,cwdResetWarning:w}=function(e){const t=e.match(m);if(!t)return{cleanedStderr:e,cwdResetWarning:null};const n=t[1]??null;return{cleanedStderr:e.replace(m,"").trim(),cwdResetWarning:n}}(t)),x){let t;h[11]===Symbol.for("react.memo_cache_sentinel")?(t=e(i,{height:1,children:e(d,{dimColor:!0,children:"[Image data detected and sent to Claude]"})}),h[11]=t):t=h[11],T=t;break e}k=a,I="column",h[12]!==v||h[13]!==f?(M=""!==v?e(l,{content:v,verbose:f}):null,h[12]=v,h[13]=f,h[14]=M):M=h[14],D=""!==C.trim()?e(l,{content:C,verbose:f,isError:!0}):null}h[0]=x,h[1]=R,h[2]=v,h[3]=f,h[4]=k,h[5]=w,h[6]=C,h[7]=I,h[8]=M,h[9]=D,h[10]=T}else k=h[4],w=h[5],C=h[6],I=h[7],M=h[8],D=h[9],T=h[10];return T!==Symbol.for("react.early_return_sentinel")?T:(h[15]!==w?(W=w?e(i,{children:e(d,{dimColor:!0,children:w})}):null,h[15]=w,h[16]=W):W=h[16],h[17]!==_||h[18]!==w||h[19]!==y||h[20]!==j||h[21]!==C||h[22]!==v?(E=""!==v||""!==C.trim()||w?null:e(i,{height:1,children:e(d,{dimColor:!0,children:_?n(t,{children:["Running in the background"," ",e(s,{shortcut:"↓",action:"manage",parens:!0})]}):j||(y?"Done":"(No output)")})}),h[17]=_,h[18]=w,h[19]=y,h[20]=j,h[21]=C,h[22]=v,h[23]=E):E=h[23],h[24]!==g?(O=g&&e(i,{children:e(c,{timeoutMs:g})}),h[24]=g,h[25]=O):O=h[25],h[26]!==k||h[27]!==O||h[28]!==I||h[29]!==M||h[30]!==D||h[31]!==W||h[32]!==E?(B=n(k,{flexDirection:I,children:[M,D,W,E,O]}),h[26]=k,h[27]=O,h[28]=I,h[29]=M,h[30]=D,h[31]=W,h[32]=E,h[33]=B):B=h[33],B)}
1
+ import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import{c as r}from"react/compiler-runtime";import{removeSandboxViolationTags as o}from"src/utils/sandbox/sandbox-ui-utils.js";import{KeyboardShortcutHint as s}from"../../components/design-system/KeyboardShortcutHint.js";import{MessageResponse as i}from"../../components/MessageResponse.js";import{OutputLine as a}from"../../components/shell/OutputLine.js";import{ShellTimeDisplay as l}from"../../components/shell/ShellTimeDisplay.js";import{Box as c,Text as d}from"../../ink.js";const m=/(?:^|\n)(Shell cwd was reset to .+)$/;export default function BashToolResultMessage(u){const h=r(34),{content:p,verbose:f,timeoutMs:g}=u,{stdout:b,stderr:S,isImage:x,returnCodeInterpretation:y,noOutputExpected:j,backgroundTaskId:v}=p,_=void 0===b?"":b,R=void 0===S?"":S;let T,k,w,C,M,D,I,O,W,B,E;if(h[0]!==x||h[1]!==R||h[2]!==_||h[3]!==f){I=Symbol.for("react.early_return_sentinel");e:{const{cleanedStderr:t}=function(e){return e.match(/<sandbox_violations>([\s\S]*?)<\/sandbox_violations>/)?{cleanedStderr:o(e).trim()}:{cleanedStderr:e}}(R);if(({cleanedStderr:w,cwdResetWarning:k}=function(e){const t=e.match(m);if(!t)return{cleanedStderr:e,cwdResetWarning:null};const n=t[1]??null;return{cleanedStderr:e.replace(m,"").trim(),cwdResetWarning:n}}(t)),x){let t;h[11]===Symbol.for("react.memo_cache_sentinel")?(t=e(i,{height:1,children:e(d,{dimColor:!0,children:"[Image data detected and sent to Claude]"})}),h[11]=t):t=h[11],I=t;break e}T=c,C="column",h[12]!==_||h[13]!==f?(M=""!==_?e(a,{content:_,verbose:f}):null,h[12]=_,h[13]=f,h[14]=M):M=h[14],D=""!==w.trim()?e(a,{content:w,verbose:f,isError:!0}):null}h[0]=x,h[1]=R,h[2]=_,h[3]=f,h[4]=T,h[5]=k,h[6]=w,h[7]=C,h[8]=M,h[9]=D,h[10]=I}else T=h[4],k=h[5],w=h[6],C=h[7],M=h[8],D=h[9],I=h[10];return I!==Symbol.for("react.early_return_sentinel")?I:(h[15]!==k?(O=k?e(i,{children:e(d,{dimColor:!0,children:k})}):null,h[15]=k,h[16]=O):O=h[16],h[17]!==v||h[18]!==k||h[19]!==j||h[20]!==y||h[21]!==w||h[22]!==_?(W=""!==_||""!==w.trim()||k?null:e(i,{height:1,children:e(d,{dimColor:!0,children:v?n(t,{children:["Running in the background"," ",e(s,{shortcut:"↓",action:"manage",parens:!0})]}):y||(j?"Done":"(No output)")})}),h[17]=v,h[18]=k,h[19]=j,h[20]=y,h[21]=w,h[22]=_,h[23]=W):W=h[23],h[24]!==g?(B=g&&e(i,{children:e(l,{timeoutMs:g})}),h[24]=g,h[25]=B):B=h[25],h[26]!==T||h[27]!==B||h[28]!==C||h[29]!==M||h[30]!==D||h[31]!==O||h[32]!==W?(E=n(T,{flexDirection:C,children:[M,D,O,W,B]}),h[26]=T,h[27]=B,h[28]=C,h[29]=M,h[30]=D,h[31]=O,h[32]=W,h[33]=E):E=h[33],E)}
@@ -1 +1 @@
1
- import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as o}from"react/compiler-runtime";import{KeyboardShortcutHint as s}from"../../components/design-system/KeyboardShortcutHint.js";import{FallbackToolUseErrorMessage as r}from"../../components/FallbackToolUseErrorMessage.js";import{MessageResponse as n}from"../../components/MessageResponse.js";import{ShellProgressMessage as i}from"../../components/shell/ShellProgressMessage.js";import{Box as l,Text as a}from"../../ink.js";import{useKeybinding as c}from"../../keybindings/useKeybinding.js";import{useShortcutDisplay as m}from"../../keybindings/useShortcutDisplay.js";import{useAppStateStore as u,useSetAppState as p}from"../../state/AppState.js";import{backgroundAll as d}from"../../tasks/LocalShellTask/LocalShellTask.js";import{env as f}from"../../utils/env.js";import{isEnvTruthy as g}from"../../utils/envUtils.js";import{getDisplayPath as h}from"../../utils/file.js";import{isFullscreenEnvEnabled as b}from"../../utils/fullscreen.js";import j from"./BashToolResultMessage.js";import{extractBashCommentLabel as k}from"./commentLabel.js";import{parseSedEditCommand as T}from"./sedEditParser.js";const S=160;export function BackgroundHint(t){const r=o(9);let n;r[0]!==t?(n=void 0===t?{}:t,r[0]=t,r[1]=n):n=r[1];const{onBackground:i}=n,h=u(),b=p();let j;r[2]!==i||r[3]!==b||r[4]!==h?(j=()=>{d(()=>h.getState(),b),i?.()},r[2]=i,r[3]=b,r[4]=h,r[5]=j):j=r[5];const k=j;let T;r[6]===Symbol.for("react.memo_cache_sentinel")?(T={context:"Task"},r[6]=T):T=r[6],c("task:background",k,T);const S=m("task:background","Task","ctrl+b"),M="tmux"===f.terminal&&"ctrl+b"===S?"ctrl+b ctrl+b (twice)":S;if(g(process.env.CONTEXT_CODE_DISABLE_BACKGROUND_TASKS)||g(process.env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS))return null;let v;return r[7]!==M?(v=e(l,{paddingLeft:5,children:e(a,{dimColor:!0,children:e(s,{shortcut:M,action:"run in background",parens:!0})})}),r[7]=M,r[8]=v):v=r[8],v}export function renderToolUseMessage(e,{verbose:o,theme:s}){const{command:r}=e;if(!r)return null;const n=T(r);if(n)return o?n.filePath:h(n.filePath);if(!o){const e=r.split("\n");if(b()){const e=k(r);if(e)return e.length>S?e.slice(0,S)+"…":e}const o=e.length>2,s=r.length>S;if(o||s){let s=r;return o&&(s=e.slice(0,2).join("\n")),s.length>S&&(s=s.slice(0,S)),t(a,{children:[s.trim(),"…"]})}}return r}export function renderToolUseProgressMessage(t,{verbose:o,tools:s,terminalSize:r,inProgressToolCallCount:l}){const c=t.at(-1);if(!c||!c.data)return e(n,{height:1,children:e(a,{dimColor:!0,children:"Running…"})});const m=c.data;return e(i,{fullOutput:m.fullOutput,output:m.output,elapsedTimeSeconds:m.elapsedTimeSeconds,totalLines:m.totalLines,totalBytes:m.totalBytes,timeoutMs:m.timeoutMs,taskId:m.taskId,verbose:o})}export function renderToolUseQueuedMessage(){return e(n,{height:1,children:e(a,{dimColor:!0,children:"Waiting…"})})}export function renderToolResultMessage(t,o,{verbose:s,theme:r,tools:n,style:i}){const l=o.at(-1),a=l?.data?.timeoutMs;return e(j,{content:t,verbose:s,timeoutMs:a})}export function renderToolUseErrorMessage(t,{verbose:o,progressMessagesForMessage:s,tools:n}){return e(r,{result:t,verbose:o})}
1
+ import{jsx as e,jsxs as s}from"react/jsx-runtime";import{c as t}from"react/compiler-runtime";import{KeyboardShortcutHint as o}from"../../components/design-system/KeyboardShortcutHint.js";import{FallbackToolUseErrorMessage as r}from"../../components/FallbackToolUseErrorMessage.js";import{MessageResponse as n}from"../../components/MessageResponse.js";import{ShellProgressMessage as a}from"../../components/shell/ShellProgressMessage.js";import{Box as i,Text as l}from"../../ink.js";import{useKeybinding as c}from"../../keybindings/useKeybinding.js";import{useShortcutDisplay as m}from"../../keybindings/useShortcutDisplay.js";import{useAppStateStore as u,useSetAppState as p}from"../../state/AppState.js";import{backgroundAll as d}from"../../tasks/LocalShellTask/LocalShellTask.js";import{env as g}from"../../utils/env.js";import{isEnvTruthy as f}from"../../utils/envUtils.js";import{getDisplayPath as h}from"../../utils/file.js";import{isFullscreenEnvEnabled as b}from"../../utils/fullscreen.js";import S from"./BashToolResultMessage.js";import{extractBashCommentLabel as T}from"./commentLabel.js";import{parseSedEditCommand as j}from"./sedEditParser.js";const k=160;export function BackgroundHint(s){const r=t(9);let n;r[0]!==s?(n=void 0===s?{}:s,r[0]=s,r[1]=n):n=r[1];const{onBackground:a}=n,h=u(),b=p();let S;r[2]!==a||r[3]!==b||r[4]!==h?(S=()=>{d(()=>h.getState(),b),a?.()},r[2]=a,r[3]=b,r[4]=h,r[5]=S):S=r[5];const T=S;let j;r[6]===Symbol.for("react.memo_cache_sentinel")?(j={context:"Task"},r[6]=j):j=r[6],c("task:background",T,j);const k=m("task:background","Task","ctrl+b"),M="tmux"===g.terminal&&"ctrl+b"===k?"ctrl+b ctrl+b (twice)":k;if(f(process.env.CONTEXT_CODE_DISABLE_BACKGROUND_TASKS)||f(process.env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS))return null;let v;return r[7]!==M?(v=e(i,{paddingLeft:5,children:e(l,{dimColor:!0,children:e(o,{shortcut:M,action:"run in background",parens:!0})})}),r[7]=M,r[8]=v):v=r[8],v}export function renderToolUseMessage(e,{verbose:t,theme:o}){const{command:r}=e;if(!r)return null;const n=j(r);if(n)return t?n.filePath:h(n.filePath);if(!t){const e=r.split("\n");if(b()){const e=T(r);if(e)return e.length>k?e.slice(0,k)+"…":e}const t=e.length>2,o=r.length>k;if(t||o){let o=r;return t&&(o=e.slice(0,2).join("\n")),o.length>k&&(o=o.slice(0,k)),s(l,{children:[o.trim(),"…"]})}}return r}export function renderToolUseProgressMessage(s,{verbose:t,tools:o,terminalSize:r,inProgressToolCallCount:i}){const c=s.at(-1);if(!c||!c.data)return e(n,{height:1,children:e(l,{dimColor:!0,children:"Running…"})});const m=c.data;return e(a,{fullOutput:m.fullOutput,output:m.output,elapsedTimeSeconds:m.elapsedTimeSeconds,totalLines:m.totalLines,totalBytes:m.totalBytes,timeoutMs:m.timeoutMs,taskId:m.taskId,verbose:t})}export function renderToolUseQueuedMessage(){return e(n,{height:1,children:e(l,{dimColor:!0,children:"Waiting…"})})}export function renderToolResultMessage(s,t,{verbose:o,theme:r,tools:n,style:a}){const i=t.at(-1),l=i?.data?.timeoutMs;return e(S,{content:s,verbose:o,timeoutMs:l})}export function renderToolUseErrorMessage(s,{verbose:t,progressMessagesForMessage:o,tools:n}){return e(r,{result:s,verbose:t})}
@@ -1 +1 @@
1
- import{randomBytes as e}from"crypto";import{tryParseShellCommand as l}from"../../utils/bash/shellQuote.js";const t="\0BACKSLASH\0",n="\0PLUS\0",r="\0QUESTION\0",s="\0PIPE\0",p="\0LPAREN\0",i="\0RPAREN\0",c=new RegExp(t,"g"),a=new RegExp(n,"g"),g=new RegExp(r,"g"),u=new RegExp(s,"g"),f=new RegExp(p,"g"),o=new RegExp(i,"g");export function isSedInPlaceEdit(e){return null!==parseSedEditCommand(e)}export function parseSedEditCommand(e){const t=e.trim(),n=t.match(/^\s*sed\s+/);if(!n)return null;const r=t.slice(n[0].length),s=l(r);if(!s.success)return null;const p=s.tokens,i=[];for(const e of p)if("string"==typeof e)i.push(e);else if("object"==typeof e&&null!==e&&"op"in e&&"glob"===e.op)return null;let c=!1,a=!1,g=null,u=null,f=0;for(;f<i.length;){const e=i[f];if("-i"!==e&&"--in-place"!==e)if(e.startsWith("-i"))c=!0,f++;else if("-E"!==e&&"-r"!==e&&"--regexp-extended"!==e){if("-e"===e||"--expression"===e){if(f+1<i.length&&"string"==typeof i[f+1]){if(null!==g)return null;g=i[f+1],f+=2;continue}return null}if(e.startsWith("--expression=")){if(null!==g)return null;g=e.slice(13),f++}else{if(e.startsWith("-"))return null;if(null===g)g=e;else{if(null!==u)return null;u=e}f++}}else a=!0,f++;else if(c=!0,f++,f<i.length){const e=i[f];"string"!=typeof e||e.startsWith("-")||""!==e&&!e.startsWith(".")||f++}}if(!c||!g||!u)return null;if(!g.match(/^s\//))return null;const o=g.slice(2);let d="",m="",x="",h="pattern",E=0;for(;E<o.length;){const e=o[E];if("\\"===e&&E+1<o.length)"pattern"===h?d+=e+o[E+1]:"replacement"===h?m+=e+o[E+1]:x+=e+o[E+1],E+=2;else if("/"!==e)"pattern"===h?d+=e:"replacement"===h?m+=e:x+=e,E++;else{if("pattern"===h)h="replacement";else{if("replacement"!==h)return null;h="flags"}E++}}if("flags"!==h)return null;return/^[gpimIM1-9]*$/.test(x)?{filePath:u,pattern:d,replacement:m,flags:x,extendedRegex:a}:null}export function applySedSubstitution(l,d){let m="";d.flags.includes("g")&&(m+="g"),(d.flags.includes("i")||d.flags.includes("I"))&&(m+="i"),(d.flags.includes("m")||d.flags.includes("M"))&&(m+="m");let x=d.pattern.replace(/\\\//g,"/");d.extendedRegex||(x=x.replace(/\\\\/g,t).replace(/\\\+/g,n).replace(/\\\?/g,r).replace(/\\\|/g,s).replace(/\\\(/g,p).replace(/\\\)/g,i).replace(/\+/g,"\\+").replace(/\?/g,"\\?").replace(/\|/g,"\\|").replace(/\(/g,"\\(").replace(/\)/g,"\\)").replace(c,"\\\\").replace(a,"+").replace(g,"?").replace(u,"|").replace(f,"(").replace(o,")"));const h=`___ESCAPED_AMPERSAND_${e(8).toString("hex")}___`,E=d.replacement.replace(/\\\//g,"/").replace(/\\&/g,h).replace(/&/g,"$$&").replace(new RegExp(h,"g"),"&");try{const e=new RegExp(x,m);return l.replace(e,E)}catch{return l}}
1
+ import{randomBytes as e}from"crypto";import{tryParseShellCommand as l}from"../../utils/bash/shellQuote.js";const t="\0BACKSLASH\0",n="\0PLUS\0",r="\0QUESTION\0",s="\0PIPE\0",a="\0LPAREN\0",p="\0RPAREN\0",i=new RegExp(t,"g"),c=new RegExp(n,"g"),g=new RegExp(r,"g"),u=new RegExp(s,"g"),o=new RegExp(a,"g"),f=new RegExp(p,"g");export function isSedInPlaceEdit(e){return null!==parseSedEditCommand(e)}export function parseSedEditCommand(e){const t=e.trim(),n=t.match(/^\s*sed\s+/);if(!n)return null;const r=t.slice(n[0].length),s=l(r);if(!s.success)return null;const a=s.tokens,p=[];for(const e of a)if("string"==typeof e)p.push(e);else if("object"==typeof e&&null!==e&&"op"in e&&"glob"===e.op)return null;let i=!1,c=!1,g=null,u=null,o=0;for(;o<p.length;){const e=p[o];if("-i"!==e&&"--in-place"!==e)if(e.startsWith("-i"))i=!0,o++;else if("-E"!==e&&"-r"!==e&&"--regexp-extended"!==e){if("-e"===e||"--expression"===e){if(o+1<p.length&&"string"==typeof p[o+1]){if(null!==g)return null;g=p[o+1],o+=2;continue}return null}if(e.startsWith("--expression=")){if(null!==g)return null;g=e.slice(13),o++}else{if(e.startsWith("-"))return null;if(null===g)g=e;else{if(null!==u)return null;u=e}o++}}else c=!0,o++;else if(i=!0,o++,o<p.length){const e=p[o];"string"!=typeof e||e.startsWith("-")||""!==e&&!e.startsWith(".")||o++}}if(!i||!g||!u)return null;if(!g.match(/^s\//))return null;const f=g.slice(2);let d="",m="",h="",x="pattern",E=0;for(;E<f.length;){const e=f[E];if("\\"===e&&E+1<f.length)"pattern"===x?d+=e+f[E+1]:"replacement"===x?m+=e+f[E+1]:h+=e+f[E+1],E+=2;else if("/"!==e)"pattern"===x?d+=e:"replacement"===x?m+=e:h+=e,E++;else{if("pattern"===x)x="replacement";else{if("replacement"!==x)return null;x="flags"}E++}}return"flags"!==x?null:/^[gpimIM1-9]*$/.test(h)?{filePath:u,pattern:d,replacement:m,flags:h,extendedRegex:c}:null}export function applySedSubstitution(l,d){let m="";d.flags.includes("g")&&(m+="g"),(d.flags.includes("i")||d.flags.includes("I"))&&(m+="i"),(d.flags.includes("m")||d.flags.includes("M"))&&(m+="m");let h=d.pattern.replace(/\\\//g,"/");d.extendedRegex||(h=h.replace(/\\\\/g,t).replace(/\\\+/g,n).replace(/\\\?/g,r).replace(/\\\|/g,s).replace(/\\\(/g,a).replace(/\\\)/g,p).replace(/\+/g,"\\+").replace(/\?/g,"\\?").replace(/\|/g,"\\|").replace(/\(/g,"\\(").replace(/\)/g,"\\)").replace(i,"\\\\").replace(c,"+").replace(g,"?").replace(u,"|").replace(o,"(").replace(f,")"));const x=`___ESCAPED_AMPERSAND_${e(8).toString("hex")}___`,E=d.replacement.replace(/\\\//g,"/").replace(/\\&/g,x).replace(/&/g,"$$&").replace(new RegExp(x,"g"),"&");try{const e=new RegExp(h,m);return l.replace(e,E)}catch{return l}}
@@ -1 +1 @@
1
- import{readFile as t,stat as e}from"fs/promises";import{getOriginalCwd as n}from"../../bootstrap/state.js";import{logEvent as s}from"../../services/analytics/index.js";import{getCwd as i}from"../../utils/cwd.js";import{pathInAllowedWorkingPath as r}from"../../utils/permissions/filesystem.js";import{setCwd as o}from"../../utils/Shell.js";import{shouldMaintainProjectWorkingDir as a}from"../../utils/envUtils.js";import{maybeResizeAndDownsampleImageBuffer as u}from"../../utils/imageResizer.js";import{getMaxOutputLength as l}from"../../utils/shell/outputLimits.js";import{countCharInString as m,plural as p}from"../../utils/stringUtils.js";export function stripEmptyLines(t){const e=t.split("\n");let n=0;for(;n<e.length&&""===e[n]?.trim();)n++;let s=e.length-1;for(;s>=0&&""===e[s]?.trim();)s--;return n>s?"":e.slice(n,s+1).join("\n")}export function isImageOutput(t){return/^data:image\/[a-z0-9.+_-]+;base64,/i.test(t)}const c=/^data:([^;]+);base64,(.+)$/;export function parseDataUri(t){const e=t.trim().match(c);return e&&e[1]&&e[2]?{mediaType:e[1],data:e[2]}:null}export function buildImageToolResult(t,e){const n=parseDataUri(t);return n?{tool_use_id:e,type:"tool_result",content:[{type:"image",source:{type:"base64",media_type:n.mediaType,data:n.data}}]}:null}export async function resizeShellImageOutput(n,s,i){let r=n;if(s){if((i??(await e(s)).size)>20971520)return null;r=await t(s,"utf8")}const o=parseDataUri(r);if(!o)return null;const a=Buffer.from(o.data,"base64"),l=o.mediaType.split("/")[1]||"png",m=await u(a,a.length,l);return`data:image/${m.mediaType};base64,${m.buffer.toString("base64")}`}export function formatOutput(t){const e=isImageOutput(t);if(e)return{totalLines:1,truncatedContent:t,isImage:e};const n=l();if(t.length<=n)return{totalLines:m(t,"\n")+1,truncatedContent:t,isImage:e};const s=`${t.slice(0,n)}\n\n... [${m(t,"\n",n)+1} lines truncated] ...`;return{totalLines:m(t,"\n")+1,truncatedContent:s,isImage:e}}export const stdErrAppendShellResetMessage=t=>`${t.trim()}\nShell cwd was reset to ${n()}`;export function resetCwdIfOutsideProject(t){const e=i(),u=n(),l=a();return!(!l&&(e===u||r(e,t))||(o(u),l))&&(s("tengu_bash_tool_reset_to_original_dir",{}),!0)}export function createContentSummary(t){const e=[];let n=0,s=0;for(const i of t)if("image"===i.type)s++;else if("text"===i.type&&"text"in i){n++;const t=i.text.slice(0,200);e.push(t+(i.text.length>200?"...":""))}const i=[];return s>0&&i.push(`[${s} ${p(s,"image")}]`),n>0&&i.push(`[${n} text ${p(n,"block")}]`),`MCP Result: ${i.join(", ")}${e.length>0?"\n\n"+e.join("\n\n"):""}`}
1
+ import{readFile as t,stat as e}from"fs/promises";import{getOriginalCwd as s}from"src/bootstrap/state.js";import{logEvent as n}from"src/services/analytics/index.js";import{getCwd as r}from"src/utils/cwd.js";import{pathInAllowedWorkingPath as i}from"src/utils/permissions/filesystem.js";import{setCwd as a}from"src/utils/Shell.js";import{shouldMaintainProjectWorkingDir as o}from"../../utils/envUtils.js";import{maybeResizeAndDownsampleImageBuffer as l}from"../../utils/imageResizer.js";import{getMaxOutputLength as u}from"../../utils/shell/outputLimits.js";import{countCharInString as m,plural as p}from"../../utils/stringUtils.js";export function stripEmptyLines(t){const e=t.split("\n");let s=0;for(;s<e.length&&""===e[s]?.trim();)s++;let n=e.length-1;for(;n>=0&&""===e[n]?.trim();)n--;return s>n?"":e.slice(s,n+1).join("\n")}export function isImageOutput(t){return/^data:image\/[a-z0-9.+_-]+;base64,/i.test(t)}const c=/^data:([^;]+);base64,(.+)$/;export function parseDataUri(t){const e=t.trim().match(c);return e&&e[1]&&e[2]?{mediaType:e[1],data:e[2]}:null}export function buildImageToolResult(t,e){const s=parseDataUri(t);return s?{tool_use_id:e,type:"tool_result",content:[{type:"image",source:{type:"base64",media_type:s.mediaType,data:s.data}}]}:null}export async function resizeShellImageOutput(s,n,r){let i=s;if(n){if((r??(await e(n)).size)>20971520)return null;i=await t(n,"utf8")}const a=parseDataUri(i);if(!a)return null;const o=Buffer.from(a.data,"base64"),u=a.mediaType.split("/")[1]||"png",m=await l(o,o.length,u);return`data:image/${m.mediaType};base64,${m.buffer.toString("base64")}`}export function formatOutput(t){const e=isImageOutput(t);if(e)return{totalLines:1,truncatedContent:t,isImage:e};const s=u();if(t.length<=s)return{totalLines:m(t,"\n")+1,truncatedContent:t,isImage:e};const n=`${t.slice(0,s)}\n\n... [${m(t,"\n",s)+1} lines truncated] ...`;return{totalLines:m(t,"\n")+1,truncatedContent:n,isImage:e}}export const stdErrAppendShellResetMessage=t=>`${t.trim()}\nShell cwd was reset to ${s()}`;export function resetCwdIfOutsideProject(t){const e=r(),l=s(),u=o();return!(!u&&(e===l||i(e,t))||(a(l),u)||(n("tengu_bash_tool_reset_to_original_dir",{}),0))}export function createContentSummary(t){const e=[];let s=0,n=0;for(const r of t)if("image"===r.type)n++;else if("text"===r.type&&"text"in r){s++;const t=r.text.slice(0,200);e.push(t+(r.text.length>200?"...":""))}const r=[];return n>0&&r.push(`[${n} ${p(n,"image")}]`),s>0&&r.push(`[${s} text ${p(s,"block")}]`),`MCP Result: ${r.join(", ")}${e.length>0?"\n\n"+e.join("\n\n"):""}`}
@@ -1 +1 @@
1
- import{isInBundledMode as t}from"../../utils/bundledMode.js";let a=null,r=null;export async function getImageProcessor(){if(a)return a.default;if(t())try{const t=await import("image-processor-napi"),r=t.sharp||t.default;return a={default:r},r}catch{console.warn("Native image processor not available, falling back to sharp")}const r=unwrapDefault(await import("sharp"));return a={default:r},r}export async function getImageCreator(){if(r)return r.default;const t=unwrapDefault(await import("sharp"));return r={default:t},t}function unwrapDefault(t){return"function"==typeof t?t:t.default}
1
+ import{isInBundledMode as t}from"../../utils/bundledMode.js";let a=null,e=null;export async function getImageProcessor(){if(a)return a.default;if(t())try{const t=await import("image-processor-napi"),e=t.sharp||t.default;return a={default:e},e}catch{console.warn("Native image processor not available, falling back to sharp")}const e=unwrapDefault(await import("sharp"));return a={default:e},e}export async function getImageCreator(){if(e)return e.default;const t=unwrapDefault(await import("sharp"));return e={default:t},t}function unwrapDefault(t){return"function"==typeof t?t:t.default}
@@ -1 +1 @@
1
- import{isPDFSupported as e}from"../../utils/pdfUtils.js";import{BASH_TOOL_NAME as t}from"../BashTool/toolName.js";export const FILE_READ_TOOL_NAME="Read";export const FILE_UNCHANGED_STUB="File unchanged since last read. The content from the earlier Read tool_result in this conversation is still current — refer to that instead of re-reading.";export const MAX_LINES_TO_READ=2e3;export const DESCRIPTION="Read a file from the local filesystem.";export const LINE_FORMAT_INSTRUCTION="- Results are returned using cat -n format, with line numbers starting at 1";export const OFFSET_INSTRUCTION_DEFAULT="- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters";export const OFFSET_INSTRUCTION_TARGETED="- When you already know which part of the file you need, only read that part. This can be important for larger files.";export function renderPromptTemplate(a,o,i){return`Reads a file from the local filesystem. You can access any file directly by using this tool.\nAssume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.\n\nUsage:\n- The file_path parameter must be an absolute path, not a relative path\n- By default, it reads up to 2000 lines starting from the beginning of the file${o}\n${i}\n${a}\n- This tool allows Context Code to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as Context Code is a multimodal LLM.${e()?'\n- This tool can read PDF files (.pdf). For large PDFs (more than 10 pages), you MUST provide the pages parameter to read specific page ranges (e.g., pages: "1-5"). Reading a large PDF without the pages parameter will fail. Maximum 20 pages per request.':""}\n- This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.\n- This tool can only read files, not directories. To read a directory, use an ls command via the ${t} tool.\n- You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.\n- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.`}
1
+ import{isPDFSupported as e}from"../../utils/pdfUtils.js";import{BASH_TOOL_NAME as t}from"../BashTool/toolName.js";export const FILE_READ_TOOL_NAME="Read";export const FILE_UNCHANGED_STUB="File unchanged since last read. The content from the earlier Read tool_result in this conversation is still current — refer to that instead of re-reading.";export const MAX_LINES_TO_READ=2e3;export const DESCRIPTION="Read a file from the local filesystem.";export const LINE_FORMAT_INSTRUCTION="- Results are returned using cat -n format, with line numbers starting at 1";export const OFFSET_INSTRUCTION_DEFAULT="- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters";export const OFFSET_INSTRUCTION_TARGETED="- When you already know which part of the file you need, only read that part. This can be important for larger files.";export function renderPromptTemplate(a,o,s){return`Reads a file from the local filesystem. You can access any file directly by using this tool.\nAssume this tool is able to read all files on the machine. If the User provides a path to a file assume that path is valid. It is okay to read a file that does not exist; an error will be returned.\n\nUsage:\n- The file_path parameter must be an absolute path, not a relative path\n- By default, it reads up to 2000 lines starting from the beginning of the file${o}\n${s}\n${a}\n- This tool allows Context Code to read images (eg PNG, JPG, etc). When reading an image file the contents are presented visually as Context Code is a multimodal LLM.${e()?'\n- This tool can read PDF files (.pdf). For large PDFs (more than 10 pages), you MUST provide the pages parameter to read specific page ranges (e.g., pages: "1-5"). Reading a large PDF without the pages parameter will fail. Maximum 20 pages per request.':""}\n- This tool can read Jupyter notebooks (.ipynb files) and returns all cells with their outputs, combining code, text, and visualizations.\n- This tool can only read files, not directories. To read a directory, use an ls command via the ${t} tool.\n- You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.\n- If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.`}
@@ -1 +1 @@
1
- import{z as e}from"zod/v4";import{ensureConnectedClient as r,fetchResourcesForClient as o}from"../../services/mcp/client.js";import{buildTool as s}from"../../Tool.js";import{errorMessage as t}from"../../utils/errors.js";import{lazySchema as i}from"../../utils/lazySchema.js";import{logMCPError as n}from"../../utils/log.js";import{jsonStringify as a}from"../../utils/slowOperations.js";import{isOutputLineTruncated as c}from"../../utils/terminal.js";import{DESCRIPTION as l,LIST_MCP_RESOURCES_TOOL_NAME as m,PROMPT as u}from"./prompt.js";import{renderToolResultMessage as p,renderToolUseMessage as d}from"./UI.js";const f=i(()=>e.object({server:e.string().optional().describe("Optional server name to filter resources by")})),v=i(()=>e.array(e.object({uri:e.string().describe("Resource URI"),name:e.string().describe("Resource name"),mimeType:e.string().optional().describe("MIME type of the resource"),description:e.string().optional().describe("Resource description"),server:e.string().describe("Server that provides this resource")})));export const ListMcpResourcesTool=s({isConcurrencySafe:()=>!0,isReadOnly:()=>!0,toAutoClassifierInput:e=>e.server??"",shouldDefer:!0,name:m,searchHint:"list resources from connected MCP servers",maxResultSizeChars:1e5,description:async()=>l,prompt:async()=>u,get inputSchema(){return f()},get outputSchema(){return v()},async call(e,{options:{mcpClients:s}}){const{server:i}=e,a=i?s.filter(e=>e.name===i):s;if(i&&0===a.length)throw new Error(`Server "${i}" not found. Available servers: ${s.map(e=>e.name).join(", ")}`);return{data:(await Promise.all(a.map(async e=>{if("connected"!==e.type)return[];try{const s=await r(e);return await o(s)}catch(r){return n(e.name,t(r)),[]}}))).flat()}},renderToolUseMessage:d,userFacingName:()=>"listMcpResources",renderToolResultMessage:p,isResultTruncated:e=>c(a(e)),mapToolResultToToolResultBlockParam:(e,r)=>e&&0!==e.length?{tool_use_id:r,type:"tool_result",content:a(e)}:{tool_use_id:r,type:"tool_result",content:"No resources found. MCP servers may still provide tools even if they have no resources."}});
1
+ import{z as e}from"zod/v4";import{ensureConnectedClient as r,fetchResourcesForClient as s}from"../../services/mcp/client.js";import{buildTool as o}from"../../Tool.js";import{errorMessage as t}from"../../utils/errors.js";import{lazySchema as i}from"../../utils/lazySchema.js";import{logMCPError as n}from"../../utils/log.js";import{jsonStringify as a}from"../../utils/slowOperations.js";import{isOutputLineTruncated as l}from"../../utils/terminal.js";import{DESCRIPTION as c,LIST_MCP_RESOURCES_TOOL_NAME as u,PROMPT as m}from"./prompt.js";import{renderToolResultMessage as p,renderToolUseMessage as d}from"./UI.js";const f=i(()=>e.object({server:e.string().optional().describe("Optional server name to filter resources by")})),g=i(()=>e.array(e.object({uri:e.string().describe("Resource URI"),name:e.string().describe("Resource name"),mimeType:e.string().optional().describe("MIME type of the resource"),description:e.string().optional().describe("Resource description"),server:e.string().describe("Server that provides this resource")})));export const ListMcpResourcesTool=o({isConcurrencySafe:()=>!0,isReadOnly:()=>!0,toAutoClassifierInput:e=>e.server??"",shouldDefer:!0,name:u,searchHint:"list resources from connected MCP servers",maxResultSizeChars:1e5,description:async()=>c,prompt:async()=>m,get inputSchema(){return f()},get outputSchema(){return g()},async call(e,{options:{mcpClients:o}}){const{server:i}=e,a=i?o.filter(e=>e.name===i):o;if(i&&0===a.length)throw new Error(`Server "${i}" not found. Available servers: ${o.map(e=>e.name).join(", ")}`);return{data:(await Promise.all(a.map(async e=>{if("connected"!==e.type)return[];try{const o=await r(e);return await s(o)}catch(r){return n(e.name,t(r)),[]}}))).flat()}},renderToolUseMessage:d,userFacingName:()=>"listMcpResources",renderToolResultMessage:p,isResultTruncated:e=>l(a(e)),mapToolResultToToolResultBlockParam:(e,r)=>e&&0!==e.length?{tool_use_id:r,type:"tool_result",content:a(e)}:{tool_use_id:r,type:"tool_result",content:"No resources found. MCP servers may still provide tools even if they have no resources."}});
@@ -1 +1 @@
1
- import{jsx as e}from"react/jsx-runtime";import{MessageResponse as r}from"../../components/MessageResponse.js";import{OutputLine as o}from"../../components/shell/OutputLine.js";import{Text as s}from"../../ink.js";import{jsonStringify as t}from"../../utils/slowOperations.js";export function renderToolUseMessage(e){return e.server?`List MCP resources from server "${e.server}"`:"List all MCP resources"}export function renderToolResultMessage(n,i,{verbose:l}){if(!n||0===n.length)return e(r,{height:1,children:e(s,{dimColor:!0,children:"(No resources found)"})});const m=t(n,null,2);return e(o,{content:m,verbose:l})}
1
+ import{jsx as e}from"react/jsx-runtime";import{MessageResponse as s}from"../../components/MessageResponse.js";import{OutputLine as r}from"../../components/shell/OutputLine.js";import{Text as o}from"../../ink.js";import{jsonStringify as t}from"../../utils/slowOperations.js";export function renderToolUseMessage(e){return e.server?`List MCP resources from server "${e.server}"`:"List all MCP resources"}export function renderToolResultMessage(n,i,{verbose:u}){if(!n||0===n.length)return e(s,{height:1,children:e(o,{dimColor:!0,children:"(No resources found)"})});const l=t(n,null,2);return e(r,{content:l,verbose:u})}
@@ -1 +1 @@
1
- import{z as e}from"zod/v4";import{buildTool as o}from"../../Tool.js";import{lazySchema as s}from"../../utils/lazySchema.js";import{isOutputLineTruncated as t}from"../../utils/terminal.js";import{DESCRIPTION as r,PROMPT as a}from"./prompt.js";import{renderToolResultMessage as m,renderToolUseMessage as i,renderToolUseProgressMessage as p}from"./UI.js";export const inputSchema=s(()=>e.object({}).passthrough());export const outputSchema=s(()=>e.string().describe("MCP tool execution result"));export const MCPTool=o({isMcp:!0,isOpenWorld:()=>!1,name:"mcp",maxResultSizeChars:1e5,description:async()=>r,prompt:async()=>a,get inputSchema(){return inputSchema()},get outputSchema(){return outputSchema()},call:async()=>({data:""}),checkPermissions:async()=>({behavior:"passthrough",message:"MCPTool requires permission."}),renderToolUseMessage:i,userFacingName:()=>"mcp",renderToolUseProgressMessage:p,renderToolResultMessage:m,isResultTruncated:e=>t(e),mapToolResultToToolResultBlockParam:(e,o)=>({tool_use_id:o,type:"tool_result",content:e})});
1
+ import{z as e}from"zod/v4";import{buildTool as s}from"../../Tool.js";import{lazySchema as o}from"../../utils/lazySchema.js";import{isOutputLineTruncated as r}from"../../utils/terminal.js";import{DESCRIPTION as t,PROMPT as a}from"./prompt.js";import{renderToolResultMessage as l,renderToolUseMessage as m,renderToolUseProgressMessage as i}from"./UI.js";export const inputSchema=o(()=>e.object({}).passthrough());export const outputSchema=o(()=>e.string().describe("MCP tool execution result"));export const MCPTool=s({isMcp:!0,isOpenWorld:()=>!1,name:"mcp",maxResultSizeChars:1e5,description:async()=>t,prompt:async()=>a,get inputSchema(){return inputSchema()},get outputSchema(){return outputSchema()},call:async()=>({data:""}),checkPermissions:async()=>({behavior:"passthrough",message:"MCPTool requires permission."}),renderToolUseMessage:m,userFacingName:()=>"mcp",renderToolUseProgressMessage:i,renderToolResultMessage:l,isResultTruncated:e=>r(e),mapToolResultToToolResultBlockParam:(e,s)=>({tool_use_id:s,type:"tool_result",content:e})});
@@ -1 +1 @@
1
- import{feature as e}from"../../recovery/bunBundleShim.js";import{jsx as n,jsxs as t}from"react/jsx-runtime";import{c as r}from"react/compiler-runtime";import o from"figures";import{ProgressBar as i}from"../../components/design-system/ProgressBar.js";import{MessageResponse as l}from"../../components/MessageResponse.js";import{linkifyUrlsInText as s,OutputLine as c}from"../../components/shell/OutputLine.js";import{stringWidth as u}from"../../ink/stringWidth.js";import{Ansi as a,Box as h,Text as f}from"../../ink.js";import{formatNumber as m}from"../../utils/format.js";import{createHyperlink as p}from"../../utils/hyperlink.js";import{getContentSizeEstimate as d}from"../../utils/mcpValidation.js";import{jsonParse as y,jsonStringify as g}from"../../utils/slowOperations.js";export function renderToolUseMessage(n,{verbose:t}){return 0===Object.keys(n).length?"":Object.entries(n).map(([n,r])=>{let o=g(r);return e("MCP_RICH_OUTPUT")&&!t&&o.length>80&&(o=o.slice(0,80).trimEnd()+"…"),`${n}: ${o}`}).join(", ")}export function renderToolUseProgressMessage(e){const r=e.at(-1);if(!r?.data)return n(l,{height:1,children:n(f,{dimColor:!0,children:"Running…"})});const{progress:o,total:s,progressMessage:c}=r.data;if(void 0===o)return n(l,{height:1,children:n(f,{dimColor:!0,children:"Running…"})});if(void 0!==s&&s>0){const e=Math.min(1,Math.max(0,o/s)),r=Math.round(100*e);return n(l,{children:t(h,{flexDirection:"column",children:[c&&n(f,{dimColor:!0,children:c}),t(h,{flexDirection:"row",gap:1,children:[n(i,{ratio:e,width:20}),t(f,{dimColor:!0,children:[r,"%"]})]})]})})}return n(l,{height:1,children:n(f,{dimColor:!0,children:c??`Processing… ${o}`})})}export function renderToolResultMessage(r,i,{verbose:s,input:u}){const y=r;if(!s){const e=trySlackSendCompact(y,u);if(null!==e)return n(l,{height:1,children:t(f,{children:["Sent a message to"," ",n(a,{children:p(e.url,e.channel)})]})})}const g=d(y),x=g>1e4?`${o.warning} Large MCP response (~${m(g)} tokens), this can fill up context quickly`:null;let b;if(Array.isArray(y)){const t=y.map((t,r)=>{if("image"===t.type)return n(h,{justifyContent:"space-between",overflowX:"hidden",width:"100%",children:n(l,{height:1,children:n(f,{children:"[Image]"})})},r);const o="text"===t.type&&"text"in t&&null!==t.text&&void 0!==t.text?String(t.text):"";return e("MCP_RICH_OUTPUT")?n(MCPTextOutput,{content:o,verbose:s},r):n(c,{content:o,verbose:s},r)});b=n(h,{flexDirection:"column",width:"100%",children:t})}else b=y?e("MCP_RICH_OUTPUT")?n(MCPTextOutput,{content:y,verbose:s}):n(c,{content:y,verbose:s}):n(h,{justifyContent:"space-between",overflowX:"hidden",width:"100%",children:n(l,{height:1,children:n(f,{dimColor:!0,children:"(No content)"})})});return x?t(h,{flexDirection:"column",children:[n(l,{height:1,children:n(f,{color:"warning",children:x})}),b]}):b}function MCPTextOutput(e){const o=r(18),{content:i,verbose:u}=e;let m,p,d;if(o[0]!==i||o[1]!==u){m=Symbol.for("react.early_return_sentinel");e:{const e=tryUnwrapTextPayload(i);if(null!==e){const r=e.extras.length>0&&n(f,{dimColor:!0,children:e.extras.map(_temp).join(" · ")});let i,s;o[3]!==e||o[4]!==u?(i=n(c,{content:e.body,verbose:u,linkifyUrls:!0}),o[3]=e,o[4]=u,o[5]=i):i=o[5],o[6]!==r||o[7]!==i?(s=n(l,{children:t(h,{flexDirection:"column",children:[r,i]})}),o[6]=r,o[7]=i,o[8]=s):s=o[8],m=s;break e}}o[0]=i,o[1]=u,o[2]=m}else m=o[2];if(m!==Symbol.for("react.early_return_sentinel"))return m;if(o[9]!==i){p=Symbol.for("react.early_return_sentinel");e:{const e=tryFlattenJson(i);if(null!==e){const r=Math.max(...e.map(_temp2));let i;o[11]!==r?(i=(e,o)=>{const[i,l]=e;return t(f,{children:[t(f,{dimColor:!0,children:[i.padEnd(r),": "]}),n(a,{children:s(l)})]},o)},o[11]=r,o[12]=i):i=o[12];const c=n(h,{flexDirection:"column",children:e.map(i)});let u;o[13]!==c?(u=n(l,{children:c}),o[13]=c,o[14]=u):u=o[14],p=u;break e}}o[9]=i,o[10]=p}else p=o[10];return p!==Symbol.for("react.early_return_sentinel")?p:(o[15]!==i||o[16]!==u?(d=n(c,{content:i,verbose:u,linkifyUrls:!0}),o[15]=i,o[16]=u,o[17]=d):d=o[17],d)}function _temp2(e){const[n]=e;return u(n)}function _temp(e){const[n,t]=e;return`${n}: ${t}`}function parseJsonEntries(e,{maxChars:n,maxKeys:t}){const r=e.trim();if(0===r.length||r.length>n||"{"!==r[0])return null;let o;try{o=y(r)}catch{return null}if(null===o||"object"!=typeof o||Array.isArray(o))return null;const i=Object.entries(o);return 0===i.length||i.length>t?null:i}export function tryFlattenJson(e){const n=parseJsonEntries(e,{maxChars:5e3,maxKeys:12});if(null===n)return null;const t=[];for(const[e,r]of n)if("string"==typeof r)t.push([e,r]);else if(null===r||"number"==typeof r||"boolean"==typeof r)t.push([e,String(r)]);else{if("object"!=typeof r)return null;{const n=g(r);if(n.length>120)return null;t.push([e,n])}}return t}export function tryUnwrapTextPayload(e){const n=parseJsonEntries(e,{maxChars:2e5,maxKeys:4});if(null===n)return null;let t=null;const r=[];for(const[e,o]of n)if("string"==typeof o){const n=o.trimEnd();if(n.length>200||n.includes("\n")&&n.length>50){if(null!==t)return null;t=n;continue}if(n.length>150)return null;r.push([e,n.replace(/\s+/g," ")])}else{if(null!==o&&"number"!=typeof o&&"boolean"!=typeof o)return null;r.push([e,String(o)])}return null===t?null:{body:t,extras:r}}const x=/^https:\/\/[a-z0-9-]+\.slack\.com\/archives\/([A-Z0-9]+)\/p\d+$/;export function trySlackSendCompact(e,n){let t=e;if(Array.isArray(e)){const n=e.find(e=>"text"===e.type);t=n&&"text"in n?n.text:void 0}if("string"!=typeof t||!t.includes('"message_link"'))return null;const r=parseJsonEntries(t,{maxChars:2e3,maxKeys:6}),o=r?.find(([e])=>"message_link"===e)?.[1];if("string"!=typeof o)return null;const i=x.exec(o);if(!i)return null;const l=n,s=l?.channel_id??l?.channel??i[1],c="string"==typeof s&&s?s:"slack";return{channel:c.startsWith("#")?c:`#${c}`,url:o}}
1
+ import{jsx as e,jsxs as n}from"react/jsx-runtime";import{c as t}from"react/compiler-runtime";import{feature as r}from"bun:bundle";import o from"figures";import{ProgressBar as i}from"../../components/design-system/ProgressBar.js";import{MessageResponse as s}from"../../components/MessageResponse.js";import{linkifyUrlsInText as l,OutputLine as c}from"../../components/shell/OutputLine.js";import{stringWidth as a}from"../../ink/stringWidth.js";import{Ansi as u,Box as f,Text as h}from"../../ink.js";import{formatNumber as m}from"../../utils/format.js";import{createHyperlink as p}from"../../utils/hyperlink.js";import{getContentSizeEstimate as d}from"../../utils/mcpValidation.js";import{jsonParse as g,jsonStringify as y}from"../../utils/slowOperations.js";export function renderToolUseMessage(e,{verbose:n}){return 0===Object.keys(e).length?"":Object.entries(e).map(([e,t])=>{let o=y(t);return r("MCP_RICH_OUTPUT")&&!n&&o.length>80&&(o=o.slice(0,80).trimEnd()+"…"),`${e}: ${o}`}).join(", ")}export function renderToolUseProgressMessage(t){const r=t.at(-1);if(!r?.data)return e(s,{height:1,children:e(h,{dimColor:!0,children:"Running…"})});const{progress:o,total:l,progressMessage:c}=r.data;if(void 0===o)return e(s,{height:1,children:e(h,{dimColor:!0,children:"Running…"})});if(void 0!==l&&l>0){const t=Math.min(1,Math.max(0,o/l)),r=Math.round(100*t);return e(s,{children:n(f,{flexDirection:"column",children:[c&&e(h,{dimColor:!0,children:c}),n(f,{flexDirection:"row",gap:1,children:[e(i,{ratio:t,width:20}),n(h,{dimColor:!0,children:[r,"%"]})]})]})})}return e(s,{height:1,children:e(h,{dimColor:!0,children:c??`Processing… ${o}`})})}export function renderToolResultMessage(t,i,{verbose:l,input:a}){const g=t;if(!l){const t=trySlackSendCompact(g,a);if(null!==t)return e(s,{height:1,children:n(h,{children:["Sent a message to"," ",e(u,{children:p(t.url,t.channel)})]})})}const y=d(g),x=y>1e4?`${o.warning} Large MCP response (~${m(y)} tokens), this can fill up context quickly`:null;let b;if(Array.isArray(g)){const n=g.map((n,t)=>{if("image"===n.type)return e(f,{justifyContent:"space-between",overflowX:"hidden",width:"100%",children:e(s,{height:1,children:e(h,{children:"[Image]"})})},t);const o="text"===n.type&&"text"in n&&null!==n.text&&void 0!==n.text?String(n.text):"";return r("MCP_RICH_OUTPUT")?e(MCPTextOutput,{content:o,verbose:l},t):e(c,{content:o,verbose:l},t)});b=e(f,{flexDirection:"column",width:"100%",children:n})}else b=g?r("MCP_RICH_OUTPUT")?e(MCPTextOutput,{content:g,verbose:l}):e(c,{content:g,verbose:l}):e(f,{justifyContent:"space-between",overflowX:"hidden",width:"100%",children:e(s,{height:1,children:e(h,{dimColor:!0,children:"(No content)"})})});return x?n(f,{flexDirection:"column",children:[e(s,{height:1,children:e(h,{color:"warning",children:x})}),b]}):b}function MCPTextOutput(r){const o=t(18),{content:i,verbose:a}=r;let m,p,d;if(o[0]!==i||o[1]!==a){m=Symbol.for("react.early_return_sentinel");e:{const t=tryUnwrapTextPayload(i);if(null!==t){const r=t.extras.length>0&&e(h,{dimColor:!0,children:t.extras.map(_temp).join(" · ")});let i,l;o[3]!==t||o[4]!==a?(i=e(c,{content:t.body,verbose:a,linkifyUrls:!0}),o[3]=t,o[4]=a,o[5]=i):i=o[5],o[6]!==r||o[7]!==i?(l=e(s,{children:n(f,{flexDirection:"column",children:[r,i]})}),o[6]=r,o[7]=i,o[8]=l):l=o[8],m=l;break e}}o[0]=i,o[1]=a,o[2]=m}else m=o[2];if(m!==Symbol.for("react.early_return_sentinel"))return m;if(o[9]!==i){p=Symbol.for("react.early_return_sentinel");e:{const t=tryFlattenJson(i);if(null!==t){const r=Math.max(...t.map(_temp2));let i;o[11]!==r?(i=(t,o)=>{const[i,s]=t;return n(h,{children:[n(h,{dimColor:!0,children:[i.padEnd(r),": "]}),e(u,{children:l(s)})]},o)},o[11]=r,o[12]=i):i=o[12];const c=e(f,{flexDirection:"column",children:t.map(i)});let a;o[13]!==c?(a=e(s,{children:c}),o[13]=c,o[14]=a):a=o[14],p=a;break e}}o[9]=i,o[10]=p}else p=o[10];return p!==Symbol.for("react.early_return_sentinel")?p:(o[15]!==i||o[16]!==a?(d=e(c,{content:i,verbose:a,linkifyUrls:!0}),o[15]=i,o[16]=a,o[17]=d):d=o[17],d)}function _temp2(e){const[n]=e;return a(n)}function _temp(e){const[n,t]=e;return`${n}: ${t}`}function parseJsonEntries(e,{maxChars:n,maxKeys:t}){const r=e.trim();if(0===r.length||r.length>n||"{"!==r[0])return null;let o;try{o=g(r)}catch{return null}if(null===o||"object"!=typeof o||Array.isArray(o))return null;const i=Object.entries(o);return 0===i.length||i.length>t?null:i}export function tryFlattenJson(e){const n=parseJsonEntries(e,{maxChars:5e3,maxKeys:12});if(null===n)return null;const t=[];for(const[e,r]of n)if("string"==typeof r)t.push([e,r]);else if(null===r||"number"==typeof r||"boolean"==typeof r)t.push([e,String(r)]);else{if("object"!=typeof r)return null;{const n=y(r);if(n.length>120)return null;t.push([e,n])}}return t}export function tryUnwrapTextPayload(e){const n=parseJsonEntries(e,{maxChars:2e5,maxKeys:4});if(null===n)return null;let t=null;const r=[];for(const[e,o]of n)if("string"==typeof o){const n=o.trimEnd();if(n.length>200||n.includes("\n")&&n.length>50){if(null!==t)return null;t=n;continue}if(n.length>150)return null;r.push([e,n.replace(/\s+/g," ")])}else{if(null!==o&&"number"!=typeof o&&"boolean"!=typeof o)return null;r.push([e,String(o)])}return null===t?null:{body:t,extras:r}}const x=/^https:\/\/[a-z0-9-]+\.slack\.com\/archives\/([A-Z0-9]+)\/p\d+$/;export function trySlackSendCompact(e,n){let t=e;if(Array.isArray(e)){const n=e.find(e=>"text"===e.type);t=n&&"text"in n?n.text:void 0}if("string"!=typeof t||!t.includes('"message_link"'))return null;const r=parseJsonEntries(t,{maxChars:2e3,maxKeys:6}),o=r?.find(([e])=>"message_link"===e)?.[1];if("string"!=typeof o)return null;const i=x.exec(o);if(!i)return null;const s=n,l=s?.channel_id??s?.channel??i[1],c="string"==typeof l&&l?l:"slack";return{channel:c.startsWith("#")?c:`#${c}`,url:o}}
@@ -1 +1 @@
1
- import t from"lodash-es/reject.js";import{z as e}from"zod/v4";import{performMCPOAuthFlow as s}from"../../services/mcp/auth.js";import{clearMcpAuthCache as o,reconnectMcpServerImpl as r}from"../../services/mcp/client.js";import{buildMcpToolName as a,getMcpPrefix as n}from"../../services/mcp/mcpStringUtils.js";import{errorMessage as i}from"../../utils/errors.js";import{lazySchema as l}from"../../utils/lazySchema.js";import{logMCPDebug as c,logMCPError as u}from"../../utils/log.js";const m=l(()=>e.object({}));export function createMcpAuthTool(e,l){const h=function(t){if("url"in t)return t.url}(l),p=l.type??"stdio",d=`The \`${e}\` MCP server (${h?`${p} at ${h}`:p}) is installed but requires authentication. Call this tool to start the OAuth flow — you'll receive an authorization URL to share with the user. Once the user completes authorization in their browser, the server's real tools will become available automatically.`;return{name:a(e,"authenticate"),isMcp:!0,mcpInfo:{serverName:e,toolName:"authenticate"},isEnabled:()=>!0,isConcurrencySafe:()=>!1,isReadOnly:()=>!1,toAutoClassifierInput:()=>e,userFacingName:()=>`${e} - authenticate (MCP)`,maxResultSizeChars:1e4,renderToolUseMessage:()=>`Authenticate ${e} MCP server`,description:async()=>d,prompt:async()=>d,get inputSchema(){return m()},checkPermissions:async t=>({behavior:"allow",updatedInput:t}),async call(a,m){if("claudeai-proxy"===l.type)return{data:{status:"unsupported",message:`This is a claude.ai MCP connector. Ask the user to run /mcp and select "${e}" to authenticate.`}};if("sse"!==l.type&&"http"!==l.type)return{data:{status:"unsupported",message:`Server "${e}" uses ${p} transport which does not support OAuth from this tool. Ask the user to run /mcp and authenticate manually.`}};const h=l;let d;const f=new Promise(t=>{d=t}),y=new AbortController,{setAppState:w}=m,v=s(e,h,t=>d?.(t),y.signal,{skipBrowserOpen:!0});v.then(async()=>{o();const s=await r(e,l),a=n(e);w(o=>({...o,mcp:{...o.mcp,clients:o.mcp.clients.map(t=>t.name===e?s.client:t),tools:[...t(o.mcp.tools,t=>t.name?.startsWith(a)),...s.tools],commands:[...t(o.mcp.commands,t=>t.name?.startsWith(a)),...s.commands],resources:s.resources?{...o.mcp.resources,[e]:s.resources}:o.mcp.resources}})),c(e,`OAuth complete, reconnected with ${s.tools.length} tool(s)`)}).catch(t=>{u(e,`OAuth flow failed after tool-triggered start: ${i(t)}`)});try{const t=await Promise.race([f,v.then(()=>null)]);return t?{data:{status:"auth_url",authUrl:t,message:`Ask the user to open this URL in their browser to authorize the ${e} MCP server:\n\n${t}\n\nOnce they complete the flow, the server's tools will become available automatically.`}}:{data:{status:"auth_url",message:`Authentication completed silently for ${e}. The server's tools should now be available.`}}}catch(t){return{data:{status:"error",message:`Failed to start OAuth flow for ${e}: ${i(t)}. Ask the user to run /mcp and authenticate manually.`}}}},mapToolResultToToolResultBlockParam:(t,e)=>({tool_use_id:e,type:"tool_result",content:t.message})}}
1
+ import e from"lodash-es/reject.js";import{z as t}from"zod/v4";import{performMCPOAuthFlow as s}from"../../services/mcp/auth.js";import{clearMcpAuthCache as r,reconnectMcpServerImpl as o}from"../../services/mcp/client.js";import{buildMcpToolName as a,getMcpPrefix as l}from"../../services/mcp/mcpStringUtils.js";import{errorMessage as n}from"../../utils/errors.js";import{lazySchema as c}from"../../utils/lazySchema.js";import{logMCPDebug as i,logMCPError as u}from"../../utils/log.js";const m=c(()=>t.object({}));export function createMcpAuthTool(t,c){const h=function(e){if("url"in e)return e.url}(c),p=c.type??"stdio",d=`The \`${t}\` MCP server (${h?`${p} at ${h}`:p}) is installed but requires authentication. Call this tool to start the OAuth flow — you'll receive an authorization URL to share with the user. Once the user completes authorization in their browser, the server's real tools will become available automatically.`;return{name:a(t,"authenticate"),isMcp:!0,mcpInfo:{serverName:t,toolName:"authenticate"},isEnabled:()=>!0,isConcurrencySafe:()=>!1,isReadOnly:()=>!1,toAutoClassifierInput:()=>t,userFacingName:()=>`${t} - authenticate (MCP)`,maxResultSizeChars:1e4,renderToolUseMessage:()=>`Authenticate ${t} MCP server`,description:async()=>d,prompt:async()=>d,get inputSchema(){return m()},checkPermissions:async e=>({behavior:"allow",updatedInput:e}),async call(a,m){if("claudeai-proxy"===c.type)return{data:{status:"unsupported",message:`This is a claude.ai MCP connector. Ask the user to run /mcp and select "${t}" to authenticate.`}};if("sse"!==c.type&&"http"!==c.type)return{data:{status:"unsupported",message:`Server "${t}" uses ${p} transport which does not support OAuth from this tool. Ask the user to run /mcp and authenticate manually.`}};const h=c;let d;const f=new Promise(e=>{d=e}),y=new AbortController,{setAppState:g}=m,w=s(t,h,e=>d?.(e),y.signal,{skipBrowserOpen:!0});w.then(async()=>{r();const s=await o(t,c),a=l(t);g(r=>({...r,mcp:{...r.mcp,clients:r.mcp.clients.map(e=>e.name===t?s.client:e),tools:[...e(r.mcp.tools,e=>e.name?.startsWith(a)),...s.tools],commands:[...e(r.mcp.commands,e=>e.name?.startsWith(a)),...s.commands],resources:s.resources?{...r.mcp.resources,[t]:s.resources}:r.mcp.resources}})),i(t,`OAuth complete, reconnected with ${s.tools.length} tool(s)`)}).catch(e=>{u(t,`OAuth flow failed after tool-triggered start: ${n(e)}`)});try{const e=await Promise.race([f,w.then(()=>null)]);return e?{data:{status:"auth_url",authUrl:e,message:`Ask the user to open this URL in their browser to authorize the ${t} MCP server:\n\n${e}\n\nOnce they complete the flow, the server's tools will become available automatically.`}}:{data:{status:"auth_url",message:`Authentication completed silently for ${t}. The server's tools should now be available.`}}}catch(e){return{data:{status:"error",message:`Failed to start OAuth flow for ${t}: ${n(e)}. Ask the user to run /mcp and authenticate manually.`}}}},mapToolResultToToolResultBlockParam:(e,t)=>({tool_use_id:t,type:"tool_result",content:e.message})}}
@@ -1 +1 @@
1
- export const DESCRIPTION="Replace the contents of a specific cell in a Jupyter notebook.";export const PROMPT="Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number.";
1
+ export const DESCRIPTION="Replace the contents of a specific cell in a Jupyter notebook.";export const PROMPT="Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number.";er.`;
@@ -1 +1 @@
1
- import{feature as t}from"../../recovery/bunBundleShim.js";import{jsx as e}from"react/jsx-runtime";import{copyFile as o,stat as n,truncate as r,link as s}from"fs/promises";import{z as i}from"zod/v4";import{getKairosActive as a}from"../../bootstrap/state.js";import{isCoreToolsEnabled as d}from"../../core/tools/contracts.js";import{startCoreShellCommand as u}from"../../core/tools/shellCore.js";import{TOOL_SUMMARY_MAX_LENGTH as l}from"../../constants/toolLimits.js";import{logEvent as c}from"../../services/analytics/index.js";import{buildTool as m}from"../../Tool.js";import{backgroundExistingForegroundTask as p,markTaskNotified as g,registerForeground as h,spawnShellTask as f,unregisterForeground as b}from"../../tasks/LocalShellTask/LocalShellTask.js";import{extractClaudeCodeHints as k}from"../../utils/claudeCodeHints.js";import{isEnvTruthy as w}from"../../utils/envUtils.js";import{errorMessage as S,ShellError as y}from"../../utils/errors.js";import{truncate as T}from"../../utils/format.js";import{lazySchema as I}from"../../utils/lazySchema.js";import{logError as _}from"../../utils/log.js";import{getPlatform as C}from"../../utils/platform.js";import{maybeRecordPluginHint as j}from"../../utils/plugins/hintRecommendation.js";import{exec as x}from"../../utils/Shell.js";import{SandboxManager as B}from"../../utils/sandbox/sandbox-adapter.js";import{semanticBoolean as P}from"../../utils/semanticBoolean.js";import{semanticNumber as v}from"../../utils/semanticNumber.js";import{getCachedPowerShellPath as O}from"../../utils/shell/powershellDetection.js";import{EndTruncatingAccumulator as A}from"../../utils/stringUtils.js";import{getTaskOutputPath as R}from"../../utils/task/diskOutput.js";import{TaskOutput as U}from"../../utils/task/TaskOutput.js";import{isOutputLineTruncated as D}from"../../utils/terminal.js";import{buildLargeToolResultMessage as F,ensureToolResultsDir as E,generatePreview as M,getToolResultPath as L,PREVIEW_SIZE_BYTES as $}from"../../utils/toolResultStorage.js";import{shouldUseSandbox as z}from"../BashTool/shouldUseSandbox.js";import{BackgroundHint as N}from"../BashTool/UI.js";import{buildImageToolResult as W,isImageOutput as K,resetCwdIfOutsideProject as J,resizeShellImageOutput as V,stdErrAppendShellResetMessage as X,stripEmptyLines as H}from"../BashTool/utils.js";import{trackGitOperations as q}from"../shared/gitOperationTracking.js";import{interpretCommandResult as G}from"./commandSemantics.js";import{powershellToolHasPermission as Q}from"./powershellPermissions.js";import{getDefaultTimeoutMs as Y,getMaxTimeoutMs as Z,getPrompt as tt}from"./prompt.js";import{hasSyncSecurityConcerns as et,isReadOnlyCommand as ot,resolveToCanonical as nt}from"./readOnlyValidation.js";import{POWERSHELL_TOOL_NAME as rt}from"./toolName.js";import{renderToolResultMessage as st,renderToolUseErrorMessage as it,renderToolUseMessage as at,renderToolUseProgressMessage as dt,renderToolUseQueuedMessage as ut}from"./UI.js";const lt=new Set(["select-string","get-childitem","findstr","where.exe"]),ct=new Set(["get-content","get-item","test-path","resolve-path","get-process","get-service","get-childitem","get-location","get-filehash","get-acl","format-hex"]),mt=new Set(["write-output","write-host"]);const pt=2e3,gt=15e3,ht=["start-sleep","sleep"];export function detectBlockedSleepPattern(t){const e=t.trim().split(/[;|&\r\n]/)[0]?.trim()??"",o=/^(?:start-sleep|sleep)(?:\s+-s(?:econds)?)?\s+(\d+)\s*$/i.exec(e);if(!o)return null;const n=parseInt(o[1],10);if(n<2)return null;const r=t.trim().slice(e.length).replace(/^[\s;|&]+/,"");return r?`Start-Sleep ${n} followed by: ${r}`:`standalone Start-Sleep ${n}`}const ft="Enterprise policy requires sandboxing, but sandboxing is not available on native Windows. Shell command execution is blocked on this platform by policy.";function isWindowsSandboxPolicyViolation(){return"windows"===C()&&B.isSandboxEnabledInSettings()&&!B.areUnsandboxedCommandsAllowed()}const bt=w(process.env.CONTEXT_CODE_DISABLE_BACKGROUND_TASKS)||w(process.env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS),kt=I(()=>i.strictObject({command:i.string().describe("The PowerShell command to execute"),timeout:v(i.number().optional()).describe(`Optional timeout in milliseconds (max ${Z()})`),description:i.string().optional().describe("Clear, concise description of what this command does in active voice."),run_in_background:P(i.boolean().optional()).describe("Set to true to run this command in the background. Use Read to read the output later."),dangerouslyDisableSandbox:P(i.boolean().optional()).describe("Set this to true to dangerously override sandbox mode and run commands without sandboxing.")})),wt=I(()=>bt?kt().omit({run_in_background:!0}):kt()),St=I(()=>i.object({stdout:i.string().describe("The standard output of the command"),stderr:i.string().describe("The standard error output of the command"),interrupted:i.boolean().describe("Whether the command was interrupted"),returnCodeInterpretation:i.string().optional().describe("Semantic interpretation for non-error exit codes with special meaning"),isImage:i.boolean().optional().describe("Flag to indicate if stdout contains image data"),persistedOutputPath:i.string().optional().describe("Path to persisted full output when too large for inline"),persistedOutputSize:i.number().optional().describe("Total output size in bytes when persisted"),backgroundTaskId:i.string().optional().describe("ID of the background task if command is running in background"),backgroundedByUser:i.boolean().optional().describe("True if the user manually backgrounded the command with Ctrl+B"),assistantAutoBackgrounded:i.boolean().optional().describe("True if the command was auto-backgrounded by the assistant-mode blocking budget")})),yt=["npm","yarn","pnpm","node","python","python3","go","cargo","make","docker","terraform","webpack","vite","jest","pytest","curl","Invoke-WebRequest","build","test","serve","watch","dev"];function getCommandTypeForLogging(t){const e=t.trim().split(/\s+/)[0]||"";for(const t of yt)if(e.toLowerCase()===t.toLowerCase())return t;return"other"}export const PowerShellTool=m({name:rt,searchHint:"execute Windows PowerShell commands",maxResultSizeChars:3e4,strict:!0,description:async({description:t})=>t||"Run PowerShell command",prompt:async()=>tt(),isConcurrencySafe(t){return this.isReadOnly?.(t)??!1},isSearchOrReadCommand:t=>t.command?function(t){const e=t.trim();if(!e)return{isSearch:!1,isRead:!1};const o=e.split(/\s*[;|]\s*/).filter(Boolean);if(0===o.length)return{isSearch:!1,isRead:!1};let n=!1,r=!1,s=!1;for(const t of o){const e=t.trim().split(/\s+/)[0];if(!e)continue;const o=nt(e);if(mt.has(o))continue;s=!0;const i=lt.has(o),a=ct.has(o);if(!i&&!a)return{isSearch:!1,isRead:!1};i&&(n=!0),a&&(r=!0)}return s?{isSearch:n,isRead:r}:{isSearch:!1,isRead:!1}}(t.command):{isSearch:!1,isRead:!1},isReadOnly:t=>!et(t.command)&&ot(t.command),toAutoClassifierInput:t=>t.command,get inputSchema(){return wt()},get outputSchema(){return St()},userFacingName:()=>"PowerShell",getToolUseSummary(t){if(!t?.command)return null;const{command:e,description:o}=t;return o||T(e,l)},getActivityDescription(t){if(!t?.command)return"Running command";return`Running ${t.description??T(t.command,l)}`},isEnabled:()=>!0,async validateInput(e){if(isWindowsSandboxPolicyViolation())return{result:!1,message:ft,errorCode:11};if(t("MONITOR_TOOL")&&!bt&&!e.run_in_background){const t=detectBlockedSleepPattern(e.command);if(null!==t)return{result:!1,message:`Blocked: ${t}. Run blocking commands in the background with run_in_background: true — you'll get a completion notification when done. For streaming events (watching logs, polling APIs), use the Monitor tool. If you genuinely need a delay (rate limiting, deliberate pacing), keep it under 2 seconds.`,errorCode:10}}return{result:!0}},checkPermissions:async(t,e)=>await Q(t,e),renderToolUseMessage:at,renderToolUseProgressMessage:dt,renderToolUseQueuedMessage:ut,renderToolResultMessage:st,renderToolUseErrorMessage:it,mapToolResultToToolResultBlockParam({interrupted:t,stdout:e,stderr:o,isImage:n,persistedOutputPath:r,persistedOutputSize:s,backgroundTaskId:i,backgroundedByUser:a,assistantAutoBackgrounded:d},u){if(n){const t=W(e,u);if(t)return t}let l=e;if(r){const t=e?e.replace(/^(\s*\n)+/,"").trimEnd():"",o=M(t,$);l=F({filepath:r,originalSize:s??0,isJson:!1,preview:o.preview,hasMore:o.hasMore})}else e&&(l=e.replace(/^(\s*\n)+/,""),l=l.trimEnd());let c=o.trim();t&&(o&&(c+="\n"),c+="<error>Command was aborted before completion</error>");let m="";if(i){const t=R(i);m=d?`Command exceeded the assistant-mode blocking budget (15s) and was moved to the background with ID: ${i}. It is still running — you will be notified when it completes. Output is being written to: ${t}. In assistant mode, delegate long-running work to a subagent or use run_in_background to keep this conversation responsive.`:a?`Command was manually backgrounded by user with ID: ${i}. Output is being written to: ${t}`:`Command running in background with ID: ${i}. Output is being written to: ${t}`}return{tool_use_id:u,type:"tool_result",content:[l,c,m].filter(Boolean).join("\n"),is_error:t}},async call(i,l,m,w,T){if(isWindowsSandboxPolicyViolation())throw new Error(ft);const{abortController:I,setAppState:B,setToolJSX:P}=l,v=!l.agentId;let R=0;try{const m=async function*({input:o,abortController:n,setAppState:r,setToolJSX:s,preventCwdChanges:i,isMainThread:l,toolUseId:m,agentId:k}){const{command:w,description:y,timeout:T,run_in_background:I,dangerouslyDisableSandbox:j}=o,B=Math.min(T||Y(),Z());let P,v="",A="",R=0,D=0,F=!1,E=!1,M=null;function createProgressSignal(){return new Promise(t=>{M=()=>t(null)})}const L=!bt&&function(t){const e=t.trim().split(/\s+/)[0];if(!e)return!0;const o=nt(e);return!ht.includes(o)}(w);if(!await O())return{stdout:"",stderr:"PowerShell is not available on this system.",code:0,interrupted:!1};const $={timeout:B,onProgress(t,e,o,n,r){A=t,v=e,R=o,D=r?n:0},preventCwdChanges:i,shouldUseSandbox:"windows"!==C()&&z({command:w,dangerouslyDisableSandbox:j}),shouldAutoBackground:L};let W;try{W=await(d()?u({command:w,timeoutMs:B,shellType:"powershell",execOptions:$},{abortSignal:n.signal}):x(w,n.signal,"powershell",{timeout:B,onProgress(t,e,o,n,r){A=t,v=e,R=o,D=r?n:0},preventCwdChanges:i,shouldUseSandbox:"windows"!==C()&&z({command:w,dangerouslyDisableSandbox:j}),shouldAutoBackground:L}))}catch(t){return _(t),{stdout:"",stderr:`Failed to execute PowerShell command: ${S(t)}`,code:0,interrupted:!1}}const K=W.result;async function spawnBackgroundTask(){return(await f({command:w,description:y||w,shellCommand:W,toolUseId:m,agentId:k},{abortController:n,getAppState:()=>{throw new Error("getAppState not available in runPowerShellCommand context")},setAppState:r})).taskId}function startBackgrounding(t,e){if(V){if(!p(V,W,y||w,r,m))return;return P=V,c(t,{command_type:getCommandTypeForLogging(w)}),void e?.(V)}spawnBackgroundTask().then(o=>{P=o;const n=M;n&&(M=null,n()),c(t,{command_type:getCommandTypeForLogging(w)}),e&&e(o)})}W.onTimeout&&L&&W.onTimeout(t=>{startBackgrounding("tengu_powershell_command_timeout_backgrounded",t)});t("KAIROS")&&a()&&l&&!bt&&!0!==I&&setTimeout(()=>{"running"===W.status&&void 0===P&&(E=!0,startBackgrounding("tengu_powershell_command_assistant_auto_backgrounded"))},gt).unref();if(!0===I&&!bt){const t=await spawnBackgroundTask();return c("tengu_powershell_command_explicitly_backgrounded",{command_type:getCommandTypeForLogging(w)}),{stdout:"",stderr:"",code:0,interrupted:!1,backgroundTaskId:t}}U.startPolling(W.taskOutput.taskId);const J=Date.now();let V,X=J+pt;try{for(;;){const t=Date.now(),o=Math.max(0,X-t),i=createProgressSignal(),a=await Promise.race([K,new Promise(t=>setTimeout(t=>t(null),o,t).unref()),i]);if(null!==a){if(void 0!==a.backgroundTaskId){g(a.backgroundTaskId,r);const t={...a,backgroundTaskId:void 0},{taskOutput:e}=W;return e.stdoutToFile&&!e.outputFileRedundant&&(t.outputFilePath=e.path,t.outputFileSize=e.outputFileSize,t.outputTaskId=e.taskId),W.cleanup(),t}return a}if(P)return{stdout:F?v:"",stderr:"",code:0,interrupted:!1,backgroundTaskId:P,assistantAutoBackgrounded:E};if(n.signal.aborted&&"interrupt"===n.signal.reason&&!F){if(F=!0,!bt){startBackgrounding("tengu_powershell_command_interrupt_backgrounded");continue}W.kill()}if(V&&"backgrounded"===W.status)return{stdout:"",stderr:"",code:0,interrupted:!1,backgroundTaskId:V,backgroundedByUser:!0};const d=Date.now()-J,u=Math.floor(d/1e3);!bt&&void 0===P&&u>=2&&s&&(V||(V=h({command:w,description:y||w,shellCommand:W,agentId:k},r,m)),s({jsx:e(N,{}),shouldHidePromptInput:!1,shouldContinueAnimation:!0,showSpinner:!0})),yield{type:"progress",fullOutput:v,output:A,elapsedTimeSeconds:u,totalLines:R,totalBytes:D,taskId:W.taskOutput.taskId,...T?{timeoutMs:B}:void 0},X=Date.now()+1e3}}finally{U.stopPolling(W.taskOutput.taskId),P||"backgrounded"===W.status||(V&&b(V,r),W.cleanup())}}({input:i,abortController:I,setAppState:l.setAppStateForTasks??B,setToolJSX:P,preventCwdChanges:!v,isMainThread:v,toolUseId:l.toolUseId,agentId:l.agentId});let w;do{if(w=await m.next(),!w.done&&T){const t=w.value;T({toolUseID:"ps-progress-"+R++,data:{type:"powershell_progress",output:t.output,fullOutput:t.fullOutput,elapsedTimeSeconds:t.elapsedTimeSeconds,totalLines:t.totalLines,totalBytes:t.totalBytes,timeoutMs:t.timeoutMs,taskId:t.taskId}})}}while(!w.done);const D=w.value;0===D.code&&!D.stdout&&D.stderr&&!D.backgroundTaskId||q(i.command,D.code,D.stdout);const F=D.interrupted&&"interrupt"===I.signal.reason;let M="";if(v){const t=l.getAppState();J(t.toolPermissionContext)&&(M=X(""))}if(D.backgroundTaskId){const t=k(D.stdout||"",i.command);if(v&&t.hints.length>0)for(const e of t.hints)j(e);return{data:{stdout:t.stripped,stderr:[D.stderr||"",M].filter(Boolean).join("\n"),interrupted:!1,backgroundTaskId:D.backgroundTaskId,backgroundedByUser:D.backgroundedByUser,assistantAutoBackgrounded:D.assistantAutoBackgrounded}}}const $=new A,W=(D.stdout||"").trimEnd();$.append(W+"\n");const Q=G(i.command,D.code,W,D.stderr||"");let tt=H($.toString());const et=k(tt,i.command);if(tt=et.stripped,v&&et.hints.length>0)for(const t of et.hints)j(t);if(D.preSpawnError)throw new Error(D.preSpawnError);if(Q.isError&&!F)throw new y(tt,D.stderr||"",D.code,D.interrupted);const ot=67108864;let rt,st;if(D.outputFilePath&&D.outputTaskId)try{const t=await n(D.outputFilePath);st=t.size,await E();const e=L(D.outputTaskId,!1);t.size>ot&&await r(D.outputFilePath,ot);try{await s(D.outputFilePath,e)}catch{await o(D.outputFilePath,e)}rt=e}catch{}let it=K(tt),at=tt;if(it){const t=await V(tt,D.outputFilePath,st);t?at=t:it=!1}const dt=[D.stderr||"",M].filter(Boolean).join("\n");return c("tengu_powershell_tool_command_executed",{command_type:getCommandTypeForLogging(i.command),stdout_length:at.length,stderr_length:dt.length,exit_code:D.code,interrupted:D.interrupted}),{data:{stdout:at,stderr:dt,interrupted:D.interrupted,returnCodeInterpretation:Q.message,isImage:it,persistedOutputPath:rt,persistedOutputSize:st}}}finally{P&&P(null)}},isResultTruncated:t=>D(t.stdout)||D(t.stderr)});
1
+ import{jsx as t}from"react/jsx-runtime";import{feature as e}from"bun:bundle";import{copyFile as o,stat as s,truncate as r,link as n}from"fs/promises";import{z as a}from"zod/v4";import{getKairosActive as i}from"../../bootstrap/state.js";import{isCoreToolsEnabled as d}from"../../core/tools/contracts.js";import{startCoreShellCommand as u}from"../../core/tools/shellCore.js";import{TOOL_SUMMARY_MAX_LENGTH as l}from"../../constants/toolLimits.js";import{logEvent as c}from"../../services/analytics/index.js";import{buildTool as m}from"../../Tool.js";import{backgroundExistingForegroundTask as p,markTaskNotified as g,registerForeground as h,spawnShellTask as f,unregisterForeground as b}from"../../tasks/LocalShellTask/LocalShellTask.js";import{extractClaudeCodeHints as k}from"../../utils/claudeCodeHints.js";import{isEnvTruthy as w}from"../../utils/envUtils.js";import{errorMessage as S,ShellError as T}from"../../utils/errors.js";import{truncate as y}from"../../utils/format.js";import{lazySchema as I}from"../../utils/lazySchema.js";import{logError as _}from"../../utils/log.js";import{getPlatform as C}from"../../utils/platform.js";import{maybeRecordPluginHint as P}from"../../utils/plugins/hintRecommendation.js";import{exec as x}from"../../utils/Shell.js";import{SandboxManager as O}from"../../utils/sandbox/sandbox-adapter.js";import{semanticBoolean as j}from"../../utils/semanticBoolean.js";import{semanticNumber as v}from"../../utils/semanticNumber.js";import{getCachedPowerShellPath as B}from"../../utils/shell/powershellDetection.js";import{EndTruncatingAccumulator as R}from"../../utils/stringUtils.js";import{getTaskOutputPath as E}from"../../utils/task/diskOutput.js";import{TaskOutput as A}from"../../utils/task/TaskOutput.js";import{isOutputLineTruncated as M}from"../../utils/terminal.js";import{buildLargeToolResultMessage as U,ensureToolResultsDir as F,generatePreview as L,getToolResultPath as D,PREVIEW_SIZE_BYTES as z}from"../../utils/toolResultStorage.js";import{shouldUseSandbox as $}from"../BashTool/shouldUseSandbox.js";import{BackgroundHint as N}from"../BashTool/UI.js";import{buildImageToolResult as H,isImageOutput as W,resetCwdIfOutsideProject as K,resizeShellImageOutput as V,stdErrAppendShellResetMessage as X,stripEmptyLines as G}from"../BashTool/utils.js";import{trackGitOperations as J}from"../shared/gitOperationTracking.js";import{interpretCommandResult as q}from"./commandSemantics.js";import{powershellToolHasPermission as Q}from"./powershellPermissions.js";import{getDefaultTimeoutMs as Y,getMaxTimeoutMs as Z,getPrompt as tt}from"./prompt.js";import{hasSyncSecurityConcerns as et,isReadOnlyCommand as ot,resolveToCanonical as st}from"./readOnlyValidation.js";import{POWERSHELL_TOOL_NAME as rt}from"./toolName.js";import{renderToolResultMessage as nt,renderToolUseErrorMessage as at,renderToolUseMessage as it,renderToolUseProgressMessage as dt,renderToolUseQueuedMessage as ut}from"./UI.js";const lt=new Set(["select-string","get-childitem","findstr","where.exe"]),ct=new Set(["get-content","get-item","test-path","resolve-path","get-process","get-service","get-childitem","get-location","get-filehash","get-acl","format-hex"]),mt=new Set(["write-output","write-host"]),pt=["start-sleep","sleep"];export function detectBlockedSleepPattern(t){const e=t.trim().split(/[;|&\r\n]/)[0]?.trim()??"",o=/^(?:start-sleep|sleep)(?:\s+-s(?:econds)?)?\s+(\d+)\s*$/i.exec(e);if(!o)return null;const s=parseInt(o[1],10);if(s<2)return null;const r=t.trim().slice(e.length).replace(/^[\s;|&]+/,"");return r?`Start-Sleep ${s} followed by: ${r}`:`standalone Start-Sleep ${s}`}const gt="Enterprise policy requires sandboxing, but sandboxing is not available on native Windows. Shell command execution is blocked on this platform by policy.";function isWindowsSandboxPolicyViolation(){return"windows"===C()&&O.isSandboxEnabledInSettings()&&!O.areUnsandboxedCommandsAllowed()}const ht=w(process.env.CONTEXT_CODE_DISABLE_BACKGROUND_TASKS)||w(process.env.CLAUDE_CODE_DISABLE_BACKGROUND_TASKS),ft=I(()=>a.strictObject({command:a.string().describe("The PowerShell command to execute"),timeout:v(a.number().optional()).describe(`Optional timeout in milliseconds (max ${Z()})`),description:a.string().optional().describe("Clear, concise description of what this command does in active voice."),run_in_background:j(a.boolean().optional()).describe("Set to true to run this command in the background. Use Read to read the output later."),dangerouslyDisableSandbox:j(a.boolean().optional()).describe("Set this to true to dangerously override sandbox mode and run commands without sandboxing.")})),bt=I(()=>ht?ft().omit({run_in_background:!0}):ft()),kt=I(()=>a.object({stdout:a.string().describe("The standard output of the command"),stderr:a.string().describe("The standard error output of the command"),interrupted:a.boolean().describe("Whether the command was interrupted"),returnCodeInterpretation:a.string().optional().describe("Semantic interpretation for non-error exit codes with special meaning"),isImage:a.boolean().optional().describe("Flag to indicate if stdout contains image data"),persistedOutputPath:a.string().optional().describe("Path to persisted full output when too large for inline"),persistedOutputSize:a.number().optional().describe("Total output size in bytes when persisted"),backgroundTaskId:a.string().optional().describe("ID of the background task if command is running in background"),backgroundedByUser:a.boolean().optional().describe("True if the user manually backgrounded the command with Ctrl+B"),assistantAutoBackgrounded:a.boolean().optional().describe("True if the command was auto-backgrounded by the assistant-mode blocking budget")})),wt=["npm","yarn","pnpm","node","python","python3","go","cargo","make","docker","terraform","webpack","vite","jest","pytest","curl","Invoke-WebRequest","build","test","serve","watch","dev"];function getCommandTypeForLogging(t){const e=t.trim().split(/\s+/)[0]||"";for(const t of wt)if(e.toLowerCase()===t.toLowerCase())return t;return"other"}export const PowerShellTool=m({name:rt,searchHint:"execute Windows PowerShell commands",maxResultSizeChars:3e4,strict:!0,description:async({description:t})=>t||"Run PowerShell command",prompt:async()=>tt(),isConcurrencySafe(t){return this.isReadOnly?.(t)??!1},isSearchOrReadCommand:t=>t.command?function(t){const e=t.trim();if(!e)return{isSearch:!1,isRead:!1};const o=e.split(/\s*[;|]\s*/).filter(Boolean);if(0===o.length)return{isSearch:!1,isRead:!1};let s=!1,r=!1,n=!1;for(const t of o){const e=t.trim().split(/\s+/)[0];if(!e)continue;const o=st(e);if(mt.has(o))continue;n=!0;const a=lt.has(o),i=ct.has(o);if(!a&&!i)return{isSearch:!1,isRead:!1};a&&(s=!0),i&&(r=!0)}return n?{isSearch:s,isRead:r}:{isSearch:!1,isRead:!1}}(t.command):{isSearch:!1,isRead:!1},isReadOnly:t=>!et(t.command)&&ot(t.command),toAutoClassifierInput:t=>t.command,get inputSchema(){return bt()},get outputSchema(){return kt()},userFacingName:()=>"PowerShell",getToolUseSummary(t){if(!t?.command)return null;const{command:e,description:o}=t;return o||y(e,l)},getActivityDescription:t=>t?.command?`Running ${t.description??y(t.command,l)}`:"Running command",isEnabled:()=>!0,async validateInput(t){if(isWindowsSandboxPolicyViolation())return{result:!1,message:gt,errorCode:11};if(e("MONITOR_TOOL")&&!ht&&!t.run_in_background){const e=detectBlockedSleepPattern(t.command);if(null!==e)return{result:!1,message:`Blocked: ${e}. Run blocking commands in the background with run_in_background: true — you'll get a completion notification when done. For streaming events (watching logs, polling APIs), use the Monitor tool. If you genuinely need a delay (rate limiting, deliberate pacing), keep it under 2 seconds.`,errorCode:10}}return{result:!0}},checkPermissions:async(t,e)=>await Q(t,e),renderToolUseMessage:it,renderToolUseProgressMessage:dt,renderToolUseQueuedMessage:ut,renderToolResultMessage:nt,renderToolUseErrorMessage:at,mapToolResultToToolResultBlockParam({interrupted:t,stdout:e,stderr:o,isImage:s,persistedOutputPath:r,persistedOutputSize:n,backgroundTaskId:a,backgroundedByUser:i,assistantAutoBackgrounded:d},u){if(s){const t=H(e,u);if(t)return t}let l=e;if(r){const t=e?e.replace(/^(\s*\n)+/,"").trimEnd():"",o=L(t,z);l=U({filepath:r,originalSize:n??0,isJson:!1,preview:o.preview,hasMore:o.hasMore})}else e&&(l=e.replace(/^(\s*\n)+/,""),l=l.trimEnd());let c=o.trim();t&&(o&&(c+="\n"),c+="<error>Command was aborted before completion</error>");let m="";if(a){const t=E(a);m=d?`Command exceeded the assistant-mode blocking budget (15s) and was moved to the background with ID: ${a}. It is still running — you will be notified when it completes. Output is being written to: ${t}. In assistant mode, delegate long-running work to a subagent or use run_in_background to keep this conversation responsive.`:i?`Command was manually backgrounded by user with ID: ${a}. Output is being written to: ${t}`:`Command running in background with ID: ${a}. Output is being written to: ${t}`}return{tool_use_id:u,type:"tool_result",content:[l,c,m].filter(Boolean).join("\n"),is_error:t}},async call(a,l,m,w,y){if(isWindowsSandboxPolicyViolation())throw new Error(gt);const{abortController:I,setAppState:O,setToolJSX:j}=l,v=!l.agentId;let E=0;try{const m=async function*({input:o,abortController:s,setAppState:r,setToolJSX:n,preventCwdChanges:a,isMainThread:l,toolUseId:m,agentId:k}){const{command:w,description:T,timeout:y,run_in_background:I,dangerouslyDisableSandbox:P}=o,O=Math.min(y||Y(),Z());let j,v="",R="",E=0,M=0,U=!1,F=!1,L=null;function createProgressSignal(){return new Promise(t=>{L=()=>t(null)})}const D=!ht&&function(t){const e=t.trim().split(/\s+/)[0];if(!e)return!0;const o=st(e);return!pt.includes(o)}(w);if(!await B())return{stdout:"",stderr:"PowerShell is not available on this system.",code:0,interrupted:!1};const z={timeout:O,onProgress(t,e,o,s,r){R=t,v=e,E=o,M=r?s:0},preventCwdChanges:a,shouldUseSandbox:"windows"!==C()&&$({command:w,dangerouslyDisableSandbox:P}),shouldAutoBackground:D};let H;try{H=await(d()?u({command:w,timeoutMs:O,shellType:"powershell",execOptions:z},{abortSignal:s.signal}):x(w,s.signal,"powershell",{timeout:O,onProgress(t,e,o,s,r){R=t,v=e,E=o,M=r?s:0},preventCwdChanges:a,shouldUseSandbox:"windows"!==C()&&$({command:w,dangerouslyDisableSandbox:P}),shouldAutoBackground:D}))}catch(t){return _(t),{stdout:"",stderr:`Failed to execute PowerShell command: ${S(t)}`,code:0,interrupted:!1}}const W=H.result;async function spawnBackgroundTask(){return(await f({command:w,description:T||w,shellCommand:H,toolUseId:m,agentId:k},{abortController:s,getAppState:()=>{throw new Error("getAppState not available in runPowerShellCommand context")},setAppState:r})).taskId}function startBackgrounding(t,e){if(V){if(!p(V,H,T||w,r,m))return;return j=V,c(t,{command_type:getCommandTypeForLogging(w)}),void e?.(V)}spawnBackgroundTask().then(o=>{j=o;const s=L;s&&(L=null,s()),c(t,{command_type:getCommandTypeForLogging(w)}),e&&e(o)})}if(H.onTimeout&&D&&H.onTimeout(t=>{startBackgrounding("tengu_powershell_command_timeout_backgrounded",t)}),e("KAIROS")&&i()&&l&&!ht&&!0!==I&&setTimeout(()=>{"running"===H.status&&void 0===j&&(F=!0,startBackgrounding("tengu_powershell_command_assistant_auto_backgrounded"))},15e3).unref(),!0===I&&!ht){const t=await spawnBackgroundTask();return c("tengu_powershell_command_explicitly_backgrounded",{command_type:getCommandTypeForLogging(w)}),{stdout:"",stderr:"",code:0,interrupted:!1,backgroundTaskId:t}}A.startPolling(H.taskOutput.taskId);const K=Date.now();let V,X=K+2e3;try{for(;;){const e=Date.now(),o=Math.max(0,X-e),a=createProgressSignal(),i=await Promise.race([W,new Promise(t=>setTimeout(t=>t(null),o,t).unref()),a]);if(null!==i){if(void 0!==i.backgroundTaskId){g(i.backgroundTaskId,r);const t={...i,backgroundTaskId:void 0},{taskOutput:e}=H;return e.stdoutToFile&&!e.outputFileRedundant&&(t.outputFilePath=e.path,t.outputFileSize=e.outputFileSize,t.outputTaskId=e.taskId),H.cleanup(),t}return i}if(j)return{stdout:U?v:"",stderr:"",code:0,interrupted:!1,backgroundTaskId:j,assistantAutoBackgrounded:F};if(s.signal.aborted&&"interrupt"===s.signal.reason&&!U){if(U=!0,!ht){startBackgrounding("tengu_powershell_command_interrupt_backgrounded");continue}H.kill()}if(V&&"backgrounded"===H.status)return{stdout:"",stderr:"",code:0,interrupted:!1,backgroundTaskId:V,backgroundedByUser:!0};const d=Date.now()-K,u=Math.floor(d/1e3);!ht&&void 0===j&&u>=2&&n&&(V||(V=h({command:w,description:T||w,shellCommand:H,agentId:k},r,m)),n({jsx:t(N,{}),shouldHidePromptInput:!1,shouldContinueAnimation:!0,showSpinner:!0})),yield{type:"progress",fullOutput:v,output:R,elapsedTimeSeconds:u,totalLines:E,totalBytes:M,taskId:H.taskOutput.taskId,...y?{timeoutMs:O}:void 0},X=Date.now()+1e3}}finally{A.stopPolling(H.taskOutput.taskId),j||"backgrounded"===H.status||(V&&b(V,r),H.cleanup())}}({input:a,abortController:I,setAppState:l.setAppStateForTasks??O,setToolJSX:j,preventCwdChanges:!v,isMainThread:v,toolUseId:l.toolUseId,agentId:l.agentId});let w;do{if(w=await m.next(),!w.done&&y){const t=w.value;y({toolUseID:"ps-progress-"+E++,data:{type:"powershell_progress",output:t.output,fullOutput:t.fullOutput,elapsedTimeSeconds:t.elapsedTimeSeconds,totalLines:t.totalLines,totalBytes:t.totalBytes,timeoutMs:t.timeoutMs,taskId:t.taskId}})}}while(!w.done);const M=w.value;0===M.code&&!M.stdout&&M.stderr&&!M.backgroundTaskId||J(a.command,M.code,M.stdout);const U=M.interrupted&&"interrupt"===I.signal.reason;let L="";if(v){const t=l.getAppState();K(t.toolPermissionContext)&&(L=X(""))}if(M.backgroundTaskId){const t=k(M.stdout||"",a.command);if(v&&t.hints.length>0)for(const e of t.hints)P(e);return{data:{stdout:t.stripped,stderr:[M.stderr||"",L].filter(Boolean).join("\n"),interrupted:!1,backgroundTaskId:M.backgroundTaskId,backgroundedByUser:M.backgroundedByUser,assistantAutoBackgrounded:M.assistantAutoBackgrounded}}}const z=new R,H=(M.stdout||"").trimEnd();z.append(H+"\n");const Q=q(a.command,M.code,H,M.stderr||"");let tt=G(z.toString());const et=k(tt,a.command);if(tt=et.stripped,v&&et.hints.length>0)for(const t of et.hints)P(t);if(M.preSpawnError)throw new Error(M.preSpawnError);if(Q.isError&&!U)throw new T(tt,M.stderr||"",M.code,M.interrupted);const ot=67108864;let rt,nt;if(M.outputFilePath&&M.outputTaskId)try{const t=await s(M.outputFilePath);nt=t.size,await F();const e=D(M.outputTaskId,!1);t.size>ot&&await r(M.outputFilePath,ot);try{await n(M.outputFilePath,e)}catch{await o(M.outputFilePath,e)}rt=e}catch{}let at=W(tt),it=tt;if(at){const t=await V(tt,M.outputFilePath,nt);t?it=t:at=!1}const dt=[M.stderr||"",L].filter(Boolean).join("\n");return c("tengu_powershell_tool_command_executed",{command_type:getCommandTypeForLogging(a.command),stdout_length:it.length,stderr_length:dt.length,exit_code:M.code,interrupted:M.interrupted}),{data:{stdout:it,stderr:dt,interrupted:M.interrupted,returnCodeInterpretation:Q.message,isImage:at,persistedOutputPath:rt,persistedOutputSize:nt}}}finally{j&&j(null)}},isResultTruncated:t=>M(t.stdout)||M(t.stderr)});
@@ -1 +1 @@
1
- import{jsxs as e,jsx as t,Fragment as o}from"react/jsx-runtime";import{KeyboardShortcutHint as r}from"../../components/design-system/KeyboardShortcutHint.js";import{FallbackToolUseErrorMessage as s}from"../../components/FallbackToolUseErrorMessage.js";import{MessageResponse as n}from"../../components/MessageResponse.js";import{OutputLine as l}from"../../components/shell/OutputLine.js";import{ShellProgressMessage as i}from"../../components/shell/ShellProgressMessage.js";import{ShellTimeDisplay as u}from"../../components/shell/ShellTimeDisplay.js";import{Box as a,Text as m}from"../../ink.js";export function renderToolUseMessage(t,{verbose:o,theme:r}){const{command:s}=t;if(!s)return null;const n=s;if(!o){const t=n.split("\n"),o=t.length>2,r=n.length>160;if(o||r){let r=n;return o&&(r=t.slice(0,2).join("\n")),r.length>160&&(r=r.slice(0,160)),e(m,{children:[r.trim(),"…"]})}}return n}export function renderToolUseProgressMessage(e,{verbose:o,tools:r,terminalSize:s,inProgressToolCallCount:l}){const u=e.at(-1);if(!u||!u.data)return t(n,{height:1,children:t(m,{dimColor:!0,children:"Running…"})});const a=u.data;return t(i,{fullOutput:a.fullOutput,output:a.output,elapsedTimeSeconds:a.elapsedTimeSeconds,totalLines:a.totalLines,totalBytes:a.totalBytes,timeoutMs:a.timeoutMs,taskId:a.taskId,verbose:o})}export function renderToolUseQueuedMessage(){return t(n,{height:1,children:t(m,{dimColor:!0,children:"Waiting…"})})}export function renderToolResultMessage(s,i,{verbose:d,theme:c,tools:p,style:h}){const g=i.at(-1),f=g?.data?.timeoutMs,{stdout:M,stderr:b,interrupted:j,returnCodeInterpretation:T,isImage:x,backgroundTaskId:v}=s;return x?t(n,{height:1,children:t(m,{dimColor:!0,children:"[Image data detected and sent to Claude]"})}):e(a,{flexDirection:"column",children:[""!==M?t(l,{content:M,verbose:d}):null,""!==b.trim()?t(l,{content:b,verbose:d,isError:!0}):null,""===M&&""===b.trim()?t(n,{height:1,children:t(m,{dimColor:!0,children:v?e(o,{children:["Running in the background"," ",t(r,{shortcut:"↓",action:"manage",parens:!0})]}):j?"Interrupted":T||"(No output)"})}):null,f?t(n,{children:t(u,{timeoutMs:f})}):null]})}export function renderToolUseErrorMessage(e,{verbose:o,progressMessagesForMessage:r,tools:n}){return t(s,{result:e,verbose:o})}
1
+ import{jsxs as e,jsx as t,Fragment as o}from"react/jsx-runtime";import{KeyboardShortcutHint as s}from"../../components/design-system/KeyboardShortcutHint.js";import{FallbackToolUseErrorMessage as r}from"../../components/FallbackToolUseErrorMessage.js";import{MessageResponse as n}from"../../components/MessageResponse.js";import{OutputLine as l}from"../../components/shell/OutputLine.js";import{ShellProgressMessage as i}from"../../components/shell/ShellProgressMessage.js";import{ShellTimeDisplay as a}from"../../components/shell/ShellTimeDisplay.js";import{Box as u,Text as m}from"../../ink.js";export function renderToolUseMessage(t,{verbose:o,theme:s}){const{command:r}=t;if(!r)return null;const n=r;if(!o){const t=n.split("\n"),o=t.length>2,s=n.length>160;if(o||s){let s=n;return o&&(s=t.slice(0,2).join("\n")),s.length>160&&(s=s.slice(0,160)),e(m,{children:[s.trim(),"…"]})}}return n}export function renderToolUseProgressMessage(e,{verbose:o,tools:s,terminalSize:r,inProgressToolCallCount:l}){const a=e.at(-1);if(!a||!a.data)return t(n,{height:1,children:t(m,{dimColor:!0,children:"Running…"})});const u=a.data;return t(i,{fullOutput:u.fullOutput,output:u.output,elapsedTimeSeconds:u.elapsedTimeSeconds,totalLines:u.totalLines,totalBytes:u.totalBytes,timeoutMs:u.timeoutMs,taskId:u.taskId,verbose:o})}export function renderToolUseQueuedMessage(){return t(n,{height:1,children:t(m,{dimColor:!0,children:"Waiting…"})})}export function renderToolResultMessage(r,i,{verbose:c,theme:d,tools:p,style:h}){const g=i.at(-1),f=g?.data?.timeoutMs,{stdout:M,stderr:b,interrupted:T,returnCodeInterpretation:j,isImage:x,backgroundTaskId:S}=r;return x?t(n,{height:1,children:t(m,{dimColor:!0,children:"[Image data detected and sent to Claude]"})}):e(u,{flexDirection:"column",children:[""!==M?t(l,{content:M,verbose:c}):null,""!==b.trim()?t(l,{content:b,verbose:c,isError:!0}):null,""===M&&""===b.trim()?t(n,{height:1,children:t(m,{dimColor:!0,children:S?e(o,{children:["Running in the background"," ",t(s,{shortcut:"↓",action:"manage",parens:!0})]}):T?"Interrupted":j||"(No output)"})}):null,f?t(n,{children:t(a,{timeoutMs:f})}):null]})}export function renderToolUseErrorMessage(e,{verbose:o,progressMessagesForMessage:s,tools:n}){return t(r,{result:e,verbose:o})}
@@ -1 +1 @@
1
- import{basename as t,posix as e,resolve as r,sep as i}from"path";import{getCwd as s}from"../../utils/cwd.js";import{PS_TOKENIZER_DASH_CHARS as n}from"../../utils/powershell/parser.js";function resolveCwdReentry(e){if(!e.startsWith("../"))return e;const r=t(s()).toLowerCase();if(!r)return e;const i="../"+r+"/";let n=e;for(;n.startsWith(i);)n=n.slice(i.length);return n==="../"+r?".":n}function normalizeGitPathArg(t){let r=t;if(r.length>0&&(n.has(r[0])||"/"===r[0])){const t=r.indexOf(":",1);t>0&&(r=r.slice(t+1))}return r=r.replace(/^['"]|['"]$/g,""),r=r.replace(/`/g,""),r=r.replace(/^(?:[A-Za-z0-9_.]+\\){0,3}FileSystem::/i,""),r=r.replace(/^[A-Za-z]:(?![/\\])/,""),r=r.replace(/\\/g,"/"),r=r.split("/").map(t=>{if(""===t)return t;let e;do{if(e=t,"."===(t=t.replace(/ +$/,""))||".."===t)return t;t=t.replace(/\.+$/,"")}while(t!==e);return t||"."}).join("/"),r=e.normalize(r),r.startsWith("./")&&(r=r.slice(2)),r.toLowerCase()}const a=["head","objects","refs","hooks"];function resolveEscapingPathToCwdRelative(t){const e=s(),n=r(e,t),a=e.endsWith(i)?e:e+i,o=n.toLowerCase(),l=e.toLowerCase(),c=a.toLowerCase();return o===l?".":o.startsWith(c)?n.slice(a.length).replace(/\\/g,"/").toLowerCase():null}function matchesGitInternalPrefix(t){if("head"===t||".git"===t)return!0;if(t.startsWith(".git/")||/^git~\d+($|\/)/.test(t))return!0;for(const e of a)if("head"!==e&&(t===e||t.startsWith(e+"/")))return!0;return!1}export function isGitInternalPathPS(t){const e=resolveCwdReentry(normalizeGitPathArg(t));if(matchesGitInternalPrefix(e))return!0;if(e.startsWith("../")||e.startsWith("/")||/^[a-z]:/.test(e)){const t=resolveEscapingPathToCwdRelative(e);if(null!==t&&matchesGitInternalPrefix(t))return!0}return!1}export function isDotGitPathPS(t){const e=resolveCwdReentry(normalizeGitPathArg(t));if(matchesDotGitPrefix(e))return!0;if(e.startsWith("../")||e.startsWith("/")||/^[a-z]:/.test(e)){const t=resolveEscapingPathToCwdRelative(e);if(null!==t&&matchesDotGitPrefix(t))return!0}return!1}function matchesDotGitPrefix(t){return!(".git"!==t&&!t.startsWith(".git/"))||/^git~\d+($|\/)/.test(t)}
1
+ import{basename as t,posix as e,resolve as r,sep as s}from"path";import{getCwd as i}from"../../utils/cwd.js";import{PS_TOKENIZER_DASH_CHARS as a}from"../../utils/powershell/parser.js";function resolveCwdReentry(e){if(!e.startsWith("../"))return e;const r=t(i()).toLowerCase();if(!r)return e;const s="../"+r+"/";let a=e;for(;a.startsWith(s);)a=a.slice(s.length);return a==="../"+r?".":a}function normalizeGitPathArg(t){let r=t;if(r.length>0&&(a.has(r[0])||"/"===r[0])){const t=r.indexOf(":",1);t>0&&(r=r.slice(t+1))}return r=r.replace(/^['"]|['"]$/g,""),r=r.replace(/`/g,""),r=r.replace(/^(?:[A-Za-z0-9_.]+\\){0,3}FileSystem::/i,""),r=r.replace(/^[A-Za-z]:(?![/\\])/,""),r=r.replace(/\\/g,"/"),r=r.split("/").map(t=>{if(""===t)return t;let e;do{if(e=t,"."===(t=t.replace(/ +$/,""))||".."===t)return t;t=t.replace(/\.+$/,"")}while(t!==e);return t||"."}).join("/"),r=e.normalize(r),r.startsWith("./")&&(r=r.slice(2)),r.toLowerCase()}const n=["head","objects","refs","hooks"];function resolveEscapingPathToCwdRelative(t){const e=i(),a=r(e,t),n=e.endsWith(s)?e:e+s,o=a.toLowerCase(),l=e.toLowerCase(),c=n.toLowerCase();return o===l?".":o.startsWith(c)?a.slice(n.length).replace(/\\/g,"/").toLowerCase():null}function matchesGitInternalPrefix(t){if("head"===t||".git"===t)return!0;if(t.startsWith(".git/")||/^git~\d+($|\/)/.test(t))return!0;for(const e of n)if("head"!==e&&(t===e||t.startsWith(e+"/")))return!0;return!1}export function isGitInternalPathPS(t){const e=resolveCwdReentry(normalizeGitPathArg(t));if(matchesGitInternalPrefix(e))return!0;if(e.startsWith("../")||e.startsWith("/")||/^[a-z]:/.test(e)){const t=resolveEscapingPathToCwdRelative(e);if(null!==t&&matchesGitInternalPrefix(t))return!0}return!1}export function isDotGitPathPS(t){const e=resolveCwdReentry(normalizeGitPathArg(t));if(matchesDotGitPrefix(e))return!0;if(e.startsWith("../")||e.startsWith("/")||/^[a-z]:/.test(e)){const t=resolveEscapingPathToCwdRelative(e);if(null!==t&&matchesDotGitPrefix(t))return!0}return!1}function matchesDotGitPrefix(t){return!(".git"!==t&&!t.startsWith(".git/"))||/^git~\d+($|\/)/.test(t)}
@@ -1 +1 @@
1
- import{deriveSecurityFlags as e,getPipelineSegments as a,PS_TOKENIZER_DASH_CHARS as t}from"../../utils/powershell/parser.js";import{argLeaksValue as n,isAllowlistedPipelineTail as s,isCwdChangingCmdlet as o,isSafeOutputCommand as i,resolveToCanonical as r}from"./readOnlyValidation.js";const m=new Set(["set-content","add-content","remove-item","clear-content"]);function isAcceptEditsAllowedCmdlet(e){const a=r(e);return m.has(a)}const c=new Set(["symboliclink","junction","hardlink"]);function isItemTypeParamAbbrev(e){return e.length>=3&&"-itemtype".startsWith(e)||e.length>=3&&"-type".startsWith(e)}export function isSymlinkCreatingCommand(e){if("new-item"!==r(e.name))return!1;for(let a=0;a<e.args.length;a++){const n=e.args[a]??"";if(0===n.length)continue;const s=(t.has(n[0])||"/"===n[0]?"-"+n.slice(1):n).toLowerCase(),o=s.indexOf(":",1);if(!isItemTypeParamAbbrev((o>0?s.slice(0,o):s).replace(/`/g,"")))continue;const i=(o>0?s.slice(o+1):e.args[a+1]?.toLowerCase()??"").replace(/`/g,"").replace(/^['"]|['"]$/g,"");if(c.has(i))return!0}return!1}export function checkPermissionMode(t,r,m){if("bypassPermissions"===m.mode||"dontAsk"===m.mode)return{behavior:"passthrough",message:"Mode is handled in main permission flow"};if("acceptEdits"!==m.mode)return{behavior:"passthrough",message:"No mode-specific validation required"};if(!r.valid)return{behavior:"passthrough",message:"Cannot validate mode for unparsed command"};const c=e(r);if(c.hasSubExpressions||c.hasScriptBlocks||c.hasMemberInvocations||c.hasSplatting||c.hasAssignments||c.hasStopParsing||c.hasExpandableStrings)return{behavior:"passthrough",message:"Command contains subexpressions, script blocks, or member invocations that require approval"};const d=a(r);if(0===d.length)return{behavior:"passthrough",message:"No commands found to validate for acceptEdits mode"};if(d.reduce((e,a)=>e+a.commands.length,0)>1){let e=!1,a=!1,t=!1;for(const n of d)for(const s of n.commands)"CommandAst"===s.elementType&&(o(s.name)&&(e=!0),isSymlinkCreatingCommand(s)&&(a=!0),isAcceptEditsAllowedCmdlet(s.name)&&(t=!0));if(e&&t)return{behavior:"passthrough",message:"Compound command contains a directory-changing command (Set-Location/Push-Location/Pop-Location) with a write operation — cannot auto-allow because path validation uses stale cwd"};if(a)return{behavior:"passthrough",message:"Compound command creates a filesystem link (New-Item -ItemType SymbolicLink/Junction/HardLink) — cannot auto-allow because path validation cannot follow just-created links"}}for(const e of d){for(const a of e.commands){if("CommandAst"!==a.elementType)return{behavior:"passthrough",message:`Pipeline contains expression source (${a.elementType}) that cannot be statically validated`};if("application"===a.nameType)return{behavior:"passthrough",message:`Command '${a.name}' resolved from a path-like name and requires approval`};if(a.elementTypes)for(let e=1;e<a.elementTypes.length;e++){const t=a.elementTypes[e];if("StringConstant"!==t&&"Parameter"!==t)return{behavior:"passthrough",message:`Command argument has unvalidatable type (${t}) — variable paths cannot be statically resolved`};if("Parameter"===t){const t=a.args[e-1]??"",n=t.indexOf(":");if(n>0&&/[$(@{[]/.test(t.slice(n+1)))return{behavior:"passthrough",message:"Colon-bound parameter contains an expression that cannot be statically validated"}}}if(!i(a.name)&&!s(a,t.command)){if(!isAcceptEditsAllowedCmdlet(a.name))return{behavior:"passthrough",message:`No mode-specific handling for '${a.name}' in acceptEdits mode`};if(n(a.name,a))return{behavior:"passthrough",message:`Arguments in '${a.name}' cannot be statically validated in acceptEdits mode`}}}if(e.nestedCommands)for(const a of e.nestedCommands){if("CommandAst"!==a.elementType)return{behavior:"passthrough",message:`Nested expression element (${a.elementType}) cannot be statically validated`};if("application"===a.nameType)return{behavior:"passthrough",message:`Nested command '${a.name}' resolved from a path-like name and requires approval`};if(!i(a.name)&&!s(a,t.command)){if(!isAcceptEditsAllowedCmdlet(a.name))return{behavior:"passthrough",message:`No mode-specific handling for '${a.name}' in acceptEdits mode`};if(n(a.name,a))return{behavior:"passthrough",message:`Arguments in nested '${a.name}' cannot be statically validated in acceptEdits mode`}}}}return{behavior:"allow",updatedInput:t,decisionReason:{type:"mode",mode:"acceptEdits"}}}
1
+ import{deriveSecurityFlags as e,getPipelineSegments as a,PS_TOKENIZER_DASH_CHARS as t}from"../../utils/powershell/parser.js";import{argLeaksValue as s,isAllowlistedPipelineTail as n,isCwdChangingCmdlet as o,isSafeOutputCommand as i,resolveToCanonical as r}from"./readOnlyValidation.js";const m=new Set(["set-content","add-content","remove-item","clear-content"]);function isAcceptEditsAllowedCmdlet(e){const a=r(e);return m.has(a)}const c=new Set(["symboliclink","junction","hardlink"]);function isItemTypeParamAbbrev(e){return e.length>=3&&"-itemtype".startsWith(e)||e.length>=3&&"-type".startsWith(e)}export function isSymlinkCreatingCommand(e){if("new-item"!==r(e.name))return!1;for(let a=0;a<e.args.length;a++){const s=e.args[a]??"";if(0===s.length)continue;const n=(t.has(s[0])||"/"===s[0]?"-"+s.slice(1):s).toLowerCase(),o=n.indexOf(":",1);if(!isItemTypeParamAbbrev((o>0?n.slice(0,o):n).replace(/`/g,"")))continue;const i=(o>0?n.slice(o+1):e.args[a+1]?.toLowerCase()??"").replace(/`/g,"").replace(/^['"]|['"]$/g,"");if(c.has(i))return!0}return!1}export function checkPermissionMode(t,r,m){if("bypassPermissions"===m.mode||"dontAsk"===m.mode)return{behavior:"passthrough",message:"Mode is handled in main permission flow"};if("acceptEdits"!==m.mode)return{behavior:"passthrough",message:"No mode-specific validation required"};if(!r.valid)return{behavior:"passthrough",message:"Cannot validate mode for unparsed command"};const c=e(r);if(c.hasSubExpressions||c.hasScriptBlocks||c.hasMemberInvocations||c.hasSplatting||c.hasAssignments||c.hasStopParsing||c.hasExpandableStrings)return{behavior:"passthrough",message:"Command contains subexpressions, script blocks, or member invocations that require approval"};const l=a(r);if(0===l.length)return{behavior:"passthrough",message:"No commands found to validate for acceptEdits mode"};if(l.reduce((e,a)=>e+a.commands.length,0)>1){let e=!1,a=!1,t=!1;for(const s of l)for(const n of s.commands)"CommandAst"===n.elementType&&(o(n.name)&&(e=!0),isSymlinkCreatingCommand(n)&&(a=!0),isAcceptEditsAllowedCmdlet(n.name)&&(t=!0));if(e&&t)return{behavior:"passthrough",message:"Compound command contains a directory-changing command (Set-Location/Push-Location/Pop-Location) with a write operation — cannot auto-allow because path validation uses stale cwd"};if(a)return{behavior:"passthrough",message:"Compound command creates a filesystem link (New-Item -ItemType SymbolicLink/Junction/HardLink) — cannot auto-allow because path validation cannot follow just-created links"}}for(const e of l){for(const a of e.commands){if("CommandAst"!==a.elementType)return{behavior:"passthrough",message:`Pipeline contains expression source (${a.elementType}) that cannot be statically validated`};if("application"===a.nameType)return{behavior:"passthrough",message:`Command '${a.name}' resolved from a path-like name and requires approval`};if(a.elementTypes)for(let e=1;e<a.elementTypes.length;e++){const t=a.elementTypes[e];if("StringConstant"!==t&&"Parameter"!==t)return{behavior:"passthrough",message:`Command argument has unvalidatable type (${t}) — variable paths cannot be statically resolved`};if("Parameter"===t){const t=a.args[e-1]??"",s=t.indexOf(":");if(s>0&&/[$(@{[]/.test(t.slice(s+1)))return{behavior:"passthrough",message:"Colon-bound parameter contains an expression that cannot be statically validated"}}}if(!i(a.name)&&!n(a,t.command)){if(!isAcceptEditsAllowedCmdlet(a.name))return{behavior:"passthrough",message:`No mode-specific handling for '${a.name}' in acceptEdits mode`};if(s(a.name,a))return{behavior:"passthrough",message:`Arguments in '${a.name}' cannot be statically validated in acceptEdits mode`}}}if(e.nestedCommands)for(const a of e.nestedCommands){if("CommandAst"!==a.elementType)return{behavior:"passthrough",message:`Nested expression element (${a.elementType}) cannot be statically validated`};if("application"===a.nameType)return{behavior:"passthrough",message:`Nested command '${a.name}' resolved from a path-like name and requires approval`};if(!i(a.name)&&!n(a,t.command)){if(!isAcceptEditsAllowedCmdlet(a.name))return{behavior:"passthrough",message:`No mode-specific handling for '${a.name}' in acceptEdits mode`};if(s(a.name,a))return{behavior:"passthrough",message:`Arguments in nested '${a.name}' cannot be statically validated in acceptEdits mode`}}}}return{behavior:"allow",updatedInput:t,decisionReason:{type:"mode",mode:"acceptEdits"}}}
@@ -1 +1 @@
1
- import{homedir as e}from"os";import{isAbsolute as a,resolve as t}from"path";import{getCwd as n}from"../../utils/cwd.js";import{getFsImplementation as r,safeResolvePath as o}from"../../utils/fsOperations.js";import{containsPathTraversal as i,getDirectoryForPath as s}from"../../utils/path.js";import{allWorkingDirectories as l,checkEditableInternalPath as p,checkPathSafetyForAutoEdit as c,checkReadableInternalPath as h,matchingRuleForInput as d,pathInAllowedWorkingPath as u}from"../../utils/permissions/filesystem.js";import{createReadRuleSuggestion as m}from"../../utils/permissions/PermissionUpdate.js";import{isDangerousRemovalPath as f,isPathInSandboxWriteAllowlist as w}from"../../utils/permissions/pathValidation.js";import{getPlatform as y}from"../../utils/platform.js";import{isNullRedirectionTarget as k,isPowerShellParameter as v}from"../../utils/powershell/parser.js";import{COMMON_SWITCHES as P,COMMON_VALUE_PARAMS as g}from"./commonParameters.js";import{resolveToCanonical as b}from"./readOnlyValidation.js";const x=/[*?[\]]/,R={"set-content":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-force","-whatif","-confirm","-usetransaction","-nonewline","-asbytestream"],knownValueParams:["-value","-filter","-include","-exclude","-credential","-encoding","-stream"]},"add-content":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-force","-whatif","-confirm","-usetransaction","-nonewline","-asbytestream"],knownValueParams:["-value","-filter","-include","-exclude","-credential","-encoding","-stream"]},"remove-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-recurse","-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-stream"]},"clear-content":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-stream"]},"out-file":{operationType:"write",pathParams:["-filepath","-path","-literalpath","-pspath","-lp"],knownSwitches:["-append","-force","-noclobber","-nonewline","-whatif","-confirm"],knownValueParams:["-inputobject","-encoding","-width"]},"tee-object":{operationType:"write",pathParams:["-filepath","-path","-literalpath","-pspath","-lp"],knownSwitches:["-append"],knownValueParams:["-inputobject","-variable","-encoding"]},"export-csv":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-append","-force","-noclobber","-notypeinformation","-includetypeinformation","-useculture","-noheader","-whatif","-confirm"],knownValueParams:["-inputobject","-delimiter","-encoding","-quotefields","-usequotes"]},"export-clixml":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-noclobber","-whatif","-confirm"],knownValueParams:["-inputobject","-depth","-encoding"]},"new-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],leafOnlyPathParams:["-name"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-itemtype","-value","-credential","-type"]},"copy-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destination"],knownSwitches:["-container","-force","-passthru","-recurse","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-fromsession","-tosession"]},"move-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destination"],knownSwitches:["-force","-passthru","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential"]},"rename-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-passthru","-whatif","-confirm","-usetransaction"],knownValueParams:["-newname","-credential","-filter","-include","-exclude"]},"set-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-passthru","-whatif","-confirm","-usetransaction"],knownValueParams:["-value","-credential","-filter","-include","-exclude"]},"get-content":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-usetransaction","-wait","-raw","-asbytestream"],knownValueParams:["-readcount","-totalcount","-tail","-first","-head","-last","-filter","-include","-exclude","-credential","-delimiter","-encoding","-stream"]},"get-childitem":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-recurse","-force","-name","-usetransaction","-followsymlink","-directory","-file","-hidden","-readonly","-system"],knownValueParams:["-filter","-include","-exclude","-depth","-attributes","-credential"]},"get-item":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-stream"]},"get-itemproperty":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-usetransaction"],knownValueParams:["-name","-filter","-include","-exclude","-credential"]},"get-itempropertyvalue":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-usetransaction"],knownValueParams:["-name","-filter","-include","-exclude","-credential"]},"get-filehash":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:[],knownValueParams:["-algorithm","-inputstream"]},"get-acl":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-audit","-allcentralaccesspolicies","-usetransaction"],knownValueParams:["-inputobject","-filter","-include","-exclude"]},"format-hex":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-raw"],knownValueParams:["-inputobject","-encoding","-count","-offset"]},"test-path":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-isvalid","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-pathtype","-credential","-olderthan","-newerthan"]},"resolve-path":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-relative","-usetransaction","-force"],knownValueParams:["-credential","-relativebasepath"]},"convert-path":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-usetransaction"],knownValueParams:[]},"select-string":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-simplematch","-casesensitive","-quiet","-list","-notmatch","-allmatches","-noemphasis","-raw"],knownValueParams:["-inputobject","-pattern","-include","-exclude","-encoding","-context","-culture"]},"set-location":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-usetransaction"],knownValueParams:["-stackname"]},"push-location":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-usetransaction"],knownValueParams:["-stackname"]},"pop-location":{operationType:"read",pathParams:[],knownSwitches:["-passthru","-usetransaction"],knownValueParams:["-stackname"]},"select-xml":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:[],knownValueParams:["-xml","-content","-xpath","-namespace"]},"get-winevent":{operationType:"read",pathParams:["-path"],knownSwitches:["-force","-oldest"],knownValueParams:["-listlog","-logname","-listprovider","-providername","-maxevents","-computername","-credential","-filterxpath","-filterxml","-filterhashtable"]},"invoke-webrequest":{operationType:"write",pathParams:["-outfile","-infile"],positionalSkip:1,optionalWrite:!0,knownSwitches:["-allowinsecureredirect","-allowunencryptedauthentication","-disablekeepalive","-nobodyprogress","-passthru","-preservefileauthorizationmetadata","-resume","-skipcertificatecheck","-skipheadervalidation","-skiphttperrorcheck","-usebasicparsing","-usedefaultcredentials"],knownValueParams:["-uri","-method","-body","-contenttype","-headers","-maximumredirection","-maximumretrycount","-proxy","-proxycredential","-retryintervalsec","-sessionvariable","-timeoutsec","-token","-transferencoding","-useragent","-websession","-credential","-authentication","-certificate","-certificatethumbprint","-form","-httpversion"]},"invoke-restmethod":{operationType:"write",pathParams:["-outfile","-infile"],positionalSkip:1,optionalWrite:!0,knownSwitches:["-allowinsecureredirect","-allowunencryptedauthentication","-disablekeepalive","-followrellink","-nobodyprogress","-passthru","-preservefileauthorizationmetadata","-resume","-skipcertificatecheck","-skipheadervalidation","-skiphttperrorcheck","-usebasicparsing","-usedefaultcredentials"],knownValueParams:["-uri","-method","-body","-contenttype","-headers","-maximumfollowrellink","-maximumredirection","-maximumretrycount","-proxy","-proxycredential","-responseheaderstvariable","-retryintervalsec","-sessionvariable","-statuscodevariable","-timeoutsec","-token","-transferencoding","-useragent","-websession","-credential","-authentication","-certificate","-certificatethumbprint","-form","-httpversion"]},"expand-archive":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destinationpath"],knownSwitches:["-force","-passthru","-whatif","-confirm"],knownValueParams:[]},"compress-archive":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destinationpath"],knownSwitches:["-force","-update","-passthru","-whatif","-confirm"],knownValueParams:["-compressionlevel"]},"set-itemproperty":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-name","-value","-type","-filter","-include","-exclude","-credential","-inputobject"]},"new-itemproperty":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-name","-value","-propertytype","-type","-filter","-include","-exclude","-credential"]},"remove-itemproperty":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-name","-filter","-include","-exclude","-credential"]},"clear-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential"]},"export-alias":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-append","-force","-noclobber","-passthru","-whatif","-confirm"],knownValueParams:["-name","-description","-scope","-as"]}};function matchesParam(e,a){for(const t of a)if(t===e||e.length>1&&t.startsWith(e))return!0;return!1}function hasComplexColonValue(e){return e.includes(",")||e.startsWith("(")||e.startsWith("[")||e.includes("`")||e.includes("@(")||e.startsWith("@{")||e.includes("$")}function formatDirectoryList(e){const a=e.length;if(a<=5)return e.map(e=>`'${e}'`).join(", ");return`${e.slice(0,5).map(e=>`'${e}'`).join(", ")}, and ${a-5} more`}function expandTilde(a){return"~"===a||a.startsWith("~/")||a.startsWith("~\\")?e()+a.slice(1):a}export function isDangerousRemovalRawPath(e){const a=expandTilde(e.replace(/^['"]|['"]$/g,"")).replace(/\\/g,"/");return f(a)}export function dangerousRemovalDeny(e){return{behavior:"deny",message:`Remove-Item on system path '${e}' is blocked. This path is protected from removal.`,decisionReason:{type:"other",reason:"Removal targets a protected system path"}}}function isPathAllowed(e,a,t,n){const r="read"===t?"read":"edit",o=d(e,a,r,"deny");if(null!==o)return{allowed:!1,decisionReason:{type:"rule",rule:o}};if("read"!==t){const a=p(e,{});if("allow"===a.behavior)return{allowed:!0,decisionReason:a.decisionReason}}if("read"!==t){const a=c(e,n);if(!a.safe)return{allowed:!1,decisionReason:{type:"safetyCheck",reason:a.message,classifierApprovable:a.classifierApprovable}}}const i=u(e,a,n);if(i&&("read"===t||"acceptEdits"===a.mode))return{allowed:!0};if("read"===t){const a=h(e,{});if("allow"===a.behavior)return{allowed:!0,decisionReason:a.decisionReason}}if("read"!==t&&!i&&w(e))return{allowed:!0,decisionReason:{type:"other",reason:"Path is in sandbox write allowlist"}};const s=d(e,a,r,"allow");return null!==s?{allowed:!0,decisionReason:{type:"rule",rule:s}}:{allowed:!1}}function checkDenyRuleForGuessedPath(e,n,i,s){if(!e||e.includes("\0"))return null;const l=expandTilde(e),p=a(l)?l:t(n,l),{resolvedPath:c}=o(r(),p),h=d(c,i,"read"===s?"read":"edit","deny");return h?{resolvedPath:c,rule:h}:null}function validatePath(e,n,s,l){const p=expandTilde(e.replace(/^['"]|['"]$/g,"")).replace(/\\/g,"/");if(p.includes("`")){const e=checkDenyRuleForGuessedPath(p.replace(/`/g,""),n,s,l);return e?{allowed:!1,resolvedPath:e.resolvedPath,decisionReason:{type:"rule",rule:e.rule}}:{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Backtick escape characters in paths cannot be statically validated and require manual approval"}}}if(p.includes("::")){const e=checkDenyRuleForGuessedPath(p.slice(p.indexOf("::")+2),n,s,l);return e?{allowed:!1,resolvedPath:e.resolvedPath,decisionReason:{type:"rule",rule:e.rule}}:{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Module-qualified provider paths (::) cannot be statically validated and require manual approval"}}}if(p.startsWith("//")||/DavWWWRoot/i.test(p)||/@SSL@/i.test(p))return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"UNC paths are blocked because they can trigger network requests and credential leakage"}};if(p.includes("$")||p.includes("%"))return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Variable expansion syntax in paths requires manual approval"}};if(("windows"===y()?/^[a-z0-9]{2,}:/i:/^[a-z0-9]+:/i).test(p))return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:`Path '${p}' uses a non-filesystem provider and requires manual approval`}};if(x.test(p)){if("write"===l||"create"===l)return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Glob patterns are not allowed in write operations. Please specify an exact file path."}};if(i(p)){const e=a(p)?p:t(n,p),{resolvedPath:i,isCanonical:c}=o(r(),e),h=isPathAllowed(i,s,l,c?[i]:void 0);return{allowed:h.allowed,resolvedPath:i,decisionReason:h.decisionReason}}const e=function(e){const a=e.match(x);if(!a||void 0===a.index)return e;const t=e.substring(0,a.index),n=Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\"));return-1===n?".":t.substring(0,n+1)||"/"}(p),c=a(e)?e:t(n,e),{resolvedPath:h}=o(r(),c),u=d(h,s,"read"===l?"read":"edit","deny");return null!==u?{allowed:!1,resolvedPath:h,decisionReason:{type:"rule",rule:u}}:{allowed:!1,resolvedPath:h,decisionReason:{type:"other",reason:"Glob patterns in paths cannot be statically validated — symlinks inside the glob expansion are not examined. Requires manual approval."}}}const c=a(p)?p:t(n,p),{resolvedPath:h,isCanonical:u}=o(r(),c),m=isPathAllowed(h,s,l,u?[h]:void 0);return{allowed:m.allowed,resolvedPath:h,decisionReason:m.decisionReason}}const T=new Set(["StringConstant","Parameter"]);function extractPathsFromCommand(e){const a=b(e.name),t=R[a];if(!t)return{paths:[],operationType:"read",hasUnvalidatablePathArg:!1,optionalWrite:!1};const n=[...t.knownSwitches,...P],r=[...t.knownValueParams,...g],o=[],i=e.args,s=e.elementTypes;let l=!1,p=0;const c=t.positionalSkip??0;function checkArgElementType(e){if(!s)return;const a=s[e+1];a&&!T.has(a)&&(l=!0)}for(let e=0;e<i.length;e++){const a=i[e];if(!a)continue;const h=s?s[e+1]:void 0;if(v(a,h)){const p="-"+a.slice(1),c=p.indexOf(":",1),h=(c>0?p.substring(0,c):p).toLowerCase();if(matchesParam(h,t.pathParams)){let t;if(c>0){const e=a.substring(c+1);hasComplexColonValue(e)?l=!0:t=e}else{const a=i[e+1],n=s?s[e+2]:void 0;a&&!v(a,n)&&(t=a,checkArgElementType(e+1),e++)}t&&o.push(t)}else if(t.leafOnlyPathParams&&matchesParam(h,t.leafOnlyPathParams)){let t;if(c>0){const e=a.substring(c+1);hasComplexColonValue(e)?l=!0:t=e}else{const a=i[e+1],n=s?s[e+2]:void 0;a&&!v(a,n)&&(t=a,checkArgElementType(e+1),e++)}void 0!==t&&(t.includes("/")||t.includes("\\")||"."===t||".."===t?l=!0:o.push(t))}else if(matchesParam(h,n));else if(matchesParam(h,r))if(c>0){hasComplexColonValue(a.substring(c+1))&&(l=!0)}else{const a=i[e+1],t=s?s[e+2]:void 0;a&&!v(a,t)&&(checkArgElementType(e+1),e++)}else if(l=!0,c>0){const e=a.substring(c+1);hasComplexColonValue(e)||o.push(e)}continue}p<c?p++:(p++,checkArgElementType(e),o.push(a))}return{paths:o,operationType:t.operationType,hasUnvalidatablePathArg:l,optionalWrite:t.optionalWrite??!1}}export function checkPathConstraints(e,a,t,n=!1){if(!a.valid)return{behavior:"passthrough",message:"Cannot validate paths for unparsed command"};let r;for(const e of a.statements){const a=checkPathConstraintsForStatement(e,t,n);if("deny"===a.behavior)return a;"ask"!==a.behavior||r||(r=a)}return r??{behavior:"passthrough",message:"All path constraints validated successfully"}}function checkPathConstraintsForStatement(e,a,t=!1){const r=n();let o;t&&(o={behavior:"ask",message:"Compound command changes working directory (Set-Location/Push-Location/Pop-Location/New-PSDrive) — relative paths cannot be validated against the original cwd and require manual approval",decisionReason:{type:"other",reason:"Compound command contains cd with path operation — manual approval required to prevent path resolution bypass"}});let i,p=!1;for(const t of e.commands){if("CommandAst"!==t.elementType){p=!0,i=t.text;continue}const{paths:e,operationType:n,hasUnvalidatablePathArg:c,optionalWrite:h}=extractPathsFromCommand(t);if(p){const e=b(t.name);if(void 0!==i){const t=checkDenyRuleForGuessedPath(i.replace(/^['"]|['"]$/g,""),r,a,n);if(t)return{behavior:"deny",message:`${e} targeting '${t.resolvedPath}' was blocked by a deny rule`,decisionReason:{type:"rule",rule:t.rule}}}o??={behavior:"ask",message:`${e} receives its path from a pipeline expression source that cannot be statically validated and requires manual approval`}}if(c){const e=b(t.name);o??={behavior:"ask",message:`${e} uses a parameter or complex path expression (array literal, subexpression, unknown parameter, etc.) that cannot be statically validated and requires manual approval`}}if("read"!==n&&!h&&0===e.length&&R[b(t.name)]){const e=b(t.name);o??={behavior:"ask",message:`${e} is a write operation but no target path could be determined; requires manual approval`};continue}const d="remove-item"===b(t.name);for(const i of e){if(d&&isDangerousRemovalRawPath(i))return dangerousRemovalDeny(i);const{allowed:e,resolvedPath:p,decisionReason:c}=validatePath(i,r,a,n);if(d&&f(p))return dangerousRemovalDeny(p);if(!e){const e=b(t.name),r=formatDirectoryList(Array.from(l(a))),i="other"===c?.type||"safetyCheck"===c?.type?c.reason:`${e} targeting '${p}' was blocked. For security, Context Code may only access files in the allowed working directories for this session: ${r}.`;if("rule"===c?.type)return{behavior:"deny",message:i,decisionReason:c};const h=[];if(p)if("read"===n){const e=m(s(p),"session");e&&h.push(e)}else h.push({type:"addDirectories",directories:[s(p)],destination:"session"});"write"!==n&&"create"!==n||h.push({type:"setMode",mode:"acceptEdits",destination:"session"}),o??={behavior:"ask",message:i,blockedPath:p,decisionReason:c,suggestions:h}}}}if(e.nestedCommands)for(const t of e.nestedCommands){const{paths:e,operationType:n,hasUnvalidatablePathArg:i,optionalWrite:c}=extractPathsFromCommand(t);if(i){const e=b(t.name);o??={behavior:"ask",message:`${e} uses a parameter or complex path expression (array literal, subexpression, unknown parameter, etc.) that cannot be statically validated and requires manual approval`}}if("read"!==n&&!c&&0===e.length&&R[b(t.name)]){const e=b(t.name);o??={behavior:"ask",message:`${e} is a write operation but no target path could be determined; requires manual approval`};continue}const h="remove-item"===b(t.name);for(const i of e){if(h&&isDangerousRemovalRawPath(i))return dangerousRemovalDeny(i);const{allowed:e,resolvedPath:p,decisionReason:c}=validatePath(i,r,a,n);if(h&&f(p))return dangerousRemovalDeny(p);if(!e){const e=b(t.name),r=formatDirectoryList(Array.from(l(a))),i="other"===c?.type||"safetyCheck"===c?.type?c.reason:`${e} targeting '${p}' was blocked. For security, Context Code may only access files in the allowed working directories for this session: ${r}.`;if("rule"===c?.type)return{behavior:"deny",message:i,decisionReason:c};const h=[];if(p)if("read"===n){const e=m(s(p),"session");e&&h.push(e)}else h.push({type:"addDirectories",directories:[s(p)],destination:"session"});"write"!==n&&"create"!==n||h.push({type:"setMode",mode:"acceptEdits",destination:"session"}),o??={behavior:"ask",message:i,blockedPath:p,decisionReason:c,suggestions:h}}}p&&(o??={behavior:"ask",message:`${b(t.name)} appears inside a control-flow or chain statement where piped expression sources cannot be statically validated and requires manual approval`})}if(e.nestedCommands)for(const t of e.nestedCommands)if(t.redirections)for(const e of t.redirections){if(e.isMerging)continue;if(!e.target)continue;if(k(e.target))continue;const{allowed:t,resolvedPath:n,decisionReason:i}=validatePath(e.target,r,a,"create");if(!t){const e=formatDirectoryList(Array.from(l(a))),t="other"===i?.type||"safetyCheck"===i?.type?i.reason:`Output redirection to '${n}' was blocked. For security, Context Code may only write to files in the allowed working directories for this session: ${e}.`;if("rule"===i?.type)return{behavior:"deny",message:t,decisionReason:i};o??={behavior:"ask",message:t,blockedPath:n,decisionReason:i,suggestions:[{type:"addDirectories",directories:[s(n)],destination:"session"}]}}}if(e.redirections)for(const t of e.redirections){if(t.isMerging)continue;if(!t.target)continue;if(k(t.target))continue;const{allowed:e,resolvedPath:n,decisionReason:i}=validatePath(t.target,r,a,"create");if(!e){const e=formatDirectoryList(Array.from(l(a))),t="other"===i?.type||"safetyCheck"===i?.type?i.reason:`Output redirection to '${n}' was blocked. For security, Context Code may only write to files in the allowed working directories for this session: ${e}.`;if("rule"===i?.type)return{behavior:"deny",message:t,decisionReason:i};o??={behavior:"ask",message:t,blockedPath:n,decisionReason:i,suggestions:[{type:"addDirectories",directories:[s(n)],destination:"session"}]}}}return o??{behavior:"passthrough",message:"All path constraints validated successfully"}}
1
+ import{homedir as e}from"os";import{isAbsolute as a,resolve as t}from"path";import{getCwd as n}from"../../utils/cwd.js";import{getFsImplementation as r,safeResolvePath as o}from"../../utils/fsOperations.js";import{containsPathTraversal as s,getDirectoryForPath as i}from"../../utils/path.js";import{allWorkingDirectories as l,checkEditableInternalPath as p,checkPathSafetyForAutoEdit as c,checkReadableInternalPath as h,matchingRuleForInput as d,pathInAllowedWorkingPath as u}from"../../utils/permissions/filesystem.js";import{createReadRuleSuggestion as m}from"../../utils/permissions/PermissionUpdate.js";import{isDangerousRemovalPath as f,isPathInSandboxWriteAllowlist as w}from"../../utils/permissions/pathValidation.js";import{getPlatform as y}from"../../utils/platform.js";import{isNullRedirectionTarget as P,isPowerShellParameter as k}from"../../utils/powershell/parser.js";import{COMMON_SWITCHES as v,COMMON_VALUE_PARAMS as g}from"./commonParameters.js";import{resolveToCanonical as b}from"./readOnlyValidation.js";const x=/[*?[\]]/,R={"set-content":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-force","-whatif","-confirm","-usetransaction","-nonewline","-asbytestream"],knownValueParams:["-value","-filter","-include","-exclude","-credential","-encoding","-stream"]},"add-content":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-force","-whatif","-confirm","-usetransaction","-nonewline","-asbytestream"],knownValueParams:["-value","-filter","-include","-exclude","-credential","-encoding","-stream"]},"remove-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-recurse","-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-stream"]},"clear-content":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-stream"]},"out-file":{operationType:"write",pathParams:["-filepath","-path","-literalpath","-pspath","-lp"],knownSwitches:["-append","-force","-noclobber","-nonewline","-whatif","-confirm"],knownValueParams:["-inputobject","-encoding","-width"]},"tee-object":{operationType:"write",pathParams:["-filepath","-path","-literalpath","-pspath","-lp"],knownSwitches:["-append"],knownValueParams:["-inputobject","-variable","-encoding"]},"export-csv":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-append","-force","-noclobber","-notypeinformation","-includetypeinformation","-useculture","-noheader","-whatif","-confirm"],knownValueParams:["-inputobject","-delimiter","-encoding","-quotefields","-usequotes"]},"export-clixml":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-noclobber","-whatif","-confirm"],knownValueParams:["-inputobject","-depth","-encoding"]},"new-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],leafOnlyPathParams:["-name"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-itemtype","-value","-credential","-type"]},"copy-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destination"],knownSwitches:["-container","-force","-passthru","-recurse","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-fromsession","-tosession"]},"move-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destination"],knownSwitches:["-force","-passthru","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential"]},"rename-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-passthru","-whatif","-confirm","-usetransaction"],knownValueParams:["-newname","-credential","-filter","-include","-exclude"]},"set-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-passthru","-whatif","-confirm","-usetransaction"],knownValueParams:["-value","-credential","-filter","-include","-exclude"]},"get-content":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-usetransaction","-wait","-raw","-asbytestream"],knownValueParams:["-readcount","-totalcount","-tail","-first","-head","-last","-filter","-include","-exclude","-credential","-delimiter","-encoding","-stream"]},"get-childitem":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-recurse","-force","-name","-usetransaction","-followsymlink","-directory","-file","-hidden","-readonly","-system"],knownValueParams:["-filter","-include","-exclude","-depth","-attributes","-credential"]},"get-item":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential","-stream"]},"get-itemproperty":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-usetransaction"],knownValueParams:["-name","-filter","-include","-exclude","-credential"]},"get-itempropertyvalue":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-usetransaction"],knownValueParams:["-name","-filter","-include","-exclude","-credential"]},"get-filehash":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:[],knownValueParams:["-algorithm","-inputstream"]},"get-acl":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-audit","-allcentralaccesspolicies","-usetransaction"],knownValueParams:["-inputobject","-filter","-include","-exclude"]},"format-hex":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-raw"],knownValueParams:["-inputobject","-encoding","-count","-offset"]},"test-path":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-isvalid","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-pathtype","-credential","-olderthan","-newerthan"]},"resolve-path":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-relative","-usetransaction","-force"],knownValueParams:["-credential","-relativebasepath"]},"convert-path":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-usetransaction"],knownValueParams:[]},"select-string":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-simplematch","-casesensitive","-quiet","-list","-notmatch","-allmatches","-noemphasis","-raw"],knownValueParams:["-inputobject","-pattern","-include","-exclude","-encoding","-context","-culture"]},"set-location":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-usetransaction"],knownValueParams:["-stackname"]},"push-location":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-usetransaction"],knownValueParams:["-stackname"]},"pop-location":{operationType:"read",pathParams:[],knownSwitches:["-passthru","-usetransaction"],knownValueParams:["-stackname"]},"select-xml":{operationType:"read",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:[],knownValueParams:["-xml","-content","-xpath","-namespace"]},"get-winevent":{operationType:"read",pathParams:["-path"],knownSwitches:["-force","-oldest"],knownValueParams:["-listlog","-logname","-listprovider","-providername","-maxevents","-computername","-credential","-filterxpath","-filterxml","-filterhashtable"]},"invoke-webrequest":{operationType:"write",pathParams:["-outfile","-infile"],positionalSkip:1,optionalWrite:!0,knownSwitches:["-allowinsecureredirect","-allowunencryptedauthentication","-disablekeepalive","-nobodyprogress","-passthru","-preservefileauthorizationmetadata","-resume","-skipcertificatecheck","-skipheadervalidation","-skiphttperrorcheck","-usebasicparsing","-usedefaultcredentials"],knownValueParams:["-uri","-method","-body","-contenttype","-headers","-maximumredirection","-maximumretrycount","-proxy","-proxycredential","-retryintervalsec","-sessionvariable","-timeoutsec","-token","-transferencoding","-useragent","-websession","-credential","-authentication","-certificate","-certificatethumbprint","-form","-httpversion"]},"invoke-restmethod":{operationType:"write",pathParams:["-outfile","-infile"],positionalSkip:1,optionalWrite:!0,knownSwitches:["-allowinsecureredirect","-allowunencryptedauthentication","-disablekeepalive","-followrellink","-nobodyprogress","-passthru","-preservefileauthorizationmetadata","-resume","-skipcertificatecheck","-skipheadervalidation","-skiphttperrorcheck","-usebasicparsing","-usedefaultcredentials"],knownValueParams:["-uri","-method","-body","-contenttype","-headers","-maximumfollowrellink","-maximumredirection","-maximumretrycount","-proxy","-proxycredential","-responseheaderstvariable","-retryintervalsec","-sessionvariable","-statuscodevariable","-timeoutsec","-token","-transferencoding","-useragent","-websession","-credential","-authentication","-certificate","-certificatethumbprint","-form","-httpversion"]},"expand-archive":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destinationpath"],knownSwitches:["-force","-passthru","-whatif","-confirm"],knownValueParams:[]},"compress-archive":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp","-destinationpath"],knownSwitches:["-force","-update","-passthru","-whatif","-confirm"],knownValueParams:["-compressionlevel"]},"set-itemproperty":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-passthru","-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-name","-value","-type","-filter","-include","-exclude","-credential","-inputobject"]},"new-itemproperty":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-name","-value","-propertytype","-type","-filter","-include","-exclude","-credential"]},"remove-itemproperty":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-name","-filter","-include","-exclude","-credential"]},"clear-item":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-force","-whatif","-confirm","-usetransaction"],knownValueParams:["-filter","-include","-exclude","-credential"]},"export-alias":{operationType:"write",pathParams:["-path","-literalpath","-pspath","-lp"],knownSwitches:["-append","-force","-noclobber","-passthru","-whatif","-confirm"],knownValueParams:["-name","-description","-scope","-as"]}};function matchesParam(e,a){for(const t of a)if(t===e||e.length>1&&t.startsWith(e))return!0;return!1}function hasComplexColonValue(e){return e.includes(",")||e.startsWith("(")||e.startsWith("[")||e.includes("`")||e.includes("@(")||e.startsWith("@{")||e.includes("$")}function formatDirectoryList(e){const a=e.length;return a<=5?e.map(e=>`'${e}'`).join(", "):`${e.slice(0,5).map(e=>`'${e}'`).join(", ")}, and ${a-5} more`}function expandTilde(a){return"~"===a||a.startsWith("~/")||a.startsWith("~\\")?e()+a.slice(1):a}export function isDangerousRemovalRawPath(e){const a=expandTilde(e.replace(/^['"]|['"]$/g,"")).replace(/\\/g,"/");return f(a)}export function dangerousRemovalDeny(e){return{behavior:"deny",message:`Remove-Item on system path '${e}' is blocked. This path is protected from removal.`,decisionReason:{type:"other",reason:"Removal targets a protected system path"}}}function isPathAllowed(e,a,t,n){const r="read"===t?"read":"edit",o=d(e,a,r,"deny");if(null!==o)return{allowed:!1,decisionReason:{type:"rule",rule:o}};if("read"!==t){const a=p(e,{});if("allow"===a.behavior)return{allowed:!0,decisionReason:a.decisionReason}}if("read"!==t){const a=c(e,n);if(!a.safe)return{allowed:!1,decisionReason:{type:"safetyCheck",reason:a.message,classifierApprovable:a.classifierApprovable}}}const s=u(e,a,n);if(s&&("read"===t||"acceptEdits"===a.mode))return{allowed:!0};if("read"===t){const a=h(e,{});if("allow"===a.behavior)return{allowed:!0,decisionReason:a.decisionReason}}if("read"!==t&&!s&&w(e))return{allowed:!0,decisionReason:{type:"other",reason:"Path is in sandbox write allowlist"}};const i=d(e,a,r,"allow");return null!==i?{allowed:!0,decisionReason:{type:"rule",rule:i}}:{allowed:!1}}function checkDenyRuleForGuessedPath(e,n,s,i){if(!e||e.includes("\0"))return null;const l=expandTilde(e),p=a(l)?l:t(n,l),{resolvedPath:c}=o(r(),p),h=d(c,s,"read"===i?"read":"edit","deny");return h?{resolvedPath:c,rule:h}:null}function validatePath(e,n,i,l){const p=expandTilde(e.replace(/^['"]|['"]$/g,"")).replace(/\\/g,"/");if(p.includes("`")){const e=checkDenyRuleForGuessedPath(p.replace(/`/g,""),n,i,l);return e?{allowed:!1,resolvedPath:e.resolvedPath,decisionReason:{type:"rule",rule:e.rule}}:{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Backtick escape characters in paths cannot be statically validated and require manual approval"}}}if(p.includes("::")){const e=checkDenyRuleForGuessedPath(p.slice(p.indexOf("::")+2),n,i,l);return e?{allowed:!1,resolvedPath:e.resolvedPath,decisionReason:{type:"rule",rule:e.rule}}:{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Module-qualified provider paths (::) cannot be statically validated and require manual approval"}}}if(p.startsWith("//")||/DavWWWRoot/i.test(p)||/@SSL@/i.test(p))return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"UNC paths are blocked because they can trigger network requests and credential leakage"}};if(p.includes("$")||p.includes("%"))return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Variable expansion syntax in paths requires manual approval"}};if(("windows"===y()?/^[a-z0-9]{2,}:/i:/^[a-z0-9]+:/i).test(p))return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:`Path '${p}' uses a non-filesystem provider and requires manual approval`}};if(x.test(p)){if("write"===l||"create"===l)return{allowed:!1,resolvedPath:p,decisionReason:{type:"other",reason:"Glob patterns are not allowed in write operations. Please specify an exact file path."}};if(s(p)){const e=a(p)?p:t(n,p),{resolvedPath:s,isCanonical:c}=o(r(),e),h=isPathAllowed(s,i,l,c?[s]:void 0);return{allowed:h.allowed,resolvedPath:s,decisionReason:h.decisionReason}}const e=function(e){const a=e.match(x);if(!a||void 0===a.index)return e;const t=e.substring(0,a.index),n=Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\"));return-1===n?".":t.substring(0,n+1)||"/"}(p),c=a(e)?e:t(n,e),{resolvedPath:h}=o(r(),c),u=d(h,i,"read"===l?"read":"edit","deny");return null!==u?{allowed:!1,resolvedPath:h,decisionReason:{type:"rule",rule:u}}:{allowed:!1,resolvedPath:h,decisionReason:{type:"other",reason:"Glob patterns in paths cannot be statically validated — symlinks inside the glob expansion are not examined. Requires manual approval."}}}const c=a(p)?p:t(n,p),{resolvedPath:h,isCanonical:u}=o(r(),c),m=isPathAllowed(h,i,l,u?[h]:void 0);return{allowed:m.allowed,resolvedPath:h,decisionReason:m.decisionReason}}const T=new Set(["StringConstant","Parameter"]);function extractPathsFromCommand(e){const a=b(e.name),t=R[a];if(!t)return{paths:[],operationType:"read",hasUnvalidatablePathArg:!1,optionalWrite:!1};const n=[...t.knownSwitches,...v],r=[...t.knownValueParams,...g],o=[],s=e.args,i=e.elementTypes;let l=!1,p=0;const c=t.positionalSkip??0;function checkArgElementType(e){if(!i)return;const a=i[e+1];a&&!T.has(a)&&(l=!0)}for(let e=0;e<s.length;e++){const a=s[e];if(!a)continue;const h=i?i[e+1]:void 0;if(k(a,h)){const p="-"+a.slice(1),c=p.indexOf(":",1),h=(c>0?p.substring(0,c):p).toLowerCase();if(matchesParam(h,t.pathParams)){let t;if(c>0){const e=a.substring(c+1);hasComplexColonValue(e)?l=!0:t=e}else{const a=s[e+1],n=i?i[e+2]:void 0;a&&!k(a,n)&&(t=a,checkArgElementType(e+1),e++)}t&&o.push(t)}else if(t.leafOnlyPathParams&&matchesParam(h,t.leafOnlyPathParams)){let t;if(c>0){const e=a.substring(c+1);hasComplexColonValue(e)?l=!0:t=e}else{const a=s[e+1],n=i?i[e+2]:void 0;a&&!k(a,n)&&(t=a,checkArgElementType(e+1),e++)}void 0!==t&&(t.includes("/")||t.includes("\\")||"."===t||".."===t?l=!0:o.push(t))}else if(matchesParam(h,n));else if(matchesParam(h,r))if(c>0)hasComplexColonValue(a.substring(c+1))&&(l=!0);else{const a=s[e+1],t=i?i[e+2]:void 0;a&&!k(a,t)&&(checkArgElementType(e+1),e++)}else if(l=!0,c>0){const e=a.substring(c+1);hasComplexColonValue(e)||o.push(e)}continue}p<c?p++:(p++,checkArgElementType(e),o.push(a))}return{paths:o,operationType:t.operationType,hasUnvalidatablePathArg:l,optionalWrite:t.optionalWrite??!1}}export function checkPathConstraints(e,a,t,n=!1){if(!a.valid)return{behavior:"passthrough",message:"Cannot validate paths for unparsed command"};let r;for(const e of a.statements){const a=checkPathConstraintsForStatement(e,t,n);if("deny"===a.behavior)return a;"ask"!==a.behavior||r||(r=a)}return r??{behavior:"passthrough",message:"All path constraints validated successfully"}}function checkPathConstraintsForStatement(e,a,t=!1){const r=n();let o;t&&(o={behavior:"ask",message:"Compound command changes working directory (Set-Location/Push-Location/Pop-Location/New-PSDrive) — relative paths cannot be validated against the original cwd and require manual approval",decisionReason:{type:"other",reason:"Compound command contains cd with path operation — manual approval required to prevent path resolution bypass"}});let s,p=!1;for(const t of e.commands){if("CommandAst"!==t.elementType){p=!0,s=t.text;continue}const{paths:e,operationType:n,hasUnvalidatablePathArg:c,optionalWrite:h}=extractPathsFromCommand(t);if(p){const e=b(t.name);if(void 0!==s){const t=checkDenyRuleForGuessedPath(s.replace(/^['"]|['"]$/g,""),r,a,n);if(t)return{behavior:"deny",message:`${e} targeting '${t.resolvedPath}' was blocked by a deny rule`,decisionReason:{type:"rule",rule:t.rule}}}o??={behavior:"ask",message:`${e} receives its path from a pipeline expression source that cannot be statically validated and requires manual approval`}}if(c){const e=b(t.name);o??={behavior:"ask",message:`${e} uses a parameter or complex path expression (array literal, subexpression, unknown parameter, etc.) that cannot be statically validated and requires manual approval`}}if("read"!==n&&!h&&0===e.length&&R[b(t.name)]){const e=b(t.name);o??={behavior:"ask",message:`${e} is a write operation but no target path could be determined; requires manual approval`};continue}const d="remove-item"===b(t.name);for(const s of e){if(d&&isDangerousRemovalRawPath(s))return dangerousRemovalDeny(s);const{allowed:e,resolvedPath:p,decisionReason:c}=validatePath(s,r,a,n);if(d&&f(p))return dangerousRemovalDeny(p);if(!e){const e=b(t.name),r=formatDirectoryList(Array.from(l(a))),s="other"===c?.type||"safetyCheck"===c?.type?c.reason:`${e} targeting '${p}' was blocked. For security, Context Code may only access files in the allowed working directories for this session: ${r}.`;if("rule"===c?.type)return{behavior:"deny",message:s,decisionReason:c};const h=[];if(p)if("read"===n){const e=m(i(p),"session");e&&h.push(e)}else h.push({type:"addDirectories",directories:[i(p)],destination:"session"});"write"!==n&&"create"!==n||h.push({type:"setMode",mode:"acceptEdits",destination:"session"}),o??={behavior:"ask",message:s,blockedPath:p,decisionReason:c,suggestions:h}}}}if(e.nestedCommands)for(const t of e.nestedCommands){const{paths:e,operationType:n,hasUnvalidatablePathArg:s,optionalWrite:c}=extractPathsFromCommand(t);if(s){const e=b(t.name);o??={behavior:"ask",message:`${e} uses a parameter or complex path expression (array literal, subexpression, unknown parameter, etc.) that cannot be statically validated and requires manual approval`}}if("read"!==n&&!c&&0===e.length&&R[b(t.name)]){const e=b(t.name);o??={behavior:"ask",message:`${e} is a write operation but no target path could be determined; requires manual approval`};continue}const h="remove-item"===b(t.name);for(const s of e){if(h&&isDangerousRemovalRawPath(s))return dangerousRemovalDeny(s);const{allowed:e,resolvedPath:p,decisionReason:c}=validatePath(s,r,a,n);if(h&&f(p))return dangerousRemovalDeny(p);if(!e){const e=b(t.name),r=formatDirectoryList(Array.from(l(a))),s="other"===c?.type||"safetyCheck"===c?.type?c.reason:`${e} targeting '${p}' was blocked. For security, Context Code may only access files in the allowed working directories for this session: ${r}.`;if("rule"===c?.type)return{behavior:"deny",message:s,decisionReason:c};const h=[];if(p)if("read"===n){const e=m(i(p),"session");e&&h.push(e)}else h.push({type:"addDirectories",directories:[i(p)],destination:"session"});"write"!==n&&"create"!==n||h.push({type:"setMode",mode:"acceptEdits",destination:"session"}),o??={behavior:"ask",message:s,blockedPath:p,decisionReason:c,suggestions:h}}}p&&(o??={behavior:"ask",message:`${b(t.name)} appears inside a control-flow or chain statement where piped expression sources cannot be statically validated and requires manual approval`})}if(e.nestedCommands)for(const t of e.nestedCommands)if(t.redirections)for(const e of t.redirections){if(e.isMerging)continue;if(!e.target)continue;if(P(e.target))continue;const{allowed:t,resolvedPath:n,decisionReason:s}=validatePath(e.target,r,a,"create");if(!t){const e=formatDirectoryList(Array.from(l(a))),t="other"===s?.type||"safetyCheck"===s?.type?s.reason:`Output redirection to '${n}' was blocked. For security, Context Code may only write to files in the allowed working directories for this session: ${e}.`;if("rule"===s?.type)return{behavior:"deny",message:t,decisionReason:s};o??={behavior:"ask",message:t,blockedPath:n,decisionReason:s,suggestions:[{type:"addDirectories",directories:[i(n)],destination:"session"}]}}}if(e.redirections)for(const t of e.redirections){if(t.isMerging)continue;if(!t.target)continue;if(P(t.target))continue;const{allowed:e,resolvedPath:n,decisionReason:s}=validatePath(t.target,r,a,"create");if(!e){const e=formatDirectoryList(Array.from(l(a))),t="other"===s?.type||"safetyCheck"===s?.type?s.reason:`Output redirection to '${n}' was blocked. For security, Context Code may only write to files in the allowed working directories for this session: ${e}.`;if("rule"===s?.type)return{behavior:"deny",message:t,decisionReason:s};o??={behavior:"ask",message:t,blockedPath:n,decisionReason:s,suggestions:[{type:"addDirectories",directories:[i(n)],destination:"session"}]}}}return o??{behavior:"passthrough",message:"All path constraints validated successfully"}}