indusagi-coding-agent 0.1.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 +2249 -0
- package/README.md +546 -0
- package/dist/cli/args.js +282 -0
- package/dist/cli/config-selector.js +30 -0
- package/dist/cli/file-processor.js +78 -0
- package/dist/cli/list-models.js +91 -0
- package/dist/cli/session-picker.js +31 -0
- package/dist/cli.js +10 -0
- package/dist/config.js +158 -0
- package/dist/core/agent-session.js +2097 -0
- package/dist/core/auth-storage.js +278 -0
- package/dist/core/bash-executor.js +211 -0
- package/dist/core/compaction/branch-summarization.js +241 -0
- package/dist/core/compaction/compaction.js +606 -0
- package/dist/core/compaction/index.js +6 -0
- package/dist/core/compaction/utils.js +137 -0
- package/dist/core/diagnostics.js +1 -0
- package/dist/core/event-bus.js +24 -0
- package/dist/core/exec.js +70 -0
- package/dist/core/export-html/ansi-to-html.js +248 -0
- package/dist/core/export-html/index.js +221 -0
- package/dist/core/export-html/template.css +905 -0
- package/dist/core/export-html/template.html +54 -0
- package/dist/core/export-html/template.js +1549 -0
- package/dist/core/export-html/tool-renderer.js +56 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +6 -0
- package/dist/core/extensions/index.js +8 -0
- package/dist/core/extensions/loader.js +395 -0
- package/dist/core/extensions/runner.js +499 -0
- package/dist/core/extensions/types.js +31 -0
- package/dist/core/extensions/wrapper.js +101 -0
- package/dist/core/footer-data-provider.js +133 -0
- package/dist/core/index.js +8 -0
- package/dist/core/keybindings.js +140 -0
- package/dist/core/messages.js +122 -0
- package/dist/core/model-registry.js +454 -0
- package/dist/core/model-resolver.js +309 -0
- package/dist/core/package-manager.js +1142 -0
- package/dist/core/prompt-templates.js +250 -0
- package/dist/core/resource-loader.js +569 -0
- package/dist/core/sdk.js +225 -0
- package/dist/core/session-manager.js +1078 -0
- package/dist/core/settings-manager.js +430 -0
- package/dist/core/skills.js +339 -0
- package/dist/core/system-prompt.js +136 -0
- package/dist/core/timings.js +24 -0
- package/dist/core/tools/bash.js +226 -0
- package/dist/core/tools/edit-diff.js +242 -0
- package/dist/core/tools/edit.js +145 -0
- package/dist/core/tools/find.js +205 -0
- package/dist/core/tools/grep.js +238 -0
- package/dist/core/tools/index.js +60 -0
- package/dist/core/tools/ls.js +117 -0
- package/dist/core/tools/path-utils.js +52 -0
- package/dist/core/tools/read.js +165 -0
- package/dist/core/tools/truncate.js +204 -0
- package/dist/core/tools/write.js +77 -0
- package/dist/index.js +41 -0
- package/dist/main.js +565 -0
- package/dist/migrations.js +260 -0
- package/dist/modes/index.js +7 -0
- package/dist/modes/interactive/components/armin.js +328 -0
- package/dist/modes/interactive/components/assistant-message.js +86 -0
- package/dist/modes/interactive/components/bash-execution.js +155 -0
- package/dist/modes/interactive/components/bordered-loader.js +47 -0
- package/dist/modes/interactive/components/branch-summary-message.js +41 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +42 -0
- package/dist/modes/interactive/components/config-selector.js +458 -0
- package/dist/modes/interactive/components/countdown-timer.js +27 -0
- package/dist/modes/interactive/components/custom-editor.js +61 -0
- package/dist/modes/interactive/components/custom-message.js +80 -0
- package/dist/modes/interactive/components/diff.js +132 -0
- package/dist/modes/interactive/components/dynamic-border.js +19 -0
- package/dist/modes/interactive/components/extension-editor.js +96 -0
- package/dist/modes/interactive/components/extension-input.js +54 -0
- package/dist/modes/interactive/components/extension-selector.js +70 -0
- package/dist/modes/interactive/components/footer.js +213 -0
- package/dist/modes/interactive/components/index.js +31 -0
- package/dist/modes/interactive/components/keybinding-hints.js +60 -0
- package/dist/modes/interactive/components/login-dialog.js +138 -0
- package/dist/modes/interactive/components/model-selector.js +253 -0
- package/dist/modes/interactive/components/oauth-selector.js +91 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +262 -0
- package/dist/modes/interactive/components/session-selector-search.js +145 -0
- package/dist/modes/interactive/components/session-selector.js +698 -0
- package/dist/modes/interactive/components/settings-selector.js +250 -0
- package/dist/modes/interactive/components/show-images-selector.js +33 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +44 -0
- package/dist/modes/interactive/components/theme-selector.js +43 -0
- package/dist/modes/interactive/components/thinking-selector.js +45 -0
- package/dist/modes/interactive/components/tool-execution.js +608 -0
- package/dist/modes/interactive/components/tree-selector.js +892 -0
- package/dist/modes/interactive/components/user-message-selector.js +109 -0
- package/dist/modes/interactive/components/user-message.js +15 -0
- package/dist/modes/interactive/components/visual-truncate.js +32 -0
- package/dist/modes/interactive/interactive-mode.js +3576 -0
- package/dist/modes/interactive/theme/dark.json +85 -0
- package/dist/modes/interactive/theme/light.json +84 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.js +938 -0
- package/dist/modes/print-mode.js +96 -0
- package/dist/modes/rpc/rpc-client.js +390 -0
- package/dist/modes/rpc/rpc-mode.js +448 -0
- package/dist/modes/rpc/rpc-types.js +7 -0
- package/dist/utils/changelog.js +86 -0
- package/dist/utils/clipboard-image.js +116 -0
- package/dist/utils/clipboard.js +58 -0
- package/dist/utils/frontmatter.js +25 -0
- package/dist/utils/git.js +5 -0
- package/dist/utils/image-convert.js +34 -0
- package/dist/utils/image-resize.js +180 -0
- package/dist/utils/mime.js +25 -0
- package/dist/utils/photon.js +120 -0
- package/dist/utils/shell.js +164 -0
- package/dist/utils/sleep.js +16 -0
- package/dist/utils/tools-manager.js +186 -0
- package/docs/compaction.md +390 -0
- package/docs/custom-provider.md +538 -0
- package/docs/development.md +69 -0
- package/docs/extensions.md +1733 -0
- package/docs/images/doom-extension.png +0 -0
- package/docs/images/interactive-mode.png +0 -0
- package/docs/images/tree-view.png +0 -0
- package/docs/json.md +79 -0
- package/docs/keybindings.md +162 -0
- package/docs/models.md +193 -0
- package/docs/packages.md +163 -0
- package/docs/prompt-templates.md +67 -0
- package/docs/providers.md +147 -0
- package/docs/rpc.md +1048 -0
- package/docs/sdk.md +957 -0
- package/docs/session.md +412 -0
- package/docs/settings.md +216 -0
- package/docs/shell-aliases.md +13 -0
- package/docs/skills.md +226 -0
- package/docs/terminal-setup.md +65 -0
- package/docs/themes.md +295 -0
- package/docs/tree.md +219 -0
- package/docs/tui.md +887 -0
- package/docs/windows.md +17 -0
- package/examples/README.md +25 -0
- package/examples/extensions/README.md +192 -0
- package/examples/extensions/antigravity-image-gen.ts +414 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +115 -0
- package/examples/extensions/custom-footer.ts +65 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +605 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +350 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +83 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +133 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +105 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/handoff.ts +151 -0
- package/examples/extensions/hello.ts +25 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +60 -0
- package/examples/extensions/modal-editor.ts +86 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +25 -0
- package/examples/extensions/overlay-qa-tests.ts +882 -0
- package/examples/extensions/overlay-test.ts +151 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +341 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +399 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/qna.ts +120 -0
- package/examples/extensions/question.ts +265 -0
- package/examples/extensions/questionnaire.ts +428 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/sandbox/index.ts +318 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +344 -0
- package/examples/extensions/space-invaders.ts +561 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/status-line.ts +40 -0
- package/examples/extensions/subagent/README.md +172 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +127 -0
- package/examples/extensions/subagent/index.ts +964 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +196 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/todo.ts +300 -0
- package/examples/extensions/tool-override.ts +144 -0
- package/examples/extensions/tools.ts +147 -0
- package/examples/extensions/trigger-compact.ts +40 -0
- package/examples/extensions/truncated-tool.ts +193 -0
- package/examples/extensions/widget-placement.ts +17 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +50 -0
- package/examples/sdk/03-custom-prompt.ts +55 -0
- package/examples/sdk/04-skills.ts +46 -0
- package/examples/sdk/05-tools.ts +56 -0
- package/examples/sdk/06-extensions.ts +88 -0
- package/examples/sdk/07-context-files.ts +40 -0
- package/examples/sdk/08-prompt-templates.ts +47 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
- package/examples/sdk/10-settings.ts +38 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +82 -0
- package/examples/sdk/13-codex-oauth.ts +37 -0
- package/examples/sdk/README.md +144 -0
- package/package.json +85 -0
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { Container, getCapabilities, SelectList, SettingsList, Spacer, Text, } from "indusagi/tui";
|
|
2
|
+
import { getSelectListTheme, getSettingsListTheme, theme } from "../theme/theme.js";
|
|
3
|
+
import { DynamicBorder } from "./dynamic-border.js";
|
|
4
|
+
const THINKING_DESCRIPTIONS = {
|
|
5
|
+
off: "No reasoning",
|
|
6
|
+
minimal: "Very brief reasoning (~1k tokens)",
|
|
7
|
+
low: "Light reasoning (~2k tokens)",
|
|
8
|
+
medium: "Moderate reasoning (~8k tokens)",
|
|
9
|
+
high: "Deep reasoning (~16k tokens)",
|
|
10
|
+
xhigh: "Maximum reasoning (~32k tokens)",
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* A submenu component for selecting from a list of options.
|
|
14
|
+
*/
|
|
15
|
+
class SelectSubmenu extends Container {
|
|
16
|
+
constructor(title, description, options, currentValue, onSelect, onCancel, onSelectionChange) {
|
|
17
|
+
super();
|
|
18
|
+
// Title
|
|
19
|
+
this.addChild(new Text(theme.bold(theme.fg("accent", title)), 0, 0));
|
|
20
|
+
// Description
|
|
21
|
+
if (description) {
|
|
22
|
+
this.addChild(new Spacer(1));
|
|
23
|
+
this.addChild(new Text(theme.fg("muted", description), 0, 0));
|
|
24
|
+
}
|
|
25
|
+
// Spacer
|
|
26
|
+
this.addChild(new Spacer(1));
|
|
27
|
+
// Select list
|
|
28
|
+
this.selectList = new SelectList(options, Math.min(options.length, 10), getSelectListTheme());
|
|
29
|
+
// Pre-select current value
|
|
30
|
+
const currentIndex = options.findIndex((o) => o.value === currentValue);
|
|
31
|
+
if (currentIndex !== -1) {
|
|
32
|
+
this.selectList.setSelectedIndex(currentIndex);
|
|
33
|
+
}
|
|
34
|
+
this.selectList.onSelect = (item) => {
|
|
35
|
+
onSelect(item.value);
|
|
36
|
+
};
|
|
37
|
+
this.selectList.onCancel = onCancel;
|
|
38
|
+
if (onSelectionChange) {
|
|
39
|
+
this.selectList.onSelectionChange = (item) => {
|
|
40
|
+
onSelectionChange(item.value);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
this.addChild(this.selectList);
|
|
44
|
+
// Hint
|
|
45
|
+
this.addChild(new Spacer(1));
|
|
46
|
+
this.addChild(new Text(theme.fg("dim", " Enter to select · Esc to go back"), 0, 0));
|
|
47
|
+
}
|
|
48
|
+
handleInput(data) {
|
|
49
|
+
this.selectList.handleInput(data);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Main settings selector component.
|
|
54
|
+
*/
|
|
55
|
+
export class SettingsSelectorComponent extends Container {
|
|
56
|
+
constructor(config, callbacks) {
|
|
57
|
+
super();
|
|
58
|
+
const supportsImages = getCapabilities().images;
|
|
59
|
+
const items = [
|
|
60
|
+
{
|
|
61
|
+
id: "autocompact",
|
|
62
|
+
label: "Auto-compact",
|
|
63
|
+
description: "Automatically compact context when it gets too large",
|
|
64
|
+
currentValue: config.autoCompact ? "true" : "false",
|
|
65
|
+
values: ["true", "false"],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
id: "steering-mode",
|
|
69
|
+
label: "Steering mode",
|
|
70
|
+
description: "Enter while streaming queues steering messages. 'one-at-a-time': deliver one, wait for response. 'all': deliver all at once.",
|
|
71
|
+
currentValue: config.steeringMode,
|
|
72
|
+
values: ["one-at-a-time", "all"],
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: "follow-up-mode",
|
|
76
|
+
label: "Follow-up mode",
|
|
77
|
+
description: "Alt+Enter queues follow-up messages until agent stops. 'one-at-a-time': deliver one, wait for response. 'all': deliver all at once.",
|
|
78
|
+
currentValue: config.followUpMode,
|
|
79
|
+
values: ["one-at-a-time", "all"],
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
id: "hide-thinking",
|
|
83
|
+
label: "Hide thinking",
|
|
84
|
+
description: "Hide thinking blocks in assistant responses",
|
|
85
|
+
currentValue: config.hideThinkingBlock ? "true" : "false",
|
|
86
|
+
values: ["true", "false"],
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: "collapse-changelog",
|
|
90
|
+
label: "Collapse changelog",
|
|
91
|
+
description: "Show condensed changelog after updates",
|
|
92
|
+
currentValue: config.collapseChangelog ? "true" : "false",
|
|
93
|
+
values: ["true", "false"],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
id: "quiet-startup",
|
|
97
|
+
label: "Quiet startup",
|
|
98
|
+
description: "Disable verbose printing at startup",
|
|
99
|
+
currentValue: config.quietStartup ? "true" : "false",
|
|
100
|
+
values: ["true", "false"],
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
id: "double-escape-action",
|
|
104
|
+
label: "Double-escape action",
|
|
105
|
+
description: "Action when pressing Escape twice with empty editor",
|
|
106
|
+
currentValue: config.doubleEscapeAction,
|
|
107
|
+
values: ["tree", "fork"],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
id: "thinking",
|
|
111
|
+
label: "Thinking level",
|
|
112
|
+
description: "Reasoning depth for thinking-capable models",
|
|
113
|
+
currentValue: config.thinkingLevel,
|
|
114
|
+
submenu: (currentValue, done) => new SelectSubmenu("Thinking Level", "Select reasoning depth for thinking-capable models", config.availableThinkingLevels.map((level) => ({
|
|
115
|
+
value: level,
|
|
116
|
+
label: level,
|
|
117
|
+
description: THINKING_DESCRIPTIONS[level],
|
|
118
|
+
})), currentValue, (value) => {
|
|
119
|
+
callbacks.onThinkingLevelChange(value);
|
|
120
|
+
done(value);
|
|
121
|
+
}, () => done()),
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: "theme",
|
|
125
|
+
label: "Theme",
|
|
126
|
+
description: "Color theme for the interface",
|
|
127
|
+
currentValue: config.currentTheme,
|
|
128
|
+
submenu: (currentValue, done) => new SelectSubmenu("Theme", "Select color theme", config.availableThemes.map((t) => ({
|
|
129
|
+
value: t,
|
|
130
|
+
label: t,
|
|
131
|
+
})), currentValue, (value) => {
|
|
132
|
+
callbacks.onThemeChange(value);
|
|
133
|
+
done(value);
|
|
134
|
+
}, () => {
|
|
135
|
+
// Restore original theme on cancel
|
|
136
|
+
callbacks.onThemePreview?.(currentValue);
|
|
137
|
+
done();
|
|
138
|
+
}, (value) => {
|
|
139
|
+
// Preview theme on selection change
|
|
140
|
+
callbacks.onThemePreview?.(value);
|
|
141
|
+
}),
|
|
142
|
+
},
|
|
143
|
+
];
|
|
144
|
+
// Only show image toggle if terminal supports it
|
|
145
|
+
if (supportsImages) {
|
|
146
|
+
// Insert after autocompact
|
|
147
|
+
items.splice(1, 0, {
|
|
148
|
+
id: "show-images",
|
|
149
|
+
label: "Show images",
|
|
150
|
+
description: "Render images inline in terminal",
|
|
151
|
+
currentValue: config.showImages ? "true" : "false",
|
|
152
|
+
values: ["true", "false"],
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// Image auto-resize toggle (always available, affects both attached and read images)
|
|
156
|
+
items.splice(supportsImages ? 2 : 1, 0, {
|
|
157
|
+
id: "auto-resize-images",
|
|
158
|
+
label: "Auto-resize images",
|
|
159
|
+
description: "Resize large images to 2000x2000 max for better model compatibility",
|
|
160
|
+
currentValue: config.autoResizeImages ? "true" : "false",
|
|
161
|
+
values: ["true", "false"],
|
|
162
|
+
});
|
|
163
|
+
// Block images toggle (always available, insert after auto-resize-images)
|
|
164
|
+
const autoResizeIndex = items.findIndex((item) => item.id === "auto-resize-images");
|
|
165
|
+
items.splice(autoResizeIndex + 1, 0, {
|
|
166
|
+
id: "block-images",
|
|
167
|
+
label: "Block images",
|
|
168
|
+
description: "Prevent images from being sent to LLM providers",
|
|
169
|
+
currentValue: config.blockImages ? "true" : "false",
|
|
170
|
+
values: ["true", "false"],
|
|
171
|
+
});
|
|
172
|
+
// Skill commands toggle (insert after block-images)
|
|
173
|
+
const blockImagesIndex = items.findIndex((item) => item.id === "block-images");
|
|
174
|
+
items.splice(blockImagesIndex + 1, 0, {
|
|
175
|
+
id: "skill-commands",
|
|
176
|
+
label: "Skill commands",
|
|
177
|
+
description: "Register skills as /skill:name commands",
|
|
178
|
+
currentValue: config.enableSkillCommands ? "true" : "false",
|
|
179
|
+
values: ["true", "false"],
|
|
180
|
+
});
|
|
181
|
+
// Hardware cursor toggle (insert after skill-commands)
|
|
182
|
+
const skillCommandsIndex = items.findIndex((item) => item.id === "skill-commands");
|
|
183
|
+
items.splice(skillCommandsIndex + 1, 0, {
|
|
184
|
+
id: "show-hardware-cursor",
|
|
185
|
+
label: "Show hardware cursor",
|
|
186
|
+
description: "Show the terminal cursor while still positioning it for IME support",
|
|
187
|
+
currentValue: config.showHardwareCursor ? "true" : "false",
|
|
188
|
+
values: ["true", "false"],
|
|
189
|
+
});
|
|
190
|
+
// Editor padding toggle (insert after show-hardware-cursor)
|
|
191
|
+
const hardwareCursorIndex = items.findIndex((item) => item.id === "show-hardware-cursor");
|
|
192
|
+
items.splice(hardwareCursorIndex + 1, 0, {
|
|
193
|
+
id: "editor-padding",
|
|
194
|
+
label: "Editor padding",
|
|
195
|
+
description: "Horizontal padding for input editor (0-3)",
|
|
196
|
+
currentValue: String(config.editorPaddingX),
|
|
197
|
+
values: ["0", "1", "2", "3"],
|
|
198
|
+
});
|
|
199
|
+
// Add borders
|
|
200
|
+
this.addChild(new DynamicBorder());
|
|
201
|
+
this.settingsList = new SettingsList(items, 10, getSettingsListTheme(), (id, newValue) => {
|
|
202
|
+
switch (id) {
|
|
203
|
+
case "autocompact":
|
|
204
|
+
callbacks.onAutoCompactChange(newValue === "true");
|
|
205
|
+
break;
|
|
206
|
+
case "show-images":
|
|
207
|
+
callbacks.onShowImagesChange(newValue === "true");
|
|
208
|
+
break;
|
|
209
|
+
case "auto-resize-images":
|
|
210
|
+
callbacks.onAutoResizeImagesChange(newValue === "true");
|
|
211
|
+
break;
|
|
212
|
+
case "block-images":
|
|
213
|
+
callbacks.onBlockImagesChange(newValue === "true");
|
|
214
|
+
break;
|
|
215
|
+
case "skill-commands":
|
|
216
|
+
callbacks.onEnableSkillCommandsChange(newValue === "true");
|
|
217
|
+
break;
|
|
218
|
+
case "steering-mode":
|
|
219
|
+
callbacks.onSteeringModeChange(newValue);
|
|
220
|
+
break;
|
|
221
|
+
case "follow-up-mode":
|
|
222
|
+
callbacks.onFollowUpModeChange(newValue);
|
|
223
|
+
break;
|
|
224
|
+
case "hide-thinking":
|
|
225
|
+
callbacks.onHideThinkingBlockChange(newValue === "true");
|
|
226
|
+
break;
|
|
227
|
+
case "collapse-changelog":
|
|
228
|
+
callbacks.onCollapseChangelogChange(newValue === "true");
|
|
229
|
+
break;
|
|
230
|
+
case "quiet-startup":
|
|
231
|
+
callbacks.onQuietStartupChange(newValue === "true");
|
|
232
|
+
break;
|
|
233
|
+
case "double-escape-action":
|
|
234
|
+
callbacks.onDoubleEscapeActionChange(newValue);
|
|
235
|
+
break;
|
|
236
|
+
case "show-hardware-cursor":
|
|
237
|
+
callbacks.onShowHardwareCursorChange(newValue === "true");
|
|
238
|
+
break;
|
|
239
|
+
case "editor-padding":
|
|
240
|
+
callbacks.onEditorPaddingXChange(parseInt(newValue, 10));
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}, callbacks.onCancel, { enableSearch: true });
|
|
244
|
+
this.addChild(this.settingsList);
|
|
245
|
+
this.addChild(new DynamicBorder());
|
|
246
|
+
}
|
|
247
|
+
getSettingsList() {
|
|
248
|
+
return this.settingsList;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Container, SelectList } from "indusagi/tui";
|
|
2
|
+
import { getSelectListTheme } from "../theme/theme.js";
|
|
3
|
+
import { DynamicBorder } from "./dynamic-border.js";
|
|
4
|
+
/**
|
|
5
|
+
* Component that renders a show images selector with borders
|
|
6
|
+
*/
|
|
7
|
+
export class ShowImagesSelectorComponent extends Container {
|
|
8
|
+
constructor(currentValue, onSelect, onCancel) {
|
|
9
|
+
super();
|
|
10
|
+
const items = [
|
|
11
|
+
{ value: "yes", label: "Yes", description: "Show images inline in terminal" },
|
|
12
|
+
{ value: "no", label: "No", description: "Show text placeholder instead" },
|
|
13
|
+
];
|
|
14
|
+
// Add top border
|
|
15
|
+
this.addChild(new DynamicBorder());
|
|
16
|
+
// Create selector
|
|
17
|
+
this.selectList = new SelectList(items, 5, getSelectListTheme());
|
|
18
|
+
// Preselect current value
|
|
19
|
+
this.selectList.setSelectedIndex(currentValue ? 0 : 1);
|
|
20
|
+
this.selectList.onSelect = (item) => {
|
|
21
|
+
onSelect(item.value === "yes");
|
|
22
|
+
};
|
|
23
|
+
this.selectList.onCancel = () => {
|
|
24
|
+
onCancel();
|
|
25
|
+
};
|
|
26
|
+
this.addChild(this.selectList);
|
|
27
|
+
// Add bottom border
|
|
28
|
+
this.addChild(new DynamicBorder());
|
|
29
|
+
}
|
|
30
|
+
getSelectList() {
|
|
31
|
+
return this.selectList;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Box, Markdown, Text } from "indusagi/tui";
|
|
2
|
+
import { getMarkdownTheme, theme } from "../theme/theme.js";
|
|
3
|
+
import { editorKey } from "./keybinding-hints.js";
|
|
4
|
+
/**
|
|
5
|
+
* Component that renders a skill invocation message with collapsed/expanded state.
|
|
6
|
+
* Uses same background color as custom messages for visual consistency.
|
|
7
|
+
* Only renders the skill block itself - user message is rendered separately.
|
|
8
|
+
*/
|
|
9
|
+
export class SkillInvocationMessageComponent extends Box {
|
|
10
|
+
constructor(skillBlock, markdownTheme = getMarkdownTheme()) {
|
|
11
|
+
super(1, 1, (t) => theme.bg("customMessageBg", t));
|
|
12
|
+
this.expanded = false;
|
|
13
|
+
this.skillBlock = skillBlock;
|
|
14
|
+
this.markdownTheme = markdownTheme;
|
|
15
|
+
this.updateDisplay();
|
|
16
|
+
}
|
|
17
|
+
setExpanded(expanded) {
|
|
18
|
+
this.expanded = expanded;
|
|
19
|
+
this.updateDisplay();
|
|
20
|
+
}
|
|
21
|
+
invalidate() {
|
|
22
|
+
super.invalidate();
|
|
23
|
+
this.updateDisplay();
|
|
24
|
+
}
|
|
25
|
+
updateDisplay() {
|
|
26
|
+
this.clear();
|
|
27
|
+
if (this.expanded) {
|
|
28
|
+
// Expanded: label + skill name header + full content
|
|
29
|
+
const label = theme.fg("customMessageLabel", `\x1b[1m[skill]\x1b[22m`);
|
|
30
|
+
this.addChild(new Text(label, 0, 0));
|
|
31
|
+
const header = `**${this.skillBlock.name}**\n\n`;
|
|
32
|
+
this.addChild(new Markdown(header + this.skillBlock.content, 0, 0, this.markdownTheme, {
|
|
33
|
+
color: (text) => theme.fg("customMessageText", text),
|
|
34
|
+
}));
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
// Collapsed: single line - [skill] name (hint to expand)
|
|
38
|
+
const line = theme.fg("customMessageLabel", `\x1b[1m[skill]\x1b[22m `) +
|
|
39
|
+
theme.fg("customMessageText", this.skillBlock.name) +
|
|
40
|
+
theme.fg("dim", ` (${editorKey("expandTools")} to expand)`);
|
|
41
|
+
this.addChild(new Text(line, 0, 0));
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Container, SelectList } from "indusagi/tui";
|
|
2
|
+
import { getAvailableThemes, getSelectListTheme } from "../theme/theme.js";
|
|
3
|
+
import { DynamicBorder } from "./dynamic-border.js";
|
|
4
|
+
/**
|
|
5
|
+
* Component that renders a theme selector
|
|
6
|
+
*/
|
|
7
|
+
export class ThemeSelectorComponent extends Container {
|
|
8
|
+
constructor(currentTheme, onSelect, onCancel, onPreview) {
|
|
9
|
+
super();
|
|
10
|
+
this.onPreview = onPreview;
|
|
11
|
+
// Get available themes and create select items
|
|
12
|
+
const themes = getAvailableThemes();
|
|
13
|
+
const themeItems = themes.map((name) => ({
|
|
14
|
+
value: name,
|
|
15
|
+
label: name,
|
|
16
|
+
description: name === currentTheme ? "(current)" : undefined,
|
|
17
|
+
}));
|
|
18
|
+
// Add top border
|
|
19
|
+
this.addChild(new DynamicBorder());
|
|
20
|
+
// Create selector
|
|
21
|
+
this.selectList = new SelectList(themeItems, 10, getSelectListTheme());
|
|
22
|
+
// Preselect current theme
|
|
23
|
+
const currentIndex = themes.indexOf(currentTheme);
|
|
24
|
+
if (currentIndex !== -1) {
|
|
25
|
+
this.selectList.setSelectedIndex(currentIndex);
|
|
26
|
+
}
|
|
27
|
+
this.selectList.onSelect = (item) => {
|
|
28
|
+
onSelect(item.value);
|
|
29
|
+
};
|
|
30
|
+
this.selectList.onCancel = () => {
|
|
31
|
+
onCancel();
|
|
32
|
+
};
|
|
33
|
+
this.selectList.onSelectionChange = (item) => {
|
|
34
|
+
this.onPreview(item.value);
|
|
35
|
+
};
|
|
36
|
+
this.addChild(this.selectList);
|
|
37
|
+
// Add bottom border
|
|
38
|
+
this.addChild(new DynamicBorder());
|
|
39
|
+
}
|
|
40
|
+
getSelectList() {
|
|
41
|
+
return this.selectList;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Container, SelectList } from "indusagi/tui";
|
|
2
|
+
import { getSelectListTheme } from "../theme/theme.js";
|
|
3
|
+
import { DynamicBorder } from "./dynamic-border.js";
|
|
4
|
+
const LEVEL_DESCRIPTIONS = {
|
|
5
|
+
off: "No reasoning",
|
|
6
|
+
minimal: "Very brief reasoning (~1k tokens)",
|
|
7
|
+
low: "Light reasoning (~2k tokens)",
|
|
8
|
+
medium: "Moderate reasoning (~8k tokens)",
|
|
9
|
+
high: "Deep reasoning (~16k tokens)",
|
|
10
|
+
xhigh: "Maximum reasoning (~32k tokens)",
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Component that renders a thinking level selector with borders
|
|
14
|
+
*/
|
|
15
|
+
export class ThinkingSelectorComponent extends Container {
|
|
16
|
+
constructor(currentLevel, availableLevels, onSelect, onCancel) {
|
|
17
|
+
super();
|
|
18
|
+
const thinkingLevels = availableLevels.map((level) => ({
|
|
19
|
+
value: level,
|
|
20
|
+
label: level,
|
|
21
|
+
description: LEVEL_DESCRIPTIONS[level],
|
|
22
|
+
}));
|
|
23
|
+
// Add top border
|
|
24
|
+
this.addChild(new DynamicBorder());
|
|
25
|
+
// Create selector
|
|
26
|
+
this.selectList = new SelectList(thinkingLevels, thinkingLevels.length, getSelectListTheme());
|
|
27
|
+
// Preselect current level
|
|
28
|
+
const currentIndex = thinkingLevels.findIndex((item) => item.value === currentLevel);
|
|
29
|
+
if (currentIndex !== -1) {
|
|
30
|
+
this.selectList.setSelectedIndex(currentIndex);
|
|
31
|
+
}
|
|
32
|
+
this.selectList.onSelect = (item) => {
|
|
33
|
+
onSelect(item.value);
|
|
34
|
+
};
|
|
35
|
+
this.selectList.onCancel = () => {
|
|
36
|
+
onCancel();
|
|
37
|
+
};
|
|
38
|
+
this.addChild(this.selectList);
|
|
39
|
+
// Add bottom border
|
|
40
|
+
this.addChild(new DynamicBorder());
|
|
41
|
+
}
|
|
42
|
+
getSelectList() {
|
|
43
|
+
return this.selectList;
|
|
44
|
+
}
|
|
45
|
+
}
|