ummaya 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (482) hide show
  1. package/README.md +15 -2
  2. package/bin/ummaya +10 -1
  3. package/bun.lock +180 -244
  4. package/npm-shrinkwrap.json +760 -1760
  5. package/package.json +39 -22
  6. package/prompts/manifest.yaml +1 -1
  7. package/prompts/system_v1.md +1 -0
  8. package/pyproject.toml +27 -2
  9. package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
  10. package/src/ummaya/_canonical/__init__.py +2 -0
  11. package/src/ummaya/_canonical/baselines.yaml +113 -0
  12. package/src/ummaya/engine/engine.py +29 -132
  13. package/src/ummaya/evidence/__init__.py +21 -2
  14. package/src/ummaya/evidence/dataset_contract.py +193 -0
  15. package/src/ummaya/evidence/document_authoring_cases.py +33 -0
  16. package/src/ummaya/evidence/document_harness.py +313 -0
  17. package/src/ummaya/evidence/document_viewer_ux.py +391 -0
  18. package/src/ummaya/evidence/gates.py +70 -0
  19. package/src/ummaya/evidence/json_types.py +20 -0
  20. package/src/ummaya/evidence/models.py +88 -1
  21. package/src/ummaya/evidence/output_payload.py +89 -0
  22. package/src/ummaya/evidence/payload_documents.py +233 -0
  23. package/src/ummaya/evidence/route_contracts.py +224 -0
  24. package/src/ummaya/evidence/route_helpers.py +150 -0
  25. package/src/ummaya/evidence/runner.py +81 -212
  26. package/src/ummaya/evidence/source_provenance.py +246 -0
  27. package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
  28. package/src/ummaya/evidence/tool_layer.py +39 -0
  29. package/src/ummaya/evidence/tool_layer_models.py +151 -0
  30. package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
  31. package/src/ummaya/ipc/document_intent_normalization.py +185 -0
  32. package/src/ummaya/ipc/frame_schema.py +5 -5
  33. package/src/ummaya/ipc/route_diagnostics.py +73 -0
  34. package/src/ummaya/ipc/stdio.py +1109 -477
  35. package/src/ummaya/llm/client.py +102 -3
  36. package/src/ummaya/llm/config.py +8 -3
  37. package/src/ummaya/primitives/__init__.py +6 -2
  38. package/src/ummaya/primitives/delegation.py +1 -1
  39. package/src/ummaya/primitives/document.py +28 -0
  40. package/src/ummaya/settings.py +0 -3
  41. package/src/ummaya/tools/discovery_bridge.py +17 -1
  42. package/src/ummaya/tools/documents/__init__.py +297 -0
  43. package/src/ummaya/tools/documents/adapter_registry.py +487 -0
  44. package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
  45. package/src/ummaya/tools/documents/artifact_store.py +454 -0
  46. package/src/ummaya/tools/documents/authoring.py +283 -0
  47. package/src/ummaya/tools/documents/baselines.py +132 -0
  48. package/src/ummaya/tools/documents/capability.py +331 -0
  49. package/src/ummaya/tools/documents/contracts.py +112 -0
  50. package/src/ummaya/tools/documents/conversion.py +521 -0
  51. package/src/ummaya/tools/documents/diff.py +275 -0
  52. package/src/ummaya/tools/documents/engines.py +163 -0
  53. package/src/ummaya/tools/documents/evaluation.py +291 -0
  54. package/src/ummaya/tools/documents/explicit_values.py +108 -0
  55. package/src/ummaya/tools/documents/fixtures.py +174 -0
  56. package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
  57. package/src/ummaya/tools/documents/formats/__init__.py +2 -0
  58. package/src/ummaya/tools/documents/formats/archive.py +528 -0
  59. package/src/ummaya/tools/documents/formats/base.py +41 -0
  60. package/src/ummaya/tools/documents/formats/code_file.py +211 -0
  61. package/src/ummaya/tools/documents/formats/data_file.py +272 -0
  62. package/src/ummaya/tools/documents/formats/hwp.py +284 -0
  63. package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
  64. package/src/ummaya/tools/documents/formats/odf.py +435 -0
  65. package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
  66. package/src/ummaya/tools/documents/formats/passive.py +766 -0
  67. package/src/ummaya/tools/documents/formats/pdf.py +702 -0
  68. package/src/ummaya/tools/documents/formats/text_web.py +268 -0
  69. package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
  70. package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
  71. package/src/ummaya/tools/documents/inspection.py +289 -0
  72. package/src/ummaya/tools/documents/intake.py +1079 -0
  73. package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
  74. package/src/ummaya/tools/documents/models.py +1598 -0
  75. package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
  76. package/src/ummaya/tools/documents/orchestrator.py +96 -0
  77. package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
  78. package/src/ummaya/tools/documents/patch.py +170 -0
  79. package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
  80. package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
  81. package/src/ummaya/tools/documents/permissions.py +110 -0
  82. package/src/ummaya/tools/documents/planner.py +616 -0
  83. package/src/ummaya/tools/documents/registry.py +2733 -0
  84. package/src/ummaya/tools/documents/render.py +978 -0
  85. package/src/ummaya/tools/documents/render_comparison.py +113 -0
  86. package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
  87. package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
  88. package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
  89. package/src/ummaya/tools/documents/reread.py +157 -0
  90. package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
  91. package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
  92. package/src/ummaya/tools/documents/scorecard.py +184 -0
  93. package/src/ummaya/tools/documents/socratic_planner.py +193 -0
  94. package/src/ummaya/tools/documents/style.py +48 -0
  95. package/src/ummaya/tools/documents/tool_defs.py +523 -0
  96. package/src/ummaya/tools/documents/validate.py +347 -0
  97. package/src/ummaya/tools/executor.py +29 -0
  98. package/src/ummaya/tools/live_proxy.py +0 -3
  99. package/src/ummaya/tools/models.py +5 -1
  100. package/src/ummaya/tools/register_all.py +8 -0
  101. package/src/ummaya/tools/registry.py +10 -1
  102. package/src/ummaya/tools/routing/__init__.py +59 -0
  103. package/src/ummaya/tools/routing/builder.py +105 -0
  104. package/src/ummaya/tools/routing/cards.py +29 -0
  105. package/src/ummaya/tools/routing/decision_service.py +534 -0
  106. package/src/ummaya/tools/routing/decision_types.py +74 -0
  107. package/src/ummaya/tools/routing/feasibility.py +122 -0
  108. package/src/ummaya/tools/routing/intent.py +17 -0
  109. package/src/ummaya/tools/routing/intent_extractor.py +207 -0
  110. package/src/ummaya/tools/routing/intent_patterns.py +160 -0
  111. package/src/ummaya/tools/routing/intent_public_data.py +150 -0
  112. package/src/ummaya/tools/routing/intent_types.py +48 -0
  113. package/src/ummaya/tools/routing/lint.py +78 -0
  114. package/src/ummaya/tools/routing/metadata.py +174 -0
  115. package/src/ummaya/tools/routing/projection.py +340 -0
  116. package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
  117. package/src/ummaya/tools/routing/schema.py +81 -0
  118. package/src/ummaya/tools/routing/types.py +96 -0
  119. package/src/ummaya/tools/routing_index.py +2 -2
  120. package/src/ummaya/tools/search.py +34 -746
  121. package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
  122. package/tui/bun.lock +126 -305
  123. package/tui/package.json +35 -22
  124. package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
  125. package/tui/src/QueryEngine.ts +12 -8
  126. package/tui/src/bridge/inboundAttachments.ts +3 -3
  127. package/tui/src/cli/handlers/auth.ts +3 -12
  128. package/tui/src/cli/handlers/mcp.tsx +0 -1
  129. package/tui/src/cli/print.ts +8 -9
  130. package/tui/src/commands/insights.ts +1 -1
  131. package/tui/src/commands/install-github-app/types.ts +8 -30
  132. package/tui/src/commands/plugin/types.ts +6 -28
  133. package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
  134. package/tui/src/commands/rename/generateSessionName.ts +1 -1
  135. package/tui/src/components/Feedback.tsx +1 -1
  136. package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
  137. package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
  138. package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
  139. package/tui/src/components/Spinner/types.ts +6 -28
  140. package/tui/src/components/agents/generateAgent.ts +1 -1
  141. package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
  142. package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
  143. package/tui/src/components/mcp/types.ts +16 -38
  144. package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
  145. package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
  146. package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
  147. package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
  148. package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
  149. package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
  150. package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
  151. package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
  152. package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
  153. package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
  154. package/tui/src/components/primitive/index.tsx +43 -1
  155. package/tui/src/components/primitive/types.ts +137 -0
  156. package/tui/src/components/ui/option.ts +4 -26
  157. package/tui/src/constants/common.ts +0 -2
  158. package/tui/src/constants/prompts.ts +4 -3
  159. package/tui/src/constants/querySource.ts +4 -26
  160. package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
  161. package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
  162. package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
  163. package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
  164. package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
  165. package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
  166. package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
  167. package/tui/src/hooks/useApiKeyVerification.ts +1 -1
  168. package/tui/src/hooks/useVirtualScroll.ts +1 -1
  169. package/tui/src/ink/ink.tsx +33 -14
  170. package/tui/src/ink/reconciler.ts +2 -3
  171. package/tui/src/ink/render-to-screen.ts +30 -10
  172. package/tui/src/ipc/bridge.ts +62 -15
  173. package/tui/src/ipc/bridgeSingleton.ts +5 -1
  174. package/tui/src/ipc/codec.ts +3 -3
  175. package/tui/src/ipc/frames.generated.ts +12 -12
  176. package/tui/src/ipc/llmClient.ts +151 -27
  177. package/tui/src/ipc/schema/frame.schema.json +1 -1
  178. package/tui/src/keybindings/defaultBindings.ts +4 -0
  179. package/tui/src/main.tsx +32 -15
  180. package/tui/src/native-ts/file-index/index.ts +33 -3
  181. package/tui/src/observability/surface.ts +2 -2
  182. package/tui/src/probes/toolRegistryProbe.tsx +3 -1
  183. package/tui/src/projectOnboardingState.ts +7 -6
  184. package/tui/src/query/chatMessageTypes.ts +18 -0
  185. package/tui/src/query/chatMessagesBuilder.ts +1 -1
  186. package/tui/src/query/deps.ts +1 -1
  187. package/tui/src/query/messageGuards.ts +106 -0
  188. package/tui/src/query/publicDataTerminalRepair.ts +384 -0
  189. package/tui/src/query/run.ts +1075 -0
  190. package/tui/src/query/supportBoundary.ts +168 -0
  191. package/tui/src/query/toolResultErrors.ts +103 -0
  192. package/tui/src/query/toolRunner.ts +687 -0
  193. package/tui/src/query/unavailableToolRepair.ts +118 -0
  194. package/tui/src/query.ts +9 -2186
  195. package/tui/src/screens/REPL.tsx +40 -29
  196. package/tui/src/services/api/adapterManifest.ts +4 -0
  197. package/tui/src/services/api/backendChat/events.ts +117 -0
  198. package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
  199. package/tui/src/services/api/backendChat/frame.ts +9 -0
  200. package/tui/src/services/api/backendChat/streaming.ts +430 -0
  201. package/tui/src/services/api/backendChat/types.ts +62 -0
  202. package/tui/src/services/api/backendChat.ts +1 -0
  203. package/tui/src/services/api/client.ts +65 -2
  204. package/tui/src/services/api/errorUtils.ts +5 -5
  205. package/tui/src/services/api/errors.ts +1 -1
  206. package/tui/src/services/api/logging.ts +1 -1
  207. package/tui/src/services/api/ummaya/evidence.ts +194 -0
  208. package/tui/src/services/api/ummaya/messages.ts +255 -0
  209. package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
  210. package/tui/src/services/api/ummaya/provider.ts +200 -0
  211. package/tui/src/services/api/ummaya/reasoning.ts +24 -0
  212. package/tui/src/services/api/ummaya/request.ts +200 -0
  213. package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
  214. package/tui/src/services/api/ummaya/streaming.ts +365 -0
  215. package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
  216. package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
  217. package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
  218. package/tui/src/services/api/ummaya/types.ts +110 -0
  219. package/tui/src/services/api/ummaya/usage.ts +30 -0
  220. package/tui/src/services/api/ummaya.ts +26 -418
  221. package/tui/src/services/api/withRetry.ts +1 -1
  222. package/tui/src/services/awaySummary.ts +2 -2
  223. package/tui/src/services/claudeAiLimits.ts +1 -1
  224. package/tui/src/services/compact/autoCompact.ts +1 -1
  225. package/tui/src/services/compact/compact.ts +1 -1
  226. package/tui/src/services/lsp/types.ts +8 -30
  227. package/tui/src/services/tips/types.ts +6 -28
  228. package/tui/src/services/tokenEstimation.ts +1 -1
  229. package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
  230. package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
  231. package/tui/src/services/tools/toolExecution.ts +94 -1
  232. package/tui/src/store/pendingPermissionSlot.ts +1 -1
  233. package/tui/src/store/session-store.ts +10 -36
  234. package/tui/src/stubs/any-stub.ts +15 -10
  235. package/tui/src/stubs/color-diff-napi.ts +37 -23
  236. package/tui/src/stubs/globals.d.ts +3 -3
  237. package/tui/src/stubs/macro-preload.ts +23 -12
  238. package/tui/src/tools/AdapterTool/AdapterTool.ts +1207 -714
  239. package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
  240. package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
  241. package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
  242. package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
  243. package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
  244. package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
  245. package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
  246. package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
  247. package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
  248. package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
  249. package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
  250. package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
  251. package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
  252. package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
  253. package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
  254. package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
  255. package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
  256. package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
  257. package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
  258. package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
  259. package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
  260. package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
  261. package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
  262. package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
  263. package/tui/src/tools/AgentTool/permissions.ts +39 -0
  264. package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
  265. package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
  266. package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
  267. package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
  268. package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
  269. package/tui/src/tools/AgentTool/runAgent.ts +1 -1
  270. package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
  271. package/tui/src/tools/AgentTool/schemas.ts +196 -0
  272. package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
  273. package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
  274. package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
  275. package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
  276. package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
  277. package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
  278. package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
  279. package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
  280. package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
  281. package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
  282. package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
  283. package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
  284. package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
  285. package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
  286. package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
  287. package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
  288. package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
  289. package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
  290. package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
  291. package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
  292. package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
  293. package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
  294. package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
  295. package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
  296. package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
  297. package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
  298. package/tui/src/tools/BashTool/call.ts +202 -0
  299. package/tui/src/tools/BashTool/callLoader.ts +35 -0
  300. package/tui/src/tools/BashTool/commandClassification.ts +151 -0
  301. package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
  302. package/tui/src/tools/BashTool/cwdReset.ts +33 -0
  303. package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
  304. package/tui/src/tools/BashTool/modeValidation.ts +13 -1
  305. package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
  306. package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
  307. package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
  308. package/tui/src/tools/BashTool/resultLoader.ts +29 -0
  309. package/tui/src/tools/BashTool/resultMapping.ts +83 -0
  310. package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
  311. package/tui/src/tools/BashTool/schemas.ts +65 -0
  312. package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
  313. package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
  314. package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
  315. package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
  316. package/tui/src/tools/BashTool/uiLoader.ts +37 -0
  317. package/tui/src/tools/BriefTool/upload.ts +1 -1
  318. package/tui/src/tools/CalculatorTool/parser.ts +2 -2
  319. package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
  320. package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
  321. package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
  322. package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
  323. package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
  324. package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
  325. package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
  326. package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
  327. package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
  328. package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
  329. package/tui/src/tools/FileEditTool/call.ts +228 -0
  330. package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
  331. package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
  332. package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
  333. package/tui/src/tools/FileWriteTool/call.ts +223 -0
  334. package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
  335. package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
  336. package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +25 -32
  337. package/tui/src/tools/LookupPrimitive/prompt.ts +0 -2
  338. package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
  339. package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
  340. package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
  341. package/tui/src/tools/NotebookEditTool/call.ts +254 -0
  342. package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
  343. package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
  344. package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
  345. package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
  346. package/tui/src/tools/PowerShellTool/call.ts +179 -0
  347. package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
  348. package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
  349. package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
  350. package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
  351. package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
  352. package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
  353. package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
  354. package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
  355. package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
  356. package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
  357. package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
  358. package/tui/src/tools/PowerShellTool/validation.ts +39 -0
  359. package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
  360. package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +1 -11
  361. package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
  362. package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
  363. package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +27 -10
  364. package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
  365. package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
  366. package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
  367. package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
  368. package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
  369. package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
  370. package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
  371. package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
  372. package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
  373. package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
  374. package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
  375. package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
  376. package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
  377. package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
  378. package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
  379. package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
  380. package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
  381. package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
  382. package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
  383. package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
  384. package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
  385. package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
  386. package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
  387. package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
  388. package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
  389. package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +2 -1
  390. package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
  391. package/tui/src/tools/WebFetchTool/call.ts +227 -0
  392. package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
  393. package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
  394. package/tui/src/tools/WebFetchTool/types.ts +23 -0
  395. package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
  396. package/tui/src/tools/WebFetchTool/utils.ts +1 -1
  397. package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
  398. package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
  399. package/tui/src/tools/WebSearchTool/call.ts +33 -0
  400. package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
  401. package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
  402. package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
  403. package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
  404. package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
  405. package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
  406. package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
  407. package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
  408. package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
  409. package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
  410. package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
  411. package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
  412. package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
  413. package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
  414. package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
  415. package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
  416. package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
  417. package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
  418. package/tui/src/tools/_shared/rootPrimitiveInput.ts +1 -0
  419. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
  420. package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
  421. package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
  422. package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
  423. package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
  424. package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
  425. package/tui/src/tools/_shared/toolChoiceRepair.ts +55 -860
  426. package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
  427. package/tui/src/tools.ts +39 -190
  428. package/tui/src/types/fileSuggestion.ts +4 -26
  429. package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
  430. package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
  431. package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
  432. package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
  433. package/tui/src/types/message.ts +80 -102
  434. package/tui/src/types/messageQueueTypes.ts +6 -28
  435. package/tui/src/types/notebook.ts +16 -38
  436. package/tui/src/types/statusLine.ts +4 -26
  437. package/tui/src/types/tools.ts +24 -46
  438. package/tui/src/types/utils.ts +6 -28
  439. package/tui/src/upstreamproxy/relay.ts +7 -3
  440. package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
  441. package/tui/src/utils/assistantMessageFactories.ts +9 -3
  442. package/tui/src/utils/auth.ts +129 -139
  443. package/tui/src/utils/bash/ast.ts +23 -23
  444. package/tui/src/utils/bash/bashParser.ts +5 -5
  445. package/tui/src/utils/billing.ts +1 -1
  446. package/tui/src/utils/claudeDesktop.ts +4 -4
  447. package/tui/src/utils/collapseReadSearch.ts +3 -3
  448. package/tui/src/utils/cronTasks.ts +1 -1
  449. package/tui/src/utils/execFileNoThrow.ts +1 -1
  450. package/tui/src/utils/filePersistence/types.ts +16 -38
  451. package/tui/src/utils/forkedAgent.ts +1 -1
  452. package/tui/src/utils/gracefulShutdown.ts +4 -4
  453. package/tui/src/utils/heapDumpService.ts +12 -8
  454. package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
  455. package/tui/src/utils/hooks/execPromptHook.ts +1 -1
  456. package/tui/src/utils/hooks/skillImprovement.ts +1 -1
  457. package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
  458. package/tui/src/utils/messages.ts +18 -0
  459. package/tui/src/utils/migrateSessions.ts +3 -3
  460. package/tui/src/utils/model/model.ts +6 -6
  461. package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
  462. package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
  463. package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
  464. package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
  465. package/tui/src/utils/plugins/pluginLoader.ts +8 -8
  466. package/tui/src/utils/protectedNamespace.ts +5 -3
  467. package/tui/src/utils/rawJsonToolCall.ts +242 -0
  468. package/tui/src/utils/ripgrep.ts +16 -7
  469. package/tui/src/utils/sessionTitle.ts +1 -1
  470. package/tui/src/utils/settings/permissionValidation.ts +14 -2
  471. package/tui/src/utils/shell/prefix.ts +1 -1
  472. package/tui/src/utils/sideQuery.ts +1 -1
  473. package/tui/src/utils/systemThemeWatcher.ts +13 -3
  474. package/tui/src/utils/teleport.tsx +1 -1
  475. package/uv.lock +426 -45
  476. package/tui/src/services/api/claude.ts +0 -3540
  477. package/tui/src/tools/_shared/directPublicDataGuard.ts +0 -362
  478. package/tui/src/tools/_shared/kmaAnalysisGuard.ts +0 -197
  479. package/tui/src/tools/_shared/kmaAviationGuard.ts +0 -70
  480. package/tui/src/tools/_shared/nmcAedGuard.ts +0 -234
  481. package/tui/src/tools/_shared/protectedCheckGuard.ts +0 -207
  482. package/tui/src/tools/_shared/textToolCallGuard.ts +0 -91
