@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
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type ChildPublicationAdmission = {
|
|
2
|
+
accepted: true;
|
|
3
|
+
duplicate: boolean;
|
|
4
|
+
} | {
|
|
5
|
+
accepted: false;
|
|
6
|
+
status: 400 | 409;
|
|
7
|
+
error: string;
|
|
8
|
+
};
|
|
9
|
+
/** Bounded parent-issued stream receipts. Retain tombstones so pane reuse cannot revive an old stream. */
|
|
10
|
+
export declare class ChildPublicationLedger {
|
|
11
|
+
private readonly capacity;
|
|
12
|
+
private readonly streams;
|
|
13
|
+
constructor(capacity?: number);
|
|
14
|
+
open(paneId: number, scope?: string): string | null;
|
|
15
|
+
admit(paneId: number, id: unknown, sequence: unknown, scope?: string): ChildPublicationAdmission;
|
|
16
|
+
invalidate(paneId: number): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
/** Bounded parent-issued stream receipts. Retain tombstones so pane reuse cannot revive an old stream. */
|
|
3
|
+
export class ChildPublicationLedger {
|
|
4
|
+
capacity;
|
|
5
|
+
streams = new Map();
|
|
6
|
+
constructor(capacity = 1024) {
|
|
7
|
+
this.capacity = capacity;
|
|
8
|
+
if (!Number.isSafeInteger(capacity) || capacity < 1)
|
|
9
|
+
throw new RangeError('Publication capacity must be a positive safe integer');
|
|
10
|
+
}
|
|
11
|
+
open(paneId, scope = '') {
|
|
12
|
+
const key = JSON.stringify([scope, paneId]);
|
|
13
|
+
if (!this.streams.has(key) && this.streams.size >= this.capacity)
|
|
14
|
+
return null;
|
|
15
|
+
const id = randomUUID();
|
|
16
|
+
this.streams.set(key, { paneId, id, sequence: 0 });
|
|
17
|
+
return id;
|
|
18
|
+
}
|
|
19
|
+
admit(paneId, id, sequence, scope = '') {
|
|
20
|
+
const stream = this.streams.get(JSON.stringify([scope, paneId]));
|
|
21
|
+
// Legacy children remain compatible only until this pane opts into ordered publication.
|
|
22
|
+
if (id === undefined && sequence === undefined) {
|
|
23
|
+
return stream ? { accepted: false, status: 409, error: 'publication_identity_required' }
|
|
24
|
+
: { accepted: true, duplicate: false };
|
|
25
|
+
}
|
|
26
|
+
if (typeof id !== 'string' || !Number.isSafeInteger(sequence) || sequence < 1) {
|
|
27
|
+
return { accepted: false, status: 400, error: 'invalid_publication_sequence' };
|
|
28
|
+
}
|
|
29
|
+
if (!stream || stream.id !== id)
|
|
30
|
+
return { accepted: false, status: 409, error: 'publication_superseded' };
|
|
31
|
+
const next = sequence;
|
|
32
|
+
if (next <= stream.sequence)
|
|
33
|
+
return { accepted: true, duplicate: true };
|
|
34
|
+
if (next !== stream.sequence + 1)
|
|
35
|
+
return { accepted: false, status: 409, error: 'publication_sequence_gap' };
|
|
36
|
+
stream.sequence = next;
|
|
37
|
+
return { accepted: true, duplicate: false };
|
|
38
|
+
}
|
|
39
|
+
invalidate(paneId) {
|
|
40
|
+
for (const stream of this.streams.values()) {
|
|
41
|
+
if (stream.paneId === paneId)
|
|
42
|
+
stream.id = null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -21,11 +21,29 @@
|
|
|
21
21
|
export interface MirrorSession {
|
|
22
22
|
expiresAtMs: number;
|
|
23
23
|
canInspectPrompts: boolean;
|
|
24
|
+
/** Absent only in callers predating capability-scoped sessions. */
|
|
25
|
+
canControl?: boolean;
|
|
26
|
+
shareId?: string;
|
|
24
27
|
}
|
|
25
28
|
export interface MirrorTokenValidationResult {
|
|
26
29
|
ok: boolean;
|
|
27
30
|
expiresAtMs: number;
|
|
28
31
|
canInspectPrompts: boolean;
|
|
32
|
+
canControl?: boolean;
|
|
33
|
+
shareId?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface MirrorShare {
|
|
36
|
+
id: string;
|
|
37
|
+
label: string;
|
|
38
|
+
expiresAtMs: number;
|
|
39
|
+
createdAtMs: number;
|
|
40
|
+
revoked: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface MirrorTokenOptions {
|
|
43
|
+
ttlMs?: number;
|
|
44
|
+
canInspectPrompts?: boolean;
|
|
45
|
+
readOnly?: boolean;
|
|
46
|
+
label?: string;
|
|
29
47
|
}
|
|
30
48
|
export interface MirrorAuthDecision {
|
|
31
49
|
ok: boolean;
|
|
@@ -56,10 +74,10 @@ export interface MirrorAuthenticator {
|
|
|
56
74
|
readonly zergId: string;
|
|
57
75
|
readonly cookieName: string;
|
|
58
76
|
readonly queryTokenName: string;
|
|
59
|
-
issueToken(opts?:
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
77
|
+
issueToken(opts?: MirrorTokenOptions): string;
|
|
78
|
+
listShares(): MirrorShare[];
|
|
79
|
+
revokeShare(id: string): boolean;
|
|
80
|
+
onShareRevoked(callback: (id: string) => void): () => void;
|
|
63
81
|
isValidToken(token: string): MirrorTokenValidationResult;
|
|
64
82
|
authenticate(ctx: MirrorAuthContext): MirrorAuthDecision;
|
|
65
83
|
authenticateUpgrade(ctx: MirrorAuthContext): boolean;
|
|
@@ -69,19 +87,22 @@ export interface MirrorAuthenticator {
|
|
|
69
87
|
}
|
|
70
88
|
/** Production HMAC + session authenticator. Denies requests without valid credentials. */
|
|
71
89
|
export declare class HmacMirrorAuthenticator implements MirrorAuthenticator {
|
|
72
|
-
|
|
90
|
+
protected requiresCredentials: boolean;
|
|
91
|
+
get enabled(): boolean;
|
|
73
92
|
readonly zergId: string;
|
|
74
93
|
readonly cookieName: string;
|
|
75
94
|
readonly queryTokenName: string;
|
|
76
95
|
protected readonly sharedSecret: string;
|
|
77
96
|
protected readonly internalToken: string;
|
|
78
97
|
protected readonly sessions: Map<string, MirrorSession>;
|
|
98
|
+
private readonly shares;
|
|
99
|
+
private readonly revocationListeners;
|
|
79
100
|
constructor(config: MirrorAuthenticatorConfig);
|
|
80
|
-
issueToken(opts?:
|
|
81
|
-
ttlMs?: number;
|
|
82
|
-
canInspectPrompts?: boolean;
|
|
83
|
-
}): string;
|
|
101
|
+
issueToken(opts?: MirrorTokenOptions): string;
|
|
84
102
|
isValidToken(token: string): MirrorTokenValidationResult;
|
|
103
|
+
listShares(): MirrorShare[];
|
|
104
|
+
revokeShare(id: string): boolean;
|
|
105
|
+
onShareRevoked(callback: (id: string) => void): () => void;
|
|
85
106
|
authenticate(ctx: MirrorAuthContext): MirrorAuthDecision;
|
|
86
107
|
authenticateUpgrade(ctx: MirrorAuthContext): boolean;
|
|
87
108
|
persistSession(session: MirrorSession): string;
|
|
@@ -98,9 +119,8 @@ export declare class HmacMirrorAuthenticator implements MirrorAuthenticator {
|
|
|
98
119
|
* legacy `!mirrorAuthEnabled` fallback that ran AFTER the token path.
|
|
99
120
|
*/
|
|
100
121
|
export declare class OpenMirrorAuthenticator extends HmacMirrorAuthenticator {
|
|
101
|
-
|
|
122
|
+
constructor(config: MirrorAuthenticatorConfig);
|
|
102
123
|
authenticate(ctx: MirrorAuthContext): MirrorAuthDecision;
|
|
103
|
-
authenticateUpgrade(_ctx: MirrorAuthContext): boolean;
|
|
104
124
|
}
|
|
105
125
|
/**
|
|
106
126
|
* Build the authenticator from environment policy, mirroring the legacy
|
|
@@ -24,13 +24,16 @@ const DEFAULT_QUERY_TOKEN_NAME = 'ztc_mirror_token';
|
|
|
24
24
|
const DEFAULT_TTL_MS = 12 * 60 * 60 * 1000;
|
|
25
25
|
/** Production HMAC + session authenticator. Denies requests without valid credentials. */
|
|
26
26
|
export class HmacMirrorAuthenticator {
|
|
27
|
-
|
|
27
|
+
requiresCredentials = true;
|
|
28
|
+
get enabled() { return this.requiresCredentials; }
|
|
28
29
|
zergId;
|
|
29
30
|
cookieName;
|
|
30
31
|
queryTokenName;
|
|
31
32
|
sharedSecret;
|
|
32
33
|
internalToken;
|
|
33
34
|
sessions = new Map();
|
|
35
|
+
shares = new Map();
|
|
36
|
+
revocationListeners = new Set();
|
|
34
37
|
constructor(config) {
|
|
35
38
|
this.sharedSecret = config.sharedSecret;
|
|
36
39
|
this.zergId = config.zergId;
|
|
@@ -40,6 +43,26 @@ export class HmacMirrorAuthenticator {
|
|
|
40
43
|
}
|
|
41
44
|
issueToken(opts = {}) {
|
|
42
45
|
const ttlMs = opts.ttlMs ?? DEFAULT_TTL_MS;
|
|
46
|
+
if (opts.readOnly) {
|
|
47
|
+
if (!Number.isSafeInteger(ttlMs) || ttlMs < 1000 || ttlMs > DEFAULT_TTL_MS)
|
|
48
|
+
throw new Error('Observation TTL must be between 1 second and 12 hours, in whole milliseconds.');
|
|
49
|
+
const label = (opts.label ?? 'Observer').trim();
|
|
50
|
+
if (!label || label.length > 64 || /[\x00-\x1f\x7f]/.test(label))
|
|
51
|
+
throw new Error('Share label must contain 1–64 printable characters.');
|
|
52
|
+
for (const [id, share] of this.shares) {
|
|
53
|
+
if (share.revoked || share.expiresAtMs <= Date.now())
|
|
54
|
+
this.shares.delete(id);
|
|
55
|
+
}
|
|
56
|
+
if (this.shares.size >= 100)
|
|
57
|
+
throw new Error('Share limit reached. Revoke an active observation share first.');
|
|
58
|
+
const id = randomUUID();
|
|
59
|
+
const expiresAtMs = Date.now() + ttlMs;
|
|
60
|
+
const signature = createHmac('sha256', this.sharedSecret).update(`${this.zergId}:${expiresAtMs}:observe:${id}`).digest('hex');
|
|
61
|
+
this.shares.set(id, { id, label, expiresAtMs, createdAtMs: Date.now(), revoked: false });
|
|
62
|
+
// Latch this on: revoking the last share must never restore open control.
|
|
63
|
+
this.requiresCredentials = true;
|
|
64
|
+
return `${expiresAtMs}.observe.${id}.${signature}`;
|
|
65
|
+
}
|
|
43
66
|
const canInspectPrompts = opts.canInspectPrompts ?? false;
|
|
44
67
|
const expiresAtSeconds = Math.floor((Date.now() + ttlMs) / 1000);
|
|
45
68
|
const promptScope = canInspectPrompts ? '1' : '0';
|
|
@@ -49,6 +72,20 @@ export class HmacMirrorAuthenticator {
|
|
|
49
72
|
}
|
|
50
73
|
isValidToken(token) {
|
|
51
74
|
const parts = token.split('.');
|
|
75
|
+
if (parts[1] === 'observe') {
|
|
76
|
+
const denied = { ok: false, expiresAtMs: 0, canInspectPrompts: false, canControl: false };
|
|
77
|
+
if (parts.length !== 4 || !/^\d+$/.test(parts[0]) || !/^[a-f0-9]{64}$/.test(parts[3]))
|
|
78
|
+
return denied;
|
|
79
|
+
const share = this.shares.get(parts[2]);
|
|
80
|
+
const expiresAtMs = Number(parts[0]);
|
|
81
|
+
if (!share || share.revoked || share.expiresAtMs !== expiresAtMs || Date.now() >= expiresAtMs || !this.sharedSecret)
|
|
82
|
+
return denied;
|
|
83
|
+
const expected = createHmac('sha256', this.sharedSecret).update(`${this.zergId}:${parts[0]}:observe:${share.id}`).digest();
|
|
84
|
+
const provided = Buffer.from(parts[3], 'hex');
|
|
85
|
+
if (!timingSafeEqual(expected, provided))
|
|
86
|
+
return denied;
|
|
87
|
+
return { ok: true, expiresAtMs, canInspectPrompts: false, canControl: false, shareId: share.id };
|
|
88
|
+
}
|
|
52
89
|
if ((parts.length !== 2 && parts.length !== 3) || !this.sharedSecret) {
|
|
53
90
|
return { ok: false, expiresAtMs: 0, canInspectPrompts: false };
|
|
54
91
|
}
|
|
@@ -77,7 +114,21 @@ export class HmacMirrorAuthenticator {
|
|
|
77
114
|
if (!timingSafeEqual(expected, provided)) {
|
|
78
115
|
return { ok: false, expiresAtMs: 0, canInspectPrompts: false };
|
|
79
116
|
}
|
|
80
|
-
return { ok: true, expiresAtMs, canInspectPrompts: promptScope === '1' };
|
|
117
|
+
return { ok: true, expiresAtMs, canInspectPrompts: promptScope === '1', canControl: true };
|
|
118
|
+
}
|
|
119
|
+
listShares() { return [...this.shares.values()].map(share => ({ ...share })); }
|
|
120
|
+
revokeShare(id) {
|
|
121
|
+
const share = this.shares.get(id);
|
|
122
|
+
if (!share || share.revoked)
|
|
123
|
+
return false;
|
|
124
|
+
share.revoked = true;
|
|
125
|
+
for (const listener of this.revocationListeners)
|
|
126
|
+
listener(id);
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
onShareRevoked(callback) {
|
|
130
|
+
this.revocationListeners.add(callback);
|
|
131
|
+
return () => { this.revocationListeners.delete(callback); };
|
|
81
132
|
}
|
|
82
133
|
authenticate(ctx) {
|
|
83
134
|
// 1. Internal-token header (process-internal callers).
|
|
@@ -95,9 +146,13 @@ export class HmacMirrorAuthenticator {
|
|
|
95
146
|
const session = {
|
|
96
147
|
expiresAtMs: result.expiresAtMs,
|
|
97
148
|
canInspectPrompts: result.canInspectPrompts,
|
|
149
|
+
canControl: result.canControl !== false,
|
|
150
|
+
...(result.shareId ? { shareId: result.shareId } : {}),
|
|
98
151
|
};
|
|
99
152
|
return { ok: true, session, issueCookie: session, source: 'browser' };
|
|
100
153
|
}
|
|
154
|
+
if (tokenCandidate.split('.')[1] === 'observe')
|
|
155
|
+
return { ok: false, session: null, issueCookie: null, source: null };
|
|
101
156
|
}
|
|
102
157
|
// 3. Existing session cookie — no re-issuance.
|
|
103
158
|
const session = this.sessionFromCookies(ctx.cookies);
|
|
@@ -108,26 +163,21 @@ export class HmacMirrorAuthenticator {
|
|
|
108
163
|
return { ok: false, session: null, issueCookie: null, source: null };
|
|
109
164
|
}
|
|
110
165
|
authenticateUpgrade(ctx) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
const bearer = this.extractBearerToken(ctx.headers);
|
|
114
|
-
if (bearer && this.isValidToken(bearer).ok)
|
|
115
|
-
return true;
|
|
116
|
-
const queryToken = ctx.url.searchParams.get(this.queryTokenName) || '';
|
|
117
|
-
if (queryToken && this.isValidToken(queryToken).ok)
|
|
118
|
-
return true;
|
|
119
|
-
return this.sessionFromCookies(ctx.cookies) !== null;
|
|
166
|
+
const decision = this.authenticate(ctx);
|
|
167
|
+
return decision.ok && decision.session?.canControl !== false;
|
|
120
168
|
}
|
|
121
169
|
persistSession(session) {
|
|
122
170
|
const sessionId = randomUUID();
|
|
123
|
-
|
|
171
|
+
const observer = session.canControl === false || session.shareId !== undefined;
|
|
172
|
+
this.sessions.set(sessionId, { ...session, canControl: !observer, canInspectPrompts: observer ? false : session.canInspectPrompts });
|
|
124
173
|
return sessionId;
|
|
125
174
|
}
|
|
126
175
|
getSession(sessionId) {
|
|
127
176
|
const session = this.sessions.get(sessionId);
|
|
128
177
|
if (!session)
|
|
129
178
|
return null;
|
|
130
|
-
|
|
179
|
+
const share = session.shareId ? this.shares.get(session.shareId) : undefined;
|
|
180
|
+
if (Date.now() >= session.expiresAtMs || (session.shareId && (!share || share.revoked || Date.now() >= share.expiresAtMs))) {
|
|
131
181
|
this.sessions.delete(sessionId);
|
|
132
182
|
return null;
|
|
133
183
|
}
|
|
@@ -165,16 +215,16 @@ export class HmacMirrorAuthenticator {
|
|
|
165
215
|
* legacy `!mirrorAuthEnabled` fallback that ran AFTER the token path.
|
|
166
216
|
*/
|
|
167
217
|
export class OpenMirrorAuthenticator extends HmacMirrorAuthenticator {
|
|
168
|
-
|
|
218
|
+
constructor(config) { super(config); this.requiresCredentials = false; }
|
|
169
219
|
authenticate(ctx) {
|
|
170
220
|
const decision = super.authenticate(ctx);
|
|
171
221
|
if (decision.ok)
|
|
172
222
|
return decision;
|
|
223
|
+
const candidate = this.extractBearerToken(ctx.headers) || ctx.url.searchParams.get(this.queryTokenName) || '';
|
|
224
|
+
if (this.enabled || candidate.split('.')[1] === 'observe')
|
|
225
|
+
return decision;
|
|
173
226
|
return { ok: true, session: null, issueCookie: null, source: 'open' };
|
|
174
227
|
}
|
|
175
|
-
authenticateUpgrade(_ctx) {
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
228
|
}
|
|
179
229
|
/**
|
|
180
230
|
* Build the authenticator from environment policy, mirroring the legacy
|
|
@@ -8,18 +8,34 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Also provides bus connectivity for inter-ZTC messaging via SSE.
|
|
10
10
|
*/
|
|
11
|
+
import { type EvidenceSnapshot } from '../agent/runtime/evidence.js';
|
|
12
|
+
import type { TaskHandoffProjection } from '../session_handoff_contract.js';
|
|
11
13
|
import type { SlashCommandUsage } from '../agent/commands/index.js';
|
|
12
14
|
import type { MirrorPublisher, BusMessage, BusMember, ZlickyWebCursor, ZlickyWebHighlight, ZlickyWebStatus, HookApprovalPublishPayload } from './mirror_stream.js';
|
|
15
|
+
export interface MirrorClientOptions {
|
|
16
|
+
/** Absolute deadline for each local HTTP exchange, including its response body. */
|
|
17
|
+
publicationTimeoutMs?: number;
|
|
18
|
+
}
|
|
13
19
|
export declare class MirrorClient implements MirrorPublisher {
|
|
14
20
|
private port;
|
|
15
21
|
private paneId;
|
|
22
|
+
private readonly sessionId;
|
|
16
23
|
private busConnection;
|
|
17
24
|
private busReconnectTimer;
|
|
18
25
|
private paneName;
|
|
19
26
|
private lastTokenUsage;
|
|
20
27
|
private internalToken;
|
|
21
28
|
private groupId;
|
|
22
|
-
|
|
29
|
+
private readonly publicationTimeoutMs;
|
|
30
|
+
private publicationId;
|
|
31
|
+
private publicationSequence;
|
|
32
|
+
private publicationQueue;
|
|
33
|
+
private publicationBytes;
|
|
34
|
+
private publicationRequest;
|
|
35
|
+
private publicationDraining;
|
|
36
|
+
private publicationFailure;
|
|
37
|
+
private publicationDrain;
|
|
38
|
+
constructor(port: number, paneId: number, options?: MirrorClientOptions | string);
|
|
23
39
|
getPaneId(): number;
|
|
24
40
|
getPaneName(): string;
|
|
25
41
|
getBusMember(): BusMember;
|
|
@@ -27,7 +43,12 @@ export declare class MirrorClient implements MirrorPublisher {
|
|
|
27
43
|
type: string;
|
|
28
44
|
data: Record<string, unknown>;
|
|
29
45
|
}): void;
|
|
46
|
+
/** Resolve after acknowledged publications, or reject with the bounded transport failure. */
|
|
47
|
+
flushPublications(): Promise<void>;
|
|
48
|
+
private failPublication;
|
|
30
49
|
private postEvent;
|
|
50
|
+
private drainPublications;
|
|
51
|
+
private postPublication;
|
|
31
52
|
storeEvent(event: {
|
|
32
53
|
type: string;
|
|
33
54
|
data: Record<string, unknown>;
|
|
@@ -54,6 +75,8 @@ export declare class MirrorClient implements MirrorPublisher {
|
|
|
54
75
|
publishSettingsPage(data?: Record<string, unknown>): void;
|
|
55
76
|
publishStreamEnd(finalMessage?: string, metadata?: Record<string, unknown>): void;
|
|
56
77
|
publishToolCall(tool: string, args: Record<string, unknown>, toolCallId: string): void;
|
|
78
|
+
publishEvidenceSnapshot(snapshot: EvidenceSnapshot, sessionId: string): void;
|
|
79
|
+
publishTaskHandoff(projection: TaskHandoffProjection | null, sessionId: string): void;
|
|
57
80
|
publishToolResult(tool: string, result: string, success: boolean, toolCallId: string): void;
|
|
58
81
|
publishTodoList(todos: Array<{
|
|
59
82
|
content: string;
|
|
@@ -67,13 +90,17 @@ export declare class MirrorClient implements MirrorPublisher {
|
|
|
67
90
|
description: string;
|
|
68
91
|
recommended?: boolean;
|
|
69
92
|
}>;
|
|
70
|
-
}>, paneId?: number, allowOther?: boolean):
|
|
93
|
+
}>, paneId?: number, allowOther?: boolean): string;
|
|
71
94
|
publishHookApprovalRequest(request: HookApprovalPublishPayload): void;
|
|
95
|
+
publishHookApprovalResolved(id: string): void;
|
|
96
|
+
publishQuestionDismiss(questionId: string): void;
|
|
72
97
|
publishWidgetPrompt(widgetId: string, options: {
|
|
73
98
|
title?: string;
|
|
74
99
|
question: string;
|
|
75
100
|
placeholder?: string;
|
|
76
101
|
defaultValue?: string;
|
|
102
|
+
isPassword?: boolean;
|
|
103
|
+
allowEmptySubmit?: boolean;
|
|
77
104
|
}): void;
|
|
78
105
|
publishWidgetSelect(widgetId: string, options: {
|
|
79
106
|
title?: string;
|
|
@@ -104,7 +131,7 @@ export declare class MirrorClient implements MirrorPublisher {
|
|
|
104
131
|
}): void;
|
|
105
132
|
publishWidgetDismiss(widgetId: string): void;
|
|
106
133
|
publishWidgetSettings(widgetId: string, data: Record<string, unknown>): void;
|
|
107
|
-
publishStatus(status: string, verb?: string): void;
|
|
134
|
+
publishStatus(status: string, verb?: string, waiting?: import('../types.js').CommandWaitingState, toolProgress?: import('../types.js').AgentState['toolProgress']): void;
|
|
108
135
|
publishQueueState(total: number, entries: string[]): void;
|
|
109
136
|
publishTokenUsage(input: number, output: number, total: number, percentage: number, options?: {
|
|
110
137
|
reset?: boolean;
|
|
@@ -168,4 +195,4 @@ export declare class MirrorClient implements MirrorPublisher {
|
|
|
168
195
|
* Create a MirrorClient if the environment indicates we're a child pane
|
|
169
196
|
* with a parent mirror server. Returns null otherwise.
|
|
170
197
|
*/
|
|
171
|
-
export declare function initMirrorClient(): MirrorClient | null;
|
|
198
|
+
export declare function initMirrorClient(sessionId?: string): MirrorClient | null;
|
|
@@ -9,18 +9,43 @@
|
|
|
9
9
|
* Also provides bus connectivity for inter-ZTC messaging via SSE.
|
|
10
10
|
*/
|
|
11
11
|
import { request } from 'http';
|
|
12
|
+
import { parseEvidenceSnapshot } from '../agent/runtime/evidence.js';
|
|
13
|
+
import { parseToolProgress } from '../tool_progress.js';
|
|
14
|
+
import { parseTaskHandoffView } from './view_plugin.js';
|
|
15
|
+
import { randomUUID } from 'node:crypto';
|
|
16
|
+
import { MAX_TOOL_IMAGE_BODY_BYTES, mirrorToolImage } from './tool_image.js';
|
|
17
|
+
const MAX_PENDING_PUBLICATIONS = 256;
|
|
18
|
+
const MAX_PENDING_PUBLICATION_BYTES = 2 * 1024 * 1024;
|
|
19
|
+
const MAX_CHILD_EVENT_BYTES = 512 * 1024 - 512;
|
|
20
|
+
const MAX_PUBLICATION_RESPONSE_BYTES = 16 * 1024;
|
|
12
21
|
export class MirrorClient {
|
|
13
22
|
port;
|
|
14
23
|
paneId;
|
|
24
|
+
sessionId;
|
|
15
25
|
busConnection = null;
|
|
16
26
|
busReconnectTimer = null;
|
|
17
27
|
paneName;
|
|
18
28
|
lastTokenUsage = null;
|
|
19
29
|
internalToken;
|
|
20
30
|
groupId;
|
|
21
|
-
|
|
31
|
+
publicationTimeoutMs;
|
|
32
|
+
publicationId = null;
|
|
33
|
+
publicationSequence = 0;
|
|
34
|
+
publicationQueue = [];
|
|
35
|
+
publicationBytes = 0;
|
|
36
|
+
publicationRequest = null;
|
|
37
|
+
publicationDraining = false;
|
|
38
|
+
publicationFailure = null;
|
|
39
|
+
publicationDrain = Promise.resolve();
|
|
40
|
+
constructor(port, paneId, options = {}) {
|
|
22
41
|
this.port = port;
|
|
23
42
|
this.paneId = paneId;
|
|
43
|
+
this.sessionId = typeof options === 'string' ? options : null;
|
|
44
|
+
const timeout = (typeof options === 'string' ? {} : options).publicationTimeoutMs ?? 5000;
|
|
45
|
+
if (!Number.isSafeInteger(timeout) || timeout < 1 || timeout > 60_000) {
|
|
46
|
+
throw new RangeError('publicationTimeoutMs must be an integer between 1 and 60000');
|
|
47
|
+
}
|
|
48
|
+
this.publicationTimeoutMs = timeout;
|
|
24
49
|
this.paneName = paneId > 0 ? `ZTC ${paneId}` : 'ZTC';
|
|
25
50
|
this.internalToken = process.env.ZTC_MIRROR_INTERNAL_TOKEN || '';
|
|
26
51
|
this.groupId = process.env.ZTC_MIRROR_GROUP || '';
|
|
@@ -37,22 +62,141 @@ export class MirrorClient {
|
|
|
37
62
|
publish(event) {
|
|
38
63
|
this.postEvent(event);
|
|
39
64
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
65
|
+
/** Resolve after acknowledged publications, or reject with the bounded transport failure. */
|
|
66
|
+
async flushPublications() {
|
|
67
|
+
await this.publicationDrain;
|
|
68
|
+
if (this.publicationFailure)
|
|
69
|
+
throw this.publicationFailure;
|
|
70
|
+
}
|
|
71
|
+
failPublication(error) {
|
|
72
|
+
if (this.publicationFailure)
|
|
73
|
+
return;
|
|
74
|
+
this.publicationFailure = error;
|
|
75
|
+
const dropped = this.publicationQueue.length;
|
|
76
|
+
this.publicationQueue = [];
|
|
77
|
+
this.publicationBytes = 0;
|
|
78
|
+
this.publicationId = null;
|
|
79
|
+
this.publicationSequence = 0;
|
|
80
|
+
this.publicationRequest?.destroy();
|
|
81
|
+
process.stderr.write(`[Mirror pane=${this.paneId}] Child publication failed: ${error.message}. ${dropped} queued update(s) discarded; later updates open a fresh stream without replay.\n`);
|
|
82
|
+
}
|
|
83
|
+
postEvent(event, storeOnly = false, toolImage = false) {
|
|
84
|
+
if (this.sessionId !== null)
|
|
85
|
+
event = { ...event, data: { ...event.data, origin_session_id: this.sessionId } };
|
|
86
|
+
// A failure already tearing down its request cannot accept another update yet.
|
|
87
|
+
if (this.publicationDraining && this.publicationFailure)
|
|
88
|
+
return;
|
|
89
|
+
if (!this.publicationDraining)
|
|
90
|
+
this.publicationFailure = null;
|
|
91
|
+
let eventJson;
|
|
92
|
+
try {
|
|
93
|
+
eventJson = JSON.stringify(event);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
this.failPublication(new Error('Child event is not JSON serializable'));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const bytes = Buffer.byteLength(eventJson) + 512;
|
|
100
|
+
if (bytes > (toolImage ? MAX_TOOL_IMAGE_BODY_BYTES : MAX_CHILD_EVENT_BYTES)) {
|
|
101
|
+
this.failPublication(new Error('Child event exceeds the 512 KiB publication limit'));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (this.publicationQueue.length >= MAX_PENDING_PUBLICATIONS || this.publicationBytes + bytes > (toolImage ? MAX_TOOL_IMAGE_BODY_BYTES + MAX_PENDING_PUBLICATION_BYTES : MAX_PENDING_PUBLICATION_BYTES)) {
|
|
105
|
+
this.failPublication(new Error('Child publication queue exceeds 256 updates or 2 MiB'));
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
this.publicationQueue.push({ eventJson, bytes, storeOnly, toolImage });
|
|
109
|
+
this.publicationBytes += bytes;
|
|
110
|
+
if (!this.publicationDraining)
|
|
111
|
+
this.publicationDrain = this.drainPublications();
|
|
112
|
+
}
|
|
113
|
+
async drainPublications() {
|
|
114
|
+
this.publicationDraining = true;
|
|
115
|
+
try {
|
|
116
|
+
if (!this.publicationId) {
|
|
117
|
+
const opened = await this.postPublication('/pane-publication', JSON.stringify({ pane_id: this.paneId }));
|
|
118
|
+
if (this.publicationFailure)
|
|
119
|
+
throw this.publicationFailure;
|
|
120
|
+
if (typeof opened.publication_id !== 'string' || !opened.publication_id || opened.publication_id.length > 256) {
|
|
121
|
+
throw new Error('Parent mirror did not issue a publication identity; update parent and child to matching versions');
|
|
122
|
+
}
|
|
123
|
+
this.publicationId = opened.publication_id;
|
|
124
|
+
}
|
|
125
|
+
while (this.publicationQueue.length) {
|
|
126
|
+
const item = this.publicationQueue[0];
|
|
127
|
+
const sequence = this.publicationSequence + 1;
|
|
128
|
+
const payload = `{"pane_id":${this.paneId},"publication_id":${JSON.stringify(this.publicationId)},"sequence":${sequence},"event":${item.eventJson}${item.storeOnly ? ',"store_only":true' : ''}}`;
|
|
129
|
+
await this.postPublication('/pane-events', payload, item.toolImage);
|
|
130
|
+
if (this.publicationFailure)
|
|
131
|
+
throw this.publicationFailure;
|
|
132
|
+
this.publicationSequence = sequence;
|
|
133
|
+
this.publicationQueue.shift();
|
|
134
|
+
this.publicationBytes -= item.bytes;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
this.failPublication(error instanceof Error ? error : new Error(String(error)));
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
this.publicationDraining = false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
postPublication(path, payload, toolImage = false) {
|
|
145
|
+
return new Promise((resolve, reject) => {
|
|
146
|
+
const req = request({
|
|
147
|
+
hostname: 'localhost', port: this.port,
|
|
148
|
+
path: this.groupId ? `${path}/${this.groupId}` : path,
|
|
149
|
+
method: 'POST', headers: {
|
|
150
|
+
'Content-Type': 'application/json', 'Content-Length': Buffer.byteLength(payload),
|
|
151
|
+
...(this.internalToken ? { 'x-ztc-internal-token': this.internalToken } : {}),
|
|
152
|
+
...(toolImage ? { 'x-ztc-tool-image': '1' } : {}),
|
|
153
|
+
},
|
|
154
|
+
}, res => {
|
|
155
|
+
let output = '';
|
|
156
|
+
let bytes = 0;
|
|
157
|
+
res.on('data', (chunk) => {
|
|
158
|
+
bytes += chunk.length;
|
|
159
|
+
if (bytes > MAX_PUBLICATION_RESPONSE_BYTES) {
|
|
160
|
+
reject(new Error('Parent publication response exceeds 16 KiB'));
|
|
161
|
+
req.destroy();
|
|
162
|
+
res.destroy();
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
output += chunk.toString();
|
|
166
|
+
});
|
|
167
|
+
res.on('aborted', () => reject(new Error('Parent publication response was interrupted')));
|
|
168
|
+
res.on('error', reject);
|
|
169
|
+
res.on('end', () => {
|
|
170
|
+
if (res.statusCode !== 200) {
|
|
171
|
+
reject(new Error(`Parent publication HTTP ${res.statusCode ?? 0}`));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
try {
|
|
175
|
+
const body = JSON.parse(output);
|
|
176
|
+
if (!body || typeof body !== 'object' || Array.isArray(body) || body.ok !== true) {
|
|
177
|
+
reject(new Error('Parent publication receipt is malformed'));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
resolve(body);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
reject(new Error('Parent publication receipt is not valid JSON'));
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
this.publicationRequest = req;
|
|
188
|
+
const timer = setTimeout(() => {
|
|
189
|
+
reject(new Error(`Child publication timed out after ${this.publicationTimeoutMs} ms`));
|
|
190
|
+
req.destroy();
|
|
191
|
+
}, this.publicationTimeoutMs);
|
|
192
|
+
req.on('error', reject);
|
|
193
|
+
req.on('close', () => {
|
|
194
|
+
clearTimeout(timer);
|
|
195
|
+
if (this.publicationRequest === req)
|
|
196
|
+
this.publicationRequest = null;
|
|
197
|
+
});
|
|
198
|
+
req.end(payload);
|
|
52
199
|
});
|
|
53
|
-
req.on('error', () => { }); // fire-and-forget
|
|
54
|
-
req.write(payload);
|
|
55
|
-
req.end();
|
|
56
200
|
}
|
|
57
201
|
storeEvent(event) {
|
|
58
202
|
this.postEvent(event, true);
|
|
@@ -194,23 +338,37 @@ export class MirrorClient {
|
|
|
194
338
|
publishToolCall(tool, args, toolCallId) {
|
|
195
339
|
this.postEvent({ type: 'tool_call', data: { tool, args, toolCallId } });
|
|
196
340
|
}
|
|
341
|
+
publishEvidenceSnapshot(snapshot, sessionId) {
|
|
342
|
+
const validated = parseEvidenceSnapshot(snapshot);
|
|
343
|
+
if (!validated || !sessionId || Buffer.byteLength(sessionId) > 1024)
|
|
344
|
+
return;
|
|
345
|
+
this.postEvent({ type: 'evidence', data: { snapshot: validated, session_id: sessionId } });
|
|
346
|
+
}
|
|
347
|
+
publishTaskHandoff(projection, sessionId) {
|
|
348
|
+
const validated = parseTaskHandoffView({ sessionId, projection });
|
|
349
|
+
if (validated)
|
|
350
|
+
this.postEvent({ type: 'task_handoff', data: { ...validated } });
|
|
351
|
+
}
|
|
197
352
|
publishToolResult(tool, result, success, toolCallId) {
|
|
353
|
+
const image = mirrorToolImage(result);
|
|
198
354
|
this.postEvent({
|
|
199
355
|
type: 'tool_result',
|
|
200
|
-
data: { tool, result: result.slice(0, 2000), success, toolCallId },
|
|
201
|
-
});
|
|
356
|
+
data: { tool, result: image ? result : result.slice(0, 2000), success, toolCallId },
|
|
357
|
+
}, false, Boolean(image));
|
|
202
358
|
}
|
|
203
359
|
publishTodoList(todos) {
|
|
204
360
|
this.postEvent({ type: 'todo_list', data: { todos } });
|
|
205
361
|
}
|
|
206
362
|
publishAskUser(questions, paneId, allowOther) {
|
|
207
|
-
const
|
|
363
|
+
const questionId = randomUUID();
|
|
364
|
+
const baseData = { pane_id: paneId, question_id: questionId, allow_other: allowOther ?? true };
|
|
208
365
|
if (questions.length === 1) {
|
|
209
366
|
this.postEvent({ type: 'ask_user', data: { ...baseData, question: questions[0].question, options: questions[0].options } });
|
|
210
367
|
}
|
|
211
368
|
else {
|
|
212
369
|
this.postEvent({ type: 'ask_user', data: { ...baseData, questions } });
|
|
213
370
|
}
|
|
371
|
+
return questionId;
|
|
214
372
|
}
|
|
215
373
|
publishHookApprovalRequest(request) {
|
|
216
374
|
this.postEvent({
|
|
@@ -226,6 +384,12 @@ export class MirrorClient {
|
|
|
226
384
|
},
|
|
227
385
|
});
|
|
228
386
|
}
|
|
387
|
+
publishHookApprovalResolved(id) {
|
|
388
|
+
this.postEvent({ type: 'hook_approval_resolved', data: { id } });
|
|
389
|
+
}
|
|
390
|
+
publishQuestionDismiss(questionId) {
|
|
391
|
+
this.postEvent({ type: 'question_dismiss', data: { question_id: questionId } });
|
|
392
|
+
}
|
|
229
393
|
publishWidgetPrompt(widgetId, options) {
|
|
230
394
|
this.postEvent({ type: 'widget_prompt', data: { widget_id: widgetId, ...options } });
|
|
231
395
|
}
|
|
@@ -241,8 +405,10 @@ export class MirrorClient {
|
|
|
241
405
|
publishWidgetSettings(widgetId, data) {
|
|
242
406
|
this.postEvent({ type: 'widget_settings', data: { widget_id: widgetId, ...data } });
|
|
243
407
|
}
|
|
244
|
-
publishStatus(status, verb) {
|
|
245
|
-
|
|
408
|
+
publishStatus(status, verb, waiting, toolProgress) {
|
|
409
|
+
const observed = status === 'tool_executing' ? parseToolProgress(toolProgress) : null;
|
|
410
|
+
this.postEvent({ type: 'status', data: { status, verb, ...(waiting ? { waiting } : {}),
|
|
411
|
+
...(observed ? { toolProgress: observed } : {}) } });
|
|
246
412
|
}
|
|
247
413
|
publishQueueState(total, entries) {
|
|
248
414
|
this.postEvent({ type: 'queue_state', data: { total, entries } });
|
|
@@ -327,10 +493,10 @@ export class MirrorClient {
|
|
|
327
493
|
* Create a MirrorClient if the environment indicates we're a child pane
|
|
328
494
|
* with a parent mirror server. Returns null otherwise.
|
|
329
495
|
*/
|
|
330
|
-
export function initMirrorClient() {
|
|
496
|
+
export function initMirrorClient(sessionId) {
|
|
331
497
|
const port = process.env.ZTC_MIRROR_PORT;
|
|
332
498
|
const paneId = process.env.ZTC_PANE_ID;
|
|
333
499
|
if (!port)
|
|
334
500
|
return null;
|
|
335
|
-
return new MirrorClient(parseInt(port, 10), paneId ? parseInt(paneId, 10) : -1);
|
|
501
|
+
return new MirrorClient(parseInt(port, 10), paneId ? parseInt(paneId, 10) : -1, sessionId);
|
|
336
502
|
}
|