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