ummaya 0.2.4 → 0.2.6

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 (482) hide show
  1. package/README.md +15 -2
  2. package/bin/ummaya +10 -1
  3. package/bun.lock +180 -244
  4. package/npm-shrinkwrap.json +760 -1760
  5. package/package.json +39 -22
  6. package/prompts/manifest.yaml +1 -1
  7. package/prompts/system_v1.md +1 -0
  8. package/pyproject.toml +27 -2
  9. package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
  10. package/src/ummaya/_canonical/__init__.py +2 -0
  11. package/src/ummaya/_canonical/baselines.yaml +113 -0
  12. package/src/ummaya/engine/engine.py +29 -132
  13. package/src/ummaya/evidence/__init__.py +21 -2
  14. package/src/ummaya/evidence/dataset_contract.py +193 -0
  15. package/src/ummaya/evidence/document_authoring_cases.py +33 -0
  16. package/src/ummaya/evidence/document_harness.py +313 -0
  17. package/src/ummaya/evidence/document_viewer_ux.py +391 -0
  18. package/src/ummaya/evidence/gates.py +70 -0
  19. package/src/ummaya/evidence/json_types.py +20 -0
  20. package/src/ummaya/evidence/models.py +88 -1
  21. package/src/ummaya/evidence/output_payload.py +89 -0
  22. package/src/ummaya/evidence/payload_documents.py +233 -0
  23. package/src/ummaya/evidence/route_contracts.py +224 -0
  24. package/src/ummaya/evidence/route_helpers.py +150 -0
  25. package/src/ummaya/evidence/runner.py +81 -212
  26. package/src/ummaya/evidence/source_provenance.py +246 -0
  27. package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
  28. package/src/ummaya/evidence/tool_layer.py +39 -0
  29. package/src/ummaya/evidence/tool_layer_models.py +151 -0
  30. package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
  31. package/src/ummaya/ipc/document_intent_normalization.py +185 -0
  32. package/src/ummaya/ipc/frame_schema.py +5 -5
  33. package/src/ummaya/ipc/route_diagnostics.py +73 -0
  34. package/src/ummaya/ipc/stdio.py +1109 -477
  35. package/src/ummaya/llm/client.py +102 -3
  36. package/src/ummaya/llm/config.py +8 -3
  37. package/src/ummaya/primitives/__init__.py +6 -2
  38. package/src/ummaya/primitives/delegation.py +1 -1
  39. package/src/ummaya/primitives/document.py +28 -0
  40. package/src/ummaya/settings.py +0 -3
  41. package/src/ummaya/tools/discovery_bridge.py +17 -1
  42. package/src/ummaya/tools/documents/__init__.py +297 -0
  43. package/src/ummaya/tools/documents/adapter_registry.py +487 -0
  44. package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
  45. package/src/ummaya/tools/documents/artifact_store.py +454 -0
  46. package/src/ummaya/tools/documents/authoring.py +283 -0
  47. package/src/ummaya/tools/documents/baselines.py +132 -0
  48. package/src/ummaya/tools/documents/capability.py +331 -0
  49. package/src/ummaya/tools/documents/contracts.py +112 -0
  50. package/src/ummaya/tools/documents/conversion.py +521 -0
  51. package/src/ummaya/tools/documents/diff.py +275 -0
  52. package/src/ummaya/tools/documents/engines.py +163 -0
  53. package/src/ummaya/tools/documents/evaluation.py +291 -0
  54. package/src/ummaya/tools/documents/explicit_values.py +108 -0
  55. package/src/ummaya/tools/documents/fixtures.py +174 -0
  56. package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
  57. package/src/ummaya/tools/documents/formats/__init__.py +2 -0
  58. package/src/ummaya/tools/documents/formats/archive.py +528 -0
  59. package/src/ummaya/tools/documents/formats/base.py +41 -0
  60. package/src/ummaya/tools/documents/formats/code_file.py +211 -0
  61. package/src/ummaya/tools/documents/formats/data_file.py +272 -0
  62. package/src/ummaya/tools/documents/formats/hwp.py +284 -0
  63. package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
  64. package/src/ummaya/tools/documents/formats/odf.py +435 -0
  65. package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
  66. package/src/ummaya/tools/documents/formats/passive.py +766 -0
  67. package/src/ummaya/tools/documents/formats/pdf.py +702 -0
  68. package/src/ummaya/tools/documents/formats/text_web.py +268 -0
  69. package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
  70. package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
  71. package/src/ummaya/tools/documents/inspection.py +289 -0
  72. package/src/ummaya/tools/documents/intake.py +1079 -0
  73. package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
  74. package/src/ummaya/tools/documents/models.py +1598 -0
  75. package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
  76. package/src/ummaya/tools/documents/orchestrator.py +96 -0
  77. package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
  78. package/src/ummaya/tools/documents/patch.py +170 -0
  79. package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
  80. package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
  81. package/src/ummaya/tools/documents/permissions.py +110 -0
  82. package/src/ummaya/tools/documents/planner.py +616 -0
  83. package/src/ummaya/tools/documents/registry.py +2733 -0
  84. package/src/ummaya/tools/documents/render.py +978 -0
  85. package/src/ummaya/tools/documents/render_comparison.py +113 -0
  86. package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
  87. package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
  88. package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
  89. package/src/ummaya/tools/documents/reread.py +157 -0
  90. package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
  91. package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
  92. package/src/ummaya/tools/documents/scorecard.py +184 -0
  93. package/src/ummaya/tools/documents/socratic_planner.py +193 -0
  94. package/src/ummaya/tools/documents/style.py +48 -0
  95. package/src/ummaya/tools/documents/tool_defs.py +523 -0
  96. package/src/ummaya/tools/documents/validate.py +347 -0
  97. package/src/ummaya/tools/executor.py +29 -0
  98. package/src/ummaya/tools/live_proxy.py +0 -3
  99. package/src/ummaya/tools/models.py +5 -1
  100. package/src/ummaya/tools/register_all.py +8 -0
  101. package/src/ummaya/tools/registry.py +10 -1
  102. package/src/ummaya/tools/routing/__init__.py +59 -0
  103. package/src/ummaya/tools/routing/builder.py +105 -0
  104. package/src/ummaya/tools/routing/cards.py +29 -0
  105. package/src/ummaya/tools/routing/decision_service.py +534 -0
  106. package/src/ummaya/tools/routing/decision_types.py +74 -0
  107. package/src/ummaya/tools/routing/feasibility.py +122 -0
  108. package/src/ummaya/tools/routing/intent.py +17 -0
  109. package/src/ummaya/tools/routing/intent_extractor.py +207 -0
  110. package/src/ummaya/tools/routing/intent_patterns.py +160 -0
  111. package/src/ummaya/tools/routing/intent_public_data.py +150 -0
  112. package/src/ummaya/tools/routing/intent_types.py +48 -0
  113. package/src/ummaya/tools/routing/lint.py +78 -0
  114. package/src/ummaya/tools/routing/metadata.py +174 -0
  115. package/src/ummaya/tools/routing/projection.py +340 -0
  116. package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
  117. package/src/ummaya/tools/routing/schema.py +81 -0
  118. package/src/ummaya/tools/routing/types.py +96 -0
  119. package/src/ummaya/tools/routing_index.py +2 -2
  120. package/src/ummaya/tools/search.py +34 -746
  121. package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
  122. package/tui/bun.lock +126 -305
  123. package/tui/package.json +35 -22
  124. package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
  125. package/tui/src/QueryEngine.ts +12 -8
  126. package/tui/src/bridge/inboundAttachments.ts +3 -3
  127. package/tui/src/cli/handlers/auth.ts +3 -12
  128. package/tui/src/cli/handlers/mcp.tsx +0 -1
  129. package/tui/src/cli/print.ts +8 -9
  130. package/tui/src/commands/insights.ts +1 -1
  131. package/tui/src/commands/install-github-app/types.ts +8 -30
  132. package/tui/src/commands/plugin/types.ts +6 -28
  133. package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
  134. package/tui/src/commands/rename/generateSessionName.ts +1 -1
  135. package/tui/src/components/Feedback.tsx +1 -1
  136. package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
  137. package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
  138. package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
  139. package/tui/src/components/Spinner/types.ts +6 -28
  140. package/tui/src/components/agents/generateAgent.ts +1 -1
  141. package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
  142. package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
  143. package/tui/src/components/mcp/types.ts +16 -38
  144. package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
  145. package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
  146. package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
  147. package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
  148. package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
  149. package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
  150. package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
  151. package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
  152. package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
  153. package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
  154. package/tui/src/components/primitive/index.tsx +43 -1
  155. package/tui/src/components/primitive/types.ts +137 -0
  156. package/tui/src/components/ui/option.ts +4 -26
  157. package/tui/src/constants/common.ts +0 -2
  158. package/tui/src/constants/prompts.ts +4 -3
  159. package/tui/src/constants/querySource.ts +4 -26
  160. package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
  161. package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
  162. package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
  163. package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
  164. package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
  165. package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
  166. package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
  167. package/tui/src/hooks/useApiKeyVerification.ts +1 -1
  168. package/tui/src/hooks/useVirtualScroll.ts +1 -1
  169. package/tui/src/ink/ink.tsx +33 -14
  170. package/tui/src/ink/reconciler.ts +2 -3
  171. package/tui/src/ink/render-to-screen.ts +30 -10
  172. package/tui/src/ipc/bridge.ts +62 -15
  173. package/tui/src/ipc/bridgeSingleton.ts +5 -1
  174. package/tui/src/ipc/codec.ts +3 -3
  175. package/tui/src/ipc/frames.generated.ts +12 -12
  176. package/tui/src/ipc/llmClient.ts +151 -27
  177. package/tui/src/ipc/schema/frame.schema.json +1 -1
  178. package/tui/src/keybindings/defaultBindings.ts +4 -0
  179. package/tui/src/main.tsx +32 -15
  180. package/tui/src/native-ts/file-index/index.ts +33 -3
  181. package/tui/src/observability/surface.ts +2 -2
  182. package/tui/src/probes/toolRegistryProbe.tsx +3 -1
  183. package/tui/src/projectOnboardingState.ts +7 -6
  184. package/tui/src/query/chatMessageTypes.ts +18 -0
  185. package/tui/src/query/chatMessagesBuilder.ts +1 -1
  186. package/tui/src/query/deps.ts +1 -1
  187. package/tui/src/query/messageGuards.ts +106 -0
  188. package/tui/src/query/publicDataTerminalRepair.ts +384 -0
  189. package/tui/src/query/run.ts +1075 -0
  190. package/tui/src/query/supportBoundary.ts +168 -0
  191. package/tui/src/query/toolResultErrors.ts +103 -0
  192. package/tui/src/query/toolRunner.ts +687 -0
  193. package/tui/src/query/unavailableToolRepair.ts +118 -0
  194. package/tui/src/query.ts +9 -2186
  195. package/tui/src/screens/REPL.tsx +40 -29
  196. package/tui/src/services/api/adapterManifest.ts +4 -0
  197. package/tui/src/services/api/backendChat/events.ts +117 -0
  198. package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
  199. package/tui/src/services/api/backendChat/frame.ts +9 -0
  200. package/tui/src/services/api/backendChat/streaming.ts +430 -0
  201. package/tui/src/services/api/backendChat/types.ts +62 -0
  202. package/tui/src/services/api/backendChat.ts +1 -0
  203. package/tui/src/services/api/client.ts +65 -2
  204. package/tui/src/services/api/errorUtils.ts +5 -5
  205. package/tui/src/services/api/errors.ts +1 -1
  206. package/tui/src/services/api/logging.ts +1 -1
  207. package/tui/src/services/api/ummaya/evidence.ts +194 -0
  208. package/tui/src/services/api/ummaya/messages.ts +255 -0
  209. package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
  210. package/tui/src/services/api/ummaya/provider.ts +200 -0
  211. package/tui/src/services/api/ummaya/reasoning.ts +24 -0
  212. package/tui/src/services/api/ummaya/request.ts +200 -0
  213. package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
  214. package/tui/src/services/api/ummaya/streaming.ts +365 -0
  215. package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
  216. package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
  217. package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
  218. package/tui/src/services/api/ummaya/types.ts +110 -0
  219. package/tui/src/services/api/ummaya/usage.ts +30 -0
  220. package/tui/src/services/api/ummaya.ts +26 -418
  221. package/tui/src/services/api/withRetry.ts +1 -1
  222. package/tui/src/services/awaySummary.ts +2 -2
  223. package/tui/src/services/claudeAiLimits.ts +1 -1
  224. package/tui/src/services/compact/autoCompact.ts +1 -1
  225. package/tui/src/services/compact/compact.ts +1 -1
  226. package/tui/src/services/lsp/types.ts +8 -30
  227. package/tui/src/services/tips/types.ts +6 -28
  228. package/tui/src/services/tokenEstimation.ts +1 -1
  229. package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
  230. package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
  231. package/tui/src/services/tools/toolExecution.ts +94 -1
  232. package/tui/src/store/pendingPermissionSlot.ts +1 -1
  233. package/tui/src/store/session-store.ts +10 -36
  234. package/tui/src/stubs/any-stub.ts +15 -10
  235. package/tui/src/stubs/color-diff-napi.ts +37 -23
  236. package/tui/src/stubs/globals.d.ts +3 -3
  237. package/tui/src/stubs/macro-preload.ts +23 -12
  238. package/tui/src/tools/AdapterTool/AdapterTool.ts +1207 -714
  239. package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
  240. package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
  241. package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
  242. package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
  243. package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
  244. package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
  245. package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
  246. package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
  247. package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
  248. package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
  249. package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
  250. package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
  251. package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
  252. package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
  253. package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
  254. package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
  255. package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
  256. package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
  257. package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
  258. package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
  259. package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
  260. package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
  261. package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
  262. package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
  263. package/tui/src/tools/AgentTool/permissions.ts +39 -0
  264. package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
  265. package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
  266. package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
  267. package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
  268. package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
  269. package/tui/src/tools/AgentTool/runAgent.ts +1 -1
  270. package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
  271. package/tui/src/tools/AgentTool/schemas.ts +196 -0
  272. package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
  273. package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
  274. package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
  275. package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
  276. package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
  277. package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
  278. package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
  279. package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
  280. package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
  281. package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
  282. package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
  283. package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
  284. package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
  285. package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
  286. package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
  287. package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
  288. package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
  289. package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
  290. package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
  291. package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
  292. package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
  293. package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
  294. package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
  295. package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
  296. package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
  297. package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
  298. package/tui/src/tools/BashTool/call.ts +202 -0
  299. package/tui/src/tools/BashTool/callLoader.ts +35 -0
  300. package/tui/src/tools/BashTool/commandClassification.ts +151 -0
  301. package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
  302. package/tui/src/tools/BashTool/cwdReset.ts +33 -0
  303. package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
  304. package/tui/src/tools/BashTool/modeValidation.ts +13 -1
  305. package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
  306. package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
  307. package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
  308. package/tui/src/tools/BashTool/resultLoader.ts +29 -0
  309. package/tui/src/tools/BashTool/resultMapping.ts +83 -0
  310. package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
  311. package/tui/src/tools/BashTool/schemas.ts +65 -0
  312. package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
  313. package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
  314. package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
  315. package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
  316. package/tui/src/tools/BashTool/uiLoader.ts +37 -0
  317. package/tui/src/tools/BriefTool/upload.ts +1 -1
  318. package/tui/src/tools/CalculatorTool/parser.ts +2 -2
  319. package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
  320. package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
  321. package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
  322. package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
  323. package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
  324. package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
  325. package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
  326. package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
  327. package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
  328. package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
  329. package/tui/src/tools/FileEditTool/call.ts +228 -0
  330. package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
  331. package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
  332. package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
  333. package/tui/src/tools/FileWriteTool/call.ts +223 -0
  334. package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
  335. package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
  336. package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +25 -32
  337. package/tui/src/tools/LookupPrimitive/prompt.ts +0 -2
  338. package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
  339. package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
  340. package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
  341. package/tui/src/tools/NotebookEditTool/call.ts +254 -0
  342. package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
  343. package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
  344. package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
  345. package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
  346. package/tui/src/tools/PowerShellTool/call.ts +179 -0
  347. package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
  348. package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
  349. package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
  350. package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
  351. package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
  352. package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
  353. package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
  354. package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
  355. package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
  356. package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
  357. package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
  358. package/tui/src/tools/PowerShellTool/validation.ts +39 -0
  359. package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
  360. package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +1 -11
  361. package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
  362. package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
  363. package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +27 -10
  364. package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
  365. package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
  366. package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
  367. package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
  368. package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
  369. package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
  370. package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
  371. package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
  372. package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
  373. package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
  374. package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
  375. package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
  376. package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
  377. package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
  378. package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
  379. package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
  380. package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
  381. package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
  382. package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
  383. package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
  384. package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
  385. package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
  386. package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
  387. package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
  388. package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
  389. package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +2 -1
  390. package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
  391. package/tui/src/tools/WebFetchTool/call.ts +227 -0
  392. package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
  393. package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
  394. package/tui/src/tools/WebFetchTool/types.ts +23 -0
  395. package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
  396. package/tui/src/tools/WebFetchTool/utils.ts +1 -1
  397. package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
  398. package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
  399. package/tui/src/tools/WebSearchTool/call.ts +33 -0
  400. package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
  401. package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
  402. package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
  403. package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
  404. package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
  405. package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
  406. package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
  407. package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
  408. package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
  409. package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
  410. package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
  411. package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
  412. package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
  413. package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
  414. package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
  415. package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
  416. package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
  417. package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
  418. package/tui/src/tools/_shared/rootPrimitiveInput.ts +1 -0
  419. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
  420. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
  421. package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
  422. package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
  423. package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
  424. package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
  425. package/tui/src/tools/_shared/toolChoiceRepair.ts +55 -860
  426. package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
  427. package/tui/src/tools.ts +39 -190
  428. package/tui/src/types/fileSuggestion.ts +4 -26
  429. package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
  430. package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
  431. package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
  432. package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
  433. package/tui/src/types/message.ts +80 -102
  434. package/tui/src/types/messageQueueTypes.ts +6 -28
  435. package/tui/src/types/notebook.ts +16 -38
  436. package/tui/src/types/statusLine.ts +4 -26
  437. package/tui/src/types/tools.ts +24 -46
  438. package/tui/src/types/utils.ts +6 -28
  439. package/tui/src/upstreamproxy/relay.ts +7 -3
  440. package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
  441. package/tui/src/utils/assistantMessageFactories.ts +9 -3
  442. package/tui/src/utils/auth.ts +129 -139
  443. package/tui/src/utils/bash/ast.ts +23 -23
  444. package/tui/src/utils/bash/bashParser.ts +5 -5
  445. package/tui/src/utils/billing.ts +1 -1
  446. package/tui/src/utils/claudeDesktop.ts +4 -4
  447. package/tui/src/utils/collapseReadSearch.ts +3 -3
  448. package/tui/src/utils/cronTasks.ts +1 -1
  449. package/tui/src/utils/execFileNoThrow.ts +1 -1
  450. package/tui/src/utils/filePersistence/types.ts +16 -38
  451. package/tui/src/utils/forkedAgent.ts +1 -1
  452. package/tui/src/utils/gracefulShutdown.ts +4 -4
  453. package/tui/src/utils/heapDumpService.ts +12 -8
  454. package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
  455. package/tui/src/utils/hooks/execPromptHook.ts +1 -1
  456. package/tui/src/utils/hooks/skillImprovement.ts +1 -1
  457. package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
  458. package/tui/src/utils/messages.ts +18 -0
  459. package/tui/src/utils/migrateSessions.ts +3 -3
  460. package/tui/src/utils/model/model.ts +6 -6
  461. package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
  462. package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
  463. package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
  464. package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
  465. package/tui/src/utils/plugins/pluginLoader.ts +8 -8
  466. package/tui/src/utils/protectedNamespace.ts +5 -3
  467. package/tui/src/utils/rawJsonToolCall.ts +242 -0
  468. package/tui/src/utils/ripgrep.ts +16 -7
  469. package/tui/src/utils/sessionTitle.ts +1 -1
  470. package/tui/src/utils/settings/permissionValidation.ts +14 -2
  471. package/tui/src/utils/shell/prefix.ts +1 -1
  472. package/tui/src/utils/sideQuery.ts +1 -1
  473. package/tui/src/utils/systemThemeWatcher.ts +13 -3
  474. package/tui/src/utils/teleport.tsx +1 -1
  475. package/uv.lock +426 -45
  476. package/tui/src/services/api/claude.ts +0 -3540
  477. package/tui/src/tools/_shared/directPublicDataGuard.ts +0 -362
  478. package/tui/src/tools/_shared/kmaAnalysisGuard.ts +0 -197
  479. package/tui/src/tools/_shared/kmaAviationGuard.ts +0 -70
  480. package/tui/src/tools/_shared/nmcAedGuard.ts +0 -234
  481. package/tui/src/tools/_shared/protectedCheckGuard.ts +0 -207
  482. package/tui/src/tools/_shared/textToolCallGuard.ts +0 -91
