miii-cli 1.0.1 → 1.0.2

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.
@@ -1,10 +1,10 @@
1
1
  import { useCallback, useRef } from 'react';
2
2
  import { readFile, guardPath } from '../../files/ops.js';
3
3
  import { getSystemPrompt } from '../../tools/index.js';
4
+ import { saveConfig } from '../../config.js';
4
5
  import { loadSession, saveSession, listSessions, deleteSession, deleteAllSessions } from '../../sessions.js';
5
6
  import { runDeepThink } from '../deepThink.js';
6
7
  import { buildGitContext, looksCodeRelated } from '../git-context.js';
7
- import { getTavilyKey, saveTavilyKey } from '../../tavily/client.js';
8
8
  import { buildIndex } from '../../index/indexer.js';
9
9
  import { indexStats, clearIndex } from '../../index/store.js';
10
10
  import { embed } from '../../index/embedder.js';
@@ -34,7 +34,7 @@ export function useSubmit(deps) {
34
34
  const depsRef = useRef(deps);
35
35
  depsRef.current = deps;
36
36
  const handleSubmit = useCallback(async (text) => {
37
- const { config, skills, cwd, version, currentModelRef, setCurrentModel, historyRef, sessionNameRef, saveTimerRef, systemPromptRef, abortRef, planningMode, setPlanningMode, runLoop, buildContext, pushHistory, setSessionName, renameFromMessage, openPicker, setStatus, setTaskLabel, setCurrentTool, runRefactor, handleGit, lastGitStatusRef, } = depsRef.current;
37
+ const { config, skills, cwd, version, currentModelRef, setCurrentModel, historyRef, sessionNameRef, saveTimerRef, systemPromptRef, abortRef, setPlanningMode, runLoop, buildContext, pushHistory, setSessionName, renameFromMessage, setStatus, setTaskLabel, setCurrentTool, runRefactor, handleGit, lastGitStatusRef, mcpTools, setConfig, setConfigOpen, } = depsRef.current;
38
38
  const cmd = text.trim();
39
39
  if (cmd === '?') {
40
40
  printer.systemMsg('shortcuts:\n' +
@@ -56,21 +56,6 @@ export function useSubmit(deps) {
56
56
  printer.systemMsg(`miii v${version ?? 'unknown'}`);
57
57
  return;
58
58
  }
59
- if (cmd === '/tavily-key' || cmd.startsWith('/tavily-key ')) {
60
- const key = cmd.slice(11).trim();
61
- if (!key) {
62
- const existing = getTavilyKey();
63
- printer.systemMsg(existing ? 'Tavily key set (use /tavily-key <key> to update)' : 'No Tavily key set. Usage: /tavily-key tvly-...');
64
- return;
65
- }
66
- if (!key.startsWith('tvly-')) {
67
- printer.systemMsg('Key should start with tvly-. Get yours at https://tavily.com');
68
- return;
69
- }
70
- saveTavilyKey(key);
71
- printer.systemMsg('Tavily API key saved to ~/.config/miii/tavily.key (mode 600)');
72
- return;
73
- }
74
59
  if (cmd === '/skills' || cmd.startsWith('/skills ')) {
75
60
  const sub = cmd.slice(7).trim();
76
61
  if (!sub || sub === 'list') {
@@ -110,6 +95,62 @@ export function useSubmit(deps) {
110
95
  printer.systemMsg('usage: /skills install <name> | /skills uninstall <name> | /skills list');
111
96
  return;
112
97
  }
98
+ if (cmd === '/config' || cmd.startsWith('/config ')) {
99
+ const sub = cmd.slice(7).trim();
100
+ if (!sub) {
101
+ setConfigOpen(true);
102
+ return;
103
+ }
104
+ if (sub.startsWith('provider ')) {
105
+ const val = sub.slice(9).trim();
106
+ const valid = ['ollama', 'anthropic', 'openai-compat'];
107
+ if (!valid.includes(val)) {
108
+ printer.systemMsg(`valid providers: ${valid.join(', ')}`);
109
+ return;
110
+ }
111
+ setConfig(c => ({ ...c, provider: val }));
112
+ saveConfig({ provider: val });
113
+ printer.systemMsg(`provider → ${val}`);
114
+ return;
115
+ }
116
+ if (sub.startsWith('model ')) {
117
+ const val = sub.slice(6).trim();
118
+ if (!val) {
119
+ printer.systemMsg('usage: /config model <name>');
120
+ return;
121
+ }
122
+ setConfig(c => ({ ...c, model: val }));
123
+ saveConfig({ model: val });
124
+ setCurrentModel(val);
125
+ currentModelRef.current = val;
126
+ printer.systemMsg(`model → ${val}`);
127
+ return;
128
+ }
129
+ if (sub.startsWith('key ')) {
130
+ const val = sub.slice(4).trim();
131
+ if (!val) {
132
+ printer.systemMsg('usage: /config key <api-key>');
133
+ return;
134
+ }
135
+ setConfig(c => ({ ...c, apiKey: val }));
136
+ saveConfig({ apiKey: val });
137
+ printer.systemMsg(`apiKey → ${val.slice(0, 8)}…`);
138
+ return;
139
+ }
140
+ if (sub.startsWith('url ')) {
141
+ const val = sub.slice(4).trim();
142
+ if (!val) {
143
+ printer.systemMsg('usage: /config url <base-url>');
144
+ return;
145
+ }
146
+ setConfig(c => ({ ...c, baseUrl: val }));
147
+ saveConfig({ baseUrl: val });
148
+ printer.systemMsg(`baseUrl → ${val}`);
149
+ return;
150
+ }
151
+ printer.systemMsg('usage: /config [provider|model|key|url] <value>');
152
+ return;
153
+ }
113
154
  if (cmd === '/model' || cmd.startsWith('/model ')) {
114
155
  const name = cmd.slice(6).trim();
115
156
  if (!name) {
@@ -121,10 +162,6 @@ export function useSubmit(deps) {
121
162
  printer.systemMsg(`model → ${name}`);
122
163
  return;
123
164
  }
124
- if (cmd === '/models') {
125
- await openPicker();
126
- return;
127
- }
128
165
  if (cmd === '/new') {
129
166
  if (saveTimerRef.current) {
130
167
  clearTimeout(saveTimerRef.current);
@@ -135,7 +172,7 @@ export function useSubmit(deps) {
135
172
  historyRef.current = [];
136
173
  setSessionName(newName);
137
174
  setPlanningMode(false);
138
- systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}`);
175
+ systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}`, mcpTools);
139
176
  printer.systemMsg(`new session → ${newName}`);
140
177
  return;
141
178
  }
@@ -143,7 +180,7 @@ export function useSubmit(deps) {
143
180
  historyRef.current = [];
144
181
  saveSession(sessionNameRef.current, []);
145
182
  setPlanningMode(false);
146
- systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}`);
183
+ systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}`, mcpTools);
147
184
  printer.systemMsg('chat cleared');
148
185
  return;
149
186
  }
@@ -201,7 +238,7 @@ export function useSubmit(deps) {
201
238
  if (cmd === '/plan' || cmd.startsWith('/plan ')) {
202
239
  const topic = cmd.slice(5).trim();
203
240
  setPlanningMode(true);
204
- systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}\n- MODE: Planning assistant. Help the user plan step by step. Ask clarifying questions. Suggest concrete next steps. Use plain text only — no markdown, no headers, no bold, no bullets with asterisks, no backtick blocks. Use numbered lists and plain indentation for structure.`);
241
+ systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}\n- MODE: Planning assistant. Help the user plan step by step. Ask clarifying questions. Suggest concrete next steps. Use plain text only — no markdown, no headers, no bold, no bullets with asterisks, no backtick blocks. Use numbered lists and plain indentation for structure.`, mcpTools);
205
242
  const msg = topic ? `I want to plan: ${topic}` : 'I want to start planning. Help me think through my goals step by step.';
206
243
  printer.userMsg(msg);
207
244
  pushHistory({ role: 'user', content: msg });
@@ -210,7 +247,7 @@ export function useSubmit(deps) {
210
247
  }
211
248
  if (cmd === '/plan:done') {
212
249
  setPlanningMode(false);
213
- systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}`);
250
+ systemPromptRef.current = getSystemPrompt(`\n- CWD: ${cwd}`, mcpTools);
214
251
  printer.systemMsg('planning mode off');
215
252
  return;
216
253
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "miii-cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "type": "module",
5
5
  "description": "The high-performance local AI coding agent for your terminal. Automate complex workflows with local LLMs.",
6
6
  "license": "MIT",