@xortex/xcode 3.0.0

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 (934) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -0
  3. package/bin/xcode +127 -0
  4. package/bin/xcode-test +84 -0
  5. package/bin/xcode.cmd +31 -0
  6. package/constants/apiLimits.ts +94 -0
  7. package/constants/betas.ts +52 -0
  8. package/constants/common.ts +33 -0
  9. package/constants/cyberRiskInstruction.ts +24 -0
  10. package/constants/errorIds.ts +15 -0
  11. package/constants/figures.ts +45 -0
  12. package/constants/files.ts +156 -0
  13. package/constants/github-app.ts +144 -0
  14. package/constants/keys.ts +11 -0
  15. package/constants/messages.ts +1 -0
  16. package/constants/oauth.ts +234 -0
  17. package/constants/outputStyles.ts +216 -0
  18. package/constants/product.ts +76 -0
  19. package/constants/prompts.ts +939 -0
  20. package/constants/spinnerVerbs.ts +204 -0
  21. package/constants/system.ts +95 -0
  22. package/constants/systemPromptSections.ts +68 -0
  23. package/constants/toolLimits.ts +56 -0
  24. package/constants/tools.ts +112 -0
  25. package/constants/turnCompletionVerbs.ts +12 -0
  26. package/constants/xml.ts +86 -0
  27. package/entrypoints/agentSdkTypes.ts +443 -0
  28. package/entrypoints/cli.tsx +307 -0
  29. package/entrypoints/init.ts +340 -0
  30. package/entrypoints/mcp.ts +196 -0
  31. package/entrypoints/sandboxTypes.ts +156 -0
  32. package/entrypoints/sdk/controlSchemas.ts +663 -0
  33. package/entrypoints/sdk/coreSchemas.ts +1889 -0
  34. package/entrypoints/sdk/coreTypes.generated.ts +2 -0
  35. package/entrypoints/sdk/coreTypes.ts +62 -0
  36. package/entrypoints/sdk/runtimeTypes.ts +140 -0
  37. package/entrypoints/sdk/sdkUtilityTypes.ts +3 -0
  38. package/entrypoints/sdk/toolTypes.ts +90 -0
  39. package/main.tsx +4686 -0
  40. package/package.json +120 -0
  41. package/services/AgentSummary/agentSummary.ts +179 -0
  42. package/services/MagicDocs/magicDocs.ts +254 -0
  43. package/services/MagicDocs/prompts.ts +127 -0
  44. package/services/PromptSuggestion/promptSuggestion.ts +523 -0
  45. package/services/PromptSuggestion/speculation.ts +991 -0
  46. package/services/SessionMemory/prompts.ts +324 -0
  47. package/services/SessionMemory/sessionMemory.ts +495 -0
  48. package/services/SessionMemory/sessionMemoryUtils.ts +207 -0
  49. package/services/analytics/config.ts +38 -0
  50. package/services/analytics/datadog.ts +307 -0
  51. package/services/analytics/firstPartyEventLogger.ts +449 -0
  52. package/services/analytics/firstPartyEventLoggingExporter.ts +806 -0
  53. package/services/analytics/growthbook.ts +1155 -0
  54. package/services/analytics/index.ts +173 -0
  55. package/services/analytics/metadata.ts +973 -0
  56. package/services/analytics/sink.ts +114 -0
  57. package/services/analytics/sinkKillswitch.ts +25 -0
  58. package/services/api/adminRequests.ts +119 -0
  59. package/services/api/bootstrap.ts +141 -0
  60. package/services/api/claude.ts +3422 -0
  61. package/services/api/client.ts +406 -0
  62. package/services/api/dumpPrompts.ts +226 -0
  63. package/services/api/emptyUsage.ts +22 -0
  64. package/services/api/errorUtils.ts +260 -0
  65. package/services/api/errors.ts +1207 -0
  66. package/services/api/filesApi.ts +748 -0
  67. package/services/api/firstTokenDate.ts +60 -0
  68. package/services/api/gemini.ts +359 -0
  69. package/services/api/geminiAdapter.ts +123 -0
  70. package/services/api/geminiClient.ts +291 -0
  71. package/services/api/grove.ts +357 -0
  72. package/services/api/logging.ts +788 -0
  73. package/services/api/metricsOptOut.ts +159 -0
  74. package/services/api/openRouterClient.ts +453 -0
  75. package/services/api/overageCreditGrant.ts +137 -0
  76. package/services/api/promptCacheBreakDetection.ts +727 -0
  77. package/services/api/referral.ts +281 -0
  78. package/services/api/sessionIngress.ts +514 -0
  79. package/services/api/ultrareviewQuota.ts +38 -0
  80. package/services/api/usage.ts +63 -0
  81. package/services/api/withRetry.ts +822 -0
  82. package/services/autoDream/autoDream.ts +324 -0
  83. package/services/autoDream/config.ts +21 -0
  84. package/services/autoDream/consolidationLock.ts +140 -0
  85. package/services/autoDream/consolidationPrompt.ts +65 -0
  86. package/services/awaySummary.ts +74 -0
  87. package/services/claudeAiLimits.ts +515 -0
  88. package/services/claudeAiLimitsHook.ts +23 -0
  89. package/services/compact/apiMicrocompact.ts +153 -0
  90. package/services/compact/autoCompact.ts +351 -0
  91. package/services/compact/compact.ts +1705 -0
  92. package/services/compact/compactWarningHook.ts +16 -0
  93. package/services/compact/compactWarningState.ts +18 -0
  94. package/services/compact/grouping.ts +63 -0
  95. package/services/compact/microCompact.ts +530 -0
  96. package/services/compact/postCompactCleanup.ts +77 -0
  97. package/services/compact/prompt.ts +374 -0
  98. package/services/compact/sessionMemoryCompact.ts +630 -0
  99. package/services/compact/timeBasedMCConfig.ts +43 -0
  100. package/services/diagnosticTracking.ts +397 -0
  101. package/services/extractMemories/extractMemories.ts +517 -0
  102. package/services/extractMemories/prompts.ts +154 -0
  103. package/services/internalLogging.ts +90 -0
  104. package/services/lsp/LSPClient.ts +447 -0
  105. package/services/lsp/LSPDiagnosticRegistry.ts +386 -0
  106. package/services/lsp/LSPServerInstance.ts +511 -0
  107. package/services/lsp/LSPServerManager.ts +420 -0
  108. package/services/lsp/config.ts +79 -0
  109. package/services/lsp/manager.ts +289 -0
  110. package/services/lsp/passiveFeedback.ts +328 -0
  111. package/services/mcp/InProcessTransport.ts +63 -0
  112. package/services/mcp/MCPConnectionManager.tsx +73 -0
  113. package/services/mcp/SdkControlTransport.ts +136 -0
  114. package/services/mcp/auth.ts +2465 -0
  115. package/services/mcp/channelAllowlist.ts +76 -0
  116. package/services/mcp/channelNotification.ts +316 -0
  117. package/services/mcp/channelPermissions.ts +240 -0
  118. package/services/mcp/claudeai.ts +164 -0
  119. package/services/mcp/client.ts +3348 -0
  120. package/services/mcp/config.ts +1578 -0
  121. package/services/mcp/elicitationHandler.ts +313 -0
  122. package/services/mcp/envExpansion.ts +38 -0
  123. package/services/mcp/headersHelper.ts +138 -0
  124. package/services/mcp/mcpStringUtils.ts +106 -0
  125. package/services/mcp/normalization.ts +23 -0
  126. package/services/mcp/oauthPort.ts +78 -0
  127. package/services/mcp/officialRegistry.ts +72 -0
  128. package/services/mcp/types.ts +258 -0
  129. package/services/mcp/useManageMCPConnections.ts +1141 -0
  130. package/services/mcp/utils.ts +575 -0
  131. package/services/mcp/vscodeSdkMcp.ts +112 -0
  132. package/services/mcp/xaa.ts +511 -0
  133. package/services/mcp/xaaIdpLogin.ts +487 -0
  134. package/services/mcpServerApproval.tsx +41 -0
  135. package/services/mockRateLimits.ts +882 -0
  136. package/services/notifier.ts +156 -0
  137. package/services/oauth/auth-code-listener.ts +211 -0
  138. package/services/oauth/client.ts +566 -0
  139. package/services/oauth/crypto.ts +23 -0
  140. package/services/oauth/getOauthProfile.ts +53 -0
  141. package/services/oauth/index.ts +198 -0
  142. package/services/plugins/PluginInstallationManager.ts +184 -0
  143. package/services/plugins/pluginCliCommands.ts +344 -0
  144. package/services/plugins/pluginOperations.ts +1088 -0
  145. package/services/policyLimits/index.ts +663 -0
  146. package/services/policyLimits/types.ts +27 -0
  147. package/services/preventSleep.ts +165 -0
  148. package/services/rateLimitMessages.ts +344 -0
  149. package/services/rateLimitMocking.ts +144 -0
  150. package/services/remoteManagedSettings/index.ts +638 -0
  151. package/services/remoteManagedSettings/securityCheck.tsx +74 -0
  152. package/services/remoteManagedSettings/syncCache.ts +112 -0
  153. package/services/remoteManagedSettings/syncCacheState.ts +96 -0
  154. package/services/remoteManagedSettings/types.ts +31 -0
  155. package/services/settingsSync/index.ts +581 -0
  156. package/services/settingsSync/types.ts +67 -0
  157. package/services/teamMemorySync/index.ts +1256 -0
  158. package/services/teamMemorySync/secretScanner.ts +324 -0
  159. package/services/teamMemorySync/teamMemSecretGuard.ts +44 -0
  160. package/services/teamMemorySync/types.ts +156 -0
  161. package/services/teamMemorySync/watcher.ts +387 -0
  162. package/services/tips/tipHistory.ts +17 -0
  163. package/services/tips/tipRegistry.ts +686 -0
  164. package/services/tips/tipScheduler.ts +58 -0
  165. package/services/tokenEstimation.ts +495 -0
  166. package/services/toolUseSummary/toolUseSummaryGenerator.ts +112 -0
  167. package/services/tools/StreamingToolExecutor.ts +530 -0
  168. package/services/tools/toolExecution.ts +1745 -0
  169. package/services/tools/toolHooks.ts +650 -0
  170. package/services/tools/toolOrchestration.ts +188 -0
  171. package/services/vcr.ts +406 -0
  172. package/services/voice.ts +525 -0
  173. package/services/voiceKeyterms.ts +106 -0
  174. package/services/voiceStreamSTT.ts +544 -0
  175. package/tools/AgentTool/AgentTool.tsx +1398 -0
  176. package/tools/AgentTool/UI.tsx +872 -0
  177. package/tools/AgentTool/agentColorManager.ts +66 -0
  178. package/tools/AgentTool/agentDisplay.ts +104 -0
  179. package/tools/AgentTool/agentMemory.ts +177 -0
  180. package/tools/AgentTool/agentMemorySnapshot.ts +197 -0
  181. package/tools/AgentTool/agentToolUtils.ts +686 -0
  182. package/tools/AgentTool/built-in/claudeCodeGuideAgent.ts +205 -0
  183. package/tools/AgentTool/built-in/exploreAgent.ts +83 -0
  184. package/tools/AgentTool/built-in/generalPurposeAgent.ts +34 -0
  185. package/tools/AgentTool/built-in/planAgent.ts +92 -0
  186. package/tools/AgentTool/built-in/statuslineSetup.ts +144 -0
  187. package/tools/AgentTool/built-in/verificationAgent.ts +152 -0
  188. package/tools/AgentTool/builtInAgents.ts +72 -0
  189. package/tools/AgentTool/constants.ts +12 -0
  190. package/tools/AgentTool/forkSubagent.ts +210 -0
  191. package/tools/AgentTool/loadAgentsDir.ts +755 -0
  192. package/tools/AgentTool/prompt.ts +287 -0
  193. package/tools/AgentTool/resumeAgent.ts +265 -0
  194. package/tools/AgentTool/runAgent.ts +973 -0
  195. package/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +266 -0
  196. package/tools/AskUserQuestionTool/prompt.ts +44 -0
  197. package/tools/BashTool/BashTool.tsx +1144 -0
  198. package/tools/BashTool/BashToolResultMessage.tsx +191 -0
  199. package/tools/BashTool/UI.tsx +185 -0
  200. package/tools/BashTool/bashCommandHelpers.ts +265 -0
  201. package/tools/BashTool/bashPermissions.ts +2621 -0
  202. package/tools/BashTool/bashSecurity.ts +2592 -0
  203. package/tools/BashTool/commandSemantics.ts +140 -0
  204. package/tools/BashTool/commentLabel.ts +13 -0
  205. package/tools/BashTool/destructiveCommandWarning.ts +102 -0
  206. package/tools/BashTool/modeValidation.ts +115 -0
  207. package/tools/BashTool/pathValidation.ts +1303 -0
  208. package/tools/BashTool/prompt.ts +369 -0
  209. package/tools/BashTool/readOnlyValidation.ts +1990 -0
  210. package/tools/BashTool/sedEditParser.ts +322 -0
  211. package/tools/BashTool/sedValidation.ts +684 -0
  212. package/tools/BashTool/shouldUseSandbox.ts +153 -0
  213. package/tools/BashTool/toolName.ts +2 -0
  214. package/tools/BashTool/utils.ts +223 -0
  215. package/tools/BriefTool/BriefTool.ts +204 -0
  216. package/tools/BriefTool/UI.tsx +101 -0
  217. package/tools/BriefTool/attachments.ts +110 -0
  218. package/tools/BriefTool/prompt.ts +22 -0
  219. package/tools/BriefTool/upload.ts +174 -0
  220. package/tools/ConfigTool/ConfigTool.ts +467 -0
  221. package/tools/ConfigTool/UI.tsx +38 -0
  222. package/tools/ConfigTool/constants.ts +1 -0
  223. package/tools/ConfigTool/prompt.ts +93 -0
  224. package/tools/ConfigTool/supportedSettings.ts +211 -0
  225. package/tools/EnterPlanModeTool/EnterPlanModeTool.ts +126 -0
  226. package/tools/EnterPlanModeTool/UI.tsx +33 -0
  227. package/tools/EnterPlanModeTool/constants.ts +1 -0
  228. package/tools/EnterPlanModeTool/prompt.ts +170 -0
  229. package/tools/EnterWorktreeTool/EnterWorktreeTool.ts +127 -0
  230. package/tools/EnterWorktreeTool/UI.tsx +20 -0
  231. package/tools/EnterWorktreeTool/constants.ts +1 -0
  232. package/tools/EnterWorktreeTool/prompt.ts +30 -0
  233. package/tools/ExitPlanModeTool/ExitPlanModeV2Tool.ts +493 -0
  234. package/tools/ExitPlanModeTool/UI.tsx +82 -0
  235. package/tools/ExitPlanModeTool/constants.ts +2 -0
  236. package/tools/ExitPlanModeTool/prompt.ts +29 -0
  237. package/tools/ExitWorktreeTool/ExitWorktreeTool.ts +329 -0
  238. package/tools/ExitWorktreeTool/UI.tsx +25 -0
  239. package/tools/ExitWorktreeTool/constants.ts +1 -0
  240. package/tools/ExitWorktreeTool/prompt.ts +32 -0
  241. package/tools/FileEditTool/FileEditTool.ts +625 -0
  242. package/tools/FileEditTool/UI.tsx +289 -0
  243. package/tools/FileEditTool/constants.ts +11 -0
  244. package/tools/FileEditTool/prompt.ts +28 -0
  245. package/tools/FileEditTool/types.ts +85 -0
  246. package/tools/FileEditTool/utils.ts +775 -0
  247. package/tools/FileReadTool/FileReadTool.ts +1183 -0
  248. package/tools/FileReadTool/UI.tsx +185 -0
  249. package/tools/FileReadTool/imageProcessor.ts +94 -0
  250. package/tools/FileReadTool/limits.ts +92 -0
  251. package/tools/FileReadTool/prompt.ts +49 -0
  252. package/tools/FileWriteTool/FileWriteTool.ts +434 -0
  253. package/tools/FileWriteTool/UI.tsx +405 -0
  254. package/tools/FileWriteTool/prompt.ts +18 -0
  255. package/tools/GlobTool/GlobTool.ts +198 -0
  256. package/tools/GlobTool/UI.tsx +63 -0
  257. package/tools/GlobTool/prompt.ts +7 -0
  258. package/tools/GrepTool/GrepTool.ts +577 -0
  259. package/tools/GrepTool/UI.tsx +201 -0
  260. package/tools/GrepTool/prompt.ts +18 -0
  261. package/tools/LSPTool/LSPTool.ts +860 -0
  262. package/tools/LSPTool/UI.tsx +228 -0
  263. package/tools/LSPTool/formatters.ts +592 -0
  264. package/tools/LSPTool/prompt.ts +21 -0
  265. package/tools/LSPTool/schemas.ts +215 -0
  266. package/tools/LSPTool/symbolContext.ts +90 -0
  267. package/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +123 -0
  268. package/tools/ListMcpResourcesTool/UI.tsx +29 -0
  269. package/tools/ListMcpResourcesTool/prompt.ts +20 -0
  270. package/tools/MCPTool/MCPTool.ts +77 -0
  271. package/tools/MCPTool/UI.tsx +403 -0
  272. package/tools/MCPTool/classifyForCollapse.ts +604 -0
  273. package/tools/MCPTool/prompt.ts +3 -0
  274. package/tools/McpAuthTool/McpAuthTool.ts +215 -0
  275. package/tools/NotebookEditTool/NotebookEditTool.ts +490 -0
  276. package/tools/NotebookEditTool/UI.tsx +93 -0
  277. package/tools/NotebookEditTool/constants.ts +2 -0
  278. package/tools/NotebookEditTool/prompt.ts +3 -0
  279. package/tools/PowerShellTool/PowerShellTool.tsx +1001 -0
  280. package/tools/PowerShellTool/UI.tsx +131 -0
  281. package/tools/PowerShellTool/clmTypes.ts +211 -0
  282. package/tools/PowerShellTool/commandSemantics.ts +142 -0
  283. package/tools/PowerShellTool/commonParameters.ts +30 -0
  284. package/tools/PowerShellTool/destructiveCommandWarning.ts +109 -0
  285. package/tools/PowerShellTool/gitSafety.ts +176 -0
  286. package/tools/PowerShellTool/modeValidation.ts +404 -0
  287. package/tools/PowerShellTool/pathValidation.ts +2049 -0
  288. package/tools/PowerShellTool/powershellPermissions.ts +1648 -0
  289. package/tools/PowerShellTool/powershellSecurity.ts +1090 -0
  290. package/tools/PowerShellTool/prompt.ts +145 -0
  291. package/tools/PowerShellTool/readOnlyValidation.ts +1823 -0
  292. package/tools/PowerShellTool/toolName.ts +2 -0
  293. package/tools/REPLTool/constants.ts +46 -0
  294. package/tools/REPLTool/primitiveTools.ts +39 -0
  295. package/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +158 -0
  296. package/tools/ReadMcpResourceTool/UI.tsx +37 -0
  297. package/tools/ReadMcpResourceTool/prompt.ts +16 -0
  298. package/tools/RemoteTriggerTool/RemoteTriggerTool.ts +161 -0
  299. package/tools/RemoteTriggerTool/UI.tsx +17 -0
  300. package/tools/RemoteTriggerTool/prompt.ts +15 -0
  301. package/tools/ScheduleCronTool/CronCreateTool.ts +157 -0
  302. package/tools/ScheduleCronTool/CronDeleteTool.ts +95 -0
  303. package/tools/ScheduleCronTool/CronListTool.ts +97 -0
  304. package/tools/ScheduleCronTool/UI.tsx +60 -0
  305. package/tools/ScheduleCronTool/prompt.ts +135 -0
  306. package/tools/SendMessageTool/SendMessageTool.ts +917 -0
  307. package/tools/SendMessageTool/UI.tsx +31 -0
  308. package/tools/SendMessageTool/constants.ts +1 -0
  309. package/tools/SendMessageTool/prompt.ts +49 -0
  310. package/tools/SkillTool/SkillTool.ts +1108 -0
  311. package/tools/SkillTool/UI.tsx +128 -0
  312. package/tools/SkillTool/constants.ts +1 -0
  313. package/tools/SkillTool/prompt.ts +241 -0
  314. package/tools/SleepTool/prompt.ts +17 -0
  315. package/tools/SyntheticOutputTool/SyntheticOutputTool.ts +163 -0
  316. package/tools/TaskCreateTool/TaskCreateTool.ts +138 -0
  317. package/tools/TaskCreateTool/constants.ts +1 -0
  318. package/tools/TaskCreateTool/prompt.ts +56 -0
  319. package/tools/TaskGetTool/TaskGetTool.ts +128 -0
  320. package/tools/TaskGetTool/constants.ts +1 -0
  321. package/tools/TaskGetTool/prompt.ts +24 -0
  322. package/tools/TaskListTool/TaskListTool.ts +116 -0
  323. package/tools/TaskListTool/constants.ts +1 -0
  324. package/tools/TaskListTool/prompt.ts +49 -0
  325. package/tools/TaskOutputTool/TaskOutputTool.tsx +584 -0
  326. package/tools/TaskOutputTool/constants.ts +1 -0
  327. package/tools/TaskStopTool/TaskStopTool.ts +131 -0
  328. package/tools/TaskStopTool/UI.tsx +41 -0
  329. package/tools/TaskStopTool/prompt.ts +8 -0
  330. package/tools/TaskUpdateTool/TaskUpdateTool.ts +406 -0
  331. package/tools/TaskUpdateTool/constants.ts +1 -0
  332. package/tools/TaskUpdateTool/prompt.ts +77 -0
  333. package/tools/TeamCreateTool/TeamCreateTool.ts +240 -0
  334. package/tools/TeamCreateTool/UI.tsx +6 -0
  335. package/tools/TeamCreateTool/constants.ts +1 -0
  336. package/tools/TeamCreateTool/prompt.ts +113 -0
  337. package/tools/TeamDeleteTool/TeamDeleteTool.ts +139 -0
  338. package/tools/TeamDeleteTool/UI.tsx +20 -0
  339. package/tools/TeamDeleteTool/constants.ts +1 -0
  340. package/tools/TeamDeleteTool/prompt.ts +16 -0
  341. package/tools/TodoWriteTool/TodoWriteTool.ts +115 -0
  342. package/tools/TodoWriteTool/constants.ts +1 -0
  343. package/tools/TodoWriteTool/prompt.ts +184 -0
  344. package/tools/ToolSearchTool/ToolSearchTool.ts +471 -0
  345. package/tools/ToolSearchTool/constants.ts +1 -0
  346. package/tools/ToolSearchTool/prompt.ts +121 -0
  347. package/tools/TungstenTool/TungstenTool.ts +4 -0
  348. package/tools/WebFetchTool/UI.tsx +72 -0
  349. package/tools/WebFetchTool/WebFetchTool.ts +318 -0
  350. package/tools/WebFetchTool/preapproved.ts +166 -0
  351. package/tools/WebFetchTool/prompt.ts +46 -0
  352. package/tools/WebFetchTool/utils.ts +530 -0
  353. package/tools/WebSearchTool/UI.tsx +101 -0
  354. package/tools/WebSearchTool/WebSearchTool.ts +435 -0
  355. package/tools/WebSearchTool/prompt.ts +34 -0
  356. package/tools/WorkflowTool/constants.ts +2 -0
  357. package/tools/XMemIngestTool/XMemIngestTool.ts +140 -0
  358. package/tools/XMemIngestTool/prompt.ts +13 -0
  359. package/tools/XMemRetrieveTool/XMemRetrieveTool.ts +177 -0
  360. package/tools/XMemRetrieveTool/prompt.ts +16 -0
  361. package/tools/XMemSearchTool/XMemSearchTool.ts +172 -0
  362. package/tools/XMemSearchTool/prompt.ts +11 -0
  363. package/tools/shared/gitOperationTracking.ts +277 -0
  364. package/tools/shared/spawnMultiAgent.ts +1093 -0
  365. package/tools/testing/TestingPermissionTool.tsx +74 -0
  366. package/tools/utils.ts +40 -0
  367. package/utils/CircularBuffer.ts +84 -0
  368. package/utils/Cursor.ts +1530 -0
  369. package/utils/QueryGuard.ts +121 -0
  370. package/utils/Shell.ts +474 -0
  371. package/utils/ShellCommand.ts +465 -0
  372. package/utils/abortController.ts +99 -0
  373. package/utils/activityManager.ts +164 -0
  374. package/utils/advisor.ts +145 -0
  375. package/utils/agentContext.ts +178 -0
  376. package/utils/agentId.ts +99 -0
  377. package/utils/agentSwarmsEnabled.ts +44 -0
  378. package/utils/agenticSessionSearch.ts +307 -0
  379. package/utils/analyzeContext.ts +1382 -0
  380. package/utils/ansiToPng.ts +334 -0
  381. package/utils/ansiToSvg.ts +272 -0
  382. package/utils/api.ts +718 -0
  383. package/utils/apiPreconnect.ts +71 -0
  384. package/utils/appleTerminalBackup.ts +124 -0
  385. package/utils/argumentSubstitution.ts +145 -0
  386. package/utils/array.ts +13 -0
  387. package/utils/asciicast.ts +239 -0
  388. package/utils/attachments.ts +4091 -0
  389. package/utils/attribution.ts +393 -0
  390. package/utils/auth.ts +2002 -0
  391. package/utils/authFileDescriptor.ts +196 -0
  392. package/utils/authPortable.ts +19 -0
  393. package/utils/autoModeDenials.ts +26 -0
  394. package/utils/autoRunIssue.tsx +122 -0
  395. package/utils/autoUpdater.ts +561 -0
  396. package/utils/aws.ts +74 -0
  397. package/utils/awsAuthStatusManager.ts +81 -0
  398. package/utils/axios.ts +8 -0
  399. package/utils/background/remote/preconditions.ts +235 -0
  400. package/utils/background/remote/remoteSession.ts +98 -0
  401. package/utils/backgroundHousekeeping.ts +94 -0
  402. package/utils/bash/ParsedCommand.ts +318 -0
  403. package/utils/bash/ShellSnapshot.ts +582 -0
  404. package/utils/bash/ast.ts +2679 -0
  405. package/utils/bash/bashParser.ts +4436 -0
  406. package/utils/bash/bashPipeCommand.ts +294 -0
  407. package/utils/bash/commands.ts +1339 -0
  408. package/utils/bash/heredoc.ts +733 -0
  409. package/utils/bash/parser.ts +230 -0
  410. package/utils/bash/prefix.ts +204 -0
  411. package/utils/bash/registry.ts +53 -0
  412. package/utils/bash/shellCompletion.ts +259 -0
  413. package/utils/bash/shellPrefix.ts +28 -0
  414. package/utils/bash/shellQuote.ts +304 -0
  415. package/utils/bash/shellQuoting.ts +128 -0
  416. package/utils/bash/specs/alias.ts +14 -0
  417. package/utils/bash/specs/index.ts +18 -0
  418. package/utils/bash/specs/nohup.ts +13 -0
  419. package/utils/bash/specs/pyright.ts +91 -0
  420. package/utils/bash/specs/sleep.ts +13 -0
  421. package/utils/bash/specs/srun.ts +31 -0
  422. package/utils/bash/specs/time.ts +13 -0
  423. package/utils/bash/specs/timeout.ts +20 -0
  424. package/utils/bash/treeSitterAnalysis.ts +506 -0
  425. package/utils/betas.ts +434 -0
  426. package/utils/billing.ts +78 -0
  427. package/utils/binaryCheck.ts +53 -0
  428. package/utils/browser.ts +68 -0
  429. package/utils/bufferedWriter.ts +100 -0
  430. package/utils/bundledMode.ts +22 -0
  431. package/utils/caCerts.ts +115 -0
  432. package/utils/caCertsConfig.ts +88 -0
  433. package/utils/cachePaths.ts +38 -0
  434. package/utils/classifierApprovals.ts +88 -0
  435. package/utils/classifierApprovalsHook.ts +17 -0
  436. package/utils/claudeCodeHints.ts +193 -0
  437. package/utils/claudeDesktop.ts +152 -0
  438. package/utils/claudeInChrome/chromeNativeHost.ts +527 -0
  439. package/utils/claudeInChrome/common.ts +540 -0
  440. package/utils/claudeInChrome/mcpServer.ts +292 -0
  441. package/utils/claudeInChrome/prompt.ts +83 -0
  442. package/utils/claudeInChrome/setup.ts +400 -0
  443. package/utils/claudeInChrome/setupPortable.ts +233 -0
  444. package/utils/claudeInChrome/toolRendering.tsx +262 -0
  445. package/utils/claudemd.ts +1479 -0
  446. package/utils/cleanup.ts +602 -0
  447. package/utils/cleanupRegistry.ts +25 -0
  448. package/utils/cliArgs.ts +60 -0
  449. package/utils/cliHighlight.ts +54 -0
  450. package/utils/codeIndexing.ts +206 -0
  451. package/utils/collapseBackgroundBashNotifications.ts +84 -0
  452. package/utils/collapseHookSummaries.ts +59 -0
  453. package/utils/collapseReadSearch.ts +1109 -0
  454. package/utils/collapseTeammateShutdowns.ts +55 -0
  455. package/utils/color-diff-mock.ts +27 -0
  456. package/utils/combinedAbortSignal.ts +47 -0
  457. package/utils/commandLifecycle.ts +21 -0
  458. package/utils/commitAttribution.ts +961 -0
  459. package/utils/completionCache.ts +166 -0
  460. package/utils/computerUse/appNames.ts +196 -0
  461. package/utils/computerUse/cleanup.ts +86 -0
  462. package/utils/computerUse/common.ts +61 -0
  463. package/utils/computerUse/computerUseLock.ts +215 -0
  464. package/utils/computerUse/drainRunLoop.ts +79 -0
  465. package/utils/computerUse/escHotkey.ts +54 -0
  466. package/utils/computerUse/executor.ts +658 -0
  467. package/utils/computerUse/gates.ts +72 -0
  468. package/utils/computerUse/hostAdapter.ts +69 -0
  469. package/utils/computerUse/inputLoader.ts +30 -0
  470. package/utils/computerUse/mcpServer.ts +106 -0
  471. package/utils/computerUse/setup.ts +53 -0
  472. package/utils/computerUse/swiftLoader.ts +23 -0
  473. package/utils/computerUse/toolRendering.tsx +125 -0
  474. package/utils/computerUse/wrapper.tsx +336 -0
  475. package/utils/concurrentSessions.ts +204 -0
  476. package/utils/config.ts +1817 -0
  477. package/utils/configConstants.ts +21 -0
  478. package/utils/contentArray.ts +51 -0
  479. package/utils/context.ts +221 -0
  480. package/utils/contextAnalysis.ts +272 -0
  481. package/utils/contextSuggestions.ts +235 -0
  482. package/utils/controlMessageCompat.ts +32 -0
  483. package/utils/conversationRecovery.ts +597 -0
  484. package/utils/cron.ts +308 -0
  485. package/utils/cronJitterConfig.ts +75 -0
  486. package/utils/cronScheduler.ts +565 -0
  487. package/utils/cronTasks.ts +458 -0
  488. package/utils/cronTasksLock.ts +195 -0
  489. package/utils/crossProjectResume.ts +75 -0
  490. package/utils/crypto.ts +13 -0
  491. package/utils/cwd.ts +32 -0
  492. package/utils/debug.ts +268 -0
  493. package/utils/debugFilter.ts +157 -0
  494. package/utils/deepLink/banner.ts +123 -0
  495. package/utils/deepLink/parseDeepLink.ts +170 -0
  496. package/utils/deepLink/protocolHandler.ts +136 -0
  497. package/utils/deepLink/registerProtocol.ts +348 -0
  498. package/utils/deepLink/terminalLauncher.ts +557 -0
  499. package/utils/deepLink/terminalPreference.ts +54 -0
  500. package/utils/desktopDeepLink.ts +236 -0
  501. package/utils/detectRepository.ts +178 -0
  502. package/utils/diagLogs.ts +94 -0
  503. package/utils/diff.ts +177 -0
  504. package/utils/directMemberMessage.ts +69 -0
  505. package/utils/displayTags.ts +51 -0
  506. package/utils/doctorContextWarnings.ts +265 -0
  507. package/utils/doctorDiagnostic.ts +625 -0
  508. package/utils/dxt/helpers.ts +88 -0
  509. package/utils/dxt/zip.ts +226 -0
  510. package/utils/earlyInput.ts +191 -0
  511. package/utils/editor.ts +183 -0
  512. package/utils/effort.ts +329 -0
  513. package/utils/embeddedTools.ts +29 -0
  514. package/utils/env.ts +347 -0
  515. package/utils/envDynamic.ts +151 -0
  516. package/utils/envUtils.ts +183 -0
  517. package/utils/envValidation.ts +38 -0
  518. package/utils/errorLogSink.ts +235 -0
  519. package/utils/errors.ts +238 -0
  520. package/utils/exampleCommands.ts +184 -0
  521. package/utils/execFileNoThrow.ts +150 -0
  522. package/utils/execFileNoThrowPortable.ts +89 -0
  523. package/utils/execSyncWrapper.ts +38 -0
  524. package/utils/exportRenderer.tsx +98 -0
  525. package/utils/extraUsage.ts +23 -0
  526. package/utils/fastMode.ts +532 -0
  527. package/utils/file.ts +584 -0
  528. package/utils/fileHistory.ts +1115 -0
  529. package/utils/fileOperationAnalytics.ts +71 -0
  530. package/utils/filePersistence/filePersistence.ts +287 -0
  531. package/utils/filePersistence/outputsScanner.ts +126 -0
  532. package/utils/fileRead.ts +102 -0
  533. package/utils/fileReadCache.ts +96 -0
  534. package/utils/fileStateCache.ts +142 -0
  535. package/utils/findExecutable.ts +17 -0
  536. package/utils/fingerprint.ts +76 -0
  537. package/utils/forkedAgent.ts +689 -0
  538. package/utils/format.ts +308 -0
  539. package/utils/formatBriefTimestamp.ts +81 -0
  540. package/utils/fpsTracker.ts +47 -0
  541. package/utils/frontmatterParser.ts +370 -0
  542. package/utils/fsOperations.ts +770 -0
  543. package/utils/fullscreen.ts +202 -0
  544. package/utils/generatedFiles.ts +136 -0
  545. package/utils/generators.ts +88 -0
  546. package/utils/genericProcessUtils.ts +184 -0
  547. package/utils/getWorktreePaths.ts +70 -0
  548. package/utils/getWorktreePathsPortable.ts +27 -0
  549. package/utils/ghPrStatus.ts +106 -0
  550. package/utils/git/gitConfigParser.ts +277 -0
  551. package/utils/git/gitFilesystem.ts +699 -0
  552. package/utils/git/gitignore.ts +99 -0
  553. package/utils/git.ts +926 -0
  554. package/utils/gitDiff.ts +532 -0
  555. package/utils/gitSettings.ts +18 -0
  556. package/utils/github/ghAuthStatus.ts +29 -0
  557. package/utils/githubRepoPathMapping.ts +162 -0
  558. package/utils/glob.ts +130 -0
  559. package/utils/gracefulShutdown.ts +529 -0
  560. package/utils/groupToolUses.ts +182 -0
  561. package/utils/handlePromptSubmit.ts +610 -0
  562. package/utils/hash.ts +46 -0
  563. package/utils/headlessProfiler.ts +178 -0
  564. package/utils/heapDumpService.ts +303 -0
  565. package/utils/heatmap.ts +198 -0
  566. package/utils/highlightMatch.tsx +28 -0
  567. package/utils/hooks/AsyncHookRegistry.ts +309 -0
  568. package/utils/hooks/apiQueryHookHelper.ts +141 -0
  569. package/utils/hooks/execAgentHook.ts +339 -0
  570. package/utils/hooks/execHttpHook.ts +242 -0
  571. package/utils/hooks/execPromptHook.ts +211 -0
  572. package/utils/hooks/fileChangedWatcher.ts +191 -0
  573. package/utils/hooks/hookEvents.ts +192 -0
  574. package/utils/hooks/hookHelpers.ts +83 -0
  575. package/utils/hooks/hooksConfigManager.ts +400 -0
  576. package/utils/hooks/hooksConfigSnapshot.ts +133 -0
  577. package/utils/hooks/hooksSettings.ts +271 -0
  578. package/utils/hooks/postSamplingHooks.ts +70 -0
  579. package/utils/hooks/registerFrontmatterHooks.ts +67 -0
  580. package/utils/hooks/registerSkillHooks.ts +64 -0
  581. package/utils/hooks/sessionHooks.ts +447 -0
  582. package/utils/hooks/skillImprovement.ts +267 -0
  583. package/utils/hooks/ssrfGuard.ts +294 -0
  584. package/utils/hooks.ts +5022 -0
  585. package/utils/horizontalScroll.ts +137 -0
  586. package/utils/http.ts +136 -0
  587. package/utils/hyperlink.ts +39 -0
  588. package/utils/iTermBackup.ts +73 -0
  589. package/utils/ide.ts +1494 -0
  590. package/utils/idePathConversion.ts +90 -0
  591. package/utils/idleTimeout.ts +53 -0
  592. package/utils/imagePaste.ts +416 -0
  593. package/utils/imageResizer.ts +880 -0
  594. package/utils/imageStore.ts +167 -0
  595. package/utils/imageValidation.ts +104 -0
  596. package/utils/immediateCommand.ts +15 -0
  597. package/utils/inProcessTeammateHelpers.ts +102 -0
  598. package/utils/ink.ts +26 -0
  599. package/utils/intl.ts +94 -0
  600. package/utils/jetbrains.ts +191 -0
  601. package/utils/json.ts +277 -0
  602. package/utils/jsonRead.ts +16 -0
  603. package/utils/keyboardShortcuts.ts +14 -0
  604. package/utils/lazySchema.ts +8 -0
  605. package/utils/listSessionsImpl.ts +454 -0
  606. package/utils/localInstaller.ts +162 -0
  607. package/utils/lockfile.ts +43 -0
  608. package/utils/log.ts +362 -0
  609. package/utils/logoV2Utils.ts +347 -0
  610. package/utils/mailbox.ts +73 -0
  611. package/utils/managedEnv.ts +199 -0
  612. package/utils/managedEnvConstants.ts +191 -0
  613. package/utils/markdown.ts +381 -0
  614. package/utils/markdownConfigLoader.ts +600 -0
  615. package/utils/mcp/dateTimeParser.ts +121 -0
  616. package/utils/mcp/elicitationValidation.ts +336 -0
  617. package/utils/mcpInstructionsDelta.ts +130 -0
  618. package/utils/mcpOutputStorage.ts +189 -0
  619. package/utils/mcpValidation.ts +208 -0
  620. package/utils/mcpWebSocketTransport.ts +200 -0
  621. package/utils/memoize.ts +269 -0
  622. package/utils/memory/types.ts +12 -0
  623. package/utils/memory/versions.ts +8 -0
  624. package/utils/memoryFileDetection.ts +289 -0
  625. package/utils/messagePredicates.ts +8 -0
  626. package/utils/messageQueueManager.ts +547 -0
  627. package/utils/messages/mappers.ts +290 -0
  628. package/utils/messages/systemInit.ts +96 -0
  629. package/utils/messages.ts +5520 -0
  630. package/utils/model/agent.ts +157 -0
  631. package/utils/model/aliases.ts +35 -0
  632. package/utils/model/antModels.ts +64 -0
  633. package/utils/model/bedrock.ts +265 -0
  634. package/utils/model/check1mAccess.ts +72 -0
  635. package/utils/model/configs.ts +158 -0
  636. package/utils/model/contextWindowUpgradeCheck.ts +47 -0
  637. package/utils/model/deprecation.ts +101 -0
  638. package/utils/model/model.ts +654 -0
  639. package/utils/model/modelAllowlist.ts +170 -0
  640. package/utils/model/modelCapabilities.ts +118 -0
  641. package/utils/model/modelOptions.ts +589 -0
  642. package/utils/model/modelStrings.ts +170 -0
  643. package/utils/model/modelSupportOverrides.ts +50 -0
  644. package/utils/model/providers.ts +42 -0
  645. package/utils/model/validateModel.ts +159 -0
  646. package/utils/modelCost.ts +231 -0
  647. package/utils/modifiers.ts +36 -0
  648. package/utils/mtls.ts +179 -0
  649. package/utils/nativeInstaller/download.ts +523 -0
  650. package/utils/nativeInstaller/index.ts +18 -0
  651. package/utils/nativeInstaller/installer.ts +1708 -0
  652. package/utils/nativeInstaller/packageManagers.ts +336 -0
  653. package/utils/nativeInstaller/pidLock.ts +433 -0
  654. package/utils/notebook.ts +224 -0
  655. package/utils/objectGroupBy.ts +18 -0
  656. package/utils/pasteStore.ts +104 -0
  657. package/utils/path.ts +155 -0
  658. package/utils/pdf.ts +300 -0
  659. package/utils/pdfUtils.ts +70 -0
  660. package/utils/peerAddress.ts +21 -0
  661. package/utils/permissions/PermissionMode.ts +141 -0
  662. package/utils/permissions/PermissionPromptToolResultSchema.ts +127 -0
  663. package/utils/permissions/PermissionResult.ts +35 -0
  664. package/utils/permissions/PermissionRule.ts +40 -0
  665. package/utils/permissions/PermissionUpdate.ts +389 -0
  666. package/utils/permissions/PermissionUpdateSchema.ts +78 -0
  667. package/utils/permissions/autoModeState.ts +39 -0
  668. package/utils/permissions/bashClassifier.ts +61 -0
  669. package/utils/permissions/bypassPermissionsKillswitch.ts +155 -0
  670. package/utils/permissions/classifierDecision.ts +98 -0
  671. package/utils/permissions/classifierShared.ts +39 -0
  672. package/utils/permissions/dangerousPatterns.ts +80 -0
  673. package/utils/permissions/denialTracking.ts +45 -0
  674. package/utils/permissions/filesystem.ts +1777 -0
  675. package/utils/permissions/getNextPermissionMode.ts +101 -0
  676. package/utils/permissions/pathValidation.ts +485 -0
  677. package/utils/permissions/permissionExplainer.ts +250 -0
  678. package/utils/permissions/permissionRuleParser.ts +198 -0
  679. package/utils/permissions/permissionSetup.ts +1532 -0
  680. package/utils/permissions/permissions.ts +1486 -0
  681. package/utils/permissions/permissionsLoader.ts +296 -0
  682. package/utils/permissions/shadowedRuleDetection.ts +234 -0
  683. package/utils/permissions/shellRuleMatching.ts +228 -0
  684. package/utils/permissions/yoloClassifier.ts +1495 -0
  685. package/utils/planModeV2.ts +95 -0
  686. package/utils/plans.ts +397 -0
  687. package/utils/platform.ts +150 -0
  688. package/utils/plugins/addDirPluginSettings.ts +71 -0
  689. package/utils/plugins/cacheUtils.ts +196 -0
  690. package/utils/plugins/dependencyResolver.ts +305 -0
  691. package/utils/plugins/fetchTelemetry.ts +135 -0
  692. package/utils/plugins/gitAvailability.ts +69 -0
  693. package/utils/plugins/headlessPluginInstall.ts +174 -0
  694. package/utils/plugins/hintRecommendation.ts +164 -0
  695. package/utils/plugins/installCounts.ts +292 -0
  696. package/utils/plugins/installedPluginsManager.ts +1268 -0
  697. package/utils/plugins/loadPluginAgents.ts +348 -0
  698. package/utils/plugins/loadPluginCommands.ts +946 -0
  699. package/utils/plugins/loadPluginHooks.ts +287 -0
  700. package/utils/plugins/loadPluginOutputStyles.ts +178 -0
  701. package/utils/plugins/lspPluginIntegration.ts +387 -0
  702. package/utils/plugins/lspRecommendation.ts +374 -0
  703. package/utils/plugins/managedPlugins.ts +27 -0
  704. package/utils/plugins/marketplaceHelpers.ts +592 -0
  705. package/utils/plugins/marketplaceManager.ts +2643 -0
  706. package/utils/plugins/mcpPluginIntegration.ts +634 -0
  707. package/utils/plugins/mcpbHandler.ts +968 -0
  708. package/utils/plugins/officialMarketplace.ts +25 -0
  709. package/utils/plugins/officialMarketplaceGcs.ts +216 -0
  710. package/utils/plugins/officialMarketplaceStartupCheck.ts +439 -0
  711. package/utils/plugins/orphanedPluginFilter.ts +114 -0
  712. package/utils/plugins/parseMarketplaceInput.ts +162 -0
  713. package/utils/plugins/performStartupChecks.tsx +70 -0
  714. package/utils/plugins/pluginAutoupdate.ts +284 -0
  715. package/utils/plugins/pluginBlocklist.ts +127 -0
  716. package/utils/plugins/pluginDirectories.ts +178 -0
  717. package/utils/plugins/pluginFlagging.ts +208 -0
  718. package/utils/plugins/pluginIdentifier.ts +123 -0
  719. package/utils/plugins/pluginInstallationHelpers.ts +595 -0
  720. package/utils/plugins/pluginLoader.ts +3302 -0
  721. package/utils/plugins/pluginOptionsStorage.ts +400 -0
  722. package/utils/plugins/pluginPolicy.ts +20 -0
  723. package/utils/plugins/pluginStartupCheck.ts +341 -0
  724. package/utils/plugins/pluginVersioning.ts +157 -0
  725. package/utils/plugins/reconciler.ts +265 -0
  726. package/utils/plugins/refresh.ts +215 -0
  727. package/utils/plugins/schemas.ts +1681 -0
  728. package/utils/plugins/validatePlugin.ts +903 -0
  729. package/utils/plugins/walkPluginMarkdown.ts +69 -0
  730. package/utils/plugins/zipCache.ts +406 -0
  731. package/utils/plugins/zipCacheAdapters.ts +164 -0
  732. package/utils/powershell/dangerousCmdlets.ts +185 -0
  733. package/utils/powershell/parser.ts +1804 -0
  734. package/utils/powershell/staticPrefix.ts +316 -0
  735. package/utils/preflightChecks.tsx +151 -0
  736. package/utils/privacyLevel.ts +55 -0
  737. package/utils/process.ts +68 -0
  738. package/utils/processUserInput/processBashCommand.tsx +140 -0
  739. package/utils/processUserInput/processSlashCommand.tsx +922 -0
  740. package/utils/processUserInput/processTextPrompt.ts +100 -0
  741. package/utils/processUserInput/processUserInput.ts +605 -0
  742. package/utils/profilerBase.ts +46 -0
  743. package/utils/promptCategory.ts +49 -0
  744. package/utils/promptEditor.ts +188 -0
  745. package/utils/promptShellExecution.ts +183 -0
  746. package/utils/proxy.ts +426 -0
  747. package/utils/queryContext.ts +179 -0
  748. package/utils/queryHelpers.ts +552 -0
  749. package/utils/queryProfiler.ts +301 -0
  750. package/utils/queueProcessor.ts +95 -0
  751. package/utils/readEditContext.ts +227 -0
  752. package/utils/readFileInRange.ts +383 -0
  753. package/utils/releaseNotes.ts +360 -0
  754. package/utils/renderOptions.ts +113 -0
  755. package/utils/ripgrep.ts +679 -0
  756. package/utils/sandbox/sandbox-adapter.ts +985 -0
  757. package/utils/sandbox/sandbox-ui-utils.ts +12 -0
  758. package/utils/sanitization.ts +91 -0
  759. package/utils/screenshotClipboard.ts +121 -0
  760. package/utils/sdkEventQueue.ts +134 -0
  761. package/utils/secureStorage/fallbackStorage.ts +70 -0
  762. package/utils/secureStorage/index.ts +17 -0
  763. package/utils/secureStorage/keychainPrefetch.ts +116 -0
  764. package/utils/secureStorage/macOsKeychainHelpers.ts +111 -0
  765. package/utils/secureStorage/macOsKeychainStorage.ts +231 -0
  766. package/utils/secureStorage/plainTextStorage.ts +84 -0
  767. package/utils/semanticBoolean.ts +29 -0
  768. package/utils/semanticNumber.ts +36 -0
  769. package/utils/semver.ts +59 -0
  770. package/utils/sequential.ts +56 -0
  771. package/utils/sessionActivity.ts +133 -0
  772. package/utils/sessionEnvVars.ts +22 -0
  773. package/utils/sessionEnvironment.ts +166 -0
  774. package/utils/sessionFileAccessHooks.ts +250 -0
  775. package/utils/sessionIngressAuth.ts +140 -0
  776. package/utils/sessionRestore.ts +551 -0
  777. package/utils/sessionStart.ts +232 -0
  778. package/utils/sessionState.ts +150 -0
  779. package/utils/sessionStorage.ts +5105 -0
  780. package/utils/sessionStoragePortable.ts +793 -0
  781. package/utils/sessionTitle.ts +129 -0
  782. package/utils/sessionUrl.ts +64 -0
  783. package/utils/set.ts +53 -0
  784. package/utils/settings/allErrors.ts +32 -0
  785. package/utils/settings/applySettingsChange.ts +92 -0
  786. package/utils/settings/changeDetector.ts +488 -0
  787. package/utils/settings/constants.ts +202 -0
  788. package/utils/settings/internalWrites.ts +37 -0
  789. package/utils/settings/managedPath.ts +34 -0
  790. package/utils/settings/mdm/constants.ts +81 -0
  791. package/utils/settings/mdm/rawRead.ts +130 -0
  792. package/utils/settings/mdm/settings.ts +316 -0
  793. package/utils/settings/permissionValidation.ts +262 -0
  794. package/utils/settings/pluginOnlyPolicy.ts +60 -0
  795. package/utils/settings/schemaOutput.ts +8 -0
  796. package/utils/settings/settings.ts +1015 -0
  797. package/utils/settings/settingsCache.ts +80 -0
  798. package/utils/settings/toolValidationConfig.ts +103 -0
  799. package/utils/settings/types.ts +1149 -0
  800. package/utils/settings/validateEditTool.ts +45 -0
  801. package/utils/settings/validation.ts +265 -0
  802. package/utils/settings/validationTips.ts +164 -0
  803. package/utils/shell/bashProvider.ts +255 -0
  804. package/utils/shell/outputLimits.ts +14 -0
  805. package/utils/shell/powershellDetection.ts +107 -0
  806. package/utils/shell/powershellProvider.ts +123 -0
  807. package/utils/shell/prefix.ts +367 -0
  808. package/utils/shell/readOnlyCommandValidation.ts +1893 -0
  809. package/utils/shell/resolveDefaultShell.ts +14 -0
  810. package/utils/shell/shellProvider.ts +33 -0
  811. package/utils/shell/shellToolUtils.ts +22 -0
  812. package/utils/shell/specPrefix.ts +241 -0
  813. package/utils/shellConfig.ts +167 -0
  814. package/utils/sideQuery.ts +222 -0
  815. package/utils/sideQuestion.ts +155 -0
  816. package/utils/signal.ts +43 -0
  817. package/utils/sinks.ts +16 -0
  818. package/utils/skills/skillChangeDetector.ts +311 -0
  819. package/utils/slashCommandParsing.ts +60 -0
  820. package/utils/sleep.ts +84 -0
  821. package/utils/sliceAnsi.ts +91 -0
  822. package/utils/slowOperations.ts +286 -0
  823. package/utils/standaloneAgent.ts +23 -0
  824. package/utils/startupProfiler.ts +194 -0
  825. package/utils/staticRender.tsx +116 -0
  826. package/utils/stats.ts +1061 -0
  827. package/utils/statsCache.ts +434 -0
  828. package/utils/status.tsx +362 -0
  829. package/utils/statusNoticeDefinitions.tsx +198 -0
  830. package/utils/statusNoticeHelpers.ts +20 -0
  831. package/utils/stream.ts +76 -0
  832. package/utils/streamJsonStdoutGuard.ts +123 -0
  833. package/utils/streamlinedTransform.ts +201 -0
  834. package/utils/stringUtils.ts +235 -0
  835. package/utils/subprocessEnv.ts +99 -0
  836. package/utils/suggestions/commandSuggestions.ts +567 -0
  837. package/utils/suggestions/directoryCompletion.ts +263 -0
  838. package/utils/suggestions/shellHistoryCompletion.ts +119 -0
  839. package/utils/suggestions/skillUsageTracking.ts +55 -0
  840. package/utils/suggestions/slackChannelSuggestions.ts +209 -0
  841. package/utils/swarm/It2SetupPrompt.tsx +380 -0
  842. package/utils/swarm/backends/ITermBackend.ts +370 -0
  843. package/utils/swarm/backends/InProcessBackend.ts +339 -0
  844. package/utils/swarm/backends/PaneBackendExecutor.ts +354 -0
  845. package/utils/swarm/backends/TmuxBackend.ts +764 -0
  846. package/utils/swarm/backends/detection.ts +128 -0
  847. package/utils/swarm/backends/it2Setup.ts +245 -0
  848. package/utils/swarm/backends/registry.ts +464 -0
  849. package/utils/swarm/backends/teammateModeSnapshot.ts +87 -0
  850. package/utils/swarm/backends/types.ts +311 -0
  851. package/utils/swarm/constants.ts +33 -0
  852. package/utils/swarm/inProcessRunner.ts +1552 -0
  853. package/utils/swarm/leaderPermissionBridge.ts +54 -0
  854. package/utils/swarm/permissionSync.ts +928 -0
  855. package/utils/swarm/reconnection.ts +119 -0
  856. package/utils/swarm/spawnInProcess.ts +328 -0
  857. package/utils/swarm/spawnUtils.ts +146 -0
  858. package/utils/swarm/teamHelpers.ts +683 -0
  859. package/utils/swarm/teammateInit.ts +129 -0
  860. package/utils/swarm/teammateLayoutManager.ts +107 -0
  861. package/utils/swarm/teammateModel.ts +10 -0
  862. package/utils/swarm/teammatePromptAddendum.ts +18 -0
  863. package/utils/systemDirectories.ts +74 -0
  864. package/utils/systemPrompt.ts +123 -0
  865. package/utils/systemPromptType.ts +14 -0
  866. package/utils/systemTheme.ts +119 -0
  867. package/utils/taggedId.ts +54 -0
  868. package/utils/task/TaskOutput.ts +390 -0
  869. package/utils/task/diskOutput.ts +451 -0
  870. package/utils/task/framework.ts +308 -0
  871. package/utils/task/outputFormatting.ts +38 -0
  872. package/utils/task/sdkProgress.ts +36 -0
  873. package/utils/tasks.ts +862 -0
  874. package/utils/teamDiscovery.ts +81 -0
  875. package/utils/teamMemoryOps.ts +88 -0
  876. package/utils/teammate.ts +292 -0
  877. package/utils/teammateContext.ts +96 -0
  878. package/utils/teammateMailbox.ts +1183 -0
  879. package/utils/telemetry/betaSessionTracing.ts +491 -0
  880. package/utils/telemetry/bigqueryExporter.ts +252 -0
  881. package/utils/telemetry/events.ts +75 -0
  882. package/utils/telemetry/instrumentation.ts +825 -0
  883. package/utils/telemetry/logger.ts +26 -0
  884. package/utils/telemetry/perfettoTracing.ts +1120 -0
  885. package/utils/telemetry/pluginTelemetry.ts +289 -0
  886. package/utils/telemetry/sessionTracing.ts +927 -0
  887. package/utils/telemetry/skillLoadedEvent.ts +39 -0
  888. package/utils/telemetryAttributes.ts +71 -0
  889. package/utils/teleport/api.ts +466 -0
  890. package/utils/teleport/environmentSelection.ts +77 -0
  891. package/utils/teleport/environments.ts +120 -0
  892. package/utils/teleport/gitBundle.ts +292 -0
  893. package/utils/teleport.tsx +1226 -0
  894. package/utils/tempfile.ts +31 -0
  895. package/utils/terminal.ts +131 -0
  896. package/utils/terminalPanel.ts +191 -0
  897. package/utils/textHighlighting.ts +166 -0
  898. package/utils/theme.ts +639 -0
  899. package/utils/thinking.ts +162 -0
  900. package/utils/timeouts.ts +39 -0
  901. package/utils/tmuxSocket.ts +427 -0
  902. package/utils/todo/types.ts +18 -0
  903. package/utils/tokenBudget.ts +73 -0
  904. package/utils/tokens.ts +261 -0
  905. package/utils/toolErrors.ts +132 -0
  906. package/utils/toolPool.ts +79 -0
  907. package/utils/toolResultStorage.ts +1040 -0
  908. package/utils/toolSchemaCache.ts +26 -0
  909. package/utils/toolSearch.ts +756 -0
  910. package/utils/transcriptSearch.ts +202 -0
  911. package/utils/treeify.ts +170 -0
  912. package/utils/truncate.ts +179 -0
  913. package/utils/ultraplan/ccrSession.ts +349 -0
  914. package/utils/ultraplan/keyword.ts +127 -0
  915. package/utils/ultraplan/prompt.txt +1 -0
  916. package/utils/unaryLogging.ts +39 -0
  917. package/utils/undercover.ts +89 -0
  918. package/utils/user.ts +194 -0
  919. package/utils/userAgent.ts +10 -0
  920. package/utils/userPromptKeywords.ts +27 -0
  921. package/utils/uuid.ts +27 -0
  922. package/utils/warningHandler.ts +121 -0
  923. package/utils/which.ts +82 -0
  924. package/utils/windowsPaths.ts +173 -0
  925. package/utils/withResolvers.ts +13 -0
  926. package/utils/words.ts +800 -0
  927. package/utils/workloadContext.ts +57 -0
  928. package/utils/worktree.ts +1519 -0
  929. package/utils/worktreeModeEnabled.ts +11 -0
  930. package/utils/xdg.ts +65 -0
  931. package/utils/xmem.ts +6 -0
  932. package/utils/xml.ts +16 -0
  933. package/utils/yaml.ts +15 -0
  934. package/utils/zodToJsonSchema.ts +23 -0
