@gajae-code/coding-agent 0.13.2 → 0.14.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 +215 -8
- package/README.md +2 -0
- package/bin/gajaessi.js +4 -0
- package/dist/types/async/job-manager.d.ts +55 -2
- package/dist/types/async/support.d.ts +14 -0
- package/dist/types/capability/mcp.d.ts +6 -0
- package/dist/types/capability/types.d.ts +6 -0
- package/dist/types/cli/accounts-cli.d.ts +19 -0
- package/dist/types/cli/args.d.ts +3 -0
- package/dist/types/cli/config-cli.d.ts +6 -0
- package/dist/types/cli/crash-cli.d.ts +10 -0
- package/dist/types/cli/customize-doctor.d.ts +145 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/mcp-cli.d.ts +11 -0
- package/dist/types/cli/notify-cli.d.ts +1 -1
- package/dist/types/cli/root-flags.d.ts +12 -0
- package/dist/types/cli/setup-cli.d.ts +3 -1
- package/dist/types/cli/skills-cli.d.ts +2 -1
- package/dist/types/cli/update-cli.d.ts +19 -1
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/commands/accounts.d.ts +40 -0
- package/dist/types/commands/crash.d.ts +24 -0
- package/dist/types/commands/customize.d.ts +22 -0
- package/dist/types/commands/daemon.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +6 -0
- package/dist/types/commands/setup.d.ts +6 -0
- package/dist/types/commands/skills.d.ts +6 -1
- package/dist/types/commands/update.d.ts +7 -0
- package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
- package/dist/types/config/config-schema-version.d.ts +10 -0
- package/dist/types/config/file-lock.d.ts +18 -0
- package/dist/types/config/model-profile-activation.d.ts +3 -1
- package/dist/types/config/model-registry.d.ts +10 -1
- package/dist/types/config/models-config-schema.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +73 -9
- package/dist/types/config/settings.d.ts +63 -0
- package/dist/types/config/skill-settings-defaults.d.ts +26 -0
- package/dist/types/config/task-delegation.d.ts +39 -0
- package/dist/types/config/update-channel.d.ts +10 -0
- package/dist/types/coordinator-mcp/server.d.ts +5 -1
- package/dist/types/crash/index-store.d.ts +87 -0
- package/dist/types/crash/nudge.d.ts +50 -0
- package/dist/types/crash/record-loader.d.ts +17 -0
- package/dist/types/crash/report.d.ts +134 -0
- package/dist/types/crash/sanitize.d.ts +25 -0
- package/dist/types/cursor.d.ts +13 -2
- package/dist/types/customization/import.d.ts +37 -0
- package/dist/types/customization/index.d.ts +4 -0
- package/dist/types/customization/inventory.d.ts +25 -0
- package/dist/types/customization/mutations.d.ts +32 -0
- package/dist/types/customization/types.d.ts +115 -0
- package/dist/types/daemon/control-types.d.ts +8 -1
- package/dist/types/daemon/operator-contract.d.ts +4 -4
- package/dist/types/discovery/claude.d.ts +39 -1
- package/dist/types/discovery/codex.d.ts +39 -1
- package/dist/types/discovery/index.d.ts +2 -0
- package/dist/types/discovery/mcp-compat.d.ts +30 -0
- package/dist/types/edit/renderer.d.ts +23 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +21 -4
- package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
- package/dist/types/extensibility/hooks/loader.d.ts +19 -5
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
- package/dist/types/extensibility/skill-management.d.ts +107 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
- package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
- package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
- package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
- package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
- package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
- package/dist/types/hooks/events.d.ts +60 -0
- package/dist/types/hooks/normalize.d.ts +83 -0
- package/dist/types/hooks/skill-state.d.ts +9 -2
- package/dist/types/main.d.ts +2 -1
- package/dist/types/modes/acp/abort-scope.d.ts +13 -0
- package/dist/types/modes/acp/acp-agent.d.ts +7 -4
- package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
- package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
- package/dist/types/modes/components/customization/index.d.ts +1 -0
- package/dist/types/modes/components/dynamic-theme-text.d.ts +9 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +6 -28
- package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
- package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
- package/dist/types/modes/components/oauth-selector.d.ts +10 -4
- package/dist/types/modes/components/pet-capability.d.ts +7 -21
- package/dist/types/modes/components/settings-selector.d.ts +5 -0
- package/dist/types/modes/components/status-line/gh.d.ts +6 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
- package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/theme/defaults/index.d.ts +118 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
- package/dist/types/runtime-mcp/config.d.ts +9 -0
- package/dist/types/runtime-mcp/manager.d.ts +26 -1
- package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
- package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
- package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
- package/dist/types/runtime-mcp/protocol.d.ts +278 -0
- package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
- package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
- package/dist/types/runtime-mcp/types.d.ts +102 -10
- package/dist/types/sdk/acp/adapter.d.ts +26 -5
- package/dist/types/sdk/broker/broker.d.ts +3 -55
- package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
- package/dist/types/sdk/broker/session-index.d.ts +14 -5
- package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
- package/dist/types/sdk/bus/config.d.ts +11 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
- package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
- package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
- package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
- package/dist/types/sdk/bus/index.d.ts +85 -99
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
- package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
- package/dist/types/sdk/bus/notification-service.d.ts +52 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
- package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
- package/dist/types/sdk/bus/session-control.d.ts +25 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
- package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
- package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
- package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
- package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
- package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
- package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
- package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
- package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
- package/dist/types/sdk/cli/rows.d.ts +2 -11
- package/dist/types/sdk/cli/session-cli.d.ts +15 -25
- package/dist/types/sdk/client/client.d.ts +97 -1
- package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
- package/dist/types/sdk/host/control/index.d.ts +1 -1
- package/dist/types/sdk/host/control/operations.d.ts +18 -5
- package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
- package/dist/types/sdk/host/host.d.ts +15 -1
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
- package/dist/types/sdk/host/session-runtime.d.ts +127 -7
- package/dist/types/sdk/host/types.d.ts +1 -1
- package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +2 -1
- package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
- package/dist/types/sdk/lifecycle/client.d.ts +59 -0
- package/dist/types/sdk/lifecycle/index.d.ts +3 -0
- package/dist/types/sdk/lifecycle/service.d.ts +232 -0
- package/dist/types/sdk/mcp/server.d.ts +9 -6
- package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
- package/dist/types/sdk/prompt-status.d.ts +10 -3
- package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
- package/dist/types/sdk/receipt-state.d.ts +17 -0
- package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
- package/dist/types/sdk/router/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +152 -0
- package/dist/types/sdk/session-list.d.ts +22 -0
- package/dist/types/sdk/session-reconnect.d.ts +43 -1
- package/dist/types/sdk/session.d.ts +34 -1
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
- package/dist/types/session/account-inventory.d.ts +86 -0
- package/dist/types/session/agent-session.d.ts +145 -6
- package/dist/types/session/agent-storage.d.ts +10 -0
- package/dist/types/session/coordinator-tool-label.d.ts +28 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
- package/dist/types/session/messages.d.ts +1 -1
- package/dist/types/session/secure-token-file.d.ts +3 -0
- package/dist/types/session/session-manager.d.ts +47 -1
- package/dist/types/session/startup-auth-config.d.ts +44 -0
- package/dist/types/session/terminal-abort.d.ts +378 -0
- package/dist/types/session/yield-queue.d.ts +7 -0
- package/dist/types/session-import/claude.d.ts +26 -0
- package/dist/types/session-import/codex.d.ts +88 -0
- package/dist/types/session-import/command.d.ts +35 -0
- package/dist/types/session-import/detect.d.ts +22 -0
- package/dist/types/session-import/index.d.ts +7 -0
- package/dist/types/session-import/provider-codex.d.ts +22 -0
- package/dist/types/session-import/provider-service.d.ts +38 -0
- package/dist/types/session-import/redact.d.ts +23 -0
- package/dist/types/session-import/service.d.ts +47 -0
- package/dist/types/session-import/types.d.ts +120 -0
- package/dist/types/setup/paseo/check.d.ts +16 -0
- package/dist/types/setup/paseo/install-saga.d.ts +115 -0
- package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
- package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
- package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
- package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
- package/dist/types/setup/paseo/provider-config.d.ts +35 -0
- package/dist/types/setup/paseo/remove.d.ts +14 -0
- package/dist/types/setup/paseo/result-types.d.ts +59 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
- package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
- package/dist/types/skill-state/active-state.d.ts +5 -1
- package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
- package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
- package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
- package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
- package/dist/types/slash-commands/types.d.ts +7 -1
- package/dist/types/task/executor.d.ts +10 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/tools/ask-answer-registry.d.ts +6 -3
- package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
- package/dist/types/tools/bash.d.ts +2 -6
- package/dist/types/tools/browser/attach.d.ts +11 -0
- package/dist/types/tools/browser/launch.d.ts +20 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
- package/dist/types/tools/browser/render.d.ts +1 -0
- package/dist/types/tools/browser.d.ts +3 -1
- package/dist/types/tools/image-gen.d.ts +10 -2
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/monitor.d.ts +1 -1
- package/dist/types/tools/skill-discovery.d.ts +8 -1
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
- package/dist/types/utils/herdr-pane.d.ts +76 -0
- package/package.json +19 -9
- package/scripts/build-binary.ts +2 -1
- package/scripts/build-sdk-package-smoke.ts +2 -13
- package/scripts/capture-sticky-viewport-showcase.ts +0 -1
- package/scripts/compile-args.ts +2 -0
- package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
- package/scripts/generate-sdk-operation-inventory.ts +28 -0
- package/scripts/generate-telegram-baseline-manifest.ts +1 -0
- package/scripts/generate-tool-catalog.ts +6 -4
- package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
- package/src/async/job-manager.ts +352 -17
- package/src/async/support.ts +25 -0
- package/src/autoresearch/dashboard.ts +28 -13
- package/src/capability/index.ts +3 -1
- package/src/capability/mcp.ts +6 -0
- package/src/capability/types.ts +6 -0
- package/src/cli/accounts-cli.ts +395 -0
- package/src/cli/args.ts +23 -0
- package/src/cli/auth-broker-cli.ts +136 -66
- package/src/cli/auth-gateway-cli.ts +94 -70
- package/src/cli/config-cli.ts +27 -2
- package/src/cli/crash-cli.ts +78 -0
- package/src/cli/customize-doctor.ts +1605 -0
- package/src/cli/daemon-cli.ts +12 -3
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/mcp-cli.ts +128 -60
- package/src/cli/notify-cli.ts +8 -14
- package/src/cli/root-flags.ts +8 -0
- package/src/cli/setup-cli.ts +145 -0
- package/src/cli/skills-cli.ts +38 -2
- package/src/cli/update-cli.ts +167 -12
- package/src/cli.ts +4 -0
- package/src/commands/accounts.ts +71 -0
- package/src/commands/crash.ts +35 -0
- package/src/commands/customize.ts +84 -0
- package/src/commands/daemon.ts +2 -2
- package/src/commands/deep-interview.ts +2 -0
- package/src/commands/launch.ts +1 -0
- package/src/commands/mcp.ts +12 -7
- package/src/commands/ralplan.ts +2 -0
- package/src/commands/sdk.ts +65 -32
- package/src/commands/setup.ts +5 -0
- package/src/commands/skills.ts +14 -4
- package/src/commands/ultragoal.ts +10 -1
- package/src/commands/update.ts +26 -15
- package/src/config/atomic-yaml-patch-worker.ts +57 -0
- package/src/config/atomic-yaml-patch.ts +769 -29
- package/src/config/config-schema-version.ts +10 -0
- package/src/config/file-lock.ts +70 -1
- package/src/config/mcp-schema.json +52 -14
- package/src/config/model-profile-activation.ts +23 -2
- package/src/config/model-profiles.ts +88 -21
- package/src/config/model-registry.ts +147 -21
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +77 -7
- package/src/config/settings.ts +4038 -199
- package/src/config/skill-settings-defaults.ts +41 -3
- package/src/config/task-delegation.ts +87 -0
- package/src/config/update-channel.ts +23 -0
- package/src/coordinator-mcp/server.ts +377 -308
- package/src/crash/index-store.ts +723 -0
- package/src/crash/nudge.ts +89 -0
- package/src/crash/record-loader.ts +149 -0
- package/src/crash/report.ts +551 -0
- package/src/crash/sanitize.ts +129 -0
- package/src/cursor.ts +36 -10
- package/src/customization/import.ts +946 -0
- package/src/customization/index.ts +4 -0
- package/src/customization/inventory.ts +335 -0
- package/src/customization/mutations.ts +141 -0
- package/src/customization/types.ts +223 -0
- package/src/daemon/control-types.ts +8 -1
- package/src/daemon/operator-contract.ts +6 -6
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +31 -6
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
- package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
- package/src/discovery/claude-hooks.ts +38 -0
- package/src/discovery/claude.ts +142 -209
- package/src/discovery/codex-hooks.ts +38 -0
- package/src/discovery/codex.ts +132 -198
- package/src/discovery/helpers.ts +8 -1
- package/src/discovery/index.ts +2 -0
- package/src/discovery/mcp-compat.ts +234 -0
- package/src/discovery/mcp-json.ts +6 -0
- package/src/edit/renderer.ts +40 -0
- package/src/edit/streaming.ts +4 -2
- package/src/exec/bash-executor.ts +24 -20
- package/src/export/html/index.ts +51 -2
- package/src/extensibility/extensions/loader.ts +9 -1
- package/src/extensibility/extensions/runner.ts +17 -4
- package/src/extensibility/extensions/types.ts +31 -6
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
- package/src/extensibility/gjc-plugins/installer.ts +9 -5
- package/src/extensibility/gjc-plugins/observability.ts +8 -2
- package/src/extensibility/gjc-plugins/registry.ts +13 -2
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
- package/src/extensibility/gjc-plugins/schema.ts +222 -39
- package/src/extensibility/hooks/loader.ts +154 -10
- package/src/extensibility/runtime-skill-discovery.ts +257 -60
- package/src/extensibility/skill-management.ts +368 -0
- package/src/extensibility/skills.ts +52 -16
- package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
- package/src/gjc-runtime/launch-worktree.ts +56 -2
- package/src/gjc-runtime/linux-proc.ts +7 -1
- package/src/gjc-runtime/ralplan-runtime.ts +100 -164
- package/src/gjc-runtime/session-state-lock.ts +992 -0
- package/src/gjc-runtime/session-state-sidecar.ts +644 -142
- package/src/gjc-runtime/state-writer.ts +39 -14
- package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
- package/src/gjc-runtime/ultragoal-guard.ts +11 -4
- package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
- package/src/gjc-runtime/workflow-settings.ts +596 -0
- package/src/goals/tools/goal-tool.ts +6 -1
- package/src/hooks/events.ts +291 -0
- package/src/hooks/native-skill-hook.ts +4 -0
- package/src/hooks/normalize.ts +369 -0
- package/src/hooks/skill-state.ts +165 -46
- package/src/internal-urls/docs-index.generated.ts +41 -32
- package/src/main.ts +36 -5
- package/src/migrate/mcp-mapper.ts +25 -2
- package/src/modes/acp/abort-scope.ts +29 -0
- package/src/modes/acp/acp-agent.ts +423 -98
- package/src/modes/components/assistant-message.ts +6 -1
- package/src/modes/components/chrome.ts +4 -3
- package/src/modes/components/customization/customization-dashboard.ts +443 -0
- package/src/modes/components/customization/import-wizard.ts +372 -0
- package/src/modes/components/customization/index.ts +1 -0
- package/src/modes/components/dynamic-theme-text.ts +22 -0
- package/src/modes/components/gajae-pet-widget.ts +607 -193
- package/src/modes/components/irc-sidebar.ts +11 -0
- package/src/modes/components/iterm-pet-transport.ts +585 -0
- package/src/modes/components/model-selector.ts +1 -6
- package/src/modes/components/oauth-selector.ts +277 -86
- package/src/modes/components/pet-capability.ts +35 -31
- package/src/modes/components/settings-selector.ts +29 -5
- package/src/modes/components/status-line/gh.ts +45 -1
- package/src/modes/components/status-line/segments.ts +19 -4
- package/src/modes/components/tool-status-header.ts +13 -3
- package/src/modes/controllers/command-controller.ts +20 -8
- package/src/modes/controllers/extension-ui-controller.ts +56 -257
- package/src/modes/controllers/input-controller.ts +10 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
- package/src/modes/controllers/selector-controller.ts +238 -77
- package/src/modes/controllers/stt-controller.ts +3 -3
- package/src/modes/interactive-mode.ts +88 -16
- package/src/modes/print-mode.ts +35 -6
- package/src/modes/runtime-init.ts +21 -68
- package/src/modes/theme/defaults/index.ts +2 -0
- package/src/modes/theme/defaults/ouroboros.json +118 -0
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/injected-user-submission.ts +25 -0
- package/src/modes/utils/terminal-bell.ts +15 -1
- package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/critic.md +1 -1
- package/src/prompts/system/rlm-research.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -2
- package/src/prompts/tools/bash.md +7 -1
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/cron.md +6 -6
- package/src/prompts/tools/read.md +0 -2
- package/src/prompts/tools/skill-discovery.md +4 -2
- package/src/runtime-mcp/client.ts +427 -23
- package/src/runtime-mcp/config.ts +37 -5
- package/src/runtime-mcp/manager-pool.test.ts +56 -0
- package/src/runtime-mcp/manager.ts +52 -2
- package/src/runtime-mcp/oauth-discovery.ts +13 -0
- package/src/runtime-mcp/oauth-flow.ts +46 -1
- package/src/runtime-mcp/pool-key.ts +5 -1
- package/src/runtime-mcp/pool.test.ts +9 -0
- package/src/runtime-mcp/protocol.test.ts +353 -0
- package/src/runtime-mcp/protocol.ts +624 -0
- package/src/runtime-mcp/scope-config.ts +78 -0
- package/src/runtime-mcp/tool-bridge.ts +44 -10
- package/src/runtime-mcp/transports/http.ts +84 -13
- package/src/runtime-mcp/types.ts +123 -12
- package/src/sdk/acp/adapter.ts +328 -97
- package/src/sdk/broker/broker.ts +160 -741
- package/src/sdk/broker/ensure.ts +9 -1
- package/src/sdk/broker/lifecycle.ts +510 -116
- package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
- package/src/sdk/broker/process-incarnation.ts +19 -0
- package/src/sdk/broker/session-index.ts +516 -117
- package/src/sdk/broker/startup-failure.ts +28 -5
- package/src/sdk/broker/transport.ts +1 -13
- package/src/sdk/bus/chat-daemon-cli.ts +4 -2
- package/src/sdk/bus/chat-daemon-control.ts +67 -6
- package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
- package/src/sdk/bus/config.ts +13 -0
- package/src/sdk/bus/conversation-store.ts +59 -171
- package/src/sdk/bus/daemon-paths.ts +20 -0
- package/src/sdk/bus/discord-conversation.ts +2 -0
- package/src/sdk/bus/discord-daemon.ts +524 -126
- package/src/sdk/bus/discord-live-provider.ts +206 -79
- package/src/sdk/bus/existing-thread-readiness.ts +4 -97
- package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
- package/src/sdk/bus/index.ts +2480 -456
- package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
- package/src/sdk/bus/lifecycle-commands.ts +2 -2
- package/src/sdk/bus/managed-daemon.ts +2 -145
- package/src/sdk/bus/notification-service.ts +196 -0
- package/src/sdk/bus/operator-runtime.ts +1 -1
- package/src/sdk/bus/prompt-reconciliation.ts +24 -15
- package/src/sdk/bus/reconciliation-store.ts +553 -24
- package/src/sdk/bus/session-control.ts +49 -3
- package/src/sdk/bus/slack-conversation.ts +4 -0
- package/src/sdk/bus/slack-daemon.ts +733 -134
- package/src/sdk/bus/slack-live-provider.ts +65 -15
- package/src/sdk/bus/slack-provider.ts +4 -0
- package/src/sdk/bus/slack-thread-binding.ts +9 -104
- package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
- package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
- package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
- package/src/sdk/bus/telegram-daemon-control.ts +3 -13
- package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
- package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
- package/src/sdk/bus/telegram-daemon.ts +2552 -2280
- package/src/sdk/bus/telegram-reference.ts +1 -226
- package/src/sdk/bus/telegram-setup.ts +2 -2
- package/src/sdk/bus/threaded-render.ts +1 -0
- package/src/sdk/bus/topic-registry.ts +279 -146
- package/src/sdk/cli/rows.ts +2 -35
- package/src/sdk/cli/session-cli.ts +776 -700
- package/src/sdk/client/client.ts +892 -1
- package/src/sdk/host/control/dispatch.ts +93 -58
- package/src/sdk/host/control/index.ts +1 -1
- package/src/sdk/host/control/operations.ts +18 -10
- package/src/sdk/host/control/runtime-gate.ts +40 -0
- package/src/sdk/host/host.ts +63 -12
- package/src/sdk/host/query/handlers.ts +66 -7
- package/src/sdk/host/reverse-leases.ts +2 -2
- package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
- package/src/sdk/host/session-runtime.test.ts +2787 -34
- package/src/sdk/host/session-runtime.ts +1489 -101
- package/src/sdk/host/surface-policy.ts +12 -8
- package/src/sdk/host/types.ts +1 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
- package/src/sdk/host/websocket-transport.ts +85 -50
- package/src/sdk/index.ts +2 -1
- package/src/sdk/lifecycle/broker-client.ts +53 -0
- package/src/sdk/lifecycle/client.ts +234 -0
- package/src/sdk/lifecycle/index.ts +3 -0
- package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
- package/src/sdk/lifecycle/service.ts +720 -0
- package/src/sdk/mcp/server.ts +226 -188
- package/src/sdk/prompt-deadline-lease.ts +55 -0
- package/src/sdk/prompt-deadline-manager.ts +148 -0
- package/src/sdk/prompt-status.ts +11 -3
- package/src/sdk/protocol/operation-inventory.generated.json +272 -129
- package/src/sdk/protocol/operation-registry.ts +71 -8
- package/src/sdk/receipt-state.ts +43 -0
- package/src/sdk/reconciliation-extensions.ts +14 -0
- package/src/sdk/router/index.ts +1 -0
- package/src/sdk/router/session-router.ts +1658 -0
- package/src/sdk/session-list.ts +93 -0
- package/src/sdk/session-reconnect.ts +45 -1
- package/src/sdk/session.ts +716 -120
- package/src/sdk/transport/serve-cli.ts +18 -34
- package/src/session/account-inventory.ts +603 -0
- package/src/session/agent-session.ts +2873 -559
- package/src/session/agent-storage.ts +35 -0
- package/src/session/blob-store.ts +32 -1
- package/src/session/coordinator-tool-label.ts +40 -0
- package/src/session/internal/managed-session-scope.ts +4 -0
- package/src/session/internal/managed-session-storage.ts +199 -31
- package/src/session/messages.ts +1 -1
- package/src/session/secure-token-file.ts +80 -0
- package/src/session/session-manager.ts +757 -57
- package/src/session/session-storage.ts +25 -16
- package/src/session/startup-auth-config.ts +297 -0
- package/src/session/terminal-abort.ts +1253 -0
- package/src/session/yield-queue.ts +57 -15
- package/src/session-import/claude.ts +334 -0
- package/src/session-import/codex.ts +1033 -0
- package/src/session-import/command.ts +77 -0
- package/src/session-import/detect.ts +133 -0
- package/src/session-import/index.ts +7 -0
- package/src/session-import/provider-codex.ts +327 -0
- package/src/session-import/provider-service.ts +457 -0
- package/src/session-import/redact.ts +128 -0
- package/src/session-import/service.ts +1264 -0
- package/src/session-import/types.ts +148 -0
- package/src/setup/paseo/check.ts +213 -0
- package/src/setup/paseo/install-saga.ts +293 -0
- package/src/setup/paseo/json-publisher.ts +263 -0
- package/src/setup/paseo/orchestration-preferences.ts +86 -0
- package/src/setup/paseo/paseo-ownership.ts +224 -0
- package/src/setup/paseo/paseo-setup.ts +253 -0
- package/src/setup/paseo/provider-config.ts +139 -0
- package/src/setup/paseo/remove.ts +183 -0
- package/src/setup/paseo/result-types.ts +79 -0
- package/src/setup/paseo/setup-deps.ts +175 -0
- package/src/setup/paseo/skills-bridge.ts +260 -0
- package/src/skill-state/active-state.ts +21 -11
- package/src/slash-commands/acp-builtins.ts +9 -1
- package/src/slash-commands/builtin-registry.ts +117 -19
- package/src/slash-commands/helpers/credential-switch.ts +143 -0
- package/src/slash-commands/helpers/mcp.ts +9 -3
- package/src/slash-commands/helpers/usage-report.ts +61 -56
- package/src/slash-commands/types.ts +7 -2
- package/src/task/executor.ts +30 -11
- package/src/task/index.ts +66 -7
- package/src/task/render.ts +23 -9
- package/src/tools/ask-answer-registry.ts +23 -7
- package/src/tools/ask.ts +8 -4
- package/src/tools/bash-sleep-advisory.ts +115 -0
- package/src/tools/bash.ts +98 -18
- package/src/tools/browser/attach.ts +71 -3
- package/src/tools/browser/launch.ts +86 -13
- package/src/tools/browser/profile-discovery.ts +57 -7
- package/src/tools/browser/render.ts +8 -1
- package/src/tools/browser.ts +130 -21
- package/src/tools/computer.enforcement.test.ts +1 -1
- package/src/tools/computer.ts +3 -2
- package/src/tools/cron.ts +12 -1
- package/src/tools/image-gen.ts +349 -142
- package/src/tools/index.ts +8 -0
- package/src/tools/job.ts +33 -6
- package/src/tools/monitor.ts +41 -2
- package/src/tools/skill-discovery.ts +21 -29
- package/src/tools/subagent.ts +142 -24
- package/src/tools/todo-contract.ts +55 -3
- package/src/tools/todo-write.ts +4 -3
- package/src/tools/tool-catalog.generated.ts +6 -6
- package/src/tools/ultragoal-ask-guard.ts +10 -3
- package/src/utils/herdr-pane.ts +345 -0
- package/src/utils/title-generator.ts +2 -0
- package/src/web/scrapers/index.ts +6 -4
- package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
- package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
- package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
- package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
- package/dist/types/runtime/lazy-service.test.d.ts +0 -1
- package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
- package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
- package/dist/types/runtime-mcp/config.test.d.ts +0 -1
- package/dist/types/runtime-mcp/http.test.d.ts +0 -1
- package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
- package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
- package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
- package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
- package/dist/types/sdk/elevation/audit.d.ts +0 -93
- package/dist/types/sdk/elevation/capability.d.ts +0 -3
- package/dist/types/sdk/elevation/digest.d.ts +0 -72
- package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
- package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
- package/dist/types/sdk/elevation/owner.d.ts +0 -48
- package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
- package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
- package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
- package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
- package/dist/types/session/auth-broker-config.d.ts +0 -13
- package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
- package/dist/types/skills/skills.test.d.ts +0 -1
- package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
- package/dist/types/task/token-log.test.d.ts +0 -1
- package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
- package/dist/types/tools/descriptors.test.d.ts +0 -1
- package/scripts/g005-daemon-smoke.ts +0 -180
- package/scripts/g011-daemon-path-smoke.ts +0 -153
- package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
- package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
- package/src/sdk/bus/telegram-cli.ts +0 -212
- package/src/sdk/elevation/allowlist.ts +0 -54
- package/src/sdk/elevation/audit.ts +0 -208
- package/src/sdk/elevation/capability.ts +0 -41
- package/src/sdk/elevation/digest.ts +0 -129
- package/src/sdk/elevation/dispatch-receipt.ts +0 -184
- package/src/sdk/elevation/grant-ledger.ts +0 -1142
- package/src/sdk/elevation/owner.ts +0 -109
- package/src/session/auth-broker-config.ts +0 -109
- /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
- /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
- /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,32 +2,217 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
## [0.
|
|
5
|
+
## [0.14.0] - 2026-08-17
|
|
6
|
+
- Documented how to run GJC inside external agent shells. `README.md` gains a support-rated integration table for [Paseo](https://paseo.sh) (★★★★★ — `gjc setup paseo` writes a conformance-tested ACP provider), [Orca](https://onorca.dev) (★★★★ — GJC runs as a custom CLI agent per worktree), and [T3 Code](https://t3.codes) (★★★ experimental — no GJC harness exists upstream yet), and [`docs/terminal-app-integrations.md`](../../docs/terminal-app-integrations.md) carries the per-host setup, verification, cancel-semantics, and troubleshooting detail. The T3 Code row is deliberately marked unsupported rather than advertising an install command for a bridge that does not exist.
|
|
7
|
+
- Added the `commandcode-goat` model profile for the Command Code GOAT provider, assigning GLM-5.3 to the default role, DeepSeek V4 Flash to execution, Kimi K3 to planning, GLM-5.2 to criticism, and DeepSeek V4 Pro to architecture.
|
|
8
|
+
|
|
9
|
+
- Session endpoints hosted on the notification-adapter transport now deliver every ring-retained session event live to attached SDK subscribers as the same positioned `event` envelope (`generation`/`seq`) that `event_replay` returns, sent per connection over the validated directed leg with the same capability gating replay applies. Previously the live leg only pushed raw side-channel frames — the native broadcast enum reduced non-native kinds (including terminal `agent_end` lifecycle) to empty `unknown` frames, and correlated lifecycle reached only the submitting connection — so an already-attached direct SDK subscriber could observe a later positioned event, including a turn's terminal lifecycle, only by issuing another replay. Each connection's directed writer now bounds queued host frames to the replay-ring capacity; a lagged subscriber rejects additional best-effort live sends and recovers through replay (including the existing sequence-gap contract) instead of growing an unbounded backlog. Ring persistence, replay ordering, event positions, correlated requester delivery, and native notification frames are unchanged.
|
|
10
|
+
- Persisted edit results no longer inline complete pre/post-edit file snapshots. `EditToolDetails.oldText`/`newText` (and each `perFileResults[]` copy) larger than 16 KiB are replaced at the session-persistence boundary by a fixed-size digest receipt (`oldTextDigest`/`newTextDigest`: UTF-8 byte length + SHA-256) plus an externalization marker, so a tiny `apply_patch` to a large file costs bytes proportional to its diff instead of ~2x the file size in the managed transcript (#4566). Live in-process results still carry full bodies for ACP `diff` ToolCallContent and editors; sub-16 KiB snapshots persist verbatim; diffs, paths, ops, first-changed-line, diagnostics, and meta are unchanged. A regression suite pins bounding, inline sub-cap behavior, multi-file copies, and the near-limit committed-edit durability contract.
|
|
11
|
+
- Near-limit managed appends are now a typed, deterministic outcome instead of a silent recovery or an unclassified abort. When a live append crosses the 128 MiB managed per-file cap, the existing full-rewrite recovery runs and is then verified: if the recovered transcript still cannot hold the entry (or the rewrite itself hits `content_too_large`), the append throws `SessionNearLimitAppendError` carrying structured fields (`code: "near_limit_append"`, entry/live/cap bytes, whether the entry is retained in memory) and a message stating whether the committed edit's receipt is preserved and how to continue (`/compact` or `gjc export`). `AgentSession` maps it to a structured tool-result outcome instead of a generic fatal `SessionAppendPersistenceError`, so a committed source mutation can no longer lose its receipt silently (#4566).
|
|
12
|
+
- Telegram notification delivery now carries an explicit per-update inbound acknowledgement contract: user messages are acked `accepted` at session preflight acceptance (before the turn starts, so a fast turn can no longer out-race the pending-update registration), late admission failures ack `rejected`, and genuinely discarded frames ack `dropped`. Policy-suspended control commands are deferred to activation instead of being acked as dropped, per-update reaction transitions are serialized with terminal states monotonic (a slow queued 👀 can no longer overwrite a later ✅), and retraction sends the empty reaction list the Bot API requires. Daemon generation bumped 167→168. (#4528)
|
|
13
|
+
|
|
14
|
+
- Managed fallback local snapshot failures now surface their one producer-boundary diagnostic immediately instead of re-issuing the identical request up to three times. The failure still never charges the provider fallback chain, advances models, or mutates credentials.
|
|
15
|
+
|
|
16
|
+
- Managed fallback local buffer overflows (`local_buffer_overflow`) now surface immediately with the original local diagnostic instead of entering the bounded `unknown` retry class: re-streaming the same request reproduces the same oversized response, and a local staging failure must never charge or advance the provider fallback chain, emit `model_fallback_switched`, or rotate credentials.
|
|
17
|
+
|
|
18
|
+
- Fixed Windows startup lock starvation in the SDK session index (#4544): a live detached broker holding `index.jsonl.lock` across a wedged Windows sync-family await exhausted every later launch's full 600-attempt lock budget. OS process-incarnation probes (which can spawn `powershell.exe` on Windows) now run before the machine-global index lock is taken in the heartbeat checkpoint pass, the conditional-unregister pass (now routed through the shared slow-operation choke point), and the own-pid registration derivation; the PowerShell fallback is time-bounded (`timeout` + `SIGKILL` enforcement); locked index transactions log an actionable slow-operation warning after 10s naming the exact operation; and lock exhaustion errors now identify the live owner (pid, liveness, lock path) instead of a bare attempt count. The heartbeat pass also rechecks probe freshness after the locked replay on the monotonic clock: a pid reused while the replay re-reads the log fails closed (no heartbeat this cycle) instead of checkpointing the wrong host, and a backward wall-clock step (NTP slew, manual fix, VM restore) cannot defeat the bound. A lock record carrying a foreign `owner_host_id` (shared-volume topic registry) reports its owner host with unknown liveness instead of probing a coincidental local pid. Stale-lock safety is unchanged: a proven-live owner's lock is never stolen.
|
|
19
|
+
|
|
20
|
+
- Fixed Windows session-index reads paying a `powershell.exe` spawn per dead registration: the incarnation probe only fences PID reuse for a live process, so `projectIdentity` no longer probes pids already observed dead. With dozens of stale registrations in `index.jsonl`, every `listSessions`/checkpoint read previously took seconds to tens of seconds (and stalled gjc startup past the session-extension 30 s watchdog); the projection is unchanged. (#4594)
|
|
21
|
+
|
|
22
|
+
- SDK terminal prompt, skill, and correlated-steer reconciliation records no longer expire after 15 minutes. Canonical status and bounded result content remain queryable across durable restart until the existing 256-record-per-kind oldest-terminal-first capacity bound evicts them; active records, selectors, response shapes, first-terminal-wins settlement, ordered non-replay behavior, and client-reference release on capacity eviction are unchanged (#4547). The age window was also removed from the SDK-only session host's prompt/skill reconciliation, which serves `turn.result`/`turn.prompt_status`/`turn.skill_status` for sessions without the notification-adapter surface, so every public reconciliation surface now retains terminal records until capacity eviction only.
|
|
23
|
+
- Fixed ACP `session/delete` retries so a durable artifact `cleanup_pending` result remains authoritative instead of re-closing the already-terminated session and misclassifying an unreaped Linux zombie as unverifiable SIGKILL uncertainty. Broker close now recognizes an identity-matching zombie as exited without weakening PID-reuse checks, and repeated deletes resume the authorized cleanup receipt idempotently.
|
|
24
|
+
|
|
25
|
+
- Added `/extensions`, an interactive project/global `.gjc` manager for skills, hooks, MCPs, and explicit Claude Code/Codex imports with redacted previews and atomic rollback.
|
|
6
26
|
|
|
7
27
|
### Added
|
|
28
|
+
- Added implicit discovery and keyless local support for oMLX (`http://127.0.0.1:8080/v1`) with `OMLX_BASE_URL` and `OMLX_API_KEY` configuration.
|
|
29
|
+
|
|
30
|
+
- Gajae Pet now renders in iTerm2 through a bounded inline GIF protected from ordinary TUI redraws by a reserved raster lease, with the same composer-side layout and lifecycle cleanup guarantees used by Kitty and Sixel.
|
|
31
|
+
- Added the bundled `ouroboros` dark theme, translating the official navy, teal, green, and gold identity into terminal-safe semantic colors while retaining the pet's vivid `#AEE80E` lime and `#7092BE` cool-scale accents. Live previews now recolor the open `/theme` selector and Settings theme submenu instead of leaving their construction-time theme visible, and confirmation consistently settles the preview into the active appearance mapping.
|
|
32
|
+
- Added the 16×16 `Ouroboros` terminal pet: a vivid lime snake with a cool `#7092BE` underside that rests in a soft coil, blinks, flicks its tongue upward, and occasionally sobs with `><` eyes. Its signature flex rolls the same silhouette through a symmetric circle into an exact 180-degree heart pose, blinks a small pink heart twice, and reuses the authored frames in reverse; agent work enters and exits a stable six-frame infinity loop through explicit unwind transitions. Pet skins now own their frame registry, source resolution, idle loop, work transitions, work loop, and signature burst; a saved skin removed by a later installation falls back to RedGajae while an explicit `off` remains off.
|
|
33
|
+
- `subagent await` now emits periodic liveness even when the awaited subagent's rendered-state signature is stable, so a healthy long wait is never indistinguishable from a hung session. A bounded liveness interval (floor 15s, derived from `heartbeat_ms`) force-re-emits `onUpdate` through the existing update channel, preserving immediate emission on genuine progress changes. Long silent `sleep N` (N ≥ 120s) in bash now appends a one-time advisory notice recommending `subagent await` or `job poll` instead — purely advisory, never blocking (#4465).
|
|
34
|
+
|
|
35
|
+
### Changed
|
|
36
|
+
- Updated every bundled GLM model profile (`glm-eco`, `glm-medium`, and `glm-pro`) from ZAI GLM-5.2 to GLM-5.3.
|
|
37
|
+
- `browser` Chrome profile mode (`app.browser: "chrome"`) now defaults an omitted `path` to installed Chrome/Chromium and an omitted `profile_directory` to `"Default"`. `user_data_dir` remains explicit and must be non-default because Chrome 136+ disables remote debugging for default Chrome data directories; Stable/Beta/Dev/Canary/Chromium roots (including trusted Linux environment, Flatpak, and Snap defaults), symlink aliases to them, and non-Chrome browser executables are rejected with remediation instead of timing out or risking cross-brand profile access. Profile and Windows executable discovery use trusted environment sources that ignore repository `.env`, platform path semantics are preserved, executable/profile-root canonicalization races stalled filesystem work against cancellation, the canonical Snap Chromium launcher is admitted only when it resolves to `/usr/bin/snap`, and wrapper-launched Linux Chrome processes are reused through an abort-aware asynchronous `/proc` scan only after kernel executable identity plus exact profile/loopback-CDP guards pass. Cancellation propagates before, during, and after CDP probing, and omitted profile names render as `Default` in the TUI.
|
|
38
|
+
- Defense-in-depth: when an Anthropic-origin assistant transcript message carrying directly adjacent `thinking`/`redacted_thinking` blocks is persisted, a single bounded warn is emitted per session manager instance — but only in development/test builds, never in production. The diagnostic names only the envelope shape (block count, adjacency presence, provider), never raw thinking text, signatures, redacted payloads, or transcript-path metadata. Storage is never mutated — the send-boundary collapse remains the wire source of truth; this is a read-only observation that helps surface upstream producers of the rejected shape (#4443).
|
|
39
|
+
### Fixed
|
|
40
|
+
- Ouroboros now keeps its own authored base, idle, work-transition, work, and burst frames across Sixel, Kitty, and iTerm2 rendering. Marked iTerm pet drag paths are also discarded in Bash and Python composer modes instead of being inserted literally.
|
|
41
|
+
- iTerm2 pet animation now stays silent while the TUI is temporarily stopped for an external editor or todo edit, preventing raster writes from corrupting the child terminal session. Its unavailable-capability deadline now begins after iTerm probing starts rather than during initialization work.
|
|
42
|
+
- Forced Kitty Gajae Pet graphics remain unavailable inside tmux, screen, and zellij; forced Sixel and verified iTerm2 transport keep their existing behavior.
|
|
43
|
+
- iTerm2 Gajae Pet rendering now uploads an animated GIF only when its meaningful state changes and holds a raster lease across ordinary TUI redraws, preventing work-animation flicker and transient composer-background frames.
|
|
44
|
+
- Dragging an iTerm2 Gajae Pet image no longer pastes its temporary named image pathname into the composer. Pet frames identify their generated image by name, and the paste controller consumes only that marked pathname while preserving native iTerm dragging and all other image-path pastes.
|
|
45
|
+
- Gajae Pet now keeps its intended two-row art footprint in iTerm2 across terminal font, Retina, and cell-geometry changes instead of rendering as a fixed undersized pixel box.
|
|
46
|
+
|
|
47
|
+
- Post-merge repair for #4542: `CHAT_DAEMON_GENERATIONS.discord` 64→65 and `.slack` 67→68 so the `SessionRouter` initial attachment replay change is generation-fenced for already-running Discord and Slack daemons. The semantic guard manifest is regenerated with the corrected generation and declaration digests.
|
|
48
|
+
- Cursor split responses now preserve canonical provider order across pre-admission artifact spilling, so a server-side tool result cannot be persisted after the assistant continuation that follows it. The canonical admission reservation is owned by each emission's own handler, so a host bridge or replay emitting the same `message_end` event object twice can no longer overwrite the reservation and deadlock every later canonical admission (#4536).
|
|
49
|
+
- Uncontended canonical `message_end` admissions no longer cost a microtask: the admission lane keeps a synchronous fast path when its predecessor slot is already released, restoring synchronous visibility of persisted appends for external emitters (successor-finalization and deep-interview continuation flows) while FIFO admission still holds under a genuinely in-flight predecessor (#4536).
|
|
50
|
+
- SDK `session.prompt`/`steer` dispatches that arrive while a default-model selection already owns the admission fence are now preserved as queued work instead of failing: the shared ingress awaits the selection fence, keeps same-session prompt entry fail-fast, and only private scheduled continuations (auto-compaction/queue continuation) bypass the fence with an explicit reentry capability. Queued dispatches reserve follow-up order before durable acceptance so a later plain prompt cannot overtake an earlier follow-up behind the same fence, and continuations parked behind a pending selection fence are tracked as settlement work so `waitForIdle` cannot report completion while the continuation is still waiting (#4519).
|
|
51
|
+
- Default-model selection now reserves a causal fence before credential probing, so an already accepted prompt preflight cannot be overtaken and a selection accepted first blocks later prompt preflight through durable publication. The fence does not hold session admission across `waitForIdle`, allowing inherited auto-compaction continuations to obtain prompt admission; same-session reentrancy still fails fast, successor sessions remain protected, and disposal deterministically drains accepted selections while rejecting queued prompts without unhandled rejections (#4519).
|
|
52
|
+
- AgentSession now observes provisional tool-call updates through a private, turn-bounded identity channel, preserving cancel-and-submit visibility and exactly-once streaming edit guards across cloned events, delayed handlers, and terminal interleavings.
|
|
53
|
+
- Ordinary sessions no longer import or execute Claude Code and Codex directory hooks as competing runtime authorities. Runtime hook discovery is fail-closed to canonical native `.gjc/hooks/` providers while explicit configured paths, constrained plugin hooks, and foreign-provider import/diagnostic discovery remain available (#4516).
|
|
54
|
+
- Telegram/Slack/Discord outbound publications no longer freeze after a session-host rehost. A rehosted fleet re-attaches every session in one reconcile pass, and each attachment's initial `event_replay` was awaited inside the serialized `#reconcileTail`, so one slow replay (up to its full retry budget) wedged all later reconciles and the sends funneling through them; leases and inbound polling stayed green while delivery died until daemon restart. Reconcile-driven attachments now publish immediately and run initial replay on the attachment's ready tail (matching the reconnect path); `start()` still drains those tails so bootstrap callers observe replay completion. Replay ordering, generation fences, cross-session isolation, and provider hooks are unchanged (#4527).
|
|
55
|
+
- Automatic session retry now honors the Anthropic transport's first-event attempt ceiling: a full-window request at or above 1 MB stops after the initial upload, while a smaller request can be attempted at most twice even when the global retry setting is higher. Attempt events and terminal elapsed diagnostics use the actual bounded ceiling. Credit: @probepark (#4464).
|
|
56
|
+
- A manual `retry()` after an exhausted provider first-event ceiling now clears that stale ceiling before re-attempting, so a later transient failure on the reissued turn consumes the ordinary retry budget instead of being exhausted by the prior turn's ceiling. Verified by a discriminating regression test that fails when the ceiling is retained (#4464).
|
|
57
|
+
- `gjc_coordinator_stop_session` no longer reports `close_failed` after a successful DR-1 terminal close. Reap now proves the same retained session is `terminal` and non-`live` for the exact `workspace/generation/incarnation` before completing local cleanup; rotated generation, different incarnation, ambiguous, still-live, and `terminal_uncertain` remain fail-closed (#4431).
|
|
58
|
+
- The crash signature index can no longer quarantine itself. `parseCrashIndex` rejects an entry whose retained count exceeds its lifetime count, and compaction produced exactly that whenever the crash log still held more identity-bearing records for a signature than the journal had counted — which happens whenever a fatal's journal append fails or spends the per-process latch while its crash-log record is still written. The next read then discarded the whole index, taking every signature in it. The retained count is now held at the journaled lifetime.
|
|
59
|
+
- Crash records whose event-journal append was lost are reportable again. Compaction recovers only never-indexed, structurally complete v1 records whose marker fingerprint recomputes from their own diagnostic text, trying only marker-proven reconstructions for the v1 header's ambiguous colon names, multiline messages, arbitrary multiline stacks, and separate serialized object payload. Record ids are deduplicated for recovery and retained counts; recovered ids remain durable until delayed journal events arrive; whole rotated-journal digests make publish-before-delete replay idempotent beyond the 256-id window; and timestamp ordering controls first/last-seen plus latest record metadata. Reported or acknowledged signatures evicted from the bounded index stay retired while their records survive: confirmed log pruning drops obsolete tombstones, uncertain crash-log or sidecar reads fail closed, retirement evidence publishes before the main index that depends on it, and replayed journal batches heal an interrupted stale tombstone without repeating counts. The separate ledger is bounded by the maximum distinct records in the bounded log rather than the live-index entry cap, so sequential retirements cannot exhaust admission (#4478, reported with measured field evidence by @yazzang-homelab).
|
|
60
|
+
- The mid-run context maintenance contract suite no longer uses real-time `Bun.sleep(10)` to settle persistence after externally emitted events. A new public `AgentSession.awaitSessionSettlement()` deterministically awaits every in-flight agent-event handler (including the synchronous canonical persistence each one performs) and the durable transcript flush queue, replacing the ambiguous fixed-duration sleep whose adequacy depended on system load. Concurrent-state observation helpers now use event-loop tick yields (`Bun.sleep(0)`) instead of paced real-time sleeps. The maintenance outcome contract (`not-needed | pruned | compacted | promoted | failed | aborted`), publication failure semantics (fail-closed `artifact_persistence`), rollback, and canonical-output retention are unchanged (#4476).
|
|
61
|
+
- `sdk-adapter-dispositions.test.ts` no longer exceeds the CI 300s file-timeout with `exit=0`. Measurement proved all 489s was genuine per-fixture runtime (291 production SDK host startups at ~1.7s each), not leaked timers/sockets/workers — the process exits ~200ms after the last test. The three machine-adapter cohorts (MCP, ACP, daemon CLI) are now split into sibling files so each runs under the unchanged timeout with byte-identical coverage; the chat-adapter loops stay in the original file (#4475).
|
|
62
|
+
- Print mode now requests a governed process exit after successful session teardown, so completed one-shot runs cannot be pinned by residual runtime handles; both stdout and stderr are drained first and the recorded exit code is preserved.
|
|
63
|
+
- `todo_write` no longer rejects a positional task handle without saying how to address a task. Callers reach for `id`/`index` because the tool result renders todos as a list, and `todo-write.ts` already had a message for exactly that confusion, but for model-issued calls raw validation rejects the unknown key before `execute` runs (only bridges that invoke a tool directly, such as `eval`'s `callSessionTool`, still reach it), so the model only saw `rejected key: "id"` next to the legal-key list and had to guess the replacement (each retry discards the whole batch, since rejection is atomic). The positional-handle family (`id`, `ids`, `index`, `taskId`, `task_id`), including one nested under `task` or `content`, now carries the same correction the executor gives: tasks have no id or index, target one with `task` set to its exact content or a whole phase with `phase`. A correction shared by several rejected keys is stated once, and raw diagnostics retain only eight keys with a deterministic omitted-key count. The executor comment claiming those keys are stripped before it runs was stale and is corrected.
|
|
64
|
+
- Post-merge repair for #4401/#4399: `CHAT_DAEMON_GENERATIONS.discord` 63→64 and `.slack` 66→67 so the shared `SessionRouter` attachment lifecycle changes from #4401 (`#attach`, `#createAttachedClient`, `#publishAttachment`) are properly generation-fenced for Discord and Slack daemons, not just Telegram. The semantic guard manifest is regenerated.
|
|
65
|
+
- Chat daemons can no longer block session opens. SDK session startup awaited Telegram/Discord/Slack daemon ownership before publishing the core endpoint — with multi-second spawn/reload/reservation-lock budgets on that path, a wedged or blocked Telegram daemon stalled or hard-failed every ACP/MCP `session/new` ("Telegram daemon ownership is blocked"). Daemon ownership is now acquired in a detached background task strictly after core publication: daemon slowness, crash, wedged lock, or a blocked identity degrades only notification delivery (adapters stay withheld until ownership settles) and never session lifecycle.
|
|
66
|
+
- `bun test` no longer writes into the live `~/.gjc/agent`. Test suites resolved the real agent dir by default, leaking fixture daemon diagnostics, transition markers, and unlink placeholders into operator state — accumulated leaked markers wedged the live Telegram daemon's dead-owner lock recovery (`left-contended`). The shared test preload now isolates every test process into a fresh temp agent dir unless an explicit non-default `GJC_CODING_AGENT_DIR` pin is present.
|
|
67
|
+
- `gjc notify recovery` now sweeps inert notification-dir debris (detached transition-marker quarantines, exact-unlink exchange placeholders, crashed-writer `.tmp` staging files) with positive staleness proof, and the Telegram daemon runs the same sweep non-blockingly at startup, so the notifications directory can no longer grow unboundedly and slow every endpoint scan. `--force-daemon-lock` — previously a no-op that only changed the diagnostic wording — now actually detaches a provenance-less (unparseable) steal marker older than the transition grace window through the identity-bound primitive, giving a wedged recovery a real operator escape while valid and young markers stay untouchable.
|
|
68
|
+
- Chat-provider ownership is now proved against the full, non-secret provider identity and re-proved whenever it changes. The identity fingerprints every provider credential (never raw values or lengths) and covers Telegram token/chat, Discord token/application/guild/channel, Slack bot+app token/workspace/channel and its authorized actor, per-provider enablement, the Telegram activation marker, and — only where a chat daemon is effective, because it is part of that daemon's durable identity — redaction and verbosity. Acquisition is single-flight and key-bound, so an outcome proved for one configuration can never authorize another, and a late or superseded outcome can never downgrade a runtime whose adapters are already active. On an identity change the runtime withholds its local adapters before re-proving, and re-proof is provider-neutral: a Discord-only or Slack-only change takes the same path. None of it is ever awaited by session lifecycle. Note that an already-attached external Discord/Slack daemon keeps its SessionRouter attachment through the window; fencing that requires a Router-level chat-attachment authority boundary and is tracked as a follow-up.
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
- The Grok Build provider (`grok-build`) fallback catalog now includes `grok-4.6`, so it can be selected when the proxy exposes that model. It uses xAI's documented 500k context window and $2/$0.50/$6 sub-200k pricing; `xhigh` is its reasoning-effort ceiling while Grok 4.5 remains capped at `high`. The `grok-4.6-latest` alias resolves to Grok 4.6 and `grok-build-latest` remains intentionally mapped to Grok 4.5. The effort allowlist accepts only exact model IDs or hyphenated variants, preventing similarly named models from retaining unsupported reasoning payloads.
|
|
72
|
+
- Documented the shipped multi-account UX: `/usage` is cache-only by default with `/usage check` for explicit sequential probes; `/login` supports OAuth account selection, **AUTO**, and **Add new account**; `/logout` supports selective local OAuth removal; and `gjc accounts list|check|pin --persistent|logout` exposes safe inventory, checks, global pins, and local removal.
|
|
8
73
|
- `/theme <name>` now switches the theme immediately without opening the selector: the name is validated against built-in and custom themes, persisted to the detected `theme.dark`/`theme.light` slot, and applied to the running session in one step. Bare `/theme` keeps the existing live-preview selector, and an unknown name is rejected with the list of available themes.
|
|
74
|
+
- Added built-in `grok-46-{eco,medium,pro}` role profiles using the existing xAI OAuth/subscription provider, and updated `/model` so direct xAI Grok 4.5/4.6 assignment prompts for a supported reasoning effort instead of retaining `(inherit)`. Grok 4.5 offers `low`/`medium`/`high`; Grok 4.6 adds `xhigh`.
|
|
75
|
+
- The model selector and argument-based `/model` assignment now require an explicit supported reasoning effort when assigning any reasoning-capable model to DEFAULT, regardless of provider. The selected `:effort` is persisted in `modelRoles.default`, while non-reasoning assignments and provider-general role-less temporary switches remain direct.
|
|
76
|
+
- `gjc setup paseo` registers GJC as an ACP provider in [Paseo](https://paseo.sh), bridges Paseo's orchestration skills into GJC skill discovery, seeds only empty orchestration role mappings, diagnoses the installation with `--check`, and rolls itself back with `--remove`. Paseo owns its own config files and exposes no lock API or reload verb, so every write is conservative: a round-trip fidelity self-check refuses to touch a file GJC cannot reproduce byte-for-byte, a compare-and-swap guards publication, backups land beside the original at mode 0600 (`~/.paseo/config.json` holds a credential, which never reaches stdout, stderr, `--json`, or a diff), and a durable credential-free intent record makes an interrupted run recoverable. `--remove` deletes a key only when GJC's own provenance ledger recorded creating it *and* the value still matches what GJC wrote, so a hand-authored or user-edited entry always survives. `~/.agents/skills` is treated as read-only, and the Paseo daemon is never restarted automatically -- `--check` reports `stale` and leaves the restart to you.
|
|
77
|
+
- `가재씨` is now installed alongside `gjc` as a Korean launcher alias. Typing `가재씨` runs Gajae-Code identically to `gjc`; it is a package-owned bin entry created by npm/Bun during install with no shell alias or dotfile edit required. Supported on Linux and macOS (UTF-8 locales); on Windows the shim is created but invoking it from `cmd.exe` depends on the console's active code page (#4363).
|
|
78
|
+
- `GJC_WORKTREE_DIR` now selects where `gjc --worktree` creates its launch worktrees. The bucket was derived entirely from the repository path (`<parent>/<repo>.gajae-code-worktrees`) with no override, so a machine that already keeps worktrees under its own convention accumulated a second bucket beside the first. The value is a path template: `{repo}` expands to the repository directory name so one exported value stays repo-scoped, a relative value resolves against the repository's parent directory (`{repo}.worktrees` adopts an existing sibling bucket), and an absolute or `~/`-prefixed value is used as given. Unset or blank keeps the previous default. See [`docs/environment-variables.md`](../../docs/environment-variables.md#6-storage-and-config-root-paths).
|
|
79
|
+
- Added `/credential` (alias `/account`), a slash command that switches a running session's active stored OAuth account for a provider mid-session, independent of quota state. With no argument it lists every provider's stored accounts and marks the one this session is currently using; `/credential <selector>` (`email:<addr>`, `id:<n>`, `account:<id>`, `project:<id>`, optionally `provider/<selector>`) switches to a specific row, inferring the provider from the current model when possible. This is a manual switch distinct from the existing automatic quota-triggered credential fallback — it works even when nothing is exhausted. Refuses to switch when a stronger override (`--credential`, `--api-key`, or a config-sourced `models.yml` `apiKey`) already owns the provider's credential selection, and switching to a still-blocked row safely falls back to a usable account instead of forcing another failed request. See [`docs/custom-providers-and-multi-account.md`](../../docs/custom-providers-and-multi-account.md#switch-accounts-mid-session).
|
|
80
|
+
- `gjc mcp add` registrations are now consumed by ordinary standalone sessions at startup (conventional autoload). Top-level sessions (`gjc`, `gjc --tmux`, print/text/json modes) discover enabled servers from GJC's own native scopes only — project `.gjc/mcp.json` and user `~/.gjc/agent/mcp.json` — with deterministic precedence (project scope wins name collisions; plugin-bundle MCPs override conventional entries). A server is skipped when marked `enabled: false`, listed in either scope's `disabledServers`, or marked `autoload: false`; project scope loads by default and is disabled only by an explicit `mcp.enableProjectConfig: false` setting. New `--no-mcp` flag opts one session out (mutually exclusive with `--mcp-config`, which remains an isolated exact-file mode that replaces autoload). Claude Code/Codex MCP files are explicit import sources into `.gjc` through a new bounded normalization layer (`normalizeClaudeMcpJson` / `normalizeCodexMcpToml` / `validateMCPCompatServer`), never implicit runtime authorities, and foreign user-home configs (`~/.claude`, `~/.codex`) are never read. `gjc mcp list` now reports source scope, path, and a deterministic runtime status (`autoload` / `autoload-off` / `disabled`) with secrets still redacted, and new canonical scope-aware read/write APIs (`runtime-mcp/scope-config.ts`) back both the CLI and the upcoming `/extensions` surface. Subagents inherit the parent's MCP tools without duplicating server processes or owning cleanup, and `/mcp reload` re-discovers native scopes in sessions without plugin-bundle MCPs (#4284, part of #4283).
|
|
81
|
+
- MCP remote (HTTP/SSE) servers now support the Model Context Protocol 2026-07-28 stateless specification ("MCP v2") alongside a bounded, observable legacy compatibility path. Each server accepts a protocol preference (`auto` | `2026-07-28` | `legacy`, default `auto`) across config, capability, and Claude/Codex import mapping. In `auto`/strict mode the client probes optional `server/discover` and applies deterministic, downgrade-safe era detection: it never falls back to legacy on auth, issuer/audience (RFC 9207), resource-audience (RFC 8707), SSRF/DNS/redirect, malformed-response, or other security/protocol-integrity failures — those fail closed. Modern requests are fully stateless (no `initialize`, `Mcp-Session-Id`, sticky session, standalone GET stream, or `DELETE`): every request carries required `_meta` (protocolVersion, clientInfo, clientCapabilities) and mirrored `MCP-Protocol-Version`/`Mcp-Method`/`Mcp-Name` headers, with `x-mcp-header` tool-parameter mirroring (tools with invalid annotations are excluded rather than breaking the catalog). Multi Round-Trip Requests (`input_required`) are recognized on `tools/call`/`prompts/get`/`resources/read`, bridged to GJC's structured ask surface, and retried exactly once under a stable correlation id with verbatim `requestState` echo and a fresh JSON-RPC id. Catalog freshness honors server `ttlMs`/`cacheScope` hints with per-connection invalidation. One authoritative secret-free protocol observation model (`MCPManager.getProtocolObservation(s)`) exposes preference, negotiated era/version, downgrade reason, and feature lifecycle for `/extensions` (#4291) and customization doctor (#4288) consumption. stdio servers keep the legacy handshake unchanged (#4292, part of #4283).
|
|
82
|
+
- Added three provider-agnostic Muse Spark 1.2 presets: Muse Spark across all roles, plus DeepSeek and Luna executor variants.
|
|
83
|
+
- Added `--prefer-credential <selector>`, a soft stored-OAuth-credential preference for multi-account provider pools (`email:<addr>`, `id:<n>`, `account:<id>`, `project:<id>`, or `provider/<selector>`). Unlike `--credential` (a hard pin that never rotates and fails the session on exhaustion), a usable preferred credential is placed ahead of the provider's normal ranking, and a content-free quota/rate-limit failure rotates it out to another active credential immediately and keeps the fallback sticky for the rest of the session. Mutually exclusive with `--credential` and `--api-key`; an unqualified selector must resolve to exactly one active OAuth provider or startup fails asking for an explicit `provider/<selector>` prefix, and a resolved model from a different provider than the preference fails closed instead of silently stranding it. See [`docs/non-compaction-retry-policy.md`](../../docs/non-compaction-retry-policy.md#preferred-credential-quota-fallback).
|
|
84
|
+
- When gjc runs inside a Herdr pane (`HERDR_ENV=1`), lifecycle state is reported through Herdr's custom-integration API (`pane report-agent --source custom:gjc`), so the pane is recognized as the `gjc` agent in Herdr's sidebar and workspace rollups with `idle`, `working`, and `blocked` (ask tool) states, and the authority is released on exit. The herdr binary is resolved from `HERDR_BIN_PATH` or PATH only, every invocation is timeout-bounded and detached, and the reporter is a no-op outside a Herdr pane (`#4318`, contributed by @ox8884).
|
|
85
|
+
- The Herdr integration now also reports the session title as display-only pane metadata (`pane report-metadata --source custom:gjc --title`), so panes are told apart by what they are working on instead of showing an identical `gjc` label each. Herdr draws it on the pane border and exposes it to the sidebar as the `pane` token. The title follows every rename, session switch, and resume, is collapsed to a single sanitized line (control characters removed, bounded to 120 characters, surrogate-safe truncation) so a model-generated name can never inject terminal escapes, and is retracted when the reporter releases the pane so a returning shell does not keep the finished session's title. Sessions that have no name yet report nothing and keep the pane's previous title (`#4402`, contributed by @nahyeongjin1).
|
|
86
|
+
- Hook discovery now records one canonical six-kind normalization contract while preserving each runtime's real authority and semantics. Native directory modules are validated before import and adapted into the session `ExtensionRunner`; Claude/Codex directory providers remain import and diagnostic sources. Constrained plugin batches validate atomically before registration and route after-phases to the post-tool path without gaining blocking authority, unsupported aliases and malformed matchers fail closed with stable diagnostics, and Codex-managed command timing/trust/redaction remain explicitly provider-owned.
|
|
87
|
+
|
|
88
|
+
- Crash records now carry a stable, versioned fingerprint (`gjc-crash-record.v1 fp:<32hex> fpv:1 id:…`), and the new `gjc crash list` / `gjc crash report` commands turn those signatures into an assisted, preview-first bug report. Nothing is transmitted before an explicit per-invocation confirmation of a digest-pinned snapshot: crash text is rewritten by the strict `sanitizeExternalCrashV1` contract (paths, URLs, credentials, ANSI/bidi/zero-width controls, pid and exact timestamps removed, fail-closed on scanner uncertainty), `gh` is first executed after consent, the duplicate search is `--repo` pinned and candidate-only, and "+1" comments carry a per-issue idempotency stamp. Records written before this release carry no identity line and are not reportable. A rate-limited, local-only startup line (`crashReport.nudge`, default on, at most once per 24h) reports that unreported signatures exist. See `docs/crash-reporting.md`.
|
|
89
|
+
- GJC plugin bundle manifests now accept the Claude Code/Codex-familiar `mcpServers` map alias and normalize transport-relevant, end-to-end representable fields into the canonical `mcps` array (per-server `type` maps to `transport`; `command` implies `stdio`, a bare `url` implies `http`), so canonical and alias manifests compile to byte-equivalent normalized surfaces. Ambiguous or unrepresentable aliases (`mcp`, a top-level `skills`/`agents`/`commands`/`slash-commands`, Claude Code-shaped or hybrid hooks, transport-incompatible MCP fields, or `mcpServers` entries with `env`/`auth`/`oauth`/`headers`/enablement controls) now fail with targeted migration diagnostics naming the canonical form and the loose `.gjc/` surface, instead of generic unknown/forbidden-key errors. Protected workflow-skill and role-agent invariants, collision authority, MCP security policy, constrained hooks, and appendix authority are unchanged and apply to normalized entries (`#4287`).
|
|
90
|
+
- `docs/gjc-plugins.md` now contains a decision table for canonical project/user `.gjc` loose customization (`.gjc/mcp.json`, `.gjc/hooks/pre|post/<tool>.ts`, `.gjc/skills/<name>/SKILL.md`, `.gjc/extensions/<name>/`) versus distributable plugin bundles, and identifies Claude Code/Codex layouts as explicit `/extensions` import sources rather than parallel runtime authorities (`#4287`, `#4291`).
|
|
91
|
+
- Filesystem skill discovery is now **on by default**: a valid `SKILL.md` in project `.gjc/skills` or a canonical user location (`~/.gjc/agent/skills`, plus legacy user roots) is advertised and invokable in a normal session with no configuration ceremony (#4285).
|
|
92
|
+
- Project and user skill trust is now explicit and bounded through `skills.trustProjectSkills` / `skills.trustUserSkills` (both default on) instead of the implementation-named `enablePiProject` / `enablePiUser` booleans, which remain as deprecated aliases (#4285).
|
|
93
|
+
- `gjc skills discover` lists filesystem-discovered skills per scope with actionable diagnostics (protected-name collisions, shadowing, include/ignore/disable filters, invalid frontmatter, missing descriptions) (#4285).
|
|
94
|
+
- Project `.claude/skills` and `.codex/skills` (and their user-home counterparts) are recognized as explicit import sources: discovery surfaces each convention skill with the exact copy command that enables it in `.gjc/skills`, so a skill placed in a documented Claude Code/Codex location is discoverable in a normal session while GJC never silently loads another host's files (#4285).
|
|
95
|
+
- Added `gjc customize doctor`, a read-only provenance and status report over every discovered customization surface (MCP servers, skills, hooks, custom tools, extension modules, slash commands, plugin bundles). For each item it reports the source class (canonical `.gjc`/bundled, registered convention, Claude Code/Codex import candidate, or plugin), effective precedence and shadowing, runtime status, a bounded reason code (`invalid-config`, `disabled-*`, `shadowed-by-precedence`, `quarantined`, `policy-blocked`, `source-ignored`, …), remediation commands, and trust notes. The command reuses the canonical discovery registry and the exact session-startup consumers (`loadSkills`, `loadSlashCommands`, `loadAllMCPConfigs`, the plugin-bundle registry) instead of re-implementing discovery, so the report cannot drift from what sessions actually load — including the #4285 invariant that bundled workflow skills always win over same-name filesystem copies. It never executes hooks, never connects MCP servers, and redacts secret-shaped MCP fields (args, env values, headers, auth, endpoint userinfo/query) in both text and `--json` output (#4288).
|
|
96
|
+
|
|
97
|
+
### Changed
|
|
98
|
+
- The four bundled GJC workflow skills (`deep-interview`, `ralplan`, `team`, `ultragoal`) are now always authoritative: a filesystem or caller-supplied skill sharing one of those names can never replace the bundled definition, and the collision is diagnosed by discovery (#4285).
|
|
99
|
+
- Duplicate skill names now resolve with documented, deterministic precedence: project scope beats user scope; within project scope the `.gjc/skills` directory nearest to the working directory wins; within user scope, canonical `~/.gjc/agent/skills` beats legacy roots. Claude/Codex convention copies never participate in runtime precedence — they are import sources. Shadowed duplicates produce warnings instead of silent skips (#4285).
|
|
100
|
+
- Skills without a parseable frontmatter block or without a `description` now produce actionable scan diagnostics instead of silent skips (#4285).
|
|
101
|
+
- Documented the skill surface in `docs/skills.md` (locations, install examples, trust/disable, precedence, diagnostics) and updated the skill-template docs and README to the zero-config install flow (#4285).
|
|
102
|
+
- The root `artifacts/` directory is now fully untracked: test evidence, QA reports, red-team output, and provenance snapshots are no longer committed. The root `.gitignore` ignores `/artifacts/`, and a new gate test (`scripts/artifacts-tracked-policy.test.ts`) enforces zero tracked files under that path. The single deterministic test fixture (`issue-3670-anthropic-cache-eval.json`) moved to `packages/ai/test/fixtures/` where it belongs, and the stale `ci-dev-affected` behavioral-owner mapping that referenced its pre-rename path (`architecture-2383-eval.json`) is corrected (#4420).
|
|
103
|
+
- ACP `session/cancel` again aborts only the active turn by default. The ACP surface's C04 terminal-abort scope had been set to `owned` so an external client that ends a run also stopped exact owned subagents and background tasks; the default is reverted to `turn` to match the SDK `turn.abort` default and other ACP clients' cancel behavior. Owned termination remains available as an explicit opt-in via `_meta.gjc.abortScope: "owned"` on the cancel notification or `GJC_ACP_ABORT_SCOPE=owned` in the agent environment, and invalid values now fail safe to `turn` instead of `owned`. Paseo keeps owned cancels by setting `GJC_ACP_ABORT_SCOPE=owned` in its provider config env with no source changes.
|
|
104
|
+
- `/model <preset>` and `/model gajae-code/<preset>` now activate a known model profile immediately instead of failing with "Unknown model". Unknown names still fall through to model resolution, and `/model <role> <preset>` keeps assigning a model to the named role.
|
|
105
|
+
- Browser `act` and `run` responses can now surface an opt-in (`open(..., { diagnostics: true })`), bounded mailbox of page exceptions and `console.error` metadata. Entries carry only kind, timestamp, origin-only URL, line/column, and an allowlisted built-in error class; path segments, query strings, messages, arguments, values, and stacks are never retained. Serialization is byte-bounded with an explicit truncation marker.
|
|
106
|
+
- A generated, host-neutral `sdk-skills/` bundle now provides namespaced external-agent skills for direct GJC SDK session discovery, approved trusted-local operations, and TypeScript/Python script authoring, with deterministic drift checks and credential-safe fail-closed templates. The bundle carries a versioned `manifest.json` (format version 1) so installed bundles fail closed on missing or unsupported layouts, and the skill prompts are authored as static Markdown sources under `scripts/gjc-sdk-skills/prompts/` that the generator copies and validates.
|
|
107
|
+
- `GJC_SESSION_CONTEXT_BUDGET_BYTES` now overrides the synchronous session-context materialization budget that backs `SessionContextTooLargeError` (previously hardcoded to 64 MiB, now a 512 MiB default). The override parses fail-closed: only a canonical positive-integer value is honored, while empty, non-numeric, negative, zero, safe-integer-overflowing, or above-ceiling (8 GiB) values fall back to the 512 MiB default with a warning, so a malformed value can never silently raise or lower the memory guard. Raise it above your measured session size to suppress the preflight, or lower it to restore the old tight bound.
|
|
108
|
+
- Custom OpenAI-compatible providers can opt into `/fast` forwarding with `compat.supportsServiceTier: true`; first-class OpenCodex discovery enables it automatically so client `service_tier: "priority"` reaches an OpenCodex proxy running in passthrough (`Auto`) mode.
|
|
109
|
+
- `/import-session <transcript-file> [--provider codex|claude]` imports an explicit Codex CLI rollout transcript, Claude Code transcript, or claude.ai conversation export into a new GJC session with reconstructed, redacted continuation context. Detection is content-based with a fail-closed `--provider` override; provenance (provider, format, source session id, source SHA-256, counts, import timestamp) is persisted on the new session, unmappable records are quarantined with digests instead of being silently dropped, secrets are redacted fail-closed, and oversized transcripts are bounded with a deterministic head/tail elision marker. The source file is only read, never modified (#3709).
|
|
9
110
|
|
|
10
111
|
### Fixed
|
|
11
|
-
-
|
|
12
|
-
-
|
|
112
|
+
- STT and OAuth selector animation frames now use the TUI's layout-only render path, avoiding unchanged transcript reconstruction while those local controls animate. The autoresearch overlay no longer starts its 80 ms spinner timer for static completed results and stops the timer as soon as a running experiment settles.
|
|
113
|
+
- Managed session persistence no longer crashes with an unhandled `ENOENT: no such file or directory, open '<session>.jsonl'` when dev's identity-bound persistence state still expects a transcript that has disappeared. Full rewrites now recreate only a confirmed-missing predecessor from the complete resident transcript, while identity mismatches still fail closed so a concurrent successor cannot be overwritten. Hot appends recover the same missing-file case through a complete rewrite rather than publishing only the new records and creating a truncated transcript. Main/release builds were unaffected because they still used unconditional `replaceSync` / `appendSync`; the regression was introduced by dev's later exact-identity persistence hardening.
|
|
13
114
|
- Task-launched canonical subagents no longer receive an ACP exact-config `toolsOnly` MCP manager that they are forbidden to reuse. Planner, Architect, Critic, and Ralplan consensus lanes now start normally while reusable plugin MCP managers continue to inherit across sub-sessions.
|
|
14
|
-
-
|
|
115
|
+
- Telegram notification failures are now contained behind an independent provider subscription: Telegram can cancel only its own cursor and cleanup scope, Router authority replacement/stop no longer awaits provider hooks, topic persistence strips SDK endpoint identity, reconnect preserves topic/cursor continuity, and only explicit terminal archive authority can retire a Telegram topic (#4399).
|
|
116
|
+
- Managed output publication no longer freezes the resident event loop when a no-replace rename stalls in the kernel (#4394). The async `publishManagedFileNoReplace` chain (staging write/fsync, no-replace rename/link publication, destination verification, directory fsync) now runs on the libuv blocking pool through async `FileHandle` operations and the new `renameNoReplacePathAsync`/`linkNoReplacePathAsync` native boundaries, so a kernel-blocked `rename(2)` — e.g. into an oversized APFS directory namespace on macOS — blocks one pool thread instead of starving every timer, sibling subagent, and `Bun.sleep`-based subagent await timeout in the process; a hung publication degrades to one unresolved receipt while the child `.jsonl` transcript remains the source of truth. Atomic no-replace semantics, staging identity verification, owner-only security checks, and crash-recovery behavior are unchanged, and the synchronous publication path is untouched. Scrubbed write-protocol remnants are now also reaped inside per-session descendant directories, not only at managed scope resolution: each bound `ManagedSessionDescendantStore` schedules a throttled (60 s), serialized, batch-yielding best-effort reaper before mutations, bounding the unbounded remnant growth (tens of thousands of zero-byte dirents on platforms without retained authority) that made the kernel hang probable in long orchestration runs.
|
|
117
|
+
- Chat daemon ownership probes now treat only `ESRCH` as proof that an owner exited. Permission errors such as `EPERM` remain fenced as live or indeterminate, preventing Discord and Slack startup from reclaiming a live owner's lock and spawning a competing daemon.
|
|
118
|
+
- Dev CI coding-agent shards preserve file-level state boundaries without Bun 1.3.14 `--isolate`: each deterministic shard enumerates its test files and runs every file in a fresh root-cwd `bun test` process with the repository preload and private HOME/XDG/TMP/GJC roots, while aggregating every failed file. This removes both isolate's preload/segfault startup failures and the shared-process contamination that followed its removal (leaked spies, fake timers, config roots, SDK endpoints, broker state, and native/worker lifecycle), while retaining eight-way shard parallelism and bounded per-file process cleanup (#4378).
|
|
119
|
+
- Overlapping ACP `session/cancel` requests are now aggregated so any acknowledged attempt resolves the waiter immediately, the last failing attempt resolves false, and the aggregate is only re-armed when an entire wave fails without any acknowledgement. A failing attempt that followed an acknowledged one previously cleared the resolved-successful aggregate, so a later cancel installed a fresh unresolved promise whose prompt-preflight rejection awaited past the grace bound. The terminal-abort steering snapshot lifecycle is also turn-bound: capture, discard, and rebind use the captured turn key so a replay/prompt race cannot leak entries, and notification-path rebind covers the full-bus terminalization path where the requester's queued prompt wins during the abort.
|
|
120
|
+
- Telegram forum topics now receive a fresh identity header when an asynchronously generated session title is persisted, so the daemon renames the active topic without depending on `agent_end` winning a race against title generation. The observer is runtime-scoped, deduplicates unchanged titles, and is stopped before session authority is released.
|
|
121
|
+
- A terminal Coordinator session (`completed`, `errored`, `stale`) no longer reports `ready_for_input: true` while `live: false`. Both the coordinator durable state writer (`writeSessionStateUnlocked`) and the runtime sidecar (`basePayload`) computed `ready_for_input` as `state === "ready_for_input" || state === "completed"`, so a completed session published contradictory lifecycle fields (`state: completed`, `live: false`, `ready_for_input: true`). Downstream clients treated the dead session as input-ready and kept incrementing its elapsed timer indefinitely. `ready_for_input` is now `true` only for `ready_for_input`; every terminal or dead state reports `false`. The runtime sidecar validation mirror (`validPreviousRuntimeStatePayload`) enforces the same invariant, so a stale pre-fix `completed + ready_for_input: true` marker is rejected instead of silently preserved. Terminal transitions now also stamp an authoritative `ended_at` timestamp, exposed through `publicCoordinatorSessionState`, so downstream consumers receive a terminal time to freeze timers against (#4351).
|
|
122
|
+
- `ensureBroker` now surfaces the real detached-broker startup-failure reason again instead of the generic "exited before publishing discovery" fallback (#4340). The durable startup-failure marker writer in the `sdk broker-internal` entrypoint was dropped during an earlier merge, so nothing ever wrote the marker `ensure.ts` reads, and every startup failure fell back to the bounded generic message regardless of the real cause (e.g. an unsupported `index.snapshot.json`). The marker writer is restored on both `broker.start()` rejection and the race-loser clean-exit path, and the marker is now bound to the pid of the exact spawned child: `ensureBroker` only trusts a marker written by that exact child, so a stale marker left by a prior spawn or a foreign broker racing the same agent dir can never be misattributed to a different spawn's failure. The bounded generic fallback remains for when no valid current marker exists.
|
|
15
123
|
- The SDK broker's Windows process-liveness probe no longer opens a console window on every poll. `runProcessIncarnationCommand` spawned `powershell.exe` without `windowsHide`, and on Windows 11 — where the default terminal delegation hands every new console to Windows Terminal — each probe therefore created a visible terminal window that stole focus. The PowerShell path runs whenever the native reader cannot bind the target pid, so one dead or inaccessible pid turned the broker's ~2s liveness polling into a continuous window flash for the life of the process. Every other internal spawn in the repo already passed `windowsHide: true`; this one did not.
|
|
16
|
-
-
|
|
17
|
-
-
|
|
124
|
+
- The SDK broker's Windows process-liveness probe no longer opens visible PowerShell/conhost windows when the native binding authoritatively reports an absent process (#4362, #4367). The broker calls `processIncarnation(pid)` every ~5 s during `#watchPublication → #checkpointSessionHeartbeats → checkpointLiveHeartbeats`; the native Rust binding (`Process.fromPid().incarnation`) reads the process creation-time FILETIME via kernel `OpenProcess` + `GetProcessTimes` without spawning any subprocess. When the native binding returns `null` (the authoritative absent-process result), the code previously fell through to spawning `powershell.exe` with `Get-Process -Id <pid>`, which on Windows 11 allocates a console that Windows Terminal renders as a brief visible window flash. Since PowerShell's `Get-Process` uses the same `OpenProcess` path, it cannot recover an incarnation the native binding already failed to read — the spawn was pure waste. `processIncarnation` now returns `undefined` immediately when `fromPid` returns `null`, treating the PID as unresolvable (identical to the prior PowerShell-failure outcome). The PowerShell fallback is preserved when the native binding throws or returns a non-canonical incarnation, so binding/permission/unknown errors still get the fallback path. The dead-registration sweep (60 s) reaps the row once `process.kill(pid, 0)` returns `ESRCH`, converging state correctly. Daemon generations bumped (Telegram 159, Discord 62, Slack 65) because the generation guard tracks the `processIncarnation` declaration body digest; the daemon lifecycle contract itself is unchanged.
|
|
125
|
+
- An acknowledged ACP `session/cancel` can no longer leave the original `session/prompt` unsettled by a wedged client transport. The bounded cancelled-settlement and prompt-rejection paths published the idle `session_info_update` before resolving/rejecting the prompt promise, but `sessionUpdate` awaits the transport write — a client that stops draining the stream (e.g. force-cancel in progress) blocks it, so `waiter.resolve`/`waiter.reject` never ran and the client's turn stayed pending forever (`cancelAgentRun: acknowledged turn still active after timeout`), with the next prompt colliding with the stale foreground turn. Settlement now happens first and the advisory idle publication is detached (`void`), so exactly one bounded `{stopReason:"cancelled"}` result settles the prompt, the running phase is still released (`gjcRunning:false`), the next prompt is accepted, and a late terminal stays fenced. The prompt-control rejection path now also tombstones its settled correlation and releases the phase like every other settlement path (#4324).
|
|
126
|
+
- Telegram notifications are delivered again, and in threaded mode they always use threads. Two defects stacked on top of the session-index fix below. First, `sdk/bus/index.ts` derived a session's `telegramTopicsEnabled` from how it was launched (`lifecycleStartupCapability !== undefined || isTelegramOrchestrationSession(process.env)`), so every ordinary interactive session declared itself topic-ineligible; the daemon (which always runs with `requireTelegramTopicEligibility: true`) rejected that identity header, never created a forum topic, and had nowhere to deliver — while still reporting healthy attachments. Eligibility now follows configuration through the new `isTelegramSessionEligible(cfg)` (Telegram configured and effectively enabled), and the launch-provenance predicate `isTelegramOrchestrationSession` is removed. Second, topic admission itself no longer consults the session's self-declaration at all: a still-running session started by an older build declares `false` forever, and refusing it silently downgraded all of its notifications to flat chat-root delivery. In threaded mode the daemon now always uses threads, keeping only the fail-closed fence that requires a loaded topic registry before it can create or reuse a topic. Daemon generation 156.
|
|
127
|
+
- Managed session appends no longer crash with `managed_replace_failed:io_error` when a transient Windows file-sharing conflict (another handle denying delete sharing on the session transcript) blocks the exact replacement for a moment (#4330). The native destination open retries the conflict for a bounded ~3 s and the append completes once the holder releases; a persistent conflict surfaces the specific `managed_replace_failed:sharing_violation` with the underlying hex Windows status attached, and nothing is retried after any namespace mutation, so no append can be duplicated or corrupted.
|
|
128
|
+
- Telegram (and other chat daemon) notifications work again for interactive sessions. The direct-session GC fence row `main.ts` appends under the agent dir (`host_registered`, `endpointGeneration: 0`, no endpoint) no longer counts as an authority-fencing root in the broker session index, so a session's real endpoint root is no longer forced to `ambiguous`/`live: false`. The post-0.13.1 symmetric ambiguity fencing (#4281) had marked every interactive session ambiguous, SessionRouter refused to attach any session, the notification daemon idle-exited with zero attachments, and broker heartbeat checkpointing skipped every row. The exemption is scoped to that exact bookkeeping shape: an unproven generation-0 `lifecycle_terminal` claim, a malformed generation, and every other unresolved root still fence (C5/C6), and surviving-authority selection is unchanged.
|
|
129
|
+
- `gjc sdk session send --wait` no longer overruns its own wait window. Each `turn.result` poll passed no timeout, so after the session reply budget widened in #4258 a wedged status reply could hold a single poll for 40s past a 30s requested wait; every poll now carries the remainder of that window. The whole poll — not just its post-connect reply — is bounded by the remaining window, so a reconnecting transport cannot dispatch past the deadline, and a poll the window itself ends is reported as the documented `wait_timeout` outcome with the last observed status instead of a transport error. The `readCompleteQ12Snapshot` budget is also described accurately: it bounds pagination (when a page may start, and the reply budget that page gets), not attachment resolution or transport reconnect, and the duplicate #4258 entry that a rebase left under `Added` is removed (#4258).
|
|
130
|
+
- Scheduled goal continuations now reuse an inherited active session admission, or queue through the same admission gate when no admission is inherited. Emergency compaction can therefore continue exactly once without colliding with an already-processing turn or deadlocking behind that turn's post-prompt settlement.
|
|
131
|
+
- Restored task details with a missing result collection now render an explicit pending or unavailable state instead of throwing on `results.length` and falling back to a generic component render error.
|
|
132
|
+
- Durable terminal-scope retention no longer deletes a transitional `no_effect_reserved` reservation that shares an evicted completed row's idempotency key pair. The retention bound chose eviction candidates from completed rows only, but applied the resulting key-pair set to every non-pending row, so the reservation an in-flight abort still had to finalize could be dropped; the mirrored asymmetry in the evicted-key collector could also tombstone a reservation and replay uncertainty over a transaction that was still open. Both now apply the same completed-row rule — neither pending markers nor transitional reservations are evictable or tombstonable. A surviving reservation keeps its key pair present, so the completed peer sharing that pair mints no tombstone — losing that peer's replay authority is the lesser harm. The 256-reservation and 4096-tombstone caps, oldest-first eviction, and FIFO tombstone expiry are unchanged, and the bus and SDK-only host session runtimes now write durable terminal state through one shared retention bound instead of eight hand-rolled copies.
|
|
133
|
+
- A chat daemon no longer reports an authorized SDK command as rejected when the transport only proved uncertainty after the frame was sent. `uncertain_after_send` now classifies as an ambiguous delivery, so the effect journal records `uncertain` and the operator is never told a prompt failed while the session may already be running it.
|
|
134
|
+
- Router attachment identity is now derived in exactly one place (`sessionAttachmentAuthorityId`). The digest binds the endpoint URL/token alongside session, generation, pid, and endpoint mtime, so a caller that persists an attachment authority id can re-derive it instead of hand-rolling a copy that silently stops matching.
|
|
135
|
+
- Resident session-cache disposal no longer retains a predecessor's cache directory when the cache root's permissions widen after adoption. The retained parent descriptor is still revalidated for identity (substitution, symlink, or foreign directory fails closed and stays retryable), but a widened mode on the same owned root no longer turns disposal into permanent retention of resident session bytes.
|
|
136
|
+
- The broker's dead-registration sweep no longer re-reaps rows it already unregistered, and reaps at most 64 registrations per pass. Since DR-1 keeps an unregistered row listed (terminal, not live), every sweep re-appended an unregistration for every dead row: the index grew without bound and the broker held or re-took the shared session-index lock continuously, so unrelated `gjc` launches failed after exhausting their lock-retry budget.
|
|
137
|
+
- Repairing an SDK session index now applies the configured retention policy to the republished snapshot. A repair of a long-lived index previously restored an unbounded snapshot that every later locked transaction had to re-parse, so one broker could pin CPU and hold the shared session-index lock long enough to fail unrelated `gjc` launches.
|
|
138
|
+
- The built-in `claude-opus` model preset now falls back deterministically to `anthropic/claude-opus-4-6` when the authenticated Anthropic catalog does not expose Opus 5, while continuing to prefer Opus 5 when available (#4251).
|
|
139
|
+
- `gjc update` now performs durable managed-notification recovery only after its replacement and installed-runtime verification succeed: force-stop, canonical daemon restart, then notification recovery run serially before local default-skill refresh. Complete provider credentials count even when the global delivery switch is disabled; incomplete, quarantined, and project/session-only configuration never triggers the lifecycle (#4305).
|
|
140
|
+
- Dev CI now runs coding-agent shards from the repository root so the root `bunfig.toml` preload remains cwd-independent, nested managed task children use their canonical provider scope for async-job ownership without rewriting persisted logical headers, bounded TaskTool replay observes the production SDK/manager seams, and the jobs overlay interaction fixture initializes the real theme contract (#4293).
|
|
141
|
+
- The legacy `agentDir/settings.json` source is now retired (`.bak`) only after the combined migration commits: a malformed `agent.db` row that aborts the load keeps the source discoverable for the next load instead of stranding its only copy.
|
|
142
|
+
- An unreadable project ownership marker (`.gjc/state/settings.json.migrated-keys`, e.g. EACCES/EISDIR) now aborts the project migration instead of treating it as empty and reimporting a stale retained value.
|
|
143
|
+
- Strict resume rejection now tears down derived state without mutating the rejected transcript, and releases the persistence writer it opened. A confirmed close is reported as successful cleanup even when the writer rethrows a queued drain failure, a quarantined `close_unknown` outcome is surfaced to the caller as an `AggregateError` alongside the resume error, and a certified pre-dispatch failure retains the writer under an unreferenced retry that releases the descriptor, resident session state, and managed authority once the close reaches a terminal state.
|
|
144
|
+
- Same-directory managed session opens now retain directory and transcript identity from admission through later persistence: existing bounded resumes reject deletion or replacement without persistence, close-time rewrites and appends cannot mutate a successor, and initially missing targets use retained no-replace publication with post-publication identity validation and sidecar initialization only after acceptance.
|
|
145
|
+
- `session.delete` now terminalizes a fully scrubbed transcript correctly instead of reporting `cleanup_pending` for a POSIX exchange-placeholder that carries `payloadDurable: true`. The native protocol always retains a zero-length scrubbed placeholder after destroying the payload; the TS classification now accepts that placeholder as terminal (matching `managed-session-storage.ts`'s `exactUnlinkCompleted`) instead of requiring its absence. A retained successor or unknown path still stays `cleanup_pending`. The `sdk-machine-lifecycle-topology` test ingress was also updated from the retired `sdk session raw global` to the correct `daemon session global` CLI (#4273).
|
|
146
|
+
- `SdkClientError` now carries `reconnect` diagnostics on every reconnect-cycle termination: attempts consumed, the configured attempt budget, elapsed wall-clock, and whether the cycle ended from attempt exhaustion, an elapsed deadline, or cancellation. A long-lived ACP session budget truncated by an unrelated wall-clock deadline was previously indistinguishable from a host that consumed every retry, and closing during a backoff sleep escaped as a bare teardown error with no attribution at all. `details` keeps its existing meaning — the terminating transport error — so consumers reading it directly are unaffected.
|
|
147
|
+
- macOS computer-use permission failures now distinguish a real Screen & System Audio Recording denial from a capture failure after a successful preflight, include the current launcher identity in diagnostics, and preserve TCC grants across GJC ad-hoc rebuilds with a stable designated requirement. Accessibility errors now carry the same launcher/relaunch guidance.
|
|
148
|
+
- Vendor-separated model profiles now delegate. A profile that maps `executor` or `planner` to a provider other than the `default` role exists to spend the other vendor's quota, but the strong "delegate by default" system-prompt directive is gated behind `task.eager`, whose default is `false` — so the main agent kept implementing everything itself and burned its own provider's quota with no warning. Such a layout now enables eager delegation, including when the profile is activated mid-session through `/model` or the model selector (which also activates the `task` tool under `tools.discoveryMode: all`). An explicit `task.eager` value in config still wins, and `gjc config doctor` reports an explicit `task.eager false` next to vendor-separated workers as an advisory. Bare provider-agnostic aliases and single-vendor profiles are unaffected.
|
|
149
|
+
- Telegram topic archives now settle in a private Threaded Mode chat. The archive dispatched `closeForumTopic`, which Telegram rejects outside supergroup forums (`400 … the chat is not a supergroup forum`), so an orphaned private-chat topic could never be archived: the stale thread stayed visible in the chat and the durable `archive_pending` record blocked the session from reusing or recreating a topic after resume. A private paired chat now archives through `deleteForumTopic` (the only archive operation Telegram offers there); supergroup validation forums keep the non-destructive `closeForumTopic`. `TOPIC_ID_INVALID` — Telegram's definitive answer for a topic that was already deleted by hand — now settles the archive instead of retrying forever. Durable archive retries are drained again by a periodic sweep; the drain was dropped in the router refactor, leaving `archive_pending` jobs parked until the next same-session event that never came.
|
|
150
|
+
- SDK workflow-gate recovery now survives a direct-control transport failure during shutdown. When `resolveGate` throws after the broker has already accepted an answer, the catch path re-checks durable completed/accepted-incomplete state and attempts recovery before falling back to quarantine — so a gate that was accepted but whose transport response was lost is no longer stranded. The `AgentSession` emitter fence is moved after `session_shutdown` emission so admitted resolutions can drain during the shutdown window, and both the gate-resolution drain and `session_shutdown` extension handlers are bounded (5 s and 60 s respectively) so a stuck emitter/controller or extension cannot hang shutdown indefinitely (#4047).
|
|
151
|
+
|
|
152
|
+
- ACP `session/new` no longer fails with an uncertain-after-send internal error against a cold session host. Session-scoped commands were dispatched through `SessionRouter` on the SDK transport's one-shot default response deadline (10s), which the first `models.list/current` (Q10) outruns whenever profile-provider credential collection has to refresh several OAuth providers — the reply landed after the deadline (measured 10002ms against an 11s answer), the outcome could then only be reported as uncertain after the frame was sent, and the ACP agent discarded the session it had just created while the immediate retry answered in ~260ms. Router-dispatched session requests now wait for a reply on the SDK's existing round-trip budget (40s, the same `2 * HEARTBEAT_TTL_MS` the session reconnect budget and prompt watchdog already use), while any caller-supplied timeout — coordinator prompt acknowledgement, lifecycle requests — still wins. Connect, reconnect, and lifecycle deadlines are unchanged. Other Router-dispatched surfaces (ACP prompt/query, chat-daemon `/sdk` commands, `gjc sdk session`, SDK MCP, non-prompt coordinator operations) intentionally inherit the same reply budget, so a connected but wedged host is reported after 40s instead of 10s. Two callers are deliberately excluded because they own a tighter promise: `turn.abort` keeps the one-shot deadline, since ACP awaits that acknowledgement before it can arm its 5s settlement grace and a cancel must stay responsive; and each `readCompleteQ12Snapshot` page now carries what is left of the coordinator's 5s snapshot budget, which was previously checked only between pages while the page request itself carried no deadline (#4258).
|
|
153
|
+
### Changed
|
|
154
|
+
- macOS now emits the terminal BEL for completion, approval, and ask notifications by default when `notifications.terminalBell` has not been configured; an explicit setting still controls the behavior.
|
|
155
|
+
## [0.13.3] - 2026-08-15
|
|
156
|
+
|
|
157
|
+
### Added
|
|
158
|
+
- Added Grok 4.6 to the bundled Grok CLI model catalog with bounded reasoning-effort parsing.
|
|
159
|
+
- Added built-in `grok-46-{eco,medium,pro}` role profiles using the existing xAI OAuth/subscription provider, with supported reasoning-effort selection for Grok 4.5/4.6.
|
|
160
|
+
- Added three provider-agnostic Muse Spark 1.2 presets: Muse Spark across all roles, plus DeepSeek and Luna executor variants.
|
|
161
|
+
- Added the bundled Ouroboros theme and pet, including transactional theme selection and RedGajae fallback (#4468).
|
|
162
|
+
- Gajae Pet now renders in iTerm2 using inline PNG frames, with the same reserved composer-side layout and lifecycle cleanup used by Kitty and Sixel (#4499).
|
|
163
|
+
|
|
164
|
+
### Fixed
|
|
165
|
+
- Managed sessions recover from `content_too_large` by rewriting live in-memory entries, and proactively compact before the managed transcript limit (#4411).
|
|
166
|
+
- Managed output publication no longer freezes the resident event loop when a no-replace rename stalls in the kernel; async publication uses blocking-pool native boundaries and per-session stores reap scrubbed protocol remnants (#4396).
|
|
167
|
+
- Print mode now requests a governed process exit after successful session teardown, so completed one-shot runs cannot be pinned by residual runtime handles; both stdout and stderr are drained first and the recorded exit code is preserved.
|
|
168
|
+
- `todo_write` no longer rejects a positional task handle without saying how to address a task. Callers reach for `id`/`index` because the tool result renders todos as a list, and raw validation rejects the unknown key before `execute` runs; positional-handle keys now explain that tasks are addressed by exact `task` content or by `phase`.
|
|
169
|
+
- Escaped-non-ASCII tool-call turns in managed fallback are retried on the same model without charging the fallback chain or advancing it — the wire defect is a sampling accident, not provider evidence — bounded to two consecutive retries before the run terminates (#4515).
|
|
170
|
+
- Image generation now redacts API keys, bearer tokens, JWTs, and other credential formats from provider error messages and surfaced metadata, bounds provider response bodies at 64 MiB before buffering, and cancels rejected bodies instead of retaining unbounded streams (#4302).
|
|
171
|
+
- A transient Windows `invalid_request` during managed replacement-receipt reconciliation is now resolved by capturing both the pending and canonical receipt paths: success when another reconciler already moved the pending receipt, fail-closed `managed_replace_cleanup_receipt_invalid` for conflicting destinations, byte-identical copies, or missing receipts (#4373).
|
|
172
|
+
- Status-line scratch roots are resolved at render time instead of process start, so path classification follows the active environment when `HOME`/`TMPDIR` are rewritten after module caching (#4452).
|
|
173
|
+
|
|
174
|
+
## [0.13.2] - 2026-08-13
|
|
175
|
+
|
|
176
|
+
### Added
|
|
177
|
+
- Added a portable Stream Deck integration for cmux sessions, including a plugin manifest, reusable profile pages, action icons, installation scripts, and a guided setup document (#4308 by @Yeachan-Heo).
|
|
178
|
+
- `/theme <name>` now switches the theme immediately without opening the selector. The name is validated against built-in and custom themes, persisted to the detected `theme.dark`/`theme.light` slot, and applied to the running session in one step (#4429 by @Yeachan-Heo).
|
|
179
|
+
|
|
180
|
+
### Fixed
|
|
181
|
+
|
|
182
|
+
- Anthropic thinking blocks emptied by `clear_thinking` now drop stale signatures before replay, preventing every subsequent request from failing with an invalid thinking-block signature (#4247, reported by @probepark).
|
|
183
|
+
- Coalesced double-Esc and triple-Esc input now emits individual Escape presses under tmux and SSH, while split ambiguous Escape sequences stay buffered until a continuation or flush timeout resolves them (#4312 by @Yeachan-Heo).
|
|
184
|
+
- Apple Terminal.app now retains its default keyboard mode when Kitty keyboard support is unavailable, preserving Korean/Hangul IME composition (#4297 by @Yeachan-Heo).
|
|
185
|
+
- Managed output publication no longer freezes the resident event loop when a no-replace rename stalls in the kernel. Async publication now uses asynchronous file operations and native blocking-pool rename/link boundaries, while per-session stores reap scrubbed protocol remnants on a throttled, serialized schedule (#4396 by @Yeachan-Heo; fixes #4394).
|
|
186
|
+
- The Telegram notification daemon now contains transient Windows state and ownership-lock read failures during steady heartbeat renewal instead of terminating its run loop; staging files are cleaned in a `finally` block, and only a proven ownership mismatch stops the owner (by @Yeachan-Heo; issue #4200).
|
|
187
|
+
- Coordinator MCP now answers the standard `ping` keepalive with an empty result instead of `method not found`, preventing liveness clients from reconnecting repeatedly (#4412 by @developjik).
|
|
188
|
+
- Task-launched canonical subagents no longer receive an ACP exact-config `toolsOnly` MCP manager that they are forbidden to reuse, restoring Planner, Architect, Critic, and Ralplan consensus launches (#4419 by @chlee1001).
|
|
189
|
+
- The SDK broker's Windows process-liveness probe no longer opens a console window on every poll; its PowerShell fallback now passes `windowsHide` so a dead or inaccessible process cannot trigger a continuous focus-stealing terminal flash (#4346 by @Dayoooun).
|
|
190
|
+
- Foreground Bash calls that finish before their auto-background deadline now cancel that deadline instead of leaving a sleep behind that keeps compiled print-mode processes alive (#4256 by @probepark).
|
|
191
|
+
- Prompt suggestions now remain visible after cancelling another interactive action and returning to the composer (#4347 by @thegreatesthoneybee).
|
|
192
|
+
|
|
18
193
|
## [0.13.1] - 2026-08-11
|
|
19
194
|
|
|
20
195
|
### Added
|
|
196
|
+
- Terminal receipt state and correlated steering are now durable. Prompt reconciliation tracks whether a terminal turn produced reportable output (`present`/`missing`/`unknown`), failing closed as `receipt_missing` when a completed turn has no final response. `turn.steer` with a `clientRef` hashes the validated text (SHA-256) and durably reserves dispatch before queueing, deduplicating replays, rejecting conflicting text, and settling to `accepted`/`rejected`/`uncertain`. The new `turn.steer_status` query (Q31) looks up durable steer status by `clientRef` or canonical `commandId`/`turnId` pair. Steer delivery is uncertain after process restart; settled records share the 15-minute/256-record retention bound.
|
|
197
|
+
|
|
21
198
|
- `/model <preset>` and `/model gajae-code/<preset>` now activate a known model profile immediately instead of failing with "Unknown model". Unknown names still fall through to model resolution, and `/model <role> <preset>` keeps assigning a model to the named role.
|
|
22
199
|
- Browser `act` and `run` responses can now surface an opt-in (`open(..., { diagnostics: true })`), bounded mailbox of page exceptions and `console.error` metadata. Entries carry only kind, timestamp, origin-only URL, line/column, and an allowlisted built-in error class; path segments, query strings, messages, arguments, values, and stacks are never retained. Serialization is byte-bounded with an explicit truncation marker.
|
|
23
|
-
- A generated, host-neutral `sdk-skills/` bundle now provides namespaced external-agent skills for
|
|
200
|
+
- A generated, host-neutral `sdk-skills/` bundle now provides namespaced external-agent skills for broker-bound GJC session discovery, approved trusted-local operations, and TypeScript/Python script authoring. Its templates invoke `gjc sdk session` without discovering endpoint records or creating transport clients; deterministic drift checks and a versioned `manifest.json` keep the generated bundle closed.
|
|
24
201
|
- `GJC_SESSION_CONTEXT_BUDGET_BYTES` now overrides the synchronous session-context materialization budget that backs `SessionContextTooLargeError` (previously hardcoded to 64 MiB, now a 512 MiB default). The override parses fail-closed: only a canonical positive-integer value is honored, while empty, non-numeric, negative, zero, safe-integer-overflowing, or above-ceiling (8 GiB) values fall back to the 512 MiB default with a warning, so a malformed value can never silently raise or lower the memory guard. Raise it above your measured session size to suppress the preflight, or lower it to restore the old tight bound.
|
|
25
202
|
- Custom OpenAI-compatible providers can opt into `/fast` forwarding with `compat.supportsServiceTier: true`; first-class OpenCodex discovery enables it automatically so client `service_tier: "priority"` reaches an OpenCodex proxy running in passthrough (`Auto`) mode.
|
|
203
|
+
- Coordinator session state now carries a bounded tool-activity snapshot of what a session is running right now, surfaced through `gjc_coordinator_read_status` and every other `session_state` projection (issue #4195). It reports a per-session sequence, the last activity time, a canonical built-in tool label (anything unproven reads as `custom`), phase, outcome, elapsed time, the exact number of in-flight calls, and a list of the newest 8 of them. The label follows the tool object the agent loop actually dispatched to, so a custom tool that takes a built-in's name mid-run is never published under the built-in's label. A settled session always reports zero active tools. The snapshot carries no tool arguments, results, command text, paths, output, model text, raw call ids, or credentials, and a snapshot that does not match the exact published shape — or that contradicts the lifecycle state published beside it — is withheld rather than repaired.
|
|
26
204
|
|
|
205
|
+
### Changed
|
|
206
|
+
- SDK core now exclusively owns managed session lifecycle and external attachments through Broker lifecycle services and `SessionRouter`; provider daemons receive opaque capabilities only, lifecycle-equivalent adapter controls fail closed, and the former public stdio/socket, standalone TypeScript, and Python raw endpoint clients are removed.
|
|
27
207
|
### Fixed
|
|
208
|
+
- A long-running managed session that grows its transcript to the 64 MiB per-file storage limit no longer permanently fails with `Extension sendUserMessage failed: content_too_large`. The emergency compaction system now includes a transcript-file-size floor (48 MiB, 75% of the managed per-file cap) so a growing session compacts before hitting the wall. When the limit is reached anyway (compaction disabled, a very large tool result, etc.), the active-session append path recovers via a full-rewrite that writes only the live in-memory entries, shrinking the file below the limit instead of permanently poisoning the session (#4408).
|
|
209
|
+
- A Telegram topic registry poisoned by v0.12.12–v0.12.17 (an archive begun during a disconnect grace window persisted `archive_pending` together with a stray `disconnectGraceExpiresAt`) no longer bricks the shared topic authority forever. The parser now tolerates the stray grace deadline on archive-family non-grace records (`archive_pending`, `archive_exhausted`, `inactive`) — the field is inert there and dropped on load, so the next persist heals the durable snapshot — instead of rejecting the whole registry, which made every authority read and CAS write fail (empty in-memory registry, duplicate topics, and on pre-0.12.18 daemons a startup crash loop). Non-archive states still reject the stray field, disconnect-grace records still require both the deadline and the orphan timestamp, and malformed values are still rejected.
|
|
28
210
|
- Foreground Bash calls that finish before their auto-background deadline now cancel that deadline instead of leaving an uncancellable `Bun.sleep()` behind. In print mode the losing sleep kept the compiled CLI alive for the full command timeout after Bash and subagent work had already completed, which appeared as a shutdown hang with no active Node handles.
|
|
211
|
+
- A cancelled persistent Bash shell that is still unwinding no longer forces same-key follow-up commands onto temporary one-shot shells. The retired shell is removed by identity, its persistent successor is installed immediately, and late retirement cleanup cannot delete that successor.
|
|
212
|
+
- Bash shell sessions are now closed rather than merely aborted when they are retired, so a completed command no longer keeps its native shell retained for the rest of the process. This covers shutdown cleanup, one-shot invocations, and shells retired after a cancellation or timeout — the retired shell is never reused, so it is released instead of held.
|
|
29
213
|
- A just-created or just-registered SDK session no longer reads as not-live (failing immediate `session.close`/`session.delete`, endpoint resolution, and chat-daemon attachment) for up to one heartbeat interval: the host-written registration now counts as initial liveness evidence, aging out exactly like a heartbeat, with the OS process-incarnation match still required. The broker's shutdown-escalation identity proof also accepts the incarnation the index auto-stamps at registration, and ACP `session/list` no longer advertises or re-adopts closed/unregistered (DR-1 terminal) rows — repeated ACP deletes answer already-gone instead of escalating against a host that no longer exists.
|
|
30
214
|
- Insane public-route search now cancels and rejects response bodies larger than 1 MiB instead of buffering unbounded feed, HTML, or JSON payloads.
|
|
215
|
+
- Telegram forum-topic ownership is now limited to coordinator/lifecycle-managed sessions; ordinary sessions can still use local SDK or other notification providers without creating Telegram topics.
|
|
31
216
|
- The Telegram notification daemon no longer terminates with an uncaught `EPERM` when publishing its heartbeat sidecar while an external Windows file lock (antivirus, indexer) briefly holds the destination. The rename is retried a bounded number of times under the ownership-lock fence, a still-failing publication is contained as a diagnostic-logged transient (the next heartbeat cycle republishes), and only a proven ownership loss stops the daemon; the stale-writer fence and staging-temp cleanup are preserved on every path (#4200).
|
|
32
217
|
- `/fast` status, model badges, and task/subagent badges no longer show `⚡` for providers that silently drop unscoped priority intent. Indicators now follow wire-effective built-in support or an explicit `compat.supportsServiceTier` capability instead of treating every provider as fast-capable.
|
|
33
218
|
- The broker's dead-registration sweep now requires positive proof of host death (ESRCH, or a readable OS process incarnation that differs from the recorded one) before unregistering a session. Under heartbeat-based liveness a registered host whose heartbeat had not yet been checkpointed read as not-live and could be reaped while still running; a stale or missing heartbeat is no longer grounds for a reap, and terminal registrations are never re-reaped.
|
|
@@ -38,6 +223,7 @@
|
|
|
38
223
|
- ACP prompts now settle when a terminal frame arrives before prompt acknowledgement with correlation split between the frame envelope and event payload. Live and deferred frames share strict ownership derivation, correlated nonterminals wait for exact acknowledgement ownership, and watchdog or cancel settlement no longer waits for a missing acknowledgement. Incomplete or foreign terminals emit structured error logs, unrelated session traffic cannot keep a wedged turn alive, and correlationless session events remain publishable without contaminating prompt-owned final-text state. Deferred terminal replay failures are contained by the session frame queue.
|
|
39
224
|
- Closing a managed session no longer crashes the process when its cold-history sidecar resident-cache directory has already been removed. `SessionManager.close()` released the sidecar cache through an unguarded `dispose()`, so a `ResidentCacheTrustError` escaped teardown as an unhandled rejection (`directory_unverifiable`) and took down the CLI. Disposing an instance directory that no longer exists is now a completed disposal rather than a trust violation — a present-but-untrusted directory still fails closed — and sidecar release both clears its state before disposing and downgrades any remaining trust failure to a warning, matching every other resident-store disposal site.
|
|
40
225
|
- `bun run restart:sdk-broker --close-session-hosts` no longer fails against session hosts whose workspace was deleted while they kept running. The teardown fence proved a pid's identity only from the spawn-time marker inside the session's own workspace state root, so deleting that workspace (a removed worktree, a cleaned scratch directory) destroyed the only evidence the broker would accept: `session.close` answered `close_refused` forever, the host stayed resident serving the source it started with, and every restart exited non-zero naming the same unkillable orphans. Hosts now publish their OS start incarnation into the broker-owned session index at registration — and reconciliation preserves it — so the pid stays provable after its workspace is gone, while a marker naming a different process still refuses the signal and an incarnation that no longer matches the live pid still fails closed. A host that dies before withdrawing its own registration is now retired by the broker on the same evidence its dead-registration sweep already uses, so a completed teardown is reported as one instead of surfacing as `endpoint_stale` or `terminal_uncertain`.
|
|
226
|
+
- Conversation-store lock cleanup now uses a best-effort close and ownership-checked unlink: a failed `close()` never skips removing the lock file (preventing a leaked well-formed lock that blocks every later waiter), while the unlink validates the lock identity so it can only ever remove the lock this holder wrote.
|
|
41
227
|
- Bounded cold-session resume now uses automatic size routing, keeps ordinary sessions eager, admits two-GiB transcripts with fork-header headroom, and reduces first-open work with reusable scanning, buffered sidecar writes, pressure-based GC, one full transcript JSON pass plus a bounded authenticated suffix read, owner-bound concurrent publication, fail-closed post-admission tamper handling, deferred secondary artifacts, and split reservation/residency/disk accounting.
|
|
42
228
|
- Session resume entrypoints now share size-aware bounded admission without weakening strict small-session validation, and hard-link fallback cleanup uses identity-bound native retirement instead of a pathname `lstat`/`unlink` pair.
|
|
43
229
|
- OpenCode Go Responses completions that carry a response id but no output items or token usage are now treated as typed retryable failures instead of successful turns; untyped proxy empty responses retain the existing context-overflow promotion and compaction path.
|
|
@@ -54,13 +240,19 @@
|
|
|
54
240
|
- CLI parsing now fails closed by default, while launch and ACP explicitly defer only their owned startup options; this preserves ACP-specific diagnostics, SDK startup forwarding, real ACP subprocess framing, and RLM typo rejection without exposing retired flags in root help or completion.
|
|
55
241
|
- Read-tool code summarization and ZIP extraction now run asynchronously instead of blocking the TUI event loop during structural parsing or decompression.
|
|
56
242
|
- `secrets.yml` entries with `mode: "replace"` and no explicit `replacement` now derive their substitute from a keyed, domain-separated HMAC-SHA256 construction over the process key instead of an unkeyed public `Bun.hash`. Derived replacements are no longer confirmable offline without the key (issue #4166); same-process determinism, same-length output, and alphanumeric character behavior are preserved, and explicit `replacement` values are unchanged. Note: derived replacements differ across processes/key rotations — set an explicit `replacement` when a stable value is required.
|
|
57
|
-
- Managed scope preparation now reaps scrubbed write-protocol remnants. The POSIX exact-unlink fallback detaches and scrubs but never deletes, and macOS has no retained directory authority to complete deletion, so every managed replacement leaked zero-length `.gjc-exact-unlink-placeholder-*`, `.gjc-receipt-remove-*`, and `.gjc-exact-replace-destination-*` entries; scope directories grew without bound (observed at 83k dirents), degrading every per-mutation receipt scan and
|
|
243
|
+
- Managed scope preparation now reaps scrubbed write-protocol remnants before the synchronous binding publication receipt scan. The POSIX exact-unlink fallback detaches and scrubs but never deletes, and macOS has no retained directory authority to complete deletion, so every managed replacement leaked zero-length `.gjc-exact-unlink-placeholder-*`, `.gjc-receipt-remove-*`, and `.gjc-exact-replace-destination-*` entries; scope directories grew without bound (observed at 83k dirents), degrading every per-mutation receipt scan and making an already-over-limit scope unable to reach its former post-publication self-healer. Preparation now removes zero-length, single-link remnants older than 15 minutes before that scan; non-zero displaced predecessors and detached receipts are retained as evidence, and in-flight protocol steps are protected by the age gate (#4303).
|
|
58
244
|
- Conversation store file locks now publish complete, synced metadata atomically and release idempotently: failed lock construction cleans its pending artifact, release cleanup is ownership-checked, and recovery reclaims only stale locks or provably abandoned locks from the same process isolate. Empty, malformed, and unproven legacy markers fail closed at the normal timeout; concurrent healers and predecessors cannot delete a successor lock.
|
|
245
|
+
- SDK lifecycle hosts now verify that their session endpoint file is removed after graceful shutdown, setting a non-zero exit code and emitting a diagnostic if the endpoint persists. This closes a gap where a `SIGTERM`/`SIGINT` stop could exit cleanly even though the host's endpoint JSON was still on disk, leaving a stale endpoint for broker discovery.
|
|
59
246
|
- Owned subprocess teardown now recognizes zombie-only Linux process groups without consuming its grace window, while failing closed on unreadable `/proc` evidence, guarding recycled process-group leaders with their spawn-time identity, and reporting an explicit incomplete-teardown outcome to MCP stdio callers. Recycled-leader guarding applies only where that identity is readable (`/proc`); on macOS and other POSIX platforms teardown still signals the owned group instead of refusing it as unverifiable.
|
|
247
|
+
- ACP clients can now map advertised `/skill:*` commands to canonical `skill.invoke` while binding the run to exact correlated prompt completion and cancellation ownership, and can answer deep-interview forms in headless lifecycle sessions. Lifecycle hosts initialize the shared theme before tools render and before the MCP readiness budget is calculated, preventing the pre-elicitation `theme.status` failure, and protocol form providers remain authoritative if a local `/notify on` registers an interactive source later.
|
|
248
|
+
- SDK session-index snapshot publication no longer fsyncs a read-only temp handle, which threw `EPERM: operation not permitted, fsync` during Windows startup whenever the broker published the session snapshot. Publication now goes through the same atomic write-and-sync helper the repair path uses (writable handle, rename, directory sync, and temp cleanup on failure), so Windows `FlushFileBuffers` succeeds and a failed publication no longer leaks the `.tmp` file (#4250).
|
|
60
249
|
|
|
61
250
|
### Added
|
|
62
251
|
- `gjc setup provider` now ships parameterized proxy presets: `--preset litellm` and `--preset openai-compatible-proxy` (aliases `litellm-proxy`, `openai-proxy`, `compatible-proxy`, `custom-proxy`) with a required `--base-url`, configurable `--api-key-env`, and live model discovery (#4123).
|
|
63
252
|
- New `modelProfile.proxyProvider` and `modelProfile.proxyMode` settings route built-in model-preset selectors through an authenticated OpenAI-compatible proxy (e.g. `xai/grok-4.3` → `litellm/xai/grok-4.3`). `fallback` preserves directly authenticated providers by default; `always` forces every proxy-routable built-in selector through the configured gateway. Routing fails closed for unconfigured or unauthenticated proxies and missing or ambiguous proxy models (#4123).
|
|
253
|
+
|
|
254
|
+
- `turn.abort` `mode:"terminal"` with `scope:"turn" | "owned"`: stops the root turn and blocks only its own continuation routes, while left-running owned work keeps running and its completions resume the agent as a fresh turn (`scope:"turn"`) or are settled/dropped (`scope:"owned"`). Durable idempotency via the reconciliation store, deterministic replay after restart/eviction, bounded reservations, and the private turn-continuation fence.
|
|
255
|
+
|
|
64
256
|
- SDK-only session hosts now publish their session ID and register their endpoint lifecycle with the broker, matching its identity and staleness fences. This restores broker/coordinator resolution for durable workflow-gate controls (`workflow.gates.list` and `workflow.gate_answer`) without relying on tmux pane input; broker unavailability leaves non-lifecycle local hosts usable and retries publication later.
|
|
65
257
|
|
|
66
258
|
- Python eval now settles managed-runtime provisioning before cancellation, retires cancelled initialization without sharing it with successors, and retains late kernels whose shutdown is unconfirmed for postmortem retry.
|
|
@@ -126,6 +318,7 @@
|
|
|
126
318
|
- `--clipboard-transport <auto|native|osc52|ssh>` and `--clipboard-ssh-host <alias>` CLI flags, plus persisted `clipboard.transport` / `clipboard.sshHost` settings (CLI overrides config, config overrides the `auto` default). `ssh` mode routes text copy/paste through `ssh -o BatchMode=yes -o ConnectTimeout=3 -- <host> pbcopy/pbpaste` via argv spawn (never a shell string) with a 5-second hard timeout covering the whole operation lifecycle, a 1 MiB payload cap enforced during streaming (never fully buffered before the check), fatal UTF-8 decoding on the inbound side (invalid bytes are rejected, not silently normalized to U+FFFD), and outbound NUL-byte/unpaired-surrogate rejection. Explicit `ssh` failures (nonzero exit, timeout, invalid host, oversize/invalid payload) surface a sanitized error and never silently fall back to native clipboard or OSC 52 — clipboard payloads are never written to logs or artifacts. `auto`/`native`/`osc52` behave exactly as before. New `app.clipboard.pasteText` action (no default key; command palette only, so it never collides with the existing image-paste binding) reads the configured `ssh` clipboard and inserts it at the cursor.
|
|
127
319
|
- `gjc sdk session` is the new broker-bound CLI for operating live SDK sessions: `list`, `inspect`, `send`, `status`, and `tail` plus the explicit `raw control|query|global` hatch. Every semantic verb resolves sessions through the SDK broker (validated endpoint identity, credentials used and never printed), output is a versioned credential-free row DTO, `send --wait` polls `turn.prompt_status` to a terminal state without ever cancelling, `tail` replays retained history from the durable checkpoint with `--strict` failing closed on `retention_gap`, and `--until-idle`/`--all-events`/`--cursor` bound and widen the follow. The removed `gjc daemon session` route is not aliased; the new surface is documented in `docs/sdk-session-cli.md` and referenced from `docs/sdk.md`.
|
|
128
320
|
|
|
321
|
+
|
|
129
322
|
### Changed
|
|
130
323
|
|
|
131
324
|
- Edit cards now keep live calls concise when collapsed and show per-file results, diff statistics, diagnostics availability, and full details consistently when expanded.
|
|
@@ -166,6 +359,7 @@
|
|
|
166
359
|
- Added plugin registry v2 as the single execution authority for plugin tools, subskills, and prompt appendices, with digest verification at final use.
|
|
167
360
|
- Added module-trace and process-tree RSS verification harnesses for startup-memory regressions.
|
|
168
361
|
- Added `bun run clean` / `bun run clean:native` (`scripts/clean.ts`) to remove build output — `dist/`, `binaries/`, `coverage/`, stray `*.bun-build`, `*.tsbuildinfo`, and with `--native` compiled `.node` addons. Sources, `node_modules/`, `.gjc/` runtime state, and `artifacts/` test evidence are refused as targets rather than silently skipped, and `--dry-run` lists targets without deleting.
|
|
362
|
+
- Workflow settings (ralplan `maxIterations`/`autoHandoff`/`maxReviewPassesPerLane`, deep-interview `ambiguityThreshold`, ultragoal `nudgeBudget`) now resolve through one shared resolver: project `.gjc/config.yml` → user `<agentDir>/config.yml` → built-in default. `config.yml` is the ONLY settings surface — the legacy `settings.json` files' workflow keys are retired: the config-root `~/.gjc/settings.json` is migrated once into the default global agent `config.yml` and the source removed, while the project `.gjc/settings.json` is retained for its non-workflow settings (only its workflow keys are migrated into project `.gjc/config.yml` and no longer read). `config.yml` values previously ignored by the workflow runtimes now take effect (`gjc config set gjc.ralplan.maxIterations 7` is honored by ralplan); project configuration beats user configuration, fixing deep-interview's former user-YAML-first inversion.
|
|
169
363
|
- Codex GPT-5.6 OAuth context-window overrides are honored instead of silently re-clamped: explicit `modelOverrides.<id>.contextWindow` values survive the bundled 372K cap when positive and finite, non-positive values are ignored with a warning, and the precedence/fallback contract is codified in the Codex context-cap policy (#3987).
|
|
170
364
|
|
|
171
365
|
### Changed
|
|
@@ -173,13 +367,23 @@
|
|
|
173
367
|
- Because `read`/`search` emit hash-line anchors and default line numbers only in `hashline` mode, `edit.mode: auto` now routes those display surfaces with the edit protocol: GPT/Codex (`apply_patch`) and Claude/DeepSeek/Qwen (`replace`) sessions no longer show hash anchors or line numbers in `read`/`search` output unless `readLineNumbers: true` is configured, while MiniMax/GLM/Kimi/Moonshot and unknown models keep the hashline display. `GJC_EDIT_VARIANT=hashline` restores the previous hashline read/search display exactly.
|
|
174
368
|
|
|
175
369
|
- Workflow skills are no longer implicitly auto-routed. The UserPromptSubmit keyword autoroute now matches only explicit `$`-prefixed tokens (`$deep-interview`, `$ralplan`, `$ultragoal`, `$team`); natural-language phrases ("don't assume", "consensus plan", "interview me", "coordinated team") and bare skill names no longer activate workflows. The system prompt now ranks explicit user intent above every routing heuristic, forbids workflow self-invocation and plan stacking, bans task-difficulty overestimation, directs the agent to offer heuristic workflow escalation (especially deep-interview for vague requirements) through the `ask` tool with an opt-out, and adds an `<engineering>` principles section.
|
|
370
|
+
- Registered `gjc.ultragoal.nudgeBudget` in the public settings schema (default 10, non-negative integer).
|
|
371
|
+
- The legacy config-root `~/.gjc/settings.json` workflow keys are migrated once into the environment-selected global agent profile's `config.yml` — `GJC_CODING_AGENT_DIR` / `PI_CODING_AGENT_DIR` when set, else the default `~/.gjc/agent/config.yml` — on the next global-scope load (absent-only, atomic marker, no-clobber `.bak`). Invalid strict ralplan legacy values keep the source active so `gjc ralplan` still fails loudly (exit 2); future-schema `config.yml` targets are never touched.
|
|
372
|
+
- ralplan settings are strict for all three keys: malformed or invalid explicit settings in any layer/format exit 2 (the former silent `maxIterations` fallback is removed). An invalid strict ralplan value in the target `config.yml` is repaired with a valid legacy value during migration.
|
|
373
|
+
- `config.yml` settings use the nested schema form; flat dotted keys are honored only in legacy `settings.json` files so every effective override stays manageable via `Settings`/`gjc config`.
|
|
374
|
+
- A strict ralplan key in a retained project `settings.json` that is shadowed by a valid project `config.yml` value is recorded as migrated (owned), so a later `gjc config unset` of that value falls through to the default layer instead of resurrecting the invalid legacy value (exit 2).
|
|
375
|
+
- Workflow commands inside an SDK session created with a custom `agentDir` (`createAgentSession({ agentDir })`) resolve the user/agent settings layer from that profile instead of the process-global default profile.
|
|
176
376
|
- Deferred notification adapters, native bindings, provider construction, tools, skills, eval, session artifacts, and history storage until their feature paths are used, reducing the CLI startup module graph without changing default behavior.
|
|
377
|
+
|
|
177
378
|
- Split SDK session hosting into a transport-neutral runtime and lazy notification adapters.
|
|
178
379
|
- `sticky-viewport-showcase.test.ts` runs in ~53s instead of ~192s, cutting the slowest CI test shard from ~369s to ~167s locally. Each of its 17 cases spawned a `bun` subprocess that re-rendered all 20 showcase frames (~9.4s per capture, ~187s of the file's ~192s) purely to obtain a pristine bundle it then corrupted. The bundle is now captured once and handed out as filesystem copies; the one case that must observe mutated `GJC_STICKY_VIEWPORT_ORACLE_COMMIT` state still captures for itself. Isolation is load-bearing and verified: sharing the directory instead of copying it fails 9 cases.
|
|
179
380
|
|
|
180
381
|
### Fixed
|
|
181
382
|
- Telegram topic archival no longer corrupts the shared topic registry when an active topic first enters disconnect grace. `beginArchive` changed `authorityState` to `archive_pending` but retained `disconnectGraceExpiresAt`, a field the persisted-state parser permits only for `disconnect_grace`; one closed or stale session therefore made the entire otherwise-valid registry unreadable, after which every daemon scan reported `shared topic authority unavailable` and no new session could create a thread or replay a message. Every transition out of disconnect grace now clears the grace-only deadline before persistence. `DAEMON_GENERATION` bumped to 57.
|
|
182
383
|
|
|
384
|
+
- Added dual execution/receipt terminal truth across SDK reconciliation, runtime sidecars, and coordinator turns. Empty terminal output now fails closed as `receipt_missing`, while version-1 records without additive receipt fields remain readable as `unknown`.
|
|
385
|
+
- Added retry-safe correlated `turn.steer` acknowledgement and Q30 `turn.steer_status`. GJC durably reserves a SHA-256 digest before dispatch, replays retained status without duplicate steering, and preserves uncertain delivery across restart without storing steer text.
|
|
386
|
+
|
|
183
387
|
- `notifications-topic-registry.test.ts` pins `DAEMON_GENERATION` at 54 after #3965 (was stale at 53; Dev CI run 31133356543).
|
|
184
388
|
- `smithery-env-trust.test.ts` no longer awaits hung probe pipes past a hard per-attempt deadline: minimal child env, `stdin: "ignore"`, SIGKILL + settled race, and up to 2 timeout-only retries. Fixes the inherited-config case that hit exactly 60001ms on Dev CI run 31133356543 after kill-at-45s left `Promise.all` on stdout/stderr unresolved. Assertions unchanged.
|
|
185
389
|
- A Telegram notification daemon that dies without a clean shutdown no longer keeps advertising itself as the ready owner. Ownership was surrendered only by `releaseDaemonOwnership`, which runs after a fully quiesced and fully persisted shutdown; an uncaught error, a failed final topic-registry persist, or a signal left `ownershipPhase: "ready"` and a matching ownership lock on disk, and every later reader attached to a process that no longer existed. Observed in the field: a daemon wrote one heartbeat 559 ms after readiness, died on an uncaught `shared topic authority unavailable` error, and was still recorded as ready eight hours and seventeen crashes later, with no notification delivered in between. The daemon-internal entrypoint now records `stoppedAt` on the way out — from its own `finally` and from a `postmortem` hook that also covers the fatal paths that call `process.exit()` without unwinding — fenced on full owner identity so a successor's state is never touched, and leaving the ownership lock for the existing reclaim path to adjudicate. `isFreshLiveOwner` already treats `stoppedAt` as disqualifying, so recovery no longer depends on a pid liveness check that a recycled pid can defeat.
|
|
@@ -321,6 +525,7 @@
|
|
|
321
525
|
### Added
|
|
322
526
|
|
|
323
527
|
- Notification settings now expose first-class Telegram, Discord, and Slack configuration, desired-intent toggles, provider-local quarantine and repair guidance, explicit `keep | replace | remove` secret actions, provider-specific health/test diagnostics, and truthful saved-but-runtime-degraded outcomes. The global master preserves provider credentials and intent, `GJC_NOTIFICATIONS=0` suppresses only automatic generic-session admission, and blocked Telegram ownership uses an isolated chat-only endpoint so verified Discord or Slack siblings can continue without exposing the shared endpoint.
|
|
528
|
+
- `/import-session codex [session-id ...]` imports selected Codex histories, or every Codex history bound to the current workspace when IDs are omitted, into resumable native v5 sessions. Imports stream through bounded sanitization and quarantine, preserve source provenance, publish atomically and idempotently, support transcripts above 64 MiB through memory-guard checkpointing, and remain unavailable to ACP/remote clients.
|
|
324
529
|
|
|
325
530
|
### Fixed
|
|
326
531
|
|
|
@@ -331,7 +536,9 @@
|
|
|
331
536
|
- Fork-context subagents no longer inherit the parent's provider continuity identity. Each child session now presents its own `session_id`/`prompt_cache_key`, so concurrent subagent fleets stop colliding on session-owning upstream transports (`owner_busy` websocket-to-HTTP fallbacks) and keep per-worker cache affinity. Because `providerSessionId` scopes sticky credential selection as well as prompt-cache affinity, each child also selects its provider credential independently instead of following the parent's sticky choice. Explicit `providerSessionId` overrides and serial same-session continuity are unchanged.
|
|
332
537
|
- Ordinary `ask` selectors now bound long question premises and page through every premise row without skipping rows hidden by overflow indicators (#3675).
|
|
333
538
|
- First-event timeout retries now require a typed, content-free failure from the current clean attempt scope, preventing prior or stale extension activity from suppressing or admitting a later request (#3553).
|
|
539
|
+
- Managed session preparation now preserves native `content_too_large` storage failures as `artifact_capacity_exceeded` instead of misreporting `binding_invalid: prepare:store`.
|
|
334
540
|
- The issue-1979 Korean prose wrap test now cleans up inherited multiplexer env vars (`TMUX`, `TMUX_PANE`, etc.) so it deterministically exercises the plain-terminal render path regardless of the CI runner's terminal session (#1979).
|
|
541
|
+
- The SDK operation inventory now classifies the local-only `/import-session` seam as a locked exclusion and regenerates the committed matrix, fixing the shard-5 `accepts the committed generated matrix` gate failure introduced by the Codex import command (#3714).
|
|
335
542
|
- The model selector's assignment menu now shows the model each role currently resolves to (`Set as EXECUTOR (Executor) — now: anthropic/claude-haiku-4-5`), distinguishing an unset default, a role that inherits the default, and a configured-but-unresolvable selector. Previously the role rows were unlabeled, so the only way to learn a role's model was to scan the whole 800+ entry model list for role badges.
|
|
336
543
|
- Standalone `AGENTS.md` ancestor discovery now bounds directory traversal, per-file reads, and aggregate instruction bytes while surfacing content-free omission warnings (#3722).
|
|
337
544
|
|
package/README.md
CHANGED
|
@@ -24,6 +24,8 @@ For simple local side effects that do not need a full extension, set the user-le
|
|
|
24
24
|
gjc config set completion.notifyCommand 'cmux notify --title "$GJC_NOTIFICATION_TITLE" --body "$GJC_NOTIFICATION_BODY"'
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
On macOS, GJC emits the terminal BEL for completion, approval, and ask notifications by default when `notifications.terminalBell` has not been configured. Set it to `false` to keep macOS terminals silent.
|
|
28
|
+
|
|
27
29
|
When GJC runs inside a cmux terminal (`CMUX_WORKSPACE_ID` is set), GJC best-effort renames that cmux workspace to the current GJC session name (with a `GJC: ` prefix) — but only when the workspace still has its default title, so a name you pinned (or one set by a peer session sharing the workspace) is never overwritten. Opt out with `GJC_NO_CMUX_RENAME=1`.
|
|
28
30
|
|
|
29
31
|
Windows Terminal may keep BEL (`[Console]::Write([char]7)`) silent depending on profile and system sound settings even when `notifications.terminalBell` is enabled. For an audible Windows completion beep, configure a user-level PowerShell command hook instead:
|
package/bin/gajaessi.js
ADDED