aemeathcli 1.0.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/README.md +607 -0
- package/dist/App-P4MYD4QY.js +2719 -0
- package/dist/App-P4MYD4QY.js.map +1 -0
- package/dist/api-key-fallback-YQQBOQIL.js +11 -0
- package/dist/api-key-fallback-YQQBOQIL.js.map +1 -0
- package/dist/chunk-4IJD72YB.js +184 -0
- package/dist/chunk-4IJD72YB.js.map +1 -0
- package/dist/chunk-6PDJ45T4.js +325 -0
- package/dist/chunk-6PDJ45T4.js.map +1 -0
- package/dist/chunk-CARHU3DO.js +562 -0
- package/dist/chunk-CARHU3DO.js.map +1 -0
- package/dist/chunk-CGEV3ARR.js +80 -0
- package/dist/chunk-CGEV3ARR.js.map +1 -0
- package/dist/chunk-CS5X3BWX.js +27 -0
- package/dist/chunk-CS5X3BWX.js.map +1 -0
- package/dist/chunk-CYQNBB25.js +44 -0
- package/dist/chunk-CYQNBB25.js.map +1 -0
- package/dist/chunk-DAHGLHNR.js +657 -0
- package/dist/chunk-DAHGLHNR.js.map +1 -0
- package/dist/chunk-H66O5Z2V.js +305 -0
- package/dist/chunk-H66O5Z2V.js.map +1 -0
- package/dist/chunk-HCIHOHLX.js +322 -0
- package/dist/chunk-HCIHOHLX.js.map +1 -0
- package/dist/chunk-HMJRPNPZ.js +1031 -0
- package/dist/chunk-HMJRPNPZ.js.map +1 -0
- package/dist/chunk-I5PZ4JTS.js +119 -0
- package/dist/chunk-I5PZ4JTS.js.map +1 -0
- package/dist/chunk-IYW62KKR.js +255 -0
- package/dist/chunk-IYW62KKR.js.map +1 -0
- package/dist/chunk-JAXXTYID.js +51 -0
- package/dist/chunk-JAXXTYID.js.map +1 -0
- package/dist/chunk-LSOYPSAT.js +183 -0
- package/dist/chunk-LSOYPSAT.js.map +1 -0
- package/dist/chunk-MFBHNWGV.js +416 -0
- package/dist/chunk-MFBHNWGV.js.map +1 -0
- package/dist/chunk-MXZSI3AY.js +311 -0
- package/dist/chunk-MXZSI3AY.js.map +1 -0
- package/dist/chunk-NBR3GHMT.js +72 -0
- package/dist/chunk-NBR3GHMT.js.map +1 -0
- package/dist/chunk-O3ZF22SW.js +246 -0
- package/dist/chunk-O3ZF22SW.js.map +1 -0
- package/dist/chunk-SUSJPZU2.js +181 -0
- package/dist/chunk-SUSJPZU2.js.map +1 -0
- package/dist/chunk-TEVZS4FA.js +310 -0
- package/dist/chunk-TEVZS4FA.js.map +1 -0
- package/dist/chunk-UY2SYSEZ.js +211 -0
- package/dist/chunk-UY2SYSEZ.js.map +1 -0
- package/dist/chunk-WAHVZH7V.js +260 -0
- package/dist/chunk-WAHVZH7V.js.map +1 -0
- package/dist/chunk-WPP3PEDE.js +234 -0
- package/dist/chunk-WPP3PEDE.js.map +1 -0
- package/dist/chunk-Y5XVD2CD.js +1610 -0
- package/dist/chunk-Y5XVD2CD.js.map +1 -0
- package/dist/chunk-YL5XFHR3.js +56 -0
- package/dist/chunk-YL5XFHR3.js.map +1 -0
- package/dist/chunk-ZGOHARPV.js +122 -0
- package/dist/chunk-ZGOHARPV.js.map +1 -0
- package/dist/claude-adapter-QMLFMSP3.js +6 -0
- package/dist/claude-adapter-QMLFMSP3.js.map +1 -0
- package/dist/claude-login-5WELXPKT.js +324 -0
- package/dist/claude-login-5WELXPKT.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +703 -0
- package/dist/cli.js.map +1 -0
- package/dist/codex-login-7HHLJHBF.js +164 -0
- package/dist/codex-login-7HHLJHBF.js.map +1 -0
- package/dist/config-store-W6FBCQAQ.js +6 -0
- package/dist/config-store-W6FBCQAQ.js.map +1 -0
- package/dist/executor-6RIKIGXK.js +4 -0
- package/dist/executor-6RIKIGXK.js.map +1 -0
- package/dist/gemini-adapter-6JIHZ7WI.js +6 -0
- package/dist/gemini-adapter-6JIHZ7WI.js.map +1 -0
- package/dist/gemini-login-ZZLYC3J6.js +346 -0
- package/dist/gemini-login-ZZLYC3J6.js.map +1 -0
- package/dist/index.d.ts +2210 -0
- package/dist/index.js +1419 -0
- package/dist/index.js.map +1 -0
- package/dist/kimi-adapter-JN4HFFHU.js +6 -0
- package/dist/kimi-adapter-JN4HFFHU.js.map +1 -0
- package/dist/kimi-login-CZPS63NK.js +149 -0
- package/dist/kimi-login-CZPS63NK.js.map +1 -0
- package/dist/native-cli-adapters-OLW3XX57.js +6 -0
- package/dist/native-cli-adapters-OLW3XX57.js.map +1 -0
- package/dist/ollama-adapter-OJQ3FKWK.js +6 -0
- package/dist/ollama-adapter-OJQ3FKWK.js.map +1 -0
- package/dist/openai-adapter-XU46EN7B.js +6 -0
- package/dist/openai-adapter-XU46EN7B.js.map +1 -0
- package/dist/registry-4KD24ZC3.js +6 -0
- package/dist/registry-4KD24ZC3.js.map +1 -0
- package/dist/registry-H7B3AHPQ.js +5 -0
- package/dist/registry-H7B3AHPQ.js.map +1 -0
- package/dist/server-manager-PTGBHCLS.js +5 -0
- package/dist/server-manager-PTGBHCLS.js.map +1 -0
- package/dist/session-manager-ECEEACGY.js +12 -0
- package/dist/session-manager-ECEEACGY.js.map +1 -0
- package/dist/team-manager-HC4XGCFY.js +11 -0
- package/dist/team-manager-HC4XGCFY.js.map +1 -0
- package/dist/tmux-manager-GPYZ3WQH.js +6 -0
- package/dist/tmux-manager-GPYZ3WQH.js.map +1 -0
- package/dist/tools-TSMXMHIF.js +6 -0
- package/dist/tools-TSMXMHIF.js.map +1 -0
- package/package.json +89 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,703 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import './chunk-CGEV3ARR.js';
|
|
3
|
+
import './chunk-CYQNBB25.js';
|
|
4
|
+
import { initializeDirectories } from './chunk-NBR3GHMT.js';
|
|
5
|
+
import './chunk-CS5X3BWX.js';
|
|
6
|
+
import './chunk-HCIHOHLX.js';
|
|
7
|
+
import './chunk-ZGOHARPV.js';
|
|
8
|
+
import { logger } from './chunk-JAXXTYID.js';
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import pc2 from 'picocolors';
|
|
11
|
+
import { randomUUID } from 'crypto';
|
|
12
|
+
|
|
13
|
+
function createChatCommand() {
|
|
14
|
+
const chat = new Command("chat").description("Start interactive chat mode (default)").argument("[message...]", "Initial message to send").option("-m, --model <model>", "Override model for this session").option("-r, --role <role>", "Set the task role (planning, coding, review, testing, bugfix)").option("--system <prompt>", "Custom system prompt").option("--no-stream", "Disable streaming output").action(async (messageParts, options) => {
|
|
15
|
+
const message = messageParts.join(" ");
|
|
16
|
+
const { startChatSession } = await import('./App-P4MYD4QY.js');
|
|
17
|
+
const model = options["model"];
|
|
18
|
+
const role = options["role"];
|
|
19
|
+
const systemPrompt = options["system"];
|
|
20
|
+
const initialMessage = message || void 0;
|
|
21
|
+
await startChatSession({
|
|
22
|
+
...initialMessage !== void 0 ? { initialMessage } : {},
|
|
23
|
+
...model !== void 0 ? { model } : {},
|
|
24
|
+
...role !== void 0 ? { role } : {},
|
|
25
|
+
...systemPrompt !== void 0 ? { systemPrompt } : {},
|
|
26
|
+
streaming: options["stream"] !== false
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
return chat;
|
|
30
|
+
}
|
|
31
|
+
function createPlanCommand() {
|
|
32
|
+
const plan = new Command("plan").description("Enter planning mode with a high-reasoning model").argument("[message...]", "Planning prompt").option("-m, --model <model>", "Override model (default: planning role)").action(async (messageParts, options) => {
|
|
33
|
+
const message = messageParts.join(" ");
|
|
34
|
+
const { startChatSession } = await import('./App-P4MYD4QY.js');
|
|
35
|
+
const model = options["model"];
|
|
36
|
+
const initialMessage = message || void 0;
|
|
37
|
+
await startChatSession({
|
|
38
|
+
...initialMessage !== void 0 ? { initialMessage } : {},
|
|
39
|
+
...model !== void 0 ? { model } : {},
|
|
40
|
+
role: "planning",
|
|
41
|
+
streaming: true
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
return plan;
|
|
45
|
+
}
|
|
46
|
+
function createReviewCommand() {
|
|
47
|
+
const review = new Command("review").description("Code review mode with a thorough model").argument("[files...]", "Files to review").option("-m, --model <model>", "Override model (default: review role)").action(async (files, options) => {
|
|
48
|
+
const message = files.length > 0 ? `Review these files: ${files.join(", ")}` : "Review the recent changes";
|
|
49
|
+
const { startChatSession } = await import('./App-P4MYD4QY.js');
|
|
50
|
+
const model = options["model"];
|
|
51
|
+
await startChatSession({
|
|
52
|
+
initialMessage: message,
|
|
53
|
+
...model !== void 0 ? { model } : {},
|
|
54
|
+
role: "review",
|
|
55
|
+
streaming: true
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
return review;
|
|
59
|
+
}
|
|
60
|
+
function createTestCommand() {
|
|
61
|
+
const test = new Command("test").description("Testing mode with a cost-efficient model").argument("[message...]", "Testing prompt").option("-m, --model <model>", "Override model (default: testing role)").action(async (messageParts, options) => {
|
|
62
|
+
const message = messageParts.join(" ");
|
|
63
|
+
const { startChatSession } = await import('./App-P4MYD4QY.js');
|
|
64
|
+
const model = options["model"];
|
|
65
|
+
await startChatSession({
|
|
66
|
+
initialMessage: message || "Generate tests for the recent changes",
|
|
67
|
+
...model !== void 0 ? { model } : {},
|
|
68
|
+
role: "testing",
|
|
69
|
+
streaming: true
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
return test;
|
|
73
|
+
}
|
|
74
|
+
function createConfigCommand() {
|
|
75
|
+
const config = new Command("config").description("Configuration management");
|
|
76
|
+
config.command("get [key]").description("Get configuration value (or all if no key)").action(async (key) => {
|
|
77
|
+
try {
|
|
78
|
+
const { ConfigStore } = await import('./config-store-W6FBCQAQ.js');
|
|
79
|
+
const store = new ConfigStore();
|
|
80
|
+
const cfg = await store.loadGlobal();
|
|
81
|
+
if (key) {
|
|
82
|
+
const value = getNestedValue(cfg, key);
|
|
83
|
+
if (value === void 0) {
|
|
84
|
+
process.stderr.write(pc2.red(`Configuration key not found: ${key}
|
|
85
|
+
`));
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
process.stdout.write(`${key} = ${JSON.stringify(value, null, 2)}
|
|
90
|
+
`);
|
|
91
|
+
} else {
|
|
92
|
+
process.stdout.write(JSON.stringify(cfg, null, 2) + "\n");
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
96
|
+
process.stderr.write(pc2.red(`Failed to read config: ${message}
|
|
97
|
+
`));
|
|
98
|
+
process.exitCode = 3;
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
config.command("set <key> <value>").description("Set a configuration value").action(async (key, value) => {
|
|
102
|
+
try {
|
|
103
|
+
const { ConfigStore } = await import('./config-store-W6FBCQAQ.js');
|
|
104
|
+
const store = new ConfigStore();
|
|
105
|
+
const cfg = await store.loadGlobal();
|
|
106
|
+
let parsedValue;
|
|
107
|
+
try {
|
|
108
|
+
parsedValue = JSON.parse(value);
|
|
109
|
+
} catch {
|
|
110
|
+
parsedValue = value;
|
|
111
|
+
}
|
|
112
|
+
setNestedValue(cfg, key, parsedValue);
|
|
113
|
+
await store.saveGlobal(cfg);
|
|
114
|
+
process.stdout.write(pc2.green(`Set ${key} = ${JSON.stringify(parsedValue)}
|
|
115
|
+
`));
|
|
116
|
+
} catch (error) {
|
|
117
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
118
|
+
process.stderr.write(pc2.red(`Failed to set config: ${message}
|
|
119
|
+
`));
|
|
120
|
+
process.exitCode = 3;
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
config.command("init").description("Initialize configuration with interactive setup").action(async () => {
|
|
124
|
+
try {
|
|
125
|
+
const { runFirstRunSetup } = await import('./App-P4MYD4QY.js');
|
|
126
|
+
await runFirstRunSetup();
|
|
127
|
+
} catch (error) {
|
|
128
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
129
|
+
process.stderr.write(pc2.red(`Setup failed: ${message}
|
|
130
|
+
`));
|
|
131
|
+
process.exitCode = 3;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
return config;
|
|
135
|
+
}
|
|
136
|
+
function getNestedValue(obj, path) {
|
|
137
|
+
const keys = path.split(".");
|
|
138
|
+
let current = obj;
|
|
139
|
+
for (const key of keys) {
|
|
140
|
+
if (current === null || current === void 0 || typeof current !== "object") {
|
|
141
|
+
return void 0;
|
|
142
|
+
}
|
|
143
|
+
current = current[key];
|
|
144
|
+
}
|
|
145
|
+
return current;
|
|
146
|
+
}
|
|
147
|
+
function setNestedValue(obj, path, value) {
|
|
148
|
+
const keys = path.split(".");
|
|
149
|
+
let current = obj;
|
|
150
|
+
for (let i = 0; i < keys.length - 1; i++) {
|
|
151
|
+
const key = keys[i];
|
|
152
|
+
if (!key) continue;
|
|
153
|
+
if (typeof current[key] !== "object" || current[key] === null) {
|
|
154
|
+
current[key] = {};
|
|
155
|
+
}
|
|
156
|
+
current = current[key];
|
|
157
|
+
}
|
|
158
|
+
const lastKey = keys[keys.length - 1];
|
|
159
|
+
if (lastKey) {
|
|
160
|
+
current[lastKey] = value;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
var VALID_PROVIDERS = ["claude", "codex", "gemini", "kimi"];
|
|
164
|
+
function isValidProvider(value) {
|
|
165
|
+
return VALID_PROVIDERS.includes(value);
|
|
166
|
+
}
|
|
167
|
+
var PROVIDER_MODEL_SWITCH = {
|
|
168
|
+
claude: { provider: "anthropic", model: "claude-sonnet-4-6" },
|
|
169
|
+
codex: { provider: "openai", model: "gpt-5.2" },
|
|
170
|
+
gemini: { provider: "google", model: "gemini-2.5-pro" },
|
|
171
|
+
kimi: { provider: "kimi", model: "kimi-for-coding" }
|
|
172
|
+
};
|
|
173
|
+
function createAuthCommand() {
|
|
174
|
+
const auth = new Command("auth").description("Authentication & account management");
|
|
175
|
+
auth.command("login <provider>").description("Log in to a provider (claude, codex, gemini, kimi)").action(async (provider) => {
|
|
176
|
+
if (!isValidProvider(provider)) {
|
|
177
|
+
process.stderr.write(
|
|
178
|
+
pc2.red(`Unknown provider: "${provider}". Valid: ${VALID_PROVIDERS.join(", ")}
|
|
179
|
+
`)
|
|
180
|
+
);
|
|
181
|
+
process.exitCode = 2;
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
process.stdout.write(pc2.cyan(`Logging in to ${provider}...
|
|
185
|
+
`));
|
|
186
|
+
try {
|
|
187
|
+
const loginModule = await loadLoginModule(provider);
|
|
188
|
+
await loginModule.login();
|
|
189
|
+
process.stdout.write(pc2.green(`Successfully logged in to ${provider}
|
|
190
|
+
`));
|
|
191
|
+
} catch (error) {
|
|
192
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
193
|
+
process.stderr.write(pc2.red(`Login failed: ${message}
|
|
194
|
+
`));
|
|
195
|
+
process.exitCode = 3;
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
auth.command("logout [provider]").description("Log out of a provider (or all with --all)").option("--all", "Log out of all providers").action(async (provider, options) => {
|
|
199
|
+
if (options.all) {
|
|
200
|
+
for (const p of VALID_PROVIDERS) {
|
|
201
|
+
try {
|
|
202
|
+
const loginModule = await loadLoginModule(p);
|
|
203
|
+
await loginModule.logout();
|
|
204
|
+
process.stdout.write(pc2.green(`Logged out of ${p}
|
|
205
|
+
`));
|
|
206
|
+
} catch {
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (!provider || !isValidProvider(provider)) {
|
|
212
|
+
process.stderr.write(
|
|
213
|
+
pc2.red(`Specify a provider or use --all. Valid: ${VALID_PROVIDERS.join(", ")}
|
|
214
|
+
`)
|
|
215
|
+
);
|
|
216
|
+
process.exitCode = 2;
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const loginModule = await loadLoginModule(provider);
|
|
221
|
+
await loginModule.logout();
|
|
222
|
+
process.stdout.write(pc2.green(`Logged out of ${provider}
|
|
223
|
+
`));
|
|
224
|
+
} catch (error) {
|
|
225
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
226
|
+
process.stderr.write(pc2.red(`Logout failed: ${message}
|
|
227
|
+
`));
|
|
228
|
+
process.exitCode = 3;
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
auth.command("status").description("Show login status for all providers").action(async () => {
|
|
232
|
+
for (const provider of VALID_PROVIDERS) {
|
|
233
|
+
try {
|
|
234
|
+
const loginModule = await loadLoginModule(provider);
|
|
235
|
+
const status = await loginModule.getStatus();
|
|
236
|
+
if (status.loggedIn) {
|
|
237
|
+
process.stdout.write(
|
|
238
|
+
pc2.green(` \u2713 ${provider}`) + ` \u2014 Logged in as ${status.email ?? "unknown"} (${status.plan ?? "unknown plan"})
|
|
239
|
+
`
|
|
240
|
+
);
|
|
241
|
+
} else {
|
|
242
|
+
process.stdout.write(pc2.red(` \u2717 ${provider}`) + " \u2014 Not logged in\n");
|
|
243
|
+
}
|
|
244
|
+
} catch {
|
|
245
|
+
process.stdout.write(pc2.red(` \u2717 ${provider}`) + " \u2014 Not configured\n");
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
try {
|
|
249
|
+
const { ApiKeyFallback } = await import('./api-key-fallback-YQQBOQIL.js');
|
|
250
|
+
const fallback = new ApiKeyFallback();
|
|
251
|
+
const apiKeyStatus = [
|
|
252
|
+
{ label: "Claude", provider: "anthropic" },
|
|
253
|
+
{ label: "OpenAI", provider: "openai" },
|
|
254
|
+
{ label: "Google", provider: "google" },
|
|
255
|
+
{ label: "Kimi", provider: "kimi" }
|
|
256
|
+
];
|
|
257
|
+
process.stdout.write("\nFallback API keys:\n");
|
|
258
|
+
for (const item of apiKeyStatus) {
|
|
259
|
+
const hasKey = await fallback.hasKey(item.provider);
|
|
260
|
+
process.stdout.write(` ${item.label}: ${hasKey ? "set" : "not set"}
|
|
261
|
+
`);
|
|
262
|
+
}
|
|
263
|
+
} catch {
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
auth.command("set-key <provider> <key>").description("Set an API key for a provider (fallback for CI/headless)").action(async (provider, key) => {
|
|
267
|
+
if (!isValidProvider(provider) && provider !== "openai" && provider !== "google") {
|
|
268
|
+
process.stderr.write(pc2.red(`Unknown provider: "${provider}"
|
|
269
|
+
`));
|
|
270
|
+
process.exitCode = 2;
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
try {
|
|
274
|
+
const { ApiKeyFallback } = await import('./api-key-fallback-YQQBOQIL.js');
|
|
275
|
+
const fallback = new ApiKeyFallback();
|
|
276
|
+
const providerMap = {
|
|
277
|
+
claude: "anthropic",
|
|
278
|
+
openai: "openai",
|
|
279
|
+
codex: "openai",
|
|
280
|
+
gemini: "google",
|
|
281
|
+
google: "google",
|
|
282
|
+
kimi: "kimi"
|
|
283
|
+
};
|
|
284
|
+
const mappedProvider = providerMap[provider];
|
|
285
|
+
if (mappedProvider) {
|
|
286
|
+
await fallback.setKey(mappedProvider, key);
|
|
287
|
+
process.stdout.write(pc2.green(`API key set for ${provider}
|
|
288
|
+
`));
|
|
289
|
+
}
|
|
290
|
+
} catch (error) {
|
|
291
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
292
|
+
process.stderr.write(pc2.red(`Failed to set key: ${message}
|
|
293
|
+
`));
|
|
294
|
+
process.exitCode = 3;
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
auth.command("switch <provider>").description("Set a provider as the default").action(async (provider) => {
|
|
298
|
+
if (!isValidProvider(provider)) {
|
|
299
|
+
process.stderr.write(
|
|
300
|
+
pc2.red(`Unknown provider: "${provider}". Valid: ${VALID_PROVIDERS.join(", ")}
|
|
301
|
+
`)
|
|
302
|
+
);
|
|
303
|
+
process.exitCode = 2;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
try {
|
|
307
|
+
const target = PROVIDER_MODEL_SWITCH[provider];
|
|
308
|
+
const { ConfigStore } = await import('./config-store-W6FBCQAQ.js');
|
|
309
|
+
const store = new ConfigStore();
|
|
310
|
+
const cfg = store.loadGlobal();
|
|
311
|
+
const nextConfig = {
|
|
312
|
+
...cfg,
|
|
313
|
+
defaultModel: target.model,
|
|
314
|
+
providers: {
|
|
315
|
+
...cfg.providers,
|
|
316
|
+
[target.provider]: {
|
|
317
|
+
...cfg.providers[target.provider] ?? {},
|
|
318
|
+
enabled: true
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
store.saveGlobal(nextConfig);
|
|
323
|
+
process.stdout.write(
|
|
324
|
+
pc2.green(`Default provider switched to ${provider} (model: ${target.model})
|
|
325
|
+
`)
|
|
326
|
+
);
|
|
327
|
+
} catch (error) {
|
|
328
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
329
|
+
process.stderr.write(pc2.red(`Failed to switch provider: ${message}
|
|
330
|
+
`));
|
|
331
|
+
process.exitCode = 3;
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
return auth;
|
|
335
|
+
}
|
|
336
|
+
async function loadLoginModule(provider) {
|
|
337
|
+
switch (provider) {
|
|
338
|
+
case "claude": {
|
|
339
|
+
const mod = await import('./claude-login-5WELXPKT.js');
|
|
340
|
+
return new mod.ClaudeLogin();
|
|
341
|
+
}
|
|
342
|
+
case "codex": {
|
|
343
|
+
const mod = await import('./codex-login-7HHLJHBF.js');
|
|
344
|
+
return new mod.CodexLogin();
|
|
345
|
+
}
|
|
346
|
+
case "gemini": {
|
|
347
|
+
const mod = await import('./gemini-login-ZZLYC3J6.js');
|
|
348
|
+
return new mod.GeminiLogin();
|
|
349
|
+
}
|
|
350
|
+
case "kimi": {
|
|
351
|
+
const mod = await import('./kimi-login-CZPS63NK.js');
|
|
352
|
+
return new mod.KimiLogin();
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// src/cli/cli.ts
|
|
358
|
+
var VERSION = "1.0.0";
|
|
359
|
+
function getFlagValue(args, flag) {
|
|
360
|
+
const index = args.indexOf(flag);
|
|
361
|
+
if (index === -1) {
|
|
362
|
+
return void 0;
|
|
363
|
+
}
|
|
364
|
+
const value = args[index + 1];
|
|
365
|
+
return value && !value.startsWith("-") ? value : void 0;
|
|
366
|
+
}
|
|
367
|
+
function isIPCMessage(value) {
|
|
368
|
+
if (typeof value !== "object" || value === null) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
const record = value;
|
|
372
|
+
return record["jsonrpc"] === "2.0" && typeof record["method"] === "string";
|
|
373
|
+
}
|
|
374
|
+
function sendAgentIPC(method, params) {
|
|
375
|
+
if (typeof process.send === "function") {
|
|
376
|
+
const message = {
|
|
377
|
+
jsonrpc: "2.0",
|
|
378
|
+
method,
|
|
379
|
+
params
|
|
380
|
+
};
|
|
381
|
+
process.send(message);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
async function maybeRunAgentMode(args) {
|
|
385
|
+
if (!args.includes("--agent") && process.env["AEMEATHCLI_AGENT_MODE"] !== "1") {
|
|
386
|
+
return false;
|
|
387
|
+
}
|
|
388
|
+
const teamName = getFlagValue(args, "--team") ?? process.env["AEMEATHCLI_TEAM_NAME"] ?? "unknown-team";
|
|
389
|
+
const agentName = getFlagValue(args, "--name") ?? process.env["AEMEATHCLI_AGENT_NAME"] ?? "agent";
|
|
390
|
+
const model = getFlagValue(args, "--model") ?? "claude-sonnet-4-6";
|
|
391
|
+
const role = getFlagValue(args, "--role") ?? "coding";
|
|
392
|
+
const agentId = process.env["AEMEATHCLI_AGENT_ID"] ?? randomUUID();
|
|
393
|
+
let registryPromise;
|
|
394
|
+
function getRegistry() {
|
|
395
|
+
if (!registryPromise) {
|
|
396
|
+
registryPromise = import('./registry-4KD24ZC3.js').then(
|
|
397
|
+
({ createDefaultRegistry }) => createDefaultRegistry()
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
return registryPromise;
|
|
401
|
+
}
|
|
402
|
+
let toolRegistryPromise;
|
|
403
|
+
function getToolRegistry() {
|
|
404
|
+
if (!toolRegistryPromise) {
|
|
405
|
+
toolRegistryPromise = import('./tools-TSMXMHIF.js').then(
|
|
406
|
+
({ createDefaultRegistry: createToolReg }) => createToolReg({
|
|
407
|
+
projectRoot: process.cwd(),
|
|
408
|
+
workingDirectory: process.cwd(),
|
|
409
|
+
permissionMode: "permissive",
|
|
410
|
+
allowedPaths: [process.cwd()],
|
|
411
|
+
blockedCommands: []
|
|
412
|
+
})
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
return toolRegistryPromise;
|
|
416
|
+
}
|
|
417
|
+
function formatToolActivity(name, args2) {
|
|
418
|
+
switch (name) {
|
|
419
|
+
case "read":
|
|
420
|
+
case "write":
|
|
421
|
+
case "edit":
|
|
422
|
+
return typeof args2["file_path"] === "string" ? args2["file_path"] : "";
|
|
423
|
+
case "glob":
|
|
424
|
+
return typeof args2["pattern"] === "string" ? args2["pattern"] : "";
|
|
425
|
+
case "grep": {
|
|
426
|
+
const pat = typeof args2["pattern"] === "string" ? args2["pattern"] : "";
|
|
427
|
+
const dir = typeof args2["path"] === "string" ? ` in ${args2["path"]}` : "";
|
|
428
|
+
return `"${pat}"${dir}`;
|
|
429
|
+
}
|
|
430
|
+
case "bash": {
|
|
431
|
+
const cmd = typeof args2["command"] === "string" ? args2["command"] : "";
|
|
432
|
+
return cmd.length > 60 ? cmd.slice(0, 60) + "..." : cmd;
|
|
433
|
+
}
|
|
434
|
+
default:
|
|
435
|
+
return JSON.stringify(args2).slice(0, 60);
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function formatResultSummary(name, content, isError) {
|
|
439
|
+
if (isError) return `Error: ${content.slice(0, 100)}`;
|
|
440
|
+
const lines = content.split("\n").length;
|
|
441
|
+
switch (name) {
|
|
442
|
+
case "read":
|
|
443
|
+
return `${lines} lines`;
|
|
444
|
+
case "glob":
|
|
445
|
+
return content === "No files found" ? "no files" : `${lines} files`;
|
|
446
|
+
case "grep":
|
|
447
|
+
return content === "No matches found." ? "no matches" : `${lines} lines`;
|
|
448
|
+
case "write":
|
|
449
|
+
case "edit":
|
|
450
|
+
return content.length > 80 ? content.slice(0, 80) : content;
|
|
451
|
+
default:
|
|
452
|
+
return content.length > 80 ? content.slice(0, 80) + "..." : content;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
const MAX_TOOL_ITERATIONS = 10;
|
|
456
|
+
const MAX_TOOL_RESULT_LENGTH = 1e4;
|
|
457
|
+
async function processTask(taskId, prompt) {
|
|
458
|
+
sendAgentIPC("agent.taskUpdate", { agentId, taskId, status: "in_progress" });
|
|
459
|
+
sendAgentIPC("agent.streamChunk", {
|
|
460
|
+
agentId,
|
|
461
|
+
taskId,
|
|
462
|
+
model,
|
|
463
|
+
content: `Initializing provider for ${model}...
|
|
464
|
+
`
|
|
465
|
+
});
|
|
466
|
+
try {
|
|
467
|
+
const registry = await getRegistry();
|
|
468
|
+
if (!registry.hasModel(model)) {
|
|
469
|
+
sendAgentIPC("agent.streamChunk", {
|
|
470
|
+
agentId,
|
|
471
|
+
taskId,
|
|
472
|
+
model,
|
|
473
|
+
content: `
|
|
474
|
+
Error: No provider available for model "${model}". Check authentication with 'aemeathcli auth login'.
|
|
475
|
+
`
|
|
476
|
+
});
|
|
477
|
+
sendAgentIPC("agent.taskUpdate", { agentId, taskId, status: "completed" });
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
const provider = registry.getForModel(model);
|
|
481
|
+
sendAgentIPC("agent.streamChunk", {
|
|
482
|
+
agentId,
|
|
483
|
+
taskId,
|
|
484
|
+
model,
|
|
485
|
+
content: `Provider ready (${provider.name}). Loading tools...
|
|
486
|
+
`
|
|
487
|
+
});
|
|
488
|
+
const toolRegistry = await getToolRegistry();
|
|
489
|
+
const toolDefs = toolRegistry.getDefinitions();
|
|
490
|
+
sendAgentIPC("agent.streamChunk", {
|
|
491
|
+
agentId,
|
|
492
|
+
taskId,
|
|
493
|
+
model,
|
|
494
|
+
content: `${toolDefs.length} tools loaded. Sending request to ${model}...
|
|
495
|
+
`
|
|
496
|
+
});
|
|
497
|
+
const toolContext = {
|
|
498
|
+
projectRoot: process.cwd(),
|
|
499
|
+
workingDirectory: process.cwd(),
|
|
500
|
+
permissionMode: "permissive",
|
|
501
|
+
allowedPaths: [process.cwd()],
|
|
502
|
+
blockedCommands: []
|
|
503
|
+
};
|
|
504
|
+
const systemPrompt = `You are ${agentName}, an AI agent in team "${teamName}" with the role of ${role}. You have access to tools for reading files, writing files, editing code, searching, and executing shell commands. Use these tools to complete the assigned task thoroughly. Focus only on your specific role.`;
|
|
505
|
+
const messages = [{
|
|
506
|
+
id: randomUUID(),
|
|
507
|
+
role: "user",
|
|
508
|
+
content: prompt,
|
|
509
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
510
|
+
}];
|
|
511
|
+
for (let iteration = 0; iteration < MAX_TOOL_ITERATIONS; iteration++) {
|
|
512
|
+
let collectedText = "";
|
|
513
|
+
const collectedToolCalls = [];
|
|
514
|
+
const stream = provider.stream({
|
|
515
|
+
model,
|
|
516
|
+
messages,
|
|
517
|
+
system: systemPrompt,
|
|
518
|
+
maxTokens: 8e3,
|
|
519
|
+
...toolDefs.length > 0 ? { tools: toolDefs } : {}
|
|
520
|
+
});
|
|
521
|
+
for await (const chunk of stream) {
|
|
522
|
+
if (chunk.type === "text" && chunk.content) {
|
|
523
|
+
collectedText += chunk.content;
|
|
524
|
+
sendAgentIPC("agent.streamChunk", {
|
|
525
|
+
agentId,
|
|
526
|
+
taskId,
|
|
527
|
+
model,
|
|
528
|
+
content: chunk.content
|
|
529
|
+
});
|
|
530
|
+
} else if (chunk.type === "tool_call" && chunk.toolCall) {
|
|
531
|
+
collectedToolCalls.push(chunk.toolCall);
|
|
532
|
+
const tc = chunk.toolCall;
|
|
533
|
+
const summary = formatToolActivity(tc.name, tc.arguments);
|
|
534
|
+
sendAgentIPC("agent.streamChunk", {
|
|
535
|
+
agentId,
|
|
536
|
+
taskId,
|
|
537
|
+
model,
|
|
538
|
+
content: `
|
|
539
|
+
\u2699 ${tc.name} ${summary}
|
|
540
|
+
`
|
|
541
|
+
});
|
|
542
|
+
} else if (chunk.type === "error" && chunk.error) {
|
|
543
|
+
const errorMsg = chunk.error.length > 300 ? chunk.error.slice(0, 300) + "..." : chunk.error;
|
|
544
|
+
sendAgentIPC("agent.streamChunk", {
|
|
545
|
+
agentId,
|
|
546
|
+
taskId,
|
|
547
|
+
model,
|
|
548
|
+
content: `
|
|
549
|
+
Stream error: ${errorMsg}
|
|
550
|
+
`
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
if (collectedToolCalls.length === 0) {
|
|
555
|
+
break;
|
|
556
|
+
}
|
|
557
|
+
messages.push({
|
|
558
|
+
id: randomUUID(),
|
|
559
|
+
role: "assistant",
|
|
560
|
+
content: collectedText,
|
|
561
|
+
toolCalls: collectedToolCalls,
|
|
562
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
563
|
+
});
|
|
564
|
+
for (const tc of collectedToolCalls) {
|
|
565
|
+
const result = await toolRegistry.execute(tc, toolContext);
|
|
566
|
+
const briefResult = formatResultSummary(tc.name, result.content, result.isError);
|
|
567
|
+
sendAgentIPC("agent.streamChunk", {
|
|
568
|
+
agentId,
|
|
569
|
+
taskId,
|
|
570
|
+
model,
|
|
571
|
+
content: ` \u2192 ${briefResult}
|
|
572
|
+
`
|
|
573
|
+
});
|
|
574
|
+
const truncatedContent = result.content.length > MAX_TOOL_RESULT_LENGTH ? result.content.slice(0, MAX_TOOL_RESULT_LENGTH) + "\n...(truncated)" : result.content;
|
|
575
|
+
messages.push({
|
|
576
|
+
id: randomUUID(),
|
|
577
|
+
role: "tool",
|
|
578
|
+
content: truncatedContent,
|
|
579
|
+
toolCalls: [{ id: tc.id, name: tc.name, arguments: {} }],
|
|
580
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
581
|
+
});
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
} catch (error) {
|
|
585
|
+
const rawMsg = error instanceof Error ? error.message : String(error);
|
|
586
|
+
const msg = rawMsg.length > 300 ? rawMsg.slice(0, 300) + "..." : rawMsg;
|
|
587
|
+
sendAgentIPC("agent.streamChunk", {
|
|
588
|
+
agentId,
|
|
589
|
+
taskId,
|
|
590
|
+
model,
|
|
591
|
+
content: `
|
|
592
|
+
Error: ${msg}
|
|
593
|
+
`
|
|
594
|
+
});
|
|
595
|
+
}
|
|
596
|
+
sendAgentIPC("agent.taskUpdate", { agentId, taskId, status: "completed" });
|
|
597
|
+
}
|
|
598
|
+
sendAgentIPC("agent.register", {
|
|
599
|
+
agentId,
|
|
600
|
+
agentName,
|
|
601
|
+
teamName,
|
|
602
|
+
model,
|
|
603
|
+
role
|
|
604
|
+
});
|
|
605
|
+
const keepAlive = setInterval(() => {
|
|
606
|
+
}, 6e4);
|
|
607
|
+
const shutdown = () => {
|
|
608
|
+
clearInterval(keepAlive);
|
|
609
|
+
process.exit(0);
|
|
610
|
+
};
|
|
611
|
+
process.on("message", (raw) => {
|
|
612
|
+
if (!isIPCMessage(raw)) {
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
if (raw.method === "hub.taskAssign") {
|
|
616
|
+
const taskId = typeof raw.params["taskId"] === "string" ? raw.params["taskId"] : randomUUID();
|
|
617
|
+
const subject = typeof raw.params["subject"] === "string" ? raw.params["subject"] : "";
|
|
618
|
+
const description = typeof raw.params["description"] === "string" ? raw.params["description"] : "";
|
|
619
|
+
void processTask(taskId, description || subject || "Describe what you can help with.");
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
if (raw.method === "hub.shutdown") {
|
|
623
|
+
shutdown();
|
|
624
|
+
}
|
|
625
|
+
});
|
|
626
|
+
process.on("SIGINT", shutdown);
|
|
627
|
+
process.on("SIGTERM", shutdown);
|
|
628
|
+
await new Promise(() => {
|
|
629
|
+
});
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
async function main() {
|
|
633
|
+
if (await maybeRunAgentMode(process.argv.slice(2))) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
initializeDirectories();
|
|
637
|
+
const program = new Command().name("aemeathcli").description(
|
|
638
|
+
"Next-generation multi-model CLI coding tool with agent teams and split-panel coordination"
|
|
639
|
+
).version(VERSION, "-v, --version").option("-m, --model <model>", "Override model for this session").option("-r, --role <role>", "Set the task role").option("--verbose", "Enable verbose output").option("--no-color", "Disable colored output").option("--permission-mode <mode>", "Permission mode (strict, standard, permissive)").option("--project-root <path>", "Override project root detection");
|
|
640
|
+
program.addCommand(createChatCommand());
|
|
641
|
+
program.addCommand(createPlanCommand());
|
|
642
|
+
program.addCommand(createReviewCommand());
|
|
643
|
+
program.addCommand(createTestCommand());
|
|
644
|
+
program.addCommand(createConfigCommand());
|
|
645
|
+
program.addCommand(createAuthCommand());
|
|
646
|
+
program.action(async (options, command) => {
|
|
647
|
+
const args = command.args;
|
|
648
|
+
let message = args.length > 0 ? args.join(" ") : void 0;
|
|
649
|
+
let isAgentPane = false;
|
|
650
|
+
if (message === void 0) {
|
|
651
|
+
const promptFilePath = process.env["AEMEATHCLI_PROMPT_FILE"];
|
|
652
|
+
if (promptFilePath !== void 0 && promptFilePath.length > 0) {
|
|
653
|
+
try {
|
|
654
|
+
const { readFileSync } = await import('fs');
|
|
655
|
+
message = readFileSync(promptFilePath, "utf-8").trim();
|
|
656
|
+
isAgentPane = true;
|
|
657
|
+
} catch {
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
const { startChatSession } = await import('./App-P4MYD4QY.js');
|
|
662
|
+
const model = options["model"];
|
|
663
|
+
const role = options["role"];
|
|
664
|
+
await startChatSession({
|
|
665
|
+
...message !== void 0 ? { initialMessage: message } : {},
|
|
666
|
+
...model !== void 0 ? { model } : {},
|
|
667
|
+
...role !== void 0 ? { role } : {},
|
|
668
|
+
...isAgentPane ? { isAgentPane: true } : {},
|
|
669
|
+
streaming: true
|
|
670
|
+
});
|
|
671
|
+
});
|
|
672
|
+
checkForUpdates();
|
|
673
|
+
try {
|
|
674
|
+
await program.parseAsync(process.argv);
|
|
675
|
+
} catch (error) {
|
|
676
|
+
if (error instanceof Error) {
|
|
677
|
+
logger.error({ error: error.message }, "CLI error");
|
|
678
|
+
process.stderr.write(pc2.red(`Error: ${error.message}
|
|
679
|
+
`));
|
|
680
|
+
}
|
|
681
|
+
process.exitCode = 1;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
function checkForUpdates() {
|
|
685
|
+
import('update-notifier').then(({ default: updateNotifier }) => {
|
|
686
|
+
const notifier = updateNotifier({
|
|
687
|
+
pkg: { name: "aemeathcli", version: VERSION },
|
|
688
|
+
updateCheckInterval: 1e3 * 60 * 60 * 24
|
|
689
|
+
// 24 hours
|
|
690
|
+
});
|
|
691
|
+
notifier.notify({ isGlobal: true });
|
|
692
|
+
}).catch(() => {
|
|
693
|
+
});
|
|
694
|
+
}
|
|
695
|
+
main().catch((error) => {
|
|
696
|
+
process.stderr.write(
|
|
697
|
+
pc2.red(`Fatal error: ${error instanceof Error ? error.message : String(error)}
|
|
698
|
+
`)
|
|
699
|
+
);
|
|
700
|
+
process.exit(1);
|
|
701
|
+
});
|
|
702
|
+
//# sourceMappingURL=cli.js.map
|
|
703
|
+
//# sourceMappingURL=cli.js.map
|