ispbills-icli 8.5.3 → 8.5.5

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
@@ -25,7 +25,7 @@ const PKG_NAME = 'ispbills-icli';
25
25
  const rawArgs = argv.slice(2);
26
26
 
27
27
  // Flags that consume the following token as their value.
28
- const VALUE_FLAGS = new Set(['--loader-style']);
28
+ const VALUE_FLAGS = new Set(['--loader-style', '-p', '--prompt', '--allow-tool', '--agent']);
29
29
 
30
30
  function has(name) {
31
31
  return rawArgs.includes(name);
@@ -109,12 +109,20 @@ function printHelp() {
109
109
 
110
110
  console.log(`\n ${BOLD}Flags${RESET}`);
111
111
  [
112
+ ['--banner', 'Force-show the animated splash banner'],
113
+ ['--allow-all / --yolo', 'Auto-approve all tool calls without prompting'],
114
+ ['--allow-tool TOOL', 'Pre-approve a specific tool (e.g. shell(git))'],
115
+ ['-p / --prompt TEXT', 'One-shot non-interactive mode'],
116
+ ['--resume / --continue', 'Resume the most recently closed session'],
117
+ ['--experimental', 'Enable experimental features'],
118
+ ['--agent=NAME', 'Delegate to a named custom agent'],
119
+ ['--cloud', 'Start session inside a cloud sandbox (stub)'],
112
120
  ['--reasoning', 'Stream reasoning inline (on by default)'],
113
121
  ['--no-reasoning', 'Hide the reasoning trace'],
114
122
  ['--loader-style STYLE', 'spinner | gradient | minimal'],
115
123
  ['--ascii', 'Force ASCII-safe glyphs (classic Windows cmd.exe)'],
116
124
  ['--unicode', 'Force full Unicode glyphs'],
117
- ].forEach(([c, d]) => console.log(` ${ACCENT}${c.padEnd(24)}${RESET}${DIM}${d}${RESET}`));
125
+ ].forEach(([c, d]) => console.log(` ${ACCENT}${c.padEnd(30)}${RESET}${DIM}${d}${RESET}`));
118
126
 
119
127
  console.log(`\n ${BOLD}Slash commands${RESET}`);
120
128
  for (const { cmd: c, hint, desc } of SLASH_COMMANDS) {
@@ -305,6 +313,25 @@ async function main() {
305
313
 
306
314
  const cfg = await ensureAuth();
307
315
 
316
+ // Apply launch flags to config
317
+ if (has('--allow-all') || has('--yolo')) {
318
+ cfg.tui = { ...(cfg.tui || {}), allowAll: true };
319
+ }
320
+ if (has('--experimental')) {
321
+ cfg.tui = { ...(cfg.tui || {}), experimental: true };
322
+ }
323
+ if (flag('--allow-tool')) {
324
+ const tool = flag('--allow-tool');
325
+ cfg.tui = { ...(cfg.tui || {}), allowedTools: [...(cfg.tui?.allowedTools || []), tool] };
326
+ }
327
+
328
+ // -p / --prompt: one-shot mode via flag
329
+ const promptFlag = flag('-p') || flag('--prompt');
330
+ if (promptFlag) {
331
+ await singleShot(cfg, promptFlag);
332
+ return;
333
+ }
334
+
308
335
  // Single-shot: any positional (non-flag) args form the question.
309
336
  if (positional.length) {
310
337
  await singleShot(cfg, positional.join(' '));
@@ -312,9 +339,15 @@ async function main() {
312
339
  }
313
340
 
314
341
  // 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
342
  const { runTui } = await import('../src/tui/run.js');
317
- const action = await runTui(cfg, { display });
343
+ const agentName = flag('--agent') || rawArgs.find((a) => a.startsWith('--agent='))?.split('=')[1];
344
+ const resumeMode = has('--resume') || has('--continue');
345
+ const action = await runTui(cfg, {
346
+ display,
347
+ banner: has('--banner'),
348
+ agentName,
349
+ resumeMode,
350
+ });
318
351
  if (action === 'logout') {
319
352
  const cleared = clearConfig();
320
353
  console.log(`\n ${cleared ? GREEN + glyphs.check + RESET + ' Logged out — credentials cleared.' : YELLOW + 'Already logged out.' + RESET}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ispbills-icli",
3
- "version": "8.5.3",
3
+ "version": "8.5.5",
4
4
  "description": "iCli — IspBills AI network engineer in your terminal",
5
5
  "keywords": [
6
6
  "ispbills",
package/src/commands.js CHANGED
@@ -1,4 +1,4 @@
1
- import { RESET, BOLD, DIM, GRAY, WHITE, ACCENT, GREEN } from './ui.js';
1
+ import { RESET, BOLD, DIM, GRAY, WHITE, ACCENT } from './ui.js';
2
2
 
3
3
  /**
4
4
  * All slash commands, used for the menu, help and Tab completion.
@@ -43,6 +43,8 @@ export const SLASH_COMMANDS = [
43
43
 
44
44
  // ── Backups & version control ──
45
45
  { cmd: '/git', hint: '[args]', desc: 'Run git in your backup repo (status/commit/push/log)', group: 'Backups', local: true },
46
+ { cmd: '/diff', hint: '', desc: 'Show the recent backup-repo diff', group: 'Backups', local: true },
47
+ { cmd: '/review', hint: '[focus]', desc: 'Review the last AI answer', group: 'Backups', local: true },
46
48
  { cmd: '/gist', hint: '', desc: 'Save the last answer or transcript to a GitHub gist', group: 'Backups', local: true },
47
49
 
48
50
  // ── Memory ──
@@ -52,26 +54,83 @@ export const SLASH_COMMANDS = [
52
54
  { cmd: '/copy', hint: '', desc: 'Copy the last AI answer to the clipboard', group: 'Memory', local: true },
53
55
 
54
56
  // ── Session & app ──
55
- { cmd: '/plan', hint: '[prompt]', desc: 'Switch to plan mode (Shift+Tab to cycle)', group: 'Session', local: true },
56
- { cmd: '/autopilot', hint: '', desc: 'Toggle autopilot mode (auto-apply fixes)', group: 'Session', local: true },
57
- { cmd: '/model', hint: '[name]', desc: 'Show or set the AI model', group: 'Session', local: true },
58
- { cmd: '/reasoning', hint: '', desc: 'Toggle reasoning display (Ctrl+T)', group: 'Session', local: true },
59
- { cmd: '/context', hint: '', desc: 'Show context window token usage', group: 'Session', local: true },
60
- { cmd: '/usage', hint: '', desc: 'Show session usage metrics', group: 'Session', local: true },
61
- { cmd: '/compact', hint: '[focus]', desc: 'Compress conversation history', group: 'Session', local: true },
62
- { cmd: '/session', hint: '', desc: 'Show session info (cwd, branch, tokens)', group: 'Session', local: true },
63
- { cmd: '/share', hint: '', desc: 'Share session to a GitHub gist', group: 'Session', local: true },
64
- { cmd: '/theme', hint: '', desc: 'View current colour theme info', group: 'Session', local: true },
65
- { cmd: '/new', hint: '', desc: 'Start a fresh conversation', group: 'Session', local: true },
66
- { cmd: '/history', hint: '', desc: 'Show conversation history', group: 'Session', local: true },
67
- { cmd: '/clear', hint: '', desc: 'Clear the screen', group: 'Session', local: true },
68
- { cmd: '/update', hint: '', desc: 'Update iCli to the latest version', group: 'Session', local: true },
69
- { cmd: '/logout', hint: '', desc: 'Log out and clear credentials', group: 'Session', local: true },
70
- { cmd: '/help', hint: '', desc: 'Show help', group: 'Session', local: true },
71
- { cmd: '/exit', hint: '', desc: 'Exit iCli', group: 'Session', local: true },
57
+ { cmd: '/plan', hint: '[prompt]', desc: 'Switch to plan mode (Shift+Tab to cycle)', group: 'Session', local: true },
58
+ { cmd: '/autopilot', hint: '', desc: 'Toggle autopilot mode (auto-apply fixes)', group: 'Session', local: true },
59
+ { cmd: '/allow-all', hint: '[on|off|show]', desc: 'Toggle auto-approval mode', group: 'Session', local: true },
60
+ { cmd: '/model', hint: '[name]', desc: 'Show or set the AI model', group: 'Session', local: true },
61
+ { cmd: '/models', hint: '[name]', desc: 'Alias for /model', group: 'Session', local: true },
62
+ { cmd: '/reasoning', hint: '', desc: 'Toggle reasoning display (Ctrl+T)', group: 'Session', local: true },
63
+ { cmd: '/context', hint: '', desc: 'Show context window token usage', group: 'Session', local: true },
64
+ { cmd: '/usage', hint: '', desc: 'Show session usage metrics', group: 'Session', local: true },
65
+ { cmd: '/compact', hint: '[focus]', desc: 'Compress conversation history', group: 'Session', local: true },
66
+ { cmd: '/session', hint: '', desc: 'Show session info (cwd, branch, tokens)', group: 'Session', local: true },
67
+ { cmd: '/resume', hint: '[id]', desc: 'Resume a previous session (picker)', group: 'Session', local: true },
68
+ { cmd: '/continue', hint: '[id]', desc: 'Alias for /resume', group: 'Session', local: true },
69
+ { cmd: '/rename', hint: '[name]', desc: 'Rename this session', group: 'Session', local: true },
70
+ { cmd: '/share', hint: '', desc: 'Share session to a GitHub gist', group: 'Session', local: true },
71
+ { cmd: '/theme', hint: '', desc: 'View current colour theme info', group: 'Session', local: true },
72
+ { cmd: '/cwd', hint: '', desc: 'Show the current working directory', group: 'Session', local: true },
73
+ { cmd: '/cd', hint: '[path]', desc: 'Change the working directory', group: 'Session', local: true },
74
+ { cmd: '/env', hint: '', desc: 'Show loaded environment info', group: 'Session', local: true },
75
+ { cmd: '/streamer-mode', hint: '', desc: 'Hide model names and token counts', group: 'Session', local: true },
76
+ { cmd: '/new', hint: '', desc: 'Start a fresh conversation', group: 'Session', local: true },
77
+ { cmd: '/reset', hint: '', desc: 'Alias for /new', group: 'Session', local: true },
78
+ { cmd: '/history', hint: '', desc: 'Show conversation history', group: 'Session', local: true },
79
+ { cmd: '/clear', hint: '', desc: 'Clear the screen', group: 'Session', local: true },
80
+ { cmd: '/restart', hint: '', desc: 'Restart CLI preserving session', group: 'Session', local: true },
81
+ { cmd: '/keep-alive', hint: '[on|off|busy|DURATION]', desc: 'Prevent machine sleep', group: 'Session', local: true },
82
+
83
+ // ── Permissions ──
84
+ { cmd: '/permissions', hint: '[show|reset]', desc: 'View or clear tool/path approvals', group: 'Permissions', local: true },
85
+ { cmd: '/allow-tool', hint: 'TOOL', desc: 'Pre-approve a specific tool', group: 'Permissions', local: true },
86
+ { cmd: '/reset-allowed-tools', hint: '', desc: 'Clear all in-session tool approvals', group: 'Permissions', local: true },
87
+ { cmd: '/add-dir', hint: 'PATH', desc: 'Add a directory to the allowed list', group: 'Permissions', local: true },
88
+ { cmd: '/list-dirs', hint: '', desc: 'Show all allowed directories', group: 'Permissions', local: true },
89
+ { cmd: '/sandbox', hint: '[enable|disable]', desc: 'Enable/disable local sandboxing', group: 'Permissions', local: true },
90
+ { cmd: '/experimental', hint: '[on|off|show]', desc: 'Toggle experimental features', group: 'Permissions', local: true },
91
+ { cmd: '/init', hint: '', desc: 'Initialize Copilot instructions for this repo', group: 'Permissions', local: true },
92
+
93
+ // ── Agents & models ──
94
+ { cmd: '/agent', hint: '', desc: 'Browse and select agents', group: 'Agents', local: true },
95
+ { cmd: '/skills', hint: '', desc: 'Toggle individual skills on/off', group: 'Agents', local: true },
96
+ { cmd: '/fleet', hint: '[prompt]', desc: 'Enable parallel subagent execution', group: 'Agents', local: true },
97
+ { cmd: '/tasks', hint: '', desc: 'View and manage background tasks', group: 'Agents', local: true },
98
+ { cmd: '/rubber-duck', hint: '[prompt]', desc: 'Get a second opinion from rubber-duck', group: 'Agents', local: true },
99
+ { cmd: '/research', hint: 'TOPIC', desc: 'Run deep research on a topic', group: 'Agents', local: true },
100
+ { cmd: '/mcp', hint: '[show|add|edit|delete|disable|enable|auth|reload|search]', desc: 'Manage MCP servers', group: 'Agents', local: true },
101
+ { cmd: '/plugin', hint: '[marketplace|install|uninstall|update|list]', desc: 'Manage plugins', group: 'Agents', local: true },
102
+ { cmd: '/delegate', hint: '[prompt]', desc: 'Delegate changes to a remote repo', group: 'Agents', local: true },
103
+
104
+ // ── Code ──
105
+ { cmd: '/terminal-setup', hint: '', desc: 'Configure terminal for Shift+Enter', group: 'Code', local: true },
106
+ { cmd: '/ide', hint: '', desc: 'Connect to a VS Code workspace', group: 'Code', local: true },
107
+ { cmd: '/pr', hint: '[view|create|fix|auto]', desc: 'Manage pull requests', group: 'Code', local: true },
108
+ { cmd: '/lsp', hint: '[show|test|reload|help]', desc: 'Manage language servers', group: 'Code', local: true },
109
+ { cmd: '/instructions', hint: '', desc: 'View and toggle custom instructions', group: 'Code', local: true },
110
+
111
+ // ── Scheduling (experimental) ──
112
+ { cmd: '/ask', hint: 'QUESTION', desc: 'Quick side-question without adding to history', group: 'Scheduling', local: true },
113
+ { cmd: '/after', hint: '[DELAY PROMPT]', desc: 'Schedule a one-shot prompt', group: 'Scheduling', local: true },
114
+ { cmd: '/every', hint: '[INTERVAL PROMPT]', desc: 'Schedule a recurring prompt', group: 'Scheduling', local: true },
115
+ { cmd: '/remote', hint: '[on|off]', desc: 'Manage remote steering', group: 'Scheduling', local: true },
116
+ { cmd: '/chronicle', hint: '[standup|tips|improve|reindex]', desc: 'Session history tools and insights', group: 'Scheduling', local: true },
117
+
118
+ // ── Help & Feedback ──
119
+ { cmd: '/changelog', hint: '', desc: 'Show recent npm package releases', group: 'Help', local: true },
120
+ { cmd: '/feedback', hint: '', desc: 'Show the feedback / bug-report URL', group: 'Help', local: true },
121
+ { cmd: '/update', hint: '', desc: 'Update iCli to the latest version', group: 'Help', local: true },
122
+ { cmd: '/downgrade', hint: 'VERSION', desc: 'Roll back to a specific CLI version', group: 'Help', local: true },
123
+ { cmd: '/app', hint: '', desc: 'Launch the GitHub Copilot desktop app', group: 'Help', local: true },
124
+ { cmd: '/user', hint: '', desc: 'Manage GitHub user list', group: 'Help', local: true },
125
+ { cmd: '/login', hint: '', desc: 'Log in to Copilot', group: 'Help', local: true },
126
+ { cmd: '/whoami', hint: '', desc: 'Show current user info', group: 'Help', local: true },
127
+ { cmd: '/clikit', hint: '[component]', desc: 'Preview CLI UI components', group: 'Help', local: true },
128
+ { cmd: '/extensions', hint: '[manage|mode]', desc: 'Manage CLI extensions', group: 'Help', local: true },
129
+ { cmd: '/logout', hint: '', desc: 'Log out and clear credentials', group: 'Help', local: true },
130
+ { cmd: '/help', hint: '', desc: 'Show help', group: 'Help', local: true },
131
+ { cmd: '/exit', hint: '', desc: 'Exit iCli', group: 'Help', local: true },
72
132
  ];
73
133
 
74
- /** readline completer for slash commands (used by the non-Ink fallback REPL). */
75
134
  export function slashCompleter(line) {
76
135
  if (line.startsWith('/')) {
77
136
  const hits = SLASH_COMMANDS.map((s) => s.cmd + ' ').filter((s) => s.startsWith(line));
@@ -80,16 +139,11 @@ export function slashCompleter(line) {
80
139
  return [[], line];
81
140
  }
82
141
 
83
- /**
84
- * Map a NOC shortcut command to a natural-language question for the AI.
85
- * Returns null for commands that are handled locally by the REPL.
86
- */
87
142
  export function slashToQuestion(line) {
88
143
  const [sc, ...rest] = line.trim().split(/\s+/);
89
144
  const arg = rest.join(' ');
90
145
  const on = (withArg, without) => (arg ? withArg : without);
91
146
  switch (sc) {
92
- // Devices & diagnostics
93
147
  case '/check': return on(`run full diagnostics on ${arg} and summarise any problems`, 'run diagnostics across all devices and flag anything unhealthy');
94
148
  case '/status': return on(`give a health summary for ${arg}`, 'give a health summary of every device in the fleet');
95
149
  case '/reachable': return 'which devices are reachable right now and which are down?';
@@ -102,7 +156,6 @@ export function slashToQuestion(line) {
102
156
  case '/reboot': return on(`reboot ${arg} safely`, 'which device should I reboot? list the devices first');
103
157
  case '/alarms': return 'show active alarms and recent faults across the network';
104
158
 
105
- // Optical / access
106
159
  case '/onu': return on(`show ONU ${arg} status and optical signal level`, 'list all ONUs with their status and signal levels');
107
160
  case '/optical': return on(`show optical RX/TX power in dBm for ${arg} and flag weak signals`, 'show optical RX/TX power across ONUs and flag any weak or out-of-range signals');
108
161
  case '/vlan': return on(`is VLAN ${arg} in use or free across the network?`, 'list all VLANs and show which are in use or free');
@@ -110,10 +163,10 @@ export function slashToQuestion(line) {
110
163
  case '/online': return 'list currently online PPPoE sessions';
111
164
  case '/offline': {
112
165
  const t = arg.toLowerCase();
113
- if (/olt/.test(t)) return 'list all OLTs that are currently offline or unreachable';
166
+ if (/olt/.test(t)) return 'list all OLTs that are currently offline or unreachable';
114
167
  if (/rout|nas|mikrotik|router/.test(t)) return 'list all routers / NAS devices that are currently offline or unreachable';
115
- if (/onu|ont/.test(t)) return 'list all ONUs that are currently offline';
116
- if (/cust|client|user/.test(t)) return 'list all customers that are currently offline';
168
+ if (/onu|ont/.test(t)) return 'list all ONUs that are currently offline';
169
+ if (/cust|client|user/.test(t)) return 'list all customers that are currently offline';
117
170
  return arg
118
171
  ? `list all ${arg} that are currently offline`
119
172
  : 'list everything that is currently offline — OLTs, routers and ONUs';
@@ -121,17 +174,16 @@ export function slashToQuestion(line) {
121
174
  case '/down': return on(`is the ${arg} circuit / uplink down? show its status`, 'list all down circuits, uplinks or backbone links across the network');
122
175
  case '/bandwidth': return on(`show traffic and bandwidth usage on ${arg}`, 'show current bandwidth usage across the network and flag the top talkers');
123
176
 
124
- // Layer 2/3 lookups
125
177
  case '/mac': return on(`locate MAC address ${arg} — which device and port is it on?`, 'how do I locate a MAC address? ask me for the address');
126
178
  case '/arp': return on(`show the ARP table for ${arg}`, 'show ARP tables and flag any duplicate or suspicious entries');
127
179
  case '/route': return on(`show the routing table for ${arg}`, 'show routing tables across the network');
128
180
  case '/overlaps': {
129
181
  const t = arg.toLowerCase();
130
- if (/vlan/.test(t)) return 'scan all devices for duplicate or overlapping VLAN ids and list each conflict with the devices/interfaces involved';
131
- if (/bgp|prefix|as\b|peer/.test(t)) return 'check BGP for overlapping or conflicting prefixes and duplicate AS announcements across routers and list each conflict';
132
- if (/route|routing/.test(t)) return 'find overlapping or conflicting routes across the routing tables and list each pair with the devices involved';
133
- if (/int|port/.test(t)) return 'find interfaces/ports with overlapping or duplicate address or VLAN assignments and list each conflict';
134
- if (/ip|subnet|network|cidr/.test(t)) return 'find overlapping or conflicting IP subnets and duplicate IP addresses across the network and list each conflict with the devices involved';
182
+ if (/vlan/.test(t)) return 'scan all devices for duplicate or overlapping VLAN ids and list each conflict with the devices/interfaces involved';
183
+ if (/bgp|prefix|as\b|peer/.test(t)) return 'check BGP for overlapping or conflicting prefixes and duplicate AS announcements across routers and list each conflict';
184
+ if (/route|routing/.test(t)) return 'find overlapping or conflicting routes across the routing tables and list each pair with the devices involved';
185
+ if (/int|port/.test(t)) return 'find interfaces/ports with overlapping or duplicate address or VLAN assignments and list each conflict';
186
+ if (/ip|subnet|network|cidr/.test(t)) return 'find overlapping or conflicting IP subnets and duplicate IP addresses across the network and list each conflict with the devices involved';
135
187
  return 'scan the whole network for any overlapping or conflicting IP subnets, duplicate IPs, duplicate/overlapping VLAN ids, interface assignment conflicts, and overlapping BGP prefixes or routes — list each conflict grouped by type with the devices involved';
136
188
  }
137
189
  case '/flapping': return on(`check ${arg} for flapping interfaces — list ports with frequent up/down transitions, their flap counts and last change time`, 'scan all devices for flapping interfaces (frequent up/down transitions) and list them with flap counts and the last state-change time');
@@ -140,7 +192,7 @@ export function slashToQuestion(line) {
140
192
  case '/trace': return on(`traceroute the path to ${arg} and show each hop`, 'what host should I traceroute?');
141
193
  case '/customer': return on(`look up customer ${arg} with their device, plan and session status`, 'show recently active customers');
142
194
 
143
- default: return null; // locally handled command
195
+ default: return null;
144
196
  }
145
197
  }
146
198