@gajae-code/coding-agent 0.7.7 → 0.7.9
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 +38 -1
- package/README.md +14 -0
- package/dist/types/cli/local-provider-smoke.d.ts +59 -0
- package/dist/types/cli/notify-cli.d.ts +1 -1
- package/dist/types/cli/update-cli.d.ts +24 -1
- package/dist/types/commands/local-provider.d.ts +34 -0
- package/dist/types/config/keybindings.d.ts +1 -1
- package/dist/types/config/model-profile-activation.d.ts +19 -2
- package/dist/types/config/model-profiles.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +9 -0
- package/dist/types/config/models-config-schema.d.ts +5 -0
- package/dist/types/config/settings-schema.d.ts +45 -0
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/coordinator-mcp/server.d.ts +8 -0
- package/dist/types/gjc-runtime/launch-tmux.d.ts +14 -5
- package/dist/types/gjc-runtime/team-runtime.d.ts +1 -1
- package/dist/types/gjc-runtime/tmux-common.d.ts +12 -0
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +3 -1
- package/dist/types/modes/components/custom-model-preset-wizard.d.ts +1 -1
- package/dist/types/modes/components/hook-input.d.ts +1 -0
- package/dist/types/modes/components/model-selector.d.ts +11 -0
- package/dist/types/modes/components/settings-selector.d.ts +4 -1
- package/dist/types/modes/components/status-line/types.d.ts +5 -7
- package/dist/types/modes/components/status-line.d.ts +7 -3
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +3 -1
- package/dist/types/modes/controllers/input-controller.d.ts +1 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +2 -1
- package/dist/types/modes/interactive-mode.d.ts +3 -1
- package/dist/types/modes/prompt-action-autocomplete.d.ts +1 -0
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +21 -1
- package/dist/types/modes/tmux-scroll.d.ts +18 -0
- package/dist/types/modes/types.d.ts +3 -1
- package/dist/types/modes/utils/terminal-bell.d.ts +3 -0
- package/dist/types/notifications/daemon-paths.d.ts +9 -0
- package/dist/types/notifications/telegram-daemon-cli.d.ts +21 -4
- package/dist/types/notifications/telegram-daemon.d.ts +1 -10
- package/dist/types/tools/ask.d.ts +24 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +9 -2
- package/package.json +7 -7
- package/src/cli/local-provider-smoke.ts +632 -0
- package/src/cli/notify-cli.ts +5 -3
- package/src/cli/update-cli.ts +155 -13
- package/src/cli.ts +19 -0
- package/src/commands/launch.ts +46 -1
- package/src/commands/local-provider.ts +62 -0
- package/src/commands/notify.ts +1 -1
- package/src/config/keybindings.ts +1 -1
- package/src/config/model-profile-activation.ts +92 -11
- package/src/config/model-profiles.ts +15 -2
- package/src/config/model-registry.ts +136 -6
- package/src/config/models-config-schema.ts +9 -0
- package/src/config/settings-schema.ts +48 -0
- package/src/config/settings.ts +11 -0
- package/src/coordinator-mcp/server.ts +280 -36
- package/src/deep-interview/render-middleware.ts +1 -0
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +14 -6
- package/src/defaults/gjc/skills/ralplan/SKILL.md +14 -7
- package/src/gjc-runtime/deep-interview-runtime.ts +1 -1
- package/src/gjc-runtime/launch-tmux.ts +321 -38
- package/src/gjc-runtime/launch-worktree.ts +16 -2
- package/src/gjc-runtime/team-runtime.ts +87 -7
- package/src/gjc-runtime/tmux-common.ts +16 -0
- package/src/gjc-runtime/tmux-sessions.ts +13 -9
- package/src/gjc-runtime/ultragoal-guard.ts +11 -5
- package/src/internal-urls/docs-index.generated.ts +10 -9
- package/src/modes/components/agent-dashboard.ts +2 -1
- package/src/modes/components/custom-model-preset-wizard.ts +31 -192
- package/src/modes/components/hook-editor.ts +7 -4
- package/src/modes/components/hook-input.ts +4 -0
- package/src/modes/components/model-selector.ts +260 -12
- package/src/modes/components/session-observer-overlay.ts +3 -3
- package/src/modes/components/settings-selector.ts +506 -5
- package/src/modes/components/status-line/segments.ts +16 -19
- package/src/modes/components/status-line/types.ts +6 -2
- package/src/modes/components/status-line.ts +70 -35
- package/src/modes/controllers/event-controller.ts +98 -4
- package/src/modes/controllers/extension-ui-controller.ts +5 -0
- package/src/modes/controllers/input-controller.ts +15 -0
- package/src/modes/controllers/selector-controller.ts +142 -11
- package/src/modes/interactive-mode.ts +7 -2
- package/src/modes/prompt-action-autocomplete.ts +8 -0
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +11 -4
- package/src/modes/tmux-scroll.ts +92 -0
- package/src/modes/types.ts +6 -1
- package/src/modes/utils/terminal-bell.ts +48 -0
- package/src/notifications/daemon-paths.ts +22 -0
- package/src/notifications/telegram-daemon-cli.ts +125 -13
- package/src/notifications/telegram-daemon.ts +6 -21
- package/src/prompts/system/system-prompt.md +5 -0
- package/src/sdk.ts +10 -1
- package/src/session/agent-session.ts +84 -6
- package/src/slash-commands/builtin-registry.ts +106 -13
- package/src/tools/ask.ts +11 -1
- package/src/tools/eval.ts +2 -2
- package/src/tools/render-utils.ts +2 -0
- package/src/tools/ultragoal-ask-guard.ts +39 -5
|
@@ -25,6 +25,7 @@ import {
|
|
|
25
25
|
matchesKey,
|
|
26
26
|
padding,
|
|
27
27
|
replaceTabs,
|
|
28
|
+
resolveTerminalColumns,
|
|
28
29
|
Spacer,
|
|
29
30
|
Text,
|
|
30
31
|
truncateToWidth,
|
|
@@ -870,7 +871,7 @@ export class AgentDashboard extends Container {
|
|
|
870
871
|
}
|
|
871
872
|
|
|
872
873
|
#uiWidth(): number {
|
|
873
|
-
return Math.max(40,
|
|
874
|
+
return Math.max(40, resolveTerminalColumns());
|
|
874
875
|
}
|
|
875
876
|
|
|
876
877
|
/** Rebuild layout and request a TUI render pass (for use after async state changes). */
|
|
@@ -1,20 +1,9 @@
|
|
|
1
1
|
import { Container, Input, matchesKey, Spacer, Text, TruncatedText } from "@gajae-code/tui";
|
|
2
|
+
import { MODEL_PROFILE_NAME_PATTERN } from "../../config/model-registry";
|
|
2
3
|
import type { ModelProfileConfig } from "../../config/models-config-schema";
|
|
3
4
|
import { theme } from "../theme/theme";
|
|
4
5
|
import { matchesAppInterrupt } from "../utils/keybinding-matchers";
|
|
5
6
|
import { DynamicBorder } from "./dynamic-border";
|
|
6
|
-
|
|
7
|
-
const PROFILE_NAME_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
8
|
-
|
|
9
|
-
type WizardStep = "name" | "display-name" | "provider" | "model" | "confirm";
|
|
10
|
-
|
|
11
|
-
interface WizardState {
|
|
12
|
-
name: string;
|
|
13
|
-
displayName: string;
|
|
14
|
-
provider: string;
|
|
15
|
-
model: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
7
|
export interface CustomModelPresetWizardSubmit {
|
|
19
8
|
name: string;
|
|
20
9
|
profile: ModelProfileConfig;
|
|
@@ -23,25 +12,21 @@ export interface CustomModelPresetWizardSubmit {
|
|
|
23
12
|
export class CustomModelPresetWizardComponent extends Container {
|
|
24
13
|
#contentContainer: Container;
|
|
25
14
|
#input: Input | null = null;
|
|
26
|
-
#step: WizardStep = "name";
|
|
27
|
-
#selectedIndex = 0;
|
|
28
15
|
#lastError: string | null = null;
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
displayName: "",
|
|
32
|
-
provider: "",
|
|
33
|
-
model: "",
|
|
34
|
-
};
|
|
16
|
+
#name = "";
|
|
17
|
+
#snapshot: ModelProfileConfig;
|
|
35
18
|
#onSubmit: (input: CustomModelPresetWizardSubmit) => void;
|
|
36
19
|
#onCancel: () => void;
|
|
37
20
|
#onRender: () => void;
|
|
38
21
|
|
|
39
22
|
constructor(
|
|
23
|
+
snapshot: ModelProfileConfig,
|
|
40
24
|
onSubmit: (input: CustomModelPresetWizardSubmit) => void,
|
|
41
25
|
onCancel: () => void,
|
|
42
26
|
onRender: () => void = () => {},
|
|
43
27
|
) {
|
|
44
28
|
super();
|
|
29
|
+
this.#snapshot = snapshot;
|
|
45
30
|
this.#onSubmit = onSubmit;
|
|
46
31
|
this.#onCancel = onCancel;
|
|
47
32
|
this.#onRender = onRender;
|
|
@@ -51,7 +36,7 @@ export class CustomModelPresetWizardComponent extends Container {
|
|
|
51
36
|
this.addChild(new TruncatedText(theme.bold("Create custom model preset")));
|
|
52
37
|
this.addChild(
|
|
53
38
|
new TruncatedText(
|
|
54
|
-
theme.fg("muted", " Save
|
|
39
|
+
theme.fg("muted", " Save the current default and explicit role models as a selectable profile."),
|
|
55
40
|
0,
|
|
56
41
|
0,
|
|
57
42
|
),
|
|
@@ -72,222 +57,76 @@ export class CustomModelPresetWizardComponent extends Container {
|
|
|
72
57
|
|
|
73
58
|
handleInput(keyData: string): void {
|
|
74
59
|
if (matchesAppInterrupt(keyData)) {
|
|
75
|
-
|
|
76
|
-
this.#onCancel();
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
this.#goBack();
|
|
60
|
+
this.#onCancel();
|
|
80
61
|
return;
|
|
81
62
|
}
|
|
82
63
|
|
|
83
64
|
if (this.#input) {
|
|
84
65
|
if (matchesKey(keyData, "enter") || matchesKey(keyData, "return") || keyData === "\n") {
|
|
85
|
-
this.#
|
|
66
|
+
this.#saveInputAndSubmit();
|
|
86
67
|
return;
|
|
87
68
|
}
|
|
88
69
|
this.#input.handleInput(keyData);
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (matchesKey(keyData, "up")) {
|
|
93
|
-
this.#moveSelection(-1);
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (matchesKey(keyData, "down")) {
|
|
97
|
-
this.#moveSelection(1);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (matchesKey(keyData, "enter") || matchesKey(keyData, "return") || keyData === "\n") {
|
|
101
|
-
this.#selectCurrentOption();
|
|
102
70
|
}
|
|
103
71
|
}
|
|
104
72
|
|
|
105
73
|
#renderStep(): void {
|
|
106
74
|
this.#contentContainer.clear();
|
|
107
75
|
this.#input = null;
|
|
108
|
-
|
|
109
|
-
case "name":
|
|
110
|
-
this.#renderInputStep(
|
|
111
|
-
"Step 1: Preset id",
|
|
112
|
-
"Enter a unique preset id:",
|
|
113
|
-
this.#state.name,
|
|
114
|
-
"e.g. my-fast-coder",
|
|
115
|
-
);
|
|
116
|
-
break;
|
|
117
|
-
case "display-name":
|
|
118
|
-
this.#renderInputStep(
|
|
119
|
-
"Step 2: Display name",
|
|
120
|
-
"Enter a display name:",
|
|
121
|
-
this.#state.displayName,
|
|
122
|
-
"e.g. My Fast Coder",
|
|
123
|
-
);
|
|
124
|
-
break;
|
|
125
|
-
case "provider":
|
|
126
|
-
this.#renderInputStep(
|
|
127
|
-
"Step 3: Provider",
|
|
128
|
-
"Enter the provider id:",
|
|
129
|
-
this.#state.provider,
|
|
130
|
-
"e.g. openai-codex, anthropic, my-oai",
|
|
131
|
-
);
|
|
132
|
-
break;
|
|
133
|
-
case "model":
|
|
134
|
-
this.#renderInputStep(
|
|
135
|
-
"Step 4: Model",
|
|
136
|
-
"Enter the model id or provider/model selector:",
|
|
137
|
-
this.#state.model,
|
|
138
|
-
"e.g. gpt-5.5:medium or my-oai/gpt-example:low",
|
|
139
|
-
);
|
|
140
|
-
break;
|
|
141
|
-
case "confirm":
|
|
142
|
-
this.#renderConfirmStep();
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
#renderInputStep(title: string, prompt: string, value: string, hint: string): void {
|
|
148
|
-
this.#contentContainer.addChild(new Text(theme.fg("accent", title)));
|
|
76
|
+
this.#contentContainer.addChild(new Text(theme.fg("accent", "Preset id")));
|
|
149
77
|
this.#contentContainer.addChild(new Spacer(1));
|
|
150
78
|
if (this.#lastError) {
|
|
151
79
|
this.#contentContainer.addChild(new Text(theme.fg("error", this.#lastError), 0, 0));
|
|
152
80
|
this.#contentContainer.addChild(new Spacer(1));
|
|
153
81
|
}
|
|
154
|
-
this.#contentContainer.addChild(new Text(
|
|
82
|
+
this.#contentContainer.addChild(new Text("Enter a unique preset id:", 0, 0));
|
|
155
83
|
this.#contentContainer.addChild(new Spacer(1));
|
|
156
84
|
this.#input = new Input();
|
|
157
|
-
this.#input.setValue(
|
|
85
|
+
this.#input.setValue(this.#name);
|
|
158
86
|
this.#contentContainer.addChild(this.#input);
|
|
159
87
|
this.#contentContainer.addChild(new Spacer(1));
|
|
160
|
-
this.#
|
|
161
|
-
this.#addHelp("
|
|
88
|
+
this.#addSnapshotPreview();
|
|
89
|
+
this.#addHelp("e.g. my-fast-coder");
|
|
90
|
+
this.#addHelp("[Enter to create, Esc to cancel]");
|
|
162
91
|
}
|
|
163
92
|
|
|
164
|
-
#
|
|
165
|
-
this.#contentContainer.addChild(new Text(theme.fg("
|
|
166
|
-
this.#
|
|
167
|
-
|
|
168
|
-
this.#contentContainer.addChild(new Text(theme.fg("error", this.#lastError), 0, 0));
|
|
169
|
-
this.#contentContainer.addChild(new Spacer(1));
|
|
93
|
+
#addSnapshotPreview(): void {
|
|
94
|
+
this.#contentContainer.addChild(new Text(theme.fg("muted", "Snapshot:"), 0, 0));
|
|
95
|
+
for (const [role, selector] of Object.entries(this.#snapshot.model_mapping)) {
|
|
96
|
+
this.#contentContainer.addChild(new Text(` ${role}: ${selector}`, 0, 0));
|
|
170
97
|
}
|
|
171
|
-
this.#contentContainer.addChild(new Text(`
|
|
172
|
-
this.#contentContainer.addChild(new Text(`Display name: ${this.#state.displayName}`, 0, 0));
|
|
173
|
-
this.#contentContainer.addChild(new Text(`Provider: ${this.#state.provider}`, 0, 0));
|
|
174
|
-
this.#contentContainer.addChild(new Text(`Default model: ${this.#selector()}`, 0, 0));
|
|
98
|
+
this.#contentContainer.addChild(new Text(` providers: ${this.#snapshot.required_providers.join(", ")}`, 0, 0));
|
|
175
99
|
this.#contentContainer.addChild(new Spacer(1));
|
|
176
|
-
this.#addOption(0, "Create preset");
|
|
177
|
-
this.#addOption(1, "Go back");
|
|
178
|
-
this.#addHelp("[↑↓ to navigate, Enter to select, Esc to go back]");
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
#addOption(index: number, label: string): void {
|
|
182
|
-
const selected = index === this.#selectedIndex;
|
|
183
|
-
const prefix = selected ? theme.fg("accent", `${theme.nav.cursor} `) : " ";
|
|
184
|
-
this.#contentContainer.addChild(new Text(`${prefix}${selected ? theme.fg("accent", label) : label}`, 0, 0));
|
|
185
100
|
}
|
|
186
101
|
|
|
187
102
|
#addHelp(text: string): void {
|
|
188
103
|
this.#contentContainer.addChild(new Text(theme.fg("muted", text), 0, 0));
|
|
189
104
|
}
|
|
190
105
|
|
|
191
|
-
#
|
|
106
|
+
#saveInputAndSubmit(): void {
|
|
192
107
|
const value = this.#input?.getValue().trim() ?? "";
|
|
193
108
|
if (!value) {
|
|
194
|
-
this.#lastError =
|
|
109
|
+
this.#lastError = "Preset id is required.";
|
|
195
110
|
this.#renderStep();
|
|
196
111
|
this.#onRender();
|
|
197
112
|
return;
|
|
198
113
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
this.#lastError = validationError;
|
|
114
|
+
if (!MODEL_PROFILE_NAME_PATTERN.test(value)) {
|
|
115
|
+
this.#lastError = "Preset id must use lowercase letters, numbers, dots, underscores, or hyphens.";
|
|
202
116
|
this.#renderStep();
|
|
203
117
|
this.#onRender();
|
|
204
118
|
return;
|
|
205
119
|
}
|
|
120
|
+
this.#name = value;
|
|
206
121
|
this.#lastError = null;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
this.#step = "display-name";
|
|
210
|
-
} else if (this.#step === "display-name") {
|
|
211
|
-
this.#state.displayName = value;
|
|
212
|
-
this.#step = "provider";
|
|
213
|
-
} else if (this.#step === "provider") {
|
|
214
|
-
this.#state.provider = value;
|
|
215
|
-
this.#step = "model";
|
|
216
|
-
} else if (this.#step === "model") {
|
|
217
|
-
this.#state.model = value;
|
|
218
|
-
this.#step = "confirm";
|
|
219
|
-
this.#selectedIndex = 0;
|
|
220
|
-
}
|
|
221
|
-
this.#renderStep();
|
|
222
|
-
this.#onRender();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
#emptyFieldMessage(): string {
|
|
226
|
-
switch (this.#step) {
|
|
227
|
-
case "name":
|
|
228
|
-
return "Preset id is required.";
|
|
229
|
-
case "display-name":
|
|
230
|
-
return "Display name is required.";
|
|
231
|
-
case "provider":
|
|
232
|
-
return "Provider is required.";
|
|
233
|
-
case "model":
|
|
234
|
-
return "Model is required.";
|
|
235
|
-
case "confirm":
|
|
236
|
-
return "Value is required.";
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
#validateCurrentInput(value: string): string | undefined {
|
|
241
|
-
if (this.#step === "name" && !PROFILE_NAME_PATTERN.test(value)) {
|
|
242
|
-
return "Preset id must use lowercase letters, numbers, dots, underscores, or hyphens.";
|
|
243
|
-
}
|
|
244
|
-
if (this.#step === "provider" && !PROFILE_NAME_PATTERN.test(value)) {
|
|
245
|
-
return "Provider id must use lowercase letters, numbers, dots, underscores, or hyphens.";
|
|
246
|
-
}
|
|
247
|
-
if (this.#step === "model" && value.includes(",")) {
|
|
248
|
-
return "Model must be one selector, not a comma-separated list.";
|
|
249
|
-
}
|
|
250
|
-
return undefined;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
#selectCurrentOption(): void {
|
|
254
|
-
if (this.#step !== "confirm") return;
|
|
255
|
-
if (this.#selectedIndex === 0) {
|
|
256
|
-
this.#onSubmit(this.#buildInput());
|
|
257
|
-
return;
|
|
258
|
-
}
|
|
259
|
-
this.#goBack();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
#buildInput(): CustomModelPresetWizardSubmit {
|
|
263
|
-
return {
|
|
264
|
-
name: this.#state.name,
|
|
122
|
+
this.#onSubmit({
|
|
123
|
+
name: value,
|
|
265
124
|
profile: {
|
|
266
|
-
|
|
267
|
-
display_name:
|
|
268
|
-
model_mapping: {
|
|
125
|
+
...this.#snapshot,
|
|
126
|
+
display_name: value,
|
|
127
|
+
model_mapping: { ...this.#snapshot.model_mapping },
|
|
128
|
+
required_providers: [...this.#snapshot.required_providers],
|
|
269
129
|
},
|
|
270
|
-
};
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
#selector(): string {
|
|
274
|
-
return this.#state.model.includes("/") ? this.#state.model : `${this.#state.provider}/${this.#state.model}`;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
#moveSelection(delta: number): void {
|
|
278
|
-
this.#selectedIndex = (this.#selectedIndex + delta + 2) % 2;
|
|
279
|
-
this.#renderStep();
|
|
280
|
-
this.#onRender();
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
#goBack(): void {
|
|
284
|
-
if (this.#step === "display-name") this.#step = "name";
|
|
285
|
-
else if (this.#step === "provider") this.#step = "display-name";
|
|
286
|
-
else if (this.#step === "model") this.#step = "provider";
|
|
287
|
-
else if (this.#step === "confirm") this.#step = "model";
|
|
288
|
-
this.#selectedIndex = 0;
|
|
289
|
-
this.#lastError = null;
|
|
290
|
-
this.#renderStep();
|
|
291
|
-
this.#onRender();
|
|
130
|
+
});
|
|
292
131
|
}
|
|
293
132
|
}
|
|
@@ -96,14 +96,17 @@ export class HookEditorComponent extends Container {
|
|
|
96
96
|
return;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
-
// Submit on
|
|
100
|
-
// newline mappings (Shift+Enter/Ctrl+J
|
|
101
|
-
if (
|
|
99
|
+
// Submit on Enter and Ctrl+Enter encodings. On Windows, raw LF is reserved for
|
|
100
|
+
// terminal newline mappings (Shift+Enter/Ctrl+J); plain Enter reports CR.
|
|
101
|
+
if (
|
|
102
|
+
!isWindowsRawLfNewlineInput(keyData) &&
|
|
103
|
+
(matchesKey(keyData, "enter") || matchesKey(keyData, "return") || matchesKey(keyData, "ctrl+enter"))
|
|
104
|
+
) {
|
|
102
105
|
this.#onSubmitCallback(this.#editor.getText());
|
|
103
106
|
return;
|
|
104
107
|
}
|
|
105
108
|
|
|
106
|
-
// Let Editor handle
|
|
109
|
+
// Let Editor handle newline-producing variants (Shift+Enter, Ctrl+J, Alt+Enter, etc.)
|
|
107
110
|
this.#editor.handleInput(keyData);
|
|
108
111
|
}
|
|
109
112
|
|
|
@@ -8,6 +8,7 @@ import { CountdownTimer } from "./countdown-timer";
|
|
|
8
8
|
import { DynamicBorder } from "./dynamic-border";
|
|
9
9
|
|
|
10
10
|
export interface HookInputOptions {
|
|
11
|
+
initialValue?: string;
|
|
11
12
|
tui?: TUI;
|
|
12
13
|
timeout?: number;
|
|
13
14
|
onTimeout?: () => void;
|
|
@@ -54,6 +55,9 @@ export class HookInputComponent extends Container {
|
|
|
54
55
|
}
|
|
55
56
|
|
|
56
57
|
this.#input = new Input();
|
|
58
|
+
if (opts?.initialValue) {
|
|
59
|
+
this.#input.setValue(opts.initialValue);
|
|
60
|
+
}
|
|
57
61
|
this.addChild(this.#input);
|
|
58
62
|
this.addChild(new Spacer(1));
|
|
59
63
|
this.addChild(new Text(theme.fg("dim", "enter submit esc cancel"), 1, 0));
|