ummaya 0.2.4 → 0.2.5

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 (477) hide show
  1. package/README.md +15 -2
  2. package/bin/ummaya +10 -1
  3. package/npm-shrinkwrap.json +253 -2
  4. package/package.json +5 -1
  5. package/prompts/manifest.yaml +1 -1
  6. package/prompts/system_v1.md +1 -0
  7. package/pyproject.toml +26 -2
  8. package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
  9. package/src/ummaya/_canonical/__init__.py +2 -0
  10. package/src/ummaya/engine/engine.py +29 -132
  11. package/src/ummaya/evidence/__init__.py +21 -2
  12. package/src/ummaya/evidence/dataset_contract.py +193 -0
  13. package/src/ummaya/evidence/document_authoring_cases.py +33 -0
  14. package/src/ummaya/evidence/document_harness.py +313 -0
  15. package/src/ummaya/evidence/document_viewer_ux.py +391 -0
  16. package/src/ummaya/evidence/gates.py +70 -0
  17. package/src/ummaya/evidence/json_types.py +20 -0
  18. package/src/ummaya/evidence/models.py +88 -1
  19. package/src/ummaya/evidence/output_payload.py +89 -0
  20. package/src/ummaya/evidence/payload_documents.py +233 -0
  21. package/src/ummaya/evidence/route_contracts.py +224 -0
  22. package/src/ummaya/evidence/route_helpers.py +150 -0
  23. package/src/ummaya/evidence/runner.py +81 -212
  24. package/src/ummaya/evidence/source_provenance.py +246 -0
  25. package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
  26. package/src/ummaya/evidence/tool_layer.py +39 -0
  27. package/src/ummaya/evidence/tool_layer_models.py +151 -0
  28. package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
  29. package/src/ummaya/ipc/document_intent_normalization.py +185 -0
  30. package/src/ummaya/ipc/frame_schema.py +5 -5
  31. package/src/ummaya/ipc/route_diagnostics.py +73 -0
  32. package/src/ummaya/ipc/stdio.py +1109 -477
  33. package/src/ummaya/llm/client.py +102 -3
  34. package/src/ummaya/llm/config.py +8 -3
  35. package/src/ummaya/primitives/__init__.py +6 -2
  36. package/src/ummaya/primitives/delegation.py +1 -1
  37. package/src/ummaya/primitives/document.py +28 -0
  38. package/src/ummaya/settings.py +0 -3
  39. package/src/ummaya/tools/discovery_bridge.py +17 -1
  40. package/src/ummaya/tools/documents/__init__.py +297 -0
  41. package/src/ummaya/tools/documents/adapter_registry.py +487 -0
  42. package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
  43. package/src/ummaya/tools/documents/artifact_store.py +454 -0
  44. package/src/ummaya/tools/documents/authoring.py +283 -0
  45. package/src/ummaya/tools/documents/baselines.py +114 -0
  46. package/src/ummaya/tools/documents/capability.py +331 -0
  47. package/src/ummaya/tools/documents/contracts.py +112 -0
  48. package/src/ummaya/tools/documents/conversion.py +521 -0
  49. package/src/ummaya/tools/documents/diff.py +275 -0
  50. package/src/ummaya/tools/documents/engines.py +163 -0
  51. package/src/ummaya/tools/documents/evaluation.py +291 -0
  52. package/src/ummaya/tools/documents/explicit_values.py +108 -0
  53. package/src/ummaya/tools/documents/fixtures.py +174 -0
  54. package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
  55. package/src/ummaya/tools/documents/formats/__init__.py +2 -0
  56. package/src/ummaya/tools/documents/formats/archive.py +528 -0
  57. package/src/ummaya/tools/documents/formats/base.py +41 -0
  58. package/src/ummaya/tools/documents/formats/code_file.py +211 -0
  59. package/src/ummaya/tools/documents/formats/data_file.py +272 -0
  60. package/src/ummaya/tools/documents/formats/hwp.py +284 -0
  61. package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
  62. package/src/ummaya/tools/documents/formats/odf.py +435 -0
  63. package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
  64. package/src/ummaya/tools/documents/formats/passive.py +766 -0
  65. package/src/ummaya/tools/documents/formats/pdf.py +702 -0
  66. package/src/ummaya/tools/documents/formats/text_web.py +268 -0
  67. package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
  68. package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
  69. package/src/ummaya/tools/documents/inspection.py +289 -0
  70. package/src/ummaya/tools/documents/intake.py +1079 -0
  71. package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
  72. package/src/ummaya/tools/documents/models.py +1598 -0
  73. package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
  74. package/src/ummaya/tools/documents/orchestrator.py +96 -0
  75. package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
  76. package/src/ummaya/tools/documents/patch.py +170 -0
  77. package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
  78. package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
  79. package/src/ummaya/tools/documents/permissions.py +110 -0
  80. package/src/ummaya/tools/documents/planner.py +616 -0
  81. package/src/ummaya/tools/documents/registry.py +2733 -0
  82. package/src/ummaya/tools/documents/render.py +978 -0
  83. package/src/ummaya/tools/documents/render_comparison.py +113 -0
  84. package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
  85. package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
  86. package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
  87. package/src/ummaya/tools/documents/reread.py +157 -0
  88. package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
  89. package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
  90. package/src/ummaya/tools/documents/scorecard.py +184 -0
  91. package/src/ummaya/tools/documents/socratic_planner.py +193 -0
  92. package/src/ummaya/tools/documents/style.py +48 -0
  93. package/src/ummaya/tools/documents/tool_defs.py +523 -0
  94. package/src/ummaya/tools/documents/validate.py +347 -0
  95. package/src/ummaya/tools/executor.py +29 -0
  96. package/src/ummaya/tools/live_proxy.py +0 -3
  97. package/src/ummaya/tools/models.py +5 -1
  98. package/src/ummaya/tools/register_all.py +8 -0
  99. package/src/ummaya/tools/registry.py +10 -1
  100. package/src/ummaya/tools/routing/__init__.py +59 -0
  101. package/src/ummaya/tools/routing/builder.py +105 -0
  102. package/src/ummaya/tools/routing/cards.py +29 -0
  103. package/src/ummaya/tools/routing/decision_service.py +534 -0
  104. package/src/ummaya/tools/routing/decision_types.py +74 -0
  105. package/src/ummaya/tools/routing/feasibility.py +122 -0
  106. package/src/ummaya/tools/routing/intent.py +17 -0
  107. package/src/ummaya/tools/routing/intent_extractor.py +207 -0
  108. package/src/ummaya/tools/routing/intent_patterns.py +160 -0
  109. package/src/ummaya/tools/routing/intent_public_data.py +150 -0
  110. package/src/ummaya/tools/routing/intent_types.py +48 -0
  111. package/src/ummaya/tools/routing/lint.py +78 -0
  112. package/src/ummaya/tools/routing/metadata.py +174 -0
  113. package/src/ummaya/tools/routing/projection.py +340 -0
  114. package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
  115. package/src/ummaya/tools/routing/schema.py +81 -0
  116. package/src/ummaya/tools/routing/types.py +96 -0
  117. package/src/ummaya/tools/routing_index.py +2 -2
  118. package/src/ummaya/tools/search.py +34 -746
  119. package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
  120. package/tui/package.json +1 -1
  121. package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
  122. package/tui/src/QueryEngine.ts +12 -8
  123. package/tui/src/bridge/inboundAttachments.ts +3 -3
  124. package/tui/src/cli/handlers/auth.ts +3 -12
  125. package/tui/src/cli/print.ts +7 -7
  126. package/tui/src/commands/insights.ts +1 -1
  127. package/tui/src/commands/install-github-app/types.ts +8 -30
  128. package/tui/src/commands/plugin/types.ts +6 -28
  129. package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
  130. package/tui/src/commands/rename/generateSessionName.ts +1 -1
  131. package/tui/src/components/Feedback.tsx +1 -1
  132. package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
  133. package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
  134. package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
  135. package/tui/src/components/Spinner/types.ts +6 -28
  136. package/tui/src/components/agents/generateAgent.ts +1 -1
  137. package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
  138. package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
  139. package/tui/src/components/mcp/types.ts +16 -38
  140. package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
  141. package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
  142. package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
  143. package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
  144. package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
  145. package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
  146. package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
  147. package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
  148. package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
  149. package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
  150. package/tui/src/components/primitive/index.tsx +43 -1
  151. package/tui/src/components/primitive/types.ts +137 -0
  152. package/tui/src/components/ui/option.ts +4 -26
  153. package/tui/src/constants/common.ts +0 -2
  154. package/tui/src/constants/prompts.ts +4 -3
  155. package/tui/src/constants/querySource.ts +4 -26
  156. package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
  157. package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
  158. package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
  159. package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
  160. package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
  161. package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
  162. package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
  163. package/tui/src/hooks/useApiKeyVerification.ts +1 -1
  164. package/tui/src/hooks/useVirtualScroll.ts +1 -1
  165. package/tui/src/ink/ink.tsx +33 -14
  166. package/tui/src/ink/reconciler.ts +2 -3
  167. package/tui/src/ink/render-to-screen.ts +30 -10
  168. package/tui/src/ipc/bridge.ts +62 -15
  169. package/tui/src/ipc/bridgeSingleton.ts +5 -1
  170. package/tui/src/ipc/codec.ts +3 -3
  171. package/tui/src/ipc/frames.generated.ts +12 -12
  172. package/tui/src/ipc/llmClient.ts +151 -27
  173. package/tui/src/ipc/schema/frame.schema.json +1 -1
  174. package/tui/src/keybindings/defaultBindings.ts +4 -0
  175. package/tui/src/main.tsx +29 -11
  176. package/tui/src/native-ts/file-index/index.ts +33 -3
  177. package/tui/src/observability/surface.ts +2 -2
  178. package/tui/src/probes/toolRegistryProbe.tsx +3 -1
  179. package/tui/src/projectOnboardingState.ts +7 -6
  180. package/tui/src/query/chatMessageTypes.ts +18 -0
  181. package/tui/src/query/chatMessagesBuilder.ts +1 -1
  182. package/tui/src/query/deps.ts +1 -1
  183. package/tui/src/query/messageGuards.ts +106 -0
  184. package/tui/src/query/publicDataTerminalRepair.ts +384 -0
  185. package/tui/src/query/run.ts +1075 -0
  186. package/tui/src/query/supportBoundary.ts +168 -0
  187. package/tui/src/query/toolResultErrors.ts +103 -0
  188. package/tui/src/query/toolRunner.ts +687 -0
  189. package/tui/src/query/unavailableToolRepair.ts +118 -0
  190. package/tui/src/query.ts +9 -2186
  191. package/tui/src/screens/REPL.tsx +40 -29
  192. package/tui/src/services/api/adapterManifest.ts +4 -0
  193. package/tui/src/services/api/backendChat/events.ts +117 -0
  194. package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
  195. package/tui/src/services/api/backendChat/frame.ts +9 -0
  196. package/tui/src/services/api/backendChat/streaming.ts +430 -0
  197. package/tui/src/services/api/backendChat/types.ts +62 -0
  198. package/tui/src/services/api/backendChat.ts +1 -0
  199. package/tui/src/services/api/client.ts +65 -2
  200. package/tui/src/services/api/errorUtils.ts +5 -5
  201. package/tui/src/services/api/errors.ts +1 -1
  202. package/tui/src/services/api/logging.ts +1 -1
  203. package/tui/src/services/api/ummaya/evidence.ts +194 -0
  204. package/tui/src/services/api/ummaya/messages.ts +255 -0
  205. package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
  206. package/tui/src/services/api/ummaya/provider.ts +200 -0
  207. package/tui/src/services/api/ummaya/reasoning.ts +24 -0
  208. package/tui/src/services/api/ummaya/request.ts +200 -0
  209. package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
  210. package/tui/src/services/api/ummaya/streaming.ts +365 -0
  211. package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
  212. package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
  213. package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
  214. package/tui/src/services/api/ummaya/types.ts +110 -0
  215. package/tui/src/services/api/ummaya/usage.ts +30 -0
  216. package/tui/src/services/api/ummaya.ts +26 -418
  217. package/tui/src/services/api/withRetry.ts +1 -1
  218. package/tui/src/services/awaySummary.ts +2 -2
  219. package/tui/src/services/claudeAiLimits.ts +1 -1
  220. package/tui/src/services/compact/autoCompact.ts +1 -1
  221. package/tui/src/services/compact/compact.ts +1 -1
  222. package/tui/src/services/lsp/types.ts +8 -30
  223. package/tui/src/services/tips/types.ts +6 -28
  224. package/tui/src/services/tokenEstimation.ts +1 -1
  225. package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
  226. package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
  227. package/tui/src/services/tools/toolExecution.ts +94 -1
  228. package/tui/src/store/pendingPermissionSlot.ts +1 -1
  229. package/tui/src/store/session-store.ts +10 -36
  230. package/tui/src/stubs/any-stub.ts +15 -10
  231. package/tui/src/stubs/color-diff-napi.ts +37 -23
  232. package/tui/src/stubs/globals.d.ts +3 -3
  233. package/tui/src/stubs/macro-preload.ts +23 -12
  234. package/tui/src/tools/AdapterTool/AdapterTool.ts +1207 -714
  235. package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
  236. package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
  237. package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
  238. package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
  239. package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
  240. package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
  241. package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
  242. package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
  243. package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
  244. package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
  245. package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
  246. package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
  247. package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
  248. package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
  249. package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
  250. package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
  251. package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
  252. package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
  253. package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
  254. package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
  255. package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
  256. package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
  257. package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
  258. package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
  259. package/tui/src/tools/AgentTool/permissions.ts +39 -0
  260. package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
  261. package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
  262. package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
  263. package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
  264. package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
  265. package/tui/src/tools/AgentTool/runAgent.ts +1 -1
  266. package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
  267. package/tui/src/tools/AgentTool/schemas.ts +196 -0
  268. package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
  269. package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
  270. package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
  271. package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
  272. package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
  273. package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
  274. package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
  275. package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
  276. package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
  277. package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
  278. package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
  279. package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
  280. package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
  281. package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
  282. package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
  283. package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
  284. package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
  285. package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
  286. package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
  287. package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
  288. package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
  289. package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
  290. package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
  291. package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
  292. package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
  293. package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
  294. package/tui/src/tools/BashTool/call.ts +202 -0
  295. package/tui/src/tools/BashTool/callLoader.ts +35 -0
  296. package/tui/src/tools/BashTool/commandClassification.ts +151 -0
  297. package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
  298. package/tui/src/tools/BashTool/cwdReset.ts +33 -0
  299. package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
  300. package/tui/src/tools/BashTool/modeValidation.ts +13 -1
  301. package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
  302. package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
  303. package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
  304. package/tui/src/tools/BashTool/resultLoader.ts +29 -0
  305. package/tui/src/tools/BashTool/resultMapping.ts +83 -0
  306. package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
  307. package/tui/src/tools/BashTool/schemas.ts +65 -0
  308. package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
  309. package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
  310. package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
  311. package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
  312. package/tui/src/tools/BashTool/uiLoader.ts +37 -0
  313. package/tui/src/tools/BriefTool/upload.ts +1 -1
  314. package/tui/src/tools/CalculatorTool/parser.ts +2 -2
  315. package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
  316. package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
  317. package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
  318. package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
  319. package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
  320. package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
  321. package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
  322. package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
  323. package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
  324. package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
  325. package/tui/src/tools/FileEditTool/call.ts +228 -0
  326. package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
  327. package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
  328. package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
  329. package/tui/src/tools/FileWriteTool/call.ts +223 -0
  330. package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
  331. package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
  332. package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +25 -32
  333. package/tui/src/tools/LookupPrimitive/prompt.ts +0 -2
  334. package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
  335. package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
  336. package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
  337. package/tui/src/tools/NotebookEditTool/call.ts +254 -0
  338. package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
  339. package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
  340. package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
  341. package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
  342. package/tui/src/tools/PowerShellTool/call.ts +179 -0
  343. package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
  344. package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
  345. package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
  346. package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
  347. package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
  348. package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
  349. package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
  350. package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
  351. package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
  352. package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
  353. package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
  354. package/tui/src/tools/PowerShellTool/validation.ts +39 -0
  355. package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
  356. package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +1 -11
  357. package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
  358. package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
  359. package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +27 -10
  360. package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
  361. package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
  362. package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
  363. package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
  364. package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
  365. package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
  366. package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
  367. package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
  368. package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
  369. package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
  370. package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
  371. package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
  372. package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
  373. package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
  374. package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
  375. package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
  376. package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
  377. package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
  378. package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
  379. package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
  380. package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
  381. package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
  382. package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
  383. package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
  384. package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
  385. package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +2 -1
  386. package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
  387. package/tui/src/tools/WebFetchTool/call.ts +227 -0
  388. package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
  389. package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
  390. package/tui/src/tools/WebFetchTool/types.ts +23 -0
  391. package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
  392. package/tui/src/tools/WebFetchTool/utils.ts +1 -1
  393. package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
  394. package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
  395. package/tui/src/tools/WebSearchTool/call.ts +33 -0
  396. package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
  397. package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
  398. package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
  399. package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
  400. package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
  401. package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
  402. package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
  403. package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
  404. package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
  405. package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
  406. package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
  407. package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
  408. package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
  409. package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
  410. package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
  411. package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
  412. package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
  413. package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
  414. package/tui/src/tools/_shared/rootPrimitiveInput.ts +1 -0
  415. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
  416. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
  417. package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
  418. package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
  419. package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
  420. package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
  421. package/tui/src/tools/_shared/toolChoiceRepair.ts +55 -860
  422. package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
  423. package/tui/src/tools.ts +39 -190
  424. package/tui/src/types/fileSuggestion.ts +4 -26
  425. package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
  426. package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
  427. package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
  428. package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
  429. package/tui/src/types/message.ts +80 -102
  430. package/tui/src/types/messageQueueTypes.ts +6 -28
  431. package/tui/src/types/notebook.ts +16 -38
  432. package/tui/src/types/statusLine.ts +4 -26
  433. package/tui/src/types/tools.ts +24 -46
  434. package/tui/src/types/utils.ts +6 -28
  435. package/tui/src/upstreamproxy/relay.ts +7 -3
  436. package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
  437. package/tui/src/utils/assistantMessageFactories.ts +9 -3
  438. package/tui/src/utils/auth.ts +129 -139
  439. package/tui/src/utils/bash/ast.ts +23 -23
  440. package/tui/src/utils/bash/bashParser.ts +5 -5
  441. package/tui/src/utils/billing.ts +1 -1
  442. package/tui/src/utils/collapseReadSearch.ts +3 -3
  443. package/tui/src/utils/cronTasks.ts +1 -1
  444. package/tui/src/utils/execFileNoThrow.ts +1 -1
  445. package/tui/src/utils/filePersistence/types.ts +16 -38
  446. package/tui/src/utils/forkedAgent.ts +1 -1
  447. package/tui/src/utils/gracefulShutdown.ts +4 -4
  448. package/tui/src/utils/heapDumpService.ts +12 -8
  449. package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
  450. package/tui/src/utils/hooks/execPromptHook.ts +1 -1
  451. package/tui/src/utils/hooks/skillImprovement.ts +1 -1
  452. package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
  453. package/tui/src/utils/messages.ts +18 -0
  454. package/tui/src/utils/migrateSessions.ts +3 -3
  455. package/tui/src/utils/model/model.ts +6 -6
  456. package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
  457. package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
  458. package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
  459. package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
  460. package/tui/src/utils/plugins/pluginLoader.ts +8 -8
  461. package/tui/src/utils/protectedNamespace.ts +5 -3
  462. package/tui/src/utils/rawJsonToolCall.ts +242 -0
  463. package/tui/src/utils/ripgrep.ts +16 -7
  464. package/tui/src/utils/sessionTitle.ts +1 -1
  465. package/tui/src/utils/settings/permissionValidation.ts +14 -2
  466. package/tui/src/utils/shell/prefix.ts +1 -1
  467. package/tui/src/utils/sideQuery.ts +1 -1
  468. package/tui/src/utils/systemThemeWatcher.ts +13 -3
  469. package/tui/src/utils/teleport.tsx +1 -1
  470. package/uv.lock +400 -14
  471. package/tui/src/services/api/claude.ts +0 -3540
  472. package/tui/src/tools/_shared/directPublicDataGuard.ts +0 -362
  473. package/tui/src/tools/_shared/kmaAnalysisGuard.ts +0 -197
  474. package/tui/src/tools/_shared/kmaAviationGuard.ts +0 -70
  475. package/tui/src/tools/_shared/nmcAedGuard.ts +0 -234
  476. package/tui/src/tools/_shared/protectedCheckGuard.ts +0 -207
  477. 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
+ }