@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
|
@@ -9,13 +9,10 @@
|
|
|
9
9
|
* /accounts login <id> run the official CLI login at the account's dir
|
|
10
10
|
* /accounts remove <id> drop an account from the pool
|
|
11
11
|
*/
|
|
12
|
-
import { spawnSync } from 'node:child_process';
|
|
13
12
|
import { configStore } from '../../config.js';
|
|
14
|
-
import {
|
|
15
|
-
import { loginAutoRunEnabled, loginFailureReasonText, runLoginCommand } from '../backends/account_login.js';
|
|
16
|
-
import { notifyAccountsChanged } from '../backends/account_events.js';
|
|
13
|
+
import { canonicalAccountProvider, defaultAccountDir, defaultSourceFor, findCodexHomeCollision, isAccountProvider, probeAccountUsable, sourceDir, } from '../backends/account_pool.js';
|
|
17
14
|
import { codexStatusCache } from '../backends/codex_account_status.js';
|
|
18
|
-
import {
|
|
15
|
+
import { applyAccountOp } from '../../web/accounts_mirror.js';
|
|
19
16
|
const PROVIDER_LABELS = {
|
|
20
17
|
claude_code: 'Claude Code (claude CLI)',
|
|
21
18
|
codex_app_server: 'Codex (codex app-server)',
|
|
@@ -121,21 +118,28 @@ function parseAdd(args) {
|
|
|
121
118
|
}
|
|
122
119
|
return { provider, id, label: labelParts.join(' ') || id, path };
|
|
123
120
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
121
|
+
/** All mutating CLI and terminal-panel actions use the same owner admission and
|
|
122
|
+
* canonical operation as the mirror. The owner callback holds its runtime lease. */
|
|
123
|
+
async function applyOperation(body, ctx) {
|
|
124
|
+
return ctx.applyAccountOperation
|
|
125
|
+
? ctx.applyAccountOperation(body)
|
|
126
|
+
: applyAccountOp(body, configStore, () => ctx.reloadAgent());
|
|
127
|
+
}
|
|
128
|
+
function showOperationResult(result, ctx) {
|
|
129
|
+
say(ctx, [result.ok ? result.message : result.error, result.loginCommand]
|
|
130
|
+
.filter(Boolean).join('\n\n'));
|
|
131
|
+
}
|
|
132
|
+
async function addAccount(parsed, ctx) {
|
|
133
|
+
const result = await applyOperation({ op: 'add', ...parsed }, ctx);
|
|
134
|
+
if (!result.ok) {
|
|
135
|
+
const dir = parsed.path ?? defaultAccountDir(parsed.provider, parsed.id);
|
|
136
|
+
const collision = findCodexHomeCollision(configStore.listAccounts(), defaultSourceFor(parsed.provider, dir));
|
|
137
|
+
return {
|
|
138
|
+
error: configStore.getAccount(parsed.id) ? 'duplicate_id' : collision ? 'codex_home_collision' : 'operation_failed',
|
|
139
|
+
message: result.error ?? 'Account operation failed.',
|
|
140
|
+
};
|
|
133
141
|
}
|
|
134
|
-
|
|
135
|
-
const account = { id: parsed.id, label: parsed.label, provider: parsed.provider, source };
|
|
136
|
-
configStore.addAccount(account);
|
|
137
|
-
await configStore.save();
|
|
138
|
-
return { account };
|
|
142
|
+
return { account: configStore.getAccount(parsed.id) };
|
|
139
143
|
}
|
|
140
144
|
async function handleAdd(args, ctx) {
|
|
141
145
|
const parsed = parseAdd(args);
|
|
@@ -143,7 +147,7 @@ async function handleAdd(args, ctx) {
|
|
|
143
147
|
say(ctx, parsed);
|
|
144
148
|
return;
|
|
145
149
|
}
|
|
146
|
-
const result = await addAccount(parsed);
|
|
150
|
+
const result = await addAccount(parsed, ctx);
|
|
147
151
|
if ('error' in result) {
|
|
148
152
|
say(ctx, result.message);
|
|
149
153
|
return;
|
|
@@ -162,151 +166,20 @@ async function handleAdd(args, ctx) {
|
|
|
162
166
|
async function handleUse(args, ctx) {
|
|
163
167
|
const id = args[0];
|
|
164
168
|
if (!id) {
|
|
165
|
-
say(ctx,
|
|
169
|
+
say(ctx, 'Usage: /accounts use <id>');
|
|
166
170
|
return;
|
|
167
171
|
}
|
|
168
|
-
|
|
169
|
-
if (!account) {
|
|
170
|
-
say(ctx, `No account "${id}". See /accounts.`);
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
if (account.source.kind === 'codex_home') {
|
|
174
|
-
const status = await codexStatusCache.read(account.source.path, true);
|
|
175
|
-
if (status.state === 'reauth_required' || status.state === 'unavailable') {
|
|
176
|
-
say(ctx, status.state === 'reauth_required'
|
|
177
|
-
? `"${account.label}" needs a fresh ChatGPT sign-in. Run /accounts login ${account.id}, then switch again.`
|
|
178
|
-
: `"${account.label}" could not be verified. Refresh its status or sign in, then switch again.`);
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
configStore.setActiveAccount(account.provider, account.id);
|
|
183
|
-
await configStore.save();
|
|
184
|
-
const accountKey = canonicalAccountProvider(account.provider);
|
|
185
|
-
const isCurrentProvider = canonicalAccountProvider(configStore.getProvider()) === accountKey;
|
|
186
|
-
if (!probeAccountUsable(account)) {
|
|
187
|
-
say(ctx, `"${account.label}" is now the active ${PROVIDER_LABELS[account.provider]} account, but it has no credentials yet. Run /accounts login ${account.id}.`);
|
|
188
|
-
return;
|
|
189
|
-
}
|
|
190
|
-
if (isCurrentProvider) {
|
|
191
|
-
ctx.reloadAgent();
|
|
192
|
-
say(ctx, `Switched live ${PROVIDER_LABELS[account.provider]} account to "${account.label}".`);
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
say(ctx, `Set "${account.label}" active for ${PROVIDER_LABELS[account.provider]}. It goes live when you switch to that provider with /model.`);
|
|
196
|
-
}
|
|
172
|
+
showOperationResult(await applyOperation({ op: 'use', id }, ctx), ctx);
|
|
197
173
|
}
|
|
198
174
|
async function handleLogin(args, ctx) {
|
|
199
175
|
const id = args[0];
|
|
200
176
|
if (!id) {
|
|
201
|
-
say(ctx,
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
const account = configStore.getAccount(id);
|
|
205
|
-
if (!account) {
|
|
206
|
-
say(ctx, `No account "${id}". See /accounts.`);
|
|
177
|
+
say(ctx, 'Usage: /accounts login <id>');
|
|
207
178
|
return;
|
|
208
179
|
}
|
|
209
|
-
|
|
210
|
-
//
|
|
211
|
-
|
|
212
|
-
if (account.source.kind === 'kimi_creds_file') {
|
|
213
|
-
const credsPath = account.source.path;
|
|
214
|
-
say(ctx, 'Starting Kimi sign-in…');
|
|
215
|
-
try {
|
|
216
|
-
const result = await runKimiDeviceLogin({
|
|
217
|
-
authFilePath: credsPath,
|
|
218
|
-
onCode: (flow) => {
|
|
219
|
-
say(ctx, [
|
|
220
|
-
`Open this link to sign in "${account.label}":`,
|
|
221
|
-
'',
|
|
222
|
-
` ${flow.verificationUriComplete}`,
|
|
223
|
-
'',
|
|
224
|
-
`and confirm the code: ${flow.userCode}`,
|
|
225
|
-
'',
|
|
226
|
-
'Waiting for the sign-in to complete…',
|
|
227
|
-
].join('\n'));
|
|
228
|
-
},
|
|
229
|
-
});
|
|
230
|
-
if (result.outcome === 'succeeded') {
|
|
231
|
-
notifyAccountsChanged();
|
|
232
|
-
// Hot-swap only when this login changes creds the live agent is using.
|
|
233
|
-
const isCurrentActive = configStore.getActiveAccount(configStore.getProvider())?.id === account.id;
|
|
234
|
-
if (isCurrentActive)
|
|
235
|
-
ctx.reloadAgent();
|
|
236
|
-
say(ctx, `"${account.label}" is signed in. Make it live with: /accounts use ${account.id}`);
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
const why = result.outcome === 'denied'
|
|
240
|
-
? `the sign-in was denied${result.description ? ` (${result.description})` : ''}`
|
|
241
|
-
: result.outcome === 'expired'
|
|
242
|
-
? 'the code expired'
|
|
243
|
-
: 'the sign-in timed out';
|
|
244
|
-
say(ctx, `Kimi sign-in failed — ${why}. Try again: /accounts login ${account.id}`);
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
say(ctx, `Kimi sign-in failed: ${error.message}`);
|
|
249
|
-
}
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
const login = buildLoginCommand(account);
|
|
253
|
-
const manualHint = [
|
|
254
|
-
`Run this in a terminal to sign in "${account.label}" (no token enters ztc):`,
|
|
255
|
-
'',
|
|
256
|
-
` ${login.display}`,
|
|
257
|
-
'',
|
|
258
|
-
`Then: /accounts use ${account.id}`,
|
|
259
|
-
].join('\n');
|
|
260
|
-
// A blocking spawnSync(stdio:'inherit') would freeze the Node event loop —
|
|
261
|
-
// and with it every mirror pane — for the entire OAuth, and attach the login
|
|
262
|
-
// prompt to a terminal a web-mirror user cannot see. When there is no TTY, OR
|
|
263
|
-
// a web mirror is attached, auto-run the OAuth with piped stdio (non-blocking)
|
|
264
|
-
// and only hand the command back if it fails. No token enters ztc either way.
|
|
265
|
-
if (!process.stdout.isTTY || ctx.mirror?.isRunning()) {
|
|
266
|
-
if (!loginAutoRunEnabled()) {
|
|
267
|
-
say(ctx, manualHint);
|
|
268
|
-
return;
|
|
269
|
-
}
|
|
270
|
-
say(ctx, `Signing in "${account.label}" on the ztc host — complete it in the browser…`);
|
|
271
|
-
const attempt = await runLoginCommand(login, () => probeAccountUsable(account));
|
|
272
|
-
if (attempt.outcome === 'succeeded') {
|
|
273
|
-
if (account.source.kind === 'codex_home') {
|
|
274
|
-
codexStatusCache.invalidate(account.source.path);
|
|
275
|
-
const status = await codexStatusCache.read(account.source.path, true);
|
|
276
|
-
if (status.state === 'reauth_required' || status.state === 'unavailable') {
|
|
277
|
-
notifyAccountsChanged();
|
|
278
|
-
say(ctx, `"${account.label}" saved credentials, but the ChatGPT subscription could not be verified. Run /accounts login ${account.id} again.`);
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
notifyAccountsChanged();
|
|
283
|
-
say(ctx, `"${account.label}" is signed in. Make it live with: /accounts use ${account.id}`);
|
|
284
|
-
}
|
|
285
|
-
else {
|
|
286
|
-
say(ctx, [`Auto sign-in failed — ${loginFailureReasonText(attempt)}.`, '', manualHint].join('\n'));
|
|
287
|
-
}
|
|
288
|
-
return;
|
|
289
|
-
}
|
|
290
|
-
say(ctx, `Launching: ${login.display}\nComplete the login in the browser, then return here.`);
|
|
291
|
-
const result = spawnSync(login.command, login.args, { stdio: 'inherit', env: login.env });
|
|
292
|
-
if (result.error) {
|
|
293
|
-
say(ctx, [
|
|
294
|
-
`Couldn't launch "${login.command}" (${result.error.message}).`,
|
|
295
|
-
`Run it yourself:`,
|
|
296
|
-
'',
|
|
297
|
-
` ${login.display}`,
|
|
298
|
-
].join('\n'));
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
|
-
let ready = probeAccountUsable(account);
|
|
302
|
-
if (ready && account.source.kind === 'codex_home') {
|
|
303
|
-
codexStatusCache.invalidate(account.source.path);
|
|
304
|
-
const status = await codexStatusCache.read(account.source.path, true);
|
|
305
|
-
ready = status.state === 'ready' || status.state === 'quota_unavailable';
|
|
306
|
-
}
|
|
307
|
-
say(ctx, ready
|
|
308
|
-
? `"${account.label}" is signed in. Make it live with: /accounts use ${account.id}`
|
|
309
|
-
: `Login exited without usable credentials in ${sourceDir(account.source)}. Try again: /accounts login ${account.id}`);
|
|
180
|
+
// The canonical operation returns pending while the official/device login
|
|
181
|
+
// runs. Completion notification and idle-safe reload belong to the owner.
|
|
182
|
+
showOperationResult(await applyOperation({ op: 'login', id }, ctx), ctx);
|
|
310
183
|
}
|
|
311
184
|
function describeRotation() {
|
|
312
185
|
const r = configStore.getRotation();
|
|
@@ -327,50 +200,45 @@ async function handleRotation(args, ctx) {
|
|
|
327
200
|
say(ctx, describeRotation());
|
|
328
201
|
return;
|
|
329
202
|
}
|
|
203
|
+
const patch = { op: 'rotation' };
|
|
330
204
|
switch (field) {
|
|
331
205
|
case 'on':
|
|
332
|
-
|
|
206
|
+
patch.enabled = true;
|
|
333
207
|
break;
|
|
334
208
|
case 'off':
|
|
335
|
-
|
|
209
|
+
patch.enabled = false;
|
|
336
210
|
break;
|
|
337
211
|
case 'mode':
|
|
338
212
|
if (value !== 'failover' && value !== 'round_robin') {
|
|
339
213
|
say(ctx, 'Usage: /accounts rotation mode failover|round_robin');
|
|
340
214
|
return;
|
|
341
215
|
}
|
|
342
|
-
|
|
216
|
+
patch.mode = value;
|
|
343
217
|
break;
|
|
344
218
|
case 'subagents':
|
|
345
219
|
if (value !== 'inherit' && value !== 'pool') {
|
|
346
220
|
say(ctx, 'Usage: /accounts rotation subagents inherit|pool');
|
|
347
221
|
return;
|
|
348
222
|
}
|
|
349
|
-
|
|
223
|
+
patch.subagentInheritance = value;
|
|
350
224
|
break;
|
|
351
225
|
default:
|
|
352
226
|
say(ctx, `Unknown rotation field "${field}".\n\n${describeRotation()}`);
|
|
353
227
|
return;
|
|
354
228
|
}
|
|
355
|
-
await
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
229
|
+
const result = await applyOperation(patch, ctx);
|
|
230
|
+
if (!result.ok)
|
|
231
|
+
showOperationResult(result, ctx);
|
|
232
|
+
else
|
|
233
|
+
say(ctx, describeRotation());
|
|
359
234
|
}
|
|
360
235
|
async function handleRemove(args, ctx) {
|
|
361
236
|
const id = args[0];
|
|
362
237
|
if (!id) {
|
|
363
|
-
say(ctx,
|
|
364
|
-
return;
|
|
365
|
-
}
|
|
366
|
-
const account = configStore.getAccount(id);
|
|
367
|
-
if (!account) {
|
|
368
|
-
say(ctx, `No account "${id}". See /accounts.`);
|
|
238
|
+
say(ctx, 'Usage: /accounts remove <id>');
|
|
369
239
|
return;
|
|
370
240
|
}
|
|
371
|
-
|
|
372
|
-
await configStore.save();
|
|
373
|
-
say(ctx, `Removed "${account.label}" (${id}) from the pool. Its credential dir was left in place:\n ${sourceDir(account.source)}`);
|
|
241
|
+
showOperationResult(await applyOperation({ op: 'remove', id }, ctx), ctx);
|
|
374
242
|
}
|
|
375
243
|
// --- interactive terminal settings page (text list in non-interactive output) ---
|
|
376
244
|
function accountFamily(provider) {
|
|
@@ -440,10 +308,11 @@ function interactiveAddPage(ctx, provider) {
|
|
|
440
308
|
id,
|
|
441
309
|
label: draft.label.trim() || id,
|
|
442
310
|
path: draft.path.trim() || undefined,
|
|
443
|
-
}).then(result => {
|
|
311
|
+
}, ctx).then(result => {
|
|
444
312
|
if ('error' in result) {
|
|
445
|
-
error = result.error === 'duplicate_id' ? 'Account ID already exists'
|
|
446
|
-
|
|
313
|
+
error = result.error === 'duplicate_id' ? 'Account ID already exists'
|
|
314
|
+
: result.error === 'codex_home_collision' ? 'Credential directory in use' : result.message;
|
|
315
|
+
errorField = result.error === 'duplicate_id' ? 'id' : result.error === 'codex_home_collision' ? 'path' : 'create';
|
|
447
316
|
showPage(errorField);
|
|
448
317
|
}
|
|
449
318
|
else {
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
const USAGE = '/attention [list [page]|show <ID>|answer <ID> <text or JSON>|approve|deny <ID> [reason]|dismiss <ID>]';
|
|
2
|
+
function describe(item) {
|
|
3
|
+
const seconds = Math.max(0, Math.floor((Date.now() - Date.parse(item.createdAt)) / 1000));
|
|
4
|
+
const age = seconds < 60 ? `${seconds}s` : `${Math.floor(seconds / 60)}m`;
|
|
5
|
+
return `${item.id}\n ${item.kind} · ${item.agent} · session ${item.sessionId} · pane ${item.paneId} · ${age}\n Task: ${item.task}\n Needs you: ${item.blocker}\n Action: /attention ${item.primaryAction === 'inspect' ? 'show' : item.primaryAction} ${item.id}`;
|
|
6
|
+
}
|
|
7
|
+
export const attentionCommand = {
|
|
8
|
+
name: 'attention', description: 'Inspect and resolve requests that need a human', usage: USAGE,
|
|
9
|
+
handler: async (args, ctx) => {
|
|
10
|
+
const say = (content) => ctx.addMessage({ role: 'system', content });
|
|
11
|
+
const action = args[0] ?? 'list';
|
|
12
|
+
if (ctx.commandOrigin === 'agent' && !['list', 'show'].includes(action)) {
|
|
13
|
+
say('Only you can answer, approve or acknowledge human attention.');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
if (!ctx.attention)
|
|
18
|
+
throw new Error('Open the attention queue in the native overseer session.');
|
|
19
|
+
if (action === 'list') {
|
|
20
|
+
const page = Number(args[1] ?? 1);
|
|
21
|
+
if (!Number.isSafeInteger(page) || page < 1)
|
|
22
|
+
throw new Error('Page must be a positive integer.');
|
|
23
|
+
const snapshot = ctx.attention.snapshot(100, (page - 1) * 100);
|
|
24
|
+
say(snapshot.total === 0 ? 'No requests need your attention.' : [`Human attention · ${snapshot.total} items · page ${page}`,
|
|
25
|
+
...snapshot.items.map(describe), ...(snapshot.total > page * 100 ? [`Next: /attention list ${page + 1}`] : [])].join('\n'));
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const id = args[1];
|
|
29
|
+
if (!id)
|
|
30
|
+
throw new Error(USAGE);
|
|
31
|
+
if (action === 'dismiss') {
|
|
32
|
+
ctx.attention.dismiss(id);
|
|
33
|
+
say('Attention acknowledged.');
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (action === 'approve' || action === 'deny') {
|
|
37
|
+
ctx.attention.respond(id, { decision: action, reason: args.slice(2).join(' ') });
|
|
38
|
+
say(`Approval ${action === 'approve' ? 'approved' : 'denied'}.`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const snapshot = ctx.attention.snapshot();
|
|
42
|
+
// Search all pages so an ID in a large queue retains its exact owner.
|
|
43
|
+
let item = snapshot.items.find(item => item.id === id);
|
|
44
|
+
for (let offset = 100; !item && offset < snapshot.total; offset += 100) {
|
|
45
|
+
item = ctx.attention.snapshot(100, offset).items.find(item => item.id === id);
|
|
46
|
+
}
|
|
47
|
+
if (!item)
|
|
48
|
+
throw new Error('Stale attention request; inspect the current queue.');
|
|
49
|
+
if (action === 'show') {
|
|
50
|
+
say(describe(item));
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (action === 'answer') {
|
|
54
|
+
const text = args.slice(2).join(' ');
|
|
55
|
+
const response = item.kind === 'prompt'
|
|
56
|
+
? text.trim().startsWith('{') ? JSON.parse(text) : { value: text } : text;
|
|
57
|
+
ctx.attention.respond(id, response);
|
|
58
|
+
say('Answer delivered to its request owner.');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
throw new Error(USAGE);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
say(`Attention: ${error instanceof Error ? error.message : String(error)}`);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
};
|
|
@@ -3,12 +3,15 @@ import { runRouterAuthCommand } from '../../router_auth.js';
|
|
|
3
3
|
export const authCommand = {
|
|
4
4
|
name: 'auth',
|
|
5
5
|
description: 'Manage Zerg Router authentication',
|
|
6
|
-
usage: '<login|logout|status> [options]',
|
|
6
|
+
usage: '<login|logout|status|readiness|billing> [options]',
|
|
7
|
+
agentRunnable: false,
|
|
7
8
|
handler: async (args, ctx) => {
|
|
8
9
|
if (args.length === 0 || args[0] === 'help') {
|
|
9
10
|
ctx.addMessage({ role: 'system', content: [
|
|
10
11
|
'Zerg Router authentication:',
|
|
11
12
|
' /auth login [--url <origin>] [--no-browser] - Sign in through your browser',
|
|
13
|
+
' /auth readiness [--json] - Check personal funding and model availability without using quota',
|
|
14
|
+
' /auth billing [--no-browser] - Review personal pay-as-you-go funding in the browser',
|
|
12
15
|
' /auth status [--json] - Show the current Router session',
|
|
13
16
|
' /auth logout [--local-only] - Sign out',
|
|
14
17
|
'',
|
|
@@ -17,11 +20,24 @@ export const authCommand = {
|
|
|
17
20
|
return;
|
|
18
21
|
}
|
|
19
22
|
try {
|
|
20
|
-
|
|
23
|
+
// Keep process-only --router-url overrides when signing in from a session.
|
|
24
|
+
const origin = args[0] === 'login' && !args.includes('--url')
|
|
25
|
+
? configStore.get().zergProxyUrl : undefined;
|
|
26
|
+
await runRouterAuthCommand(origin ? [...args, '--url', origin] : args, message => {
|
|
21
27
|
ctx.addMessage({ role: 'system', content: message.trimEnd() });
|
|
22
28
|
});
|
|
23
29
|
if (args[0] === 'login' || args[0] === 'logout') {
|
|
24
30
|
await configStore.refresh();
|
|
31
|
+
if (args[0] === 'login' && configStore.resolveLLMBackendConfig().useProxy) {
|
|
32
|
+
// Sign-in changes catalog ownership. Discover before constructing the
|
|
33
|
+
// backend so the first turn uses the new account's model metadata.
|
|
34
|
+
try {
|
|
35
|
+
await ctx.models.catalog?.(undefined, { refresh: true });
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Catalog availability must not undo a successful sign-in.
|
|
39
|
+
}
|
|
40
|
+
}
|
|
25
41
|
// Logout must dispose of the old backend without building a new one
|
|
26
42
|
// from missing credentials. Login builds from the newly loaded session.
|
|
27
43
|
ctx.reloadAgent({ defer: args[0] === 'logout' });
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { BOARD_PENDING_MAX_BYTES } from '../../board/binding.js';
|
|
4
|
+
import { boardRequest, configuredBoardOrigin, boardCardResponse, boardDetailsResponse, boardAttachmentResponse } from '../../board/client.js';
|
|
5
|
+
import { buildSessionEvidencePackage } from '../../diagnostics/session_evidence_package.js';
|
|
6
|
+
import { loadSessionFromFile, updateSessionBoardBinding } from '../../session.js';
|
|
7
|
+
import { projectTaskHandoff } from '../../session_handoff_contract.js';
|
|
8
|
+
import { withPathLock } from '../../utils/path_lock.js';
|
|
9
|
+
const usage = '/board attach <board-uuid> <card-uuid> | create <board-uuid> <column-uuid> <title> | status | refresh | state <running|blocked|review|done> <state-uuid> | share | sync | discard <operation-uuid> | detach';
|
|
10
|
+
const identity = (value) => z.string().uuid('Invalid Zergboard UUID').parse(value);
|
|
11
|
+
const taskId = (session) => session.task_handoff?.taskId
|
|
12
|
+
?? `request:${session.messages.find(message => message.role === 'user')?.id ?? session.metadata.id}`;
|
|
13
|
+
async function run(args, ctx) {
|
|
14
|
+
const action = args[0];
|
|
15
|
+
if (!action)
|
|
16
|
+
return usage;
|
|
17
|
+
if (!['status'].includes(action) && ctx.commandOrigin === 'agent')
|
|
18
|
+
return 'Zergboard writes and association changes require an explicit user command.';
|
|
19
|
+
if (!ctx.checkpointSession || !ctx.getSessionId)
|
|
20
|
+
return 'Zergboard sync requires a host with a saved session checkpoint.';
|
|
21
|
+
const sessionId = ctx.getSessionId();
|
|
22
|
+
const file = await ctx.checkpointSession();
|
|
23
|
+
// Distinct from the canonical writer lock: serialize whole board operations
|
|
24
|
+
// in this process, but allow ordinary autosaves while HTTP is pending.
|
|
25
|
+
return withPathLock(file + '.board-operation', async () => {
|
|
26
|
+
const session = await loadSessionFromFile(file, false);
|
|
27
|
+
if (!session || session.metadata.id !== sessionId)
|
|
28
|
+
throw new Error('Zergboard checkpoint does not belong to the current session');
|
|
29
|
+
let binding = session.board_binding;
|
|
30
|
+
const save = async (next) => {
|
|
31
|
+
await updateSessionBoardBinding(file, sessionId, binding, next);
|
|
32
|
+
binding = next;
|
|
33
|
+
};
|
|
34
|
+
const origin = configuredBoardOrigin();
|
|
35
|
+
if (binding && binding.origin !== origin)
|
|
36
|
+
throw new Error('Configured Zergboard origin differs from the attached destination');
|
|
37
|
+
if (action === 'discard') {
|
|
38
|
+
if (args.length !== 2)
|
|
39
|
+
return usage;
|
|
40
|
+
const key = identity(args[1]);
|
|
41
|
+
if (!binding?.pending || binding.pending.key !== key)
|
|
42
|
+
return 'Discard requires the matching pending operation ID; use /board status to inspect it.';
|
|
43
|
+
// This is an explicit local retirement, not remote cancellation. An
|
|
44
|
+
// accepted operation can still exist even when its receipt was lost.
|
|
45
|
+
const next = binding.pending.kind === 'create' ? undefined : { ...binding, pending: undefined };
|
|
46
|
+
await save(next);
|
|
47
|
+
return `Pending operation ${key} discarded locally; remote outcome remains unknown. Inspect Zergboard before choosing a fresh operation; /board refresh acknowledges manual changes on an attached card.`;
|
|
48
|
+
}
|
|
49
|
+
if (action === 'detach') {
|
|
50
|
+
if (args.length !== 1)
|
|
51
|
+
return usage;
|
|
52
|
+
if (binding?.pending)
|
|
53
|
+
return `Pending operation ${binding.pending.key} has an unknown remote outcome. Use /board sync first; explicitly /board discard ${binding.pending.key} only after inspecting Zergboard.`;
|
|
54
|
+
await save(undefined);
|
|
55
|
+
return 'Zergboard card detached; remote card unchanged.';
|
|
56
|
+
}
|
|
57
|
+
if (action === 'attach' || action === 'create') {
|
|
58
|
+
if (binding)
|
|
59
|
+
return 'Session already linked or has a pending operation. Use /board status or /board sync; detach before choosing a different task.';
|
|
60
|
+
const boardId = identity(args[1]), target = identity(args[2]);
|
|
61
|
+
if (action === 'attach' && args.length !== 3)
|
|
62
|
+
return usage;
|
|
63
|
+
if (action === 'create' && args.length < 4)
|
|
64
|
+
return usage;
|
|
65
|
+
const details = await boardRequest(origin, sessionId, `/api/boards/${boardId}`, boardDetailsResponse);
|
|
66
|
+
if (details.board.id !== boardId)
|
|
67
|
+
throw new Error('Zergboard response belongs to a different board');
|
|
68
|
+
const next = { version: 1, sessionId, taskUuid: randomUUID(), taskId: taskId(session), origin, boardId };
|
|
69
|
+
if (action === 'attach') {
|
|
70
|
+
const { card } = await boardRequest(origin, sessionId, `/api/cards/${target}`, boardCardResponse);
|
|
71
|
+
if (card.id !== target || card.board_id !== boardId)
|
|
72
|
+
throw new Error('Zergboard card belongs to a different board');
|
|
73
|
+
await save({ ...next, cardId: card.id, revision: card.revision });
|
|
74
|
+
return `Attached Zergboard card ${card.id} to task ${next.taskUuid}. ${card.title} — ${card.status} (revision ${card.revision}).`;
|
|
75
|
+
}
|
|
76
|
+
if (!details.columns.some(column => column.id === target))
|
|
77
|
+
throw new Error('Zergboard column does not belong to the selected board');
|
|
78
|
+
const title = z.string().min(1).max(255).parse(args.slice(3).join(' '));
|
|
79
|
+
await save({ ...next, pending: { kind: 'create', key: randomUUID(), body: { boardId, columnId: target, title,
|
|
80
|
+
description: `ZTC session ${sessionId}\nTask ${next.taskUuid}\nSource task ${next.taskId}\nCompletion requires an explicit user decision; idle is not completion.` } } });
|
|
81
|
+
}
|
|
82
|
+
else if (!binding)
|
|
83
|
+
return 'No Zergboard card attached. ' + usage;
|
|
84
|
+
if (!binding)
|
|
85
|
+
throw new Error('Zergboard association unavailable');
|
|
86
|
+
if (action === 'status' || action === 'refresh') {
|
|
87
|
+
if (args.length !== 1)
|
|
88
|
+
return usage;
|
|
89
|
+
if (!binding.cardId)
|
|
90
|
+
return `Zergboard creation pending for task ${binding.taskUuid}; operation ${binding.pending?.key}. Use /board sync first; inspect Zergboard before explicitly discarding an unknown outcome.`;
|
|
91
|
+
const { card } = await boardRequest(origin, sessionId, `/api/cards/${binding.cardId}`, boardCardResponse);
|
|
92
|
+
if (card.id !== binding.cardId || card.board_id !== binding.boardId)
|
|
93
|
+
throw new Error('Attached card moved to a different board; sync refused');
|
|
94
|
+
if (action === 'refresh') {
|
|
95
|
+
if (binding.pending)
|
|
96
|
+
return `Pending operation ${binding.pending.key} retains its original revision. Use /board sync first; inspect Zergboard before explicitly /board discard ${binding.pending.key}.`;
|
|
97
|
+
await save({ ...binding, revision: card.revision });
|
|
98
|
+
}
|
|
99
|
+
return `Zergboard ${card.id}: ${card.title} — ${card.status}, state ${card.state_id ?? 'unknown'}, revision ${card.revision}; acknowledged revision ${binding.revision}. Task ${binding.taskUuid}.${binding.pending ? ` Pending operation ${binding.pending.key} retained; use /board sync first; inspect Zergboard before explicitly discarding an unknown outcome.` : ''} Idle never establishes completion.`;
|
|
100
|
+
}
|
|
101
|
+
if (action === 'state') {
|
|
102
|
+
if (args.length !== 3 || !['running', 'blocked', 'review', 'done'].includes(args[1]))
|
|
103
|
+
return usage;
|
|
104
|
+
if (!binding.cardId || binding.pending)
|
|
105
|
+
return 'Reconcile the pending operation with /board sync before changing state.';
|
|
106
|
+
const stateId = identity(args[2]);
|
|
107
|
+
const details = await boardRequest(origin, sessionId, `/api/boards/${binding.boardId}`, boardDetailsResponse);
|
|
108
|
+
const state = details.states.find(state => state.id === stateId);
|
|
109
|
+
if (details.board.id !== binding.boardId || !state || (args[1] === 'done') !== (state.kind === 'done'))
|
|
110
|
+
throw new Error('Selected state is not a matching state on the attached board');
|
|
111
|
+
const { card } = await boardRequest(origin, sessionId, `/api/cards/${binding.cardId}`, boardCardResponse, { method: 'PATCH', body: { stateId }, revision: binding.revision });
|
|
112
|
+
if (card.id !== binding.cardId || card.board_id !== binding.boardId || card.state_id !== stateId)
|
|
113
|
+
throw new Error('Zergboard state receipt does not match the requested card/state');
|
|
114
|
+
await save({ ...binding, revision: card.revision });
|
|
115
|
+
return `Zergboard ${args[1]} decision saved: ${card.status}, revision ${card.revision}.`;
|
|
116
|
+
}
|
|
117
|
+
if (action === 'share') {
|
|
118
|
+
if (args.length !== 1)
|
|
119
|
+
return usage;
|
|
120
|
+
if (binding.pending)
|
|
121
|
+
return 'Pending operation retained. Use /board sync before sharing a newer checkpoint.';
|
|
122
|
+
if (!binding.cardId)
|
|
123
|
+
return 'Create or attach a card before sharing evidence.';
|
|
124
|
+
if (binding.taskId !== taskId(session))
|
|
125
|
+
return 'Current session task changed; detach and explicitly attach the new task before sharing evidence.';
|
|
126
|
+
const pkg = buildSessionEvidencePackage({ sessionId, messages: session.messages, diagnostics: session.diagnostics,
|
|
127
|
+
evidence: session.evidence, taskHandoff: session.task_handoff ? projectTaskHandoff(session.task_handoff) : null });
|
|
128
|
+
if (binding.lastEvidence?.packageId === pkg.packageId)
|
|
129
|
+
return `Evidence package ${pkg.packageId} already shared as attachment ${binding.lastEvidence.attachmentId}.`;
|
|
130
|
+
const bytes = Buffer.from(JSON.stringify(pkg));
|
|
131
|
+
if (bytes.length > BOARD_PENDING_MAX_BYTES)
|
|
132
|
+
return 'Evidence package exceeds the 512 KiB sync limit. Use /clipboard package save to export the full package to a file.';
|
|
133
|
+
await save({ ...binding, pending: { kind: 'evidence', key: randomUUID(), packageId: pkg.packageId,
|
|
134
|
+
expectedRevision: binding.revision, body: { filename: `ztc-${pkg.packageId}.json`, mime_type: 'application/json', data: bytes.toString('base64') } } });
|
|
135
|
+
}
|
|
136
|
+
if (['sync', 'share', 'create'].includes(action)) {
|
|
137
|
+
if (action === 'sync' && args.length !== 1)
|
|
138
|
+
return usage;
|
|
139
|
+
const pending = binding.pending;
|
|
140
|
+
if (!pending)
|
|
141
|
+
return 'No pending Zergboard operation. Use /board status to inspect the remote card.';
|
|
142
|
+
if (pending.kind === 'create') {
|
|
143
|
+
const { card } = await boardRequest(origin, sessionId, '/api/cards/terminal-sync-v1', boardCardResponse, { method: 'POST', body: pending.body, key: pending.key });
|
|
144
|
+
if (card.board_id !== binding.boardId)
|
|
145
|
+
throw new Error('Zergboard creation receipt belongs to a different board');
|
|
146
|
+
await save({ ...binding, pending: undefined, cardId: card.id, revision: card.revision });
|
|
147
|
+
return `Attached Zergboard card ${card.id} to task ${binding.taskUuid}.`;
|
|
148
|
+
}
|
|
149
|
+
const receipt = await boardRequest(origin, sessionId, `/api/cards/${binding.cardId}/terminal-evidence-v1`, boardAttachmentResponse, { method: 'POST', body: pending.body, key: pending.key, revision: pending.expectedRevision });
|
|
150
|
+
if (receipt.attachment.card_id !== binding.cardId)
|
|
151
|
+
throw new Error('Zergboard evidence receipt belongs to a different card');
|
|
152
|
+
await save({ ...binding, pending: undefined, revision: receipt.revision,
|
|
153
|
+
lastEvidence: { packageId: pending.packageId, attachmentId: receipt.attachment.id, revision: receipt.revision } });
|
|
154
|
+
return `Evidence receipt saved: attachment ${receipt.attachment.id}, package ${pending.packageId}. Receipt proves accepted bytes; it does not establish task completion.`;
|
|
155
|
+
}
|
|
156
|
+
return usage;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
export const boardCommand = { name: 'board', description: 'Attach a saved session to Zergboard and explicitly sync state/evidence', usage,
|
|
160
|
+
async handler(args, ctx) {
|
|
161
|
+
try {
|
|
162
|
+
ctx.addMessage({ role: 'system', content: await run(args, ctx) });
|
|
163
|
+
}
|
|
164
|
+
catch (error) {
|
|
165
|
+
// Never echo remote response bodies or credentials into the transcript.
|
|
166
|
+
const message = error instanceof Error ? error.message : 'Request failed';
|
|
167
|
+
ctx.addMessage({ role: 'system', content: `Zergboard: ${message}. Operation outcome may be unknown; pending intent is retained for /board sync.` });
|
|
168
|
+
}
|
|
169
|
+
} };
|