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,258 @@
1
+ import { feature } from 'bun:bundle';
2
+ import * as React from 'react';
3
+ import { getKairosActive } from '../../bootstrap/state.js';
4
+ import { logEvent } from '../../services/analytics/index.js';
5
+ import type { SetToolJSXFn } from '../../Tool.js';
6
+ import type { AppState } from '../../state/AppState.js';
7
+ import { backgroundExistingForegroundTask, markTaskNotified, registerForeground, spawnShellTask, unregisterForeground } from '../../tasks/LocalShellTask/LocalShellTask.js';
8
+ import type { AgentId } from '../../types/ids.js';
9
+ import { errorMessage as getErrorMessage } from '../../utils/errors.js';
10
+ import { logError } from '../../utils/log.js';
11
+ import { getPlatform } from '../../utils/platform.js';
12
+ import { exec } from '../../utils/Shell.js';
13
+ import type { ExecResult } from '../../utils/ShellCommand.js';
14
+ import { getCachedPowerShellPath } from '../../utils/shell/powershellDetection.js';
15
+ import { TaskOutput } from '../../utils/task/TaskOutput.js';
16
+ import { shouldUseSandboxForShell } from '../BashTool/sandboxPolicy.js';
17
+ import { loadBashUI } from '../BashTool/uiLoader.js';
18
+ import { isAutobackgroundingAllowed, getCommandTypeForLogging } from './commandClassification.js';
19
+ import { getDefaultTimeoutMs, getMaxTimeoutMs } from './prompt.js';
20
+ import { isBackgroundTasksDisabled, type PowerShellToolInput } from './schemas.js';
21
+
22
+ const PROGRESS_THRESHOLD_MS = 2000;
23
+ const PROGRESS_INTERVAL_MS = 1000;
24
+ const ASSISTANT_BLOCKING_BUDGET_MS = 15_000;
25
+
26
+ export type PowerShellExecutionProgress = {
27
+ readonly type: 'progress'; readonly output: string; readonly fullOutput: string;
28
+ readonly elapsedTimeSeconds: number; readonly totalLines: number;
29
+ readonly totalBytes: number; readonly taskId?: string; readonly timeoutMs?: number;
30
+ };
31
+
32
+ type RunPowerShellCommandInput = {
33
+ readonly input: PowerShellToolInput; readonly abortController: AbortController;
34
+ readonly setAppState: (f: (prev: AppState) => AppState) => void;
35
+ readonly setToolJSX?: SetToolJSXFn; readonly preventCwdChanges?: boolean;
36
+ readonly isMainThread?: boolean; readonly toolUseId?: string; readonly agentId?: AgentId;
37
+ };
38
+
39
+ export async function* runPowerShellCommand({
40
+ input,
41
+ abortController,
42
+ setAppState,
43
+ setToolJSX,
44
+ preventCwdChanges,
45
+ isMainThread,
46
+ toolUseId,
47
+ agentId
48
+ }: RunPowerShellCommandInput): AsyncGenerator<PowerShellExecutionProgress, ExecResult, void> {
49
+ const { command, description, timeout, run_in_background, dangerouslyDisableSandbox } = input;
50
+ const timeoutMs = Math.min(timeout || getDefaultTimeoutMs(), getMaxTimeoutMs());
51
+ let fullOutput = '';
52
+ let lastProgressOutput = '';
53
+ let lastTotalLines = 0;
54
+ let lastTotalBytes = 0;
55
+ const updateProgress = (lastLines: string, allLines: string, totalLines: number, totalBytes: number, isIncomplete: boolean): void => {
56
+ lastProgressOutput = lastLines;
57
+ fullOutput = allLines;
58
+ lastTotalLines = totalLines;
59
+ lastTotalBytes = isIncomplete ? totalBytes : 0;
60
+ };
61
+ const powershellPath = await getCachedPowerShellPath();
62
+ if (!powershellPath) {
63
+ return {
64
+ stdout: '',
65
+ stderr: 'PowerShell is not available on this system.',
66
+ code: 0,
67
+ interrupted: false
68
+ };
69
+ }
70
+ const shellCommand = await createShellCommand({ command, abortController, timeoutMs, preventCwdChanges, dangerouslyDisableSandbox, onProgress: updateProgress });
71
+ if (shellCommand.kind === 'preflight') {
72
+ return shellCommand.result;
73
+ }
74
+ const execution = shellCommand.value;
75
+ const resultPromise = execution.result;
76
+ let backgroundShellId: string | undefined = undefined;
77
+ let interruptBackgroundingStarted = false;
78
+ let assistantAutoBackgrounded = false;
79
+ let resolveProgress: (() => void) | null = null;
80
+ function createProgressSignal(): Promise<null> {
81
+ return new Promise<null>(resolve => {
82
+ resolveProgress = () => resolve(null);
83
+ });
84
+ }
85
+ async function spawnBackgroundTask(): Promise<string> {
86
+ const handle = await spawnShellTask({
87
+ command,
88
+ description: description || command,
89
+ shellCommand: execution,
90
+ toolUseId,
91
+ agentId
92
+ }, {
93
+ abortController,
94
+ getAppState: () => {
95
+ throw new Error('getAppState not available in runPowerShellCommand context');
96
+ },
97
+ setAppState
98
+ });
99
+ return handle.taskId;
100
+ }
101
+ function startBackgrounding(eventName: string, backgroundFn?: (shellId: string) => void): void {
102
+ if (foregroundTaskId) {
103
+ if (!backgroundExistingForegroundTask(foregroundTaskId, execution, description || command, setAppState, toolUseId)) {
104
+ return;
105
+ }
106
+ backgroundShellId = foregroundTaskId;
107
+ logEvent(eventName, { command_type: getCommandTypeForLogging(command) });
108
+ backgroundFn?.(foregroundTaskId);
109
+ return;
110
+ }
111
+ void spawnBackgroundTask().then(shellId => {
112
+ backgroundShellId = shellId;
113
+ const resolve = resolveProgress;
114
+ if (resolve) {
115
+ resolveProgress = null;
116
+ resolve();
117
+ }
118
+ logEvent(eventName, { command_type: getCommandTypeForLogging(command) });
119
+ backgroundFn?.(shellId);
120
+ });
121
+ }
122
+ const shouldAutoBackground = !isBackgroundTasksDisabled && isAutobackgroundingAllowed(command);
123
+ if (execution.onTimeout && shouldAutoBackground) {
124
+ execution.onTimeout(backgroundFn => startBackgrounding('tengu_powershell_command_timeout_backgrounded', backgroundFn));
125
+ }
126
+ if (feature('KAIROS') && getKairosActive() && isMainThread && !isBackgroundTasksDisabled && run_in_background !== true) {
127
+ setTimeout(() => {
128
+ if (execution.status === 'running' && backgroundShellId === undefined) {
129
+ assistantAutoBackgrounded = true;
130
+ startBackgrounding('tengu_powershell_command_assistant_auto_backgrounded');
131
+ }
132
+ }, ASSISTANT_BLOCKING_BUDGET_MS).unref();
133
+ }
134
+ if (run_in_background === true && !isBackgroundTasksDisabled) {
135
+ const shellId = await spawnBackgroundTask();
136
+ logEvent('tengu_powershell_command_explicitly_backgrounded', { command_type: getCommandTypeForLogging(command) });
137
+ return { stdout: '', stderr: '', code: 0, interrupted: false, backgroundTaskId: shellId };
138
+ }
139
+ TaskOutput.startPolling(execution.taskOutput.taskId);
140
+ const startTime = Date.now();
141
+ let nextProgressTime = startTime + PROGRESS_THRESHOLD_MS;
142
+ let foregroundTaskId: string | undefined = undefined;
143
+ try {
144
+ while (true) {
145
+ const result = await Promise.race([resultPromise, progressDelay(nextProgressTime), createProgressSignal()]);
146
+ if (result !== null) {
147
+ return finishCompletedPowerShellResult(result, execution, setAppState);
148
+ }
149
+ if (backgroundShellId) {
150
+ return { stdout: interruptBackgroundingStarted ? fullOutput : '', stderr: '', code: 0, interrupted: false, backgroundTaskId: backgroundShellId, assistantAutoBackgrounded };
151
+ }
152
+ if (abortController.signal.aborted && abortController.signal.reason === 'interrupt' && !interruptBackgroundingStarted) {
153
+ interruptBackgroundingStarted = true;
154
+ if (!isBackgroundTasksDisabled) {
155
+ startBackgrounding('tengu_powershell_command_interrupt_backgrounded');
156
+ continue;
157
+ }
158
+ execution.kill();
159
+ }
160
+ if (foregroundTaskId && execution.status === 'backgrounded') {
161
+ return { stdout: '', stderr: '', code: 0, interrupted: false, backgroundTaskId: foregroundTaskId, backgroundedByUser: true };
162
+ }
163
+ const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000);
164
+ foregroundTaskId = maybeShowBackgroundHint({ command, description, execution, agentId, setAppState, setToolJSX, toolUseId, foregroundTaskId, backgroundShellId, elapsedSeconds });
165
+ yield { type: 'progress', fullOutput, output: lastProgressOutput, elapsedTimeSeconds: elapsedSeconds, totalLines: lastTotalLines, totalBytes: lastTotalBytes, taskId: execution.taskOutput.taskId, ...(timeout ? { timeoutMs } : undefined) };
166
+ nextProgressTime = Date.now() + PROGRESS_INTERVAL_MS;
167
+ }
168
+ } finally {
169
+ TaskOutput.stopPolling(execution.taskOutput.taskId);
170
+ if (!backgroundShellId && execution.status !== 'backgrounded') {
171
+ if (foregroundTaskId) unregisterForeground(foregroundTaskId, setAppState);
172
+ execution.cleanup();
173
+ }
174
+ }
175
+ }
176
+
177
+ type ShellCommand = Awaited<ReturnType<typeof exec>>;
178
+ type ShellCommandResult =
179
+ | { readonly kind: 'ok'; readonly value: ShellCommand }
180
+ | { readonly kind: 'preflight'; readonly result: ExecResult };
181
+
182
+ async function createShellCommand(input: {
183
+ readonly command: string;
184
+ readonly abortController: AbortController;
185
+ readonly timeoutMs: number;
186
+ readonly preventCwdChanges?: boolean;
187
+ readonly dangerouslyDisableSandbox?: boolean;
188
+ readonly onProgress: (lastLines: string, allLines: string, totalLines: number, totalBytes: number, isIncomplete: boolean) => void;
189
+ }): Promise<ShellCommandResult> {
190
+ try {
191
+ const value = await exec(input.command, input.abortController.signal, 'powershell', {
192
+ timeout: input.timeoutMs,
193
+ onProgress: input.onProgress,
194
+ preventCwdChanges: input.preventCwdChanges,
195
+ shouldUseSandbox: getPlatform() === 'windows' ? false : shouldUseSandboxForShell(input),
196
+ shouldAutoBackground: !isBackgroundTasksDisabled && isAutobackgroundingAllowed(input.command)
197
+ });
198
+ return { kind: 'ok', value };
199
+ } catch (error) {
200
+ if (error instanceof Error) {
201
+ logError(error);
202
+ return { kind: 'preflight', result: { stdout: '', stderr: `Failed to execute PowerShell command: ${getErrorMessage(error)}`, code: 0, interrupted: false } };
203
+ }
204
+ throw error;
205
+ }
206
+ }
207
+
208
+ function progressDelay(nextProgressTime: number): Promise<null> {
209
+ const delayMs = Math.max(0, nextProgressTime - Date.now());
210
+ return new Promise<null>(resolve => setTimeout(done => done(null), delayMs, resolve).unref());
211
+ }
212
+
213
+ function finishCompletedPowerShellResult(result: ExecResult, shellCommand: ShellCommand, setAppState: (f: (prev: AppState) => AppState) => void): ExecResult {
214
+ if (result.backgroundTaskId === undefined) {
215
+ return result;
216
+ }
217
+ markTaskNotified(result.backgroundTaskId, setAppState);
218
+ const fixedResult: ExecResult = { ...result, backgroundTaskId: undefined };
219
+ const { taskOutput } = shellCommand;
220
+ if (taskOutput.stdoutToFile && !taskOutput.outputFileRedundant) {
221
+ fixedResult.outputFilePath = taskOutput.path;
222
+ fixedResult.outputFileSize = taskOutput.outputFileSize;
223
+ fixedResult.outputTaskId = taskOutput.taskId;
224
+ }
225
+ shellCommand.cleanup();
226
+ return fixedResult;
227
+ }
228
+
229
+ function maybeShowBackgroundHint(input: {
230
+ readonly command: string;
231
+ readonly description?: string;
232
+ readonly execution: ShellCommand;
233
+ readonly agentId?: AgentId;
234
+ readonly setAppState: (f: (prev: AppState) => AppState) => void;
235
+ readonly setToolJSX?: SetToolJSXFn;
236
+ readonly toolUseId?: string;
237
+ readonly foregroundTaskId?: string;
238
+ readonly backgroundShellId?: string;
239
+ readonly elapsedSeconds: number;
240
+ }): string | undefined {
241
+ if (isBackgroundTasksDisabled || input.backgroundShellId !== undefined || input.elapsedSeconds < PROGRESS_THRESHOLD_MS / 1000 || !input.setToolJSX) {
242
+ return input.foregroundTaskId;
243
+ }
244
+ const foregroundTaskId = input.foregroundTaskId ?? registerForeground({
245
+ command: input.command,
246
+ description: input.description || input.command,
247
+ shellCommand: input.execution,
248
+ agentId: input.agentId
249
+ }, input.setAppState, input.toolUseId);
250
+ const { BackgroundHint } = loadBashUI();
251
+ input.setToolJSX({
252
+ jsx: <BackgroundHint />,
253
+ shouldHidePromptInput: false,
254
+ shouldContinueAnimation: true,
255
+ showSpinner: true
256
+ });
257
+ return foregroundTaskId;
258
+ }
@@ -0,0 +1,44 @@
1
+ import { PS_TOKENIZER_DASH_CHARS } from '../../utils/powershell/parser.js'
2
+ import { resolveToCanonical } from './readOnlyValidation.js'
3
+
4
+ const LINK_ITEM_TYPES = new Set(['symboliclink', 'junction', 'hardlink'])
5
+
6
+ function isItemTypeParamAbbrev(param: string): boolean {
7
+ return (
8
+ (param.length >= 3 && '-itemtype'.startsWith(param)) ||
9
+ (param.length >= 3 && '-type'.startsWith(param))
10
+ )
11
+ }
12
+
13
+ export function isSymlinkCreatingCommand(cmd: {
14
+ name: string
15
+ args: string[]
16
+ }): boolean {
17
+ const canonical = resolveToCanonical(cmd.name)
18
+ if (canonical !== 'new-item') return false
19
+
20
+ for (let index = 0; index < cmd.args.length; index++) {
21
+ const raw = cmd.args[index] ?? ''
22
+ if (raw.length === 0) continue
23
+
24
+ const first = raw.charAt(0)
25
+ const normalized =
26
+ PS_TOKENIZER_DASH_CHARS.has(first) || first === '/'
27
+ ? '-' + raw.slice(1)
28
+ : raw
29
+ const lower = normalized.toLowerCase()
30
+ const colonIdx = lower.indexOf(':', 1)
31
+ const paramRaw = colonIdx > 0 ? lower.slice(0, colonIdx) : lower
32
+ const param = paramRaw.replace(/`/g, '')
33
+ if (!isItemTypeParamAbbrev(param)) continue
34
+
35
+ const rawVal =
36
+ colonIdx > 0
37
+ ? lower.slice(colonIdx + 1)
38
+ : (cmd.args[index + 1]?.toLowerCase() ?? '')
39
+ const value = rawVal.replace(/`/g, '').replace(/^['"]|['"]$/g, '')
40
+ if (LINK_ITEM_TYPES.has(value)) return true
41
+ }
42
+
43
+ return false
44
+ }
@@ -0,0 +1,37 @@
1
+ import { createRequire } from 'node:module'
2
+
3
+ type PowerShellUIRuntime = Pick<
4
+ typeof import('./UI.js'),
5
+ | 'renderToolResultMessage'
6
+ | 'renderToolUseErrorMessage'
7
+ | 'renderToolUseMessage'
8
+ | 'renderToolUseProgressMessage'
9
+ | 'renderToolUseQueuedMessage'
10
+ >
11
+
12
+ const requireModule = createRequire(import.meta.url)
13
+ let cachedPowerShellUI: PowerShellUIRuntime | undefined
14
+
15
+ function isPowerShellUIRuntime(
16
+ value: unknown,
17
+ ): value is PowerShellUIRuntime {
18
+ if (typeof value !== 'object' || value === null) return false
19
+ const module = value as Partial<Record<keyof PowerShellUIRuntime, unknown>>
20
+ return (
21
+ typeof module.renderToolResultMessage === 'function' &&
22
+ typeof module.renderToolUseErrorMessage === 'function' &&
23
+ typeof module.renderToolUseMessage === 'function' &&
24
+ typeof module.renderToolUseProgressMessage === 'function' &&
25
+ typeof module.renderToolUseQueuedMessage === 'function'
26
+ )
27
+ }
28
+
29
+ export function loadPowerShellUI(): PowerShellUIRuntime {
30
+ if (cachedPowerShellUI !== undefined) return cachedPowerShellUI
31
+ const loaded: unknown = requireModule('./UI.js')
32
+ if (!isPowerShellUIRuntime(loaded)) {
33
+ throw new Error('PowerShell UI module did not expose expected renderers')
34
+ }
35
+ cachedPowerShellUI = loaded
36
+ return loaded
37
+ }
@@ -0,0 +1,39 @@
1
+ import { feature } from 'bun:bundle';
2
+ import type { ValidationResult } from '../../Tool.js';
3
+ import { getPlatform } from '../../utils/platform.js';
4
+ import {
5
+ areUnsandboxedShellCommandsAllowed,
6
+ isShellSandboxEnabledInSettings
7
+ } from '../BashTool/sandboxPolicy.js';
8
+ import { detectBlockedSleepPattern } from './commandClassification.js';
9
+ import { isBackgroundTasksDisabled } from './schemas.js';
10
+ import type { PowerShellToolInput } from './schemas.js';
11
+
12
+ export const WINDOWS_SANDBOX_POLICY_REFUSAL = 'Enterprise policy requires sandboxing, but sandboxing is not available on native Windows. Shell command execution is blocked on this platform by policy.';
13
+
14
+ export function isWindowsSandboxPolicyViolation(): boolean {
15
+ return getPlatform() === 'windows' && isShellSandboxEnabledInSettings() && !areUnsandboxedShellCommandsAllowed();
16
+ }
17
+
18
+ export async function validatePowerShellInput(input: PowerShellToolInput): Promise<ValidationResult> {
19
+ if (isWindowsSandboxPolicyViolation()) {
20
+ return {
21
+ result: false,
22
+ message: WINDOWS_SANDBOX_POLICY_REFUSAL,
23
+ errorCode: 11
24
+ };
25
+ }
26
+ if (feature('MONITOR_TOOL') && !isBackgroundTasksDisabled && !input.run_in_background) {
27
+ const sleepPattern = detectBlockedSleepPattern(input.command);
28
+ if (sleepPattern !== null) {
29
+ return {
30
+ result: false,
31
+ message: `Blocked: ${sleepPattern}. Run blocking commands in the background with run_in_background: true — you'll get a completion notification when done. For streaming events (watching logs, polling APIs), use the Monitor tool. If you genuinely need a delay (rate limiting, deliberate pacing), keep it under 2 seconds.`,
32
+ errorCode: 10
33
+ };
34
+ }
35
+ }
36
+ return {
37
+ result: true
38
+ };
39
+ }
@@ -12,6 +12,10 @@ import {
12
12
  } from '../../utils/mcpOutputStorage.js'
13
13
  import { jsonStringify } from '../../utils/slowOperations.js'
14
14
  import { isOutputLineTruncated } from '../../utils/terminal.js'
15
+ import {
16
+ assertNonEmptyMcpResourceUri,
17
+ assertTrustedMcpServerForResourceAccess,
18
+ } from '../MCPTool/trustPolicy.js'
15
19
  import { DESCRIPTION, PROMPT } from './prompt.js'
16
20
  import {
17
21
  renderToolResultMessage,
@@ -21,8 +25,16 @@ import {
21
25
 
22
26
  export const inputSchema = lazySchema(() =>
23
27
  z.object({
24
- server: z.string().describe('The MCP server name'),
25
- uri: z.string().describe('The resource URI to read'),
28
+ server: z
29
+ .string()
30
+ .trim()
31
+ .min(1, 'Server name cannot be empty')
32
+ .describe('The MCP server name'),
33
+ uri: z
34
+ .string()
35
+ .trim()
36
+ .min(1, 'Resource URI cannot be empty')
37
+ .describe('The resource URI to read'),
26
38
  }),
27
39
  )
28
40
  type InputSchema = ReturnType<typeof inputSchema>
@@ -72,8 +84,12 @@ export const ReadMcpResourceTool = buildTool({
72
84
  get outputSchema(): OutputSchema {
73
85
  return outputSchema()
74
86
  },
75
- async call(input, { options: { mcpClients } }) {
87
+ async call(input, { options: { mcpClients }, getAppState }) {
76
88
  const { server: serverName, uri } = input
89
+ const permissionContext = getAppState().toolPermissionContext
90
+
91
+ assertTrustedMcpServerForResourceAccess(permissionContext, serverName)
92
+ assertNonEmptyMcpResourceUri(uri)
77
93
 
78
94
  const client = mcpClients.find(client => client.name === serverName)
79
95
 
@@ -16,8 +16,6 @@ import {
16
16
  LOCATE_TOOL_PROMPT,
17
17
  } from './prompt.js'
18
18
  import { dispatchPrimitive } from '../_shared/dispatchPrimitive.js'
19
- import { validateKmaAviationToolChoice } from '../_shared/kmaAviationGuard.js'
20
- import { validateDirectPublicDataToolChoice } from '../_shared/directPublicDataGuard.js'
21
19
  import {
22
20
  renderVerboseInputJson,
23
21
  renderVerboseOutputJson,
@@ -269,7 +267,7 @@ export const ResolveLocationPrimitive = buildTool({
269
267
 
270
268
  isMcp: false,
271
269
 
272
- async validateInput(input: z.infer<InputSchema>, context: ToolUseContext) {
270
+ async validateInput(input: z.infer<InputSchema>, _context: ToolUseContext) {
273
271
  if (isRootPrimitiveToolId(input.tool_id)) {
274
272
  return {
275
273
  result: false as const,
@@ -277,14 +275,6 @@ export const ResolveLocationPrimitive = buildTool({
277
275
  errorCode: 1,
278
276
  }
279
277
  }
280
- const kmaAviationChoice = validateKmaAviationToolChoice(input.tool_id, context)
281
- if (kmaAviationChoice) return kmaAviationChoice
282
- const directPublicDataChoice = validateDirectPublicDataToolChoice(
283
- input.tool_id,
284
- context,
285
- input.params,
286
- )
287
- if (directPublicDataChoice) return directPublicDataChoice
288
278
  return { result: true as const }
289
279
  },
290
280
 
@@ -12,18 +12,14 @@ export const LOCATE_TOOL_PROMPT = `Resolve Korean location phrases with concrete
12
12
 
13
13
  Preferred path:
14
14
  - Call concrete adapter functions directly after their schemas are loaded.
15
- - Examples: kakao_keyword_search({ query: "부산 사하구 다대1동" }) or kakao_coord_to_region({ lat: 35.115446, lon: 128.967669 })
16
15
  - Adapter schemas are progressively disclosed by ToolSearch or by backend top-K retrieval for the current citizen request.
17
16
 
18
17
  Legacy root wrapper:
19
18
  - If a concrete adapter function is not loaded and only the root primitive is available, locate accepts { tool_id, params } for old transcripts and compatibility paths.
20
19
  - tool_id must be a concrete locate adapter id from <available_adapters>, never "locate", "find", "check", or "send".
21
20
  - Invalid: locate({ tool_id: "locate", params: {...} })
22
- - Compatibility-only: locate({ tool_id: "kakao_address_search", params: { query: "부산 사하구 다대1동" } })
23
21
 
24
22
  Rules:
25
- - Use kakao_keyword_search for named places, campuses, stations, landmarks, hospitals, and POIs.
26
- - Coordinate-producing locate results may include KMA nx/ny; pass those exact values to KMA weather adapters that require nx and ny.
27
- - Use kakao_address_search or juso_adm_cd_lookup for structured road/jibun addresses and district text.
28
- - Use kakao_coord_to_region after a coordinate result when a downstream adapter needs q0/q1 or region names.
23
+ - Use the concrete location adapter schema fields exactly.
24
+ - Reuse exact coordinate, region, or administrative-code fields from successful location results when a downstream adapter requires them.
29
25
  - If the result is kind="error", do not invent coordinates or administrative codes.`
@@ -523,7 +523,7 @@ export const SkillTool: Tool<InputSchema, Output, Progress> = buildTool({
523
523
  }
524
524
 
525
525
  // Auto-allow skills that only use safe properties.
526
- // This is an allowlist: if a skill has any property NOT in this set with a
526
+ // This is an allowlist: if a skill includes a property NOT in this set with a
527
527
  // meaningful value, it requires permission. This ensures new properties added
528
528
  // in the future default to requiring permission.
529
529
  if (
@@ -869,7 +869,7 @@ export const SkillTool: Tool<InputSchema, Output, Progress> = buildTool({
869
869
  } satisfies ToolDef<InputSchema, Output, Progress>)
870
870
 
871
871
  // Allowlist of PromptCommand property keys that are safe and don't require permission.
872
- // If a skill has any property NOT in this set with a meaningful value, it requires
872
+ // If a skill defines a property NOT in this set with a meaningful value, it requires
873
873
  // permission. This ensures new properties added to PromptCommand in the future
874
874
  // default to requiring permission until explicitly reviewed and added here.
875
875
  const SAFE_SKILL_PROPERTIES = new Set([
@@ -27,6 +27,11 @@ import {
27
27
  resolveAdapter,
28
28
  } from '../../services/api/adapterManifest.js'
29
29
  import { dispatchPrimitive } from '../_shared/dispatchPrimitive.js'
30
+ import {
31
+ applyDocumentVisualRenderGateToOutput,
32
+ isDocumentVisualRenderFailedOutput,
33
+ renderDocumentToolResultIfPresent,
34
+ } from '../_shared/documentToolResultRender.js'
30
35
  import {
31
36
  renderVerboseInputJson,
32
37
  renderVerboseOutputJson,
@@ -63,7 +68,7 @@ const inputSchema = lazySchema(() =>
63
68
  tool_id: z
64
69
  .string()
65
70
  .min(1)
66
- .describe('Registered send adapter identifier from <available_adapters>'),
71
+ .describe('Registered adapter identifier for a send adapter from <available_adapters>'),
67
72
  params: z
68
73
  .record(z.string(), z.unknown())
69
74
  .describe('Adapter-defined Pydantic-validated parameter body'),
@@ -253,19 +258,21 @@ export const SubmitPrimitive = buildTool({
253
258
  },
254
259
 
255
260
  mapToolResultToToolResultBlockParam(output, toolUseID) {
261
+ const gatedOutput = applyDocumentVisualRenderGateToOutput(output)
256
262
  // Spec 2521 (2026-05-02) — outbound_traces is UI-only (see Lookup).
257
263
  const llmContent =
258
- typeof output === 'object' && output !== null
264
+ typeof gatedOutput === 'object' && gatedOutput !== null
259
265
  ? Object.fromEntries(
260
- Object.entries(output as Record<string, unknown>).filter(
266
+ Object.entries(gatedOutput as Record<string, unknown>).filter(
261
267
  ([k]) => k !== 'outbound_traces',
262
268
  ),
263
269
  )
264
- : output
270
+ : gatedOutput
265
271
  return {
266
272
  tool_use_id: toolUseID,
267
273
  type: 'tool_result',
268
274
  content: JSON.stringify(llmContent),
275
+ ...(isDocumentVisualRenderFailedOutput(gatedOutput) ? { is_error: true } : {}),
269
276
  }
270
277
  },
271
278
 
@@ -368,11 +375,16 @@ export const SubmitPrimitive = buildTool({
368
375
  _progress: unknown,
369
376
  options: { verbose: boolean; isTranscriptMode?: boolean } = { verbose: false },
370
377
  ) {
378
+ const gatedOutput = applyDocumentVisualRenderGateToOutput(output) as Output
379
+ const documentResult = renderDocumentToolResultIfPresent(gatedOutput, options)
380
+ if (documentResult !== null) {
381
+ return documentResult
382
+ }
371
383
  // Spec 2521 (2026-05-01 evening) — verbose / transcript mode surface
372
384
  // the full envelope JSON. CC BashTool/UI.tsx:renderToolResultMessage
373
385
  // pattern.
374
386
  if (options.verbose || options.isTranscriptMode) {
375
- return renderVerboseOutputJson(output)
387
+ return renderVerboseOutputJson(gatedOutput)
376
388
  }
377
389
  // NOTE: This file is `.ts` (not `.tsx`); Bun runtime cannot parse JSX in
378
390
  // `.ts`. Use `React.createElement` for parity with the other 3 primitives.
@@ -381,11 +393,11 @@ export const SubmitPrimitive = buildTool({
381
393
  // rewrite, output.result is the actual send primitive output
382
394
  // (transaction_id / ministry / status / agency_handoff_url) unwrapped
383
395
  // from ToolResultEnvelope.result.
384
- if (output.ok) {
385
- return renderCompactPrimitiveResult(buildSubmitSuccessRows(output))
396
+ if (gatedOutput.ok) {
397
+ return renderCompactPrimitiveResult(buildSubmitSuccessRows(gatedOutput))
386
398
  }
387
399
 
388
- return renderCompactPrimitiveResult(buildSubmitErrorRows(output))
400
+ return renderCompactPrimitiveResult(buildSubmitErrorRows(gatedOutput))
389
401
  },
390
402
 
391
403
  isResultTruncated(output: Output): boolean {
@@ -405,7 +417,8 @@ export const SubmitPrimitive = buildTool({
405
417
  async checkPermissions(_input) {
406
418
  return {
407
419
  behavior: 'ask' as const,
408
- message: 'Permission delegation required: send a submission request to the agency. Continue?',
420
+ message:
421
+ '권한 위임 필요: 제출 요청을 기관에 전송합니다. 계속할까요? / Permission delegation required: send a submission request to the agency.',
409
422
  }
410
423
  },
411
424
 
@@ -413,12 +426,16 @@ export const SubmitPrimitive = buildTool({
413
426
  * Dispatch send call via real IPC bridge (T011 — stub replaced).
414
427
  */
415
428
  async call(input, context) {
416
- return dispatchPrimitive<Output>({
429
+ const result = await dispatchPrimitive<Output>({
417
430
  primitive: 'send',
418
431
  args: input as Record<string, unknown>,
419
432
  context,
420
433
  registry: getOrCreatePendingCallRegistry(),
421
434
  bridge: getOrCreateUmmayaBridge(),
422
435
  })
436
+ return {
437
+ ...result,
438
+ data: applyDocumentVisualRenderGateToOutput(result.data) as Output,
439
+ }
423
440
  },
424
441
  } satisfies ToolDef<InputSchema, Output>)
@@ -12,6 +12,7 @@ import {
12
12
  isTodoV2Enabled,
13
13
  } from '../../utils/tasks.js'
14
14
  import { getAgentName, getTeamName } from '../../utils/teammate.js'
15
+ import { buildAgentSupportMetadata } from '../AgentTool/orchestrationSupport.js'
15
16
  import { TASK_CREATE_TOOL_NAME } from './constants.js'
16
17
  import { DESCRIPTION, getPrompt } from './prompt.js'
17
18
 
@@ -39,6 +40,10 @@ const outputSchema = lazySchema(() =>
39
40
  id: z.string(),
40
41
  subject: z.string(),
41
42
  }),
43
+ evidenceJoinKey: z.string(),
44
+ parentToolUseId: z.string(),
45
+ resumeToken: z.string(),
46
+ permissionFlow: z.literal('coordinator_parent_round_trip'),
42
47
  }),
43
48
  )
44
49
  type OutputSchema = ReturnType<typeof outputSchema>
@@ -124,15 +129,24 @@ export const TaskCreateTool = buildTool({
124
129
  id: taskId,
125
130
  subject,
126
131
  },
132
+ ...buildAgentSupportMetadata({
133
+ taskId,
134
+ parentToolUseId: context.toolUseId,
135
+ }),
127
136
  },
128
137
  }
129
138
  },
130
139
  mapToolResultToToolResultBlockParam(content, toolUseID) {
131
- const { task } = content as Output
140
+ const { task, evidenceJoinKey, parentToolUseId, resumeToken, permissionFlow } =
141
+ outputSchema().parse(content)
132
142
  return {
133
143
  tool_use_id: toolUseID,
134
144
  type: 'tool_result',
135
- content: `Task #${task.id} created successfully: ${task.subject}`,
145
+ content: `Task #${task.id} created successfully: ${task.subject}
146
+ evidence_join_key: ${evidenceJoinKey}
147
+ parent_tool_use_id: ${parentToolUseId}
148
+ resume_token: ${resumeToken}
149
+ permission_flow: ${permissionFlow}`,
136
150
  }
137
151
  },
138
152
  } satisfies ToolDef<InputSchema, Output>)