@sayknow-cli/coding-agent 0.3.1 → 0.3.4
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/bin/skc.js +4 -0
- package/dist/types/cli/mcp-cli.d.ts +25 -0
- package/dist/types/cli/plugin-cli.d.ts +2 -0
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/commands/mcp.d.ts +70 -0
- package/dist/types/commands/plugin.d.ts +6 -0
- package/dist/types/commands/session.d.ts +6 -0
- package/dist/types/config/keybindings.d.ts +2 -2
- package/dist/types/config/model-profile-activation.d.ts +8 -1
- package/dist/types/config/model-profiles.d.ts +2 -2
- package/dist/types/config/model-registry.d.ts +3 -3
- package/dist/types/config/models-config-schema.d.ts +0 -5
- package/dist/types/config/settings-schema.d.ts +79 -68
- package/dist/types/deep-interview/plaintext-gate-guard.d.ts +11 -0
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/extensibility/skc-plugins/compiler.d.ts +19 -0
- package/dist/types/extensibility/skc-plugins/constrained-hooks.d.ts +29 -0
- package/dist/types/extensibility/skc-plugins/index.d.ts +9 -0
- package/dist/types/extensibility/skc-plugins/injection.d.ts +9 -0
- package/dist/types/extensibility/skc-plugins/installer.d.ts +13 -0
- package/dist/types/extensibility/skc-plugins/mcp-policy.d.ts +26 -0
- package/dist/types/extensibility/skc-plugins/observability.d.ts +27 -0
- package/dist/types/extensibility/skc-plugins/prompt-appendix.d.ts +16 -0
- package/dist/types/extensibility/skc-plugins/registry.d.ts +32 -0
- package/dist/types/extensibility/skc-plugins/runtime-adapters.d.ts +64 -0
- package/dist/types/extensibility/skc-plugins/session-validation.d.ts +42 -0
- package/dist/types/extensibility/skc-plugins/types.d.ts +158 -2
- package/dist/types/extensibility/skc-plugins/validation.d.ts +8 -1
- package/dist/types/i18n/messages/en.d.ts +0 -1
- package/dist/types/main.d.ts +2 -0
- package/dist/types/modes/components/custom-editor.d.ts +1 -1
- package/dist/types/modes/components/model-selector.d.ts +8 -0
- package/dist/types/modes/components/settings-defs.d.ts +0 -1
- package/dist/types/modes/components/status-line/git-utils.d.ts +6 -0
- package/dist/types/modes/theme/defaults/index.d.ts +99 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/notifications/html-format.d.ts +11 -0
- package/dist/types/notifications/index.d.ts +149 -1
- package/dist/types/notifications/lifecycle-commands.d.ts +60 -0
- package/dist/types/notifications/lifecycle-control-runtime.d.ts +98 -0
- package/dist/types/notifications/lifecycle-orchestrator.d.ts +144 -0
- package/dist/types/notifications/operator-runtime.d.ts +52 -0
- package/dist/types/notifications/rate-limit-pool.d.ts +2 -0
- package/dist/types/notifications/recent-activity.d.ts +35 -0
- package/dist/types/notifications/telegram-daemon.d.ts +114 -16
- package/dist/types/notifications/telegram-reference.d.ts +3 -1
- package/dist/types/notifications/topic-registry.d.ts +12 -9
- package/dist/types/runtime-mcp/types.d.ts +7 -0
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/session/agent-session.d.ts +14 -4
- package/dist/types/session/blob-store.d.ts +25 -0
- package/dist/types/session/session-manager.d.ts +57 -0
- package/dist/types/skc-runtime/launch-tmux.d.ts +1 -0
- package/dist/types/skc-runtime/psmux-detect.d.ts +78 -0
- package/dist/types/skc-runtime/state-renderer.d.ts +5 -0
- package/dist/types/skc-runtime/team-runtime.d.ts +2 -0
- package/dist/types/skc-runtime/tmux-common.d.ts +30 -2
- package/dist/types/skc-runtime/tmux-sessions.d.ts +18 -0
- package/dist/types/skc-runtime/ultragoal-guard.d.ts +37 -1
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +80 -0
- package/dist/types/slash-commands/helpers/fast-status-report.d.ts +6 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +9 -1
- package/dist/types/tools/browser/tab-supervisor.d.ts +31 -0
- package/dist/types/tools/composer-bash-policy.d.ts +14 -0
- package/dist/types/tools/computer-gc.d.ts +23 -0
- package/dist/types/tools/cron.d.ts +36 -61
- package/dist/types/tools/index.d.ts +3 -2
- package/dist/types/tools/resource-gc.d.ts +54 -0
- package/dist/types/utils/changelog.d.ts +1 -0
- package/dist/types/web/insane/url-guard.d.ts +6 -3
- package/dist/types/web/scrapers/types.d.ts +5 -0
- package/dist/types/web/scrapers/utils.d.ts +7 -1
- package/dist/types/web/search/index.d.ts +1 -0
- package/dist/types/web/search/providers/utils.d.ts +11 -4
- package/package.json +11 -9
- package/scripts/g004-tmux-smoke.ts +100 -0
- package/scripts/g005-daemon-smoke.ts +180 -0
- package/scripts/g011-daemon-path-smoke.ts +153 -0
- package/src/cli/args.ts +0 -1
- package/src/cli/fast-help.ts +29 -2
- package/src/cli/mcp-cli.ts +272 -0
- package/src/cli/plugin-cli.ts +66 -3
- package/src/cli/web-search-cli.ts +5 -0
- package/src/cli.ts +30 -12
- package/src/commands/mcp.ts +117 -0
- package/src/commands/plugin.ts +4 -0
- package/src/commands/session.ts +18 -0
- package/src/config/keybindings.ts +2 -2
- package/src/config/model-profile-activation.ts +62 -8
- package/src/config/model-profiles.ts +3 -4
- package/src/config/model-registry.ts +3 -6
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +88 -103
- package/src/deep-interview/plaintext-gate-guard.ts +94 -0
- package/src/defaults/skc/extensions/grok-cli-vendor/biome.json +1 -1
- package/src/defaults/skc/skills/deep-interview/SKILL.md +7 -6
- package/src/defaults/skc/skills/team/SKILL.md +5 -3
- package/src/defaults/skc/skills/ultragoal/SKILL.md +41 -13
- package/src/export/html/index.ts +2 -2
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +0 -12
- package/src/extensibility/extensions/runner.ts +1 -0
- package/src/extensibility/skc-plugins/compiler.ts +351 -0
- package/src/extensibility/skc-plugins/constrained-hooks.ts +170 -0
- package/src/extensibility/skc-plugins/index.ts +9 -0
- package/src/extensibility/skc-plugins/injection.ts +109 -0
- package/src/extensibility/skc-plugins/installer.ts +434 -0
- package/src/extensibility/skc-plugins/loader.ts +3 -1
- package/src/extensibility/skc-plugins/mcp-policy.ts +239 -0
- package/src/extensibility/skc-plugins/observability.ts +84 -0
- package/src/extensibility/skc-plugins/paths.ts +1 -1
- package/src/extensibility/skc-plugins/prompt-appendix.ts +109 -0
- package/src/extensibility/skc-plugins/registry.ts +180 -0
- package/src/extensibility/skc-plugins/runtime-adapters.ts +234 -0
- package/src/extensibility/skc-plugins/schema.ts +250 -20
- package/src/extensibility/skc-plugins/session-validation.ts +147 -0
- package/src/extensibility/skc-plugins/types.ts +199 -3
- package/src/extensibility/skc-plugins/validation.ts +80 -0
- package/src/extensibility/skills.ts +15 -0
- package/src/goals/tools/goal-tool.ts +14 -1
- package/src/hooks/skill-state.ts +57 -0
- package/src/i18n/messages/de.ts +0 -1
- package/src/i18n/messages/en.ts +0 -1
- package/src/i18n/messages/es.ts +0 -1
- package/src/i18n/messages/fr.ts +0 -1
- package/src/i18n/messages/ja.ts +0 -1
- package/src/i18n/messages/ko.ts +0 -1
- package/src/i18n/messages/zh.ts +0 -1
- package/src/internal-urls/docs-index.generated.ts +14 -11
- package/src/main.ts +14 -3
- package/src/modes/bridge/bridge-mode.ts +11 -0
- package/src/modes/components/assistant-message.ts +49 -1
- package/src/modes/components/custom-editor.ts +2 -0
- package/src/modes/components/footer.ts +2 -3
- package/src/modes/components/hook-editor.ts +1 -1
- package/src/modes/components/hook-selector.ts +67 -43
- package/src/modes/components/model-selector.ts +65 -12
- package/src/modes/components/settings-defs.ts +1 -2
- package/src/modes/components/settings-selector.ts +2 -7
- package/src/modes/components/status-line/git-utils.ts +25 -0
- package/src/modes/components/status-line.ts +10 -11
- package/src/modes/components/welcome.ts +2 -3
- package/src/modes/controllers/extension-ui-controller.ts +0 -27
- package/src/modes/controllers/selector-controller.ts +59 -11
- package/src/modes/interactive-mode.ts +4 -1
- package/src/modes/shared/agent-wire/scopes.ts +1 -1
- package/src/modes/theme/defaults/gruvbox-dark.json +99 -0
- package/src/modes/theme/defaults/index.ts +2 -0
- package/src/modes/theme/theme.ts +0 -4
- package/src/modes/utils/hotkeys-markdown.ts +1 -1
- package/src/notifications/html-format.ts +38 -0
- package/src/notifications/index.ts +242 -12
- package/src/notifications/lifecycle-commands.ts +238 -0
- package/src/notifications/lifecycle-control-runtime.ts +405 -0
- package/src/notifications/lifecycle-orchestrator.ts +358 -0
- package/src/notifications/operator-runtime.ts +171 -0
- package/src/notifications/rate-limit-pool.ts +19 -0
- package/src/notifications/recent-activity.ts +132 -0
- package/src/notifications/telegram-daemon.ts +778 -257
- package/src/notifications/telegram-reference.ts +25 -7
- package/src/notifications/topic-registry.ts +23 -9
- package/src/prompts/agents/executor.md +2 -2
- package/src/prompts/system/system-prompt.md +2 -2
- package/src/prompts/tools/cron.md +5 -3
- package/src/prompts/tools/read.md +1 -1
- package/src/runtime-mcp/transports/stdio.ts +38 -4
- package/src/runtime-mcp/types.ts +7 -0
- package/src/sdk.ts +162 -10
- package/src/session/agent-session.ts +210 -74
- package/src/session/blob-store.ts +196 -8
- package/src/session/session-manager.ts +762 -12
- package/src/skc-runtime/launch-tmux.ts +68 -19
- package/src/skc-runtime/psmux-detect.ts +239 -0
- package/src/skc-runtime/state-renderer.ts +13 -0
- package/src/skc-runtime/team-runtime.ts +56 -23
- package/src/skc-runtime/tmux-common.ts +88 -4
- package/src/skc-runtime/tmux-sessions.ts +111 -9
- package/src/skc-runtime/ultragoal-guard.ts +192 -8
- package/src/skc-runtime/ultragoal-runtime.ts +296 -16
- package/src/slash-commands/builtin-registry.ts +23 -3
- package/src/slash-commands/helpers/fast-status-report.ts +13 -3
- package/src/slash-commands/helpers/parse.ts +2 -1
- package/src/system-prompt.ts +9 -0
- package/src/task/executor.ts +31 -7
- package/src/task/index.ts +2 -0
- package/src/tools/ask.ts +5 -1
- package/src/tools/bash.ts +9 -0
- package/src/tools/browser/tab-supervisor.ts +86 -2
- package/src/tools/composer-bash-policy.ts +96 -0
- package/src/tools/computer-gc.ts +66 -0
- package/src/tools/computer.ts +2 -0
- package/src/tools/cron.ts +75 -112
- package/src/tools/fetch.ts +18 -2
- package/src/tools/index.ts +5 -9
- package/src/tools/read.ts +25 -55
- package/src/tools/renderers.ts +0 -2
- package/src/tools/resource-gc.ts +291 -0
- package/src/tools/ultragoal-ask-guard.ts +7 -1
- package/src/utils/changelog.ts +8 -0
- package/src/web/insane/url-guard.ts +18 -14
- package/src/web/scrapers/types.ts +143 -45
- package/src/web/scrapers/utils.ts +70 -19
- package/src/web/search/index.ts +1 -0
- package/src/web/search/providers/utils.ts +22 -5
- package/vendor/insane-search/MANIFEST.json +3 -1
- package/vendor/insane-search/engine/__init__.py +14 -0
- package/vendor/insane-search/engine/content_safety.py +151 -0
- package/vendor/insane-search/engine/fetch_chain.py +32 -0
- package/vendor/insane-search/engine/tests/test_u8.py +216 -0
- package/dist/types/tools/inspect-image-renderer.d.ts +0 -26
- package/dist/types/tools/inspect-image.d.ts +0 -31
- package/src/prompts/tools/inspect-image-system.md +0 -20
- package/src/prompts/tools/inspect-image.md +0 -32
- package/src/tools/inspect-image-renderer.ts +0 -103
- package/src/tools/inspect-image.ts +0 -172
|
@@ -26,8 +26,6 @@ import type { InteractiveModeContext } from "../../modes/types";
|
|
|
26
26
|
import { setSessionTerminalTitle, setTerminalTitle } from "../../utils/title-generator";
|
|
27
27
|
|
|
28
28
|
const MAX_WIDGET_LINES = 10;
|
|
29
|
-
const HOOK_SELECTOR_MOUSE_REPORTING_ENABLE = "\x1b[?1006h\x1b[?1000h";
|
|
30
|
-
const HOOK_SELECTOR_MOUSE_REPORTING_DISABLE = "\x1b[?1000l\x1b[?1006l";
|
|
31
29
|
const HOOK_SELECTOR_CHROME_ROWS = 7;
|
|
32
30
|
const HOOK_SELECTOR_OUTLINE_ROWS = 2;
|
|
33
31
|
const HOOK_SELECTOR_INLINE_INPUT_ROWS = 2;
|
|
@@ -36,7 +34,6 @@ export class ExtensionUiController {
|
|
|
36
34
|
#extensionTerminalInputUnsubscribers = new Set<() => void>();
|
|
37
35
|
#hookWidgetsAbove = new Map<string, ExtensionUiComponent>();
|
|
38
36
|
#hookWidgetsBelow = new Map<string, ExtensionUiComponent>();
|
|
39
|
-
#hookSelectorMouseReportingEnabled = false;
|
|
40
37
|
#activeHookCustomComponent?: Component & { dispose?(): void };
|
|
41
38
|
#activeHookCustomOverlay?: OverlayHandle;
|
|
42
39
|
|
|
@@ -625,9 +622,6 @@ export class ExtensionUiController {
|
|
|
625
622
|
this.ctx.ui.terminal.rows - scrollOptionRows - listChromeRows - inlineInputRows - HOOK_SELECTOR_CHROME_ROWS;
|
|
626
623
|
const scrollTitleRows =
|
|
627
624
|
requestedTitleRows === undefined ? undefined : Math.max(1, Math.min(requestedTitleRows, availableTitleRows));
|
|
628
|
-
if (scrollTitleRows !== undefined) {
|
|
629
|
-
this.#enableHookSelectorMouseReporting();
|
|
630
|
-
}
|
|
631
625
|
|
|
632
626
|
this.ctx.hookSelector = new HookSelectorComponent(
|
|
633
627
|
title,
|
|
@@ -692,31 +686,10 @@ export class ExtensionUiController {
|
|
|
692
686
|
return promise;
|
|
693
687
|
}
|
|
694
688
|
|
|
695
|
-
#enableHookSelectorMouseReporting(): void {
|
|
696
|
-
if (this.#hookSelectorMouseReportingEnabled) return;
|
|
697
|
-
this.#hookSelectorMouseReportingEnabled = true;
|
|
698
|
-
this.#writeTerminalControl(HOOK_SELECTOR_MOUSE_REPORTING_ENABLE);
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
#disableHookSelectorMouseReporting(): void {
|
|
702
|
-
if (!this.#hookSelectorMouseReportingEnabled) return;
|
|
703
|
-
this.#hookSelectorMouseReportingEnabled = false;
|
|
704
|
-
this.#writeTerminalControl(HOOK_SELECTOR_MOUSE_REPORTING_DISABLE);
|
|
705
|
-
}
|
|
706
|
-
|
|
707
|
-
#writeTerminalControl(sequence: string): void {
|
|
708
|
-
try {
|
|
709
|
-
this.ctx.ui.terminal.write(sequence);
|
|
710
|
-
} catch {
|
|
711
|
-
// Terminal teardown can race selector cleanup; normal shutdown restores modes.
|
|
712
|
-
}
|
|
713
|
-
}
|
|
714
|
-
|
|
715
689
|
/**
|
|
716
690
|
* Hide the hook selector.
|
|
717
691
|
*/
|
|
718
692
|
hideHookSelector(): void {
|
|
719
|
-
this.#disableHookSelectorMouseReporting();
|
|
720
693
|
this.ctx.hookSelector?.dispose();
|
|
721
694
|
this.ctx.editorContainer.clear();
|
|
722
695
|
this.ctx.editorContainer.addChild(this.ctx.editor);
|
|
@@ -4,8 +4,10 @@ import type { OAuthProvider } from "@sayknow-cli/ai/utils/oauth/types";
|
|
|
4
4
|
import type { Component, OverlayHandle } from "@sayknow-cli/tui";
|
|
5
5
|
import { Input, Loader, Spacer, Text } from "@sayknow-cli/tui";
|
|
6
6
|
import { getAgentDbPath, getProjectDir } from "@sayknow-cli/utils";
|
|
7
|
-
import { activateModelProfile } from "../../config/model-profile-activation";
|
|
7
|
+
import { activateModelProfile, materializeActiveModelProfileAssignment } from "../../config/model-profile-activation";
|
|
8
8
|
import { recommendModelProfileForProvider } from "../../config/model-profiles";
|
|
9
|
+
import { SKC_MODEL_ASSIGNMENT_TARGETS } from "../../config/model-registry";
|
|
10
|
+
import { formatModelSelectorValue } from "../../config/model-resolver";
|
|
9
11
|
import { settings } from "../../config/settings";
|
|
10
12
|
import { DebugSelectorComponent } from "../../debug";
|
|
11
13
|
import { disableProvider, enableProvider } from "../../discovery";
|
|
@@ -49,6 +51,7 @@ import {
|
|
|
49
51
|
setPreferredImageProvider,
|
|
50
52
|
setPreferredSearchProvider,
|
|
51
53
|
setSearchFallbackProviders,
|
|
54
|
+
setSearchHardTimeoutMs,
|
|
52
55
|
} from "../../tools";
|
|
53
56
|
import { setSessionTerminalTitle } from "../../utils/title-generator";
|
|
54
57
|
import { AgentDashboard } from "../components/agent-dashboard";
|
|
@@ -643,6 +646,11 @@ export class SelectorController {
|
|
|
643
646
|
);
|
|
644
647
|
}
|
|
645
648
|
break;
|
|
649
|
+
case "web_search.timeout":
|
|
650
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0) {
|
|
651
|
+
setSearchHardTimeoutMs(value * 1000);
|
|
652
|
+
}
|
|
653
|
+
break;
|
|
646
654
|
case "providers.image":
|
|
647
655
|
if (
|
|
648
656
|
value === "auto" ||
|
|
@@ -667,7 +675,8 @@ export class SelectorController {
|
|
|
667
675
|
|
|
668
676
|
showModelSelector(options?: { temporaryOnly?: boolean }): void {
|
|
669
677
|
this.showSelector(done => {
|
|
670
|
-
|
|
678
|
+
let modelSelector: ModelSelectorComponent;
|
|
679
|
+
modelSelector = new ModelSelectorComponent(
|
|
671
680
|
this.ctx.ui,
|
|
672
681
|
this.ctx.session.model,
|
|
673
682
|
this.ctx.settings,
|
|
@@ -717,38 +726,73 @@ export class SelectorController {
|
|
|
717
726
|
this.ctx.ui.requestRender();
|
|
718
727
|
return;
|
|
719
728
|
}
|
|
720
|
-
const { model, role, thinkingLevel, selector } = selection;
|
|
729
|
+
const { model, role, thinkingLevel, selector: selectedSelector } = selection;
|
|
721
730
|
if (role === null) {
|
|
722
731
|
// Temporary: update agent state but don't persist to settings
|
|
723
732
|
await this.ctx.session.setModelTemporary(model, thinkingLevel);
|
|
724
733
|
this.ctx.statusLine.invalidate();
|
|
725
734
|
this.ctx.updateEditorBorderColor();
|
|
726
|
-
this.ctx.showStatus(`Temporary model: ${
|
|
735
|
+
this.ctx.showStatus(`Temporary model: ${selectedSelector ?? model.id}`);
|
|
727
736
|
done();
|
|
728
737
|
this.ctx.ui.requestRender();
|
|
729
738
|
} else if (role === "default") {
|
|
730
739
|
// Default: update agent state and persist as the active default model.
|
|
731
740
|
await this.ctx.session.setModel(model, role, {
|
|
732
|
-
selector,
|
|
741
|
+
selector: selectedSelector,
|
|
742
|
+
thinkingLevel,
|
|
743
|
+
});
|
|
744
|
+
const value = formatModelSelectorValue(
|
|
745
|
+
selectedSelector ?? `${model.provider}/${model.id}`,
|
|
733
746
|
thinkingLevel,
|
|
747
|
+
);
|
|
748
|
+
materializeActiveModelProfileAssignment({
|
|
749
|
+
session: this.ctx.session,
|
|
750
|
+
settings: this.ctx.settings,
|
|
751
|
+
role,
|
|
752
|
+
selector: value,
|
|
734
753
|
});
|
|
735
754
|
if (thinkingLevel && thinkingLevel !== ThinkingLevel.Inherit) {
|
|
736
755
|
this.ctx.session.setThinkingLevel(thinkingLevel);
|
|
737
756
|
}
|
|
757
|
+
modelSelector.refreshRoleAssignments({
|
|
758
|
+
currentModel: this.ctx.session.model,
|
|
759
|
+
currentThinkingLevel: this.ctx.session.thinkingLevel,
|
|
760
|
+
activeModelProfile:
|
|
761
|
+
this.ctx.session.getActiveModelProfile?.() ?? this.ctx.settings.get("modelProfile.default"),
|
|
762
|
+
});
|
|
738
763
|
this.ctx.statusLine.invalidate();
|
|
739
764
|
this.ctx.updateEditorBorderColor();
|
|
740
|
-
this.ctx.showStatus(`Default model: ${
|
|
765
|
+
this.ctx.showStatus(`Default model: ${selectedSelector ?? model.id}`);
|
|
741
766
|
done();
|
|
742
767
|
this.ctx.ui.requestRender();
|
|
743
768
|
} else {
|
|
744
|
-
// Role-agent assignments configure Task dispatch and must not switch the active chat model.
|
|
745
769
|
const apiKey = await this.ctx.session.modelRegistry.getApiKey(model, this.ctx.session.sessionId);
|
|
746
770
|
if (!apiKey) {
|
|
747
771
|
throw new Error(`No API key for ${model.provider}/${model.id}`);
|
|
748
772
|
}
|
|
749
|
-
const
|
|
750
|
-
|
|
751
|
-
|
|
773
|
+
const value =
|
|
774
|
+
selectedSelector ?? formatModelSelectorValue(`${model.provider}/${model.id}`, thinkingLevel);
|
|
775
|
+
const materializedProfile = materializeActiveModelProfileAssignment({
|
|
776
|
+
session: this.ctx.session,
|
|
777
|
+
settings: this.ctx.settings,
|
|
778
|
+
role,
|
|
779
|
+
selector: value,
|
|
780
|
+
});
|
|
781
|
+
if (!materializedProfile) {
|
|
782
|
+
const target = SKC_MODEL_ASSIGNMENT_TARGETS[role];
|
|
783
|
+
if (target.settingsPath === "modelRoles") {
|
|
784
|
+
this.ctx.settings.setModelRole(role, value);
|
|
785
|
+
} else {
|
|
786
|
+
const overrides = this.ctx.settings.get("task.agentModelOverrides");
|
|
787
|
+
this.ctx.settings.set("task.agentModelOverrides", { ...overrides, [role]: value });
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
modelSelector.refreshRoleAssignments({
|
|
791
|
+
currentModel: this.ctx.session.model,
|
|
792
|
+
currentThinkingLevel: this.ctx.session.thinkingLevel,
|
|
793
|
+
activeModelProfile:
|
|
794
|
+
this.ctx.session.getActiveModelProfile?.() ?? this.ctx.settings.get("modelProfile.default"),
|
|
795
|
+
});
|
|
752
796
|
this.ctx.settings.getStorage()?.recordModelUsage(`${model.provider}/${model.id}`);
|
|
753
797
|
this.ctx.showStatus(`${role} agent model: ${value}`);
|
|
754
798
|
done();
|
|
@@ -765,11 +809,15 @@ export class SelectorController {
|
|
|
765
809
|
{
|
|
766
810
|
...options,
|
|
767
811
|
sessionId: this.ctx.session.sessionId,
|
|
812
|
+
currentThinkingLevel: this.ctx.session.thinkingLevel,
|
|
813
|
+
activeModelProfile:
|
|
814
|
+
this.ctx.session.getActiveModelProfile?.() ?? this.ctx.settings.get("modelProfile.default"),
|
|
768
815
|
isFastForProvider: provider => this.ctx.session.isFastForProvider(provider),
|
|
769
816
|
isFastForSubagentProvider: provider => this.ctx.session.isFastForSubagentProvider(provider),
|
|
817
|
+
isCurrentModelFastModeActive: () => this.ctx.session.isFastModeActive(),
|
|
770
818
|
},
|
|
771
819
|
);
|
|
772
|
-
return { component:
|
|
820
|
+
return { component: modelSelector, focus: modelSelector };
|
|
773
821
|
});
|
|
774
822
|
}
|
|
775
823
|
|
|
@@ -156,7 +156,7 @@ function getShellInputPrefix(isNoContext: boolean): string {
|
|
|
156
156
|
|
|
157
157
|
function configureDefaultComposerChrome(editor: CustomEditor): void {
|
|
158
158
|
editor.setBorderVisible(true);
|
|
159
|
-
editor.setBorderStyle("
|
|
159
|
+
editor.setBorderStyle("round");
|
|
160
160
|
editor.setClosedBorderBox(true);
|
|
161
161
|
editor.setPromptGutter(undefined);
|
|
162
162
|
editor.setInputPrefix(getDefaultInputPrefix());
|
|
@@ -432,6 +432,8 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
432
432
|
this.#resizeHandler = () => {
|
|
433
433
|
this.#syncEditorMaxHeight();
|
|
434
434
|
this.updateEditorChrome();
|
|
435
|
+
this.editor.invalidate();
|
|
436
|
+
this.ui.requestRender(true, "resize");
|
|
435
437
|
};
|
|
436
438
|
process.stdout.on("resize", this.#resizeHandler);
|
|
437
439
|
try {
|
|
@@ -569,6 +571,7 @@ export class InteractiveMode implements InteractiveModeContext {
|
|
|
569
571
|
this.ui.addChild(this.hookWidgetContainerAbove);
|
|
570
572
|
this.ui.addChild(this.editorContainer);
|
|
571
573
|
this.ui.addChild(this.hookWidgetContainerBelow);
|
|
574
|
+
this.ui.setBottomPinnedComponent(this.statusLine);
|
|
572
575
|
this.ui.setFocus(this.editor);
|
|
573
576
|
|
|
574
577
|
this.#inputController.setupKeyHandlers();
|
|
@@ -73,7 +73,7 @@ const RPC_COMMAND_SCOPE_REGISTRY: Record<RpcCommandType, BridgeCommandScope> = {
|
|
|
73
73
|
get_login_providers: "admin",
|
|
74
74
|
login: "admin",
|
|
75
75
|
negotiate_unattended: "control",
|
|
76
|
-
workflow_gate_response: "
|
|
76
|
+
workflow_gate_response: "control",
|
|
77
77
|
};
|
|
78
78
|
|
|
79
79
|
export const RPC_COMMAND_TYPES: readonly RpcCommandType[] = Object.keys(RPC_COMMAND_SCOPE_REGISTRY) as RpcCommandType[];
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/jaybeyond/Sayknow_CLI/main/packages/coding-agent/theme-schema.json",
|
|
3
|
+
"name": "gruvbox-dark",
|
|
4
|
+
"vars": {
|
|
5
|
+
"bgHard": "#1d2021",
|
|
6
|
+
"surface": "#32302f",
|
|
7
|
+
"surfaceBright": "#504945",
|
|
8
|
+
"borderNeutral": "#504945",
|
|
9
|
+
"borderSubtle": "#3c3836",
|
|
10
|
+
"fg": "#ebdbb2",
|
|
11
|
+
"muted": "#a89984",
|
|
12
|
+
"dim": "#7c6f64",
|
|
13
|
+
"gray": "#928374",
|
|
14
|
+
"red": "#fb4934",
|
|
15
|
+
"green": "#b8bb26",
|
|
16
|
+
"yellow": "#fabd2f",
|
|
17
|
+
"blue": "#83a598",
|
|
18
|
+
"purple": "#d3869b",
|
|
19
|
+
"aqua": "#8ec07c",
|
|
20
|
+
"orange": "#fe8019",
|
|
21
|
+
"diffRemovalRed": "#cc241d"
|
|
22
|
+
},
|
|
23
|
+
"colors": {
|
|
24
|
+
"accent": "orange",
|
|
25
|
+
"border": "borderNeutral",
|
|
26
|
+
"borderAccent": "orange",
|
|
27
|
+
"borderMuted": "borderSubtle",
|
|
28
|
+
"success": "green",
|
|
29
|
+
"error": "red",
|
|
30
|
+
"warning": "yellow",
|
|
31
|
+
"muted": "muted",
|
|
32
|
+
"dim": "dim",
|
|
33
|
+
"text": "fg",
|
|
34
|
+
"thinkingText": "muted",
|
|
35
|
+
"selectedBg": "surfaceBright",
|
|
36
|
+
"userMessageBg": "surface",
|
|
37
|
+
"userMessageText": "fg",
|
|
38
|
+
"customMessageBg": "surface",
|
|
39
|
+
"customMessageText": "fg",
|
|
40
|
+
"customMessageLabel": "orange",
|
|
41
|
+
"toolPendingBg": "surface",
|
|
42
|
+
"toolSuccessBg": "#283626",
|
|
43
|
+
"toolErrorBg": "#3c2323",
|
|
44
|
+
"toolTitle": "fg",
|
|
45
|
+
"toolOutput": "muted",
|
|
46
|
+
"mdHeading": "yellow",
|
|
47
|
+
"mdLink": "blue",
|
|
48
|
+
"mdLinkUrl": "muted",
|
|
49
|
+
"mdCode": "aqua",
|
|
50
|
+
"mdCodeBlock": "fg",
|
|
51
|
+
"mdCodeBlockBorder": "borderNeutral",
|
|
52
|
+
"mdQuote": "muted",
|
|
53
|
+
"mdQuoteBorder": "borderNeutral",
|
|
54
|
+
"mdHr": "dim",
|
|
55
|
+
"mdListBullet": "orange",
|
|
56
|
+
"toolDiffAdded": "green",
|
|
57
|
+
"toolDiffRemoved": "diffRemovalRed",
|
|
58
|
+
"toolDiffContext": "muted",
|
|
59
|
+
"syntaxComment": "gray",
|
|
60
|
+
"syntaxKeyword": "red",
|
|
61
|
+
"syntaxFunction": "green",
|
|
62
|
+
"syntaxVariable": "blue",
|
|
63
|
+
"syntaxString": "green",
|
|
64
|
+
"syntaxNumber": "purple",
|
|
65
|
+
"syntaxType": "yellow",
|
|
66
|
+
"syntaxOperator": "aqua",
|
|
67
|
+
"syntaxPunctuation": "muted",
|
|
68
|
+
"thinkingOff": "dim",
|
|
69
|
+
"thinkingMinimal": "muted",
|
|
70
|
+
"thinkingLow": "aqua",
|
|
71
|
+
"thinkingMedium": "yellow",
|
|
72
|
+
"thinkingHigh": "orange",
|
|
73
|
+
"thinkingXhigh": "red",
|
|
74
|
+
"bashMode": "green",
|
|
75
|
+
"pythonMode": "yellow",
|
|
76
|
+
"statusLineBg": "bgHard",
|
|
77
|
+
"statusLineSep": "dim",
|
|
78
|
+
"statusLineModel": "orange",
|
|
79
|
+
"statusLinePath": "blue",
|
|
80
|
+
"statusLineGitClean": "green",
|
|
81
|
+
"statusLineGitDirty": "yellow",
|
|
82
|
+
"statusLineContext": "aqua",
|
|
83
|
+
"statusLineSpend": "yellow",
|
|
84
|
+
"statusLineStaged": "green",
|
|
85
|
+
"statusLineDirty": "yellow",
|
|
86
|
+
"statusLineUntracked": "diffRemovalRed",
|
|
87
|
+
"statusLineOutput": "fg",
|
|
88
|
+
"statusLineCost": "orange",
|
|
89
|
+
"statusLineSubagents": "purple"
|
|
90
|
+
},
|
|
91
|
+
"export": {
|
|
92
|
+
"pageBg": "#1d2021",
|
|
93
|
+
"cardBg": "#282828",
|
|
94
|
+
"infoBg": "#32302f"
|
|
95
|
+
},
|
|
96
|
+
"symbols": {
|
|
97
|
+
"preset": "unicode"
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import blue_octopus from "./blue-octopus.json" with { type: "json" };
|
|
2
2
|
import claude_code from "./claude-code.json" with { type: "json" };
|
|
3
3
|
import codex from "./codex.json" with { type: "json" };
|
|
4
|
+
import gruvbox_dark from "./gruvbox-dark.json" with { type: "json" };
|
|
4
5
|
import opencode from "./opencode.json" with { type: "json" };
|
|
5
6
|
import red_octopus from "./red-octopus.json" with { type: "json" };
|
|
6
7
|
|
|
@@ -8,6 +9,7 @@ export const defaultThemes = {
|
|
|
8
9
|
"blue-octopus": blue_octopus,
|
|
9
10
|
"claude-code": claude_code,
|
|
10
11
|
codex,
|
|
12
|
+
"gruvbox-dark": gruvbox_dark,
|
|
11
13
|
opencode,
|
|
12
14
|
"red-octopus": red_octopus,
|
|
13
15
|
};
|
package/src/modes/theme/theme.ts
CHANGED
|
@@ -183,7 +183,6 @@ export type SymbolKey =
|
|
|
183
183
|
| "tab.appearance"
|
|
184
184
|
| "tab.model"
|
|
185
185
|
| "tab.interaction"
|
|
186
|
-
| "tab.notifications"
|
|
187
186
|
| "tab.context"
|
|
188
187
|
| "tab.editing"
|
|
189
188
|
| "tab.tools"
|
|
@@ -348,7 +347,6 @@ const UNICODE_SYMBOLS: SymbolMap = {
|
|
|
348
347
|
"tab.appearance": "🎨",
|
|
349
348
|
"tab.model": "🤖",
|
|
350
349
|
"tab.interaction": "⌨",
|
|
351
|
-
"tab.notifications": "🔔",
|
|
352
350
|
"tab.context": "📋",
|
|
353
351
|
"tab.editing": "💻",
|
|
354
352
|
"tab.tools": "🔧",
|
|
@@ -608,7 +606,6 @@ const NERD_SYMBOLS: SymbolMap = {
|
|
|
608
606
|
"tab.appearance": "",
|
|
609
607
|
"tab.model": "",
|
|
610
608
|
"tab.interaction": "",
|
|
611
|
-
"tab.notifications": "",
|
|
612
609
|
"tab.context": "",
|
|
613
610
|
"tab.editing": "",
|
|
614
611
|
"tab.tools": "",
|
|
@@ -771,7 +768,6 @@ const ASCII_SYMBOLS: SymbolMap = {
|
|
|
771
768
|
"tab.appearance": "[A]",
|
|
772
769
|
"tab.model": "[M]",
|
|
773
770
|
"tab.interaction": "[I]",
|
|
774
|
-
"tab.notifications": "[N]",
|
|
775
771
|
"tab.context": "[X]",
|
|
776
772
|
"tab.editing": "[E]",
|
|
777
773
|
"tab.tools": "[T]",
|
|
@@ -23,7 +23,7 @@ export function buildHotkeysMarkdown(bindings: HotkeysMarkdownBindings): string
|
|
|
23
23
|
"|-----|--------|",
|
|
24
24
|
"| `Enter` | Send / queue while busy |",
|
|
25
25
|
`| \`${appKey(bindings, "app.message.queue")}\` | Queue message for next turn |`,
|
|
26
|
-
"| `Shift+Enter` | New line |",
|
|
26
|
+
"| `Shift+Enter` / `Ctrl+J` | New line |",
|
|
27
27
|
"| `Ctrl+W` / `Option+Backspace` | Delete word backwards |",
|
|
28
28
|
"| `Ctrl+U` | Delete to start of line |",
|
|
29
29
|
"| `Ctrl+K` | Delete to end of line |",
|
|
@@ -349,16 +349,54 @@ export function buttonLabel(label: string, index: number): string {
|
|
|
349
349
|
return `${index + 1}. ${stripped}`;
|
|
350
350
|
}
|
|
351
351
|
|
|
352
|
+
/** Numbered, escaped option list for the Telegram message body. */
|
|
353
|
+
export function numberedOptionList(labels: string[]): string {
|
|
354
|
+
return labels.map((label, i) => `${i + 1}. ${escapeHtml(label.replace(/^\s*\d+[.)]\s+/, ""))}`).join("\n");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/** Compact numeric button label; full option text belongs in the message body. */
|
|
358
|
+
export function choiceButtonLabel(index: number): string {
|
|
359
|
+
return String(index + 1);
|
|
360
|
+
}
|
|
361
|
+
|
|
352
362
|
export interface InlineButton {
|
|
353
363
|
text: string;
|
|
354
364
|
callback_data: string;
|
|
355
365
|
}
|
|
356
366
|
|
|
367
|
+
const COMPACT_BUTTONS_PER_ROW = 5;
|
|
368
|
+
|
|
357
369
|
/** A prefixed button label is "long" when it is wide or contains a newline. */
|
|
358
370
|
function isLongLabel(label: string): boolean {
|
|
359
371
|
return label.length > 18 || /[\r\n]/.test(label);
|
|
360
372
|
}
|
|
361
373
|
|
|
374
|
+
/**
|
|
375
|
+
* Lay out option callbacks as compact numeric buttons. Telegram mobile clients
|
|
376
|
+
* ellipsize long inline-keyboard labels and tall keyboards can be obscured by
|
|
377
|
+
* the composer, so the full choice text is rendered in the message body while
|
|
378
|
+
* the keyboard keeps only stable one-based tap targets.
|
|
379
|
+
*/
|
|
380
|
+
export function buildCompactChoiceGrid(
|
|
381
|
+
labels: string[],
|
|
382
|
+
callbackForIndex: (index: number) => string,
|
|
383
|
+
): InlineButton[][] {
|
|
384
|
+
const rows: InlineButton[][] = [];
|
|
385
|
+
let run: InlineButton[] = [];
|
|
386
|
+
const flush = () => {
|
|
387
|
+
if (run.length) {
|
|
388
|
+
rows.push(run);
|
|
389
|
+
run = [];
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
labels.forEach((_label, i) => {
|
|
393
|
+
run.push({ text: choiceButtonLabel(i), callback_data: callbackForIndex(i) });
|
|
394
|
+
if (run.length === COMPACT_BUTTONS_PER_ROW) flush();
|
|
395
|
+
});
|
|
396
|
+
flush();
|
|
397
|
+
return rows;
|
|
398
|
+
}
|
|
399
|
+
|
|
362
400
|
/**
|
|
363
401
|
* Lay out option labels as a numbered button grid. Long buttons take a
|
|
364
402
|
* full-width row; runs of short buttons are packed into rows of up to 3. The
|