@lotagate/cli 0.1.21 → 0.1.22
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/dist/application/agent/agent-history.d.ts +3 -0
- package/dist/application/agent/agent-history.js +81 -0
- package/dist/application/agent/agent-input-context.d.ts +9 -0
- package/dist/application/agent/agent-input-context.js +12 -0
- package/dist/application/agent/agent-limit.d.ts +3 -0
- package/dist/application/agent/agent-limit.js +12 -0
- package/dist/application/agent/agent-run-tracker.d.ts +30 -0
- package/dist/application/agent/agent-run-tracker.js +68 -0
- package/dist/application/agent/agent-session-store.d.ts +19 -0
- package/dist/application/agent/agent-session-store.js +74 -0
- package/dist/application/agent/capability-profile.d.ts +37 -0
- package/dist/application/agent/capability-profile.js +13 -0
- package/dist/application/agent/cli-agent-execution-service.d.ts +81 -0
- package/dist/application/agent/cli-agent-execution-service.js +279 -0
- package/dist/application/agent/context-compaction-persistence.d.ts +8 -0
- package/dist/application/agent/context-compaction-persistence.js +27 -0
- package/dist/application/agent/context-compaction.d.ts +20 -0
- package/dist/application/agent/context-compaction.js +114 -0
- package/dist/application/agent/prompt-data-safety.d.ts +14 -0
- package/dist/application/agent/prompt-data-safety.js +38 -0
- package/dist/application/agent/safe-system-prompt.d.ts +3 -0
- package/dist/application/agent/safe-system-prompt.js +19 -0
- package/dist/application/agent/scoped-tool-executor.d.ts +13 -0
- package/dist/application/agent/scoped-tool-executor.js +32 -0
- package/dist/application/agent/system-prompt-builder.d.ts +14 -0
- package/dist/application/agent/system-prompt-builder.js +199 -0
- package/dist/application/agent/tool-catalog.d.ts +14 -0
- package/dist/application/agent/tool-catalog.js +30 -0
- package/dist/application/agent/tool-display.d.ts +6 -0
- package/dist/application/agent/tool-display.js +59 -0
- package/dist/application/agent/tool-hook-lifecycle.d.ts +19 -0
- package/dist/application/agent/tool-hook-lifecycle.js +85 -0
- package/dist/application/auth/authentication-service.d.ts +20 -0
- package/dist/application/auth/authentication-service.js +44 -0
- package/dist/application/chat/chat-service.d.ts +12 -0
- package/dist/application/chat/chat-service.js +19 -0
- package/dist/application/chat/pending-attachment-store.d.ts +12 -0
- package/dist/application/chat/pending-attachment-store.js +28 -0
- package/dist/application/commands/application-command-executor.d.ts +20 -0
- package/dist/application/commands/application-command-executor.js +66 -0
- package/dist/application/commands/cli-args.d.ts +6 -0
- package/dist/application/commands/cli-args.js +43 -0
- package/dist/application/commands/cli-command-services.d.ts +16 -0
- package/dist/application/commands/cli-command-services.js +405 -0
- package/dist/application/commands/command-catalog.d.ts +6 -0
- package/dist/application/commands/command-catalog.js +159 -0
- package/dist/application/commands/command-contract.d.ts +58 -0
- package/dist/application/commands/command-contract.js +1 -0
- package/dist/application/commands/command-hints.d.ts +9 -0
- package/dist/application/commands/command-hints.js +17 -0
- package/dist/application/commands/command-output.d.ts +4 -0
- package/dist/application/commands/command-output.js +1 -0
- package/dist/application/commands/command-parser.d.ts +10 -0
- package/dist/application/commands/command-parser.js +155 -0
- package/dist/application/commands/command-presentation.d.ts +7 -0
- package/dist/application/commands/command-presentation.js +131 -0
- package/dist/application/commands/command-registry.d.ts +11 -0
- package/dist/application/commands/command-registry.js +64 -0
- package/dist/application/commands/command-runtime.d.ts +2 -0
- package/dist/application/commands/command-runtime.js +3 -0
- package/dist/application/commands/goal-command-handlers.d.ts +3 -0
- package/dist/application/commands/goal-command-handlers.js +120 -0
- package/dist/application/commands/media-command-handlers.d.ts +9 -0
- package/dist/application/commands/media-command-handlers.js +307 -0
- package/dist/application/commands/media-command-output.d.ts +11 -0
- package/dist/application/commands/media-command-output.js +8 -0
- package/dist/application/commands/runtime-command-handlers.d.ts +7 -0
- package/dist/application/commands/runtime-command-handlers.js +177 -0
- package/dist/application/commands/stream-output.d.ts +4 -0
- package/dist/application/commands/stream-output.js +10 -0
- package/dist/application/commands/utility-commands.d.ts +6 -0
- package/dist/application/commands/utility-commands.js +81 -0
- package/dist/application/config/execution-config.d.ts +4 -0
- package/dist/application/config/execution-config.js +6 -0
- package/dist/application/extensions/extension-list-contract.d.ts +13 -0
- package/dist/application/extensions/extension-list-contract.js +1 -0
- package/dist/application/extensions/extension-list-formatters.d.ts +31 -0
- package/dist/application/extensions/extension-list-formatters.js +98 -0
- package/dist/application/extensions/extension-list-output.d.ts +3 -0
- package/dist/application/extensions/extension-list-output.js +7 -0
- package/dist/application/extensions/plugin-contribution-registry.d.ts +15 -0
- package/dist/application/extensions/plugin-contribution-registry.js +80 -0
- package/dist/application/extensions/skill-scope-store.d.ts +23 -0
- package/dist/application/extensions/skill-scope-store.js +33 -0
- package/dist/application/formatting/compact-number.d.ts +2 -0
- package/dist/application/formatting/compact-number.js +18 -0
- package/dist/application/formatting/compact-table.d.ts +22 -0
- package/dist/application/formatting/compact-table.js +49 -0
- package/dist/application/media/video-operation-poller.d.ts +5 -0
- package/dist/application/media/video-operation-poller.js +42 -0
- package/dist/application/model/cached-model-catalog.d.ts +13 -0
- package/dist/application/model/cached-model-catalog.js +31 -0
- package/dist/application/model/initial-model-selection.d.ts +10 -0
- package/dist/application/model/initial-model-selection.js +11 -0
- package/dist/application/model/model-catalog-service.d.ts +6 -0
- package/dist/application/model/model-catalog-service.js +13 -0
- package/dist/application/model/model-context-window.d.ts +3 -0
- package/dist/application/model/model-context-window.js +23 -0
- package/dist/application/orchestration/cli-subagent-service.d.ts +70 -0
- package/dist/application/orchestration/cli-subagent-service.js +328 -0
- package/dist/application/orchestration/cli-turn-event-projector.d.ts +12 -0
- package/dist/application/orchestration/cli-turn-event-projector.js +81 -0
- package/dist/application/orchestration/cli-turn-events.d.ts +76 -0
- package/dist/application/orchestration/cli-turn-events.js +39 -0
- package/dist/application/orchestration/cli-turn-persistence.d.ts +6 -0
- package/dist/application/orchestration/cli-turn-persistence.js +14 -0
- package/dist/application/orchestration/goal-evaluator.d.ts +18 -0
- package/dist/application/orchestration/goal-evaluator.js +88 -0
- package/dist/application/orchestration/goal-input.d.ts +3 -0
- package/dist/application/orchestration/goal-input.js +19 -0
- package/dist/application/orchestration/goal-output.d.ts +2 -0
- package/dist/application/orchestration/goal-output.js +11 -0
- package/dist/application/orchestration/goal-runner.d.ts +22 -0
- package/dist/application/orchestration/goal-runner.js +153 -0
- package/dist/application/orchestration/goal-usage.d.ts +9 -0
- package/dist/application/orchestration/goal-usage.js +19 -0
- package/dist/application/orchestration/headless-agent-turn.d.ts +32 -0
- package/dist/application/orchestration/headless-agent-turn.js +82 -0
- package/dist/application/orchestration/plan-generator.d.ts +7 -0
- package/dist/application/orchestration/plan-generator.js +34 -0
- package/dist/application/orchestration/subagent-coordinator.d.ts +33 -0
- package/dist/application/orchestration/subagent-coordinator.js +28 -0
- package/dist/application/orchestration/subagent-handoff.d.ts +2 -0
- package/dist/application/orchestration/subagent-handoff.js +68 -0
- package/dist/application/orchestration/subagent-tool-executor.d.ts +12 -0
- package/dist/application/orchestration/subagent-tool-executor.js +93 -0
- package/dist/application/orchestration/task-assessment.d.ts +4 -0
- package/dist/application/orchestration/task-assessment.js +35 -0
- package/dist/application/orchestration/task-graph.d.ts +13 -0
- package/dist/application/orchestration/task-graph.js +56 -0
- package/dist/application/orchestration/task-scheduler.d.ts +18 -0
- package/dist/application/orchestration/task-scheduler.js +88 -0
- package/dist/application/project/project-trust-service.d.ts +13 -0
- package/dist/application/project/project-trust-service.js +74 -0
- package/dist/application/protocol/browser-host-tool-executor.d.ts +41 -0
- package/dist/application/protocol/browser-host-tool-executor.js +88 -0
- package/dist/application/protocol/desktop-agent-command.d.ts +9 -0
- package/dist/application/protocol/desktop-agent-command.js +663 -0
- package/dist/application/protocol/desktop-attachment-store.d.ts +16 -0
- package/dist/application/protocol/desktop-attachment-store.js +82 -0
- package/dist/application/protocol/desktop-command-catalog.d.ts +2 -0
- package/dist/application/protocol/desktop-command-catalog.js +19 -0
- package/dist/application/protocol/desktop-command-contract.d.ts +22 -0
- package/dist/application/protocol/desktop-command-contract.js +3 -0
- package/dist/application/protocol/desktop-command-executor.d.ts +16 -0
- package/dist/application/protocol/desktop-command-executor.js +47 -0
- package/dist/application/protocol/desktop-command-output.d.ts +15 -0
- package/dist/application/protocol/desktop-command-output.js +24 -0
- package/dist/application/protocol/desktop-execution-policy.d.ts +17 -0
- package/dist/application/protocol/desktop-execution-policy.js +49 -0
- package/dist/application/protocol/desktop-host-tool-executor.d.ts +57 -0
- package/dist/application/protocol/desktop-host-tool-executor.js +53 -0
- package/dist/application/protocol/desktop-orchestration-events.d.ts +5 -0
- package/dist/application/protocol/desktop-orchestration-events.js +37 -0
- package/dist/application/protocol/json-line-writer.d.ts +9 -0
- package/dist/application/protocol/json-line-writer.js +19 -0
- package/dist/application/protocol/jsonl-agent-command.d.ts +3 -0
- package/dist/application/protocol/jsonl-agent-command.js +97 -0
- package/dist/application/protocol/jsonl-protocol.d.ts +52 -0
- package/dist/application/protocol/jsonl-protocol.js +170 -0
- package/dist/application/security/desktop-tool-scope-policy.d.ts +3 -0
- package/dist/application/security/desktop-tool-scope-policy.js +52 -0
- package/dist/application/security/tool-action-risk-analyzer.d.ts +13 -0
- package/dist/application/security/tool-action-risk-analyzer.js +64 -0
- package/dist/application/security/tool-approval-service.d.ts +35 -0
- package/dist/application/security/tool-approval-service.js +97 -0
- package/dist/application/security/tool-risk-classifier.d.ts +11 -0
- package/dist/application/security/tool-risk-classifier.js +65 -0
- package/dist/application/security/workspace-permission-policy.d.ts +10 -0
- package/dist/application/security/workspace-permission-policy.js +50 -0
- package/dist/application/session/project-session-access.d.ts +8 -0
- package/dist/application/session/project-session-access.js +19 -0
- package/dist/application/session/session-compaction-service.d.ts +10 -0
- package/dist/application/session/session-compaction-service.js +43 -0
- package/dist/application/session/session-turn-lifecycle.d.ts +5 -0
- package/dist/application/session/session-turn-lifecycle.js +31 -0
- package/dist/application/workspace/workspace-file-index.d.ts +15 -0
- package/dist/application/workspace/workspace-file-index.js +60 -0
- package/dist/application/workspace/workspace-file-reference-resolver.d.ts +14 -0
- package/dist/application/workspace/workspace-file-reference-resolver.js +123 -0
- package/dist/application/workspace/workspace-instruction-loader.d.ts +8 -0
- package/dist/application/workspace/workspace-instruction-loader.js +55 -0
- package/dist/bootstrap/composition-root.d.ts +6 -0
- package/dist/bootstrap/composition-root.js +4 -0
- package/dist/bootstrap/global-cli-options.d.ts +6 -0
- package/dist/bootstrap/global-cli-options.js +29 -0
- package/dist/bootstrap/native-devtools-stub.d.ts +10 -0
- package/dist/bootstrap/native-devtools-stub.js +10 -0
- package/dist/bootstrap/native-entry.d.ts +1 -0
- package/dist/bootstrap/native-entry.js +6 -0
- package/dist/bootstrap/native-tiktoken.d.ts +4 -0
- package/dist/bootstrap/native-tiktoken.js +5 -0
- package/dist/bootstrap/runtime-factory.d.ts +35 -0
- package/dist/bootstrap/runtime-factory.js +44 -0
- package/dist/bootstrap/shutdown-manager.d.ts +10 -0
- package/dist/bootstrap/shutdown-manager.js +14 -0
- package/dist/bootstrap/startup-sequence.d.ts +5 -0
- package/dist/bootstrap/startup-sequence.js +10 -0
- package/dist/domain/auth/auth-profile.d.ts +14 -0
- package/dist/domain/auth/auth-profile.js +39 -0
- package/dist/domain/config/config-schema.d.ts +17 -0
- package/dist/domain/config/config-schema.js +105 -0
- package/dist/domain/errors/cli-command-hint.d.ts +5 -0
- package/dist/domain/errors/cli-command-hint.js +1 -0
- package/dist/domain/errors/cli-error.d.ts +35 -0
- package/dist/domain/errors/cli-error.js +129 -0
- package/dist/domain/errors/error-codes.d.ts +46 -0
- package/dist/domain/errors/error-codes.js +45 -0
- package/dist/domain/extensions/extension-scope.d.ts +3 -0
- package/dist/domain/extensions/extension-scope.js +23 -0
- package/dist/domain/extensions/extension-state.d.ts +5 -0
- package/dist/domain/extensions/extension-state.js +11 -0
- package/dist/domain/extensions/hook-manifest.d.ts +10 -0
- package/dist/domain/extensions/hook-manifest.js +23 -0
- package/dist/domain/extensions/mcp-config.d.ts +18 -0
- package/dist/domain/extensions/mcp-config.js +111 -0
- package/dist/domain/extensions/plugin-manifest.d.ts +11 -0
- package/dist/domain/extensions/plugin-manifest.js +43 -0
- package/dist/domain/extensions/skill-manifest.d.ts +10 -0
- package/dist/domain/extensions/skill-manifest.js +51 -0
- package/dist/domain/filesystem/file-change-diff.d.ts +21 -0
- package/dist/domain/filesystem/file-change-diff.js +60 -0
- package/dist/domain/media/gateway-media-contract.d.ts +23 -0
- package/dist/domain/media/gateway-media-contract.js +163 -0
- package/dist/domain/media/media-contract.d.ts +28 -0
- package/dist/domain/media/media-contract.js +1 -0
- package/dist/domain/media/media-execution-policy.d.ts +9 -0
- package/dist/domain/media/media-execution-policy.js +31 -0
- package/dist/domain/orchestration/goal.d.ts +58 -0
- package/dist/domain/orchestration/goal.js +113 -0
- package/dist/domain/orchestration/subagent-identity.d.ts +2 -0
- package/dist/domain/orchestration/subagent-identity.js +8 -0
- package/dist/domain/orchestration/subagent.d.ts +33 -0
- package/dist/domain/orchestration/subagent.js +1 -0
- package/dist/domain/orchestration/task.d.ts +31 -0
- package/dist/domain/orchestration/task.js +1 -0
- package/dist/domain/project/project-identity.d.ts +6 -0
- package/dist/domain/project/project-identity.js +4 -0
- package/dist/domain/runtime/assistant-delta-normalizer.d.ts +11 -0
- package/dist/domain/runtime/assistant-delta-normalizer.js +19 -0
- package/dist/domain/runtime/resource-limits.d.ts +60 -0
- package/dist/domain/runtime/resource-limits.js +60 -0
- package/dist/domain/session/attachment.d.ts +13 -0
- package/dist/domain/session/attachment.js +1 -0
- package/dist/domain/session/session-schema.d.ts +6 -0
- package/dist/domain/session/session-schema.js +28 -0
- package/dist/domain/session/session.d.ts +27 -0
- package/dist/domain/session/session.js +1 -0
- package/dist/domain/settings/settings-document.d.ts +8 -0
- package/dist/domain/settings/settings-document.js +36 -0
- package/dist/domain/validation/record-schema.d.ts +4 -0
- package/dist/domain/validation/record-schema.js +9 -0
- package/dist/domain/workspace/workspace-settings.d.ts +12 -0
- package/dist/domain/workspace/workspace-settings.js +44 -0
- package/dist/infrastructure/agent-sdk/agent-instance-factory.d.ts +22 -0
- package/dist/infrastructure/agent-sdk/agent-instance-factory.js +31 -0
- package/dist/infrastructure/agent-sdk/tool-calling-model-client.d.ts +11 -0
- package/dist/infrastructure/agent-sdk/tool-calling-model-client.js +447 -0
- package/dist/infrastructure/cache/cache-policy.d.ts +7 -0
- package/dist/infrastructure/cache/cache-policy.js +18 -0
- package/dist/infrastructure/cache/file-cache-store.d.ts +17 -0
- package/dist/infrastructure/cache/file-cache-store.js +121 -0
- package/dist/infrastructure/clipboard/clipboard-adapter-factory.d.ts +11 -0
- package/dist/infrastructure/clipboard/clipboard-adapter-factory.js +98 -0
- package/dist/infrastructure/clipboard/clipboard-policy.d.ts +8 -0
- package/dist/infrastructure/clipboard/clipboard-policy.js +19 -0
- package/dist/infrastructure/clipboard/clipboard-text-adapter-factory.d.ts +10 -0
- package/dist/infrastructure/clipboard/clipboard-text-adapter-factory.js +94 -0
- package/dist/infrastructure/clipboard/image-normalizer.d.ts +12 -0
- package/dist/infrastructure/clipboard/image-normalizer.js +78 -0
- package/dist/infrastructure/clipboard/windows-clipboard-adapter.d.ts +7 -0
- package/dist/infrastructure/clipboard/windows-clipboard-adapter.js +66 -0
- package/dist/infrastructure/clipboard/windows-clipboard-text-adapter.d.ts +7 -0
- package/dist/infrastructure/clipboard/windows-clipboard-text-adapter.js +70 -0
- package/dist/infrastructure/config/config-loader.d.ts +19 -0
- package/dist/infrastructure/config/config-loader.js +76 -0
- package/dist/infrastructure/config/environment-values.d.ts +2 -0
- package/dist/infrastructure/config/environment-values.js +7 -0
- package/dist/infrastructure/credentials/composite-credential-store.d.ts +11 -0
- package/dist/infrastructure/credentials/composite-credential-store.js +32 -0
- package/dist/infrastructure/credentials/encrypted-file-credential-store.d.ts +17 -0
- package/dist/infrastructure/credentials/encrypted-file-credential-store.js +181 -0
- package/dist/infrastructure/credentials/environment-credential-store.d.ts +11 -0
- package/dist/infrastructure/credentials/environment-credential-store.js +37 -0
- package/dist/infrastructure/credentials/secret-input.d.ts +7 -0
- package/dist/infrastructure/credentials/secret-input.js +44 -0
- package/dist/infrastructure/extensions/composite-mcp-config-store.d.ts +9 -0
- package/dist/infrastructure/extensions/composite-mcp-config-store.js +10 -0
- package/dist/infrastructure/extensions/extension-directory-reader.d.ts +2 -0
- package/dist/infrastructure/extensions/extension-directory-reader.js +15 -0
- package/dist/infrastructure/extensions/extension-source-resolver.d.ts +6 -0
- package/dist/infrastructure/extensions/extension-source-resolver.js +126 -0
- package/dist/infrastructure/extensions/file-mcp-config-store.d.ts +15 -0
- package/dist/infrastructure/extensions/file-mcp-config-store.js +66 -0
- package/dist/infrastructure/extensions/hook-runtime.d.ts +18 -0
- package/dist/infrastructure/extensions/hook-runtime.js +66 -0
- package/dist/infrastructure/extensions/mcp-runtime.d.ts +12 -0
- package/dist/infrastructure/extensions/mcp-runtime.js +52 -0
- package/dist/infrastructure/extensions/plugin-discovery.d.ts +5 -0
- package/dist/infrastructure/extensions/plugin-discovery.js +52 -0
- package/dist/infrastructure/extensions/plugin-manager.d.ts +26 -0
- package/dist/infrastructure/extensions/plugin-manager.js +139 -0
- package/dist/infrastructure/extensions/skill-discovery.d.ts +4 -0
- package/dist/infrastructure/extensions/skill-discovery.js +29 -0
- package/dist/infrastructure/extensions/skill-installer.d.ts +8 -0
- package/dist/infrastructure/extensions/skill-installer.js +88 -0
- package/dist/infrastructure/extensions/skill-manager.d.ts +22 -0
- package/dist/infrastructure/extensions/skill-manager.js +67 -0
- package/dist/infrastructure/extensions/skill-roots.d.ts +19 -0
- package/dist/infrastructure/extensions/skill-roots.js +25 -0
- package/dist/infrastructure/extensions/skill-tool-executor.d.ts +18 -0
- package/dist/infrastructure/extensions/skill-tool-executor.js +53 -0
- package/dist/infrastructure/filesystem/atomic-file-store.d.ts +12 -0
- package/dist/infrastructure/filesystem/atomic-file-store.js +106 -0
- package/dist/infrastructure/filesystem/bounded-file-reader.d.ts +6 -0
- package/dist/infrastructure/filesystem/bounded-file-reader.js +24 -0
- package/dist/infrastructure/filesystem/bounded-json-reader.d.ts +1 -0
- package/dist/infrastructure/filesystem/bounded-json-reader.js +7 -0
- package/dist/infrastructure/filesystem/fs-errors.d.ts +2 -0
- package/dist/infrastructure/filesystem/fs-errors.js +6 -0
- package/dist/infrastructure/filesystem/gateway-media-input-reader.d.ts +12 -0
- package/dist/infrastructure/filesystem/gateway-media-input-reader.js +49 -0
- package/dist/infrastructure/filesystem/local-filesystem-tool-executor.d.ts +21 -0
- package/dist/infrastructure/filesystem/local-filesystem-tool-executor.js +176 -0
- package/dist/infrastructure/filesystem/path-resolver.d.ts +20 -0
- package/dist/infrastructure/filesystem/path-resolver.js +119 -0
- package/dist/infrastructure/filesystem/workspace-media-artifact-store.d.ts +13 -0
- package/dist/infrastructure/filesystem/workspace-media-artifact-store.js +152 -0
- package/dist/infrastructure/logging/daily-rotating-file-writer.d.ts +20 -0
- package/dist/infrastructure/logging/daily-rotating-file-writer.js +75 -0
- package/dist/infrastructure/logging/log-redactor.d.ts +2 -0
- package/dist/infrastructure/logging/log-redactor.js +26 -0
- package/dist/infrastructure/logging/logging-policy.d.ts +6 -0
- package/dist/infrastructure/logging/logging-policy.js +6 -0
- package/dist/infrastructure/logging/structured-logger.d.ts +24 -0
- package/dist/infrastructure/logging/structured-logger.js +40 -0
- package/dist/infrastructure/network/safe-media-downloader.d.ts +23 -0
- package/dist/infrastructure/network/safe-media-downloader.js +239 -0
- package/dist/infrastructure/platform/host-platform.d.ts +14 -0
- package/dist/infrastructure/platform/host-platform.js +23 -0
- package/dist/infrastructure/platform/host-process.d.ts +17 -0
- package/dist/infrastructure/platform/host-process.js +116 -0
- package/dist/infrastructure/platform/platform-paths.d.ts +25 -0
- package/dist/infrastructure/platform/platform-paths.js +33 -0
- package/dist/infrastructure/project/file-project-trust-store.d.ts +12 -0
- package/dist/infrastructure/project/file-project-trust-store.js +59 -0
- package/dist/infrastructure/sdk/chat-completion-adapter.d.ts +8 -0
- package/dist/infrastructure/sdk/chat-completion-adapter.js +115 -0
- package/dist/infrastructure/sdk/lotagate-client-factory.d.ts +3 -0
- package/dist/infrastructure/sdk/lotagate-client-factory.js +8 -0
- package/dist/infrastructure/sdk/model-catalog-adapter.d.ts +19 -0
- package/dist/infrastructure/sdk/model-catalog-adapter.js +28 -0
- package/dist/infrastructure/sdk/sdk-media-gateway-client.d.ts +20 -0
- package/dist/infrastructure/sdk/sdk-media-gateway-client.js +97 -0
- package/dist/infrastructure/sessions/file-goal-store.d.ts +21 -0
- package/dist/infrastructure/sessions/file-goal-store.js +160 -0
- package/dist/infrastructure/sessions/file-session-store.d.ts +48 -0
- package/dist/infrastructure/sessions/file-session-store.js +525 -0
- package/dist/infrastructure/sessions/project-session-paths.d.ts +17 -0
- package/dist/infrastructure/sessions/project-session-paths.js +41 -0
- package/dist/infrastructure/sessions/session-index.d.ts +16 -0
- package/dist/infrastructure/sessions/session-index.js +84 -0
- package/dist/infrastructure/sessions/session-journal.d.ts +22 -0
- package/dist/infrastructure/sessions/session-journal.js +137 -0
- package/dist/infrastructure/sessions/subagent-journal-store.d.ts +28 -0
- package/dist/infrastructure/sessions/subagent-journal-store.js +30 -0
- package/dist/infrastructure/shell/shell-tool-executor.d.ts +17 -0
- package/dist/infrastructure/shell/shell-tool-executor.js +115 -0
- package/dist/infrastructure/tokens/tiktoken-token-estimator.d.ts +18 -0
- package/dist/infrastructure/tokens/tiktoken-token-estimator.js +48 -0
- package/dist/infrastructure/workspace/workspace-settings-store.d.ts +9 -0
- package/dist/infrastructure/workspace/workspace-settings-store.js +75 -0
- package/dist/main.d.ts +7 -0
- package/dist/main.js +66 -0
- package/dist/ports/cache-store.d.ts +10 -0
- package/dist/ports/cache-store.js +1 -0
- package/dist/ports/chat-model.d.ts +30 -0
- package/dist/ports/chat-model.js +1 -0
- package/dist/ports/clipboard-adapter.d.ts +7 -0
- package/dist/ports/clipboard-adapter.js +1 -0
- package/dist/ports/clipboard-text-adapter.d.ts +3 -0
- package/dist/ports/clipboard-text-adapter.js +1 -0
- package/dist/ports/credential-store.d.ts +7 -0
- package/dist/ports/credential-store.js +1 -0
- package/dist/ports/goal-store.d.ts +12 -0
- package/dist/ports/goal-store.js +1 -0
- package/dist/ports/logger.d.ts +8 -0
- package/dist/ports/logger.js +1 -0
- package/dist/ports/media-gateway-client.d.ts +54 -0
- package/dist/ports/media-gateway-client.js +1 -0
- package/dist/ports/model-diagnostics.d.ts +17 -0
- package/dist/ports/model-diagnostics.js +1 -0
- package/dist/ports/project-trust-store.d.ts +12 -0
- package/dist/ports/project-trust-store.js +1 -0
- package/dist/ports/session-store.d.ts +58 -0
- package/dist/ports/session-store.js +1 -0
- package/dist/ports/subagent-lifecycle.d.ts +31 -0
- package/dist/ports/subagent-lifecycle.js +1 -0
- package/dist/ports/tool-activity.d.ts +13 -0
- package/dist/ports/tool-activity.js +1 -0
- package/dist/presentation/themes/theme.d.ts +19 -0
- package/dist/presentation/themes/theme.js +8 -0
- package/dist/presentation/tui/agent-initialization-renderer.d.ts +4 -0
- package/dist/presentation/tui/agent-initialization-renderer.js +37 -0
- package/dist/presentation/tui/context-display.d.ts +21 -0
- package/dist/presentation/tui/context-display.js +33 -0
- package/dist/presentation/tui/formatters.d.ts +6 -0
- package/dist/presentation/tui/formatters.js +60 -0
- package/dist/presentation/tui/ink/choice-window.d.ts +5 -0
- package/dist/presentation/tui/ink/choice-window.js +5 -0
- package/dist/presentation/tui/ink/components/activity-entry.d.ts +6 -0
- package/dist/presentation/tui/ink/components/activity-entry.js +16 -0
- package/dist/presentation/tui/ink/components/activity-status.d.ts +10 -0
- package/dist/presentation/tui/ink/components/activity-status.js +21 -0
- package/dist/presentation/tui/ink/components/choice-modal.d.ts +11 -0
- package/dist/presentation/tui/ink/components/choice-modal.js +29 -0
- package/dist/presentation/tui/ink/components/composer.d.ts +40 -0
- package/dist/presentation/tui/ink/components/composer.js +271 -0
- package/dist/presentation/tui/ink/components/file-diff.d.ts +6 -0
- package/dist/presentation/tui/ink/components/file-diff.js +34 -0
- package/dist/presentation/tui/ink/components/modal.d.ts +8 -0
- package/dist/presentation/tui/ink/components/modal.js +110 -0
- package/dist/presentation/tui/ink/components/shimmer-text.d.ts +6 -0
- package/dist/presentation/tui/ink/components/shimmer-text.js +9 -0
- package/dist/presentation/tui/ink/components/subagent-activity.d.ts +11 -0
- package/dist/presentation/tui/ink/components/subagent-activity.js +61 -0
- package/dist/presentation/tui/ink/components/transcript.d.ts +39 -0
- package/dist/presentation/tui/ink/components/transcript.js +121 -0
- package/dist/presentation/tui/ink/components/welcome-panel.d.ts +6 -0
- package/dist/presentation/tui/ink/components/welcome-panel.js +20 -0
- package/dist/presentation/tui/ink/lotagate-tui.d.ts +6 -0
- package/dist/presentation/tui/ink/lotagate-tui.js +136 -0
- package/dist/presentation/tui/ink/markdown-inline-renderer.d.ts +4 -0
- package/dist/presentation/tui/ink/markdown-inline-renderer.js +20 -0
- package/dist/presentation/tui/ink/markdown-inline.d.ts +13 -0
- package/dist/presentation/tui/ink/markdown-inline.js +91 -0
- package/dist/presentation/tui/ink/markdown-message.d.ts +6 -0
- package/dist/presentation/tui/ink/markdown-message.js +66 -0
- package/dist/presentation/tui/ink/markdown-table.d.ts +16 -0
- package/dist/presentation/tui/ink/markdown-table.js +77 -0
- package/dist/presentation/tui/ink/tui-bridge.d.ts +195 -0
- package/dist/presentation/tui/ink/tui-bridge.js +289 -0
- package/dist/presentation/tui/terminal-capabilities.d.ts +15 -0
- package/dist/presentation/tui/terminal-capabilities.js +7 -0
- package/dist/presentation/tui/terminal-mouse.d.ts +5 -0
- package/dist/presentation/tui/terminal-mouse.js +19 -0
- package/dist/presentation/tui/terminal-screen.d.ts +10 -0
- package/dist/presentation/tui/terminal-screen.js +23 -0
- package/dist/presentation/tui/tui-agent-event-runner.d.ts +24 -0
- package/dist/presentation/tui/tui-agent-event-runner.js +69 -0
- package/dist/presentation/tui/tui-application-contract.d.ts +10 -0
- package/dist/presentation/tui/tui-application-contract.js +8 -0
- package/dist/presentation/tui/tui-application.d.ts +62 -0
- package/dist/presentation/tui/tui-application.js +675 -0
- package/dist/presentation/tui/tui-attachment-input.d.ts +2 -0
- package/dist/presentation/tui/tui-attachment-input.js +5 -0
- package/dist/presentation/tui/tui-clipboard-paste-handlers.d.ts +11 -0
- package/dist/presentation/tui/tui-clipboard-paste-handlers.js +25 -0
- package/dist/presentation/tui/tui-command-context.d.ts +3 -0
- package/dist/presentation/tui/tui-command-context.js +1 -0
- package/dist/presentation/tui/tui-command-executor.d.ts +38 -0
- package/dist/presentation/tui/tui-command-executor.js +214 -0
- package/dist/presentation/tui/tui-command-host-factory.d.ts +40 -0
- package/dist/presentation/tui/tui-command-host-factory.js +23 -0
- package/dist/presentation/tui/tui-context-compaction.d.ts +5 -0
- package/dist/presentation/tui/tui-context-compaction.js +22 -0
- package/dist/presentation/tui/tui-context-service.d.ts +34 -0
- package/dist/presentation/tui/tui-context-service.js +126 -0
- package/dist/presentation/tui/tui-file-suggestions.d.ts +3 -0
- package/dist/presentation/tui/tui-file-suggestions.js +8 -0
- package/dist/presentation/tui/tui-goal-controller.d.ts +14 -0
- package/dist/presentation/tui/tui-goal-controller.js +52 -0
- package/dist/presentation/tui/tui-initial-model.d.ts +3 -0
- package/dist/presentation/tui/tui-initial-model.js +28 -0
- package/dist/presentation/tui/tui-lifecycle-actions.d.ts +13 -0
- package/dist/presentation/tui/tui-lifecycle-actions.js +45 -0
- package/dist/presentation/tui/tui-manual-compaction.d.ts +18 -0
- package/dist/presentation/tui/tui-manual-compaction.js +31 -0
- package/dist/presentation/tui/tui-media-model-selection.d.ts +12 -0
- package/dist/presentation/tui/tui-media-model-selection.js +38 -0
- package/dist/presentation/tui/tui-prompt-dispatcher.d.ts +16 -0
- package/dist/presentation/tui/tui-prompt-dispatcher.js +38 -0
- package/dist/presentation/tui/tui-skill-controller.d.ts +11 -0
- package/dist/presentation/tui/tui-skill-controller.js +13 -0
- package/dist/presentation/tui/tui-tool-approval.d.ts +22 -0
- package/dist/presentation/tui/tui-tool-approval.js +73 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/package.json +8 -7
- package/scripts/install-native.mjs +11 -11
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useAnimation } from 'ink';
|
|
3
|
+
import { DARK_THEME as palette } from '../../../themes/theme.js';
|
|
4
|
+
import { ShimmerText } from './shimmer-text.js';
|
|
5
|
+
export function ActivityStatus({ status, activityStartedAt, elapsedMs, usage, paused = false }) {
|
|
6
|
+
const active = status !== 'Done' && status !== 'Cancelled' && status !== 'Failed';
|
|
7
|
+
const animation = useAnimation({ interval: 120, isActive: active && !paused });
|
|
8
|
+
const elapsed = active && activityStartedAt !== undefined ? Math.max(elapsedMs ?? 0, Date.now() - activityStartedAt) : elapsedMs ?? 0;
|
|
9
|
+
const details = [formatDuration(elapsed)];
|
|
10
|
+
const outputTokens = usage?.completionTokens ?? usage?.totalTokens;
|
|
11
|
+
if (outputTokens !== undefined)
|
|
12
|
+
details.push(`${usage?.estimated === true ? '~' : ''}${outputTokens} output tokens`);
|
|
13
|
+
if (active)
|
|
14
|
+
details.push('Esc cancel');
|
|
15
|
+
const indicator = active ? ['◐', '◓', '◑', '◒'][animation.frame % 4] ?? '◐' : '●';
|
|
16
|
+
const color = status === 'Failed' ? palette.error : active ? palette.warning : palette.success;
|
|
17
|
+
return _jsxs(Box, { marginBottom: 1, children: [_jsxs(Text, { color: color, children: [indicator, " "] }), _jsx(ShimmerText, { value: status, active: active && !paused, frame: animation.frame }), _jsxs(Text, { color: palette.muted, children: [" ", details.join(' · ')] })] });
|
|
18
|
+
}
|
|
19
|
+
function formatDuration(milliseconds) {
|
|
20
|
+
return milliseconds < 1000 ? `${milliseconds}ms` : `${(milliseconds / 1000).toFixed(1)}s`;
|
|
21
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
import type { InkTuiBridge, TuiChoice } from '../tui-bridge.js';
|
|
3
|
+
export interface ChoiceModalProps {
|
|
4
|
+
bridge: InkTuiBridge;
|
|
5
|
+
title: string;
|
|
6
|
+
choices: readonly TuiChoice[];
|
|
7
|
+
currentValue?: string;
|
|
8
|
+
detail?: string;
|
|
9
|
+
borderColor?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function ChoiceModal({ bridge, title, choices, currentValue, detail, borderColor }: ChoiceModalProps): JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import { Box, Text, useInput } from 'ink';
|
|
4
|
+
import { DARK_THEME as palette } from '../../../themes/theme.js';
|
|
5
|
+
import { choiceWindow } from '../choice-window.js';
|
|
6
|
+
export function ChoiceModal({ bridge, title, choices, currentValue, detail, borderColor = palette.accent }) {
|
|
7
|
+
const initial = choices.findIndex((choice) => choice.value === currentValue);
|
|
8
|
+
const [selected, setSelected] = useState(Math.max(0, initial));
|
|
9
|
+
const window = choiceWindow(choices, selected, 8);
|
|
10
|
+
useInput((input, key) => {
|
|
11
|
+
if (key.upArrow)
|
|
12
|
+
setSelected((current) => Math.max(0, current - 1));
|
|
13
|
+
else if (key.downArrow)
|
|
14
|
+
setSelected((current) => Math.min(Math.max(0, choices.length - 1), current + 1));
|
|
15
|
+
else if (key.return)
|
|
16
|
+
bridge.resolveActiveModal(choices[selected]?.value);
|
|
17
|
+
else if (input.toLowerCase() === 'y' && choices.some((choice) => choice.value === 'allow'))
|
|
18
|
+
bridge.resolveActiveModal('allow');
|
|
19
|
+
else if (input.toLowerCase() === 'n' && choices.some((choice) => choice.value === 'deny'))
|
|
20
|
+
bridge.resolveActiveModal('deny');
|
|
21
|
+
else if (key.escape || input === 'q')
|
|
22
|
+
bridge.resolveActiveModal(undefined);
|
|
23
|
+
});
|
|
24
|
+
return _jsxs(Box, { borderStyle: "double", borderColor: borderColor, flexDirection: "column", marginTop: 1, paddingX: 1, children: [_jsx(Text, { bold: true, color: palette.text, children: "Action required" }), _jsx(Text, { color: palette.text, children: title }), detail !== undefined && _jsx(Text, { color: palette.muted, children: detail }), window.entries.map((choice, index) => {
|
|
25
|
+
const active = window.start + index === selected;
|
|
26
|
+
const activeBackground = active ? { backgroundColor: palette.selection } : {};
|
|
27
|
+
return _jsxs(Box, { width: "100%", alignSelf: "stretch", flexDirection: "row", ...activeBackground, children: [_jsx(Text, { color: active ? palette.accent : palette.muted, ...activeBackground, children: "\u203A " }), _jsx(Text, { color: palette.text, ...activeBackground, children: choice.label }), choice.description !== undefined && _jsxs(Text, { color: palette.muted, ...activeBackground, children: [" ", choice.description] })] }, choice.value);
|
|
28
|
+
}), _jsx(Text, { color: palette.muted, children: "\u2191\u2193 navigate \u00B7 Enter select \u00B7 Esc cancel" })] });
|
|
29
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
import type { Attachment } from '../../../../domain/session/attachment.js';
|
|
3
|
+
import type { InkTuiBridge, TuiChoice } from '../tui-bridge.js';
|
|
4
|
+
export interface ComposerCursorPosition {
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
}
|
|
8
|
+
interface ComposerInputLayout {
|
|
9
|
+
x: number;
|
|
10
|
+
y: number;
|
|
11
|
+
width: number;
|
|
12
|
+
}
|
|
13
|
+
export declare function calculateComposerCursorPosition({ layout, value, cursor, terminalRows }: {
|
|
14
|
+
layout: ComposerInputLayout;
|
|
15
|
+
value: string;
|
|
16
|
+
cursor: number;
|
|
17
|
+
terminalRows?: number;
|
|
18
|
+
}): ComposerCursorPosition | undefined;
|
|
19
|
+
export declare function Composer({ bridge, enabled, activeRun, visible, clearBlockedUntil, footerNotice, contextUsage, attachments, fileChoices, onLayoutRowsChange }: {
|
|
20
|
+
bridge: InkTuiBridge;
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
activeRun: boolean;
|
|
23
|
+
visible?: boolean;
|
|
24
|
+
clearBlockedUntil?: number;
|
|
25
|
+
footerNotice?: string;
|
|
26
|
+
contextUsage?: {
|
|
27
|
+
usedTokens: number;
|
|
28
|
+
contextWindow?: number;
|
|
29
|
+
};
|
|
30
|
+
attachments: readonly Attachment[];
|
|
31
|
+
fileChoices: readonly TuiChoice[];
|
|
32
|
+
onLayoutRowsChange?: (rows: number) => void;
|
|
33
|
+
}): JSX.Element | null;
|
|
34
|
+
export interface AtFileReference {
|
|
35
|
+
start: number;
|
|
36
|
+
query: string;
|
|
37
|
+
}
|
|
38
|
+
/** Returns the active unquoted @workspace-file token immediately before the cursor. */
|
|
39
|
+
export declare function atFileReference(value: string, cursor: number): AtFileReference | undefined;
|
|
40
|
+
export {};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
3
|
+
import { Box, Text, measureElement, useCursor, useInput, usePaste, useStdout } from 'ink';
|
|
4
|
+
import { formatContextUsage, terminalTextWidth } from '../../formatters.js';
|
|
5
|
+
import { DARK_THEME as palette } from '../../../themes/theme.js';
|
|
6
|
+
import { AttachmentChip } from './transcript.js';
|
|
7
|
+
import { isMouseSequence } from '../../terminal-mouse.js';
|
|
8
|
+
import { commandSuggestions } from '../../../../application/commands/command-presentation.js';
|
|
9
|
+
import { parseCommandInvocation, tokenizeCommandInput } from '../../../../application/commands/command-parser.js';
|
|
10
|
+
import { COMMAND_REGISTRY } from '../../../../application/commands/command-runtime.js';
|
|
11
|
+
const INPUT_CONTENT_OFFSET = 4;
|
|
12
|
+
export function calculateComposerCursorPosition({ layout, value, cursor, terminalRows }) {
|
|
13
|
+
const beforeCursor = value.slice(0, cursor).split('\n');
|
|
14
|
+
const contentWidth = Math.max(1, layout.width - (INPUT_CONTENT_OFFSET + 2));
|
|
15
|
+
const completedRows = beforeCursor.slice(0, -1).reduce((rows, line) => rows + Math.max(1, Math.ceil(terminalTextWidth(line) / contentWidth)), 0);
|
|
16
|
+
const activeLineWidth = terminalTextWidth(beforeCursor.at(-1) ?? '');
|
|
17
|
+
const y = layout.y + 1 + completedRows + Math.floor(activeLineWidth / contentWidth);
|
|
18
|
+
if (terminalRows !== undefined && (y < 0 || y >= terminalRows))
|
|
19
|
+
return undefined;
|
|
20
|
+
return { x: layout.x + INPUT_CONTENT_OFFSET + (activeLineWidth % contentWidth), y };
|
|
21
|
+
}
|
|
22
|
+
export function Composer({ bridge, enabled, activeRun, visible = true, clearBlockedUntil, footerNotice, contextUsage, attachments, fileChoices, onLayoutRowsChange }) {
|
|
23
|
+
const [value, setValue] = useState('');
|
|
24
|
+
const [cursor, setCursor] = useState(0);
|
|
25
|
+
const [selected, setSelected] = useState(0);
|
|
26
|
+
const [clearHint, setClearHint] = useState();
|
|
27
|
+
const clearTimer = useRef(undefined);
|
|
28
|
+
const clearArmed = useRef(false);
|
|
29
|
+
const valueRef = useRef('');
|
|
30
|
+
const cursorRef = useRef(0);
|
|
31
|
+
const selectedCommandRef = useRef(undefined);
|
|
32
|
+
const inputRef = useRef(null);
|
|
33
|
+
const [inputMetrics, setInputMetrics] = useState({ left: 0, top: 0, width: 0, hasMeasured: false });
|
|
34
|
+
const { setCursorPosition: setInkCursorPosition } = useCursor();
|
|
35
|
+
const { stdout } = useStdout();
|
|
36
|
+
const suggestions = value.startsWith('/') && !value.includes('\n') && selectedCommandRef.current !== value
|
|
37
|
+
? commandSuggestions(value, COMMAND_REGISTRY, 'tui').slice(0, 8)
|
|
38
|
+
: [];
|
|
39
|
+
const fileReference = atFileReference(value, cursor);
|
|
40
|
+
const fileSuggestions = fileReference === undefined ? [] : fileChoices.filter((choice) => choice.value.slice(1).toLowerCase().includes(fileReference.query.toLowerCase())).slice(0, 8);
|
|
41
|
+
const choices = suggestions.length > 0 ? suggestions : fileSuggestions;
|
|
42
|
+
const dismissClearPrompt = () => {
|
|
43
|
+
clearArmed.current = false;
|
|
44
|
+
setClearHint(undefined);
|
|
45
|
+
if (clearTimer.current !== undefined)
|
|
46
|
+
clearTimeout(clearTimer.current);
|
|
47
|
+
clearTimer.current = undefined;
|
|
48
|
+
};
|
|
49
|
+
const updateDraft = (nextValue, nextCursor) => {
|
|
50
|
+
valueRef.current = nextValue;
|
|
51
|
+
cursorRef.current = nextCursor;
|
|
52
|
+
setValue(nextValue);
|
|
53
|
+
setCursor(nextCursor);
|
|
54
|
+
};
|
|
55
|
+
const clearSelectedCommand = () => {
|
|
56
|
+
selectedCommandRef.current = undefined;
|
|
57
|
+
};
|
|
58
|
+
const chooseCommand = (choice) => {
|
|
59
|
+
updateDraft(choice.value, choice.value.length);
|
|
60
|
+
selectedCommandRef.current = choice.value;
|
|
61
|
+
setSelected(0);
|
|
62
|
+
};
|
|
63
|
+
const insert = (text) => {
|
|
64
|
+
const normalized = text.replace(/\r\n?/gu, '\n');
|
|
65
|
+
if (normalized.length === 0)
|
|
66
|
+
return;
|
|
67
|
+
dismissClearPrompt();
|
|
68
|
+
clearSelectedCommand();
|
|
69
|
+
const current = valueRef.current;
|
|
70
|
+
const position = cursorRef.current;
|
|
71
|
+
updateDraft(`${current.slice(0, position)}${normalized}${current.slice(position)}`, position + normalized.length);
|
|
72
|
+
};
|
|
73
|
+
const applyFileChoice = (choice) => {
|
|
74
|
+
if (fileReference === undefined)
|
|
75
|
+
return;
|
|
76
|
+
clearSelectedCommand();
|
|
77
|
+
const current = valueRef.current;
|
|
78
|
+
updateDraft(`${current.slice(0, fileReference.start)}${choice.value} ${current.slice(cursorRef.current)}`, fileReference.start + choice.value.length + 1);
|
|
79
|
+
setSelected(0);
|
|
80
|
+
};
|
|
81
|
+
const erase = () => {
|
|
82
|
+
const position = cursorRef.current;
|
|
83
|
+
if (position === 0)
|
|
84
|
+
return;
|
|
85
|
+
dismissClearPrompt();
|
|
86
|
+
clearSelectedCommand();
|
|
87
|
+
const current = valueRef.current;
|
|
88
|
+
updateDraft(`${current.slice(0, position - 1)}${current.slice(position)}`, position - 1);
|
|
89
|
+
};
|
|
90
|
+
const submit = () => {
|
|
91
|
+
const trimmed = valueRef.current.trim();
|
|
92
|
+
if (trimmed.length > 0) {
|
|
93
|
+
dismissClearPrompt();
|
|
94
|
+
clearSelectedCommand();
|
|
95
|
+
updateDraft('', 0);
|
|
96
|
+
setSelected(0);
|
|
97
|
+
void bridge.submit(trimmed);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const clearDraft = () => {
|
|
101
|
+
dismissClearPrompt();
|
|
102
|
+
updateDraft('', 0);
|
|
103
|
+
setSelected(0);
|
|
104
|
+
bridge.clearAttachments();
|
|
105
|
+
};
|
|
106
|
+
const armClearPrompt = () => {
|
|
107
|
+
clearArmed.current = true;
|
|
108
|
+
setClearHint('Press Esc again to clear text and references.');
|
|
109
|
+
if (clearTimer.current !== undefined)
|
|
110
|
+
clearTimeout(clearTimer.current);
|
|
111
|
+
clearTimer.current = setTimeout(() => {
|
|
112
|
+
clearArmed.current = false;
|
|
113
|
+
setClearHint(undefined);
|
|
114
|
+
clearTimer.current = undefined;
|
|
115
|
+
}, 1500);
|
|
116
|
+
};
|
|
117
|
+
useInput((input, key) => {
|
|
118
|
+
if (!enabled)
|
|
119
|
+
return;
|
|
120
|
+
if (isMouseSequence(input))
|
|
121
|
+
return;
|
|
122
|
+
if (key.escape || input === '\u001b') {
|
|
123
|
+
if (activeRun || (clearBlockedUntil !== undefined && clearBlockedUntil > Date.now()))
|
|
124
|
+
return;
|
|
125
|
+
if (value.length === 0 && attachments.length === 0)
|
|
126
|
+
return;
|
|
127
|
+
if (clearArmed.current)
|
|
128
|
+
clearDraft();
|
|
129
|
+
else
|
|
130
|
+
armClearPrompt();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
if (key.meta && input.toLowerCase() === 'v') {
|
|
134
|
+
void bridge.pasteImage().catch(() => undefined);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
if (key.ctrl && input.toLowerCase() === 'v') {
|
|
138
|
+
void bridge.pasteText().then((text) => { if (text !== undefined)
|
|
139
|
+
insert(text); }).catch(() => undefined);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (key.return && key.shift) {
|
|
143
|
+
insert('\n');
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (key.return) {
|
|
147
|
+
const choice = choices[selected];
|
|
148
|
+
if (suggestions.length > 0 && choice !== undefined && choice.value !== value) {
|
|
149
|
+
chooseCommand(choice);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (isCompleteTuiCommand(value)) {
|
|
153
|
+
submit();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
if (choice !== undefined && fileSuggestions.length > 0)
|
|
157
|
+
applyFileChoice(choice);
|
|
158
|
+
else
|
|
159
|
+
submit();
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (key.tab && choices[selected] !== undefined) {
|
|
163
|
+
const choice = choices[selected];
|
|
164
|
+
if (choice !== undefined) {
|
|
165
|
+
if (suggestions.length > 0)
|
|
166
|
+
chooseCommand(choice);
|
|
167
|
+
else
|
|
168
|
+
applyFileChoice(choice);
|
|
169
|
+
}
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (key.upArrow && choices.length > 0) {
|
|
173
|
+
setSelected((current) => Math.max(0, current - 1));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (key.downArrow && choices.length > 0) {
|
|
177
|
+
setSelected((current) => Math.min(choices.length - 1, current + 1));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (key.leftArrow) {
|
|
181
|
+
clearSelectedCommand();
|
|
182
|
+
const nextCursor = Math.max(0, cursorRef.current - 1);
|
|
183
|
+
cursorRef.current = nextCursor;
|
|
184
|
+
setCursor(nextCursor);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (key.rightArrow) {
|
|
188
|
+
clearSelectedCommand();
|
|
189
|
+
const nextCursor = Math.min(valueRef.current.length, cursorRef.current + 1);
|
|
190
|
+
cursorRef.current = nextCursor;
|
|
191
|
+
setCursor(nextCursor);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (key.backspace || key.delete) {
|
|
195
|
+
erase();
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (!key.ctrl && !key.meta && input.length > 0)
|
|
199
|
+
insert(input);
|
|
200
|
+
}, { isActive: enabled });
|
|
201
|
+
usePaste((text) => { if (enabled)
|
|
202
|
+
insert(text); }, { isActive: enabled });
|
|
203
|
+
useEffect(() => () => {
|
|
204
|
+
if (clearTimer.current !== undefined)
|
|
205
|
+
clearTimeout(clearTimer.current);
|
|
206
|
+
}, []);
|
|
207
|
+
const lines = value.split('\n');
|
|
208
|
+
const inputWidth = inputMetrics.hasMeasured ? inputMetrics.width : Math.max(40, stdout.columns ?? 80);
|
|
209
|
+
const inputContentWidth = Math.max(1, inputWidth - (INPUT_CONTENT_OFFSET + 2));
|
|
210
|
+
const inputRows = lines.reduce((rows, line) => rows + Math.max(1, Math.ceil(terminalTextWidth(line) / inputContentWidth)), 0);
|
|
211
|
+
const layoutRows = calculateComposerRows({ attachmentCount: attachments.length, inputRows, hasClearHint: clearHint !== undefined, hasFooterNotice: footerNotice !== undefined, choiceCount: choices.length });
|
|
212
|
+
useLayoutEffect(() => {
|
|
213
|
+
onLayoutRowsChange?.(layoutRows + 1);
|
|
214
|
+
}, [layoutRows, onLayoutRowsChange]);
|
|
215
|
+
useLayoutEffect(() => {
|
|
216
|
+
const input = inputRef.current;
|
|
217
|
+
if (input === null) {
|
|
218
|
+
setInputMetrics((current) => current.hasMeasured ? { left: 0, top: 0, width: 0, hasMeasured: false } : current);
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
const measured = measureElement(input);
|
|
222
|
+
setInputMetrics((current) => current.left === measured.x && current.top === measured.y && current.width === measured.width && current.hasMeasured
|
|
223
|
+
? current
|
|
224
|
+
: { left: measured.x, top: measured.y, width: measured.width, hasMeasured: true });
|
|
225
|
+
});
|
|
226
|
+
const cursorPosition = enabled && visible && inputMetrics.hasMeasured
|
|
227
|
+
? calculateComposerCursorPosition({ layout: { x: inputMetrics.left, y: inputMetrics.top, width: inputMetrics.width }, value, cursor, terminalRows: stdout.rows })
|
|
228
|
+
: undefined;
|
|
229
|
+
setInkCursorPosition(cursorPosition);
|
|
230
|
+
if (!visible)
|
|
231
|
+
return null;
|
|
232
|
+
return _jsxs(Box, { width: "100%", flexDirection: "column", marginTop: 1, children: [attachments.map((attachment) => _jsx(AttachmentChip, { attachment: attachment }, attachment.id)), _jsx(Box, { ref: inputRef, width: "100%", borderStyle: "round", borderColor: enabled ? palette.accent : palette.border, flexDirection: "column", paddingX: 1, children: _jsxs(Box, { children: [_jsx(Text, { color: palette.accent, children: "\u203A " }), _jsx(Text, { wrap: "wrap", color: value.length === 0 ? palette.muted : palette.text, children: value.length === 0 ? 'Ask LotaGate to work on this project…' : renderInputValue(lines.join('\n')) })] }) }), _jsxs(Box, { paddingX: 1, justifyContent: "space-between", children: [_jsx(Text, { color: palette.muted, dimColor: true, children: "Enter send \u00B7 Shift+Enter newline \u00B7 / commands \u00B7 @ files \u00B7 Ctrl+V text \u00B7 Alt+V image" }), contextUsage !== undefined && _jsx(Text, { color: palette.muted, dimColor: true, children: formatContextUsage(contextUsage.usedTokens, contextUsage.contextWindow) })] }), clearHint !== undefined && _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: palette.muted, dimColor: true, children: clearHint }) }), footerNotice !== undefined && _jsx(Box, { paddingX: 1, children: _jsx(Text, { color: palette.muted, dimColor: true, children: footerNotice }) }), choices.length > 0 && _jsx(Box, { borderStyle: "round", borderColor: palette.border, flexDirection: "column", paddingX: 1, children: choices.map((choice, index) => _jsxs(Box, { ...(index === selected ? { backgroundColor: palette.selection } : {}), children: [_jsx(Text, { color: index === selected ? palette.accent : palette.muted, children: "\u203A " }), _jsxs(Text, { color: choice.kind === 'directory' ? palette.warning : palette.text, children: [choice.kind === 'directory' ? '▸ ' : '', choice.label] }), _jsxs(Text, { color: palette.muted, children: [" ", choice.description] })] }, choice.value)) })] });
|
|
233
|
+
}
|
|
234
|
+
function isCompleteTuiCommand(value) {
|
|
235
|
+
if (!value.startsWith('/') || value.includes('\n'))
|
|
236
|
+
return false;
|
|
237
|
+
try {
|
|
238
|
+
parseCommandInvocation(tokenizeCommandInput(value.trimStart().slice(1)), 'tui', COMMAND_REGISTRY);
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
function calculateComposerRows({ attachmentCount, inputRows, hasClearHint, hasFooterNotice, choiceCount }) {
|
|
246
|
+
const attachmentRows = attachmentCount * 2;
|
|
247
|
+
const inputBoxRows = Math.max(1, inputRows) + 2;
|
|
248
|
+
const suggestionRows = choiceCount > 0 ? choiceCount + 2 : 0;
|
|
249
|
+
return attachmentRows + inputBoxRows + 1 + (hasClearHint ? 1 : 0) + (hasFooterNotice ? 1 : 0) + suggestionRows;
|
|
250
|
+
}
|
|
251
|
+
function renderInputValue(value) {
|
|
252
|
+
const parts = value.split(/(@[^\s@]+|https?:\/\/[^\s]+|\/[A-Za-z][\w-]*)/gu);
|
|
253
|
+
return parts.filter((part) => part.length > 0).map((part, index) => {
|
|
254
|
+
if (part.startsWith('@'))
|
|
255
|
+
return _jsx(Text, { color: palette.accent, children: part }, index);
|
|
256
|
+
if (/^https?:\/\//u.test(part))
|
|
257
|
+
return _jsx(Text, { color: palette.link, underline: true, children: part }, index);
|
|
258
|
+
if (/^\/[A-Za-z][\w-]*$/u.test(part))
|
|
259
|
+
return _jsx(Text, { color: palette.accent, children: part }, index);
|
|
260
|
+
return _jsx(Text, { children: part }, index);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
/** Returns the active unquoted @workspace-file token immediately before the cursor. */
|
|
264
|
+
export function atFileReference(value, cursor) {
|
|
265
|
+
const beforeCursor = value.slice(0, cursor);
|
|
266
|
+
const match = /(?:^|\s)@([^\s@]*)$/u.exec(beforeCursor);
|
|
267
|
+
if (match === null)
|
|
268
|
+
return undefined;
|
|
269
|
+
const query = match[1] ?? '';
|
|
270
|
+
return { start: cursor - query.length - 1, query };
|
|
271
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
import type { FileChangeDiff } from '../../../../domain/filesystem/file-change-diff.js';
|
|
3
|
+
export declare function FileDiff({ change }: {
|
|
4
|
+
change: FileChangeDiff;
|
|
5
|
+
}): JSX.Element;
|
|
6
|
+
export declare function fileDiffRowCount(change: FileChangeDiff, columns: number): number;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useStdout } from 'ink';
|
|
3
|
+
import { DARK_THEME as palette } from '../../../themes/theme.js';
|
|
4
|
+
import { truncateTerminalText, wrapTerminalText } from '../../formatters.js';
|
|
5
|
+
export function FileDiff({ change }) {
|
|
6
|
+
const { stdout } = useStdout();
|
|
7
|
+
const cardWidth = Math.max(20, (stdout.columns ?? 80) - 4);
|
|
8
|
+
const lineNumberWidth = getLineNumberWidth(change.lines);
|
|
9
|
+
return _jsxs(Box, { flexDirection: "column", marginBottom: 1, borderStyle: "round", borderColor: palette.border, paddingX: 1, children: [_jsxs(Text, { color: palette.text, children: [_jsx(Text, { color: palette.accent, children: "\u25A3" }), " ", _jsx(Text, { bold: true, children: "Updated" }), " ", _jsx(Text, { color: palette.muted, children: truncateTerminalText(change.path, Math.max(1, cardWidth - 30)) }), " ", _jsx(Text, { color: palette.muted, children: " \u00B7 " }), _jsxs(Text, { color: palette.success, children: ["+", change.additions] }), _jsx(Text, { color: palette.muted, children: " " }), _jsxs(Text, { color: palette.error, children: ["-", change.deletions] })] }), _jsx(Text, { color: palette.muted, children: " Workspace change" }), _jsx(Box, { flexDirection: "column", marginTop: 1, children: change.lines.map((line, index) => _jsx(DiffLine, { line: line, lineNumberWidth: lineNumberWidth, textWidth: Math.max(1, cardWidth - (lineNumberWidth * 2 + 8)) }, `${index}-${line.kind}`)) }), change.truncated && _jsx(Text, { color: palette.muted, children: " \u2026 diff truncated for display" })] });
|
|
10
|
+
}
|
|
11
|
+
export function fileDiffRowCount(change, columns) {
|
|
12
|
+
const cardWidth = Math.max(20, columns - 4);
|
|
13
|
+
const lineNumberWidth = getLineNumberWidth(change.lines);
|
|
14
|
+
const textWidth = Math.max(1, cardWidth - (lineNumberWidth * 2 + 8));
|
|
15
|
+
const contentRows = change.lines.reduce((total, line) => total + wrapTerminalText(line.text.length === 0 ? ' ' : line.text, textWidth).length, 0);
|
|
16
|
+
return contentRows + 3 + (change.truncated ? 1 : 0);
|
|
17
|
+
}
|
|
18
|
+
function DiffLine({ line, lineNumberWidth, textWidth }) {
|
|
19
|
+
const isAddition = line.kind === 'addition';
|
|
20
|
+
const isDeletion = line.kind === 'deletion';
|
|
21
|
+
const color = isAddition ? palette.success : isDeletion ? palette.error : palette.text;
|
|
22
|
+
const backgroundColor = isAddition ? palette.diffAdded : isDeletion ? palette.diffRemoved : undefined;
|
|
23
|
+
const marker = line.kind === 'addition' ? '+' : line.kind === 'deletion' ? '-' : ' ';
|
|
24
|
+
const oldNumber = line.oldLine === undefined ? ' '.repeat(lineNumberWidth) : String(line.oldLine).padStart(lineNumberWidth, ' ');
|
|
25
|
+
const newNumber = line.newLine === undefined ? ' '.repeat(lineNumberWidth) : String(line.newLine).padStart(lineNumberWidth, ' ');
|
|
26
|
+
const rows = wrapTerminalText(line.text.length === 0 ? ' ' : line.text, textWidth);
|
|
27
|
+
return _jsx(Box, { flexDirection: "column", backgroundColor: backgroundColor, paddingX: 1, children: rows.map((row, index) => _jsxs(Box, { flexDirection: "row", children: [index === 0
|
|
28
|
+
? _jsxs(_Fragment, { children: [_jsxs(Text, { color: palette.muted, children: [oldNumber, " ", newNumber, " "] }), _jsxs(Text, { color: color, bold: isAddition || isDeletion, children: [marker, " "] })] })
|
|
29
|
+
: _jsxs(Text, { color: palette.muted, children: [' '.repeat(lineNumberWidth * 2 + 3), " "] }), _jsx(Text, { color: color, bold: index === 0 && (isAddition || isDeletion), children: row })] }, `${index}-${row}`)) });
|
|
30
|
+
}
|
|
31
|
+
function getLineNumberWidth(lines) {
|
|
32
|
+
const largest = lines.reduce((maximum, line) => Math.max(maximum, line.oldLine ?? 0, line.newLine ?? 0), 0);
|
|
33
|
+
return Math.max(2, String(largest).length);
|
|
34
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
import type { InkTuiBridge, TuiModal } from '../tui-bridge.js';
|
|
3
|
+
export declare function Modal({ bridge, modal, onLayoutRowsChange }: {
|
|
4
|
+
bridge: InkTuiBridge;
|
|
5
|
+
modal?: TuiModal;
|
|
6
|
+
onLayoutRowsChange?: (rows: number) => void;
|
|
7
|
+
}): JSX.Element | null;
|
|
8
|
+
export declare function estimateModalRows(modal: TuiModal): number;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useLayoutEffect, useRef, useState } from 'react';
|
|
3
|
+
import { Box, Text, useBoxMetrics, useInput, usePaste } from 'ink';
|
|
4
|
+
import { DARK_THEME as palette } from '../../../themes/theme.js';
|
|
5
|
+
import { ChoiceModal } from './choice-modal.js';
|
|
6
|
+
export function Modal({ bridge, modal, onLayoutRowsChange }) {
|
|
7
|
+
const modalRef = useRef(null);
|
|
8
|
+
const modalMetrics = useBoxMetrics(modalRef);
|
|
9
|
+
useLayoutEffect(() => {
|
|
10
|
+
if (modalMetrics.hasMeasured)
|
|
11
|
+
onLayoutRowsChange?.(modalMetrics.height);
|
|
12
|
+
}, [modalMetrics.height, modalMetrics.hasMeasured, onLayoutRowsChange]);
|
|
13
|
+
if (modal === undefined)
|
|
14
|
+
return null;
|
|
15
|
+
const content = modal.kind === 'choice'
|
|
16
|
+
? _jsx(ChoiceModal, { bridge: bridge, title: modal.title, choices: modal.choices, ...(modal.currentValue === undefined ? {} : { currentValue: modal.currentValue }), ...(modal.detail === undefined ? {} : { detail: modal.detail }) })
|
|
17
|
+
: modal.kind === 'secret'
|
|
18
|
+
? _jsx(SecretModal, { bridge: bridge, label: modal.label })
|
|
19
|
+
: modal.kind === 'approval'
|
|
20
|
+
? _jsx(ApprovalModal, { bridge: bridge, toolName: modal.toolName, ...(modal.detail === undefined ? {} : { detail: modal.detail }) })
|
|
21
|
+
: modal.kind === 'subagent'
|
|
22
|
+
? _jsx(SubagentDetailModal, { bridge: bridge, subagent: modal.subagent })
|
|
23
|
+
: _jsx(DecisionContent, { bridge: bridge, modal: modal });
|
|
24
|
+
return _jsx(Box, { ref: modalRef, width: "100%", flexDirection: "column", children: content });
|
|
25
|
+
}
|
|
26
|
+
export function estimateModalRows(modal) {
|
|
27
|
+
if (modal.kind === 'choice')
|
|
28
|
+
return Math.min(8, modal.choices.length) + (modal.detail === undefined ? 5 : 6);
|
|
29
|
+
if (modal.kind === 'approval')
|
|
30
|
+
return 8 + (modal.detail === undefined ? 0 : 1);
|
|
31
|
+
if (modal.kind === 'secret')
|
|
32
|
+
return 6;
|
|
33
|
+
if (modal.kind === 'subagent')
|
|
34
|
+
return 10;
|
|
35
|
+
if (modal.kind === 'trust')
|
|
36
|
+
return 6;
|
|
37
|
+
return Math.min(8, modal.plan.tasks.length) + 6;
|
|
38
|
+
}
|
|
39
|
+
function DecisionContent({ bridge, modal }) {
|
|
40
|
+
const title = modal.kind === 'trust' ? 'Trust this workspace?' : `Approve plan · ${modal.plan.tasks.length} tasks`;
|
|
41
|
+
const detail = modal.kind === 'trust' ? 'Local tools, MCP, and extensions remain disabled until you grant trust.' : modal.plan.tasks.map((task, index) => `${index + 1}. ${task.title}`).join('\n');
|
|
42
|
+
return _jsx(DecisionModal, { title: title, detail: detail, onDecision: (accepted) => bridge.resolveActiveModal(accepted) });
|
|
43
|
+
}
|
|
44
|
+
function DialogFrame({ children, title = 'Action required' }) {
|
|
45
|
+
return _jsxs(Box, { borderStyle: "double", borderColor: palette.accent, flexDirection: "column", marginTop: 1, paddingX: 1, children: [_jsx(Text, { bold: true, color: palette.text, children: title }), children] });
|
|
46
|
+
}
|
|
47
|
+
function SubagentDetailModal({ bridge, subagent }) {
|
|
48
|
+
useInput((input, key) => {
|
|
49
|
+
if (key.return || key.escape || input === '\u001b' || input.toLowerCase() === 'q')
|
|
50
|
+
bridge.closeSubagentDetails();
|
|
51
|
+
});
|
|
52
|
+
const handoff = subagent.handoff;
|
|
53
|
+
return _jsxs(DialogFrame, { title: `Subagent handoff · ${subagent.displayName}`, children: [_jsx(Text, { color: palette.text, children: subagent.task }), _jsxs(Text, { color: palette.muted, children: [subagent.mode, " \u00B7 ", subagent.status, " \u00B7 ", subagent.model] }), handoff === undefined
|
|
54
|
+
? _jsx(Text, { color: palette.muted, children: "Handoff is available when this subagent completes." })
|
|
55
|
+
: _jsxs(Box, { flexDirection: "column", children: [_jsx(DetailSection, { label: "Summary", values: [handoff.summary] }), _jsx(DetailSection, { label: "Files inspected", values: handoff.filesInspected }), _jsx(DetailSection, { label: "Files changed", values: handoff.filesChanged }), _jsx(DetailSection, { label: "Commands run", values: handoff.commandsRun }), _jsx(DetailSection, { label: "Verification", values: handoff.verification }), _jsx(DetailSection, { label: "Warnings", values: handoff.warnings })] }), _jsx(Text, { color: palette.accent, children: "Enter / Esc / Q close" })] });
|
|
56
|
+
}
|
|
57
|
+
function DetailSection({ label, values }) {
|
|
58
|
+
return _jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, color: palette.accent, children: label }), _jsx(Text, { color: palette.muted, wrap: "wrap", children: values.length === 0 ? 'None' : values.map((value) => `• ${safeDetail(value)}`).join('\n') })] });
|
|
59
|
+
}
|
|
60
|
+
function safeDetail(value) {
|
|
61
|
+
const redacted = value.replace(/Bearer\s+[^\s]+/giu, 'Bearer [REDACTED]').replace(/sk-[A-Za-z0-9_-]{8,}/gu, '[REDACTED]');
|
|
62
|
+
return redacted.length <= 500 ? redacted : `${redacted.slice(0, 497)}...`;
|
|
63
|
+
}
|
|
64
|
+
function DecisionModal({ title, detail, onDecision }) {
|
|
65
|
+
useInput((input, key) => {
|
|
66
|
+
if (key.return || input.toLowerCase() === 'y')
|
|
67
|
+
onDecision(true);
|
|
68
|
+
else if (key.escape || input.toLowerCase() === 'n')
|
|
69
|
+
onDecision(false);
|
|
70
|
+
});
|
|
71
|
+
return _jsxs(DialogFrame, { children: [_jsx(Text, { color: palette.text, children: title }), _jsx(Text, { color: palette.muted, children: detail }), _jsx(Text, { color: palette.accent, children: "Enter / Y approve \u00B7 Esc / N cancel" })] });
|
|
72
|
+
}
|
|
73
|
+
function ApprovalModal({ bridge, toolName, detail }) {
|
|
74
|
+
return _jsx(ChoiceModal, { bridge: bridge, title: `Approval · ${approvalTitle(toolName)}`, choices: [
|
|
75
|
+
{ value: 'allow', label: 'Allow', description: 'Run this tool action' },
|
|
76
|
+
{ value: 'deny', label: 'Deny', description: 'Block this tool action' },
|
|
77
|
+
], ...(detail === undefined ? {} : { detail: compactDetail(detail) }), borderColor: palette.warning });
|
|
78
|
+
}
|
|
79
|
+
function approvalTitle(toolName) {
|
|
80
|
+
if (toolName === 'shell.exec')
|
|
81
|
+
return 'Shell command';
|
|
82
|
+
if (toolName === 'filesystem.write')
|
|
83
|
+
return 'File write';
|
|
84
|
+
return 'Tool action';
|
|
85
|
+
}
|
|
86
|
+
function compactDetail(detail) {
|
|
87
|
+
const value = detail.trim();
|
|
88
|
+
if (value.startsWith('Write workspace file: '))
|
|
89
|
+
return `write ${value.slice('Write workspace file: '.length)}`;
|
|
90
|
+
if (value.startsWith('Run command: '))
|
|
91
|
+
return `run ${value.slice('Run command: '.length)}`;
|
|
92
|
+
if (value.startsWith('This '))
|
|
93
|
+
return value.replace(/^This /u, '').replace(/ operation may change workspace or external state\.$/u, '');
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
function SecretModal({ bridge, label }) {
|
|
97
|
+
const [value, setValue] = useState('');
|
|
98
|
+
useInput((input, key) => {
|
|
99
|
+
if (key.return)
|
|
100
|
+
bridge.resolveActiveModal(value.trim() || undefined);
|
|
101
|
+
else if (key.escape)
|
|
102
|
+
bridge.resolveActiveModal(undefined);
|
|
103
|
+
else if (key.backspace || key.delete)
|
|
104
|
+
setValue((current) => current.slice(0, -1));
|
|
105
|
+
else if (!key.ctrl && !key.meta && input.length > 0)
|
|
106
|
+
setValue((current) => `${current}${input}`);
|
|
107
|
+
});
|
|
108
|
+
usePaste((text) => setValue((current) => `${current}${text.replace(/[\r\n]/gu, '')}`));
|
|
109
|
+
return _jsxs(DialogFrame, { children: [_jsx(Text, { color: palette.text, children: label }), _jsx(Text, { color: palette.accent, children: `> ${'•'.repeat(value.length)}▌` }), _jsx(Text, { color: palette.muted, children: "Enter save \u00B7 Esc cancel" })] });
|
|
110
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Text } from 'ink';
|
|
3
|
+
import { DARK_THEME as palette } from '../../../themes/theme.js';
|
|
4
|
+
export function ShimmerText({ value, active, frame }) {
|
|
5
|
+
if (!active || value.length === 0)
|
|
6
|
+
return _jsx(Text, { color: palette.text, children: value });
|
|
7
|
+
const highlight = frame % [...value].length;
|
|
8
|
+
return _jsx(Text, { color: palette.muted, children: [...value].map((character, index) => _jsx(Text, { color: index === highlight ? palette.text : palette.muted, bold: index === highlight, children: character }, `${index}-${character}`)) });
|
|
9
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { JSX } from 'react';
|
|
2
|
+
import type { TuiSubagent } from '../tui-bridge.js';
|
|
3
|
+
export declare function SubagentCreatedEntry({ subagent }: {
|
|
4
|
+
subagent: TuiSubagent;
|
|
5
|
+
}): JSX.Element;
|
|
6
|
+
export declare function visibleSubagents(subagents: readonly TuiSubagent[]): readonly TuiSubagent[];
|
|
7
|
+
export declare function SubagentActivity({ subagents, selectedId, paused }: {
|
|
8
|
+
subagents: readonly TuiSubagent[];
|
|
9
|
+
selectedId?: string;
|
|
10
|
+
paused?: boolean;
|
|
11
|
+
}): JSX.Element | null;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text, useAnimation } from 'ink';
|
|
3
|
+
import { DARK_THEME as palette } from '../../../themes/theme.js';
|
|
4
|
+
const MAX_VISIBLE_ACTIVE = 5;
|
|
5
|
+
export function SubagentCreatedEntry({ subagent }) {
|
|
6
|
+
return _jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Text, { color: palette.accent, children: ["\u25CC ", _jsx(Text, { bold: true, children: "Created agent" }), " ", _jsxs(Text, { color: palette.muted, children: ["\u00B7 ", displayTitle(subagent)] })] }), _jsxs(Text, { color: palette.muted, children: [" ", subagent.mode, subagent.background ? ' · background' : ''] })] });
|
|
7
|
+
}
|
|
8
|
+
export function visibleSubagents(subagents) {
|
|
9
|
+
return subagents.filter(isActive).sort(byRecent).slice(0, MAX_VISIBLE_ACTIVE);
|
|
10
|
+
}
|
|
11
|
+
export function SubagentActivity({ subagents, selectedId, paused = false }) {
|
|
12
|
+
const active = subagents.filter(isActive);
|
|
13
|
+
const { frame } = useAnimation({ interval: 250, isActive: active.length > 0 && !paused });
|
|
14
|
+
const visible = visibleSubagents(subagents);
|
|
15
|
+
if (visible.length === 0)
|
|
16
|
+
return null;
|
|
17
|
+
return _jsxs(Box, { borderStyle: "round", borderColor: palette.border, flexDirection: "column", marginBottom: 1, paddingX: 1, children: [_jsxs(Text, { color: palette.text, children: [_jsx(Text, { bold: true, children: "Subagents" }), _jsx(Text, { color: palette.muted, children: active.length === 0 ? '' : ` · ${active.length} working` })] }), visible.map((subagent) => _jsx(SubagentRow, { subagent: subagent, selected: subagent.id === selectedId, frame: frame }, subagent.id)), active.length > MAX_VISIBLE_ACTIVE && _jsxs(Text, { color: palette.muted, children: [" and ", active.length - MAX_VISIBLE_ACTIVE, " other subagents working"] }), _jsx(Text, { color: palette.muted, dimColor: true, children: "Ctrl+J/K select \u00B7 Ctrl+O handoff" })] });
|
|
18
|
+
}
|
|
19
|
+
function SubagentRow({ subagent, selected, frame }) {
|
|
20
|
+
const color = statusColor(subagent.status);
|
|
21
|
+
const elapsed = subagent.status === 'running' || subagent.status === 'queued'
|
|
22
|
+
? Date.now() - subagent.createdAt
|
|
23
|
+
: subagent.durationMs ?? subagent.updatedAt - subagent.createdAt;
|
|
24
|
+
return _jsxs(Box, { backgroundColor: selected ? palette.selection : undefined, flexDirection: "column", marginTop: 1, paddingX: selected ? 1 : 0, children: [_jsxs(Text, { color: color, children: [indicator(subagent.status, frame), " ", _jsx(Text, { bold: true, children: displayTitle(subagent) })] }), _jsxs(Text, { color: palette.muted, children: [" ", subagent.mode, " \u00B7 ", subagent.status, " \u00B7 ", formatDuration(elapsed)] }), subagent.lastAction !== undefined && _jsxs(Text, { color: palette.muted, wrap: "truncate", children: [" ", subagent.lastAction.label] })] });
|
|
25
|
+
}
|
|
26
|
+
function isActive(subagent) {
|
|
27
|
+
return subagent.status === 'queued' || subagent.status === 'running';
|
|
28
|
+
}
|
|
29
|
+
function byRecent(left, right) {
|
|
30
|
+
return right.updatedAt - left.updatedAt;
|
|
31
|
+
}
|
|
32
|
+
function displayTitle(subagent) {
|
|
33
|
+
return `${subagent.displayName} · ${shortTask(subagent.task)}`;
|
|
34
|
+
}
|
|
35
|
+
function shortTask(value) {
|
|
36
|
+
const normalized = value.replace(/\s+/gu, ' ').trim();
|
|
37
|
+
return normalized.length <= 56 ? normalized : `${normalized.slice(0, 53)}...`;
|
|
38
|
+
}
|
|
39
|
+
function statusColor(status) {
|
|
40
|
+
if (status === 'completed')
|
|
41
|
+
return palette.success;
|
|
42
|
+
if (status === 'completed_with_warning')
|
|
43
|
+
return palette.warning;
|
|
44
|
+
if (status === 'failed' || status === 'cancelled')
|
|
45
|
+
return palette.error;
|
|
46
|
+
return status === 'queued' ? palette.muted : palette.warning;
|
|
47
|
+
}
|
|
48
|
+
function indicator(status, frame) {
|
|
49
|
+
if (status === 'completed')
|
|
50
|
+
return '✓';
|
|
51
|
+
if (status === 'completed_with_warning')
|
|
52
|
+
return '⚠';
|
|
53
|
+
if (status === 'failed' || status === 'cancelled')
|
|
54
|
+
return '!';
|
|
55
|
+
if (status === 'queued')
|
|
56
|
+
return '◌';
|
|
57
|
+
return ['◐', '◓', '◑', '◒'][frame % 4] ?? '◐';
|
|
58
|
+
}
|
|
59
|
+
function formatDuration(milliseconds) {
|
|
60
|
+
return milliseconds < 1000 ? `${Math.max(0, milliseconds)}ms` : `${(milliseconds / 1000).toFixed(1)}s`;
|
|
61
|
+
}
|