tsunami-code 3.11.9 → 3.12.0

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 (3) hide show
  1. package/index.js +2 -3
  2. package/lib/ui.js +25 -9
  3. package/package.json +1 -1
package/index.js CHANGED
@@ -26,7 +26,7 @@ import {
26
26
  } from './lib/memory.js';
27
27
  import { listMemories, readMemory, saveMemory, deleteMemory, getMemdirPath } from './lib/memdir.js';
28
28
 
29
- const VERSION = '3.11.9';
29
+ const VERSION = '3.12.0';
30
30
  const CONFIG_DIR = join(os.homedir(), '.tsunami-code');
31
31
  const CONFIG_FILE = join(CONFIG_DIR, 'config.json');
32
32
  const DEFAULT_SERVER = 'https://radiometric-reita-amuck.ngrok-free.dev';
@@ -831,9 +831,8 @@ async function run() {
831
831
  const m = rest[0]?.toLowerCase();
832
832
  if (!m) {
833
833
  // Interactive arrow-key picker
834
- process.stdout.write(blue('\n Select permission mode:\n\n'));
835
834
  const currentIdx = PERM_MODES.indexOf(permMode);
836
- const selected = await ui.selectFromList(PERM_MODES, currentIdx >= 0 ? currentIdx : 0);
835
+ const selected = await ui.selectFromList(PERM_MODES, currentIdx >= 0 ? currentIdx : 0, blue(' Select permission mode:'));
837
836
  if (selected) {
838
837
  permMode = selected;
839
838
  planMode = selected === 'readonly';
package/lib/ui.js CHANGED
@@ -282,13 +282,16 @@ export function createUI({ planMode: initPlanMode = false, onLine, onTab, onExit
282
282
  }
283
283
 
284
284
  // ── selectFromList — arrow-key interactive picker ─────────────────────────
285
- function selectFromList(items, initialIdx = 0) {
285
+ function selectFromList(items, initialIdx = 0, header = null) {
286
286
  return new Promise((resolve) => {
287
287
  let idx = initialIdx;
288
- const n = items.length;
288
+ const n = items.length;
289
+ const extra = header ? 2 : 0; // header line + blank line
290
+
291
+ if (header) process.stdout.write(`\n${header}\n\n`);
289
292
 
290
293
  function render(isFirst) {
291
- if (!isFirst) process.stdout.write(`\x1b[${n}A`); // move back up
294
+ if (!isFirst) process.stdout.write(`\x1b[${n}A`);
292
295
  for (let i = 0; i < n; i++) {
293
296
  const active = i === idx;
294
297
  const label = active ? ` ${cyan('❯')} ${items[i]}` : ` ${dim(items[i])}`;
@@ -298,20 +301,33 @@ export function createUI({ planMode: initPlanMode = false, onLine, onTab, onExit
298
301
 
299
302
  render(true);
300
303
 
304
+ function clearList() {
305
+ // Erase list + header
306
+ const total = n + extra;
307
+ process.stdout.write(`\x1b[${n}A`); // back to top of list
308
+ for (let i = 0; i < n; i++) process.stdout.write(`\x1b[2K\n`);
309
+ process.stdout.write(`\x1b[${n}A`); // cursor to top of list
310
+ if (extra) {
311
+ process.stdout.write(`\x1b[${extra}A`); // back past header
312
+ for (let i = 0; i < extra; i++) process.stdout.write(`\x1b[2K\n`);
313
+ process.stdout.write(`\x1b[${extra}A`);
314
+ }
315
+ }
316
+
301
317
  lineHandler = (key) => {
302
- if (key === '\x1b[A') { // up
318
+ if (key === '\x1b[A') {
303
319
  idx = (idx - 1 + n) % n;
304
320
  render(false);
305
- } else if (key === '\x1b[B') { // down
321
+ } else if (key === '\x1b[B') {
306
322
  idx = (idx + 1) % n;
307
323
  render(false);
308
- } else if (key === '\r' || key === '\n') { // confirm
324
+ } else if (key === '\r' || key === '\n') {
309
325
  lineHandler = null;
310
- process.stdout.write('\n');
326
+ clearList();
311
327
  resolve(items[idx]);
312
- } else if (key === '\x1b' || key === '\x03') { // cancel
328
+ } else if (key === '\x1b' || key === '\x03') {
313
329
  lineHandler = null;
314
- process.stdout.write('\n');
330
+ clearList();
315
331
  resolve(null);
316
332
  }
317
333
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsunami-code",
3
- "version": "3.11.9",
3
+ "version": "3.12.0",
4
4
  "description": "Tsunami Code CLI — AI coding agent by Keystone World Management Navy Seal Unit XI3",
5
5
  "type": "module",
6
6
  "bin": {