lazyclaw 6.3.0 → 6.3.1

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/commands/chat.mjs CHANGED
@@ -305,13 +305,14 @@ export async function cmdChat(flags = {}) {
305
305
  }
306
306
  return;
307
307
  } catch (e) {
308
- // Fall through to legacy path on any ink failure (missing import,
309
- // narrow terminal, sandboxed stdout).
310
- if (process.env.LAZYCLAW_DEBUG) console.error('[ink] fallback:', e.message);
308
+ // Fall through to the legacy readline path on any ink failure. ALWAYS
309
+ // say why, in one dim line — the silent downgrade made real-terminal
310
+ // failures (node incompat, <60-col windows) undiagnosable from reports.
311
+ process.stderr.write(`\x1b[2m(ink UI unavailable: ${e?.message || e} — using the legacy reader)\x1b[0m\n`);
311
312
  }
312
313
  }
313
314
  // ─── legacy v4 path (unchanged) ─────────────────────────────────
314
- _printChatBanner(activeProvName, activeModel, readVersionFromRepo());
315
+ await _printChatBanner(activeProvName, activeModel, readVersionFromRepo());
315
316
 
316
317
  const readline = await import('node:readline');
317
318
  // Use terminal:true when we're attached to a TTY so the prompt shows
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lazyclaw",
3
- "version": "6.3.0",
3
+ "version": "6.3.1",
4
4
  "description": "Lazy, elegant terminal CLI for chatting with Claude / OpenAI / Gemini / Ollama, orchestrating multi-step LLM workflows, and running multi-agent Slack teams with cross-task memory. Banner-on-launch, slash-command ghost autocomplete, persistent sessions, local HTTP gateway.",
5
5
  "keywords": [
6
6
  "claude",
package/tui/pickers.mjs CHANGED
@@ -1,8 +1,8 @@
1
- // Interactive TUI helpers — readline pickers, banner/mascot renderers,
2
- // arrow-key menu, provider/model selection, and the _quickPrompt line reader.
3
- // Extracted from cli.mjs in Phase D4. Lives in tui/ so banner asset imports
4
- // are siblings (./banner.generated.mjs, ./wordmark.mjs).
1
+ // Interactive TUI helpers — readline pickers, banner renderers, arrow-key
2
+ // menu, provider/model selection, _quickPrompt. Extracted from cli.mjs (D4);
3
+ // lives in tui/ so banner asset imports are siblings.
5
4
  import { readConfig, writeConfig, _resolveAuthKey } from '../lib/config.mjs';
5
+ import { SLASH_COMMANDS } from './slash_commands.mjs';
6
6
  import { ensureRegistry, getRegistry } from '../lib/registry_boot.mjs';
7
7
  import { bucketProviders as _bucketProviders } from './provider_families.mjs';
8
8
  import { addCustomProvider } from '../providers/custom_provider.mjs';
@@ -13,13 +13,11 @@ import {
13
13
  } from '../providers/model_catalogue.mjs';
14
14
 
15
15
  export function _attachGhostAutocomplete(rl) {
16
- // Returns `{ dispose, suspend, resume }`. Dispose detaches the
17
- // keypress + rl 'line' listeners (failure to do so leaks the
18
- // event-loop ref, which is exactly the slow-exit bug v3.92
19
- // fixed). Suspend / resume gate the keypress handler so the
20
- // streaming chat output isn't interleaved with `\x1b[s\x1b[K\x1b[u`
21
- // ghost-render escapes — that interleaving is what surfaces as
22
- // visible gaps between Korean characters in long replies.
16
+ // Returns `{ dispose, suspend, resume }`. Dispose detaches the keypress +
17
+ // rl 'line' listeners (leaking them is the v3.92 slow-exit bug). Suspend /
18
+ // resume gate the keypress handler so streaming chat output isn't
19
+ // interleaved with `\x1b[s\x1b[K\x1b[u` ghost-render escapes that
20
+ // interleaving surfaced as visible gaps between Korean characters.
23
21
  const noop = () => {};
24
22
  if (!process.stdout.isTTY) return { dispose: noop, suspend: noop, resume: noop };
25
23
  const cmds = SLASH_COMMANDS.map((c) => c.cmd);
@@ -219,15 +217,16 @@ export async function _renderV5Banner(version) {
219
217
  return rows;
220
218
  }
221
219
 
222
- export function _printChatBanner(activeProvName, activeModel, version) {
220
+ export async function _printChatBanner(activeProvName, activeModel, version) {
223
221
  if (!process.stdout.isTTY) return;
224
- // Single-hue header: labels dim-orange, values/emphasis full-orange, so the
225
- // four caption rows below the box read as part of the same warm badge.
222
+ // Single-hue header: labels dim-orange, values/emphasis full-orange. Uses
223
+ // the v5 sloth splash (NOT the retired v4 figlet box see _renderV5Banner;
224
+ // figlet remains only as the missing-asset last resort).
226
225
  const dimOrange = (s) => `\x1b[2m\x1b[38;2;${_ORANGE_RGB}m${s}\x1b[0m`;
227
226
  const orange = _orange;
228
227
  const lines = [
229
228
  '',
230
- ..._renderBanner(version),
229
+ ...(await _renderV5Banner(version)),
231
230
  '',
232
231
  ` ${dimOrange('provider ·')} ${orange(activeProvName)}`,
233
232
  ` ${dimOrange('model ·')} ${orange(activeModel || '(default)')}`,