@gajae-code/coding-agent 0.11.11 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +131 -4
- package/dist/types/async/job-manager.d.ts +17 -3
- package/dist/types/cli/read-cli.d.ts +1 -0
- package/dist/types/commands/deep-interview.d.ts +9 -0
- package/dist/types/commands/harness.d.ts +22 -0
- package/dist/types/commands/read.d.ts +6 -0
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/provider-auth-health.d.ts +14 -0
- package/dist/types/config/provider-ranking.d.ts +59 -0
- package/dist/types/config/settings-schema.d.ts +83 -1
- package/dist/types/config/settings.d.ts +2 -0
- package/dist/types/exa/mcp-client.d.ts +10 -1
- package/dist/types/exec/bash-executor.d.ts +45 -12
- package/dist/types/extensibility/extensions/types.d.ts +38 -4
- package/dist/types/extensibility/gjc-plugins/index.d.ts +12 -2
- package/dist/types/extensibility/gjc-plugins/installer.d.ts +63 -7
- package/dist/types/extensibility/gjc-plugins/lifecycle-reconciliation.d.ts +55 -0
- package/dist/types/extensibility/gjc-plugins/lifecycle.d.ts +64 -0
- package/dist/types/extensibility/gjc-plugins/runtime-quarantine.d.ts +67 -0
- package/dist/types/extensibility/gjc-plugins/session-validation.d.ts +3 -1
- package/dist/types/extensibility/gjc-plugins/types.d.ts +124 -0
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/gjc-runtime/deep-interview-ambiguity.d.ts +5 -12
- package/dist/types/gjc-runtime/deep-interview-recorder.d.ts +17 -32
- package/dist/types/gjc-runtime/deep-interview-stage.d.ts +37 -0
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +4 -135
- package/dist/types/gjc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/gjc-runtime/launch-tmux.d.ts +1 -0
- package/dist/types/gjc-runtime/memory-guard-owner-claims.d.ts +47 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +70 -1
- package/dist/types/gjc-runtime/state-writer.d.ts +5 -46
- package/dist/types/gjc-runtime/team-launch.d.ts +1 -1
- package/dist/types/gjc-runtime/team-runtime.d.ts +27 -1
- package/dist/types/gjc-runtime/team-store.d.ts +12 -0
- package/dist/types/gjc-runtime/team-worker-heartbeat.d.ts +43 -0
- package/dist/types/gjc-runtime/team-worker-memory-guard.d.ts +92 -0
- package/dist/types/gjc-runtime/tmux-owner-isolation.d.ts +17 -0
- package/dist/types/gjc-runtime/ultragoal-receipt-freshness.d.ts +8 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +31 -80
- package/dist/types/gjc-runtime/workflow-manifest.d.ts +3 -5
- package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
- package/dist/types/main.d.ts +1 -1
- package/dist/types/memories/index.d.ts +2 -0
- package/dist/types/modes/acp/acp-agent.d.ts +10 -19
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/gjc-bundle-settings.d.ts +34 -0
- package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
- package/dist/types/modes/components/notifications-settings-editor.d.ts +1 -0
- package/dist/types/modes/components/read-tool-group.d.ts +4 -4
- package/dist/types/modes/components/session-observer-overlay.d.ts +22 -0
- package/dist/types/modes/components/settings-selector.d.ts +11 -0
- package/dist/types/modes/components/status-line/gh.d.ts +5 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/transcript-viewer-overlay.d.ts +18 -1
- package/dist/types/modes/controllers/event-controller.d.ts +3 -0
- package/dist/types/modes/interactive-mode.d.ts +2 -0
- package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
- package/dist/types/modes/types.d.ts +2 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
- package/dist/types/reminders/star-reminder.d.ts +3 -13
- package/dist/types/runtime-mcp/manager.d.ts +1 -0
- package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
- package/dist/types/sdk/acp/adapter.d.ts +3 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +5 -0
- package/dist/types/sdk/broker/transport.d.ts +2 -0
- package/dist/types/sdk/bus/attachment-registry.d.ts +1 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +4 -1
- package/dist/types/sdk/bus/config.d.ts +6 -2
- package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
- package/dist/types/sdk/bus/index.d.ts +44 -1
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +44 -0
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +4 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +2 -1
- package/dist/types/sdk/bus/reconciliation-store.d.ts +69 -0
- package/dist/types/sdk/bus/rich-draft.d.ts +1 -0
- package/dist/types/sdk/bus/rich-render.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +165 -0
- package/dist/types/sdk/bus/telegram-cli.d.ts +12 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +11 -4
- package/dist/types/sdk/bus/telegram-daemon.d.ts +25 -1
- package/dist/types/sdk/bus/telegram-reference.d.ts +11 -1
- package/dist/types/sdk/bus/threaded-render.d.ts +3 -2
- package/dist/types/sdk/bus/topic-registry.d.ts +11 -1
- package/dist/types/sdk/host/control/operations.d.ts +1 -1
- package/dist/types/sdk/host/host.d.ts +2 -0
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/host/query/revision-store.d.ts +2 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
- package/dist/types/sdk/prompt-status.d.ts +23 -3
- package/dist/types/sdk/session.d.ts +6 -0
- package/dist/types/session/agent-session.d.ts +82 -12
- package/dist/types/session/artifacts.d.ts +8 -0
- package/dist/types/session/blob-store.d.ts +57 -4
- package/dist/types/session/internal/managed-session-storage.d.ts +8 -1
- package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
- package/dist/types/session/session-manager.d.ts +48 -19
- package/dist/types/session/session-storage.d.ts +4 -0
- package/dist/types/session/streaming-output.d.ts +96 -12
- package/dist/types/setup/credential-import.d.ts +12 -0
- package/dist/types/skill-state/active-state.d.ts +12 -4
- package/dist/types/skill-state/workflow-hud.d.ts +9 -0
- package/dist/types/task/executor.d.ts +3 -2
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/task/provider-retry-status.d.ts +8 -0
- package/dist/types/task/receipt.d.ts +7 -1
- package/dist/types/task/types.d.ts +23 -0
- package/dist/types/tools/ask-answer-registry.d.ts +2 -2
- package/dist/types/tools/bash-interactive.d.ts +4 -1
- package/dist/types/tools/bash.d.ts +3 -1
- package/dist/types/tools/browser/launch.d.ts +7 -0
- package/dist/types/tools/fetch.d.ts +17 -1
- package/dist/types/tools/image-gen.d.ts +4 -0
- package/dist/types/tools/index.d.ts +4 -0
- package/dist/types/tools/output-meta.d.ts +44 -3
- package/dist/types/tools/path-utils.d.ts +1 -0
- package/dist/types/tools/read-internals.d.ts +12 -0
- package/dist/types/tools/read.d.ts +45 -7
- package/dist/types/tools/resource-gc.d.ts +4 -0
- package/dist/types/tools/review.d.ts +5 -7
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/tool-result.d.ts +7 -1
- package/dist/types/utils/gh.d.ts +13 -0
- package/dist/types/utils/image-resize.d.ts +1 -0
- package/dist/types/web/search/providers/kimi.d.ts +2 -0
- package/dist/types/web/search/providers/searxng.d.ts +7 -0
- package/dist/types/web/search/providers/xai.d.ts +2 -0
- package/package.json +11 -13
- package/scripts/acp-conformance-agent.ts +218 -0
- package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
- package/scripts/capture-gjc-bundle-settings.ts +306 -0
- package/scripts/capture-sticky-viewport-showcase.ts +292 -0
- package/scripts/generate-sdk-operation-inventory.ts +5 -0
- package/scripts/resident-memory-bench.ts +1341 -0
- package/scripts/run-acp-conformance.ts +285 -0
- package/scripts/verify-gjc-sdk-canonicalization.ts +122 -18
- package/scripts/verify-sticky-viewport-showcase.ts +611 -0
- package/src/async/job-manager.ts +78 -20
- package/src/capability/index.ts +8 -0
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/plugin-cli.ts +176 -18
- package/src/cli/read-cli.ts +2 -1
- package/src/cli.ts +1 -0
- package/src/commands/deep-interview.ts +29 -9
- package/src/commands/harness.ts +35 -12
- package/src/commands/read.ts +11 -2
- package/src/commands/team.ts +20 -2
- package/src/config/file-lock.ts +11 -2
- package/src/config/model-registry.ts +21 -2
- package/src/config/provider-auth-health.ts +42 -0
- package/src/config/provider-ranking.ts +119 -0
- package/src/config/settings-schema.ts +74 -1
- package/src/config/settings.ts +246 -108
- package/src/coordinator-mcp/question-gate-codec.ts +1 -1
- package/src/coordinator-mcp/server.ts +5 -12
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +230 -82
- package/src/defaults/gjc/skills/ralplan/SKILL.md +77 -41
- package/src/defaults/gjc/skills/team/SKILL.md +3 -1
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +62 -39
- package/src/defaults/gjc/skills/ultragoal/validation-batch-contracts.md +12 -0
- package/src/defaults/gjc-defaults.ts +4 -4
- package/src/eval/py/executor.ts +7 -2
- package/src/exa/mcp-client.ts +12 -3
- package/src/exec/bash-executor.ts +144 -27
- package/src/extensibility/extensions/runner.ts +15 -0
- package/src/extensibility/extensions/types.ts +46 -5
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +8 -2
- package/src/extensibility/gjc-plugins/index.ts +19 -2
- package/src/extensibility/gjc-plugins/installer.ts +189 -50
- package/src/extensibility/gjc-plugins/lifecycle-reconciliation.ts +199 -0
- package/src/extensibility/gjc-plugins/lifecycle.ts +626 -0
- package/src/extensibility/gjc-plugins/observability.ts +3 -3
- package/src/extensibility/gjc-plugins/prompt-appendix.ts +5 -1
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +12 -2
- package/src/extensibility/gjc-plugins/runtime-quarantine.ts +121 -0
- package/src/extensibility/gjc-plugins/schema.ts +84 -12
- package/src/extensibility/gjc-plugins/session-validation.ts +9 -3
- package/src/extensibility/gjc-plugins/types.ts +141 -0
- package/src/extensibility/gjc-plugins/validation.ts +9 -0
- package/src/extensibility/shared-events.ts +5 -0
- package/src/gjc-runtime/deep-interview-ambiguity.ts +47 -82
- package/src/gjc-runtime/deep-interview-recorder.ts +227 -310
- package/src/gjc-runtime/deep-interview-runtime.ts +109 -270
- package/src/gjc-runtime/deep-interview-stage.ts +1016 -0
- package/src/gjc-runtime/deep-interview-state.ts +12 -943
- package/src/gjc-runtime/gc-render.ts +1 -0
- package/src/gjc-runtime/gc-runtime.ts +11 -1
- package/src/gjc-runtime/launch-tmux.ts +25 -6
- package/src/gjc-runtime/managed-owner-admission.ts +1 -1
- package/src/gjc-runtime/memory-guard-owner-claims.ts +389 -0
- package/src/gjc-runtime/ralplan-runtime.ts +1149 -98
- package/src/gjc-runtime/state-runtime.ts +2 -1
- package/src/gjc-runtime/state-writer.ts +70 -222
- package/src/gjc-runtime/team-launch.ts +42 -5
- package/src/gjc-runtime/team-runtime.ts +1085 -40
- package/src/gjc-runtime/team-store.ts +32 -0
- package/src/gjc-runtime/team-worker-heartbeat.ts +149 -0
- package/src/gjc-runtime/team-worker-memory-guard.ts +363 -0
- package/src/gjc-runtime/team-workers.ts +1 -0
- package/src/gjc-runtime/tmux-owner-isolation.ts +28 -0
- package/src/gjc-runtime/tmux-sessions.ts +58 -13
- package/src/gjc-runtime/ultragoal-receipt-freshness.ts +20 -0
- package/src/gjc-runtime/ultragoal-runtime.ts +414 -618
- package/src/gjc-runtime/workflow-manifest.generated.json +105 -449
- package/src/gjc-runtime/workflow-manifest.ts +38 -247
- package/src/hooks/native-skill-hook.ts +17 -4
- package/src/hooks/skill-state.ts +1 -23
- package/src/internal-urls/docs-index.generated.ts +21 -22
- package/src/internal-urls/local-root-gc.ts +127 -0
- package/src/main.ts +9 -5
- package/src/memories/index.ts +10 -0
- package/src/modes/DESIGN.md +98 -0
- package/src/modes/acp/acp-agent.ts +339 -191
- package/src/modes/acp/acp-event-mapper.ts +14 -7
- package/src/modes/acp/acp-mode.ts +39 -3
- package/src/modes/components/assistant-message.ts +123 -22
- package/src/modes/components/gjc-bundle-settings.ts +508 -0
- package/src/modes/components/irc-sidebar.ts +176 -62
- package/src/modes/components/model-selector.ts +61 -4
- package/src/modes/components/notifications-settings-editor.ts +12 -1
- package/src/modes/components/oauth-selector.ts +96 -28
- package/src/modes/components/read-tool-group.ts +82 -14
- package/src/modes/components/session-observer-overlay.ts +457 -83
- package/src/modes/components/settings-selector.ts +116 -23
- package/src/modes/components/status-line/gh.ts +16 -0
- package/src/modes/components/tool-execution.ts +138 -27
- package/src/modes/components/tool-status-header.ts +3 -14
- package/src/modes/components/transcript-viewer-overlay.ts +99 -24
- package/src/modes/controllers/command-controller.ts +4 -0
- package/src/modes/controllers/event-controller.ts +109 -27
- package/src/modes/controllers/extension-ui-controller.ts +26 -2
- package/src/modes/controllers/input-controller.ts +18 -3
- package/src/modes/controllers/selector-controller.ts +127 -36
- package/src/modes/interactive-mode.ts +62 -3
- package/src/modes/irc-observation-ledger.ts +71 -15
- package/src/modes/runtime-init.ts +22 -2
- package/src/modes/types.ts +2 -0
- package/src/modes/utils/ui-helpers.ts +94 -1
- package/src/prompts/agent-fragments/ralplan-persistence.md +4 -3
- package/src/prompts/agents/architect.md +9 -1
- package/src/prompts/agents/critic.md +9 -0
- package/src/prompts/system/eager-todo.md +8 -4
- package/src/prompts/system/system-prompt.md +11 -5
- package/src/prompts/tools/bash.md +5 -5
- package/src/prompts/tools/read.md +4 -2
- package/src/prompts/tools/search-tool-bm25.md +5 -0
- package/src/prompts/tools/task.md +1 -1
- package/src/reminders/star-reminder.ts +4 -42
- package/src/runtime-mcp/manager.ts +19 -4
- package/src/runtime-mcp/smithery-auth.ts +17 -2
- package/src/runtime-mcp/smithery-connect.ts +11 -1
- package/src/sdk/acp/adapter.ts +22 -6
- package/src/sdk/broker/lifecycle.ts +25 -6
- package/src/sdk/broker/transport.ts +35 -3
- package/src/sdk/bus/attachment-registry.ts +5 -1
- package/src/sdk/bus/chat-daemon-cli.ts +4 -39
- package/src/sdk/bus/chat-daemon-control.ts +6 -3
- package/src/sdk/bus/config.ts +18 -2
- package/src/sdk/bus/control-drain-lease.ts +104 -0
- package/src/sdk/bus/index.ts +984 -146
- package/src/sdk/bus/kind-aware-reconciliation.ts +317 -0
- package/src/sdk/bus/lifecycle-commands.ts +4 -1
- package/src/sdk/bus/lifecycle-control-runtime.ts +403 -88
- package/src/sdk/bus/prompt-reconciliation.ts +2 -1
- package/src/sdk/bus/reconciliation-store.ts +303 -0
- package/src/sdk/bus/rich-draft.ts +1 -1
- package/src/sdk/bus/rich-render.ts +2 -2
- package/src/sdk/bus/telegram-adoption-intent.ts +574 -0
- package/src/sdk/bus/telegram-cli.ts +33 -8
- package/src/sdk/bus/telegram-daemon-cli.ts +1 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +11 -4
- package/src/sdk/bus/telegram-daemon.ts +916 -23
- package/src/sdk/bus/telegram-reference.ts +40 -3
- package/src/sdk/bus/threaded-render.ts +48 -3
- package/src/sdk/bus/topic-registry.ts +20 -0
- package/src/sdk/host/control/dispatch.ts +5 -1
- package/src/sdk/host/control/operations.ts +1 -1
- package/src/sdk/host/host.ts +23 -1
- package/src/sdk/host/query/handlers.ts +55 -0
- package/src/sdk/host/query/revision-store.ts +36 -2
- package/src/sdk/host/reverse-leases.ts +44 -7
- package/src/sdk/mcp/server.ts +46 -18
- package/src/sdk/prompt-status.ts +16 -3
- package/src/sdk/protocol/operation-inventory.generated.json +51 -0
- package/src/sdk/protocol/operation-registry.ts +7 -2
- package/src/sdk/session.ts +101 -10
- package/src/session/agent-session.ts +1286 -220
- package/src/session/artifacts.ts +22 -0
- package/src/session/auth-broker-config.ts +10 -3
- package/src/session/blob-store.ts +915 -24
- package/src/session/internal/managed-session-scope.ts +44 -6
- package/src/session/internal/managed-session-storage.ts +48 -6
- package/src/session/memory-guard-checkpoint-participant.ts +131 -0
- package/src/session/session-manager.ts +2364 -438
- package/src/session/session-storage.ts +9 -1
- package/src/session/streaming-output.ts +500 -111
- package/src/setup/credential-import.ts +75 -13
- package/src/setup/provider-onboarding.ts +19 -4
- package/src/skill-state/active-state.ts +32 -10
- package/src/skill-state/workflow-hud.ts +42 -2
- package/src/skill-state/workflow-mutation-guard.ts +560 -8
- package/src/task/executor.ts +122 -39
- package/src/task/index.ts +23 -14
- package/src/task/provider-retry-status.ts +16 -0
- package/src/task/receipt.ts +23 -7
- package/src/task/render.ts +6 -2
- package/src/task/types.ts +108 -0
- package/src/tools/ask-answer-registry.ts +12 -6
- package/src/tools/ask.ts +169 -118
- package/src/tools/ast-edit.ts +1 -0
- package/src/tools/ast-grep.ts +1 -0
- package/src/tools/bash-interactive.ts +8 -3
- package/src/tools/bash.ts +503 -60
- package/src/tools/browser/launch.ts +41 -6
- package/src/tools/fetch.ts +114 -23
- package/src/tools/find.ts +1 -0
- package/src/tools/image-gen.ts +29 -5
- package/src/tools/index.ts +4 -0
- package/src/tools/output-meta.ts +281 -20
- package/src/tools/path-utils.ts +8 -3
- package/src/tools/read-internals.ts +44 -0
- package/src/tools/read.ts +1560 -310
- package/src/tools/resource-gc.ts +182 -18
- package/src/tools/review.ts +5 -7
- package/src/tools/search.ts +1 -0
- package/src/tools/subagent-render.ts +6 -2
- package/src/tools/subagent.ts +6 -0
- package/src/tools/telegram-send.ts +6 -3
- package/src/tools/tool-result.ts +14 -1
- package/src/utils/gh.ts +39 -0
- package/src/utils/image-resize.ts +3 -0
- package/src/web/search/providers/anthropic.ts +4 -4
- package/src/web/search/providers/codex.ts +1 -1
- package/src/web/search/providers/kimi.ts +15 -5
- package/src/web/search/providers/searxng.ts +47 -4
- package/src/web/search/providers/xai.ts +7 -2
- package/dist/types/gjc-runtime/deep-interview-draft.d.ts +0 -8
- package/dist/types/gjc-runtime/deep-interview-payload.d.ts +0 -41
- package/dist/types/gjc-runtime/deep-interview-repair.d.ts +0 -17
- package/dist/types/gjc-runtime/ultragoal-pipeline.d.ts +0 -23
- package/src/defaults/gjc/skills/ultragoal/pipeline-validation-contracts.md +0 -30
- package/src/gjc-runtime/deep-interview-draft.ts +0 -843
- package/src/gjc-runtime/deep-interview-payload.ts +0 -262
- package/src/gjc-runtime/deep-interview-repair.ts +0 -1674
- package/src/gjc-runtime/ultragoal-pipeline.ts +0 -306
|
@@ -2044,9 +2044,24 @@ export class InputController {
|
|
|
2044
2044
|
}
|
|
2045
2045
|
|
|
2046
2046
|
toggleThinkingBlockVisibility(): void {
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2047
|
+
if (!settings.canWriteDurableConfig()) {
|
|
2048
|
+
this.ctx.showError(
|
|
2049
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
2050
|
+
);
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
const hideThinkingBlock = !this.ctx.hideThinkingBlock;
|
|
2054
|
+
try {
|
|
2055
|
+
settings.set("hideThinkingBlock", hideThinkingBlock);
|
|
2056
|
+
} catch (error) {
|
|
2057
|
+
if (!settings.canWriteDurableConfig()) {
|
|
2058
|
+
this.ctx.showError(error instanceof Error ? error.message : String(error));
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
2061
|
+
throw error;
|
|
2062
|
+
}
|
|
2063
|
+
this.ctx.hideThinkingBlock = hideThinkingBlock;
|
|
2064
|
+
this.ctx.session.setThinkingVisibility(hideThinkingBlock ? "hidden" : "visible");
|
|
2050
2065
|
|
|
2051
2066
|
// Rebuild chat from session messages
|
|
2052
2067
|
// Detach the live streaming component before the disposing clear() so the
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
getPluginsCacheDir,
|
|
31
31
|
MarketplaceManager,
|
|
32
32
|
} from "../../extensibility/plugins/marketplace";
|
|
33
|
+
import { INTERACTIVE_SELECTOR_RESUME_ORIGIN } from "../../extensibility/shared-events";
|
|
33
34
|
import {
|
|
34
35
|
getAvailableThemes,
|
|
35
36
|
getCurrentThemeName,
|
|
@@ -129,6 +130,7 @@ import { CustomProviderWizardComponent, type CustomProviderWizardSubmit } from "
|
|
|
129
130
|
import { ExtensionDashboard } from "../components/extensions";
|
|
130
131
|
import type { PetMode } from "../components/gajae-pet-widget";
|
|
131
132
|
import { HistorySearchComponent } from "../components/history-search";
|
|
133
|
+
import { HookSelectorComponent } from "../components/hook-selector";
|
|
132
134
|
import { JobsOverlayComponent } from "../components/jobs-overlay";
|
|
133
135
|
import { ModelSelectorComponent } from "../components/model-selector";
|
|
134
136
|
import type {
|
|
@@ -165,6 +167,7 @@ import type { JobsObserver } from "../jobs-observer";
|
|
|
165
167
|
import type { SessionObserverRegistry } from "../session-observer-registry";
|
|
166
168
|
import type { TasksAggregator } from "../tasks-aggregator";
|
|
167
169
|
import type { TranscriptItemRegistry } from "../transcript-item-registry";
|
|
170
|
+
import { acquireResumeProgressLease } from "../utils/ui-helpers";
|
|
168
171
|
|
|
169
172
|
const CALLBACK_SERVER_PROVIDERS = new Set<string>([
|
|
170
173
|
"anthropic",
|
|
@@ -349,6 +352,7 @@ export function createNotificationsEditorOperations(
|
|
|
349
352
|
richDraftEnabled: config.richDraft.enabled,
|
|
350
353
|
toolActivityEnabled: config.toolActivity.enabled,
|
|
351
354
|
streamingEnabled: config.streaming.enabled,
|
|
355
|
+
sound: config.sound,
|
|
352
356
|
},
|
|
353
357
|
};
|
|
354
358
|
},
|
|
@@ -722,6 +726,7 @@ export function createNotificationsEditorOperations(
|
|
|
722
726
|
{ path: "notifications.redact", op: "set", value: preferences.redact },
|
|
723
727
|
{ path: "notifications.verbosity", op: "set", value: preferences.verbosity },
|
|
724
728
|
{ path: "notifications.sessionScope", op: "set", value: preferences.sessionScope },
|
|
729
|
+
{ path: "notifications.telegram.sound", op: "set", value: preferences.sound },
|
|
725
730
|
{ path: "notifications.telegram.rich.enabled", op: "set", value: preferences.richEnabled },
|
|
726
731
|
{ path: "notifications.telegram.richDraft.enabled", op: "set", value: preferences.richDraftEnabled },
|
|
727
732
|
{ path: "notifications.telegram.streaming.enabled", op: "set", value: preferences.streamingEnabled },
|
|
@@ -1151,6 +1156,12 @@ export class SelectorController {
|
|
|
1151
1156
|
);
|
|
1152
1157
|
if (scope === undefined) return;
|
|
1153
1158
|
const persistDefault = scope.trim().toLowerCase() === "default";
|
|
1159
|
+
if (persistDefault && !this.ctx.settings.canWriteDurableConfig()) {
|
|
1160
|
+
this.ctx.showError(
|
|
1161
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
1162
|
+
);
|
|
1163
|
+
return;
|
|
1164
|
+
}
|
|
1154
1165
|
|
|
1155
1166
|
const imageProvider = normalized as
|
|
1156
1167
|
| "auto"
|
|
@@ -1224,13 +1235,18 @@ export class SelectorController {
|
|
|
1224
1235
|
const selector = new ThinkingSelectorComponent(
|
|
1225
1236
|
this.ctx.session.thinkingLevel,
|
|
1226
1237
|
availableLevels,
|
|
1227
|
-
selection => {
|
|
1228
|
-
done();
|
|
1229
|
-
|
|
1238
|
+
async selection => {
|
|
1230
1239
|
const { level, persistDefault } = selection;
|
|
1231
1240
|
const configuredDefault = this.ctx.settings.get("defaultThinkingLevel");
|
|
1232
1241
|
const levelToApply = level === ThinkingLevel.Inherit ? configuredDefault : level;
|
|
1233
|
-
|
|
1242
|
+
try {
|
|
1243
|
+
await this.ctx.session.setThinkingLevelForControl(level, persistDefault);
|
|
1244
|
+
} catch (error) {
|
|
1245
|
+
this.ctx.showError(error instanceof Error ? error.message : String(error));
|
|
1246
|
+
return;
|
|
1247
|
+
}
|
|
1248
|
+
done();
|
|
1249
|
+
|
|
1234
1250
|
const effectiveLevel = this.ctx.session.thinkingLevel ?? ThinkingLevel.Off;
|
|
1235
1251
|
const requestedLabel =
|
|
1236
1252
|
level === ThinkingLevel.Inherit ? `${level} (configured default: ${configuredDefault})` : level;
|
|
@@ -1267,9 +1283,12 @@ export class SelectorController {
|
|
|
1267
1283
|
availableThemes,
|
|
1268
1284
|
availableModelProfiles: [...this.ctx.session.modelRegistry.getModelProfiles().keys()],
|
|
1269
1285
|
cwd: getProjectDir(),
|
|
1286
|
+
gjcRuntimeSnapshot: this.ctx.session.gjcRuntimeSnapshot,
|
|
1287
|
+
gjcActivationGeneration: this.ctx.session.gjcActivationGeneration,
|
|
1270
1288
|
},
|
|
1271
1289
|
{
|
|
1272
1290
|
onChange: (id, value) => this.handleSettingChange(id, value),
|
|
1291
|
+
onError: message => this.ctx.showError(message),
|
|
1273
1292
|
onThemePreview: themeName => {
|
|
1274
1293
|
return previewTheme(themeName).then(result => {
|
|
1275
1294
|
if (!result.success && result.error && !isThemePreviewSuperseded(result)) {
|
|
@@ -1289,6 +1308,7 @@ export class SelectorController {
|
|
|
1289
1308
|
onPetPreview: mode => {
|
|
1290
1309
|
this.ctx.previewPetMode(mode as PetMode);
|
|
1291
1310
|
},
|
|
1311
|
+
onPetCommit: mode => this.ctx.commitPetPreviewMode(mode as PetMode),
|
|
1292
1312
|
onStatusLinePreview: previewSettings => {
|
|
1293
1313
|
// Update status line with preview settings
|
|
1294
1314
|
this.ctx.statusLine.updateSettings({
|
|
@@ -1332,24 +1352,40 @@ export class SelectorController {
|
|
|
1332
1352
|
getAvailableThemes().then(availableThemes => {
|
|
1333
1353
|
const initialTheme = getCurrentThemeName() ?? "red-claw";
|
|
1334
1354
|
this.showSelector(done => {
|
|
1355
|
+
const restoreAndClose = () => {
|
|
1356
|
+
void restoreThemePreview(initialTheme).then(result => {
|
|
1357
|
+
if (!result.success && result.error) {
|
|
1358
|
+
this.ctx.showError(`Failed to restore theme preview: ${result.error}`);
|
|
1359
|
+
}
|
|
1360
|
+
this.#refreshThemeUi();
|
|
1361
|
+
});
|
|
1362
|
+
done();
|
|
1363
|
+
};
|
|
1335
1364
|
const selector = new ThemeSelectorComponent(
|
|
1336
1365
|
initialTheme,
|
|
1337
1366
|
availableThemes,
|
|
1338
1367
|
themeName => {
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1368
|
+
if (!settings.canWriteDurableConfig()) {
|
|
1369
|
+
this.ctx.showError(
|
|
1370
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
1371
|
+
);
|
|
1372
|
+
restoreAndClose();
|
|
1373
|
+
return;
|
|
1374
|
+
}
|
|
1375
|
+
try {
|
|
1376
|
+
settings.set(getDetectedThemeSettingsPath(), themeName);
|
|
1377
|
+
} catch (error) {
|
|
1378
|
+
if (!settings.canWriteDurableConfig()) {
|
|
1379
|
+
this.ctx.showError(error instanceof Error ? error.message : String(error));
|
|
1380
|
+
restoreAndClose();
|
|
1381
|
+
return;
|
|
1348
1382
|
}
|
|
1349
|
-
|
|
1350
|
-
}
|
|
1383
|
+
throw error;
|
|
1384
|
+
}
|
|
1385
|
+
this.#refreshThemeUi();
|
|
1351
1386
|
done();
|
|
1352
1387
|
},
|
|
1388
|
+
restoreAndClose,
|
|
1353
1389
|
themeName => {
|
|
1354
1390
|
void previewTheme(themeName).then(result => {
|
|
1355
1391
|
if (!result.success && result.error) {
|
|
@@ -1373,8 +1409,9 @@ export class SelectorController {
|
|
|
1373
1409
|
const selector = new PetSelectorComponent(
|
|
1374
1410
|
initial,
|
|
1375
1411
|
mode => {
|
|
1376
|
-
this.ctx.setPetMode(mode)
|
|
1377
|
-
|
|
1412
|
+
if (this.ctx.setPetMode(mode)) {
|
|
1413
|
+
done();
|
|
1414
|
+
}
|
|
1378
1415
|
},
|
|
1379
1416
|
() => {
|
|
1380
1417
|
this.ctx.previewPetMode(initial);
|
|
@@ -2262,28 +2299,82 @@ export class SelectorController {
|
|
|
2262
2299
|
async handleResumeSession(sessionPath: string): Promise<void> {
|
|
2263
2300
|
const previousSessionId = this.ctx.sessionManager.getSessionId();
|
|
2264
2301
|
this.#clearTransientSessionUi();
|
|
2265
|
-
const
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
sessionPath
|
|
2273
|
-
|
|
2274
|
-
|
|
2302
|
+
const progressLease = acquireResumeProgressLease(this.ctx);
|
|
2303
|
+
try {
|
|
2304
|
+
await progressLease.committed;
|
|
2305
|
+
const migrationPolicy =
|
|
2306
|
+
this.ctx.settings?.get("session.directoryMigration") === "disabled" ? "disabled" : "copy-retain";
|
|
2307
|
+
let writableSessionPath = sessionPath;
|
|
2308
|
+
if (this.ctx.sessionManager.isManagedDestination()) {
|
|
2309
|
+
const inspection = await SessionManager.inspectSessionTailReadOnly(sessionPath);
|
|
2310
|
+
if (inspection.kind === "error")
|
|
2311
|
+
throw new Error(`Could not inspect selected session: ${inspection.reason}`);
|
|
2312
|
+
writableSessionPath = await this.ctx.sessionManager.prepareManagedCandidateForStrictAdoption(
|
|
2313
|
+
sessionPath,
|
|
2314
|
+
migrationPolicy,
|
|
2315
|
+
inspection.identity,
|
|
2316
|
+
);
|
|
2317
|
+
}
|
|
2318
|
+
// Switch session via AgentSession (emits hook and tool session events)
|
|
2319
|
+
if (
|
|
2320
|
+
!(await this.ctx.session.switchSession(writableSessionPath, {
|
|
2321
|
+
transition: { origin: INTERACTIVE_SELECTOR_RESUME_ORIGIN },
|
|
2322
|
+
}))
|
|
2323
|
+
)
|
|
2324
|
+
return;
|
|
2325
|
+
const switchingToDifferentSession = previousSessionId !== this.ctx.sessionManager.getSessionId();
|
|
2326
|
+
if (switchingToDifferentSession) this.ctx.resetIrcSidebarSession();
|
|
2327
|
+
this.#refreshSessionTerminalTitle();
|
|
2328
|
+
this.ctx.updateEditorBorderColor();
|
|
2329
|
+
|
|
2330
|
+
this.ctx.rebuildInitialMessages(
|
|
2331
|
+
switchingToDifferentSession ? "replace-identity" : "reconcile-same-transcript",
|
|
2275
2332
|
);
|
|
2333
|
+
await this.ctx.reloadTodos();
|
|
2334
|
+
this.ctx.showStatus("Resumed session");
|
|
2335
|
+
this.#maybePromptResumeModelChoice();
|
|
2336
|
+
} finally {
|
|
2337
|
+
progressLease.clear();
|
|
2276
2338
|
}
|
|
2277
|
-
|
|
2278
|
-
if (!(await this.ctx.session.switchSession(writableSessionPath))) return;
|
|
2279
|
-
const switchingToDifferentSession = previousSessionId !== this.ctx.sessionManager.getSessionId();
|
|
2280
|
-
if (switchingToDifferentSession) this.ctx.resetIrcSidebarSession();
|
|
2281
|
-
this.#refreshSessionTerminalTitle();
|
|
2282
|
-
this.ctx.updateEditorBorderColor();
|
|
2339
|
+
}
|
|
2283
2340
|
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2341
|
+
/**
|
|
2342
|
+
* When `session.resumeModelBehavior` is "ask", offer a one-shot choice after
|
|
2343
|
+
* resuming: keep the model the session was last using, or switch to whatever
|
|
2344
|
+
* `modelRoles.default` currently resolves to. No-op if the setting is unset,
|
|
2345
|
+
* the two models already match, or either model can't be resolved.
|
|
2346
|
+
*/
|
|
2347
|
+
#maybePromptResumeModelChoice(): void {
|
|
2348
|
+
if (this.ctx.settings?.get("session.resumeModelBehavior") !== "ask") return;
|
|
2349
|
+
const sessionModel = this.ctx.session.model;
|
|
2350
|
+
const currentDefault = this.ctx.session.resolveConfiguredDefaultModel?.();
|
|
2351
|
+
if (!sessionModel || !currentDefault) return;
|
|
2352
|
+
if (sessionModel.provider === currentDefault.provider && sessionModel.id === currentDefault.id) return;
|
|
2353
|
+
|
|
2354
|
+
this.showSelector(done => {
|
|
2355
|
+
const selector = new HookSelectorComponent(
|
|
2356
|
+
`This session last used ${sessionModel.provider}/${sessionModel.id}.\n` +
|
|
2357
|
+
`Current default model is ${currentDefault.provider}/${currentDefault.id}.`,
|
|
2358
|
+
[`Keep ${sessionModel.id}`, `Use ${currentDefault.id}`],
|
|
2359
|
+
async (option: string) => {
|
|
2360
|
+
done();
|
|
2361
|
+
if (option === `Use ${currentDefault.id}`) {
|
|
2362
|
+
try {
|
|
2363
|
+
await this.ctx.session.setModel(currentDefault);
|
|
2364
|
+
this.ctx.showStatus(`Switched to ${currentDefault.provider}/${currentDefault.id}`);
|
|
2365
|
+
} catch (err) {
|
|
2366
|
+
this.ctx.showError(err instanceof Error ? err.message : String(err));
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
this.ctx.ui.requestRender();
|
|
2370
|
+
},
|
|
2371
|
+
() => {
|
|
2372
|
+
done();
|
|
2373
|
+
this.ctx.ui.requestRender();
|
|
2374
|
+
},
|
|
2375
|
+
);
|
|
2376
|
+
return { component: selector, focus: selector };
|
|
2377
|
+
});
|
|
2287
2378
|
}
|
|
2288
2379
|
|
|
2289
2380
|
async handleSessionDeleteCommand(): Promise<void> {
|
|
@@ -61,7 +61,7 @@ import { GajaePetWidget, type PetMode } from "./components/gajae-pet-widget";
|
|
|
61
61
|
import type { HookEditorComponent } from "./components/hook-editor";
|
|
62
62
|
import type { HookInputComponent } from "./components/hook-input";
|
|
63
63
|
import type { HookSelectorComponent } from "./components/hook-selector";
|
|
64
|
-
import { IrcSplitViewComponent } from "./components/irc-sidebar";
|
|
64
|
+
import { computeIrcSplitWidths, getIrcSidebarSemanticToken, IrcSplitViewComponent } from "./components/irc-sidebar";
|
|
65
65
|
import {
|
|
66
66
|
getPetUnavailableWarning,
|
|
67
67
|
isPetAvailable,
|
|
@@ -416,6 +416,9 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
416
416
|
#sttController: SttModeController | undefined;
|
|
417
417
|
#resizeHandler?: () => void;
|
|
418
418
|
#observerRegistry: SessionObserverRegistry;
|
|
419
|
+
#viewportOutputRevision = 0n;
|
|
420
|
+
#viewportOutputIdentity: string;
|
|
421
|
+
|
|
419
422
|
#transcriptRegistry = new TranscriptItemRegistry();
|
|
420
423
|
|
|
421
424
|
/** Direct controller capabilities for consumers that coordinate mode transitions. */
|
|
@@ -484,6 +487,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
484
487
|
this.mcpManager = mcpManager;
|
|
485
488
|
this.#eventBus = eventBus;
|
|
486
489
|
this.#keyDisplayContext = keyDisplayContext;
|
|
490
|
+
this.#viewportOutputIdentity = `session:${this.sessionManager.getSessionId()}`;
|
|
491
|
+
|
|
487
492
|
this.keybindings.setDisplayContext(this.#keyDisplayContext);
|
|
488
493
|
const thisMode = this;
|
|
489
494
|
this.#goalModeController = new GoalModeController({
|
|
@@ -738,6 +743,11 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
738
743
|
this.ui.addChild(this.hookWidgetContainerBelow);
|
|
739
744
|
this.ui.setBottomPinnedComponent(this.statusLine);
|
|
740
745
|
this.ui.setFocus(this.editor);
|
|
746
|
+
this.ui.setViewportOutputSource({
|
|
747
|
+
identity: this.#viewportOutputIdentity,
|
|
748
|
+
revision: this.#viewportOutputRevision,
|
|
749
|
+
});
|
|
750
|
+
|
|
741
751
|
this.petWidget?.dispose();
|
|
742
752
|
this.petWidget = this.#createPetWidget(this.editor);
|
|
743
753
|
const configuredPetMode = settings.get("pet.mode");
|
|
@@ -770,6 +780,12 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
770
780
|
|
|
771
781
|
this.#inputController.setupKeyHandlers();
|
|
772
782
|
this.#inputController.setupEditorSubmitHandler();
|
|
783
|
+
this.editor.onViewportPageScroll = direction => {
|
|
784
|
+
this.ui.scrollViewportPages(direction);
|
|
785
|
+
};
|
|
786
|
+
this.editor.onViewportFollowLive = () => {
|
|
787
|
+
this.ui.followLiveViewport();
|
|
788
|
+
};
|
|
773
789
|
|
|
774
790
|
// Wire observer registry to EventBus
|
|
775
791
|
if (this.#eventBus) {
|
|
@@ -891,6 +907,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
891
907
|
// Set up theme file watcher
|
|
892
908
|
onThemeChange(() => {
|
|
893
909
|
clearRenderCache();
|
|
910
|
+
this.#ircSplitView.invalidateTheme();
|
|
894
911
|
configureDefaultComposerChrome(this.editor);
|
|
895
912
|
this.editor.setPlaceholder(this.#getComposerPlaceholder());
|
|
896
913
|
this.ui.invalidate();
|
|
@@ -1132,6 +1149,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1132
1149
|
this.statusLine,
|
|
1133
1150
|
this.hookWidgetContainerAbove,
|
|
1134
1151
|
this.editorContainer,
|
|
1152
|
+
this.petFloorContainer,
|
|
1135
1153
|
this.hookWidgetContainerBelow,
|
|
1136
1154
|
].reduce((rows, component) => rows + component.render(width).length, 0);
|
|
1137
1155
|
|
|
@@ -1199,8 +1217,22 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1199
1217
|
this.ui.requestRender();
|
|
1200
1218
|
return false;
|
|
1201
1219
|
}
|
|
1220
|
+
if (!settings.canWriteDurableConfig()) {
|
|
1221
|
+
this.showError(
|
|
1222
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
1223
|
+
);
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1226
|
+
try {
|
|
1227
|
+
settings.set("pet.mode", mode);
|
|
1228
|
+
} catch (error) {
|
|
1229
|
+
if (!settings.canWriteDurableConfig()) {
|
|
1230
|
+
this.showError(error instanceof Error ? error.message : String(error));
|
|
1231
|
+
return false;
|
|
1232
|
+
}
|
|
1233
|
+
throw error;
|
|
1234
|
+
}
|
|
1202
1235
|
apply(mode);
|
|
1203
|
-
settings.set("pet.mode", mode);
|
|
1204
1236
|
this.ui.requestRender();
|
|
1205
1237
|
return true;
|
|
1206
1238
|
}
|
|
@@ -1499,6 +1531,12 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1499
1531
|
|
|
1500
1532
|
this.#inputController.setupKeyHandlers();
|
|
1501
1533
|
this.#inputController.setupEditorSubmitHandler();
|
|
1534
|
+
this.editor.onViewportPageScroll = direction => {
|
|
1535
|
+
this.ui.scrollViewportPages(direction);
|
|
1536
|
+
};
|
|
1537
|
+
this.editor.onViewportFollowLive = () => {
|
|
1538
|
+
this.ui.followLiveViewport();
|
|
1539
|
+
};
|
|
1502
1540
|
|
|
1503
1541
|
void this.refreshSlashCommandState().catch(error => {
|
|
1504
1542
|
logger.warn("Failed to refresh slash command state for custom editor", { error: String(error) });
|
|
@@ -1649,6 +1687,21 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
1649
1687
|
return this.#uiHelpers.isKnownSlashCommand(text);
|
|
1650
1688
|
}
|
|
1651
1689
|
|
|
1690
|
+
/** Advances the sticky-viewport source only for semantic transcript output. */
|
|
1691
|
+
recordVisibleTranscriptMutation(): void {
|
|
1692
|
+
const identity = `session:${this.sessionManager.getSessionId()}`;
|
|
1693
|
+
if (identity !== this.#viewportOutputIdentity) {
|
|
1694
|
+
this.#viewportOutputIdentity = identity;
|
|
1695
|
+
this.#viewportOutputRevision = 0n;
|
|
1696
|
+
} else {
|
|
1697
|
+
this.#viewportOutputRevision += 1n;
|
|
1698
|
+
}
|
|
1699
|
+
this.ui.setViewportOutputSource({
|
|
1700
|
+
identity: this.#viewportOutputIdentity,
|
|
1701
|
+
revision: this.#viewportOutputRevision,
|
|
1702
|
+
});
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1652
1705
|
addMessageToChat(message: AgentMessage, options?: { populateHistory?: boolean }): Component[] {
|
|
1653
1706
|
return this.#uiHelpers.addMessageToChat(message, options);
|
|
1654
1707
|
}
|
|
@@ -2176,12 +2229,18 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
2176
2229
|
}
|
|
2177
2230
|
|
|
2178
2231
|
resetIrcSidebarSession(): void {
|
|
2179
|
-
this.
|
|
2232
|
+
const sidebarVisible = this.#ircSplitView.effectiveSidebarVisible(this.ui.terminal.columns);
|
|
2233
|
+
const rightWidth = computeIrcSplitWidths(this.ui.terminal.columns).rightWidth;
|
|
2234
|
+
const beforeToken = sidebarVisible ? getIrcSidebarSemanticToken(this.ircLedger, rightWidth) : "";
|
|
2235
|
+
this.ircLedger.reset({ retireCurrentSessionIdentities: true });
|
|
2236
|
+
this.#ircSplitView.resetSource();
|
|
2237
|
+
const afterToken = sidebarVisible ? getIrcSidebarSemanticToken(this.ircLedger, rightWidth) : "";
|
|
2180
2238
|
this.#eventController.resetIrcObservations();
|
|
2181
2239
|
this.#ircSidebarRequestedVisible = false;
|
|
2182
2240
|
this.#ircSplitView.setVisible(false);
|
|
2183
2241
|
this.#uiHelpers.resetIrcSidebarHint();
|
|
2184
2242
|
this.#syncIrcSidebarAvailabilityFromSettings();
|
|
2243
|
+
if (sidebarVisible && beforeToken !== afterToken) this.recordVisibleTranscriptMutation();
|
|
2185
2244
|
}
|
|
2186
2245
|
|
|
2187
2246
|
#invalidateIrcSidebarRender(): void {
|
|
@@ -4,9 +4,26 @@ import type { ParsedIrcMessage } from "./utils/irc-message";
|
|
|
4
4
|
|
|
5
5
|
type InlineMode = "persistent" | "ephemeral";
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
7
|
+
export const IRC_OBSERVATION_LEDGER_MAX_RECORDS = 10_000;
|
|
8
|
+
export const IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES = 16 * 1024 * 1024;
|
|
9
|
+
export const IRC_OBSERVATION_LEDGER_MAX_SEEN_IDENTITIES = 100_000;
|
|
10
|
+
|
|
11
|
+
export const __ircLedgerPerfCounters = {
|
|
12
|
+
enabled: false,
|
|
13
|
+
epochAdvances: 0,
|
|
14
|
+
snapshot() {
|
|
15
|
+
return { epochAdvances: this.epochAdvances };
|
|
16
|
+
},
|
|
17
|
+
enable(): void {
|
|
18
|
+
this.enabled = true;
|
|
19
|
+
},
|
|
20
|
+
disable(): void {
|
|
21
|
+
this.enabled = false;
|
|
22
|
+
},
|
|
23
|
+
reset(): void {
|
|
24
|
+
this.epochAdvances = 0;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
10
27
|
|
|
11
28
|
export type IrcObservationRecord = Readonly<
|
|
12
29
|
ParsedIrcMessage & {
|
|
@@ -22,7 +39,7 @@ function measureRetainedUtf8Bytes(message: ParsedIrcMessage): number {
|
|
|
22
39
|
let bytes = 4;
|
|
23
40
|
for (const value of [message.observationId, message.from, message.to, message.text, message.kind]) {
|
|
24
41
|
bytes += Buffer.byteLength(value, "utf8");
|
|
25
|
-
if (bytes >
|
|
42
|
+
if (bytes > IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES) return bytes;
|
|
26
43
|
}
|
|
27
44
|
return bytes;
|
|
28
45
|
}
|
|
@@ -43,12 +60,28 @@ export class IrcObservationLedger {
|
|
|
43
60
|
#nextSequence = 0;
|
|
44
61
|
#seenObservationIdentities = new Set<string>();
|
|
45
62
|
#identityCapacityExhausted = false;
|
|
63
|
+
#retiredSessionIdentities = new Set<string>();
|
|
46
64
|
#evictedObservationIds = new Set<string>();
|
|
65
|
+
#mutationEpoch = 0;
|
|
66
|
+
|
|
67
|
+
get mutationEpoch(): number {
|
|
68
|
+
return this.#mutationEpoch;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#advanceMutationEpoch(): void {
|
|
72
|
+
this.#mutationEpoch++;
|
|
73
|
+
if (__ircLedgerPerfCounters.enabled) __ircLedgerPerfCounters.epochAdvances++;
|
|
74
|
+
}
|
|
47
75
|
|
|
48
76
|
#rememberObservationIdentity(observationId: string): boolean {
|
|
49
77
|
const identity = tombstoneIdentity(observationId);
|
|
50
|
-
if (
|
|
51
|
-
|
|
78
|
+
if (
|
|
79
|
+
this.#seenObservationIdentities.has(identity) ||
|
|
80
|
+
this.#retiredSessionIdentities.has(identity) ||
|
|
81
|
+
this.#identityCapacityExhausted
|
|
82
|
+
)
|
|
83
|
+
return false;
|
|
84
|
+
if (this.#seenObservationIdentities.size >= IRC_OBSERVATION_LEDGER_MAX_SEEN_IDENTITIES) {
|
|
52
85
|
this.#identityCapacityExhausted = true;
|
|
53
86
|
return false;
|
|
54
87
|
}
|
|
@@ -56,6 +89,18 @@ export class IrcObservationLedger {
|
|
|
56
89
|
return true;
|
|
57
90
|
}
|
|
58
91
|
|
|
92
|
+
#retireCurrentSessionIdentities(): void {
|
|
93
|
+
for (const identity of this.#seenObservationIdentities) {
|
|
94
|
+
this.#retiredSessionIdentities.delete(identity);
|
|
95
|
+
this.#retiredSessionIdentities.add(identity);
|
|
96
|
+
while (this.#retiredSessionIdentities.size > IRC_OBSERVATION_LEDGER_MAX_SEEN_IDENTITIES) {
|
|
97
|
+
const oldest = this.#retiredSessionIdentities.values().next().value;
|
|
98
|
+
if (oldest === undefined) break;
|
|
99
|
+
this.#retiredSessionIdentities.delete(oldest);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
59
104
|
#evict(observationId: string): void {
|
|
60
105
|
const record = this.#records.get(observationId);
|
|
61
106
|
if (!record) return;
|
|
@@ -65,7 +110,10 @@ export class IrcObservationLedger {
|
|
|
65
110
|
}
|
|
66
111
|
|
|
67
112
|
#enforceBounds(): void {
|
|
68
|
-
while (
|
|
113
|
+
while (
|
|
114
|
+
this.#records.size > IRC_OBSERVATION_LEDGER_MAX_RECORDS ||
|
|
115
|
+
this.#retainedUtf8Bytes > IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES
|
|
116
|
+
) {
|
|
69
117
|
const oldestObservationId = this.#records.keys().next().value;
|
|
70
118
|
if (oldestObservationId === undefined) return;
|
|
71
119
|
this.#evict(oldestObservationId);
|
|
@@ -76,10 +124,9 @@ export class IrcObservationLedger {
|
|
|
76
124
|
observe(message: ParsedIrcMessage, panelVisibleAtObservation: boolean): IrcObservationRecord | undefined {
|
|
77
125
|
const existing = this.#records.get(message.observationId);
|
|
78
126
|
if (existing) return existing;
|
|
79
|
-
if (!this.#rememberObservationIdentity(message.observationId)) return undefined;
|
|
80
|
-
|
|
81
127
|
const estimatedBytes = measureRetainedUtf8Bytes(message);
|
|
82
|
-
if (estimatedBytes >
|
|
128
|
+
if (estimatedBytes > IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES) return undefined;
|
|
129
|
+
if (!this.#rememberObservationIdentity(message.observationId)) return undefined;
|
|
83
130
|
|
|
84
131
|
const observedAt = Date.now();
|
|
85
132
|
const mode: InlineMode = panelVisibleAtObservation ? "ephemeral" : "persistent";
|
|
@@ -94,6 +141,7 @@ export class IrcObservationLedger {
|
|
|
94
141
|
this.#records.set(record.observationId, record);
|
|
95
142
|
this.#retainedUtf8Bytes += estimatedBytes;
|
|
96
143
|
this.#enforceBounds();
|
|
144
|
+
this.#advanceMutationEpoch();
|
|
97
145
|
return this.#records.get(record.observationId);
|
|
98
146
|
}
|
|
99
147
|
|
|
@@ -116,12 +164,20 @@ export class IrcObservationLedger {
|
|
|
116
164
|
return observationIds;
|
|
117
165
|
}
|
|
118
166
|
|
|
119
|
-
reset(): void {
|
|
120
|
-
|
|
121
|
-
|
|
167
|
+
reset(options?: { retireCurrentSessionIdentities?: boolean }): void {
|
|
168
|
+
const retainedRecordsChanged = this.#records.size > 0;
|
|
169
|
+
if (options?.retireCurrentSessionIdentities) this.#retireCurrentSessionIdentities();
|
|
170
|
+
else this.#retiredSessionIdentities.clear();
|
|
171
|
+
if (retainedRecordsChanged) {
|
|
172
|
+
for (const observationId of this.#records.keys()) {
|
|
173
|
+
this.#evictedObservationIds.add(observationId);
|
|
174
|
+
}
|
|
175
|
+
this.#records.clear();
|
|
176
|
+
this.#retainedUtf8Bytes = 0;
|
|
122
177
|
}
|
|
123
|
-
this.#records.clear();
|
|
124
|
-
this.#retainedUtf8Bytes = 0;
|
|
125
178
|
this.#nextSequence = 0;
|
|
179
|
+
this.#seenObservationIdentities.clear();
|
|
180
|
+
this.#identityCapacityExhausted = false;
|
|
181
|
+
if (retainedRecordsChanged) this.#advanceMutationEpoch();
|
|
126
182
|
}
|
|
127
183
|
}
|
|
@@ -94,7 +94,9 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
94
94
|
{
|
|
95
95
|
getModel: () => session.model,
|
|
96
96
|
isIdle: () => !session.isStreaming,
|
|
97
|
+
getActivePromptHandle: () => session.activePromptHandle,
|
|
97
98
|
abort: () => session.abort(),
|
|
99
|
+
abortPromptAndWait: (handle, abortOptions) => session.abortPromptAndWait(handle, abortOptions),
|
|
98
100
|
hasPendingMessages: () => session.queuedMessageCount > 0,
|
|
99
101
|
getPendingMessageCounts: () => session.pendingMessageCounts,
|
|
100
102
|
getTranscript: () => session.getTranscript(),
|
|
@@ -132,7 +134,7 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
132
134
|
}
|
|
133
135
|
return false;
|
|
134
136
|
},
|
|
135
|
-
invokeSkill: (name, args) => session.invokeSkill(name, args),
|
|
137
|
+
invokeSkill: (name, args, options) => session.invokeSkill(name, args, options),
|
|
136
138
|
setPlanMode: on => session.setSdkPlanMode(on),
|
|
137
139
|
operateGoal: (op, objective) => session.operateGoal(op, objective),
|
|
138
140
|
getSkillState: () => session.skills.map(skill => ({ name: skill.name, description: skill.description })),
|
|
@@ -168,6 +170,7 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
168
170
|
},
|
|
169
171
|
getJobs: () => session.getAsyncJobSnapshot(),
|
|
170
172
|
setSdkPermissionProvider: provider => session.setSdkPermissionProvider(provider),
|
|
173
|
+
setSdkClientBridge: bridge => session.setClientBridge(bridge),
|
|
171
174
|
sdkControl: async (operation, input) => {
|
|
172
175
|
switch (operation) {
|
|
173
176
|
case "model.set": {
|
|
@@ -380,7 +383,24 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
380
383
|
const disabled = [...(session.settings.get("disabledExtensions") ?? [])];
|
|
381
384
|
const on = input.on === true;
|
|
382
385
|
const next = on ? disabled.filter(value => value !== id) : [...new Set([...disabled, id])];
|
|
383
|
-
session.settings.
|
|
386
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
387
|
+
throw Object.assign(
|
|
388
|
+
new Error(
|
|
389
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
390
|
+
),
|
|
391
|
+
{ code: "invalid_request" },
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
try {
|
|
395
|
+
session.settings.set("disabledExtensions", next);
|
|
396
|
+
} catch (error) {
|
|
397
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
398
|
+
throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), {
|
|
399
|
+
code: "invalid_request",
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
throw error;
|
|
403
|
+
}
|
|
384
404
|
return { changed: true, enabled: on };
|
|
385
405
|
}
|
|
386
406
|
case "session.delete":
|
package/src/modes/types.ts
CHANGED
|
@@ -248,6 +248,8 @@ export interface InteractiveModeContext {
|
|
|
248
248
|
getAssistantViewportAnchorId?(message: AssistantMessage): string;
|
|
249
249
|
findLastAssistantMessage(): AssistantMessage | undefined;
|
|
250
250
|
extractAssistantText(message: AssistantMessage): string;
|
|
251
|
+
/** Records one semantic visible-transcript mutation for the sticky viewport. */
|
|
252
|
+
recordVisibleTranscriptMutation?(): void;
|
|
251
253
|
updateEditorTopBorder(): void;
|
|
252
254
|
updateEditorBorderColor(): void;
|
|
253
255
|
rebuildChatFromMessages(policy: TranscriptRebuildPolicy): void;
|