@austinthesing/magic-shell 0.2.28 → 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/dist/cli.js +141 -115
- package/dist/tui.js +141 -115
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -76817,11 +76817,10 @@ var inputHintText;
|
|
|
76817
76817
|
var helpBarText;
|
|
76818
76818
|
var modelSelector = null;
|
|
76819
76819
|
var providerSelector = null;
|
|
76820
|
-
var slashCommandContainer = null;
|
|
76821
|
-
var slashCommandSelector = null;
|
|
76822
76820
|
var slashCommandMatches = [];
|
|
76823
76821
|
var slashCommandSelectedIndex = 0;
|
|
76824
76822
|
var slashCommandSyncQueued = false;
|
|
76823
|
+
var slashCommandExecuting = false;
|
|
76825
76824
|
var pendingMessageId = null;
|
|
76826
76825
|
var awaitingConfirmation = false;
|
|
76827
76826
|
function generateMessageId() {
|
|
@@ -77106,6 +77105,10 @@ function createMainUI() {
|
|
|
77106
77105
|
{ name: "j", ctrl: true, action: "newline" }
|
|
77107
77106
|
],
|
|
77108
77107
|
onSubmit: () => {
|
|
77108
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
77109
|
+
executeSelectedSlashCommand();
|
|
77110
|
+
return;
|
|
77111
|
+
}
|
|
77109
77112
|
const value = inputField.editBuffer.getText();
|
|
77110
77113
|
handleInput(value);
|
|
77111
77114
|
}
|
|
@@ -77434,27 +77437,18 @@ function refreshThemeColors() {
|
|
|
77434
77437
|
if (inputHintText) {
|
|
77435
77438
|
inputHintText.content = getInputHintContent();
|
|
77436
77439
|
}
|
|
77437
|
-
if (slashCommandContainer) {
|
|
77438
|
-
slashCommandContainer.borderColor = theme.colors.border;
|
|
77439
|
-
slashCommandContainer.backgroundColor = theme.colors.backgroundPanel;
|
|
77440
|
-
}
|
|
77441
|
-
if (slashCommandSelector) {
|
|
77442
|
-
slashCommandSelector.selectedBackgroundColor = theme.colors.backgroundElement;
|
|
77443
|
-
slashCommandSelector.textColor = theme.colors.text;
|
|
77444
|
-
slashCommandSelector.selectedTextColor = theme.colors.primary;
|
|
77445
|
-
slashCommandSelector.descriptionColor = theme.colors.textMuted;
|
|
77446
|
-
slashCommandSelector.selectedDescriptionColor = theme.colors.textMuted;
|
|
77447
|
-
}
|
|
77448
77440
|
}
|
|
77449
77441
|
async function handleInput(value) {
|
|
77450
77442
|
const input = value.trim();
|
|
77451
77443
|
if (!input)
|
|
77452
77444
|
return;
|
|
77453
|
-
inputField.setText("");
|
|
77454
|
-
closeSlashCommandMenu();
|
|
77455
77445
|
if (input.startsWith("/") && await tryHandleSlashCommand(input)) {
|
|
77446
|
+
inputField.setText("");
|
|
77447
|
+
closeSlashCommandMenu();
|
|
77456
77448
|
return;
|
|
77457
77449
|
}
|
|
77450
|
+
inputField.setText("");
|
|
77451
|
+
closeSlashCommandMenu();
|
|
77458
77452
|
if (input.startsWith("!")) {
|
|
77459
77453
|
await handleSpecialCommand(input);
|
|
77460
77454
|
return;
|
|
@@ -77466,15 +77460,22 @@ async function handleInput(value) {
|
|
|
77466
77460
|
}
|
|
77467
77461
|
await translateAndProcess(input);
|
|
77468
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
|
+
}
|
|
77469
77476
|
async function tryHandleSlashCommand(input) {
|
|
77470
77477
|
if (!input.startsWith("/"))
|
|
77471
77478
|
return false;
|
|
77472
|
-
const slashBody = input.slice(1).trim();
|
|
77473
|
-
if (!slashBody.includes(" ") && slashCommandMatches.length > 0) {
|
|
77474
|
-
const selected = slashCommandMatches[Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1)];
|
|
77475
|
-
await handleSpecialCommand(`/${selected.slash}`);
|
|
77476
|
-
return true;
|
|
77477
|
-
}
|
|
77478
77479
|
await handleSpecialCommand(input);
|
|
77479
77480
|
return true;
|
|
77480
77481
|
}
|
|
@@ -77957,7 +77958,10 @@ function showThemeSelector() {
|
|
|
77957
77958
|
renderer.keyInput.on("keypress", escHandler);
|
|
77958
77959
|
themeSelector.focus();
|
|
77959
77960
|
}
|
|
77960
|
-
var
|
|
77961
|
+
var MODAL_LIST_WIDTH = 55;
|
|
77962
|
+
var MODAL_LIST_MAX_ITEMS = 12;
|
|
77963
|
+
var commandPaletteModal = null;
|
|
77964
|
+
var slashCommandModal = null;
|
|
77961
77965
|
var commandPaletteQuery = "";
|
|
77962
77966
|
var chordMode = "none";
|
|
77963
77967
|
function cycleThinkingLevel() {
|
|
@@ -78149,60 +78153,100 @@ function getSlashCommandMatches(inputText) {
|
|
|
78149
78153
|
return `${cmd.slash} ${cmd.name} ${cmd.description}`.toLowerCase().includes(query);
|
|
78150
78154
|
});
|
|
78151
78155
|
}
|
|
78152
|
-
function
|
|
78153
|
-
|
|
78154
|
-
|
|
78155
|
-
|
|
78156
|
-
|
|
78157
|
-
|
|
78156
|
+
function openModalList(config3) {
|
|
78157
|
+
const theme = getTheme();
|
|
78158
|
+
const width = MODAL_LIST_WIDTH;
|
|
78159
|
+
const termWidth = process.stdout.columns || 80;
|
|
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;
|
|
78164
|
+
const container = new BoxRenderable(renderer, {
|
|
78165
|
+
id: config3.containerId,
|
|
78166
|
+
position: "absolute",
|
|
78167
|
+
left,
|
|
78168
|
+
top: 3,
|
|
78169
|
+
width,
|
|
78170
|
+
height: containerHeight,
|
|
78171
|
+
backgroundColor: theme.colors.backgroundPanel,
|
|
78158
78172
|
border: true,
|
|
78159
|
-
borderColor:
|
|
78173
|
+
borderColor: theme.colors.primary,
|
|
78160
78174
|
borderStyle: "single",
|
|
78161
|
-
|
|
78162
|
-
|
|
78163
|
-
|
|
78164
|
-
|
|
78165
|
-
paddingBottom: 0,
|
|
78166
|
-
marginTop: 1
|
|
78175
|
+
title: config3.title,
|
|
78176
|
+
titleAlignment: "center",
|
|
78177
|
+
zIndex: 200,
|
|
78178
|
+
padding: 1
|
|
78167
78179
|
});
|
|
78168
|
-
|
|
78169
|
-
|
|
78170
|
-
id:
|
|
78180
|
+
renderer.root.add(container);
|
|
78181
|
+
const selector = new SelectRenderable(renderer, {
|
|
78182
|
+
id: config3.selectorId,
|
|
78171
78183
|
width: "100%",
|
|
78172
|
-
height:
|
|
78173
|
-
options:
|
|
78184
|
+
height: listHeight,
|
|
78185
|
+
options: config3.options,
|
|
78174
78186
|
backgroundColor: "transparent",
|
|
78175
78187
|
focusedBackgroundColor: "transparent",
|
|
78176
|
-
selectedBackgroundColor:
|
|
78177
|
-
textColor:
|
|
78178
|
-
selectedTextColor:
|
|
78179
|
-
descriptionColor:
|
|
78180
|
-
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,
|
|
78181
78193
|
showDescription: true,
|
|
78182
78194
|
wrapSelection: true
|
|
78183
78195
|
});
|
|
78184
|
-
|
|
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;
|
|
78185
78229
|
}
|
|
78186
|
-
function
|
|
78187
|
-
|
|
78188
|
-
return;
|
|
78189
|
-
slashCommandSelector.options = slashCommandMatches.map((cmd) => ({
|
|
78230
|
+
function getSlashCommandSelectOptions() {
|
|
78231
|
+
return slashCommandMatches.map((cmd) => ({
|
|
78190
78232
|
name: `/${cmd.slash}`,
|
|
78191
78233
|
description: cmd.description,
|
|
78192
78234
|
value: cmd
|
|
78193
78235
|
}));
|
|
78194
|
-
slashCommandSelector.height = Math.min(Math.max(slashCommandMatches.length, 1), 6);
|
|
78195
|
-
slashCommandSelector.setSelectedIndex(slashCommandSelectedIndex);
|
|
78196
78236
|
}
|
|
78197
78237
|
function closeSlashCommandMenu() {
|
|
78198
|
-
if (
|
|
78199
|
-
|
|
78200
|
-
|
|
78201
|
-
slashCommandSelector = null;
|
|
78238
|
+
if (slashCommandModal) {
|
|
78239
|
+
slashCommandModal.close();
|
|
78240
|
+
slashCommandModal = null;
|
|
78202
78241
|
}
|
|
78203
78242
|
slashCommandMatches = [];
|
|
78204
78243
|
slashCommandSelectedIndex = 0;
|
|
78205
78244
|
}
|
|
78245
|
+
function updateSlashCommandModalOptions() {
|
|
78246
|
+
if (!slashCommandModal)
|
|
78247
|
+
return;
|
|
78248
|
+
slashCommandModal.updateOptions(getSlashCommandSelectOptions(), slashCommandSelectedIndex);
|
|
78249
|
+
}
|
|
78206
78250
|
function syncSlashCommandMenu() {
|
|
78207
78251
|
const inputText = inputField.editBuffer.getText();
|
|
78208
78252
|
const matches = getSlashCommandMatches(inputText);
|
|
@@ -78210,10 +78254,21 @@ function syncSlashCommandMenu() {
|
|
|
78210
78254
|
closeSlashCommandMenu();
|
|
78211
78255
|
return;
|
|
78212
78256
|
}
|
|
78213
|
-
ensureSlashCommandMenu();
|
|
78214
78257
|
slashCommandMatches = matches;
|
|
78215
78258
|
slashCommandSelectedIndex = Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1);
|
|
78216
|
-
|
|
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
|
+
});
|
|
78217
78272
|
}
|
|
78218
78273
|
function queueSlashCommandSync() {
|
|
78219
78274
|
if (slashCommandSyncQueued)
|
|
@@ -78226,55 +78281,24 @@ function queueSlashCommandSync() {
|
|
|
78226
78281
|
}, 0);
|
|
78227
78282
|
}
|
|
78228
78283
|
function showCommandPalette() {
|
|
78229
|
-
if (
|
|
78284
|
+
if (commandPaletteModal) {
|
|
78230
78285
|
return;
|
|
78231
78286
|
}
|
|
78232
78287
|
commandPaletteQuery = "";
|
|
78233
|
-
|
|
78234
|
-
|
|
78235
|
-
|
|
78236
|
-
const paletteLeft = Math.max(2, Math.floor((termWidth - paletteWidth) / 2));
|
|
78237
|
-
const container = new BoxRenderable(renderer, {
|
|
78238
|
-
id: "command-palette-container",
|
|
78239
|
-
position: "absolute",
|
|
78240
|
-
left: paletteLeft,
|
|
78241
|
-
top: 3,
|
|
78242
|
-
width: paletteWidth,
|
|
78243
|
-
height: Math.min(commands.length + 4, 16),
|
|
78244
|
-
backgroundColor: "#1e293b",
|
|
78245
|
-
border: true,
|
|
78246
|
-
borderColor: "#60a5fa",
|
|
78247
|
-
borderStyle: "single",
|
|
78288
|
+
commandPaletteModal = openModalList({
|
|
78289
|
+
containerId: "command-palette-container",
|
|
78290
|
+
selectorId: "command-palette-select",
|
|
78248
78291
|
title: "Commands",
|
|
78249
|
-
titleAlignment: "center",
|
|
78250
|
-
zIndex: 200,
|
|
78251
|
-
padding: 1
|
|
78252
|
-
});
|
|
78253
|
-
renderer.root.add(container);
|
|
78254
|
-
commandPalette = new SelectRenderable(renderer, {
|
|
78255
|
-
id: "command-palette-select",
|
|
78256
|
-
width: "100%",
|
|
78257
|
-
height: Math.min(commands.length + 2, 12),
|
|
78258
78292
|
options: getCommandPaletteSelectOptions(),
|
|
78259
|
-
|
|
78260
|
-
|
|
78261
|
-
|
|
78262
|
-
|
|
78263
|
-
|
|
78264
|
-
|
|
78265
|
-
|
|
78266
|
-
|
|
78267
|
-
wrapSelection: true
|
|
78268
|
-
});
|
|
78269
|
-
container.add(commandPalette);
|
|
78270
|
-
commandPalette.on(SelectRenderableEvents.ITEM_SELECTED, async (_2, option) => {
|
|
78271
|
-
if (!option.value)
|
|
78272
|
-
return;
|
|
78273
|
-
const cmd = option.value;
|
|
78274
|
-
closeCommandPalette();
|
|
78275
|
-
await cmd.action();
|
|
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
|
+
}
|
|
78276
78301
|
});
|
|
78277
|
-
commandPalette.focus();
|
|
78278
78302
|
}
|
|
78279
78303
|
function getCommandPaletteSelectOptions() {
|
|
78280
78304
|
const query = commandPaletteQuery.toLowerCase();
|
|
@@ -78297,30 +78321,28 @@ function getCommandPaletteSelectOptions() {
|
|
|
78297
78321
|
}));
|
|
78298
78322
|
}
|
|
78299
78323
|
function updateCommandPaletteOptions() {
|
|
78300
|
-
if (!
|
|
78324
|
+
if (!commandPaletteModal)
|
|
78301
78325
|
return;
|
|
78302
|
-
|
|
78303
|
-
commandPalette.setSelectedIndex(0);
|
|
78326
|
+
commandPaletteModal.updateOptions(getCommandPaletteSelectOptions(), 0);
|
|
78304
78327
|
}
|
|
78305
78328
|
function closeCommandPalette() {
|
|
78306
|
-
if (
|
|
78307
|
-
|
|
78308
|
-
|
|
78329
|
+
if (commandPaletteModal) {
|
|
78330
|
+
commandPaletteModal.close();
|
|
78331
|
+
commandPaletteModal = null;
|
|
78309
78332
|
commandPaletteQuery = "";
|
|
78310
|
-
inputField?.focus();
|
|
78311
78333
|
}
|
|
78312
78334
|
}
|
|
78313
78335
|
function handleKeypress(key) {
|
|
78314
78336
|
const commands = getCommandPaletteOptions();
|
|
78315
|
-
if (slashCommandMatches.length > 0) {
|
|
78337
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
78316
78338
|
if (key.name === "up") {
|
|
78317
78339
|
slashCommandSelectedIndex = slashCommandSelectedIndex === 0 ? slashCommandMatches.length - 1 : slashCommandSelectedIndex - 1;
|
|
78318
|
-
|
|
78340
|
+
updateSlashCommandModalOptions();
|
|
78319
78341
|
return;
|
|
78320
78342
|
}
|
|
78321
78343
|
if (key.name === "down") {
|
|
78322
78344
|
slashCommandSelectedIndex = (slashCommandSelectedIndex + 1) % slashCommandMatches.length;
|
|
78323
|
-
|
|
78345
|
+
updateSlashCommandModalOptions();
|
|
78324
78346
|
return;
|
|
78325
78347
|
}
|
|
78326
78348
|
if (key.name === "tab") {
|
|
@@ -78329,6 +78351,10 @@ function handleKeypress(key) {
|
|
|
78329
78351
|
inputField.focus();
|
|
78330
78352
|
return;
|
|
78331
78353
|
}
|
|
78354
|
+
if (key.name === "return" && !key.shift && !key.ctrl && !key.meta) {
|
|
78355
|
+
executeSelectedSlashCommand();
|
|
78356
|
+
return;
|
|
78357
|
+
}
|
|
78332
78358
|
}
|
|
78333
78359
|
if (key.ctrl && key.name === "p") {
|
|
78334
78360
|
showCommandPalette();
|
|
@@ -78356,7 +78382,7 @@ function handleKeypress(key) {
|
|
|
78356
78382
|
}
|
|
78357
78383
|
return;
|
|
78358
78384
|
}
|
|
78359
|
-
if (
|
|
78385
|
+
if (commandPaletteModal) {
|
|
78360
78386
|
if (key.name === "backspace" || key.name === "delete") {
|
|
78361
78387
|
commandPaletteQuery = commandPaletteQuery.slice(0, -1);
|
|
78362
78388
|
updateCommandPaletteOptions();
|
|
@@ -78370,7 +78396,7 @@ function handleKeypress(key) {
|
|
|
78370
78396
|
}
|
|
78371
78397
|
}
|
|
78372
78398
|
if (key.ctrl && key.name === "c") {
|
|
78373
|
-
if (
|
|
78399
|
+
if (commandPaletteModal) {
|
|
78374
78400
|
closeCommandPalette();
|
|
78375
78401
|
return;
|
|
78376
78402
|
}
|
|
@@ -78401,7 +78427,7 @@ function handleKeypress(key) {
|
|
|
78401
78427
|
}
|
|
78402
78428
|
if (key.name === "escape") {
|
|
78403
78429
|
chordMode = "none";
|
|
78404
|
-
if (
|
|
78430
|
+
if (commandPaletteModal) {
|
|
78405
78431
|
closeCommandPalette();
|
|
78406
78432
|
return;
|
|
78407
78433
|
}
|
|
@@ -78448,7 +78474,7 @@ function handleKeypress(key) {
|
|
|
78448
78474
|
addSystemMessage(`Copied to clipboard: ${msg.command}`);
|
|
78449
78475
|
}
|
|
78450
78476
|
}
|
|
78451
|
-
if (key.name === "o" && !awaitingConfirmation && !
|
|
78477
|
+
if (key.name === "o" && !awaitingConfirmation && !commandPaletteModal && !modelSelector) {
|
|
78452
78478
|
toggleLastResultExpand();
|
|
78453
78479
|
}
|
|
78454
78480
|
}
|
package/dist/tui.js
CHANGED
|
@@ -76817,11 +76817,10 @@ var inputHintText;
|
|
|
76817
76817
|
var helpBarText;
|
|
76818
76818
|
var modelSelector = null;
|
|
76819
76819
|
var providerSelector = null;
|
|
76820
|
-
var slashCommandContainer = null;
|
|
76821
|
-
var slashCommandSelector = null;
|
|
76822
76820
|
var slashCommandMatches = [];
|
|
76823
76821
|
var slashCommandSelectedIndex = 0;
|
|
76824
76822
|
var slashCommandSyncQueued = false;
|
|
76823
|
+
var slashCommandExecuting = false;
|
|
76825
76824
|
var pendingMessageId = null;
|
|
76826
76825
|
var awaitingConfirmation = false;
|
|
76827
76826
|
function generateMessageId() {
|
|
@@ -77106,6 +77105,10 @@ function createMainUI() {
|
|
|
77106
77105
|
{ name: "j", ctrl: true, action: "newline" }
|
|
77107
77106
|
],
|
|
77108
77107
|
onSubmit: () => {
|
|
77108
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
77109
|
+
executeSelectedSlashCommand();
|
|
77110
|
+
return;
|
|
77111
|
+
}
|
|
77109
77112
|
const value = inputField.editBuffer.getText();
|
|
77110
77113
|
handleInput(value);
|
|
77111
77114
|
}
|
|
@@ -77434,27 +77437,18 @@ function refreshThemeColors() {
|
|
|
77434
77437
|
if (inputHintText) {
|
|
77435
77438
|
inputHintText.content = getInputHintContent();
|
|
77436
77439
|
}
|
|
77437
|
-
if (slashCommandContainer) {
|
|
77438
|
-
slashCommandContainer.borderColor = theme.colors.border;
|
|
77439
|
-
slashCommandContainer.backgroundColor = theme.colors.backgroundPanel;
|
|
77440
|
-
}
|
|
77441
|
-
if (slashCommandSelector) {
|
|
77442
|
-
slashCommandSelector.selectedBackgroundColor = theme.colors.backgroundElement;
|
|
77443
|
-
slashCommandSelector.textColor = theme.colors.text;
|
|
77444
|
-
slashCommandSelector.selectedTextColor = theme.colors.primary;
|
|
77445
|
-
slashCommandSelector.descriptionColor = theme.colors.textMuted;
|
|
77446
|
-
slashCommandSelector.selectedDescriptionColor = theme.colors.textMuted;
|
|
77447
|
-
}
|
|
77448
77440
|
}
|
|
77449
77441
|
async function handleInput(value) {
|
|
77450
77442
|
const input = value.trim();
|
|
77451
77443
|
if (!input)
|
|
77452
77444
|
return;
|
|
77453
|
-
inputField.setText("");
|
|
77454
|
-
closeSlashCommandMenu();
|
|
77455
77445
|
if (input.startsWith("/") && await tryHandleSlashCommand(input)) {
|
|
77446
|
+
inputField.setText("");
|
|
77447
|
+
closeSlashCommandMenu();
|
|
77456
77448
|
return;
|
|
77457
77449
|
}
|
|
77450
|
+
inputField.setText("");
|
|
77451
|
+
closeSlashCommandMenu();
|
|
77458
77452
|
if (input.startsWith("!")) {
|
|
77459
77453
|
await handleSpecialCommand(input);
|
|
77460
77454
|
return;
|
|
@@ -77466,15 +77460,22 @@ async function handleInput(value) {
|
|
|
77466
77460
|
}
|
|
77467
77461
|
await translateAndProcess(input);
|
|
77468
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
|
+
}
|
|
77469
77476
|
async function tryHandleSlashCommand(input) {
|
|
77470
77477
|
if (!input.startsWith("/"))
|
|
77471
77478
|
return false;
|
|
77472
|
-
const slashBody = input.slice(1).trim();
|
|
77473
|
-
if (!slashBody.includes(" ") && slashCommandMatches.length > 0) {
|
|
77474
|
-
const selected = slashCommandMatches[Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1)];
|
|
77475
|
-
await handleSpecialCommand(`/${selected.slash}`);
|
|
77476
|
-
return true;
|
|
77477
|
-
}
|
|
77478
77479
|
await handleSpecialCommand(input);
|
|
77479
77480
|
return true;
|
|
77480
77481
|
}
|
|
@@ -77957,7 +77958,10 @@ function showThemeSelector() {
|
|
|
77957
77958
|
renderer.keyInput.on("keypress", escHandler);
|
|
77958
77959
|
themeSelector.focus();
|
|
77959
77960
|
}
|
|
77960
|
-
var
|
|
77961
|
+
var MODAL_LIST_WIDTH = 55;
|
|
77962
|
+
var MODAL_LIST_MAX_ITEMS = 12;
|
|
77963
|
+
var commandPaletteModal = null;
|
|
77964
|
+
var slashCommandModal = null;
|
|
77961
77965
|
var commandPaletteQuery = "";
|
|
77962
77966
|
var chordMode = "none";
|
|
77963
77967
|
function cycleThinkingLevel() {
|
|
@@ -78149,60 +78153,100 @@ function getSlashCommandMatches(inputText) {
|
|
|
78149
78153
|
return `${cmd.slash} ${cmd.name} ${cmd.description}`.toLowerCase().includes(query);
|
|
78150
78154
|
});
|
|
78151
78155
|
}
|
|
78152
|
-
function
|
|
78153
|
-
|
|
78154
|
-
|
|
78155
|
-
|
|
78156
|
-
|
|
78157
|
-
|
|
78156
|
+
function openModalList(config3) {
|
|
78157
|
+
const theme = getTheme();
|
|
78158
|
+
const width = MODAL_LIST_WIDTH;
|
|
78159
|
+
const termWidth = process.stdout.columns || 80;
|
|
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;
|
|
78164
|
+
const container = new BoxRenderable(renderer, {
|
|
78165
|
+
id: config3.containerId,
|
|
78166
|
+
position: "absolute",
|
|
78167
|
+
left,
|
|
78168
|
+
top: 3,
|
|
78169
|
+
width,
|
|
78170
|
+
height: containerHeight,
|
|
78171
|
+
backgroundColor: theme.colors.backgroundPanel,
|
|
78158
78172
|
border: true,
|
|
78159
|
-
borderColor:
|
|
78173
|
+
borderColor: theme.colors.primary,
|
|
78160
78174
|
borderStyle: "single",
|
|
78161
|
-
|
|
78162
|
-
|
|
78163
|
-
|
|
78164
|
-
|
|
78165
|
-
paddingBottom: 0,
|
|
78166
|
-
marginTop: 1
|
|
78175
|
+
title: config3.title,
|
|
78176
|
+
titleAlignment: "center",
|
|
78177
|
+
zIndex: 200,
|
|
78178
|
+
padding: 1
|
|
78167
78179
|
});
|
|
78168
|
-
|
|
78169
|
-
|
|
78170
|
-
id:
|
|
78180
|
+
renderer.root.add(container);
|
|
78181
|
+
const selector = new SelectRenderable(renderer, {
|
|
78182
|
+
id: config3.selectorId,
|
|
78171
78183
|
width: "100%",
|
|
78172
|
-
height:
|
|
78173
|
-
options:
|
|
78184
|
+
height: listHeight,
|
|
78185
|
+
options: config3.options,
|
|
78174
78186
|
backgroundColor: "transparent",
|
|
78175
78187
|
focusedBackgroundColor: "transparent",
|
|
78176
|
-
selectedBackgroundColor:
|
|
78177
|
-
textColor:
|
|
78178
|
-
selectedTextColor:
|
|
78179
|
-
descriptionColor:
|
|
78180
|
-
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,
|
|
78181
78193
|
showDescription: true,
|
|
78182
78194
|
wrapSelection: true
|
|
78183
78195
|
});
|
|
78184
|
-
|
|
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;
|
|
78185
78229
|
}
|
|
78186
|
-
function
|
|
78187
|
-
|
|
78188
|
-
return;
|
|
78189
|
-
slashCommandSelector.options = slashCommandMatches.map((cmd) => ({
|
|
78230
|
+
function getSlashCommandSelectOptions() {
|
|
78231
|
+
return slashCommandMatches.map((cmd) => ({
|
|
78190
78232
|
name: `/${cmd.slash}`,
|
|
78191
78233
|
description: cmd.description,
|
|
78192
78234
|
value: cmd
|
|
78193
78235
|
}));
|
|
78194
|
-
slashCommandSelector.height = Math.min(Math.max(slashCommandMatches.length, 1), 6);
|
|
78195
|
-
slashCommandSelector.setSelectedIndex(slashCommandSelectedIndex);
|
|
78196
78236
|
}
|
|
78197
78237
|
function closeSlashCommandMenu() {
|
|
78198
|
-
if (
|
|
78199
|
-
|
|
78200
|
-
|
|
78201
|
-
slashCommandSelector = null;
|
|
78238
|
+
if (slashCommandModal) {
|
|
78239
|
+
slashCommandModal.close();
|
|
78240
|
+
slashCommandModal = null;
|
|
78202
78241
|
}
|
|
78203
78242
|
slashCommandMatches = [];
|
|
78204
78243
|
slashCommandSelectedIndex = 0;
|
|
78205
78244
|
}
|
|
78245
|
+
function updateSlashCommandModalOptions() {
|
|
78246
|
+
if (!slashCommandModal)
|
|
78247
|
+
return;
|
|
78248
|
+
slashCommandModal.updateOptions(getSlashCommandSelectOptions(), slashCommandSelectedIndex);
|
|
78249
|
+
}
|
|
78206
78250
|
function syncSlashCommandMenu() {
|
|
78207
78251
|
const inputText = inputField.editBuffer.getText();
|
|
78208
78252
|
const matches = getSlashCommandMatches(inputText);
|
|
@@ -78210,10 +78254,21 @@ function syncSlashCommandMenu() {
|
|
|
78210
78254
|
closeSlashCommandMenu();
|
|
78211
78255
|
return;
|
|
78212
78256
|
}
|
|
78213
|
-
ensureSlashCommandMenu();
|
|
78214
78257
|
slashCommandMatches = matches;
|
|
78215
78258
|
slashCommandSelectedIndex = Math.min(slashCommandSelectedIndex, slashCommandMatches.length - 1);
|
|
78216
|
-
|
|
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
|
+
});
|
|
78217
78272
|
}
|
|
78218
78273
|
function queueSlashCommandSync() {
|
|
78219
78274
|
if (slashCommandSyncQueued)
|
|
@@ -78226,55 +78281,24 @@ function queueSlashCommandSync() {
|
|
|
78226
78281
|
}, 0);
|
|
78227
78282
|
}
|
|
78228
78283
|
function showCommandPalette() {
|
|
78229
|
-
if (
|
|
78284
|
+
if (commandPaletteModal) {
|
|
78230
78285
|
return;
|
|
78231
78286
|
}
|
|
78232
78287
|
commandPaletteQuery = "";
|
|
78233
|
-
|
|
78234
|
-
|
|
78235
|
-
|
|
78236
|
-
const paletteLeft = Math.max(2, Math.floor((termWidth - paletteWidth) / 2));
|
|
78237
|
-
const container = new BoxRenderable(renderer, {
|
|
78238
|
-
id: "command-palette-container",
|
|
78239
|
-
position: "absolute",
|
|
78240
|
-
left: paletteLeft,
|
|
78241
|
-
top: 3,
|
|
78242
|
-
width: paletteWidth,
|
|
78243
|
-
height: Math.min(commands.length + 4, 16),
|
|
78244
|
-
backgroundColor: "#1e293b",
|
|
78245
|
-
border: true,
|
|
78246
|
-
borderColor: "#60a5fa",
|
|
78247
|
-
borderStyle: "single",
|
|
78288
|
+
commandPaletteModal = openModalList({
|
|
78289
|
+
containerId: "command-palette-container",
|
|
78290
|
+
selectorId: "command-palette-select",
|
|
78248
78291
|
title: "Commands",
|
|
78249
|
-
titleAlignment: "center",
|
|
78250
|
-
zIndex: 200,
|
|
78251
|
-
padding: 1
|
|
78252
|
-
});
|
|
78253
|
-
renderer.root.add(container);
|
|
78254
|
-
commandPalette = new SelectRenderable(renderer, {
|
|
78255
|
-
id: "command-palette-select",
|
|
78256
|
-
width: "100%",
|
|
78257
|
-
height: Math.min(commands.length + 2, 12),
|
|
78258
78292
|
options: getCommandPaletteSelectOptions(),
|
|
78259
|
-
|
|
78260
|
-
|
|
78261
|
-
|
|
78262
|
-
|
|
78263
|
-
|
|
78264
|
-
|
|
78265
|
-
|
|
78266
|
-
|
|
78267
|
-
wrapSelection: true
|
|
78268
|
-
});
|
|
78269
|
-
container.add(commandPalette);
|
|
78270
|
-
commandPalette.on(SelectRenderableEvents.ITEM_SELECTED, async (_2, option) => {
|
|
78271
|
-
if (!option.value)
|
|
78272
|
-
return;
|
|
78273
|
-
const cmd = option.value;
|
|
78274
|
-
closeCommandPalette();
|
|
78275
|
-
await cmd.action();
|
|
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
|
+
}
|
|
78276
78301
|
});
|
|
78277
|
-
commandPalette.focus();
|
|
78278
78302
|
}
|
|
78279
78303
|
function getCommandPaletteSelectOptions() {
|
|
78280
78304
|
const query = commandPaletteQuery.toLowerCase();
|
|
@@ -78297,30 +78321,28 @@ function getCommandPaletteSelectOptions() {
|
|
|
78297
78321
|
}));
|
|
78298
78322
|
}
|
|
78299
78323
|
function updateCommandPaletteOptions() {
|
|
78300
|
-
if (!
|
|
78324
|
+
if (!commandPaletteModal)
|
|
78301
78325
|
return;
|
|
78302
|
-
|
|
78303
|
-
commandPalette.setSelectedIndex(0);
|
|
78326
|
+
commandPaletteModal.updateOptions(getCommandPaletteSelectOptions(), 0);
|
|
78304
78327
|
}
|
|
78305
78328
|
function closeCommandPalette() {
|
|
78306
|
-
if (
|
|
78307
|
-
|
|
78308
|
-
|
|
78329
|
+
if (commandPaletteModal) {
|
|
78330
|
+
commandPaletteModal.close();
|
|
78331
|
+
commandPaletteModal = null;
|
|
78309
78332
|
commandPaletteQuery = "";
|
|
78310
|
-
inputField?.focus();
|
|
78311
78333
|
}
|
|
78312
78334
|
}
|
|
78313
78335
|
function handleKeypress(key) {
|
|
78314
78336
|
const commands = getCommandPaletteOptions();
|
|
78315
|
-
if (slashCommandMatches.length > 0) {
|
|
78337
|
+
if (slashCommandModal && slashCommandMatches.length > 0) {
|
|
78316
78338
|
if (key.name === "up") {
|
|
78317
78339
|
slashCommandSelectedIndex = slashCommandSelectedIndex === 0 ? slashCommandMatches.length - 1 : slashCommandSelectedIndex - 1;
|
|
78318
|
-
|
|
78340
|
+
updateSlashCommandModalOptions();
|
|
78319
78341
|
return;
|
|
78320
78342
|
}
|
|
78321
78343
|
if (key.name === "down") {
|
|
78322
78344
|
slashCommandSelectedIndex = (slashCommandSelectedIndex + 1) % slashCommandMatches.length;
|
|
78323
|
-
|
|
78345
|
+
updateSlashCommandModalOptions();
|
|
78324
78346
|
return;
|
|
78325
78347
|
}
|
|
78326
78348
|
if (key.name === "tab") {
|
|
@@ -78329,6 +78351,10 @@ function handleKeypress(key) {
|
|
|
78329
78351
|
inputField.focus();
|
|
78330
78352
|
return;
|
|
78331
78353
|
}
|
|
78354
|
+
if (key.name === "return" && !key.shift && !key.ctrl && !key.meta) {
|
|
78355
|
+
executeSelectedSlashCommand();
|
|
78356
|
+
return;
|
|
78357
|
+
}
|
|
78332
78358
|
}
|
|
78333
78359
|
if (key.ctrl && key.name === "p") {
|
|
78334
78360
|
showCommandPalette();
|
|
@@ -78356,7 +78382,7 @@ function handleKeypress(key) {
|
|
|
78356
78382
|
}
|
|
78357
78383
|
return;
|
|
78358
78384
|
}
|
|
78359
|
-
if (
|
|
78385
|
+
if (commandPaletteModal) {
|
|
78360
78386
|
if (key.name === "backspace" || key.name === "delete") {
|
|
78361
78387
|
commandPaletteQuery = commandPaletteQuery.slice(0, -1);
|
|
78362
78388
|
updateCommandPaletteOptions();
|
|
@@ -78370,7 +78396,7 @@ function handleKeypress(key) {
|
|
|
78370
78396
|
}
|
|
78371
78397
|
}
|
|
78372
78398
|
if (key.ctrl && key.name === "c") {
|
|
78373
|
-
if (
|
|
78399
|
+
if (commandPaletteModal) {
|
|
78374
78400
|
closeCommandPalette();
|
|
78375
78401
|
return;
|
|
78376
78402
|
}
|
|
@@ -78401,7 +78427,7 @@ function handleKeypress(key) {
|
|
|
78401
78427
|
}
|
|
78402
78428
|
if (key.name === "escape") {
|
|
78403
78429
|
chordMode = "none";
|
|
78404
|
-
if (
|
|
78430
|
+
if (commandPaletteModal) {
|
|
78405
78431
|
closeCommandPalette();
|
|
78406
78432
|
return;
|
|
78407
78433
|
}
|
|
@@ -78448,7 +78474,7 @@ function handleKeypress(key) {
|
|
|
78448
78474
|
addSystemMessage(`Copied to clipboard: ${msg.command}`);
|
|
78449
78475
|
}
|
|
78450
78476
|
}
|
|
78451
|
-
if (key.name === "o" && !awaitingConfirmation && !
|
|
78477
|
+
if (key.name === "o" && !awaitingConfirmation && !commandPaletteModal && !modelSelector) {
|
|
78452
78478
|
toggleLastResultExpand();
|
|
78453
78479
|
}
|
|
78454
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",
|