ispbills-icli 8.7.8 → 8.7.10

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ispbills-icli",
3
- "version": "8.7.8",
3
+ "version": "8.7.10",
4
4
  "description": "iCli — IspBills AI network engineer in your terminal",
5
5
  "keywords": [
6
6
  "ispbills",
package/src/banner.js CHANGED
@@ -13,7 +13,7 @@ const LOGO = [
13
13
  const LOGO_WIDTH = Math.max(...LOGO.map((l) => l.length));
14
14
 
15
15
  /**
16
- * Full iPolot banner. On narrow terminals falls back to a compact header.
16
+ * Full iCopilot banner. On narrow terminals falls back to a compact header.
17
17
  * A full-width rule frames the header so it uses the whole window.
18
18
  *
19
19
  * @param {object} cfg Loaded config ({ url, user, _model }).
@@ -26,9 +26,9 @@ export function printBanner(cfg = {}, opts = {}) {
26
26
  console.log();
27
27
  if (width >= LOGO_WIDTH) {
28
28
  for (const line of LOGO) console.log(ACCENT + BOLD + line + RESET);
29
- console.log(` ${DIM}iPolot — network engineer in your terminal${RESET}`);
29
+ console.log(` ${DIM}iCopilot — network engineer in your terminal${RESET}`);
30
30
  } else {
31
- console.log(` ${BOLD}iPolot${RESET} ${DIM}— IspBills AI terminal${RESET}`);
31
+ console.log(` ${BOLD}iCopilot${RESET} ${DIM}— IspBills AI terminal${RESET}`);
32
32
  }
33
33
  console.log();
34
34
 
package/src/commands.js CHANGED
@@ -121,9 +121,9 @@ export const SLASH_COMMANDS = [
121
121
  { cmd: '/bug', hint: '', desc: 'Report a bug (alias for /feedback)', group: 'Help', local: true },
122
122
  { cmd: '/update', hint: '', desc: 'Update iCli to the latest version', group: 'Help', local: true },
123
123
  { cmd: '/downgrade', hint: 'VERSION', desc: 'Roll back to a specific CLI version', group: 'Help', local: true },
124
- { cmd: '/app', hint: '', desc: 'Show instructions to open the iPolot web app', group: 'Help', local: true },
124
+ { cmd: '/app', hint: '', desc: 'Show instructions to open the iCopilot web app', group: 'Help', local: true },
125
125
  { cmd: '/user', hint: '', desc: 'Manage GitHub user list', group: 'Help', local: true },
126
- { cmd: '/login', hint: '', desc: 'Log in to iPolot', group: 'Help', local: true },
126
+ { cmd: '/login', hint: '', desc: 'Log in to iCopilot', group: 'Help', local: true },
127
127
  { cmd: '/whoami', hint: '', desc: 'Show current user info', group: 'Help', local: true },
128
128
  { cmd: '/clikit', hint: '[component]', desc: 'Preview CLI UI components', group: 'Help', local: true },
129
129
  { cmd: '/extensions', hint: '[manage|mode]', desc: 'Manage CLI extensions', group: 'Help', local: true },
package/src/tui/app.js CHANGED
@@ -439,7 +439,7 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
439
439
  const [deviceError, setDeviceError] = useState(null);
440
440
  const chipsRows = (!busy && chips.length && !choice && !search && !sessionPicker && !diffState) ? 1 : 0;
441
441
  const composerRows = 2;
442
- const chromeRows = 2 + composerRows + 1 + chipsRows + 2; // +2 for two footer rows
442
+ const chromeRows = 2 + composerRows + 1 + chipsRows + 1; // tabBar + composer + sep + chips + 1 footer row
443
443
  const viewportRows = Math.max(3, rows - chromeRows);
444
444
  const scrollPage = Math.max(4, viewportRows - 2);
445
445
 
@@ -916,7 +916,7 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
916
916
  options: [
917
917
  { label: '1. Yes', value: TOOL_APPROVAL_ONCE },
918
918
  { label: `2. Yes, and approve ${toolName} for the rest of the session`, value: TOOL_APPROVAL_SESSION },
919
- { label: '3. No, and tell iPolot what to do differently (Esc)', value: null },
919
+ { label: '3. No, and tell iCopilot what to do differently (Esc)', value: null },
920
920
  ],
921
921
  });
922
922
  } else if (type === 'prompt' || type === 'choice') {
@@ -1685,7 +1685,7 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
1685
1685
  return;
1686
1686
  }
1687
1687
  if (q === '/app') {
1688
- pushNotice('iPolot web app — open your IspBills instance in the browser with /o or by typing the URL.', C.muted);
1688
+ pushNotice('iCopilot web app — open your IspBills instance in the browser with /o or by typing the URL.', C.muted);
1689
1689
  return;
1690
1690
  }
1691
1691
  if (q === '/user' || q.startsWith('/user ')) {
@@ -1776,7 +1776,7 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
1776
1776
  if (value == null) {
1777
1777
  if (currentChoice?.isToolApproval || /⚙ Tool request|tool request|approval|shell:/i.test(`${currentChoice?.title || ''} ${currentChoice?.note || ''}`)) {
1778
1778
  setChoice({
1779
- title: 'Tell iPolot what to do differently:',
1779
+ title: 'Tell iCopilot what to do differently:',
1780
1780
  note: '',
1781
1781
  sel: 0,
1782
1782
  text: '',
@@ -2133,23 +2133,23 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
2133
2133
  const tokenCount = approxTokens(convo.current);
2134
2134
  const tokenLabel = contextUsageLabel(tokenCount);
2135
2135
  const modelLabel = streamerMode ? '' : shortModel(model || modelRef.current || 'server default');
2136
- // §8: progressive path shorteningreserve space for right section
2137
- const footerRightEstLen = (modelLabel.length || 0) + (tokenLabel.length || 0) + 8;
2136
+ // §8: single footer row (GH Copilot CLI style) cwd·branch on left, mode·model·tokens on right
2137
+ const modeLabel = mode === 'autopilot' ? 'AUTOPILOT' : mode === 'plan' ? 'PLAN' : null;
2138
+ const footerRightEstLen = (modeLabel ? modeLabel.length + 3 : 0) + (modelLabel.length || 0) + (tokenLabel.length || 0) + 8;
2138
2139
  const cwdMaxLen = Math.max(12, cols - footerRightEstLen - (branch ? branch.length + 6 : 0) - 4);
2139
2140
  const cwd = shortenPath(process.cwd(), cwdMaxLen);
2140
- const footerLeft = [cwd, branch ? `${glyphs.gitBranch}${branch}` : null].filter(Boolean).join(midDot());
2141
- const footerInfoRight = streamerMode ? '' : [modelLabel, tokenLabel].filter(Boolean).join(midDot());
2142
- // Status row: working indicator when busy, key hints when idle, hint message when set
2143
- const footerStatusLeft = busy
2144
- ? `${glyphs.spinner} Working\u2026`
2141
+ const footerLeft = busy
2142
+ ? `${glyphs.arrow} Working\u2026`
2145
2143
  : hint
2146
2144
  ? hint
2147
- : activeTab !== 'session'
2148
- ? `Enter Session ${midDot()} r refresh ${midDot()} Tab next tab ${midDot()} 1-9 insert command`
2149
- : `? help ${midDot()} / commands ${midDot()} @ mention ${midDot()} \u2191\u2193 history ${midDot()} Tab mode`;
2150
- const footerStatusColor = busy ? C.warning : hint ? C.accent : C.brand;
2151
- const footerStatusRight = busy ? `Ctrl+C cancel` : mode === 'autopilot' ? 'AUTOPILOT' : mode === 'plan' ? 'PLAN' : '';
2152
- const footerStatusRightColor = busy ? C.warning : mode === 'autopilot' ? C.warning : mode === 'plan' ? C.accent : C.muted;
2145
+ : [cwd, branch ? `${glyphs.gitBranch}${branch}` : null].filter(Boolean).join(midDot());
2146
+ const footerLeftColor = busy ? C.warning : hint ? C.accent : C.muted;
2147
+ const footerRight = busy
2148
+ ? `Ctrl+C cancel`
2149
+ : streamerMode
2150
+ ? ''
2151
+ : [modeLabel, modelLabel, tokenLabel].filter(Boolean).join(midDot());
2152
+ const footerRightColor = busy ? C.warning : mode === 'autopilot' ? C.warning : mode === 'plan' ? C.accent : C.muted;
2153
2153
  const composerMode = shellMode ? 'shell' : mode;
2154
2154
 
2155
2155
  // ── Viewport slicing ───────────────────────────────────────────────────────
@@ -2175,9 +2175,8 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
2175
2175
 
2176
2176
  const scrollPct = maxScrollRef.current > 0 ? Math.round((scrollOffset / maxScrollRef.current) * 100) : 100;
2177
2177
  const scrollIndicator = hasAbove
2178
- ? html`<${Box} paddingX=${1} justifyContent="space-between" width=${cols}>
2179
- <${Text} color=${C.muted} dimColor>${glyphs.up} ${aboveCount} above ${midDot()} PgUp/PgDn ${midDot()} scroll<//>
2180
- <${Text} color=${C.muted} dimColor>${scrollPct}%<//>
2178
+ ? html`<${Box} paddingX=${1} justifyContent="flex-end" width=${cols}>
2179
+ <${Text} color=${C.muted} dimColor>${glyphs.up} ${aboveCount} above ${midDot()} ${scrollPct}%<//>
2181
2180
  <//>`
2182
2181
  : null;
2183
2182
 
@@ -2194,7 +2193,7 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
2194
2193
  />
2195
2194
  ${diffState.commentInput
2196
2195
  ? html`<${Choice}
2197
- title=${`Tell iPolot what stands out about ${diffState.commentInput.file}:${diffState.commentInput.lineNumber || '?'}`}
2196
+ title=${`Tell iCopilot what stands out about ${diffState.commentInput.file}:${diffState.commentInput.lineNumber || '?'}`}
2198
2197
  note=${diffState.commentInput.content}
2199
2198
  sel=${0}
2200
2199
  allowText=${true}
@@ -2270,16 +2269,9 @@ export function App({ cfg, display = {}, onExternal, onExit, initialQuestion, sh
2270
2269
  <${Text} color=${C.separator}>${'─'.repeat(Math.max(1, cols))}<//>
2271
2270
  <${Box} paddingX=${1} width=${cols}>
2272
2271
  <${Box} flexGrow=${1}>
2273
- <${Text} color=${footerStatusColor} bold=${busy} wrap="truncate-end">${footerStatusLeft}<//>
2272
+ <${Text} color=${footerLeftColor} bold=${busy} dimColor=${!busy && !hint} wrap="truncate-end">${footerLeft}<//>
2274
2273
  <//>
2275
- <${Text} color=${footerStatusRightColor} bold wrap="truncate-end">${footerStatusRight}<//>
2276
- <//>
2277
-
2278
- <${Box} paddingX=${1} width=${cols}>
2279
- <${Box} flexGrow=${1}>
2280
- <${Text} color=${C.muted} dimColor wrap="truncate-end">${footerLeft}<//>
2281
- <//>
2282
- <${Text} color=${C.muted} dimColor wrap="truncate-end">${footerInfoRight}<//>
2274
+ <${Text} color=${footerRightColor} bold=${mode === 'autopilot' || mode === 'plan'} dimColor=${!busy && !modeLabel} wrap="truncate-end">${footerRight}<//>
2283
2275
  <//>
2284
2276
  <//>
2285
2277
  <//>`;
@@ -168,7 +168,7 @@ export function Banner({ cfg = {}, model, width = 80, compact = false, streamerM
168
168
  if (compact) {
169
169
  return html`
170
170
  <${Box} marginBottom=${1}>
171
- <${Text} color=${C.accent} bold>${glyphs.ring} iPolot <//>
171
+ <${Text} color=${C.accent} bold>${glyphs.ring} iCopilot <//>
172
172
  <${Text} color=${C.muted}>${midDot()}<//>
173
173
  <${Text} color=${C.muted}>${m}<//>
174
174
  ${cfg.user?.name ? html`<${Text} color=${C.muted}>${midDot()}<//>` : null}
@@ -183,7 +183,7 @@ export function Banner({ cfg = {}, model, width = 80, compact = false, streamerM
183
183
  <//>
184
184
 
185
185
  <${Box} marginTop=${1} justifyContent="center">
186
- <${Text} color=${C.accent} bold>${glyphs.ring} iPolot<//>
186
+ <${Text} color=${C.accent} bold>${glyphs.ring} iCopilot<//>
187
187
  <${Text} color=${C.muted}> ${dash()} IspBills network engineer in your terminal<//>
188
188
  <//>
189
189
 
@@ -271,7 +271,7 @@ export function AssistantMessage({ text, cols = 80, ts, label, streaming = false
271
271
  <${Sep} cols=${cols} />
272
272
  <${Box} flexDirection="row" justifyContent="space-between" width=${cols} paddingX=${1}>
273
273
  <${Box}>
274
- <${Text} color=${C.accent} bold>${glyphs.copilotDot} <//><${Text} bold>iPolot${streaming ? ' ●' : ''}<//>
274
+ <${Text} color=${C.accent} bold>${glyphs.copilotDot} <//><${Text} bold>iCopilot${streaming ? ' ●' : ''}<//>
275
275
  <//>
276
276
  <${Text} color=${C.muted}>${stamp}<//>
277
277
  <//>
@@ -380,7 +380,7 @@ export function StatusLines({ lines = [], busy = false, navigable = false }) {
380
380
  useEffect(() => { setSel(-1); setExpanded(new Set()); }, [lines.length]);
381
381
 
382
382
  useInput((input, key) => {
383
- if (!navigable) return;
383
+ if (!navigable || !key) return;
384
384
  if (key.upArrow || input === 'k') { setSel((i) => Math.max(0, (i < 0 ? lines.length - 1 : i) - 1)); return; }
385
385
  if (key.downArrow || input === 'j') { setSel((i) => Math.min(lines.length - 1, (i < 0 ? -1 : i) + 1)); return; }
386
386
  if ((key.return || input === ' ') && sel >= 0) {
@@ -388,7 +388,7 @@ export function StatusLines({ lines = [], busy = false, navigable = false }) {
388
388
  return;
389
389
  }
390
390
  if (key.escape) { setSel(-1); return; }
391
- });
391
+ }, { isActive: navigable });
392
392
 
393
393
  if (!lines.length) return null;
394
394
  const lastIdx = lines.length - 1;
@@ -686,7 +686,7 @@ export function Choice({ title, note, options = [], sel = 0, allowText = false,
686
686
  ${allowText
687
687
  ? html`<${Box} key="freetext" marginTop=${1}>
688
688
  <${Text} color=${focusText ? C.accent : C.muted}>${focusText ? glyphs.prompt + ' ' : ' '}<//>
689
- <${Text} color=${C.muted}>Tell iPolot what to do differently: <//>
689
+ <${Text} color=${C.muted}>Tell iCopilot what to do differently: <//>
690
690
  <${Text} color=${C.white}>${text}<//>${focusText ? html`<${Text} inverse> <//>` : null}
691
691
  <//>`
692
692
  : null}
package/src/tui/run.js CHANGED
@@ -93,7 +93,7 @@ function exitAltScreen() {
93
93
  altScreenActive = false;
94
94
  }
95
95
 
96
- // iPolot wordmark in block letters
96
+ // iCopilot wordmark in block letters
97
97
  const LOGO = [
98
98
  ' ██╗ ██████╗ ██████╗ ██████╗ ██╗██╗ ██████╗ ████████╗',
99
99
  ' ██║██╔════╝██╔═══██╗██╔══██╗██║██║ ██╔═══██╗╚══██╔══╝',
@@ -145,7 +145,7 @@ async function animateSplash(cfg = {}) {
145
145
  const R = '\x1b[0m';
146
146
 
147
147
  const hr = `${SEP}${'─'.repeat(cols)}${R}`;
148
- const subtitle = `${ACC}◈ iPolot${R} ${DIM}IspBills network engineer in your terminal${R}`;
148
+ const subtitle = `${ACC}◈ iCopilot${R} ${DIM}IspBills network engineer in your terminal${R}`;
149
149
  const subtitleLen = subtitle.replace(/\x1b\[[0-9;]*m/g, '').length;
150
150
  const subPad = ' '.repeat(Math.max(0, Math.floor((cols - subtitleLen) / 2)));
151
151