ispbills-icli 4.0.3 → 4.0.4

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/bin/icli.js +6 -6
  2. package/package.json +1 -1
  3. package/src/chat.js +16 -32
package/bin/icli.js CHANGED
@@ -4,18 +4,18 @@ import { stdin as input, stdout as output, argv, exit } from 'process';
4
4
  import chalk from 'chalk';
5
5
  import { loadConfig, configPath } from '../src/config.js';
6
6
  import { loginFlow } from '../src/auth.js';
7
- import { cols, inner, onResize, boxTop, boxBot, boxMid, boxRow, boxTopOpen, boxBotOpen } from '../src/layout.js';
7
+ import { inner, onResize, boxTop, boxBot, boxMid, boxRow } from '../src/layout.js';
8
8
  import {
9
9
  streamChat, printBanner, printSlashMenu, printUserBox,
10
10
  SLASH_COMMANDS, slashCompleter,
11
11
  } from '../src/chat.js';
12
12
 
13
13
  const P = {
14
- border: chalk.hex('#3D444D'),
15
- dim: chalk.hex('#9198A1'),
16
- muted: chalk.hex('#6e7781'),
17
- accent: chalk.hex('#4493F8').bold,
18
- accentD: chalk.hex('#4493F8'),
14
+ border: chalk.hex('#303134'),
15
+ dim: chalk.hex('#9AA0A6'),
16
+ muted: chalk.hex('#80868B'),
17
+ accent: chalk.hex('#8AB4F8').bold,
18
+ accentD: chalk.hex('#8AB4F8'),
19
19
  bold: chalk.bold.white,
20
20
  ok: chalk.green,
21
21
  warn: chalk.yellow,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ispbills-icli",
3
- "version": "4.0.3",
3
+ "version": "4.0.4",
4
4
  "description": "iCli — IspBills AI network engineer in your terminal",
5
5
  "keywords": [
6
6
  "ispbills",
package/src/chat.js CHANGED
@@ -7,13 +7,13 @@ import { cols, inner, visLen, padRight, stripAnsi,
7
7
  boxTop, boxMid, boxBot, boxTopOpen, boxBotOpen,
8
8
  boxRow, boxLine } from './layout.js';
9
9
 
10
- // ── Copilot CLI palette ────────────────────────────────────────────────────────
10
+ // ── Gemini-style palette ───────────────────────────────────────────────────────
11
11
  const P = {
12
- border: chalk.hex('#3D444D'),
13
- dim: chalk.hex('#9198A1'),
14
- muted: chalk.hex('#6e7781'),
15
- accent: chalk.hex('#4493F8'),
16
- accentB: chalk.hex('#4493F8').bold,
12
+ border: chalk.hex('#303134'),
13
+ dim: chalk.hex('#9AA0A6'),
14
+ muted: chalk.hex('#80868B'),
15
+ accent: chalk.hex('#8AB4F8'),
16
+ accentB: chalk.hex('#8AB4F8').bold,
17
17
  white: chalk.white,
18
18
  bold: chalk.bold.white,
19
19
  ok: chalk.green,
@@ -70,21 +70,12 @@ const shortModel = (m) =>
70
70
  // ── Banner ────────────────────────────────────────────────────────────────────
71
71
  export function printBanner(cfg, meta = {}) {
72
72
  const model = meta.model ? shortModel(meta.model) : (cfg?._model ?? null);
73
- const w = cols();
74
73
 
75
74
  process.stdout.write('\n');
76
-
77
- // Top border
78
- process.stdout.write(boxTop('', P.border) + '\n');
79
-
80
- // Title row
81
- const title = P.bold('iCopilot') + P.dim(' · IspBills AI Network Engineer');
82
- process.stdout.write(boxRow(title, P.border) + '\n');
83
-
84
- // Divider
75
+ process.stdout.write(boxTop('iCopilot', P.border) + '\n');
76
+ process.stdout.write(boxRow(P.dim('Gemini-style terminal mode'), P.border) + '\n');
85
77
  process.stdout.write(boxMid(P.border) + '\n');
86
78
 
87
- // Session info rows
88
79
  const row1parts = [];
89
80
  if (model) row1parts.push(P.dim('model ') + P.white(model));
90
81
  if (cfg?.user?.name) row1parts.push(P.dim('user ') + P.white(cfg.user.name));
@@ -98,10 +89,8 @@ export function printBanner(cfg, meta = {}) {
98
89
  process.stdout.write(boxRow(P.dim('url ') + P.accent(url), P.border) + '\n');
99
90
  }
100
91
 
101
- // Divider
102
92
  process.stdout.write(boxMid(P.border) + '\n');
103
93
 
104
- // Hints row
105
94
  const hints = [
106
95
  P.accentB('/') + P.muted(' commands'),
107
96
  P.accentB('Tab') + P.muted(' autocomplete'),
@@ -109,8 +98,6 @@ export function printBanner(cfg, meta = {}) {
109
98
  P.accentB('Ctrl+C') + P.muted(' exit'),
110
99
  ].join(P.muted(' '));
111
100
  process.stdout.write(boxRow(hints, P.border) + '\n');
112
-
113
- // Bottom border
114
101
  process.stdout.write(boxBot(P.border) + '\n\n');
115
102
  }
116
103
 
@@ -130,7 +117,7 @@ export const SLASH_COMMANDS = [
130
117
 
131
118
  export function printSlashMenu() {
132
119
  process.stdout.write('\n');
133
- process.stdout.write(boxTop('Commands', P.border) + '\n');
120
+ process.stdout.write(boxTop('Slash commands', P.border) + '\n');
134
121
  for (const { cmd: c, hint, desc } of SLASH_COMMANDS) {
135
122
  const key = P.accentB(c) + (hint ? P.dim(' ' + hint) : '');
136
123
  const line = padRight(key, 22) + ' ' + P.dim(desc);
@@ -150,21 +137,21 @@ export function slashCompleter(line) {
150
137
  // ── User message box ───────────────────────────────────────────────────────────
151
138
  export function printUserBox(question) {
152
139
  process.stdout.write('\n');
153
- process.stdout.write(boxTop('You', P.accentB) + '\n');
140
+ process.stdout.write(boxTop('You', P.border) + '\n');
154
141
  // Word-wrap the question to fit inside the box
155
142
  const maxW = inner();
156
143
  const words = question.split(' ');
157
144
  let line = '';
158
145
  for (const word of words) {
159
146
  if (line.length + word.length + 1 > maxW && line) {
160
- process.stdout.write(boxRow(P.white(line), P.accentB) + '\n');
147
+ process.stdout.write(boxRow(P.white(line), P.border) + '\n');
161
148
  line = word;
162
149
  } else {
163
150
  line = line ? line + ' ' + word : word;
164
151
  }
165
152
  }
166
- if (line) process.stdout.write(boxRow(P.white(line), P.accentB) + '\n');
167
- process.stdout.write(boxBot(P.accentB) + '\n');
153
+ if (line) process.stdout.write(boxRow(P.white(line), P.border) + '\n');
154
+ process.stdout.write(boxBot(P.border) + '\n');
168
155
  }
169
156
 
170
157
  // ── streamChat ────────────────────────────────────────────────────────────────
@@ -203,19 +190,17 @@ export async function streamChat(cfg, messages, context = {}, opts = {}) {
203
190
  let rawAnswer = '';
204
191
  let finalResult = null;
205
192
 
206
- // Open the iCopilot response box
207
193
  function ensureBoxOpen() {
208
194
  if (boxOpen) return;
209
195
  boxOpen = true;
210
196
  process.stdout.write('\n' + boxTopOpen('iCopilot', P.border) + '\n');
211
197
  }
212
198
 
213
- // Ora spinner — sits on a │ prefixed line
214
199
  const spinner = ora({
215
200
  text: P.dim('Thinking…'),
216
201
  color: 'blue',
217
202
  spinner: 'dots',
218
- prefixText: P.border('│') + ' ',
203
+ prefixText: P.border('│') + ' ',
219
204
  });
220
205
 
221
206
  const stopSpinner = () => { if (spinner.isSpinning) spinner.stop(); };
@@ -224,8 +209,7 @@ export async function streamChat(cfg, messages, context = {}, opts = {}) {
224
209
  if (reasoningOpen) return;
225
210
  stopSpinner();
226
211
  reasoningOpen = true;
227
- process.stdout.write(boxLine('', P.border) + '\n');
228
- process.stdout.write(boxLine(P.dim('╌ Reasoning ') + P.border('╌'.repeat(Math.max(0, inner() - 14))), P.border) + '\n');
212
+ process.stdout.write(boxLine(P.dim('reasoning'), P.border) + '\n');
229
213
  process.stdout.write(boxLine(P.border('│ '), P.border));
230
214
  }
231
215
 
@@ -240,7 +224,7 @@ export async function streamChat(cfg, messages, context = {}, opts = {}) {
240
224
 
241
225
  function closeReasoning() {
242
226
  if (!reasoningOpen) return;
243
- process.stdout.write('\n' + boxLine('', P.border) + '\n');
227
+ process.stdout.write('\n');
244
228
  reasoningOpen = false;
245
229
  }
246
230