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.
- package/README.md +15 -2
- package/bin/ummaya +10 -1
- package/bun.lock +180 -244
- package/npm-shrinkwrap.json +760 -1760
- package/package.json +39 -22
- package/prompts/manifest.yaml +1 -1
- package/prompts/system_v1.md +1 -0
- package/pyproject.toml +27 -2
- package/specs/2803-document-production-hardening/contracts/document-tools.schema.json +1043 -0
- package/src/ummaya/_canonical/__init__.py +2 -0
- package/src/ummaya/_canonical/baselines.yaml +113 -0
- package/src/ummaya/engine/engine.py +29 -132
- package/src/ummaya/evidence/__init__.py +21 -2
- package/src/ummaya/evidence/dataset_contract.py +193 -0
- package/src/ummaya/evidence/document_authoring_cases.py +33 -0
- package/src/ummaya/evidence/document_harness.py +313 -0
- package/src/ummaya/evidence/document_viewer_ux.py +391 -0
- package/src/ummaya/evidence/gates.py +70 -0
- package/src/ummaya/evidence/json_types.py +20 -0
- package/src/ummaya/evidence/models.py +88 -1
- package/src/ummaya/evidence/output_payload.py +89 -0
- package/src/ummaya/evidence/payload_documents.py +233 -0
- package/src/ummaya/evidence/route_contracts.py +224 -0
- package/src/ummaya/evidence/route_helpers.py +150 -0
- package/src/ummaya/evidence/runner.py +81 -212
- package/src/ummaya/evidence/source_provenance.py +246 -0
- package/src/ummaya/evidence/source_provenance_redaction.py +176 -0
- package/src/ummaya/evidence/tool_layer.py +39 -0
- package/src/ummaya/evidence/tool_layer_models.py +151 -0
- package/src/ummaya/ipc/adapter_manifest_emitter.py +26 -10
- package/src/ummaya/ipc/document_intent_normalization.py +185 -0
- package/src/ummaya/ipc/frame_schema.py +5 -5
- package/src/ummaya/ipc/route_diagnostics.py +73 -0
- package/src/ummaya/ipc/stdio.py +1109 -477
- package/src/ummaya/llm/client.py +102 -3
- package/src/ummaya/llm/config.py +8 -3
- package/src/ummaya/primitives/__init__.py +6 -2
- package/src/ummaya/primitives/delegation.py +1 -1
- package/src/ummaya/primitives/document.py +28 -0
- package/src/ummaya/settings.py +0 -3
- package/src/ummaya/tools/discovery_bridge.py +17 -1
- package/src/ummaya/tools/documents/__init__.py +297 -0
- package/src/ummaya/tools/documents/adapter_registry.py +487 -0
- package/src/ummaya/tools/documents/archive_container_probe.py +167 -0
- package/src/ummaya/tools/documents/artifact_store.py +454 -0
- package/src/ummaya/tools/documents/authoring.py +283 -0
- package/src/ummaya/tools/documents/baselines.py +132 -0
- package/src/ummaya/tools/documents/capability.py +331 -0
- package/src/ummaya/tools/documents/contracts.py +112 -0
- package/src/ummaya/tools/documents/conversion.py +521 -0
- package/src/ummaya/tools/documents/diff.py +275 -0
- package/src/ummaya/tools/documents/engines.py +163 -0
- package/src/ummaya/tools/documents/evaluation.py +291 -0
- package/src/ummaya/tools/documents/explicit_values.py +108 -0
- package/src/ummaya/tools/documents/fixtures.py +174 -0
- package/src/ummaya/tools/documents/format_completion_audit.py +471 -0
- package/src/ummaya/tools/documents/formats/__init__.py +2 -0
- package/src/ummaya/tools/documents/formats/archive.py +528 -0
- package/src/ummaya/tools/documents/formats/base.py +41 -0
- package/src/ummaya/tools/documents/formats/code_file.py +211 -0
- package/src/ummaya/tools/documents/formats/data_file.py +272 -0
- package/src/ummaya/tools/documents/formats/hwp.py +284 -0
- package/src/ummaya/tools/documents/formats/hwpx.py +1837 -0
- package/src/ummaya/tools/documents/formats/odf.py +435 -0
- package/src/ummaya/tools/documents/formats/ooxml.py +1030 -0
- package/src/ummaya/tools/documents/formats/passive.py +766 -0
- package/src/ummaya/tools/documents/formats/pdf.py +702 -0
- package/src/ummaya/tools/documents/formats/text_web.py +268 -0
- package/src/ummaya/tools/documents/hwp_conversion_probe.py +178 -0
- package/src/ummaya/tools/documents/hwp_direct_candidate.py +141 -0
- package/src/ummaya/tools/documents/inspection.py +289 -0
- package/src/ummaya/tools/documents/intake.py +1079 -0
- package/src/ummaya/tools/documents/legacy_office_promotion_probe.py +366 -0
- package/src/ummaya/tools/documents/models.py +1598 -0
- package/src/ummaya/tools/documents/odf_promotion_probe.py +167 -0
- package/src/ummaya/tools/documents/orchestrator.py +96 -0
- package/src/ummaya/tools/documents/passive_capability_probe.py +251 -0
- package/src/ummaya/tools/documents/patch.py +170 -0
- package/src/ummaya/tools/documents/pdfa_conformance.py +284 -0
- package/src/ummaya/tools/documents/pdfa_promotion_probe.py +198 -0
- package/src/ummaya/tools/documents/permissions.py +110 -0
- package/src/ummaya/tools/documents/planner.py +616 -0
- package/src/ummaya/tools/documents/registry.py +2733 -0
- package/src/ummaya/tools/documents/render.py +978 -0
- package/src/ummaya/tools/documents/render_comparison.py +113 -0
- package/src/ummaya/tools/documents/render_comparison_models.py +74 -0
- package/src/ummaya/tools/documents/render_comparison_regions.py +73 -0
- package/src/ummaya/tools/documents/render_comparison_style.py +161 -0
- package/src/ummaya/tools/documents/reread.py +157 -0
- package/src/ummaya/tools/documents/runtime_authoring.py +244 -0
- package/src/ummaya/tools/documents/runtime_authoring_bundle.py +76 -0
- package/src/ummaya/tools/documents/scorecard.py +184 -0
- package/src/ummaya/tools/documents/socratic_planner.py +193 -0
- package/src/ummaya/tools/documents/style.py +48 -0
- package/src/ummaya/tools/documents/tool_defs.py +523 -0
- package/src/ummaya/tools/documents/validate.py +347 -0
- package/src/ummaya/tools/executor.py +29 -0
- package/src/ummaya/tools/live_proxy.py +0 -3
- package/src/ummaya/tools/models.py +5 -1
- package/src/ummaya/tools/register_all.py +8 -0
- package/src/ummaya/tools/registry.py +10 -1
- package/src/ummaya/tools/routing/__init__.py +59 -0
- package/src/ummaya/tools/routing/builder.py +105 -0
- package/src/ummaya/tools/routing/cards.py +29 -0
- package/src/ummaya/tools/routing/decision_service.py +534 -0
- package/src/ummaya/tools/routing/decision_types.py +74 -0
- package/src/ummaya/tools/routing/feasibility.py +122 -0
- package/src/ummaya/tools/routing/intent.py +17 -0
- package/src/ummaya/tools/routing/intent_extractor.py +207 -0
- package/src/ummaya/tools/routing/intent_patterns.py +160 -0
- package/src/ummaya/tools/routing/intent_public_data.py +150 -0
- package/src/ummaya/tools/routing/intent_types.py +48 -0
- package/src/ummaya/tools/routing/lint.py +78 -0
- package/src/ummaya/tools/routing/metadata.py +174 -0
- package/src/ummaya/tools/routing/projection.py +340 -0
- package/src/ummaya/tools/routing/retrieval_policy.py +629 -0
- package/src/ummaya/tools/routing/schema.py +81 -0
- package/src/ummaya/tools/routing/types.py +96 -0
- package/src/ummaya/tools/routing_index.py +2 -2
- package/src/ummaya/tools/search.py +34 -746
- package/tests/fixtures/documents/public_forms/baselines.yaml +113 -0
- package/tui/bun.lock +126 -305
- package/tui/package.json +35 -22
- package/tui/src/.cc-byte-identical-whitelist.yaml +266 -0
- package/tui/src/QueryEngine.ts +12 -8
- package/tui/src/bridge/inboundAttachments.ts +3 -3
- package/tui/src/cli/handlers/auth.ts +3 -12
- package/tui/src/cli/handlers/mcp.tsx +0 -1
- package/tui/src/cli/print.ts +8 -9
- package/tui/src/commands/insights.ts +1 -1
- package/tui/src/commands/install-github-app/types.ts +8 -30
- package/tui/src/commands/plugin/types.ts +6 -28
- package/tui/src/commands/plugin/unifiedTypes.ts +4 -26
- package/tui/src/commands/rename/generateSessionName.ts +1 -1
- package/tui/src/components/Feedback.tsx +1 -1
- package/tui/src/components/LogoV2/EmergencyTip.tsx +11 -2
- package/tui/src/components/LogoV2/WelcomeV2.tsx +1 -3
- package/tui/src/components/ScrollKeybindingHandler.tsx +6 -6
- package/tui/src/components/Spinner/types.ts +6 -28
- package/tui/src/components/agents/generateAgent.ts +1 -1
- package/tui/src/components/agents/new-agent-creation/types.ts +4 -26
- package/tui/src/components/config/EnvSecretIsolatedEditor.tsx +1 -1
- package/tui/src/components/mcp/types.ts +16 -38
- package/tui/src/components/messages/AssistantToolUseMessage.tsx +3 -2
- package/tui/src/components/messages/UserCrossSessionMessage.ts +16 -4
- package/tui/src/components/messages/UserForkBoilerplateMessage.ts +16 -4
- package/tui/src/components/messages/UserGitHubWebhookMessage.ts +16 -4
- package/tui/src/components/messages/UserToolResultMessage/utils.tsx +3 -2
- package/tui/src/components/permissions/MonitorPermissionRequest/MonitorPermissionRequest.ts +9 -4
- package/tui/src/components/permissions/ReviewArtifactPermissionRequest/ReviewArtifactPermissionRequest.ts +9 -4
- package/tui/src/components/primitive/DocumentSocraticReviewBlock.tsx +129 -0
- package/tui/src/components/primitive/DocumentToolResultCard.tsx +224 -0
- package/tui/src/components/primitive/documentSocraticReview.ts +215 -0
- package/tui/src/components/primitive/index.tsx +43 -1
- package/tui/src/components/primitive/types.ts +137 -0
- package/tui/src/components/ui/option.ts +4 -26
- package/tui/src/constants/common.ts +0 -2
- package/tui/src/constants/prompts.ts +4 -3
- package/tui/src/constants/querySource.ts +4 -26
- package/tui/src/entrypoints/sdk/controlTypes.ts +26 -48
- package/tui/src/entrypoints/sdk/coreTypes.generated.ts +3 -25
- package/tui/src/entrypoints/sdk/runtimeTypes.ts +38 -60
- package/tui/src/entrypoints/sdk/sdkUtilityTypes.ts +4 -26
- package/tui/src/entrypoints/sdk/settingsTypes.generated.ts +3 -25
- package/tui/src/entrypoints/sdk/toolTypes.ts +3 -25
- package/tui/src/hooks/toolPermission/handlers/interactiveHandler.ts +10 -0
- package/tui/src/hooks/useApiKeyVerification.ts +1 -1
- package/tui/src/hooks/useVirtualScroll.ts +1 -1
- package/tui/src/ink/ink.tsx +33 -14
- package/tui/src/ink/reconciler.ts +2 -3
- package/tui/src/ink/render-to-screen.ts +30 -10
- package/tui/src/ipc/bridge.ts +62 -15
- package/tui/src/ipc/bridgeSingleton.ts +5 -1
- package/tui/src/ipc/codec.ts +3 -3
- package/tui/src/ipc/frames.generated.ts +12 -12
- package/tui/src/ipc/llmClient.ts +151 -27
- package/tui/src/ipc/schema/frame.schema.json +1 -1
- package/tui/src/keybindings/defaultBindings.ts +4 -0
- package/tui/src/main.tsx +32 -15
- package/tui/src/native-ts/file-index/index.ts +33 -3
- package/tui/src/observability/surface.ts +2 -2
- package/tui/src/probes/toolRegistryProbe.tsx +3 -1
- package/tui/src/projectOnboardingState.ts +7 -6
- package/tui/src/query/chatMessageTypes.ts +18 -0
- package/tui/src/query/chatMessagesBuilder.ts +1 -1
- package/tui/src/query/deps.ts +1 -1
- package/tui/src/query/messageGuards.ts +106 -0
- package/tui/src/query/publicDataTerminalRepair.ts +384 -0
- package/tui/src/query/run.ts +1075 -0
- package/tui/src/query/supportBoundary.ts +168 -0
- package/tui/src/query/toolResultErrors.ts +103 -0
- package/tui/src/query/toolRunner.ts +687 -0
- package/tui/src/query/unavailableToolRepair.ts +118 -0
- package/tui/src/query.ts +9 -2186
- package/tui/src/screens/REPL.tsx +40 -29
- package/tui/src/services/api/adapterManifest.ts +4 -0
- package/tui/src/services/api/backendChat/events.ts +117 -0
- package/tui/src/services/api/backendChat/finalMessage.ts +40 -0
- package/tui/src/services/api/backendChat/frame.ts +9 -0
- package/tui/src/services/api/backendChat/streaming.ts +430 -0
- package/tui/src/services/api/backendChat/types.ts +62 -0
- package/tui/src/services/api/backendChat.ts +1 -0
- package/tui/src/services/api/client.ts +65 -2
- package/tui/src/services/api/errorUtils.ts +5 -5
- package/tui/src/services/api/errors.ts +1 -1
- package/tui/src/services/api/logging.ts +1 -1
- package/tui/src/services/api/ummaya/evidence.ts +194 -0
- package/tui/src/services/api/ummaya/messages.ts +255 -0
- package/tui/src/services/api/ummaya/nonStreaming.ts +66 -0
- package/tui/src/services/api/ummaya/provider.ts +200 -0
- package/tui/src/services/api/ummaya/reasoning.ts +24 -0
- package/tui/src/services/api/ummaya/request.ts +200 -0
- package/tui/src/services/api/ummaya/selectionContext.ts +240 -0
- package/tui/src/services/api/ummaya/streaming.ts +365 -0
- package/tui/src/services/api/ummaya/streamingPayload.ts +129 -0
- package/tui/src/services/api/ummaya/streamingReader.ts +40 -0
- package/tui/src/services/api/ummaya/toolSelection.ts +217 -0
- package/tui/src/services/api/ummaya/types.ts +110 -0
- package/tui/src/services/api/ummaya/usage.ts +30 -0
- package/tui/src/services/api/ummaya.ts +26 -418
- package/tui/src/services/api/withRetry.ts +1 -1
- package/tui/src/services/awaySummary.ts +2 -2
- package/tui/src/services/claudeAiLimits.ts +1 -1
- package/tui/src/services/compact/autoCompact.ts +1 -1
- package/tui/src/services/compact/compact.ts +1 -1
- package/tui/src/services/lsp/types.ts +8 -30
- package/tui/src/services/tips/types.ts +6 -28
- package/tui/src/services/tokenEstimation.ts +1 -1
- package/tui/src/services/toolRegistry/bootGuard.ts +5 -5
- package/tui/src/services/toolUseSummary/toolUseSummaryGenerator.ts +1 -1
- package/tui/src/services/tools/toolExecution.ts +94 -1
- package/tui/src/store/pendingPermissionSlot.ts +1 -1
- package/tui/src/store/session-store.ts +10 -36
- package/tui/src/stubs/any-stub.ts +15 -10
- package/tui/src/stubs/color-diff-napi.ts +37 -23
- package/tui/src/stubs/globals.d.ts +3 -3
- package/tui/src/stubs/macro-preload.ts +23 -12
- package/tui/src/tools/AdapterTool/AdapterTool.ts +1207 -714
- package/tui/src/tools/AdapterTool/routeDiagnostics.ts +75 -0
- package/tui/src/tools/AgentTool/AgentTool.tsx +84 -1371
- package/tui/src/tools/AgentTool/agentToolHandoff.ts +114 -0
- package/tui/src/tools/AgentTool/agentToolPartialResult.ts +16 -0
- package/tui/src/tools/AgentTool/agentToolProgress.ts +32 -0
- package/tui/src/tools/AgentTool/agentToolResolver.ts +161 -0
- package/tui/src/tools/AgentTool/agentToolResult.ts +163 -0
- package/tui/src/tools/AgentTool/agentToolUtils.ts +14 -686
- package/tui/src/tools/AgentTool/asyncAgentLifecycle.ts +208 -0
- package/tui/src/tools/AgentTool/asyncLifecycle.ts +153 -0
- package/tui/src/tools/AgentTool/backgroundedCompletion.ts +126 -0
- package/tui/src/tools/AgentTool/backgroundedLifecycle.ts +174 -0
- package/tui/src/tools/AgentTool/foregroundBackground.ts +83 -0
- package/tui/src/tools/AgentTool/foregroundDrain.tsx +133 -0
- package/tui/src/tools/AgentTool/foregroundFinalize.ts +98 -0
- package/tui/src/tools/AgentTool/foregroundLifecycle.tsx +237 -0
- package/tui/src/tools/AgentTool/foregroundProgress.tsx +169 -0
- package/tui/src/tools/AgentTool/foregroundTask.ts +89 -0
- package/tui/src/tools/AgentTool/forkSubagent.ts +1 -12
- package/tui/src/tools/AgentTool/forkSubagentGate.ts +34 -0
- package/tui/src/tools/AgentTool/launchRouting.ts +203 -0
- package/tui/src/tools/AgentTool/lifecycle.ts +244 -0
- package/tui/src/tools/AgentTool/mcpRouting.ts +73 -0
- package/tui/src/tools/AgentTool/orchestrationSupport.ts +70 -0
- package/tui/src/tools/AgentTool/permissions.ts +39 -0
- package/tui/src/tools/AgentTool/promptSetup.ts +181 -0
- package/tui/src/tools/AgentTool/remoteRouting.ts +62 -0
- package/tui/src/tools/AgentTool/resultMapping.ts +116 -0
- package/tui/src/tools/AgentTool/resumeAgent.ts +39 -107
- package/tui/src/tools/AgentTool/resumeAgentHelpers.ts +140 -0
- package/tui/src/tools/AgentTool/runAgent.ts +1 -1
- package/tui/src/tools/AgentTool/runtimeConfig.ts +57 -0
- package/tui/src/tools/AgentTool/schemas.ts +196 -0
- package/tui/src/tools/AgentTool/sourceVerificationPropagation.ts +263 -0
- package/tui/src/tools/AgentTool/worktreeLifecycle.ts +105 -0
- package/tui/src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx +174 -202
- package/tui/src/tools/BashTool/BashTool.tsx +71 -1072
- package/tui/src/tools/BashTool/bashCommandHelpers.ts +12 -12
- package/tui/src/tools/BashTool/bashPermissions/astPreflight.ts +173 -0
- package/tui/src/tools/BashTool/bashPermissions/classifierChecks.ts +199 -0
- package/tui/src/tools/BashTool/bashPermissions/compoundGuards.ts +53 -0
- package/tui/src/tools/BashTool/bashPermissions/constants.ts +99 -0
- package/tui/src/tools/BashTool/bashPermissions/index.ts +38 -0
- package/tui/src/tools/BashTool/bashPermissions/legacyMisparsing.ts +62 -0
- package/tui/src/tools/BashTool/bashPermissions/main.ts +135 -0
- package/tui/src/tools/BashTool/bashPermissions/normalizedCommands.ts +33 -0
- package/tui/src/tools/BashTool/bashPermissions/operatorFlow.ts +98 -0
- package/tui/src/tools/BashTool/bashPermissions/permissionChecks.ts +200 -0
- package/tui/src/tools/BashTool/bashPermissions/prefixSuggestions.ts +88 -0
- package/tui/src/tools/BashTool/bashPermissions/promptClassifierRules.ts +125 -0
- package/tui/src/tools/BashTool/bashPermissions/ruleDelegates.ts +19 -0
- package/tui/src/tools/BashTool/bashPermissions/ruleMatching.ts +145 -0
- package/tui/src/tools/BashTool/bashPermissions/sandboxAutoAllow.ts +75 -0
- package/tui/src/tools/BashTool/bashPermissions/subcommandFlow.ts +205 -0
- package/tui/src/tools/BashTool/bashPermissions/subcommandGuards.ts +73 -0
- package/tui/src/tools/BashTool/bashPermissions/subcommandResultHelpers.ts +116 -0
- package/tui/src/tools/BashTool/bashPermissions/types.ts +26 -0
- package/tui/src/tools/BashTool/bashPermissions/wrapperStripping.ts +139 -0
- package/tui/src/tools/BashTool/bashPermissions.ts +26 -2621
- package/tui/src/tools/BashTool/call.ts +202 -0
- package/tui/src/tools/BashTool/callLoader.ts +35 -0
- package/tui/src/tools/BashTool/commandClassification.ts +151 -0
- package/tui/src/tools/BashTool/commandClassificationLoader.ts +40 -0
- package/tui/src/tools/BashTool/cwdReset.ts +33 -0
- package/tui/src/tools/BashTool/lineTruncation.ts +11 -0
- package/tui/src/tools/BashTool/modeValidation.ts +13 -1
- package/tui/src/tools/BashTool/outputPersistence.ts +42 -0
- package/tui/src/tools/BashTool/permissionClassification.ts +66 -0
- package/tui/src/tools/BashTool/permissionLoader.ts +44 -0
- package/tui/src/tools/BashTool/resultLoader.ts +29 -0
- package/tui/src/tools/BashTool/resultMapping.ts +83 -0
- package/tui/src/tools/BashTool/sandboxPolicy.ts +79 -0
- package/tui/src/tools/BashTool/schemas.ts +65 -0
- package/tui/src/tools/BashTool/sedEditExecution.ts +59 -0
- package/tui/src/tools/BashTool/shellExecution.tsx +245 -0
- package/tui/src/tools/BashTool/shellOutputUtils.ts +85 -0
- package/tui/src/tools/BashTool/shellPermissionGauntlet.ts +97 -0
- package/tui/src/tools/BashTool/uiLoader.ts +37 -0
- package/tui/src/tools/BriefTool/upload.ts +1 -1
- package/tui/src/tools/CalculatorTool/parser.ts +2 -2
- package/tui/src/tools/DocumentPrimitive/DocumentPrimitive.ts +262 -0
- package/tui/src/tools/DocumentPrimitive/dispatchNormalization.ts +270 -0
- package/tui/src/tools/DocumentPrimitive/documentDestinationPath.ts +18 -0
- package/tui/src/tools/DocumentPrimitive/documentMutationGuard.ts +22 -0
- package/tui/src/tools/DocumentPrimitive/documentPatchNormalization.ts +248 -0
- package/tui/src/tools/DocumentPrimitive/documentSourceVerification.ts +245 -0
- package/tui/src/tools/DocumentPrimitive/documentSourceVerificationFields.ts +103 -0
- package/tui/src/tools/DocumentPrimitive/modelVisibleOutput.ts +40 -0
- package/tui/src/tools/DocumentPrimitive/prompt.ts +35 -0
- package/tui/src/tools/FileEditTool/FileEditTool.ts +9 -507
- package/tui/src/tools/FileEditTool/call.ts +228 -0
- package/tui/src/tools/FileEditTool/validateInput.ts +196 -0
- package/tui/src/tools/FileReadTool/imageProcessor.ts +13 -0
- package/tui/src/tools/FileWriteTool/FileWriteTool.ts +7 -300
- package/tui/src/tools/FileWriteTool/call.ts +223 -0
- package/tui/src/tools/FileWriteTool/validateInput.ts +80 -0
- package/tui/src/tools/ListMcpResourcesTool/ListMcpResourcesTool.ts +19 -3
- package/tui/src/tools/LookupPrimitive/LookupPrimitive.ts +25 -32
- package/tui/src/tools/LookupPrimitive/prompt.ts +0 -2
- package/tui/src/tools/MCPTool/trustPolicy.ts +118 -0
- package/tui/src/tools/McpAuthTool/McpAuthTool.ts +21 -3
- package/tui/src/tools/NotebookEditTool/NotebookEditTool.ts +7 -326
- package/tui/src/tools/NotebookEditTool/call.ts +254 -0
- package/tui/src/tools/NotebookEditTool/notebookModel.ts +51 -0
- package/tui/src/tools/NotebookEditTool/validateInput.ts +142 -0
- package/tui/src/tools/PowerShellTool/PowerShellTool.tsx +46 -937
- package/tui/src/tools/PowerShellTool/acceptEditsCommandValidation.ts +162 -0
- package/tui/src/tools/PowerShellTool/call.ts +179 -0
- package/tui/src/tools/PowerShellTool/callLoader.ts +37 -0
- package/tui/src/tools/PowerShellTool/commandClassification.ts +86 -0
- package/tui/src/tools/PowerShellTool/modeValidation.ts +25 -332
- package/tui/src/tools/PowerShellTool/outputPersistence.ts +42 -0
- package/tui/src/tools/PowerShellTool/permissionClassification.ts +28 -0
- package/tui/src/tools/PowerShellTool/resultLoader.ts +31 -0
- package/tui/src/tools/PowerShellTool/resultMapping.ts +75 -0
- package/tui/src/tools/PowerShellTool/schemas.ts +40 -0
- package/tui/src/tools/PowerShellTool/shellExecution.tsx +258 -0
- package/tui/src/tools/PowerShellTool/symlinkModeValidation.ts +44 -0
- package/tui/src/tools/PowerShellTool/uiLoader.ts +37 -0
- package/tui/src/tools/PowerShellTool/validation.ts +39 -0
- package/tui/src/tools/ReadMcpResourceTool/ReadMcpResourceTool.ts +19 -3
- package/tui/src/tools/ResolveLocationPrimitive/ResolveLocationPrimitive.ts +1 -11
- package/tui/src/tools/ResolveLocationPrimitive/prompt.ts +2 -6
- package/tui/src/tools/SkillTool/SkillTool.ts +2 -2
- package/tui/src/tools/SubmitPrimitive/SubmitPrimitive.ts +27 -10
- package/tui/src/tools/TaskCreateTool/TaskCreateTool.ts +16 -2
- package/tui/src/tools/TaskGetTool/TaskGetTool.ts +23 -3
- package/tui/src/tools/TaskListTool/TaskListTool.ts +22 -4
- package/tui/src/tools/TaskOutputTool/TaskOutputTool.tsx +46 -547
- package/tui/src/tools/TaskOutputTool/lookup.ts +216 -0
- package/tui/src/tools/TaskOutputTool/render.tsx +257 -0
- package/tui/src/tools/TaskOutputTool/schemas.ts +55 -0
- package/tui/src/tools/TaskOutputTool/serialization.ts +36 -0
- package/tui/src/tools/TaskStopTool/TaskStopTool.ts +10 -0
- package/tui/src/tools/TaskUpdateTool/TaskUpdateTool.ts +14 -364
- package/tui/src/tools/TaskUpdateTool/completion.ts +62 -0
- package/tui/src/tools/TaskUpdateTool/schemas.ts +62 -0
- package/tui/src/tools/TaskUpdateTool/serialization.ts +46 -0
- package/tui/src/tools/TaskUpdateTool/statusUpdate.ts +247 -0
- package/tui/src/tools/TodoWriteTool/TodoWriteTool.ts +21 -2
- package/tui/src/tools/ToolSearchTool/ToolSearchTool.ts +21 -302
- package/tui/src/tools/ToolSearchTool/ccSupportTools.ts +223 -0
- package/tui/src/tools/ToolSearchTool/descriptionCache.ts +50 -0
- package/tui/src/tools/ToolSearchTool/keywordSearch.ts +216 -0
- package/tui/src/tools/ToolSearchTool/prompt.ts +10 -4
- package/tui/src/tools/ToolSearchTool/resultMapping.ts +30 -0
- package/tui/src/tools/ToolSearchTool/schemas.ts +30 -0
- package/tui/src/tools/ToolSearchTool/searchPool.ts +47 -0
- package/tui/src/tools/ToolSearchTool/supportIntentHints.ts +140 -0
- package/tui/src/tools/TranslateTool/TranslateTool.ts +1 -1
- package/tui/src/tools/VerifyPrimitive/VerifyPrimitive.ts +2 -1
- package/tui/src/tools/WebFetchTool/WebFetchTool.ts +43 -138
- package/tui/src/tools/WebFetchTool/call.ts +227 -0
- package/tui/src/tools/WebFetchTool/resolvedAddressSafety.ts +78 -0
- package/tui/src/tools/WebFetchTool/sourceVerification.ts +204 -0
- package/tui/src/tools/WebFetchTool/types.ts +23 -0
- package/tui/src/tools/WebFetchTool/urlSafety.ts +181 -0
- package/tui/src/tools/WebFetchTool/utils.ts +1 -1
- package/tui/src/tools/WebSearchTool/UI.tsx +0 -1
- package/tui/src/tools/WebSearchTool/WebSearchTool.ts +9 -313
- package/tui/src/tools/WebSearchTool/call.ts +33 -0
- package/tui/src/tools/WebSearchTool/responseMapping.ts +190 -0
- package/tui/src/tools/WebSearchTool/resultBlock.ts +47 -0
- package/tui/src/tools/WebSearchTool/schemas.ts +47 -0
- package/tui/src/tools/WebSearchTool/toolSchema.ts +12 -0
- package/tui/src/tools/WorkspaceToolAdapter/WorkspaceToolAdapter.ts +79 -0
- package/tui/src/tools/WorkspaceToolAdapter/allowedRootPolicy.ts +85 -0
- package/tui/src/tools/WorkspaceToolAdapter/documentFormatGuards.ts +73 -0
- package/tui/src/tools/WorkspaceToolAdapter/inputNormalization.ts +105 -0
- package/tui/src/tools/WorkspaceToolAdapter/mcpExposurePolicy.ts +64 -0
- package/tui/src/tools/WorkspaceToolAdapter/toolDefFactory.ts +215 -0
- package/tui/src/tools/WorkspaceToolAdapter/toolNames.ts +6 -0
- package/tui/src/tools/WorkspaceToolAdapter/workspacePolicy.ts +15 -0
- package/tui/src/tools/_shared/dispatchPrimitive.ts +6 -6
- package/tui/src/tools/_shared/documentChangeToPatch.ts +125 -0
- package/tui/src/tools/_shared/documentDispatchArguments.ts +87 -0
- package/tui/src/tools/_shared/documentPrimitiveTimeout.ts +13 -0
- package/tui/src/tools/_shared/documentToolResultRender.ts +98 -0
- package/tui/src/tools/_shared/pendingCallRegistry.ts +1 -6
- package/tui/src/tools/_shared/rootPrimitiveInput.ts +1 -0
- package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPatterns.ts +58 -0
- package/tui/src/tools/_shared/toolChoiceRepair/documentCompletionPrompt.ts +271 -0
- package/tui/src/tools/_shared/toolChoiceRepair/documentRepair.ts +452 -0
- package/tui/src/tools/_shared/toolChoiceRepair/messageAccess.ts +80 -0
- package/tui/src/tools/_shared/toolChoiceRepair/publicDataRepair.ts +92 -0
- package/tui/src/tools/_shared/toolChoiceRepair/supportRepair.ts +135 -0
- package/tui/src/tools/_shared/toolChoiceRepair.ts +55 -860
- package/tui/src/tools/shared/mockDisclaimer.ts +1 -1
- package/tui/src/tools.ts +39 -190
- package/tui/src/types/fileSuggestion.ts +4 -26
- package/tui/src/types/generated/events_mono/claude_code/v1/claude_code_internal_event.ts +186 -148
- package/tui/src/types/generated/events_mono/common/v1/auth.ts +25 -11
- package/tui/src/types/generated/events_mono/growthbook/v1/growthbook_experiment_event.ts +47 -30
- package/tui/src/types/generated/google/protobuf/timestamp.ts +21 -7
- package/tui/src/types/message.ts +80 -102
- package/tui/src/types/messageQueueTypes.ts +6 -28
- package/tui/src/types/notebook.ts +16 -38
- package/tui/src/types/statusLine.ts +4 -26
- package/tui/src/types/tools.ts +24 -46
- package/tui/src/types/utils.ts +6 -28
- package/tui/src/upstreamproxy/relay.ts +7 -3
- package/tui/src/upstreamproxy/upstreamproxy.ts +1 -1
- package/tui/src/utils/assistantMessageFactories.ts +9 -3
- package/tui/src/utils/auth.ts +129 -139
- package/tui/src/utils/bash/ast.ts +23 -23
- package/tui/src/utils/bash/bashParser.ts +5 -5
- package/tui/src/utils/billing.ts +1 -1
- package/tui/src/utils/claudeDesktop.ts +4 -4
- package/tui/src/utils/collapseReadSearch.ts +3 -3
- package/tui/src/utils/cronTasks.ts +1 -1
- package/tui/src/utils/execFileNoThrow.ts +1 -1
- package/tui/src/utils/filePersistence/types.ts +16 -38
- package/tui/src/utils/forkedAgent.ts +1 -1
- package/tui/src/utils/gracefulShutdown.ts +4 -4
- package/tui/src/utils/heapDumpService.ts +12 -8
- package/tui/src/utils/hooks/apiQueryHookHelper.ts +1 -1
- package/tui/src/utils/hooks/execPromptHook.ts +1 -1
- package/tui/src/utils/hooks/skillImprovement.ts +1 -1
- package/tui/src/utils/mcp/dateTimeParser.ts +1 -1
- package/tui/src/utils/messages.ts +18 -0
- package/tui/src/utils/migrateSessions.ts +3 -3
- package/tui/src/utils/model/model.ts +6 -6
- package/tui/src/utils/permissions/yoloClassifier.ts +1 -1
- package/tui/src/utils/plugins/headlessPluginInstall.ts +1 -1
- package/tui/src/utils/plugins/mcpPluginIntegration.ts +1 -1
- package/tui/src/utils/plugins/mcpbHandler.ts +1 -1
- package/tui/src/utils/plugins/pluginLoader.ts +8 -8
- package/tui/src/utils/protectedNamespace.ts +5 -3
- package/tui/src/utils/rawJsonToolCall.ts +242 -0
- package/tui/src/utils/ripgrep.ts +16 -7
- package/tui/src/utils/sessionTitle.ts +1 -1
- package/tui/src/utils/settings/permissionValidation.ts +14 -2
- package/tui/src/utils/shell/prefix.ts +1 -1
- package/tui/src/utils/sideQuery.ts +1 -1
- package/tui/src/utils/systemThemeWatcher.ts +13 -3
- package/tui/src/utils/teleport.tsx +1 -1
- package/uv.lock +426 -45
- package/tui/src/services/api/claude.ts +0 -3540
- package/tui/src/tools/_shared/directPublicDataGuard.ts +0 -362
- package/tui/src/tools/_shared/kmaAnalysisGuard.ts +0 -197
- package/tui/src/tools/_shared/kmaAviationGuard.ts +0 -70
- package/tui/src/tools/_shared/nmcAedGuard.ts +0 -234
- package/tui/src/tools/_shared/protectedCheckGuard.ts +0 -207
- 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
|
-
})
|
|
370
|
+
})
|
|
367
371
|
} else {
|
|
368
|
-
|
|
369
|
-
|
|
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:
|
|
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 {
|
|
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:
|
|
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 |
|
|
77
|
+
content: string | AssistantContentBlock[]
|
|
72
78
|
usage?: Usage
|
|
73
79
|
isVirtual?: true
|
|
74
80
|
}): AssistantMessage {
|
package/tui/src/utils/auth.ts
CHANGED
|
@@ -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
|
-
|
|
35
|
-
|
|
37
|
+
type FriendliKeychainIdentity = {
|
|
38
|
+
readonly account: string
|
|
39
|
+
readonly service: string
|
|
36
40
|
}
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
47
|
-
|
|
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
|
-
|
|
51
|
-
|
|
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
|
|
55
|
-
return false
|
|
56
|
-
}
|
|
121
|
+
export async function getClaudeAIOAuthTokens(): Promise<null> { return null }
|
|
57
122
|
|
|
58
|
-
export function
|
|
59
|
-
return false
|
|
60
|
-
}
|
|
123
|
+
export function isClaudeAISubscriber(): boolean { return false }
|
|
61
124
|
|
|
62
|
-
export function
|
|
63
|
-
return false
|
|
64
|
-
}
|
|
125
|
+
export function isConsumerSubscriber(): boolean { return false }
|
|
65
126
|
|
|
66
|
-
export function
|
|
67
|
-
return false
|
|
68
|
-
}
|
|
127
|
+
export function isMaxSubscriber(): boolean { return false }
|
|
69
128
|
|
|
70
|
-
export function
|
|
71
|
-
return false
|
|
72
|
-
}
|
|
129
|
+
export function isProSubscriber(): boolean { return false }
|
|
73
130
|
|
|
74
|
-
export function
|
|
75
|
-
return false
|
|
76
|
-
}
|
|
131
|
+
export function isTeamSubscriber(): boolean { return false }
|
|
77
132
|
|
|
78
|
-
export function
|
|
79
|
-
return false
|
|
80
|
-
}
|
|
133
|
+
export function isTeamPremiumSubscriber(): boolean { return false }
|
|
81
134
|
|
|
82
|
-
export function
|
|
83
|
-
return false
|
|
84
|
-
}
|
|
135
|
+
export function isEnterpriseSubscriber(): boolean { return false }
|
|
85
136
|
|
|
86
|
-
export function
|
|
87
|
-
return null
|
|
88
|
-
}
|
|
137
|
+
export function isAnthropicAuthEnabled(): boolean { return false }
|
|
89
138
|
|
|
90
|
-
export function
|
|
91
|
-
return null
|
|
92
|
-
}
|
|
139
|
+
export function is1PApiCustomer(): boolean { return false }
|
|
93
140
|
|
|
94
|
-
export function
|
|
95
|
-
return null
|
|
96
|
-
}
|
|
141
|
+
export function isUsing3PServices(): boolean { return false }
|
|
97
142
|
|
|
98
|
-
export function
|
|
99
|
-
return 'free'
|
|
100
|
-
}
|
|
143
|
+
export function isOverageProvisioningAllowed(): boolean { return false }
|
|
101
144
|
|
|
102
|
-
export function
|
|
103
|
-
|
|
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
|
-
|
|
260
|
-
getClaudeAIOAuthTokens,
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
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:
|
|
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
|
|
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
|
|
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 —
|
|
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
|
|
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 —
|
|
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
|
|
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 (
|
|
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:
|
|
1326
|
-
// resolved (or we'd have returned too-complex). This catches $VAR at
|
|
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
|
|
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
|
|
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
|
|
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 —
|
|
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
|
-
//
|
|
1913
|
-
// doesn't expand). Conservative:
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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++
|
package/tui/src/utils/billing.ts
CHANGED
|
@@ -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
|
|
22
|
+
// Check if user has a configured authentication source
|
|
23
23
|
const authSource = getAuthTokenSource()
|
|
24
24
|
const hasApiKey = getAnthropicApiKey() !== null
|
|
25
25
|
|