ispbills-icli 8.5.1 → 8.5.3

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/bin/icli.js CHANGED
@@ -311,22 +311,17 @@ async function main() {
311
311
  return;
312
312
  }
313
313
 
314
- // Interactive: use the rich Ink TUI on a real terminal; fall back to the
315
- // plain readline REPL when stdout/stdin is not a TTY (pipes, dumb terminals).
316
- if (output.isTTY && input.isTTY) {
317
- const { runTui } = await import('../src/tui/run.js');
318
- const action = await runTui(cfg, { display });
319
- if (action === 'logout') {
320
- const cleared = clearConfig();
321
- console.log(`\n ${cleared ? GREEN + glyphs.check + RESET + ' Logged out — credentials cleared.' : YELLOW + 'Already logged out.' + RESET}`);
322
- console.log(` ${DIM}Run ${RESET}${ACCENT}icli login${RESET}${DIM} to sign in again.${RESET}\n`);
323
- } else if (action === 'update') {
324
- selfUpdate();
325
- }
326
- return;
314
+ // Always use the Ink TUI Ink handles non-TTY environments gracefully.
315
+ // The old readline REPL fallback is kept only for explicit pipe/script usage.
316
+ const { runTui } = await import('../src/tui/run.js');
317
+ const action = await runTui(cfg, { display });
318
+ if (action === 'logout') {
319
+ const cleared = clearConfig();
320
+ console.log(`\n ${cleared ? GREEN + glyphs.check + RESET + ' Logged out — credentials cleared.' : YELLOW + 'Already logged out.' + RESET}`);
321
+ console.log(` ${DIM}Run ${RESET}${ACCENT}icli login${RESET}${DIM} to sign in again.${RESET}\n`);
322
+ } else if (action === 'update') {
323
+ selfUpdate();
327
324
  }
328
-
329
- await interactiveRepl(cfg);
330
325
  }
331
326
 
332
327
  main().catch((e) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ispbills-icli",
3
- "version": "8.5.1",
3
+ "version": "8.5.3",
4
4
  "description": "iCli — IspBills AI network engineer in your terminal",
5
5
  "keywords": [
6
6
  "ispbills",
package/src/tui/app.js CHANGED
@@ -627,7 +627,7 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion })
627
627
  <//>`
628
628
  : null}
629
629
 
630
- <${TabBar} active=${activeTab} cols=${cols} />
630
+ <${TabBar} active=${activeTab} cols=${cols} mode=${mode} />
631
631
 
632
632
  ${!busy && chips.length ? html`<${FollowupChips} chips=${chips} active=${activeChip} />` : null}
633
633
 
@@ -636,8 +636,6 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion })
636
636
  ? html`<${Choice} ...${choice} />`
637
637
  : html`<${Composer} onSubmit=${onSubmit} busy=${busy} width=${cols} />`}
638
638
 
639
- <${Text} color=${C.separator}>${'─'.repeat(Math.max(1, cols))}<//>
640
-
641
639
  <${Box} paddingX=${1} width=${cols}>
642
640
  <${Box} flexGrow=${1}>
643
641
  <${Text} color=${C.muted} wrap="truncate-end">${footerLeft}<//>
@@ -25,19 +25,28 @@ const TABS = [
25
25
  { id: 'alarms', label: 'Alarms' },
26
26
  ];
27
27
 
28
- export function TabBar({ active = 'session', cols = 80, onSwitch }) {
28
+ export function TabBar({ active = 'session', cols = 80, mode = 'ask' }) {
29
+ // Deep-blue background track per spec (mirrors \x1b[44m ANSI blue).
30
+ // Active tab wrapped in [brackets] bold/white; inactive dimmed.
31
+ // Right side shows the current mode badge.
32
+ const modeBadge = mode !== 'ask'
33
+ ? ` ${mode === 'autopilot' ? '⚡ AUTO' : '📋 PLAN'}`
34
+ : '';
29
35
  return html`
30
- <${Box} width=${cols} paddingX=${1} backgroundColor="#0D1117">
31
- ${TABS.map((t, i) => {
32
- const on = t.id === active;
33
- return html`
34
- <${Box} key=${t.id}>
35
- ${i > 0 ? html`<${Text} color=${C.muted}> <//>` : null}
36
- ${on
37
- ? html`<${Text} color="white" bold>[${t.label}]<//>`
38
- : html`<${Text} color=${C.muted}>${t.label}<//>`}
39
- <//>`;
40
- })}
36
+ <${Box} width=${cols} backgroundColor="blue">
37
+ <${Box} paddingX=${1} flexGrow=${1}>
38
+ ${TABS.map((t, i) => {
39
+ const on = t.id === active;
40
+ return html`
41
+ <${Box} key=${t.id}>
42
+ ${i > 0 ? html`<${Text} color="cyan" backgroundColor="blue"> <//>` : null}
43
+ ${on
44
+ ? html`<${Text} color="white" bold backgroundColor="blue">[${t.label}]<//>`
45
+ : html`<${Text} color="cyan" backgroundColor="blue">${t.label}<//>`}
46
+ <//>`;
47
+ })}
48
+ <//>
49
+ ${modeBadge ? html`<${Box} paddingRight=${1}><${Text} color="yellow" bold backgroundColor="blue">${modeBadge}<//><//>` : null}
41
50
  <//>`;
42
51
  }
43
52
 
@@ -111,10 +120,9 @@ function withMentions(text, base = C.white) {
111
120
  );
112
121
  }
113
122
 
114
- // Full-width separator line, drawn in muted separator colour.
123
+ // Full-width separator line using - (ASCII dash) per spec §6: "Full-width `-` characters in #30363D".
115
124
  function Sep({ cols = 80 }) {
116
- return html`<${Text} color=${C.separator}>${''.repeat(Math.max(1, cols))}<//>`;
117
- }
125
+ return html`<${Text} color=${C.separator}>${'-'.repeat(Math.max(1, cols))}<//>`;}
118
126
 
119
127
  /** The user's prompt block — separator + "You" label + text. */
120
128
  export function UserMessage({ text, cols = 80 }) {
@@ -218,8 +218,8 @@ export function Composer({ onSubmit, busy, width = 80 }) {
218
218
  // Prompt glyph: ❯ (success/green) idle; ⧖ (warning/amber) busy.
219
219
  const promptGlyph = busy ? glyphs.busy : glyphs.prompt;
220
220
  const promptColor = busy ? C.warning : C.success;
221
- // Ghost hint text when empty
222
- const ghostHint = busy ? 'Working…' : 'Enter @ to mention a device or / for commands…';
221
+ // Ghost hint text when empty — per spec §7
222
+ const ghostHint = busy ? 'Working…' : 'Enter @ to mention files or / for commands…';
223
223
 
224
224
  return html`
225
225
  <${Box} flexDirection="column" width=${width}>
@@ -259,5 +259,7 @@ export function Composer({ onSubmit, busy, width = 80 }) {
259
259
  <${Text}>${before}<//><${Text} inverse>${at}<//><${Text}>${after}<//><${Text} color=${C.muted}>${ghost}<//>
260
260
  <//>`}
261
261
  <//>
262
+
263
+ <${Text} color=${C.separator}>${'─'.repeat(Math.max(1, width))}<//>
262
264
  <//>`;
263
265
  }