@zergai/ztc 0.4.0-beta.1 → 0.5.0-beta.1
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 +398 -45
- package/RUST_THIRD_PARTY_LICENSES.txt +1080 -822
- package/THIRD_PARTY_NOTICES.md +273 -12
- package/bin/zmux-darwin-arm64 +0 -0
- package/bin/ztc-audio-darwin-arm64 +0 -0
- package/bin/ztc-capture-darwin-arm64 +0 -0
- package/bin/ztc-computer-darwin-arm64 +0 -0
- package/bin/ztc-llm-darwin-arm64 +0 -0
- package/bin/ztc-tts-darwin-arm64 +0 -0
- package/bin/ztc-tui-darwin-arm64 +0 -0
- package/bin/ztc-zlicky-overlay-darwin-arm64 +0 -0
- package/bin/zterm-darwin-arm64 +0 -0
- package/dist/App.js +1206 -209
- package/dist/agent/agent.d.ts +74 -8
- package/dist/agent/agent.js +1073 -184
- package/dist/agent/backends/account_rotation.d.ts +4 -0
- package/dist/agent/backends/account_rotation.js +8 -2
- package/dist/agent/backends/anthropic.d.ts +13 -0
- package/dist/agent/backends/anthropic.js +169 -28
- package/dist/agent/backends/claude_cli.js +18 -8
- package/dist/agent/backends/codex_app_server.d.ts +1 -0
- package/dist/agent/backends/codex_app_server.js +55 -3
- package/dist/agent/backends/codex_auth.d.ts +1 -0
- package/dist/agent/backends/codex_auth.js +67 -13
- package/dist/agent/backends/codex_buffered_recovery.d.ts +27 -0
- package/dist/agent/backends/codex_buffered_recovery.js +293 -0
- package/dist/agent/backends/gemini.js +3 -1
- package/dist/agent/backends/http_error.d.ts +26 -0
- package/dist/agent/backends/http_error.js +221 -0
- package/dist/agent/backends/index.d.ts +9 -2
- package/dist/agent/backends/index.js +22 -2
- package/dist/agent/backends/openai.d.ts +0 -6
- package/dist/agent/backends/openai.js +5 -2
- package/dist/agent/backends/openai_compatible.d.ts +5 -4
- package/dist/agent/backends/openai_compatible.js +26 -19
- package/dist/agent/backends/openai_responses.d.ts +8 -3
- package/dist/agent/backends/openai_responses.js +77 -33
- package/dist/agent/backends/provider_ids.d.ts +1 -0
- package/dist/agent/backends/provider_ids.js +4 -0
- package/dist/agent/backends/request_metrics.js +12 -2
- package/dist/agent/backends/types.d.ts +109 -6
- package/dist/agent/backends/types.js +5 -1
- package/dist/agent/backends/zrouter_stream.d.ts +6 -1
- package/dist/agent/backends/zrouter_stream.js +160 -42
- package/dist/agent/background_registry.d.ts +2 -0
- package/dist/agent/background_registry.js +1 -0
- package/dist/agent/claim_observation.d.ts +6 -0
- package/dist/agent/claim_observation.js +54 -0
- package/dist/agent/commands/accounts.js +46 -177
- package/dist/agent/commands/attention.d.ts +2 -0
- package/dist/agent/commands/attention.js +67 -0
- package/dist/agent/commands/auth.js +18 -2
- package/dist/agent/commands/board.d.ts +2 -0
- package/dist/agent/commands/board.js +169 -0
- package/dist/agent/commands/clipboard.js +50 -1
- package/dist/agent/commands/compact.js +21 -13
- package/dist/agent/commands/config.js +4 -1
- package/dist/agent/commands/context.js +6 -1
- package/dist/agent/commands/desktop.d.ts +2 -0
- package/dist/agent/commands/desktop.js +29 -0
- package/dist/agent/commands/effort.js +14 -6
- package/dist/agent/commands/environment.d.ts +3 -0
- package/dist/agent/commands/environment.js +109 -0
- package/dist/agent/commands/evidence.d.ts +2 -0
- package/dist/agent/commands/evidence.js +9 -0
- package/dist/agent/commands/fork.js +4 -3
- package/dist/agent/commands/goal.d.ts +33 -1
- package/dist/agent/commands/goal.js +174 -14
- package/dist/agent/commands/goal_exit.d.ts +36 -0
- package/dist/agent/commands/goal_exit.js +120 -0
- package/dist/agent/commands/help.js +3 -1
- package/dist/agent/commands/history.js +3 -1
- package/dist/agent/commands/inbox.d.ts +2 -0
- package/dist/agent/commands/inbox.js +148 -0
- package/dist/agent/commands/index.js +16 -1
- package/dist/agent/commands/input_mode.js +8 -6
- package/dist/agent/commands/job.d.ts +2 -0
- package/dist/agent/commands/job.js +93 -0
- package/dist/agent/commands/keybindings.js +4 -1
- package/dist/agent/commands/label.d.ts +2 -0
- package/dist/agent/commands/label.js +77 -0
- package/dist/agent/commands/layout.d.ts +2 -0
- package/dist/agent/commands/layout.js +20 -0
- package/dist/agent/commands/mirror.js +16 -1
- package/dist/agent/commands/model.js +12 -2
- package/dist/agent/commands/permissions.d.ts +3 -1
- package/dist/agent/commands/permissions.js +79 -89
- package/dist/agent/commands/plan.js +5 -15
- package/dist/agent/commands/profile.js +21 -2
- package/dist/agent/commands/provider_selection.js +20 -1
- package/dist/agent/commands/rename.js +1 -1
- package/dist/agent/commands/resources.d.ts +2 -0
- package/dist/agent/commands/resources.js +67 -0
- package/dist/agent/commands/rewind.d.ts +3 -0
- package/dist/agent/commands/rewind.js +16 -0
- package/dist/agent/commands/runbooks.d.ts +2 -0
- package/dist/agent/commands/runbooks.js +73 -0
- package/dist/agent/commands/runbooks_lazy.d.ts +2 -0
- package/dist/agent/commands/runbooks_lazy.js +8 -0
- package/dist/agent/commands/sessions.d.ts +1 -1
- package/dist/agent/commands/sessions.js +33 -5
- package/dist/agent/commands/settings.js +185 -39
- package/dist/agent/commands/setup.d.ts +2 -0
- package/dist/agent/commands/setup.js +78 -0
- package/dist/agent/commands/share.d.ts +2 -0
- package/dist/agent/commands/share.js +64 -0
- package/dist/agent/commands/status.js +14 -2
- package/dist/agent/commands/types.d.ts +99 -6
- package/dist/agent/commands/update.js +8 -0
- package/dist/agent/commands/usage.d.ts +2 -0
- package/dist/agent/commands/usage.js +8 -0
- package/dist/agent/factory.d.ts +11 -0
- package/dist/agent/factory.js +113 -88
- package/dist/agent/loop_policy.d.ts +6 -3
- package/dist/agent/loop_policy.js +12 -3
- package/dist/agent/measurement_guidance.d.ts +2 -0
- package/dist/agent/measurement_guidance.js +5 -0
- package/dist/agent/request_encoder.d.ts +8 -1
- package/dist/agent/request_encoder.js +95 -23
- package/dist/agent/runtime/benchmark_comparison.d.ts +30 -0
- package/dist/agent/runtime/benchmark_comparison.js +94 -0
- package/dist/agent/runtime/benchmark_contract.d.ts +48 -0
- package/dist/agent/runtime/benchmark_contract.js +90 -0
- package/dist/agent/runtime/checked_commands.d.ts +32 -0
- package/dist/agent/runtime/checked_commands.js +119 -0
- package/dist/agent/runtime/command_execution_policy.d.ts +26 -0
- package/dist/agent/runtime/command_execution_policy.js +91 -0
- package/dist/agent/runtime/command_jobs.d.ts +36 -18
- package/dist/agent/runtime/command_jobs.js +151 -13
- package/dist/agent/runtime/command_panes.d.ts +59 -0
- package/dist/agent/runtime/command_panes.js +398 -0
- package/dist/agent/runtime/command_wait.d.ts +19 -0
- package/dist/agent/runtime/command_wait.js +167 -0
- package/dist/agent/runtime/cpu_benchmark.d.ts +30 -0
- package/dist/agent/runtime/cpu_benchmark.js +126 -0
- package/dist/agent/runtime/delegated_evidence.d.ts +26 -0
- package/dist/agent/runtime/delegated_evidence.js +80 -0
- package/dist/agent/runtime/evidence.d.ts +127 -0
- package/dist/agent/runtime/evidence.js +468 -0
- package/dist/agent/runtime/execution_context.d.ts +7 -0
- package/dist/agent/runtime/execution_context.js +39 -3
- package/dist/agent/runtime/json_verifier_recipe.d.ts +8 -0
- package/dist/agent/runtime/json_verifier_recipe.js +66 -0
- package/dist/agent/runtime/measurements.d.ts +110 -0
- package/dist/agent/runtime/measurements.js +317 -0
- package/dist/agent/runtime/policy.d.ts +4 -0
- package/dist/agent/runtime/policy.js +31 -20
- package/dist/agent/runtime/provider_native_evidence.d.ts +20 -0
- package/dist/agent/runtime/provider_native_evidence.js +86 -0
- package/dist/agent/runtime/recovery.d.ts +2 -0
- package/dist/agent/runtime/recovery.js +45 -2
- package/dist/agent/runtime/remote_broker_transport.d.ts +10 -0
- package/dist/agent/runtime/remote_broker_transport.js +84 -0
- package/dist/agent/runtime/remote_deletion_receipts.d.ts +3 -0
- package/dist/agent/runtime/remote_deletion_receipts.js +43 -0
- package/dist/agent/runtime/remote_journal_replay.d.ts +13 -0
- package/dist/agent/runtime/remote_journal_replay.js +233 -0
- package/dist/agent/runtime/remote_mutation_journal.d.ts +25 -0
- package/dist/agent/runtime/remote_mutation_journal.js +208 -0
- package/dist/agent/runtime/remote_resource_endpoint.d.ts +7 -0
- package/dist/agent/runtime/remote_resource_endpoint.js +6 -0
- package/dist/agent/runtime/remote_resource_errors.d.ts +5 -0
- package/dist/agent/runtime/remote_resource_errors.js +9 -0
- package/dist/agent/runtime/remote_resource_script.d.ts +2 -0
- package/dist/agent/runtime/remote_resource_script.js +1009 -0
- package/dist/agent/runtime/remote_resources.d.ts +29 -0
- package/dist/agent/runtime/remote_resources.js +160 -0
- package/dist/agent/runtime/source_verification.d.ts +12 -0
- package/dist/agent/runtime/source_verification.js +210 -0
- package/dist/agent/runtime/source_verification_contract.d.ts +75 -0
- package/dist/agent/runtime/source_verification_contract.js +203 -0
- package/dist/agent/runtime/tool_checkpoints.d.ts +11 -0
- package/dist/agent/runtime/tool_checkpoints.js +26 -0
- package/dist/agent/runtime/tool_effects.d.ts +5 -0
- package/dist/agent/runtime/tool_progress.d.ts +12 -0
- package/dist/agent/runtime/tool_progress.js +76 -0
- package/dist/agent/runtime/tool_runtime.d.ts +16 -1
- package/dist/agent/runtime/tool_runtime.js +204 -10
- package/dist/agent/runtime/tracing.d.ts +1 -1
- package/dist/agent/runtime/verifier_capture.d.ts +9 -0
- package/dist/agent/runtime/verifier_capture.js +100 -0
- package/dist/agent/runtime/verifier_contract.d.ts +24 -0
- package/dist/agent/runtime/verifier_contract.js +41 -0
- package/dist/agent/subagent.d.ts +20 -10
- package/dist/agent/subagent.js +266 -29
- package/dist/agent/tool_response_directory.d.ts +24 -0
- package/dist/agent/tool_response_directory.js +61 -0
- package/dist/agent/tool_response_source.d.ts +8 -0
- package/dist/agent/tool_response_source.js +49 -0
- package/dist/agent/tool_response_store.d.ts +75 -4
- package/dist/agent/tool_response_store.js +583 -64
- package/dist/agent/tools/ask_user.d.ts +3 -1
- package/dist/agent/tools/ask_user.js +30 -11
- package/dist/agent/tools/background.js +1 -0
- package/dist/agent/tools/benchmark_cpu.d.ts +2 -0
- package/dist/agent/tools/benchmark_cpu.js +102 -0
- package/dist/agent/tools/compare_benchmarks.d.ts +2 -0
- package/dist/agent/tools/compare_benchmarks.js +53 -0
- package/dist/agent/tools/deferred.js +1 -0
- package/dist/agent/tools/delegate.js +18 -2
- package/dist/agent/tools/helper_requirements.d.ts +7 -0
- package/dist/agent/tools/helper_requirements.js +19 -0
- package/dist/agent/tools/index.d.ts +1 -0
- package/dist/agent/tools/index.js +3 -0
- package/dist/agent/tools/measurement_report.d.ts +22 -0
- package/dist/agent/tools/measurement_report.js +190 -0
- package/dist/agent/tools/pane.d.ts +0 -7
- package/dist/agent/tools/pane.js +5 -4
- package/dist/agent/tools/project_context.d.ts +3 -0
- package/dist/agent/tools/project_context.js +45 -0
- package/dist/agent/tools/recall_tool_response.d.ts +3 -5
- package/dist/agent/tools/recall_tool_response.js +19 -29
- package/dist/agent/tools/registry.d.ts +1 -0
- package/dist/agent/tools/registry.js +23 -0
- package/dist/agent/tools/related_sessions.d.ts +2 -0
- package/dist/agent/tools/related_sessions.js +156 -0
- package/dist/agent/tools/routine.js +13 -3
- package/dist/agent/tools/session_evidence.d.ts +3 -0
- package/dist/agent/tools/session_evidence.js +72 -0
- package/dist/agent/tools/shell.d.ts +4 -3
- package/dist/agent/tools/shell.js +174 -47
- package/dist/agent/tools/tool_search.js +3 -2
- package/dist/agent/tools/types.d.ts +28 -0
- package/dist/agent/tools/verify_artifact.d.ts +2 -0
- package/dist/agent/tools/verify_artifact.js +60 -0
- package/dist/agent/tools/workflow.js +1 -0
- package/dist/app/activity.d.ts +6 -1
- package/dist/app/activity.js +81 -12
- package/dist/app/agent_runner.d.ts +6 -1
- package/dist/app/agent_runner.js +34 -19
- package/dist/app/command_context.js +106 -10
- package/dist/app/controller.d.ts +15 -4
- package/dist/app/controller.js +29 -3
- package/dist/app/escape_stop.d.ts +11 -0
- package/dist/app/escape_stop.js +15 -0
- package/dist/app/liveness.d.ts +6 -4
- package/dist/app/liveness.js +13 -3
- package/dist/app/model_catalog_cache.d.ts +5 -0
- package/dist/app/model_catalog_cache.js +138 -0
- package/dist/app/ordered_transcript.js +43 -4
- package/dist/app/prompt_turn.d.ts +14 -0
- package/dist/app/prompt_turn.js +53 -0
- package/dist/app/recap.d.ts +3 -0
- package/dist/app/recap.js +9 -3
- package/dist/app/restart.d.ts +3 -2
- package/dist/app/restart.js +22 -7
- package/dist/app/rewind.d.ts +3 -3
- package/dist/app/rewind.js +3 -3
- package/dist/app/selection_completion.d.ts +17 -2
- package/dist/app/selection_completion.js +84 -9
- package/dist/app/session_manager.d.ts +38 -6
- package/dist/app/session_manager.js +263 -60
- package/dist/app/session_messages.d.ts +3 -0
- package/dist/app/session_messages.js +60 -0
- package/dist/app/task_scope_router.d.ts +20 -0
- package/dist/app/task_scope_router.js +173 -0
- package/dist/app/transcript_window.d.ts +2 -0
- package/dist/app/transcript_window.js +4 -0
- package/dist/app/workspace_admission_details.d.ts +3 -0
- package/dist/app/workspace_admission_details.js +26 -0
- package/dist/app/workspace_layout_controller.d.ts +11 -0
- package/dist/app/workspace_layout_controller.js +88 -0
- package/dist/app/workspace_monitor.d.ts +1 -0
- package/dist/app/workspace_monitor.js +216 -0
- package/dist/app/workspace_presets.d.ts +29 -0
- package/dist/app/workspace_presets.js +192 -0
- package/dist/attention/queue.d.ts +37 -0
- package/dist/attention/queue.js +183 -0
- package/dist/bench/rf_shared.d.ts +2 -0
- package/dist/board/binding.d.ts +42 -0
- package/dist/board/binding.js +38 -0
- package/dist/board/client.d.ts +42 -0
- package/dist/board/client.js +60 -0
- package/dist/cli.js +1 -1
- package/dist/cli_args.js +19 -17
- package/dist/cli_main.js +110 -13
- package/dist/cli_ratatui.d.ts +183 -16
- package/dist/cli_ratatui.js +3989 -1255
- package/dist/components/ActivityLine.d.ts +3 -2
- package/dist/components/ActivityLine.js +2 -2
- package/dist/components/InputArea.d.ts +19 -1
- package/dist/components/InputArea.js +264 -190
- package/dist/components/MessageList.d.ts +2 -0
- package/dist/components/MessageList.js +3 -1
- package/dist/components/SingleMessage.d.ts +2 -0
- package/dist/components/SingleMessage.js +4 -2
- package/dist/components/StatusBar.d.ts +4 -2
- package/dist/components/StatusBar.js +3 -1
- package/dist/conductor_branch.js +3 -0
- package/dist/config/api_retry.d.ts +6 -1
- package/dist/config/api_retry.js +19 -1
- package/dist/config/defaults.d.ts +2 -1
- package/dist/config/defaults.js +9 -2
- package/dist/config/message_display.d.ts +1 -0
- package/dist/config/message_display.js +17 -2
- package/dist/config/permissions.d.ts +21 -0
- package/dist/config/permissions.js +89 -0
- package/dist/config/resolved.d.ts +2 -2
- package/dist/config/types.d.ts +32 -5
- package/dist/config.d.ts +38 -4
- package/dist/config.js +290 -42
- package/dist/context/project_intelligence.d.ts +44 -0
- package/dist/context/project_intelligence.js +246 -0
- package/dist/desktop/cli_launch.d.ts +8 -0
- package/dist/desktop/cli_launch.js +6 -0
- package/dist/desktop/cli_shim.d.ts +8 -0
- package/dist/desktop/cli_shim.js +120 -0
- package/dist/desktop/runtime.d.ts +16 -0
- package/dist/desktop/runtime.js +161 -0
- package/dist/desktop/worker_launch.d.ts +7 -0
- package/dist/desktop/worker_launch.js +7 -0
- package/dist/diagnostics/cargo_mutants_selection.d.ts +27 -0
- package/dist/diagnostics/cargo_mutants_selection.js +48 -0
- package/dist/diagnostics/native_terminal_benchmark.d.ts +58 -0
- package/dist/diagnostics/native_terminal_benchmark.js +1247 -0
- package/dist/diagnostics/session_evidence_package.d.ts +40 -0
- package/dist/diagnostics/session_evidence_package.js +234 -0
- package/dist/diagnostics/session_export.d.ts +93 -0
- package/dist/diagnostics/session_export.js +634 -0
- package/dist/emulation/tool_adapters.js +48 -18
- package/dist/emulation/ztc_addendum.d.ts +1 -0
- package/dist/emulation/ztc_addendum.js +13 -12
- package/dist/environment/service_runner.d.ts +1 -0
- package/dist/environment/service_runner.js +68 -0
- package/dist/environment/store.d.ts +120 -0
- package/dist/environment/store.js +387 -0
- package/dist/events.d.ts +40 -1
- package/dist/events.js +10 -17
- package/dist/goal_contract.d.ts +25 -0
- package/dist/goal_contract.js +44 -0
- package/dist/headless.d.ts +31 -0
- package/dist/headless.js +578 -70
- package/dist/headless_cli.js +8 -0
- package/dist/headless_cli_args.d.ts +1 -0
- package/dist/headless_cli_args.js +1 -0
- package/dist/intake/cli.d.ts +1 -0
- package/dist/intake/cli.js +33 -0
- package/dist/intake/format.d.ts +2 -0
- package/dist/intake/format.js +14 -0
- package/dist/intake/notifications.d.ts +16 -0
- package/dist/intake/notifications.js +132 -0
- package/dist/intake/store.d.ts +56 -0
- package/dist/intake/store.js +238 -0
- package/dist/library.d.ts +8 -0
- package/dist/library.js +19 -10
- package/dist/mcp/client.d.ts +1 -0
- package/dist/mcp/client.js +20 -0
- package/dist/modes/builtin/plan.yaml +2 -2
- package/dist/modes/handlers.js +1 -1
- package/dist/onboarding/first_run.d.ts +3 -0
- package/dist/onboarding/first_run.js +33 -25
- package/dist/onboarding/setup.d.ts +32 -0
- package/dist/onboarding/setup.js +133 -0
- package/dist/onboarding/setup_agent_health.d.ts +17 -0
- package/dist/onboarding/setup_agent_health.js +79 -0
- package/dist/onboarding/setup_environment.d.ts +66 -0
- package/dist/onboarding/setup_environment.js +219 -0
- package/dist/onboarding/setup_workspace.d.ts +17 -0
- package/dist/onboarding/setup_workspace.js +129 -0
- package/dist/optimize/adapters/index.d.ts +4 -1
- package/dist/optimize/adapters/index.js +7 -0
- package/dist/optimize/adapters/kernelbench.js +14 -5
- package/dist/optimize/adapters/popcorn.js +3 -2
- package/dist/optimize/adapters/profile_benchmark.js +13 -7
- package/dist/optimize/adapters/rfbench.js +25 -14
- package/dist/optimize/adapters/types.d.ts +3 -0
- package/dist/optimize/adapters/zergpod.js +5 -2
- package/dist/optimize/baseline.js +10 -21
- package/dist/optimize/branch.js +9 -12
- package/dist/optimize/combine.js +2 -3
- package/dist/optimize/executor.js +34 -48
- package/dist/optimize/measurements.d.ts +55 -0
- package/dist/optimize/measurements.js +173 -0
- package/dist/optimize/results.d.ts +1 -0
- package/dist/optimize/results.js +11 -33
- package/dist/optimize/tge.js +2 -1
- package/dist/panes/initial_input.d.ts +19 -0
- package/dist/panes/initial_input.js +206 -0
- package/dist/panes/labels.d.ts +16 -0
- package/dist/panes/labels.js +42 -0
- package/dist/panes/model_catalog.d.ts +3 -3
- package/dist/panes/model_catalog.js +28 -4
- package/dist/panes/pane_registry.js +6 -2
- package/dist/panes/types.d.ts +3 -0
- package/dist/panes/ztc_launch.js +19 -0
- package/dist/plugin/optimization.d.ts +2 -0
- package/dist/plugin/optimization.js +1 -0
- package/dist/plugin/runtime.d.ts +2 -0
- package/dist/plugin/simulation.d.ts +6 -1
- package/dist/plugin/simulation_contract.d.ts +836 -1
- package/dist/plugin/simulation_documents.d.ts +22 -0
- package/dist/plugin/simulation_documents.js +1 -0
- package/dist/plugin/simulation_interventions.d.ts +103 -0
- package/dist/plugin/simulation_interventions.js +1 -0
- package/dist/plugin/simulation_living.d.ts +1 -0
- package/dist/plugin/simulation_living.js +3 -0
- package/dist/plugin/simulation_meetings.d.ts +121 -0
- package/dist/plugin/simulation_meetings.js +1 -0
- package/dist/plugin/simulation_story_review.d.ts +111 -0
- package/dist/plugin/simulation_story_review.js +1 -0
- package/dist/plugin/simulation_storyteller.d.ts +91 -0
- package/dist/plugin/simulation_storyteller.js +1 -0
- package/dist/plugin/simulation_structured.d.ts +2 -0
- package/dist/plugin/simulation_structured.js +2 -0
- package/dist/plugin/simulation_toolkit.d.ts +21 -0
- package/dist/plugin/simulation_toolkit.js +24 -0
- package/dist/prompts/tool_delegate_task.j2 +1 -1
- package/dist/remote-broker/Dockerfile +10 -0
- package/dist/remote-broker/archive.py +1227 -0
- package/dist/remote-broker/cutover.py +761 -0
- package/dist/remote-broker/requirements.txt +5 -0
- package/dist/remote-broker/resources.json +6 -0
- package/dist/remote-broker/resources.write-staging.example.json +18 -0
- package/dist/remote-broker/retained.py +686 -0
- package/dist/remote-broker/retained_cleanup.py +550 -0
- package/dist/remote-broker/server.py +648 -0
- package/dist/remote-broker/worker.py +1007 -0
- package/dist/router_auth.d.ts +31 -0
- package/dist/router_auth.js +155 -9
- package/dist/runbooks/catalog.d.ts +3 -0
- package/dist/runbooks/catalog.js +26 -0
- package/dist/runbooks/library.d.ts +11 -0
- package/dist/runbooks/library.js +95 -0
- package/dist/runbooks/package.d.ts +43 -0
- package/dist/runbooks/package.js +102 -0
- package/dist/session.d.ts +65 -13
- package/dist/session.js +548 -43
- package/dist/session_handoff.d.ts +25 -0
- package/dist/session_handoff.js +322 -0
- package/dist/session_handoff_contract.d.ts +89 -0
- package/dist/session_handoff_contract.js +179 -0
- package/dist/session_media.d.ts +41 -0
- package/dist/session_media.js +357 -0
- package/dist/session_ownership.d.ts +16 -0
- package/dist/session_ownership.js +221 -0
- package/dist/session_public.d.ts +10 -2
- package/dist/session_public.js +6 -1
- package/dist/simulation/dynamic_history.d.ts +42 -0
- package/dist/simulation/dynamic_history.js +173 -0
- package/dist/simulation/engines/swarm/pane_manager.js +7 -6
- package/dist/simulation/inference.d.ts +3 -1
- package/dist/simulation/inference.js +19 -1
- package/dist/simulation/intervention_generation.d.ts +27 -0
- package/dist/simulation/intervention_generation.js +246 -0
- package/dist/simulation/intervention_material.d.ts +4 -0
- package/dist/simulation/intervention_material.js +81 -0
- package/dist/simulation/living/context.d.ts +3130 -0
- package/dist/simulation/living/context.js +944 -0
- package/dist/simulation/living/definer.d.ts +12 -0
- package/dist/simulation/living/definer.js +223 -0
- package/dist/simulation/living/definition.d.ts +257 -0
- package/dist/simulation/living/definition.js +341 -0
- package/dist/simulation/living/frame.d.ts +259 -0
- package/dist/simulation/living/frame.js +223 -0
- package/dist/simulation/living/identifiers.d.ts +2 -0
- package/dist/simulation/living/identifiers.js +12 -0
- package/dist/simulation/living/index.d.ts +15 -0
- package/dist/simulation/living/index.js +15 -0
- package/dist/simulation/living/inference.d.ts +219 -0
- package/dist/simulation/living/inference.js +576 -0
- package/dist/simulation/living/mechanics.d.ts +54 -0
- package/dist/simulation/living/mechanics.js +588 -0
- package/dist/simulation/living/model-input.d.ts +25 -0
- package/dist/simulation/living/model-input.js +215 -0
- package/dist/simulation/living/open-world.d.ts +257 -0
- package/dist/simulation/living/open-world.js +102 -0
- package/dist/simulation/living/projection.d.ts +7 -0
- package/dist/simulation/living/projection.js +31 -0
- package/dist/simulation/living/recall.d.ts +17 -0
- package/dist/simulation/living/recall.js +25 -0
- package/dist/simulation/living/reduce.d.ts +15 -0
- package/dist/simulation/living/reduce.js +1853 -0
- package/dist/simulation/living/replay.d.ts +6 -0
- package/dist/simulation/living/replay.js +22 -0
- package/dist/simulation/living/runtime.d.ts +140 -0
- package/dist/simulation/living/runtime.js +3020 -0
- package/dist/simulation/living/shared-kinds.d.ts +24 -0
- package/dist/simulation/living/shared-kinds.js +96 -0
- package/dist/simulation/living/types.d.ts +2785 -0
- package/dist/simulation/living/types.js +669 -0
- package/dist/simulation/llm.d.ts +3 -1
- package/dist/simulation/llm.js +90 -30
- package/dist/simulation/memory/embedding.d.ts +1 -1
- package/dist/simulation/memory/embedding.js +9 -3
- package/dist/simulation/memory/filesystem.d.ts +2 -0
- package/dist/simulation/memory/filesystem.js +5 -1
- package/dist/simulation/memory/filesystem_file_tree.d.ts +4 -1
- package/dist/simulation/memory/filesystem_file_tree.js +41 -10
- package/dist/simulation/memory/filesystem_invariants.js +1 -2
- package/dist/simulation/memory/filesystem_types.d.ts +1 -0
- package/dist/simulation/memory/memory.d.ts +2 -0
- package/dist/simulation/memory/memory.js +5 -1
- package/dist/simulation/orchestration/intent.js +0 -2
- package/dist/simulation/orchestration/lifecycle.js +0 -2
- package/dist/simulation/plugin_host.d.ts +25 -1
- package/dist/simulation/plugin_host.js +334 -17
- package/dist/simulation/session_documents.d.ts +20 -0
- package/dist/simulation/session_documents.js +62 -0
- package/dist/simulation/session_input_validation.d.ts +43 -0
- package/dist/simulation/session_input_validation.js +364 -0
- package/dist/simulation/session_inputs.d.ts +32 -0
- package/dist/simulation/session_inputs.js +154 -0
- package/dist/simulation/telemetry.d.ts +11 -14
- package/dist/simulation/telemetry.js +177 -54
- package/dist/simulation/toolkit/bounded_turns.d.ts +13 -0
- package/dist/simulation/toolkit/bounded_turns.js +80 -0
- package/dist/simulation/toolkit/dynamic_agents.d.ts +25 -0
- package/dist/simulation/toolkit/dynamic_agents.js +218 -0
- package/dist/simulation/toolkit/dynamic_digest.d.ts +1 -0
- package/dist/simulation/toolkit/dynamic_digest.js +8 -0
- package/dist/simulation/toolkit/dynamic_documents.d.ts +7 -0
- package/dist/simulation/toolkit/dynamic_documents.js +71 -0
- package/dist/simulation/toolkit/dynamic_driver.d.ts +8 -0
- package/dist/simulation/toolkit/dynamic_driver.js +269 -0
- package/dist/simulation/toolkit/dynamic_game.d.ts +53 -0
- package/dist/simulation/toolkit/dynamic_game.js +805 -0
- package/dist/simulation/toolkit/dynamic_knowledge.d.ts +15 -0
- package/dist/simulation/toolkit/dynamic_knowledge.js +91 -0
- package/dist/simulation/toolkit/dynamic_mechanics.d.ts +22 -0
- package/dist/simulation/toolkit/dynamic_mechanics.js +910 -0
- package/dist/simulation/toolkit/dynamic_meetings.d.ts +239 -0
- package/dist/simulation/toolkit/dynamic_meetings.js +350 -0
- package/dist/simulation/toolkit/dynamic_progress.d.ts +131 -0
- package/dist/simulation/toolkit/dynamic_progress.js +214 -0
- package/dist/simulation/toolkit/dynamic_projection.d.ts +9 -0
- package/dist/simulation/toolkit/dynamic_projection.js +219 -0
- package/dist/simulation/toolkit/dynamic_runtime.d.ts +412 -0
- package/dist/simulation/toolkit/dynamic_runtime.js +6536 -0
- package/dist/simulation/toolkit/dynamic_state.d.ts +111 -0
- package/dist/simulation/toolkit/dynamic_state.js +1967 -0
- package/dist/simulation/toolkit/dynamic_story_review.d.ts +508 -0
- package/dist/simulation/toolkit/dynamic_story_review.js +333 -0
- package/dist/simulation/toolkit/dynamic_storyteller.d.ts +77 -0
- package/dist/simulation/toolkit/dynamic_storyteller.js +114 -0
- package/dist/simulation/toolkit/dynamic_storyteller_runtime.d.ts +26 -0
- package/dist/simulation/toolkit/dynamic_storyteller_runtime.js +126 -0
- package/dist/simulation/toolkit/dynamic_world.d.ts +22 -0
- package/dist/simulation/toolkit/dynamic_world.js +377 -0
- package/dist/simulation/toolkit/structured_output.d.ts +5 -0
- package/dist/simulation/toolkit/structured_output.js +321 -0
- package/dist/simulation/types/world.d.ts +2 -0
- package/dist/simulation/world/artifact_store.js +1 -1
- package/dist/simulation/world/memory_manager.d.ts +5 -0
- package/dist/simulation/world/memory_manager.js +17 -2
- package/dist/simulation/world/state.d.ts +3 -2
- package/dist/simulation/world/state.js +15 -5
- package/dist/skills/bundled/measurement-validation/SKILL.md +144 -0
- package/dist/terminal_attach.d.ts +1 -0
- package/dist/terminal_attach.js +113 -0
- package/dist/tool_progress.d.ts +3 -0
- package/dist/tool_progress.js +27 -0
- package/dist/types.d.ts +145 -10
- package/dist/types.js +3 -0
- package/dist/ui/core/input.d.ts +3 -0
- package/dist/ui/core/input_segments.d.ts +18 -1
- package/dist/ui/core/input_segments.js +131 -47
- package/dist/ui/core/input_state.d.ts +12 -0
- package/dist/ui/core/layout_yoga.d.ts +1 -1
- package/dist/ui/core/turn_metadata.d.ts +5 -0
- package/dist/ui/core/turn_metadata.js +22 -0
- package/dist/ui/ink/render.d.ts +2 -1
- package/dist/ui/ink/render.js +6 -5
- package/dist/ui/ratatui/headless_pane_manager.d.ts +14 -1
- package/dist/ui/ratatui/headless_pane_manager.js +293 -104
- package/dist/ui/ratatui/index.d.ts +1 -0
- package/dist/ui/ratatui/input.d.ts +4 -0
- package/dist/ui/ratatui/input.js +15 -0
- package/dist/ui/ratatui/ipc_path.d.ts +2 -0
- package/dist/ui/ratatui/ipc_path.js +29 -1
- package/dist/ui/ratatui/mux_persistence.d.ts +3 -1
- package/dist/ui/ratatui/mux_persistence.js +139 -1
- package/dist/ui/ratatui/pane_relay.d.ts +1 -1
- package/dist/ui/ratatui/pane_relay.js +55 -27
- package/dist/ui/ratatui/process.d.ts +17 -1
- package/dist/ui/ratatui/process.js +80 -7
- package/dist/ui/ratatui/protocol.d.ts +236 -1
- package/dist/ui/ratatui/protocol.js +90 -0
- package/dist/ui/scrollback.d.ts +2 -1
- package/dist/ui/scrollback.js +9 -4
- package/dist/ui/stream_typewriter.d.ts +8 -3
- package/dist/ui/stream_typewriter.js +30 -1
- package/dist/ui/streaming_scrollback.d.ts +1 -0
- package/dist/ui/streaming_scrollback.js +1 -1
- package/dist/ui/transcript_render_cache.js +10 -0
- package/dist/ui/views/activity_line.d.ts +5 -3
- package/dist/ui/views/activity_line.js +65 -7
- package/dist/ui/views/app.d.ts +6 -3
- package/dist/ui/views/app.js +17 -6
- package/dist/ui/views/completion_menu.js +10 -5
- package/dist/ui/views/input_area.d.ts +7 -3
- package/dist/ui/views/input_area.js +15 -9
- package/dist/ui/views/message_list.d.ts +4 -1
- package/dist/ui/views/message_list.js +89 -19
- package/dist/ui/views/queue_panel.d.ts +3 -1
- package/dist/ui/views/queue_panel.js +9 -2
- package/dist/ui/views/status_bar.d.ts +4 -2
- package/dist/ui/views/status_bar.js +28 -13
- package/dist/ui/views/theme.d.ts +2 -0
- package/dist/ui/views/theme.js +2 -0
- package/dist/ui/widgets/color_panel.js +18 -0
- package/dist/ui/widgets/form.js +8 -0
- package/dist/ui/widgets/log_view.js +7 -0
- package/dist/ui/widgets/navigator_panel.js +8 -0
- package/dist/ui/widgets/prompt_viewer.js +2 -0
- package/dist/ui/widgets/questionnaire.d.ts +2 -0
- package/dist/ui/widgets/questionnaire.js +79 -16
- package/dist/ui/widgets/resume_panel.d.ts +2 -0
- package/dist/ui/widgets/resume_panel.js +26 -15
- package/dist/ui/widgets/rewind_panel.d.ts +2 -2
- package/dist/ui/widgets/rewind_panel.js +4 -2
- package/dist/ui/widgets/select.js +16 -27
- package/dist/ui/widgets/settings_panel.js +16 -0
- package/dist/ui/widgets/status_line_panel.d.ts +1 -0
- package/dist/ui/widgets/status_line_panel.js +30 -4
- package/dist/ui/widgets/text_input.d.ts +2 -0
- package/dist/ui/widgets/text_input.js +15 -1
- package/dist/ui/widgets/types.d.ts +2 -0
- package/dist/usage_projection.d.ts +24 -0
- package/dist/usage_projection.js +130 -0
- package/dist/usage_snapshot.d.ts +36 -0
- package/dist/usage_snapshot.js +131 -0
- package/dist/utils/assistant_message.d.ts +2 -0
- package/dist/utils/assistant_message.js +5 -0
- package/dist/utils/atomic_write.d.ts +6 -2
- package/dist/utils/atomic_write.js +29 -4
- package/dist/utils/checked_shell.d.ts +25 -0
- package/dist/utils/checked_shell.js +107 -0
- package/dist/utils/compaction.d.ts +4 -1
- package/dist/utils/compaction.js +31 -7
- package/dist/utils/context.d.ts +4 -4
- package/dist/utils/context.js +14 -12
- package/dist/utils/deepseek.d.ts +2 -2
- package/dist/utils/deepseek.js +13 -5
- package/dist/utils/ephemeral.js +4 -0
- package/dist/utils/ephemeral_tools.d.ts +18 -0
- package/dist/utils/ephemeral_tools.js +97 -0
- package/dist/utils/jev_client.d.ts +4 -0
- package/dist/utils/jev_client.js +15 -0
- package/dist/utils/model_cache.d.ts +15 -0
- package/dist/utils/model_cache.js +143 -0
- package/dist/utils/models.d.ts +4 -2
- package/dist/utils/models.js +12 -16
- package/dist/utils/reasoning.d.ts +8 -1
- package/dist/utils/reasoning.js +31 -11
- package/dist/utils/router_catalog.d.ts +49 -0
- package/dist/utils/router_catalog.js +271 -0
- package/dist/utils/sandbox.d.ts +9 -0
- package/dist/utils/sandbox.js +118 -15
- package/dist/utils/shell.d.ts +7 -0
- package/dist/utils/shell.js +98 -34
- package/dist/utils/subprocess_env.d.ts +3 -0
- package/dist/utils/subprocess_env.js +27 -1
- package/dist/web/accounts_mirror.d.ts +3 -1
- package/dist/web/accounts_mirror.js +13 -9
- package/dist/web/child_publication.d.ts +17 -0
- package/dist/web/child_publication.js +45 -0
- package/dist/web/mirror_authenticator.d.ts +31 -11
- package/dist/web/mirror_authenticator.js +67 -17
- package/dist/web/mirror_client.d.ts +31 -4
- package/dist/web/mirror_client.js +189 -23
- package/dist/web/mirror_stream.d.ts +84 -22
- package/dist/web/mirror_stream.js +676 -95
- package/dist/web/observer_query_redaction.d.ts +6 -0
- package/dist/web/observer_query_redaction.js +58 -0
- package/dist/web/pane_registry.d.ts +2 -0
- package/dist/web/pane_registry.js +86 -22
- package/dist/web/tool_image.d.ts +6 -0
- package/dist/web/tool_image.js +17 -0
- package/dist/web/view_plugin.d.ts +14 -0
- package/dist/web/view_plugin.js +23 -1
- package/dist/worker/executor.js +31 -12
- package/dist/worker/index.d.ts +1 -0
- package/dist/worker/toolsets.js +3 -1
- package/dist/worker/types.d.ts +12 -1
- package/dist/workflows/registry.js +1 -0
- package/dist/workflows/registry_handle.d.ts +2 -0
- package/dist/workflows/runtime.d.ts +2 -0
- package/dist/workflows/runtime.js +1 -0
- package/dist/workspace_agent.d.ts +7 -0
- package/dist/workspace_agent.js +36 -0
- package/dist/workspace_collision.d.ts +76 -0
- package/dist/workspace_collision.js +688 -0
- package/dist/workspace_layout.d.ts +18 -0
- package/dist/workspace_layout.js +121 -0
- package/dist/workspace_runtime.d.ts +44 -0
- package/dist/workspace_runtime.js +82 -0
- package/dist/workspace_session_context.d.ts +62 -0
- package/dist/workspace_session_context.js +160 -0
- package/dist/zlm-embed.mjs +32518 -9615
- package/dist/zlm.js +1 -0
- package/node_modules/@zerg/model-contracts/LICENSE.md +375 -0
- package/node_modules/@zerg/model-contracts/README.md +90 -0
- package/node_modules/@zerg/model-contracts/index.d.ts +20 -0
- package/node_modules/@zerg/model-contracts/index.js +223 -0
- package/node_modules/@zerg/model-contracts/package.json +8 -0
- package/node_modules/glob/node_modules/brace-expansion/index.js +78 -22
- package/node_modules/glob/node_modules/brace-expansion/package.json +1 -1
- package/node_modules/readdir-glob/node_modules/brace-expansion/index.js +78 -22
- package/node_modules/readdir-glob/node_modules/brace-expansion/package.json +1 -1
- package/package.json +45 -24
- package/packages/model-contracts/LICENSE.md +375 -0
- package/packages/model-contracts/README.md +90 -0
- package/packages/model-contracts/index.d.ts +20 -0
- package/packages/model-contracts/index.js +223 -0
- package/packages/model-contracts/package.json +8 -0
- package/remote-broker/Dockerfile +10 -0
- package/remote-broker/README.md +308 -0
- package/remote-broker/archive.py +1227 -0
- package/remote-broker/cutover.py +761 -0
- package/remote-broker/requirements.txt +5 -0
- package/remote-broker/resources.example.json +6 -0
- package/remote-broker/resources.write-staging.example.json +18 -0
- package/remote-broker/retained.py +686 -0
- package/remote-broker/retained_cleanup.py +550 -0
- package/remote-broker/server.py +648 -0
- package/scripts/build-remote-broker.mjs +13 -0
- package/scripts/ensure-local-packages.mjs +6 -0
- package/scripts/node-pty-helpers.mjs +103 -0
|
@@ -3,6 +3,7 @@ import React, { useReducer, useCallback } from 'react';
|
|
|
3
3
|
import { useInput, useStdout, useApp } from 'ink';
|
|
4
4
|
import { InkNode } from '../ui/ink/index.js';
|
|
5
5
|
import { buildInputAreaView, wrapInputSegments } from '../ui/views/input_area.js';
|
|
6
|
+
import { PLAN_ACCENT } from '../ui/views/theme.js';
|
|
6
7
|
import { moveVertical } from '../ui/core/input_segments.js';
|
|
7
8
|
import { debugLog } from '../debug/logger.js';
|
|
8
9
|
import chalk from 'chalk';
|
|
@@ -16,7 +17,7 @@ import { maybeFilterFillers } from '../utils/dictation_filter.js';
|
|
|
16
17
|
const useNative = isNativeDictationAvailable();
|
|
17
18
|
const isRecording = () => useNative ? isNativeRecording() : isLegacyRecording();
|
|
18
19
|
const isDictationAvailable = () => useNative ? true : isLegacyDictationAvailable();
|
|
19
|
-
import { createEmptyState, insertText, insertBadge, backspace, deleteForward, moveLeft, moveRight, moveWordLeft, moveWordRight, getPlainText, serializeSegments, PASTE_BADGE_THRESHOLD } from '../ui/core/input_segments.js';
|
|
20
|
+
import { createEmptyState, historyUp, historyDown, recordInputHistory, killInputDraft, yankInputKill, getInputShortcutHint, insertText, insertBadge, expandPasteBadge, backspace, deleteForward, moveLeft, moveRight, moveWordLeft, moveWordRight, getPlainText, serializeSegments, PASTE_BADGE_THRESHOLD } from '../ui/core/input_segments.js';
|
|
20
21
|
// Helper to check for Ctrl key combinations
|
|
21
22
|
// Handles multiple formats:
|
|
22
23
|
// 1. Ink's key.ctrl + letter
|
|
@@ -44,56 +45,34 @@ function reducer(state, action) {
|
|
|
44
45
|
switch (action.type) {
|
|
45
46
|
case 'apply':
|
|
46
47
|
return { ...state, ...action.state };
|
|
47
|
-
case 'submit':
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
return {
|
|
52
|
-
...state,
|
|
53
|
-
segments: [],
|
|
54
|
-
cursor: { index: 0, offset: 0 },
|
|
55
|
-
historyIdx: -1,
|
|
56
|
-
history
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
case 'history_nav': {
|
|
60
|
-
if (!action.historyEnabled || state.history.length === 0)
|
|
61
|
-
return state;
|
|
62
|
-
let newIdx;
|
|
63
|
-
if (action.direction === 'up') {
|
|
64
|
-
newIdx = state.historyIdx === -1
|
|
65
|
-
? state.history.length - 1
|
|
66
|
-
: Math.max(0, state.historyIdx - 1);
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
newIdx = state.historyIdx === -1 ? -1 : state.historyIdx + 1;
|
|
70
|
-
if (newIdx >= state.history.length)
|
|
71
|
-
newIdx = -1;
|
|
72
|
-
}
|
|
73
|
-
if (newIdx === -1) {
|
|
74
|
-
return { ...state, historyIdx: -1, segments: [], cursor: { index: 0, offset: 0 } };
|
|
75
|
-
}
|
|
76
|
-
const historyValue = state.history[newIdx];
|
|
77
|
-
const nextSegments = historyValue.length > 0
|
|
78
|
-
? [{ type: 'text', text: historyValue }]
|
|
79
|
-
: [];
|
|
80
|
-
return {
|
|
81
|
-
...state,
|
|
82
|
-
historyIdx: newIdx,
|
|
83
|
-
segments: nextSegments,
|
|
84
|
-
cursor: { index: nextSegments.length ? 0 : 0, offset: historyValue.length }
|
|
85
|
-
};
|
|
86
|
-
}
|
|
48
|
+
case 'submit':
|
|
49
|
+
return recordInputHistory(state, action.historyEnabled ? action.historyEntry : undefined, 101);
|
|
50
|
+
case 'history_nav':
|
|
51
|
+
return !action.historyEnabled ? state : action.direction === 'up' ? historyUp(state) : historyDown(state);
|
|
87
52
|
default:
|
|
88
53
|
return state;
|
|
89
54
|
}
|
|
90
55
|
}
|
|
91
|
-
export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, onToast, onDictationStateChange, cols = process.stdout.columns || 80, inputBus, disabled = false, placeholder = 'Type a message...', historyEnabled = true, debug = false, cwd = process.cwd(), spinnerLabel, spinnerFrame, passwordMode = false, onCycleMode, }) => {
|
|
56
|
+
export const InputArea = ({ onSubmit, onCancelRun, isRunning = false, onQueue, onCommand, commands = [], onStateChange, onToast, onDictationStateChange, cols = process.stdout.columns || 80, inputBus, clearDraftVersion = 0, disabled = false, mode = 'normal', inputBlocked, placeholder = 'Type a message...', historyEnabled: requestedHistoryEnabled = true, debug = false, cwd = process.cwd(), spinnerLabel, spinnerFrame, passwordMode = false, promptOwner, allowEmptySubmit = false, onCycleMode, }) => {
|
|
57
|
+
// Password ownership never retains or recalls ordinary composer history.
|
|
58
|
+
const historyEnabled = requestedHistoryEnabled && !passwordMode;
|
|
92
59
|
const [state, dispatch] = useReducer(reducer, initialState);
|
|
60
|
+
const clearDraftVersionRef = React.useRef(clearDraftVersion);
|
|
93
61
|
const stateRef = React.useRef(state);
|
|
62
|
+
const draftRevisionRef = React.useRef(0);
|
|
63
|
+
const draftSegmentsRef = React.useRef(state.segments);
|
|
64
|
+
if (process.env.ZTC_INPUT_OVERLAY !== '1' && draftSegmentsRef.current !== state.segments) {
|
|
65
|
+
draftSegmentsRef.current = state.segments;
|
|
66
|
+
draftRevisionRef.current += 1;
|
|
67
|
+
}
|
|
94
68
|
const [badgePreview, setBadgePreview] = React.useState(null);
|
|
95
69
|
const killRingRef = React.useRef([]);
|
|
96
70
|
const killIndexRef = React.useRef(-1);
|
|
71
|
+
const passwordKillRingRef = React.useRef([]);
|
|
72
|
+
const passwordKillIndexRef = React.useRef(-1);
|
|
73
|
+
const activeKillRingRef = passwordMode ? passwordKillRingRef : killRingRef;
|
|
74
|
+
const activeKillIndexRef = passwordMode ? passwordKillIndexRef : killIndexRef;
|
|
75
|
+
const passwordOwnershipRef = React.useRef(null);
|
|
97
76
|
const dictationBusyRef = React.useRef(false);
|
|
98
77
|
// Bracketed paste mode support - buffer paste content between \x1b[200~ and \x1b[201~
|
|
99
78
|
const pasteBufferRef = React.useRef('');
|
|
@@ -138,34 +117,34 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
138
117
|
const pushKill = useCallback((text, next) => {
|
|
139
118
|
if (!text)
|
|
140
119
|
return;
|
|
141
|
-
const ring =
|
|
120
|
+
const ring = activeKillRingRef.current;
|
|
142
121
|
ring.unshift(text);
|
|
143
122
|
if (ring.length > 20)
|
|
144
123
|
ring.pop();
|
|
145
|
-
|
|
124
|
+
activeKillIndexRef.current = 0;
|
|
146
125
|
// A kill that empties the composer reads as losing the prompt — Ctrl+U/Ctrl+K
|
|
147
126
|
// and Ghostty's Cmd+Backspace (encoded as Ctrl+U) all land here. The text is
|
|
148
127
|
// still in the kill ring, so say which key brings it back. Mirrors the
|
|
149
128
|
// Ratatui composer's notice.
|
|
150
129
|
if (next && next.segments.length === 0)
|
|
151
130
|
onToast?.('Cleared · Ctrl+Y restores');
|
|
152
|
-
}, [onToast]);
|
|
131
|
+
}, [activeKillRingRef, activeKillIndexRef, onToast]);
|
|
153
132
|
const yank = useCallback((current) => {
|
|
154
|
-
const ring =
|
|
133
|
+
const ring = activeKillRingRef.current;
|
|
155
134
|
if (ring.length === 0)
|
|
156
135
|
return current;
|
|
157
|
-
const next =
|
|
136
|
+
const next = yankInputKill(current, ring[0]);
|
|
158
137
|
return { ...next, historyIdx: -1 };
|
|
159
|
-
}, []);
|
|
138
|
+
}, [activeKillRingRef]);
|
|
160
139
|
const yankPop = useCallback((current) => {
|
|
161
|
-
const ring =
|
|
140
|
+
const ring = activeKillRingRef.current;
|
|
162
141
|
if (ring.length === 0)
|
|
163
142
|
return current;
|
|
164
|
-
const idx =
|
|
165
|
-
|
|
166
|
-
const next =
|
|
143
|
+
const idx = activeKillIndexRef.current === -1 ? 0 : (activeKillIndexRef.current + 1) % ring.length;
|
|
144
|
+
activeKillIndexRef.current = idx;
|
|
145
|
+
const next = yankInputKill(current, ring[idx]);
|
|
167
146
|
return { ...next, historyIdx: -1 };
|
|
168
|
-
}, []);
|
|
147
|
+
}, [activeKillRingRef, activeKillIndexRef]);
|
|
169
148
|
const killToStart = useCallback((current) => {
|
|
170
149
|
const segments = [...current.segments];
|
|
171
150
|
const cursor = current.cursor;
|
|
@@ -175,7 +154,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
175
154
|
const killed = seg.text.slice(0, cursor.offset);
|
|
176
155
|
seg.text = seg.text.slice(cursor.offset);
|
|
177
156
|
return {
|
|
178
|
-
next: { ...current, segments, cursor: { index: cursor.index, offset: 0 }
|
|
157
|
+
next: { ...current, segments, cursor: { index: cursor.index, offset: 0 } },
|
|
179
158
|
killed
|
|
180
159
|
};
|
|
181
160
|
}, []);
|
|
@@ -188,7 +167,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
188
167
|
const killed = seg.text.slice(cursor.offset);
|
|
189
168
|
seg.text = seg.text.slice(0, cursor.offset);
|
|
190
169
|
return {
|
|
191
|
-
next: { ...current, segments, cursor: { index: cursor.index, offset: seg.text.length }
|
|
170
|
+
next: { ...current, segments, cursor: { index: cursor.index, offset: seg.text.length } },
|
|
192
171
|
killed
|
|
193
172
|
};
|
|
194
173
|
}, []);
|
|
@@ -206,7 +185,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
206
185
|
const killed = before.slice(killStart);
|
|
207
186
|
seg.text = before.slice(0, killStart) + after;
|
|
208
187
|
return {
|
|
209
|
-
next: { ...current, segments, cursor: { index: cursor.index, offset: killStart }
|
|
188
|
+
next: { ...current, segments, cursor: { index: cursor.index, offset: killStart } },
|
|
210
189
|
killed
|
|
211
190
|
};
|
|
212
191
|
}, []);
|
|
@@ -222,7 +201,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
222
201
|
const killed = match ? match[1] : '';
|
|
223
202
|
seg.text = before + after.slice(killed.length);
|
|
224
203
|
return {
|
|
225
|
-
next: { ...current, segments, cursor
|
|
204
|
+
next: { ...current, segments, cursor },
|
|
226
205
|
killed
|
|
227
206
|
};
|
|
228
207
|
}, []);
|
|
@@ -241,7 +220,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
241
220
|
chars[idx] = chars[idx + 1];
|
|
242
221
|
chars[idx + 1] = a;
|
|
243
222
|
seg.text = chars.join('');
|
|
244
|
-
return { ...current, segments, cursor: { index: cursor.index, offset: Math.min(text.length, cursor.offset + 1) }
|
|
223
|
+
return { ...current, segments, cursor: { index: cursor.index, offset: Math.min(text.length, cursor.offset + 1) } };
|
|
245
224
|
}, []);
|
|
246
225
|
const transposeWords = useCallback((current) => {
|
|
247
226
|
const segments = [...current.segments];
|
|
@@ -262,7 +241,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
262
241
|
const rightEnd = rightMatch[0].length;
|
|
263
242
|
const replacedLeft = left.slice(0, leftStart) + rightWord;
|
|
264
243
|
seg.text = replacedLeft + right.slice(rightEnd);
|
|
265
|
-
return { ...current, segments, cursor: { index: cursor.index, offset: replacedLeft.length }
|
|
244
|
+
return { ...current, segments, cursor: { index: cursor.index, offset: replacedLeft.length } };
|
|
266
245
|
}, []);
|
|
267
246
|
// Tab completion state
|
|
268
247
|
const tabCompletionAlternativesRef = React.useRef([]);
|
|
@@ -282,7 +261,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
282
261
|
const completed = alts[nextIdx];
|
|
283
262
|
const newText = `/${completed}`;
|
|
284
263
|
const newSegments = [{ type: 'text', text: newText }];
|
|
285
|
-
return { ...current, segments: newSegments, cursor: { index: 0, offset: newText.length }
|
|
264
|
+
return { ...current, segments: newSegments, cursor: { index: 0, offset: newText.length } };
|
|
286
265
|
}
|
|
287
266
|
const matches = commands.filter(c => c.name.startsWith(prefix));
|
|
288
267
|
if (matches.length === 0)
|
|
@@ -296,7 +275,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
296
275
|
if (matches.length > 1) {
|
|
297
276
|
onToast?.(formatCommandCompletionPreview(matches));
|
|
298
277
|
}
|
|
299
|
-
return { ...current, segments: newSegments, cursor: { index: 0, offset: newText.length }
|
|
278
|
+
return { ...current, segments: newSegments, cursor: { index: 0, offset: newText.length } };
|
|
300
279
|
}
|
|
301
280
|
// Only complete if this looks like a shell command with a path
|
|
302
281
|
// Match: !cd path, !ls path, !cat path, etc.
|
|
@@ -337,7 +316,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
337
316
|
...current,
|
|
338
317
|
segments: newSegments,
|
|
339
318
|
cursor: { index: 0, offset: newText.length },
|
|
340
|
-
historyIdx:
|
|
319
|
+
historyIdx: current.historyIdx
|
|
341
320
|
};
|
|
342
321
|
}, [cwd, onToast]);
|
|
343
322
|
const inputRenderCount = React.useRef(0);
|
|
@@ -348,7 +327,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
348
327
|
});
|
|
349
328
|
const handleSubmit = useCallback(() => {
|
|
350
329
|
const serialized = serializeSegments(state.segments).trim();
|
|
351
|
-
if (!serialized)
|
|
330
|
+
if (!serialized && !allowEmptySubmit)
|
|
352
331
|
return;
|
|
353
332
|
const plainText = getPlainText(state.segments).trim();
|
|
354
333
|
const isCommand = state.segments.length === 1 && state.segments[0].type === 'text' && plainText.startsWith('/');
|
|
@@ -367,24 +346,51 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
367
346
|
onCommand?.(cmd, args);
|
|
368
347
|
}
|
|
369
348
|
else {
|
|
370
|
-
|
|
349
|
+
const saved = structuredClone(state);
|
|
350
|
+
const submittedRevision = draftRevisionRef.current;
|
|
351
|
+
onSubmit(serialized, { restore: () => {
|
|
352
|
+
if (draftRevisionRef.current !== submittedRevision + 1)
|
|
353
|
+
return false;
|
|
354
|
+
draftRevisionRef.current += 1;
|
|
355
|
+
dispatch({ type: 'apply', state: { segments: saved.segments, cursor: saved.cursor, historyIdx: -1 } });
|
|
356
|
+
return true;
|
|
357
|
+
} });
|
|
371
358
|
}
|
|
372
359
|
dispatch({ type: 'submit', historyEnabled, historyEntry: serialized });
|
|
373
|
-
}, [state.segments, onSubmit, onCommand, historyEnabled]);
|
|
360
|
+
}, [state.segments, onSubmit, onCommand, historyEnabled, allowEmptySubmit]);
|
|
374
361
|
const navigateHistory = useCallback((direction) => {
|
|
375
362
|
dispatch({ type: 'history_nav', direction, historyEnabled });
|
|
376
363
|
}, [historyEnabled]);
|
|
377
364
|
const { stdout } = useStdout();
|
|
378
365
|
const { exit } = useApp();
|
|
366
|
+
const clearComposer = useCallback((current) => {
|
|
367
|
+
if (onCancelRun?.())
|
|
368
|
+
return null;
|
|
369
|
+
if (current.segments.length === 0) {
|
|
370
|
+
exit();
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
const kill = killInputDraft(current);
|
|
374
|
+
killRingRef.current.unshift(kill.killed);
|
|
375
|
+
if (killRingRef.current.length > 20)
|
|
376
|
+
killRingRef.current.pop();
|
|
377
|
+
killIndexRef.current = 0;
|
|
378
|
+
onToast?.('Cleared · Ctrl+Y restores');
|
|
379
|
+
return kill.state;
|
|
380
|
+
}, [onCancelRun, onToast, exit]);
|
|
379
381
|
const overlayEnabled = process.env.ZTC_INPUT_OVERLAY === '1';
|
|
380
382
|
const overlayStateRef = React.useRef(initialState);
|
|
381
383
|
const overlayBusyRef = React.useRef(false);
|
|
382
384
|
const insertTextIntoState = useCallback((text) => {
|
|
383
385
|
const current = stateRef.current;
|
|
384
386
|
const next = insertText(current, text);
|
|
385
|
-
dispatch({ type: 'apply', state: { ...next
|
|
387
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
386
388
|
}, []);
|
|
387
389
|
const renderOverlay = useCallback((overlayState) => {
|
|
390
|
+
if (draftSegmentsRef.current !== overlayState.segments) {
|
|
391
|
+
draftSegmentsRef.current = overlayState.segments;
|
|
392
|
+
draftRevisionRef.current += 1;
|
|
393
|
+
}
|
|
388
394
|
if (!stdout || !stdout.isTTY)
|
|
389
395
|
return;
|
|
390
396
|
if (overlayBusyRef.current)
|
|
@@ -393,12 +399,23 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
393
399
|
const rows = stdout.rows || 24;
|
|
394
400
|
const statusHeight = 1;
|
|
395
401
|
const cols = stdout.columns || 80;
|
|
396
|
-
|
|
402
|
+
let visibleOverlayState = overlayState;
|
|
403
|
+
if (passwordMode) {
|
|
404
|
+
visibleOverlayState = {
|
|
405
|
+
...overlayState,
|
|
406
|
+
segments: overlayState.segments.map(segment => segment.type === 'text'
|
|
407
|
+
? { ...segment, text: '•'.repeat(segment.text.length) } : segment),
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
const wrapped = wrapInputSegments(visibleOverlayState.segments, visibleOverlayState.cursor, cols);
|
|
397
411
|
const inputLines = Math.max(1, wrapped.lines.length);
|
|
398
|
-
const
|
|
412
|
+
const plan = mode === 'plan';
|
|
413
|
+
const inputHeight = inputLines + 4 + (plan ? 1 : 0);
|
|
399
414
|
const startRow = Math.max(1, rows - (inputHeight + statusHeight) + 1);
|
|
400
|
-
const prompt = disabled ? chalk.gray('❯ ') : chalk.blue('❯ ');
|
|
415
|
+
const prompt = plan ? chalk.hex(PLAN_ACCENT).bold('❯ ') : disabled ? chalk.gray('❯ ') : chalk.blue('❯ ');
|
|
401
416
|
const lines = [];
|
|
417
|
+
if (plan)
|
|
418
|
+
lines.push(chalk.bold(' PLAN ') + chalk.hex(PLAN_ACCENT)('─'.repeat(Math.max(0, cols - 6))));
|
|
402
419
|
if (disabled) {
|
|
403
420
|
lines.push(prompt + chalk.gray(placeholder));
|
|
404
421
|
}
|
|
@@ -414,6 +431,9 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
414
431
|
if (isCursor) {
|
|
415
432
|
lineText += chalk.inverse(token.text || ' ');
|
|
416
433
|
}
|
|
434
|
+
else if (token.style?.bold && token.style?.badge?.type === 'paste') {
|
|
435
|
+
lineText += chalk.yellow.bold(token.text);
|
|
436
|
+
}
|
|
417
437
|
else if (token.style?.color === 'yellow') {
|
|
418
438
|
lineText += chalk.gray(token.text);
|
|
419
439
|
}
|
|
@@ -427,18 +447,19 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
427
447
|
lines.push(lineText);
|
|
428
448
|
});
|
|
429
449
|
}
|
|
430
|
-
const plainText =
|
|
431
|
-
?
|
|
450
|
+
const plainText = visibleOverlayState.segments.length === 1 && visibleOverlayState.segments[0].type === 'text'
|
|
451
|
+
? visibleOverlayState.segments[0].text
|
|
432
452
|
: '';
|
|
433
453
|
const isCommandMode = plainText.startsWith('/');
|
|
434
454
|
const commandQuery = isCommandMode ? plainText.slice(1).trim() : '';
|
|
435
455
|
const commandMatches = isCommandMode
|
|
436
456
|
? commands.filter(c => c.name.startsWith(commandQuery)).slice(0, 4)
|
|
437
457
|
: [];
|
|
458
|
+
const expansionHint = disabled ? null : getInputShortcutHint(overlayState, isRunning, activeKillRingRef.current.length > 0);
|
|
438
459
|
for (let i = 0; i < 4; i += 1) {
|
|
439
460
|
const cmd = commandMatches[i];
|
|
440
461
|
if (!cmd) {
|
|
441
|
-
lines.push(' ');
|
|
462
|
+
lines.push(i === 0 && expansionHint ? chalk.gray(expansionHint) : ' ');
|
|
442
463
|
continue;
|
|
443
464
|
}
|
|
444
465
|
const usage = cmd.usage ? ` ${cmd.usage}` : '';
|
|
@@ -454,11 +475,11 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
454
475
|
}
|
|
455
476
|
stdout.write('\x1b[u');
|
|
456
477
|
overlayBusyRef.current = false;
|
|
457
|
-
}, [commands, disabled, placeholder, stdout]);
|
|
478
|
+
}, [commands, disabled, placeholder, stdout, passwordMode, cols, mode, isRunning]);
|
|
458
479
|
const insertTextIntoOverlay = useCallback((text) => {
|
|
459
480
|
const current = overlayStateRef.current;
|
|
460
481
|
const next = insertText(current, text);
|
|
461
|
-
overlayStateRef.current = { ...next
|
|
482
|
+
overlayStateRef.current = { ...next };
|
|
462
483
|
renderOverlay(overlayStateRef.current);
|
|
463
484
|
}, [renderOverlay]);
|
|
464
485
|
// The Ink renderer has no native clipboard bridge. Image pastes are read by
|
|
@@ -477,6 +498,16 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
477
498
|
const isKittyCtrl = modifier === 5;
|
|
478
499
|
const isKittyMeta = modifier === 9;
|
|
479
500
|
const lowerChar = char.toLowerCase();
|
|
501
|
+
if (isKittyCtrl && lowerChar === 'c') {
|
|
502
|
+
const next = clearComposer(state);
|
|
503
|
+
if (next)
|
|
504
|
+
dispatch({ type: 'apply', state: next });
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
if (isKittyCtrl && lowerChar === 'x') {
|
|
508
|
+
dispatch({ type: 'apply', state: expandPasteBadge(state) });
|
|
509
|
+
return;
|
|
510
|
+
}
|
|
480
511
|
// Navigation
|
|
481
512
|
if (isKittyCtrl && lowerChar === 'a') {
|
|
482
513
|
dispatch({ type: 'apply', state: { cursor: { index: 0, offset: 0 } } });
|
|
@@ -627,7 +658,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
627
658
|
return;
|
|
628
659
|
}
|
|
629
660
|
// Unknown Kitty sequence - don't insert as text
|
|
630
|
-
}, [disabled, killToEnd, killToStart, killWordBackward, killWordForward, navigateHistory, onDictationStateChange, onToast, pushKill, state, transposeChars, transposeWords, yank, yankPop]);
|
|
661
|
+
}, [clearComposer, disabled, killToEnd, killToStart, killWordBackward, killWordForward, navigateHistory, onDictationStateChange, onToast, pushKill, state, transposeChars, transposeWords, yank, yankPop]);
|
|
631
662
|
const handleInput = useCallback((input, key) => {
|
|
632
663
|
// Detect Kitty keyboard protocol CSI u sequences
|
|
633
664
|
// Format: ESC [ <keycode> ; <modifiers> u
|
|
@@ -648,8 +679,8 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
648
679
|
const modifier = parseInt(kittyMatch[2], 10);
|
|
649
680
|
const isKittyCtrl = modifier === 5;
|
|
650
681
|
const isKittyMeta = modifier === 9;
|
|
651
|
-
// Ctrl+C
|
|
652
|
-
if (keycode === 99 &&
|
|
682
|
+
// Ctrl+C follows the composer lifecycle; retain the existing Cmd+C exit.
|
|
683
|
+
if (keycode === 99 && isKittyMeta) {
|
|
653
684
|
exit();
|
|
654
685
|
return;
|
|
655
686
|
}
|
|
@@ -669,6 +700,16 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
669
700
|
}
|
|
670
701
|
if (disabled)
|
|
671
702
|
return;
|
|
703
|
+
if (key.ctrl && isCtrl(input, key, 'c') && !isPastingRef.current) {
|
|
704
|
+
const next = clearComposer(state);
|
|
705
|
+
if (next)
|
|
706
|
+
dispatch({ type: 'apply', state: next });
|
|
707
|
+
return;
|
|
708
|
+
}
|
|
709
|
+
if (key.ctrl && isCtrl(input, key, 'x') && !isPastingRef.current) {
|
|
710
|
+
dispatch({ type: 'apply', state: expandPasteBadge(state) });
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
672
713
|
// Handle bracketed paste mode markers
|
|
673
714
|
// Note: ESC might be stripped or sent separately by Ink, so check both with and without ESC
|
|
674
715
|
const PASTE_START_FULL = '\x1b[200~';
|
|
@@ -695,11 +736,11 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
695
736
|
const lineCount = pasteContent.split('\n').length;
|
|
696
737
|
if (lineCount >= PASTE_BADGE_THRESHOLD) {
|
|
697
738
|
const next = insertBadge(state, { type: 'paste', text: pasteContent });
|
|
698
|
-
dispatch({ type: 'apply', state: { ...next
|
|
739
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
699
740
|
}
|
|
700
741
|
else {
|
|
701
742
|
const next = insertText(state, pasteContent);
|
|
702
|
-
dispatch({ type: 'apply', state: { ...next
|
|
743
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
703
744
|
}
|
|
704
745
|
}
|
|
705
746
|
else {
|
|
@@ -727,11 +768,11 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
727
768
|
if (pasteContent.length > 0) {
|
|
728
769
|
if (lineCount >= PASTE_BADGE_THRESHOLD) {
|
|
729
770
|
const next = insertBadge(state, { type: 'paste', text: pasteContent });
|
|
730
|
-
dispatch({ type: 'apply', state: { ...next
|
|
771
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
731
772
|
}
|
|
732
773
|
else {
|
|
733
774
|
const next = insertText(state, pasteContent);
|
|
734
|
-
dispatch({ type: 'apply', state: { ...next
|
|
775
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
735
776
|
}
|
|
736
777
|
}
|
|
737
778
|
else {
|
|
@@ -780,7 +821,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
780
821
|
// kitty keyboard protocol enabled (macOS Terminal.app, default iTerm2).
|
|
781
822
|
if (key.return && (key.shift || key.meta)) {
|
|
782
823
|
const next = insertText(state, '\n');
|
|
783
|
-
dispatch({ type: 'apply', state: { ...next
|
|
824
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
784
825
|
return;
|
|
785
826
|
}
|
|
786
827
|
// Line-wise movement first (Codex parity): the arrows walk a multi-line
|
|
@@ -789,7 +830,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
789
830
|
if (key.upArrow || key.downArrow) {
|
|
790
831
|
const vertical = moveVertical(state, key.upArrow ? -1 : 1);
|
|
791
832
|
if (vertical.moved) {
|
|
792
|
-
dispatch({ type: 'apply', state: { ...vertical.state
|
|
833
|
+
dispatch({ type: 'apply', state: { ...vertical.state } });
|
|
793
834
|
return;
|
|
794
835
|
}
|
|
795
836
|
navigateHistory(key.upArrow ? 'up' : 'down');
|
|
@@ -801,6 +842,14 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
801
842
|
return;
|
|
802
843
|
}
|
|
803
844
|
if (safeKey.tab || input === '\t') {
|
|
845
|
+
const serialized = serializeSegments(state.segments).trim();
|
|
846
|
+
const plain = getPlainText(state.segments).trim();
|
|
847
|
+
if (onQueue && serialized && !plain.startsWith('/') && !plain.startsWith('!')) {
|
|
848
|
+
if (onQueue(serialized)) {
|
|
849
|
+
dispatch({ type: 'submit', historyEnabled, historyEntry: serialized });
|
|
850
|
+
}
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
804
853
|
void handleTabComplete(state).then(nextState => {
|
|
805
854
|
if (nextState !== state) {
|
|
806
855
|
dispatch({ type: 'apply', state: nextState });
|
|
@@ -995,14 +1044,14 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
995
1044
|
const lineCount = input.split('\n').length;
|
|
996
1045
|
if (lineCount >= PASTE_BADGE_THRESHOLD) {
|
|
997
1046
|
const next = insertBadge(state, { type: 'paste', text: input });
|
|
998
|
-
dispatch({ type: 'apply', state: { ...next
|
|
1047
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
999
1048
|
return;
|
|
1000
1049
|
}
|
|
1001
1050
|
}
|
|
1002
1051
|
const next = insertText(state, input);
|
|
1003
|
-
dispatch({ type: 'apply', state: { ...next
|
|
1052
|
+
dispatch({ type: 'apply', state: { ...next } });
|
|
1004
1053
|
}
|
|
1005
|
-
}, [disabled, exit, handleClipboardImagePaste, handleKittyInput, handleSubmit, navigateHistory, state]);
|
|
1054
|
+
}, [clearComposer, disabled, exit, handleClipboardImagePaste, handleKittyInput, handleSubmit, navigateHistory, state, onQueue, historyEnabled, pushKill, yank, yankPop]);
|
|
1006
1055
|
// Handle Kitty keyboard protocol sequences for overlay mode
|
|
1007
1056
|
const handleKittyOverlayInput = useCallback((char, key, keycode, modifier) => {
|
|
1008
1057
|
if (disabled)
|
|
@@ -1011,6 +1060,19 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1011
1060
|
const isKittyCtrl = modifier === 5;
|
|
1012
1061
|
const isKittyMeta = modifier === 9;
|
|
1013
1062
|
const lowerChar = char.toLowerCase();
|
|
1063
|
+
if (isKittyCtrl && lowerChar === 'c') {
|
|
1064
|
+
const next = clearComposer(current);
|
|
1065
|
+
if (next) {
|
|
1066
|
+
overlayStateRef.current = next;
|
|
1067
|
+
renderOverlay(next);
|
|
1068
|
+
}
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
if (isKittyCtrl && lowerChar === 'x') {
|
|
1072
|
+
overlayStateRef.current = expandPasteBadge(current);
|
|
1073
|
+
renderOverlay(overlayStateRef.current);
|
|
1074
|
+
return;
|
|
1075
|
+
}
|
|
1014
1076
|
// Navigation
|
|
1015
1077
|
if (isKittyCtrl && lowerChar === 'a') {
|
|
1016
1078
|
overlayStateRef.current = { ...current, cursor: { index: 0, offset: 0 } };
|
|
@@ -1033,36 +1095,15 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1033
1095
|
return;
|
|
1034
1096
|
}
|
|
1035
1097
|
if (isKittyCtrl && lowerChar === 'p') {
|
|
1036
|
-
if (historyEnabled
|
|
1037
|
-
|
|
1038
|
-
const historyValue = current.history[newIdx] || '';
|
|
1039
|
-
overlayStateRef.current = {
|
|
1040
|
-
...current,
|
|
1041
|
-
historyIdx: newIdx,
|
|
1042
|
-
segments: historyValue.length > 0 ? [{ type: 'text', text: historyValue }] : [],
|
|
1043
|
-
cursor: { index: historyValue.length > 0 ? 0 : 0, offset: historyValue.length }
|
|
1044
|
-
};
|
|
1098
|
+
if (historyEnabled) {
|
|
1099
|
+
overlayStateRef.current = historyUp(current);
|
|
1045
1100
|
renderOverlay(overlayStateRef.current);
|
|
1046
1101
|
}
|
|
1047
1102
|
return;
|
|
1048
1103
|
}
|
|
1049
1104
|
if (isKittyCtrl && lowerChar === 'n') {
|
|
1050
|
-
if (historyEnabled
|
|
1051
|
-
|
|
1052
|
-
if (newIdx >= current.history.length)
|
|
1053
|
-
newIdx = -1;
|
|
1054
|
-
if (newIdx === -1) {
|
|
1055
|
-
overlayStateRef.current = { ...createEmptyState(), history: current.history, historyIdx: -1 };
|
|
1056
|
-
}
|
|
1057
|
-
else {
|
|
1058
|
-
const historyValue = current.history[newIdx];
|
|
1059
|
-
overlayStateRef.current = {
|
|
1060
|
-
...current,
|
|
1061
|
-
historyIdx: newIdx,
|
|
1062
|
-
segments: historyValue.length > 0 ? [{ type: 'text', text: historyValue }] : [],
|
|
1063
|
-
cursor: { index: historyValue.length > 0 ? 0 : 0, offset: historyValue.length }
|
|
1064
|
-
};
|
|
1065
|
-
}
|
|
1105
|
+
if (historyEnabled) {
|
|
1106
|
+
overlayStateRef.current = historyDown(current);
|
|
1066
1107
|
renderOverlay(overlayStateRef.current);
|
|
1067
1108
|
}
|
|
1068
1109
|
return;
|
|
@@ -1071,7 +1112,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1071
1112
|
if (isKittyCtrl && lowerChar === 'u') {
|
|
1072
1113
|
const { next, killed } = killToStart(current);
|
|
1073
1114
|
pushKill(killed, next);
|
|
1074
|
-
overlayStateRef.current = { ...next, history: current.history
|
|
1115
|
+
overlayStateRef.current = { ...next, history: current.history };
|
|
1075
1116
|
renderOverlay(overlayStateRef.current);
|
|
1076
1117
|
return;
|
|
1077
1118
|
}
|
|
@@ -1119,7 +1160,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1119
1160
|
if (text && text.trim()) {
|
|
1120
1161
|
// Filter filler words and submit the transcribed text
|
|
1121
1162
|
onSubmit(maybeFilterFillers(text.trim()));
|
|
1122
|
-
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 }
|
|
1163
|
+
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 } };
|
|
1123
1164
|
renderOverlay(overlayStateRef.current);
|
|
1124
1165
|
}
|
|
1125
1166
|
else {
|
|
@@ -1140,7 +1181,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1140
1181
|
if (result.text && result.text.trim()) {
|
|
1141
1182
|
// Filter filler words and submit the transcribed text
|
|
1142
1183
|
onSubmit(maybeFilterFillers(result.text.trim()));
|
|
1143
|
-
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 }
|
|
1184
|
+
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 } };
|
|
1144
1185
|
renderOverlay(overlayStateRef.current);
|
|
1145
1186
|
}
|
|
1146
1187
|
else {
|
|
@@ -1205,7 +1246,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1205
1246
|
return;
|
|
1206
1247
|
}
|
|
1207
1248
|
// Unknown Kitty sequence - don't insert as text
|
|
1208
|
-
}, [disabled, historyEnabled, killToEnd, killToStart, killWordBackward, killWordForward, onDictationStateChange, onToast, pushKill, renderOverlay, transposeChars, transposeWords, yank, yankPop]);
|
|
1249
|
+
}, [clearComposer, disabled, historyEnabled, killToEnd, killToStart, killWordBackward, killWordForward, onDictationStateChange, onToast, pushKill, renderOverlay, transposeChars, transposeWords, yank, yankPop]);
|
|
1209
1250
|
const handleOverlayInput = useCallback((input, key) => {
|
|
1210
1251
|
if (disabled)
|
|
1211
1252
|
return;
|
|
@@ -1237,13 +1278,38 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1237
1278
|
return;
|
|
1238
1279
|
}
|
|
1239
1280
|
const current = overlayStateRef.current;
|
|
1281
|
+
if (key.ctrl && isCtrl(input, key, 'c')) {
|
|
1282
|
+
const next = clearComposer(current);
|
|
1283
|
+
if (next) {
|
|
1284
|
+
overlayStateRef.current = next;
|
|
1285
|
+
renderOverlay(next);
|
|
1286
|
+
}
|
|
1287
|
+
return;
|
|
1288
|
+
}
|
|
1289
|
+
if (key.ctrl && isCtrl(input, key, 'x')) {
|
|
1290
|
+
overlayStateRef.current = expandPasteBadge(current);
|
|
1291
|
+
renderOverlay(overlayStateRef.current);
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
if ((safeKey.tab || input === '\t') && !safeKey.shift) {
|
|
1295
|
+
const serialized = serializeSegments(current.segments).trim();
|
|
1296
|
+
const plain = getPlainText(current.segments).trim();
|
|
1297
|
+
if (onQueue && serialized && !plain.startsWith('/') && !plain.startsWith('!')) {
|
|
1298
|
+
if (onQueue(serialized)) {
|
|
1299
|
+
const history = historyEnabled ? [...current.history.slice(-100), serialized] : current.history;
|
|
1300
|
+
overlayStateRef.current = { ...createEmptyState(), history, historyIdx: -1 };
|
|
1301
|
+
renderOverlay(overlayStateRef.current);
|
|
1302
|
+
}
|
|
1303
|
+
return;
|
|
1304
|
+
}
|
|
1305
|
+
}
|
|
1240
1306
|
if ((key.ctrl || key.meta) && (input === 'v' || input === '\u0016')) {
|
|
1241
1307
|
void handleClipboardImagePaste('overlay');
|
|
1242
1308
|
return;
|
|
1243
1309
|
}
|
|
1244
1310
|
if (key.return && !key.shift && !key.meta) {
|
|
1245
1311
|
const serialized = serializeSegments(current.segments).trim();
|
|
1246
|
-
if (serialized) {
|
|
1312
|
+
if (serialized || allowEmptySubmit) {
|
|
1247
1313
|
const plainText = getPlainText(current.segments).trim();
|
|
1248
1314
|
const isCommand = current.segments.length === 1 && current.segments[0].type === 'text' && plainText.startsWith('/');
|
|
1249
1315
|
if (isCommand) {
|
|
@@ -1252,7 +1318,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1252
1318
|
const args = parts.slice(1);
|
|
1253
1319
|
// Handle /pi (paste image) command directly
|
|
1254
1320
|
if (cmd === 'pi' || cmd === 'paste-image') {
|
|
1255
|
-
overlayStateRef.current =
|
|
1321
|
+
overlayStateRef.current = recordInputHistory(current, historyEnabled ? serialized : undefined, 101);
|
|
1256
1322
|
renderOverlay(overlayStateRef.current);
|
|
1257
1323
|
void handleClipboardImagePaste('overlay');
|
|
1258
1324
|
return;
|
|
@@ -1260,18 +1326,25 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1260
1326
|
onCommand?.(cmd, args);
|
|
1261
1327
|
}
|
|
1262
1328
|
else {
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1329
|
+
const saved = structuredClone(current);
|
|
1330
|
+
const submittedRevision = draftRevisionRef.current;
|
|
1331
|
+
onSubmit(serialized, { restore: () => {
|
|
1332
|
+
if (draftRevisionRef.current !== submittedRevision + 1)
|
|
1333
|
+
return false;
|
|
1334
|
+
draftRevisionRef.current += 1;
|
|
1335
|
+
overlayStateRef.current = { ...overlayStateRef.current,
|
|
1336
|
+
segments: saved.segments, cursor: saved.cursor, historyIdx: -1 };
|
|
1337
|
+
renderOverlay(overlayStateRef.current);
|
|
1338
|
+
return true;
|
|
1339
|
+
} });
|
|
1267
1340
|
}
|
|
1268
1341
|
}
|
|
1269
|
-
overlayStateRef.current =
|
|
1342
|
+
overlayStateRef.current = recordInputHistory(current, historyEnabled && serialized ? serialized : undefined, 101);
|
|
1270
1343
|
renderOverlay(overlayStateRef.current);
|
|
1271
1344
|
return;
|
|
1272
1345
|
}
|
|
1273
1346
|
if (key.return && (key.shift || key.meta)) {
|
|
1274
|
-
overlayStateRef.current = { ...insertText(current, '\n')
|
|
1347
|
+
overlayStateRef.current = { ...insertText(current, '\n') };
|
|
1275
1348
|
renderOverlay(overlayStateRef.current);
|
|
1276
1349
|
return;
|
|
1277
1350
|
}
|
|
@@ -1279,32 +1352,12 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1279
1352
|
const direction = key.upArrow ? 'up' : 'down';
|
|
1280
1353
|
const vertical = moveVertical(current, direction === 'up' ? -1 : 1);
|
|
1281
1354
|
if (vertical.moved) {
|
|
1282
|
-
overlayStateRef.current = { ...vertical.state
|
|
1355
|
+
overlayStateRef.current = { ...vertical.state };
|
|
1283
1356
|
renderOverlay(overlayStateRef.current);
|
|
1284
1357
|
return;
|
|
1285
1358
|
}
|
|
1286
|
-
if (historyEnabled
|
|
1287
|
-
|
|
1288
|
-
if (direction === 'up') {
|
|
1289
|
-
newIdx = current.historyIdx === -1 ? current.history.length - 1 : Math.max(0, current.historyIdx - 1);
|
|
1290
|
-
}
|
|
1291
|
-
else {
|
|
1292
|
-
newIdx = current.historyIdx === -1 ? -1 : current.historyIdx + 1;
|
|
1293
|
-
if (newIdx >= current.history.length)
|
|
1294
|
-
newIdx = -1;
|
|
1295
|
-
}
|
|
1296
|
-
if (newIdx === -1) {
|
|
1297
|
-
overlayStateRef.current = { ...createEmptyState(), history: current.history, historyIdx: -1 };
|
|
1298
|
-
}
|
|
1299
|
-
else {
|
|
1300
|
-
const historyValue = current.history[newIdx];
|
|
1301
|
-
overlayStateRef.current = {
|
|
1302
|
-
...current,
|
|
1303
|
-
historyIdx: newIdx,
|
|
1304
|
-
segments: historyValue.length > 0 ? [{ type: 'text', text: historyValue }] : [],
|
|
1305
|
-
cursor: { index: historyValue.length > 0 ? 0 : 0, offset: historyValue.length }
|
|
1306
|
-
};
|
|
1307
|
-
}
|
|
1359
|
+
if (historyEnabled) {
|
|
1360
|
+
overlayStateRef.current = key.upArrow ? historyUp(current) : historyDown(current);
|
|
1308
1361
|
renderOverlay(overlayStateRef.current);
|
|
1309
1362
|
}
|
|
1310
1363
|
return;
|
|
@@ -1351,36 +1404,15 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1351
1404
|
}
|
|
1352
1405
|
if (isCtrl(input, key, 'p')) {
|
|
1353
1406
|
const direction = 'up';
|
|
1354
|
-
if (historyEnabled
|
|
1355
|
-
|
|
1356
|
-
const historyValue = current.history[newIdx] || '';
|
|
1357
|
-
overlayStateRef.current = {
|
|
1358
|
-
...current,
|
|
1359
|
-
historyIdx: newIdx,
|
|
1360
|
-
segments: historyValue.length > 0 ? [{ type: 'text', text: historyValue }] : [],
|
|
1361
|
-
cursor: { index: historyValue.length > 0 ? 0 : 0, offset: historyValue.length }
|
|
1362
|
-
};
|
|
1407
|
+
if (historyEnabled) {
|
|
1408
|
+
overlayStateRef.current = historyUp(current);
|
|
1363
1409
|
renderOverlay(overlayStateRef.current);
|
|
1364
1410
|
}
|
|
1365
1411
|
return;
|
|
1366
1412
|
}
|
|
1367
1413
|
if (isCtrl(input, key, 'n')) {
|
|
1368
|
-
if (historyEnabled
|
|
1369
|
-
|
|
1370
|
-
if (newIdx >= current.history.length)
|
|
1371
|
-
newIdx = -1;
|
|
1372
|
-
if (newIdx === -1) {
|
|
1373
|
-
overlayStateRef.current = { ...createEmptyState(), history: current.history, historyIdx: -1 };
|
|
1374
|
-
}
|
|
1375
|
-
else {
|
|
1376
|
-
const historyValue = current.history[newIdx];
|
|
1377
|
-
overlayStateRef.current = {
|
|
1378
|
-
...current,
|
|
1379
|
-
historyIdx: newIdx,
|
|
1380
|
-
segments: historyValue.length > 0 ? [{ type: 'text', text: historyValue }] : [],
|
|
1381
|
-
cursor: { index: historyValue.length > 0 ? 0 : 0, offset: historyValue.length }
|
|
1382
|
-
};
|
|
1383
|
-
}
|
|
1414
|
+
if (historyEnabled) {
|
|
1415
|
+
overlayStateRef.current = historyDown(current);
|
|
1384
1416
|
renderOverlay(overlayStateRef.current);
|
|
1385
1417
|
}
|
|
1386
1418
|
return;
|
|
@@ -1391,7 +1423,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1391
1423
|
if (key.meta || key.ctrl) {
|
|
1392
1424
|
const { next, killed } = killWordBackward(current);
|
|
1393
1425
|
pushKill(killed, next);
|
|
1394
|
-
overlayStateRef.current = { ...next, history: current.history
|
|
1426
|
+
overlayStateRef.current = { ...next, history: current.history };
|
|
1395
1427
|
}
|
|
1396
1428
|
else {
|
|
1397
1429
|
overlayStateRef.current = backspace(current);
|
|
@@ -1402,7 +1434,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1402
1434
|
if (isCtrl(input, key, 'u')) {
|
|
1403
1435
|
const { next, killed } = killToStart(current);
|
|
1404
1436
|
pushKill(killed, next);
|
|
1405
|
-
overlayStateRef.current = { ...next, history: current.history
|
|
1437
|
+
overlayStateRef.current = { ...next, history: current.history };
|
|
1406
1438
|
renderOverlay(overlayStateRef.current);
|
|
1407
1439
|
return;
|
|
1408
1440
|
}
|
|
@@ -1431,7 +1463,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1431
1463
|
if (text && text.trim()) {
|
|
1432
1464
|
// Filter filler words and submit the transcribed text
|
|
1433
1465
|
onSubmit(maybeFilterFillers(text.trim()));
|
|
1434
|
-
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 }
|
|
1466
|
+
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 } };
|
|
1435
1467
|
renderOverlay(overlayStateRef.current);
|
|
1436
1468
|
}
|
|
1437
1469
|
else {
|
|
@@ -1452,7 +1484,7 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1452
1484
|
if (result.text && result.text.trim()) {
|
|
1453
1485
|
// Filter filler words and submit the transcribed text
|
|
1454
1486
|
onSubmit(maybeFilterFillers(result.text.trim()));
|
|
1455
|
-
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 }
|
|
1487
|
+
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 } };
|
|
1456
1488
|
renderOverlay(overlayStateRef.current);
|
|
1457
1489
|
}
|
|
1458
1490
|
else {
|
|
@@ -1552,42 +1584,84 @@ export const InputArea = ({ onSubmit, onCommand, commands = [], onStateChange, o
|
|
|
1552
1584
|
else {
|
|
1553
1585
|
overlayStateRef.current = insertText(current, input);
|
|
1554
1586
|
}
|
|
1555
|
-
overlayStateRef.current = { ...overlayStateRef.current
|
|
1587
|
+
overlayStateRef.current = { ...overlayStateRef.current };
|
|
1556
1588
|
renderOverlay(overlayStateRef.current);
|
|
1557
1589
|
}
|
|
1558
|
-
}, [disabled, handleKittyOverlayInput, historyEnabled, onCommand, onSubmit, renderOverlay]);
|
|
1559
|
-
|
|
1590
|
+
}, [clearComposer, disabled, handleKittyOverlayInput, historyEnabled, onCommand, onSubmit, onQueue, renderOverlay, pushKill, yank, yankPop, allowEmptySubmit]);
|
|
1591
|
+
const currentInputHandler = (input, key) => {
|
|
1592
|
+
if (inputBlocked?.())
|
|
1593
|
+
return;
|
|
1560
1594
|
if (overlayEnabled) {
|
|
1561
1595
|
handleOverlayInput(input, key);
|
|
1562
1596
|
return;
|
|
1563
1597
|
}
|
|
1564
1598
|
handleInput(input, key);
|
|
1565
|
-
}
|
|
1599
|
+
};
|
|
1600
|
+
const inputHandlerRef = React.useRef(currentInputHandler);
|
|
1601
|
+
React.useLayoutEffect(() => {
|
|
1602
|
+
inputHandlerRef.current = currentInputHandler;
|
|
1603
|
+
}, [currentInputHandler]);
|
|
1604
|
+
// Ink subscribes in a passive effect. Keep that subscription stable, while
|
|
1605
|
+
// committed draft and prompt ownership reach the listener before the next key.
|
|
1606
|
+
const dispatchInput = useCallback((input, key) => {
|
|
1607
|
+
inputHandlerRef.current(input, key);
|
|
1608
|
+
}, []);
|
|
1609
|
+
useInput(dispatchInput);
|
|
1566
1610
|
React.useEffect(() => {
|
|
1567
1611
|
if (!inputBus)
|
|
1568
1612
|
return;
|
|
1569
|
-
return inputBus.subscribe(({ input, key }) =>
|
|
1570
|
-
|
|
1571
|
-
handleOverlayInput(input, key);
|
|
1572
|
-
return;
|
|
1573
|
-
}
|
|
1574
|
-
handleInput(input, key);
|
|
1575
|
-
});
|
|
1576
|
-
}, [handleInput, handleOverlayInput, inputBus, overlayEnabled]);
|
|
1613
|
+
return inputBus.subscribe(({ input, key }) => dispatchInput(input, key));
|
|
1614
|
+
}, [dispatchInput, inputBus]);
|
|
1577
1615
|
React.useEffect(() => {
|
|
1578
1616
|
if (!overlayEnabled)
|
|
1579
1617
|
return;
|
|
1580
1618
|
renderOverlay(overlayStateRef.current);
|
|
1581
1619
|
}, [overlayEnabled, renderOverlay]);
|
|
1620
|
+
React.useLayoutEffect(() => {
|
|
1621
|
+
const previous = passwordOwnershipRef.current;
|
|
1622
|
+
if (previous && previous.passwordMode === passwordMode && previous.promptOwner === promptOwner)
|
|
1623
|
+
return;
|
|
1624
|
+
passwordOwnershipRef.current = { passwordMode, promptOwner };
|
|
1625
|
+
// Each password owner can recall ordinary cuts without retaining another
|
|
1626
|
+
// owner's private cuts or changing the ordinary ring's order/index.
|
|
1627
|
+
passwordKillRingRef.current = passwordMode ? [...killRingRef.current] : [];
|
|
1628
|
+
passwordKillIndexRef.current = passwordMode ? killIndexRef.current : -1;
|
|
1629
|
+
if (previous?.passwordMode && passwordMode && previous.promptOwner !== promptOwner) {
|
|
1630
|
+
dispatch({ type: 'submit', historyEnabled: false });
|
|
1631
|
+
if (overlayEnabled) {
|
|
1632
|
+
draftRevisionRef.current += 1;
|
|
1633
|
+
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 }, historyIdx: -1 };
|
|
1634
|
+
renderOverlay(overlayStateRef.current);
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
}, [passwordMode, promptOwner, overlayEnabled, renderOverlay]);
|
|
1638
|
+
React.useLayoutEffect(() => {
|
|
1639
|
+
if (clearDraftVersionRef.current === clearDraftVersion)
|
|
1640
|
+
return;
|
|
1641
|
+
clearDraftVersionRef.current = clearDraftVersion;
|
|
1642
|
+
passwordKillRingRef.current = [];
|
|
1643
|
+
passwordKillIndexRef.current = -1;
|
|
1644
|
+
dispatch({ type: 'submit', historyEnabled: false });
|
|
1645
|
+
if (overlayEnabled) {
|
|
1646
|
+
draftRevisionRef.current += 1;
|
|
1647
|
+
overlayStateRef.current = { ...overlayStateRef.current, segments: [], cursor: { index: 0, offset: 0 }, historyIdx: -1 };
|
|
1648
|
+
renderOverlay(overlayStateRef.current);
|
|
1649
|
+
}
|
|
1650
|
+
}, [clearDraftVersion, overlayEnabled, renderOverlay]);
|
|
1582
1651
|
// Create masked state for password mode
|
|
1652
|
+
const visibleState = clearDraftVersionRef.current !== clearDraftVersion
|
|
1653
|
+
? { ...state, segments: [], cursor: { index: 0, offset: 0 } }
|
|
1654
|
+
: state;
|
|
1583
1655
|
const displayState = passwordMode ? {
|
|
1584
|
-
...
|
|
1585
|
-
segments:
|
|
1586
|
-
} :
|
|
1656
|
+
...visibleState,
|
|
1657
|
+
segments: visibleState.segments.map(seg => seg.type === 'text' ? { ...seg, text: '•'.repeat(seg.text.length) } : seg)
|
|
1658
|
+
} : visibleState;
|
|
1587
1659
|
const node = buildInputAreaView({
|
|
1588
1660
|
state: displayState,
|
|
1589
1661
|
placeholder,
|
|
1590
1662
|
disabled,
|
|
1663
|
+
mode,
|
|
1664
|
+
isRunning,
|
|
1591
1665
|
commands,
|
|
1592
1666
|
cols,
|
|
1593
1667
|
badgePreview,
|