@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{readFile as t}from"fs/promises";import e from"lodash-es/memoize.js";import{logForDebugging as s}from"../debug.js";import{execFileNoThrow as o}from"../execFileNoThrow.js";import{getPlatform as r}from"../platform.js";export const getOsRelease=e(async()=>{try{const e=await t("/etc/os-release","utf8"),s=e.match(/^ID=["']?(\S+?)["']?\s*$/m),o=e.match(/^ID_LIKE=["']?(.+?)["']?\s*$/m);return{id:s?.[1]??"",idLike:o?.[1]?.split(" ")??[]}}catch{return null}});function isDistroFamily(t,e){return e.includes(t.id)||t.idLike.some(t=>e.includes(t))}export function detectMise(){const t=process.execPath||process.argv[0]||"";return!!/[/\\]mise[/\\]installs[/\\]/i.test(t)&&(s(`Detected mise installation: ${t}`),!0)}export function detectAsdf(){const t=process.execPath||process.argv[0]||"";return!!/[/\\]\.?asdf[/\\]installs[/\\]/i.test(t)&&(s(`Detected asdf installation: ${t}`),!0)}export function detectHomebrew(){const t=r();if("macos"!==t&&"linux"!==t&&"wsl"!==t)return!1;const e=process.execPath||process.argv[0]||"";return!!e.includes("/Caskroom/")&&(s(`Detected Homebrew cask installation: ${e}`),!0)}export function detectWinget(){if("windows"!==r())return!1;const t=process.execPath||process.argv[0]||"",e=[/Microsoft[/\\]WinGet[/\\]Packages/i,/Microsoft[/\\]WinGet[/\\]Links/i];for(const o of e)if(o.test(t))return s(`Detected winget installation: ${t}`),!0;return!1}export const detectPacman=e(async()=>{if("linux"!==r())return!1;const t=await getOsRelease();if(t&&!isDistroFamily(t,["arch"]))return!1;const e=process.execPath||process.argv[0]||"",i=await o("pacman",["-Qo",e],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout)&&(s(`Detected pacman installation: ${i.stdout.trim()}`),!0)});export const detectDeb=e(async()=>{if("linux"!==r())return!1;const t=await getOsRelease();if(t&&!isDistroFamily(t,["debian"]))return!1;const e=process.execPath||process.argv[0]||"",i=await o("dpkg",["-S",e],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout)&&(s(`Detected deb installation: ${i.stdout.trim()}`),!0)});export const detectRpm=e(async()=>{if("linux"!==r())return!1;const t=await getOsRelease();if(t&&!isDistroFamily(t,["fedora","rhel","suse"]))return!1;const e=process.execPath||process.argv[0]||"",i=await o("rpm",["-qf",e],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout)&&(s(`Detected rpm installation: ${i.stdout.trim()}`),!0)});export const detectApk=e(async()=>{if("linux"!==r())return!1;const t=await getOsRelease();if(t&&!isDistroFamily(t,["alpine"]))return!1;const e=process.execPath||process.argv[0]||"",i=await o("apk",["info","--who-owns",e],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout)&&(s(`Detected apk installation: ${i.stdout.trim()}`),!0)});export const getPackageManager=e(async()=>detectHomebrew()?"homebrew":detectWinget()?"winget":detectMise()?"mise":detectAsdf()?"asdf":await detectPacman()?"pacman":await detectApk()?"apk":await detectDeb()?"deb":await detectRpm()?"rpm":"unknown");
1
+ import{readFile as e}from"fs/promises";import t from"lodash-es/memoize.js";import{logForDebugging as s}from"../debug.js";import{execFileNoThrow as o}from"../execFileNoThrow.js";import{getPlatform as r}from"../platform.js";export const getOsRelease=t(async()=>{try{const t=await e("/etc/os-release","utf8"),s=t.match(/^ID=["']?(\S+?)["']?\s*$/m),o=t.match(/^ID_LIKE=["']?(.+?)["']?\s*$/m);return{id:s?.[1]??"",idLike:o?.[1]?.split(" ")??[]}}catch{return null}});function isDistroFamily(e,t){return t.includes(e.id)||e.idLike.some(e=>t.includes(e))}export function detectMise(){const e=process.execPath||process.argv[0]||"";return!!/[/\\]mise[/\\]installs[/\\]/i.test(e)&&(s(`Detected mise installation: ${e}`),!0)}export function detectAsdf(){const e=process.execPath||process.argv[0]||"";return!!/[/\\]\.?asdf[/\\]installs[/\\]/i.test(e)&&(s(`Detected asdf installation: ${e}`),!0)}export function detectHomebrew(){const e=r();if("macos"!==e&&"linux"!==e&&"wsl"!==e)return!1;const t=process.execPath||process.argv[0]||"";return!!t.includes("/Caskroom/")&&(s(`Detected Homebrew cask installation: ${t}`),!0)}export function detectWinget(){if("windows"!==r())return!1;const e=process.execPath||process.argv[0]||"",t=[/Microsoft[/\\]WinGet[/\\]Packages/i,/Microsoft[/\\]WinGet[/\\]Links/i];for(const o of t)if(o.test(e))return s(`Detected winget installation: ${e}`),!0;return!1}export const detectPacman=t(async()=>{if("linux"!==r())return!1;const e=await getOsRelease();if(e&&!isDistroFamily(e,["arch"]))return!1;const t=process.execPath||process.argv[0]||"",i=await o("pacman",["-Qo",t],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout||(s(`Detected pacman installation: ${i.stdout.trim()}`),0))});export const detectDeb=t(async()=>{if("linux"!==r())return!1;const e=await getOsRelease();if(e&&!isDistroFamily(e,["debian"]))return!1;const t=process.execPath||process.argv[0]||"",i=await o("dpkg",["-S",t],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout||(s(`Detected deb installation: ${i.stdout.trim()}`),0))});export const detectRpm=t(async()=>{if("linux"!==r())return!1;const e=await getOsRelease();if(e&&!isDistroFamily(e,["fedora","rhel","suse"]))return!1;const t=process.execPath||process.argv[0]||"",i=await o("rpm",["-qf",t],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout||(s(`Detected rpm installation: ${i.stdout.trim()}`),0))});export const detectApk=t(async()=>{if("linux"!==r())return!1;const e=await getOsRelease();if(e&&!isDistroFamily(e,["alpine"]))return!1;const t=process.execPath||process.argv[0]||"",i=await o("apk",["info","--who-owns",t],{timeout:5e3,useCwd:!1});return!(0!==i.code||!i.stdout||(s(`Detected apk installation: ${i.stdout.trim()}`),0))});export const getPackageManager=t(async()=>detectHomebrew()?"homebrew":detectWinget()?"winget":detectMise()?"mise":detectAsdf()?"asdf":await detectPacman()?"pacman":await detectApk()?"apk":await detectDeb()?"deb":await detectRpm()?"rpm":"unknown");
@@ -1 +1 @@
1
- import{basename as t,join as r}from"path";import{getFeatureValue_CACHED_MAY_BE_STALE as n}from"../../services/analytics/growthbook.js";import{logForDebugging as e}from"../debug.js";import{isEnvDefinedFalsy as o,isEnvTruthy as c}from"../envUtils.js";import{isENOENT as i,toError as s}from"../errors.js";import{getFsImplementation as u}from"../fsOperations.js";import{getProcessCommand as a}from"../genericProcessUtils.js";import{logError as l}from"../log.js";import{jsonParse as p,jsonStringify as f,writeFileSync_DEPRECATED as d}from"../slowOperations.js";export function isPidBasedLockingEnabled(){const t=process.env.ENABLE_PID_BASED_VERSION_LOCKING;return!!c(t)||!o(t)&&n("tengu_pid_based_version_locking",!1)}export function isProcessRunning(t){if(t<=1)return!1;try{return process.kill(t,0),!0}catch{return!1}}export function readLockContent(t){const r=u();try{const n=r.readFileSync(t,{encoding:"utf8"});if(!n||""===n.trim())return null;const e=p(n);return"number"==typeof e.pid&&e.version&&e.execPath?e:null}catch{return null}}export function isLockActive(t){const r=readLockContent(t);if(!r)return!1;const{pid:n,execPath:o}=r;if(!isProcessRunning(n))return!1;if(!function(t,r){if(!isProcessRunning(t))return!1;if(t===process.pid)return!0;try{const n=a(t);if(!n)return!0;const e=n.toLowerCase(),o=r.toLowerCase();return e.includes("claude")||e.includes(o)}catch{return!0}}(n,o))return e(`Lock PID ${n} is running but does not appear to be Claude - treating as stale`),!1;const c=u();try{const r=c.statSync(t);if(Date.now()-r.mtimeMs>72e5&&!isProcessRunning(n))return!1}catch{}return!0}export async function tryAcquireLock(r,n){const o=u(),c=t(r);if(isLockActive(n)){const t=readLockContent(n);return e(`Cannot acquire lock for ${c} - held by PID ${t?.pid}`),null}const i={pid:process.pid,version:c,execPath:process.execPath,acquiredAt:Date.now()};try{!function(t,r){const n=u(),e=`${t}.tmp.${process.pid}.${Date.now()}`;try{d(e,f(r,null,2),{encoding:"utf8",flush:!0}),n.renameSync(e,t)}catch(t){try{n.unlinkSync(e)}catch{}throw t}}(n,i);const t=readLockContent(n);return t?.pid!==process.pid?null:(e(`Acquired PID lock for ${c} (PID ${process.pid})`),()=>{try{const t=readLockContent(n);t?.pid===process.pid&&(o.unlinkSync(n),e(`Released PID lock for ${c}`))}catch(t){e(`Failed to release lock for ${c}: ${t}`)}})}catch(t){return e(`Failed to acquire lock for ${c}: ${t}`),null}}export async function acquireProcessLifetimeLock(t,r){const n=await tryAcquireLock(t,r);if(!n)return!1;const cleanup=()=>{try{n()}catch{}};return process.on("exit",cleanup),process.on("SIGINT",cleanup),process.on("SIGTERM",cleanup),!0}export async function withLock(t,r,n){const e=await tryAcquireLock(t,r);if(!e)return!1;try{return await n(),!0}finally{e()}}export function getAllLockInfo(t){const n=u(),e=[];try{const o=n.readdirStringSync(t).filter(t=>t.endsWith(".lock"));for(const n of o){const o=r(t,n),c=readLockContent(o);c&&e.push({version:c.version,pid:c.pid,isProcessRunning:isProcessRunning(c.pid),execPath:c.execPath,acquiredAt:new Date(c.acquiredAt),lockFilePath:o})}}catch(t){if(i(t))return e;l(s(t))}return e}export function cleanupStaleLocks(t){const n=u();let o=0;try{const c=n.readdirStringSync(t).filter(t=>t.endsWith(".lock"));for(const i of c){const c=r(t,i);try{n.lstatSync(c).isDirectory()?(n.rmSync(c,{recursive:!0,force:!0}),o++,e(`Cleaned up legacy directory lock: ${i}`)):isLockActive(c)||(n.unlinkSync(c),o++,e(`Cleaned up stale lock: ${i}`))}catch{}}}catch(t){if(i(t))return 0;l(s(t))}return o}
1
+ import{basename as t,join as r}from"path";import{getFeatureValue_CACHED_MAY_BE_STALE as e}from"../../services/analytics/growthbook.js";import{logForDebugging as n}from"../debug.js";import{isEnvDefinedFalsy as o,isEnvTruthy as c}from"../envUtils.js";import{isENOENT as s,toError as i}from"../errors.js";import{getFsImplementation as a}from"../fsOperations.js";import{getProcessCommand as u}from"../genericProcessUtils.js";import{logError as l}from"../log.js";import{jsonParse as p,jsonStringify as f,writeFileSync_DEPRECATED as d}from"../slowOperations.js";export function isPidBasedLockingEnabled(){const t=process.env.ENABLE_PID_BASED_VERSION_LOCKING;return!!c(t)||!o(t)&&e("tengu_pid_based_version_locking",!1)}export function isProcessRunning(t){if(t<=1)return!1;try{return process.kill(t,0),!0}catch{return!1}}export function readLockContent(t){const r=a();try{const e=r.readFileSync(t,{encoding:"utf8"});if(!e||""===e.trim())return null;const n=p(e);return"number"==typeof n.pid&&n.version&&n.execPath?n:null}catch{return null}}export function isLockActive(t){const r=readLockContent(t);if(!r)return!1;const{pid:e,execPath:o}=r;if(!isProcessRunning(e))return!1;if(!function(t,r){if(!isProcessRunning(t))return!1;if(t===process.pid)return!0;try{const e=u(t);if(!e)return!0;const n=e.toLowerCase(),o=r.toLowerCase();return n.includes("claude")||n.includes(o)}catch{return!0}}(e,o))return n(`Lock PID ${e} is running but does not appear to be Claude - treating as stale`),!1;const c=a();try{const r=c.statSync(t);if(Date.now()-r.mtimeMs>72e5&&!isProcessRunning(e))return!1}catch{}return!0}export async function tryAcquireLock(r,e){const o=a(),c=t(r);if(isLockActive(e)){const t=readLockContent(e);return n(`Cannot acquire lock for ${c} - held by PID ${t?.pid}`),null}const s={pid:process.pid,version:c,execPath:process.execPath,acquiredAt:Date.now()};try{!function(t,r){const e=a(),n=`${t}.tmp.${process.pid}.${Date.now()}`;try{d(n,f(r,null,2),{encoding:"utf8",flush:!0}),e.renameSync(n,t)}catch(t){try{e.unlinkSync(n)}catch{}throw t}}(e,s);const t=readLockContent(e);return t?.pid!==process.pid?null:(n(`Acquired PID lock for ${c} (PID ${process.pid})`),()=>{try{const t=readLockContent(e);t?.pid===process.pid&&(o.unlinkSync(e),n(`Released PID lock for ${c}`))}catch(t){n(`Failed to release lock for ${c}: ${t}`)}})}catch(t){return n(`Failed to acquire lock for ${c}: ${t}`),null}}export async function acquireProcessLifetimeLock(t,r){const e=await tryAcquireLock(t,r);if(!e)return!1;const cleanup=()=>{try{e()}catch{}};return process.on("exit",cleanup),process.on("SIGINT",cleanup),process.on("SIGTERM",cleanup),!0}export async function withLock(t,r,e){const n=await tryAcquireLock(t,r);if(!n)return!1;try{return await e(),!0}finally{n()}}export function getAllLockInfo(t){const e=a(),n=[];try{const o=e.readdirStringSync(t).filter(t=>t.endsWith(".lock"));for(const e of o){const o=r(t,e),c=readLockContent(o);c&&n.push({version:c.version,pid:c.pid,isProcessRunning:isProcessRunning(c.pid),execPath:c.execPath,acquiredAt:new Date(c.acquiredAt),lockFilePath:o})}}catch(t){if(s(t))return n;l(i(t))}return n}export function cleanupStaleLocks(t){const e=a();let o=0;try{const c=e.readdirStringSync(t).filter(t=>t.endsWith(".lock"));for(const s of c){const c=r(t,s);try{e.lstatSync(c).isDirectory()?(e.rmSync(c,{recursive:!0,force:!0}),o++,n(`Cleaned up legacy directory lock: ${s}`)):isLockActive(c)||(e.unlinkSync(c),o++,n(`Cleaned up stale lock: ${s}`))}catch{}}}catch(t){if(s(t))return 0;l(i(t))}return o}
@@ -1 +1 @@
1
- import{BASH_TOOL_NAME as t}from"../tools/BashTool/toolName.js";import{formatOutput as e}from"../tools/BashTool/utils.js";import{getFsImplementation as o}from"./fsOperations.js";import{expandPath as u}from"./path.js";import{jsonParse as l}from"./slowOperations.js";function processOutputText(t){if(!t)return"";const o=Array.isArray(t)?t.join(""):t,{truncatedContent:u}=e(o);return u}function processOutput(t){switch(t.output_type){case"stream":return{output_type:t.output_type,text:processOutputText(t.text)};case"execute_result":case"display_data":return{output_type:t.output_type,text:processOutputText(t.data?.["text/plain"]),image:t.data&&(e=t.data,"string"==typeof e["image/png"]?{image_data:e["image/png"].replace(/\s/g,""),media_type:"image/png"}:"string"==typeof e["image/jpeg"]?{image_data:e["image/jpeg"].replace(/\s/g,""),media_type:"image/jpeg"}:void 0)};case"error":return{output_type:t.output_type,text:processOutputText(`${t.ename}: ${t.evalue}\n${t.traceback.join("\n")}`)}}var e}function processCell(e,o,u,l){const n=e.id??`cell-${o}`,a={cellType:e.cell_type,source:Array.isArray(e.source)?e.source.join(""):e.source,execution_count:"code"===e.cell_type&&e.execution_count||void 0,cell_id:n};if("code"===e.cell_type&&(a.language=u),"code"===e.cell_type&&e.outputs?.length){const u=e.outputs.map(processOutput);!l&&function(t){let e=0;for(const o of t)if(o&&(e+=(o.text?.length??0)+(o.image?.image_data.length??0),e>1e4))return!0;return!1}(u)?a.outputs=[{output_type:"stream",text:`Outputs are too large to include. Use ${t} with: cat <notebook_path> | jq '.cells[${o}].outputs'`}]:a.outputs=u}return a}function cellOutputToToolResult(t){const e=[];return t.text&&e.push({text:`\n${t.text}`,type:"text"}),t.image&&e.push({type:"image",source:{data:t.image.image_data,media_type:t.image.media_type,type:"base64"}}),e}function getToolResultFromCell(t){const e=function(t){const e=[];return"code"!==t.cellType&&e.push(`<cell_type>${t.cellType}</cell_type>`),"python"!==t.language&&"code"===t.cellType&&e.push(`<language>${t.language}</language>`),{text:`<cell id="${t.cell_id}">${e.join("")}${t.source}</cell id="${t.cell_id}">`,type:"text"}}(t),o=t.outputs?.flatMap(cellOutputToToolResult);return[e,...o??[]]}export async function readNotebook(t,e){const n=u(t),a=(await o().readFileBytes(n)).toString("utf-8"),r=l(a),p=r.metadata.language_info?.name??"python";if(e){const t=r.cells.find(t=>t.id===e);if(!t)throw new Error(`Cell with ID "${e}" not found in notebook`);return[processCell(t,r.cells.indexOf(t),p,!0)]}return r.cells.map((t,e)=>processCell(t,e,p,!1))}export function mapNotebookCellsToToolResult(t,e){return{tool_use_id:e,type:"tool_result",content:t.flatMap(getToolResultFromCell).reduce((t,e)=>{if(0===t.length)return[e];const o=t[t.length-1];return o&&"text"===o.type&&"text"===e.type?(o.text+="\n"+e.text,t):(t.push(e),t)},[])}}export function parseCellId(t){const e=t.match(/^cell-(\d+)$/);if(e&&e[1]){const t=parseInt(e[1],10);return isNaN(t)?void 0:t}}
1
+ import{BASH_TOOL_NAME as t}from"../tools/BashTool/toolName.js";import{formatOutput as e}from"../tools/BashTool/utils.js";import{getFsImplementation as o}from"./fsOperations.js";import{expandPath as u}from"./path.js";import{jsonParse as a}from"./slowOperations.js";function processOutputText(t){if(!t)return"";const o=Array.isArray(t)?t.join(""):t,{truncatedContent:u}=e(o);return u}function processOutput(t){switch(t.output_type){case"stream":return{output_type:t.output_type,text:processOutputText(t.text)};case"execute_result":case"display_data":return{output_type:t.output_type,text:processOutputText(t.data?.["text/plain"]),image:t.data&&(e=t.data,"string"==typeof e["image/png"]?{image_data:e["image/png"].replace(/\s/g,""),media_type:"image/png"}:"string"==typeof e["image/jpeg"]?{image_data:e["image/jpeg"].replace(/\s/g,""),media_type:"image/jpeg"}:void 0)};case"error":return{output_type:t.output_type,text:processOutputText(`${t.ename}: ${t.evalue}\n${t.traceback.join("\n")}`)}}var e}function processCell(e,o,u,a){const l=e.id??`cell-${o}`,n={cellType:e.cell_type,source:Array.isArray(e.source)?e.source.join(""):e.source,execution_count:"code"===e.cell_type&&e.execution_count||void 0,cell_id:l};if("code"===e.cell_type&&(n.language=u),"code"===e.cell_type&&e.outputs?.length){const u=e.outputs.map(processOutput);!a&&function(t){let e=0;for(const o of t)if(o&&(e+=(o.text?.length??0)+(o.image?.image_data.length??0),e>1e4))return!0;return!1}(u)?n.outputs=[{output_type:"stream",text:`Outputs are too large to include. Use ${t} with: cat <notebook_path> | jq '.cells[${o}].outputs'`}]:n.outputs=u}return n}function cellOutputToToolResult(t){const e=[];return t.text&&e.push({text:`\n${t.text}`,type:"text"}),t.image&&e.push({type:"image",source:{data:t.image.image_data,media_type:t.image.media_type,type:"base64"}}),e}function getToolResultFromCell(t){const e=function(t){const e=[];return"code"!==t.cellType&&e.push(`<cell_type>${t.cellType}</cell_type>`),"python"!==t.language&&"code"===t.cellType&&e.push(`<language>${t.language}</language>`),{text:`<cell id="${t.cell_id}">${e.join("")}${t.source}</cell id="${t.cell_id}">`,type:"text"}}(t),o=t.outputs?.flatMap(cellOutputToToolResult);return[e,...o??[]]}export async function readNotebook(t,e){const l=u(t),n=(await o().readFileBytes(l)).toString("utf-8"),s=a(n),r=s.metadata.language_info?.name??"python";if(e){const t=s.cells.find(t=>t.id===e);if(!t)throw new Error(`Cell with ID "${e}" not found in notebook`);return[processCell(t,s.cells.indexOf(t),r,!0)]}return s.cells.map((t,e)=>processCell(t,e,r,!1))}export function mapNotebookCellsToToolResult(t,e){return{tool_use_id:e,type:"tool_result",content:t.flatMap(getToolResultFromCell).reduce((t,e)=>{if(0===t.length)return[e];const o=t[t.length-1];return o&&"text"===o.type&&"text"===e.type?(o.text+="\n"+e.text,t):(t.push(e),t)},[])}}export function parseCellId(t){const e=t.match(/^cell-(\d+)$/);if(e&&e[1]){const t=parseInt(e[1],10);return isNaN(t)?void 0:t}}
@@ -1 +1 @@
1
- import{createHash as t}from"crypto";import{mkdir as e,readdir as r,readFile as o,stat as a,unlink as s,writeFile as n}from"fs/promises";import{join as i}from"path";import{logForDebugging as c}from"./debug.js";import{getClaudeConfigHomeDir as p}from"./envUtils.js";import{isENOENT as u}from"./errors.js";function getPasteStoreDir(){return i(p(),"paste-cache")}export function hashPastedText(e){return t("sha256").update(e).digest("hex").slice(0,16)}function getPastePath(t){return i(getPasteStoreDir(),`${t}.txt`)}export async function storePastedText(t,r){try{const o=getPasteStoreDir();await e(o,{recursive:!0});const a=getPastePath(t);await n(a,r,{encoding:"utf8",mode:384}),c(`Stored paste ${t} to ${a}`)}catch(t){c(`Failed to store paste: ${t}`)}}export async function retrievePastedText(t){try{const e=getPastePath(t);return await o(e,{encoding:"utf8"})}catch(e){return u(e)||c(`Failed to retrieve paste ${t}: ${e}`),null}}export async function cleanupOldPastes(t){const e=getPasteStoreDir();let o;try{o=await r(e)}catch{return}const n=t.getTime();for(const t of o){if(!t.endsWith(".txt"))continue;const r=i(e,t);try{(await a(r)).mtimeMs<n&&(await s(r),c(`Cleaned up old paste: ${r}`))}catch{}}}
1
+ import{createHash as t}from"crypto";import{mkdir as e,readdir as a,readFile as r,stat as s,unlink as o,writeFile as i}from"fs/promises";import{join as n}from"path";import{logForDebugging as c}from"./debug.js";import{getClaudeConfigHomeDir as u}from"./envUtils.js";import{isENOENT as d}from"./errors.js";function getPasteStoreDir(){return n(u(),"paste-cache")}export function hashPastedText(e){return t("sha256").update(e).digest("hex").slice(0,16)}function getPastePath(t){return n(getPasteStoreDir(),`${t}.txt`)}export async function storePastedText(t,a){try{const r=getPasteStoreDir();await e(r,{recursive:!0});const s=getPastePath(t);await i(s,a,{encoding:"utf8",mode:384}),c(`Stored paste ${t} to ${s}`)}catch(t){c(`Failed to store paste: ${t}`)}}export async function retrievePastedText(t){try{const e=getPastePath(t);return await r(e,{encoding:"utf8"})}catch(e){return d(e)||c(`Failed to retrieve paste ${t}: ${e}`),null}}export async function cleanupOldPastes(t){const e=getPasteStoreDir();let r;try{r=await a(e)}catch{return}const i=t.getTime();for(const t of r){if(!t.endsWith(".txt"))continue;const a=n(e,t);try{(await s(a)).mtimeMs<i&&(await o(a),c(`Cleaned up old paste: ${a}`))}catch{}}}
@@ -1 +1 @@
1
- import{homedir as t}from"os";import{dirname as r,isAbsolute as e,join as o,normalize as i,relative as n,resolve as s}from"path";import{getCwd as a}from"./cwd.js";import{getFsImplementation as c}from"./fsOperations.js";import{getPlatform as f}from"./platform.js";import{posixPathToWindowsPath as m}from"./windowsPaths.js";export function expandPath(r,n){const p=n??a()??c().cwd();if("string"!=typeof r)throw new TypeError("Path must be a string, received "+typeof r);if("string"!=typeof p)throw new TypeError("Base directory must be a string, received "+typeof p);if(r.includes("\0")||p.includes("\0"))throw new Error("Path contains null bytes");const h=r.trim();if(!h)return i(p).normalize("NFC");if("~"===h)return t().normalize("NFC");if(h.startsWith("~/"))return o(t(),h.slice(2)).normalize("NFC");let u=h;if("windows"===f()&&h.match(/^\/[a-z]\//i))try{u=m(h)}catch{u=h}return e(u)?i(u).normalize("NFC"):s(p,u).normalize("NFC")}export function toRelativePath(t){const r=n(a(),t);return r.startsWith("..")?t:r}export function getDirectoryForPath(t){const e=expandPath(t);if(e.startsWith("\\\\")||e.startsWith("//"))return r(e);try{if(c().statSync(e).isDirectory())return e}catch{}return r(e)}export function containsPathTraversal(t){return/(?:^|[\\/])\.\.(?:[\\/]|$)/.test(t)}export{sanitizePath}from"./sessionStoragePortable.js";export function normalizePathForConfigKey(t){return i(t).replace(/\\/g,"/")}
1
+ import{homedir as t}from"os";import{dirname as r,isAbsolute as e,join as o,normalize as i,relative as s,resolve as a}from"path";import{getCwd as n}from"./cwd.js";import{getFsImplementation as m}from"./fsOperations.js";import{getPlatform as f}from"./platform.js";import{posixPathToWindowsPath as c}from"./windowsPaths.js";export function expandPath(r,s){const p=s??n()??m().cwd();if("string"!=typeof r)throw new TypeError("Path must be a string, received "+typeof r);if("string"!=typeof p)throw new TypeError("Base directory must be a string, received "+typeof p);if(r.includes("\0")||p.includes("\0"))throw new Error("Path contains null bytes");const h=r.trim();if(!h)return i(p).normalize("NFC");if("~"===h)return t().normalize("NFC");if(h.startsWith("~/"))return o(t(),h.slice(2)).normalize("NFC");let l=h;if("windows"===f()&&h.match(/^\/[a-z]\//i))try{l=c(h)}catch{l=h}return e(l)?i(l).normalize("NFC"):a(p,l).normalize("NFC")}export function toRelativePath(t){const r=s(n(),t);return r.startsWith("..")?t:r}export function getDirectoryForPath(t){const e=expandPath(t);if(e.startsWith("\\\\")||e.startsWith("//"))return r(e);try{if(m().statSync(e).isDirectory())return e}catch{}return r(e)}export function containsPathTraversal(t){return/(?:^|[\\/])\.\.(?:[\\/]|$)/.test(t)}export{sanitizePath}from"./sessionStoragePortable.js";export function normalizePathForConfigKey(t){return i(t).replace(/\\/g,"/")}
@@ -1 +1 @@
1
- import{feature as e}from"../../recovery/bunBundleShim.js";import o from"zod/v4";import{PAUSE_ICON as t}from"../../constants/figures.js";import{EXTERNAL_PERMISSION_MODES as r,PERMISSION_MODES as n}from"../../types/permissions.js";import{lazySchema as i}from"../lazySchema.js";export{r as EXTERNAL_PERMISSION_MODES,n as PERMISSION_MODES};export const permissionModeSchema=i(()=>o.enum(n));export const externalPermissionModeSchema=i(()=>o.enum(r));const s={default:{title:"Por defecto",shortTitle:"Defecto",symbol:"",color:"text",external:"default"},plan:{title:"Modo plan",shortTitle:"Plan",symbol:t,color:"planMode",external:"plan"},acceptEdits:{title:"Aceptar ediciones",shortTitle:"Aceptar",symbol:"⏵⏵",color:"autoAccept",external:"acceptEdits"},bypassPermissions:{title:"Permisos saltados",shortTitle:"Sin permisos",symbol:"⏵⏵",color:"error",external:"bypassPermissions"},dontAsk:{title:"Sin preguntar",shortTitle:"Sin pregunta",symbol:"⏵⏵",color:"error",external:"dontAsk"},...e("TRANSCRIPT_CLASSIFIER")?{auto:{title:"Modo automático",shortTitle:"Auto",symbol:"⏵⏵",color:"warning",external:"default"}}:{}};export function isExternalPermissionMode(e){return"ant"!==process.env.USER_TYPE||"auto"!==e&&"bubble"!==e}function getModeConfig(e){return s[e]??s.default}export function toExternalPermissionMode(e){return getModeConfig(e).external}export function permissionModeFromString(e){return n.includes(e)?e:"default"}export function permissionModeTitle(e){return getModeConfig(e).title}export function isDefaultMode(e){return"default"===e||void 0===e}export function permissionModeShortTitle(e){return getModeConfig(e).shortTitle}export function permissionModeSymbol(e){return getModeConfig(e).symbol}export function getModeColor(e){return getModeConfig(e).color}
1
+ import{feature as e}from"bun:bundle";import o from"zod/v4";import{PAUSE_ICON as t}from"../../constants/figures.js";import{EXTERNAL_PERMISSION_MODES as r,PERMISSION_MODES as n}from"../../types/permissions.js";import{lazySchema as s}from"../lazySchema.js";export{r as EXTERNAL_PERMISSION_MODES,n as PERMISSION_MODES};export const permissionModeSchema=s(()=>o.enum(n));export const externalPermissionModeSchema=s(()=>o.enum(r));const i={default:{title:"Por defecto",shortTitle:"Defecto",symbol:"",color:"text",external:"default"},plan:{title:"Modo plan",shortTitle:"Plan",symbol:t,color:"planMode",external:"plan"},acceptEdits:{title:"Aceptar ediciones",shortTitle:"Aceptar",symbol:"⏵⏵",color:"autoAccept",external:"acceptEdits"},bypassPermissions:{title:"Permisos saltados",shortTitle:"Sin permisos",symbol:"⏵⏵",color:"error",external:"bypassPermissions"},dontAsk:{title:"Sin preguntar",shortTitle:"Sin pregunta",symbol:"⏵⏵",color:"error",external:"dontAsk"},...e("TRANSCRIPT_CLASSIFIER")?{auto:{title:"Modo automático",shortTitle:"Auto",symbol:"⏵⏵",color:"warning",external:"default"}}:{}};export function isExternalPermissionMode(e){return"ant"!==process.env.USER_TYPE||"auto"!==e&&"bubble"!==e}function getModeConfig(e){return i[e]??i.default}export function toExternalPermissionMode(e){return getModeConfig(e).external}export function permissionModeFromString(e){return n.includes(e)?e:"default"}export function permissionModeTitle(e){return getModeConfig(e).title}export function isDefaultMode(e){return"default"===e||void 0===e}export function permissionModeShortTitle(e){return getModeConfig(e).shortTitle}export function permissionModeSymbol(e){return getModeConfig(e).symbol}export function getModeColor(e){return getModeConfig(e).color}
@@ -1 +1 @@
1
- import o from"zod/v4";import{logForDebugging as e}from"../debug.js";import{lazySchema as t}from"../lazySchema.js";import{applyPermissionUpdates as n,persistPermissionUpdates as s}from"./PermissionUpdate.js";import{permissionUpdateSchema as i}from"./PermissionUpdateSchema.js";export const inputSchema=t(()=>o.object({tool_name:o.string().describe("The name of the tool requesting permission"),input:o.record(o.string(),o.unknown()).describe("The input for the tool"),tool_use_id:o.string().optional().describe("The unique tool use request ID")}));const r=t(()=>o.enum(["user_temporary","user_permanent","user_reject"]).optional().catch(void 0)),a=t(()=>o.object({behavior:o.literal("allow"),updatedInput:o.record(o.string(),o.unknown()),updatedPermissions:o.array(i()).optional().catch(o=>{e(`Malformed updatedPermissions from SDK host ignored: ${o.error.issues[0]?.message??"unknown"}`,{level:"warn"})}),toolUseID:o.string().optional(),decisionClassification:r()})),p=t(()=>o.object({behavior:o.literal("deny"),message:o.string(),interrupt:o.boolean().optional(),toolUseID:o.string().optional(),decisionClassification:r()}));export const outputSchema=t(()=>o.union([a(),p()]));export function permissionPromptToolResultToPermissionDecision(o,t,i,r){const a={type:"permissionPromptTool",permissionPromptToolName:t.name,toolResult:o};if("allow"===o.behavior){const e=o.updatedPermissions;e&&(r.setAppState(o=>({...o,toolPermissionContext:n(o.toolPermissionContext,e)})),s(e));const t=Object.keys(o.updatedInput).length>0?o.updatedInput:i;return{...o,updatedInput:t,decisionReason:a}}return"deny"===o.behavior&&o.interrupt&&(e(`SDK permission prompt deny+interrupt: tool=${t.name} message=${o.message}`),r.abortController.abort()),{...o,decisionReason:a}}
1
+ import e from"zod/v4";import{logForDebugging as o}from"../debug.js";import{lazySchema as t}from"../lazySchema.js";import{applyPermissionUpdates as s,persistPermissionUpdates as i}from"./PermissionUpdate.js";import{permissionUpdateSchema as n}from"./PermissionUpdateSchema.js";export const inputSchema=t(()=>e.object({tool_name:e.string().describe("The name of the tool requesting permission"),input:e.record(e.string(),e.unknown()).describe("The input for the tool"),tool_use_id:e.string().optional().describe("The unique tool use request ID")}));const r=t(()=>e.enum(["user_temporary","user_permanent","user_reject"]).optional().catch(void 0)),a=t(()=>e.object({behavior:e.literal("allow"),updatedInput:e.record(e.string(),e.unknown()),updatedPermissions:e.array(n()).optional().catch(e=>{o(`Malformed updatedPermissions from SDK host ignored: ${e.error.issues[0]?.message??"unknown"}`,{level:"warn"})}),toolUseID:e.string().optional(),decisionClassification:r()})),p=t(()=>e.object({behavior:e.literal("deny"),message:e.string(),interrupt:e.boolean().optional(),toolUseID:e.string().optional(),decisionClassification:r()}));export const outputSchema=t(()=>e.union([a(),p()]));export function permissionPromptToolResultToPermissionDecision(e,t,n,r){const a={type:"permissionPromptTool",permissionPromptToolName:t.name,toolResult:e};if("allow"===e.behavior){const o=e.updatedPermissions;o&&(r.setAppState(e=>({...e,toolPermissionContext:s(e.toolPermissionContext,o)})),i(o));const t=Object.keys(e.updatedInput).length>0?e.updatedInput:n;return{...e,updatedInput:t,decisionReason:a}}return"deny"===e.behavior&&e.interrupt&&(o(`SDK permission prompt deny+interrupt: tool=${t.name} message=${e.message}`),r.abortController.abort()),{...e,decisionReason:a}}
@@ -1 +1 @@
1
- import{posix as e}from"path";import{logForDebugging as s}from"../debug.js";import{getSettingsForSource as i,updateSettingsForSource as t}from"../settings/settings.js";import{jsonStringify as o}from"../slowOperations.js";import{upsertPermissionRule as r,addTrustedDirectory as n,removeTrustedDirectory as a,setPermissionMode as l,deletePermissionRule as d,getPermissionRules as c}from"./permissionsDb.js";import{toPosixPath as u}from"./filesystem.js";import{permissionRuleValueFromString as p,permissionRuleValueToString as m}from"./permissionRuleParser.js";import{addPermissionRulesToSettings as f}from"./permissionsLoader.js";export function extractRules(e){return e?e.flatMap(e=>"addRules"===e.type?e.rules:[]):[]}export function hasRules(e){return extractRules(e).length>0}export function applyPermissionUpdate(e,i){switch(i.type){case"setMode":return s(`Applying permission update: Setting mode to '${i.mode}'`),{...e,mode:i.mode};case"addRules":{const t=i.rules.map(e=>m(e));s(`Applying permission update: Adding ${i.rules.length} ${i.behavior} rule(s) to destination '${i.destination}': ${o(t)}`);const r="allow"===i.behavior?"alwaysAllowRules":"deny"===i.behavior?"alwaysDenyRules":"alwaysAskRules";return{...e,[r]:{...e[r],[i.destination]:[...e[r][i.destination]||[],...t]}}}case"replaceRules":{const t=i.rules.map(e=>m(e));s(`Replacing all ${i.behavior} rules for destination '${i.destination}' with ${i.rules.length} rule(s): ${o(t)}`);const r="allow"===i.behavior?"alwaysAllowRules":"deny"===i.behavior?"alwaysDenyRules":"alwaysAskRules";return{...e,[r]:{...e[r],[i.destination]:t}}}case"addDirectories":{s(`Applying permission update: Adding ${i.directories.length} director${1===i.directories.length?"y":"ies"} with destination '${i.destination}': ${o(i.directories)}`);const t=new Map(e.additionalWorkingDirectories);for(const e of i.directories)t.set(e,{path:e,source:i.destination});return{...e,additionalWorkingDirectories:t}}case"removeRules":{const t=i.rules.map(e=>m(e));s(`Applying permission update: Removing ${i.rules.length} ${i.behavior} rule(s) from source '${i.destination}': ${o(t)}`);const r="allow"===i.behavior?"alwaysAllowRules":"deny"===i.behavior?"alwaysDenyRules":"alwaysAskRules",n=e[r][i.destination]||[],a=new Set(t),l=n.filter(e=>!a.has(e));return{...e,[r]:{...e[r],[i.destination]:l}}}case"removeDirectories":{s(`Applying permission update: Removing ${i.directories.length} director${1===i.directories.length?"y":"ies"}: ${o(i.directories)}`);const t=new Map(e.additionalWorkingDirectories);for(const e of i.directories)t.delete(e);return{...e,additionalWorkingDirectories:t}}default:return e}}export function applyPermissionUpdates(e,s){let i=e;for(const e of s)i=applyPermissionUpdate(i,e);return i}export function supportsPersistence(e){return"localSettings"===e||"userSettings"===e||"projectSettings"===e}export function persistPermissionUpdate(e){if(supportsPersistence(e.destination)){switch(s(`Persisting permission update: ${e.type} to source '${e.destination}'`),e.type){case"addRules":s(`Persisting ${e.rules.length} ${e.behavior} rule(s) to ${e.destination}`),f({ruleValues:e.rules,ruleBehavior:e.behavior},e.destination);break;case"addDirectories":{s(`Persisting ${e.directories.length} director${1===e.directories.length?"y":"ies"} to ${e.destination}`);const o=i(e.destination),r=o?.permissions?.additionalDirectories||[],n=e.directories.filter(e=>!r.includes(e));if(n.length>0){const s=[...r,...n];t(e.destination,{permissions:{additionalDirectories:s}})}break}case"removeRules":{s(`Removing ${e.rules.length} ${e.behavior} rule(s) from ${e.destination}`);const o=i(e.destination),r=(o?.permissions||{})[e.behavior]||[],n=new Set(e.rules.map(m)),a=r.filter(e=>{const s=m(p(e));return!n.has(s)});t(e.destination,{permissions:{[e.behavior]:a}});break}case"removeDirectories":{s(`Removing ${e.directories.length} director${1===e.directories.length?"y":"ies"} from ${e.destination}`);const o=i(e.destination),r=o?.permissions?.additionalDirectories||[],n=new Set(e.directories),a=r.filter(e=>!n.has(e));t(e.destination,{permissions:{additionalDirectories:a}});break}case"setMode":s(`Persisting mode '${e.mode}' to ${e.destination}`),t(e.destination,{permissions:{defaultMode:e.mode}});break;case"replaceRules":{s(`Replacing all ${e.behavior} rules in ${e.destination} with ${e.rules.length} rule(s)`);const i=e.rules.map(m);t(e.destination,{permissions:{[e.behavior]:i}});break}}(async function(e){const s=(e=>{switch(e){case"userSettings":default:return"global";case"projectSettings":case"localSettings":return"project"}})(e.destination);switch(e.type){case"addRules":case"replaceRules":for(const i of e.rules){const t=m(i);await r(s,null,t,e.behavior)}break;case"removeRules":for(const i of e.rules){const t=m(i),o=await c(s,null);for(const s of o)s.toolName===t&&s.behavior===e.behavior&&await d(s.id)}break;case"addDirectories":for(const s of e.directories)await n(s,"full");break;case"removeDirectories":for(const s of e.directories)await a(s);break;case"setMode":await l(s,e.mode)}})(e).catch(()=>{})}}export function persistPermissionUpdates(e){for(const s of e)persistPermissionUpdate(s)}export function createReadRuleSuggestion(s,i="session"){const t=u(s);if("/"===t)return;return{type:"addRules",rules:[{toolName:"Read",ruleContent:e.isAbsolute(t)?`/${t}/**`:`${t}/**`}],behavior:"allow",destination:i}}
1
+ import{posix as e}from"path";import{logForDebugging as s}from"../debug.js";import{getSettingsForSource as i,updateSettingsForSource as t}from"../settings/settings.js";import{jsonStringify as o}from"../slowOperations.js";import{upsertPermissionRule as r,addTrustedDirectory as n,removeTrustedDirectory as a,setPermissionMode as l,deletePermissionRule as d,getPermissionRules as c}from"./permissionsDb.js";import{toPosixPath as u}from"./filesystem.js";import{permissionRuleValueFromString as p,permissionRuleValueToString as m}from"./permissionRuleParser.js";import{addPermissionRulesToSettings as g}from"./permissionsLoader.js";export function extractRules(e){return e?e.flatMap(e=>"addRules"===e.type?e.rules:[]):[]}export function hasRules(e){return extractRules(e).length>0}export function applyPermissionUpdate(e,i){switch(i.type){case"setMode":return s(`Applying permission update: Setting mode to '${i.mode}'`),{...e,mode:i.mode};case"addRules":{const t=i.rules.map(e=>m(e));s(`Applying permission update: Adding ${i.rules.length} ${i.behavior} rule(s) to destination '${i.destination}': ${o(t)}`);const r="allow"===i.behavior?"alwaysAllowRules":"deny"===i.behavior?"alwaysDenyRules":"alwaysAskRules";return{...e,[r]:{...e[r],[i.destination]:[...e[r][i.destination]||[],...t]}}}case"replaceRules":{const t=i.rules.map(e=>m(e));s(`Replacing all ${i.behavior} rules for destination '${i.destination}' with ${i.rules.length} rule(s): ${o(t)}`);const r="allow"===i.behavior?"alwaysAllowRules":"deny"===i.behavior?"alwaysDenyRules":"alwaysAskRules";return{...e,[r]:{...e[r],[i.destination]:t}}}case"addDirectories":{s(`Applying permission update: Adding ${i.directories.length} director${1===i.directories.length?"y":"ies"} with destination '${i.destination}': ${o(i.directories)}`);const t=new Map(e.additionalWorkingDirectories);for(const e of i.directories)t.set(e,{path:e,source:i.destination});return{...e,additionalWorkingDirectories:t}}case"removeRules":{const t=i.rules.map(e=>m(e));s(`Applying permission update: Removing ${i.rules.length} ${i.behavior} rule(s) from source '${i.destination}': ${o(t)}`);const r="allow"===i.behavior?"alwaysAllowRules":"deny"===i.behavior?"alwaysDenyRules":"alwaysAskRules",n=e[r][i.destination]||[],a=new Set(t),l=n.filter(e=>!a.has(e));return{...e,[r]:{...e[r],[i.destination]:l}}}case"removeDirectories":{s(`Applying permission update: Removing ${i.directories.length} director${1===i.directories.length?"y":"ies"}: ${o(i.directories)}`);const t=new Map(e.additionalWorkingDirectories);for(const e of i.directories)t.delete(e);return{...e,additionalWorkingDirectories:t}}default:return e}}export function applyPermissionUpdates(e,s){let i=e;for(const e of s)i=applyPermissionUpdate(i,e);return i}export function supportsPersistence(e){return"localSettings"===e||"userSettings"===e||"projectSettings"===e}export function persistPermissionUpdate(e){if(supportsPersistence(e.destination)){switch(s(`Persisting permission update: ${e.type} to source '${e.destination}'`),e.type){case"addRules":s(`Persisting ${e.rules.length} ${e.behavior} rule(s) to ${e.destination}`),g({ruleValues:e.rules,ruleBehavior:e.behavior},e.destination);break;case"addDirectories":{s(`Persisting ${e.directories.length} director${1===e.directories.length?"y":"ies"} to ${e.destination}`);const o=i(e.destination),r=o?.permissions?.additionalDirectories||[],n=e.directories.filter(e=>!r.includes(e));if(n.length>0){const s=[...r,...n];t(e.destination,{permissions:{additionalDirectories:s}})}break}case"removeRules":{s(`Removing ${e.rules.length} ${e.behavior} rule(s) from ${e.destination}`);const o=i(e.destination),r=(o?.permissions||{})[e.behavior]||[],n=new Set(e.rules.map(m)),a=r.filter(e=>{const s=m(p(e));return!n.has(s)});t(e.destination,{permissions:{[e.behavior]:a}});break}case"removeDirectories":{s(`Removing ${e.directories.length} director${1===e.directories.length?"y":"ies"} from ${e.destination}`);const o=i(e.destination),r=o?.permissions?.additionalDirectories||[],n=new Set(e.directories),a=r.filter(e=>!n.has(e));t(e.destination,{permissions:{additionalDirectories:a}});break}case"setMode":s(`Persisting mode '${e.mode}' to ${e.destination}`),t(e.destination,{permissions:{defaultMode:e.mode}});break;case"replaceRules":{s(`Replacing all ${e.behavior} rules in ${e.destination} with ${e.rules.length} rule(s)`);const i=e.rules.map(m);t(e.destination,{permissions:{[e.behavior]:i}});break}}(async function(e){const s=(e=>{switch(e){case"userSettings":default:return"global";case"projectSettings":case"localSettings":return"project"}})(e.destination);switch(e.type){case"addRules":case"replaceRules":for(const i of e.rules){const t=m(i);await r(s,null,t,e.behavior)}break;case"removeRules":for(const i of e.rules){const t=m(i),o=await c(s,null);for(const s of o)s.toolName===t&&s.behavior===e.behavior&&await d(s.id)}break;case"addDirectories":for(const s of e.directories)await n(s,"full");break;case"removeDirectories":for(const s of e.directories)await a(s);break;case"setMode":await l(s,e.mode)}})(e).catch(()=>{})}}export function persistPermissionUpdates(e){for(const s of e)persistPermissionUpdate(s)}export function createReadRuleSuggestion(s,i="session"){const t=u(s);if("/"!==t)return{type:"addRules",rules:[{toolName:"Read",ruleContent:e.isAbsolute(t)?`/${t}/**`:`${t}/**`}],behavior:"allow",destination:i}}
@@ -1 +1 @@
1
- import e from"zod/v4";import{lazySchema as i}from"../lazySchema.js";import{externalPermissionModeSchema as t}from"./PermissionMode.js";import{permissionBehaviorSchema as r,permissionRuleValueSchema as s}from"./PermissionRule.js";export const permissionUpdateDestinationSchema=i(()=>e.enum(["userSettings","projectSettings","localSettings","session","cliArg"]));export const permissionUpdateSchema=i(()=>e.discriminatedUnion("type",[e.object({type:e.literal("addRules"),rules:e.array(s()),behavior:r(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("replaceRules"),rules:e.array(s()),behavior:r(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("removeRules"),rules:e.array(s()),behavior:r(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("setMode"),mode:t(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("addDirectories"),directories:e.array(e.string()),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("removeDirectories"),directories:e.array(e.string()),destination:permissionUpdateDestinationSchema()})]));
1
+ import e from"zod/v4";import{lazySchema as i}from"../lazySchema.js";import{externalPermissionModeSchema as t}from"./PermissionMode.js";import{permissionBehaviorSchema as s,permissionRuleValueSchema as a}from"./PermissionRule.js";export const permissionUpdateDestinationSchema=i(()=>e.enum(["userSettings","projectSettings","localSettings","session","cliArg"]));export const permissionUpdateSchema=i(()=>e.discriminatedUnion("type",[e.object({type:e.literal("addRules"),rules:e.array(a()),behavior:s(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("replaceRules"),rules:e.array(a()),behavior:s(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("removeRules"),rules:e.array(a()),behavior:s(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("setMode"),mode:t(),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("addDirectories"),directories:e.array(e.string()),destination:permissionUpdateDestinationSchema()}),e.object({type:e.literal("removeDirectories"),directories:e.array(e.string()),destination:permissionUpdateDestinationSchema()})]));
@@ -1 +1 @@
1
- import{feature as t}from"../../recovery/bunBundleShim.js";import{createRequire as o}from"module";o(import.meta.url);let e=!1,r=!1,i=!1;export function setAutoModeActive(t){e=t}export function isAutoModeActive(){return e}export function setAutoModeFlagCli(t){r=t}export function getAutoModeFlagCli(){return r}export function setAutoModeCircuitBroken(t){i=t}export function isAutoModeCircuitBroken(){return i}export function _resetForTesting(){e=!1,r=!1,i=!1}
1
+ import{createRequire as t}from"module";t(import.meta.url);let e=!1,o=!1,r=!1;export function setAutoModeActive(t){e=t}export function isAutoModeActive(){return e}export function setAutoModeFlagCli(t){o=t}export function getAutoModeFlagCli(){return o}export function setAutoModeCircuitBroken(t){r=t}export function isAutoModeCircuitBroken(){return r}export function _resetForTesting(){e=!1,o=!1,r=!1}
@@ -1 +1 @@
1
- import{feature as e}from"../../recovery/bunBundleShim.js";import{useEffect as o,useRef as t}from"react";import{useAppState as i,useAppStateStore as s,useSetAppState as n}from"../../state/AppState.js";import{getIsRemoteMode as r}from"../../bootstrap/state.js";import{createDisabledBypassPermissionsContext as a,shouldDisableBypassPermissions as c,verifyAutoModeGateAccess as f}from"./permissionSetup.js";let d=!1;export async function checkAndDisableBypassPermissionsIfNeeded(e,o){if(d)return;if(d=!0,!e.isBypassPermissionsModeAvailable)return;await c()&&o(e=>({...e,toolPermissionContext:a(e.toolPermissionContext)}))}export function resetBypassPermissionsCheck(){d=!1}export function useKickOffCheckAndDisableBypassPermissionsIfNeeded(){const e=i(e=>e.toolPermissionContext),t=n();o(()=>{r()||checkAndDisableBypassPermissionsIfNeeded(e,t)},[])}let u=!1;export async function checkAndDisableAutoModeIfNeeded(o,t,i){if(e("TRANSCRIPT_CLASSIFIER")){if(u)return;u=!0;const{updateContext:e,notification:s}=await f(o,i);t(o=>{const t=e(o.toolPermissionContext),i=t===o.toolPermissionContext?o:{...o,toolPermissionContext:t};return s?{...i,notifications:{...i.notifications,queue:[...i.notifications.queue,{key:"auto-mode-gate-notification",text:s,color:"warning",priority:"high"}]}}:i})}}export function resetAutoModeGateCheck(){u=!1}export function useKickOffCheckAndDisableAutoModeIfNeeded(){const e=i(e=>e.mainLoopModel),a=i(e=>e.mainLoopModelForSession),c=i(e=>e.fastMode),f=n(),d=s(),u=t(!0);o(()=>{r()||(u.current?u.current=!1:resetAutoModeGateCheck(),checkAndDisableAutoModeIfNeeded(d.getState().toolPermissionContext,f,c))},[e,a,c])}
1
+ import{feature as e}from"bun:bundle";import{useEffect as t,useRef as o}from"react";import{useAppState as s,useAppStateStore as i,useSetAppState as n}from"src/state/AppState.js";import{getIsRemoteMode as a}from"../../bootstrap/state.js";import{createDisabledBypassPermissionsContext as r,shouldDisableBypassPermissions as c,verifyAutoModeGateAccess as d}from"./permissionSetup.js";let f=!1;export async function checkAndDisableBypassPermissionsIfNeeded(e,t){f||(f=!0,e.isBypassPermissionsModeAvailable&&await c()&&t(e=>({...e,toolPermissionContext:r(e.toolPermissionContext)})))}export function resetBypassPermissionsCheck(){f=!1}export function useKickOffCheckAndDisableBypassPermissionsIfNeeded(){const e=s(e=>e.toolPermissionContext),o=n();t(()=>{a()||checkAndDisableBypassPermissionsIfNeeded(e,o)},[])}let u=!1;export async function checkAndDisableAutoModeIfNeeded(t,o,s){if(e("TRANSCRIPT_CLASSIFIER")){if(u)return;u=!0;const{updateContext:e,notification:i}=await d(t,s);o(t=>{const o=e(t.toolPermissionContext),s=o===t.toolPermissionContext?t:{...t,toolPermissionContext:o};return i?{...s,notifications:{...s.notifications,queue:[...s.notifications.queue,{key:"auto-mode-gate-notification",text:i,color:"warning",priority:"high"}]}}:s})}}export function resetAutoModeGateCheck(){u=!1}export function useKickOffCheckAndDisableAutoModeIfNeeded(){const e=s(e=>e.mainLoopModel),r=s(e=>e.mainLoopModelForSession),c=s(e=>e.fastMode),d=n(),f=i(),u=o(!0);t(()=>{a()||(u.current?u.current=!1:resetAutoModeGateCheck(),checkAndDisableAutoModeIfNeeded(f.getState().toolPermissionContext,d,c))},[e,r,c])}
@@ -1 +1 @@
1
- import{MACRO as e,feature as t}from"../../recovery/bunBundleShim.js";import{randomBytes as o}from"crypto";import r from"ignore";import s from"lodash-es/memoize.js";import{homedir as n,tmpdir as i}from"os";import{join as a,normalize as l,posix as c,sep as u}from"path";import{hasAutoMemPathOverride as p,isAutoMemPath as d}from"../../memdir/paths.js";import{isAgentMemoryPath as h}from"../../tools/AgentTool/agentMemory.js";import{CLAUDE_FOLDER_PERMISSION_PATTERN as f,FILE_EDIT_TOOL_NAME as m,GLOBAL_CLAUDE_FOLDER_PERMISSION_PATTERN as g}from"../../tools/FileEditTool/constants.js";import{getOriginalCwd as w,getSessionId as P}from"../../bootstrap/state.js";import{checkStatsigFeatureGate_CACHED_MAY_BE_STALE as v}from"../../services/analytics/growthbook.js";import{FILE_READ_TOOL_NAME as y}from"../../tools/FileReadTool/prompt.js";import{getCwd as C}from"../cwd.js";import{getClaudeConfigHomeDir as R}from"../envUtils.js";import{getFsImplementation as b,getPathsForPermissionCheck as k}from"../fsOperations.js";import{containsPathTraversal as S,expandPath as W,getDirectoryForPath as I,sanitizePath as x}from"../path.js";import{getPlanSlug as D,getPlansDirectory as F}from"../plans.js";import{getPlatform as j}from"../platform.js";import{getProjectDir as $}from"../sessionStorage.js";import{SETTING_SOURCES as E}from"../settings/constants.js";import{getSettingsFilePathForSource as T,getSettingsRootPathForSource as A}from"../settings/settings.js";import{containsVulnerableUncPath as z}from"../shell/readOnlyCommandValidation.js";import{getToolResultsDir as O}from"../toolResultStorage.js";import{windowsPathToPosixPath as N}from"../windowsPaths.js";import{createReadRuleSuggestion as M}from"./PermissionUpdate.js";import{getRuleByContentsForToolName as _}from"./permissions.js";export const DANGEROUS_FILES=[".gitconfig",".gitmodules",".bashrc",".bash_profile",".zshrc",".zprofile",".profile",".ripgreprc",".mcp.json",".claude.json"];export const DANGEROUS_DIRECTORIES=[".git",".vscode",".idea",".claude"];export function normalizeCaseForComparison(e){return e.toLowerCase()}export function getClaudeSkillScope(e){const t=W(e),o=normalizeCaseForComparison(t),r=[{dir:W(a(w(),".context","skills")),prefix:"/.context/skills/"},{dir:W(a(R(),"skills")),prefix:"~/.context/skills/"},{dir:W(a(w(),".context","skills")),prefix:"/.context/skills/"},{dir:W(a(n(),".context","skills")),prefix:"~/.context/skills/"}];for(const{dir:e,prefix:s}of r){const r=normalizeCaseForComparison(e);for(const n of[u,"/"])if(o.startsWith(r+n.toLowerCase())){const o=t.slice(e.length+n.length),r=o.indexOf("/"),i="\\"===u?o.indexOf("\\"):-1,a=-1===r?i:-1===i?r:Math.min(r,i);if(a<=0)return null;const l=o.slice(0,a);return!l||"."===l||l.includes("..")||/[*?[\]]/.test(l)?null:{skillName:l,pattern:s+l+"/**"}}}return null}const U=c.sep;export function relativePath(e,t){if("windows"===j()){const o=N(e),r=N(t);return c.relative(o,r)}return c.relative(e,t)}export function toPosixPath(e){return"windows"===j()?N(e):e}export function isClaudeSettingsPath(e){const t=normalizeCaseForComparison(W(e));return!(!t.endsWith(`${u}.context${u}settings.json`)&&!t.endsWith(`${u}.context${u}settings.local.json`))||E.map(e=>T(e)).filter(e=>void 0!==e).some(e=>normalizeCaseForComparison(e)===t)}function isClaudeConfigFilePath(e){if(isClaudeSettingsPath(e))return!0;const t=a(w(),".claude","commands"),o=a(w(),".claude","agents"),r=a(w(),".claude","skills"),s=a(w(),".context","commands"),n=a(w(),".context","agents"),i=a(w(),".context","skills");return pathInWorkingPath(e,t)||pathInWorkingPath(e,o)||pathInWorkingPath(e,r)||pathInWorkingPath(e,s)||pathInWorkingPath(e,n)||pathInWorkingPath(e,i)}function isSessionPlanFile(e){const t=a(F(),D()),o=l(e);return o.startsWith(t)&&o.endsWith(".md")}export function getSessionMemoryDir(){return a($(C()),P(),"session-memory")+u}export function getSessionMemoryPath(){return a(getSessionMemoryDir(),"summary.md")}export function isScratchpadEnabled(){return v("tengu_scratch")}export function getClaudeTempDirName(){if("windows"===j())return"claude";return`claude-${process.getuid?.()??0}`}export const getClaudeTempDir=s(function(){const e=process.env.CONTEXT_CODE_TMPDIR||process.env.CLAUDE_CODE_TMPDIR||("windows"===j()?i():"/tmp"),t=b();let o=e;try{o=t.realpathSync(e)}catch{}return a(o,getClaudeTempDirName())+u});export const getBundledSkillsRoot=s(function(){const t=o(16).toString("hex");return a(getClaudeTempDir(),"bundled-skills",e.VERSION,t)});export function getProjectTempDir(){return a(getClaudeTempDir(),x(w()))+u}export function getScratchpadDir(){return a(getProjectTempDir(),P(),"scratchpad")}export async function ensureScratchpadDir(){if(!isScratchpadEnabled())throw new Error("Scratchpad directory feature is not enabled");const e=b(),t=getScratchpadDir();return await e.mkdir(t,{mode:448}),t}function isScratchpadPath(e){if(!isScratchpadEnabled())return!1;const t=getScratchpadDir(),o=l(e);return o===t||o.startsWith(t+u)}function isDangerousFilePathToAutoEdit(e){const t=W(e).split(u),o=t.at(-1);if(e.startsWith("\\\\")||e.startsWith("//"))return!0;for(let e=0;e<t.length;e++){const o=normalizeCaseForComparison(t[e]);for(const r of DANGEROUS_DIRECTORIES)if(o===normalizeCaseForComparison(r)){if(".claude"===r){const o=t[e+1];if(o&&"worktrees"===normalizeCaseForComparison(o))break}return!0}}if(o){const e=normalizeCaseForComparison(o);if(DANGEROUS_FILES.some(t=>normalizeCaseForComparison(t)===e))return!0}return!1}function hasSuspiciousWindowsPathPattern(e){if("windows"===j()||"wsl"===j()){if(-1!==e.indexOf(":",2))return!0}return!!/~\d/.test(e)||(!!(e.startsWith("\\\\?\\")||e.startsWith("\\\\.\\")||e.startsWith("//?/")||e.startsWith("//./"))||(!!/[.\s]+$/.test(e)||(!!/\.(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(e)||(!!/(^|\/|\\)\.{3,}(\/|\\|$)/.test(e)||!!z(e)))))}export function checkPathSafetyForAutoEdit(e,t){const o=t??k(e);for(const t of o)if(hasSuspiciousWindowsPathPattern(t))return{safe:!1,message:`Claude requested permissions to write to ${e}, which contains a suspicious Windows path pattern that requires manual approval.`,classifierApprovable:!1};for(const t of o)if(isClaudeConfigFilePath(t))return{safe:!1,message:`Context solicitó permisos para escribir en ${e}, pero aún no se los has otorgado.`,classifierApprovable:!0};for(const t of o)if(isDangerousFilePathToAutoEdit(t))return{safe:!1,message:`Claude requested permissions to edit ${e} which is a sensitive file.`,classifierApprovable:!0};return{safe:!0}}export function allWorkingDirectories(e){return new Set([w(),...e.additionalWorkingDirectories.keys()])}export const getResolvedWorkingDirPaths=s(k);export function pathInAllowedWorkingPath(e,t,o){const r=o??k(e),s=Array.from(allWorkingDirectories(t)).flatMap(e=>getResolvedWorkingDirPaths(e));return r.every(e=>s.some(t=>pathInWorkingPath(e,t)))}export function pathInWorkingPath(e,t){const o=W(e),r=W(t),s=o.replace(/^\/private\/var\//,"/var/").replace(/^\/private\/tmp(\/|$)/,"/tmp$1"),n=r.replace(/^\/private\/var\//,"/var/").replace(/^\/private\/tmp(\/|$)/,"/tmp$1"),i=normalizeCaseForComparison(s),a=relativePath(normalizeCaseForComparison(n),i);return""===a||!S(a)&&!c.isAbsolute(a)}function rootPathForSource(e){switch(e){case"cliArg":case"command":case"session":return W(w());case"userSettings":case"policySettings":case"projectSettings":case"localSettings":case"flagSettings":return A(e)}}function prependDirSep(e){return c.join(U,e)}function normalizePatternToPath({patternRoot:e,pattern:t,rootPath:o}){const r=c.join(e,t);if(e===o)return prependDirSep(t);if(r.startsWith(`${o}${U}`)){return prependDirSep(r.slice(o.length))}{const r=c.relative(o,e);if(!r||r.startsWith(`..${U}`)||".."===r)return null;return prependDirSep(c.join(r,t))}}export function normalizePatternsToPath(e,t){const o=new Set(e.get(null)??[]);for(const[r,s]of e.entries())if(null!==r)for(const e of s){const s=normalizePatternToPath({patternRoot:r,pattern:e,rootPath:t});s&&o.add(s)}return Array.from(o)}export function getFileReadIgnorePatterns(e){const t=getPatternsByRoot(e,"read","deny"),o=new Map;for(const[e,r]of t.entries())o.set(e,Array.from(r.keys()));return o}function patternWithRoot(e,t){if(e.startsWith(`${U}${U}`)){const t=e.slice(1);if("windows"===j()&&t.match(/^\/[a-z]\//i)){const e=t[1]?.toUpperCase()??"C",o=t.slice(2),r=`${e}:\\`;return{relativePattern:o.startsWith("/")?o.slice(1):o,root:r}}return{relativePattern:t,root:U}}if(e.startsWith(`~${U}`))return{relativePattern:e.slice(1),root:n().normalize("NFC")};if(e.startsWith(U))return{relativePattern:e,root:rootPathForSource(t)};let o=e;return e.startsWith(`.${U}`)&&(o=e.slice(2)),{relativePattern:o,root:null}}function getPatternsByRoot(e,t,o){const r=(()=>{switch(t){case"edit":return m;case"read":return y}})(),s=_(e,r,o),n=new Map;for(const[e,t]of s.entries()){const{relativePattern:o,root:r}=patternWithRoot(e,t.source);let s=n.get(r);void 0===s&&(s=new Map,n.set(r,s)),s.set(o,t)}return n}export function matchingRuleForInput(e,t,o,s){let n=W(e);"windows"===j()&&n.includes("\\")&&(n=N(n));const i=getPatternsByRoot(t,o,s);for(const[e,t]of i.entries()){const o=Array.from(t.keys()).map(e=>{let t=e;return t.endsWith("/**")&&(t=t.slice(0,-3)),t}),s=r().add(o),i=relativePath(e??C(),n??C());if(i.startsWith(`..${U}`))continue;if(!i)continue;const a=s.test(i);if(a.ignored&&a.rule){const e=a.rule.pattern,o=e+"/**";return t.has(o)?t.get(o)??null:t.get(e)??null}}return null}export function checkReadPermissionForTool(e,t,o){if("function"!=typeof e.getPath)return{behavior:"ask",message:`Claude requested permissions to use ${e.name}, but you haven't granted it yet.`};const r=e.getPath(t),s=k(r);for(const e of s)if(e.startsWith("\\\\")||e.startsWith("//"))return{behavior:"ask",message:`Claude requested permissions to read from ${r}, which appears to be a UNC path that could access network resources.`,decisionReason:{type:"other",reason:"UNC path detected (defense-in-depth check)"}};for(const e of s)if(hasSuspiciousWindowsPathPattern(e))return{behavior:"ask",message:`Claude requested permissions to read from ${r}, which contains a suspicious Windows path pattern that requires manual approval.`,decisionReason:{type:"other",reason:"Path contains suspicious Windows-specific patterns (alternate data streams, short names, long path prefixes, or three or more consecutive dots) that require manual verification"}};for(const e of s){const t=matchingRuleForInput(e,o,"read","deny");if(t)return{behavior:"deny",message:`Permission to read ${r} has been denied.`,decisionReason:{type:"rule",rule:t}}}for(const e of s){const t=matchingRuleForInput(e,o,"read","ask");if(t)return{behavior:"ask",message:`Context solicitó permisos para leer desde ${r}, pero aún no se los has otorgado.`,decisionReason:{type:"rule",rule:t}}}const n=checkWritePermissionForTool(e,t,o,s);if("allow"===n.behavior)return n;if(pathInAllowedWorkingPath(r,o,s))return{behavior:"allow",updatedInput:t,decisionReason:{type:"mode",mode:"default"}};const i=checkReadableInternalPath(W(r),t);if("passthrough"!==i.behavior)return i;const a=matchingRuleForInput(r,o,"read","allow");return a?{behavior:"allow",updatedInput:t,decisionReason:{type:"rule",rule:a}}:{behavior:"ask",message:`Context solicitó permisos para leer desde ${r}, pero aún no se los has otorgado.`,suggestions:generateSuggestions(r,"read",o,s),decisionReason:{type:"workingDir",reason:"Path is outside allowed working directories"}}}export function checkWritePermissionForTool(e,t,o,r){if("function"!=typeof e.getPath)return{behavior:"ask",message:`Claude requested permissions to use ${e.name}, but you haven't granted it yet.`};const s=e.getPath(t),n=r??k(s);for(const e of n){const t=matchingRuleForInput(e,o,"edit","deny");if(t)return{behavior:"deny",message:`Permission to edit ${s} has been denied.`,decisionReason:{type:"rule",rule:t}}}const i=checkEditableInternalPath(W(s),t);if("passthrough"!==i.behavior)return i;const a=matchingRuleForInput(s,{...o,alwaysAllowRules:{session:o.alwaysAllowRules.session??[]}},"edit","allow");if(a){const e=a.ruleValue.ruleContent;if(e&&(e.startsWith(f.slice(0,-2))||e.startsWith(g.slice(0,-2)))&&!e.includes("..")&&e.endsWith("/**"))return{behavior:"allow",updatedInput:t,decisionReason:{type:"rule",rule:a}}}const l=checkPathSafetyForAutoEdit(s,n);if(!l.safe){const e=getClaudeSkillScope(s),t=e?[{type:"addRules",rules:[{toolName:m,ruleContent:e.pattern}],behavior:"allow",destination:"session"}]:generateSuggestions(s,"write",o,n);return{behavior:"ask",message:l.message,suggestions:t,decisionReason:{type:"safetyCheck",reason:l.message,classifierApprovable:l.classifierApprovable}}}for(const e of n){const t=matchingRuleForInput(e,o,"edit","ask");if(t)return{behavior:"ask",message:`Context solicitó permisos para escribir en ${s}, pero aún no se los has otorgado.`,decisionReason:{type:"rule",rule:t}}}const c=pathInAllowedWorkingPath(s,o,n);if("acceptEdits"===o.mode&&c)return{behavior:"allow",updatedInput:t,decisionReason:{type:"mode",mode:o.mode}};const u=matchingRuleForInput(s,o,"edit","allow");return u?{behavior:"allow",updatedInput:t,decisionReason:{type:"rule",rule:u}}:{behavior:"ask",message:`Context solicitó permisos para escribir en ${s}, pero aún no se los has otorgado.`,suggestions:generateSuggestions(s,"write",o,n),decisionReason:c?void 0:{type:"workingDir",reason:"Path is outside allowed working directories"}}}export function generateSuggestions(e,t,o,r){const s=!pathInAllowedWorkingPath(e,o,r);if("read"===t&&s){const t=I(e);return k(t).map(e=>M(e,"session")).filter(e=>void 0!==e)}const n="default"===o.mode||"plan"===o.mode;if("write"===t||"create"===t){const t=n?[{type:"setMode",mode:"acceptEdits",destination:"session"}]:[];if(s){const o=I(e),r=k(o);t.push({type:"addDirectories",directories:r,destination:"session"})}return t}return n?[{type:"setMode",mode:"acceptEdits",destination:"session"}]:[]}export function checkEditableInternalPath(e,o){const r=l(e);if(isSessionPlanFile(r))return{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Plan files for current session are allowed for writing"}};if(isScratchpadPath(r))return{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Scratchpad files for current session are allowed for writing"}};if(t("TEMPLATES")){const t=process.env.CONTEXT_JOB_DIR??process.env.CLAUDE_JOB_DIR;if(t){const r=a(R(),"jobs"),s=k(t).map(l),n=k(r).map(l);if(s.every(e=>n.some(t=>e.startsWith(t+u)))){if(k(e).every(e=>{const t=l(e);return s.some(e=>t===e||t.startsWith(e+u))}))return{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Job directory files for current job are allowed for writing"}}}}}return h(r)?{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Agent memory files are allowed for writing"}}:!p()&&d(r)?{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"auto memory files are allowed for writing"}}:normalizeCaseForComparison(r)===normalizeCaseForComparison(a(w(),".claude","launch.json"))?{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Preview launch config is allowed for writing"}}:{behavior:"passthrough",message:""}}export function checkReadableInternalPath(e,t){const o=l(e);if(function(e){return l(e).startsWith(getSessionMemoryDir())}(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Session memory files are allowed for reading"}};if(function(e){const t=$(C()),o=l(e);return o===t||o.startsWith(t+u)}(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Project directory files are allowed for reading"}};if(isSessionPlanFile(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Plan files for current session are allowed for reading"}};const r=O(),s=r.endsWith(u)?r:r+u;if(o===r||o.startsWith(s))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Tool result files are allowed for reading"}};if(isScratchpadPath(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Scratchpad files for current session are allowed for reading"}};const n=getProjectTempDir();if(o.startsWith(n))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Project temp directory files are allowed for reading"}};if(h(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Agent memory files are allowed for reading"}};if(d(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"auto memory files are allowed for reading"}};const i=a(R(),"tasks")+u;if(o===i.slice(0,-1)||o.startsWith(i))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Task files are allowed for reading"}};const c=a(R(),"teams")+u;if(o===c.slice(0,-1)||o.startsWith(c))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Team files are allowed for reading"}};const p=getBundledSkillsRoot()+u;return o.startsWith(p)?{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Bundled skill reference files are allowed for reading"}}:{behavior:"passthrough",message:""}}
1
+ import{MACRO as e}from"../../recovery/bunBundleShim.js";import{feature as t}from"bun:bundle";import{randomBytes as o}from"crypto";import r from"ignore";import s from"lodash-es/memoize.js";import{homedir as n,tmpdir as a}from"os";import{join as i,normalize as l,posix as c,sep as u}from"path";import{hasAutoMemPathOverride as p,isAutoMemPath as d}from"src/memdir/paths.js";import{isAgentMemoryPath as h}from"src/tools/AgentTool/agentMemory.js";import{CLAUDE_FOLDER_PERMISSION_PATTERN as f,FILE_EDIT_TOOL_NAME as m,GLOBAL_CLAUDE_FOLDER_PERMISSION_PATTERN as g}from"src/tools/FileEditTool/constants.js";import{getOriginalCwd as w,getSessionId as P}from"../../bootstrap/state.js";import{checkStatsigFeatureGate_CACHED_MAY_BE_STALE as y}from"../../services/analytics/growthbook.js";import{FILE_READ_TOOL_NAME as v}from"../../tools/FileReadTool/prompt.js";import{getCwd as R}from"../cwd.js";import{getClaudeConfigHomeDir as C}from"../envUtils.js";import{getFsImplementation as S,getPathsForPermissionCheck as b}from"../fsOperations.js";import{containsPathTraversal as k,expandPath as I,getDirectoryForPath as W,sanitizePath as x}from"../path.js";import{getPlanSlug as D,getPlansDirectory as F}from"../plans.js";import{getPlatform as E}from"../platform.js";import{getProjectDir as T}from"../sessionStorage.js";import{SETTING_SOURCES as A}from"../settings/constants.js";import{getSettingsFilePathForSource as j,getSettingsRootPathForSource as $}from"../settings/settings.js";import{containsVulnerableUncPath as O}from"../shell/readOnlyCommandValidation.js";import{getToolResultsDir as _}from"../toolResultStorage.js";import{windowsPathToPosixPath as N}from"../windowsPaths.js";import{createReadRuleSuggestion as z}from"./PermissionUpdate.js";import{getRuleByContentsForToolName as M}from"./permissions.js";export const DANGEROUS_FILES=[".gitconfig",".gitmodules",".bashrc",".bash_profile",".zshrc",".zprofile",".profile",".ripgreprc",".mcp.json",".claude.json"];export const DANGEROUS_DIRECTORIES=[".git",".vscode",".idea",".claude"];export function normalizeCaseForComparison(e){return e.toLowerCase()}export function getClaudeSkillScope(e){const t=I(e),o=normalizeCaseForComparison(t),r=[{dir:I(i(w(),".context","skills")),prefix:"/.context/skills/"},{dir:I(i(C(),"skills")),prefix:"~/.context/skills/"},{dir:I(i(w(),".context","skills")),prefix:"/.context/skills/"},{dir:I(i(n(),".context","skills")),prefix:"~/.context/skills/"}];for(const{dir:e,prefix:s}of r){const r=normalizeCaseForComparison(e);for(const n of[u,"/"])if(o.startsWith(r+n.toLowerCase())){const o=t.slice(e.length+n.length),r=o.indexOf("/"),a="\\"===u?o.indexOf("\\"):-1,i=-1===r?a:-1===a?r:Math.min(r,a);if(i<=0)return null;const l=o.slice(0,i);return!l||"."===l||l.includes("..")||/[*?[\]]/.test(l)?null:{skillName:l,pattern:s+l+"/**"}}}return null}const L=c.sep;export function relativePath(e,t){if("windows"===E()){const o=N(e),r=N(t);return c.relative(o,r)}return c.relative(e,t)}export function toPosixPath(e){return"windows"===E()?N(e):e}export function isClaudeSettingsPath(e){const t=normalizeCaseForComparison(I(e));return!(!t.endsWith(`${u}.context${u}settings.json`)&&!t.endsWith(`${u}.context${u}settings.local.json`))||A.map(e=>j(e)).filter(e=>void 0!==e).some(e=>normalizeCaseForComparison(e)===t)}function isClaudeConfigFilePath(e){if(isClaudeSettingsPath(e))return!0;const t=i(w(),".claude","commands"),o=i(w(),".claude","agents"),r=i(w(),".claude","skills"),s=i(w(),".context","commands"),n=i(w(),".context","agents"),a=i(w(),".context","skills");return pathInWorkingPath(e,t)||pathInWorkingPath(e,o)||pathInWorkingPath(e,r)||pathInWorkingPath(e,s)||pathInWorkingPath(e,n)||pathInWorkingPath(e,a)}function isSessionPlanFile(e){const t=i(F(),D()),o=l(e);return o.startsWith(t)&&o.endsWith(".md")}export function getSessionMemoryDir(){return i(T(R()),P(),"session-memory")+u}export function getSessionMemoryPath(){return i(getSessionMemoryDir(),"summary.md")}export function isScratchpadEnabled(){return y("tengu_scratch")}export function getClaudeTempDirName(){return"windows"===E()?"claude":`claude-${process.getuid?.()??0}`}export const getClaudeTempDir=s(function(){const e=process.env.CONTEXT_CODE_TMPDIR||process.env.CLAUDE_CODE_TMPDIR||("windows"===E()?a():"/tmp"),t=S();let o=e;try{o=t.realpathSync(e)}catch{}return i(o,getClaudeTempDirName())+u});export const getBundledSkillsRoot=s(function(){const t=o(16).toString("hex");return i(getClaudeTempDir(),"bundled-skills",e.VERSION,t)});export function getProjectTempDir(){return i(getClaudeTempDir(),x(w()))+u}export function getScratchpadDir(){return i(getProjectTempDir(),P(),"scratchpad")}export async function ensureScratchpadDir(){if(!isScratchpadEnabled())throw new Error("Scratchpad directory feature is not enabled");const e=S(),t=getScratchpadDir();return await e.mkdir(t,{mode:448}),t}function isScratchpadPath(e){if(!isScratchpadEnabled())return!1;const t=getScratchpadDir(),o=l(e);return o===t||o.startsWith(t+u)}function isDangerousFilePathToAutoEdit(e){const t=I(e).split(u),o=t.at(-1);if(e.startsWith("\\\\")||e.startsWith("//"))return!0;for(let e=0;e<t.length;e++){const o=normalizeCaseForComparison(t[e]);for(const r of DANGEROUS_DIRECTORIES)if(o===normalizeCaseForComparison(r)){if(".claude"===r){const o=t[e+1];if(o&&"worktrees"===normalizeCaseForComparison(o))break}return!0}}if(o){const e=normalizeCaseForComparison(o);if(DANGEROUS_FILES.some(t=>normalizeCaseForComparison(t)===e))return!0}return!1}function hasSuspiciousWindowsPathPattern(e){return("windows"===E()||"wsl"===E())&&-1!==e.indexOf(":",2)||!!(/~\d/.test(e)||e.startsWith("\\\\?\\")||e.startsWith("\\\\.\\")||e.startsWith("//?/")||e.startsWith("//./")||/[.\s]+$/.test(e)||/\.(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/i.test(e)||/(^|\/|\\)\.{3,}(\/|\\|$)/.test(e)||O(e))}export function checkPathSafetyForAutoEdit(e,t){const o=t??b(e);for(const t of o)if(hasSuspiciousWindowsPathPattern(t))return{safe:!1,message:`Claude requested permissions to write to ${e}, which contains a suspicious Windows path pattern that requires manual approval.`,classifierApprovable:!1};for(const t of o)if(isClaudeConfigFilePath(t))return{safe:!1,message:`Context solicitó permisos para escribir en ${e}, pero aún no se los has otorgado.`,classifierApprovable:!0};for(const t of o)if(isDangerousFilePathToAutoEdit(t))return{safe:!1,message:`Claude requested permissions to edit ${e} which is a sensitive file.`,classifierApprovable:!0};return{safe:!0}}export function allWorkingDirectories(e){return new Set([w(),...e.additionalWorkingDirectories.keys()])}export const getResolvedWorkingDirPaths=s(b);export function pathInAllowedWorkingPath(e,t,o){const r=o??b(e),s=Array.from(allWorkingDirectories(t)).flatMap(e=>getResolvedWorkingDirPaths(e));return r.every(e=>s.some(t=>pathInWorkingPath(e,t)))}export function pathInWorkingPath(e,t){const o=I(e),r=I(t),s=o.replace(/^\/private\/var\//,"/var/").replace(/^\/private\/tmp(\/|$)/,"/tmp$1"),n=r.replace(/^\/private\/var\//,"/var/").replace(/^\/private\/tmp(\/|$)/,"/tmp$1"),a=normalizeCaseForComparison(s),i=relativePath(normalizeCaseForComparison(n),a);return""===i||!k(i)&&!c.isAbsolute(i)}function rootPathForSource(e){switch(e){case"cliArg":case"command":case"session":return I(w());case"userSettings":case"policySettings":case"projectSettings":case"localSettings":case"flagSettings":return $(e)}}function prependDirSep(e){return c.join(L,e)}function normalizePatternToPath({patternRoot:e,pattern:t,rootPath:o}){const r=c.join(e,t);if(e===o)return prependDirSep(t);if(r.startsWith(`${o}${L}`))return prependDirSep(r.slice(o.length));{const r=c.relative(o,e);return!r||r.startsWith(`..${L}`)||".."===r?null:prependDirSep(c.join(r,t))}}export function normalizePatternsToPath(e,t){const o=new Set(e.get(null)??[]);for(const[r,s]of e.entries())if(null!==r)for(const e of s){const s=normalizePatternToPath({patternRoot:r,pattern:e,rootPath:t});s&&o.add(s)}return Array.from(o)}export function getFileReadIgnorePatterns(e){const t=getPatternsByRoot(e,"read","deny"),o=new Map;for(const[e,r]of t.entries())o.set(e,Array.from(r.keys()));return o}function patternWithRoot(e,t){if(e.startsWith(`${L}${L}`)){const t=e.slice(1);if("windows"===E()&&t.match(/^\/[a-z]\//i)){const e=t[1]?.toUpperCase()??"C",o=t.slice(2),r=`${e}:\\`;return{relativePattern:o.startsWith("/")?o.slice(1):o,root:r}}return{relativePattern:t,root:L}}if(e.startsWith(`~${L}`))return{relativePattern:e.slice(1),root:n().normalize("NFC")};if(e.startsWith(L))return{relativePattern:e,root:rootPathForSource(t)};let o=e;return e.startsWith(`.${L}`)&&(o=e.slice(2)),{relativePattern:o,root:null}}function getPatternsByRoot(e,t,o){const r=(()=>{switch(t){case"edit":return m;case"read":return v}})(),s=M(e,r,o),n=new Map;for(const[e,t]of s.entries()){const{relativePattern:o,root:r}=patternWithRoot(e,t.source);let s=n.get(r);void 0===s&&(s=new Map,n.set(r,s)),s.set(o,t)}return n}export function matchingRuleForInput(e,t,o,s){let n=I(e);"windows"===E()&&n.includes("\\")&&(n=N(n));const a=getPatternsByRoot(t,o,s);for(const[e,t]of a.entries()){const o=Array.from(t.keys()).map(e=>{let t=e;return t.endsWith("/**")&&(t=t.slice(0,-3)),t}),s=r().add(o),a=relativePath(e??R(),n??R());if(a.startsWith(`..${L}`))continue;if(!a)continue;const i=s.test(a);if(i.ignored&&i.rule){const e=i.rule.pattern,o=e+"/**";return t.has(o)?t.get(o)??null:t.get(e)??null}}return null}export function checkReadPermissionForTool(e,t,o){if("function"!=typeof e.getPath)return{behavior:"ask",message:`Claude requested permissions to use ${e.name}, but you haven't granted it yet.`};const r=e.getPath(t),s=b(r);for(const e of s)if(e.startsWith("\\\\")||e.startsWith("//"))return{behavior:"ask",message:`Claude requested permissions to read from ${r}, which appears to be a UNC path that could access network resources.`,decisionReason:{type:"other",reason:"UNC path detected (defense-in-depth check)"}};for(const e of s)if(hasSuspiciousWindowsPathPattern(e))return{behavior:"ask",message:`Claude requested permissions to read from ${r}, which contains a suspicious Windows path pattern that requires manual approval.`,decisionReason:{type:"other",reason:"Path contains suspicious Windows-specific patterns (alternate data streams, short names, long path prefixes, or three or more consecutive dots) that require manual verification"}};for(const e of s){const t=matchingRuleForInput(e,o,"read","deny");if(t)return{behavior:"deny",message:`Permission to read ${r} has been denied.`,decisionReason:{type:"rule",rule:t}}}for(const e of s){const t=matchingRuleForInput(e,o,"read","ask");if(t)return{behavior:"ask",message:`Context solicitó permisos para leer desde ${r}, pero aún no se los has otorgado.`,decisionReason:{type:"rule",rule:t}}}const n=checkWritePermissionForTool(e,t,o,s);if("allow"===n.behavior)return n;if(pathInAllowedWorkingPath(r,o,s))return{behavior:"allow",updatedInput:t,decisionReason:{type:"mode",mode:"default"}};const a=checkReadableInternalPath(I(r),t);if("passthrough"!==a.behavior)return a;const i=matchingRuleForInput(r,o,"read","allow");return i?{behavior:"allow",updatedInput:t,decisionReason:{type:"rule",rule:i}}:{behavior:"ask",message:`Context solicitó permisos para leer desde ${r}, pero aún no se los has otorgado.`,suggestions:generateSuggestions(r,"read",o,s),decisionReason:{type:"workingDir",reason:"Path is outside allowed working directories"}}}export function checkWritePermissionForTool(e,t,o,r){if("function"!=typeof e.getPath)return{behavior:"ask",message:`Claude requested permissions to use ${e.name}, but you haven't granted it yet.`};const s=e.getPath(t),n=r??b(s);for(const e of n){const t=matchingRuleForInput(e,o,"edit","deny");if(t)return{behavior:"deny",message:`Permission to edit ${s} has been denied.`,decisionReason:{type:"rule",rule:t}}}const a=checkEditableInternalPath(I(s),t);if("passthrough"!==a.behavior)return a;const i=matchingRuleForInput(s,{...o,alwaysAllowRules:{session:o.alwaysAllowRules.session??[]}},"edit","allow");if(i){const e=i.ruleValue.ruleContent;if(e&&(e.startsWith(f.slice(0,-2))||e.startsWith(g.slice(0,-2)))&&!e.includes("..")&&e.endsWith("/**"))return{behavior:"allow",updatedInput:t,decisionReason:{type:"rule",rule:i}}}const l=checkPathSafetyForAutoEdit(s,n);if(!l.safe){const e=getClaudeSkillScope(s),t=e?[{type:"addRules",rules:[{toolName:m,ruleContent:e.pattern}],behavior:"allow",destination:"session"}]:generateSuggestions(s,"write",o,n);return{behavior:"ask",message:l.message,suggestions:t,decisionReason:{type:"safetyCheck",reason:l.message,classifierApprovable:l.classifierApprovable}}}for(const e of n){const t=matchingRuleForInput(e,o,"edit","ask");if(t)return{behavior:"ask",message:`Context solicitó permisos para escribir en ${s}, pero aún no se los has otorgado.`,decisionReason:{type:"rule",rule:t}}}const c=pathInAllowedWorkingPath(s,o,n);if("acceptEdits"===o.mode&&c)return{behavior:"allow",updatedInput:t,decisionReason:{type:"mode",mode:o.mode}};const u=matchingRuleForInput(s,o,"edit","allow");return u?{behavior:"allow",updatedInput:t,decisionReason:{type:"rule",rule:u}}:{behavior:"ask",message:`Context solicitó permisos para escribir en ${s}, pero aún no se los has otorgado.`,suggestions:generateSuggestions(s,"write",o,n),decisionReason:c?void 0:{type:"workingDir",reason:"Path is outside allowed working directories"}}}export function generateSuggestions(e,t,o,r){const s=!pathInAllowedWorkingPath(e,o,r);if("read"===t&&s){const t=W(e);return b(t).map(e=>z(e,"session")).filter(e=>void 0!==e)}const n="default"===o.mode||"plan"===o.mode;if("write"===t||"create"===t){const t=n?[{type:"setMode",mode:"acceptEdits",destination:"session"}]:[];if(s){const o=W(e),r=b(o);t.push({type:"addDirectories",directories:r,destination:"session"})}return t}return n?[{type:"setMode",mode:"acceptEdits",destination:"session"}]:[]}export function checkEditableInternalPath(e,o){const r=l(e);if(isSessionPlanFile(r))return{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Plan files for current session are allowed for writing"}};if(isScratchpadPath(r))return{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Scratchpad files for current session are allowed for writing"}};if(t("TEMPLATES")){const t=process.env.CONTEXT_JOB_DIR??process.env.CLAUDE_JOB_DIR;if(t){const r=i(C(),"jobs"),s=b(t).map(l),n=b(r).map(l);if(s.every(e=>n.some(t=>e.startsWith(t+u)))&&b(e).every(e=>{const t=l(e);return s.some(e=>t===e||t.startsWith(e+u))}))return{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Job directory files for current job are allowed for writing"}}}}return h(r)?{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Agent memory files are allowed for writing"}}:!p()&&d(r)?{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"auto memory files are allowed for writing"}}:normalizeCaseForComparison(r)===normalizeCaseForComparison(i(w(),".claude","launch.json"))?{behavior:"allow",updatedInput:o,decisionReason:{type:"other",reason:"Preview launch config is allowed for writing"}}:{behavior:"passthrough",message:""}}export function checkReadableInternalPath(e,t){const o=l(e);if(function(e){return l(e).startsWith(getSessionMemoryDir())}(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Session memory files are allowed for reading"}};if(function(e){const t=T(R()),o=l(e);return o===t||o.startsWith(t+u)}(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Project directory files are allowed for reading"}};if(isSessionPlanFile(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Plan files for current session are allowed for reading"}};const r=_(),s=r.endsWith(u)?r:r+u;if(o===r||o.startsWith(s))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Tool result files are allowed for reading"}};if(isScratchpadPath(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Scratchpad files for current session are allowed for reading"}};const n=getProjectTempDir();if(o.startsWith(n))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Project temp directory files are allowed for reading"}};if(h(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Agent memory files are allowed for reading"}};if(d(o))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"auto memory files are allowed for reading"}};const a=i(C(),"tasks")+u;if(o===a.slice(0,-1)||o.startsWith(a))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Task files are allowed for reading"}};const c=i(C(),"teams")+u;if(o===c.slice(0,-1)||o.startsWith(c))return{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Team files are allowed for reading"}};const p=getBundledSkillsRoot()+u;return o.startsWith(p)?{behavior:"allow",updatedInput:t,decisionReason:{type:"other",reason:"Bundled skill reference files are allowed for reading"}}:{behavior:"passthrough",message:""}}
@@ -1 +1 @@
1
- import{feature as e}from"../../recovery/bunBundleShim.js";import{logForDebugging as o}from"../debug.js";import{getAutoModeUnavailableReason as s,isAutoModeGateEnabled as t,transitionPermissionMode as a}from"./permissionSetup.js";function canCycleToAuto(a){if(e("TRANSCRIPT_CLASSIFIER")){const e=t(),i=!!a.isAutoModeAvailable&&e;return i||o(`[auto-mode] canCycleToAuto=false: ctx.isAutoModeAvailable=${a.isAutoModeAvailable} isAutoModeGateEnabled=${e} reason=${s()}`),i}return!1}export function getNextPermissionMode(e,o){switch(e.mode){case"default":return"ant"===process.env.USER_TYPE?e.isBypassPermissionsModeAvailable?"bypassPermissions":canCycleToAuto(e)?"auto":"default":"acceptEdits";case"acceptEdits":return"plan";case"plan":return e.isBypassPermissionsModeAvailable?"bypassPermissions":canCycleToAuto(e)?"auto":"default";case"bypassPermissions":return canCycleToAuto(e)?"auto":"default";default:return"default"}}export function cyclePermissionMode(e,o){const s=getNextPermissionMode(e,o);return{nextMode:s,context:a(e.mode,s,e)}}
1
+ import{feature as e}from"bun:bundle";import{logForDebugging as o}from"../debug.js";import{getAutoModeUnavailableReason as s,isAutoModeGateEnabled as t,transitionPermissionMode as a}from"./permissionSetup.js";function canCycleToAuto(a){if(e("TRANSCRIPT_CLASSIFIER")){const e=t(),n=!!a.isAutoModeAvailable&&e;return n||o(`[auto-mode] canCycleToAuto=false: ctx.isAutoModeAvailable=${a.isAutoModeAvailable} isAutoModeGateEnabled=${e} reason=${s()}`),n}return!1}export function getNextPermissionMode(e,o){switch(e.mode){case"default":return"ant"===process.env.USER_TYPE?e.isBypassPermissionsModeAvailable?"bypassPermissions":canCycleToAuto(e)?"auto":"default":"acceptEdits";case"acceptEdits":return"plan";case"plan":return e.isBypassPermissionsModeAvailable?"bypassPermissions":canCycleToAuto(e)?"auto":"default";case"bypassPermissions":return canCycleToAuto(e)?"auto":"default";default:return"default"}}export function cyclePermissionMode(e,o){const s=getNextPermissionMode(e,o);return{nextMode:s,context:a(e.mode,s,e)}}
@@ -1 +1 @@
1
- import e from"lodash-es/memoize.js";import{homedir as o}from"os";import{dirname as t,isAbsolute as a,resolve as n}from"path";import{getPlatform as r}from"../platform.js";import{getFsImplementation as i,getPathsForPermissionCheck as s,safeResolvePath as l}from"../fsOperations.js";import{containsPathTraversal as d}from"../path.js";import{SandboxManager as c}from"../sandbox/sandbox-adapter.js";import{containsVulnerableUncPath as p}from"../shell/readOnlyCommandValidation.js";import{checkEditableInternalPath as f,checkPathSafetyForAutoEdit as u,checkReadableInternalPath as h,matchingRuleForInput as m,pathInAllowedWorkingPath as w,pathInWorkingPath as v}from"./filesystem.js";const x=/[*?[\]{}]/;export function formatDirectoryList(e){const o=e.length;if(o<=5)return e.map(e=>`'${e}'`).join(", ");return`${e.slice(0,5).map(e=>`'${e}'`).join(", ")}, and ${o-5} more`}export function getGlobBaseDirectory(e){const o=e.match(x);if(!o||void 0===o.index)return e;const t=e.substring(0,o.index),a="windows"===r()?Math.max(t.lastIndexOf("/"),t.lastIndexOf("\\")):t.lastIndexOf("/");return-1===a?".":t.substring(0,a)||"/"}export function expandTilde(e){return"~"===e||e.startsWith("~/")||"win32"===process.platform&&e.startsWith("~\\")?o()+e.slice(1):e}export function isPathInSandboxWriteAllowlist(e){if(!c.isSandboxingEnabled())return!1;const{allowOnly:o,denyWithinAllow:t}=c.getFsWriteConfig(),a=s(e),n=o.flatMap(P),r=t.flatMap(P);return a.every(e=>{for(const o of r)if(v(e,o))return!1;return n.some(o=>v(e,o))})}const P=e(s);export function isPathAllowed(e,o,t,a){const n="read"===t?"read":"edit",r=m(e,o,n,"deny");if(null!==r)return{allowed:!1,decisionReason:{type:"rule",rule:r}};if("read"!==t){const o=f(e,{});if("allow"===o.behavior)return{allowed:!0,decisionReason:o.decisionReason}}if("read"!==t){const o=u(e,a);if(!o.safe)return{allowed:!1,decisionReason:{type:"safetyCheck",reason:o.message,classifierApprovable:o.classifierApprovable}}}const i=w(e,o,a);if(i&&("read"===t||"acceptEdits"===o.mode))return{allowed:!0};if("read"===t){const o=h(e,{});if("allow"===o.behavior)return{allowed:!0,decisionReason:o.decisionReason}}if("read"!==t&&!i&&isPathInSandboxWriteAllowlist(e))return{allowed:!0,decisionReason:{type:"other",reason:"Path is in sandbox write allowlist"}};const s=m(e,o,n,"allow");return null!==s?{allowed:!0,decisionReason:{type:"rule",rule:s}}:{allowed:!1}}export function validateGlobPattern(e,o,t,r){if(d(e)){const s=a(e)?e:n(o,e),{resolvedPath:d,isCanonical:c}=l(i(),s),p=isPathAllowed(d,t,r,c?[d]:void 0);return{allowed:p.allowed,resolvedPath:d,decisionReason:p.decisionReason}}const s=getGlobBaseDirectory(e),c=a(s)?s:n(o,s),{resolvedPath:p,isCanonical:f}=l(i(),c),u=isPathAllowed(p,t,r,f?[p]:void 0);return{allowed:u.allowed,resolvedPath:p,decisionReason:u.decisionReason}}const y=/^[A-Za-z]:\/?$/,R=/^[A-Za-z]:\/[^/]+$/;export function isDangerousRemovalPath(e){const a=e.replace(/[\\/]+/g,"/");if("*"===a||a.endsWith("/*"))return!0;const n="/"===a?a:a.replace(/\/$/,"");if("/"===n)return!0;if(y.test(n))return!0;if(n===o().replace(/[\\/]+/g,"/"))return!0;return"/"===t(n)||!!R.test(n)}export function validatePath(e,o,t,r){const s=expandTilde(e.replace(/^['"]|['"]$/g,""));if(p(s))return{allowed:!1,resolvedPath:s,decisionReason:{type:"other",reason:"UNC network paths require manual approval"}};if(s.startsWith("~"))return{allowed:!1,resolvedPath:s,decisionReason:{type:"other",reason:"Tilde expansion variants (~user, ~+, ~-) in paths require manual approval"}};if(s.includes("$")||s.includes("%")||s.startsWith("="))return{allowed:!1,resolvedPath:s,decisionReason:{type:"other",reason:"Shell expansion syntax in paths requires manual approval"}};if(x.test(s))return"write"===r||"create"===r?{allowed:!1,resolvedPath:s,decisionReason:{type:"other",reason:"Glob patterns are not allowed in write operations. Please specify an exact file path."}}:validateGlobPattern(s,o,t,r);const d=a(s)?s:n(o,s),{resolvedPath:c,isCanonical:f}=l(i(),d),u=isPathAllowed(c,t,r,f?[c]:void 0);return{allowed:u.allowed,resolvedPath:c,decisionReason:u.decisionReason}}
1
+ import e from"lodash-es/memoize.js";import{homedir as a}from"os";import{dirname as o,isAbsolute as t,resolve as n}from"path";import{getPlatform as s}from"../platform.js";import{getFsImplementation as r,getPathsForPermissionCheck as i,safeResolvePath as l}from"../fsOperations.js";import{containsPathTraversal as d}from"../path.js";import{SandboxManager as c}from"../sandbox/sandbox-adapter.js";import{containsVulnerableUncPath as p}from"../shell/readOnlyCommandValidation.js";import{checkEditableInternalPath as h,checkPathSafetyForAutoEdit as f,checkReadableInternalPath as u,matchingRuleForInput as m,pathInAllowedWorkingPath as w,pathInWorkingPath as P}from"./filesystem.js";const v=/[*?[\]{}]/;export 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`}export function getGlobBaseDirectory(e){const a=e.match(v);if(!a||void 0===a.index)return e;const o=e.substring(0,a.index),t="windows"===s()?Math.max(o.lastIndexOf("/"),o.lastIndexOf("\\")):o.lastIndexOf("/");return-1===t?".":o.substring(0,t)||"/"}export function expandTilde(e){return"~"===e||e.startsWith("~/")||"win32"===process.platform&&e.startsWith("~\\")?a()+e.slice(1):e}export function isPathInSandboxWriteAllowlist(e){if(!c.isSandboxingEnabled())return!1;const{allowOnly:a,denyWithinAllow:o}=c.getFsWriteConfig(),t=i(e),n=a.flatMap(x),s=o.flatMap(x);return t.every(e=>{for(const a of s)if(P(e,a))return!1;return n.some(a=>P(e,a))})}const x=e(i);export function isPathAllowed(e,a,o,t){const n="read"===o?"read":"edit",s=m(e,a,n,"deny");if(null!==s)return{allowed:!1,decisionReason:{type:"rule",rule:s}};if("read"!==o){const a=h(e,{});if("allow"===a.behavior)return{allowed:!0,decisionReason:a.decisionReason}}if("read"!==o){const a=f(e,t);if(!a.safe)return{allowed:!1,decisionReason:{type:"safetyCheck",reason:a.message,classifierApprovable:a.classifierApprovable}}}const r=w(e,a,t);if(r&&("read"===o||"acceptEdits"===a.mode))return{allowed:!0};if("read"===o){const a=u(e,{});if("allow"===a.behavior)return{allowed:!0,decisionReason:a.decisionReason}}if("read"!==o&&!r&&isPathInSandboxWriteAllowlist(e))return{allowed:!0,decisionReason:{type:"other",reason:"Path is in sandbox write allowlist"}};const i=m(e,a,n,"allow");return null!==i?{allowed:!0,decisionReason:{type:"rule",rule:i}}:{allowed:!1}}export function validateGlobPattern(e,a,o,s){if(d(e)){const i=t(e)?e:n(a,e),{resolvedPath:d,isCanonical:c}=l(r(),i),p=isPathAllowed(d,o,s,c?[d]:void 0);return{allowed:p.allowed,resolvedPath:d,decisionReason:p.decisionReason}}const i=getGlobBaseDirectory(e),c=t(i)?i:n(a,i),{resolvedPath:p,isCanonical:h}=l(r(),c),f=isPathAllowed(p,o,s,h?[p]:void 0);return{allowed:f.allowed,resolvedPath:p,decisionReason:f.decisionReason}}const b=/^[A-Za-z]:\/?$/,R=/^[A-Za-z]:\/[^/]+$/;export function isDangerousRemovalPath(e){const t=e.replace(/[\\/]+/g,"/");if("*"===t||t.endsWith("/*"))return!0;const n="/"===t?t:t.replace(/\/$/,"");return"/"===n||(!!b.test(n)||(n===a().replace(/[\\/]+/g,"/")||("/"===o(n)||!!R.test(n))))}export function validatePath(e,a,o,s){const i=expandTilde(e.replace(/^['"]|['"]$/g,""));if(p(i))return{allowed:!1,resolvedPath:i,decisionReason:{type:"other",reason:"UNC network paths require manual approval"}};if(i.startsWith("~"))return{allowed:!1,resolvedPath:i,decisionReason:{type:"other",reason:"Tilde expansion variants (~user, ~+, ~-) in paths require manual approval"}};if(i.includes("$")||i.includes("%")||i.startsWith("="))return{allowed:!1,resolvedPath:i,decisionReason:{type:"other",reason:"Shell expansion syntax in paths requires manual approval"}};if(v.test(i))return"write"===s||"create"===s?{allowed:!1,resolvedPath:i,decisionReason:{type:"other",reason:"Glob patterns are not allowed in write operations. Please specify an exact file path."}}:validateGlobPattern(i,a,o,s);const d=t(i)?i:n(a,i),{resolvedPath:c,isCanonical:h}=l(r(),d),f=isPathAllowed(c,o,s,h?[c]:void 0);return{allowed:f.allowed,resolvedPath:c,decisionReason:f.decisionReason}}
@@ -1 +1 @@
1
- import{feature as o}from"../../recovery/bunBundleShim.js";import{createRequire as e}from"module";const t=e(import.meta.url);import{AGENT_TOOL_NAME as r}from"../../tools/AgentTool/constants.js";import{TASK_OUTPUT_TOOL_NAME as n}from"../../tools/TaskOutputTool/constants.js";import{TASK_STOP_TOOL_NAME as l}from"../../tools/TaskStopTool/prompt.js";const u=o("KAIROS")||o("KAIROS_BRIEF")?t("../../tools/BriefTool/prompt.js").BRIEF_TOOL_NAME:null,a={Task:r,KillShell:l,AgentOutputTool:n,BashOutputTool:n,...(o("KAIROS")||o("KAIROS_BRIEF"))&&u?{Brief:u}:{}};export function normalizeLegacyToolName(o){return a[o]??o}export function getLegacyToolNames(o){const e=[];for(const[t,r]of Object.entries(a))r===o&&e.push(t);return e}export function escapeRuleContent(o){return o.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")}export function unescapeRuleContent(o){return o.replace(/\\\(/g,"(").replace(/\\\)/g,")").replace(/\\\\/g,"\\")}export function permissionRuleValueFromString(o){const e=function(o,e){for(let t=0;t<o.length;t++)if(o[t]===e){let e=0,r=t-1;for(;r>=0&&"\\"===o[r];)e++,r--;if(e%2==0)return t}return-1}(o,"(");if(-1===e)return{toolName:normalizeLegacyToolName(o)};const t=function(o,e){for(let t=o.length-1;t>=0;t--)if(o[t]===e){let e=0,r=t-1;for(;r>=0&&"\\"===o[r];)e++,r--;if(e%2==0)return t}return-1}(o,")");if(-1===t||t<=e)return{toolName:normalizeLegacyToolName(o)};if(t!==o.length-1)return{toolName:normalizeLegacyToolName(o)};const r=o.substring(0,e),n=o.substring(e+1,t);if(!r)return{toolName:normalizeLegacyToolName(o)};if(""===n||"*"===n)return{toolName:normalizeLegacyToolName(r)};const l=unescapeRuleContent(n);return{toolName:normalizeLegacyToolName(r),ruleContent:l}}export function permissionRuleValueToString(o){if(!o.ruleContent)return o.toolName;const e=escapeRuleContent(o.ruleContent);return`${o.toolName}(${e})`}
1
+ import{createRequire as e}from"module";const o=e(import.meta.url);import{feature as t}from"bun:bundle";import{AGENT_TOOL_NAME as r}from"../../tools/AgentTool/constants.js";import{TASK_OUTPUT_TOOL_NAME as n}from"../../tools/TaskOutputTool/constants.js";import{TASK_STOP_TOOL_NAME as l}from"../../tools/TaskStopTool/prompt.js";const a=t("KAIROS")||t("KAIROS_BRIEF")?o("../../tools/BriefTool/prompt.js").BRIEF_TOOL_NAME:null,u={Task:r,KillShell:l,AgentOutputTool:n,BashOutputTool:n,...(t("KAIROS")||t("KAIROS_BRIEF"))&&a?{Brief:a}:{}};export function normalizeLegacyToolName(e){return u[e]??e}export function getLegacyToolNames(e){const o=[];for(const[t,r]of Object.entries(u))r===e&&o.push(t);return o}export function escapeRuleContent(e){return e.replace(/\\/g,"\\\\").replace(/\(/g,"\\(").replace(/\)/g,"\\)")}export function unescapeRuleContent(e){return e.replace(/\\\(/g,"(").replace(/\\\)/g,")").replace(/\\\\/g,"\\")}export function permissionRuleValueFromString(e){const o=function(e){for(let o=0;o<e.length;o++)if("("===e[o]){let t=0,r=o-1;for(;r>=0&&"\\"===e[r];)t++,r--;if(t%2==0)return o}return-1}(e);if(-1===o)return{toolName:normalizeLegacyToolName(e)};const t=function(e){for(let o=e.length-1;o>=0;o--)if(")"===e[o]){let t=0,r=o-1;for(;r>=0&&"\\"===e[r];)t++,r--;if(t%2==0)return o}return-1}(e);if(-1===t||t<=o)return{toolName:normalizeLegacyToolName(e)};if(t!==e.length-1)return{toolName:normalizeLegacyToolName(e)};const r=e.substring(0,o),n=e.substring(o+1,t);if(!r)return{toolName:normalizeLegacyToolName(e)};if(""===n||"*"===n)return{toolName:normalizeLegacyToolName(r)};const l=unescapeRuleContent(n);return{toolName:normalizeLegacyToolName(r),ruleContent:l}}export function permissionRuleValueToString(e){if(!e.ruleContent)return e.toolName;const o=escapeRuleContent(e.ruleContent);return`${e.toolName}(${o})`}
@@ -1 +1 @@
1
- import{randomUUID as e}from"node:crypto";import{ProviderProfilesDb as t}from"../model/providerProfilesDb.js";export async function upsertPermissionRule(r,n,o,a,s){const i=(await t.get()).db,p=(new Date).toISOString(),c=e();return i.prepare("\n INSERT INTO permission_rules (id, scope, scope_path, tool_name, behavior, created_at, expires_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(scope, scope_path, tool_name) DO UPDATE SET\n behavior = excluded.behavior,\n expires_at = excluded.expires_at\n ").run(c,r,n??null,o,a,p,s??null),{id:c,scope:r,scopePath:n??null,toolName:o,behavior:a,createdAt:p,expiresAt:s??null}}export async function getPermissionRules(e,r){const n=(await t.get()).db;let o="\n SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at\n FROM permission_rules\n WHERE (expires_at IS NULL OR expires_at > ?)\n ";const a=[(new Date).toISOString()];void 0!==e&&(o+=" AND scope = ?",a.push(e)),void 0!==r&&(o+=" AND scope_path = ?",a.push(r??null)),o+=" ORDER BY created_at DESC";return n.prepare(o).all(...a).map(rowToPermissionRule)}export async function findPermissionRule(e,r,n){const o=(await t.get()).db,a=(new Date).toISOString(),s=[];n&&s.push({scope:"directory",path:n}),r&&s.push({scope:"project",path:r}),s.push({scope:"global",path:null});for(const{scope:t,path:r}of s){const n=o.prepare("\n SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at\n FROM permission_rules\n WHERE tool_name = ? AND scope = ? AND scope_path IS ?\n AND (expires_at IS NULL OR expires_at > ?)\n LIMIT 1\n ").get(e,t,r,a);if(n)return rowToPermissionRule(n);const s=o.prepare("\n SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at\n FROM permission_rules\n WHERE scope = ? AND scope_path IS ?\n AND (expires_at IS NULL OR expires_at > ?)\n ORDER BY created_at DESC\n ").all(t,r,a);for(const t of s){if(matchesToolPattern(String(t.tool_name??""),e))return rowToPermissionRule(t)}}return null}export async function deletePermissionRule(e){const r=(await t.get()).db.prepare("DELETE FROM permission_rules WHERE id = ?").run(e);return(r?.changes??0)>0}export async function clearPermissionRules(e,r){const n=(await t.get()).db;if(void 0===e){const e=n.prepare("DELETE FROM permission_rules").run();return e?.changes??0}const o=n.prepare("DELETE FROM permission_rules WHERE scope = ? AND scope_path IS ?").run(e,r??null);return o?.changes??0}export async function purgeExpiredRules(){const e=(await t.get()).db,r=(new Date).toISOString(),n=e.prepare("DELETE FROM permission_rules WHERE expires_at IS NOT NULL AND expires_at <= ?").run(r);return n?.changes??0}export async function setPermissionMode(r,n,o){const a=(await t.get()).db,s=(new Date).toISOString(),i=e();a.prepare("\n INSERT INTO permission_mode_config (id, scope, scope_path, mode, updated_at)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(scope, scope_path) DO UPDATE SET\n mode = excluded.mode,\n updated_at = excluded.updated_at\n ").run(i,r,o??null,n,s)}export async function getEffectivePermissionMode(e){const r=(await t.get()).db;if(e){const t=r.prepare("\n SELECT mode FROM permission_mode_config\n WHERE scope = 'project' AND scope_path = ?\n ").get(e);if(t?.mode)return t.mode}const n=r.prepare("\n SELECT mode FROM permission_mode_config\n WHERE scope = 'global' AND scope_path IS NULL\n ").get();return n?.mode??"default"}export async function getAllPermissionModes(){return(await t.get()).db.prepare("\n SELECT id, scope, scope_path, mode, updated_at\n FROM permission_mode_config\n ORDER BY scope, scope_path\n ").all().map(e=>({id:String(e.id??""),scope:String(e.scope??"global"),scopePath:e.scope_path?String(e.scope_path):null,mode:String(e.mode??"default"),updatedAt:String(e.updated_at??"")}))}export async function addTrustedDirectory(e,r="full"){const n=(await t.get()).db,o=(new Date).toISOString();n.prepare("\n INSERT INTO trusted_directories (path, trust_level, created_at)\n VALUES (?, ?, ?)\n ON CONFLICT(path) DO UPDATE SET\n trust_level = excluded.trust_level\n ").run(e,r,o)}export async function removeTrustedDirectory(e){const r=(await t.get()).db.prepare("DELETE FROM trusted_directories WHERE path = ?").run(e);return(r?.changes??0)>0}export async function isTrustedDirectory(e){const r=(await t.get()).db.prepare("SELECT path, trust_level, created_at FROM trusted_directories WHERE path = ?").get(e);return r?{path:String(r.path??""),trustLevel:String(r.trust_level??"full"),createdAt:String(r.created_at??"")}:null}export async function isPathInTrustedDirectory(e){const r=(await t.get()).db.prepare("SELECT path, trust_level, created_at FROM trusted_directories ORDER BY length(path) DESC").all(),n=e.replace(/\\/g,"/").toLowerCase();for(const e of r){const t=String(e.path??"").replace(/\\/g,"/").toLowerCase();if(n.startsWith(t))return{path:String(e.path??""),trustLevel:String(e.trust_level??"full"),createdAt:String(e.created_at??"")}}return null}export async function getAllTrustedDirectories(){return(await t.get()).db.prepare("SELECT path, trust_level, created_at FROM trusted_directories ORDER BY path").all().map(e=>({path:String(e.path??""),trustLevel:String(e.trust_level??"full"),createdAt:String(e.created_at??"")}))}export async function migratePermissionsFromSettings(e,t,r,n){let o=0,a=0;if(e)for(const t of e)await upsertPermissionRule("global",null,t,"allow"),o++;if(t)for(const e of t)await upsertPermissionRule("global",null,e,"deny"),o++;if(r&&"default"!==r&&await setPermissionMode("global",r),n)for(const e of n)await addTrustedDirectory(e,"full"),a++;return{rulesAdded:o,directoriesAdded:a}}function rowToPermissionRule(e){return{id:String(e.id??""),scope:String(e.scope??"global"),scopePath:e.scope_path?String(e.scope_path):null,toolName:String(e.tool_name??""),behavior:String(e.behavior??"ask"),createdAt:String(e.created_at??""),expiresAt:e.expires_at?String(e.expires_at):null}}function matchesToolPattern(e,t){if(e===t)return!0;if(!e.includes("*"))return!1;const r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");try{return new RegExp(`^${r}$`).test(t)}catch{return!1}}
1
+ import{randomUUID as e}from"node:crypto";import{ProviderProfilesDb as t}from"../model/providerProfilesDb.js";export async function upsertPermissionRule(r,o,n,a,s){const i=(await t.get()).db,p=(new Date).toISOString(),c=e();return i.prepare("\n INSERT INTO permission_rules (id, scope, scope_path, tool_name, behavior, created_at, expires_at)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ON CONFLICT(scope, scope_path, tool_name) DO UPDATE SET\n behavior = excluded.behavior,\n expires_at = excluded.expires_at\n ").run(c,r,o??null,n,a,p,s??null),{id:c,scope:r,scopePath:o??null,toolName:n,behavior:a,createdAt:p,expiresAt:s??null}}export async function getPermissionRules(e,r){const o=(await t.get()).db;let n="\n SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at\n FROM permission_rules\n WHERE (expires_at IS NULL OR expires_at > ?)\n ";const a=[(new Date).toISOString()];return void 0!==e&&(n+=" AND scope = ?",a.push(e)),void 0!==r&&(n+=" AND scope_path = ?",a.push(r??null)),n+=" ORDER BY created_at DESC",o.prepare(n).all(...a).map(rowToPermissionRule)}export async function findPermissionRule(e,r,o){const n=(await t.get()).db,a=(new Date).toISOString(),s=[];o&&s.push({scope:"directory",path:o}),r&&s.push({scope:"project",path:r}),s.push({scope:"global",path:null});for(const{scope:t,path:r}of s){const o=n.prepare("\n SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at\n FROM permission_rules\n WHERE tool_name = ? AND scope = ? AND scope_path IS ?\n AND (expires_at IS NULL OR expires_at > ?)\n LIMIT 1\n ").get(e,t,r,a);if(o)return rowToPermissionRule(o);const s=n.prepare("\n SELECT id, scope, scope_path, tool_name, behavior, created_at, expires_at\n FROM permission_rules\n WHERE scope = ? AND scope_path IS ?\n AND (expires_at IS NULL OR expires_at > ?)\n ORDER BY created_at DESC\n ").all(t,r,a);for(const t of s)if(matchesToolPattern(String(t.tool_name??""),e))return rowToPermissionRule(t)}return null}export async function deletePermissionRule(e){const r=(await t.get()).db.prepare("DELETE FROM permission_rules WHERE id = ?").run(e);return(r?.changes??0)>0}export async function clearPermissionRules(e,r){const o=(await t.get()).db;if(void 0===e){const e=o.prepare("DELETE FROM permission_rules").run();return e?.changes??0}const n=o.prepare("DELETE FROM permission_rules WHERE scope = ? AND scope_path IS ?").run(e,r??null);return n?.changes??0}export async function purgeExpiredRules(){const e=(await t.get()).db,r=(new Date).toISOString(),o=e.prepare("DELETE FROM permission_rules WHERE expires_at IS NOT NULL AND expires_at <= ?").run(r);return o?.changes??0}export async function setPermissionMode(r,o,n){const a=(await t.get()).db,s=(new Date).toISOString(),i=e();a.prepare("\n INSERT INTO permission_mode_config (id, scope, scope_path, mode, updated_at)\n VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(scope, scope_path) DO UPDATE SET\n mode = excluded.mode,\n updated_at = excluded.updated_at\n ").run(i,r,n??null,o,s)}export async function getEffectivePermissionMode(e){const r=(await t.get()).db;if(e){const t=r.prepare("\n SELECT mode FROM permission_mode_config\n WHERE scope = 'project' AND scope_path = ?\n ").get(e);if(t?.mode)return t.mode}const o=r.prepare("\n SELECT mode FROM permission_mode_config\n WHERE scope = 'global' AND scope_path IS NULL\n ").get();return o?.mode??"default"}export async function getAllPermissionModes(){return(await t.get()).db.prepare("\n SELECT id, scope, scope_path, mode, updated_at\n FROM permission_mode_config\n ORDER BY scope, scope_path\n ").all().map(e=>({id:String(e.id??""),scope:String(e.scope??"global"),scopePath:e.scope_path?String(e.scope_path):null,mode:String(e.mode??"default"),updatedAt:String(e.updated_at??"")}))}export async function addTrustedDirectory(e,r="full"){const o=(await t.get()).db,n=(new Date).toISOString();o.prepare("\n INSERT INTO trusted_directories (path, trust_level, created_at)\n VALUES (?, ?, ?)\n ON CONFLICT(path) DO UPDATE SET\n trust_level = excluded.trust_level\n ").run(e,r,n)}export async function removeTrustedDirectory(e){const r=(await t.get()).db.prepare("DELETE FROM trusted_directories WHERE path = ?").run(e);return(r?.changes??0)>0}export async function isTrustedDirectory(e){const r=(await t.get()).db.prepare("SELECT path, trust_level, created_at FROM trusted_directories WHERE path = ?").get(e);return r?{path:String(r.path??""),trustLevel:String(r.trust_level??"full"),createdAt:String(r.created_at??"")}:null}export async function isPathInTrustedDirectory(e){const r=(await t.get()).db.prepare("SELECT path, trust_level, created_at FROM trusted_directories ORDER BY length(path) DESC").all(),o=e.replace(/\\/g,"/").toLowerCase();for(const e of r){const t=String(e.path??"").replace(/\\/g,"/").toLowerCase();if(o.startsWith(t))return{path:String(e.path??""),trustLevel:String(e.trust_level??"full"),createdAt:String(e.created_at??"")}}return null}export async function getAllTrustedDirectories(){return(await t.get()).db.prepare("SELECT path, trust_level, created_at FROM trusted_directories ORDER BY path").all().map(e=>({path:String(e.path??""),trustLevel:String(e.trust_level??"full"),createdAt:String(e.created_at??"")}))}export async function migratePermissionsFromSettings(e,t,r,o){let n=0,a=0;if(e)for(const t of e)await upsertPermissionRule("global",null,t,"allow"),n++;if(t)for(const e of t)await upsertPermissionRule("global",null,e,"deny"),n++;if(r&&"default"!==r&&await setPermissionMode("global",r),o)for(const e of o)await addTrustedDirectory(e,"full"),a++;return{rulesAdded:n,directoriesAdded:a}}function rowToPermissionRule(e){return{id:String(e.id??""),scope:String(e.scope??"global"),scopePath:e.scope_path?String(e.scope_path):null,toolName:String(e.tool_name??""),behavior:String(e.behavior??"ask"),createdAt:String(e.created_at??""),expiresAt:e.expires_at?String(e.expires_at):null}}function matchesToolPattern(e,t){if(e===t)return!0;if(!e.includes("*"))return!1;const r=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&").replace(/\*/g,".*");try{return new RegExp(`^${r}$`).test(t)}catch{return!1}}
@@ -1 +1 @@
1
- import{readFileSync as r}from"../fileRead.js";import{getFsImplementation as s,safeResolvePath as e}from"../fsOperations.js";import{safeParseJSON as o}from"../json.js";import{logError as n}from"../log.js";import{getEnabledSettingSources as t}from"../settings/constants.js";import{getSettingsFilePathForSource as i,getSettingsForSource as u,updateSettingsForSource as l}from"../settings/settings.js";import{permissionRuleValueFromString as c,permissionRuleValueToString as m}from"./permissionRuleParser.js";export function shouldAllowManagedPermissionRulesOnly(){return!0===u("policySettings")?.allowManagedPermissionRulesOnly}export function shouldShowAlwaysAllowOptions(){return!shouldAllowManagedPermissionRulesOnly()}const f=["allow","deny","ask"];export function loadAllPermissionRulesFromDisk(){if(shouldAllowManagedPermissionRulesOnly())return getPermissionRulesForSource("policySettings");const r=[];for(const s of t())r.push(...getPermissionRulesForSource(s));return r}export function getPermissionRulesForSource(r){return function(r,s){if(!r||!r.permissions)return[];const{permissions:e}=r,o=[];for(const r of f){const n=e[r];if(n)for(const e of n)o.push({source:s,ruleBehavior:r,ruleValue:c(e)})}return o}(u(r),r)}const a=["userSettings","projectSettings","localSettings"];export function deletePermissionRuleFromSettings(r){if(!a.includes(r.source))return!1;const s=m(r.ruleValue),e=u(r.source);if(!e||!e.permissions)return!1;const o=e.permissions[r.ruleBehavior];if(!o)return!1;const normalizeEntry=r=>m(c(r));if(!o.some(r=>normalizeEntry(r)===s))return!1;try{const n={...e,permissions:{...e.permissions,[r.ruleBehavior]:o.filter(r=>normalizeEntry(r)!==s)}},{error:t}=l(r.source,n);return!t}catch(r){return n(r),!1}}export function addPermissionRulesToSettings({ruleValues:t,ruleBehavior:f},a){if(shouldAllowManagedPermissionRulesOnly())return!1;if(t.length<1)return!0;const p=t.map(m),g=u(a)||function(n){const t=i(n);if(!t)return null;try{const{resolvedPath:n}=e(s(),t),i=r(n);if(""===i.trim())return{};const u=o(i,!1);return u&&"object"==typeof u?u:null}catch{return null}}(a)||{permissions:{}};try{const r=g.permissions||{},s=r[f]||[],e=new Set(s.map(r=>m(c(r)))),o=p.filter(r=>!e.has(r));if(0===o.length)return!0;const n={...g,permissions:{...r,[f]:[...s,...o]}},t=l(a,n);if(t.error)throw t.error;return!0}catch(r){return n(r),!1}}
1
+ import{readFileSync as e}from"../fileRead.js";import{getFsImplementation as r,safeResolvePath as s}from"../fsOperations.js";import{safeParseJSON as o}from"../json.js";import{logError as t}from"../log.js";import{getEnabledSettingSources as n}from"../settings/constants.js";import{getSettingsFilePathForSource as i,getSettingsForSource as u,updateSettingsForSource as l}from"../settings/settings.js";import{permissionRuleValueFromString as a,permissionRuleValueToString as c}from"./permissionRuleParser.js";export function shouldAllowManagedPermissionRulesOnly(){return!0===u("policySettings")?.allowManagedPermissionRulesOnly}export function shouldShowAlwaysAllowOptions(){return!shouldAllowManagedPermissionRulesOnly()}const m=["allow","deny","ask"];export function loadAllPermissionRulesFromDisk(){if(shouldAllowManagedPermissionRulesOnly())return getPermissionRulesForSource("policySettings");const e=[];for(const r of n())e.push(...getPermissionRulesForSource(r));return e}export function getPermissionRulesForSource(e){return function(e,r){if(!e||!e.permissions)return[];const{permissions:s}=e,o=[];for(const e of m){const t=s[e];if(t)for(const s of t)o.push({source:r,ruleBehavior:e,ruleValue:a(s)})}return o}(u(e),e)}const f=["userSettings","projectSettings","localSettings"];export function deletePermissionRuleFromSettings(e){if(!f.includes(e.source))return!1;const r=c(e.ruleValue),s=u(e.source);if(!s||!s.permissions)return!1;const o=s.permissions[e.ruleBehavior];if(!o)return!1;const normalizeEntry=e=>c(a(e));if(!o.some(e=>normalizeEntry(e)===r))return!1;try{const t={...s,permissions:{...s.permissions,[e.ruleBehavior]:o.filter(e=>normalizeEntry(e)!==r)}},{error:n}=l(e.source,t);return!n}catch(e){return t(e),!1}}export function addPermissionRulesToSettings({ruleValues:n,ruleBehavior:m},f){if(shouldAllowManagedPermissionRulesOnly())return!1;if(n.length<1)return!0;const p=n.map(c),g=u(f)||function(t){const n=i(t);if(!n)return null;try{const{resolvedPath:t}=s(r(),n),i=e(t);if(""===i.trim())return{};const u=o(i,!1);return u&&"object"==typeof u?u:null}catch{return null}}(f)||{permissions:{}};try{const e=g.permissions||{},r=e[m]||[],s=new Set(r.map(e=>c(a(e)))),o=p.filter(e=>!s.has(e));if(0===o.length)return!0;const t={...g,permissions:{...e,[m]:[...r,...o]}},n=l(f,t);if(n.error)throw n.error;return!0}catch(e){return t(e),!1}}
@@ -1 +1 @@
1
- const e="\0ESCAPED_STAR\0",t="\0ESCAPED_BACKSLASH\0",n=new RegExp(e,"g"),r=new RegExp(t,"g");export function permissionRuleExtractPrefix(e){const t=e.match(/^(.+):\*$/);return t?.[1]??null}export function hasWildcards(e){if(e.endsWith(":*"))return!1;for(let t=0;t<e.length;t++)if("*"===e[t]){let n=0,r=t-1;for(;r>=0&&"\\"===e[r];)n++,r--;if(n%2==0)return!0}return!1}export function matchWildcardPattern(o,i,l=!1){const s=o.trim();let a="",c=0;for(;c<s.length;){const n=s[c];if("\\"===n&&c+1<s.length){const n=s[c+1];if("*"===n){a+=e,c+=2;continue}if("\\"===n){a+=t,c+=2;continue}}a+=n,c++}let u=a.replace(/[.+?^${}()|[\]\\'"]/g,"\\$&").replace(/\*/g,".*").replace(n,"\\*").replace(r,"\\\\");const p=(a.match(/\*/g)||[]).length;u.endsWith(" .*")&&1===p&&(u=u.slice(0,-3)+"( .*)?");return new RegExp(`^${u}$`,"s"+(l?"i":"")).test(i)}export function parsePermissionRule(e){const t=permissionRuleExtractPrefix(e);return null!==t?{type:"prefix",prefix:t}:hasWildcards(e)?{type:"wildcard",pattern:e}:{type:"exact",command:e}}export function suggestionForExactCommand(e,t){return[{type:"addRules",rules:[{toolName:e,ruleContent:t}],behavior:"allow",destination:"localSettings"}]}export function suggestionForPrefix(e,t){return[{type:"addRules",rules:[{toolName:e,ruleContent:`${t}:*`}],behavior:"allow",destination:"localSettings"}]}
1
+ const e="\0ESCAPED_STAR\0",t="\0ESCAPED_BACKSLASH\0",n=new RegExp(e,"g"),r=new RegExp(t,"g");export function permissionRuleExtractPrefix(e){const t=e.match(/^(.+):\*$/);return t?.[1]??null}export function hasWildcards(e){if(e.endsWith(":*"))return!1;for(let t=0;t<e.length;t++)if("*"===e[t]){let n=0,r=t-1;for(;r>=0&&"\\"===e[r];)n++,r--;if(n%2==0)return!0}return!1}export function matchWildcardPattern(o,i,l=!1){const s=o.trim();let a="",c=0;for(;c<s.length;){const n=s[c];if("\\"===n&&c+1<s.length){const n=s[c+1];if("*"===n){a+=e,c+=2;continue}if("\\"===n){a+=t,c+=2;continue}}a+=n,c++}let u=a.replace(/[.+?^${}()|[\]\\'"]/g,"\\$&").replace(/\*/g,".*").replace(n,"\\*").replace(r,"\\\\");const p=(a.match(/\*/g)||[]).length;return u.endsWith(" .*")&&1===p&&(u=u.slice(0,-3)+"( .*)?"),new RegExp(`^${u}$`,"s"+(l?"i":"")).test(i)}export function parsePermissionRule(e){const t=permissionRuleExtractPrefix(e);return null!==t?{type:"prefix",prefix:t}:hasWildcards(e)?{type:"wildcard",pattern:e}:{type:"exact",command:e}}export function suggestionForExactCommand(e,t){return[{type:"addRules",rules:[{toolName:e,ruleContent:t}],behavior:"allow",destination:"localSettings"}]}export function suggestionForPrefix(e,t){return[{type:"addRules",rules:[{toolName:e,ruleContent:`${t}:*`}],behavior:"allow",destination:"localSettings"}]}
@@ -1 +1 @@
1
- import{getFeatureValue_CACHED_MAY_BE_STALE as e}from"../services/analytics/growthbook.js";import{getRateLimitTier as n,getSubscriptionType as t}from"./auth.js";import{isEnvDefinedFalsy as r,isEnvTruthy as _}from"./envUtils.js";export function getPlanModeV2AgentCount(){const e=process.env.CONTEXT_CODE_PLAN_V2_AGENT_COUNT??process.env.CLAUDE_CODE_PLAN_V2_AGENT_COUNT;if(e){const n=parseInt(e,10);if(!isNaN(n)&&n>0&&n<=10)return n}const r=t(),_=n();return"max"===r&&"default_claude_max_20x"===_||"enterprise"===r||"team"===r?3:1}export function getPlanModeV2ExploreAgentCount(){const e=process.env.CONTEXT_CODE_PLAN_V2_EXPLORE_AGENT_COUNT??process.env.CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT;if(e){const n=parseInt(e,10);if(!isNaN(n)&&n>0&&n<=10)return n}return 3}export function isPlanModeInterviewPhaseEnabled(){if("ant"===process.env.USER_TYPE)return!0;const n=process.env.CONTEXT_CODE_PLAN_MODE_INTERVIEW_PHASE??process.env.CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE;return!!_(n)||!r(n)&&e("tengu_plan_mode_interview_phase",!1)}export function getPewterLedgerVariant(){const n=e("tengu_pewter_ledger",null);return"trim"===n||"cut"===n||"cap"===n?n:null}
1
+ import{getFeatureValue_CACHED_MAY_BE_STALE as e}from"../services/analytics/growthbook.js";import{getRateLimitTier as t,getSubscriptionType as n}from"./auth.js";import{isEnvDefinedFalsy as r,isEnvTruthy as _}from"./envUtils.js";export function getPlanModeV2AgentCount(){const e=process.env.CONTEXT_CODE_PLAN_V2_AGENT_COUNT??process.env.CLAUDE_CODE_PLAN_V2_AGENT_COUNT;if(e){const t=parseInt(e,10);if(!isNaN(t)&&t>0&&t<=10)return t}const r=n(),_=t();return"max"===r&&"default_claude_max_20x"===_||"enterprise"===r||"team"===r?3:1}export function getPlanModeV2ExploreAgentCount(){const e=process.env.CONTEXT_CODE_PLAN_V2_EXPLORE_AGENT_COUNT??process.env.CLAUDE_CODE_PLAN_V2_EXPLORE_AGENT_COUNT;if(e){const t=parseInt(e,10);if(!isNaN(t)&&t>0&&t<=10)return t}return 3}export function isPlanModeInterviewPhaseEnabled(){if("ant"===process.env.USER_TYPE)return!0;const t=process.env.CONTEXT_CODE_PLAN_MODE_INTERVIEW_PHASE??process.env.CLAUDE_CODE_PLAN_MODE_INTERVIEW_PHASE;return!!_(t)||!r(t)&&e("tengu_plan_mode_interview_phase",!1)}export function getPewterLedgerVariant(){const t=e("tengu_pewter_ledger",null);return"trim"===t||"cut"===t||"cap"===t?t:null}
@@ -1 +1 @@
1
- import{randomUUID as t}from"crypto";import{copyFile as e,writeFile as n}from"fs/promises";import r from"lodash-es/memoize.js";import{join as o,resolve as s,sep as i}from"path";import{getPlanSlugCache as l,getSessionId as a}from"../bootstrap/state.js";import{EXIT_PLAN_MODE_V2_TOOL_NAME as c}from"../tools/ExitPlanModeTool/constants.js";import{getCwd as f}from"./cwd.js";import{logForDebugging as p}from"./debug.js";import{getClaudeConfigHomeDir as u}from"./envUtils.js";import{isENOENT as m}from"./errors.js";import{getEnvironmentKind as g}from"./filePersistence/outputsScanner.js";import{getFsImplementation as y}from"./fsOperations.js";import{logError as h}from"./log.js";import{getInitialSettings as P}from"./settings/settings.js";import{generateWordSlug as d}from"./words.js";export function getPlanSlug(t){const e=t??a(),n=l();let r=n.get(e);if(!r){const t=getPlansDirectory();for(let e=0;e<10;e++){r=d();const e=o(t,`${r}.md`);if(!y().existsSync(e))break}n.set(e,r)}return r}export function setPlanSlug(t,e){l().set(t,e)}export function clearPlanSlug(t){const e=t??a();l().delete(e)}export function clearAllPlanSlugs(){l().clear()}export const getPlansDirectory=r(function(){const t=P().plansDirectory;let e;if(t){const n=f(),r=s(n,t);r.startsWith(n+i)||r===n?e=r:(h(new Error(`plansDirectory must be within project root: ${t}`)),e=o(u(),"plans"))}else e=o(u(),"plans");try{y().mkdirSync(e)}catch(t){h(t)}return e});export function getPlanFilePath(t){const e=getPlanSlug(a());return o(getPlansDirectory(),t?`${e}-agent-${t}.md`:`${e}.md`)}export function getPlan(t){const e=getPlanFilePath(t);try{return y().readFileSync(e,{encoding:"utf-8"})}catch(t){return m(t)||h(t),null}}function getSlugFromLog(t){return t.messages.find(t=>t.slug)?.slug}export async function copyPlanForResume(t,e){const r=getSlugFromLog(t);if(!r)return!1;setPlanSlug(e??a(),r);const s=o(getPlansDirectory(),`${r}.md`);try{return await y().readFile(s,{encoding:"utf-8"}),!0}catch(e){if(!m(e))return h(e),!1;if(null===g())return!1;p(`Plan file missing during resume: ${s}. Attempting recovery.`);const r=function(t,e){for(let n=t.length-1;n>=0;n--){const r=t[n];if("system"===r?.type&&"subtype"in r&&"file_snapshot"===r.subtype&&"snapshotFiles"in r){return r.snapshotFiles.find(t=>t.key===e)}}return}(t.messages,"plan");let o=null;if(r&&r.content.length>0?(o=r.content,p(`Plan recovered from file snapshot, ${o.length} chars`,{level:"info"})):(o=function(t){for(let e=t.messages.length-1;e>=0;e--){const n=t.messages[e];if(n){if("assistant"===n.type){const{content:t}=n.message;if(Array.isArray(t))for(const e of t)if("tool_use"===e.type&&e.name===c){const t=e.input,n=t?.plan;if("string"==typeof n&&n.length>0)return n}}if("user"===n.type){const t=n;if("string"==typeof t.planContent&&t.planContent.length>0)return t.planContent}if("attachment"===n.type){const t=n;if("plan_file_reference"===t.attachment?.type){const e=t.attachment.planContent;if("string"==typeof e&&e.length>0)return e}}}}return null}(t),o&&p(`Plan recovered from message history, ${o.length} chars`,{level:"info"})),o)try{return await n(s,o,{encoding:"utf-8"}),!0}catch(t){return h(t),!1}return p("Plan file recovery failed: no file snapshot or plan content found in message history"),!1}}export async function copyPlanForFork(t,n){const r=getSlugFromLog(t);if(!r)return!1;const s=getPlansDirectory(),i=o(s,`${r}.md`),l=getPlanSlug(n),a=o(s,`${l}.md`);try{return await e(i,a),!0}catch(t){return m(t)||h(t),!1}}export async function persistFileSnapshotIfRemote(){if(null!==g())try{const e=[],n=getPlan();if(n&&e.push({key:"plan",path:getPlanFilePath(),content:n}),0===e.length)return;const r={type:"system",subtype:"file_snapshot",content:"File snapshot",level:"info",isMeta:!0,timestamp:(new Date).toISOString(),uuid:t(),snapshotFiles:e},{recordTranscript:o}=await import("./sessionStorage.js");await o([r])}catch(t){h(t)}}
1
+ import{randomUUID as t}from"crypto";import{copyFile as e,writeFile as n}from"fs/promises";import r from"lodash-es/memoize.js";import{join as o,resolve as s,sep as i}from"path";import{getPlanSlugCache as a,getSessionId as l}from"../bootstrap/state.js";import{EXIT_PLAN_MODE_V2_TOOL_NAME as c}from"../tools/ExitPlanModeTool/constants.js";import{getCwd as f}from"./cwd.js";import{logForDebugging as g}from"./debug.js";import{getClaudeConfigHomeDir as p}from"./envUtils.js";import{isENOENT as u}from"./errors.js";import{getEnvironmentKind as m}from"./filePersistence/outputsScanner.js";import{getFsImplementation as y}from"./fsOperations.js";import{logError as h}from"./log.js";import{getInitialSettings as d}from"./settings/settings.js";import{generateWordSlug as P}from"./words.js";export function getPlanSlug(t){const e=t??l(),n=a();let r=n.get(e);if(!r){const t=getPlansDirectory();for(let e=0;e<10;e++){r=P();const e=o(t,`${r}.md`);if(!y().existsSync(e))break}n.set(e,r)}return r}export function setPlanSlug(t,e){a().set(t,e)}export function clearPlanSlug(t){const e=t??l();a().delete(e)}export function clearAllPlanSlugs(){a().clear()}export const getPlansDirectory=r(function(){const t=d().plansDirectory;let e;if(t){const n=f(),r=s(n,t);r.startsWith(n+i)||r===n?e=r:(h(new Error(`plansDirectory must be within project root: ${t}`)),e=o(p(),"plans"))}else e=o(p(),"plans");try{y().mkdirSync(e)}catch(t){h(t)}return e});export function getPlanFilePath(t){const e=getPlanSlug(l());return o(getPlansDirectory(),t?`${e}-agent-${t}.md`:`${e}.md`)}export function getPlan(t){const e=getPlanFilePath(t);try{return y().readFileSync(e,{encoding:"utf-8"})}catch(t){return u(t)||h(t),null}}function getSlugFromLog(t){return t.messages.find(t=>t.slug)?.slug}export async function copyPlanForResume(t,e){const r=getSlugFromLog(t);if(!r)return!1;setPlanSlug(e??l(),r);const s=o(getPlansDirectory(),`${r}.md`);try{return await y().readFile(s,{encoding:"utf-8"}),!0}catch(e){if(!u(e))return h(e),!1;if(null===m())return!1;g(`Plan file missing during resume: ${s}. Attempting recovery.`);const r=function(t){for(let e=t.length-1;e>=0;e--){const n=t[e];if("system"===n?.type&&"subtype"in n&&"file_snapshot"===n.subtype&&"snapshotFiles"in n)return n.snapshotFiles.find(t=>"plan"===t.key)}}(t.messages);let o=null;if(r&&r.content.length>0?(o=r.content,g(`Plan recovered from file snapshot, ${o.length} chars`,{level:"info"})):(o=function(t){for(let e=t.messages.length-1;e>=0;e--){const n=t.messages[e];if(n){if("assistant"===n.type){const{content:t}=n.message;if(Array.isArray(t))for(const e of t)if("tool_use"===e.type&&e.name===c){const t=e.input,n=t?.plan;if("string"==typeof n&&n.length>0)return n}}if("user"===n.type){const t=n;if("string"==typeof t.planContent&&t.planContent.length>0)return t.planContent}if("attachment"===n.type){const t=n;if("plan_file_reference"===t.attachment?.type){const e=t.attachment.planContent;if("string"==typeof e&&e.length>0)return e}}}}return null}(t),o&&g(`Plan recovered from message history, ${o.length} chars`,{level:"info"})),o)try{return await n(s,o,{encoding:"utf-8"}),!0}catch(t){return h(t),!1}return g("Plan file recovery failed: no file snapshot or plan content found in message history"),!1}}export async function copyPlanForFork(t,n){const r=getSlugFromLog(t);if(!r)return!1;const s=getPlansDirectory(),i=o(s,`${r}.md`),a=getPlanSlug(n),l=o(s,`${a}.md`);try{return await e(i,l),!0}catch(t){return u(t)||h(t),!1}}export async function persistFileSnapshotIfRemote(){if(null!==m())try{const e=[],n=getPlan();if(n&&e.push({key:"plan",path:getPlanFilePath(),content:n}),0===e.length)return;const r={type:"system",subtype:"file_snapshot",content:"File snapshot",level:"info",isMeta:!0,timestamp:(new Date).toISOString(),uuid:t(),snapshotFiles:e},{recordTranscript:o}=await import("./sessionStorage.js");await o([r])}catch(t){h(t)}}
@@ -1 +1 @@
1
- import{readdir as o,readFile as r}from"fs/promises";import t from"lodash-es/memoize.js";import{release as s}from"os";import{getFsImplementation as e}from"./fsOperations.js";import{logError as n}from"./log.js";export const SUPPORTED_PLATFORMS=["macos","wsl"];export const getPlatform=t(()=>{try{if("darwin"===process.platform)return"macos";if("win32"===process.platform)return"windows";if("linux"===process.platform){try{const o=e().readFileSync("/proc/version",{encoding:"utf8"});if(o.toLowerCase().includes("microsoft")||o.toLowerCase().includes("wsl"))return"wsl"}catch(o){n(o)}return"linux"}return"unknown"}catch(o){return n(o),"unknown"}});export const getWslVersion=t(()=>{if("linux"===process.platform)try{const o=e().readFileSync("/proc/version",{encoding:"utf8"}),r=o.match(/WSL(\d+)/i);return r&&r[1]?r[1]:o.toLowerCase().includes("microsoft")?"1":void 0}catch(o){return void n(o)}});export const getLinuxDistroInfo=t(async()=>{if("linux"!==process.platform)return;const o={linuxKernel:s()};try{const t=await r("/etc/os-release","utf8");for(const r of t.split("\n")){const t=r.match(/^(ID|VERSION_ID)=(.*)$/);if(t&&t[1]&&t[2]){const r=t[2].replace(/^"|"$/g,"");"ID"===t[1]?o.linuxDistroId=r:o.linuxDistroVersion=r}}}catch{}return o});const c=[[".git","git"],[".hg","mercurial"],[".svn","svn"],[".p4config","perforce"],["$tf","tfs"],[".tfvc","tfs"],[".jj","jujutsu"],[".sl","sapling"]];export async function detectVcs(r){const t=new Set;process.env.P4PORT&&t.add("perforce");try{const s=r??e().cwd(),n=new Set(await o(s));for(const[o,r]of c)n.has(o)&&t.add(r)}catch{}return[...t]}
1
+ import{readdir as r,readFile as o}from"fs/promises";import t from"lodash-es/memoize.js";import{release as s}from"os";import{getFsImplementation as e}from"./fsOperations.js";import{logError as n}from"./log.js";export const SUPPORTED_PLATFORMS=["macos","wsl"];export const getPlatform=t(()=>{try{if("darwin"===process.platform)return"macos";if("win32"===process.platform)return"windows";if("linux"===process.platform){try{const r=e().readFileSync("/proc/version",{encoding:"utf8"});if(r.toLowerCase().includes("microsoft")||r.toLowerCase().includes("wsl"))return"wsl"}catch(r){n(r)}return"linux"}return"unknown"}catch(r){return n(r),"unknown"}});export const getWslVersion=t(()=>{if("linux"===process.platform)try{const r=e().readFileSync("/proc/version",{encoding:"utf8"}),o=r.match(/WSL(\d+)/i);return o&&o[1]?o[1]:r.toLowerCase().includes("microsoft")?"1":void 0}catch(r){return void n(r)}});export const getLinuxDistroInfo=t(async()=>{if("linux"!==process.platform)return;const r={linuxKernel:s()};try{const t=await o("/etc/os-release","utf8");for(const o of t.split("\n")){const t=o.match(/^(ID|VERSION_ID)=(.*)$/);if(t&&t[1]&&t[2]){const o=t[2].replace(/^"|"$/g,"");"ID"===t[1]?r.linuxDistroId=o:r.linuxDistroVersion=o}}}catch{}return r});const c=[[".git","git"],[".hg","mercurial"],[".svn","svn"],[".p4config","perforce"],["$tf","tfs"],[".tfvc","tfs"],[".jj","jujutsu"],[".sl","sapling"]];export async function detectVcs(o){const t=new Set;process.env.P4PORT&&t.add("perforce");try{const s=o??e().cwd(),n=new Set(await r(s));for(const[r,o]of c)n.has(r)&&t.add(o)}catch{}return[...t]}
@@ -1 +1 @@
1
- import{join as t}from"path";import{getAdditionalDirectoriesForClaudeMd as n}from"../../bootstrap/state.js";import{parseSettingsFile as o}from"../settings/settings.js";const s=["settings.json","settings.local.json"],e=[".context",".claude"];function readAddDirSettings(n,s){for(const r of e){const{settings:e}=o(t(n,r,s));if(e)return e}return null}export function getAddDirEnabledPlugins(){const t={};for(const o of n())for(const n of s){const s=readAddDirSettings(o,n);s?.enabledPlugins&&Object.assign(t,s.enabledPlugins)}return t}export function getAddDirExtraMarketplaces(){const t={};for(const o of n())for(const n of s){const s=readAddDirSettings(o,n);s?.extraKnownMarketplaces&&Object.assign(t,s.extraKnownMarketplaces)}return t}
1
+ import{join as t}from"path";import{getAdditionalDirectoriesForClaudeMd as n}from"../../bootstrap/state.js";import{parseSettingsFile as s}from"../settings/settings.js";const e=["settings.json","settings.local.json"],o=[".context",".claude"];function readAddDirSettings(n,e){for(const r of o){const{settings:o}=s(t(n,r,e));if(o)return o}return null}export function getAddDirEnabledPlugins(){const t={};for(const s of n())for(const n of e){const e=readAddDirSettings(s,n);e?.enabledPlugins&&Object.assign(t,e.enabledPlugins)}return t}export function getAddDirExtraMarketplaces(){const t={};for(const s of n())for(const n of e){const e=readAddDirSettings(s,n);e?.extraKnownMarketplaces&&Object.assign(t,e.extraKnownMarketplaces)}return t}
@@ -1 +1 @@
1
- import{readdir as t,rm as r,stat as o,unlink as a,writeFile as e}from"fs/promises";import{join as n}from"path";import{clearCommandsCache as i}from"../../commands.js";import{clearAllOutputStylesCache as s}from"../../constants/outputStyles.js";import{clearAgentDefinitionsCache as c}from"../../tools/AgentTool/loadAgentsDir.js";import{clearPromptCache as l}from"../../tools/SkillTool/prompt.js";import{resetSentSkillNames as m}from"../attachments.js";import{logForDebugging as p}from"../debug.js";import{getErrnoCode as u}from"../errors.js";import{logError as f}from"../log.js";import{loadInstalledPluginsFromDisk as d}from"./installedPluginsManager.js";import{clearPluginAgentCache as h}from"./loadPluginAgents.js";import{clearPluginCommandCache as g}from"./loadPluginCommands.js";import{clearPluginHookCache as y,pruneRemovedPluginHooks as w}from"./loadPluginHooks.js";import{clearPluginOutputStyleCache as P}from"./loadPluginOutputStyles.js";import{clearPluginCache as j,getPluginCachePath as O}from"./pluginLoader.js";import{clearPluginOptionsCache as $}from"./pluginOptionsStorage.js";import{isPluginZipCacheEnabled as v}from"./zipCache.js";export function clearAllPluginCaches(){j(),g(),h(),y(),w().catch(t=>f(t)),$(),P(),s()}export function clearAllCaches(){clearAllPluginCaches(),i(),c(),l(),m()}export async function markPluginVersionOrphaned(t){try{await e(getOrphanedAtPath(t),`${Date.now()}`,"utf-8")}catch(r){p(`Failed to write .orphaned_at: ${t}: ${r}`)}}export async function cleanupOrphanedPluginVersionsInBackground(){if(!v())try{const t=function(){try{const t=new Set,r=d();for(const o of Object.values(r.plugins))for(const r of o)t.add(r.installPath);return t}catch(t){return p(`Failed to load installed plugins: ${t}`),null}}();if(!t)return;const r=O(),o=Date.now();await Promise.all([...t].map(t=>async function(t){const r=getOrphanedAtPath(t);try{await a(r)}catch(r){if("ENOENT"===u(r))return;p(`Failed to remove .orphaned_at: ${t}: ${r}`)}}(t)));for(const a of await readSubdirs(r)){const e=n(r,a);for(const r of await readSubdirs(e)){const a=n(e,r);for(const r of await readSubdirs(a)){const e=n(a,r);t.has(e)||await processOrphanedPluginVersion(e,o)}await removeIfEmpty(a)}await removeIfEmpty(e)}}catch(t){p(`Plugin cache cleanup failed: ${t}`)}}function getOrphanedAtPath(t){return n(t,".orphaned_at")}async function processOrphanedPluginVersion(t,a){const e=getOrphanedAtPath(t);let n;try{n=(await o(e)).mtimeMs}catch(r){return"ENOENT"===u(r)?void await markPluginVersionOrphaned(t):void p(`Failed to stat orphaned marker: ${t}: ${r}`)}if(a-n>6048e5)try{await r(t,{recursive:!0,force:!0})}catch(r){p(`Failed to delete orphaned version: ${t}: ${r}`)}}async function removeIfEmpty(t){if(0===(await readSubdirs(t)).length)try{await r(t,{recursive:!0,force:!0})}catch(r){p(`Failed to remove empty dir: ${t}: ${r}`)}}async function readSubdirs(r){try{return(await t(r,{withFileTypes:!0})).filter(t=>t.isDirectory()).map(t=>t.name)}catch{return[]}}
1
+ import{readdir as a,rm as t,stat as r,unlink as e,writeFile as o}from"fs/promises";import{join as n}from"path";import{clearCommandsCache as i}from"../../commands.js";import{clearAllOutputStylesCache as s}from"../../constants/outputStyles.js";import{clearAgentDefinitionsCache as l}from"../../tools/AgentTool/loadAgentsDir.js";import{clearPromptCache as c}from"../../tools/SkillTool/prompt.js";import{resetSentSkillNames as m}from"../attachments.js";import{logForDebugging as u}from"../debug.js";import{getErrnoCode as p}from"../errors.js";import{logError as d}from"../log.js";import{loadInstalledPluginsFromDisk as f}from"./installedPluginsManager.js";import{clearPluginAgentCache as h}from"./loadPluginAgents.js";import{clearPluginCommandCache as g}from"./loadPluginCommands.js";import{clearPluginHookCache as P,pruneRemovedPluginHooks as y}from"./loadPluginHooks.js";import{clearPluginOutputStyleCache as w}from"./loadPluginOutputStyles.js";import{clearPluginCache as C,getPluginCachePath as j}from"./pluginLoader.js";import{clearPluginOptionsCache as O}from"./pluginOptionsStorage.js";import{isPluginZipCacheEnabled as S}from"./zipCache.js";export function clearAllPluginCaches(){C(),g(),h(),P(),y().catch(a=>d(a)),O(),w(),s()}export function clearAllCaches(){clearAllPluginCaches(),i(),l(),c(),m()}export async function markPluginVersionOrphaned(a){try{await o(getOrphanedAtPath(a),`${Date.now()}`,"utf-8")}catch(t){u(`Failed to write .orphaned_at: ${a}: ${t}`)}}export async function cleanupOrphanedPluginVersionsInBackground(){if(!S())try{const a=function(){try{const a=new Set,t=f();for(const r of Object.values(t.plugins))for(const t of r)a.add(t.installPath);return a}catch(a){return u(`Failed to load installed plugins: ${a}`),null}}();if(!a)return;const t=j(),r=Date.now();await Promise.all([...a].map(a=>async function(a){const t=getOrphanedAtPath(a);try{await e(t)}catch(t){if("ENOENT"===p(t))return;u(`Failed to remove .orphaned_at: ${a}: ${t}`)}}(a)));for(const e of await readSubdirs(t)){const o=n(t,e);for(const t of await readSubdirs(o)){const e=n(o,t);for(const t of await readSubdirs(e)){const o=n(e,t);a.has(o)||await processOrphanedPluginVersion(o,r)}await removeIfEmpty(e)}await removeIfEmpty(o)}}catch(a){u(`Plugin cache cleanup failed: ${a}`)}}function getOrphanedAtPath(a){return n(a,".orphaned_at")}async function processOrphanedPluginVersion(a,e){const o=getOrphanedAtPath(a);let n;try{n=(await r(o)).mtimeMs}catch(t){return"ENOENT"===p(t)?void await markPluginVersionOrphaned(a):void u(`Failed to stat orphaned marker: ${a}: ${t}`)}if(e-n>6048e5)try{await t(a,{recursive:!0,force:!0})}catch(t){u(`Failed to delete orphaned version: ${a}: ${t}`)}}async function removeIfEmpty(a){if(0===(await readSubdirs(a)).length)try{await t(a,{recursive:!0,force:!0})}catch(t){u(`Failed to remove empty dir: ${a}: ${t}`)}}async function readSubdirs(t){try{return(await a(t,{withFileTypes:!0})).filter(a=>a.isDirectory()).map(a=>a.name)}catch{return[]}}
@@ -1 +1 @@
1
- import{getSettingsForSource as e}from"../settings/settings.js";import{parsePluginIdentifier as n}from"./pluginIdentifier.js";export function qualifyDependency(e,t){if(n(e).marketplace)return e;const r=n(t).marketplace;return r&&"inline"!==r?`${e}@${r}`:e}export async function resolveDependencyClosure(e,t,r,o=new Set){const s=n(e).marketplace,a=[],c=new Set,i=[];const u=await async function walk(u,f){if(u!==e&&r.has(u))return null;const p=n(u).marketplace;if(!(p===s||p&&o.has(p)))return{ok:!1,reason:"cross-marketplace",dependency:u,requiredBy:f};if(i.includes(u))return{ok:!1,reason:"cycle",chain:[...i,u]};if(c.has(u))return null;c.add(u);const d=await t(u);if(!d)return{ok:!1,reason:"not-found",missing:u,requiredBy:f};i.push(u);for(const e of d.dependencies??[]){const n=qualifyDependency(e,u),t=await walk(n,u);if(t)return t}return i.pop(),a.push(u),null}(e,e);return u||{ok:!0,closure:a}}export function verifyAndDemote(e){const t=new Set(e.map(e=>e.source)),r=new Set(e.filter(e=>e.enabled).map(e=>e.source)),o=new Set(e.map(e=>n(e.source).name)),s=new Map;for(const e of r){const t=n(e).name;s.set(t,(s.get(t)??0)+1)}const a=[];let c=!0;for(;c;){c=!1;for(const i of e)if(r.has(i.source))for(const e of i.manifest.dependencies??[]){const u=qualifyDependency(e,i.source),f=!n(u).marketplace;if(!(f?(s.get(u)??0)>0:r.has(u))){r.delete(i.source);const e=s.get(i.name)??0;e<=1?s.delete(i.name):s.set(i.name,e-1),a.push({type:"dependency-unsatisfied",source:i.source,plugin:i.name,dependency:u,reason:(f?o.has(u):t.has(u))?"not-enabled":"not-found"}),c=!0;break}}}return{demoted:new Set(e.filter(e=>e.enabled&&!r.has(e.source)).map(e=>e.source)),errors:a}}export function findReverseDependents(e,t){const{name:r}=n(e);return t.filter(t=>t.enabled&&t.source!==e&&(t.manifest.dependencies??[]).some(o=>{const s=qualifyDependency(o,t.source);return n(s).marketplace?s===e:s===r})).map(e=>e.name)}export function getEnabledPluginIdsForScope(n){return new Set(Object.entries(e(n)?.enabledPlugins??{}).filter(([,e])=>!0===e||Array.isArray(e)).map(([e])=>e))}export function formatDependencyCountSuffix(e){if(0===e.length)return"";const n=e.length;return` (+ ${n} ${1===n?"dependency":"dependencies"})`}export function formatReverseDependentsSuffix(e){return e&&0!==e.length?` — warning: required by ${e.join(", ")}`:""}
1
+ import{getSettingsForSource as e}from"../settings/settings.js";import{parsePluginIdentifier as n}from"./pluginIdentifier.js";export function qualifyDependency(e,t){if(n(e).marketplace)return e;const r=n(t).marketplace;return r&&"inline"!==r?`${e}@${r}`:e}export async function resolveDependencyClosure(e,t,r,o=new Set){const s=n(e).marketplace,a=[],c=new Set,i=[],u=await async function walk(u,f){if(u!==e&&r.has(u))return null;const p=n(u).marketplace;if(!(p===s||p&&o.has(p)))return{ok:!1,reason:"cross-marketplace",dependency:u,requiredBy:f};if(i.includes(u))return{ok:!1,reason:"cycle",chain:[...i,u]};if(c.has(u))return null;c.add(u);const d=await t(u);if(!d)return{ok:!1,reason:"not-found",missing:u,requiredBy:f};i.push(u);for(const e of d.dependencies??[]){const n=qualifyDependency(e,u),t=await walk(n,u);if(t)return t}return i.pop(),a.push(u),null}(e,e);return u||{ok:!0,closure:a}}export function verifyAndDemote(e){const t=new Set(e.map(e=>e.source)),r=new Set(e.filter(e=>e.enabled).map(e=>e.source)),o=new Set(e.map(e=>n(e.source).name)),s=new Map;for(const e of r){const t=n(e).name;s.set(t,(s.get(t)??0)+1)}const a=[];let c=!0;for(;c;){c=!1;for(const i of e)if(r.has(i.source))for(const e of i.manifest.dependencies??[]){const u=qualifyDependency(e,i.source),f=!n(u).marketplace;if(!(f?(s.get(u)??0)>0:r.has(u))){r.delete(i.source);const e=s.get(i.name)??0;e<=1?s.delete(i.name):s.set(i.name,e-1),a.push({type:"dependency-unsatisfied",source:i.source,plugin:i.name,dependency:u,reason:(f?o.has(u):t.has(u))?"not-enabled":"not-found"}),c=!0;break}}}return{demoted:new Set(e.filter(e=>e.enabled&&!r.has(e.source)).map(e=>e.source)),errors:a}}export function findReverseDependents(e,t){const{name:r}=n(e);return t.filter(t=>t.enabled&&t.source!==e&&(t.manifest.dependencies??[]).some(o=>{const s=qualifyDependency(o,t.source);return n(s).marketplace?s===e:s===r})).map(e=>e.name)}export function getEnabledPluginIdsForScope(n){return new Set(Object.entries(e(n)?.enabledPlugins??{}).filter(([,e])=>!0===e||Array.isArray(e)).map(([e])=>e))}export function formatDependencyCountSuffix(e){if(0===e.length)return"";const n=e.length;return` (+ ${n} ${1===n?"dependency":"dependencies"})`}export function formatReverseDependentsSuffix(e){return e&&0!==e.length?` — warning: required by ${e.join(", ")}`:""}
@@ -1 +1 @@
1
- import{logEvent as t}from"../../services/analytics/index.js";import{OFFICIAL_MARKETPLACE_NAME as e}from"./officialMarketplace.js";const o=new Set(["github.com","raw.githubusercontent.com","objects.githubusercontent.com","gist.githubusercontent.com","gitlab.com","bitbucket.org","codeberg.org","dev.azure.com","ssh.dev.azure.com","storage.googleapis.com"]);function extractHost(t){let e;const n=/^[^@/]+@([^:/]+):/.exec(t);if(n)e=n[1];else try{e=new URL(t).hostname}catch{return"unknown"}const i=e.toLowerCase();return o.has(i)?i:"other"}function isOfficialRepo(t){return t.includes(`anthropics/${e}`)}export function logPluginFetch(e,o,n,i,s){t("tengu_plugin_remote_fetch",{source:e,host:o?extractHost(o):"unknown",is_official:!!o&&isOfficialRepo(o),outcome:n,duration_ms:Math.round(i),...s&&{error_kind:s}})}export function classifyFetchError(t){const e=String(t?.message??t);return/ENOTFOUND|ECONNREFUSED|EAI_AGAIN|Could not resolve host|Connection refused/i.test(e)?"dns_or_refused":/ETIMEDOUT|timed out|timeout/i.test(e)?"timeout":/ECONNRESET|socket hang up|Connection reset by peer|remote end hung up/i.test(e)?"conn_reset":/403|401|authentication|permission denied/i.test(e)?"auth":/404|not found|repository not found/i.test(e)?"not_found":/certificate|SSL|TLS|unable to get local issuer/i.test(e)?"tls":/Invalid response format|Invalid marketplace schema/i.test(e)?"invalid_schema":"other"}
1
+ import{logEvent as t}from"../../services/analytics/index.js";import{OFFICIAL_MARKETPLACE_NAME as e}from"./officialMarketplace.js";const o=new Set(["github.com","raw.githubusercontent.com","objects.githubusercontent.com","gist.githubusercontent.com","gitlab.com","bitbucket.org","codeberg.org","dev.azure.com","ssh.dev.azure.com","storage.googleapis.com"]);function extractHost(t){let e;const n=/^[^@/]+@([^:/]+):/.exec(t);if(n)e=n[1];else try{e=new URL(t).hostname}catch{return"unknown"}const s=e.toLowerCase();return o.has(s)?s:"other"}function isOfficialRepo(t){return t.includes(`anthropics/${e}`)}export function logPluginFetch(e,o,n,s,i){t("tengu_plugin_remote_fetch",{source:e,host:o?extractHost(o):"unknown",is_official:!!o&&isOfficialRepo(o),outcome:n,duration_ms:Math.round(s),...i&&{error_kind:i}})}export function classifyFetchError(t){const e=String(t?.message??t);return/ENOTFOUND|ECONNREFUSED|EAI_AGAIN|Could not resolve host|Connection refused/i.test(e)?"dns_or_refused":/ETIMEDOUT|timed out|timeout/i.test(e)?"timeout":/ECONNRESET|socket hang up|Connection reset by peer|remote end hung up/i.test(e)?"conn_reset":/403|401|authentication|permission denied/i.test(e)?"auth":/404|not found|repository not found/i.test(e)?"not_found":/certificate|SSL|TLS|unable to get local issuer/i.test(e)?"tls":/Invalid response format|Invalid marketplace schema/i.test(e)?"invalid_schema":"other"}
@@ -1 +1 @@
1
- import e from"lodash-es/memoize.js";import{which as a}from"../which.js";export const checkGitAvailable=e(async()=>async function(e){try{return!!await a(e)}catch{return!1}}("git"));export function markGitUnavailable(){checkGitAvailable.cache?.set?.(void 0,Promise.resolve(!1))}export function clearGitAvailabilityCache(){checkGitAvailable.cache?.clear?.()}
1
+ import a from"lodash-es/memoize.js";import{which as e}from"../which.js";export const checkGitAvailable=a(async()=>async function(){try{return!!await e("git")}catch{return!1}}());export function markGitUnavailable(){checkGitAvailable.cache?.set?.(void 0,Promise.resolve(!1))}export function clearGitAvailabilityCache(){checkGitAvailable.cache?.clear?.()}
@@ -1 +1 @@
1
- import{getFeatureValue_CACHED_MAY_BE_STALE as e}from"../../services/analytics/growthbook.js";import{logEvent as n}from"../../services/analytics/index.js";import{hasShownHintThisSession as i,setPendingHint as t}from"../claudeCodeHints.js";import{getGlobalConfig as o,saveGlobalConfig as r}from"../config.js";import{logForDebugging as a}from"../debug.js";import{isPluginInstalled as s}from"./installedPluginsManager.js";import{getPluginById as c}from"./marketplaceManager.js";import{isOfficialMarketplaceName as l,parsePluginIdentifier as u}from"./pluginIdentifier.js";import{isPluginBlockedByPolicy as d}from"./pluginPolicy.js";export function maybeRecordPluginHint(n){if(!e("tengu_lapis_finch",!1))return;if(i())return;const r=o().claudeCodeHints;if(r?.disabled)return;const a=r?.plugin??[];if(a.length>=100)return;const c=n.value,{name:p,marketplace:g}=u(c);p&&g&&l(g)&&(a.includes(c)||s(c)||d(c)||m.has(c)||(m.add(c),t(n)))}const m=new Set;export function _resetHintRecommendationForTesting(){m.clear()}export async function resolvePluginHint(e){const i=e.value,{name:t,marketplace:o}=u(i),r=await c(i);return n("tengu_plugin_hint_detected",{_PROTO_plugin_name:t??"",_PROTO_marketplace_name:o??"",result:r?"passed":"not_in_cache"}),r?{pluginId:i,pluginName:r.entry.name,marketplaceName:o??"",pluginDescription:r.entry.description,sourceCommand:e.sourceCommand}:(a(`[hintRecommendation] ${i} not found in marketplace cache`),null)}export function markHintPluginShown(e){r(n=>{const i=n.claudeCodeHints?.plugin??[];return i.includes(e)?n:{...n,claudeCodeHints:{...n.claudeCodeHints,plugin:[...i,e]}}})}export function disableHintRecommendations(){r(e=>e.claudeCodeHints?.disabled?e:{...e,claudeCodeHints:{...e.claudeCodeHints,disabled:!0}})}
1
+ import{getFeatureValue_CACHED_MAY_BE_STALE as e}from"../../services/analytics/growthbook.js";import{logEvent as n}from"../../services/analytics/index.js";import{hasShownHintThisSession as i,setPendingHint as t}from"../claudeCodeHints.js";import{getGlobalConfig as a,saveGlobalConfig as o}from"../config.js";import{logForDebugging as s}from"../debug.js";import{isPluginInstalled as l}from"./installedPluginsManager.js";import{getPluginById as r}from"./marketplaceManager.js";import{isOfficialMarketplaceName as c,parsePluginIdentifier as u}from"./pluginIdentifier.js";import{isPluginBlockedByPolicy as d}from"./pluginPolicy.js";export function maybeRecordPluginHint(n){if(!e("tengu_lapis_finch",!1))return;if(i())return;const o=a().claudeCodeHints;if(o?.disabled)return;const s=o?.plugin??[];if(s.length>=100)return;const r=n.value,{name:g,marketplace:p}=u(r);g&&p&&c(p)&&(s.includes(r)||l(r)||d(r)||m.has(r)||(m.add(r),t(n)))}const m=new Set;export function _resetHintRecommendationForTesting(){m.clear()}export async function resolvePluginHint(e){const i=e.value,{name:t,marketplace:a}=u(i),o=await r(i);return n("tengu_plugin_hint_detected",{_PROTO_plugin_name:t??"",_PROTO_marketplace_name:a??"",result:o?"passed":"not_in_cache"}),o?{pluginId:i,pluginName:o.entry.name,marketplaceName:a??"",pluginDescription:o.entry.description,sourceCommand:e.sourceCommand}:(s(`[hintRecommendation] ${i} not found in marketplace cache`),null)}export function markHintPluginShown(e){o(n=>{const i=n.claudeCodeHints?.plugin??[];return i.includes(e)?n:{...n,claudeCodeHints:{...n.claudeCodeHints,plugin:[...i,e]}}})}export function disableHintRecommendations(){o(e=>e.claudeCodeHints?.disabled?e:{...e,claudeCodeHints:{...e.claudeCodeHints,disabled:!0}})}