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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/ui/add-repos.ts +146 -31
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "letmecook",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/rustydotwtf/letmecook.git"
@@ -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
- detailsLabel.content = "\nRepository details:";
166
- detailsLabel.fg = "#e2e8f0";
167
- detailsReadOnly.content = ` Read-only: ${currentReadOnly ? "Yes [r]" : "No [r]"}`;
168
- detailsReadOnly.fg = currentReadOnly ? "#f59e0b" : "#94a3b8";
169
- detailsLatest.content = ` Latest: ${currentLatest ? "Yes [l]" : "No [l]"}`;
170
- detailsLatest.fg = currentLatest ? "#22d3ee" : "#94a3b8";
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
- // Toggle read-only
291
- if (key.name === "r" && currentValidRepo) {
292
- currentReadOnly = !currentReadOnly;
293
- if (!currentReadOnly) {
294
- currentLatest = false;
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
- // Toggle latest
301
- if (key.name === "l" && currentValidRepo) {
302
- currentLatest = !currentLatest;
303
- if (currentLatest) {
304
- currentReadOnly = true;
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
- updateDetails();
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
- // Enter to add repo or continue
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
- addCurrentRepo();
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
  }