pulseed 0.5.2 → 0.5.3
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/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/interface/chat/chat-event-state.d.ts +10 -0
- package/dist/interface/chat/chat-event-state.d.ts.map +1 -1
- package/dist/interface/chat/chat-event-state.js +184 -9
- package/dist/interface/chat/chat-event-state.js.map +1 -1
- package/dist/interface/chat/chat-events.d.ts +3 -1
- package/dist/interface/chat/chat-events.d.ts.map +1 -1
- package/dist/interface/chat/chat-runner.d.ts +24 -1
- package/dist/interface/chat/chat-runner.d.ts.map +1 -1
- package/dist/interface/chat/chat-runner.js +678 -67
- package/dist/interface/chat/chat-runner.js.map +1 -1
- package/dist/interface/chat/chat-verifier.d.ts +3 -1
- package/dist/interface/chat/chat-verifier.d.ts.map +1 -1
- package/dist/interface/chat/chat-verifier.js +2 -2
- package/dist/interface/chat/chat-verifier.js.map +1 -1
- package/dist/interface/chat/cross-platform-session.d.ts +1 -0
- package/dist/interface/chat/cross-platform-session.d.ts.map +1 -1
- package/dist/interface/chat/cross-platform-session.js +24 -0
- package/dist/interface/chat/cross-platform-session.js.map +1 -1
- package/dist/interface/chat/failure-recovery.d.ts +11 -0
- package/dist/interface/chat/failure-recovery.d.ts.map +1 -0
- package/dist/interface/chat/failure-recovery.js +115 -0
- package/dist/interface/chat/failure-recovery.js.map +1 -0
- package/dist/interface/chat/ingress-router.d.ts +9 -0
- package/dist/interface/chat/ingress-router.d.ts.map +1 -1
- package/dist/interface/chat/ingress-router.js +35 -1
- package/dist/interface/chat/ingress-router.js.map +1 -1
- package/dist/interface/chat/tend-command.d.ts +8 -0
- package/dist/interface/chat/tend-command.d.ts.map +1 -1
- package/dist/interface/chat/tend-command.js +80 -4
- package/dist/interface/chat/tend-command.js.map +1 -1
- package/dist/interface/cli/cli-command-registry.d.ts.map +1 -1
- package/dist/interface/cli/cli-command-registry.js +4 -0
- package/dist/interface/cli/cli-command-registry.js.map +1 -1
- package/dist/interface/cli/commands/runtime.d.ts +3 -0
- package/dist/interface/cli/commands/runtime.d.ts.map +1 -0
- package/dist/interface/cli/commands/runtime.js +231 -0
- package/dist/interface/cli/commands/runtime.js.map +1 -0
- package/dist/interface/cli/utils.d.ts.map +1 -1
- package/dist/interface/cli/utils.js +4 -0
- package/dist/interface/cli/utils.js.map +1 -1
- package/dist/interface/tui/app.d.ts.map +1 -1
- package/dist/interface/tui/app.js +22 -1
- package/dist/interface/tui/app.js.map +1 -1
- package/dist/interface/tui/chat/scroll.d.ts +3 -0
- package/dist/interface/tui/chat/scroll.d.ts.map +1 -1
- package/dist/interface/tui/chat/scroll.js +15 -0
- package/dist/interface/tui/chat/scroll.js.map +1 -1
- package/dist/interface/tui/chat/types.d.ts +1 -1
- package/dist/interface/tui/chat/types.d.ts.map +1 -1
- package/dist/interface/tui/chat/viewport.d.ts.map +1 -1
- package/dist/interface/tui/chat/viewport.js +8 -2
- package/dist/interface/tui/chat/viewport.js.map +1 -1
- package/dist/interface/tui/chat-surface.d.ts +2 -0
- package/dist/interface/tui/chat-surface.d.ts.map +1 -1
- package/dist/interface/tui/chat-surface.js +11 -0
- package/dist/interface/tui/chat-surface.js.map +1 -1
- package/dist/interface/tui/chat.d.ts.map +1 -1
- package/dist/interface/tui/chat.js +15 -7
- package/dist/interface/tui/chat.js.map +1 -1
- package/dist/interface/tui/clipboard.d.ts +6 -1
- package/dist/interface/tui/clipboard.d.ts.map +1 -1
- package/dist/interface/tui/clipboard.js +24 -5
- package/dist/interface/tui/clipboard.js.map +1 -1
- package/dist/interface/tui/entry.d.ts.map +1 -1
- package/dist/interface/tui/entry.js +14 -2
- package/dist/interface/tui/entry.js.map +1 -1
- package/dist/interface/tui/flicker/MouseTracking.d.ts +1 -1
- package/dist/interface/tui/flicker/MouseTracking.d.ts.map +1 -1
- package/dist/interface/tui/flicker/MouseTracking.js +8 -4
- package/dist/interface/tui/flicker/MouseTracking.js.map +1 -1
- package/dist/interface/tui/fullscreen-chat.d.ts +86 -5
- package/dist/interface/tui/fullscreen-chat.d.ts.map +1 -1
- package/dist/interface/tui/fullscreen-chat.js +586 -32
- package/dist/interface/tui/fullscreen-chat.js.map +1 -1
- package/dist/interface/tui/help-overlay.d.ts.map +1 -1
- package/dist/interface/tui/help-overlay.js +1 -1
- package/dist/interface/tui/help-overlay.js.map +1 -1
- package/dist/interface/tui/markdown-renderer.d.ts.map +1 -1
- package/dist/interface/tui/markdown-renderer.js +40 -12
- package/dist/interface/tui/markdown-renderer.js.map +1 -1
- package/dist/interface/tui/test-entry.js +1 -1
- package/dist/interface/tui/test-entry.js.map +1 -1
- package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.d.ts.map +1 -1
- package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.js +1 -0
- package/dist/orchestrator/execution/agent-loop/agent-loop-context-assembler.js.map +1 -1
- package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.d.ts.map +1 -1
- package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.js +27 -13
- package/dist/orchestrator/execution/agent-loop/agent-loop-default-profile.js.map +1 -1
- package/dist/orchestrator/execution/agent-loop/agent-loop-dogfood-benchmark.d.ts.map +1 -1
- package/dist/orchestrator/execution/agent-loop/agent-loop-dogfood-benchmark.js +7 -4
- package/dist/orchestrator/execution/agent-loop/agent-loop-dogfood-benchmark.js.map +1 -1
- package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.d.ts.map +1 -1
- package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.js +6 -0
- package/dist/orchestrator/execution/agent-loop/bounded-agent-loop-runner.js.map +1 -1
- package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.d.ts +1 -0
- package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.d.ts.map +1 -1
- package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js +1 -0
- package/dist/orchestrator/execution/agent-loop/chat-agent-loop-runner.js.map +1 -1
- package/dist/orchestrator/execution/agent-loop/index.d.ts +1 -0
- package/dist/orchestrator/execution/agent-loop/index.d.ts.map +1 -1
- package/dist/orchestrator/execution/agent-loop/index.js +1 -0
- package/dist/orchestrator/execution/agent-loop/index.js.map +1 -1
- package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.d.ts +34 -0
- package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.d.ts.map +1 -0
- package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.js +54 -0
- package/dist/orchestrator/execution/agent-loop/kaggle-training-benchmark.js.map +1 -0
- package/dist/orchestrator/loop/core-loop/phase-policy.d.ts.map +1 -1
- package/dist/orchestrator/loop/core-loop/phase-policy.js +3 -0
- package/dist/orchestrator/loop/core-loop/phase-policy.js.map +1 -1
- package/dist/platform/code-search/candidate-normalizer.d.ts +3 -0
- package/dist/platform/code-search/candidate-normalizer.d.ts.map +1 -0
- package/dist/platform/code-search/candidate-normalizer.js +61 -0
- package/dist/platform/code-search/candidate-normalizer.js.map +1 -0
- package/dist/platform/code-search/candidate.d.ts +25 -0
- package/dist/platform/code-search/candidate.d.ts.map +1 -0
- package/dist/platform/code-search/candidate.js +61 -0
- package/dist/platform/code-search/candidate.js.map +1 -0
- package/dist/platform/code-search/contracts.d.ts +275 -0
- package/dist/platform/code-search/contracts.d.ts.map +1 -0
- package/dist/platform/code-search/contracts.js +22 -0
- package/dist/platform/code-search/contracts.js.map +1 -0
- package/dist/platform/code-search/eval/fixtures.d.ts +14 -0
- package/dist/platform/code-search/eval/fixtures.d.ts.map +1 -0
- package/dist/platform/code-search/eval/fixtures.js +24 -0
- package/dist/platform/code-search/eval/fixtures.js.map +1 -0
- package/dist/platform/code-search/eval/metrics.d.ts +10 -0
- package/dist/platform/code-search/eval/metrics.d.ts.map +1 -0
- package/dist/platform/code-search/eval/metrics.js +20 -0
- package/dist/platform/code-search/eval/metrics.js.map +1 -0
- package/dist/platform/code-search/eval/runner.d.ts +3 -0
- package/dist/platform/code-search/eval/runner.d.ts.map +1 -0
- package/dist/platform/code-search/eval/runner.js +13 -0
- package/dist/platform/code-search/eval/runner.js.map +1 -0
- package/dist/platform/code-search/fusion.d.ts +6 -0
- package/dist/platform/code-search/fusion.d.ts.map +1 -0
- package/dist/platform/code-search/fusion.js +12 -0
- package/dist/platform/code-search/fusion.js.map +1 -0
- package/dist/platform/code-search/generated-detector.d.ts +15 -0
- package/dist/platform/code-search/generated-detector.d.ts.map +1 -0
- package/dist/platform/code-search/generated-detector.js +42 -0
- package/dist/platform/code-search/generated-detector.js.map +1 -0
- package/dist/platform/code-search/indexes/call-graph.d.ts +3 -0
- package/dist/platform/code-search/indexes/call-graph.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/call-graph.js +13 -0
- package/dist/platform/code-search/indexes/call-graph.js.map +1 -0
- package/dist/platform/code-search/indexes/config-index.d.ts +3 -0
- package/dist/platform/code-search/indexes/config-index.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/config-index.js +7 -0
- package/dist/platform/code-search/indexes/config-index.js.map +1 -0
- package/dist/platform/code-search/indexes/file-index.d.ts +5 -0
- package/dist/platform/code-search/indexes/file-index.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/file-index.js +106 -0
- package/dist/platform/code-search/indexes/file-index.js.map +1 -0
- package/dist/platform/code-search/indexes/index-store.d.ts +6 -0
- package/dist/platform/code-search/indexes/index-store.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/index-store.js +14 -0
- package/dist/platform/code-search/indexes/index-store.js.map +1 -0
- package/dist/platform/code-search/indexes/indexer.d.ts +3 -0
- package/dist/platform/code-search/indexes/indexer.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/indexer.js +27 -0
- package/dist/platform/code-search/indexes/indexer.js.map +1 -0
- package/dist/platform/code-search/indexes/package-graph.d.ts +3 -0
- package/dist/platform/code-search/indexes/package-graph.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/package-graph.js +26 -0
- package/dist/platform/code-search/indexes/package-graph.js.map +1 -0
- package/dist/platform/code-search/indexes/repo-map-index.d.ts +3 -0
- package/dist/platform/code-search/indexes/repo-map-index.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/repo-map-index.js +26 -0
- package/dist/platform/code-search/indexes/repo-map-index.js.map +1 -0
- package/dist/platform/code-search/indexes/semantic-index.d.ts +3 -0
- package/dist/platform/code-search/indexes/semantic-index.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/semantic-index.js +4 -0
- package/dist/platform/code-search/indexes/semantic-index.js.map +1 -0
- package/dist/platform/code-search/indexes/symbol-index.d.ts +3 -0
- package/dist/platform/code-search/indexes/symbol-index.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/symbol-index.js +84 -0
- package/dist/platform/code-search/indexes/symbol-index.js.map +1 -0
- package/dist/platform/code-search/indexes/test-index.d.ts +3 -0
- package/dist/platform/code-search/indexes/test-index.d.ts.map +1 -0
- package/dist/platform/code-search/indexes/test-index.js +22 -0
- package/dist/platform/code-search/indexes/test-index.js.map +1 -0
- package/dist/platform/code-search/orchestrator.d.ts +9 -0
- package/dist/platform/code-search/orchestrator.d.ts.map +1 -0
- package/dist/platform/code-search/orchestrator.js +81 -0
- package/dist/platform/code-search/orchestrator.js.map +1 -0
- package/dist/platform/code-search/path-policy.d.ts +6 -0
- package/dist/platform/code-search/path-policy.d.ts.map +1 -0
- package/dist/platform/code-search/path-policy.js +60 -0
- package/dist/platform/code-search/path-policy.js.map +1 -0
- package/dist/platform/code-search/progressive-reader.d.ts +8 -0
- package/dist/platform/code-search/progressive-reader.d.ts.map +1 -0
- package/dist/platform/code-search/progressive-reader.js +173 -0
- package/dist/platform/code-search/progressive-reader.js.map +1 -0
- package/dist/platform/code-search/query-planner.d.ts +4 -0
- package/dist/platform/code-search/query-planner.d.ts.map +1 -0
- package/dist/platform/code-search/query-planner.js +107 -0
- package/dist/platform/code-search/query-planner.js.map +1 -0
- package/dist/platform/code-search/reranker.d.ts +4 -0
- package/dist/platform/code-search/reranker.d.ts.map +1 -0
- package/dist/platform/code-search/reranker.js +57 -0
- package/dist/platform/code-search/reranker.js.map +1 -0
- package/dist/platform/code-search/retrievers/callgraph-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/callgraph-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/callgraph-retriever.js +31 -0
- package/dist/platform/code-search/retrievers/callgraph-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/config-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/config-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/config-retriever.js +23 -0
- package/dist/platform/code-search/retrievers/config-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/lexical-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/lexical-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/lexical-retriever.js +49 -0
- package/dist/platform/code-search/retrievers/lexical-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/package-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/package-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/package-retriever.js +29 -0
- package/dist/platform/code-search/retrievers/package-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/repo-map-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/repo-map-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/repo-map-retriever.js +30 -0
- package/dist/platform/code-search/retrievers/repo-map-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/semantic-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/semantic-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/semantic-retriever.js +18 -0
- package/dist/platform/code-search/retrievers/semantic-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/stacktrace-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/stacktrace-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/stacktrace-retriever.js +30 -0
- package/dist/platform/code-search/retrievers/stacktrace-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/symbol-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/symbol-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/symbol-retriever.js +32 -0
- package/dist/platform/code-search/retrievers/symbol-retriever.js.map +1 -0
- package/dist/platform/code-search/retrievers/test-retriever.d.ts +6 -0
- package/dist/platform/code-search/retrievers/test-retriever.d.ts.map +1 -0
- package/dist/platform/code-search/retrievers/test-retriever.js +30 -0
- package/dist/platform/code-search/retrievers/test-retriever.js.map +1 -0
- package/dist/platform/code-search/session-store.d.ts +11 -0
- package/dist/platform/code-search/session-store.d.ts.map +1 -0
- package/dist/platform/code-search/session-store.js +41 -0
- package/dist/platform/code-search/session-store.js.map +1 -0
- package/dist/platform/code-search/trace.d.ts +9 -0
- package/dist/platform/code-search/trace.d.ts.map +1 -0
- package/dist/platform/code-search/trace.js +25 -0
- package/dist/platform/code-search/trace.js.map +1 -0
- package/dist/platform/code-search/verification-retrieval.d.ts +3 -0
- package/dist/platform/code-search/verification-retrieval.d.ts.map +1 -0
- package/dist/platform/code-search/verification-retrieval.js +33 -0
- package/dist/platform/code-search/verification-retrieval.js.map +1 -0
- package/dist/platform/observation/context-provider.d.ts.map +1 -1
- package/dist/platform/observation/context-provider.js +37 -0
- package/dist/platform/observation/context-provider.js.map +1 -1
- package/dist/platform/observation/workspace-context.d.ts.map +1 -1
- package/dist/platform/observation/workspace-context.js +27 -0
- package/dist/platform/observation/workspace-context.js.map +1 -1
- package/dist/runtime/daemon/client.d.ts +13 -1
- package/dist/runtime/daemon/client.d.ts.map +1 -1
- package/dist/runtime/daemon/client.js +2 -2
- package/dist/runtime/daemon/client.js.map +1 -1
- package/dist/runtime/daemon/runner-commands.d.ts +9 -1
- package/dist/runtime/daemon/runner-commands.d.ts.map +1 -1
- package/dist/runtime/daemon/runner-commands.js +33 -2
- package/dist/runtime/daemon/runner-commands.js.map +1 -1
- package/dist/runtime/daemon/runner-startup.d.ts.map +1 -1
- package/dist/runtime/daemon/runner-startup.js +22 -1
- package/dist/runtime/daemon/runner-startup.js.map +1 -1
- package/dist/runtime/daemon/runner.d.ts.map +1 -1
- package/dist/runtime/daemon/runner.js +3 -2
- package/dist/runtime/daemon/runner.js.map +1 -1
- package/dist/runtime/daemon/runtime-root.d.ts +5 -0
- package/dist/runtime/daemon/runtime-root.d.ts.map +1 -0
- package/dist/runtime/daemon/runtime-root.js +60 -0
- package/dist/runtime/daemon/runtime-root.js.map +1 -0
- package/dist/runtime/event/server-command-handler.d.ts.map +1 -1
- package/dist/runtime/event/server-command-handler.js +47 -3
- package/dist/runtime/event/server-command-handler.js.map +1 -1
- package/dist/runtime/executor/goal-worker.d.ts +1 -0
- package/dist/runtime/executor/goal-worker.d.ts.map +1 -1
- package/dist/runtime/executor/goal-worker.js +1 -0
- package/dist/runtime/executor/goal-worker.js.map +1 -1
- package/dist/runtime/executor/loop-supervisor.d.ts +24 -1
- package/dist/runtime/executor/loop-supervisor.d.ts.map +1 -1
- package/dist/runtime/executor/loop-supervisor.js +191 -12
- package/dist/runtime/executor/loop-supervisor.js.map +1 -1
- package/dist/runtime/gateway/telegram-gateway-adapter.d.ts.map +1 -1
- package/dist/runtime/gateway/telegram-gateway-adapter.js +2 -1
- package/dist/runtime/gateway/telegram-gateway-adapter.js.map +1 -1
- package/dist/runtime/session-registry/index.d.ts +3 -0
- package/dist/runtime/session-registry/index.d.ts.map +1 -0
- package/dist/runtime/session-registry/index.js +3 -0
- package/dist/runtime/session-registry/index.js.map +1 -0
- package/dist/runtime/session-registry/registry.d.ts +39 -0
- package/dist/runtime/session-registry/registry.d.ts.map +1 -0
- package/dist/runtime/session-registry/registry.js +761 -0
- package/dist/runtime/session-registry/registry.js.map +1 -0
- package/dist/runtime/session-registry/types.d.ts +985 -0
- package/dist/runtime/session-registry/types.d.ts.map +1 -0
- package/dist/runtime/session-registry/types.js +108 -0
- package/dist/runtime/session-registry/types.js.map +1 -0
- package/dist/runtime/store/background-run-store.d.ts +75 -0
- package/dist/runtime/store/background-run-store.d.ts.map +1 -0
- package/dist/runtime/store/background-run-store.js +157 -0
- package/dist/runtime/store/background-run-store.js.map +1 -0
- package/dist/runtime/store/index.d.ts +2 -0
- package/dist/runtime/store/index.d.ts.map +1 -1
- package/dist/runtime/store/index.js +1 -0
- package/dist/runtime/store/index.js.map +1 -1
- package/dist/runtime/store/runtime-operation-schemas.d.ts +24 -24
- package/dist/runtime/store/runtime-paths.d.ts +2 -0
- package/dist/runtime/store/runtime-paths.d.ts.map +1 -1
- package/dist/runtime/store/runtime-paths.js +6 -0
- package/dist/runtime/store/runtime-paths.js.map +1 -1
- package/dist/runtime/types/daemon.d.ts +3 -0
- package/dist/runtime/types/daemon.d.ts.map +1 -1
- package/dist/runtime/types/daemon.js +1 -0
- package/dist/runtime/types/daemon.js.map +1 -1
- package/dist/tools/builtin/exports.d.ts +4 -0
- package/dist/tools/builtin/exports.d.ts.map +1 -1
- package/dist/tools/builtin/exports.js +4 -0
- package/dist/tools/builtin/exports.js.map +1 -1
- package/dist/tools/builtin/factory.d.ts.map +1 -1
- package/dist/tools/builtin/factory.js +18 -0
- package/dist/tools/builtin/factory.js.map +1 -1
- package/dist/tools/fs/GlobTool/GlobTool.js +2 -2
- package/dist/tools/fs/GlobTool/GlobTool.js.map +1 -1
- package/dist/tools/fs/GrepTool/GrepTool.js +2 -2
- package/dist/tools/fs/GrepTool/GrepTool.js.map +1 -1
- package/dist/tools/fs/ReadTool/ReadTool.js +2 -2
- package/dist/tools/fs/ReadTool/ReadTool.js.map +1 -1
- package/dist/tools/kaggle/KaggleExperimentTools.d.ts +395 -0
- package/dist/tools/kaggle/KaggleExperimentTools.d.ts.map +1 -0
- package/dist/tools/kaggle/KaggleExperimentTools.js +923 -0
- package/dist/tools/kaggle/KaggleExperimentTools.js.map +1 -0
- package/dist/tools/kaggle/KaggleSubmissionTools.d.ts +241 -0
- package/dist/tools/kaggle/KaggleSubmissionTools.d.ts.map +1 -0
- package/dist/tools/kaggle/KaggleSubmissionTools.js +558 -0
- package/dist/tools/kaggle/KaggleSubmissionTools.js.map +1 -0
- package/dist/tools/kaggle/KaggleWorkspacePrepareTool.d.ts +105 -0
- package/dist/tools/kaggle/KaggleWorkspacePrepareTool.d.ts.map +1 -0
- package/dist/tools/kaggle/KaggleWorkspacePrepareTool.js +135 -0
- package/dist/tools/kaggle/KaggleWorkspacePrepareTool.js.map +1 -0
- package/dist/tools/kaggle/index.d.ts +6 -0
- package/dist/tools/kaggle/index.d.ts.map +1 -0
- package/dist/tools/kaggle/index.js +6 -0
- package/dist/tools/kaggle/index.js.map +1 -0
- package/dist/tools/kaggle/metrics.d.ts +89 -0
- package/dist/tools/kaggle/metrics.d.ts.map +1 -0
- package/dist/tools/kaggle/metrics.js +51 -0
- package/dist/tools/kaggle/metrics.js.map +1 -0
- package/dist/tools/kaggle/paths.d.ts +15 -0
- package/dist/tools/kaggle/paths.d.ts.map +1 -0
- package/dist/tools/kaggle/paths.js +136 -0
- package/dist/tools/kaggle/paths.js.map +1 -0
- package/dist/tools/network/GitHubCliTool/GitHubCliTool.d.ts +2 -2
- package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.d.ts +801 -0
- package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.d.ts.map +1 -0
- package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.js +147 -0
- package/dist/tools/query/CodeReadContextTool/CodeReadContextTool.js.map +1 -0
- package/dist/tools/query/CodeReadContextTool/constants.d.ts +5 -0
- package/dist/tools/query/CodeReadContextTool/constants.d.ts.map +1 -0
- package/dist/tools/query/CodeReadContextTool/constants.js +5 -0
- package/dist/tools/query/CodeReadContextTool/constants.js.map +1 -0
- package/dist/tools/query/CodeReadContextTool/prompt.d.ts +2 -0
- package/dist/tools/query/CodeReadContextTool/prompt.d.ts.map +1 -0
- package/dist/tools/query/CodeReadContextTool/prompt.js +6 -0
- package/dist/tools/query/CodeReadContextTool/prompt.js.map +1 -0
- package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.d.ts +125 -0
- package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.d.ts.map +1 -0
- package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.js +97 -0
- package/dist/tools/query/CodeSearchRepairTool/CodeSearchRepairTool.js.map +1 -0
- package/dist/tools/query/CodeSearchRepairTool/constants.d.ts +5 -0
- package/dist/tools/query/CodeSearchRepairTool/constants.d.ts.map +1 -0
- package/dist/tools/query/CodeSearchRepairTool/constants.js +5 -0
- package/dist/tools/query/CodeSearchRepairTool/constants.js.map +1 -0
- package/dist/tools/query/CodeSearchRepairTool/prompt.d.ts +2 -0
- package/dist/tools/query/CodeSearchRepairTool/prompt.d.ts.map +1 -0
- package/dist/tools/query/CodeSearchRepairTool/prompt.js +5 -0
- package/dist/tools/query/CodeSearchRepairTool/prompt.js.map +1 -0
- package/dist/tools/query/CodeSearchTool/CodeSearchTool.d.ts +123 -0
- package/dist/tools/query/CodeSearchTool/CodeSearchTool.d.ts.map +1 -0
- package/dist/tools/query/CodeSearchTool/CodeSearchTool.js +95 -0
- package/dist/tools/query/CodeSearchTool/CodeSearchTool.js.map +1 -0
- package/dist/tools/query/CodeSearchTool/constants.d.ts +5 -0
- package/dist/tools/query/CodeSearchTool/constants.d.ts.map +1 -0
- package/dist/tools/query/CodeSearchTool/constants.js +5 -0
- package/dist/tools/query/CodeSearchTool/constants.js.map +1 -0
- package/dist/tools/query/CodeSearchTool/prompt.d.ts +2 -0
- package/dist/tools/query/CodeSearchTool/prompt.d.ts.map +1 -0
- package/dist/tools/query/CodeSearchTool/prompt.js +6 -0
- package/dist/tools/query/CodeSearchTool/prompt.js.map +1 -0
- package/package.json +2 -1
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import React, { useCallback, useState } from "react";
|
|
3
|
+
import { spawnSync } from "child_process";
|
|
4
|
+
import { mkdtempSync, writeFileSync } from "fs";
|
|
5
|
+
import { tmpdir } from "os";
|
|
6
|
+
import path from "path";
|
|
3
7
|
import { Box, Text, useInput } from "ink";
|
|
4
|
-
import { getClipboardContent } from "./clipboard.js";
|
|
8
|
+
import { copyToClipboard, getClipboardContent } from "./clipboard.js";
|
|
5
9
|
import { logTuiDebug } from "./debug-log.js";
|
|
6
10
|
import { theme } from "./theme.js";
|
|
7
11
|
import { pickSpinnerVerb } from "./spinner-verbs.js";
|
|
@@ -9,8 +13,10 @@ import { buildHiddenCursorEscapeFromPosition, CARET_MARKER, PROTECTED_ROW_MARKER
|
|
|
9
13
|
import { measureCharWidth, measureTextWidth } from "./text-width.js";
|
|
10
14
|
import { isBashModeInput } from "./bash-mode.js";
|
|
11
15
|
import { buildChatViewport } from "./chat/viewport.js";
|
|
12
|
-
import { getScrollRequest, normalizeTerminalInputChunk, parseMouseEvent, } from "./chat/scroll.js";
|
|
16
|
+
import { getScrollLineStep, getScrollRequest, normalizeTerminalInputChunk, parseMouseEvent, } from "./chat/scroll.js";
|
|
13
17
|
import { getMatchingSuggestions } from "./chat/suggestions.js";
|
|
18
|
+
import { writeTrustedTuiControl } from "./terminal-output.js";
|
|
19
|
+
import { CURSOR_HOME, ENTER_ALT_SCREEN, ERASE_SCREEN, EXIT_ALT_SCREEN, HIDE_CURSOR, SHOW_CURSOR, } from "./flicker/dec.js";
|
|
14
20
|
const SCROLL_LINE_STEP = 1;
|
|
15
21
|
const SCROLL_ANIMATION_INTERVAL_MS = 16;
|
|
16
22
|
const DEFAULT_PROMPT = "◉";
|
|
@@ -22,6 +28,8 @@ const SELECTION_FOREGROUND = "#1F2329";
|
|
|
22
28
|
const FAKE_CURSOR_GLYPH = "▌";
|
|
23
29
|
const PROCESSING_SPINNER_FRAMES = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
24
30
|
const PROCESSING_SPINNER_INTERVAL_MS = 80;
|
|
31
|
+
const COLLAPSED_PASTE_MIN_CHARS = 120;
|
|
32
|
+
const COLLAPSED_PASTE_MIN_MULTILINE_CHARS = 40;
|
|
25
33
|
function charWidth(ch) {
|
|
26
34
|
return measureCharWidth(ch);
|
|
27
35
|
}
|
|
@@ -100,6 +108,31 @@ function formatSuggestionLabel(suggestion) {
|
|
|
100
108
|
? ` ${suggestion.name} ${suggestion.description.padEnd(20)} [goal]`
|
|
101
109
|
: ` ${suggestion.name.padEnd(20)}${suggestion.description}`;
|
|
102
110
|
}
|
|
111
|
+
function countTextLines(text) {
|
|
112
|
+
return text.length === 0 ? 0 : text.split("\n").length;
|
|
113
|
+
}
|
|
114
|
+
export function shouldCollapsePastedText(rawInput, normalizedInput) {
|
|
115
|
+
const isBracketedPaste = rawInput.includes("[200~") || rawInput.includes("\u001b[200~");
|
|
116
|
+
if (normalizedInput.length >= COLLAPSED_PASTE_MIN_CHARS) {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
if (normalizedInput.includes("\n") && normalizedInput.length >= COLLAPSED_PASTE_MIN_MULTILINE_CHARS) {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
return isBracketedPaste && normalizedInput.length >= COLLAPSED_PASTE_MIN_MULTILINE_CHARS;
|
|
123
|
+
}
|
|
124
|
+
export function buildCollapsedPasteRange(text, start) {
|
|
125
|
+
const lineCount = countTextLines(text);
|
|
126
|
+
const charCount = Array.from(text).length;
|
|
127
|
+
const label = lineCount > 1
|
|
128
|
+
? `[pasted ${lineCount} lines, ${charCount} chars]`
|
|
129
|
+
: `[pasted ${charCount} chars]`;
|
|
130
|
+
return {
|
|
131
|
+
start,
|
|
132
|
+
end: start + text.length,
|
|
133
|
+
label,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
103
136
|
function normalizeSelection(selection) {
|
|
104
137
|
if (!selection || selection.anchor === selection.focus) {
|
|
105
138
|
return null;
|
|
@@ -109,6 +142,21 @@ function normalizeSelection(selection) {
|
|
|
109
142
|
end: Math.max(selection.anchor, selection.focus),
|
|
110
143
|
};
|
|
111
144
|
}
|
|
145
|
+
export function getSelectedInputText(input, selection) {
|
|
146
|
+
const range = normalizeSelection(selection);
|
|
147
|
+
return range ? input.slice(range.start, range.end) : "";
|
|
148
|
+
}
|
|
149
|
+
export async function copySelectedInputText(input, selection, copy = copyToClipboard) {
|
|
150
|
+
const selectedText = getSelectedInputText(input, selection);
|
|
151
|
+
if (!selectedText) {
|
|
152
|
+
return { ok: false };
|
|
153
|
+
}
|
|
154
|
+
return copy(selectedText);
|
|
155
|
+
}
|
|
156
|
+
function formatCopyToast(charCount, result) {
|
|
157
|
+
const suffix = result.method ? ` via ${result.method}` : "";
|
|
158
|
+
return `copied ${charCount} chars${suffix}`;
|
|
159
|
+
}
|
|
112
160
|
function pushSegment(segments, text, style = {}) {
|
|
113
161
|
if (text.length === 0)
|
|
114
162
|
return;
|
|
@@ -123,7 +171,7 @@ function pushSegment(segments, text, style = {}) {
|
|
|
123
171
|
}
|
|
124
172
|
segments.push({ text, ...style });
|
|
125
173
|
}
|
|
126
|
-
function buildInputRows(input, cursorOffset, contentWidth, placeholder, selection) {
|
|
174
|
+
function buildInputRows(input, cursorOffset, contentWidth, placeholder, selection, collapsedPaste) {
|
|
127
175
|
if (contentWidth <= 0) {
|
|
128
176
|
return {
|
|
129
177
|
rows: [{
|
|
@@ -167,6 +215,11 @@ function buildInputRows(input, cursorOffset, contentWidth, placeholder, selectio
|
|
|
167
215
|
let currentWidth = 0;
|
|
168
216
|
let rowStartOffset = 0;
|
|
169
217
|
let rowEndOffset = 0;
|
|
218
|
+
const activeCollapsedPaste = collapsedPaste
|
|
219
|
+
&& !(cursorOffset > collapsedPaste.start && cursorOffset < collapsedPaste.end)
|
|
220
|
+
&& !(selection && selection.start < collapsedPaste.end && selection.end > collapsedPaste.start)
|
|
221
|
+
? collapsedPaste
|
|
222
|
+
: null;
|
|
170
223
|
const pushRow = () => {
|
|
171
224
|
rows.push({
|
|
172
225
|
cells: currentCells,
|
|
@@ -194,6 +247,28 @@ function buildInputRows(input, cursorOffset, contentWidth, placeholder, selectio
|
|
|
194
247
|
if (offset === input.length) {
|
|
195
248
|
break;
|
|
196
249
|
}
|
|
250
|
+
if (activeCollapsedPaste && offset === activeCollapsedPaste.start) {
|
|
251
|
+
const label = stringWidth(activeCollapsedPaste.label) <= contentWidth
|
|
252
|
+
? activeCollapsedPaste.label
|
|
253
|
+
: trimToWidth("[paste]", contentWidth);
|
|
254
|
+
const labelWidth = stringWidth(label);
|
|
255
|
+
if (currentWidth + labelWidth > contentWidth && currentCells.length > 0) {
|
|
256
|
+
pushRow();
|
|
257
|
+
rowStartOffset = offset;
|
|
258
|
+
rowEndOffset = offset;
|
|
259
|
+
}
|
|
260
|
+
currentCells.push({
|
|
261
|
+
text: label,
|
|
262
|
+
width: labelWidth,
|
|
263
|
+
offsetBefore: activeCollapsedPaste.start,
|
|
264
|
+
offsetAfter: activeCollapsedPaste.end,
|
|
265
|
+
dim: true,
|
|
266
|
+
});
|
|
267
|
+
currentWidth += labelWidth;
|
|
268
|
+
rowEndOffset = activeCollapsedPaste.end;
|
|
269
|
+
offset = activeCollapsedPaste.end;
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
197
272
|
const codePoint = input.codePointAt(offset) ?? 0;
|
|
198
273
|
const ch = String.fromCodePoint(codePoint);
|
|
199
274
|
const nextOffset = offset + ch.length;
|
|
@@ -253,7 +328,7 @@ function buildInputContentSegments(row, contentWidth, bashMode) {
|
|
|
253
328
|
}
|
|
254
329
|
pushSegment(segments, cell.text, {
|
|
255
330
|
color: defaultColor,
|
|
256
|
-
dim: cell.placeholder,
|
|
331
|
+
dim: cell.placeholder || cell.dim,
|
|
257
332
|
});
|
|
258
333
|
}
|
|
259
334
|
if (usedWidth < contentWidth) {
|
|
@@ -263,6 +338,222 @@ function buildInputContentSegments(row, contentWidth, bashMode) {
|
|
|
263
338
|
}
|
|
264
339
|
return segments;
|
|
265
340
|
}
|
|
341
|
+
function compareBodySelectionPoints(a, b) {
|
|
342
|
+
if (a.rowIndex !== b.rowIndex) {
|
|
343
|
+
return a.rowIndex - b.rowIndex;
|
|
344
|
+
}
|
|
345
|
+
return a.offset - b.offset;
|
|
346
|
+
}
|
|
347
|
+
function normalizeBodySelection(selection) {
|
|
348
|
+
if (!selection || compareBodySelectionPoints(selection.anchor, selection.focus) === 0) {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
return compareBodySelectionPoints(selection.anchor, selection.focus) <= 0
|
|
352
|
+
? { start: selection.anchor, end: selection.focus }
|
|
353
|
+
: { start: selection.focus, end: selection.anchor };
|
|
354
|
+
}
|
|
355
|
+
function getBodySelectionForRow(selection, rowIndex, textLength) {
|
|
356
|
+
if (!selection || rowIndex < selection.start.rowIndex || rowIndex > selection.end.rowIndex) {
|
|
357
|
+
return null;
|
|
358
|
+
}
|
|
359
|
+
const start = rowIndex === selection.start.rowIndex ? selection.start.offset : 0;
|
|
360
|
+
const end = rowIndex === selection.end.rowIndex ? selection.end.offset : textLength;
|
|
361
|
+
if (start === end)
|
|
362
|
+
return null;
|
|
363
|
+
return { start: Math.max(0, start), end: Math.min(textLength, end) };
|
|
364
|
+
}
|
|
365
|
+
function getDisplayOffsetForText(text, col) {
|
|
366
|
+
if (col <= 0)
|
|
367
|
+
return 0;
|
|
368
|
+
let usedWidth = 0;
|
|
369
|
+
let offset = 0;
|
|
370
|
+
for (const ch of text) {
|
|
371
|
+
const width = charWidth(ch);
|
|
372
|
+
const midpoint = usedWidth + width / 2;
|
|
373
|
+
if (col <= midpoint)
|
|
374
|
+
return offset;
|
|
375
|
+
offset += ch.length;
|
|
376
|
+
usedWidth += width;
|
|
377
|
+
if (col <= usedWidth)
|
|
378
|
+
return offset;
|
|
379
|
+
}
|
|
380
|
+
return text.length;
|
|
381
|
+
}
|
|
382
|
+
function applySelectionToTextSegments(text, selection, style) {
|
|
383
|
+
if (!selection) {
|
|
384
|
+
return [{ text, ...style }];
|
|
385
|
+
}
|
|
386
|
+
const segments = [];
|
|
387
|
+
const before = text.slice(0, selection.start);
|
|
388
|
+
const selected = text.slice(selection.start, selection.end);
|
|
389
|
+
const after = text.slice(selection.end);
|
|
390
|
+
pushSegment(segments, before, style);
|
|
391
|
+
pushSegment(segments, selected, {
|
|
392
|
+
...style,
|
|
393
|
+
color: SELECTION_FOREGROUND,
|
|
394
|
+
backgroundColor: SELECTION_BACKGROUND,
|
|
395
|
+
});
|
|
396
|
+
pushSegment(segments, after, style);
|
|
397
|
+
return segments;
|
|
398
|
+
}
|
|
399
|
+
export function getSelectedBodyText(rows, selection) {
|
|
400
|
+
const range = normalizeBodySelection(selection);
|
|
401
|
+
if (!range)
|
|
402
|
+
return "";
|
|
403
|
+
const selectedRows = [];
|
|
404
|
+
for (let rowIndex = range.start.rowIndex; rowIndex <= range.end.rowIndex; rowIndex += 1) {
|
|
405
|
+
const row = rows[rowIndex];
|
|
406
|
+
if (!row || row.kind === "spacer")
|
|
407
|
+
continue;
|
|
408
|
+
const rowRange = getBodySelectionForRow(range, rowIndex, row.text.length);
|
|
409
|
+
if (!rowRange)
|
|
410
|
+
continue;
|
|
411
|
+
selectedRows.push(row.text.slice(rowRange.start, rowRange.end).trimEnd());
|
|
412
|
+
}
|
|
413
|
+
return selectedRows.join("\n").trim();
|
|
414
|
+
}
|
|
415
|
+
export function extractClickableTargetAt(text, offset) {
|
|
416
|
+
const patterns = [
|
|
417
|
+
/https?:\/\/[^\s)>\]}]+/g,
|
|
418
|
+
/(?:\.{1,2}\/|\/)[^\s:]+(?::\d+)?/g,
|
|
419
|
+
];
|
|
420
|
+
for (const pattern of patterns) {
|
|
421
|
+
for (const match of text.matchAll(pattern)) {
|
|
422
|
+
const value = match[0];
|
|
423
|
+
const start = match.index ?? 0;
|
|
424
|
+
const end = start + value.length;
|
|
425
|
+
if (offset >= start && offset <= end) {
|
|
426
|
+
return value;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
return null;
|
|
431
|
+
}
|
|
432
|
+
function openClickableTarget(target) {
|
|
433
|
+
if (/^https?:\/\//.test(target)) {
|
|
434
|
+
if (process.platform === "darwin") {
|
|
435
|
+
return spawnSync("open", [target], { stdio: "ignore" }).status === 0;
|
|
436
|
+
}
|
|
437
|
+
if (process.platform === "linux") {
|
|
438
|
+
return spawnSync("xdg-open", [target], { stdio: "ignore" }).status === 0;
|
|
439
|
+
}
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
const [filePart, linePart] = target.split(/:(\d+)$/);
|
|
443
|
+
const resolvedPath = path.resolve(process.cwd(), filePart || target);
|
|
444
|
+
const editor = process.env.VISUAL || process.env.EDITOR;
|
|
445
|
+
if (editor) {
|
|
446
|
+
const editorTarget = linePart ? `${resolvedPath}:${linePart}` : resolvedPath;
|
|
447
|
+
return spawnSync(editor, [editorTarget], { stdio: "ignore", shell: true }).status === 0;
|
|
448
|
+
}
|
|
449
|
+
if (process.platform === "darwin") {
|
|
450
|
+
return spawnSync("open", [resolvedPath], { stdio: "ignore" }).status === 0;
|
|
451
|
+
}
|
|
452
|
+
if (process.platform === "linux") {
|
|
453
|
+
return spawnSync("xdg-open", [resolvedPath], { stdio: "ignore" }).status === 0;
|
|
454
|
+
}
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
export function formatTranscript(messages) {
|
|
458
|
+
return messages
|
|
459
|
+
.map((message) => {
|
|
460
|
+
const label = message.role === "user" ? "User" : "PulSeed";
|
|
461
|
+
return `${label}:\n${message.text.trimEnd()}`;
|
|
462
|
+
})
|
|
463
|
+
.join("\n\n");
|
|
464
|
+
}
|
|
465
|
+
function wrapPlainTextToRows(text, width) {
|
|
466
|
+
const rows = [];
|
|
467
|
+
for (const sourceLine of text.split("\n")) {
|
|
468
|
+
if (sourceLine.length === 0) {
|
|
469
|
+
rows.push("");
|
|
470
|
+
continue;
|
|
471
|
+
}
|
|
472
|
+
let current = "";
|
|
473
|
+
let currentWidth = 0;
|
|
474
|
+
for (const ch of sourceLine) {
|
|
475
|
+
const widthOfChar = charWidth(ch);
|
|
476
|
+
if (currentWidth + widthOfChar > width && current.length > 0) {
|
|
477
|
+
rows.push(current);
|
|
478
|
+
current = "";
|
|
479
|
+
currentWidth = 0;
|
|
480
|
+
}
|
|
481
|
+
current += ch;
|
|
482
|
+
currentWidth += widthOfChar;
|
|
483
|
+
}
|
|
484
|
+
rows.push(current);
|
|
485
|
+
}
|
|
486
|
+
return rows;
|
|
487
|
+
}
|
|
488
|
+
function buildTranscriptRows(messages, cols) {
|
|
489
|
+
const rows = [];
|
|
490
|
+
for (const message of messages) {
|
|
491
|
+
const label = message.role === "user" ? "User" : "PulSeed";
|
|
492
|
+
rows.push(...wrapPlainTextToRows(`${label}:`, cols));
|
|
493
|
+
rows.push(...wrapPlainTextToRows(message.text.trimEnd(), cols));
|
|
494
|
+
rows.push("");
|
|
495
|
+
}
|
|
496
|
+
return rows;
|
|
497
|
+
}
|
|
498
|
+
export function buildTranscriptRenderLines(args) {
|
|
499
|
+
const { messages, cols, rows, scrollOffset, searchQuery, searchMode, status } = args;
|
|
500
|
+
const bodyRows = Math.max(1, rows - 2);
|
|
501
|
+
const transcriptRows = buildTranscriptRows(messages, cols);
|
|
502
|
+
const maxScrollOffset = Math.max(0, transcriptRows.length - bodyRows);
|
|
503
|
+
const clampedOffset = Math.max(0, Math.min(maxScrollOffset, scrollOffset));
|
|
504
|
+
const visibleRows = transcriptRows.slice(clampedOffset, clampedOffset + bodyRows);
|
|
505
|
+
const lines = [{
|
|
506
|
+
key: "transcript-header",
|
|
507
|
+
text: padToWidth("transcript / search n/N next [ write scrollback v editor Esc return", cols),
|
|
508
|
+
color: theme.command,
|
|
509
|
+
}];
|
|
510
|
+
visibleRows.forEach((row, index) => {
|
|
511
|
+
lines.push({
|
|
512
|
+
key: `transcript-${clampedOffset + index}`,
|
|
513
|
+
text: padToWidth(row, cols),
|
|
514
|
+
backgroundColor: searchQuery.length > 0 && row.toLowerCase().includes(searchQuery.toLowerCase())
|
|
515
|
+
? "#3A3A22"
|
|
516
|
+
: undefined,
|
|
517
|
+
});
|
|
518
|
+
});
|
|
519
|
+
while (lines.length < rows - 1) {
|
|
520
|
+
lines.push({ key: `transcript-filler-${lines.length}`, text: " ".repeat(cols) });
|
|
521
|
+
}
|
|
522
|
+
lines.push({
|
|
523
|
+
key: "transcript-footer",
|
|
524
|
+
text: padToWidth(searchMode
|
|
525
|
+
? `/${searchQuery}`
|
|
526
|
+
: status
|
|
527
|
+
? status
|
|
528
|
+
: `${clampedOffset + 1}-${Math.min(clampedOffset + bodyRows, transcriptRows.length)} / ${transcriptRows.length}`, cols),
|
|
529
|
+
dim: !searchMode && !status,
|
|
530
|
+
color: searchMode ? theme.command : undefined,
|
|
531
|
+
});
|
|
532
|
+
return { lines: lines.slice(0, rows), totalRows: transcriptRows.length, maxScrollOffset };
|
|
533
|
+
}
|
|
534
|
+
function writeTranscriptToNativeScrollback(messages) {
|
|
535
|
+
const transcript = formatTranscript(messages);
|
|
536
|
+
writeTrustedTuiControl(SHOW_CURSOR +
|
|
537
|
+
EXIT_ALT_SCREEN +
|
|
538
|
+
`\n${transcript}\n` +
|
|
539
|
+
ENTER_ALT_SCREEN +
|
|
540
|
+
ERASE_SCREEN +
|
|
541
|
+
CURSOR_HOME +
|
|
542
|
+
HIDE_CURSOR);
|
|
543
|
+
}
|
|
544
|
+
function openTranscriptInEditor(messages) {
|
|
545
|
+
const editor = process.env.VISUAL || process.env.EDITOR;
|
|
546
|
+
if (!editor) {
|
|
547
|
+
return { ok: false };
|
|
548
|
+
}
|
|
549
|
+
const dir = mkdtempSync(path.join(tmpdir(), "pulseed-transcript-"));
|
|
550
|
+
const filePath = path.join(dir, "transcript.md");
|
|
551
|
+
writeFileSync(filePath, formatTranscript(messages), "utf8");
|
|
552
|
+
writeTrustedTuiControl(SHOW_CURSOR + EXIT_ALT_SCREEN);
|
|
553
|
+
const result = spawnSync(editor, [filePath], { stdio: "inherit", shell: true });
|
|
554
|
+
writeTrustedTuiControl(ENTER_ALT_SCREEN + ERASE_SCREEN + CURSOR_HOME + HIDE_CURSOR);
|
|
555
|
+
return result.status === 0 ? { ok: true, method: "osc52" } : { ok: false };
|
|
556
|
+
}
|
|
266
557
|
function getCursorPositionFromComposerLayout(layout) {
|
|
267
558
|
for (let rowIndex = 0; rowIndex < layout.rows.length; rowIndex += 1) {
|
|
268
559
|
const row = layout.rows[rowIndex];
|
|
@@ -281,8 +572,8 @@ function getCursorPositionFromComposerLayout(layout) {
|
|
|
281
572
|
}
|
|
282
573
|
return null;
|
|
283
574
|
}
|
|
284
|
-
function buildComposerLines(args) {
|
|
285
|
-
const { cols, input, cursorOffset, bashMode, emptyHint, matches, selectedIdx, copyToast, selection, } = args;
|
|
575
|
+
export function buildComposerLines(args) {
|
|
576
|
+
const { cols, input, cursorOffset, bashMode, emptyHint, matches, selectedIdx, copyToast, selection, collapsedPaste, } = args;
|
|
286
577
|
const lines = [];
|
|
287
578
|
lines.push({
|
|
288
579
|
key: "copy-toast",
|
|
@@ -294,7 +585,7 @@ function buildComposerLines(args) {
|
|
|
294
585
|
const prompt = `${promptLabel} `;
|
|
295
586
|
const promptWidth = stringWidth(prompt);
|
|
296
587
|
const contentWidth = Math.max(1, innerWidth - INPUT_MARGIN - promptWidth);
|
|
297
|
-
const inputRender = buildInputRows(input, cursorOffset, contentWidth, getPlaceholder(bashMode), selection);
|
|
588
|
+
const inputRender = buildInputRows(input, cursorOffset, contentWidth, getPlaceholder(bashMode), selection, collapsedPaste);
|
|
298
589
|
const inputRows = inputRender.rows;
|
|
299
590
|
lines.push({
|
|
300
591
|
key: "composer-top",
|
|
@@ -363,10 +654,23 @@ function buildComposerLines(args) {
|
|
|
363
654
|
contentStartCol: 3 + promptWidth,
|
|
364
655
|
};
|
|
365
656
|
}
|
|
366
|
-
function renderMessageRow(row, cols) {
|
|
657
|
+
function renderMessageRow(row, cols, rowIndex, bodySelection) {
|
|
367
658
|
if (row.kind === "spacer") {
|
|
368
659
|
return { key: row.key, text: " ".repeat(cols) };
|
|
369
660
|
}
|
|
661
|
+
const selection = getBodySelectionForRow(bodySelection, rowIndex, row.text.length);
|
|
662
|
+
if (selection) {
|
|
663
|
+
const text = padToWidth(row.text, cols);
|
|
664
|
+
return {
|
|
665
|
+
key: row.key,
|
|
666
|
+
segments: applySelectionToTextSegments(text, selection, {
|
|
667
|
+
color: row.color,
|
|
668
|
+
backgroundColor: row.backgroundColor,
|
|
669
|
+
bold: row.bold,
|
|
670
|
+
dim: row.dim,
|
|
671
|
+
}),
|
|
672
|
+
};
|
|
673
|
+
}
|
|
370
674
|
return {
|
|
371
675
|
key: row.key,
|
|
372
676
|
text: padToWidth(row.text, cols),
|
|
@@ -376,14 +680,14 @@ function renderMessageRow(row, cols) {
|
|
|
376
680
|
dim: row.dim,
|
|
377
681
|
};
|
|
378
682
|
}
|
|
379
|
-
export function buildFullscreenChatRenderLines({ availableCols, availableRows, viewport, composerLines, isProcessing, spinnerGlyph, spinnerVerb, }) {
|
|
683
|
+
export function buildFullscreenChatRenderLines({ availableCols, availableRows, viewport, composerLines, isProcessing, spinnerGlyph, spinnerVerb, bodySelection, transcriptStatus, }) {
|
|
380
684
|
const lines = [];
|
|
381
685
|
lines.push({
|
|
382
686
|
key: "indicator-top",
|
|
383
687
|
text: padToWidth(viewport.hiddenAboveRows > 0 ? `↑ ${viewport.hiddenAboveRows} earlier lines` : "", availableCols),
|
|
384
688
|
dim: true,
|
|
385
689
|
});
|
|
386
|
-
const renderedRows = viewport.rows.map((row) => renderMessageRow(row, availableCols));
|
|
690
|
+
const renderedRows = viewport.rows.map((row, index) => (renderMessageRow(row, availableCols, index, bodySelection ?? null)));
|
|
387
691
|
const fillerCount = Math.max(0, viewport.maxVisibleRows - renderedRows.length);
|
|
388
692
|
for (let index = 0; index < fillerCount; index += 1) {
|
|
389
693
|
lines.push({ key: `filler-${index}`, text: " ".repeat(availableCols) });
|
|
@@ -396,9 +700,9 @@ export function buildFullscreenChatRenderLines({ availableCols, availableRows, v
|
|
|
396
700
|
});
|
|
397
701
|
lines.push({
|
|
398
702
|
key: "processing",
|
|
399
|
-
text: padToWidth(isProcessing ? `${spinnerGlyph} ${spinnerVerb}...` : "", availableCols),
|
|
703
|
+
text: padToWidth(transcriptStatus ?? (isProcessing ? `${spinnerGlyph} ${spinnerVerb}...` : ""), availableCols),
|
|
400
704
|
color: isProcessing ? theme.command : undefined,
|
|
401
|
-
dim: !isProcessing,
|
|
705
|
+
dim: !isProcessing && !transcriptStatus,
|
|
402
706
|
});
|
|
403
707
|
lines.push(...composerLines);
|
|
404
708
|
while (lines.length < availableRows) {
|
|
@@ -451,10 +755,25 @@ function getMouseOffsetFromComposer(layout, x, y, clampOutside) {
|
|
|
451
755
|
}
|
|
452
756
|
return row.endOffset;
|
|
453
757
|
}
|
|
758
|
+
function getMousePositionFromBody(rows, x, y, fillerRows) {
|
|
759
|
+
const rowIndex = y - 2 - fillerRows;
|
|
760
|
+
if (rowIndex < 0 || rowIndex >= rows.length) {
|
|
761
|
+
return null;
|
|
762
|
+
}
|
|
763
|
+
const row = rows[rowIndex];
|
|
764
|
+
if (!row || row.kind === "spacer") {
|
|
765
|
+
return null;
|
|
766
|
+
}
|
|
767
|
+
return {
|
|
768
|
+
rowIndex,
|
|
769
|
+
offset: getDisplayOffsetForText(row.text, x - 1),
|
|
770
|
+
};
|
|
771
|
+
}
|
|
454
772
|
export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goalNames = [], availableRows, availableCols, cursorOriginX = 0, cursorOriginY = 0, }) {
|
|
455
773
|
const [input, setInput] = useState("");
|
|
456
774
|
const [cursorOffset, setCursorOffset] = useState(0);
|
|
457
775
|
const [selection, setSelection] = useState(null);
|
|
776
|
+
const [collapsedPaste, setCollapsedPaste] = useState(null);
|
|
458
777
|
const selectionAnchor = React.useRef(null);
|
|
459
778
|
const [selectedIdx, setSelectedIdx] = useState(0);
|
|
460
779
|
const justSelected = React.useRef(false);
|
|
@@ -466,6 +785,12 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
466
785
|
const emptyHintTimer = React.useRef(null);
|
|
467
786
|
const [scrollOffset, setScrollOffset] = React.useState(0);
|
|
468
787
|
const [targetScrollOffset, setTargetScrollOffset] = React.useState(0);
|
|
788
|
+
const [bodySelection, setBodySelection] = React.useState(null);
|
|
789
|
+
const bodySelectionAnchor = React.useRef(null);
|
|
790
|
+
const [transcriptMode, setTranscriptMode] = React.useState(false);
|
|
791
|
+
const [transcriptScrollOffset, setTranscriptScrollOffset] = React.useState(0);
|
|
792
|
+
const [transcriptSearchQuery, setTranscriptSearchQuery] = React.useState("");
|
|
793
|
+
const [transcriptSearchMode, setTranscriptSearchMode] = React.useState(false);
|
|
469
794
|
const [spinnerVerb, setSpinnerVerb] = React.useState(() => pickSpinnerVerb());
|
|
470
795
|
const [spinnerFrameIndex, setSpinnerFrameIndex] = React.useState(0);
|
|
471
796
|
React.useEffect(() => {
|
|
@@ -515,22 +840,32 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
515
840
|
selectionAnchor.current = null;
|
|
516
841
|
setSelection(null);
|
|
517
842
|
}, []);
|
|
518
|
-
const
|
|
843
|
+
const clearBodySelection = useCallback(() => {
|
|
844
|
+
bodySelectionAnchor.current = null;
|
|
845
|
+
setBodySelection(null);
|
|
846
|
+
}, []);
|
|
847
|
+
const replaceInputRange = useCallback((start, end, replacement, nextCollapsedPaste = null) => {
|
|
519
848
|
const next = input.slice(0, start) + replacement + input.slice(end);
|
|
520
849
|
setInput(next);
|
|
521
850
|
setCursorOffset(start + replacement.length);
|
|
851
|
+
setCollapsedPaste(nextCollapsedPaste);
|
|
522
852
|
clearSelection();
|
|
523
853
|
}, [clearSelection, input]);
|
|
524
|
-
const insertText = useCallback((text) => {
|
|
854
|
+
const insertText = useCallback((text, options = {}) => {
|
|
525
855
|
justSelected.current = false;
|
|
526
856
|
const selectedRange = normalizeSelection(selection);
|
|
857
|
+
const start = selectedRange ? selectedRange.start : cursorOffset;
|
|
858
|
+
const nextCollapsedPaste = options.collapsePaste
|
|
859
|
+
? buildCollapsedPasteRange(text, start)
|
|
860
|
+
: null;
|
|
527
861
|
if (selectedRange) {
|
|
528
|
-
replaceInputRange(selectedRange.start, selectedRange.end, text);
|
|
862
|
+
replaceInputRange(selectedRange.start, selectedRange.end, text, nextCollapsedPaste);
|
|
529
863
|
return;
|
|
530
864
|
}
|
|
531
865
|
const next = input.slice(0, cursorOffset) + text + input.slice(cursorOffset);
|
|
532
866
|
setInput(next);
|
|
533
867
|
setCursorOffset(cursorOffset + text.length);
|
|
868
|
+
setCollapsedPaste(nextCollapsedPaste);
|
|
534
869
|
clearSelection();
|
|
535
870
|
}, [clearSelection, cursorOffset, input, replaceInputRange, selection]);
|
|
536
871
|
const deleteSelection = useCallback(() => {
|
|
@@ -541,6 +876,19 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
541
876
|
replaceInputRange(selectedRange.start, selectedRange.end, "");
|
|
542
877
|
return true;
|
|
543
878
|
}, [replaceInputRange, selection]);
|
|
879
|
+
const copySelectedInput = useCallback((nextSelection) => {
|
|
880
|
+
const selectedText = getSelectedInputText(input, nextSelection);
|
|
881
|
+
if (!selectedText) {
|
|
882
|
+
return;
|
|
883
|
+
}
|
|
884
|
+
void copySelectedInputText(input, nextSelection).then((result) => {
|
|
885
|
+
if (!result.ok) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
setCopyToast(formatCopyToast(selectedText.length, result));
|
|
889
|
+
setTimeout(() => setCopyToast(null), 2000);
|
|
890
|
+
});
|
|
891
|
+
}, [input]);
|
|
544
892
|
const matches = justSelected.current ? [] : getMatchingSuggestions(input, goalNames);
|
|
545
893
|
const hasMatches = matches.length > 0;
|
|
546
894
|
const bashMode = isBashModeInput(input);
|
|
@@ -555,10 +903,22 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
555
903
|
selectedIdx,
|
|
556
904
|
copyToast,
|
|
557
905
|
selection: normalizedSelection,
|
|
906
|
+
collapsedPaste,
|
|
558
907
|
});
|
|
559
908
|
const messageRows = Math.max(1, availableRows - composer.lines.length - 3);
|
|
560
909
|
const viewport = buildChatViewport(messages, availableCols, messageRows, scrollOffset);
|
|
561
910
|
const maxScrollOffset = Math.max(0, viewport.totalRows - viewport.maxVisibleRows);
|
|
911
|
+
const bodySelectionRange = normalizeBodySelection(bodySelection);
|
|
912
|
+
const viewportFillerRows = Math.max(0, viewport.maxVisibleRows - viewport.rows.length);
|
|
913
|
+
const transcript = buildTranscriptRenderLines({
|
|
914
|
+
messages,
|
|
915
|
+
cols: availableCols,
|
|
916
|
+
rows: availableRows,
|
|
917
|
+
scrollOffset: transcriptScrollOffset,
|
|
918
|
+
searchQuery: transcriptSearchQuery,
|
|
919
|
+
searchMode: transcriptSearchMode,
|
|
920
|
+
status: copyToast,
|
|
921
|
+
});
|
|
562
922
|
const composerLayout = {
|
|
563
923
|
startLine: viewport.maxVisibleRows + 3 + composer.inputRowStartIndex + 1,
|
|
564
924
|
contentStartCol: composer.contentStartCol,
|
|
@@ -583,6 +943,9 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
583
943
|
setScrollOffset((prev) => Math.min(prev, maxScrollOffset));
|
|
584
944
|
setTargetScrollOffset((prev) => Math.min(prev, maxScrollOffset));
|
|
585
945
|
}, [maxScrollOffset]);
|
|
946
|
+
React.useEffect(() => {
|
|
947
|
+
setTranscriptScrollOffset((prev) => Math.min(prev, transcript.maxScrollOffset));
|
|
948
|
+
}, [transcript.maxScrollOffset]);
|
|
586
949
|
React.useEffect(() => {
|
|
587
950
|
if (scrollOffset === targetScrollOffset) {
|
|
588
951
|
return;
|
|
@@ -601,18 +964,63 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
601
964
|
}, [scrollOffset, targetScrollOffset]);
|
|
602
965
|
const applyScroll = useCallback((direction, kind) => {
|
|
603
966
|
setTargetScrollOffset((prev) => {
|
|
967
|
+
if (kind === "top")
|
|
968
|
+
return maxScrollOffset;
|
|
969
|
+
if (kind === "bottom")
|
|
970
|
+
return 0;
|
|
604
971
|
const amount = kind === "page" ? viewport.maxVisibleRows : SCROLL_LINE_STEP;
|
|
605
|
-
const
|
|
972
|
+
const effectiveAmount = kind === "line" ? amount * getScrollLineStep() : amount;
|
|
973
|
+
const delta = direction === "up" ? effectiveAmount : -effectiveAmount;
|
|
606
974
|
return Math.max(0, Math.min(maxScrollOffset, prev + delta));
|
|
607
975
|
});
|
|
608
976
|
}, [maxScrollOffset, viewport.maxVisibleRows]);
|
|
977
|
+
const applyTranscriptScroll = useCallback((direction, kind) => {
|
|
978
|
+
setTranscriptScrollOffset((prev) => {
|
|
979
|
+
if (kind === "top")
|
|
980
|
+
return 0;
|
|
981
|
+
if (kind === "bottom")
|
|
982
|
+
return transcript.maxScrollOffset;
|
|
983
|
+
const pageRows = Math.max(1, availableRows - 2);
|
|
984
|
+
const amount = kind === "page" ? pageRows : getScrollLineStep();
|
|
985
|
+
const delta = direction === "up" ? -amount : amount;
|
|
986
|
+
return Math.max(0, Math.min(transcript.maxScrollOffset, prev + delta));
|
|
987
|
+
});
|
|
988
|
+
}, [availableRows, transcript.maxScrollOffset]);
|
|
989
|
+
const jumpToTranscriptMatch = useCallback((direction) => {
|
|
990
|
+
if (!transcriptSearchQuery)
|
|
991
|
+
return;
|
|
992
|
+
const rows = buildTranscriptRows(messages, availableCols);
|
|
993
|
+
const query = transcriptSearchQuery.toLowerCase();
|
|
994
|
+
const matches = rows
|
|
995
|
+
.map((row, index) => ({ row, index }))
|
|
996
|
+
.filter(({ row }) => row.toLowerCase().includes(query))
|
|
997
|
+
.map(({ index }) => index);
|
|
998
|
+
if (matches.length === 0)
|
|
999
|
+
return;
|
|
1000
|
+
const current = direction === "next"
|
|
1001
|
+
? matches.find((index) => index > transcriptScrollOffset)
|
|
1002
|
+
: [...matches].reverse().find((index) => index < transcriptScrollOffset);
|
|
1003
|
+
setTranscriptScrollOffset(current ?? (direction === "next" ? matches[0] : matches[matches.length - 1]));
|
|
1004
|
+
}, [availableCols, messages, transcriptScrollOffset, transcriptSearchQuery]);
|
|
1005
|
+
useInput((inputChar, key) => {
|
|
1006
|
+
if (transcriptMode)
|
|
1007
|
+
return;
|
|
1008
|
+
const scrollRequest = getScrollRequest(inputChar, key);
|
|
1009
|
+
if (!scrollRequest)
|
|
1010
|
+
return;
|
|
1011
|
+
logTuiDebug("fullscreen-chat", "processing-scroll-request", {
|
|
1012
|
+
direction: scrollRequest.direction,
|
|
1013
|
+
kind: scrollRequest.kind,
|
|
1014
|
+
});
|
|
1015
|
+
applyScroll(scrollRequest.direction, scrollRequest.kind);
|
|
1016
|
+
}, { isActive: isProcessing });
|
|
609
1017
|
const handleSubmit = useCallback((value) => {
|
|
610
1018
|
logTuiDebug("fullscreen-chat", "submit-attempt", {
|
|
611
1019
|
value,
|
|
612
1020
|
hasMatches,
|
|
613
1021
|
isProcessing,
|
|
614
1022
|
});
|
|
615
|
-
if (hasMatches
|
|
1023
|
+
if (hasMatches)
|
|
616
1024
|
return;
|
|
617
1025
|
if (!value.trim()) {
|
|
618
1026
|
setEmptyHint(true);
|
|
@@ -626,6 +1034,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
626
1034
|
onClear?.();
|
|
627
1035
|
setInput("");
|
|
628
1036
|
setCursorOffset(0);
|
|
1037
|
+
setCollapsedPaste(null);
|
|
629
1038
|
clearSelection();
|
|
630
1039
|
setHistory((prev) => [...prev, trimmed]);
|
|
631
1040
|
setHistoryIdx(-1);
|
|
@@ -633,16 +1042,102 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
633
1042
|
setTargetScrollOffset(0);
|
|
634
1043
|
return;
|
|
635
1044
|
}
|
|
636
|
-
onSubmit(
|
|
1045
|
+
onSubmit(value);
|
|
637
1046
|
setInput("");
|
|
638
1047
|
setCursorOffset(0);
|
|
1048
|
+
setCollapsedPaste(null);
|
|
639
1049
|
clearSelection();
|
|
640
|
-
setHistory((prev) => [...prev,
|
|
1050
|
+
setHistory((prev) => [...prev, value]);
|
|
641
1051
|
setHistoryIdx(-1);
|
|
642
1052
|
setScrollOffset(0);
|
|
643
1053
|
setTargetScrollOffset(0);
|
|
644
1054
|
}, [clearSelection, hasMatches, isProcessing, onClear, onSubmit]);
|
|
645
1055
|
useInput((inputChar, key) => {
|
|
1056
|
+
if (key.ctrl && (inputChar === "o" || inputChar === "O")) {
|
|
1057
|
+
setTranscriptMode((prev) => !prev);
|
|
1058
|
+
setTranscriptSearchMode(false);
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
if (transcriptMode) {
|
|
1062
|
+
if (transcriptSearchMode) {
|
|
1063
|
+
if (key.escape) {
|
|
1064
|
+
setTranscriptSearchMode(false);
|
|
1065
|
+
return;
|
|
1066
|
+
}
|
|
1067
|
+
if (key.return) {
|
|
1068
|
+
setTranscriptSearchMode(false);
|
|
1069
|
+
jumpToTranscriptMatch("next");
|
|
1070
|
+
return;
|
|
1071
|
+
}
|
|
1072
|
+
if (isBackspaceInput(inputChar, key)) {
|
|
1073
|
+
setTranscriptSearchQuery((prev) => prev.slice(0, -1));
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1076
|
+
if (inputChar && !key.ctrl && !key.meta) {
|
|
1077
|
+
setTranscriptSearchQuery((prev) => prev + inputChar);
|
|
1078
|
+
}
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
if (key.escape || inputChar === "q") {
|
|
1082
|
+
setTranscriptMode(false);
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
if (inputChar === "/") {
|
|
1086
|
+
setTranscriptSearchMode(true);
|
|
1087
|
+
setTranscriptSearchQuery("");
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
if (inputChar === "n") {
|
|
1091
|
+
jumpToTranscriptMatch("next");
|
|
1092
|
+
return;
|
|
1093
|
+
}
|
|
1094
|
+
if (inputChar === "N") {
|
|
1095
|
+
jumpToTranscriptMatch("previous");
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
if (inputChar === "[") {
|
|
1099
|
+
writeTranscriptToNativeScrollback(messages);
|
|
1100
|
+
setCopyToast("wrote transcript to terminal scrollback");
|
|
1101
|
+
setTimeout(() => setCopyToast(null), 2000);
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1104
|
+
if (inputChar === "v") {
|
|
1105
|
+
const result = openTranscriptInEditor(messages);
|
|
1106
|
+
setCopyToast(result.ok ? "opened transcript in editor" : "set VISUAL or EDITOR to open transcript");
|
|
1107
|
+
setTimeout(() => setCopyToast(null), 2000);
|
|
1108
|
+
return;
|
|
1109
|
+
}
|
|
1110
|
+
if (inputChar === "g" || key.home) {
|
|
1111
|
+
applyTranscriptScroll("up", "top");
|
|
1112
|
+
return;
|
|
1113
|
+
}
|
|
1114
|
+
if (inputChar === "G" || key.end) {
|
|
1115
|
+
applyTranscriptScroll("down", "bottom");
|
|
1116
|
+
return;
|
|
1117
|
+
}
|
|
1118
|
+
if (inputChar === "j" || key.downArrow) {
|
|
1119
|
+
applyTranscriptScroll("down", "line");
|
|
1120
|
+
return;
|
|
1121
|
+
}
|
|
1122
|
+
if (inputChar === "k" || key.upArrow) {
|
|
1123
|
+
applyTranscriptScroll("up", "line");
|
|
1124
|
+
return;
|
|
1125
|
+
}
|
|
1126
|
+
const transcriptScrollRequest = getScrollRequest(inputChar, key);
|
|
1127
|
+
if (transcriptScrollRequest) {
|
|
1128
|
+
applyTranscriptScroll(transcriptScrollRequest.direction, transcriptScrollRequest.kind);
|
|
1129
|
+
return;
|
|
1130
|
+
}
|
|
1131
|
+
if (inputChar === " " || (key.ctrl && inputChar === "f")) {
|
|
1132
|
+
applyTranscriptScroll("down", "page");
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
if (inputChar === "b" || (key.ctrl && inputChar === "b")) {
|
|
1136
|
+
applyTranscriptScroll("up", "page");
|
|
1137
|
+
return;
|
|
1138
|
+
}
|
|
1139
|
+
return;
|
|
1140
|
+
}
|
|
646
1141
|
logTuiDebug("fullscreen-chat", "input-event", {
|
|
647
1142
|
inputChar,
|
|
648
1143
|
key: summarizeKey(key),
|
|
@@ -657,12 +1152,16 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
657
1152
|
direction: scrollRequest.direction,
|
|
658
1153
|
kind: scrollRequest.kind,
|
|
659
1154
|
});
|
|
660
|
-
|
|
1155
|
+
if (!isProcessing) {
|
|
1156
|
+
applyScroll(scrollRequest.direction, scrollRequest.kind);
|
|
1157
|
+
}
|
|
661
1158
|
return;
|
|
662
1159
|
}
|
|
663
1160
|
const mouseEvent = parseMouseEvent(inputChar);
|
|
664
1161
|
if (mouseEvent && mouseEvent.kind !== "wheel" && mouseEvent.button === "left") {
|
|
665
|
-
const
|
|
1162
|
+
const localMouseX = mouseEvent.x - cursorOriginX;
|
|
1163
|
+
const localMouseY = mouseEvent.y - cursorOriginY;
|
|
1164
|
+
const offset = getMouseOffsetFromComposer(composerLayout, localMouseX, localMouseY, mouseEvent.kind !== "press" && selectionAnchor.current !== null);
|
|
666
1165
|
if (mouseEvent.kind === "release" && offset === null) {
|
|
667
1166
|
selectionAnchor.current = null;
|
|
668
1167
|
return;
|
|
@@ -681,12 +1180,51 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
681
1180
|
const nextSelection = { anchor: selectionAnchor.current, focus: offset };
|
|
682
1181
|
selectionAnchor.current = null;
|
|
683
1182
|
setSelection(nextSelection.anchor === nextSelection.focus ? null : nextSelection);
|
|
1183
|
+
copySelectedInput(nextSelection);
|
|
684
1184
|
}
|
|
685
1185
|
return;
|
|
686
1186
|
}
|
|
1187
|
+
const bodyPosition = getMousePositionFromBody(viewport.rows, localMouseX, localMouseY, viewportFillerRows);
|
|
1188
|
+
if (bodyPosition !== null) {
|
|
1189
|
+
clearSelection();
|
|
1190
|
+
if (mouseEvent.kind === "press") {
|
|
1191
|
+
bodySelectionAnchor.current = bodyPosition;
|
|
1192
|
+
setBodySelection({ anchor: bodyPosition, focus: bodyPosition });
|
|
1193
|
+
return;
|
|
1194
|
+
}
|
|
1195
|
+
if (mouseEvent.kind === "drag" && bodySelectionAnchor.current !== null) {
|
|
1196
|
+
setBodySelection({ anchor: bodySelectionAnchor.current, focus: bodyPosition });
|
|
1197
|
+
return;
|
|
1198
|
+
}
|
|
1199
|
+
if (mouseEvent.kind === "release" && bodySelectionAnchor.current !== null) {
|
|
1200
|
+
const nextSelection = { anchor: bodySelectionAnchor.current, focus: bodyPosition };
|
|
1201
|
+
bodySelectionAnchor.current = null;
|
|
1202
|
+
setBodySelection(nextSelection);
|
|
1203
|
+
const selectedText = getSelectedBodyText(viewport.rows, nextSelection);
|
|
1204
|
+
if (selectedText) {
|
|
1205
|
+
void copyToClipboard(selectedText).then((result) => {
|
|
1206
|
+
if (!result.ok)
|
|
1207
|
+
return;
|
|
1208
|
+
setCopyToast(formatCopyToast(selectedText.length, result));
|
|
1209
|
+
setTimeout(() => setCopyToast(null), 2000);
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
else {
|
|
1213
|
+
const row = viewport.rows[bodyPosition.rowIndex];
|
|
1214
|
+
const target = row ? extractClickableTargetAt(row.text, bodyPosition.offset) : null;
|
|
1215
|
+
if (target) {
|
|
1216
|
+
const opened = openClickableTarget(target);
|
|
1217
|
+
setCopyToast(opened ? `opened ${target}` : `could not open ${target}`);
|
|
1218
|
+
setTimeout(() => setCopyToast(null), 2000);
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
return;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
687
1224
|
}
|
|
688
1225
|
if (key.return && key.shift) {
|
|
689
1226
|
logTuiDebug("fullscreen-chat", "insert-newline", { cursorOffset });
|
|
1227
|
+
clearBodySelection();
|
|
690
1228
|
insertText("\n");
|
|
691
1229
|
return;
|
|
692
1230
|
}
|
|
@@ -707,6 +1245,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
707
1245
|
: selected.name;
|
|
708
1246
|
setInput(value);
|
|
709
1247
|
setCursorOffset(value.length);
|
|
1248
|
+
setCollapsedPaste(null);
|
|
710
1249
|
clearSelection();
|
|
711
1250
|
setSelectedIdx(0);
|
|
712
1251
|
justSelected.current = true;
|
|
@@ -717,7 +1256,9 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
717
1256
|
setSelectedIdx(0);
|
|
718
1257
|
setInput("");
|
|
719
1258
|
setCursorOffset(0);
|
|
1259
|
+
setCollapsedPaste(null);
|
|
720
1260
|
clearSelection();
|
|
1261
|
+
clearBodySelection();
|
|
721
1262
|
return;
|
|
722
1263
|
}
|
|
723
1264
|
}
|
|
@@ -770,6 +1311,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
770
1311
|
const next = input.slice(0, previousOffset) + input.slice(cursorOffset);
|
|
771
1312
|
setInput(next);
|
|
772
1313
|
setCursorOffset(previousOffset);
|
|
1314
|
+
setCollapsedPaste(null);
|
|
773
1315
|
logTuiDebug("fullscreen-chat", "backspace-applied", {
|
|
774
1316
|
previousOffset,
|
|
775
1317
|
next,
|
|
@@ -796,6 +1338,7 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
796
1338
|
const nextOffset = getNextOffset(input, cursorOffset);
|
|
797
1339
|
const next = input.slice(0, cursorOffset) + input.slice(nextOffset);
|
|
798
1340
|
setInput(next);
|
|
1341
|
+
setCollapsedPaste(null);
|
|
799
1342
|
logTuiDebug("fullscreen-chat", "delete-applied", {
|
|
800
1343
|
nextOffset,
|
|
801
1344
|
next,
|
|
@@ -815,12 +1358,14 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
815
1358
|
setHistoryIdx(idx);
|
|
816
1359
|
setInput(history[idx]);
|
|
817
1360
|
setCursorOffset(history[idx].length);
|
|
1361
|
+
setCollapsedPaste(null);
|
|
818
1362
|
}
|
|
819
1363
|
else if (historyIdx > 0) {
|
|
820
1364
|
const idx = historyIdx - 1;
|
|
821
1365
|
setHistoryIdx(idx);
|
|
822
1366
|
setInput(history[idx]);
|
|
823
1367
|
setCursorOffset(history[idx].length);
|
|
1368
|
+
setCollapsedPaste(null);
|
|
824
1369
|
}
|
|
825
1370
|
}
|
|
826
1371
|
return;
|
|
@@ -832,11 +1377,13 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
832
1377
|
setHistoryIdx(idx);
|
|
833
1378
|
setInput(history[idx]);
|
|
834
1379
|
setCursorOffset(history[idx].length);
|
|
1380
|
+
setCollapsedPaste(null);
|
|
835
1381
|
}
|
|
836
1382
|
else {
|
|
837
1383
|
setHistoryIdx(-1);
|
|
838
1384
|
setInput(draft);
|
|
839
1385
|
setCursorOffset(draft.length);
|
|
1386
|
+
setCollapsedPaste(null);
|
|
840
1387
|
}
|
|
841
1388
|
return;
|
|
842
1389
|
}
|
|
@@ -844,9 +1391,12 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
844
1391
|
const clean = normalizeTerminalInputChunk(inputChar);
|
|
845
1392
|
if (clean.length === 0)
|
|
846
1393
|
return;
|
|
847
|
-
|
|
1394
|
+
clearBodySelection();
|
|
1395
|
+
insertText(clean, {
|
|
1396
|
+
collapsePaste: shouldCollapsePastedText(inputChar, clean),
|
|
1397
|
+
});
|
|
848
1398
|
}
|
|
849
|
-
}, { isActive:
|
|
1399
|
+
}, { isActive: true });
|
|
850
1400
|
React.useEffect(() => {
|
|
851
1401
|
setSelectedIdx(0);
|
|
852
1402
|
}, [matches.map((match) => match.name).join(",")]);
|
|
@@ -857,15 +1407,19 @@ export function FullscreenChat({ messages, onSubmit, onClear, isProcessing, goal
|
|
|
857
1407
|
};
|
|
858
1408
|
}, []);
|
|
859
1409
|
const spinnerGlyph = PROCESSING_SPINNER_FRAMES[spinnerFrameIndex] ?? PROCESSING_SPINNER_FRAMES[0];
|
|
860
|
-
const visibleLines =
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
1410
|
+
const visibleLines = transcriptMode
|
|
1411
|
+
? transcript.lines
|
|
1412
|
+
: buildFullscreenChatRenderLines({
|
|
1413
|
+
availableCols,
|
|
1414
|
+
availableRows,
|
|
1415
|
+
viewport,
|
|
1416
|
+
composerLines: composer.lines,
|
|
1417
|
+
isProcessing,
|
|
1418
|
+
spinnerGlyph,
|
|
1419
|
+
spinnerVerb,
|
|
1420
|
+
bodySelection: bodySelectionRange,
|
|
1421
|
+
transcriptStatus: copyToast,
|
|
1422
|
+
});
|
|
869
1423
|
return (_jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: visibleLines.map((line) => (_jsx(Box, { height: 1, overflow: "hidden", children: line.segments ? (line.segments.map((segment, index) => (_jsx(Text, { color: segment.color ?? line.color, backgroundColor: segment.backgroundColor ?? line.backgroundColor, bold: segment.bold ?? line.bold, dimColor: segment.dim ?? line.dim, children: index === 0 && line.protected
|
|
870
1424
|
? `${PROTECTED_ROW_MARKER}${segment.text}`
|
|
871
1425
|
: segment.text }, `${line.key}-${index}`)))) : (_jsx(Text, { color: line.color, backgroundColor: line.backgroundColor, bold: line.bold, dimColor: line.dim, children: line.protected
|