letmecook 0.0.14 → 0.0.15
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/package.json +1 -1
- package/src/ui/add-repos.ts +146 -31
package/package.json
CHANGED
package/src/ui/add-repos.ts
CHANGED
|
@@ -28,6 +28,8 @@ export async function showAddReposPrompt(renderer: CliRenderer): Promise<AddRepo
|
|
|
28
28
|
let selectedMatchIndex = -1; // -1 means no match selected, user is typing freely
|
|
29
29
|
let lastQuery = ""; // Track the query that generated current matches
|
|
30
30
|
let isNavigating = false; // Flag to prevent input handler from resetting when navigating
|
|
31
|
+
let isConfirming = false; // Flag for confirmation mode (showing checkboxes)
|
|
32
|
+
let confirmOptionIndex = 0; // 0 = read-only, 1 = latest, 2 = confirm button
|
|
31
33
|
|
|
32
34
|
// Repository input
|
|
33
35
|
const repoLabel = new TextRenderable(renderer, {
|
|
@@ -93,6 +95,14 @@ export async function showAddReposPrompt(renderer: CliRenderer): Promise<AddRepo
|
|
|
93
95
|
});
|
|
94
96
|
content.add(detailsLatest);
|
|
95
97
|
|
|
98
|
+
const confirmButton = new TextRenderable(renderer, {
|
|
99
|
+
id: "confirm-button",
|
|
100
|
+
content: "",
|
|
101
|
+
fg: "#10b981",
|
|
102
|
+
marginTop: 1,
|
|
103
|
+
});
|
|
104
|
+
content.add(confirmButton);
|
|
105
|
+
|
|
96
106
|
repoInput.onPaste = (event) => {
|
|
97
107
|
const text = event.text.replace(/[\r\n]+/g, "");
|
|
98
108
|
if (!text) return;
|
|
@@ -161,17 +171,35 @@ export async function showAddReposPrompt(renderer: CliRenderer): Promise<AddRepo
|
|
|
161
171
|
}
|
|
162
172
|
|
|
163
173
|
function updateDetails() {
|
|
164
|
-
if (currentValidRepo) {
|
|
165
|
-
|
|
166
|
-
detailsLabel.
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
174
|
+
if (isConfirming && currentValidRepo) {
|
|
175
|
+
// Confirmation mode with interactive checkboxes
|
|
176
|
+
detailsLabel.content = `\nConfigure options for: ${currentInput.trim()}`;
|
|
177
|
+
detailsLabel.fg = "#38bdf8";
|
|
178
|
+
|
|
179
|
+
const roCheckbox = currentReadOnly ? "[✓]" : "[ ]";
|
|
180
|
+
const roSelected = confirmOptionIndex === 0;
|
|
181
|
+
detailsReadOnly.content = ` ${roSelected ? "▶" : " "} ${roCheckbox} Read-only [r]`;
|
|
182
|
+
detailsReadOnly.fg = roSelected ? "#f8fafc" : currentReadOnly ? "#f59e0b" : "#94a3b8";
|
|
183
|
+
|
|
184
|
+
const latestCheckbox = currentLatest ? "[✓]" : "[ ]";
|
|
185
|
+
const latestSelected = confirmOptionIndex === 1;
|
|
186
|
+
detailsLatest.content = ` ${latestSelected ? "▶" : " "} ${latestCheckbox} Latest [l]`;
|
|
187
|
+
detailsLatest.fg = latestSelected ? "#f8fafc" : currentLatest ? "#22d3ee" : "#94a3b8";
|
|
188
|
+
|
|
189
|
+
const confirmSelected = confirmOptionIndex === 2;
|
|
190
|
+
confirmButton.content = ` ${confirmSelected ? "▶" : " "} [Add repository]`;
|
|
191
|
+
confirmButton.fg = confirmSelected ? "#10b981" : "#64748b";
|
|
192
|
+
} else if (currentValidRepo) {
|
|
193
|
+
detailsLabel.content = "\nPress Enter to configure options";
|
|
194
|
+
detailsLabel.fg = "#64748b";
|
|
195
|
+
detailsReadOnly.content = "";
|
|
196
|
+
detailsLatest.content = "";
|
|
197
|
+
confirmButton.content = "";
|
|
171
198
|
} else {
|
|
172
199
|
detailsLabel.content = "";
|
|
173
200
|
detailsReadOnly.content = "";
|
|
174
201
|
detailsLatest.content = "";
|
|
202
|
+
confirmButton.content = "";
|
|
175
203
|
}
|
|
176
204
|
}
|
|
177
205
|
|
|
@@ -280,37 +308,131 @@ export async function showAddReposPrompt(renderer: CliRenderer): Promise<AddRepo
|
|
|
280
308
|
statusText.content = "";
|
|
281
309
|
}
|
|
282
310
|
|
|
311
|
+
function enterConfirmMode() {
|
|
312
|
+
isConfirming = true;
|
|
313
|
+
confirmOptionIndex = 2; // Start on confirm button for quick add
|
|
314
|
+
repoInput.blur();
|
|
315
|
+
updateDetails();
|
|
316
|
+
updateFooter();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
function exitConfirmMode() {
|
|
320
|
+
isConfirming = false;
|
|
321
|
+
confirmOptionIndex = 0;
|
|
322
|
+
repoInput.focus();
|
|
323
|
+
updateDetails();
|
|
324
|
+
updateFooter();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function toggleCurrentOption() {
|
|
328
|
+
if (confirmOptionIndex === 0) {
|
|
329
|
+
// Toggle read-only
|
|
330
|
+
currentReadOnly = !currentReadOnly;
|
|
331
|
+
if (!currentReadOnly) {
|
|
332
|
+
currentLatest = false;
|
|
333
|
+
}
|
|
334
|
+
} else if (confirmOptionIndex === 1) {
|
|
335
|
+
// Toggle latest
|
|
336
|
+
currentLatest = !currentLatest;
|
|
337
|
+
if (currentLatest) {
|
|
338
|
+
currentReadOnly = true;
|
|
339
|
+
}
|
|
340
|
+
} else if (confirmOptionIndex === 2) {
|
|
341
|
+
// Confirm button - add the repo
|
|
342
|
+
addCurrentRepo();
|
|
343
|
+
exitConfirmMode();
|
|
344
|
+
}
|
|
345
|
+
updateDetails();
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
function updateFooter() {
|
|
349
|
+
if (isConfirming) {
|
|
350
|
+
showFooter(renderer, content, {
|
|
351
|
+
navigate: true,
|
|
352
|
+
select: false,
|
|
353
|
+
back: true,
|
|
354
|
+
custom: ["r Read-only", "l Latest", "space Toggle", "enter Add"],
|
|
355
|
+
});
|
|
356
|
+
} else {
|
|
357
|
+
showFooter(renderer, content, {
|
|
358
|
+
navigate: true,
|
|
359
|
+
select: true,
|
|
360
|
+
back: true,
|
|
361
|
+
custom: repos.length > 0 ? ["enter (empty) Continue"] : [],
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
283
366
|
const handleKeypress = (key: KeyEvent) => {
|
|
367
|
+
// Escape behavior differs based on mode
|
|
284
368
|
if (isEscape(key)) {
|
|
369
|
+
if (isConfirming) {
|
|
370
|
+
// Exit confirmation mode, go back to input
|
|
371
|
+
exitConfirmMode();
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
285
374
|
cleanup();
|
|
286
375
|
resolve({ repos, cancelled: true });
|
|
287
376
|
return;
|
|
288
377
|
}
|
|
289
378
|
|
|
290
|
-
//
|
|
291
|
-
if (
|
|
292
|
-
|
|
293
|
-
if (
|
|
294
|
-
|
|
379
|
+
// Confirmation mode handling
|
|
380
|
+
if (isConfirming) {
|
|
381
|
+
// Toggle read-only with 'r' hotkey
|
|
382
|
+
if (key.name === "r") {
|
|
383
|
+
currentReadOnly = !currentReadOnly;
|
|
384
|
+
if (!currentReadOnly) {
|
|
385
|
+
currentLatest = false;
|
|
386
|
+
}
|
|
387
|
+
updateDetails();
|
|
388
|
+
return;
|
|
295
389
|
}
|
|
296
|
-
updateDetails();
|
|
297
|
-
return;
|
|
298
|
-
}
|
|
299
390
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
391
|
+
// Toggle latest with 'l' hotkey
|
|
392
|
+
if (key.name === "l") {
|
|
393
|
+
currentLatest = !currentLatest;
|
|
394
|
+
if (currentLatest) {
|
|
395
|
+
currentReadOnly = true;
|
|
396
|
+
}
|
|
397
|
+
updateDetails();
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Space to toggle current option
|
|
402
|
+
if (key.name === "space") {
|
|
403
|
+
toggleCurrentOption();
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Enter to confirm/add
|
|
408
|
+
if (isEnter(key)) {
|
|
409
|
+
addCurrentRepo();
|
|
410
|
+
exitConfirmMode();
|
|
411
|
+
return;
|
|
305
412
|
}
|
|
306
|
-
|
|
413
|
+
|
|
414
|
+
// Arrow keys to navigate options
|
|
415
|
+
if (isArrowUp(key)) {
|
|
416
|
+
confirmOptionIndex = Math.max(0, confirmOptionIndex - 1);
|
|
417
|
+
updateDetails();
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (isArrowDown(key)) {
|
|
422
|
+
confirmOptionIndex = Math.min(2, confirmOptionIndex + 1);
|
|
423
|
+
updateDetails();
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
|
|
307
427
|
return;
|
|
308
428
|
}
|
|
309
429
|
|
|
310
|
-
//
|
|
430
|
+
// Normal input mode handling
|
|
431
|
+
|
|
432
|
+
// Enter to enter confirmation mode or continue
|
|
311
433
|
if (isEnter(key)) {
|
|
312
434
|
if (currentInput.trim() && currentValidRepo) {
|
|
313
|
-
|
|
435
|
+
enterConfirmMode();
|
|
314
436
|
} else if (!currentInput.trim() && repos.length > 0) {
|
|
315
437
|
// Empty input + repos added = continue
|
|
316
438
|
cleanup();
|
|
@@ -385,16 +507,9 @@ export async function showAddReposPrompt(renderer: CliRenderer): Promise<AddRepo
|
|
|
385
507
|
clearLayout(renderer);
|
|
386
508
|
};
|
|
387
509
|
|
|
388
|
-
// Show footer with context-aware actions
|
|
389
|
-
showFooter(renderer, content, {
|
|
390
|
-
navigate: true,
|
|
391
|
-
select: true,
|
|
392
|
-
back: true,
|
|
393
|
-
custom: currentValidRepo ? ["r Toggle RO", "l Toggle Latest"] : ["↑↓ Navigate matches"],
|
|
394
|
-
});
|
|
395
|
-
|
|
396
510
|
renderer.keyInput.on("keypress", handleKeypress);
|
|
397
511
|
updateDetails();
|
|
398
512
|
updateReposList();
|
|
513
|
+
updateFooter();
|
|
399
514
|
});
|
|
400
515
|
}
|