@@ -132,7 +132,7 @@ import { getGlobalConfig, saveGlobalConfig, getGlobalConfigWriteCount } from '..
132
132
  import { hasConsoleBillingAccess } from '../utils/billing.js';
133
133
  import { logEvent, type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS } from 'src/services/analytics/index.js';
134
134
  import { getFeatureValue_CACHED_MAY_BE_STALE } from 'src/services/analytics/growthbook.js';
135
- import { textForResubmit, handleMessageFromStream, type StreamingToolUse, type StreamingThinking, isCompactBoundaryMessage, getMessagesAfterCompactBoundary, getContentText, createUserMessage, createAssistantMessage, createTurnDurationMessage, createAgentsKilledMessage, createApiMetricsMessage, createSystemMessage, createCommandInputMessage, formatCommandInputTags } from '../utils/messages.js';
135
+ import { textForResubmit, handleMessageFromStream, type StreamingToolUse, type StreamingThinking, isCompactBoundaryMessage, getMessagesAfterCompactBoundary, getContentText, createUserMessage, createTurnDurationMessage, createAgentsKilledMessage, createApiMetricsMessage, createSystemMessage, createCommandInputMessage, finalizeStreamingAssistantMessage, formatCommandInputTags } from '../utils/messages.js';
136
136
  import { generateSessionTitle } from '../utils/sessionTitle.js';