@@ -0,0 +1,162 @@
1
+ import type { PermissionResult } from '../../utils/permissions/PermissionResult.js'
2
+ import type { ParsedPowerShellCommand } from '../../utils/powershell/parser.js'
3
+ import { getPipelineSegments } from '../../utils/powershell/parser.js'
4
+ import {
5
+ argLeaksValue,
6
+ isAllowlistedPipelineTail,
7
+ isCwdChangingCmdlet,
8
+ isSafeOutputCommand,
9
+ resolveToCanonical,
10
+ } from './readOnlyValidation.js'
11
+ import { isSymlinkCreatingCommand } from './symlinkModeValidation.js'
12
+
13
+ const ACCEPT_EDITS_ALLOWED_CMDLETS = new Set([
14
+ 'set-content',
15
+ 'add-content',
16
+ 'remove-item',
17
+ 'clear-content',
18
+ ])
19
+
20
+ export function isAcceptEditsAllowedCmdlet(name: string): boolean {
21
+ return ACCEPT_EDITS_ALLOWED_CMDLETS.has(resolveToCanonical(name))
22
+ }
23
+
24
+ function checkCompoundGuards(
25
+ segments: ReturnType<typeof getPipelineSegments>,
26
+ ): PermissionResult | null {
27
+ const totalCommands = segments.reduce(
28
+ (sum, segment) => sum + segment.commands.length,
29
+ 0,
30
+ )
31
+ if (totalCommands <= 1) return null
32
+
33
+ let hasCdCommand = false
34
+ let hasSymlinkCreate = false
35
+ let hasWriteCommand = false
36
+ for (const segment of segments) {
37
+ for (const cmd of segment.commands) {
38
+ if (cmd.elementType !== 'CommandAst') continue
39
+ if (isCwdChangingCmdlet(cmd.name)) hasCdCommand = true
40
+ if (isSymlinkCreatingCommand(cmd)) hasSymlinkCreate = true
41
+ if (isAcceptEditsAllowedCmdlet(cmd.name)) hasWriteCommand = true
42
+ }
43
+ }
44
+
45
+ if (hasCdCommand && hasWriteCommand) {
46
+ return {
47
+ behavior: 'passthrough',
48
+ message:
49
+ 'Compound command contains a directory-changing command with a write operation; path validation would use a stale cwd',
50
+ }
51
+ }
52
+ if (hasSymlinkCreate) {
53
+ return {
54
+ behavior: 'passthrough',
55
+ message:
56
+ 'Compound command creates a filesystem link; path validation cannot follow just-created links',
57
+ }
58
+ }
59
+ return null
60
+ }
61
+
62
+ function checkCommandAst(
63
+ cmd: ReturnType<typeof getPipelineSegments>[number]['commands'][number],
64
+ command: string,
65
+ nested: boolean,
66
+ ): PermissionResult | null {
67
+ if (cmd.elementType !== 'CommandAst') {
68
+ return {
69
+ behavior: 'passthrough',
70
+ message: `${nested ? 'Nested expression' : 'Pipeline source'} element (${cmd.elementType}) cannot be statically validated`,
71
+ }
72
+ }
73
+ if (cmd.nameType === 'application') {
74
+ return {
75
+ behavior: 'passthrough',
76
+ message: `${nested ? 'Nested command' : 'Command'} '${cmd.name}' resolved from a path-like name and requires approval`,
77
+ }
78
+ }
79
+ if (isSafeOutputCommand(cmd.name) || isAllowlistedPipelineTail(cmd, command)) {
80
+ return null
81
+ }
82
+ if (!isAcceptEditsAllowedCmdlet(cmd.name)) {
83
+ return {
84
+ behavior: 'passthrough',
85
+ message: `No mode-specific handling for '${cmd.name}' in acceptEdits mode`,
86
+ }
87
+ }
88
+ if (argLeaksValue(cmd.name, cmd)) {
89
+ return {
90
+ behavior: 'passthrough',
91
+ message: `Arguments in '${cmd.name}' cannot be statically validated in acceptEdits mode`,
92
+ }
93
+ }
94
+ return null
95
+ }
96
+
97
+ function checkCommandArguments(
98
+ cmd: ReturnType<typeof getPipelineSegments>[number]['commands'][number],
99
+ ): PermissionResult | null {
100
+ if (cmd.elementType !== 'CommandAst' || !cmd.elementTypes) return null
101
+
102
+ for (let index = 1; index < cmd.elementTypes.length; index++) {
103
+ const elementType = cmd.elementTypes[index]
104
+ if (elementType !== 'StringConstant' && elementType !== 'Parameter') {
105
+ return {
106
+ behavior: 'passthrough',
107
+ message: `Command argument has unvalidatable type (${elementType})`,
108
+ }
109
+ }
110
+ if (elementType !== 'Parameter') continue
111
+
112
+ const arg = cmd.args[index - 1] ?? ''
113
+ const colonIdx = arg.indexOf(':')
114
+ if (colonIdx > 0 && /[$(@{[]/.test(arg.slice(colonIdx + 1))) {
115
+ return {
116
+ behavior: 'passthrough',
117
+ message:
118
+ 'Colon-bound parameter contains an expression that cannot be statically validated',
119
+ }
120
+ }
121
+ }
122
+ return null
123
+ }
124
+
125
+ export function checkAcceptEditsCommands(
126
+ input: { command: string },
127
+ parsed: ParsedPowerShellCommand,
128
+ ): PermissionResult {
129
+ const segments = getPipelineSegments(parsed)
130
+ if (segments.length === 0) {
131
+ return {
132
+ behavior: 'passthrough',
133
+ message: 'No commands found to validate for acceptEdits mode',
134
+ }
135
+ }
136
+
137
+ const compoundResult = checkCompoundGuards(segments)
138
+ if (compoundResult !== null) return compoundResult
139
+
140
+ for (const segment of segments) {
141
+ for (const cmd of segment.commands) {
142
+ const argumentResult = checkCommandArguments(cmd)
143
+ if (argumentResult !== null) return argumentResult
144
+ const commandResult = checkCommandAst(cmd, input.command, false)
145
+ if (commandResult !== null) return commandResult
146
+ }
147
+
148
+ for (const cmd of segment.nestedCommands ?? []) {
149
+ const commandResult = checkCommandAst(cmd, input.command, true)
150
+ if (commandResult !== null) return commandResult
151
+ }
152
+ }
153
+
154
+ return {
155
+ behavior: 'allow',
156
+ updatedInput: input,
157
+ decisionReason: {
158
+ type: 'mode',
159
+ mode: 'acceptEdits',
160
+ },
161
+ }
162
+ }
@@ -0,0 +1,179 @@
1
+ import type { CanUseToolFn } from 'src/hooks/useCanUseTool.js';
2
+ import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from '../../services/analytics/index.js';
3
+ import type { ToolCallProgress, ToolUseContext } from '../../Tool.js';
4
+ import type { AssistantMessage } from '../../types/message.js';
5
+ import type { PowerShellProgress } from '../../types/tools.js';
6
+ import { extractClaudeCodeHints } from '../../utils/claudeCodeHints.js';
7
+ import { ShellError } from '../../utils/errors.js';
8
+ import { maybeRecordPluginHint } from '../../utils/plugins/hintRecommendation.js';
9
+ import type { ExecResult } from '../../utils/ShellCommand.js';
10
+ import { EndTruncatingAccumulator } from '../../utils/stringUtils.js';
11
+ import { trackGitOperations } from '../shared/gitOperationTracking.js';
12
+ import { resetShellCwdIfOutsideProject } from '../BashTool/cwdReset.js';
13
+ import { isImageOutput, resizeShellImageOutput, stdErrAppendShellResetMessage, stripEmptyLines } from '../BashTool/shellOutputUtils.js';
14
+ import { getCommandTypeForLogging } from './commandClassification.js';
15
+ import { interpretCommandResult } from './commandSemantics.js';
16
+ import { persistLargePowerShellOutput } from './outputPersistence.js';
17
+ import { runPowerShellCommand } from './shellExecution.js';
18
+ import { isWindowsSandboxPolicyViolation, WINDOWS_SANDBOX_POLICY_REFUSAL } from './validation.js';
19
+ import type { Out, PowerShellToolInput } from './schemas.js';
20
+
21
+ const EOL = '\n';
22
+
23
+ export async function callPowerShellTool(
24
+ input: PowerShellToolInput,
25
+ toolUseContext: ToolUseContext,
26
+ _canUseTool?: CanUseToolFn,
27
+ _parentMessage?: AssistantMessage,
28
+ onProgress?: ToolCallProgress<PowerShellProgress>
29
+ ): Promise<{ readonly data: Out }> {
30
+ if (isWindowsSandboxPolicyViolation()) {
31
+ throw new Error(WINDOWS_SANDBOX_POLICY_REFUSAL);
32
+ }
33
+ const { abortController, setToolJSX } = toolUseContext;
34
+ const isMainThread = !toolUseContext.agentId;
35
+ try {
36
+ const result = await consumePowerShellCommand({ input, toolUseContext, isMainThread, onProgress });
37
+ const isPreFlightSentinel = result.code === 0 && !result.stdout && result.stderr && !result.backgroundTaskId;
38
+ if (!isPreFlightSentinel) {
39
+ trackGitOperations(input.command, result.code, result.stdout);
40
+ }
41
+ const isInterrupt = result.interrupted && abortController.signal.reason === 'interrupt';
42
+ const stderrForShellReset = getShellResetStderr(toolUseContext, isMainThread);
43
+ if (result.backgroundTaskId) {
44
+ return buildBackgroundResult(input.command, result, stderrForShellReset, isMainThread);
45
+ }
46
+ const stdout = prepareCompletedStdout(result, input.command, isMainThread);
47
+ const interpretation = interpretCommandResult(input.command, result.code, stdout, result.stderr || '');
48
+ if (result.preSpawnError) {
49
+ throw new Error(result.preSpawnError);
50
+ }
51
+ if (interpretation.isError && !isInterrupt) {
52
+ throw new ShellError(stdout, result.stderr || '', result.code, result.interrupted);
53
+ }
54
+ const persisted = await persistLargePowerShellOutput(result);
55
+ const imageResult = await normalizeImageOutput(stdout, result.outputFilePath, persisted.size);
56
+ const finalStderr = [result.stderr || '', stderrForShellReset].filter(Boolean).join('\n');
57
+ logEvent('tengu_powershell_tool_command_executed', {
58
+ command_type: getCommandTypeForLogging(input.command),
59
+ stdout_length: imageResult.stdout.length,
60
+ stderr_length: finalStderr.length,
61
+ exit_code: result.code,
62
+ interrupted: result.interrupted
63
+ });
64
+ return {
65
+ data: {
66
+ stdout: imageResult.stdout,
67
+ stderr: finalStderr,
68
+ interrupted: result.interrupted,
69
+ returnCodeInterpretation: interpretation.message,
70
+ isImage: imageResult.isImage,
71
+ persistedOutputPath: persisted.path,
72
+ persistedOutputSize: persisted.size
73
+ }
74
+ };
75
+ } finally {
76
+ if (setToolJSX) setToolJSX(null);
77
+ }
78
+ }
79
+
80
+ type ConsumeInput = {
81
+ readonly input: PowerShellToolInput;
82
+ readonly toolUseContext: ToolUseContext;
83
+ readonly isMainThread: boolean;
84
+ readonly onProgress?: ToolCallProgress<PowerShellProgress>;
85
+ };
86
+
87
+ async function consumePowerShellCommand({
88
+ input,
89
+ toolUseContext,
90
+ isMainThread,
91
+ onProgress
92
+ }: ConsumeInput): Promise<ExecResult> {
93
+ const commandGenerator = runPowerShellCommand({
94
+ input,
95
+ abortController: toolUseContext.abortController,
96
+ setAppState: toolUseContext.setAppStateForTasks ?? toolUseContext.setAppState,
97
+ setToolJSX: toolUseContext.setToolJSX,
98
+ preventCwdChanges: !isMainThread,
99
+ isMainThread,
100
+ toolUseId: toolUseContext.toolUseId,
101
+ agentId: toolUseContext.agentId
102
+ });
103
+ let progressCounter = 0;
104
+ let generatorResult;
105
+ do {
106
+ generatorResult = await commandGenerator.next();
107
+ if (!generatorResult.done && onProgress) {
108
+ const progress = generatorResult.value;
109
+ onProgress({
110
+ toolUseID: `ps-progress-${progressCounter++}`,
111
+ data: {
112
+ type: 'powershell_progress',
113
+ output: progress.output,
114
+ fullOutput: progress.fullOutput,
115
+ elapsedTimeSeconds: progress.elapsedTimeSeconds,
116
+ totalLines: progress.totalLines,
117
+ totalBytes: progress.totalBytes,
118
+ timeoutMs: progress.timeoutMs,
119
+ taskId: progress.taskId
120
+ }
121
+ });
122
+ }
123
+ } while (!generatorResult.done);
124
+ return generatorResult.value;
125
+ }
126
+
127
+ function getShellResetStderr(toolUseContext: ToolUseContext, isMainThread: boolean): string {
128
+ if (!isMainThread) {
129
+ return '';
130
+ }
131
+ const appState = toolUseContext.getAppState();
132
+ return resetShellCwdIfOutsideProject(appState.toolPermissionContext) ? stdErrAppendShellResetMessage('') : '';
133
+ }
134
+
135
+ function buildBackgroundResult(command: string, result: ExecResult, stderrForShellReset: string, isMainThread: boolean): { readonly data: Out } {
136
+ const extracted = extractClaudeCodeHints(result.stdout || '', command);
137
+ if (isMainThread && extracted.hints.length > 0) {
138
+ for (const hint of extracted.hints) maybeRecordPluginHint(hint);
139
+ }
140
+ return {
141
+ data: {
142
+ stdout: extracted.stripped,
143
+ stderr: [result.stderr || '', stderrForShellReset].filter(Boolean).join('\n'),
144
+ interrupted: false,
145
+ backgroundTaskId: result.backgroundTaskId,
146
+ backgroundedByUser: result.backgroundedByUser,
147
+ assistantAutoBackgrounded: result.assistantAutoBackgrounded
148
+ }
149
+ };
150
+ }
151
+
152
+ function prepareCompletedStdout(result: ExecResult, command: string, isMainThread: boolean): string {
153
+ const stdoutAccumulator = new EndTruncatingAccumulator();
154
+ const processedStdout = (result.stdout || '').trimEnd();
155
+ stdoutAccumulator.append(processedStdout + EOL);
156
+ let stdout = stripEmptyLines(stdoutAccumulator.toString());
157
+ const extracted = extractClaudeCodeHints(stdout, command);
158
+ stdout = extracted.stripped;
159
+ if (isMainThread && extracted.hints.length > 0) {
160
+ for (const hint of extracted.hints) maybeRecordPluginHint(hint);
161
+ }
162
+ return stdout;
163
+ }
164
+
165
+ type ImageOutput = {
166
+ readonly stdout: string;
167
+ readonly isImage: boolean;
168
+ };
169
+
170
+ async function normalizeImageOutput(stdout: string, outputFilePath?: string, persistedOutputSize?: number): Promise<ImageOutput> {
171
+ if (!isImageOutput(stdout)) {
172
+ return { stdout, isImage: false };
173
+ }
174
+ const resized = await resizeShellImageOutput(stdout, outputFilePath, persistedOutputSize);
175
+ if (resized) {
176
+ return { stdout: resized, isImage: true };
177
+ }
178
+ return { stdout, isImage: false };
179
+ }
@@ -0,0 +1,37 @@
1
+ import { createRequire } from 'node:module'
2
+ import type { CanUseToolFn } from 'src/hooks/useCanUseTool.js'
3
+ import type { ToolCallProgress, ToolUseContext } from '../../Tool.js'
4
+ import type { AssistantMessage } from '../../types/message.js'
5
+ import type { PowerShellProgress } from '../../types/tools.js'
6
+ import type { Out, PowerShellToolInput } from './schemas.js'
7
+
8
+ type PowerShellCallRuntime = {
9
+ readonly callPowerShellTool: (
10
+ input: PowerShellToolInput,
11
+ toolUseContext: ToolUseContext,
12
+ canUseTool?: CanUseToolFn,
13
+ parentMessage?: AssistantMessage,
14
+ onProgress?: ToolCallProgress<PowerShellProgress>,
15
+ ) => Promise<{ readonly data: Out }>
16
+ }
17
+
18
+ const requireModule = createRequire(import.meta.url)
19
+ let cachedRuntime: PowerShellCallRuntime | undefined
20
+
21
+ function isPowerShellCallRuntime(
22
+ value: unknown,
23
+ ): value is PowerShellCallRuntime {
24
+ if (typeof value !== 'object' || value === null) return false
25
+ const module = value as Partial<Record<keyof PowerShellCallRuntime, unknown>>
26
+ return typeof module.callPowerShellTool === 'function'
27
+ }
28
+
29
+ export function loadPowerShellCallRuntime(): PowerShellCallRuntime {
30
+ if (cachedRuntime !== undefined) return cachedRuntime
31
+ const loaded: unknown = requireModule('./call.js')
32
+ if (!isPowerShellCallRuntime(loaded)) {
33
+ throw new Error('PowerShell call module did not expose expected lifecycle')
34
+ }
35
+ cachedRuntime = loaded
36
+ return loaded
37
+ }
@@ -0,0 +1,86 @@
1
+ import type { AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from '../../services/analytics/index.js';
2
+ import { resolveToCanonical } from './readOnlyValidation.js';
3
+
4
+ const PS_SEARCH_COMMANDS = new Set(['select-string', 'get-childitem', 'findstr', 'where.exe']);
5
+ const PS_READ_COMMANDS = new Set(['get-content', 'get-item', 'test-path', 'resolve-path', 'get-process', 'get-service', 'get-childitem', 'get-location', 'get-filehash', 'get-acl', 'format-hex']);
6
+ const PS_SEMANTIC_NEUTRAL_COMMANDS = new Set(['write-output', 'write-host']);
7
+ const DISALLOWED_AUTO_BACKGROUND_COMMANDS = ['start-sleep', 'sleep'];
8
+ const COMMON_BACKGROUND_COMMANDS = ['npm', 'yarn', 'pnpm', 'node', 'python', 'python3', 'go', 'cargo', 'make', 'docker', 'terraform', 'webpack', 'vite', 'jest', 'pytest', 'curl', 'Invoke-WebRequest', 'build', 'test', 'serve', 'watch', 'dev'] as const;
9
+
10
+ type SearchReadClassification = {
11
+ readonly isSearch: boolean;
12
+ readonly isRead: boolean;
13
+ };
14
+
15
+ const NOT_SEARCH_OR_READ: SearchReadClassification = {
16
+ isSearch: false,
17
+ isRead: false
18
+ };
19
+
20
+ export function isSearchOrReadPowerShellCommand(command: string): SearchReadClassification {
21
+ const trimmed = command.trim();
22
+ if (!trimmed) {
23
+ return NOT_SEARCH_OR_READ;
24
+ }
25
+ const parts = trimmed.split(/\s*[;|]\s*/).filter(Boolean);
26
+ if (parts.length === 0) {
27
+ return NOT_SEARCH_OR_READ;
28
+ }
29
+ let hasSearch = false;
30
+ let hasRead = false;
31
+ let hasNonNeutralCommand = false;
32
+ for (const part of parts) {
33
+ const baseCommand = part.trim().split(/\s+/)[0];
34
+ if (!baseCommand) {
35
+ continue;
36
+ }
37
+ const canonical = resolveToCanonical(baseCommand);
38
+ if (PS_SEMANTIC_NEUTRAL_COMMANDS.has(canonical)) {
39
+ continue;
40
+ }
41
+ hasNonNeutralCommand = true;
42
+ const isPartSearch = PS_SEARCH_COMMANDS.has(canonical);
43
+ const isPartRead = PS_READ_COMMANDS.has(canonical);
44
+ if (!isPartSearch && !isPartRead) {
45
+ return NOT_SEARCH_OR_READ;
46
+ }
47
+ if (isPartSearch) hasSearch = true;
48
+ if (isPartRead) hasRead = true;
49
+ }
50
+ if (!hasNonNeutralCommand) {
51
+ return NOT_SEARCH_OR_READ;
52
+ }
53
+ return {
54
+ isSearch: hasSearch,
55
+ isRead: hasRead
56
+ };
57
+ }
58
+
59
+ export function isAutobackgroundingAllowed(command: string): boolean {
60
+ const firstWord = command.trim().split(/\s+/)[0];
61
+ if (!firstWord) return true;
62
+ const canonical = resolveToCanonical(firstWord);
63
+ return !DISALLOWED_AUTO_BACKGROUND_COMMANDS.includes(canonical);
64
+ }
65
+
66
+ export function detectBlockedSleepPattern(command: string): string | null {
67
+ const first = command.trim().split(/[;|&\r\n]/)[0]?.trim() ?? '';
68
+ const match = /^(?:start-sleep|sleep)(?:\s+-s(?:econds)?)?\s+(\d+)\s*$/i.exec(first);
69
+ const secondsText = match?.[1];
70
+ if (!secondsText) return null;
71
+ const seconds = parseInt(secondsText, 10);
72
+ if (seconds < 2) return null;
73
+ const rest = command.trim().slice(first.length).replace(/^[\s;|&]+/, '');
74
+ return rest ? `Start-Sleep ${seconds} followed by: ${rest}` : `standalone Start-Sleep ${seconds}`;
75
+ }
76
+
77
+ export function getCommandTypeForLogging(command: string): AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS {
78
+ const trimmed = command.trim();
79
+ const firstWord = trimmed.split(/\s+/)[0] || '';
80
+ for (const cmd of COMMON_BACKGROUND_COMMANDS) {
81
+ if (firstWord.toLowerCase() === cmd.toLowerCase()) {
82
+ return cmd as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS;
83
+ }
84
+ }
85
+ return 'other' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS;
86
+ }