mu-coding 0.2.0 → 0.4.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/package.json +3 -3
- package/src/cli.ts +11 -7
- package/src/main.tsx +0 -14
- package/src/singleShot.ts +0 -42
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mu-coding",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Minimal terminal AI assistant for local models",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"ink": "^7.0.1",
|
|
15
|
-
"mu-agents": "0.
|
|
16
|
-
"mu-provider": "0.
|
|
15
|
+
"mu-agents": "0.4.0",
|
|
16
|
+
"mu-provider": "0.4.0",
|
|
17
17
|
"react": "^19.2.5"
|
|
18
18
|
}
|
|
19
19
|
}
|
package/src/cli.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
1
3
|
import type { ChatMessage } from 'mu-provider';
|
|
2
4
|
import { getLatestSession, loadSession } from './session';
|
|
3
5
|
|
|
4
6
|
interface CliArgs {
|
|
5
7
|
model?: string;
|
|
6
|
-
prompt?: string;
|
|
7
8
|
continueSession?: boolean;
|
|
8
9
|
sessionPath?: string;
|
|
9
10
|
}
|
|
@@ -13,13 +14,12 @@ function printHelp(): never {
|
|
|
13
14
|
|
|
14
15
|
Usage:
|
|
15
16
|
mu Start interactive chat
|
|
16
|
-
mu -p "prompt" Single-shot prompt, then exit
|
|
17
|
-
mu -m model -p "p" Single-shot with specific model
|
|
18
17
|
mu -m model Interactive with specific model
|
|
19
18
|
mu -c Continue most recent session
|
|
20
19
|
mu --session <path> Resume a specific session file
|
|
21
20
|
mu install npm:<package> Install a plugin from npm
|
|
22
21
|
mu uninstall npm:<pkg> Remove an installed plugin
|
|
22
|
+
mu -v, --version Print version and exit
|
|
23
23
|
|
|
24
24
|
Config (XDG):
|
|
25
25
|
~/.config/mu/config.json — configuration (baseUrl, model, streamTimeoutMs)
|
|
@@ -41,6 +41,12 @@ Keyboard shortcuts (interactive):
|
|
|
41
41
|
process.exit(0);
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
function printVersion(): never {
|
|
45
|
+
const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
46
|
+
console.log(`mu ${pkg.version}`);
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
44
50
|
export function parseArgs(): CliArgs {
|
|
45
51
|
const args = process.argv.slice(2);
|
|
46
52
|
const result: CliArgs = {};
|
|
@@ -49,16 +55,14 @@ export function parseArgs(): CliArgs {
|
|
|
49
55
|
const arg = args[i];
|
|
50
56
|
if (arg === '-m' && args[i + 1]) {
|
|
51
57
|
result.model = args[++i];
|
|
52
|
-
} else if (arg === '-p' && args[i + 1]) {
|
|
53
|
-
result.prompt = args[++i];
|
|
54
58
|
} else if (arg === '-c' || arg === '--continue') {
|
|
55
59
|
result.continueSession = true;
|
|
56
60
|
} else if (arg === '--session' && args[i + 1]) {
|
|
57
61
|
result.sessionPath = args[++i];
|
|
62
|
+
} else if (arg === '-v' || arg === '--version') {
|
|
63
|
+
printVersion();
|
|
58
64
|
} else if (arg === '-h' || arg === '--help') {
|
|
59
65
|
printHelp();
|
|
60
|
-
} else if (!(result.prompt || arg.startsWith('-'))) {
|
|
61
|
-
result.prompt = arg;
|
|
62
66
|
}
|
|
63
67
|
}
|
|
64
68
|
|
package/src/main.tsx
CHANGED
|
@@ -6,7 +6,6 @@ import { render } from 'ink';
|
|
|
6
6
|
import { createBuiltinPlugin, PluginRegistry } from 'mu-agents';
|
|
7
7
|
import { parseArgs, resolveInitialMessages } from './cli';
|
|
8
8
|
import { type AppConfig, getDataDir, getPluginsDir, loadConfig } from './config';
|
|
9
|
-
import { runSingleShot } from './singleShot';
|
|
10
9
|
import { handleSubcommand } from './subcommands';
|
|
11
10
|
import { ChatPanel } from './tui/components/chat/ChatPanel';
|
|
12
11
|
import { InkUIService } from './tui/services/uiService';
|
|
@@ -130,19 +129,6 @@ async function main() {
|
|
|
130
129
|
const uiService = new InkUIService();
|
|
131
130
|
const registry = await createRegistry(root, config, uiService);
|
|
132
131
|
|
|
133
|
-
if (cliArgs.prompt) {
|
|
134
|
-
try {
|
|
135
|
-
await runSingleShot(cliArgs.prompt, config, registry);
|
|
136
|
-
} catch (err: unknown) {
|
|
137
|
-
const msg = err instanceof Error ? err.message : 'Unknown error';
|
|
138
|
-
console.error(`Error: ${msg}`);
|
|
139
|
-
process.exit(1);
|
|
140
|
-
} finally {
|
|
141
|
-
await registry.shutdown();
|
|
142
|
-
}
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
132
|
const initialMessages = resolveInitialMessages(cliArgs);
|
|
147
133
|
|
|
148
134
|
render(<ChatPanel config={config} initialMessages={initialMessages} registry={registry} uiService={uiService} />, {
|
package/src/singleShot.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import type { PluginRegistry } from 'mu-agents';
|
|
2
|
-
import type { ChatMessage, ProviderConfig } from 'mu-provider';
|
|
3
|
-
import { listModels, streamChat } from 'mu-provider';
|
|
4
|
-
|
|
5
|
-
export async function runSingleShot(prompt: string, config: ProviderConfig, registry: PluginRegistry): Promise<void> {
|
|
6
|
-
const messages: ChatMessage[] = [{ role: 'user', content: prompt }];
|
|
7
|
-
|
|
8
|
-
let resolvedModel = config.model;
|
|
9
|
-
if (!resolvedModel) {
|
|
10
|
-
const models = await listModels(config.baseUrl);
|
|
11
|
-
if (models.length === 0) {
|
|
12
|
-
console.error('Error: no models available at', config.baseUrl);
|
|
13
|
-
process.exit(1);
|
|
14
|
-
}
|
|
15
|
-
resolvedModel = models[0].id;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const toolDefinitions = registry.getToolDefinitions();
|
|
19
|
-
|
|
20
|
-
let tokens = 0;
|
|
21
|
-
let hasToolCalls = false;
|
|
22
|
-
process.stdout.write('mu: ');
|
|
23
|
-
for await (const chunk of streamChat(messages, config, resolvedModel, {
|
|
24
|
-
onUsage: (usage) => {
|
|
25
|
-
tokens = usage.totalTokens;
|
|
26
|
-
},
|
|
27
|
-
tools: toolDefinitions,
|
|
28
|
-
})) {
|
|
29
|
-
if (chunk.type === 'content') {
|
|
30
|
-
process.stdout.write(chunk.text);
|
|
31
|
-
} else if (chunk.type === 'tool_call') {
|
|
32
|
-
hasToolCalls = true;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
if (hasToolCalls) {
|
|
36
|
-
process.stderr.write('\n[tool calls made — use interactive mode for tool execution]\n');
|
|
37
|
-
}
|
|
38
|
-
process.stdout.write('\n');
|
|
39
|
-
if (tokens > 0) {
|
|
40
|
-
process.stderr.write(`(${tokens} tokens)\n`);
|
|
41
|
-
}
|
|
42
|
-
}
|