137
137
  import { BASH_INPUT_TAG, COMMAND_MESSAGE_TAG, COMMAND_NAME_TAG, LOCAL_COMMAND_STDOUT_TAG } from '../constants/xml.js';
138
138
  import { escapeXml } from '../utils/xml.js';
@@ -713,7 +713,7 @@ export function REPL({
713
713
  // Incremented on transcript exit. Async v-render captures this at start;
714
714
  // each status write no-ops if stale (user left transcript mid-render —
715
715
  // the stable setState would otherwise stamp a ghost toast into the next
716
- // session). Also clears any pending 4s auto-clear.
716
+ // session). Also clears a pending 4s auto-clear.
717
717
  const editorGenRef = useRef(0);
718
718
  const editorTimerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
719
719
  const editorRenderingRef = useRef(false);
@@ -910,7 +910,7 @@ export function REPL({
910
910
  // Initialize true if remote mode with initial prompt (CCR processing it).
911
911
  const [isExternalLoading, setIsExternalLoadingRaw] = React.useState(remoteSessionConfig?.hasInitialPrompt ?? false);
912
912
 
913
- // Derived: any loading source active. Read-only — no setter. Local query
913
+ // Derived: a loading source is active. Read-only — no setter. Local query
914
914
  // loading is driven by queryGuard (reserve/tryStart/end/cancelReservation),
915
915
  // external loading by setIsExternalLoading.
916
916
  const isLoading = isQueryActive || isExternalLoading;
@@ -1091,7 +1091,7 @@ export function REPL({
1091
1091
  return;
1092
1092
  }
1093
1093
 
1094
- // No active local JSX command, allow any update
1094
+ // No active local JSX command, allow updates
1095
1095
  if (args?.clearLocalJSX) {
1096
1096
  setToolJSXInternal(null);
1097
1097
  return;
@@ -1254,7 +1254,7 @@ export function REPL({
1254
1254
  // eslint-disable-next-line react-hooks/exhaustive-deps -- length change covers appends; useUnseenDivider's count-drop guard clears dividerIndex on replace/rewind
1255
1255
  [dividerIndex, messages.length]);
1256
1256
  // Re-pin scroll to bottom and clear the unseen-messages baseline. Called
1257
- // on any user-driven return-to-live action (submit, type-into-empty,
1257
+ // on user-driven return-to-live actions (submit, type-into-empty,
1258
1258
  // overlay appear/dismiss).
1259
1259
  const repinScroll = useCallback(() => {
1260
1260
  scrollRef.current?.scrollToBottom();
@@ -1326,7 +1326,7 @@ export function REPL({
1326
1326
  messagesLength: number;
1327
1327
  streamingToolUsesLength: number;
1328
1328
  } | null>(null);
1329
- // Initialize input with any early input that was captured before REPL was ready.
1329
+ // Initialize input with early input captured before REPL was ready.
1330
1330
  // Using lazy initialization ensures cursor offset is set correctly in PromptInput.
1331
1331
  const [inputValue, setInputValueRaw] = useState(() => consumeEarlyInput());
1332
1332
  const inputValueRef = useRef(inputValue);
@@ -1459,18 +1459,18 @@ export function REPL({
1459
1459
  // throttle batches rapid updates). Cleared on message arrival (messages.ts)
1460
1460
  // so displayedMessages switches from deferredMessages to messages atomically.
1461
1461
  const [streamingText, setStreamingText] = useState<string | null>(null);
1462
+ const streamingTextRef = useRef<string | null>(null);
1463
+ const turnStartMessageCountRef = useRef(0);
1462
1464
  const reducedMotion = useAppState(s => s.settings.prefersReducedMotion) ?? false;
1463
1465
  const showStreamingText = !reducedMotion && !hasCursorUpViewportYankBug();
1464
1466
  const onStreamingText = useCallback((f: (current: string | null) => string | null) => {
1467
+ const nextStreamingText = f(streamingTextRef.current);
1468
+ streamingTextRef.current = nextStreamingText;
1465
1469
  if (!showStreamingText) return;
1466
- setStreamingText(f);
1470
+ setStreamingText(nextStreamingText);
1467
1471
  }, [showStreamingText]);
1468
1472
 
1469
- // Hide the in-progress source line so text streams line-by-line, not
1470
- // char-by-char. lastIndexOf returns -1 when no newline, giving '' → null.
1471
- // Guard on showStreamingText so toggling reducedMotion mid-stream
1472
- // immediately hides the streaming preview.
1473
- const visibleStreamingText = streamingText && showStreamingText ? streamingText.substring(0, streamingText.lastIndexOf('\n') + 1) || null : null;
1473
+ const visibleStreamingText = streamingText && showStreamingText ? streamingText.substring(0, streamingText.lastIndexOf('\n') + 1) || streamingText : null;
1474
1474
  const [lastQueryCompletionTime, setLastQueryCompletionTime] = useState(0);
1475
1475
  const [spinnerMessage, setSpinnerMessage] = useState<string | null>(null);
1476
1476
  const [spinnerColor, setSpinnerColor] = useState<keyof Theme | null>(null);
@@ -1573,6 +1573,7 @@ export function REPL({
1573
1573
  setUserInputOnProcessing(undefined);
1574
1574
  responseLengthRef.current = 0;
1575
1575
  apiMetricsRef.current = [];
1576
+ streamingTextRef.current = null;
1576
1577
  setStreamingText(null);
1577
1578
  setStreamingToolUses([]);
1578
1579
  setSpinnerMessage(null);
@@ -1586,6 +1587,16 @@ export function REPL({
1586
1587
  clearSpeculativeChecks();
1587
1588
  }, [pickNewSpinnerTip]);
1588
1589
 
1590
+ const finalizeStreamingAssistantIfNeeded = useCallback(() => {
1591
+ setMessages(prev =>
1592
+ finalizeStreamingAssistantMessage({
1593
+ messages: prev,
1594
+ streamingText: streamingTextRef.current,
1595
+ turnStartMessageCount: turnStartMessageCountRef.current,
1596
+ }),
1597
+ );
1598
+ }, [setMessages]);
1599
+
1589
1600
  // Session backgrounding — hook is below, after getToolUseContext
1590
1601
 
1591
1602
  const hasRunningTeammates = useMemo(() => getAllInProcessTeammateTasks(tasks).some(t => t.status === 'running'), [tasks]);
@@ -1684,7 +1695,7 @@ export function REPL({
1684
1695
  // but keep it when isBriefOnly suppresses the streaming text display
1685
1696
  !visibleStreamingText || isBriefOnly);
1686
1697
 
1687
- // Check if any permission or ask question prompt is currently visible
1698
+ // Check whether a permission or ask-question prompt is currently visible
1688
1699
  // This is used to prevent the survey from opening while prompts are active
1689
1700
  const hasActivePrompt = toolUseConfirmQueue.length > 0 || promptQueue.length > 0 || sandboxPermissionRequestQueue.length > 0 || elicitation.queue.length > 0 || workerSandboxPermissions.queue.length > 0;
1690
1701
  const feedbackSurveyOriginal = useFeedbackSurvey(messages, isLoading, submitCount, 'session', hasActivePrompt);
@@ -1825,7 +1836,7 @@ export function REPL({
1825
1836
  // Restore read file state from the message history
1826
1837
  restoreReadFileState(messages, log.projectPath ?? getOriginalCwd());
1827
1838
 
1828
- // Clear any active loading state (no queryId since we're not in a query)
1839
+ // Clear active loading state (no queryId since we're not in a query)
1829
1840
  resetLoadingState();
1830
1841
  setAbortController(null);
1831
1842
  setConversationId(sessionId);
@@ -1864,7 +1875,7 @@ export function REPL({
1864
1875
  haikuTitleAttemptedRef.current = true;
1865
1876
  setHaikuTitle(undefined);
1866
1877
 
1867
- // Exit any worktree a prior /resume entered, then cd into the one
1878
+ // Exit the worktree a prior /resume entered, then cd into the one
1868
1879
  // this session was in. Without the exit, resuming from worktree B
1869
1880
  // to non-worktree C leaves cwd/currentWorktreeSession stale;
1870
1881
  // resuming B→C where C is also a worktree fails entirely
@@ -1910,7 +1921,7 @@ export function REPL({
1910
1921
  }
1911
1922
 
1912
1923
  // Reconstruct replacement state for the resumed session. Runs after
1913
- // setSessionId so any NEW replacements post-resume write to the
1924
+ // setSessionId so NEW replacements post-resume write to the
1914
1925
  // resumed session's tool-results dir. Gated on ref.current: the
1915
1926
  // initial mount already read the feature flag, so we don't re-read
1916
1927
  // it here (mid-session flag flips stay unobservable in both
@@ -1928,7 +1939,7 @@ export function REPL({
1928
1939
  // Use a callback to ensure we're not dependent on stale state
1929
1940
  setMessages(() => messages);
1930
1941
 
1931
- // Clear any active tool JSX
1942
+ // Clear active tool JSX
1932
1943
  setToolJSX(null);
1933
1944
 
1934
1945
  // Clear input to ensure no residual state
@@ -2010,7 +2021,7 @@ export function REPL({
2010
2021
  // Calculate if cost dialog should be shown
2011
2022
  const showingCostDialog = !isLoading && showCostDialog;
2012
2023
 
2013
- // Determine which dialog should have focus (if any)
2024
+ // Determine which dialog should have focus, when one exists
2014
2025
  // Permission and interactive dialogs can show even when toolJSX is set,
2015
2026
  // as long as shouldContinueAnimation is true. This prevents deadlocks when
2016
2027
  // agents set background hints while waiting for user interaction.
@@ -2105,7 +2116,7 @@ export function REPL({
2105
2116
  }, [focusedInputDialog, repinScroll]);
2106
2117
  function onCancel() {
2107
2118
  if (focusedInputDialog === 'elicitation') {
2108
- // Elicitation dialog handles its own Escape, and closing it shouldn't affect any loading state.
2119
+ // Elicitation dialog handles its own Escape, and closing it shouldn't affect loading state.
2109
2120
  return;
2110
2121
  }
2111
2122
  logForDebugging(`[onCancel] focusedInputDialog=${focusedInputDialog} streamMode=${streamMode}`);
@@ -2122,14 +2133,10 @@ export function REPL({
2122
2133
  // generated before pressing Esc. Pushed before resetLoadingState clears
2123
2134
  // streamingText, and before query.ts yields the async interrupt marker,
2124
2135
  // giving final order [user, partial-assistant, [Request interrupted by user]].
2125
- if (streamingText?.trim()) {
2126
- setMessages(prev => [...prev, createAssistantMessage({
2127
- content: streamingText
2128
- })]);
2129
- }
2136
+ finalizeStreamingAssistantIfNeeded();
2130
2137
  resetLoadingState();
2131
2138
 
2132
- // Clear any active token budget so the backstop doesn't fire on
2139
+ // Clear active token budget so the backstop doesn't fire on
2133
2140
  // a stale budget if the query generator hasn't exited yet.
2134
2141
  if (feature('TOKEN_BUDGET')) {
2135
2142
  snapshotOutputTokensForTurn(null);
@@ -2671,7 +2678,7 @@ export function REPL({
2671
2678
  }
2672
2679
  }
2673
2680
 
2674
- // Mark onboarding as complete when any user message is sent to UMMAYA.
2681
+ // Mark onboarding as complete when a user message is sent to UMMAYA.
2675
2682
  void maybeMarkProjectOnboardingComplete();
2676
2683
 
2677
2684
  // Extract a session title from the first real user message. One-shot
@@ -2844,6 +2851,7 @@ export function REPL({
2844
2851
  configWriteCount: getGlobalConfigWriteCount()
2845
2852
  })]);
2846
2853
  }
2854
+ finalizeStreamingAssistantIfNeeded();
2847
2855
  resetLoadingState();
2848
2856
 
2849
2857
  // Log query profiling report if enabled
@@ -2896,6 +2904,7 @@ export function REPL({
2896
2904
  }
2897
2905
  apiMetricsRef.current = [];
2898
2906
  setStreamingToolUses([]);
2907
+ streamingTextRef.current = null;
2899
2908
  setStreamingText(null);
2900
2909
 
2901
2910
  // messagesRef is updated synchronously by the setMessages wrapper
@@ -2904,6 +2913,7 @@ export function REPL({
2904
2913
  // React's scheduler (previously cost 20-56ms per prompt; the 56ms
2905
2914
  // case was a GC pause caught during the await).
2906
2915
  const latestMessages = messagesRef.current;
2916
+ turnStartMessageCountRef.current = latestMessages.length;
2907
2917
  if (input) {
2908
2918
  await mrOnBeforeQuery(input, latestMessages, newMessages.length);
2909
2919
  }
@@ -2926,6 +2936,7 @@ export function REPL({
2926
2936
  // Always reset loading state in finally - this ensures cleanup even
2927
2937
  // if onQueryImpl throws. onTurnComplete is called separately in
2928
2938
  // onQueryImpl only on successful completion.
2939
+ finalizeStreamingAssistantIfNeeded();
2929
2940
  resetLoadingState();
2930
2941
  await mrOnTurnComplete(messagesRef.current, abortController.signal.aborted);
2931
2942
 
@@ -2993,7 +3004,7 @@ export function REPL({
2993
3004
  setAbortController(null);
2994
3005
  }
2995
3006
 
2996
- // Auto-restore: if the user interrupted before any meaningful response
3007
+ // Auto-restore: if the user interrupted before a meaningful response
2997
3008
  // arrived, rewind the conversation and restore their prompt — same as
2998
3009
  // opening the message selector and picking the last message.
2999
3010
  // This runs OUTSIDE the queryGuard.end() check because onCancel calls
@@ -3281,7 +3292,7 @@ export function REPL({
3281
3292
  }
3282
3293
  }
3283
3294
 
3284
- // Remote mode: skip empty input early before any state mutations
3295
+ // Remote mode: skip empty input early before state mutations
3285
3296
  if (activeRemote.isRemoteMode && !input.trim()) {
3286
3297
  return;
3287
3298
  }
@@ -4163,7 +4174,7 @@ export function REPL({
4163
4174
  return 'hookEvent' in attachment && (attachment.hookEvent === 'Stop' || attachment.hookEvent === 'SubagentStop') && 'toolUseID' in attachment && attachment.toolUseID === currentToolUseID;
4164
4175
  });
4165
4176
 
4166
- // Check if any hook has a custom status message
4177
+ // Check whether a hook has a custom status message
4167
4178
  const customMessage = currentHooks.find(p => p.data.statusMessage)?.data.statusMessage;
4168
4179
  if (customMessage) {
4169
4180
  // Use custom message with progress counter if multiple hooks
@@ -94,6 +94,10 @@ export function listAdapters(): AdapterManifestEntry[] {
94
94
  )
95
95
  }
96
96
 
97
+ export function getAdapterManifestHash(): string | null {
98
+ return _cache?.manifestHash ?? null
99
+ }
100
+
97
101
  /**
98
102
  * Returns ``true`` when at least one manifest frame has been ingested.
99
103
  *
@@ -0,0 +1,117 @@
1
+ import { SYNTHETIC_MODEL } from '../../../utils/messageText.js'
2
+ import type { PendingToolUseBlock } from './types.js'
3
+
4
+ const EMPTY_USAGE = {
5
+ input_tokens: 0,
6
+ output_tokens: 0,
7
+ cache_creation_input_tokens: 0,
8
+ cache_read_input_tokens: 0,
9
+ }
10
+
11
+ export function createMessageStartStreamEvent(
12
+ innerMessageId: string,
13
+ ttftMs: number,
14
+ ): unknown {
15
+ return {
16
+ type: 'stream_event' as const,
17
+ event: {
18
+ type: 'message_start' as const,
19
+ message: {
20
+ id: innerMessageId,
21
+ type: 'message',
22
+ role: 'assistant',
23
+ content: [],
24
+ model: SYNTHETIC_MODEL,
25
+ stop_reason: null,
26
+ stop_sequence: null,
27
+ usage: EMPTY_USAGE,
28
+ },
29
+ },
30
+ ttftMs,
31
+ }
32
+ }
33
+
34
+ export function createThinkingBlockStartEvent(index: number): unknown {
35
+ return {
36
+ type: 'stream_event' as const,
37
+ event: {
38
+ type: 'content_block_start' as const,
39
+ index,
40
+ content_block: { type: 'thinking' as const, thinking: '' },
41
+ },
42
+ }
43
+ }
44
+
45
+ export function createTextBlockStartEvent(index: number): unknown {
46
+ return {
47
+ type: 'stream_event' as const,
48
+ event: {
49
+ type: 'content_block_start' as const,
50
+ index,
51
+ content_block: { type: 'text' as const, text: '' },
52
+ },
53
+ }
54
+ }
55
+
56
+ export function createThinkingDeltaEvent(index: number, thinking: string): unknown {
57
+ return {
58
+ type: 'stream_event' as const,
59
+ event: {
60
+ type: 'content_block_delta' as const,
61
+ index,
62
+ delta: { type: 'thinking_delta' as const, thinking },
63
+ },
64
+ }
65
+ }
66
+
67
+ export function createTextDeltaEvent(index: number, text: string): unknown {
68
+ return {
69
+ type: 'stream_event' as const,
70
+ event: {
71
+ type: 'content_block_delta' as const,
72
+ index,
73
+ delta: { type: 'text_delta' as const, text },
74
+ },
75
+ }
76
+ }
77
+
78
+ export function createContentBlockStopEvent(index: number): unknown {
79
+ return {
80
+ type: 'stream_event' as const,
81
+ event: { type: 'content_block_stop' as const, index },
82
+ }
83
+ }
84
+
85
+ export function createToolUseBlockStartEvent(
86
+ index: number,
87
+ contentBlock: PendingToolUseBlock,
88
+ ): unknown {
89
+ return {
90
+ type: 'stream_event' as const,
91
+ event: {
92
+ type: 'content_block_start' as const,
93
+ index,
94
+ content_block: contentBlock,
95
+ },
96
+ }
97
+ }
98
+
99
+ export function createMessageDeltaEvent(
100
+ stopReason: 'end_turn' | 'tool_use',
101
+ ): unknown {
102
+ return {
103
+ type: 'stream_event' as const,
104
+ event: {
105
+ type: 'message_delta' as const,
106
+ delta: { stop_reason: stopReason, stop_sequence: null },
107
+ usage: { output_tokens: 0 },
108
+ },
109
+ }
110
+ }
111
+
112
+ export function createMessageStopEvent(): unknown {
113
+ return {
114
+ type: 'stream_event' as const,
115
+ event: { type: 'message_stop' as const },
116
+ }
117
+ }
@@ -0,0 +1,40 @@
1
+ import { createAssistantMessage } from '../../../utils/assistantMessageFactories.js'
2
+ import type { PendingToolUseBlock } from './types.js'
3
+
4
+ type FinalAssistantBlock =
5
+ | { readonly type: 'thinking'; readonly thinking: string }
6
+ | { readonly type: 'text'; readonly text: string }
7
+ | PendingToolUseBlock
8
+
9
+ export function createFinalAssistantMessage({
10
+ accumulated,
11
+ accumulatedThinking,
12
+ messageUuid,
13
+ innerMessageId,
14
+ pendingContentBlocks,
15
+ persistThinking,
16
+ }: {
17
+ readonly accumulated: string
18
+ readonly accumulatedThinking: string
19
+ readonly messageUuid: string
20
+ readonly innerMessageId: string
21
+ readonly pendingContentBlocks: readonly PendingToolUseBlock[]
22
+ readonly persistThinking: boolean
23
+ }): unknown {
24
+ const trimmedText = accumulated.trimStart()
25
+ const blocks: FinalAssistantBlock[] = []
26
+ if (persistThinking && accumulatedThinking.length > 0) {
27
+ blocks.push({ type: 'thinking', thinking: accumulatedThinking })
28
+ }
29
+ if (trimmedText.length > 0) {
30
+ blocks.push({ type: 'text', text: trimmedText })
31
+ }
32
+ blocks.push(...pendingContentBlocks)
33
+
34
+ const finalMessage = createAssistantMessage({
35
+ content: blocks.length > 0 ? blocks : trimmedText,
36
+ })
37
+ finalMessage.uuid = messageUuid
38
+ finalMessage.message.id = innerMessageId
39
+ return finalMessage
40
+ }
@@ -0,0 +1,9 @@
1
+ import type { ChatMessage, ChatRequestFrame } from '../../../ipc/frames.generated.js'
2
+
3
+ export function toNonEmptyMessages(
4
+ messages: readonly ChatMessage[],
5
+ ): ChatRequestFrame['messages'] {
6
+ const [first, ...rest] = messages
7
+ if (first === undefined) return [{ role: 'user', content: '' }]
8
+ return [first, ...rest]
9
+ }