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
@@ -46,6 +46,10 @@ type WebSocketLike = Pick<
46
46
  | 'binaryType'
47
47
  >
48
48
 
49
+ type BunWebSocketConstructor = {
50
+ new (url: string | URL, options?: Bun.WebSocketOptions): WebSocket
51
+ }
52
+
49
53
  // Envoy per-request buffer cap. Week-1 Datadog payloads won't hit this, but
50
54
  // design for it so git-push doesn't need a relay rewrite.
51
55
  const MAX_CHUNK_BYTES = 512 * 1024
@@ -363,10 +367,10 @@ function openTunnel(
363
367
  headers,
364
368
  agent: getWebSocketProxyAgent(wsUrl),
365
369
  ...getWebSocketTLSOptions(),
366
- }) as unknown as WebSocketLike
370
+ })
367
371
  } else {
368
- ws = new globalThis.WebSocket(wsUrl, {
369
- // @ts-expect-error Bun extension; not in lib.dom WebSocket types
372
+ const BunWebSocket = globalThis.WebSocket as BunWebSocketConstructor
373
+ ws = new BunWebSocket(wsUrl, {
370
374
  headers,
371
375
  proxy: getWebSocketProxyUrl(wsUrl),
372
376
  tls: getWebSocketTLSOptions() || undefined,
@@ -13,7 +13,7 @@
13
13
  * so a supervisor restart can retry)
14
14
  * 6. Exposes HTTPS_PROXY / SSL_CERT_FILE env vars for all agent subprocesses
15
15
  *
16
- * Every step fails open: any error logs a warning and disables the proxy.
16
+ * Every step fails open: each error logs a warning and disables the proxy.
17
17
  * A broken proxy setup must never break an otherwise-working session.
18
18
  *
19
19
  * Design doc: api-go/ccr/docs/plans/CCR_AUTH_DESIGN.md § "Week-1 pilot scope".
@@ -1,4 +1,8 @@
1
- import type { BetaContentBlock, BetaUsage as Usage } from 'src/sdk-compat.js'
1
+ import type {
2
+ BetaContentBlock,
3
+ BetaUsage as Usage,
4
+ ThinkingBlock,
5
+ } from 'src/sdk-compat.js'
2
6
  import type { SDKAssistantMessageError } from 'src/entrypoints/agentSdkTypes.js'
3
7
  import { randomUUID } from 'crypto'
4
8
  import { NO_CONTENT_MESSAGE } from '../constants/messages.js'
@@ -21,6 +25,8 @@ const EMPTY_USAGE: Usage = {
21
25
  speed: null,
22
26
  }
23
27
 
28
+ type AssistantContentBlock = BetaContentBlock | ThinkingBlock
29
+
24
30
  function baseCreateAssistantMessage({
25
31
  content,
26
32
  isApiErrorMessage = false,
@@ -30,7 +36,7 @@ function baseCreateAssistantMessage({
30
36
  isVirtual,
31
37
  usage = EMPTY_USAGE,
32
38
  }: {
33
- content: BetaContentBlock[]
39
+ content: AssistantContentBlock[]
34
40
  isApiErrorMessage?: boolean
35
41
  apiError?: AssistantMessage['apiError']
36
42
  error?: SDKAssistantMessageError
@@ -68,7 +74,7 @@ export function createAssistantMessage({
68
74
  usage,
69
75
  isVirtual,
70
76
  }: {
71
- content: string | BetaContentBlock[]
77
+ content: string | AssistantContentBlock[]
72
78
  usage?: Usage
73
79
  isVirtual?: true
74
80
  }): AssistantMessage {
@@ -1,6 +1,9 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { execa, execaSync } from 'execa'
1
3
  import memoize from 'lodash-es/memoize.js'
2
4
  import { normalizeApiKeyForConfig } from './authPortable.js'
3
5
  import { getGlobalConfig, saveGlobalConfig } from './config.js'
6
+ import { getClaudeConfigHomeDir } from './envUtils.js'
4
7
 
5
8
  export const FRIENDLI_PRIMARY_ENV = 'UMMAYA_FRIENDLI_TOKEN'
6
9
  export const FRIENDLI_LOGIN_REQUIRED_MESSAGE =
@@ -31,77 +34,125 @@ function normalizeFriendliApiKey(apiKey: string): string {
31
34
  return trimmed
32
35
  }
33
36
 
34
- export async function getClaudeAIOAuthTokens(): Promise<null> {
35
- return null
37
+ type FriendliKeychainIdentity = {
38
+ readonly account: string
39
+ readonly service: string
36
40
  }
37
41
 
38
- export function isClaudeAISubscriber(): boolean {
39
- return false
42
+ function getFriendliKeychainIdentity(): FriendliKeychainIdentity {
43
+ const configHash = createHash('sha256')
44
+ .update(getClaudeConfigHomeDir())
45
+ .digest('hex')
46
+ .substring(0, 16)
47
+ return {
48
+ account: `ummaya-friendli:${configHash}`,
49
+ service: `UMMAYA FriendliAI API Key (${configHash})`,
50
+ }
40
51
  }
41
52
 
42
- export function isConsumerSubscriber(): boolean {
43
- return false
53
+ async function saveApiKeyToMacOSKeychain(apiKey: string): Promise<boolean> {
54
+ if (process.platform !== 'darwin') {
55
+ return false
56
+ }
57
+ const identity = getFriendliKeychainIdentity()
58
+ const hexValue = Buffer.from(apiKey, 'utf-8').toString('hex')
59
+ const command = `add-generic-password -U -a "${identity.account}" -s "${identity.service}" -X "${hexValue}"\n`
60
+ try {
61
+ const result = await execa('security', ['-i'], {
62
+ input: command,
63
+ reject: false,
64
+ })
65
+ return result.exitCode === 0
66
+ } catch (error) {
67
+ if (error instanceof Error) {
68
+ return false
69
+ }
70
+ throw error
71
+ }
44
72
  }
45
73
 
46
- export function isMaxSubscriber(): boolean {
47
- return false
74
+ function getApiKeyFromMacOSKeychain(): null | string {
75
+ if (process.platform !== 'darwin') {
76
+ return null
77
+ }
78
+ const identity = getFriendliKeychainIdentity()
79
+ try {
80
+ const result = execaSync(
81
+ 'security',
82
+ [
83
+ 'find-generic-password',
84
+ '-a',
85
+ identity.account,
86
+ '-w',
87
+ '-s',
88
+ identity.service,
89
+ ],
90
+ { reject: false, stdio: ['ignore', 'pipe', 'pipe'] },
91
+ )
92
+ const stdout = result.stdout.trim()
93
+ return result.exitCode === 0 && stdout.length > 0 ? stdout : null
94
+ } catch (error) {
95
+ if (error instanceof Error) {
96
+ return null
97
+ }
98
+ throw error
99
+ }
48
100
  }
49
101
 
50
- export function isProSubscriber(): boolean {
51
- return false
102
+ async function removeApiKeyFromMacOSKeychain(): Promise<void> {
103
+ if (process.platform !== 'darwin') {
104
+ return
105
+ }
106
+ const identity = getFriendliKeychainIdentity()
107
+ try {
108
+ await execa(
109
+ 'security',
110
+ ['delete-generic-password', '-a', identity.account, '-s', identity.service],
111
+ { reject: false },
112
+ )
113
+ } catch (error) {
114
+ if (error instanceof Error) {
115
+ return
116
+ }
117
+ throw error
118
+ }
52
119
  }
53
120
 
54
- export function isTeamSubscriber(): boolean {
55
- return false
56
- }
121
+ export async function getClaudeAIOAuthTokens(): Promise<null> { return null }
57
122
 
58
- export function isTeamPremiumSubscriber(): boolean {
59
- return false
60
- }
123
+ export function isClaudeAISubscriber(): boolean { return false }
61
124
 
62
- export function isEnterpriseSubscriber(): boolean {
63
- return false
64
- }
125
+ export function isConsumerSubscriber(): boolean { return false }
65
126
 
66
- export function isAnthropicAuthEnabled(): boolean {
67
- return false
68
- }
127
+ export function isMaxSubscriber(): boolean { return false }
69
128
 
70
- export function is1PApiCustomer(): boolean {
71
- return false
72
- }
129
+ export function isProSubscriber(): boolean { return false }
73
130
 
74
- export function isUsing3PServices(): boolean {
75
- return false
76
- }
131
+ export function isTeamSubscriber(): boolean { return false }
77
132
 
78
- export function isOverageProvisioningAllowed(): boolean {
79
- return false
80
- }
133
+ export function isTeamPremiumSubscriber(): boolean { return false }
81
134
 
82
- export function hasProfileScope(): boolean {
83
- return false
84
- }
135
+ export function isEnterpriseSubscriber(): boolean { return false }
85
136
 
86
- export function getAccountInformation(): null {
87
- return null
88
- }
137
+ export function isAnthropicAuthEnabled(): boolean { return false }
89
138
 
90
- export function getOauthAccountInfo(): null {
91
- return null
92
- }
139
+ export function is1PApiCustomer(): boolean { return false }
93
140
 
94
- export function getOauthOrgUUID(): null {
95
- return null
96
- }
141
+ export function isUsing3PServices(): boolean { return false }
97
142
 
98
- export function getSubscriptionType(): 'free' {
99
- return 'free'
100
- }
143
+ export function isOverageProvisioningAllowed(): boolean { return false }
101
144
 
102
- export function getSubscriptionName(): string {
103
- return ''
104
- }
145
+ export function hasProfileScope(): boolean { return false }
146
+
147
+ export function getAccountInformation(): null { return null }
148
+
149
+ export function getOauthAccountInfo(): null { return null }
150
+
151
+ export function getOauthOrgUUID(): null { return null }
152
+
153
+ export function getSubscriptionType(): 'free' { return 'free' }
154
+
155
+ export function getSubscriptionName(): string { return '' }
105
156
 
106
157
  export function getAuthTokenSource(): {
107
158
  source: AuthTokenSource
@@ -110,9 +161,7 @@ export function getAuthTokenSource(): {
110
161
  return { source: 'none', hasToken: false }
111
162
  }
112
163
 
113
- export function getRateLimitTier(): 0 {
114
- return 0
115
- }
164
+ export function getRateLimitTier(): 0 { return 0 }
116
165
 
117
166
  export function getAnthropicApiKey(): null | string {
118
167
  return getAnthropicApiKeyWithSource().key
@@ -145,12 +194,13 @@ export function hasAnthropicApiKeyAuth(): boolean {
145
194
  export async function saveApiKey(apiKey: string): Promise<void> {
146
195
  const normalized = normalizeFriendliApiKey(apiKey)
147
196
  process.env[FRIENDLI_PRIMARY_ENV] = normalized
197
+ const savedToKeychain = await saveApiKeyToMacOSKeychain(normalized)
148
198
  saveGlobalConfig(current => {
149
199
  const truncated = normalizeApiKeyForConfig(normalized)
150
200
  const approved = current.customApiKeyResponses?.approved ?? []
151
201
  return {
152
202
  ...current,
153
- primaryApiKey: normalized,
203
+ primaryApiKey: savedToKeychain ? undefined : normalized,
154
204
  customApiKeyResponses: {
155
205
  ...current.customApiKeyResponses,
156
206
  approved: approved.includes(truncated)
@@ -165,6 +215,7 @@ export async function saveApiKey(apiKey: string): Promise<void> {
165
215
 
166
216
  export async function removeApiKey(): Promise<void> {
167
217
  delete process.env[FRIENDLI_PRIMARY_ENV]
218
+ await removeApiKeyFromMacOSKeychain()
168
219
  saveGlobalConfig(current => ({
169
220
  ...current,
170
221
  primaryApiKey: undefined,
@@ -172,70 +223,47 @@ export async function removeApiKey(): Promise<void> {
172
223
  getApiKeyFromConfigOrMacOSKeychain.cache?.clear?.()
173
224
  }
174
225
 
175
- export function getApiKeyFromApiKeyHelper(): null {
176
- return null
177
- }
226
+ export function getApiKeyFromApiKeyHelper(): null { return null }
178
227
 
179
228
  export const getApiKeyFromConfigOrMacOSKeychain = memoize((): null | string => {
229
+ const keychainKey = getApiKeyFromMacOSKeychain()
230
+ if (keychainKey) {
231
+ return keychainKey
232
+ }
233
+
180
234
  const configKey = getGlobalConfig().primaryApiKey?.trim()
181
235
  return configKey && configKey.length > 0 ? configKey : null
182
236
  })
183
237
 
184
- export function getConfiguredApiKeyHelper(): null {
185
- return null
186
- }
238
+ export function getConfiguredApiKeyHelper(): null { return null }
187
239
 
188
- export function getApiKeyHelperElapsedMs(): number {
189
- return 0
190
- }
240
+ export function getApiKeyHelperElapsedMs(): number { return 0 }
191
241
 
192
- export async function checkAndRefreshOAuthTokenIfNeeded(): Promise<void> {
193
- /* no-op */
194
- }
242
+ export async function checkAndRefreshOAuthTokenIfNeeded(): Promise<void> {}
195
243
 
196
- export async function refreshAndGetAwsCredentials(): Promise<null> {
197
- return null
198
- }
244
+ export async function refreshAndGetAwsCredentials(): Promise<null> { return null }
199
245
 
200
- export async function prefetchAwsCredentialsAndBedRockInfoIfSafe(): Promise<void> {
201
- /* no-op */
202
- }
246
+ export async function prefetchAwsCredentialsAndBedRockInfoIfSafe(): Promise<void> {}
203
247
 
204
- export async function prefetchGcpCredentialsIfSafe(): Promise<void> {
205
- /* no-op */
206
- }
248
+ export async function prefetchGcpCredentialsIfSafe(): Promise<void> {}
207
249
 
208
- export async function prefetchApiKeyFromApiKeyHelperIfSafe(): Promise<void> {
209
- /* no-op */
210
- }
250
+ export async function prefetchApiKeyFromApiKeyHelperIfSafe(): Promise<void> {}
211
251
 
212
252
  export function clearApiKeyHelperCache(): void {
213
253
  getApiKeyFromConfigOrMacOSKeychain.cache?.clear?.()
214
254
  }
215
255
 
216
- export function clearAwsCredentialsCache(): void {
217
- /* no-op */
218
- }
256
+ export function clearAwsCredentialsCache(): void {}
219
257
 
220
- export function clearGcpCredentialsCache(): void {
221
- /* no-op */
222
- }
258
+ export function clearGcpCredentialsCache(): void {}
223
259
 
224
- export function clearOAuthTokenCache(): void {
225
- /* no-op */
226
- }
260
+ export function clearOAuthTokenCache(): void {}
227
261
 
228
- export async function handleOAuth401Error(): Promise<void> {
229
- /* no-op */
230
- }
262
+ export async function handleOAuth401Error(): Promise<void> {}
231
263
 
232
- export async function saveOAuthTokensIfNeeded(): Promise<void> {
233
- /* no-op */
234
- }
264
+ export async function saveOAuthTokensIfNeeded(): Promise<void> {}
235
265
 
236
- export async function validateForceLoginOrg(): Promise<{ valid: true }> {
237
- return { valid: true }
238
- }
266
+ export async function validateForceLoginOrg(): Promise<{ valid: true }> { return { valid: true } }
239
267
 
240
268
  export function assertFriendliApiKeyForUse(
241
269
  env: Record<string, string | undefined> = process.env,
@@ -256,48 +284,10 @@ export function assertFriendliApiKeyForUse(
256
284
  throw new Error(FRIENDLI_LOGIN_REQUIRED_MESSAGE)
257
285
  }
258
286
 
259
- const _default = {
260
- getClaudeAIOAuthTokens,
261
- isClaudeAISubscriber,
262
- isConsumerSubscriber,
263
- isMaxSubscriber,
264
- isProSubscriber,
265
- isTeamSubscriber,
266
- isTeamPremiumSubscriber,
267
- isEnterpriseSubscriber,
268
- isAnthropicAuthEnabled,
269
- is1PApiCustomer,
270
- isUsing3PServices,
271
- isOverageProvisioningAllowed,
272
- hasProfileScope,
273
- getAccountInformation,
274
- getOauthAccountInfo,
275
- getOauthOrgUUID,
276
- getSubscriptionType,
277
- getAuthTokenSource,
278
- getRateLimitTier,
279
- getAnthropicApiKey,
280
- getAnthropicApiKeyWithSource,
281
- hasAnthropicApiKeyAuth,
282
- saveApiKey,
283
- removeApiKey,
284
- getApiKeyFromApiKeyHelper,
285
- getApiKeyFromConfigOrMacOSKeychain,
286
- getConfiguredApiKeyHelper,
287
- getApiKeyHelperElapsedMs,
288
- checkAndRefreshOAuthTokenIfNeeded,
289
- refreshAndGetAwsCredentials,
290
- prefetchAwsCredentialsAndBedRockInfoIfSafe,
291
- prefetchGcpCredentialsIfSafe,
292
- prefetchApiKeyFromApiKeyHelperIfSafe,
293
- clearApiKeyHelperCache,
294
- clearAwsCredentialsCache,
295
- clearGcpCredentialsCache,
296
- clearOAuthTokenCache,
297
- handleOAuth401Error,
298
- saveOAuthTokensIfNeeded,
299
- validateForceLoginOrg,
300
- assertFriendliApiKeyForUse,
287
+ export default {
288
+ getClaudeAIOAuthTokens, isClaudeAISubscriber, isConsumerSubscriber, isMaxSubscriber, isProSubscriber, isTeamSubscriber, isTeamPremiumSubscriber, isEnterpriseSubscriber, isAnthropicAuthEnabled, is1PApiCustomer,
289
+ isUsing3PServices, isOverageProvisioningAllowed, hasProfileScope, getAccountInformation, getOauthAccountInfo, getOauthOrgUUID, getSubscriptionType, getAuthTokenSource, getRateLimitTier,
290
+ getAnthropicApiKey, getAnthropicApiKeyWithSource, hasAnthropicApiKeyAuth, saveApiKey, removeApiKey, getApiKeyFromApiKeyHelper, getApiKeyFromConfigOrMacOSKeychain, getConfiguredApiKeyHelper,
291
+ getApiKeyHelperElapsedMs, checkAndRefreshOAuthTokenIfNeeded, refreshAndGetAwsCredentials, prefetchAwsCredentialsAndBedRockInfoIfSafe, prefetchGcpCredentialsIfSafe, prefetchApiKeyFromApiKeyHelperIfSafe,
292
+ clearApiKeyHelperCache, clearAwsCredentialsCache, clearGcpCredentialsCache, clearOAuthTokenCache, handleOAuth401Error, saveOAuthTokensIfNeeded, validateForceLoginOrg, assertFriendliApiKeyForUse,
301
293
  }
302
-
303
- export default _default
@@ -180,7 +180,7 @@ const SPECIAL_VAR_NAMES = new Set([
180
180
  * expansion, brace expressions).
181
181
  *
182
182
  * This set is not exhaustive — it documents KNOWN dangerous types. The real
183
- * safety property is the allowlist in walkArgument/walkCommand: any type NOT
183
+ * safety property is the allowlist in walkArgument/walkCommand: types NOT
184
184
  * explicitly handled there also triggers too-complex.
185
185
  */
186
186
  const DANGEROUS_TYPES = new Set([
@@ -355,7 +355,7 @@ function maskBracesInQuotedContexts(cmd: string): string {
355
355
  i++
356
356
  }
357
357
  } else {
358
- // Unquoted: `\` escapes any next char.
358
+ // Unquoted: `\` escapes the next char.
359
359
  if (c === '\\' && i + 1 < cmd.length) {
360
360
  out.push(c, cmd[i + 1]!)
361
361
  i += 2
@@ -374,7 +374,7 @@ const DOLLAR = String.fromCharCode(0x24)
374
374
 
375
375
  /**
376
376
  * Parse a bash command string and extract a flat list of simple commands.
377
- * Returns 'too-complex' if the command uses any shell feature we can't
377
+ * Returns 'too-complex' if the command uses a shell feature we can't
378
378
  * statically analyze. Returns 'parse-unavailable' if tree-sitter WASM isn't
379
379
  * loaded — caller should fall back to conservative behavior.
380
380
  */
@@ -460,7 +460,7 @@ export function parseForSecurityFromAst(
460
460
  }
461
461
 
462
462
  function walkProgram(root: Node): ParseForSecurityResult {
463
- // ERROR-node check folded into collectCommands — any unhandled node type
463
+ // ERROR-node check folded into collectCommands — each unhandled node type
464
464
  // (including ERROR) falls through to tooComplex() in the default branch.
465
465
  // Avoids a separate full-tree walk for error detection.
466
466
  const commands: SimpleCommand[] = []
@@ -477,7 +477,7 @@ function walkProgram(root: Node): ParseForSecurityResult {
477
477
 
478
478
  /**
479
479
  * Recursively collect leaf `command` nodes from a structural wrapper node.
480
- * Returns an error result on any disallowed node type, or null on success.
480
+ * Returns an error result on a disallowed node type, or null on success.
481
481
  */
482
482
  function collectCommands(
483
483
  node: Node,
@@ -485,7 +485,7 @@ function collectCommands(
485
485
  varScope: Map<string, string>,
486
486
  ): ParseForSecurityResult | null {
487
487
  if (node.type === 'command') {
488
- // Pass `commands` as the innerCommands accumulator — any $() extracted
488
+ // Pass `commands` as the innerCommands accumulator — extracted $()
489
489
  // during walkCommand gets appended alongside the outer command.
490
490
  const result = walkCommand(node, [], commands, varScope)
491
491
  if (result.kind !== 'simple') return result
@@ -798,7 +798,7 @@ function collectCommands(
798
798
  }
799
799
  if (child.type === 'do_group') {
800
800
  // while body: recurse with scope COPY (body assignments don't leak
801
- // past done). The COPY contains any `read VAR` tracking from the
801
+ // past done). The COPY contains `read VAR` tracking from the
802
802
  // condition (already in real varScope at this point).
803
803
  const bodyScope = new Map(varScope)
804
804
  for (const c of child.children) {
@@ -994,7 +994,7 @@ function walkTestExpr(
994
994
  case 'regex':
995
995
  case 'extglob_pattern':
996
996
  // RHS of =~ or ==/!= in [[ ]]. Pattern text only — no code execution.
997
- // Parser emits these as leaf nodes with no children (any $(...) or ${...}
997
+ // Parser emits these as leaf nodes with no children ($(...) or ${...}
998
998
  // inside the pattern is a sibling, not a child, and is walked separately).
999
999
  argv.push(node.text)
1000
1000
  return null
@@ -1322,8 +1322,8 @@ function walkCommand(
1322
1322
  // argv = ['git', 'push', '--force'] ← correct, path validation sees 'push'
1323
1323
  // .text = 'git $SUB --force' ← deny rule 'git push:*' doesn't match
1324
1324
  //
1325
- // Detection: any `$<identifier>` in node.text means a simple_expansion was
1326
- // resolved (or we'd have returned too-complex). This catches $VAR at any
1325
+ // Detection: `$<identifier>` in node.text means a simple_expansion was
1326
+ // resolved (or we'd have returned too-complex). This catches $VAR at each
1327
1327
  // position — command_name, word, string interior, concatenation part.
1328
1328
  // `$(...)` doesn't match (paren, not identifier start). `'$VAR'` in single
1329
1329
  // quotes: tree-sitter's .text includes the quotes, so a naive check would
@@ -1408,7 +1408,7 @@ function walkArgument(
1408
1408
  switch (node.type) {
1409
1409
  case 'word': {
1410
1410
  // Unescape backslash sequences. In unquoted context, bash's quote
1411
- // removal turns `\X` → `X` for any character X. tree-sitter preserves
1411
+ // removal turns `\X` → `X` for character X. tree-sitter preserves
1412
1412
  // the raw text. Required for checkSemantics: `\eval` must match
1413
1413
  // EVAL_LIKE_BUILTINS, `\zmodload` must match ZSH_DANGEROUS_BUILTINS.
1414
1414
  // Also makes argv accurate: `find -exec {} \;` → argv has `;` not
@@ -1513,7 +1513,7 @@ function walkString(
1513
1513
  let result = ''
1514
1514
  let cursor = -1
1515
1515
  // SECURITY: Track whether the string contains a runtime-unknown
1516
- // placeholder ($() output or unknown-value tracked var) vs any literal
1516
+ // placeholder ($() output or unknown-value tracked var) vs literal
1517
1517
  // content. A string that is ONLY a placeholder (`"$(cmd)"`, `"$VAR"`
1518
1518
  // where VAR holds an unknown sentinel) produces an argv element that IS
1519
1519
  // the placeholder — which downstream path validation resolves as a
@@ -1670,7 +1670,7 @@ const ARITH_LEAF_RE =
1670
1670
  *
1671
1671
  * When safe, the caller puts the full `$((…))` span into argv as a literal
1672
1672
  * string. bash will expand it to an integer at runtime; the static string
1673
- * won't match any sensitive path/deny patterns.
1673
+ * won't match sensitive path/deny patterns.
1674
1674
  */
1675
1675
  function walkArithmetic(node: Node): ParseForSecurityResult | null {
1676
1676
  for (const child of node.children) {
@@ -1863,7 +1863,7 @@ function walkVariableAssignment(
1863
1863
  // scope-model gaps: `||` reset, env-prefix chain (PS4='' && PS4='$'
1864
1864
  // PS4+='(id)' cmd reads stale parent value), subshell.
1865
1865
  // - bash's decode_prompt_string runs BEFORE promptvars, so `\044(id)`
1866
- // (octal for `$`) becomes `$(id)` at trace time — any literal-char
1866
+ // (octal for `$`) becomes `$(id)` at trace time — literal-char
1867
1867
  // check must model prompt-escape decoding exactly.
1868
1868
  // - assignment paths exist outside walkVariableAssignment (for_statement
1869
1869
  // sets loopVar directly, see that handler's PS4 check).
@@ -1909,8 +1909,8 @@ function walkVariableAssignment(
1909
1909
  // literal `~/x`. Later `cd $VAR` → our argv `['cd','~/x']`, bash runs
1910
1910
  // `cd /home/user/x`. Tilde expansion also happens after `=` and `:` in
1911
1911
  // assignment values (e.g. PATH=~/bin:~/sbin). We can't model it — reject
1912
- // any value containing `~` that isn't already quoted-literal (where bash
1913
- // doesn't expand). Conservative: any `~` in value → reject.
1912
+ // values containing `~` that aren't already quoted-literal (where bash
1913
+ // doesn't expand). Conservative: `~` in value → reject.
1914
1914
  if (value.includes('~')) {
1915
1915
  return {
1916
1916
  kind: 'too-complex',
@@ -1955,7 +1955,7 @@ function resolveSimpleExpansion(
1955
1955
  if (varName === null) return tooComplex(node)
1956
1956
  // Tracked vars: check stored value. Literal strings (VAR=/tmp) are
1957
1957
  // returned DIRECTLY so downstream path validation sees the real path.
1958
- // Non-literal values (containing any placeholder — loop vars, $() output,
1958
+ // Non-literal values (containing a placeholder — loop vars, $() output,
1959
1959
  // read vars, composites like `VAR="prefix$(cmd)"`) are ONLY safe inside
1960
1960
  // strings; as bare args they'd hide the runtime path/flag from validation.
1961
1961
  //
@@ -2228,7 +2228,7 @@ export function checkSemantics(commands: SimpleCommand[]): SemanticCheckResult {
2228
2228
  // SECURITY (SAST Mar 2026): the previous loop only skipped `--long`
2229
2229
  // flags, so `timeout -k 5 10 eval ...` broke out with name='timeout'
2230
2230
  // and the wrapped eval was never checked. Now handle known short
2231
- // flags AND fail closed on any unrecognized flag — an unknown flag
2231
+ // flags AND fail closed on unrecognized flags — an unknown flag
2232
2232
  // means we can't locate the wrapped command, so we must not silently
2233
2233
  // fall through to name='timeout'.
2234
2234
  let i = 1
@@ -2351,7 +2351,7 @@ export function checkSemantics(commands: SimpleCommand[]): SemanticCheckResult {
2351
2351
  // SECURITY: previous handling only stripped ONE flag and fell through
2352
2352
  // to slice(2) for anything unrecognized, so `stdbuf --output 0 eval`
2353
2353
  // → ['0','eval',...] → name='0' hid eval. Now iterate all known flag
2354
- // forms and fail closed on any unknown flag.
2354
+ // forms and fail closed on unknown flags.
2355
2355
  let i = 1
2356
2356
  while (i < a.length) {
2357
2357
  const arg = a[i]!
@@ -2390,7 +2390,7 @@ export function checkSemantics(commands: SimpleCommand[]): SemanticCheckResult {
2390
2390
  // UNQUOTED empty expansion at command position (`V="" && $V cmd`) is a
2391
2391
  // bypass: bash drops the empty field and runs `cmd` as argv[0], while
2392
2392
  // our name="" skips every builtin check below. resolveSimpleExpansion
2393
- // rejects the $V case; this catches any other path to empty argv[0]
2393
+ // rejects the $V case; this catches other paths to empty argv[0]
2394
2394
  // (concatenation of empties, walkString whitespace-quirk, future bugs).
2395
2395
  if (name === '') {
2396
2396
  return {
@@ -2437,7 +2437,7 @@ export function checkSemantics(commands: SimpleCommand[]): SemanticCheckResult {
2437
2437
  }
2438
2438
  }
2439
2439
  // Combined short flags: `-ra` is bash shorthand for `-r -a`.
2440
- // Check if any danger flag character appears in a combined flag
2440
+ // Check if a danger flag character appears in a combined flag
2441
2441
  // string. The danger flag's NAME operand is the next argument.
2442
2442
  if (
2443
2443
  arg.length > 2 &&
@@ -2636,7 +2636,7 @@ export function checkSemantics(commands: SimpleCommand[]): SemanticCheckResult {
2636
2636
  // `fc -l`, `fc -ln` list history — safe. `fc -e ed` invokes an
2637
2637
  // editor then executes. `fc -s [pat=rep]` RE-EXECUTES the last
2638
2638
  // matching command (optionally with substitution) — as dangerous
2639
- // as eval. Block any short-opt containing `e` or `s`.
2639
+ // as eval. Block short-opts containing `e` or `s`.
2640
2640
  // to avoid introducing FPs for `fc -l` (list history).
2641
2641
  } else if (
2642
2642
  name === 'compgen' &&
@@ -2645,7 +2645,7 @@ export function checkSemantics(commands: SimpleCommand[]): SemanticCheckResult {
2645
2645
  // `compgen -c/-f/-v` only list completions — safe. `compgen -C cmd`
2646
2646
  // immediately executes cmd; `-F func` calls a shell function; `-W list`
2647
2647
  // word-expands its argument (including $(cmd) even from single-quoted
2648
- // raw_string). Block any short-opt containing C/F/W (case-sensitive:
2648
+ // raw_string). Block short-opts containing C/F/W (case-sensitive:
2649
2649
  // -c/-f are safe).
2650
2650
  } else {
2651
2651
  return {
@@ -1591,7 +1591,7 @@ function isRedirectLiteralStart(P: ParseState): boolean {
1591
1591
  // Shell terminators and operators
1592
1592
  if (c === '|' || c === '&' || c === ';' || c === '(' || c === ')')
1593
1593
  return false
1594
- // Redirect operators (< > with any suffix; <( >( handled by caller)
1594
+ // Redirect operators (< > with suffixes; <( >( handled by caller)
1595
1595
  if (c === '<' || c === '>') {
1596
1596
  // <( >( are process substitutions — those ARE literals
1597
1597
  return peek(P.L, 1) === '('
@@ -1707,11 +1707,11 @@ function tryParseRedirect(P: ParseState, greedy = false): TsNode | null {
1707
1707
  })
1708
1708
  const kids = fd ? [fd, op, startNode] : [op, startNode]
1709
1709
  const startIdx = fd ? fd.startIndex : op.startIndex
1710
- // SECURITY: tree-sitter nests any pipeline/list/file_redirect appearing
1710
+ // SECURITY: tree-sitter nests pipeline/list/file_redirect nodes appearing
1711
1711
  // between heredoc_start and the newline as a CHILD of heredoc_redirect.
1712
1712
  // `ls <<'EOF' | rm -rf /tmp/evil` must not silently drop the rm. Parse
1713
1713
  // trailing words and file_redirects properly (ast.ts walkHeredocRedirect
1714
- // fails closed on any unrecognized child via tooComplex). Pipeline / list
1714
+ // fails closed on unrecognized children via tooComplex). Pipeline / list
1715
1715
  // operators (| && || ;) are structurally complex — emit ERROR so the same
1716
1716
  // fail-closed path rejects them.
1717
1717
  while (true) {
@@ -2753,7 +2753,7 @@ function parseExpansionBody(P: ParseState): TsNode[] {
2753
2753
  }
2754
2754
  // Pattern: per grammar _expansion_regex_replacement, pattern is
2755
2755
  // choice(regex, string, cmd_sub, seq(string, regex)). If it STARTS
2756
- // with ", emit (string) and any trailing chars become (regex).
2756
+ // with ", emit (string) and trailing chars become (regex).
2757
2757
  // `${v//"${old}"/}` → (string(expansion)); `${v//"${c}"\//}` →
2758
2758
  // (string)(regex).
2759
2759
  if (peek(P.L) === '"') {
@@ -3468,7 +3468,7 @@ function parseCasePattern(P: ParseState): TsNode[] {
3468
3468
  if (peek(P.L) === c) advance(P.L)
3469
3469
  continue
3470
3470
  }
3471
- // Paren counting: any ( inside pattern opens a scope; don't break at ) or |
3471
+ // Paren counting: ( inside pattern opens a scope; don't break at ) or |
3472
3472
  // until balanced. Handles extglob *(a|b) and nested shapes *([0-9])([0-9]).
3473
3473
  if (c === '(') {
3474
3474
  parenDepth++
@@ -19,7 +19,7 @@ export function hasConsoleBillingAccess(): boolean {
19
19
  // we already show a warning on launch in that case
20
20
  if (isSubscriber) return false
21
21
 
22
- // Check if user has any form of authentication
22
+ // Check if user has a configured authentication source
23
23
  const authSource = getAuthTokenSource()
24
24
  const hasApiKey = getAnthropicApiKey() !== null
25
25