indusagi 0.12.18 → 0.12.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -37
- package/dist/agent/agent-loop.d.ts +3 -9
- package/dist/agent/agent-loop.d.ts.map +1 -1
- package/dist/agent/agent-loop.js +19 -58
- package/dist/agent/agent-loop.js.map +1 -1
- package/dist/agent/agent.d.ts +9 -10
- package/dist/agent/agent.d.ts.map +1 -1
- package/dist/agent/agent.js +182 -129
- package/dist/agent/agent.js.map +1 -1
- package/dist/agent/error-handler.d.ts.map +1 -1
- package/dist/agent/error-handler.js.map +1 -1
- package/dist/agent/event-bus.d.ts.map +1 -1
- package/dist/agent/event-bus.js +1 -3
- package/dist/agent/event-bus.js.map +1 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +0 -6
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/messages.d.ts +1 -1
- package/dist/agent/messages.d.ts.map +1 -1
- package/dist/agent/proxy.d.ts +1 -14
- package/dist/agent/proxy.d.ts.map +1 -1
- package/dist/agent/proxy.js +67 -148
- package/dist/agent/proxy.js.map +1 -1
- package/dist/agent/session-manager.d.ts +10 -10
- package/dist/agent/session-manager.d.ts.map +1 -1
- package/dist/agent/session-manager.js +20 -16
- package/dist/agent/session-manager.js.map +1 -1
- package/dist/agent/state-manager.d.ts +1 -1
- package/dist/agent/state-manager.d.ts.map +1 -1
- package/dist/agent/state-manager.js +1 -0
- package/dist/agent/state-manager.js.map +1 -1
- package/dist/agent/telemetry.d.ts.map +1 -1
- package/dist/agent/telemetry.js +1 -3
- package/dist/agent/telemetry.js.map +1 -1
- package/dist/agent/tools/bash.d.ts.map +1 -1
- package/dist/agent/tools/bash.js +143 -118
- package/dist/agent/tools/bash.js.map +1 -1
- package/dist/agent/tools/edit-diff.d.ts +1 -1
- package/dist/agent/tools/edit-diff.d.ts.map +1 -1
- package/dist/agent/tools/edit-diff.js +189 -175
- package/dist/agent/tools/edit-diff.js.map +1 -1
- package/dist/agent/tools/edit.d.ts.map +1 -1
- package/dist/agent/tools/edit.js +137 -121
- package/dist/agent/tools/edit.js.map +1 -1
- package/dist/agent/tools/find.d.ts.map +1 -1
- package/dist/agent/tools/find.js +100 -65
- package/dist/agent/tools/find.js.map +1 -1
- package/dist/agent/tools/grep.d.ts.map +1 -1
- package/dist/agent/tools/grep.js +126 -97
- package/dist/agent/tools/grep.js.map +1 -1
- package/dist/agent/tools/index.d.ts +53 -40
- package/dist/agent/tools/index.d.ts.map +1 -1
- package/dist/agent/tools/index.js +19 -12
- package/dist/agent/tools/index.js.map +1 -1
- package/dist/agent/tools/ls.d.ts +2 -1
- package/dist/agent/tools/ls.d.ts.map +1 -1
- package/dist/agent/tools/ls.js +145 -94
- package/dist/agent/tools/ls.js.map +1 -1
- package/dist/agent/tools/path-utils.d.ts.map +1 -1
- package/dist/agent/tools/path-utils.js +48 -29
- package/dist/agent/tools/path-utils.js.map +1 -1
- package/dist/agent/tools/process-controller.d.ts +15 -0
- package/dist/agent/tools/process-controller.d.ts.map +1 -0
- package/dist/agent/tools/process-controller.js +39 -0
- package/dist/agent/tools/process-controller.js.map +1 -0
- package/dist/agent/tools/process-manager.d.ts +60 -0
- package/dist/agent/tools/process-manager.d.ts.map +1 -0
- package/dist/agent/tools/process-manager.js +485 -0
- package/dist/agent/tools/process-manager.js.map +1 -0
- package/dist/agent/tools/process-types.d.ts +74 -0
- package/dist/agent/tools/process-types.d.ts.map +1 -0
- package/dist/agent/tools/process-types.js +7 -0
- package/dist/agent/tools/process-types.js.map +1 -0
- package/dist/agent/tools/process.d.ts +38 -0
- package/dist/agent/tools/process.d.ts.map +1 -0
- package/dist/agent/tools/process.js +360 -0
- package/dist/agent/tools/process.js.map +1 -0
- package/dist/agent/tools/read.d.ts.map +1 -1
- package/dist/agent/tools/read.js +157 -135
- package/dist/agent/tools/read.js.map +1 -1
- package/dist/agent/tools/registry.js +2 -4
- package/dist/agent/tools/registry.js.map +1 -1
- package/dist/agent/tools/teams/activity-tracker.d.ts +66 -0
- package/dist/agent/tools/teams/activity-tracker.d.ts.map +1 -0
- package/dist/agent/tools/teams/activity-tracker.js +480 -0
- package/dist/agent/tools/teams/activity-tracker.js.map +1 -0
- package/dist/agent/tools/teams/cleanup.d.ts +51 -0
- package/dist/agent/tools/teams/cleanup.d.ts.map +1 -0
- package/dist/agent/tools/teams/cleanup.js +219 -0
- package/dist/agent/tools/teams/cleanup.js.map +1 -0
- package/dist/agent/tools/teams/fs-lock.d.ts +12 -0
- package/dist/agent/tools/teams/fs-lock.d.ts.map +1 -0
- package/dist/agent/tools/teams/fs-lock.js +74 -0
- package/dist/agent/tools/teams/fs-lock.js.map +1 -0
- package/dist/agent/tools/teams/index.d.ts +12 -0
- package/dist/agent/tools/teams/index.d.ts.map +1 -0
- package/dist/agent/tools/teams/index.js +12 -0
- package/dist/agent/tools/teams/index.js.map +1 -0
- package/dist/agent/tools/teams/mailbox.d.ts +21 -0
- package/dist/agent/tools/teams/mailbox.d.ts.map +1 -0
- package/dist/agent/tools/teams/mailbox.js +106 -0
- package/dist/agent/tools/teams/mailbox.js.map +1 -0
- package/dist/agent/tools/teams/model-policy.d.ts +23 -0
- package/dist/agent/tools/teams/model-policy.d.ts.map +1 -0
- package/dist/agent/tools/teams/model-policy.js +113 -0
- package/dist/agent/tools/teams/model-policy.js.map +1 -0
- package/dist/agent/tools/teams/names.d.ts +28 -0
- package/dist/agent/tools/teams/names.d.ts.map +1 -0
- package/dist/agent/tools/teams/names.js +109 -0
- package/dist/agent/tools/teams/names.js.map +1 -0
- package/dist/agent/tools/teams/protocol.d.ts +75 -0
- package/dist/agent/tools/teams/protocol.d.ts.map +1 -0
- package/dist/agent/tools/teams/protocol.js +205 -0
- package/dist/agent/tools/teams/protocol.js.map +1 -0
- package/dist/agent/tools/teams/task-store.d.ts +89 -0
- package/dist/agent/tools/teams/task-store.d.ts.map +1 -0
- package/dist/agent/tools/teams/task-store.js +445 -0
- package/dist/agent/tools/teams/task-store.js.map +1 -0
- package/dist/agent/tools/teams/team-attach-claim.d.ts +36 -0
- package/dist/agent/tools/teams/team-attach-claim.d.ts.map +1 -0
- package/dist/agent/tools/teams/team-attach-claim.js +144 -0
- package/dist/agent/tools/teams/team-attach-claim.js.map +1 -0
- package/dist/agent/tools/teams/team-config.d.ts +55 -0
- package/dist/agent/tools/teams/team-config.d.ts.map +1 -0
- package/dist/agent/tools/teams/team-config.js +252 -0
- package/dist/agent/tools/teams/team-config.js.map +1 -0
- package/dist/agent/tools/teams/worktree.d.ts +40 -0
- package/dist/agent/tools/teams/worktree.d.ts.map +1 -0
- package/dist/agent/tools/teams/worktree.js +213 -0
- package/dist/agent/tools/teams/worktree.js.map +1 -0
- package/dist/agent/tools/todo-store.js +2 -1
- package/dist/agent/tools/todo-store.js.map +1 -1
- package/dist/agent/tools/todo.d.ts +2 -2
- package/dist/agent/tools/todo.js +2 -2
- package/dist/agent/tools/truncate.d.ts.map +1 -1
- package/dist/agent/tools/truncate.js +150 -134
- package/dist/agent/tools/truncate.js.map +1 -1
- package/dist/agent/tools/utils/hook-runner.d.ts +9 -10
- package/dist/agent/tools/utils/hook-runner.d.ts.map +1 -1
- package/dist/agent/tools/utils/hook-runner.js +18 -16
- package/dist/agent/tools/utils/hook-runner.js.map +1 -1
- package/dist/agent/tools/utils/image-resize.d.ts +1 -14
- package/dist/agent/tools/utils/image-resize.d.ts.map +1 -1
- package/dist/agent/tools/utils/image-resize.js +80 -34
- package/dist/agent/tools/utils/image-resize.js.map +1 -1
- package/dist/agent/tools/utils/mime.d.ts +0 -8
- package/dist/agent/tools/utils/mime.d.ts.map +1 -1
- package/dist/agent/tools/utils/mime.js +43 -32
- package/dist/agent/tools/utils/mime.js.map +1 -1
- package/dist/agent/tools/utils/shell.d.ts +1 -23
- package/dist/agent/tools/utils/shell.d.ts.map +1 -1
- package/dist/agent/tools/utils/shell.js +43 -86
- package/dist/agent/tools/utils/shell.js.map +1 -1
- package/dist/agent/tools/write.d.ts.map +1 -1
- package/dist/agent/tools/write.js +105 -62
- package/dist/agent/tools/write.js.map +1 -1
- package/dist/agent/types.d.ts +69 -64
- package/dist/agent/types.d.ts.map +1 -1
- package/dist/agent/types.js +38 -23
- package/dist/agent/types.js.map +1 -1
- package/dist/agent.d.ts +4 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +4 -0
- package/dist/agent.js.map +1 -1
- package/dist/ai/api-registry.d.ts.map +1 -1
- package/dist/ai/api-registry.js +3 -4
- package/dist/ai/api-registry.js.map +1 -1
- package/dist/ai/cli.js +62 -82
- package/dist/ai/cli.js.map +1 -1
- package/dist/ai/env-api-keys.d.ts.map +1 -1
- package/dist/ai/env-api-keys.js +78 -81
- package/dist/ai/env-api-keys.js.map +1 -1
- package/dist/ai/index.d.ts +6 -0
- package/dist/ai/index.d.ts.map +1 -1
- package/dist/ai/index.js +6 -0
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/models.d.ts +7 -17
- package/dist/ai/models.d.ts.map +1 -1
- package/dist/ai/models.generated.d.ts +87 -244
- package/dist/ai/models.generated.d.ts.map +1 -1
- package/dist/ai/models.generated.js +82 -241
- package/dist/ai/models.generated.js.map +1 -1
- package/dist/ai/models.js +17 -11
- package/dist/ai/models.js.map +1 -1
- package/dist/ai/providers/amazon-bedrock.d.ts.map +1 -1
- package/dist/ai/providers/amazon-bedrock.js +319 -248
- package/dist/ai/providers/amazon-bedrock.js.map +1 -1
- package/dist/ai/providers/anthropic.d.ts.map +1 -1
- package/dist/ai/providers/anthropic.js +378 -324
- package/dist/ai/providers/anthropic.js.map +1 -1
- package/dist/ai/providers/azure-openai-responses.d.ts.map +1 -1
- package/dist/ai/providers/azure-openai-responses.js +164 -123
- package/dist/ai/providers/azure-openai-responses.js.map +1 -1
- package/dist/ai/providers/google-shared.d.ts +0 -18
- package/dist/ai/providers/google-shared.d.ts.map +1 -1
- package/dist/ai/providers/google-shared.js +224 -225
- package/dist/ai/providers/google-shared.js.map +1 -1
- package/dist/ai/providers/google-vertex.d.ts.map +1 -1
- package/dist/ai/providers/google-vertex.js +244 -226
- package/dist/ai/providers/google-vertex.js.map +1 -1
- package/dist/ai/providers/google.d.ts +3 -0
- package/dist/ai/providers/google.d.ts.map +1 -1
- package/dist/ai/providers/google.js +232 -210
- package/dist/ai/providers/google.js.map +1 -1
- package/dist/ai/providers/kimi.js +1 -0
- package/dist/ai/providers/kimi.js.map +1 -1
- package/dist/ai/providers/mock.d.ts +10 -0
- package/dist/ai/providers/mock.d.ts.map +1 -0
- package/dist/ai/providers/mock.js +64 -0
- package/dist/ai/providers/mock.js.map +1 -0
- package/dist/ai/providers/openai-codex-responses.d.ts.map +1 -1
- package/dist/ai/providers/openai-codex-responses.js +178 -133
- package/dist/ai/providers/openai-codex-responses.js.map +1 -1
- package/dist/ai/providers/openai-completions.d.ts.map +1 -1
- package/dist/ai/providers/openai-completions.js +468 -387
- package/dist/ai/providers/openai-completions.js.map +1 -1
- package/dist/ai/providers/openai-responses-shared.d.ts.map +1 -1
- package/dist/ai/providers/openai-responses-shared.js +187 -166
- package/dist/ai/providers/openai-responses-shared.js.map +1 -1
- package/dist/ai/providers/openai-responses.d.ts.map +1 -1
- package/dist/ai/providers/openai-responses.js +108 -85
- package/dist/ai/providers/openai-responses.js.map +1 -1
- package/dist/ai/providers/openai-scaffold.d.ts +4 -0
- package/dist/ai/providers/openai-scaffold.d.ts.map +1 -0
- package/dist/ai/providers/openai-scaffold.js +33 -0
- package/dist/ai/providers/openai-scaffold.js.map +1 -0
- package/dist/ai/providers/register-builtins.d.ts.map +1 -1
- package/dist/ai/providers/register-builtins.js +109 -42
- package/dist/ai/providers/register-builtins.js.map +1 -1
- package/dist/ai/providers/simple-options.js +2 -0
- package/dist/ai/providers/simple-options.js.map +1 -1
- package/dist/ai/providers/transform-messages.js +3 -9
- package/dist/ai/providers/transform-messages.js.map +1 -1
- package/dist/ai/stream.d.ts +4 -14
- package/dist/ai/stream.d.ts.map +1 -1
- package/dist/ai/stream.js +0 -36
- package/dist/ai/stream.js.map +1 -1
- package/dist/ai/types.d.ts +22 -3
- package/dist/ai/types.d.ts.map +1 -1
- package/dist/ai/types.js +154 -77
- package/dist/ai/types.js.map +1 -1
- package/dist/ai/utils/base-stream-handler.js +1 -0
- package/dist/ai/utils/base-stream-handler.js.map +1 -1
- package/dist/ai/utils/event-stream.d.ts +2 -0
- package/dist/ai/utils/event-stream.d.ts.map +1 -1
- package/dist/ai/utils/event-stream.js +22 -5
- package/dist/ai/utils/event-stream.js.map +1 -1
- package/dist/ai/utils/json-parse.d.ts +3 -0
- package/dist/ai/utils/json-parse.d.ts.map +1 -1
- package/dist/ai/utils/json-parse.js +8 -5
- package/dist/ai/utils/json-parse.js.map +1 -1
- package/dist/ai/utils/oauth/anthropic.d.ts.map +1 -1
- package/dist/ai/utils/oauth/anthropic.js +110 -65
- package/dist/ai/utils/oauth/anthropic.js.map +1 -1
- package/dist/ai/utils/oauth/github-copilot.d.ts +8 -16
- package/dist/ai/utils/oauth/github-copilot.d.ts.map +1 -1
- package/dist/ai/utils/oauth/github-copilot.js +218 -227
- package/dist/ai/utils/oauth/github-copilot.js.map +1 -1
- package/dist/ai/utils/oauth/openai-codex.d.ts +4 -2
- package/dist/ai/utils/oauth/openai-codex.d.ts.map +1 -1
- package/dist/ai/utils/oauth/openai-codex.js +221 -236
- package/dist/ai/utils/oauth/openai-codex.js.map +1 -1
- package/dist/ai/utils/oauth/pkce.d.ts +6 -5
- package/dist/ai/utils/oauth/pkce.d.ts.map +1 -1
- package/dist/ai/utils/oauth/pkce.js +24 -21
- package/dist/ai/utils/oauth/pkce.js.map +1 -1
- package/dist/ai/utils/oauth/types.d.ts +31 -12
- package/dist/ai/utils/oauth/types.d.ts.map +1 -1
- package/dist/ai/utils/oauth/types.js +10 -1
- package/dist/ai/utils/oauth/types.js.map +1 -1
- package/dist/ai/utils/overflow.d.ts.map +1 -1
- package/dist/ai/utils/overflow.js +49 -21
- package/dist/ai/utils/overflow.js.map +1 -1
- package/dist/ai/utils/provider-adapter.js +9 -0
- package/dist/ai/utils/provider-adapter.js.map +1 -1
- package/dist/ai/utils/provider-client-builder.js +1 -1
- package/dist/ai/utils/provider-client-builder.js.map +1 -1
- package/dist/ai/utils/provider-errors.js +2 -0
- package/dist/ai/utils/provider-errors.js.map +1 -1
- package/dist/ai/utils/sanitize-unicode.d.ts +0 -20
- package/dist/ai/utils/sanitize-unicode.d.ts.map +1 -1
- package/dist/ai/utils/sanitize-unicode.js +35 -17
- package/dist/ai/utils/sanitize-unicode.js.map +1 -1
- package/dist/ai/utils/stream-event-helper.js +3 -0
- package/dist/ai/utils/stream-event-helper.js.map +1 -1
- package/dist/ai/utils/stream-handler-types.js +5 -0
- package/dist/ai/utils/stream-handler-types.js.map +1 -1
- package/dist/ai/utils/streaming-state-manager.js +4 -2
- package/dist/ai/utils/streaming-state-manager.js.map +1 -1
- package/dist/ai/utils/typebox-helpers.d.ts +6 -4
- package/dist/ai/utils/typebox-helpers.d.ts.map +1 -1
- package/dist/ai/utils/typebox-helpers.js +25 -7
- package/dist/ai/utils/typebox-helpers.js.map +1 -1
- package/dist/ai/utils/validation.d.ts.map +1 -1
- package/dist/ai/utils/validation.js +67 -34
- package/dist/ai/utils/validation.js.map +1 -1
- package/dist/ai.d.ts +4 -0
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +4 -0
- package/dist/ai.js.map +1 -1
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/client-pool.js +3 -2
- package/dist/mcp/client-pool.js.map +1 -1
- package/dist/mcp/client.js +19 -6
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/config.d.ts +6 -6
- package/dist/mcp/config.js +17 -17
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/errors.js +8 -0
- package/dist/mcp/errors.js.map +1 -1
- package/dist/mcp/index.d.ts +5 -5
- package/dist/mcp/index.js +5 -5
- package/dist/mcp/schema-converter.d.ts +1 -1
- package/dist/mcp/schema-converter.js +1 -1
- package/dist/mcp/server.d.ts +4 -4
- package/dist/mcp/server.js +12 -7
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-factory.d.ts +2 -2
- package/dist/mcp/tool-factory.js +2 -2
- package/dist/mcp.d.ts +0 -4
- package/dist/mcp.d.ts.map +1 -1
- package/dist/mcp.js +0 -4
- package/dist/mcp.js.map +1 -1
- package/dist/observability.d.ts +2 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +2 -0
- package/dist/observability.js.map +1 -0
- package/dist/tui/autocomplete.d.ts +14 -18
- package/dist/tui/autocomplete.d.ts.map +1 -1
- package/dist/tui/autocomplete.js +290 -402
- package/dist/tui/autocomplete.js.map +1 -1
- package/dist/tui/components/box.d.ts +1 -6
- package/dist/tui/components/box.d.ts.map +1 -1
- package/dist/tui/components/box.js +98 -67
- package/dist/tui/components/box.js.map +1 -1
- package/dist/tui/components/cancellable-loader.d.ts +6 -3
- package/dist/tui/components/cancellable-loader.d.ts.map +1 -1
- package/dist/tui/components/cancellable-loader.js +8 -9
- package/dist/tui/components/cancellable-loader.js.map +1 -1
- package/dist/tui/components/editor.d.ts +18 -0
- package/dist/tui/components/editor.d.ts.map +1 -1
- package/dist/tui/components/editor.js +356 -354
- package/dist/tui/components/editor.js.map +1 -1
- package/dist/tui/components/image.d.ts +2 -0
- package/dist/tui/components/image.d.ts.map +1 -1
- package/dist/tui/components/image.js +79 -37
- package/dist/tui/components/image.js.map +1 -1
- package/dist/tui/components/input.d.ts +4 -8
- package/dist/tui/components/input.d.ts.map +1 -1
- package/dist/tui/components/input.js +236 -232
- package/dist/tui/components/input.js.map +1 -1
- package/dist/tui/components/loader.d.ts +5 -5
- package/dist/tui/components/loader.d.ts.map +1 -1
- package/dist/tui/components/loader.js +22 -19
- package/dist/tui/components/loader.js.map +1 -1
- package/dist/tui/components/markdown.d.ts +2 -32
- package/dist/tui/components/markdown.d.ts.map +1 -1
- package/dist/tui/components/markdown.js +338 -357
- package/dist/tui/components/markdown.js.map +1 -1
- package/dist/tui/components/select-list.d.ts +1 -0
- package/dist/tui/components/select-list.d.ts.map +1 -1
- package/dist/tui/components/select-list.js +83 -82
- package/dist/tui/components/select-list.js.map +1 -1
- package/dist/tui/components/settings-list.d.ts +10 -10
- package/dist/tui/components/settings-list.d.ts.map +1 -1
- package/dist/tui/components/settings-list.js +48 -40
- package/dist/tui/components/settings-list.js.map +1 -1
- package/dist/tui/components/spacer.d.ts +1 -0
- package/dist/tui/components/spacer.d.ts.map +1 -1
- package/dist/tui/components/spacer.js +20 -5
- package/dist/tui/components/spacer.js.map +1 -1
- package/dist/tui/components/text.d.ts.map +1 -1
- package/dist/tui/components/text.js +47 -20
- package/dist/tui/components/text.js.map +1 -1
- package/dist/tui/components/truncated-text.d.ts +8 -4
- package/dist/tui/components/truncated-text.d.ts.map +1 -1
- package/dist/tui/components/truncated-text.js +15 -12
- package/dist/tui/components/truncated-text.js.map +1 -1
- package/dist/tui/editor-component.d.ts +87 -23
- package/dist/tui/editor-component.d.ts.map +1 -1
- package/dist/tui/fuzzy.d.ts.map +1 -1
- package/dist/tui/fuzzy.js +101 -50
- package/dist/tui/fuzzy.js.map +1 -1
- package/dist/tui/keybindings.d.ts +3 -3
- package/dist/tui/keybindings.d.ts.map +1 -1
- package/dist/tui/keybindings.js +137 -111
- package/dist/tui/keybindings.js.map +1 -1
- package/dist/tui/keys.d.ts +46 -43
- package/dist/tui/keys.d.ts.map +1 -1
- package/dist/tui/keys.js +493 -411
- package/dist/tui/keys.js.map +1 -1
- package/dist/tui/stdin-buffer.d.ts.map +1 -1
- package/dist/tui/stdin-buffer.js +162 -159
- package/dist/tui/stdin-buffer.js.map +1 -1
- package/dist/tui/terminal-image.d.ts +10 -5
- package/dist/tui/terminal-image.d.ts.map +1 -1
- package/dist/tui/terminal-image.js +53 -51
- package/dist/tui/terminal-image.js.map +1 -1
- package/dist/tui/terminal.d.ts +4 -27
- package/dist/tui/terminal.d.ts.map +1 -1
- package/dist/tui/terminal.js +123 -121
- package/dist/tui/terminal.js.map +1 -1
- package/dist/tui/tui.d.ts +14 -1
- package/dist/tui/tui.d.ts.map +1 -1
- package/dist/tui/tui.js +185 -145
- package/dist/tui/tui.js.map +1 -1
- package/dist/tui/utils.d.ts.map +1 -1
- package/dist/tui/utils.js +235 -216
- package/dist/tui/utils.js.map +1 -1
- package/dist/tui.d.ts +4 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +4 -0
- package/dist/tui.js.map +1 -1
- package/package.json +23 -43
- package/LICENSE.md +0 -22
- package/dist/agent/tools/task-types.d.ts +0 -74
- package/dist/agent/tools/task-types.d.ts.map +0 -1
- package/dist/agent/tools/task-types.js +0 -8
- package/dist/agent/tools/task-types.js.map +0 -1
- package/dist/agent/tools/task.d.ts +0 -84
- package/dist/agent/tools/task.d.ts.map +0 -1
- package/dist/agent/tools/task.js +0 -184
- package/dist/agent/tools/task.js.map +0 -1
- package/dist/memory/embedder/base.d.ts +0 -41
- package/dist/memory/embedder/base.d.ts.map +0 -1
- package/dist/memory/embedder/base.js +0 -10
- package/dist/memory/embedder/base.js.map +0 -1
- package/dist/memory/embedder/index.d.ts +0 -8
- package/dist/memory/embedder/index.d.ts.map +0 -1
- package/dist/memory/embedder/index.js +0 -6
- package/dist/memory/embedder/index.js.map +0 -1
- package/dist/memory/embedder/openai.d.ts +0 -35
- package/dist/memory/embedder/openai.d.ts.map +0 -1
- package/dist/memory/embedder/openai.js +0 -103
- package/dist/memory/embedder/openai.js.map +0 -1
- package/dist/memory/index.d.ts +0 -33
- package/dist/memory/index.d.ts.map +0 -1
- package/dist/memory/index.js +0 -31
- package/dist/memory/index.js.map +0 -1
- package/dist/memory/memory.d.ts +0 -126
- package/dist/memory/memory.d.ts.map +0 -1
- package/dist/memory/memory.js +0 -280
- package/dist/memory/memory.js.map +0 -1
- package/dist/memory/processors/base.d.ts +0 -42
- package/dist/memory/processors/base.d.ts.map +0 -1
- package/dist/memory/processors/base.js +0 -6
- package/dist/memory/processors/base.js.map +0 -1
- package/dist/memory/processors/index.d.ts +0 -16
- package/dist/memory/processors/index.d.ts.map +0 -1
- package/dist/memory/processors/index.js +0 -18
- package/dist/memory/processors/index.js.map +0 -1
- package/dist/memory/processors/message-history.d.ts +0 -35
- package/dist/memory/processors/message-history.d.ts.map +0 -1
- package/dist/memory/processors/message-history.js +0 -51
- package/dist/memory/processors/message-history.js.map +0 -1
- package/dist/memory/processors/observational-memory/index.d.ts +0 -82
- package/dist/memory/processors/observational-memory/index.d.ts.map +0 -1
- package/dist/memory/processors/observational-memory/index.js +0 -234
- package/dist/memory/processors/observational-memory/index.js.map +0 -1
- package/dist/memory/processors/observational-memory/observer-agent.d.ts +0 -64
- package/dist/memory/processors/observational-memory/observer-agent.d.ts.map +0 -1
- package/dist/memory/processors/observational-memory/observer-agent.js +0 -362
- package/dist/memory/processors/observational-memory/observer-agent.js.map +0 -1
- package/dist/memory/processors/observational-memory/reflector-agent.d.ts +0 -38
- package/dist/memory/processors/observational-memory/reflector-agent.d.ts.map +0 -1
- package/dist/memory/processors/observational-memory/reflector-agent.js +0 -213
- package/dist/memory/processors/observational-memory/reflector-agent.js.map +0 -1
- package/dist/memory/processors/observational-memory/token-counter.d.ts +0 -35
- package/dist/memory/processors/observational-memory/token-counter.d.ts.map +0 -1
- package/dist/memory/processors/observational-memory/token-counter.js +0 -90
- package/dist/memory/processors/observational-memory/token-counter.js.map +0 -1
- package/dist/memory/processors/semantic-recall.d.ts +0 -55
- package/dist/memory/processors/semantic-recall.d.ts.map +0 -1
- package/dist/memory/processors/semantic-recall.js +0 -143
- package/dist/memory/processors/semantic-recall.js.map +0 -1
- package/dist/memory/processors/working-memory.d.ts +0 -41
- package/dist/memory/processors/working-memory.d.ts.map +0 -1
- package/dist/memory/processors/working-memory.js +0 -82
- package/dist/memory/processors/working-memory.js.map +0 -1
- package/dist/memory/storage/base.d.ts +0 -288
- package/dist/memory/storage/base.d.ts.map +0 -1
- package/dist/memory/storage/base.js +0 -211
- package/dist/memory/storage/base.js.map +0 -1
- package/dist/memory/storage/index.d.ts +0 -9
- package/dist/memory/storage/index.d.ts.map +0 -1
- package/dist/memory/storage/index.js +0 -7
- package/dist/memory/storage/index.js.map +0 -1
- package/dist/memory/storage/inmemory.d.ts +0 -93
- package/dist/memory/storage/inmemory.d.ts.map +0 -1
- package/dist/memory/storage/inmemory.js +0 -646
- package/dist/memory/storage/inmemory.js.map +0 -1
- package/dist/memory/tools/working-memory.d.ts +0 -100
- package/dist/memory/tools/working-memory.d.ts.map +0 -1
- package/dist/memory/tools/working-memory.js +0 -237
- package/dist/memory/tools/working-memory.js.map +0 -1
- package/dist/memory/types.d.ts +0 -386
- package/dist/memory/types.d.ts.map +0 -1
- package/dist/memory/types.js +0 -58
- package/dist/memory/types.js.map +0 -1
- package/dist/memory/vector/base.d.ts +0 -145
- package/dist/memory/vector/base.d.ts.map +0 -1
- package/dist/memory/vector/base.js +0 -83
- package/dist/memory/vector/base.js.map +0 -1
- package/dist/memory/vector/index.d.ts +0 -8
- package/dist/memory/vector/index.d.ts.map +0 -1
- package/dist/memory/vector/index.js +0 -7
- package/dist/memory/vector/index.js.map +0 -1
- package/dist/memory/vector/inmemory.d.ts +0 -47
- package/dist/memory/vector/inmemory.d.ts.map +0 -1
- package/dist/memory/vector/inmemory.js +0 -234
- package/dist/memory/vector/inmemory.js.map +0 -1
|
@@ -102,40 +102,94 @@ function decodeKittyPrintable(data) {
|
|
|
102
102
|
return undefined;
|
|
103
103
|
}
|
|
104
104
|
}
|
|
105
|
+
class EditorLayoutProjector {
|
|
106
|
+
static buildVisualLineMap(lines, width) {
|
|
107
|
+
const visualLines = [];
|
|
108
|
+
for (let logicalIndex = 0; logicalIndex < lines.length; logicalIndex++) {
|
|
109
|
+
const line = lines[logicalIndex] || "";
|
|
110
|
+
if (line.length === 0) {
|
|
111
|
+
visualLines.push({ logicalLine: logicalIndex, startCol: 0, length: 0 });
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
if (visibleWidth(line) <= width) {
|
|
115
|
+
visualLines.push({ logicalLine: logicalIndex, startCol: 0, length: line.length });
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
for (const chunk of wordWrapLine(line, width)) {
|
|
119
|
+
visualLines.push({
|
|
120
|
+
logicalLine: logicalIndex,
|
|
121
|
+
startCol: chunk.startIndex,
|
|
122
|
+
length: chunk.endIndex - chunk.startIndex,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return visualLines;
|
|
127
|
+
}
|
|
128
|
+
static findCurrentVisualLine(visualLines, cursorLine, cursorCol) {
|
|
129
|
+
for (let visualIndex = 0; visualIndex < visualLines.length; visualIndex++) {
|
|
130
|
+
const segment = visualLines[visualIndex];
|
|
131
|
+
if (!segment || segment.logicalLine !== cursorLine)
|
|
132
|
+
continue;
|
|
133
|
+
const offset = cursorCol - segment.startCol;
|
|
134
|
+
const lastSegment = visualIndex === visualLines.length - 1 || visualLines[visualIndex + 1]?.logicalLine !== segment.logicalLine;
|
|
135
|
+
if (offset >= 0 && (offset < segment.length || (lastSegment && offset <= segment.length))) {
|
|
136
|
+
return visualIndex;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return visualLines.length - 1;
|
|
140
|
+
}
|
|
141
|
+
static resolveCursorAtVisualLine(visualLines, visualIndex, visualCol, lines) {
|
|
142
|
+
const segment = visualLines[visualIndex];
|
|
143
|
+
if (!segment)
|
|
144
|
+
return null;
|
|
145
|
+
const line = segment.logicalLine;
|
|
146
|
+
const targetCol = segment.startCol + Math.min(visualCol, segment.length);
|
|
147
|
+
return { line, col: Math.min(targetCol, (lines[line] || "").length) };
|
|
148
|
+
}
|
|
149
|
+
}
|
|
105
150
|
export class Editor extends ComponentBase {
|
|
151
|
+
state = {
|
|
152
|
+
lines: [""],
|
|
153
|
+
cursorLine: 0,
|
|
154
|
+
cursorCol: 0,
|
|
155
|
+
};
|
|
156
|
+
/** Focusable interface - set by TUI when focus changes */
|
|
157
|
+
focused = false;
|
|
158
|
+
tui;
|
|
159
|
+
theme;
|
|
160
|
+
paddingX = 0;
|
|
161
|
+
// Store last render width for cursor navigation
|
|
162
|
+
lastWidth = 80;
|
|
163
|
+
// Vertical scrolling support
|
|
164
|
+
scrollOffset = 0;
|
|
165
|
+
// Border color (can be changed dynamically)
|
|
166
|
+
borderColor;
|
|
167
|
+
// Autocomplete support
|
|
168
|
+
autocompleteProvider;
|
|
169
|
+
autocompleteList;
|
|
170
|
+
isAutocompleting = false;
|
|
171
|
+
autocompletePrefix = "";
|
|
172
|
+
// Paste tracking for large pastes
|
|
173
|
+
pastes = new Map();
|
|
174
|
+
pasteCounter = 0;
|
|
175
|
+
// Bracketed paste mode buffering
|
|
176
|
+
pasteBuffer = "";
|
|
177
|
+
isInPaste = false;
|
|
178
|
+
pendingShiftEnter = false;
|
|
179
|
+
// Prompt history for up/down navigation
|
|
180
|
+
history = [];
|
|
181
|
+
historyIndex = -1; // -1 = not browsing, 0 = most recent, 1 = older, etc.
|
|
182
|
+
// Kill ring for Emacs-style kill/yank operations
|
|
183
|
+
// Also tracks undo coalescing: "type-word" means we're mid-word (coalescing)
|
|
184
|
+
killRing = [];
|
|
185
|
+
lastAction = null;
|
|
186
|
+
// Undo support
|
|
187
|
+
undoStack = [];
|
|
188
|
+
onSubmit;
|
|
189
|
+
onChange;
|
|
190
|
+
disableSubmit = false;
|
|
106
191
|
constructor(tui, theme, options = {}) {
|
|
107
192
|
super();
|
|
108
|
-
this.state = {
|
|
109
|
-
lines: [""],
|
|
110
|
-
cursorLine: 0,
|
|
111
|
-
cursorCol: 0,
|
|
112
|
-
};
|
|
113
|
-
/** Focusable interface - set by TUI when focus changes */
|
|
114
|
-
this.focused = false;
|
|
115
|
-
this.paddingX = 0;
|
|
116
|
-
// Store last render width for cursor navigation
|
|
117
|
-
this.lastWidth = 80;
|
|
118
|
-
// Vertical scrolling support
|
|
119
|
-
this.scrollOffset = 0;
|
|
120
|
-
this.isAutocompleting = false;
|
|
121
|
-
this.autocompletePrefix = "";
|
|
122
|
-
// Paste tracking for large pastes
|
|
123
|
-
this.pastes = new Map();
|
|
124
|
-
this.pasteCounter = 0;
|
|
125
|
-
// Bracketed paste mode buffering
|
|
126
|
-
this.pasteBuffer = "";
|
|
127
|
-
this.isInPaste = false;
|
|
128
|
-
this.pendingShiftEnter = false;
|
|
129
|
-
// Prompt history for up/down navigation
|
|
130
|
-
this.history = [];
|
|
131
|
-
this.historyIndex = -1; // -1 = not browsing, 0 = most recent, 1 = older, etc.
|
|
132
|
-
// Kill ring for Emacs-style kill/yank operations
|
|
133
|
-
// Also tracks undo coalescing: "type-word" means we're mid-word (coalescing)
|
|
134
|
-
this.killRing = [];
|
|
135
|
-
this.lastAction = null;
|
|
136
|
-
// Undo support
|
|
137
|
-
this.undoStack = [];
|
|
138
|
-
this.disableSubmit = false;
|
|
139
193
|
this.tui = tui;
|
|
140
194
|
this.theme = theme;
|
|
141
195
|
this.borderColor = theme.borderColor;
|
|
@@ -223,294 +277,274 @@ export class Editor extends ComponentBase {
|
|
|
223
277
|
this.autocompleteList?.invalidate?.();
|
|
224
278
|
}
|
|
225
279
|
render(width) {
|
|
280
|
+
const state = this.prepareRenderState(width);
|
|
281
|
+
const out = [];
|
|
282
|
+
out.push(this.renderTopBorder(width, state.horizontal));
|
|
283
|
+
const emitCursorMarker = this.focused && !this.isAutocompleting;
|
|
284
|
+
for (const layoutLine of state.visibleLines) {
|
|
285
|
+
out.push(this.renderVisibleLine(layoutLine, state.contentWidth, state.leftPadding, state.rightPadding, emitCursorMarker));
|
|
286
|
+
}
|
|
287
|
+
const linesBelow = state.layoutLines.length - (this.scrollOffset + state.visibleLines.length);
|
|
288
|
+
out.push(this.renderBottomBorder(width, state.horizontal, linesBelow));
|
|
289
|
+
if (this.isAutocompleting && this.autocompleteList) {
|
|
290
|
+
this.appendAutocompleteLines(out, state.contentWidth, state.leftPadding, state.rightPadding);
|
|
291
|
+
}
|
|
292
|
+
return out;
|
|
293
|
+
}
|
|
294
|
+
prepareRenderState(width) {
|
|
226
295
|
const maxPadding = Math.max(0, Math.floor((width - 1) / 2));
|
|
227
296
|
const paddingX = Math.min(this.paddingX, maxPadding);
|
|
228
297
|
const contentWidth = Math.max(1, width - paddingX * 2);
|
|
229
|
-
// Layout width: with padding the cursor can overflow into it,
|
|
230
|
-
// without padding we reserve 1 column for the cursor.
|
|
231
298
|
const layoutWidth = Math.max(1, contentWidth - (paddingX ? 0 : 1));
|
|
232
|
-
// Store for cursor navigation (must match wrapping width)
|
|
233
299
|
this.lastWidth = layoutWidth;
|
|
234
|
-
const horizontal = this.borderColor("─");
|
|
235
|
-
// Layout the text
|
|
236
300
|
const layoutLines = this.layoutText(layoutWidth);
|
|
237
|
-
|
|
238
|
-
const
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
301
|
+
const maxVisibleLines = Math.max(5, Math.floor(this.tui.terminal.rows * 0.3));
|
|
302
|
+
const cursorLineIndex = Math.max(0, layoutLines.findIndex((line) => line.hasCursor));
|
|
303
|
+
this.syncScrollOffset(cursorLineIndex, maxVisibleLines, layoutLines.length);
|
|
304
|
+
const visibleLines = layoutLines.slice(this.scrollOffset, this.scrollOffset + maxVisibleLines);
|
|
305
|
+
const sidePadding = " ".repeat(paddingX);
|
|
306
|
+
return {
|
|
307
|
+
horizontal: this.borderColor("─"),
|
|
308
|
+
contentWidth,
|
|
309
|
+
leftPadding: sidePadding,
|
|
310
|
+
rightPadding: sidePadding,
|
|
311
|
+
layoutLines,
|
|
312
|
+
visibleLines,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
syncScrollOffset(cursorLineIndex, maxVisibleLines, totalLayoutLines) {
|
|
245
316
|
if (cursorLineIndex < this.scrollOffset) {
|
|
246
317
|
this.scrollOffset = cursorLineIndex;
|
|
247
318
|
}
|
|
248
319
|
else if (cursorLineIndex >= this.scrollOffset + maxVisibleLines) {
|
|
249
320
|
this.scrollOffset = cursorLineIndex - maxVisibleLines + 1;
|
|
250
321
|
}
|
|
251
|
-
|
|
252
|
-
const maxScrollOffset = Math.max(0, layoutLines.length - maxVisibleLines);
|
|
322
|
+
const maxScrollOffset = Math.max(0, totalLayoutLines - maxVisibleLines);
|
|
253
323
|
this.scrollOffset = Math.max(0, Math.min(this.scrollOffset, maxScrollOffset));
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
const
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
const
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (after.length > 0) {
|
|
282
|
-
// Cursor is on a character (grapheme) - replace it with highlighted version
|
|
283
|
-
// Get the first grapheme from 'after'
|
|
284
|
-
const afterGraphemes = [...segmenter.segment(after)];
|
|
285
|
-
const firstGrapheme = afterGraphemes[0]?.segment || "";
|
|
286
|
-
const restAfter = after.slice(firstGrapheme.length);
|
|
287
|
-
const cursor = `\x1b[7m${firstGrapheme}\x1b[0m`;
|
|
288
|
-
displayText = before + marker + cursor + restAfter;
|
|
289
|
-
// lineVisibleWidth stays the same - we're replacing, not adding
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
// Cursor is at the end - add highlighted space
|
|
293
|
-
const cursor = "\x1b[7m \x1b[0m";
|
|
294
|
-
displayText = before + marker + cursor;
|
|
295
|
-
lineVisibleWidth = lineVisibleWidth + 1;
|
|
296
|
-
// If cursor overflows content width into the padding, flag it
|
|
297
|
-
if (lineVisibleWidth > contentWidth && paddingX > 0) {
|
|
298
|
-
cursorInPadding = true;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
324
|
+
}
|
|
325
|
+
renderTopBorder(width, horizontal) {
|
|
326
|
+
if (this.scrollOffset <= 0)
|
|
327
|
+
return horizontal.repeat(width);
|
|
328
|
+
const indicator = `─── ↑ ${this.scrollOffset} more `;
|
|
329
|
+
const remaining = width - visibleWidth(indicator);
|
|
330
|
+
return this.borderColor(indicator + "─".repeat(Math.max(0, remaining)));
|
|
331
|
+
}
|
|
332
|
+
renderBottomBorder(width, horizontal, linesBelow) {
|
|
333
|
+
if (linesBelow <= 0)
|
|
334
|
+
return horizontal.repeat(width);
|
|
335
|
+
const indicator = `─── ↓ ${linesBelow} more `;
|
|
336
|
+
const remaining = width - visibleWidth(indicator);
|
|
337
|
+
return this.borderColor(indicator + "─".repeat(Math.max(0, remaining)));
|
|
338
|
+
}
|
|
339
|
+
renderVisibleLine(layoutLine, contentWidth, leftPadding, rightPadding, emitCursorMarker) {
|
|
340
|
+
let displayText = layoutLine.text;
|
|
341
|
+
let measuredWidth = visibleWidth(layoutLine.text);
|
|
342
|
+
let cursorInPadding = false;
|
|
343
|
+
if (layoutLine.hasCursor && layoutLine.cursorPos !== undefined) {
|
|
344
|
+
const before = displayText.slice(0, layoutLine.cursorPos);
|
|
345
|
+
const after = displayText.slice(layoutLine.cursorPos);
|
|
346
|
+
const marker = emitCursorMarker ? CURSOR_MARKER : "";
|
|
347
|
+
if (after.length > 0) {
|
|
348
|
+
const first = [...segmenter.segment(after)][0]?.segment || "";
|
|
349
|
+
const highlighted = `\x1b[7m${first}\x1b[0m`;
|
|
350
|
+
displayText = before + marker + highlighted + after.slice(first.length);
|
|
301
351
|
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
result.push(`${leftPadding}${displayText}${padding}${lineRightPadding}`);
|
|
307
|
-
}
|
|
308
|
-
// Render bottom border (with scroll indicator if more content below)
|
|
309
|
-
const linesBelow = layoutLines.length - (this.scrollOffset + visibleLines.length);
|
|
310
|
-
if (linesBelow > 0) {
|
|
311
|
-
const indicator = `─── ↓ ${linesBelow} more `;
|
|
312
|
-
const remaining = width - visibleWidth(indicator);
|
|
313
|
-
result.push(this.borderColor(indicator + "─".repeat(Math.max(0, remaining))));
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
result.push(horizontal.repeat(width));
|
|
317
|
-
}
|
|
318
|
-
// Add autocomplete list if active
|
|
319
|
-
if (this.isAutocompleting && this.autocompleteList) {
|
|
320
|
-
const autocompleteResult = this.autocompleteList.render(contentWidth);
|
|
321
|
-
for (const line of autocompleteResult) {
|
|
322
|
-
const lineWidth = visibleWidth(line);
|
|
323
|
-
const linePadding = " ".repeat(Math.max(0, contentWidth - lineWidth));
|
|
324
|
-
result.push(`${leftPadding}${line}${linePadding}${rightPadding}`);
|
|
352
|
+
else {
|
|
353
|
+
displayText = before + marker + "\x1b[7m \x1b[0m";
|
|
354
|
+
measuredWidth += 1;
|
|
355
|
+
cursorInPadding = measuredWidth > contentWidth && rightPadding.length > 0;
|
|
325
356
|
}
|
|
326
357
|
}
|
|
327
|
-
|
|
358
|
+
const fill = " ".repeat(Math.max(0, contentWidth - measuredWidth));
|
|
359
|
+
const adjustedRightPadding = cursorInPadding ? rightPadding.slice(1) : rightPadding;
|
|
360
|
+
return `${leftPadding}${displayText}${fill}${adjustedRightPadding}`;
|
|
361
|
+
}
|
|
362
|
+
appendAutocompleteLines(target, contentWidth, leftPadding, rightPadding) {
|
|
363
|
+
const autocompleteResult = this.autocompleteList?.render(contentWidth) ?? [];
|
|
364
|
+
for (const line of autocompleteResult) {
|
|
365
|
+
const linePadding = " ".repeat(Math.max(0, contentWidth - visibleWidth(line)));
|
|
366
|
+
target.push(`${leftPadding}${line}${linePadding}${rightPadding}`);
|
|
367
|
+
}
|
|
328
368
|
}
|
|
329
369
|
handleInput(data) {
|
|
330
370
|
const kb = getEditorKeybindings();
|
|
331
|
-
|
|
332
|
-
if (
|
|
333
|
-
this.isInPaste = true;
|
|
334
|
-
this.pasteBuffer = "";
|
|
335
|
-
data = data.replace("\x1b[200~", "");
|
|
336
|
-
}
|
|
337
|
-
if (this.isInPaste) {
|
|
338
|
-
this.pasteBuffer += data;
|
|
339
|
-
const endIndex = this.pasteBuffer.indexOf("\x1b[201~");
|
|
340
|
-
if (endIndex !== -1) {
|
|
341
|
-
const pasteContent = this.pasteBuffer.substring(0, endIndex);
|
|
342
|
-
if (pasteContent.length > 0) {
|
|
343
|
-
this.handlePaste(pasteContent);
|
|
344
|
-
}
|
|
345
|
-
this.isInPaste = false;
|
|
346
|
-
const remaining = this.pasteBuffer.substring(endIndex + 6);
|
|
347
|
-
this.pasteBuffer = "";
|
|
348
|
-
if (remaining.length > 0) {
|
|
349
|
-
this.handleInput(remaining);
|
|
350
|
-
}
|
|
351
|
-
return;
|
|
352
|
-
}
|
|
371
|
+
const pasteResult = this.consumePasteInput(data);
|
|
372
|
+
if (!pasteResult)
|
|
353
373
|
return;
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
this.pendingShiftEnter = false;
|
|
362
|
-
this.insertCharacter("\\");
|
|
363
|
-
}
|
|
374
|
+
data = pasteResult;
|
|
375
|
+
const pendingResult = this.consumePendingShiftEnter(data);
|
|
376
|
+
if (!pendingResult)
|
|
377
|
+
return;
|
|
378
|
+
data = pendingResult;
|
|
364
379
|
if (data === "\\") {
|
|
365
380
|
this.pendingShiftEnter = true;
|
|
366
381
|
return;
|
|
367
382
|
}
|
|
368
|
-
|
|
369
|
-
if (kb.matches(data, "copy")) {
|
|
383
|
+
if (this.runEarlyActions(data, kb))
|
|
370
384
|
return;
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
if (kb.matches(data, "undo")) {
|
|
374
|
-
this.undo();
|
|
385
|
+
const autocompleteResult = this.handleAutocompleteInput(data, kb);
|
|
386
|
+
if (autocompleteResult === "handled")
|
|
375
387
|
return;
|
|
376
|
-
|
|
377
|
-
// Handle autocomplete mode
|
|
378
|
-
if (this.isAutocompleting && this.autocompleteList) {
|
|
379
|
-
if (kb.matches(data, "selectCancel")) {
|
|
380
|
-
this.cancelAutocomplete();
|
|
381
|
-
return;
|
|
382
|
-
}
|
|
383
|
-
if (kb.matches(data, "selectUp") || kb.matches(data, "selectDown")) {
|
|
384
|
-
this.autocompleteList.handleInput(data);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
if (kb.matches(data, "tab")) {
|
|
388
|
-
const selected = this.autocompleteList.getSelectedItem();
|
|
389
|
-
if (selected && this.autocompleteProvider) {
|
|
390
|
-
this.pushUndoSnapshot();
|
|
391
|
-
this.lastAction = null;
|
|
392
|
-
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
|
|
393
|
-
this.state.lines = result.lines;
|
|
394
|
-
this.state.cursorLine = result.cursorLine;
|
|
395
|
-
this.state.cursorCol = result.cursorCol;
|
|
396
|
-
this.cancelAutocomplete();
|
|
397
|
-
if (this.onChange)
|
|
398
|
-
this.onChange(this.getText());
|
|
399
|
-
}
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
if (kb.matches(data, "selectConfirm")) {
|
|
403
|
-
const selected = this.autocompleteList.getSelectedItem();
|
|
404
|
-
if (selected && this.autocompleteProvider) {
|
|
405
|
-
this.pushUndoSnapshot();
|
|
406
|
-
this.lastAction = null;
|
|
407
|
-
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
|
|
408
|
-
this.state.lines = result.lines;
|
|
409
|
-
this.state.cursorLine = result.cursorLine;
|
|
410
|
-
this.state.cursorCol = result.cursorCol;
|
|
411
|
-
if (this.autocompletePrefix.startsWith("/")) {
|
|
412
|
-
this.cancelAutocomplete();
|
|
413
|
-
// Fall through to submit
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
this.cancelAutocomplete();
|
|
417
|
-
if (this.onChange)
|
|
418
|
-
this.onChange(this.getText());
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
// Tab - trigger completion
|
|
425
|
-
if (kb.matches(data, "tab") && !this.isAutocompleting) {
|
|
388
|
+
if (!this.isAutocompleting && kb.matches(data, "tab")) {
|
|
426
389
|
this.handleTabCompletion();
|
|
427
390
|
return;
|
|
428
391
|
}
|
|
429
|
-
|
|
430
|
-
if (kb.matches(data, "deleteToLineEnd")) {
|
|
431
|
-
this.deleteToEndOfLine();
|
|
392
|
+
if (this.runDeleteActions(data, kb))
|
|
432
393
|
return;
|
|
433
|
-
|
|
434
|
-
if (kb.matches(data, "deleteToLineStart")) {
|
|
435
|
-
this.deleteToStartOfLine();
|
|
394
|
+
if (this.runKillRingActions(data, kb))
|
|
436
395
|
return;
|
|
437
|
-
|
|
438
|
-
if (kb.matches(data, "deleteWordBackward")) {
|
|
439
|
-
this.deleteWordBackwards();
|
|
396
|
+
if (this.runCursorActions(data, kb))
|
|
440
397
|
return;
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
this.deleteWordForward();
|
|
398
|
+
if (this.isNewLineInput(data, kb)) {
|
|
399
|
+
this.addNewLine();
|
|
444
400
|
return;
|
|
445
401
|
}
|
|
446
|
-
if (kb.matches(data, "
|
|
447
|
-
this.
|
|
402
|
+
if (kb.matches(data, "submit")) {
|
|
403
|
+
this.submitEditor();
|
|
448
404
|
return;
|
|
449
405
|
}
|
|
450
|
-
if (
|
|
451
|
-
this.handleForwardDelete();
|
|
406
|
+
if (this.runArrowActions(data, kb))
|
|
452
407
|
return;
|
|
453
|
-
|
|
454
|
-
// Kill ring actions
|
|
455
|
-
if (kb.matches(data, "yank")) {
|
|
456
|
-
this.yank();
|
|
408
|
+
if (this.runPagingActions(data, kb))
|
|
457
409
|
return;
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
this.yankPop();
|
|
410
|
+
if (matchesKey(data, "shift+space")) {
|
|
411
|
+
this.insertCharacter(" ");
|
|
461
412
|
return;
|
|
462
413
|
}
|
|
463
|
-
|
|
464
|
-
if (
|
|
465
|
-
this.
|
|
414
|
+
const kittyPrintable = decodeKittyPrintable(data);
|
|
415
|
+
if (kittyPrintable !== undefined) {
|
|
416
|
+
this.insertCharacter(kittyPrintable);
|
|
466
417
|
return;
|
|
467
418
|
}
|
|
468
|
-
if (
|
|
469
|
-
this.
|
|
470
|
-
return;
|
|
419
|
+
if (data.charCodeAt(0) >= 32) {
|
|
420
|
+
this.insertCharacter(data);
|
|
471
421
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
422
|
+
}
|
|
423
|
+
consumePasteInput(data) {
|
|
424
|
+
if (data.includes("\x1b[200~")) {
|
|
425
|
+
this.isInPaste = true;
|
|
426
|
+
this.pasteBuffer = "";
|
|
427
|
+
data = data.replace("\x1b[200~", "");
|
|
475
428
|
}
|
|
476
|
-
if (
|
|
477
|
-
|
|
478
|
-
|
|
429
|
+
if (!this.isInPaste)
|
|
430
|
+
return data;
|
|
431
|
+
this.pasteBuffer += data;
|
|
432
|
+
const endIndex = this.pasteBuffer.indexOf("\x1b[201~");
|
|
433
|
+
if (endIndex === -1)
|
|
434
|
+
return null;
|
|
435
|
+
const pasteContent = this.pasteBuffer.substring(0, endIndex);
|
|
436
|
+
if (pasteContent.length > 0) {
|
|
437
|
+
this.handlePaste(pasteContent);
|
|
479
438
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
439
|
+
this.isInPaste = false;
|
|
440
|
+
const remaining = this.pasteBuffer.substring(endIndex + 6);
|
|
441
|
+
this.pasteBuffer = "";
|
|
442
|
+
if (remaining.length > 0) {
|
|
443
|
+
this.handleInput(remaining);
|
|
444
|
+
}
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
consumePendingShiftEnter(data) {
|
|
448
|
+
if (!this.pendingShiftEnter)
|
|
449
|
+
return data;
|
|
450
|
+
if (data === "\r") {
|
|
451
|
+
this.pendingShiftEnter = false;
|
|
488
452
|
this.addNewLine();
|
|
489
|
-
return;
|
|
453
|
+
return null;
|
|
490
454
|
}
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
this.
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
455
|
+
this.pendingShiftEnter = false;
|
|
456
|
+
this.insertCharacter("\\");
|
|
457
|
+
return data;
|
|
458
|
+
}
|
|
459
|
+
runEarlyActions(data, kb) {
|
|
460
|
+
if (kb.matches(data, "copy")) {
|
|
461
|
+
return true;
|
|
462
|
+
}
|
|
463
|
+
if (kb.matches(data, "undo")) {
|
|
464
|
+
this.undo();
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
handleAutocompleteInput(data, kb) {
|
|
470
|
+
if (!this.isAutocompleting || !this.autocompleteList)
|
|
471
|
+
return "none";
|
|
472
|
+
if (kb.matches(data, "selectCancel")) {
|
|
473
|
+
this.cancelAutocomplete();
|
|
474
|
+
return "handled";
|
|
475
|
+
}
|
|
476
|
+
if (kb.matches(data, "selectUp") || kb.matches(data, "selectDown")) {
|
|
477
|
+
this.autocompleteList.handleInput(data);
|
|
478
|
+
return "handled";
|
|
479
|
+
}
|
|
480
|
+
if (kb.matches(data, "tab")) {
|
|
481
|
+
this.applySelectedAutocompleteItem(true);
|
|
482
|
+
return "handled";
|
|
483
|
+
}
|
|
484
|
+
if (kb.matches(data, "selectConfirm")) {
|
|
485
|
+
const applied = this.applySelectedAutocompleteItem(false);
|
|
486
|
+
if (!applied)
|
|
487
|
+
return "handled";
|
|
488
|
+
return this.autocompletePrefix.startsWith("/") ? "continue" : "handled";
|
|
489
|
+
}
|
|
490
|
+
return "none";
|
|
491
|
+
}
|
|
492
|
+
applySelectedAutocompleteItem(notifyOnSlash) {
|
|
493
|
+
const selected = this.autocompleteList?.getSelectedItem();
|
|
494
|
+
if (!selected || !this.autocompleteProvider)
|
|
495
|
+
return false;
|
|
496
|
+
this.pushUndoSnapshot();
|
|
497
|
+
this.lastAction = null;
|
|
498
|
+
const result = this.autocompleteProvider.applyCompletion(this.state.lines, this.state.cursorLine, this.state.cursorCol, selected, this.autocompletePrefix);
|
|
499
|
+
this.state.lines = result.lines;
|
|
500
|
+
this.state.cursorLine = result.cursorLine;
|
|
501
|
+
this.state.cursorCol = result.cursorCol;
|
|
502
|
+
this.cancelAutocomplete();
|
|
503
|
+
if (this.onChange && (notifyOnSlash || !this.autocompletePrefix.startsWith("/"))) {
|
|
504
|
+
this.onChange(this.getText());
|
|
505
|
+
}
|
|
506
|
+
return true;
|
|
507
|
+
}
|
|
508
|
+
runDeleteActions(data, kb) {
|
|
509
|
+
const actions = [
|
|
510
|
+
{ match: kb.matches(data, "deleteToLineEnd"), run: () => this.deleteToEndOfLine() },
|
|
511
|
+
{ match: kb.matches(data, "deleteToLineStart"), run: () => this.deleteToStartOfLine() },
|
|
512
|
+
{ match: kb.matches(data, "deleteWordBackward"), run: () => this.deleteWordBackwards() },
|
|
513
|
+
{ match: kb.matches(data, "deleteWordForward"), run: () => this.deleteWordForward() },
|
|
514
|
+
{ match: kb.matches(data, "deleteCharBackward") || matchesKey(data, "shift+backspace"), run: () => this.handleBackspace() },
|
|
515
|
+
{ match: kb.matches(data, "deleteCharForward") || matchesKey(data, "shift+delete"), run: () => this.handleForwardDelete() },
|
|
516
|
+
];
|
|
517
|
+
const route = actions.find((entry) => entry.match);
|
|
518
|
+
if (!route)
|
|
519
|
+
return false;
|
|
520
|
+
route.run();
|
|
521
|
+
return true;
|
|
522
|
+
}
|
|
523
|
+
runKillRingActions(data, kb) {
|
|
524
|
+
if (kb.matches(data, "yank")) {
|
|
525
|
+
this.yank();
|
|
526
|
+
return true;
|
|
527
|
+
}
|
|
528
|
+
if (kb.matches(data, "yankPop")) {
|
|
529
|
+
this.yankPop();
|
|
530
|
+
return true;
|
|
512
531
|
}
|
|
513
|
-
|
|
532
|
+
return false;
|
|
533
|
+
}
|
|
534
|
+
runCursorActions(data, kb) {
|
|
535
|
+
const routes = [
|
|
536
|
+
{ match: kb.matches(data, "cursorLineStart"), run: () => this.moveToLineStart() },
|
|
537
|
+
{ match: kb.matches(data, "cursorLineEnd"), run: () => this.moveToLineEnd() },
|
|
538
|
+
{ match: kb.matches(data, "cursorWordLeft"), run: () => this.moveWordBackwards() },
|
|
539
|
+
{ match: kb.matches(data, "cursorWordRight"), run: () => this.moveWordForwards() },
|
|
540
|
+
];
|
|
541
|
+
const route = routes.find((entry) => entry.match);
|
|
542
|
+
if (!route)
|
|
543
|
+
return false;
|
|
544
|
+
route.run();
|
|
545
|
+
return true;
|
|
546
|
+
}
|
|
547
|
+
runArrowActions(data, kb) {
|
|
514
548
|
if (kb.matches(data, "cursorUp")) {
|
|
515
549
|
if (this.isEditorEmpty()) {
|
|
516
550
|
this.navigateHistory(-1);
|
|
@@ -521,7 +555,7 @@ export class Editor extends ComponentBase {
|
|
|
521
555
|
else {
|
|
522
556
|
this.moveCursor(-1, 0);
|
|
523
557
|
}
|
|
524
|
-
return;
|
|
558
|
+
return true;
|
|
525
559
|
}
|
|
526
560
|
if (kb.matches(data, "cursorDown")) {
|
|
527
561
|
if (this.historyIndex > -1 && this.isOnLastVisualLine()) {
|
|
@@ -530,39 +564,57 @@ export class Editor extends ComponentBase {
|
|
|
530
564
|
else {
|
|
531
565
|
this.moveCursor(1, 0);
|
|
532
566
|
}
|
|
533
|
-
return;
|
|
567
|
+
return true;
|
|
534
568
|
}
|
|
535
569
|
if (kb.matches(data, "cursorRight")) {
|
|
536
570
|
this.moveCursor(0, 1);
|
|
537
|
-
return;
|
|
571
|
+
return true;
|
|
538
572
|
}
|
|
539
573
|
if (kb.matches(data, "cursorLeft")) {
|
|
540
574
|
this.moveCursor(0, -1);
|
|
541
|
-
return;
|
|
575
|
+
return true;
|
|
542
576
|
}
|
|
543
|
-
|
|
577
|
+
return false;
|
|
578
|
+
}
|
|
579
|
+
runPagingActions(data, kb) {
|
|
544
580
|
if (kb.matches(data, "pageUp")) {
|
|
545
581
|
this.pageScroll(-1);
|
|
546
|
-
return;
|
|
582
|
+
return true;
|
|
547
583
|
}
|
|
548
584
|
if (kb.matches(data, "pageDown")) {
|
|
549
585
|
this.pageScroll(1);
|
|
550
|
-
return;
|
|
586
|
+
return true;
|
|
551
587
|
}
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
588
|
+
return false;
|
|
589
|
+
}
|
|
590
|
+
isNewLineInput(data, kb) {
|
|
591
|
+
return (kb.matches(data, "newLine") ||
|
|
592
|
+
(data.charCodeAt(0) === 10 && data.length > 1) ||
|
|
593
|
+
data === "\x1b\r" ||
|
|
594
|
+
data === "\x1b[13;2~" ||
|
|
595
|
+
(data.length > 1 && data.includes("\x1b") && data.includes("\r")) ||
|
|
596
|
+
(data === "\n" && data.length === 1) ||
|
|
597
|
+
data === "\\\r");
|
|
598
|
+
}
|
|
599
|
+
submitEditor() {
|
|
600
|
+
if (this.disableSubmit)
|
|
560
601
|
return;
|
|
602
|
+
let result = this.state.lines.join("\n").trim();
|
|
603
|
+
for (const [pasteId, pasteContent] of this.pastes) {
|
|
604
|
+
const markerRegex = new RegExp(`\\[paste #${pasteId}( (\\+\\d+ lines|\\d+ chars))?\\]`, "g");
|
|
605
|
+
result = result.replace(markerRegex, pasteContent);
|
|
561
606
|
}
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
607
|
+
this.state = { lines: [""], cursorLine: 0, cursorCol: 0 };
|
|
608
|
+
this.pastes.clear();
|
|
609
|
+
this.pasteCounter = 0;
|
|
610
|
+
this.historyIndex = -1;
|
|
611
|
+
this.scrollOffset = 0;
|
|
612
|
+
this.undoStack.length = 0;
|
|
613
|
+
this.lastAction = null;
|
|
614
|
+
if (this.onChange)
|
|
615
|
+
this.onChange("");
|
|
616
|
+
if (this.onSubmit)
|
|
617
|
+
this.onSubmit(result);
|
|
566
618
|
}
|
|
567
619
|
layoutText(contentWidth) {
|
|
568
620
|
const layoutLines = [];
|
|
@@ -1085,72 +1137,28 @@ export class Editor extends ComponentBase {
|
|
|
1085
1137
|
* - length: length of this visual line segment
|
|
1086
1138
|
*/
|
|
1087
1139
|
buildVisualLineMap(width) {
|
|
1088
|
-
|
|
1089
|
-
for (let i = 0; i < this.state.lines.length; i++) {
|
|
1090
|
-
const line = this.state.lines[i] || "";
|
|
1091
|
-
const lineVisWidth = visibleWidth(line);
|
|
1092
|
-
if (line.length === 0) {
|
|
1093
|
-
// Empty line still takes one visual line
|
|
1094
|
-
visualLines.push({ logicalLine: i, startCol: 0, length: 0 });
|
|
1095
|
-
}
|
|
1096
|
-
else if (lineVisWidth <= width) {
|
|
1097
|
-
visualLines.push({ logicalLine: i, startCol: 0, length: line.length });
|
|
1098
|
-
}
|
|
1099
|
-
else {
|
|
1100
|
-
// Line needs wrapping - use word-aware wrapping
|
|
1101
|
-
const chunks = wordWrapLine(line, width);
|
|
1102
|
-
for (const chunk of chunks) {
|
|
1103
|
-
visualLines.push({
|
|
1104
|
-
logicalLine: i,
|
|
1105
|
-
startCol: chunk.startIndex,
|
|
1106
|
-
length: chunk.endIndex - chunk.startIndex,
|
|
1107
|
-
});
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
}
|
|
1111
|
-
return visualLines;
|
|
1140
|
+
return EditorLayoutProjector.buildVisualLineMap(this.state.lines, width);
|
|
1112
1141
|
}
|
|
1113
1142
|
/**
|
|
1114
1143
|
* Find the visual line index for the current cursor position.
|
|
1115
1144
|
*/
|
|
1116
1145
|
findCurrentVisualLine(visualLines) {
|
|
1117
|
-
|
|
1118
|
-
const vl = visualLines[i];
|
|
1119
|
-
if (!vl)
|
|
1120
|
-
continue;
|
|
1121
|
-
if (vl.logicalLine === this.state.cursorLine) {
|
|
1122
|
-
const colInSegment = this.state.cursorCol - vl.startCol;
|
|
1123
|
-
// Cursor is in this segment if it's within range
|
|
1124
|
-
// For the last segment of a logical line, cursor can be at length (end position)
|
|
1125
|
-
const isLastSegmentOfLine = i === visualLines.length - 1 || visualLines[i + 1]?.logicalLine !== vl.logicalLine;
|
|
1126
|
-
if (colInSegment >= 0 && (colInSegment < vl.length || (isLastSegmentOfLine && colInSegment <= vl.length))) {
|
|
1127
|
-
return i;
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
// Fallback: return last visual line
|
|
1132
|
-
return visualLines.length - 1;
|
|
1146
|
+
return EditorLayoutProjector.findCurrentVisualLine(visualLines, this.state.cursorLine, this.state.cursorCol);
|
|
1133
1147
|
}
|
|
1134
1148
|
moveCursor(deltaLine, deltaCol) {
|
|
1135
1149
|
this.lastAction = null;
|
|
1136
1150
|
const width = this.lastWidth;
|
|
1137
1151
|
if (deltaLine !== 0) {
|
|
1138
|
-
// Build visual line map for navigation
|
|
1139
1152
|
const visualLines = this.buildVisualLineMap(width);
|
|
1140
1153
|
const currentVisualLine = this.findCurrentVisualLine(visualLines);
|
|
1141
|
-
|
|
1142
|
-
const
|
|
1143
|
-
const visualCol = currentVL ? this.state.cursorCol - currentVL.startCol : 0;
|
|
1144
|
-
// Move to target visual line
|
|
1154
|
+
const currentSegment = visualLines[currentVisualLine];
|
|
1155
|
+
const visualCol = currentSegment ? this.state.cursorCol - currentSegment.startCol : 0;
|
|
1145
1156
|
const targetVisualLine = currentVisualLine + deltaLine;
|
|
1146
1157
|
if (targetVisualLine >= 0 && targetVisualLine < visualLines.length) {
|
|
1147
|
-
const
|
|
1148
|
-
if (
|
|
1149
|
-
this.state.cursorLine =
|
|
1150
|
-
|
|
1151
|
-
const targetCol = targetVL.startCol + Math.min(visualCol, targetVL.length);
|
|
1152
|
-
const logicalLine = this.state.lines[targetVL.logicalLine] || "";
|
|
1153
|
-
this.state.cursorCol = Math.min(targetCol, logicalLine.length);
|
|
1158
|
+
const target = EditorLayoutProjector.resolveCursorAtVisualLine(visualLines, targetVisualLine, visualCol, this.state.lines);
|
|
1159
|
+
if (target) {
|
|
1160
|
+
this.state.cursorLine = target.line;
|
|
1161
|
+
this.state.cursorCol = target.col;
|
|
1154
1162
|
}
|
|
1155
1163
|
}
|
|
1156
1164
|
}
|
|
@@ -1196,21 +1204,15 @@ export class Editor extends ComponentBase {
|
|
|
1196
1204
|
const width = this.lastWidth;
|
|
1197
1205
|
const terminalRows = this.tui.terminal.rows;
|
|
1198
1206
|
const pageSize = Math.max(5, Math.floor(terminalRows * 0.3));
|
|
1199
|
-
// Build visual line map
|
|
1200
1207
|
const visualLines = this.buildVisualLineMap(width);
|
|
1201
1208
|
const currentVisualLine = this.findCurrentVisualLine(visualLines);
|
|
1202
|
-
// Calculate target visual line
|
|
1203
1209
|
const targetVisualLine = Math.max(0, Math.min(visualLines.length - 1, currentVisualLine + direction * pageSize));
|
|
1204
|
-
|
|
1205
|
-
const
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
this.state.cursorLine = targetVL.logicalLine;
|
|
1211
|
-
const targetCol = targetVL.startCol + Math.min(visualCol, targetVL.length);
|
|
1212
|
-
const logicalLine = this.state.lines[targetVL.logicalLine] || "";
|
|
1213
|
-
this.state.cursorCol = Math.min(targetCol, logicalLine.length);
|
|
1210
|
+
const currentSegment = visualLines[currentVisualLine];
|
|
1211
|
+
const visualCol = currentSegment ? this.state.cursorCol - currentSegment.startCol : 0;
|
|
1212
|
+
const target = EditorLayoutProjector.resolveCursorAtVisualLine(visualLines, targetVisualLine, visualCol, this.state.lines);
|
|
1213
|
+
if (target) {
|
|
1214
|
+
this.state.cursorLine = target.line;
|
|
1215
|
+
this.state.cursorCol = target.col;
|
|
1214
1216
|
}
|
|
1215
1217
|
}
|
|
1216
1218
|
moveWordBackwards() {
|