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,79 @@
1
+ import type { Tool } from '../../Tool.js'
2
+ import { BashTool } from '../BashTool/BashTool.js'
3
+ import { FileEditTool } from '../FileEditTool/FileEditTool.js'
4
+ import { FileReadTool } from '../FileReadTool/FileReadTool.js'
5
+ import { FileWriteTool } from '../FileWriteTool/FileWriteTool.js'
6
+ import { GlobTool } from '../GlobTool/GlobTool.js'
7
+ import { GrepTool } from '../GrepTool/GrepTool.js'
8
+ import { buildWorkspaceTool, type WorkspaceToolSpec } from './toolDefFactory.js'
9
+ import {
10
+ WORKSPACE_BASH_TOOL_NAME,
11
+ WORKSPACE_EDIT_TOOL_NAME,
12
+ WORKSPACE_GLOB_TOOL_NAME,
13
+ WORKSPACE_GREP_TOOL_NAME,
14
+ WORKSPACE_READ_TOOL_NAME,
15
+ WORKSPACE_WRITE_TOOL_NAME,
16
+ } from './toolNames.js'
17
+
18
+ export {
19
+ WORKSPACE_BASH_TOOL_NAME,
20
+ WORKSPACE_EDIT_TOOL_NAME,
21
+ WORKSPACE_GLOB_TOOL_NAME,
22
+ WORKSPACE_GREP_TOOL_NAME,
23
+ WORKSPACE_READ_TOOL_NAME,
24
+ WORKSPACE_WRITE_TOOL_NAME,
25
+ } from './toolNames.js'
26
+
27
+ const WORKSPACE_TOOL_SPECS: readonly WorkspaceToolSpec[] = [
28
+ {
29
+ name: WORKSPACE_GLOB_TOOL_NAME,
30
+ source: () => GlobTool,
31
+ searchHint: 'find local files by name pattern',
32
+ alwaysLoad: true,
33
+ supportsUserFolderHints: true,
34
+ enforcesAllowedRoots: true,
35
+ readSearchDefaultAllowed: true,
36
+ },
37
+ {
38
+ name: WORKSPACE_GREP_TOOL_NAME,
39
+ source: () => GrepTool,
40
+ searchHint: 'search local file contents',
41
+ alwaysLoad: true,
42
+ supportsUserFolderHints: true,
43
+ enforcesAllowedRoots: true,
44
+ readSearchDefaultAllowed: true,
45
+ },
46
+ {
47
+ name: WORKSPACE_READ_TOOL_NAME,
48
+ source: () => FileReadTool,
49
+ searchHint: 'read local text files',
50
+ alwaysLoad: true,
51
+ enforcesAllowedRoots: true,
52
+ readSearchDefaultAllowed: true,
53
+ },
54
+ {
55
+ name: WORKSPACE_WRITE_TOOL_NAME,
56
+ source: () => FileWriteTool,
57
+ searchHint:
58
+ 'create or overwrite local text files with visible permission boundary and blocked state',
59
+ blocksDocumentFormats: true,
60
+ enforcesAllowedRoots: true,
61
+ },
62
+ {
63
+ name: WORKSPACE_EDIT_TOOL_NAME,
64
+ source: () => FileEditTool,
65
+ searchHint: 'modify local text files in place',
66
+ blocksDocumentFormats: true,
67
+ enforcesAllowedRoots: true,
68
+ },
69
+ {
70
+ name: WORKSPACE_BASH_TOOL_NAME,
71
+ source: () => BashTool,
72
+ searchHint:
73
+ 'run local shell commands with visible permission boundary and blocked state',
74
+ },
75
+ ]
76
+
77
+ export function getWorkspaceTools(): readonly Tool[] {
78
+ return WORKSPACE_TOOL_SPECS.map(buildWorkspaceTool)
79
+ }
@@ -0,0 +1,85 @@
1
+ import { relative } from 'node:path'
2
+ import type { ToolUseContext, ValidationResult } from '../../Tool.js'
3
+ import { getCwd } from '../../utils/cwd.js'
4
+ import { getPathsForPermissionCheck } from '../../utils/fsOperations.js'
5
+ import { expandPath } from '../../utils/path.js'
6
+ import type { PermissionDecision } from '../../utils/permissions/PermissionResult.js'
7
+ import {
8
+ inferredDownloadsPath,
9
+ latestUserTextFromWorkspaceContext,
10
+ } from './inputNormalization.js'
11
+
12
+ export const WORKSPACE_PATH_ESCAPE_MESSAGE =
13
+ 'Path resolves outside the allowed workspace roots. Re-select the folder or use an explicit document primitive flow.'
14
+
15
+ function pathIsInsideRoot(candidate: string, root: string): boolean {
16
+ const rel = relative(root, candidate)
17
+ return rel === '' || (!rel.startsWith('..') && !rel.startsWith('/'))
18
+ }
19
+
20
+ function resolvedForms(path: string): readonly string[] {
21
+ return getPathsForPermissionCheck(expandPath(path))
22
+ }
23
+
24
+ function allowedWorkspaceRoots(context: ToolUseContext): readonly string[] {
25
+ const roots = new Set<string>(resolvedForms(getCwd()))
26
+ const appState = context.getAppState()
27
+ for (const directory of appState.toolPermissionContext.additionalWorkingDirectories.values()) {
28
+ for (const resolved of resolvedForms(directory.path)) {
29
+ roots.add(resolved)
30
+ }
31
+ }
32
+ const downloadsPath = inferredDownloadsPath(
33
+ latestUserTextFromWorkspaceContext(context),
34
+ )
35
+ if (downloadsPath !== undefined) {
36
+ for (const resolved of resolvedForms(downloadsPath)) {
37
+ roots.add(resolved)
38
+ }
39
+ }
40
+ return Array.from(roots)
41
+ }
42
+
43
+ export function validateWorkspacePathInsideAllowedRoots(
44
+ path: string,
45
+ context: ToolUseContext,
46
+ ): ValidationResult {
47
+ if (typeof context.getAppState !== 'function') return { result: true }
48
+ const targetForms = resolvedForms(path)
49
+ const rootForms = allowedWorkspaceRoots(context)
50
+ const inside = targetForms.every(target =>
51
+ rootForms.some(root => pathIsInsideRoot(target, root)),
52
+ )
53
+ if (inside) return { result: true }
54
+ return {
55
+ result: false,
56
+ message: WORKSPACE_PATH_ESCAPE_MESSAGE,
57
+ errorCode: 20,
58
+ }
59
+ }
60
+
61
+ export function workspaceReadSearchDecision(
62
+ path: string,
63
+ input: Record<string, unknown>,
64
+ context: ToolUseContext,
65
+ ): PermissionDecision {
66
+ const validation = validateWorkspacePathInsideAllowedRoots(path, context)
67
+ if (!validation.result) {
68
+ return {
69
+ behavior: 'deny',
70
+ message: validation.message,
71
+ decisionReason: {
72
+ type: 'workingDir',
73
+ reason: 'Path resolves outside allowed workspace roots',
74
+ },
75
+ }
76
+ }
77
+ return {
78
+ behavior: 'allow',
79
+ updatedInput: input,
80
+ decisionReason: {
81
+ type: 'mode',
82
+ mode: 'default',
83
+ },
84
+ }
85
+ }
@@ -0,0 +1,73 @@
1
+ import type { Tool, ValidationResult } from '../../Tool.js'
2
+ import { isWorkspaceInputRecord } from './inputNormalization.js'
3
+ import { WORKSPACE_BASH_TOOL_NAME } from './toolNames.js'
4
+
5
+ const DOCUMENT_DERIVATIVE_PATH_RE = /\.(?:hwp|hwpx|docx|pdf|xlsx|pptx)$/iu
6
+ const DOCUMENT_FORMAT_PATH_RE = /\.(?:hwp|hwpx|docx|pdf|xlsx|pptx)$/iu
7
+ const DOCUMENT_FORMAT_COMMAND_RE =
8
+ /\.(?:hwp|hwpx|docx|pdf|xlsx|pptx)(?=$|[\s"'`;|&<>])/iu
9
+
10
+ export const DOCUMENT_DERIVATIVE_MUTATION_MESSAGE =
11
+ 'Document derivatives must be mutated through the document primitive, not raw file tools.'
12
+
13
+ const WORKSPACE_DOCUMENT_FORMAT_MESSAGE_PREFIX =
14
+ 'Document formats must be edited through the document primitive, not'
15
+
16
+ export function isDocumentDerivativePath(filePath: string): boolean {
17
+ return DOCUMENT_DERIVATIVE_PATH_RE.test(filePath)
18
+ }
19
+
20
+ export function documentDerivativeMutationValidation(
21
+ filePath: string,
22
+ ): ValidationResult | null {
23
+ if (!isDocumentDerivativePath(filePath)) return null
24
+ return {
25
+ result: false,
26
+ message: DOCUMENT_DERIVATIVE_MUTATION_MESSAGE,
27
+ errorCode: 20,
28
+ }
29
+ }
30
+
31
+ export function documentPathFromInput(input: unknown): string | undefined {
32
+ if (!isWorkspaceInputRecord(input)) return undefined
33
+ return typeof input.file_path === 'string' ? input.file_path : undefined
34
+ }
35
+
36
+ export function workspaceDocumentFormatPathValidation(
37
+ toolName: string,
38
+ input: unknown,
39
+ ): ValidationResult | null {
40
+ const filePath = documentPathFromInput(input)
41
+ if (filePath === undefined || !DOCUMENT_FORMAT_PATH_RE.test(filePath)) {
42
+ return null
43
+ }
44
+ return {
45
+ result: false,
46
+ message: `${WORKSPACE_DOCUMENT_FORMAT_MESSAGE_PREFIX} ${toolName}.`,
47
+ errorCode: 1,
48
+ }
49
+ }
50
+
51
+ export function workspaceBashDocumentFormatValidation(
52
+ source: Tool,
53
+ input: unknown,
54
+ ): ValidationResult | null {
55
+ if (!isWorkspaceInputRecord(input)) return null
56
+ if (input.dangerouslyDisableSandbox === true) {
57
+ return {
58
+ result: false,
59
+ message:
60
+ 'workspace_bash does not allow dangerouslyDisableSandbox. Use the normal permission and sandbox boundary.',
61
+ errorCode: 2,
62
+ }
63
+ }
64
+ const command = typeof input.command === 'string' ? input.command : ''
65
+ if (DOCUMENT_FORMAT_COMMAND_RE.test(command) && !source.isReadOnly(input)) {
66
+ return {
67
+ result: false,
68
+ message: `${WORKSPACE_DOCUMENT_FORMAT_MESSAGE_PREFIX} ${WORKSPACE_BASH_TOOL_NAME}.`,
69
+ errorCode: 1,
70
+ }
71
+ }
72
+ return null
73
+ }
@@ -0,0 +1,105 @@
1
+ import { homedir } from 'node:os'
2
+ import { join } from 'node:path'
3
+ import type { ToolUseContext } from '../../Tool.js'
4
+ import { WORKSPACE_GLOB_TOOL_NAME } from './toolNames.js'
5
+
6
+ const DOCUMENT_FORMAT_HINT_RE =
7
+ /\b(?:hwp|hwpx|docx|pdf|xlsx|pptx)\b|\.(?:hwp|hwpx|docx|pdf|xlsx|pptx)\b/iu
8
+ const HWPX_DOCUMENT_HINT_RE = /\bhwpx\b|\.hwpx\b/iu
9
+ const MALFORMED_GLOB_EXTENSION_RE =
10
+ /\s|\*\.hwp\s+\*\.hwpx|\*\.hwpx\s+\*\.hwp/iu
11
+ const DOWNLOADS_FOLDER_RE = /\bdownloads?\b|다운로드/iu
12
+
13
+ type WorkspaceInputNormalizationSpec = {
14
+ readonly name: string
15
+ readonly supportsUserFolderHints?: boolean
16
+ }
17
+
18
+ export function isWorkspaceInputRecord(
19
+ input: unknown,
20
+ ): input is Record<string, unknown> {
21
+ return typeof input === 'object' && input !== null && !Array.isArray(input)
22
+ }
23
+
24
+ function textFromContent(content: unknown): string {
25
+ if (typeof content === 'string') return content
26
+ if (!Array.isArray(content)) return ''
27
+ return content
28
+ .map(block => {
29
+ if (typeof block === 'string') return block
30
+ if (!isWorkspaceInputRecord(block)) return ''
31
+ return typeof block.text === 'string' ? block.text : ''
32
+ })
33
+ .filter(Boolean)
34
+ .join('\n')
35
+ }
36
+
37
+ export function latestUserTextFromWorkspaceContext(
38
+ context: ToolUseContext,
39
+ ): string {
40
+ for (let index = context.messages.length - 1; index >= 0; index -= 1) {
41
+ const message = context.messages[index]
42
+ if (!isWorkspaceInputRecord(message)) continue
43
+ const nested = message.message
44
+ if (!isWorkspaceInputRecord(nested)) continue
45
+ if (nested.role !== 'user') continue
46
+ const text = textFromContent(nested.content)
47
+ if (text.trim()) return text
48
+ }
49
+ return ''
50
+ }
51
+
52
+ export function userTextMentionsDownloads(text: string): boolean {
53
+ return DOWNLOADS_FOLDER_RE.test(text)
54
+ }
55
+
56
+ export function inferredDownloadsPath(text: string): string | undefined {
57
+ return userTextMentionsDownloads(text)
58
+ ? join(homedir(), 'Downloads')
59
+ : undefined
60
+ }
61
+
62
+ function normalizedDocumentGlobPattern(
63
+ text: string,
64
+ pattern: unknown,
65
+ ): string | undefined {
66
+ if (typeof pattern !== 'string') return undefined
67
+ if (!DOCUMENT_FORMAT_HINT_RE.test(text)) return undefined
68
+ if (pattern.startsWith('**/') && !pattern.startsWith('**/*')) {
69
+ const basenamePattern = pattern.slice('**/'.length)
70
+ if (
71
+ !basenamePattern.includes('/') &&
72
+ /\.(?:hwp|hwpx|docx|pdf|xlsx|pptx)$/iu.test(basenamePattern)
73
+ ) {
74
+ return `**/*${basenamePattern}`
75
+ }
76
+ }
77
+ if (!HWPX_DOCUMENT_HINT_RE.test(text)) return undefined
78
+ if (!MALFORMED_GLOB_EXTENSION_RE.test(pattern)) return undefined
79
+ return '**/*.hwpx'
80
+ }
81
+
82
+ export function normalizeWorkspaceInputFromContext(
83
+ spec: WorkspaceInputNormalizationSpec,
84
+ input: unknown,
85
+ context: ToolUseContext,
86
+ ): unknown {
87
+ if (!spec.supportsUserFolderHints) return input
88
+ if (!isWorkspaceInputRecord(input)) return input
89
+ const userText = latestUserTextFromWorkspaceContext(context)
90
+ if (spec.name === WORKSPACE_GLOB_TOOL_NAME) {
91
+ const normalizedPattern = normalizedDocumentGlobPattern(
92
+ userText,
93
+ input.pattern,
94
+ )
95
+ if (normalizedPattern !== undefined) {
96
+ input.pattern = normalizedPattern
97
+ }
98
+ }
99
+ if (typeof input.path === 'string' && input.path.trim()) return input
100
+ const inferredPath = inferredDownloadsPath(userText)
101
+ if (inferredPath !== undefined) {
102
+ input.path = inferredPath
103
+ }
104
+ return input
105
+ }
@@ -0,0 +1,64 @@
1
+ import type { ToolPermissionContext } from '../../Tool.js'
2
+ import { mcpInfoFromString } from '../../services/mcp/mcpStringUtils.js'
3
+ import { getAllowRules } from '../../utils/permissions/permissions.js'
4
+
5
+ type McpExposureCandidate = {
6
+ readonly name: string
7
+ readonly mcpInfo?: { readonly serverName: string; readonly toolName: string }
8
+ }
9
+
10
+ export const MCP_MODEL_EXPOSURE_SERVER_CLASSES = [
11
+ 'ummaya',
12
+ 'trusted-configured',
13
+ 'untrusted-configured',
14
+ ] as const
15
+
16
+ export type McpModelExposureServerClass =
17
+ (typeof MCP_MODEL_EXPOSURE_SERVER_CLASSES)[number]
18
+
19
+ function getMcpServerName(tool: McpExposureCandidate): string | null {
20
+ if (tool.mcpInfo?.serverName) return tool.mcpInfo.serverName
21
+ return mcpInfoFromString(tool.name)?.serverName ?? null
22
+ }
23
+
24
+ function hasTrustedConfiguredMcpServerRecord(
25
+ permissionContext: ToolPermissionContext,
26
+ serverName: string,
27
+ ): boolean {
28
+ return getAllowRules(permissionContext).some(rule => {
29
+ if (rule.ruleValue.ruleContent !== undefined) return false
30
+ const ruleInfo = mcpInfoFromString(rule.ruleValue.toolName)
31
+ if (ruleInfo === null) return false
32
+ return (
33
+ ruleInfo.serverName === serverName &&
34
+ (ruleInfo.toolName === undefined || ruleInfo.toolName === '*')
35
+ )
36
+ })
37
+ }
38
+
39
+ export function classifyMcpServerForModelExposure(
40
+ tool: McpExposureCandidate,
41
+ permissionContext: ToolPermissionContext,
42
+ ): McpModelExposureServerClass {
43
+ const serverName = getMcpServerName(tool)
44
+ if (serverName === 'ummaya') return 'ummaya'
45
+ if (serverName === null) return 'untrusted-configured'
46
+ if (hasTrustedConfiguredMcpServerRecord(permissionContext, serverName)) {
47
+ return 'trusted-configured'
48
+ }
49
+ return 'untrusted-configured'
50
+ }
51
+
52
+ export function isModelFacingMcpTool(
53
+ tool: McpExposureCandidate,
54
+ permissionContext: ToolPermissionContext,
55
+ ): boolean {
56
+ const serverClass = classifyMcpServerForModelExposure(tool, permissionContext)
57
+ switch (serverClass) {
58
+ case 'ummaya':
59
+ case 'trusted-configured':
60
+ return true
61
+ case 'untrusted-configured':
62
+ return false
63
+ }
64
+ }
@@ -0,0 +1,215 @@
1
+ import type { Tool } from '../../Tool.js'
2
+ import { validateWorkspacePathInsideAllowedRoots, workspaceReadSearchDecision } from './allowedRootPolicy.js'
3
+ import {
4
+ isWorkspaceInputRecord,
5
+ normalizeWorkspaceInputFromContext,
6
+ } from './inputNormalization.js'
7
+ import {
8
+ workspaceBashDocumentFormatValidation,
9
+ workspaceDocumentFormatPathValidation,
10
+ } from './documentFormatGuards.js'
11
+ import { WORKSPACE_BASH_TOOL_NAME } from './toolNames.js'
12
+
13
+ export type WorkspaceToolSpec = {
14
+ readonly name: string
15
+ readonly source: () => Tool
16
+ readonly searchHint: string
17
+ readonly alwaysLoad?: boolean
18
+ readonly shouldDefer?: boolean
19
+ readonly blocksDocumentFormats?: boolean
20
+ readonly supportsUserFolderHints?: boolean
21
+ readonly enforcesAllowedRoots?: boolean
22
+ readonly readSearchDefaultAllowed?: boolean
23
+ }
24
+
25
+ function migrateToolText(text: string): string {
26
+ return text
27
+ .replace(/\bGlob\b/g, 'workspace_glob')
28
+ .replace(/\bGrep\b/g, 'workspace_grep')
29
+ .replace(/\bRead\b/g, 'workspace_read')
30
+ .replace(/\bWrite\b/g, 'workspace_write')
31
+ .replace(/\bEdit\b/g, 'workspace_edit')
32
+ .replace(/\bBash\b/g, WORKSPACE_BASH_TOOL_NAME)
33
+ }
34
+
35
+ function lazyWorkspaceToolOptionals(
36
+ tool: Tool,
37
+ source: () => Tool,
38
+ ): Tool {
39
+ Object.defineProperties(tool, {
40
+ backfillObservableInput: { get: () => source().backfillObservableInput },
41
+ extractSearchText: { get: () => source().extractSearchText },
42
+ getToolUseSummary: { get: () => source().getToolUseSummary },
43
+ inputJSONSchema: { get: () => source().inputJSONSchema },
44
+ inputsEquivalent: { get: () => source().inputsEquivalent },
45
+ isLsp: { get: () => source().isLsp },
46
+ isMcp: { get: () => source().isMcp },
47
+ isOpenWorld: { get: () => source().isOpenWorld },
48
+ isResultTruncated: { get: () => source().isResultTruncated },
49
+ isTransparentWrapper: { get: () => source().isTransparentWrapper },
50
+ mcpInfo: { get: () => source().mcpInfo },
51
+ outputSchema: { get: () => source().outputSchema },
52
+ preparePermissionMatcher: { get: () => source().preparePermissionMatcher },
53
+ renderGroupedToolUse: { get: () => source().renderGroupedToolUse },
54
+ renderToolResultMessage: { get: () => source().renderToolResultMessage },
55
+ renderToolUseErrorMessage: { get: () => source().renderToolUseErrorMessage },
56
+ renderToolUseProgressMessage: {
57
+ get: () => source().renderToolUseProgressMessage,
58
+ },
59
+ renderToolUseQueuedMessage: { get: () => source().renderToolUseQueuedMessage },
60
+ renderToolUseRejectedMessage: {
61
+ get: () => source().renderToolUseRejectedMessage,
62
+ },
63
+ renderToolUseTag: { get: () => source().renderToolUseTag },
64
+ requiresUserInteraction: { get: () => source().requiresUserInteraction },
65
+ strict: { get: () => source().strict },
66
+ userFacingNameBackgroundColor: {
67
+ get: () => source().userFacingNameBackgroundColor,
68
+ },
69
+ })
70
+ return tool
71
+ }
72
+
73
+ export function buildWorkspaceTool(spec: WorkspaceToolSpec): Tool {
74
+ const source = spec.source
75
+ const workspaceTool: Tool = {
76
+ name: spec.name,
77
+ aliases: [],
78
+ searchHint: spec.searchHint,
79
+ alwaysLoad: spec.alwaysLoad,
80
+ shouldDefer: spec.alwaysLoad ? false : spec.shouldDefer ?? true,
81
+ get maxResultSizeChars() {
82
+ return source().maxResultSizeChars
83
+ },
84
+ get inputSchema() {
85
+ return source().inputSchema
86
+ },
87
+ call(input, context, canUseTool, parentMessage, onProgress) {
88
+ const normalizedInput = normalizeWorkspaceInputFromContext(
89
+ spec,
90
+ input,
91
+ context,
92
+ )
93
+ return source().call(
94
+ normalizedInput,
95
+ context,
96
+ canUseTool,
97
+ parentMessage,
98
+ onProgress,
99
+ )
100
+ },
101
+ async description(input, options) {
102
+ const base = await source().description(input, options)
103
+ return `${migrateToolText(base)}
104
+
105
+ UMMAYA workspace adapter: this tool delegates to the Claude Code local workspace implementation under a namespaced tool id. Use the document primitive for HWPX, HWP, DOCX, PDF, XLSX, and PPTX content edits.`
106
+ },
107
+ async prompt(options) {
108
+ const base = await source().prompt(options)
109
+ return `${migrateToolText(base)}
110
+
111
+ UMMAYA workspace boundary:
112
+ - This adapter is for local workspace text/file access.
113
+ - Use document for HWPX, HWP, DOCX, PDF, XLSX, and PPTX reading, editing, rendering, diffing, or saving.
114
+ - Do not call raw Claude Code tool names; use the workspace_* adapter names exposed in this session.`
115
+ },
116
+ async validateInput(input, context) {
117
+ const sourceTool = source()
118
+ normalizeWorkspaceInputFromContext(spec, input, context)
119
+ if (spec.blocksDocumentFormats) {
120
+ const documentValidation = workspaceDocumentFormatPathValidation(
121
+ spec.name,
122
+ input,
123
+ )
124
+ if (documentValidation !== null) return documentValidation
125
+ }
126
+ const workspacePath =
127
+ typeof sourceTool.getPath === 'function' && isWorkspaceInputRecord(input)
128
+ ? sourceTool.getPath(input)
129
+ : undefined
130
+ if (spec.enforcesAllowedRoots && workspacePath) {
131
+ const workspaceValidation = validateWorkspacePathInsideAllowedRoots(
132
+ workspacePath,
133
+ context,
134
+ )
135
+ if (!workspaceValidation.result) return workspaceValidation
136
+ }
137
+ if (spec.name === WORKSPACE_BASH_TOOL_NAME) {
138
+ const bashValidation = workspaceBashDocumentFormatValidation(
139
+ sourceTool,
140
+ input,
141
+ )
142
+ if (bashValidation !== null) return bashValidation
143
+ }
144
+ return sourceTool.validateInput
145
+ ? sourceTool.validateInput(input, context)
146
+ : { result: true }
147
+ },
148
+ async checkPermissions(input, context) {
149
+ const sourceTool = source()
150
+ const normalizedInput = normalizeWorkspaceInputFromContext(
151
+ spec,
152
+ input,
153
+ context,
154
+ )
155
+ if (
156
+ spec.readSearchDefaultAllowed &&
157
+ typeof sourceTool.getPath === 'function'
158
+ ) {
159
+ if (!isWorkspaceInputRecord(normalizedInput)) {
160
+ return sourceTool.checkPermissions(normalizedInput, context)
161
+ }
162
+ return workspaceReadSearchDecision(
163
+ sourceTool.getPath(normalizedInput),
164
+ normalizedInput,
165
+ context,
166
+ )
167
+ }
168
+ return sourceTool.checkPermissions(normalizedInput, context)
169
+ },
170
+ isConcurrencySafe(input) {
171
+ return source().isConcurrencySafe(input)
172
+ },
173
+ isDestructive(input) {
174
+ return source().isDestructive?.(input) ?? false
175
+ },
176
+ isEnabled() {
177
+ return source().isEnabled()
178
+ },
179
+ isReadOnly(input) {
180
+ return source().isReadOnly(input)
181
+ },
182
+ interruptBehavior() {
183
+ return source().interruptBehavior?.() ?? 'block'
184
+ },
185
+ isSearchOrReadCommand(input) {
186
+ return (
187
+ source().isSearchOrReadCommand?.(input) ?? {
188
+ isSearch: false,
189
+ isRead: false,
190
+ isList: false,
191
+ }
192
+ )
193
+ },
194
+ mapToolResultToToolResultBlockParam(content, toolUseID) {
195
+ return source().mapToolResultToToolResultBlockParam(content, toolUseID)
196
+ },
197
+ renderToolUseMessage(input, options) {
198
+ return source().renderToolUseMessage(input, options)
199
+ },
200
+ toAutoClassifierInput(input) {
201
+ return source().toAutoClassifierInput(input)
202
+ },
203
+ userFacingName() {
204
+ return spec.name
205
+ },
206
+ getActivityDescription(input) {
207
+ const activity = source().getActivityDescription?.(input)
208
+ return activity ? migrateToolText(activity) : spec.name
209
+ },
210
+ }
211
+ Object.defineProperty(workspaceTool, 'getPath', {
212
+ get: () => source().getPath,
213
+ })
214
+ return lazyWorkspaceToolOptionals(workspaceTool, source)
215
+ }
@@ -0,0 +1,6 @@
1
+ export const WORKSPACE_GLOB_TOOL_NAME = 'workspace_glob'
2
+ export const WORKSPACE_GREP_TOOL_NAME = 'workspace_grep'
3
+ export const WORKSPACE_READ_TOOL_NAME = 'workspace_read'
4
+ export const WORKSPACE_WRITE_TOOL_NAME = 'workspace_write'
5
+ export const WORKSPACE_EDIT_TOOL_NAME = 'workspace_edit'
6
+ export const WORKSPACE_BASH_TOOL_NAME = 'workspace_bash'
@@ -0,0 +1,15 @@
1
+ export {
2
+ validateWorkspacePathInsideAllowedRoots,
3
+ workspaceReadSearchDecision,
4
+ WORKSPACE_PATH_ESCAPE_MESSAGE,
5
+ } from './allowedRootPolicy.js'
6
+ export {
7
+ documentDerivativeMutationValidation,
8
+ DOCUMENT_DERIVATIVE_MUTATION_MESSAGE,
9
+ isDocumentDerivativePath,
10
+ } from './documentFormatGuards.js'
11
+ export {
12
+ inferredDownloadsPath,
13
+ latestUserTextFromWorkspaceContext,
14
+ userTextMentionsDownloads,
15
+ } from './inputNormalization.js'