@gajae-code/coding-agent 0.18.11 → 0.19.0
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/CHANGELOG.md +760 -0
- package/dist/types/async/job-manager.d.ts +7 -3
- package/dist/types/async/result-formatting.d.ts +2 -0
- package/dist/types/autoresearch/git.d.ts +1 -1
- package/dist/types/capability/fs.d.ts +2 -2
- package/dist/types/capability/rule.d.ts +7 -2
- package/dist/types/cli/accounts-cli.d.ts +2 -2
- package/dist/types/cli/append-system-prompt.d.ts +6 -0
- package/dist/types/cli/args.d.ts +7 -2
- package/dist/types/cli/customize-doctor-precedence.d.ts +16 -0
- package/dist/types/cli/customize-doctor.d.ts +4 -3
- package/dist/types/cli/doctor/install-repairs.d.ts +4 -1
- package/dist/types/cli/install-activation.d.ts +10 -4
- package/dist/types/cli/public-command-errors.d.ts +2 -0
- package/dist/types/cli/root-flags.d.ts +0 -12
- package/dist/types/cli/update-cli.d.ts +21 -3
- package/dist/types/cli-main.d.ts +0 -6
- package/dist/types/cli-ordinary.d.ts +2 -2
- package/dist/types/commands/accounts.d.ts +2 -1
- package/dist/types/commands/launch.d.ts +0 -6
- package/dist/types/commands/migrate.d.ts +1 -1
- package/dist/types/commands/sdk.d.ts +13 -0
- package/dist/types/commit/changelog/index.d.ts +1 -0
- package/dist/types/commit/map-reduce/index.d.ts +4 -4
- package/dist/types/config/autorouting-tier-map.d.ts +53 -1
- package/dist/types/config/config-hot-reload-trust.d.ts +12 -0
- package/dist/types/config/config-hot-reload.d.ts +44 -0
- package/dist/types/config/file-lock.d.ts +52 -3
- package/dist/types/config/model-discovery-manager.d.ts +2 -0
- package/dist/types/config/model-profile-activation.d.ts +79 -9
- package/dist/types/config/model-registry.d.ts +72 -8
- package/dist/types/config/model-resolver.d.ts +7 -4
- package/dist/types/config/models-config-schema.d.ts +10 -0
- package/dist/types/config/settings-schema.d.ts +57 -4
- package/dist/types/config/settings.d.ts +33 -1
- package/dist/types/coordinator-mcp/server.d.ts +4 -0
- package/dist/types/customization/import.d.ts +2 -0
- package/dist/types/customization/types.d.ts +1 -1
- package/dist/types/dap/config.d.ts +8 -4
- package/dist/types/dap/session.d.ts +11 -2
- package/dist/types/debug/system-info.d.ts +6 -1
- package/dist/types/discovery/helpers.d.ts +7 -2
- package/dist/types/discovery/mcp-compat.d.ts +3 -1
- package/dist/types/edit/index.d.ts +5 -0
- package/dist/types/edit/modes/patch.d.ts +14 -0
- package/dist/types/edit/modes/replace.d.ts +3 -0
- package/dist/types/eval/py/runtime.d.ts +9 -0
- package/dist/types/exec/bash-executor.d.ts +12 -0
- package/dist/types/export/ttsr.d.ts +19 -0
- package/dist/types/extensibility/extensions/types.d.ts +5 -1
- package/dist/types/extensibility/slash-commands.d.ts +1 -0
- package/dist/types/gjc-runtime/managed-owner-admission.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-current-final.d.ts +54 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +5 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +2 -0
- package/dist/types/gjc-runtime/state-runtime.d.ts +0 -2
- package/dist/types/gjc-runtime/tmux-sessions.d.ts +24 -0
- package/dist/types/gjc-runtime/ultragoal-change-set.d.ts +6 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +1 -0
- package/dist/types/harness-control-plane/receipt-spool.d.ts +4 -0
- package/dist/types/hindsight/content.d.ts +5 -6
- package/dist/types/internal-urls/types.d.ts +2 -0
- package/dist/types/lsp/clients/swiftlint-client.d.ts +0 -4
- package/dist/types/main.d.ts +23 -18
- package/dist/types/migrate/action-planner.d.ts +10 -1
- package/dist/types/migrate/adapters/codex.d.ts +2 -1
- package/dist/types/migrate/adapters/index.d.ts +42 -1
- package/dist/types/migrate/executor.d.ts +3 -1
- package/dist/types/migrate/hook-module.d.ts +23 -0
- package/dist/types/migrate/report.d.ts +2 -1
- package/dist/types/migrate/types.d.ts +82 -3
- package/dist/types/modes/components/agent-dashboard.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +43 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -0
- package/dist/types/modes/prompt-suggestion-controller.d.ts +1 -1
- package/dist/types/modes/theme/theme.d.ts +1 -0
- package/dist/types/modes/utils/host-status.d.ts +15 -11
- package/dist/types/runtime-mcp/content-limits.d.ts +4 -0
- package/dist/types/runtime-mcp/manager.d.ts +7 -0
- package/dist/types/runtime-mcp/plugin-mcp-name-filter.d.ts +22 -0
- package/dist/types/runtime-mcp/project-host-values.d.ts +11 -5
- package/dist/types/runtime-mcp/tool-bridge.d.ts +4 -0
- package/dist/types/sdk/broker/broker-exit.d.ts +3 -3
- package/dist/types/sdk/broker/broker.d.ts +29 -2
- package/dist/types/sdk/broker/daemon-entry.d.ts +11 -1
- package/dist/types/sdk/broker/doctor-restart.d.ts +1 -1
- package/dist/types/sdk/broker/ensure.d.ts +141 -9
- package/dist/types/sdk/broker/hop.d.ts +45 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +18 -10
- package/dist/types/sdk/broker/lifecycle.d.ts +22 -0
- package/dist/types/sdk/broker/lock-host-identity.d.ts +5 -0
- package/dist/types/sdk/broker/session-index.d.ts +6 -1
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/chat-command-policy.d.ts +2 -1
- package/dist/types/sdk/bus/index.d.ts +44 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +9 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +2 -0
- package/dist/types/sdk/bus/threaded-render.d.ts +2 -1
- package/dist/types/sdk/cli/session-cli.d.ts +0 -1
- package/dist/types/sdk/host/control/operations.d.ts +5 -1
- package/dist/types/sdk/host/events.d.ts +4 -0
- package/dist/types/sdk/host/host.d.ts +2 -1
- package/dist/types/sdk/host/prompt-image-upload.d.ts +43 -0
- package/dist/types/sdk/host/session-runtime.d.ts +40 -8
- package/dist/types/sdk/host/surface-policy.d.ts +2 -1
- package/dist/types/sdk/lifecycle/service.d.ts +12 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +42 -4
- package/dist/types/sdk/prompt-deadline-manager.d.ts +2 -0
- package/dist/types/sdk/prompt-status.d.ts +11 -4
- package/dist/types/sdk/protocol/adapter-validation.d.ts +10 -4
- package/dist/types/sdk/reconciliation-extensions.d.ts +1 -1
- package/dist/types/sdk/session-list.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +107 -9
- package/dist/types/session/internal/managed-session-scope.d.ts +2 -2
- package/dist/types/session/internal/managed-session-storage.d.ts +1 -1
- package/dist/types/session/internal/native-publish-outcome.d.ts +1 -1
- package/dist/types/session/messages.d.ts +5 -1
- package/dist/types/session/session-manager.d.ts +29 -3
- package/dist/types/session/startup-auth-config.d.ts +24 -2
- package/dist/types/session/streaming-output.d.ts +11 -0
- package/dist/types/session/terminal-abort.d.ts +3 -1
- package/dist/types/session-import/service.d.ts +1 -1
- package/dist/types/skill-state/workflow-mutation-guard.d.ts +20 -4
- package/dist/types/slash-commands/helpers/mcp.d.ts +5 -0
- package/dist/types/slash-commands/helpers/provider-auth-status.d.ts +8 -0
- package/dist/types/ssh/ssh-executor.d.ts +8 -1
- package/dist/types/system-prompt.d.ts +3 -2
- package/dist/types/task/executor.d.ts +19 -2
- package/dist/types/task/role-body.d.ts +11 -0
- package/dist/types/tools/ast-edit-write-path.d.ts +10 -0
- package/dist/types/tools/atomic-file-write.d.ts +9 -7
- package/dist/types/tools/awaiting-input.d.ts +28 -0
- package/dist/types/tools/bash-allowed-prefixes.d.ts +17 -0
- package/dist/types/tools/bash-skill-urls.d.ts +4 -0
- package/dist/types/tools/bash.d.ts +7 -0
- package/dist/types/tools/descriptors.d.ts +15 -2
- package/dist/types/tools/fetch.d.ts +7 -1
- package/dist/types/tools/index.d.ts +2 -0
- package/dist/types/tools/irc.d.ts +5 -3
- package/dist/types/tools/python.d.ts +1 -1
- package/dist/types/tools/report-issue.d.ts +41 -0
- package/dist/types/tools/subagent.d.ts +23 -0
- package/dist/types/tools/tmux-self-injection-guard.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +1 -1
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/file-mentions.d.ts +5 -0
- package/dist/types/utils/image-limits.d.ts +7 -0
- package/dist/types/utils/image-loading.d.ts +0 -1
- package/dist/types/utils/open.d.ts +0 -1
- package/dist/types/utils/pasted-image-loading.d.ts +1 -5
- package/dist/types/utils/prompt-suggestion.d.ts +2 -2
- package/dist/types/utils/shell-snapshot.d.ts +2 -0
- package/dist/types/utils/title-generator.d.ts +13 -3
- package/dist/types/web/scrapers/types.d.ts +8 -1
- package/dist/types/web/search/providers/codex.d.ts +6 -7
- package/dist/types/web/search/providers/insane.d.ts +7 -1
- package/dist/types/web/search/providers/searxng.d.ts +5 -0
- package/package.json +10 -9
- package/scripts/acp-conformance-agent.ts +12 -2
- package/scripts/build-binary.ts +2 -1
- package/scripts/capture-subagent-compact-panel-showcase.ts +105 -0
- package/scripts/generate-docs-index.ts +8 -1
- package/scripts/generate-sdk-operation-inventory.ts +38 -4
- package/src/async/job-manager.ts +356 -56
- package/src/async/result-formatting.ts +40 -0
- package/src/autoresearch/git.ts +9 -2
- package/src/autoresearch/prompts/prompt-setup.md +1 -1
- package/src/capability/fs.ts +58 -22
- package/src/capability/index.ts +2 -2
- package/src/capability/rule.ts +11 -2
- package/src/cli/accounts-cli.ts +176 -8
- package/src/cli/append-system-prompt.ts +12 -0
- package/src/cli/args.ts +11 -7
- package/src/cli/auth-broker-cli.ts +21 -11
- package/src/cli/customize-doctor-precedence.ts +31 -0
- package/src/cli/customize-doctor.ts +49 -39
- package/src/cli/doctor/install-repairs.ts +35 -5
- package/src/cli/fast-help.ts +1 -3
- package/src/cli/install-activation.ts +47 -4
- package/src/cli/migrate-cli.ts +19 -6
- package/src/cli/public-command-errors.ts +6 -0
- package/src/cli/root-flags.ts +2 -4
- package/src/cli/stats-cli.ts +9 -5
- package/src/cli/update-cli.ts +471 -13
- package/src/cli-ordinary.ts +7 -2
- package/src/commands/accounts.ts +10 -5
- package/src/commands/harness.ts +25 -15
- package/src/commands/migrate.ts +3 -3
- package/src/commands/sdk.ts +277 -50
- package/src/commands/ultragoal.ts +16 -8
- package/src/commit/agentic/agent.ts +6 -6
- package/src/commit/analysis/conventional.ts +14 -5
- package/src/commit/changelog/index.ts +39 -1
- package/src/commit/map-reduce/index.ts +7 -7
- package/src/commit/message.ts +10 -3
- package/src/commit/pipeline.ts +12 -12
- package/src/config/autorouting-tier-map.ts +50 -1
- package/src/config/config-file.ts +106 -3
- package/src/config/config-hot-reload-trust.ts +148 -0
- package/src/config/config-hot-reload.ts +742 -0
- package/src/config/file-lock.ts +1615 -328
- package/src/config/keybindings.ts +154 -7
- package/src/config/model-bindings-applier.ts +85 -47
- package/src/config/model-discovery-manager.ts +10 -0
- package/src/config/model-profile-activation.ts +889 -148
- package/src/config/model-registry.ts +1706 -205
- package/src/config/model-resolver.ts +52 -22
- package/src/config/models-config-schema.ts +6 -0
- package/src/config/settings-schema.ts +73 -4
- package/src/config/settings.ts +460 -24
- package/src/coordinator-mcp/policy.ts +26 -1
- package/src/coordinator-mcp/server.ts +37 -2
- package/src/crash/sanitize.ts +7 -1
- package/src/customization/import.ts +279 -8
- package/src/customization/inventory.ts +24 -8
- package/src/customization/types.ts +1 -0
- package/src/dap/client.ts +3 -2
- package/src/dap/config.ts +31 -11
- package/src/dap/defaults.json +1 -1
- package/src/dap/session.ts +161 -36
- package/src/debug/crash-diagnostics.ts +89 -6
- package/src/debug/report-bundle.ts +90 -2
- package/src/debug/system-info.ts +8 -3
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/shared/base-url.ts +21 -7
- package/src/discovery/agents-md.ts +1 -1
- package/src/discovery/builtin.ts +4 -3
- package/src/discovery/helpers.ts +25 -16
- package/src/discovery/mcp-compat.ts +120 -17
- package/src/edit/apply-patch/index.ts +12 -1
- package/src/edit/index.ts +204 -22
- package/src/edit/modes/patch.ts +214 -8
- package/src/edit/modes/replace.ts +136 -0
- package/src/eval/js/context-manager.ts +29 -3
- package/src/eval/js/worker-entry.ts +51 -18
- package/src/eval/py/executor.ts +14 -4
- package/src/eval/py/runner.py +144 -5
- package/src/eval/py/runtime.ts +44 -4
- package/src/exec/bash-executor.ts +81 -4
- package/src/exec/bash-shell-guardian.ts +4 -1
- package/src/exec/bash-shell-supervisor.ts +8 -4
- package/src/exec/isolated-shell.ts +5 -1
- package/src/exec/non-interactive-env.ts +0 -1
- package/src/export/html/index.ts +86 -6
- package/src/export/ttsr.ts +176 -1
- package/src/extensibility/custom-tools/wrapper.ts +3 -1
- package/src/extensibility/extensions/loader.ts +10 -1
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +63 -1
- package/src/extensibility/extensions/types.ts +5 -1
- package/src/extensibility/hooks/loader.ts +10 -2
- package/src/extensibility/plugins/marketplace/fetcher.ts +2 -2
- package/src/extensibility/plugins/marketplace/manager.ts +36 -10
- package/src/extensibility/slash-commands.ts +5 -0
- package/src/gjc-runtime/gc-runtime.ts +37 -7
- package/src/gjc-runtime/launch-tmux.ts +30 -15
- package/src/gjc-runtime/launch-worktree.test.ts +148 -0
- package/src/gjc-runtime/launch-worktree.ts +101 -14
- package/src/gjc-runtime/managed-owner-admission.ts +46 -2
- package/src/gjc-runtime/ralplan-current-final.ts +294 -0
- package/src/gjc-runtime/ralplan-runtime.ts +95 -1
- package/src/gjc-runtime/session-resolution.ts +38 -6
- package/src/gjc-runtime/session-state-lock.ts +59 -14
- package/src/gjc-runtime/state-runtime.ts +23 -19
- package/src/gjc-runtime/state-writer.ts +109 -5
- package/src/gjc-runtime/tmux-sessions.ts +93 -13
- package/src/gjc-runtime/ultragoal-change-set.ts +90 -11
- package/src/gjc-runtime/ultragoal-guard.ts +9 -1
- package/src/gjc-runtime/ultragoal-runtime.ts +15 -5
- package/src/harness-control-plane/finalize.ts +11 -0
- package/src/harness-control-plane/receipt-spool.ts +105 -28
- package/src/harness-control-plane/storage.ts +124 -6
- package/src/hindsight/content.ts +116 -16
- package/src/hindsight/mental-models.ts +22 -10
- package/src/hindsight/state.ts +7 -4
- package/src/hooks/native-skill-hook.ts +17 -12
- package/src/internal-urls/artifact-protocol.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +23 -22
- package/src/internal-urls/local-protocol.ts +167 -8
- package/src/internal-urls/types.ts +2 -0
- package/src/lsp/client.ts +2 -1
- package/src/lsp/clients/biome-client.ts +2 -0
- package/src/lsp/clients/swiftlint-client.ts +2 -0
- package/src/lsp/index.ts +29 -0
- package/src/lsp/workspace-path.ts +23 -0
- package/src/main.ts +330 -92
- package/src/memories/index.ts +25 -2
- package/src/migrate/action-planner.ts +574 -2
- package/src/migrate/adapters/claude-code.ts +162 -5
- package/src/migrate/adapters/codex.ts +77 -7
- package/src/migrate/adapters/index.ts +258 -5
- package/src/migrate/adapters/opencode.ts +10 -1
- package/src/migrate/executor.ts +222 -7
- package/src/migrate/hook-module.ts +193 -0
- package/src/migrate/report.ts +63 -2
- package/src/migrate/types.ts +84 -4
- package/src/modes/DESIGN.md +51 -0
- package/src/modes/acp/acp-agent.ts +10 -1
- package/src/modes/acp/permission-mode.ts +18 -1
- package/src/modes/components/agent-dashboard.ts +20 -4
- package/src/modes/components/assistant-message.ts +55 -1
- package/src/modes/components/customization/customization-dashboard.ts +7 -0
- package/src/modes/components/customization/import-wizard.ts +29 -3
- package/src/modes/components/model-selector.ts +157 -103
- package/src/modes/components/settings-selector.ts +103 -37
- package/src/modes/components/welcome.ts +3 -1
- package/src/modes/controllers/command-controller.ts +300 -9
- package/src/modes/controllers/event-controller.ts +1 -1
- package/src/modes/controllers/extension-ui-controller.ts +31 -1
- package/src/modes/controllers/goal-mode-controller.ts +79 -10
- package/src/modes/controllers/input-controller.ts +2 -0
- package/src/modes/controllers/plan-mode-controller.ts +66 -11
- package/src/modes/controllers/runtime-mcp-command-controller.ts +7 -6
- package/src/modes/controllers/selector-controller.ts +76 -7
- package/src/modes/interactive-mode.ts +123 -4
- package/src/modes/prompt-suggestion-controller.ts +1 -1
- package/src/modes/runtime-init.ts +5 -1
- package/src/modes/theme/theme.ts +15 -0
- package/src/modes/utils/host-status.ts +21 -10
- package/src/prompts/agent-fragments/browser-aside.md +2 -2
- package/src/prompts/system/irc-incoming.md +3 -1
- package/src/prompts/tools/debug.md +1 -1
- package/src/prompts/tools/irc.md +1 -1
- package/src/prompts/tools/read.md +1 -1
- package/src/prompts/tools/report-issue.md +13 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/runtime-credential-selector.ts +2 -2
- package/src/runtime-mcp/content-limits.ts +7 -0
- package/src/runtime-mcp/manager-pool.test.ts +5 -4
- package/src/runtime-mcp/manager.ts +40 -3
- package/src/runtime-mcp/oauth-flow.ts +32 -6
- package/src/runtime-mcp/plugin-mcp-name-filter.ts +62 -0
- package/src/runtime-mcp/project-host-values.ts +12 -8
- package/src/runtime-mcp/render.ts +16 -1
- package/src/runtime-mcp/tool-bridge.ts +194 -21
- package/src/runtime-mcp/transports/stdio.ts +2 -1
- package/src/sdk/broker/broker-exit.ts +10 -5
- package/src/sdk/broker/broker.ts +484 -85
- package/src/sdk/broker/daemon-entry.ts +338 -116
- package/src/sdk/broker/doctor-restart.ts +2 -1
- package/src/sdk/broker/ensure.ts +1214 -268
- package/src/sdk/broker/hop.ts +286 -0
- package/src/sdk/broker/lifecycle-ledger.ts +38 -11
- package/src/sdk/broker/lifecycle.ts +102 -6
- package/src/sdk/broker/lock-host-identity.ts +29 -0
- package/src/sdk/broker/session-index.ts +91 -16
- package/src/sdk/broker/transport.ts +17 -1
- package/src/sdk/bus/chat-command-policy.ts +16 -3
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/index.ts +460 -35
- package/src/sdk/bus/reconciliation-store.ts +201 -8
- package/src/sdk/bus/session-control.ts +2 -0
- package/src/sdk/bus/slack-daemon.ts +105 -9
- package/src/sdk/bus/telegram-daemon-contract.ts +9 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -2
- package/src/sdk/bus/threaded-render.ts +20 -1
- package/src/sdk/cli/session-cli.ts +23 -6
- package/src/sdk/host/control/dispatch.ts +13 -1
- package/src/sdk/host/control/operations.ts +10 -1
- package/src/sdk/host/events.ts +67 -4
- package/src/sdk/host/host.ts +8 -2
- package/src/sdk/host/prompt-image-upload.ts +438 -0
- package/src/sdk/host/sdk-surface-parity.test.ts +15 -0
- package/src/sdk/host/session-runtime.test.ts +1737 -129
- package/src/sdk/host/session-runtime.ts +684 -83
- package/src/sdk/host/surface-policy.ts +4 -0
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +90 -2
- package/src/sdk/host/websocket-transport.ts +19 -7
- package/src/sdk/lifecycle/service.ts +15 -1
- package/src/sdk/prompt-deadline-flush.ts +78 -5
- package/src/sdk/prompt-deadline-manager.ts +68 -14
- package/src/sdk/prompt-status.ts +6 -4
- package/src/sdk/protocol/adapter-validation.ts +81 -12
- package/src/sdk/protocol/operation-inventory.generated.json +261 -2
- package/src/sdk/protocol/operation-registry.ts +33 -3
- package/src/sdk/reconciliation-extensions.ts +1 -0
- package/src/sdk/session-list.ts +1 -0
- package/src/sdk/session.ts +237 -97
- package/src/session/agent-session.ts +2726 -479
- package/src/session/history-storage.ts +182 -12
- package/src/session/internal/managed-session-scope.ts +173 -57
- package/src/session/internal/managed-session-storage.ts +85 -12
- package/src/session/internal/native-publish-outcome.ts +5 -1
- package/src/session/messages.ts +47 -6
- package/src/session/session-manager.ts +326 -19
- package/src/session/startup-auth-config.ts +116 -8
- package/src/session/streaming-output.ts +262 -4
- package/src/session/terminal-abort.ts +14 -2
- package/src/session-import/redact.ts +53 -2
- package/src/session-import/service.ts +1 -0
- package/src/skill-state/workflow-mutation-guard.ts +2145 -206
- package/src/slash-commands/builtin-registry.ts +21 -6
- package/src/slash-commands/helpers/credential-switch.ts +10 -5
- package/src/slash-commands/helpers/mcp.ts +11 -3
- package/src/slash-commands/helpers/provider-auth-status.ts +456 -0
- package/src/ssh/ssh-executor.ts +9 -2
- package/src/stt/recorder.ts +26 -9
- package/src/system-prompt.ts +61 -16
- package/src/task/executor.ts +115 -20
- package/src/task/index.ts +389 -175
- package/src/task/role-body.ts +84 -0
- package/src/task/token-log-mode.test.ts +162 -0
- package/src/task/token-log.ts +91 -2
- package/src/tools/archive-reader.ts +650 -37
- package/src/tools/ask.ts +1 -0
- package/src/tools/ast-edit-write-path.ts +64 -0
- package/src/tools/ast-edit.ts +18 -1
- package/src/tools/ast-grep.ts +7 -2
- package/src/tools/atomic-file-write.ts +46 -15
- package/src/tools/auto-generated-guard.ts +15 -3
- package/src/tools/awaiting-input.ts +114 -0
- package/src/tools/bash-allowed-prefixes.ts +214 -6
- package/src/tools/bash-interactive.ts +14 -2
- package/src/tools/bash-skill-urls.ts +58 -5
- package/src/tools/bash.ts +113 -26
- package/src/tools/browser/tab-worker.ts +39 -13
- package/src/tools/browser.ts +17 -7
- package/src/tools/cron.ts +10 -1
- package/src/tools/debug.ts +16 -8
- package/src/tools/descriptors.test.ts +44 -0
- package/src/tools/descriptors.ts +50 -6
- package/src/tools/eval.ts +15 -0
- package/src/tools/fetch.ts +93 -4
- package/src/tools/gh.ts +27 -12
- package/src/tools/image-gen.ts +20 -6
- package/src/tools/index.ts +2 -0
- package/src/tools/irc.ts +5 -3
- package/src/tools/monitor.ts +9 -1
- package/src/tools/output-meta.ts +74 -5
- package/src/tools/python.ts +1 -1
- package/src/tools/read.ts +26 -37
- package/src/tools/recipe/runner.ts +23 -12
- package/src/tools/render-utils.ts +2 -2
- package/src/tools/report-issue.ts +184 -0
- package/src/tools/search.ts +3 -2
- package/src/tools/ssh.ts +274 -8
- package/src/tools/subagent-render.ts +114 -12
- package/src/tools/subagent.ts +118 -5
- package/src/tools/tmux-self-injection-guard.ts +3301 -122
- package/src/tools/todo-write.ts +41 -3
- package/src/tools/tool-catalog.generated.ts +32 -4
- package/src/tools/ultragoal-ask-guard.ts +13 -1
- package/src/tools/write.ts +42 -3
- package/src/tui/tree-list.ts +15 -1
- package/src/utils/commit-message-generator.ts +12 -4
- package/src/utils/external-editor.ts +21 -7
- package/src/utils/file-mentions.ts +75 -7
- package/src/utils/git.ts +38 -7
- package/src/utils/image-limits.ts +8 -0
- package/src/utils/image-loading.ts +1 -1
- package/src/utils/open.ts +73 -4
- package/src/utils/pasted-image-loading.ts +9 -8
- package/src/utils/prompt-suggestion.ts +5 -4
- package/src/utils/shell-snapshot.ts +9 -1
- package/src/utils/title-generator.ts +72 -22
- package/src/web/scrapers/index.ts +3 -1
- package/src/web/scrapers/types.ts +8 -0
- package/src/web/scrapers/youtube.ts +3 -2
- package/src/web/search/index.ts +2 -1
- package/src/web/search/providers/codex.ts +29 -32
- package/src/web/search/providers/insane.ts +91 -28
- package/src/web/search/providers/searxng.ts +62 -10
package/src/commands/harness.ts
CHANGED
|
@@ -47,7 +47,11 @@ import {
|
|
|
47
47
|
} from "../harness-control-plane/lifecycle-reconciliation";
|
|
48
48
|
import { type ResolvedOwner, RuntimeOwner, resolveOwner, resolveOwnerLive } from "../harness-control-plane/owner";
|
|
49
49
|
import { preserveDirtyWorktree } from "../harness-control-plane/preserve";
|
|
50
|
-
import {
|
|
50
|
+
import {
|
|
51
|
+
RECEIPT_SPOOL_DIR_ENV,
|
|
52
|
+
resolveReceiptSpoolDir,
|
|
53
|
+
trustedReceiptSpoolDir,
|
|
54
|
+
} from "../harness-control-plane/receipt-spool";
|
|
51
55
|
import { buildReceipt, requiresVanishBeforeAction, type VanishEvidence } from "../harness-control-plane/receipts";
|
|
52
56
|
import { createSdkSessionTransport, spawnNormalHarnessSession } from "../harness-control-plane/sdk-transport";
|
|
53
57
|
import { classifyLeaseStatus, readLease } from "../harness-control-plane/session-lease";
|
|
@@ -1004,8 +1008,9 @@ export default class Harness extends Command {
|
|
|
1004
1008
|
`${GJC_TMUX_OWNER_STATE_DIR_ENV}=${shellQuote(ownerStateDir)}`,
|
|
1005
1009
|
`${GJC_TMUX_OWNER_SERVER_KEY_ENV}=${shellQuote(socketKey)}`,
|
|
1006
1010
|
];
|
|
1007
|
-
|
|
1008
|
-
|
|
1011
|
+
const trustedSpoolDir = resolveReceiptSpoolDir();
|
|
1012
|
+
if (trustedSpoolDir) envAssignments.push(`${RECEIPT_SPOOL_DIR_ENV}=${shellQuote(trustedSpoolDir)}`);
|
|
1013
|
+
else envAssignments.unshift(`-u ${RECEIPT_SPOOL_DIR_ENV}`);
|
|
1009
1014
|
if (process.env.GJC_HARNESS_TEST_NODE_MODULES)
|
|
1010
1015
|
envAssignments.push(`GJC_HARNESS_TEST_NODE_MODULES=${shellQuote(process.env.GJC_HARNESS_TEST_NODE_MODULES)}`);
|
|
1011
1016
|
if (process.env.GJC_SDK_DISABLE)
|
|
@@ -1203,19 +1208,20 @@ export default class Harness extends Command {
|
|
|
1203
1208
|
}
|
|
1204
1209
|
const fallbackReason = tmux.reason;
|
|
1205
1210
|
const cmd = this.#buildOwnerCommand(sessionId);
|
|
1211
|
+
const trustedSpoolDir = resolveReceiptSpoolDir();
|
|
1212
|
+
const childEnv: NodeJS.ProcessEnv = {
|
|
1213
|
+
...process.env,
|
|
1214
|
+
GJC_HARNESS_STATE_ROOT: root,
|
|
1215
|
+
...(process.env.GJC_HARNESS_TEST_NODE_MODULES
|
|
1216
|
+
? { GJC_HARNESS_TEST_NODE_MODULES: process.env.GJC_HARNESS_TEST_NODE_MODULES }
|
|
1217
|
+
: {}),
|
|
1218
|
+
...(process.env.GJC_SDK_DISABLE ? { GJC_SDK_DISABLE: process.env.GJC_SDK_DISABLE } : {}),
|
|
1219
|
+
};
|
|
1220
|
+
if (trustedSpoolDir) childEnv[RECEIPT_SPOOL_DIR_ENV] = trustedSpoolDir;
|
|
1221
|
+
else delete childEnv[RECEIPT_SPOOL_DIR_ENV];
|
|
1206
1222
|
const child = Bun.spawn(cmd, {
|
|
1207
1223
|
cwd,
|
|
1208
|
-
env:
|
|
1209
|
-
...process.env,
|
|
1210
|
-
GJC_HARNESS_STATE_ROOT: root,
|
|
1211
|
-
...(process.env[RECEIPT_SPOOL_DIR_ENV]
|
|
1212
|
-
? { [RECEIPT_SPOOL_DIR_ENV]: process.env[RECEIPT_SPOOL_DIR_ENV] }
|
|
1213
|
-
: {}),
|
|
1214
|
-
...(process.env.GJC_HARNESS_TEST_NODE_MODULES
|
|
1215
|
-
? { GJC_HARNESS_TEST_NODE_MODULES: process.env.GJC_HARNESS_TEST_NODE_MODULES }
|
|
1216
|
-
: {}),
|
|
1217
|
-
...(process.env.GJC_SDK_DISABLE ? { GJC_SDK_DISABLE: process.env.GJC_SDK_DISABLE } : {}),
|
|
1218
|
-
},
|
|
1224
|
+
env: childEnv,
|
|
1219
1225
|
stdout: "ignore",
|
|
1220
1226
|
stderr: "ignore",
|
|
1221
1227
|
stdin: "ignore",
|
|
@@ -1374,7 +1380,11 @@ export default class Harness extends Command {
|
|
|
1374
1380
|
if (!owner.live || !owner.socketPath) return false;
|
|
1375
1381
|
const priorSpoolDir = input[RECEIPT_SPOOL_DIR_ENV];
|
|
1376
1382
|
try {
|
|
1377
|
-
|
|
1383
|
+
const fromEnv = resolveReceiptSpoolDir();
|
|
1384
|
+
const fromInput = trustedReceiptSpoolDir(typeof priorSpoolDir === "string" ? priorSpoolDir : undefined);
|
|
1385
|
+
const trustedSpoolDir = fromEnv ?? fromInput;
|
|
1386
|
+
if (trustedSpoolDir) input[RECEIPT_SPOOL_DIR_ENV] = trustedSpoolDir;
|
|
1387
|
+
else delete input[RECEIPT_SPOOL_DIR_ENV];
|
|
1378
1388
|
const res = (await callEndpoint(owner.socketPath, { verb, input })) as { ok?: boolean };
|
|
1379
1389
|
writeJson(res);
|
|
1380
1390
|
if (res?.ok === false) process.exitCode = 1;
|
package/src/commands/migrate.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Import MCP servers and
|
|
2
|
+
* Import MCP servers, skills, slash commands, and instructions from other coding agents into GJC.
|
|
3
3
|
*/
|
|
4
4
|
import { Command, Flags } from "@gajae-code/utils/cli";
|
|
5
5
|
import { type MigrateCommandArgs, runMigrateCommand } from "../cli/migrate-cli";
|
|
6
6
|
|
|
7
7
|
export default class Migrate extends Command {
|
|
8
|
-
static description = "Import MCP servers and
|
|
8
|
+
static description = "Import MCP servers, skills, slash commands, and instructions from other coding agents";
|
|
9
9
|
|
|
10
10
|
static examples = [
|
|
11
11
|
"gjc migrate --from claude-code",
|
|
@@ -25,7 +25,7 @@ export default class Migrate extends Command {
|
|
|
25
25
|
default: false,
|
|
26
26
|
}),
|
|
27
27
|
force: Flags.boolean({
|
|
28
|
-
description: "Overwrite existing skills
|
|
28
|
+
description: "Overwrite existing skills, commands, MCP servers, or instruction files instead of skipping them",
|
|
29
29
|
default: false,
|
|
30
30
|
}),
|
|
31
31
|
"dry-run": Flags.boolean({ description: "Preview the migration without writing anything", default: false }),
|
package/src/commands/sdk.ts
CHANGED
|
@@ -12,12 +12,15 @@ import {
|
|
|
12
12
|
} from "@gajae-code/natives";
|
|
13
13
|
import { getAgentDir, logger, postmortem } from "@gajae-code/utils";
|
|
14
14
|
import { CliParseError, Command } from "@gajae-code/utils/cli";
|
|
15
|
+
import { startupProjectEnvSnapshot } from "@gajae-code/utils/env";
|
|
16
|
+
import { type ProjectEnvSnapshot, projectEnvSnapshot } from "@gajae-code/utils/env-file";
|
|
15
17
|
import type { Args as ParsedArgs } from "../cli/args";
|
|
16
18
|
import { isSafeSdkInternalAgentDir, scanPublicCommand } from "../cli/public-command-entry";
|
|
17
19
|
import { PublicCommandFailure } from "../cli/public-command-errors";
|
|
18
|
-
import { FileLockAcquireError } from "../config/file-lock";
|
|
20
|
+
import { FileLockAcquireError, isFileLockAcquireTimeout } from "../config/file-lock";
|
|
19
21
|
import { parseModelString } from "../config/model-resolver";
|
|
20
22
|
import { Settings } from "../config/settings";
|
|
23
|
+
import { trustedCoordinatorEnv } from "../gjc-runtime/sidecar-bootstrap-env";
|
|
21
24
|
import { usePostmortemSignalExitAuthority } from "../lsp/client";
|
|
22
25
|
import { applyStartupModelProfiles, createSessionManager } from "../main";
|
|
23
26
|
import { initializeExtensions } from "../modes/runtime-init";
|
|
@@ -29,15 +32,21 @@ import {
|
|
|
29
32
|
type BrokerStartupExitWriteStatus,
|
|
30
33
|
writeBrokerStartupExitRecordBounded,
|
|
31
34
|
} from "../sdk/broker/broker-exit";
|
|
32
|
-
import {
|
|
35
|
+
import {
|
|
36
|
+
type BrokerRestartIntentWithIdentity,
|
|
37
|
+
readBrokerDiscovery,
|
|
38
|
+
readBrokerRestartIntent,
|
|
39
|
+
} from "../sdk/broker/discovery";
|
|
33
40
|
import { type EndpointFileRead, readEndpointFile } from "../sdk/broker/endpoint-authority";
|
|
34
41
|
import {
|
|
35
42
|
BROKER_DISCOVERY_BUDGET,
|
|
36
43
|
emitBrokerStartupTestSignal,
|
|
44
|
+
reapBrokerTrampolineChild,
|
|
37
45
|
reconcileBrokerGenerationForStartup,
|
|
38
46
|
SDK_BROKER_AUTOSTART_ENV,
|
|
39
47
|
withBrokerStartupLock,
|
|
40
48
|
} from "../sdk/broker/ensure";
|
|
49
|
+
import { waitForBrokerHandoffAcknowledgement, waitForBrokerHandoffDecision } from "../sdk/broker/hop";
|
|
41
50
|
import {
|
|
42
51
|
LifecycleFailurePublicationCleanupError,
|
|
43
52
|
LifecycleReadinessCleanupError,
|
|
@@ -88,11 +97,17 @@ export async function lifecycleArgs(
|
|
|
88
97
|
if (targetScope.kind !== "resolved") throw new Error(`Lifecycle session scope is invalid: ${targetScope.message}`);
|
|
89
98
|
const forkSessionDir =
|
|
90
99
|
request.operation === "session.fork" ? SessionManager.getDefaultSessionDir(cwd, agentDir) : undefined;
|
|
100
|
+
// Bun has already copied the project dotenv into process.env. A matching or
|
|
101
|
+
// dynamic declaration must not select an in-memory session. The exact "1"
|
|
102
|
+
// check stays; an operator value the project does not declare is still honored.
|
|
103
|
+
const inMemorySession =
|
|
104
|
+
process.env.GJC_SDK_TEST_IN_MEMORY_SESSION === "1" &&
|
|
105
|
+
trustedCoordinatorEnv("GJC_SDK_TEST_IN_MEMORY_SESSION", process.env, projectEnvSnapshot(cwd)) === "1";
|
|
91
106
|
return {
|
|
92
107
|
messages: [],
|
|
93
108
|
fileArgs: [],
|
|
94
109
|
unknownFlags: new Map(),
|
|
95
|
-
...(
|
|
110
|
+
...(inMemorySession ? { noSession: true } : {}),
|
|
96
111
|
...(request.operation === "session.resume" ? { resume: request.sessionPath } : {}),
|
|
97
112
|
...(request.modelPreset ? { mpreset: request.modelPreset } : {}),
|
|
98
113
|
// Explicit model pin (#4707): coordinator-resolved `provider/model`
|
|
@@ -547,6 +562,65 @@ export function startMemoryBackendAfterReadiness(start: () => Promise<void>): vo
|
|
|
547
562
|
});
|
|
548
563
|
}
|
|
549
564
|
|
|
565
|
+
const SDK_CWD_EQUALITY_TEST_SEAMS = [
|
|
566
|
+
"GJC_SDK_TEST_HANG_MODEL_PROFILE",
|
|
567
|
+
"GJC_SDK_TEST_FAIL_AFTER_REGISTRATION",
|
|
568
|
+
"GJC_SDK_TEST_EXIT_AFTER_READY",
|
|
569
|
+
"GJC_SDK_TEST_REJECT_AFTER_READY",
|
|
570
|
+
] as const;
|
|
571
|
+
|
|
572
|
+
type SdkCwdEqualityTestSeam = (typeof SDK_CWD_EQUALITY_TEST_SEAMS)[number];
|
|
573
|
+
|
|
574
|
+
function isSdkCwdEqualityTestSeam(name: string): name is SdkCwdEqualityTestSeam {
|
|
575
|
+
return (SDK_CWD_EQUALITY_TEST_SEAMS as readonly string[]).includes(name);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
function sdkCwdEqualitySnapshots(cwd: string): ProjectEnvSnapshot[] {
|
|
579
|
+
// The startup snapshot keeps a declaration Bun loaded before a later chdir.
|
|
580
|
+
return [projectEnvSnapshot(cwd), startupProjectEnvSnapshot()];
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* Cwd-equality test seams accept only an operator value. A project dotenv line,
|
|
585
|
+
* including one Bun expands from `$PWD`, never arms the seam.
|
|
586
|
+
*/
|
|
587
|
+
export function sdkCwdEqualityTestSeamActive(
|
|
588
|
+
name: string,
|
|
589
|
+
cwd: string,
|
|
590
|
+
env: NodeJS.ProcessEnv = process.env,
|
|
591
|
+
snapshots: readonly ProjectEnvSnapshot[] = sdkCwdEqualitySnapshots(cwd),
|
|
592
|
+
): boolean {
|
|
593
|
+
if (!isSdkCwdEqualityTestSeam(name) || env[name] !== cwd) return false;
|
|
594
|
+
// Provenance only. trustedCoordinatorEnv trims, so a second compare to cwd
|
|
595
|
+
// would drop a trusted path that still matches exactly, including trailing space.
|
|
596
|
+
return snapshots.every(snapshot => trustedCoordinatorEnv(name, env, snapshot) !== undefined);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
/** Copy `env` without project-dotenv values for the four cwd-equality seams. */
|
|
600
|
+
export function omitUntrustedSdkCwdEqualitySeams(
|
|
601
|
+
env: NodeJS.ProcessEnv,
|
|
602
|
+
snapshots: readonly ProjectEnvSnapshot[],
|
|
603
|
+
): NodeJS.ProcessEnv {
|
|
604
|
+
const denied: string[] = [];
|
|
605
|
+
for (const name of SDK_CWD_EQUALITY_TEST_SEAMS) {
|
|
606
|
+
const raw = env[name];
|
|
607
|
+
if (typeof raw !== "string" || raw.length === 0) continue;
|
|
608
|
+
if (snapshots.some(snapshot => trustedCoordinatorEnv(name, env, snapshot) === undefined)) denied.push(name);
|
|
609
|
+
}
|
|
610
|
+
if (denied.length === 0) return env;
|
|
611
|
+
const next: NodeJS.ProcessEnv = { ...env };
|
|
612
|
+
for (const name of denied) delete next[name];
|
|
613
|
+
return next;
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
function dropUntrustedSdkCwdEqualitySeams(env: NodeJS.ProcessEnv, snapshots: readonly ProjectEnvSnapshot[]): void {
|
|
617
|
+
const next = omitUntrustedSdkCwdEqualitySeams(env, snapshots);
|
|
618
|
+
if (next === env) return;
|
|
619
|
+
for (const name of SDK_CWD_EQUALITY_TEST_SEAMS) {
|
|
620
|
+
if (next[name] === undefined) delete env[name];
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
550
624
|
/** Runs the same persisted AgentSession bootstrap used by the production CLI. */
|
|
551
625
|
export async function runSessionHost(
|
|
552
626
|
timing: {
|
|
@@ -578,6 +652,11 @@ export async function runSessionHost(
|
|
|
578
652
|
const agentDir = process.env.GJC_AGENT_DIR;
|
|
579
653
|
if (!agentDir) throw new Error("GJC_AGENT_DIR is required for sdk session-host-internal.");
|
|
580
654
|
const cwd = timing.cwd ?? process.cwd();
|
|
655
|
+
const cwdSeamSnapshots = sdkCwdEqualitySnapshots(cwd);
|
|
656
|
+
// Drop rejected copies before startup work can spawn a child that inherits them.
|
|
657
|
+
dropUntrustedSdkCwdEqualitySeams(process.env, cwdSeamSnapshots);
|
|
658
|
+
const cwdEqualitySeam = (name: SdkCwdEqualityTestSeam): boolean =>
|
|
659
|
+
sdkCwdEqualityTestSeamActive(name, cwd, process.env, cwdSeamSnapshots);
|
|
581
660
|
if ((await fs.realpath(request.cwd)) !== (await fs.realpath(cwd)))
|
|
582
661
|
throw new Error(`Lifecycle worktree mismatch: expected ${request.cwd}, got ${cwd}.`);
|
|
583
662
|
if (
|
|
@@ -1409,7 +1488,7 @@ export async function runSessionHost(
|
|
|
1409
1488
|
try {
|
|
1410
1489
|
const startupThinkingLevel = request.modelId ? parseModelString(request.modelId)?.thinkingLevel : undefined;
|
|
1411
1490
|
await beforeCutoff(() =>
|
|
1412
|
-
|
|
1491
|
+
cwdEqualitySeam("GJC_SDK_TEST_HANG_MODEL_PROFILE")
|
|
1413
1492
|
? new Promise<void>(() => {})
|
|
1414
1493
|
: applyModelProfiles({
|
|
1415
1494
|
session,
|
|
@@ -1436,7 +1515,7 @@ export async function runSessionHost(
|
|
|
1436
1515
|
const startup = await beforeCutoff<SdkStartupResult>(() => capability.promise);
|
|
1437
1516
|
if (startup.status !== "started") throw startup.failure;
|
|
1438
1517
|
throwIfStartupInterrupted();
|
|
1439
|
-
if (
|
|
1518
|
+
if (cwdEqualitySeam("GJC_SDK_TEST_FAIL_AFTER_REGISTRATION"))
|
|
1440
1519
|
throw new Error("Lifecycle test failure after SDK host registration.");
|
|
1441
1520
|
|
|
1442
1521
|
await beforeCutoff(() => session.sessionManager.ensureOnDisk());
|
|
@@ -1505,11 +1584,11 @@ export async function runSessionHost(
|
|
|
1505
1584
|
// Readiness is published; the session is live. Memory startup issues one LLM
|
|
1506
1585
|
// request per queued rollout, so it must run outside the readiness window and
|
|
1507
1586
|
// its failure must never take the session down.
|
|
1508
|
-
if (
|
|
1587
|
+
if (cwdEqualitySeam("GJC_SDK_TEST_EXIT_AFTER_READY")) {
|
|
1509
1588
|
process.stderr.write("GJC_SDK_TEST_EXIT_AFTER_READY\n");
|
|
1510
1589
|
process.exit(7);
|
|
1511
1590
|
}
|
|
1512
|
-
if (
|
|
1591
|
+
if (cwdEqualitySeam("GJC_SDK_TEST_REJECT_AFTER_READY")) {
|
|
1513
1592
|
// Simulates the post-readiness liveness watcher rejecting. With the
|
|
1514
1593
|
// post-ready startup receipt removed, this unhandled rejection kills the
|
|
1515
1594
|
// host without writing any startup receipt; the broker must classify the
|
|
@@ -1713,6 +1792,34 @@ export default class Sdk extends Command {
|
|
|
1713
1792
|
}
|
|
1714
1793
|
}
|
|
1715
1794
|
|
|
1795
|
+
/** Captures and removes one-shot restart credentials before the broker forks descendants. */
|
|
1796
|
+
export function consumeBrokerRestartEnvironment(environment: NodeJS.ProcessEnv): {
|
|
1797
|
+
requestIdEnv: string | undefined;
|
|
1798
|
+
restartDeadlineAt: number | undefined;
|
|
1799
|
+
} {
|
|
1800
|
+
const restartRequestEnv = environment.GJC_BROKER_RESTART_REQUEST;
|
|
1801
|
+
const restartDeadlineEnv = environment.GJC_BROKER_RESTART_DEADLINE;
|
|
1802
|
+
delete environment.GJC_BROKER_RESTART_REQUEST;
|
|
1803
|
+
delete environment.GJC_BROKER_RESTART_DEADLINE;
|
|
1804
|
+
const requestIdEnv =
|
|
1805
|
+
typeof restartRequestEnv === "string" && /^[A-Za-z0-9_-]{1,256}$/.test(restartRequestEnv)
|
|
1806
|
+
? restartRequestEnv
|
|
1807
|
+
: undefined;
|
|
1808
|
+
let restartDeadlineAt: number | undefined;
|
|
1809
|
+
if (restartDeadlineEnv !== undefined) {
|
|
1810
|
+
const parsedDeadlineAt = Number(restartDeadlineEnv);
|
|
1811
|
+
if (
|
|
1812
|
+
requestIdEnv === undefined ||
|
|
1813
|
+
!/^[0-9]{1,16}$/.test(restartDeadlineEnv) ||
|
|
1814
|
+
!Number.isSafeInteger(parsedDeadlineAt) ||
|
|
1815
|
+
parsedDeadlineAt <= Date.now()
|
|
1816
|
+
)
|
|
1817
|
+
throw new Error("Invalid SDK broker restart deadline; refusing successor startup.");
|
|
1818
|
+
restartDeadlineAt = parsedDeadlineAt;
|
|
1819
|
+
}
|
|
1820
|
+
return { requestIdEnv, restartDeadlineAt };
|
|
1821
|
+
}
|
|
1822
|
+
|
|
1716
1823
|
/**
|
|
1717
1824
|
* Runs one parsed SDK internal entry point. `publicBrokerRun` is set only by
|
|
1718
1825
|
* the stable `gjc sdk broker run` contract, which must report a lost ownership
|
|
@@ -1722,13 +1829,17 @@ export default class Sdk extends Command {
|
|
|
1722
1829
|
async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false): Promise<void> {
|
|
1723
1830
|
if (internal.action === "broker-trampoline-internal") {
|
|
1724
1831
|
if (process.platform === "win32") throw new CliParseError("Broker trampoline is unavailable on Windows.");
|
|
1832
|
+
const retainChildUntilPublication = process.env.GJC_BROKER_TRAMPOLINE_RETAIN_UNTIL_PUBLICATION === "1";
|
|
1725
1833
|
const command = resolveSdkInternalSpawnCommand("broker-internal");
|
|
1834
|
+
const brokerEnvironment = { ...command.env };
|
|
1835
|
+
delete brokerEnvironment.GJC_BROKER_TRAMPOLINE_RETAIN_UNTIL_PUBLICATION;
|
|
1836
|
+
dropUntrustedSdkCwdEqualitySeams(brokerEnvironment, sdkCwdEqualitySnapshots(process.cwd()));
|
|
1726
1837
|
let child: ChildProcess;
|
|
1727
1838
|
try {
|
|
1728
1839
|
child = spawn(command.file, [...command.args, "--agent-dir", internal.agentDir], {
|
|
1729
1840
|
detached: true,
|
|
1730
1841
|
stdio: ["ignore", "ignore", "inherit"],
|
|
1731
|
-
env:
|
|
1842
|
+
env: brokerEnvironment,
|
|
1732
1843
|
...(command.kind === "bun-source" ? { cwd: command.cwd } : {}),
|
|
1733
1844
|
});
|
|
1734
1845
|
} catch (error) {
|
|
@@ -1741,11 +1852,7 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
1741
1852
|
if (child.pid === undefined) throw new Error("Broker trampoline could not start broker.");
|
|
1742
1853
|
const incarnation = processIncarnation(child.pid);
|
|
1743
1854
|
if (!incarnation) {
|
|
1744
|
-
|
|
1745
|
-
child.kill("SIGKILL");
|
|
1746
|
-
} catch {
|
|
1747
|
-
// The child may already have exited; either way identity was not established.
|
|
1748
|
-
}
|
|
1855
|
+
await reapBrokerTrampolineChild(child, child.pid);
|
|
1749
1856
|
throw new Error("Broker trampoline could not observe broker identity.");
|
|
1750
1857
|
}
|
|
1751
1858
|
if (spawnError) throw new Error("Broker trampoline could not start broker.", { cause: spawnError });
|
|
@@ -1757,13 +1864,19 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
1757
1864
|
try {
|
|
1758
1865
|
await stdoutWrite.promise;
|
|
1759
1866
|
} catch (error) {
|
|
1760
|
-
|
|
1761
|
-
child.kill("SIGKILL");
|
|
1762
|
-
} catch {
|
|
1763
|
-
// The child may already have exited; reporting failure remains authoritative.
|
|
1764
|
-
}
|
|
1867
|
+
await reapBrokerTrampolineChild(child, child.pid, incarnation);
|
|
1765
1868
|
throw error;
|
|
1766
1869
|
}
|
|
1870
|
+
if (retainChildUntilPublication) {
|
|
1871
|
+
const decision = await waitForBrokerHandoffDecision(process.stdin);
|
|
1872
|
+
if (decision === "abort") {
|
|
1873
|
+
await reapBrokerTrampolineChild(child, child.pid, incarnation);
|
|
1874
|
+
return;
|
|
1875
|
+
}
|
|
1876
|
+
} else if (!(await waitForBrokerHandoffAcknowledgement(process.stdin))) {
|
|
1877
|
+
await reapBrokerTrampolineChild(child, child.pid, incarnation);
|
|
1878
|
+
throw new Error("Broker trampoline handoff was not acknowledged; its direct child was reaped.");
|
|
1879
|
+
}
|
|
1767
1880
|
child.unref();
|
|
1768
1881
|
return;
|
|
1769
1882
|
}
|
|
@@ -1846,7 +1959,13 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
1846
1959
|
if (startupExitLogged) return;
|
|
1847
1960
|
startupExitLogged = true;
|
|
1848
1961
|
const level = record.exitCode === 1 ? "error" : "warn";
|
|
1849
|
-
if (record.exitCode === 1)
|
|
1962
|
+
if (record.exitCode === 1)
|
|
1963
|
+
logger.error(
|
|
1964
|
+
record.reason === "startup-deadline"
|
|
1965
|
+
? "sdk broker: startup watchdog forcing exit"
|
|
1966
|
+
: "sdk broker: startup refused",
|
|
1967
|
+
record,
|
|
1968
|
+
);
|
|
1850
1969
|
else logger.warn("sdk broker: startup interrupted", record);
|
|
1851
1970
|
process.stderr.write(`${JSON.stringify({ level, message, ...record })}\n`);
|
|
1852
1971
|
};
|
|
@@ -1866,9 +1985,11 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
1866
1985
|
const message =
|
|
1867
1986
|
reason === "startup-lock-blocked" && blockingLockPath
|
|
1868
1987
|
? `SDK broker startup blocked by retained removal transition ${blockingLockPath}.`
|
|
1869
|
-
: reason === "startup-
|
|
1870
|
-
? `SDK broker startup
|
|
1871
|
-
:
|
|
1988
|
+
: reason === "startup-lock-unavailable"
|
|
1989
|
+
? `SDK broker startup could not acquire ${blockingLockPath ?? "a required lock"}.`
|
|
1990
|
+
: reason === "startup-deadline"
|
|
1991
|
+
? `SDK broker startup exceeded its ${timeoutMs}ms fence deadline.`
|
|
1992
|
+
: `SDK broker startup interrupted by ${signal} before readiness.`;
|
|
1872
1993
|
writeStartupExitLog(exitRecord, message);
|
|
1873
1994
|
startupExitTask = (async () => {
|
|
1874
1995
|
const exitRecordWrite = await beginStartupExitRecordWrite(exitRecord);
|
|
@@ -1922,33 +2043,124 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
1922
2043
|
await exitDuringStartup("startup-signal", startupSignalExitCode(signal), signal);
|
|
1923
2044
|
return true;
|
|
1924
2045
|
};
|
|
2046
|
+
let startupFenceAcquired = false;
|
|
1925
2047
|
try {
|
|
2048
|
+
const { requestIdEnv, restartDeadlineAt } = consumeBrokerRestartEnvironment(process.env);
|
|
2049
|
+
const MAX_SESSION_INDEX_TIMEOUT_RETRIES = 2;
|
|
2050
|
+
let sessionIndexTimeoutRetries = 0;
|
|
2051
|
+
let activeStartupDeadlineAt = 0;
|
|
1926
2052
|
const startupOperation = async (deadline: number): Promise<Broker | undefined> => {
|
|
2053
|
+
for (;;) {
|
|
2054
|
+
activeStartupDeadlineAt = deadline;
|
|
2055
|
+
try {
|
|
2056
|
+
return await singleStartupAttempt(deadline);
|
|
2057
|
+
} catch (error) {
|
|
2058
|
+
if (
|
|
2059
|
+
!isFileLockAcquireTimeout(error) ||
|
|
2060
|
+
!startupFenceAcquired ||
|
|
2061
|
+
path.resolve(error.filePath) !==
|
|
2062
|
+
path.resolve(path.join(agentDir, "sdk", "sessions", "index.jsonl")) ||
|
|
2063
|
+
sessionIndexTimeoutRetries >= MAX_SESSION_INDEX_TIMEOUT_RETRIES
|
|
2064
|
+
)
|
|
2065
|
+
throw error;
|
|
2066
|
+
sessionIndexTimeoutRetries++;
|
|
2067
|
+
const backoffMs = 100 * 2 ** (sessionIndexTimeoutRetries - 1);
|
|
2068
|
+
if (Date.now() + backoffMs >= activeStartupDeadlineAt) throw error;
|
|
2069
|
+
const failedBroker = broker;
|
|
2070
|
+
if (failedBroker) {
|
|
2071
|
+
try {
|
|
2072
|
+
await failedBroker.stop({ kind: "startup-failure" });
|
|
2073
|
+
} catch (cleanupError) {
|
|
2074
|
+
throw new AggregateError(
|
|
2075
|
+
[error, cleanupError],
|
|
2076
|
+
"Session-index startup retry could not clean up the failed broker candidate.",
|
|
2077
|
+
);
|
|
2078
|
+
}
|
|
2079
|
+
if (broker === failedBroker) broker = undefined;
|
|
2080
|
+
if (runningBroker === failedBroker) runningBroker = undefined;
|
|
2081
|
+
}
|
|
2082
|
+
candidateStartTask = undefined;
|
|
2083
|
+
logger.debug("sdk broker: session-index lock timeout, retrying startup", {
|
|
2084
|
+
reason: "session-index-timeout-retry",
|
|
2085
|
+
attempt: sessionIndexTimeoutRetries,
|
|
2086
|
+
backoffMs,
|
|
2087
|
+
});
|
|
2088
|
+
await Bun.sleep(backoffMs);
|
|
2089
|
+
}
|
|
2090
|
+
}
|
|
2091
|
+
};
|
|
2092
|
+
const singleStartupAttempt = async (deadline: number): Promise<Broker | undefined> => {
|
|
1927
2093
|
const remainingMs = Math.max(1, deadline - Date.now());
|
|
1928
2094
|
const testWatchdogMs = Number(process.env.GJC_SDK_TEST_BROKER_STARTUP_WATCHDOG_MS ?? 0);
|
|
1929
|
-
const
|
|
2095
|
+
const ordinaryWatchdogMs =
|
|
1930
2096
|
Number.isSafeInteger(testWatchdogMs) && testWatchdogMs > 0 && testWatchdogMs <= remainingMs
|
|
1931
2097
|
? testWatchdogMs
|
|
1932
2098
|
: remainingMs;
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
2099
|
+
let restartRequestId: string | undefined;
|
|
2100
|
+
let startupDeadlineAt = deadline;
|
|
2101
|
+
let effectiveWatchdogMs = ordinaryWatchdogMs;
|
|
2102
|
+
let startupCheckpointDeadline = performance.now() + Math.max(1, effectiveWatchdogMs - 1_000);
|
|
2103
|
+
const armStartupWatchdog = (): NodeJS.Timeout =>
|
|
2104
|
+
setTimeout(() => {
|
|
2105
|
+
startupAbortController.abort();
|
|
2106
|
+
void exitDuringStartup("startup-deadline", 1, null, effectiveWatchdogMs).then(async started => {
|
|
2107
|
+
if (!started) {
|
|
2108
|
+
// A prior startup signal owns the exit cause; its postmortem callback
|
|
2109
|
+
// returns after bounded cleanup and preserves the signal status.
|
|
2110
|
+
return;
|
|
2111
|
+
}
|
|
2112
|
+
await waitForStartupAbortCleanup();
|
|
2113
|
+
process.exit(1);
|
|
2114
|
+
});
|
|
2115
|
+
}, effectiveWatchdogMs);
|
|
2116
|
+
let startupWatchdog = armStartupWatchdog();
|
|
1946
2117
|
try {
|
|
2118
|
+
let restartIntent: BrokerRestartIntentWithIdentity | null;
|
|
2119
|
+
try {
|
|
2120
|
+
restartIntent = await readBrokerRestartIntent(agentDir);
|
|
2121
|
+
} catch (error) {
|
|
2122
|
+
throw new Error("Could not validate SDK broker restart intent; refusing untagged startup.", {
|
|
2123
|
+
cause: error,
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
// A committed request survives the prior owner's exit. Ordinary or
|
|
2127
|
+
// mismatched starts must not publish ahead of its exact successor.
|
|
2128
|
+
if (
|
|
2129
|
+
restartIntent?.phase === "committed" &&
|
|
2130
|
+
restartIntent.expiresAt > Date.now() &&
|
|
2131
|
+
restartIntent.requestId !== requestIdEnv
|
|
2132
|
+
)
|
|
2133
|
+
throw new Error("A committed SDK broker restart is active; startup requires its exact request ID.");
|
|
2134
|
+
if (
|
|
2135
|
+
restartDeadlineAt !== undefined &&
|
|
2136
|
+
(restartIntent?.phase !== "committed" ||
|
|
2137
|
+
restartIntent.requestId !== requestIdEnv ||
|
|
2138
|
+
restartIntent.expiresAt !== restartDeadlineAt)
|
|
2139
|
+
)
|
|
2140
|
+
throw new Error("Could not validate SDK broker restart deadline; refusing successor startup.");
|
|
2141
|
+
if (requestIdEnv !== undefined && restartIntent?.requestId === requestIdEnv) {
|
|
2142
|
+
if (restartIntent.phase !== "committed")
|
|
2143
|
+
throw new Error("SDK broker restart intent is not committed; refusing successor startup.");
|
|
2144
|
+
const remainingSuccessorMs = restartIntent.expiresAt - Date.now();
|
|
2145
|
+
if (remainingSuccessorMs <= 0)
|
|
2146
|
+
throw new Error("SDK broker restart intent expired; refusing untagged startup.");
|
|
2147
|
+
restartRequestId = requestIdEnv;
|
|
2148
|
+
startupDeadlineAt = restartDeadlineAt ?? restartIntent.expiresAt;
|
|
2149
|
+
activeStartupDeadlineAt = startupDeadlineAt;
|
|
2150
|
+
effectiveWatchdogMs =
|
|
2151
|
+
Number.isSafeInteger(testWatchdogMs) && testWatchdogMs > 0 && testWatchdogMs <= remainingSuccessorMs
|
|
2152
|
+
? testWatchdogMs
|
|
2153
|
+
: remainingSuccessorMs;
|
|
2154
|
+
clearTimeout(startupWatchdog);
|
|
2155
|
+
startupCheckpointDeadline = performance.now() + Math.max(1, effectiveWatchdogMs - 1_000);
|
|
2156
|
+
startupWatchdog = armStartupWatchdog();
|
|
2157
|
+
}
|
|
2158
|
+
if (startupAbortController.signal.aborted) return undefined;
|
|
1947
2159
|
// `gjc sdk broker run` never retires another owner, even one this generation cannot
|
|
1948
2160
|
// reuse: any live incumbent is a refusal. Autostart repairs unusable generations.
|
|
1949
2161
|
const existing = publicBrokerRun
|
|
1950
2162
|
? ((await readBrokerDiscovery(agentDir)) ?? undefined)
|
|
1951
|
-
: await reconcileBrokerGenerationForStartup({ agentDir },
|
|
2163
|
+
: await reconcileBrokerGenerationForStartup({ agentDir }, startupDeadlineAt);
|
|
1952
2164
|
if (startupAbortController.signal.aborted) return undefined;
|
|
1953
2165
|
if (existing) {
|
|
1954
2166
|
logger.info("sdk broker: startup reused an existing owner", {
|
|
@@ -1985,11 +2197,9 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
1985
2197
|
// launcher-supplied environment variable; it is validated here and handed
|
|
1986
2198
|
// to Broker as a typed setting, never read a second time inside broker.ts
|
|
1987
2199
|
// from process.env directly.
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
? restartRequestEnv
|
|
1992
|
-
: undefined;
|
|
2200
|
+
// Restart authorization is revalidated before constructing the broker; the
|
|
2201
|
+
// watchdog was already armed before any intent-file I/O.
|
|
2202
|
+
const effectiveCheckpointDeadline = startupCheckpointDeadline;
|
|
1993
2203
|
const testPostPublicationDelayMs = Number(process.env.GJC_SDK_TEST_BROKER_POST_PUBLICATION_DELAY_MS ?? 0);
|
|
1994
2204
|
const startupPostPublicationDelayMs =
|
|
1995
2205
|
Number.isSafeInteger(testPostPublicationDelayMs) &&
|
|
@@ -2027,14 +2237,19 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
2027
2237
|
}
|
|
2028
2238
|
}
|
|
2029
2239
|
: undefined;
|
|
2240
|
+
const brokerSettings = await Settings.loadForScope({ cwd: process.cwd(), agentDir });
|
|
2030
2241
|
const candidate = new Broker({
|
|
2031
2242
|
agentDir,
|
|
2032
2243
|
startupAbortSignal: startupAbortController.signal,
|
|
2033
|
-
startupCheckpointDeadline,
|
|
2244
|
+
startupCheckpointDeadline: effectiveCheckpointDeadline,
|
|
2034
2245
|
onStartupReady: () => clearTimeout(startupWatchdog),
|
|
2035
|
-
masterOrphanGraceMs:
|
|
2036
|
-
|
|
2037
|
-
|
|
2246
|
+
masterOrphanGraceMs: brokerSettings.get("sdk.masterOrphanGraceMs"),
|
|
2247
|
+
abandonedGraceMs: brokerSettings.get("sdk.brokerAbandonedGraceMs"),
|
|
2248
|
+
// Only the detached autostart entry retires itself when nobody is left to
|
|
2249
|
+
// use it. A supervised `gjc sdk broker run` service is owned by its
|
|
2250
|
+
// operator's process manager, which reads an owned-root completion as a
|
|
2251
|
+
// clean exit and would not restart it.
|
|
2252
|
+
reapWhenAbandoned: !publicBrokerRun,
|
|
2038
2253
|
resolveDirectoryMigration: async cwd => {
|
|
2039
2254
|
const settings = await Settings.loadForScope({ cwd, agentDir });
|
|
2040
2255
|
try {
|
|
@@ -2066,7 +2281,11 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
2066
2281
|
}
|
|
2067
2282
|
};
|
|
2068
2283
|
broker = await withBrokerStartupLock(agentDir, startupOperation, {
|
|
2069
|
-
|
|
2284
|
+
...(restartDeadlineAt === undefined ? {} : { deadlineAt: restartDeadlineAt }),
|
|
2285
|
+
onAcquired: () => {
|
|
2286
|
+
startupFenceAcquired = true;
|
|
2287
|
+
void emitBrokerStartupTestSignal("fence-acquired");
|
|
2288
|
+
},
|
|
2070
2289
|
onContended: () => void emitBrokerStartupTestSignal("fence-contended"),
|
|
2071
2290
|
});
|
|
2072
2291
|
} catch (error) {
|
|
@@ -2074,9 +2293,14 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
2074
2293
|
await finishPendingStartupSignal();
|
|
2075
2294
|
return;
|
|
2076
2295
|
}
|
|
2077
|
-
//
|
|
2078
|
-
//
|
|
2079
|
-
if (
|
|
2296
|
+
// Only a retained transition on the outer startup fence gets its own
|
|
2297
|
+
// blocked reason. Nested resource-lock failures are retryable unavailability.
|
|
2298
|
+
if (
|
|
2299
|
+
error instanceof FileLockAcquireError &&
|
|
2300
|
+
!startupFenceAcquired &&
|
|
2301
|
+
error.code === "orphan_transition" &&
|
|
2302
|
+
error.orphanPath
|
|
2303
|
+
) {
|
|
2080
2304
|
await exitDuringStartup(
|
|
2081
2305
|
"startup-lock-blocked",
|
|
2082
2306
|
1,
|
|
@@ -2084,6 +2308,9 @@ async function runSdkInternal(internal: SdkInternalArgv, publicBrokerRun = false
|
|
|
2084
2308
|
BROKER_DISCOVERY_BUDGET.startupLockWaitMs,
|
|
2085
2309
|
error.orphanPath,
|
|
2086
2310
|
);
|
|
2311
|
+
} else if (error instanceof FileLockAcquireError) {
|
|
2312
|
+
// Nested lock failures or non-orphan-transition errors
|
|
2313
|
+
await exitDuringStartup("startup-lock-unavailable", 1, null, undefined, error.orphanPath ?? error.lockPath);
|
|
2087
2314
|
}
|
|
2088
2315
|
if (broker) {
|
|
2089
2316
|
try {
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
writeCurrentSessionGoalModeState,
|
|
9
9
|
writePendingGoalModeRequest,
|
|
10
10
|
} from "../gjc-runtime/goal-mode-request";
|
|
11
|
+
import { trustedCoordinatorEnv } from "../gjc-runtime/sidecar-bootstrap-env";
|
|
11
12
|
import { isUltragoalHelpInvocation, runNativeUltragoalCommand } from "../gjc-runtime/ultragoal-runtime";
|
|
12
13
|
|
|
13
14
|
export default class Ultragoal extends Command {
|
|
@@ -44,16 +45,23 @@ export default class Ultragoal extends Command {
|
|
|
44
45
|
const { objective, goalsPath, provenance } = await readUltragoalGjcObjective(cwd);
|
|
45
46
|
|
|
46
47
|
await writeCurrentSessionGoalModeState({
|
|
47
|
-
|
|
48
|
+
// Bun has already copied the project dotenv into the environment. A
|
|
49
|
+
// value that matches that snapshot must not select the transcript.
|
|
50
|
+
sessionFile: trustedCoordinatorEnv(GJC_SESSION_FILE_ENV),
|
|
48
51
|
objective,
|
|
49
52
|
provenance,
|
|
50
53
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
// A matching or dynamic project declaration must not select the session.
|
|
55
|
+
// Skip the write in that case: the helper falls back to the same env value.
|
|
56
|
+
const sessionId = trustedCoordinatorEnv(GJC_SESSION_ID_ENV);
|
|
57
|
+
if (sessionId !== undefined || !process.env[GJC_SESSION_ID_ENV]?.trim()) {
|
|
58
|
+
await writePendingGoalModeRequest({
|
|
59
|
+
cwd,
|
|
60
|
+
objective,
|
|
61
|
+
goalsPath,
|
|
62
|
+
provenance,
|
|
63
|
+
sessionId,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
58
66
|
}
|
|
59
67
|
}
|