@@ -0,0 +1,903 @@
1
+ import type { Dirent, Stats } from 'fs'
2
+ import { readdir, readFile, stat } from 'fs/promises'
3
+ import * as path from 'path'
4
+ import { z } from 'zod/v4'
5
+ import { errorMessage, getErrnoCode, isENOENT } from '../errors.js'
6
+ import { FRONTMATTER_REGEX } from '../frontmatterParser.js'
7
+ import { jsonParse } from '../slowOperations.js'
8
+ import { parseYaml } from '../yaml.js'
9
+ import {
10
+ PluginHooksSchema,
11
+ PluginManifestSchema,
12
+ PluginMarketplaceEntrySchema,
13
+ PluginMarketplaceSchema,
14
+ } from './schemas.js'
15
+
16
+ /**
17
+ * Fields that belong in marketplace.json entries (PluginMarketplaceEntrySchema)
18
+ * but not plugin.json (PluginManifestSchema). Plugin authors reasonably copy
19
+ * one into the other. Surfaced as warnings by `claude plugin validate` since
20
+ * they're a known confusion point — the load path silently strips all unknown
21
+ * keys via zod's default behavior, so they're harmless at runtime but worth
22
+ * flagging to authors.
23
+ */
24
+ const MARKETPLACE_ONLY_MANIFEST_FIELDS = new Set([
25
+ 'category',
26
+ 'source',
27
+ 'tags',
28
+ 'strict',
29
+ 'id',
30
+ ])
31
+
32
+ export type ValidationResult = {
33
+ success: boolean
34
+ errors: ValidationError[]
35
+ warnings: ValidationWarning[]
36
+ filePath: string
37
+ fileType: 'plugin' | 'marketplace' | 'skill' | 'agent' | 'command' | 'hooks'
38
+ }
39
+
40
+ export type ValidationError = {
41
+ path: string
42
+ message: string
43
+ code?: string
44
+ }
45
+
46
+ export type ValidationWarning = {
47
+ path: string
48
+ message: string
49
+ }
50
+
51
+ /**
52
+ * Detect whether a file is a plugin manifest or marketplace manifest
53
+ */
54
+ function detectManifestType(
55
+ filePath: string,
56
+ ): 'plugin' | 'marketplace' | 'unknown' {
57
+ const fileName = path.basename(filePath)
58
+ const dirName = path.basename(path.dirname(filePath))
59
+
60
+ // Check filename patterns
61
+ if (fileName === 'plugin.json') return 'plugin'
62
+ if (fileName === 'marketplace.json') return 'marketplace'
63
+
64
+ // Check if it's in .claude-plugin directory
65
+ if (dirName === '.claude-plugin') {
66
+ return 'plugin' // Most likely plugin.json
67
+ }
68
+
69
+ return 'unknown'
70
+ }
71
+
72
+ /**
73
+ * Format Zod validation errors into a readable format
74
+ */
75
+ function formatZodErrors(zodError: z.ZodError): ValidationError[] {
76
+ return zodError.issues.map(error => ({
77
+ path: error.path.join('.') || 'root',
78
+ message: error.message,
79
+ code: error.code,
80
+ }))
81
+ }
82
+
83
+ /**
84
+ * Check for parent-directory segments ('..') in a path string.
85
+ *
86
+ * For plugin.json component paths this is a security concern (escaping the plugin dir).
87
+ * For marketplace.json source paths it's almost always a resolution-base misunderstanding:
88
+ * paths resolve from the marketplace repo root, not from marketplace.json itself, so the
89
+ * '..' a user added to "climb out of .claude-plugin/" is unnecessary. Callers pass `hint`
90
+ * to attach the right explanation.
91
+ */
92
+ function checkPathTraversal(
93
+ p: string,
94
+ field: string,
95
+ errors: ValidationError[],
96
+ hint?: string,
97
+ ): void {
98
+ if (p.includes('..')) {
99
+ errors.push({
100
+ path: field,
101
+ message: hint
102
+ ? `Path contains "..": ${p}. ${hint}`
103
+ : `Path contains ".." which could be a path traversal attempt: ${p}`,
104
+ })
105
+ }
106
+ }
107
+
108
+ // Shown when a marketplace plugin source contains '..'. Most users hit this because
109
+ // they expect paths to resolve relative to marketplace.json (inside .claude-plugin/),
110
+ // but resolution actually starts at the marketplace repo root — see gh-29485.
111
+ // Computes a tailored "use X instead of Y" suggestion from the user's actual path
112
+ // rather than a hardcoded example (review feedback on #20895).
113
+ function marketplaceSourceHint(p: string): string {
114
+ // Strip leading ../ segments: the '..' a user added to "climb out of
115
+ // .claude-plugin/" is unnecessary since paths already start at the repo root.
116
+ // If '..' appears mid-path (rare), fall back to a generic example.
117
+ const stripped = p.replace(/^(\.\.\/)+/, '')
118
+ const corrected = stripped !== p ? `./${stripped}` : './plugins/my-plugin'
119
+ return (
120
+ 'Plugin source paths are resolved relative to the marketplace root (the directory ' +
121
+ 'containing .claude-plugin/), not relative to marketplace.json. ' +
122
+ `Use "${corrected}" instead of "${p}".`
123
+ )
124
+ }
125
+
126
+ /**
127
+ * Validate a plugin manifest file (plugin.json)
128
+ */
129
+ export async function validatePluginManifest(
130
+ filePath: string,
131
+ ): Promise<ValidationResult> {
132
+ const errors: ValidationError[] = []
133
+ const warnings: ValidationWarning[] = []
134
+ const absolutePath = path.resolve(filePath)
135
+
136
+ // Read file content — handle ENOENT / EISDIR / permission errors directly
137
+ let content: string
138
+ try {
139
+ content = await readFile(absolutePath, { encoding: 'utf-8' })
140
+ } catch (error: unknown) {
141
+ const code = getErrnoCode(error)
142
+ let message: string
143
+ if (code === 'ENOENT') {
144
+ message = `File not found: ${absolutePath}`
145
+ } else if (code === 'EISDIR') {
146
+ message = `Path is not a file: ${absolutePath}`
147
+ } else {
148
+ message = `Failed to read file: ${errorMessage(error)}`
149
+ }
150
+ return {
151
+ success: false,
152
+ errors: [{ path: 'file', message, code }],
153
+ warnings: [],
154
+ filePath: absolutePath,
155
+ fileType: 'plugin',
156
+ }
157
+ }
158
+
159
+ let parsed: unknown
160
+ try {
161
+ parsed = jsonParse(content)
162
+ } catch (error) {
163
+ return {
164
+ success: false,
165
+ errors: [
166
+ {
167
+ path: 'json',
168
+ message: `Invalid JSON syntax: ${errorMessage(error)}`,
169
+ },
170
+ ],
171
+ warnings: [],
172
+ filePath: absolutePath,
173
+ fileType: 'plugin',
174
+ }
175
+ }
176
+
177
+ // Check for path traversal in the parsed JSON before schema validation
178
+ // This ensures we catch security issues even if schema validation fails
179
+ if (parsed && typeof parsed === 'object') {
180
+ const obj = parsed as Record<string, unknown>
181
+
182
+ // Check commands
183
+ if (obj.commands) {
184
+ const commands = Array.isArray(obj.commands)
185
+ ? obj.commands
186
+ : [obj.commands]
187
+ commands.forEach((cmd, i) => {
188
+ if (typeof cmd === 'string') {
189
+ checkPathTraversal(cmd, `commands[${i}]`, errors)
190
+ }
191
+ })
192
+ }
193
+
194
+ // Check agents
195
+ if (obj.agents) {
196
+ const agents = Array.isArray(obj.agents) ? obj.agents : [obj.agents]
197
+ agents.forEach((agent, i) => {
198
+ if (typeof agent === 'string') {
199
+ checkPathTraversal(agent, `agents[${i}]`, errors)
200
+ }
201
+ })
202
+ }
203
+
204
+ // Check skills
205
+ if (obj.skills) {
206
+ const skills = Array.isArray(obj.skills) ? obj.skills : [obj.skills]
207
+ skills.forEach((skill, i) => {
208
+ if (typeof skill === 'string') {
209
+ checkPathTraversal(skill, `skills[${i}]`, errors)
210
+ }
211
+ })
212
+ }
213
+ }
214
+
215
+ // Surface marketplace-only fields as a warning BEFORE validation flags
216
+ // them. `claude plugin validate` is a developer tool — authors running it
217
+ // want to know these fields don't belong here. But it's a warning, not an
218
+ // error: the plugin loads fine at runtime (the base schema strips unknown
219
+ // keys). We strip them here so the .strict() call below doesn't double-
220
+ // report them as unrecognized-key errors on top of the targeted warnings.
221
+ let toValidate = parsed
222
+ if (typeof parsed === 'object' && parsed !== null) {
223
+ const obj = parsed as Record<string, unknown>
224
+ const strayKeys = Object.keys(obj).filter(k =>
225
+ MARKETPLACE_ONLY_MANIFEST_FIELDS.has(k),
226
+ )
227
+ if (strayKeys.length > 0) {
228
+ const stripped = { ...obj }
229
+ for (const key of strayKeys) {
230
+ delete stripped[key]
231
+ warnings.push({
232
+ path: key,
233
+ message:
234
+ `Field '${key}' belongs in the marketplace entry (marketplace.json), ` +
235
+ `not plugin.json. It's harmless here but unused — Claude Code ` +
236
+ `ignores it at load time.`,
237
+ })
238
+ }
239
+ toValidate = stripped
240
+ }
241
+ }
242
+
243
+ // Validate against schema (post-strip, so marketplace fields don't fail it).
244
+ // We call .strict() locally here even though the base schema is lenient —
245
+ // the runtime load path silently strips unknown keys for resilience, but
246
+ // this is a developer tool and authors running it want typo feedback.
247
+ const result = PluginManifestSchema().strict().safeParse(toValidate)
248
+
249
+ if (!result.success) {
250
+ errors.push(...formatZodErrors(result.error))
251
+ }
252
+
253
+ // Check for common issues and add warnings
254
+ if (result.success) {
255
+ const manifest = result.data
256
+
257
+ // Warn if name isn't strict kebab-case. CC's schema only rejects spaces,
258
+ // but the Claude.ai marketplace sync rejects non-kebab names. Surfacing
259
+ // this here lets authors catch it in CI before the sync fails on them.
260
+ if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(manifest.name)) {
261
+ warnings.push({
262
+ path: 'name',
263
+ message:
264
+ `Plugin name "${manifest.name}" is not kebab-case. Claude Code accepts ` +
265
+ `it, but the Claude.ai marketplace sync requires kebab-case ` +
266
+ `(lowercase letters, digits, and hyphens only, e.g., "my-plugin").`,
267
+ })
268
+ }
269
+
270
+ // Warn if no version specified
271
+ if (!manifest.version) {
272
+ warnings.push({
273
+ path: 'version',
274
+ message:
275
+ 'No version specified. Consider adding a version following semver (e.g., "1.0.0")',
276
+ })
277
+ }
278
+
279
+ // Warn if no description
280
+ if (!manifest.description) {
281
+ warnings.push({
282
+ path: 'description',
283
+ message:
284
+ 'No description provided. Adding a description helps users understand what your plugin does',
285
+ })
286
+ }
287
+
288
+ // Warn if no author
289
+ if (!manifest.author) {
290
+ warnings.push({
291
+ path: 'author',
292
+ message:
293
+ 'No author information provided. Consider adding author details for plugin attribution',
294
+ })
295
+ }
296
+ }
297
+
298
+ return {
299
+ success: errors.length === 0,
300
+ errors,
301
+ warnings,
302
+ filePath: absolutePath,
303
+ fileType: 'plugin',
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Validate a marketplace manifest file (marketplace.json)
309
+ */
310
+ export async function validateMarketplaceManifest(
311
+ filePath: string,
312
+ ): Promise<ValidationResult> {
313
+ const errors: ValidationError[] = []
314
+ const warnings: ValidationWarning[] = []
315
+ const absolutePath = path.resolve(filePath)
316
+
317
+ // Read file content — handle ENOENT / EISDIR / permission errors directly
318
+ let content: string
319
+ try {
320
+ content = await readFile(absolutePath, { encoding: 'utf-8' })
321
+ } catch (error: unknown) {
322
+ const code = getErrnoCode(error)
323
+ let message: string
324
+ if (code === 'ENOENT') {
325
+ message = `File not found: ${absolutePath}`
326
+ } else if (code === 'EISDIR') {
327
+ message = `Path is not a file: ${absolutePath}`
328
+ } else {
329
+ message = `Failed to read file: ${errorMessage(error)}`
330
+ }
331
+ return {
332
+ success: false,
333
+ errors: [{ path: 'file', message, code }],
334
+ warnings: [],
335
+ filePath: absolutePath,
336
+ fileType: 'marketplace',
337
+ }
338
+ }
339
+
340
+ let parsed: unknown
341
+ try {
342
+ parsed = jsonParse(content)
343
+ } catch (error) {
344
+ return {
345
+ success: false,
346
+ errors: [
347
+ {
348
+ path: 'json',
349
+ message: `Invalid JSON syntax: ${errorMessage(error)}`,
350
+ },
351
+ ],
352
+ warnings: [],
353
+ filePath: absolutePath,
354
+ fileType: 'marketplace',
355
+ }
356
+ }
357
+
358
+ // Check for path traversal in plugin sources before schema validation
359
+ // This ensures we catch security issues even if schema validation fails
360
+ if (parsed && typeof parsed === 'object') {
361
+ const obj = parsed as Record<string, unknown>
362
+
363
+ if (Array.isArray(obj.plugins)) {
364
+ obj.plugins.forEach((plugin: unknown, i: number) => {
365
+ if (plugin && typeof plugin === 'object' && 'source' in plugin) {
366
+ const source = (plugin as { source: unknown }).source
367
+ // Check string sources (relative paths)
368
+ if (typeof source === 'string') {
369
+ checkPathTraversal(
370
+ source,
371
+ `plugins[${i}].source`,
372
+ errors,
373
+ marketplaceSourceHint(source),
374
+ )
375
+ }
376
+ // Check object-source .path (git-subdir: subdirectory within the
377
+ // remote repo, sparse-cloned). '..' here is a genuine traversal attempt
378
+ // within the remote repo tree, not a marketplace-root misunderstanding —
379
+ // keep the security framing (no marketplaceSourceHint). See #20895 review.
380
+ if (
381
+ source &&
382
+ typeof source === 'object' &&
383
+ 'path' in source &&
384
+ typeof (source as { path: unknown }).path === 'string'
385
+ ) {
386
+ checkPathTraversal(
387
+ (source as { path: string }).path,
388
+ `plugins[${i}].source.path`,
389
+ errors,
390
+ )
391
+ }
392
+ }
393
+ })
394
+ }
395
+ }
396
+
397
+ // Validate against schema.
398
+ // The base schemas are lenient (strip unknown keys) for runtime resilience,
399
+ // but this is a developer tool — authors want typo feedback. We rebuild the
400
+ // schema with .strict() here. Note .strict() on the outer object does NOT
401
+ // propagate into z.array() elements, so we also override the plugins array
402
+ // with strict entries to catch typos inside individual plugin entries too.
403
+ const strictMarketplaceSchema = PluginMarketplaceSchema()
404
+ .extend({
405
+ plugins: z.array(PluginMarketplaceEntrySchema().strict()),
406
+ })
407
+ .strict()
408
+ const result = strictMarketplaceSchema.safeParse(parsed)
409
+
410
+ if (!result.success) {
411
+ errors.push(...formatZodErrors(result.error))
412
+ }
413
+
414
+ // Check for common issues and add warnings
415
+ if (result.success) {
416
+ const marketplace = result.data
417
+
418
+ // Warn if no plugins
419
+ if (!marketplace.plugins || marketplace.plugins.length === 0) {
420
+ warnings.push({
421
+ path: 'plugins',
422
+ message: 'Marketplace has no plugins defined',
423
+ })
424
+ }
425
+
426
+ // Check each plugin entry
427
+ if (marketplace.plugins) {
428
+ marketplace.plugins.forEach((plugin, i) => {
429
+ // Check for duplicate plugin names
430
+ const duplicates = marketplace.plugins.filter(
431
+ p => p.name === plugin.name,
432
+ )
433
+ if (duplicates.length > 1) {
434
+ errors.push({
435
+ path: `plugins[${i}].name`,
436
+ message: `Duplicate plugin name "${plugin.name}" found in marketplace`,
437
+ })
438
+ }
439
+ })
440
+
441
+ // Version-mismatch check: for local-source entries that declare a
442
+ // version, compare against the plugin's own plugin.json. At install
443
+ // time, calculatePluginVersion (pluginVersioning.ts) prefers the
444
+ // manifest version and silently ignores the entry version — so a
445
+ // stale entry.version is invisible user confusion (marketplace UI
446
+ // shows one version, /status shows another after install).
447
+ // Only local sources: remote sources would need cloning to check.
448
+ const manifestDir = path.dirname(absolutePath)
449
+ const marketplaceRoot =
450
+ path.basename(manifestDir) === '.claude-plugin'
451
+ ? path.dirname(manifestDir)
452
+ : manifestDir
453
+ for (const [i, entry] of marketplace.plugins.entries()) {
454
+ if (
455
+ !entry.version ||
456
+ typeof entry.source !== 'string' ||
457
+ !entry.source.startsWith('./')
458
+ ) {
459
+ continue
460
+ }
461
+ const pluginJsonPath = path.join(
462
+ marketplaceRoot,
463
+ entry.source,
464
+ '.claude-plugin',
465
+ 'plugin.json',
466
+ )
467
+ let manifestVersion: string | undefined
468
+ try {
469
+ const raw = await readFile(pluginJsonPath, { encoding: 'utf-8' })
470
+ const parsed = jsonParse(raw) as { version?: unknown }
471
+ if (typeof parsed.version === 'string') {
472
+ manifestVersion = parsed.version
473
+ }
474
+ } catch {
475
+ // Missing/unreadable plugin.json is someone else's error to report
476
+ continue
477
+ }
478
+ if (manifestVersion && manifestVersion !== entry.version) {
479
+ warnings.push({
480
+ path: `plugins[${i}].version`,
481
+ message:
482
+ `Entry declares version "${entry.version}" but ${entry.source}/.claude-plugin/plugin.json says "${manifestVersion}". ` +
483
+ `At install time, plugin.json wins (calculatePluginVersion precedence) — the entry version is silently ignored. ` +
484
+ `Update this entry to "${manifestVersion}" to match.`,
485
+ })
486
+ }
487
+ }
488
+ }
489
+
490
+ // Warn if no description in metadata
491
+ if (!marketplace.metadata?.description) {
492
+ warnings.push({
493
+ path: 'metadata.description',
494
+ message:
495
+ 'No marketplace description provided. Adding a description helps users understand what this marketplace offers',
496
+ })
497
+ }
498
+ }
499
+
500
+ return {
501
+ success: errors.length === 0,
502
+ errors,
503
+ warnings,
504
+ filePath: absolutePath,
505
+ fileType: 'marketplace',
506
+ }
507
+ }
508
+ /**
509
+ * Validate the YAML frontmatter in a plugin component markdown file.
510
+ *
511
+ * The runtime loader (parseFrontmatter) silently drops unparseable YAML to a
512
+ * debug log and returns an empty object. That's the right resilience choice
513
+ * for the load path, but authors running `claude plugin validate` want a hard
514
+ * signal. This re-parses the frontmatter block and surfaces what the loader
515
+ * would silently swallow.
516
+ */
517
+ function validateComponentFile(
518
+ filePath: string,
519
+ content: string,
520
+ fileType: 'skill' | 'agent' | 'command',
521
+ ): ValidationResult {
522
+ const errors: ValidationError[] = []
523
+ const warnings: ValidationWarning[] = []
524
+
525
+ const match = content.match(FRONTMATTER_REGEX)
526
+ if (!match) {
527
+ warnings.push({
528
+ path: 'frontmatter',
529
+ message:
530
+ 'No frontmatter block found. Add YAML frontmatter between --- delimiters ' +
531
+ 'at the top of the file to set description and other metadata.',
532
+ })
533
+ return { success: true, errors, warnings, filePath, fileType }
534
+ }
535
+
536
+ const frontmatterText = match[1] || ''
537
+ let parsed: unknown
538
+ try {
539
+ parsed = parseYaml(frontmatterText)
540
+ } catch (e) {
541
+ errors.push({
542
+ path: 'frontmatter',
543
+ message:
544
+ `YAML frontmatter failed to parse: ${errorMessage(e)}. ` +
545
+ `At runtime this ${fileType} loads with empty metadata (all frontmatter ` +
546
+ `fields silently dropped).`,
547
+ })
548
+ return { success: false, errors, warnings, filePath, fileType }
549
+ }
550
+
551
+ if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {
552
+ errors.push({
553
+ path: 'frontmatter',
554
+ message:
555
+ 'Frontmatter must be a YAML mapping (key: value pairs), got ' +
556
+ `${Array.isArray(parsed) ? 'an array' : parsed === null ? 'null' : typeof parsed}.`,
557
+ })
558
+ return { success: false, errors, warnings, filePath, fileType }
559
+ }
560
+
561
+ const fm = parsed as Record<string, unknown>
562
+
563
+ // description: must be scalar. coerceDescriptionToString logs+drops arrays/objects at runtime.
564
+ if (fm.description !== undefined) {
565
+ const d = fm.description
566
+ if (
567
+ typeof d !== 'string' &&
568
+ typeof d !== 'number' &&
569
+ typeof d !== 'boolean' &&
570
+ d !== null
571
+ ) {
572
+ errors.push({
573
+ path: 'description',
574
+ message:
575
+ `description must be a string, got ${Array.isArray(d) ? 'array' : typeof d}. ` +
576
+ `At runtime this value is dropped.`,
577
+ })
578
+ }
579
+ } else {
580
+ warnings.push({
581
+ path: 'description',
582
+ message:
583
+ `No description in frontmatter. A description helps users and Claude ` +
584
+ `understand when to use this ${fileType}.`,
585
+ })
586
+ }
587
+
588
+ // name: if present, must be a string (skills/commands use it as displayName;
589
+ // plugin agents use it as the agentType stem — non-strings would stringify to garbage)
590
+ if (
591
+ fm.name !== undefined &&
592
+ fm.name !== null &&
593
+ typeof fm.name !== 'string'
594
+ ) {
595
+ errors.push({
596
+ path: 'name',
597
+ message: `name must be a string, got ${typeof fm.name}.`,
598
+ })
599
+ }
600
+
601
+ // allowed-tools: string or array of strings
602
+ const at = fm['allowed-tools']
603
+ if (at !== undefined && at !== null) {
604
+ if (typeof at !== 'string' && !Array.isArray(at)) {
605
+ errors.push({
606
+ path: 'allowed-tools',
607
+ message: `allowed-tools must be a string or array of strings, got ${typeof at}.`,
608
+ })
609
+ } else if (Array.isArray(at) && at.some(t => typeof t !== 'string')) {
610
+ errors.push({
611
+ path: 'allowed-tools',
612
+ message: 'allowed-tools array must contain only strings.',
613
+ })
614
+ }
615
+ }
616
+
617
+ // shell: 'bash' | 'powershell' (controls !`cmd` block routing)
618
+ const sh = fm.shell
619
+ if (sh !== undefined && sh !== null) {
620
+ if (typeof sh !== 'string') {
621
+ errors.push({
622
+ path: 'shell',
623
+ message: `shell must be a string, got ${typeof sh}.`,
624
+ })
625
+ } else {
626
+ // Normalize to match parseShellFrontmatter() runtime behavior —
627
+ // `shell: PowerShell` should not fail validation but work at runtime.
628
+ const normalized = sh.trim().toLowerCase()
629
+ if (normalized !== 'bash' && normalized !== 'powershell') {
630
+ errors.push({
631
+ path: 'shell',
632
+ message: `shell must be 'bash' or 'powershell', got '${sh}'.`,
633
+ })
634
+ }
635
+ }
636
+ }
637
+
638
+ return { success: errors.length === 0, errors, warnings, filePath, fileType }
639
+ }
640
+
641
+ /**
642
+ * Validate a plugin's hooks.json file. Unlike frontmatter, this one HARD-ERRORS
643
+ * at runtime (pluginLoader uses .parse() not .safeParse()) — a bad hooks.json
644
+ * breaks the whole plugin. Surfacing it here is essential.
645
+ */
646
+ async function validateHooksJson(filePath: string): Promise<ValidationResult> {
647
+ let content: string
648
+ try {
649
+ content = await readFile(filePath, { encoding: 'utf-8' })
650
+ } catch (e: unknown) {
651
+ const code = getErrnoCode(e)
652
+ // ENOENT is fine — hooks are optional
653
+ if (code === 'ENOENT') {
654
+ return {
655
+ success: true,
656
+ errors: [],
657
+ warnings: [],
658
+ filePath,
659
+ fileType: 'hooks',
660
+ }
661
+ }
662
+ return {
663
+ success: false,
664
+ errors: [
665
+ { path: 'file', message: `Failed to read file: ${errorMessage(e)}` },
666
+ ],
667
+ warnings: [],
668
+ filePath,
669
+ fileType: 'hooks',
670
+ }
671
+ }
672
+
673
+ let parsed: unknown
674
+ try {
675
+ parsed = jsonParse(content)
676
+ } catch (e) {
677
+ return {
678
+ success: false,
679
+ errors: [
680
+ {
681
+ path: 'json',
682
+ message:
683
+ `Invalid JSON syntax: ${errorMessage(e)}. ` +
684
+ `At runtime this breaks the entire plugin load.`,
685
+ },
686
+ ],
687
+ warnings: [],
688
+ filePath,
689
+ fileType: 'hooks',
690
+ }
691
+ }
692
+
693
+ const result = PluginHooksSchema().safeParse(parsed)
694
+ if (!result.success) {
695
+ return {
696
+ success: false,
697
+ errors: formatZodErrors(result.error),
698
+ warnings: [],
699
+ filePath,
700
+ fileType: 'hooks',
701
+ }
702
+ }
703
+
704
+ return {
705
+ success: true,
706
+ errors: [],
707
+ warnings: [],
708
+ filePath,
709
+ fileType: 'hooks',
710
+ }
711
+ }
712
+
713
+ /**
714
+ * Recursively collect .md files under a directory. Uses withFileTypes to
715
+ * avoid a stat per entry. Returns absolute paths so error messages stay
716
+ * readable.
717
+ */
718
+ async function collectMarkdown(
719
+ dir: string,
720
+ isSkillsDir: boolean,
721
+ ): Promise<string[]> {
722
+ let entries: Dirent[]
723
+ try {
724
+ entries = await readdir(dir, { withFileTypes: true })
725
+ } catch (e: unknown) {
726
+ const code = getErrnoCode(e)
727
+ if (code === 'ENOENT' || code === 'ENOTDIR') return []
728
+ throw e
729
+ }
730
+
731
+ // Skills use <name>/SKILL.md — only descend one level, only collect SKILL.md.
732
+ // Matches the runtime loader: single .md files in skills/ are NOT loaded,
733
+ // and subdirectories of a skill dir aren't scanned. Paths are speculative
734
+ // (the subdir may lack SKILL.md); the caller handles ENOENT.
735
+ if (isSkillsDir) {
736
+ return entries
737
+ .filter(e => e.isDirectory())
738
+ .map(e => path.join(dir, e.name, 'SKILL.md'))
739
+ }
740
+
741
+ // Commands/agents: recurse and collect all .md files.
742
+ const out: string[] = []
743
+ for (const entry of entries) {
744
+ const full = path.join(dir, entry.name)
745
+ if (entry.isDirectory()) {
746
+ out.push(...(await collectMarkdown(full, false)))
747
+ } else if (entry.isFile() && entry.name.toLowerCase().endsWith('.md')) {
748
+ out.push(full)
749
+ }
750
+ }
751
+ return out
752
+ }
753
+
754
+ /**
755
+ * Validate the content files inside a plugin directory — skills, agents,
756
+ * commands, and hooks.json. Scans the default component directories (the
757
+ * manifest can declare custom paths but the default layout covers the vast
758
+ * majority of plugins; this is a linter, not a loader).
759
+ *
760
+ * Returns one ValidationResult per file that has errors or warnings. A clean
761
+ * plugin returns an empty array.
762
+ */
763
+ export async function validatePluginContents(
764
+ pluginDir: string,
765
+ ): Promise<ValidationResult[]> {
766
+ const results: ValidationResult[] = []
767
+
768
+ const dirs: Array<['skill' | 'agent' | 'command', string]> = [
769
+ ['skill', path.join(pluginDir, 'skills')],
770
+ ['agent', path.join(pluginDir, 'agents')],
771
+ ['command', path.join(pluginDir, 'commands')],
772
+ ]
773
+
774
+ for (const [fileType, dir] of dirs) {
775
+ const files = await collectMarkdown(dir, fileType === 'skill')
776
+ for (const filePath of files) {
777
+ let content: string
778
+ try {
779
+ content = await readFile(filePath, { encoding: 'utf-8' })
780
+ } catch (e: unknown) {
781
+ // ENOENT is expected for speculative skill paths (subdirs without SKILL.md)
782
+ if (isENOENT(e)) continue
783
+ results.push({
784
+ success: false,
785
+ errors: [
786
+ { path: 'file', message: `Failed to read: ${errorMessage(e)}` },
787
+ ],
788
+ warnings: [],
789
+ filePath,
790
+ fileType,
791
+ })
792
+ continue
793
+ }
794
+ const r = validateComponentFile(filePath, content, fileType)
795
+ if (r.errors.length > 0 || r.warnings.length > 0) {
796
+ results.push(r)
797
+ }
798
+ }
799
+ }
800
+
801
+ const hooksResult = await validateHooksJson(
802
+ path.join(pluginDir, 'hooks', 'hooks.json'),
803
+ )
804
+ if (hooksResult.errors.length > 0 || hooksResult.warnings.length > 0) {
805
+ results.push(hooksResult)
806
+ }
807
+
808
+ return results
809
+ }
810
+
811
+ /**
812
+ * Validate a manifest file or directory (auto-detects type)
813
+ */
814
+ export async function validateManifest(
815
+ filePath: string,
816
+ ): Promise<ValidationResult> {
817
+ const absolutePath = path.resolve(filePath)
818
+
819
+ // Stat path to check if it's a directory — handle ENOENT inline
820
+ let stats: Stats | null = null
821
+ try {
822
+ stats = await stat(absolutePath)
823
+ } catch (e: unknown) {
824
+ if (!isENOENT(e)) {
825
+ throw e
826
+ }
827
+ }
828
+
829
+ if (stats?.isDirectory()) {
830
+ // Look for manifest files in .claude-plugin directory
831
+ // Prefer marketplace.json over plugin.json
832
+ const marketplacePath = path.join(
833
+ absolutePath,
834
+ '.claude-plugin',
835
+ 'marketplace.json',
836
+ )
837
+ const marketplaceResult = await validateMarketplaceManifest(marketplacePath)
838
+ // Only fall through if the marketplace file was not found (ENOENT)
839
+ if (marketplaceResult.errors[0]?.code !== 'ENOENT') {
840
+ return marketplaceResult
841
+ }
842
+
843
+ const pluginPath = path.join(absolutePath, '.claude-plugin', 'plugin.json')
844
+ const pluginResult = await validatePluginManifest(pluginPath)
845
+ if (pluginResult.errors[0]?.code !== 'ENOENT') {
846
+ return pluginResult
847
+ }
848
+
849
+ return {
850
+ success: false,
851
+ errors: [
852
+ {
853
+ path: 'directory',
854
+ message: `No manifest found in directory. Expected .claude-plugin/marketplace.json or .claude-plugin/plugin.json`,
855
+ },
856
+ ],
857
+ warnings: [],
858
+ filePath: absolutePath,
859
+ fileType: 'plugin',
860
+ }
861
+ }
862
+
863
+ const manifestType = detectManifestType(filePath)
864
+
865
+ switch (manifestType) {
866
+ case 'plugin':
867
+ return validatePluginManifest(filePath)
868
+ case 'marketplace':
869
+ return validateMarketplaceManifest(filePath)
870
+ case 'unknown': {
871
+ // Try to parse and guess based on content
872
+ try {
873
+ const content = await readFile(absolutePath, { encoding: 'utf-8' })
874
+ const parsed = jsonParse(content) as Record<string, unknown>
875
+
876
+ // Heuristic: if it has a "plugins" array, it's probably a marketplace
877
+ if (Array.isArray(parsed.plugins)) {
878
+ return validateMarketplaceManifest(filePath)
879
+ }
880
+ } catch (e: unknown) {
881
+ const code = getErrnoCode(e)
882
+ if (code === 'ENOENT') {
883
+ return {
884
+ success: false,
885
+ errors: [
886
+ {
887
+ path: 'file',
888
+ message: `File not found: ${absolutePath}`,
889
+ },
890
+ ],
891
+ warnings: [],
892
+ filePath: absolutePath,
893
+ fileType: 'plugin', // Default to plugin for error reporting
894
+ }
895
+ }
896
+ // Fall through to default validation for other errors (e.g., JSON parse)
897
+ }
898
+
899
+ // Default: validate as plugin manifest
900
+ return validatePluginManifest(filePath)
901
+ }
902
+ }
903
+ }