@austinthesing/magic-shell 0.2.27 → 0.2.29
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/README.md +13 -8
- package/dist/cli.js +291 -45
- package/dist/tui.js +291 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -145,7 +145,7 @@ Launch with `mshell` for a full interactive experience.
|
|
|
145
145
|
|
|
146
146
|
### Keyboard Shortcuts
|
|
147
147
|
|
|
148
|
-
Magic Shell follows OpenCode-style TUI shortcuts where they
|
|
148
|
+
Magic Shell follows OpenCode-style TUI shortcuts where they fit cleanly:
|
|
149
149
|
|
|
150
150
|
| Shortcut | Action |
|
|
151
151
|
| ---------- | ---------------------- |
|
|
@@ -154,23 +154,28 @@ Magic Shell follows OpenCode-style TUI shortcuts where they map cleanly:
|
|
|
154
154
|
| `Ctrl+X T` | Change theme |
|
|
155
155
|
| `Ctrl+X Q` | Exit |
|
|
156
156
|
| `Ctrl+T` | Cycle thinking level |
|
|
157
|
-
| `Ctrl+C` | Exit /
|
|
157
|
+
| `Ctrl+C` | Exit, or cancel/close the active dialog first |
|
|
158
158
|
| `Ctrl+D` | Exit |
|
|
159
|
-
| `Esc` | Close dialogs
|
|
159
|
+
| `Esc` | Close dialogs or cancel pending actions |
|
|
160
160
|
|
|
161
|
-
###
|
|
161
|
+
### Slash Commands in TUI
|
|
162
162
|
|
|
163
|
-
|
|
163
|
+
Typing `/` opens a slash command menu under the prompt. Type to filter, use arrow keys to move, `Tab` to complete, and `Enter` to run the selected command.
|
|
164
|
+
|
|
165
|
+
You can also submit slash commands directly:
|
|
164
166
|
|
|
165
167
|
- `!help` or `/help` - Show help
|
|
166
|
-
- `!model` or `/
|
|
167
|
-
- `!provider` or `/
|
|
168
|
+
- `!model` or `/models` - Change model
|
|
169
|
+
- `!provider` or `/providers` - Switch provider
|
|
170
|
+
- `!theme` or `/themes` - Change theme
|
|
168
171
|
- `!dry` or `/dry` - Toggle dry-run mode
|
|
172
|
+
- `!thinking` or `/thinking` - Cycle thinking level
|
|
169
173
|
- `!config` or `/config` - Show current configuration
|
|
170
174
|
- `!history` or `/history` - Show command history
|
|
171
175
|
- `!clear` or `/clear` - Clear output
|
|
176
|
+
- `!exit` or `/exit` - Exit the TUI
|
|
172
177
|
|
|
173
|
-
|
|
178
|
+
Both `!` and `/` prefixes work for these commands.
|
|
174
179
|
|
|
175
180
|
## AI Providers
|
|
176
181
|
|
package/dist/cli.js
CHANGED
|
@@ -76817,6 +76817,10 @@ var inputHintText;
|
|
|
76817
76817
|
var helpBarText;
|
|
76818
76818
|
var modelSelector = null;
|
|
76819
76819
|
var providerSelector = null;
|
|
76820
|
+
var slashCommandMatches = [];
|
|
76821
|
+
var slashCommandSelectedIndex = 0;
|
|
76822
|
+
var slashCommandSyncQueued = false;
|
|
76823
|
+
var slashCommandExecuting = false;
|
|
76820
76824
|
var pendingMessageId = null;
|
|
76821
76825
|
var awaitingConfirmation = false;
|
|
76822
76826
|
function generateMessageId() {
|
|
@@ -77101,6 +77105,10 @@ function createMainUI() {
|
|
|
77101
77105
|
{ name: "j", ctrl: true, action: "newline" }
|
|
77102
77106
|
],
|
|
77103
77107
|
onSubmit: () => {
|
|
77108
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
77109
|
+
executeSelectedSlashCommand();
|
|
77110
|
+
return;
|
|
77111
|
+
}
|
|
77104
77112
|
const value = inputField.editBuffer.getText();
|
|
77105
77113
|
handleInput(value);
|
|
77106
77114
|
}
|
|
@@ -77119,6 +77127,7 @@ function createMainUI() {
|
|
|
77119
77127
|
});
|
|
77120
77128
|
mainContainer.add(helpBarText);
|
|
77121
77129
|
renderer.keyInput.on("keypress", handleKeypress);
|
|
77130
|
+
renderer.keyInput.on("keypress", queueSlashCommandSync);
|
|
77122
77131
|
inputField.focus();
|
|
77123
77132
|
}
|
|
77124
77133
|
function getStatusBarContent() {
|
|
@@ -77433,8 +77442,14 @@ async function handleInput(value) {
|
|
|
77433
77442
|
const input = value.trim();
|
|
77434
77443
|
if (!input)
|
|
77435
77444
|
return;
|
|
77445
|
+
if (input.startsWith("/") && await tryHandleSlashCommand(input)) {
|
|
77446
|
+
inputField.setText("");
|
|
77447
|
+
closeSlashCommandMenu();
|
|
77448
|
+
return;
|
|
77449
|
+
}
|
|
77436
77450
|
inputField.setText("");
|
|
77437
|
-
|
|
77451
|
+
closeSlashCommandMenu();
|
|
77452
|
+
if (input.startsWith("!")) {
|
|
77438
77453
|
await handleSpecialCommand(input);
|
|
77439
77454
|
return;
|
|
77440
77455
|
}
|
|
@@ -77445,6 +77460,25 @@ async function handleInput(value) {
|
|
|
77445
77460
|
}
|
|
77446
77461
|
await translateAndProcess(input);
|
|
77447
77462
|
}
|
|
77463
|
+
async function executeSelectedSlashCommand() {
|
|
77464
|
+
if (slashCommandExecuting || !slashCommandModal || slashCommandMatches.length === 0)
|
|
77465
|
+
return;
|
|
77466
|
+
slashCommandExecuting = true;
|
|
77467
|
+
try {
|
|
77468
|
+
const selected = slashCommandMatches[Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1)];
|
|
77469
|
+
inputField.setText("");
|
|
77470
|
+
closeSlashCommandMenu();
|
|
77471
|
+
await selected.action();
|
|
77472
|
+
} finally {
|
|
77473
|
+
slashCommandExecuting = false;
|
|
77474
|
+
}
|
|
77475
|
+
}
|
|
77476
|
+
async function tryHandleSlashCommand(input) {
|
|
77477
|
+
if (!input.startsWith("/"))
|
|
77478
|
+
return false;
|
|
77479
|
+
await handleSpecialCommand(input);
|
|
77480
|
+
return true;
|
|
77481
|
+
}
|
|
77448
77482
|
function isDirectCommand(input) {
|
|
77449
77483
|
const directCommands = ["ls", "pwd", "cd", "cat", "echo", "mkdir", "touch", "rm", "cp", "mv", "git", "npm", "bun", "node", "python", "pip", "brew", "apt", "docker", "kubectl"];
|
|
77450
77484
|
const firstWord = input.split(/\s+/)[0].toLowerCase();
|
|
@@ -77620,6 +77654,7 @@ async function handleSpecialCommand(input) {
|
|
|
77620
77654
|
}
|
|
77621
77655
|
}
|
|
77622
77656
|
function clearChat() {
|
|
77657
|
+
closeSlashCommandMenu();
|
|
77623
77658
|
for (const msg of chatMessages) {
|
|
77624
77659
|
chatScrollBox.remove(`msg-${msg.id}`);
|
|
77625
77660
|
}
|
|
@@ -77923,7 +77958,10 @@ function showThemeSelector() {
|
|
|
77923
77958
|
renderer.keyInput.on("keypress", escHandler);
|
|
77924
77959
|
themeSelector.focus();
|
|
77925
77960
|
}
|
|
77926
|
-
var
|
|
77961
|
+
var MODAL_LIST_WIDTH = 55;
|
|
77962
|
+
var MODAL_LIST_MAX_ITEMS = 12;
|
|
77963
|
+
var commandPaletteModal = null;
|
|
77964
|
+
var slashCommandModal = null;
|
|
77927
77965
|
var commandPaletteQuery = "";
|
|
77928
77966
|
var chordMode = "none";
|
|
77929
77967
|
function cycleThinkingLevel() {
|
|
@@ -78031,56 +78069,236 @@ function getCommandPaletteOptions() {
|
|
|
78031
78069
|
}
|
|
78032
78070
|
];
|
|
78033
78071
|
}
|
|
78034
|
-
function
|
|
78035
|
-
|
|
78036
|
-
|
|
78037
|
-
|
|
78038
|
-
|
|
78039
|
-
|
|
78040
|
-
|
|
78072
|
+
function getSlashCommands() {
|
|
78073
|
+
return [
|
|
78074
|
+
{
|
|
78075
|
+
slash: "help",
|
|
78076
|
+
name: "Help",
|
|
78077
|
+
description: "Show commands and shortcuts",
|
|
78078
|
+
action: () => showHelp()
|
|
78079
|
+
},
|
|
78080
|
+
{
|
|
78081
|
+
slash: "models",
|
|
78082
|
+
name: "Models",
|
|
78083
|
+
description: `Change model · ${currentModel.name}`,
|
|
78084
|
+
action: () => showModelSelector()
|
|
78085
|
+
},
|
|
78086
|
+
{
|
|
78087
|
+
slash: "providers",
|
|
78088
|
+
name: "Providers",
|
|
78089
|
+
description: `Switch provider · ${getProviderDisplayName(config2.provider)}`,
|
|
78090
|
+
action: () => switchProvider()
|
|
78091
|
+
},
|
|
78092
|
+
{
|
|
78093
|
+
slash: "themes",
|
|
78094
|
+
name: "Themes",
|
|
78095
|
+
description: `Change theme · ${getTheme().name}`,
|
|
78096
|
+
action: () => showThemeSelector()
|
|
78097
|
+
},
|
|
78098
|
+
{
|
|
78099
|
+
slash: "dry",
|
|
78100
|
+
name: "Dry Run",
|
|
78101
|
+
description: dryRunMode ? "Turn dry-run off" : "Turn dry-run on",
|
|
78102
|
+
action: () => {
|
|
78103
|
+
dryRunMode = !dryRunMode;
|
|
78104
|
+
statusBarText.content = getStatusBarContent();
|
|
78105
|
+
addSystemMessage(`Dry-run mode: ${dryRunMode ? "ON" : "OFF"}`);
|
|
78106
|
+
}
|
|
78107
|
+
},
|
|
78108
|
+
{
|
|
78109
|
+
slash: "thinking",
|
|
78110
|
+
name: "Thinking",
|
|
78111
|
+
description: `Cycle thinking level · ${config2.thinkingLevel}`,
|
|
78112
|
+
action: () => cycleThinkingLevel()
|
|
78113
|
+
},
|
|
78114
|
+
{
|
|
78115
|
+
slash: "config",
|
|
78116
|
+
name: "Config",
|
|
78117
|
+
description: "Show current configuration",
|
|
78118
|
+
action: () => showConfig()
|
|
78119
|
+
},
|
|
78120
|
+
{
|
|
78121
|
+
slash: "history",
|
|
78122
|
+
name: "History",
|
|
78123
|
+
description: `${history.length} commands`,
|
|
78124
|
+
action: () => showHistory()
|
|
78125
|
+
},
|
|
78126
|
+
{
|
|
78127
|
+
slash: "clear",
|
|
78128
|
+
name: "Clear",
|
|
78129
|
+
description: "Clear the chat history",
|
|
78130
|
+
action: () => clearChat()
|
|
78131
|
+
},
|
|
78132
|
+
{
|
|
78133
|
+
slash: "exit",
|
|
78134
|
+
name: "Exit",
|
|
78135
|
+
description: "Close magic-shell",
|
|
78136
|
+
action: () => {
|
|
78137
|
+
renderer.destroy();
|
|
78138
|
+
process.exit(0);
|
|
78139
|
+
}
|
|
78140
|
+
}
|
|
78141
|
+
];
|
|
78142
|
+
}
|
|
78143
|
+
function getSlashCommandMatches(inputText) {
|
|
78144
|
+
if (!inputText.startsWith("/"))
|
|
78145
|
+
return [];
|
|
78146
|
+
const slashBody = inputText.slice(1);
|
|
78147
|
+
if (slashBody.includes(" "))
|
|
78148
|
+
return [];
|
|
78149
|
+
const query = slashBody.trim().toLowerCase();
|
|
78150
|
+
return getSlashCommands().filter((cmd) => {
|
|
78151
|
+
if (!query)
|
|
78152
|
+
return true;
|
|
78153
|
+
return `${cmd.slash} ${cmd.name} ${cmd.description}`.toLowerCase().includes(query);
|
|
78154
|
+
});
|
|
78155
|
+
}
|
|
78156
|
+
function openModalList(config3) {
|
|
78157
|
+
const theme = getTheme();
|
|
78158
|
+
const width = MODAL_LIST_WIDTH;
|
|
78041
78159
|
const termWidth = process.stdout.columns || 80;
|
|
78042
|
-
const
|
|
78160
|
+
const left = Math.max(2, Math.floor((termWidth - width) / 2));
|
|
78161
|
+
const itemCount = Math.max(config3.options.length, 1);
|
|
78162
|
+
const listHeight = Math.min(itemCount + 2, MODAL_LIST_MAX_ITEMS);
|
|
78163
|
+
const containerHeight = listHeight + 2;
|
|
78043
78164
|
const container = new BoxRenderable(renderer, {
|
|
78044
|
-
id:
|
|
78165
|
+
id: config3.containerId,
|
|
78045
78166
|
position: "absolute",
|
|
78046
|
-
left
|
|
78167
|
+
left,
|
|
78047
78168
|
top: 3,
|
|
78048
|
-
width
|
|
78049
|
-
height:
|
|
78050
|
-
backgroundColor:
|
|
78169
|
+
width,
|
|
78170
|
+
height: containerHeight,
|
|
78171
|
+
backgroundColor: theme.colors.backgroundPanel,
|
|
78051
78172
|
border: true,
|
|
78052
|
-
borderColor:
|
|
78173
|
+
borderColor: theme.colors.primary,
|
|
78053
78174
|
borderStyle: "single",
|
|
78054
|
-
title:
|
|
78175
|
+
title: config3.title,
|
|
78055
78176
|
titleAlignment: "center",
|
|
78056
78177
|
zIndex: 200,
|
|
78057
78178
|
padding: 1
|
|
78058
78179
|
});
|
|
78059
78180
|
renderer.root.add(container);
|
|
78060
|
-
|
|
78061
|
-
id:
|
|
78181
|
+
const selector = new SelectRenderable(renderer, {
|
|
78182
|
+
id: config3.selectorId,
|
|
78062
78183
|
width: "100%",
|
|
78063
|
-
height:
|
|
78064
|
-
options:
|
|
78184
|
+
height: listHeight,
|
|
78185
|
+
options: config3.options,
|
|
78065
78186
|
backgroundColor: "transparent",
|
|
78066
78187
|
focusedBackgroundColor: "transparent",
|
|
78067
|
-
selectedBackgroundColor:
|
|
78068
|
-
textColor:
|
|
78069
|
-
selectedTextColor:
|
|
78070
|
-
descriptionColor:
|
|
78071
|
-
selectedDescriptionColor:
|
|
78188
|
+
selectedBackgroundColor: theme.colors.backgroundElement,
|
|
78189
|
+
textColor: theme.colors.text,
|
|
78190
|
+
selectedTextColor: theme.colors.primary,
|
|
78191
|
+
descriptionColor: theme.colors.textMuted,
|
|
78192
|
+
selectedDescriptionColor: theme.colors.textMuted,
|
|
78072
78193
|
showDescription: true,
|
|
78073
78194
|
wrapSelection: true
|
|
78074
78195
|
});
|
|
78075
|
-
container.add(
|
|
78076
|
-
|
|
78077
|
-
|
|
78078
|
-
|
|
78079
|
-
|
|
78080
|
-
|
|
78081
|
-
|
|
78196
|
+
container.add(selector);
|
|
78197
|
+
const handle = {
|
|
78198
|
+
containerId: config3.containerId,
|
|
78199
|
+
container,
|
|
78200
|
+
selector,
|
|
78201
|
+
updateOptions(options, selectedIndex = 0) {
|
|
78202
|
+
const count = Math.max(options.length, 1);
|
|
78203
|
+
const newListHeight = Math.min(count + 2, MODAL_LIST_MAX_ITEMS);
|
|
78204
|
+
selector.options = options;
|
|
78205
|
+
selector.height = newListHeight;
|
|
78206
|
+
container.height = newListHeight + 2;
|
|
78207
|
+
selector.setSelectedIndex(Math.min(selectedIndex, Math.max(options.length - 1, 0)));
|
|
78208
|
+
},
|
|
78209
|
+
setSelectedIndex(index) {
|
|
78210
|
+
selector.setSelectedIndex(index);
|
|
78211
|
+
},
|
|
78212
|
+
close() {
|
|
78213
|
+
renderer.root.remove(config3.containerId);
|
|
78214
|
+
inputField?.focus();
|
|
78215
|
+
}
|
|
78216
|
+
};
|
|
78217
|
+
if (config3.onSelect) {
|
|
78218
|
+
selector.on(SelectRenderableEvents.ITEM_SELECTED, async (index, option) => {
|
|
78219
|
+
await config3.onSelect?.(index, option);
|
|
78220
|
+
});
|
|
78221
|
+
}
|
|
78222
|
+
const initialIndex = config3.selectedIndex ?? 0;
|
|
78223
|
+
if (config3.focusList !== false) {
|
|
78224
|
+
selector.focus();
|
|
78225
|
+
} else {
|
|
78226
|
+
selector.setSelectedIndex(initialIndex);
|
|
78227
|
+
}
|
|
78228
|
+
return handle;
|
|
78229
|
+
}
|
|
78230
|
+
function getSlashCommandSelectOptions() {
|
|
78231
|
+
return slashCommandMatches.map((cmd) => ({
|
|
78232
|
+
name: `/${cmd.slash}`,
|
|
78233
|
+
description: cmd.description,
|
|
78234
|
+
value: cmd
|
|
78235
|
+
}));
|
|
78236
|
+
}
|
|
78237
|
+
function closeSlashCommandMenu() {
|
|
78238
|
+
if (slashCommandModal) {
|
|
78239
|
+
slashCommandModal.close();
|
|
78240
|
+
slashCommandModal = null;
|
|
78241
|
+
}
|
|
78242
|
+
slashCommandMatches = [];
|
|
78243
|
+
slashCommandSelectedIndex = 0;
|
|
78244
|
+
}
|
|
78245
|
+
function updateSlashCommandModalOptions() {
|
|
78246
|
+
if (!slashCommandModal)
|
|
78247
|
+
return;
|
|
78248
|
+
slashCommandModal.updateOptions(getSlashCommandSelectOptions(), slashCommandSelectedIndex);
|
|
78249
|
+
}
|
|
78250
|
+
function syncSlashCommandMenu() {
|
|
78251
|
+
const inputText = inputField.editBuffer.getText();
|
|
78252
|
+
const matches = getSlashCommandMatches(inputText);
|
|
78253
|
+
if (matches.length === 0) {
|
|
78254
|
+
closeSlashCommandMenu();
|
|
78255
|
+
return;
|
|
78256
|
+
}
|
|
78257
|
+
slashCommandMatches = matches;
|
|
78258
|
+
slashCommandSelectedIndex = Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1);
|
|
78259
|
+
const options = getSlashCommandSelectOptions();
|
|
78260
|
+
if (slashCommandModal) {
|
|
78261
|
+
slashCommandModal.updateOptions(options, slashCommandSelectedIndex);
|
|
78262
|
+
return;
|
|
78263
|
+
}
|
|
78264
|
+
slashCommandModal = openModalList({
|
|
78265
|
+
containerId: "slash-command-modal",
|
|
78266
|
+
selectorId: "slash-command-select",
|
|
78267
|
+
title: "Commands",
|
|
78268
|
+
options,
|
|
78269
|
+
focusList: false,
|
|
78270
|
+
selectedIndex: slashCommandSelectedIndex
|
|
78271
|
+
});
|
|
78272
|
+
}
|
|
78273
|
+
function queueSlashCommandSync() {
|
|
78274
|
+
if (slashCommandSyncQueued)
|
|
78275
|
+
return;
|
|
78276
|
+
slashCommandSyncQueued = true;
|
|
78277
|
+
setTimeout(() => {
|
|
78278
|
+
slashCommandSyncQueued = false;
|
|
78279
|
+
if (inputField)
|
|
78280
|
+
syncSlashCommandMenu();
|
|
78281
|
+
}, 0);
|
|
78282
|
+
}
|
|
78283
|
+
function showCommandPalette() {
|
|
78284
|
+
if (commandPaletteModal) {
|
|
78285
|
+
return;
|
|
78286
|
+
}
|
|
78287
|
+
commandPaletteQuery = "";
|
|
78288
|
+
commandPaletteModal = openModalList({
|
|
78289
|
+
containerId: "command-palette-container",
|
|
78290
|
+
selectorId: "command-palette-select",
|
|
78291
|
+
title: "Commands",
|
|
78292
|
+
options: getCommandPaletteSelectOptions(),
|
|
78293
|
+
focusList: true,
|
|
78294
|
+
onSelect: async (_2, option) => {
|
|
78295
|
+
if (!option.value)
|
|
78296
|
+
return;
|
|
78297
|
+
const cmd = option.value;
|
|
78298
|
+
closeCommandPalette();
|
|
78299
|
+
await cmd.action();
|
|
78300
|
+
}
|
|
78082
78301
|
});
|
|
78083
|
-
commandPalette.focus();
|
|
78084
78302
|
}
|
|
78085
78303
|
function getCommandPaletteSelectOptions() {
|
|
78086
78304
|
const query = commandPaletteQuery.toLowerCase();
|
|
@@ -78103,21 +78321,41 @@ function getCommandPaletteSelectOptions() {
|
|
|
78103
78321
|
}));
|
|
78104
78322
|
}
|
|
78105
78323
|
function updateCommandPaletteOptions() {
|
|
78106
|
-
if (!
|
|
78324
|
+
if (!commandPaletteModal)
|
|
78107
78325
|
return;
|
|
78108
|
-
|
|
78109
|
-
commandPalette.setSelectedIndex(0);
|
|
78326
|
+
commandPaletteModal.updateOptions(getCommandPaletteSelectOptions(), 0);
|
|
78110
78327
|
}
|
|
78111
78328
|
function closeCommandPalette() {
|
|
78112
|
-
if (
|
|
78113
|
-
|
|
78114
|
-
|
|
78329
|
+
if (commandPaletteModal) {
|
|
78330
|
+
commandPaletteModal.close();
|
|
78331
|
+
commandPaletteModal = null;
|
|
78115
78332
|
commandPaletteQuery = "";
|
|
78116
|
-
inputField?.focus();
|
|
78117
78333
|
}
|
|
78118
78334
|
}
|
|
78119
78335
|
function handleKeypress(key) {
|
|
78120
78336
|
const commands = getCommandPaletteOptions();
|
|
78337
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
78338
|
+
if (key.name === "up") {
|
|
78339
|
+
slashCommandSelectedIndex = slashCommandSelectedIndex === 0 ? slashCommandMatches.length - 1 : slashCommandSelectedIndex - 1;
|
|
78340
|
+
updateSlashCommandModalOptions();
|
|
78341
|
+
return;
|
|
78342
|
+
}
|
|
78343
|
+
if (key.name === "down") {
|
|
78344
|
+
slashCommandSelectedIndex = (slashCommandSelectedIndex + 1) % slashCommandMatches.length;
|
|
78345
|
+
updateSlashCommandModalOptions();
|
|
78346
|
+
return;
|
|
78347
|
+
}
|
|
78348
|
+
if (key.name === "tab") {
|
|
78349
|
+
inputField.setText(`/${slashCommandMatches[slashCommandSelectedIndex].slash}`);
|
|
78350
|
+
syncSlashCommandMenu();
|
|
78351
|
+
inputField.focus();
|
|
78352
|
+
return;
|
|
78353
|
+
}
|
|
78354
|
+
if (key.name === "return" && !key.shift && !key.ctrl && !key.meta) {
|
|
78355
|
+
executeSelectedSlashCommand();
|
|
78356
|
+
return;
|
|
78357
|
+
}
|
|
78358
|
+
}
|
|
78121
78359
|
if (key.ctrl && key.name === "p") {
|
|
78122
78360
|
showCommandPalette();
|
|
78123
78361
|
return;
|
|
@@ -78144,7 +78382,7 @@ function handleKeypress(key) {
|
|
|
78144
78382
|
}
|
|
78145
78383
|
return;
|
|
78146
78384
|
}
|
|
78147
|
-
if (
|
|
78385
|
+
if (commandPaletteModal) {
|
|
78148
78386
|
if (key.name === "backspace" || key.name === "delete") {
|
|
78149
78387
|
commandPaletteQuery = commandPaletteQuery.slice(0, -1);
|
|
78150
78388
|
updateCommandPaletteOptions();
|
|
@@ -78158,10 +78396,14 @@ function handleKeypress(key) {
|
|
|
78158
78396
|
}
|
|
78159
78397
|
}
|
|
78160
78398
|
if (key.ctrl && key.name === "c") {
|
|
78161
|
-
if (
|
|
78399
|
+
if (commandPaletteModal) {
|
|
78162
78400
|
closeCommandPalette();
|
|
78163
78401
|
return;
|
|
78164
78402
|
}
|
|
78403
|
+
if (slashCommandMatches.length > 0) {
|
|
78404
|
+
closeSlashCommandMenu();
|
|
78405
|
+
return;
|
|
78406
|
+
}
|
|
78165
78407
|
if (modelSelector) {
|
|
78166
78408
|
renderer.root.remove("model-selector-container");
|
|
78167
78409
|
modelSelector = null;
|
|
@@ -78185,10 +78427,14 @@ function handleKeypress(key) {
|
|
|
78185
78427
|
}
|
|
78186
78428
|
if (key.name === "escape") {
|
|
78187
78429
|
chordMode = "none";
|
|
78188
|
-
if (
|
|
78430
|
+
if (commandPaletteModal) {
|
|
78189
78431
|
closeCommandPalette();
|
|
78190
78432
|
return;
|
|
78191
78433
|
}
|
|
78434
|
+
if (slashCommandMatches.length > 0) {
|
|
78435
|
+
closeSlashCommandMenu();
|
|
78436
|
+
return;
|
|
78437
|
+
}
|
|
78192
78438
|
if (modelSelector) {
|
|
78193
78439
|
renderer.root.remove("model-selector-container");
|
|
78194
78440
|
modelSelector = null;
|
|
@@ -78228,7 +78474,7 @@ function handleKeypress(key) {
|
|
|
78228
78474
|
addSystemMessage(`Copied to clipboard: ${msg.command}`);
|
|
78229
78475
|
}
|
|
78230
78476
|
}
|
|
78231
|
-
if (key.name === "o" && !awaitingConfirmation && !
|
|
78477
|
+
if (key.name === "o" && !awaitingConfirmation && !commandPaletteModal && !modelSelector) {
|
|
78232
78478
|
toggleLastResultExpand();
|
|
78233
78479
|
}
|
|
78234
78480
|
}
|
package/dist/tui.js
CHANGED
|
@@ -76817,6 +76817,10 @@ var inputHintText;
|
|
|
76817
76817
|
var helpBarText;
|
|
76818
76818
|
var modelSelector = null;
|
|
76819
76819
|
var providerSelector = null;
|
|
76820
|
+
var slashCommandMatches = [];
|
|
76821
|
+
var slashCommandSelectedIndex = 0;
|
|
76822
|
+
var slashCommandSyncQueued = false;
|
|
76823
|
+
var slashCommandExecuting = false;
|
|
76820
76824
|
var pendingMessageId = null;
|
|
76821
76825
|
var awaitingConfirmation = false;
|
|
76822
76826
|
function generateMessageId() {
|
|
@@ -77101,6 +77105,10 @@ function createMainUI() {
|
|
|
77101
77105
|
{ name: "j", ctrl: true, action: "newline" }
|
|
77102
77106
|
],
|
|
77103
77107
|
onSubmit: () => {
|
|
77108
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
77109
|
+
executeSelectedSlashCommand();
|
|
77110
|
+
return;
|
|
77111
|
+
}
|
|
77104
77112
|
const value = inputField.editBuffer.getText();
|
|
77105
77113
|
handleInput(value);
|
|
77106
77114
|
}
|
|
@@ -77119,6 +77127,7 @@ function createMainUI() {
|
|
|
77119
77127
|
});
|
|
77120
77128
|
mainContainer.add(helpBarText);
|
|
77121
77129
|
renderer.keyInput.on("keypress", handleKeypress);
|
|
77130
|
+
renderer.keyInput.on("keypress", queueSlashCommandSync);
|
|
77122
77131
|
inputField.focus();
|
|
77123
77132
|
}
|
|
77124
77133
|
function getStatusBarContent() {
|
|
@@ -77433,8 +77442,14 @@ async function handleInput(value) {
|
|
|
77433
77442
|
const input = value.trim();
|
|
77434
77443
|
if (!input)
|
|
77435
77444
|
return;
|
|
77445
|
+
if (input.startsWith("/") && await tryHandleSlashCommand(input)) {
|
|
77446
|
+
inputField.setText("");
|
|
77447
|
+
closeSlashCommandMenu();
|
|
77448
|
+
return;
|
|
77449
|
+
}
|
|
77436
77450
|
inputField.setText("");
|
|
77437
|
-
|
|
77451
|
+
closeSlashCommandMenu();
|
|
77452
|
+
if (input.startsWith("!")) {
|
|
77438
77453
|
await handleSpecialCommand(input);
|
|
77439
77454
|
return;
|
|
77440
77455
|
}
|
|
@@ -77445,6 +77460,25 @@ async function handleInput(value) {
|
|
|
77445
77460
|
}
|
|
77446
77461
|
await translateAndProcess(input);
|
|
77447
77462
|
}
|
|
77463
|
+
async function executeSelectedSlashCommand() {
|
|
77464
|
+
if (slashCommandExecuting || !slashCommandModal || slashCommandMatches.length === 0)
|
|
77465
|
+
return;
|
|
77466
|
+
slashCommandExecuting = true;
|
|
77467
|
+
try {
|
|
77468
|
+
const selected = slashCommandMatches[Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1)];
|
|
77469
|
+
inputField.setText("");
|
|
77470
|
+
closeSlashCommandMenu();
|
|
77471
|
+
await selected.action();
|
|
77472
|
+
} finally {
|
|
77473
|
+
slashCommandExecuting = false;
|
|
77474
|
+
}
|
|
77475
|
+
}
|
|
77476
|
+
async function tryHandleSlashCommand(input) {
|
|
77477
|
+
if (!input.startsWith("/"))
|
|
77478
|
+
return false;
|
|
77479
|
+
await handleSpecialCommand(input);
|
|
77480
|
+
return true;
|
|
77481
|
+
}
|
|
77448
77482
|
function isDirectCommand(input) {
|
|
77449
77483
|
const directCommands = ["ls", "pwd", "cd", "cat", "echo", "mkdir", "touch", "rm", "cp", "mv", "git", "npm", "bun", "node", "python", "pip", "brew", "apt", "docker", "kubectl"];
|
|
77450
77484
|
const firstWord = input.split(/\s+/)[0].toLowerCase();
|
|
@@ -77620,6 +77654,7 @@ async function handleSpecialCommand(input) {
|
|
|
77620
77654
|
}
|
|
77621
77655
|
}
|
|
77622
77656
|
function clearChat() {
|
|
77657
|
+
closeSlashCommandMenu();
|
|
77623
77658
|
for (const msg of chatMessages) {
|
|
77624
77659
|
chatScrollBox.remove(`msg-${msg.id}`);
|
|
77625
77660
|
}
|
|
@@ -77923,7 +77958,10 @@ function showThemeSelector() {
|
|
|
77923
77958
|
renderer.keyInput.on("keypress", escHandler);
|
|
77924
77959
|
themeSelector.focus();
|
|
77925
77960
|
}
|
|
77926
|
-
var
|
|
77961
|
+
var MODAL_LIST_WIDTH = 55;
|
|
77962
|
+
var MODAL_LIST_MAX_ITEMS = 12;
|
|
77963
|
+
var commandPaletteModal = null;
|
|
77964
|
+
var slashCommandModal = null;
|
|
77927
77965
|
var commandPaletteQuery = "";
|
|
77928
77966
|
var chordMode = "none";
|
|
77929
77967
|
function cycleThinkingLevel() {
|
|
@@ -78031,56 +78069,236 @@ function getCommandPaletteOptions() {
|
|
|
78031
78069
|
}
|
|
78032
78070
|
];
|
|
78033
78071
|
}
|
|
78034
|
-
function
|
|
78035
|
-
|
|
78036
|
-
|
|
78037
|
-
|
|
78038
|
-
|
|
78039
|
-
|
|
78040
|
-
|
|
78072
|
+
function getSlashCommands() {
|
|
78073
|
+
return [
|
|
78074
|
+
{
|
|
78075
|
+
slash: "help",
|
|
78076
|
+
name: "Help",
|
|
78077
|
+
description: "Show commands and shortcuts",
|
|
78078
|
+
action: () => showHelp()
|
|
78079
|
+
},
|
|
78080
|
+
{
|
|
78081
|
+
slash: "models",
|
|
78082
|
+
name: "Models",
|
|
78083
|
+
description: `Change model · ${currentModel.name}`,
|
|
78084
|
+
action: () => showModelSelector()
|
|
78085
|
+
},
|
|
78086
|
+
{
|
|
78087
|
+
slash: "providers",
|
|
78088
|
+
name: "Providers",
|
|
78089
|
+
description: `Switch provider · ${getProviderDisplayName(config2.provider)}`,
|
|
78090
|
+
action: () => switchProvider()
|
|
78091
|
+
},
|
|
78092
|
+
{
|
|
78093
|
+
slash: "themes",
|
|
78094
|
+
name: "Themes",
|
|
78095
|
+
description: `Change theme · ${getTheme().name}`,
|
|
78096
|
+
action: () => showThemeSelector()
|
|
78097
|
+
},
|
|
78098
|
+
{
|
|
78099
|
+
slash: "dry",
|
|
78100
|
+
name: "Dry Run",
|
|
78101
|
+
description: dryRunMode ? "Turn dry-run off" : "Turn dry-run on",
|
|
78102
|
+
action: () => {
|
|
78103
|
+
dryRunMode = !dryRunMode;
|
|
78104
|
+
statusBarText.content = getStatusBarContent();
|
|
78105
|
+
addSystemMessage(`Dry-run mode: ${dryRunMode ? "ON" : "OFF"}`);
|
|
78106
|
+
}
|
|
78107
|
+
},
|
|
78108
|
+
{
|
|
78109
|
+
slash: "thinking",
|
|
78110
|
+
name: "Thinking",
|
|
78111
|
+
description: `Cycle thinking level · ${config2.thinkingLevel}`,
|
|
78112
|
+
action: () => cycleThinkingLevel()
|
|
78113
|
+
},
|
|
78114
|
+
{
|
|
78115
|
+
slash: "config",
|
|
78116
|
+
name: "Config",
|
|
78117
|
+
description: "Show current configuration",
|
|
78118
|
+
action: () => showConfig()
|
|
78119
|
+
},
|
|
78120
|
+
{
|
|
78121
|
+
slash: "history",
|
|
78122
|
+
name: "History",
|
|
78123
|
+
description: `${history.length} commands`,
|
|
78124
|
+
action: () => showHistory()
|
|
78125
|
+
},
|
|
78126
|
+
{
|
|
78127
|
+
slash: "clear",
|
|
78128
|
+
name: "Clear",
|
|
78129
|
+
description: "Clear the chat history",
|
|
78130
|
+
action: () => clearChat()
|
|
78131
|
+
},
|
|
78132
|
+
{
|
|
78133
|
+
slash: "exit",
|
|
78134
|
+
name: "Exit",
|
|
78135
|
+
description: "Close magic-shell",
|
|
78136
|
+
action: () => {
|
|
78137
|
+
renderer.destroy();
|
|
78138
|
+
process.exit(0);
|
|
78139
|
+
}
|
|
78140
|
+
}
|
|
78141
|
+
];
|
|
78142
|
+
}
|
|
78143
|
+
function getSlashCommandMatches(inputText) {
|
|
78144
|
+
if (!inputText.startsWith("/"))
|
|
78145
|
+
return [];
|
|
78146
|
+
const slashBody = inputText.slice(1);
|
|
78147
|
+
if (slashBody.includes(" "))
|
|
78148
|
+
return [];
|
|
78149
|
+
const query = slashBody.trim().toLowerCase();
|
|
78150
|
+
return getSlashCommands().filter((cmd) => {
|
|
78151
|
+
if (!query)
|
|
78152
|
+
return true;
|
|
78153
|
+
return `${cmd.slash} ${cmd.name} ${cmd.description}`.toLowerCase().includes(query);
|
|
78154
|
+
});
|
|
78155
|
+
}
|
|
78156
|
+
function openModalList(config3) {
|
|
78157
|
+
const theme = getTheme();
|
|
78158
|
+
const width = MODAL_LIST_WIDTH;
|
|
78041
78159
|
const termWidth = process.stdout.columns || 80;
|
|
78042
|
-
const
|
|
78160
|
+
const left = Math.max(2, Math.floor((termWidth - width) / 2));
|
|
78161
|
+
const itemCount = Math.max(config3.options.length, 1);
|
|
78162
|
+
const listHeight = Math.min(itemCount + 2, MODAL_LIST_MAX_ITEMS);
|
|
78163
|
+
const containerHeight = listHeight + 2;
|
|
78043
78164
|
const container = new BoxRenderable(renderer, {
|
|
78044
|
-
id:
|
|
78165
|
+
id: config3.containerId,
|
|
78045
78166
|
position: "absolute",
|
|
78046
|
-
left
|
|
78167
|
+
left,
|
|
78047
78168
|
top: 3,
|
|
78048
|
-
width
|
|
78049
|
-
height:
|
|
78050
|
-
backgroundColor:
|
|
78169
|
+
width,
|
|
78170
|
+
height: containerHeight,
|
|
78171
|
+
backgroundColor: theme.colors.backgroundPanel,
|
|
78051
78172
|
border: true,
|
|
78052
|
-
borderColor:
|
|
78173
|
+
borderColor: theme.colors.primary,
|
|
78053
78174
|
borderStyle: "single",
|
|
78054
|
-
title:
|
|
78175
|
+
title: config3.title,
|
|
78055
78176
|
titleAlignment: "center",
|
|
78056
78177
|
zIndex: 200,
|
|
78057
78178
|
padding: 1
|
|
78058
78179
|
});
|
|
78059
78180
|
renderer.root.add(container);
|
|
78060
|
-
|
|
78061
|
-
id:
|
|
78181
|
+
const selector = new SelectRenderable(renderer, {
|
|
78182
|
+
id: config3.selectorId,
|
|
78062
78183
|
width: "100%",
|
|
78063
|
-
height:
|
|
78064
|
-
options:
|
|
78184
|
+
height: listHeight,
|
|
78185
|
+
options: config3.options,
|
|
78065
78186
|
backgroundColor: "transparent",
|
|
78066
78187
|
focusedBackgroundColor: "transparent",
|
|
78067
|
-
selectedBackgroundColor:
|
|
78068
|
-
textColor:
|
|
78069
|
-
selectedTextColor:
|
|
78070
|
-
descriptionColor:
|
|
78071
|
-
selectedDescriptionColor:
|
|
78188
|
+
selectedBackgroundColor: theme.colors.backgroundElement,
|
|
78189
|
+
textColor: theme.colors.text,
|
|
78190
|
+
selectedTextColor: theme.colors.primary,
|
|
78191
|
+
descriptionColor: theme.colors.textMuted,
|
|
78192
|
+
selectedDescriptionColor: theme.colors.textMuted,
|
|
78072
78193
|
showDescription: true,
|
|
78073
78194
|
wrapSelection: true
|
|
78074
78195
|
});
|
|
78075
|
-
container.add(
|
|
78076
|
-
|
|
78077
|
-
|
|
78078
|
-
|
|
78079
|
-
|
|
78080
|
-
|
|
78081
|
-
|
|
78196
|
+
container.add(selector);
|
|
78197
|
+
const handle = {
|
|
78198
|
+
containerId: config3.containerId,
|
|
78199
|
+
container,
|
|
78200
|
+
selector,
|
|
78201
|
+
updateOptions(options, selectedIndex = 0) {
|
|
78202
|
+
const count = Math.max(options.length, 1);
|
|
78203
|
+
const newListHeight = Math.min(count + 2, MODAL_LIST_MAX_ITEMS);
|
|
78204
|
+
selector.options = options;
|
|
78205
|
+
selector.height = newListHeight;
|
|
78206
|
+
container.height = newListHeight + 2;
|
|
78207
|
+
selector.setSelectedIndex(Math.min(selectedIndex, Math.max(options.length - 1, 0)));
|
|
78208
|
+
},
|
|
78209
|
+
setSelectedIndex(index) {
|
|
78210
|
+
selector.setSelectedIndex(index);
|
|
78211
|
+
},
|
|
78212
|
+
close() {
|
|
78213
|
+
renderer.root.remove(config3.containerId);
|
|
78214
|
+
inputField?.focus();
|
|
78215
|
+
}
|
|
78216
|
+
};
|
|
78217
|
+
if (config3.onSelect) {
|
|
78218
|
+
selector.on(SelectRenderableEvents.ITEM_SELECTED, async (index, option) => {
|
|
78219
|
+
await config3.onSelect?.(index, option);
|
|
78220
|
+
});
|
|
78221
|
+
}
|
|
78222
|
+
const initialIndex = config3.selectedIndex ?? 0;
|
|
78223
|
+
if (config3.focusList !== false) {
|
|
78224
|
+
selector.focus();
|
|
78225
|
+
} else {
|
|
78226
|
+
selector.setSelectedIndex(initialIndex);
|
|
78227
|
+
}
|
|
78228
|
+
return handle;
|
|
78229
|
+
}
|
|
78230
|
+
function getSlashCommandSelectOptions() {
|
|
78231
|
+
return slashCommandMatches.map((cmd) => ({
|
|
78232
|
+
name: `/${cmd.slash}`,
|
|
78233
|
+
description: cmd.description,
|
|
78234
|
+
value: cmd
|
|
78235
|
+
}));
|
|
78236
|
+
}
|
|
78237
|
+
function closeSlashCommandMenu() {
|
|
78238
|
+
if (slashCommandModal) {
|
|
78239
|
+
slashCommandModal.close();
|
|
78240
|
+
slashCommandModal = null;
|
|
78241
|
+
}
|
|
78242
|
+
slashCommandMatches = [];
|
|
78243
|
+
slashCommandSelectedIndex = 0;
|
|
78244
|
+
}
|
|
78245
|
+
function updateSlashCommandModalOptions() {
|
|
78246
|
+
if (!slashCommandModal)
|
|
78247
|
+
return;
|
|
78248
|
+
slashCommandModal.updateOptions(getSlashCommandSelectOptions(), slashCommandSelectedIndex);
|
|
78249
|
+
}
|
|
78250
|
+
function syncSlashCommandMenu() {
|
|
78251
|
+
const inputText = inputField.editBuffer.getText();
|
|
78252
|
+
const matches = getSlashCommandMatches(inputText);
|
|
78253
|
+
if (matches.length === 0) {
|
|
78254
|
+
closeSlashCommandMenu();
|
|
78255
|
+
return;
|
|
78256
|
+
}
|
|
78257
|
+
slashCommandMatches = matches;
|
|
78258
|
+
slashCommandSelectedIndex = Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1);
|
|
78259
|
+
const options = getSlashCommandSelectOptions();
|
|
78260
|
+
if (slashCommandModal) {
|
|
78261
|
+
slashCommandModal.updateOptions(options, slashCommandSelectedIndex);
|
|
78262
|
+
return;
|
|
78263
|
+
}
|
|
78264
|
+
slashCommandModal = openModalList({
|
|
78265
|
+
containerId: "slash-command-modal",
|
|
78266
|
+
selectorId: "slash-command-select",
|
|
78267
|
+
title: "Commands",
|
|
78268
|
+
options,
|
|
78269
|
+
focusList: false,
|
|
78270
|
+
selectedIndex: slashCommandSelectedIndex
|
|
78271
|
+
});
|
|
78272
|
+
}
|
|
78273
|
+
function queueSlashCommandSync() {
|
|
78274
|
+
if (slashCommandSyncQueued)
|
|
78275
|
+
return;
|
|
78276
|
+
slashCommandSyncQueued = true;
|
|
78277
|
+
setTimeout(() => {
|
|
78278
|
+
slashCommandSyncQueued = false;
|
|
78279
|
+
if (inputField)
|
|
78280
|
+
syncSlashCommandMenu();
|
|
78281
|
+
}, 0);
|
|
78282
|
+
}
|
|
78283
|
+
function showCommandPalette() {
|
|
78284
|
+
if (commandPaletteModal) {
|
|
78285
|
+
return;
|
|
78286
|
+
}
|
|
78287
|
+
commandPaletteQuery = "";
|
|
78288
|
+
commandPaletteModal = openModalList({
|
|
78289
|
+
containerId: "command-palette-container",
|
|
78290
|
+
selectorId: "command-palette-select",
|
|
78291
|
+
title: "Commands",
|
|
78292
|
+
options: getCommandPaletteSelectOptions(),
|
|
78293
|
+
focusList: true,
|
|
78294
|
+
onSelect: async (_2, option) => {
|
|
78295
|
+
if (!option.value)
|
|
78296
|
+
return;
|
|
78297
|
+
const cmd = option.value;
|
|
78298
|
+
closeCommandPalette();
|
|
78299
|
+
await cmd.action();
|
|
78300
|
+
}
|
|
78082
78301
|
});
|
|
78083
|
-
commandPalette.focus();
|
|
78084
78302
|
}
|
|
78085
78303
|
function getCommandPaletteSelectOptions() {
|
|
78086
78304
|
const query = commandPaletteQuery.toLowerCase();
|
|
@@ -78103,21 +78321,41 @@ function getCommandPaletteSelectOptions() {
|
|
|
78103
78321
|
}));
|
|
78104
78322
|
}
|
|
78105
78323
|
function updateCommandPaletteOptions() {
|
|
78106
|
-
if (!
|
|
78324
|
+
if (!commandPaletteModal)
|
|
78107
78325
|
return;
|
|
78108
|
-
|
|
78109
|
-
commandPalette.setSelectedIndex(0);
|
|
78326
|
+
commandPaletteModal.updateOptions(getCommandPaletteSelectOptions(), 0);
|
|
78110
78327
|
}
|
|
78111
78328
|
function closeCommandPalette() {
|
|
78112
|
-
if (
|
|
78113
|
-
|
|
78114
|
-
|
|
78329
|
+
if (commandPaletteModal) {
|
|
78330
|
+
commandPaletteModal.close();
|
|
78331
|
+
commandPaletteModal = null;
|
|
78115
78332
|
commandPaletteQuery = "";
|
|
78116
|
-
inputField?.focus();
|
|
78117
78333
|
}
|
|
78118
78334
|
}
|
|
78119
78335
|
function handleKeypress(key) {
|
|
78120
78336
|
const commands = getCommandPaletteOptions();
|
|
78337
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
78338
|
+
if (key.name === "up") {
|
|
78339
|
+
slashCommandSelectedIndex = slashCommandSelectedIndex === 0 ? slashCommandMatches.length - 1 : slashCommandSelectedIndex - 1;
|
|
78340
|
+
updateSlashCommandModalOptions();
|
|
78341
|
+
return;
|
|
78342
|
+
}
|
|
78343
|
+
if (key.name === "down") {
|
|
78344
|
+
slashCommandSelectedIndex = (slashCommandSelectedIndex + 1) % slashCommandMatches.length;
|
|
78345
|
+
updateSlashCommandModalOptions();
|
|
78346
|
+
return;
|
|
78347
|
+
}
|
|
78348
|
+
if (key.name === "tab") {
|
|
78349
|
+
inputField.setText(`/${slashCommandMatches[slashCommandSelectedIndex].slash}`);
|
|
78350
|
+
syncSlashCommandMenu();
|
|
78351
|
+
inputField.focus();
|
|
78352
|
+
return;
|
|
78353
|
+
}
|
|
78354
|
+
if (key.name === "return" && !key.shift && !key.ctrl && !key.meta) {
|
|
78355
|
+
executeSelectedSlashCommand();
|
|
78356
|
+
return;
|
|
78357
|
+
}
|
|
78358
|
+
}
|
|
78121
78359
|
if (key.ctrl && key.name === "p") {
|
|
78122
78360
|
showCommandPalette();
|
|
78123
78361
|
return;
|
|
@@ -78144,7 +78382,7 @@ function handleKeypress(key) {
|
|
|
78144
78382
|
}
|
|
78145
78383
|
return;
|
|
78146
78384
|
}
|
|
78147
|
-
if (
|
|
78385
|
+
if (commandPaletteModal) {
|
|
78148
78386
|
if (key.name === "backspace" || key.name === "delete") {
|
|
78149
78387
|
commandPaletteQuery = commandPaletteQuery.slice(0, -1);
|
|
78150
78388
|
updateCommandPaletteOptions();
|
|
@@ -78158,10 +78396,14 @@ function handleKeypress(key) {
|
|
|
78158
78396
|
}
|
|
78159
78397
|
}
|
|
78160
78398
|
if (key.ctrl && key.name === "c") {
|
|
78161
|
-
if (
|
|
78399
|
+
if (commandPaletteModal) {
|
|
78162
78400
|
closeCommandPalette();
|
|
78163
78401
|
return;
|
|
78164
78402
|
}
|
|
78403
|
+
if (slashCommandMatches.length > 0) {
|
|
78404
|
+
closeSlashCommandMenu();
|
|
78405
|
+
return;
|
|
78406
|
+
}
|
|
78165
78407
|
if (modelSelector) {
|
|
78166
78408
|
renderer.root.remove("model-selector-container");
|
|
78167
78409
|
modelSelector = null;
|
|
@@ -78185,10 +78427,14 @@ function handleKeypress(key) {
|
|
|
78185
78427
|
}
|
|
78186
78428
|
if (key.name === "escape") {
|
|
78187
78429
|
chordMode = "none";
|
|
78188
|
-
if (
|
|
78430
|
+
if (commandPaletteModal) {
|
|
78189
78431
|
closeCommandPalette();
|
|
78190
78432
|
return;
|
|
78191
78433
|
}
|
|
78434
|
+
if (slashCommandMatches.length > 0) {
|
|
78435
|
+
closeSlashCommandMenu();
|
|
78436
|
+
return;
|
|
78437
|
+
}
|
|
78192
78438
|
if (modelSelector) {
|
|
78193
78439
|
renderer.root.remove("model-selector-container");
|
|
78194
78440
|
modelSelector = null;
|
|
@@ -78228,7 +78474,7 @@ function handleKeypress(key) {
|
|
|
78228
78474
|
addSystemMessage(`Copied to clipboard: ${msg.command}`);
|
|
78229
78475
|
}
|
|
78230
78476
|
}
|
|
78231
|
-
if (key.name === "o" && !awaitingConfirmation && !
|
|
78477
|
+
if (key.name === "o" && !awaitingConfirmation && !commandPaletteModal && !modelSelector) {
|
|
78232
78478
|
toggleLastResultExpand();
|
|
78233
78479
|
}
|
|
78234
78480
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@austinthesing/magic-shell",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.29",
|
|
4
4
|
"description": "Natural language to terminal commands with safety features. Supports OpenCode Zen, OpenRouter, AI gateways, Workers AI, and custom models.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|