@openinference/cli 1.1.0 → 1.2.0

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/dist/setup.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.WIZARD_PICK_COUNT = void 0;
3
+ exports.WIZARD_SHOW_COUNT = exports.WIZARD_PICK_COUNT = void 0;
4
4
  exports.runSetup = runSetup;
5
5
  exports.printRecommendPreview = printRecommendPreview;
6
6
  const recommend_1 = require("./recommend");
@@ -9,7 +9,10 @@ const config_1 = require("./config");
9
9
  const prompt_1 = require("./prompt");
10
10
  const ollama_1 = require("./ollama");
11
11
  const use_cases_1 = require("./use-cases");
12
- exports.WIZARD_PICK_COUNT = 10;
12
+ /** How many picks to compute (so "show more" has content). */
13
+ exports.WIZARD_PICK_COUNT = 15;
14
+ /** How many to show before the user asks for more. */
15
+ exports.WIZARD_SHOW_COUNT = 5;
13
16
  async function resolvePool(catalog, hw, opts) {
14
17
  const auto = Boolean(opts.yes);
15
18
  const lockedUseCase = opts.useCase;
@@ -102,12 +105,12 @@ async function runSetup(opts) {
102
105
  (0, prompt_1.printTooSmallHelp)(hw);
103
106
  return;
104
107
  }
105
- if (!auto && !opts.model) {
106
- (0, prompt_1.printWizardRecommendations)(picks, runnable.length, {
107
- fallback: hardwareFallback,
108
- useCaseLabel: (0, use_cases_1.useCaseLabel)(useCase),
109
- });
110
- }
108
+ const needsOllama = !remote && !opts.skipInstall && !(await (0, ollama_1.pingOllama)(baseUrl)) && !(0, ollama_1.isOllamaInstalled)();
109
+ const cpuNote = () => {
110
+ if (!hw.gpuUsable && hw.ramGb < 8) {
111
+ console.log(' Note: CPU-only on limited RAM — only small models are recommended.\n');
112
+ }
113
+ };
111
114
  let chosen;
112
115
  if (opts.model) {
113
116
  const fromRecs = picks.find((r) => r.id === opts.model);
@@ -123,30 +126,49 @@ async function runSetup(opts) {
123
126
  throw new Error(`Model "${opts.model}" does not fit this machine.`);
124
127
  chosen = { ...m, fit, score: 0 };
125
128
  }
126
- if (!auto)
129
+ if (!auto) {
127
130
  console.log(` Using model: ${chosen.name} (${chosen.id})\n`);
131
+ cpuNote();
132
+ const action = await (0, prompt_1.confirmInstall)({ modelName: chosen.name, sizeMb: chosen.sizeMb, needsOllama });
133
+ if (action !== 'install') {
134
+ console.log('\n Setup cancelled. Run `oi` again when ready.\n');
135
+ return;
136
+ }
137
+ console.log('');
138
+ }
128
139
  }
129
140
  else if (auto) {
130
141
  chosen = picks[0];
131
142
  console.log(` → ${chosen.name} (best match)\n`);
132
143
  }
133
144
  else {
134
- chosen = await (0, prompt_1.pickRecommendation)(picks);
135
- console.log(`\n Selected: ${chosen.name}\n`);
136
- }
137
- if (!hw.hasGpu && hw.ramGb < 8) {
138
- console.log(' Note: CPU-only on limited RAM — only small models are recommended.\n');
139
- }
140
- const needsOllama = !remote && !opts.skipInstall && !(await (0, ollama_1.pingOllama)(baseUrl)) && !(0, ollama_1.isOllamaInstalled)();
141
- if (!auto) {
142
- const ok = await (0, prompt_1.confirmInstall)({
143
- modelName: chosen.name,
144
- sizeMb: chosen.sizeMb,
145
- needsOllama,
146
- });
147
- if (!ok)
148
- return;
149
- console.log('');
145
+ // Pick confirm, with "Browse" looping back to the picker.
146
+ while (true) {
147
+ chosen = await (0, prompt_1.pickRecommendation)(picks, {
148
+ show: exports.WIZARD_SHOW_COUNT,
149
+ totalFit: runnable.length,
150
+ fallback: hardwareFallback,
151
+ useCaseLabel: (0, use_cases_1.useCaseLabel)(useCase),
152
+ budgetGb: hw.budgetGb,
153
+ });
154
+ console.log(` Selected: ${chosen.name}\n`);
155
+ cpuNote();
156
+ const action = await (0, prompt_1.confirmInstall)({
157
+ modelName: chosen.name,
158
+ sizeMb: chosen.sizeMb,
159
+ needsOllama,
160
+ canBrowse: picks.length > 1,
161
+ });
162
+ if (action === 'install') {
163
+ console.log('');
164
+ break;
165
+ }
166
+ if (action === 'cancel') {
167
+ console.log('\n Setup cancelled. Run `oi` again when ready.\n');
168
+ return;
169
+ }
170
+ console.log(' Pick another model:\n'); // browse → loop
171
+ }
150
172
  }
151
173
  if (remote) {
152
174
  console.log(' Connecting to Ollama…\n');
@@ -188,15 +210,21 @@ async function runSetup(opts) {
188
210
  function printRecommendPreview(recs, hw, meta) {
189
211
  console.log('\n OpenInference — model recommendations\n');
190
212
  (0, prompt_1.printHardwareResults)(hw);
191
- console.log(` Use case: ${(0, use_cases_1.useCaseLabel)(meta.useCase)}`);
192
- console.log(` ${meta.poolSize} models for this goal · ${meta.runnableSize} fit your hardware` +
193
- `${meta.all ? '' : ' (verified tags preferred; use --all for full catalog)'}\n`);
213
+ console.log(` Use case: ${(0, use_cases_1.useCaseLabel)(meta.useCase)}\n`);
214
+ console.log(` ${meta.poolSize} ${(0, use_cases_1.useCaseLabel)(meta.useCase)} models available.`);
215
+ const filtered = meta.poolSize - meta.runnableSize;
216
+ if (filtered > 0) {
217
+ console.log(` ${filtered} need more RAM, GPU, or disk than this computer has.`);
218
+ }
194
219
  if (recs.length === 0) {
195
- console.log(' No models fit this machine. Try: oi browse --use-case chat\n');
220
+ console.log('\n None will run well here. Try another goal: oi browse --use-case chat\n');
196
221
  return;
197
222
  }
198
- console.log(` Top ${recs.length}:\n`);
223
+ console.log(` Showing the ${recs.length} that will run well:\n`);
199
224
  (0, prompt_1.printRecommendations)(recs);
225
+ if (meta.runnableSize > recs.length) {
226
+ console.log(` +${meta.runnableSize - recs.length} more fit your hardware — run \`oi browse\` (or /browse) to see them.`);
227
+ }
200
228
  console.log(' Run `oi` for the setup wizard, or `oi -y` to auto-install the top pick.\n');
201
229
  }
202
230
  //# sourceMappingURL=setup.js.map
package/dist/setup.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AA8NF,wBAAsB,QAAQ,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAiErE"}
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"AAwBA,MAAM,MAAM,YAAY,GAAG;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AA2XF,wBAAsB,QAAQ,CAAC,IAAI,GAAE,YAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyErE"}
package/dist/shell.js CHANGED
@@ -4,40 +4,46 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.runShell = runShell;
7
- const node_readline_1 = __importDefault(require("node:readline"));
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
8
9
  const config_1 = require("./config");
10
+ const ollama_1 = require("./ollama");
9
11
  const hardware_1 = require("./hardware");
10
12
  const start_1 = require("./start");
11
13
  const recommend_run_1 = require("./recommend-run");
12
14
  const use_cases_1 = require("./use-cases");
13
15
  const chat_1 = require("./chat");
16
+ const recommend_1 = require("./recommend");
14
17
  const manage_1 = require("./manage");
15
18
  const prompt_1 = require("./prompt");
16
19
  const version_1 = require("./version");
20
+ const linereader_1 = require("./linereader");
17
21
  // ── colors ──────────────────────────────────────────────
18
- const brand = (s) => `\x1b[38;5;43m${s}\x1b[0m`;
22
+ const C = (code, s) => `\x1b[38;5;${code}m${s}\x1b[0m`;
23
+ const brand = (s) => C(43, s);
19
24
  const dim = (s) => `\x1b[2m${s}\x1b[0m`;
20
25
  const bold = (s) => `\x1b[1m${s}\x1b[0m`;
21
26
  const green = (s) => `\x1b[32m${s}\x1b[0m`;
22
27
  const red = (s) => `\x1b[31m${s}\x1b[0m`;
23
28
  const COMMANDS = [
24
- { name: '/help', help: 'Show this help' },
25
- { name: '/recommend', args: '[use-case]', help: 'Best models for your hardware' },
26
- { name: '/browse', args: '[use-case]', help: 'Browse the full catalog' },
27
- { name: '/use', args: '<model>', help: 'Switch active model (pulls if needed)' },
28
- { name: '/pull', args: '<model>', help: 'Download a model' },
29
- { name: '/models', help: 'List downloaded models' },
30
- { name: '/storage', help: 'Where models are stored' },
31
- { name: '/status', help: 'Show current setup' },
32
- { name: '/scan', help: 'Re-scan this computer' },
33
- { name: '/setup', help: 'Run the setup wizard' },
34
- { name: '/clear', help: 'Clear screen and conversation' },
35
- { name: '/quit', help: 'Exit' },
29
+ { name: '/setup', help: 'Pick a goal, scan hardware, install a model', group: 'Setup & models' },
30
+ { name: '/recommend', args: '[goal]', help: 'Best models for your hardware', group: 'Setup & models' },
31
+ { name: '/browse', args: '[goal]', help: 'Browse the full catalog', group: 'Setup & models' },
32
+ { name: '/use', args: '<model>', help: 'Switch active model (pulls if needed)', group: 'Setup & models' },
33
+ { name: '/pull', args: '<model>', help: 'Download a model', group: 'Setup & models' },
34
+ { name: '/models', help: 'List downloaded models', group: 'Setup & models' },
35
+ { name: '/storage', help: 'Where models are stored', group: 'Setup & models' },
36
+ { name: '/config', help: 'Show model & connection settings', group: 'Setup & models' },
37
+ { name: '/status', help: 'Show current setup', group: 'Session' },
38
+ { name: '/scan', help: 'Re-scan this computer', group: 'Session' },
39
+ { name: '/clear', help: 'Clear screen and conversation', group: 'Session' },
40
+ { name: '/help', help: 'Show this help', group: 'Session' },
41
+ { name: '/quit', help: 'Exit', group: 'Session' },
36
42
  ];
37
- // 256-color helper
38
- const C = (code, s) => `\x1b[38;5;${code}m${s}\x1b[0m`;
43
+ const USE_CASE_IDS = use_cases_1.USE_CASES.map((u) => u.id);
44
+ // ── logo ────────────────────────────────────────────────
39
45
  const LOGO = [
40
- '██ ██ ██ ___ ____ _____ _ _ ',
46
+ ' ██ ██ ██ ___ ____ _____ _ _ ',
41
47
  ' ██ ██ ██ / _ \\| _ \\| ____| \\ | |',
42
48
  ' ██ ██ ██ ██ ██ | | | | |_) | _| | \\| |',
43
49
  ' ██ ██ ██ ██ ██ | |_| | __/| |___| |\\ |',
@@ -48,41 +54,71 @@ const LOGO = [
48
54
  ' | || |\\ | _| | |___| _ <| |___| |\\ | |___| |___ ',
49
55
  ' |___|_| \\_|_| |_____|_| \\_\\_____|_| \\_|\\____|_____|',
50
56
  ];
51
- // On-brand teal wordmark; bars get a brighter green accent.
52
- const LETTER_GRAD = [43, 43, 43, 43, 43, 43, 43, 43, 43, 43];
57
+ const LOGO_WIDTH = Math.max(...LOGO.map((l) => l.length)) + 2;
53
58
  const BAR_COLOR = 48; // bright spring-green for the ██ blocks
54
- function printBanner() {
55
- const cfg = (0, config_1.loadConfig)();
56
- const hw = (0, hardware_1.detectHardware)();
59
+ const WORD_COLOR = 43; // on-brand teal for the wordmark
60
+ function termWidth() {
61
+ return process.stdout.columns ?? 80;
62
+ }
63
+ function printLogo() {
57
64
  console.log('');
58
- LOGO.forEach((line, i) => {
65
+ if (termWidth() < LOGO_WIDTH) {
66
+ // Compact fallback for narrow terminals
67
+ console.log(` ${C(BAR_COLOR, '██')} ${bold(brand('OPEN INFERENCE'))} ${dim('v' + version_1.VERSION)}`);
68
+ return;
69
+ }
70
+ for (const line of LOGO) {
59
71
  const bars = line.match(/^[█ ]*/)?.[0] ?? '';
60
72
  const rest = line.slice(bars.length);
61
- console.log(` ${C(BAR_COLOR, bars)}${C(LETTER_GRAD[i] ?? 45, rest)}`);
62
- });
73
+ console.log(` ${C(BAR_COLOR, bars)}${C(WORD_COLOR, rest)}`);
74
+ }
63
75
  console.log('');
64
76
  console.log(` ${bold(brand('AI infrastructure, fully governed.'))} ${dim('v' + version_1.VERSION)}`);
77
+ }
78
+ function printWelcome() {
79
+ const cfg = (0, config_1.loadConfig)();
80
+ const hw = (0, hardware_1.detectHardware)();
65
81
  console.log('');
66
82
  if (cfg) {
67
- console.log(` ${bold(cfg.modelName)} ${dim('·')} ${dim((0, hardware_1.formatHardware)(hw))}`);
68
- console.log(` ${dim((0, hardware_1.ollamaModelsPath)())}`);
83
+ console.log(` Chatting with ${bold(cfg.modelName)} ${dim('· ' + (0, hardware_1.formatHardware)(hw))}`);
84
+ console.log('');
85
+ console.log(` ${dim('Ask anything below, or:')}`);
86
+ console.log(` ${brand('/models')} ${dim('see installed')} ${brand('/use <model>')} ${dim('switch')}`);
87
+ console.log(` ${brand('/status')} ${dim('your setup')} ${brand('/help')} ${dim('all commands')}`);
69
88
  }
70
89
  else {
71
- console.log(` ${dim('not set uptype /setup to begin')}`);
90
+ console.log(` ${dim('Run local open-source AI on your own machine no API keys, no cloud.')}`);
72
91
  console.log(` ${dim((0, hardware_1.formatHardware)(hw))}`);
92
+ console.log('');
93
+ console.log(` ${bold('Get started')}`);
94
+ console.log(` ${brand('/setup'.padEnd(20))} ${dim('pick a goal, scan hardware, install a model')}`);
95
+ console.log(` ${brand('/recommend coding'.padEnd(20))} ${dim('see which models fit this computer')}`);
96
+ console.log(` ${brand('/help'.padEnd(20))} ${dim('all commands')}`);
97
+ console.log('');
98
+ console.log(` ${dim('Or just type a question — I’ll set you up first.')}`);
73
99
  }
74
100
  console.log('');
75
- console.log(dim(' Type a message to chat, or /help for commands. /quit to exit.'));
101
+ console.log(dim(' Type “/” to see commands · ↑↓ to pick · Tab/Enter to choose · /quit to exit'));
76
102
  console.log('');
77
103
  }
104
+ function printBanner() {
105
+ printLogo();
106
+ printWelcome();
107
+ }
78
108
  function printHelp() {
79
109
  console.log('');
80
110
  console.log(bold(' Commands'));
81
- for (const c of COMMANDS) {
82
- const usage = `${c.name}${c.args ? ' ' + c.args : ''}`;
83
- console.log(` ${brand(usage.padEnd(22))} ${dim(c.help)}`);
111
+ for (const group of ['Setup & models', 'Session']) {
112
+ console.log('');
113
+ console.log(` ${dim(group)}`);
114
+ for (const c of COMMANDS.filter((x) => x.group === group)) {
115
+ const usage = `${c.name}${c.args ? ' ' + c.args : ''}`;
116
+ console.log(` ${brand(usage.padEnd(20))} ${dim(c.help)}`);
117
+ }
84
118
  }
85
119
  console.log('');
120
+ console.log(` ${dim('goals:')} ${USE_CASE_IDS.join(' · ')}`);
121
+ console.log(dim(' Custom model? /use or /pull any tag from ollama.com/library'));
86
122
  console.log(dim(' Anything that is not a /command is sent to the active model.'));
87
123
  console.log('');
88
124
  }
@@ -100,6 +136,55 @@ function printStatus() {
100
136
  console.log(` Storage: ${(0, hardware_1.ollamaModelsPath)()}`);
101
137
  console.log('');
102
138
  }
139
+ function printConfig(opts) {
140
+ const cfg = (0, config_1.loadConfig)();
141
+ console.log('');
142
+ console.log(bold(' Configuration'));
143
+ console.log('');
144
+ if (!cfg) {
145
+ const hw = (0, hardware_1.detectHardware)();
146
+ const gpu = !hw.hasGpu
147
+ ? 'none — CPU inference'
148
+ : hw.gpuUsable
149
+ ? `${hw.gpuName ?? 'GPU'} (${hw.vramGb} GB)`
150
+ : `${hw.gpuName ?? 'GPU'} (${hw.vramGb} GB — too small, using CPU)`;
151
+ const label = (s) => s.padEnd(12);
152
+ console.log(' No configuration yet — type /setup to create one.');
153
+ console.log('');
154
+ console.log(` ${dim('Current defaults')}`);
155
+ console.log(` ${label('Provider')}Ollama`);
156
+ console.log(` ${label('Model')}none`);
157
+ console.log(` ${label('Host')}${(0, ollama_1.resolveOllamaUrl)(opts.ollamaUrl)}`);
158
+ console.log(` ${label('🎮 GPU')}${gpu}`);
159
+ console.log(` ${label('Config')}${(0, config_1.configPath)()}`);
160
+ console.log('');
161
+ return;
162
+ }
163
+ const entry = (0, recommend_1.loadCatalog)().find((m) => m.id === cfg.model);
164
+ const base = (0, ollama_1.resolveOllamaUrl)(opts.ollamaUrl);
165
+ const urlSource = opts.ollamaUrl
166
+ ? 'from --ollama-url'
167
+ : process.env.OLLAMA_URL
168
+ ? 'from $OLLAMA_URL'
169
+ : cfg.ollamaUrl
170
+ ? 'from config'
171
+ : 'default';
172
+ const label = (s) => s.padEnd(15);
173
+ console.log(` ${label('Active model')}${bold(cfg.modelName)} ${dim('(' + cfg.model + ')')}`);
174
+ if (entry) {
175
+ const size = entry.sizeMb >= 1000 ? `${(entry.sizeMb / 1024).toFixed(1)} GB` : `${entry.sizeMb} MB`;
176
+ console.log(` ${label('')}${dim(`~${entry.ramGb} GB RAM · ${size} download · quality ${entry.quality}/100`)}`);
177
+ }
178
+ if (cfg.useCase)
179
+ console.log(` ${label('Use case')}${(0, use_cases_1.useCaseLabel)(cfg.useCase)}`);
180
+ console.log(` ${label('Ollama URL')}${base} ${dim('(' + urlSource + ')')}`);
181
+ console.log(` ${label('Model storage')}${(0, hardware_1.ollamaModelsPath)()}`);
182
+ console.log(` ${label('Config file')}${(0, config_1.configPath)()}`);
183
+ console.log(` ${label('Set up')}${new Date(cfg.setupAt).toLocaleDateString()}`);
184
+ console.log('');
185
+ console.log(dim(' Switch model: /use <model> · Reconfigure: /setup'));
186
+ console.log('');
187
+ }
103
188
  async function showModels(opts) {
104
189
  const names = await (0, chat_1.listInstalledModels)(opts.ollamaUrl);
105
190
  if (names.length === 0) {
@@ -110,26 +195,23 @@ async function showModels(opts) {
110
195
  names.forEach((n) => console.log(` ${n}`));
111
196
  console.log('');
112
197
  }
113
- /** Run one chat turn with a streamed, live-printed reply. */
198
+ /** Run one chat turn with a streamed, live-printed reply and a thinking indicator. */
114
199
  async function chat(history, message, opts) {
115
200
  history.push({ role: 'user', content: message });
116
- process.stdout.write('\n');
201
+ process.stdout.write('\n' + dim(' thinking…'));
117
202
  let started = false;
118
203
  const reply = await (0, chat_1.streamChatTurn)(history, (chunk) => {
119
204
  if (!started) {
120
- process.stdout.write(' ');
205
+ process.stdout.write('\r' + ' '.repeat(12) + '\r ');
121
206
  started = true;
122
207
  }
123
208
  process.stdout.write(chunk.replace(/\n/g, '\n '));
124
209
  }, { ollamaUrl: opts.ollamaUrl, remote: opts.remote });
210
+ if (!started)
211
+ process.stdout.write('\r' + ' '.repeat(12) + '\r');
125
212
  history.push({ role: 'assistant', content: reply });
126
213
  process.stdout.write('\n\n');
127
214
  }
128
- /**
129
- * Dispatch a slash command. Returns false to signal the shell should exit.
130
- * `reopen` is used by commands that need their own stdin prompts (the wizard):
131
- * the caller closes the shell readline before dispatch and reopens after.
132
- */
133
215
  async function dispatch(raw, history, opts) {
134
216
  const [cmd, ...rest] = raw.slice(1).trim().split(/\s+/);
135
217
  const arg = rest.join(' ').trim();
@@ -140,22 +222,27 @@ async function dispatch(raw, history, opts) {
140
222
  printHelp();
141
223
  return {};
142
224
  case 'recommend':
143
- case 'rec':
144
- (0, recommend_run_1.runRecommend)({ useCase: (0, use_cases_1.parseUseCaseArg)(arg) });
225
+ case 'rec': {
226
+ // No goal given → ask the user to pick a task first, then recommend.
227
+ const useCase = (0, use_cases_1.parseUseCaseArg)(arg) ?? (await (0, use_cases_1.pickUseCase)());
228
+ (0, recommend_run_1.runRecommend)({ useCase });
145
229
  return {};
146
- case 'browse':
147
- (0, recommend_run_1.runBrowse)({ useCase: (0, use_cases_1.parseUseCaseArg)(arg), all: true });
230
+ }
231
+ case 'browse': {
232
+ const useCase = (0, use_cases_1.parseUseCaseArg)(arg) ?? (await (0, use_cases_1.pickUseCase)());
233
+ (0, recommend_run_1.runBrowse)({ useCase, all: true });
148
234
  return {};
235
+ }
149
236
  case 'use':
150
237
  if (!arg) {
151
- console.log('\n Usage: /use <model>\n');
238
+ console.log('\n Usage: /use <model> (Tab to autocomplete)\n');
152
239
  return {};
153
240
  }
154
241
  await (0, manage_1.runUse)(arg, { ollamaUrl: opts.ollamaUrl, docker: opts.remote });
155
242
  return {};
156
243
  case 'pull':
157
244
  if (!arg) {
158
- console.log('\n Usage: /pull <model>\n');
245
+ console.log('\n Usage: /pull <model> (Tab to autocomplete)\n');
159
246
  return {};
160
247
  }
161
248
  await (0, manage_1.runPull)(arg, { ollamaUrl: opts.ollamaUrl, docker: opts.remote });
@@ -166,6 +253,10 @@ async function dispatch(raw, history, opts) {
166
253
  case 'storage':
167
254
  await (0, manage_1.runStorage)();
168
255
  return {};
256
+ case 'config':
257
+ case 'cfg':
258
+ printConfig(opts);
259
+ return {};
169
260
  case 'status':
170
261
  printStatus();
171
262
  return {};
@@ -189,36 +280,116 @@ async function dispatch(raw, history, opts) {
189
280
  return {};
190
281
  }
191
282
  }
192
- function makeRl() {
193
- return node_readline_1.default.createInterface({ input: process.stdin, output: process.stdout });
283
+ // ── tab completion ──────────────────────────────────────
284
+ let catalogIds = [];
285
+ function loadCatalogIds() {
286
+ if (catalogIds.length)
287
+ return catalogIds;
288
+ try {
289
+ catalogIds = (0, recommend_1.loadCatalog)().map((m) => m.id);
290
+ }
291
+ catch {
292
+ catalogIds = [];
293
+ }
294
+ return catalogIds;
295
+ }
296
+ function suggest(line) {
297
+ if (!line.startsWith('/'))
298
+ return [];
299
+ const model = /^(\/use|\/pull)\s+(.*)$/.exec(line);
300
+ if (model) {
301
+ const [, cmd, partial] = model;
302
+ const ids = loadCatalogIds();
303
+ const hits = ids
304
+ .filter((id) => id.startsWith(partial))
305
+ .slice(0, 7)
306
+ .map((id) => ({ value: `${cmd} ${id}`, label: id, submit: true }));
307
+ // Let the user pull ANY Ollama tag, even if it's not in our catalog.
308
+ if (partial && !ids.includes(partial)) {
309
+ hits.push({ value: `${cmd} ${partial}`, label: partial, hint: 'pull this exact tag', submit: true });
310
+ }
311
+ return hits;
312
+ }
313
+ const goal = /^(\/recommend|\/browse)\s+(.*)$/.exec(line);
314
+ if (goal) {
315
+ const [, cmd, partial] = goal;
316
+ return use_cases_1.USE_CASES.filter((u) => u.id.startsWith(partial)).map((u) => ({
317
+ value: `${cmd} ${u.id}`,
318
+ label: u.id,
319
+ hint: u.description,
320
+ submit: true,
321
+ }));
322
+ }
323
+ // Once a command has a space/args, stop showing the command menu.
324
+ if (/\s/.test(line))
325
+ return [];
326
+ return COMMANDS.filter((c) => c.name.startsWith(line)).map((c) => {
327
+ const needsArg = c.name === '/use' || c.name === '/pull';
328
+ return {
329
+ value: needsArg ? `${c.name} ` : c.name,
330
+ label: `${c.name}${c.args ? ' ' + c.args : ''}`,
331
+ hint: c.help,
332
+ submit: !needsArg,
333
+ };
334
+ });
335
+ }
336
+ // ── persistent history ──────────────────────────────────
337
+ function historyPath() {
338
+ return node_path_1.default.join((0, config_1.configDir)(), 'history');
339
+ }
340
+ function loadHistory() {
341
+ try {
342
+ return node_fs_1.default.readFileSync(historyPath(), 'utf8').split('\n').filter(Boolean);
343
+ }
344
+ catch {
345
+ return [];
346
+ }
194
347
  }
195
- function ask(rl, prompt) {
196
- return new Promise((resolve) => rl.question(prompt, resolve));
348
+ function saveHistory(lines) {
349
+ try {
350
+ node_fs_1.default.mkdirSync((0, config_1.configDir)(), { recursive: true });
351
+ node_fs_1.default.writeFileSync(historyPath(), lines.slice(-200).join('\n') + '\n', 'utf8');
352
+ }
353
+ catch {
354
+ /* history is best-effort */
355
+ }
197
356
  }
198
357
  async function runShell(opts = {}) {
199
358
  printBanner();
200
359
  const history = [];
201
- let rl = makeRl();
360
+ const cmdHistory = loadHistory();
361
+ const reader = new linereader_1.LineReader({
362
+ prompt: brand(' › '),
363
+ promptWidth: 4,
364
+ suggest,
365
+ history: cmdHistory,
366
+ });
367
+ const remember = (line) => {
368
+ if (line && line !== cmdHistory[cmdHistory.length - 1])
369
+ cmdHistory.push(line);
370
+ };
202
371
  try {
203
372
  while (true) {
204
- const line = (await ask(rl, brand(' › '))).trim();
373
+ const raw = await reader.question();
374
+ if (raw === null)
375
+ break; // Ctrl+C / Ctrl+D
376
+ const line = raw.trim();
205
377
  if (!line)
206
378
  continue;
379
+ remember(line);
207
380
  // Slash command
208
381
  if (line.startsWith('/')) {
209
- let result;
210
- // Commands that open their own prompts need exclusive stdin.
211
- if (/^\/(setup)\b/i.test(line)) {
212
- rl.close();
382
+ // Commands that open their own prompts run the wizard (its own stdin).
383
+ if (/^\/setup\b/i.test(line)) {
213
384
  try {
214
385
  await (0, start_1.runStart)({ chat: false, force: true, ollamaUrl: opts.ollamaUrl, docker: opts.remote });
215
386
  }
216
387
  catch (e) {
217
388
  console.error(`\n ${red('Error')}: ${msg(e)}\n`);
218
389
  }
219
- rl = makeRl();
220
390
  continue;
221
391
  }
392
+ let result;
222
393
  try {
223
394
  result = await dispatch(line, history, opts);
224
395
  }
@@ -233,14 +404,12 @@ async function runShell(opts = {}) {
233
404
  // Plain text → chat. Run setup first if needed.
234
405
  if (!(0, config_1.loadConfig)()) {
235
406
  console.log(`\n No model yet — starting setup.\n`);
236
- rl.close();
237
407
  try {
238
408
  await (0, start_1.runStart)({ chat: false, ollamaUrl: opts.ollamaUrl, docker: opts.remote });
239
409
  }
240
410
  catch (e) {
241
411
  console.error(`\n ${red('Error')}: ${msg(e)}\n`);
242
412
  }
243
- rl = makeRl();
244
413
  if (!(0, config_1.loadConfig)()) {
245
414
  console.log(' Setup not finished — type /setup to try again.\n');
246
415
  continue;
@@ -250,7 +419,6 @@ async function runShell(opts = {}) {
250
419
  await chat(history, line, opts);
251
420
  }
252
421
  catch (e) {
253
- // Drop the failed user turn so history stays consistent.
254
422
  if (history[history.length - 1]?.role === 'user')
255
423
  history.pop();
256
424
  console.error(` ${red('Error')}: ${msg(e)}\n`);
@@ -258,7 +426,7 @@ async function runShell(opts = {}) {
258
426
  }
259
427
  }
260
428
  finally {
261
- rl.close();
429
+ saveHistory(cmdHistory);
262
430
  }
263
431
  console.log(green('\n Bye.\n'));
264
432
  }