ikie-cli 0.1.33 → 0.1.35

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/config.d.ts CHANGED
@@ -18,6 +18,14 @@ export declare const IKIE_API_BASE: string;
18
18
  export declare const IKIE_PORT: number;
19
19
  export interface IkieConfig {
20
20
  model: string;
21
+ /**
22
+ * True once the user has explicitly chosen a model (via /model, /settings
23
+ * model, or the picker). When false/unset, startup follows the server's
24
+ * default model. Tracked explicitly because the chosen model may legitimately
25
+ * equal DEFAULT_MODEL — value comparison alone can't tell "picked" from "never
26
+ * picked".
27
+ */
28
+ modelPinned?: boolean;
21
29
  maxTokens: number;
22
30
  autoApprove: boolean;
23
31
  apiKey?: string;
package/dist/config.js CHANGED
@@ -74,6 +74,10 @@ export function hasExplicitModel() {
74
74
  try {
75
75
  if (existsSync(CONFIG_FILE)) {
76
76
  const raw = JSON.parse(readFileSync(CONFIG_FILE, 'utf-8'));
77
+ // Preferred: the explicit pin flag, written whenever the user picks a model.
78
+ if (typeof raw.modelPinned === 'boolean')
79
+ return raw.modelPinned;
80
+ // Legacy configs (pre-flag): infer a choice from a non-default saved model.
77
81
  return typeof raw.model === 'string' && raw.model !== DEFAULT_MODEL;
78
82
  }
79
83
  }
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@ import { loadAllMemory, formatMemoryForPrompt } from './memory.js';
8
8
  import { discoverSkills, formatSkillsForPrompt } from './skills.js';
9
9
  import { buildSystemPrompt, Agent } from './agent.js';
10
10
  import { startREPL } from './repl.js';
11
+ import { getMcpManager } from './mcp-manager.js';
11
12
  import { login, logout } from './auth.js';
12
13
  import { c, errorLine } from './theme.js';
13
14
  import { runOnboarding, shouldRunOnboarding } from './onboarding.js';
@@ -135,6 +136,22 @@ async function main() {
135
136
  await runSkillsCli(argv._.slice(1).map(String), Boolean(argv.force));
136
137
  process.exit(0);
137
138
  }
139
+ // ── show-output: print a previously truncated tool output ─────
140
+ if (cmd === 'show-output') {
141
+ const id = argv._[1];
142
+ if (!id) {
143
+ console.error(errorLine('Usage: ikie show-output <id>'));
144
+ process.exit(1);
145
+ }
146
+ const savedOutputs = globalThis._ikieOutputs;
147
+ const output = savedOutputs?.get(id);
148
+ if (!output) {
149
+ console.error(errorLine(`No saved output with id "${id}". Outputs are only kept for the current session.`));
150
+ process.exit(1);
151
+ }
152
+ console.log(output);
153
+ process.exit(0);
154
+ }
138
155
  let config = loadConfig();
139
156
  if (argv.model)
140
157
  config.model = argv.model;
@@ -169,6 +186,7 @@ async function main() {
169
186
  if (argv.onboarding || (!oneShot && shouldRunOnboarding(config))) {
170
187
  config = loadConfig(); // reload — onboarding may have saved login
171
188
  await runOnboarding(config);
189
+ config = loadConfig(); // reload again — onboarding saved account + completion flag
172
190
  }
173
191
  const apiKey = getApiKey(config);
174
192
  if (!apiKey) {
@@ -199,7 +217,25 @@ ${errorLine('Not signed in.')}
199
217
  console.log();
200
218
  }
201
219
  const agent = new Agent(client, config, systemPrompt);
202
- await startREPL(agent, config, projectContextStr, oneShot);
220
+ // Connect configured MCP servers before the first turn.
221
+ const cwd = process.cwd();
222
+ try {
223
+ await getMcpManager().connectAll(cwd);
224
+ }
225
+ catch {
226
+ // Failures are recorded per-server; don't crash the REPL.
227
+ }
228
+ try {
229
+ await startREPL(agent, config, projectContextStr, oneShot);
230
+ }
231
+ finally {
232
+ try {
233
+ getMcpManager().disconnectAll();
234
+ }
235
+ catch {
236
+ // Ignore cleanup errors
237
+ }
238
+ }
203
239
  }
204
240
  main().catch((err) => {
205
241
  console.error(errorLine(`Fatal: ${err instanceof Error ? err.message : String(err)}`));
@@ -1,96 +1,82 @@
1
- export interface MCPTool {
1
+ import type OpenAI from 'openai';
2
+ export type McpTransportType = 'stdio' | 'http' | 'streamable-http' | 'sse';
3
+ export interface McpServerEntry {
4
+ type?: McpTransportType;
5
+ command?: string;
6
+ args?: string[];
7
+ env?: Record<string, string>;
8
+ url?: string;
9
+ headers?: Record<string, string>;
10
+ timeout?: number;
11
+ enabled?: boolean;
12
+ autoStart?: boolean;
13
+ description?: string;
14
+ }
15
+ export interface McpScopeConfig {
16
+ mcpServers?: Record<string, McpServerEntry>;
17
+ }
18
+ export interface McpTool {
2
19
  name: string;
3
- description: string;
4
- inputSchema: {
5
- type: string;
6
- properties: Record<string, any>;
7
- required?: string[];
8
- };
20
+ description?: string;
21
+ inputSchema?: Record<string, unknown>;
9
22
  }
10
- export interface MCPServer {
23
+ export interface McpServerStatus {
11
24
  name: string;
12
- command: string;
13
- args: string[];
14
- env?: Record<string, string>;
15
- description: string;
16
25
  enabled: boolean;
17
- autoStart: boolean;
18
- tools?: MCPTool[];
26
+ connected: boolean;
27
+ tools: McpTool[];
28
+ error?: string;
19
29
  }
20
- export interface MCPRegistry {
21
- servers: Record<string, MCPServer>;
22
- builtIn: string[];
30
+ export interface McpClient {
31
+ connect(): Promise<McpTool[]>;
32
+ callTool(name: string, args: Record<string, unknown>, timeout?: number): Promise<string>;
33
+ close(): void;
34
+ }
35
+ export declare function expandEnvVars(value: string, env: Record<string, string | undefined>): string;
36
+ export declare function expandEnvVarsInEntry(entry: McpServerEntry, env: Record<string, string | undefined>): McpServerEntry;
37
+ export declare function inferTransport(entry: McpServerEntry): McpTransportType;
38
+ export declare function mergeScopes(local: McpScopeConfig, project: McpScopeConfig, user: McpScopeConfig): Record<string, McpServerEntry>;
39
+ export declare function sanitizeMcpName(s: string): string;
40
+ export declare function mcpToolName(server: string, tool: string): string;
41
+ export interface QualifiedTool {
42
+ server: string;
43
+ tool: string;
44
+ }
45
+ export declare function buildReverseToolMap(tools: Map<string, McpTool[]>): Map<string, QualifiedTool>;
46
+ export declare function parseClaudeMcpAddCommand(str: string, defaultScope?: 'user' | 'project' | 'local'): {
47
+ name: string;
48
+ entry: McpServerEntry;
49
+ scope: 'user' | 'project' | 'local';
50
+ scopeExplicit: boolean;
51
+ } | {
52
+ error: string;
53
+ };
54
+ export declare class LineBuffer {
55
+ private tail;
56
+ private lines;
57
+ push(chunk: string): string[];
58
+ flush(): string[];
23
59
  }
24
- export declare class MCPManager {
25
- private registry;
26
- private processes;
27
- private messageHandlers;
28
- constructor();
29
- private ensureMCPDir;
30
- private loadRegistry;
31
- private saveRegistry;
32
- private initializeBuiltInServers;
33
- installMCP(config: {
34
- name: string;
35
- source: string;
36
- description?: string;
37
- env?: Record<string, string>;
38
- autoStart?: boolean;
39
- }): Promise<{
40
- success: boolean;
41
- error?: string;
42
- server?: MCPServer;
43
- }>;
44
- addMCP(config: {
45
- name: string;
46
- command: string;
47
- args: string[];
48
- env?: Record<string, string>;
49
- description?: string;
50
- }): {
51
- success: boolean;
52
- error?: string;
53
- server?: MCPServer;
54
- };
55
- uninstallMCP(name: string): {
56
- success: boolean;
57
- error?: string;
58
- };
59
- startMCP(name: string): Promise<{
60
- success: boolean;
61
- error?: string;
62
- tools?: MCPTool[];
63
- }>;
64
- stopMCP(name: string): {
65
- success: boolean;
66
- error?: string;
67
- };
68
- private initializeMCP;
69
- private requestMCPTools;
70
- private sendMCPMessage;
71
- private handleMCPMessage;
72
- callMCPTool(serverName: string, toolName: string, args: Record<string, any>): Promise<{
73
- success: boolean;
74
- result?: any;
75
- error?: string;
76
- }>;
77
- getAllTools(): Array<{
78
- server: string;
79
- tool: MCPTool;
80
- }>;
81
- listMCPs(): Array<{
82
- name: string;
83
- description: string;
84
- enabled: boolean;
85
- running: boolean;
86
- builtIn: boolean;
87
- tools?: MCPTool[];
88
- }>;
89
- setMCPEnabled(name: string, enabled: boolean): {
90
- success: boolean;
91
- error?: string;
92
- };
93
- startAutoStartMCPs(): Promise<void>;
94
- stopAllMCPs(): void;
60
+ export declare class McpManager {
61
+ private clients;
62
+ private tools;
63
+ private statuses;
64
+ private cwd?;
65
+ private loadScope;
66
+ private loadUserConfig;
67
+ private migrateOldRegistry;
68
+ private resolveEnv;
69
+ private createClient;
70
+ connectAll(cwd: string): Promise<void>;
71
+ private connectServer;
72
+ private withTimeout;
73
+ getToolDefsSync(): OpenAI.Chat.ChatCompletionTool[];
74
+ callTool(qualified: string, args: Record<string, unknown>): Promise<string>;
75
+ private findServerEntry;
76
+ listServers(): McpServerStatus[];
77
+ addServer(name: string, entry: McpServerEntry, scope: 'user' | 'project' | 'local'): Promise<void>;
78
+ removeServer(name: string, scope: 'user' | 'project' | 'local'): boolean;
79
+ reconnectServer(name: string): Promise<void>;
80
+ disconnectAll(): void;
95
81
  }
96
- export declare function getMCPManager(): MCPManager;
82
+ export declare function getMcpManager(): McpManager;