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