monk-pi 0.10.2 → 0.11.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 +41 -5
- package/dist/{chunk-GGAUER4O.js → chunk-5XGED4S4.js} +189 -187
- package/dist/cli.js +208 -39
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -16,18 +16,29 @@
|
|
|
16
16
|
|
|
17
17
|
## 🚀 快速开始
|
|
18
18
|
|
|
19
|
-
### 1.
|
|
20
|
-
|
|
21
|
-
无需全局安装,直接通过 `npx` 启动:
|
|
19
|
+
### 1. 快速安装与运行
|
|
22
20
|
|
|
21
|
+
#### 方式 A:纯免安装直接运行 (推荐)
|
|
22
|
+
无需全局安装任何环境,直接通过 `npx` 启动:
|
|
23
23
|
```bash
|
|
24
24
|
npx monk-pi
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
#### 方式 B:使用 Homebrew 安装 (macOS / Linux 首选)
|
|
28
|
+
Homebrew 会**自动帮你处理并安装 Node.js 依赖**(完全无需担心电脑缺少环境):
|
|
29
|
+
```bash
|
|
30
|
+
brew install yaoleifly/tap/monk-pi
|
|
31
|
+
```
|
|
28
32
|
|
|
33
|
+
#### 方式 C:通过 npm / pnpm / bun 全局安装
|
|
29
34
|
```bash
|
|
30
35
|
npm install -g monk-pi
|
|
36
|
+
# 或者使用 bun (最快)
|
|
37
|
+
bun add -g monk-pi
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
安装完成后,在任意项目目录下直接输入:
|
|
41
|
+
```bash
|
|
31
42
|
monk-pi
|
|
32
43
|
```
|
|
33
44
|
|
|
@@ -83,6 +94,7 @@ monk-pi --model monk "帮我设计一套分布式系统的架构方案"
|
|
|
83
94
|
### 终端 CLI 指令
|
|
84
95
|
| 命令 | 说明 |
|
|
85
96
|
| :--- | :--- |
|
|
97
|
+
| `monk-pi run <命令>` | **监控运行命令**,报错时自动捕获日志并提示一键呼叫 AI 代码自愈 (Auto-Fix) |
|
|
86
98
|
| `monk-pi resume` (或 `-r`) | 可视化交互式浏览历史会话列表,带相对时间和摘要快速恢复 (断点续写) |
|
|
87
99
|
| `monk-pi login` (或 `auth`) | 交互式配置或更新 Monk API Key,并自动同步至 Pi |
|
|
88
100
|
| `monk-pi status` (或 `check`) | 检测 API 网络延迟、认证有效性及推演通道 |
|
|
@@ -103,7 +115,31 @@ monk-pi --model monk "帮我设计一套分布式系统的架构方案"
|
|
|
103
115
|
|
|
104
116
|
---
|
|
105
117
|
|
|
106
|
-
##
|
|
118
|
+
## 🛠️ 命令报错一键自愈 (Auto-Fix on Error)
|
|
119
|
+
|
|
120
|
+
日常开发中最繁琐的痛点就是“编译挂了 / 跑测试挂了,得复制报错去问 AI”。Monk-Pi 提供了零摩擦的包装运行命令:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# 监控任何本地命令运行
|
|
124
|
+
monk-pi run "npm run build"
|
|
125
|
+
monk-pi run "npm test"
|
|
126
|
+
monk-pi run "cargo check"
|
|
127
|
+
monk-pi run "go test ./..."
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
- **命令成功 (exit 0)**:正常透传输出并退出,零额外打扰。
|
|
131
|
+
- **命令报错 (exit != 0)**:自动捕获 stderr 与异常堆栈,在终端无缝弹出自愈向导:
|
|
132
|
+
```text
|
|
133
|
+
✖ 命令执行失败 (退出码: 1 · 耗时 2.4s)
|
|
134
|
+
|
|
135
|
+
? 检测到命令报错,请选择 Monk 介入处理方式:
|
|
136
|
+
❯ 1. 呼叫 Monk 分析报错并自动修复代码 (一键自愈 Auto-Fix · 推荐)
|
|
137
|
+
2. 进入交互式终端协助排查 (带入报错日志)
|
|
138
|
+
3. 忽略并直接退出终端
|
|
139
|
+
```
|
|
140
|
+
- **选第 1 项**:AI 自动读取报错涉及的源码文件、分析根因、自动精准编辑修复,并**重新在后台跑一遍命令验证**,整个过程无需复制粘贴一个字符!
|
|
141
|
+
|
|
142
|
+
---
|
|
107
143
|
|
|
108
144
|
告别面对空白输入框与闪烁光标“不知道该问什么”的迷茫感:
|
|
109
145
|
- **项目画像智能感知**:首次启动或新会话打开时,自动识别当前技术栈(如 `Vue 3 技术栈`、`Next.js 全栈`、`Go 后端应用` 等)及 Git 状态。
|
|
@@ -4,6 +4,7 @@ import path from "path";
|
|
|
4
4
|
var MONK_BASE_URL = "https://monk.party/v1";
|
|
5
5
|
var MONK_WEBSITE = "https://monk.party";
|
|
6
6
|
var MONK_ACCOUNT_URL = "https://monk.party/account/";
|
|
7
|
+
var MONK_PI_VERSION = "0.11.0";
|
|
7
8
|
var MONK_MODELS = [
|
|
8
9
|
{
|
|
9
10
|
id: "monk-coding",
|
|
@@ -220,131 +221,6 @@ function getDefaultModel() {
|
|
|
220
221
|
return DEFAULT_MONK_MODEL;
|
|
221
222
|
}
|
|
222
223
|
|
|
223
|
-
// src/monk-api.ts
|
|
224
|
-
async function validateApiKey(apiKey, baseUrl = MONK_BASE_URL) {
|
|
225
|
-
const trimmedKey = apiKey.trim();
|
|
226
|
-
if (!trimmedKey) {
|
|
227
|
-
return {
|
|
228
|
-
valid: false,
|
|
229
|
-
latencyMs: 0,
|
|
230
|
-
models: [],
|
|
231
|
-
error: "API Key \u4E0D\u80FD\u4E3A\u7A7A"
|
|
232
|
-
};
|
|
233
|
-
}
|
|
234
|
-
const endpoint = `${baseUrl.replace(/\/+$/, "")}/models`;
|
|
235
|
-
const startTime = Date.now();
|
|
236
|
-
try {
|
|
237
|
-
const controller = new AbortController();
|
|
238
|
-
const timeoutId = setTimeout(() => controller.abort(), 8e3);
|
|
239
|
-
const response = await fetch(endpoint, {
|
|
240
|
-
method: "GET",
|
|
241
|
-
headers: {
|
|
242
|
-
Authorization: `Bearer ${trimmedKey}`,
|
|
243
|
-
Accept: "application/json"
|
|
244
|
-
},
|
|
245
|
-
signal: controller.signal
|
|
246
|
-
});
|
|
247
|
-
clearTimeout(timeoutId);
|
|
248
|
-
const latencyMs = Date.now() - startTime;
|
|
249
|
-
if (response.status === 401 || response.status === 403) {
|
|
250
|
-
const body = await response.json().catch(() => ({}));
|
|
251
|
-
return {
|
|
252
|
-
valid: false,
|
|
253
|
-
latencyMs,
|
|
254
|
-
models: [],
|
|
255
|
-
statusCode: response.status,
|
|
256
|
-
error: body.error?.message || "API Key \u65E0\u6548\u6216\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u68C0\u67E5 monk.party \u7684\u8BA2\u9605\u51ED\u8BC1"
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
if (!response.ok) {
|
|
260
|
-
return {
|
|
261
|
-
valid: false,
|
|
262
|
-
latencyMs,
|
|
263
|
-
models: [],
|
|
264
|
-
statusCode: response.status,
|
|
265
|
-
error: `Monk API \u54CD\u5E94\u5F02\u5E38 (HTTP ${response.status})`
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
const data = await response.json().catch(() => ({}));
|
|
269
|
-
const models = Array.isArray(data.data) ? data.data.map((m) => m.id) : [];
|
|
270
|
-
return {
|
|
271
|
-
valid: true,
|
|
272
|
-
latencyMs,
|
|
273
|
-
models,
|
|
274
|
-
statusCode: response.status
|
|
275
|
-
};
|
|
276
|
-
} catch (err) {
|
|
277
|
-
const latencyMs = Date.now() - startTime;
|
|
278
|
-
const isAbort = err instanceof Error && err.name === "AbortError";
|
|
279
|
-
return {
|
|
280
|
-
valid: false,
|
|
281
|
-
latencyMs,
|
|
282
|
-
models: [],
|
|
283
|
-
error: isAbort ? "\u8FDE\u63A5 Monk \u670D\u52A1\u8D85\u65F6\uFF08\u8D85\u8FC7 8 \u79D2\uFF09\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5" : `\u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
function extractFirstJson(text) {
|
|
288
|
-
try {
|
|
289
|
-
return JSON.parse(text);
|
|
290
|
-
} catch {
|
|
291
|
-
const cleaned = text.replace(/^data:\s*/gm, "");
|
|
292
|
-
const start = cleaned.indexOf("{");
|
|
293
|
-
const end = cleaned.lastIndexOf("}");
|
|
294
|
-
if (start === -1 || end <= start) return {};
|
|
295
|
-
try {
|
|
296
|
-
return JSON.parse(cleaned.slice(start, end + 1));
|
|
297
|
-
} catch {
|
|
298
|
-
return {};
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
async function testChatCompletion(apiKey, model = "monk-fast", baseUrl = MONK_BASE_URL) {
|
|
303
|
-
const endpoint = `${baseUrl.replace(/\/+$/, "")}/chat/completions`;
|
|
304
|
-
const startTime = Date.now();
|
|
305
|
-
try {
|
|
306
|
-
const controller = new AbortController();
|
|
307
|
-
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
308
|
-
const response = await fetch(endpoint, {
|
|
309
|
-
method: "POST",
|
|
310
|
-
headers: {
|
|
311
|
-
"Content-Type": "application/json",
|
|
312
|
-
Authorization: `Bearer ${apiKey.trim()}`
|
|
313
|
-
},
|
|
314
|
-
body: JSON.stringify({
|
|
315
|
-
model,
|
|
316
|
-
messages: [{ role: "user", content: "pong" }],
|
|
317
|
-
max_tokens: 10,
|
|
318
|
-
temperature: 0.1
|
|
319
|
-
}),
|
|
320
|
-
signal: controller.signal
|
|
321
|
-
});
|
|
322
|
-
clearTimeout(timeoutId);
|
|
323
|
-
const latencyMs = Date.now() - startTime;
|
|
324
|
-
const payload = extractFirstJson(await response.text());
|
|
325
|
-
if (!response.ok) {
|
|
326
|
-
return {
|
|
327
|
-
success: false,
|
|
328
|
-
latencyMs,
|
|
329
|
-
error: payload.error?.message || `HTTP ${response.status}`
|
|
330
|
-
};
|
|
331
|
-
}
|
|
332
|
-
const reply = (payload.choices?.[0]?.message?.content ?? "").trim();
|
|
333
|
-
return {
|
|
334
|
-
success: true,
|
|
335
|
-
latencyMs,
|
|
336
|
-
reply
|
|
337
|
-
};
|
|
338
|
-
} catch (err) {
|
|
339
|
-
const latencyMs = Date.now() - startTime;
|
|
340
|
-
return {
|
|
341
|
-
success: false,
|
|
342
|
-
latencyMs,
|
|
343
|
-
error: err instanceof Error ? err.message : String(err)
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
224
|
// src/ui.ts
|
|
349
225
|
import spawn from "cross-spawn";
|
|
350
226
|
import pc from "picocolors";
|
|
@@ -666,41 +542,208 @@ function launchPi(options) {
|
|
|
666
542
|
});
|
|
667
543
|
}
|
|
668
544
|
|
|
545
|
+
// src/monk-api.ts
|
|
546
|
+
async function validateApiKey(apiKey, baseUrl = MONK_BASE_URL) {
|
|
547
|
+
const trimmedKey = apiKey.trim();
|
|
548
|
+
if (!trimmedKey) {
|
|
549
|
+
return {
|
|
550
|
+
valid: false,
|
|
551
|
+
latencyMs: 0,
|
|
552
|
+
models: [],
|
|
553
|
+
error: "API Key \u4E0D\u80FD\u4E3A\u7A7A"
|
|
554
|
+
};
|
|
555
|
+
}
|
|
556
|
+
const endpoint = `${baseUrl.replace(/\/+$/, "")}/models`;
|
|
557
|
+
const startTime = Date.now();
|
|
558
|
+
try {
|
|
559
|
+
const controller = new AbortController();
|
|
560
|
+
const timeoutId = setTimeout(() => controller.abort(), 8e3);
|
|
561
|
+
const response = await fetch(endpoint, {
|
|
562
|
+
method: "GET",
|
|
563
|
+
headers: {
|
|
564
|
+
Authorization: `Bearer ${trimmedKey}`,
|
|
565
|
+
Accept: "application/json"
|
|
566
|
+
},
|
|
567
|
+
signal: controller.signal
|
|
568
|
+
});
|
|
569
|
+
clearTimeout(timeoutId);
|
|
570
|
+
const latencyMs = Date.now() - startTime;
|
|
571
|
+
if (response.status === 401 || response.status === 403) {
|
|
572
|
+
const body = await response.json().catch(() => ({}));
|
|
573
|
+
return {
|
|
574
|
+
valid: false,
|
|
575
|
+
latencyMs,
|
|
576
|
+
models: [],
|
|
577
|
+
statusCode: response.status,
|
|
578
|
+
error: body.error?.message || "API Key \u65E0\u6548\u6216\u5DF2\u8FC7\u671F\uFF0C\u8BF7\u68C0\u67E5 monk.party \u7684\u8BA2\u9605\u51ED\u8BC1"
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
if (!response.ok) {
|
|
582
|
+
return {
|
|
583
|
+
valid: false,
|
|
584
|
+
latencyMs,
|
|
585
|
+
models: [],
|
|
586
|
+
statusCode: response.status,
|
|
587
|
+
error: `Monk API \u54CD\u5E94\u5F02\u5E38 (HTTP ${response.status})`
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
const data = await response.json().catch(() => ({}));
|
|
591
|
+
const models = Array.isArray(data.data) ? data.data.map((m) => m.id) : [];
|
|
592
|
+
return {
|
|
593
|
+
valid: true,
|
|
594
|
+
latencyMs,
|
|
595
|
+
models,
|
|
596
|
+
statusCode: response.status
|
|
597
|
+
};
|
|
598
|
+
} catch (err) {
|
|
599
|
+
const latencyMs = Date.now() - startTime;
|
|
600
|
+
const isAbort = err instanceof Error && err.name === "AbortError";
|
|
601
|
+
return {
|
|
602
|
+
valid: false,
|
|
603
|
+
latencyMs,
|
|
604
|
+
models: [],
|
|
605
|
+
error: isAbort ? "\u8FDE\u63A5 Monk \u670D\u52A1\u8D85\u65F6\uFF08\u8D85\u8FC7 8 \u79D2\uFF09\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5" : `\u7F51\u7EDC\u8FDE\u63A5\u5931\u8D25: ${err instanceof Error ? err.message : String(err)}`
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
function extractFirstJson(text) {
|
|
610
|
+
try {
|
|
611
|
+
return JSON.parse(text);
|
|
612
|
+
} catch {
|
|
613
|
+
const cleaned = text.replace(/^data:\s*/gm, "");
|
|
614
|
+
const start = cleaned.indexOf("{");
|
|
615
|
+
const end = cleaned.lastIndexOf("}");
|
|
616
|
+
if (start === -1 || end <= start) return {};
|
|
617
|
+
try {
|
|
618
|
+
return JSON.parse(cleaned.slice(start, end + 1));
|
|
619
|
+
} catch {
|
|
620
|
+
return {};
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
async function testChatCompletion(apiKey, model = "monk-fast", baseUrl = MONK_BASE_URL) {
|
|
625
|
+
const endpoint = `${baseUrl.replace(/\/+$/, "")}/chat/completions`;
|
|
626
|
+
const startTime = Date.now();
|
|
627
|
+
try {
|
|
628
|
+
const controller = new AbortController();
|
|
629
|
+
const timeoutId = setTimeout(() => controller.abort(), 3e4);
|
|
630
|
+
const response = await fetch(endpoint, {
|
|
631
|
+
method: "POST",
|
|
632
|
+
headers: {
|
|
633
|
+
"Content-Type": "application/json",
|
|
634
|
+
Authorization: `Bearer ${apiKey.trim()}`
|
|
635
|
+
},
|
|
636
|
+
body: JSON.stringify({
|
|
637
|
+
model,
|
|
638
|
+
messages: [{ role: "user", content: "pong" }],
|
|
639
|
+
max_tokens: 10,
|
|
640
|
+
temperature: 0.1
|
|
641
|
+
}),
|
|
642
|
+
signal: controller.signal
|
|
643
|
+
});
|
|
644
|
+
clearTimeout(timeoutId);
|
|
645
|
+
const latencyMs = Date.now() - startTime;
|
|
646
|
+
const payload = extractFirstJson(await response.text());
|
|
647
|
+
if (!response.ok) {
|
|
648
|
+
return {
|
|
649
|
+
success: false,
|
|
650
|
+
latencyMs,
|
|
651
|
+
error: payload.error?.message || `HTTP ${response.status}`
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
const reply = (payload.choices?.[0]?.message?.content ?? "").trim();
|
|
655
|
+
return {
|
|
656
|
+
success: true,
|
|
657
|
+
latencyMs,
|
|
658
|
+
reply
|
|
659
|
+
};
|
|
660
|
+
} catch (err) {
|
|
661
|
+
const latencyMs = Date.now() - startTime;
|
|
662
|
+
return {
|
|
663
|
+
success: false,
|
|
664
|
+
latencyMs,
|
|
665
|
+
error: err instanceof Error ? err.message : String(err)
|
|
666
|
+
};
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
// src/commands/login.ts
|
|
671
|
+
import pc3 from "picocolors";
|
|
672
|
+
async function loginCommand() {
|
|
673
|
+
printBanner();
|
|
674
|
+
const current = resolveApiKey();
|
|
675
|
+
const apiKey = await promptForApiKey(current.key || void 0);
|
|
676
|
+
if (!apiKey) {
|
|
677
|
+
logWarn("\u672A\u8F93\u5165 API Key\uFF0C\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002");
|
|
678
|
+
return false;
|
|
679
|
+
}
|
|
680
|
+
logInfo("\u6B63\u5728\u8FDE\u63A5 Monk API \u9A8C\u8BC1\u5BC6\u94A5...");
|
|
681
|
+
const result = await validateApiKey(apiKey);
|
|
682
|
+
if (!result.valid) {
|
|
683
|
+
logError(`\u9A8C\u8BC1\u5931\u8D25: ${result.error || "\u672A\u77E5\u9519\u8BEF"}`);
|
|
684
|
+
logWarn("\u8BF7\u6838\u5BF9\u540E\u91CD\u65B0\u8FD0\u884C `monk-pi login`\u3002");
|
|
685
|
+
return false;
|
|
686
|
+
}
|
|
687
|
+
logSuccess(`\u9A8C\u8BC1\u901A\u8FC7\uFF01\u7F51\u7EDC\u5EF6\u8FDF: ${pc3.green(`${result.latencyMs}ms`)}`);
|
|
688
|
+
if (result.models.length > 0) {
|
|
689
|
+
logInfo(`\u53EF\u7528\u6A21\u578B: ${pc3.yellow(result.models.join(", "))}`);
|
|
690
|
+
}
|
|
691
|
+
saveMonkConfig({
|
|
692
|
+
apiKey,
|
|
693
|
+
lastVerified: (/* @__PURE__ */ new Date()).toISOString()
|
|
694
|
+
});
|
|
695
|
+
logSuccess(`\u51ED\u8BC1\u5DF2\u4FDD\u5B58\u81F3\u672C\u5730\u914D\u7F6E`);
|
|
696
|
+
const syncResult = syncPiModelsJson(apiKey);
|
|
697
|
+
const extResult = syncPiExtension();
|
|
698
|
+
if (syncResult.success) {
|
|
699
|
+
logSuccess(`\u5DF2\u6210\u529F\u540C\u6B65\u5E76\u4F18\u5316 Pi \u914D\u7F6E\u6587\u4EF6: ${pc3.dim(syncResult.path)}`);
|
|
700
|
+
} else {
|
|
701
|
+
logWarn(`\u540C\u6B65 Pi \u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${syncResult.error}`);
|
|
702
|
+
}
|
|
703
|
+
if (extResult.success) {
|
|
704
|
+
logSuccess(`\u5DF2\u5B89\u88C5 Monk \u539F\u751F TUI \u6269\u5C55: ${pc3.dim(extResult.path)}`);
|
|
705
|
+
}
|
|
706
|
+
console.log();
|
|
707
|
+
logSuccess(`Monk \xD7 Pi \u5C31\u7EEA\uFF01\u73B0\u5728\u60A8\u53EF\u4EE5\u76F4\u63A5\u8F93\u5165 ${pc3.bold(pc3.yellow("monk-pi"))} \u5F00\u59CB\u7F16\u7801\u3002`);
|
|
708
|
+
console.log();
|
|
709
|
+
return true;
|
|
710
|
+
}
|
|
711
|
+
|
|
669
712
|
// src/commands/doctor.ts
|
|
670
713
|
import fs3 from "fs";
|
|
671
714
|
import os2 from "os";
|
|
672
|
-
import
|
|
715
|
+
import pc4 from "picocolors";
|
|
673
716
|
async function doctorCommand() {
|
|
674
717
|
printBanner();
|
|
675
|
-
console.log(` ${
|
|
718
|
+
console.log(` ${pc4.bold("\u3010Monk \xD7 Pi \u73AF\u5883\u8BCA\u65AD (Doctor)\u3011")}`);
|
|
676
719
|
console.log();
|
|
677
720
|
let hasIssue = false;
|
|
678
721
|
const nodeVersion = process.version;
|
|
679
722
|
const major = parseInt(nodeVersion.slice(1).split(".")[0], 10);
|
|
680
723
|
if (major >= 18) {
|
|
681
|
-
logSuccess(`Node.js \u7248\u672C: ${
|
|
724
|
+
logSuccess(`Node.js \u7248\u672C: ${pc4.bold(nodeVersion)} (\u6EE1\u8DB3 >= 18 \u8981\u6C42)`);
|
|
682
725
|
} else {
|
|
683
726
|
hasIssue = true;
|
|
684
|
-
logError(`Node.js \u7248\u672C: ${
|
|
727
|
+
logError(`Node.js \u7248\u672C: ${pc4.bold(nodeVersion)} (\u8FC7\u4F4E\uFF0C\u8BF7\u5347\u7EA7\u5230 Node 18+)`);
|
|
685
728
|
}
|
|
686
729
|
logInfo(`\u64CD\u4F5C\u7CFB\u7EDF: ${os2.type()} ${os2.release()} (${os2.arch()})`);
|
|
687
730
|
const pi = detectPi();
|
|
688
731
|
if (pi.installed) {
|
|
689
732
|
logSuccess(
|
|
690
|
-
`Pi \u6838\u5FC3\u5957\u4EF6: ${
|
|
733
|
+
`Pi \u6838\u5FC3\u5957\u4EF6: ${pc4.bold(`\u5DF2\u5C31\u7EEA (v${pi.version})`)} \xB7 ${pc4.dim(`[\u6765\u6E90: ${pi.description}]`)}`
|
|
691
734
|
);
|
|
692
735
|
} else {
|
|
693
736
|
hasIssue = true;
|
|
694
|
-
logError(`Pi \u6838\u5FC3\u5957\u4EF6: ${
|
|
695
|
-
console.log(` ${
|
|
737
|
+
logError(`Pi \u6838\u5FC3\u5957\u4EF6: ${pc4.bold("\u672A\u627E\u5230\u53EF\u7528\u8FD0\u884C\u65F6")}`);
|
|
738
|
+
console.log(` ${pc4.dim("\u89E3\u51B3\u529E\u6CD5: \u8FD0\u884C npm install -g @earendil-works/pi-coding-agent")}`);
|
|
696
739
|
}
|
|
697
740
|
const { key, source } = resolveApiKey();
|
|
698
741
|
if (key) {
|
|
699
|
-
logSuccess(`Monk API Key: ${
|
|
742
|
+
logSuccess(`Monk API Key: ${pc4.bold(maskKey(key))} (\u6765\u6E90: ${source})`);
|
|
700
743
|
} else {
|
|
701
744
|
hasIssue = true;
|
|
702
745
|
logError(`Monk API Key: \u672A\u914D\u7F6E`);
|
|
703
|
-
console.log(` ${
|
|
746
|
+
console.log(` ${pc4.dim("\u89E3\u51B3\u529E\u6CD5: \u8FD0\u884C monk-pi login")}`);
|
|
704
747
|
}
|
|
705
748
|
const modelsFile = getPiModelsFile();
|
|
706
749
|
if (fs3.existsSync(modelsFile)) {
|
|
@@ -710,10 +753,10 @@ async function doctorCommand() {
|
|
|
710
753
|
if (monk) {
|
|
711
754
|
const hasCompat = monk.compat?.supportsDeveloperRole === false && monk.compat?.maxTokensField === "max_tokens";
|
|
712
755
|
if (hasCompat) {
|
|
713
|
-
logSuccess(`Pi \u914D\u7F6E\u6587\u4EF6: ${
|
|
756
|
+
logSuccess(`Pi \u914D\u7F6E\u6587\u4EF6: ${pc4.bold("\u5DF2\u914D\u7F6E Monk \u4E13\u5C5E\u4F18\u5316\u517C\u5BB9\u53C2\u6570")}`);
|
|
714
757
|
} else {
|
|
715
758
|
logWarn(`Pi \u914D\u7F6E\u6587\u4EF6: \u5B58\u5728 Monk \u914D\u7F6E\uFF0C\u4F46\u7F3A\u5C11\u6700\u4F73 compat \u53C2\u6570`);
|
|
716
|
-
console.log(` ${
|
|
759
|
+
console.log(` ${pc4.dim("\u6B63\u5728\u4E3A\u60A8\u81EA\u52A8\u7EA0\u6B63...")}`);
|
|
717
760
|
syncPiModelsJson(key);
|
|
718
761
|
logSuccess(`Pi \u914D\u7F6E\u6587\u4EF6: \u5DF2\u81EA\u52A8\u4FEE\u590D\u4F18\u5316`);
|
|
719
762
|
}
|
|
@@ -734,79 +777,37 @@ async function doctorCommand() {
|
|
|
734
777
|
if (extRes.success) {
|
|
735
778
|
if (extRes.updated) {
|
|
736
779
|
logSuccess(
|
|
737
|
-
`Pi \u539F\u751F\u6269\u5C55: ${
|
|
780
|
+
`Pi \u539F\u751F\u6269\u5C55: ${pc4.bold("\u5DF2\u81EA\u52A8\u66F4\u65B0\u81F3\u6700\u65B0\u7248")} (\u4E2D\u6587\u5DE5\u7A0B\u63D0\u793A\u8BCD\u3001/monk \u6307\u4EE4\u4E0E\u81EA\u52A8\u91CD\u8BD5\u5C31\u7EEA)`
|
|
738
781
|
);
|
|
739
782
|
} else {
|
|
740
783
|
logSuccess(
|
|
741
|
-
`Pi \u539F\u751F\u6269\u5C55: ${
|
|
784
|
+
`Pi \u539F\u751F\u6269\u5C55: ${pc4.bold("\u5DF2\u5C31\u7EEA")} (\u4E2D\u6587\u5DE5\u7A0B\u63D0\u793A\u8BCD\u3001/monk \u6307\u4EE4\u4E0E\u81EA\u52A8\u91CD\u8BD5\u5C31\u7EEA)`
|
|
742
785
|
);
|
|
743
786
|
}
|
|
744
787
|
} else {
|
|
745
788
|
logError(`Pi \u539F\u751F\u6269\u5C55\u90E8\u7F72\u5931\u8D25: ${extRes.error}`);
|
|
746
789
|
}
|
|
747
790
|
if (key) {
|
|
748
|
-
process.stdout.write(` ${
|
|
791
|
+
process.stdout.write(` ${pc4.dim("\u23F3 \u6B63\u5728\u63A2\u6D4B\u4E0E monk.party \u63A5\u53E3\u7684\u8FDE\u901A\u6027...")} `);
|
|
749
792
|
const val = await validateApiKey(key);
|
|
750
793
|
process.stdout.write("\r" + " ".repeat(50) + "\r");
|
|
751
794
|
if (val.valid) {
|
|
752
|
-
logSuccess(`Monk \u8FDE\u901A\u6027: ${
|
|
795
|
+
logSuccess(`Monk \u8FDE\u901A\u6027: ${pc4.green("\u4F18\u79C0")} \xB7 \u5EF6\u8FDF ${val.latencyMs}ms`);
|
|
753
796
|
} else {
|
|
754
797
|
hasIssue = true;
|
|
755
798
|
logError(`Monk \u8FDE\u901A\u6027\u5F02\u5E38: ${val.error}`);
|
|
756
799
|
}
|
|
757
800
|
}
|
|
758
801
|
console.log();
|
|
759
|
-
console.log(
|
|
802
|
+
console.log(pc4.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
760
803
|
if (hasIssue) {
|
|
761
804
|
logWarn("\u68C0\u6D4B\u5230\u73AF\u5883\u5B58\u5728\u90E8\u5206\u95EE\u9898\uFF0C\u8BF7\u53C2\u8003\u4E0A\u65B9\u63D0\u793A\u5904\u7406\u3002");
|
|
762
805
|
} else {
|
|
763
|
-
logSuccess(
|
|
806
|
+
logSuccess(pc4.bold("\u592A\u68D2\u4E86\uFF01\u6240\u6709\u68C0\u67E5\u9879\u5168\u90E8\u901A\u8FC7\uFF0C\u73AF\u5883\u5904\u4E8E\u6700\u4F73\u72B6\u6001\u3002"));
|
|
764
807
|
}
|
|
765
808
|
console.log();
|
|
766
809
|
}
|
|
767
810
|
|
|
768
|
-
// src/commands/login.ts
|
|
769
|
-
import pc4 from "picocolors";
|
|
770
|
-
async function loginCommand() {
|
|
771
|
-
printBanner();
|
|
772
|
-
const current = resolveApiKey();
|
|
773
|
-
const apiKey = await promptForApiKey(current.key || void 0);
|
|
774
|
-
if (!apiKey) {
|
|
775
|
-
logWarn("\u672A\u8F93\u5165 API Key\uFF0C\u64CD\u4F5C\u5DF2\u53D6\u6D88\u3002");
|
|
776
|
-
return false;
|
|
777
|
-
}
|
|
778
|
-
logInfo("\u6B63\u5728\u8FDE\u63A5 Monk API \u9A8C\u8BC1\u5BC6\u94A5...");
|
|
779
|
-
const result = await validateApiKey(apiKey);
|
|
780
|
-
if (!result.valid) {
|
|
781
|
-
logError(`\u9A8C\u8BC1\u5931\u8D25: ${result.error || "\u672A\u77E5\u9519\u8BEF"}`);
|
|
782
|
-
logWarn("\u8BF7\u6838\u5BF9\u540E\u91CD\u65B0\u8FD0\u884C `monk-pi login`\u3002");
|
|
783
|
-
return false;
|
|
784
|
-
}
|
|
785
|
-
logSuccess(`\u9A8C\u8BC1\u901A\u8FC7\uFF01\u7F51\u7EDC\u5EF6\u8FDF: ${pc4.green(`${result.latencyMs}ms`)}`);
|
|
786
|
-
if (result.models.length > 0) {
|
|
787
|
-
logInfo(`\u53EF\u7528\u6A21\u578B: ${pc4.yellow(result.models.join(", "))}`);
|
|
788
|
-
}
|
|
789
|
-
saveMonkConfig({
|
|
790
|
-
apiKey,
|
|
791
|
-
lastVerified: (/* @__PURE__ */ new Date()).toISOString()
|
|
792
|
-
});
|
|
793
|
-
logSuccess(`\u51ED\u8BC1\u5DF2\u4FDD\u5B58\u81F3\u672C\u5730\u914D\u7F6E`);
|
|
794
|
-
const syncResult = syncPiModelsJson(apiKey);
|
|
795
|
-
const extResult = syncPiExtension();
|
|
796
|
-
if (syncResult.success) {
|
|
797
|
-
logSuccess(`\u5DF2\u6210\u529F\u540C\u6B65\u5E76\u4F18\u5316 Pi \u914D\u7F6E\u6587\u4EF6: ${pc4.dim(syncResult.path)}`);
|
|
798
|
-
} else {
|
|
799
|
-
logWarn(`\u540C\u6B65 Pi \u914D\u7F6E\u6587\u4EF6\u5931\u8D25: ${syncResult.error}`);
|
|
800
|
-
}
|
|
801
|
-
if (extResult.success) {
|
|
802
|
-
logSuccess(`\u5DF2\u5B89\u88C5 Monk \u539F\u751F TUI \u6269\u5C55: ${pc4.dim(extResult.path)}`);
|
|
803
|
-
}
|
|
804
|
-
console.log();
|
|
805
|
-
logSuccess(`Monk \xD7 Pi \u5C31\u7EEA\uFF01\u73B0\u5728\u60A8\u53EF\u4EE5\u76F4\u63A5\u8F93\u5165 ${pc4.bold(pc4.yellow("monk-pi"))} \u5F00\u59CB\u7F16\u7801\u3002`);
|
|
806
|
-
console.log();
|
|
807
|
-
return true;
|
|
808
|
-
}
|
|
809
|
-
|
|
810
811
|
// src/commands/model.ts
|
|
811
812
|
import pc5 from "picocolors";
|
|
812
813
|
async function modelCommand(targetModel) {
|
|
@@ -963,6 +964,7 @@ export {
|
|
|
963
964
|
MONK_BASE_URL,
|
|
964
965
|
MONK_WEBSITE,
|
|
965
966
|
MONK_ACCOUNT_URL,
|
|
967
|
+
MONK_PI_VERSION,
|
|
966
968
|
MONK_MODELS,
|
|
967
969
|
DEFAULT_MONK_MODEL,
|
|
968
970
|
getMonkHomeDir,
|
|
@@ -979,8 +981,6 @@ export {
|
|
|
979
981
|
getMonkExtensionRaw,
|
|
980
982
|
syncPiExtension,
|
|
981
983
|
getDefaultModel,
|
|
982
|
-
validateApiKey,
|
|
983
|
-
testChatCompletion,
|
|
984
984
|
openBrowser,
|
|
985
985
|
printBanner,
|
|
986
986
|
logSuccess,
|
|
@@ -997,8 +997,10 @@ export {
|
|
|
997
997
|
detectPackageManager,
|
|
998
998
|
installPi,
|
|
999
999
|
launchPi,
|
|
1000
|
-
|
|
1000
|
+
validateApiKey,
|
|
1001
|
+
testChatCompletion,
|
|
1001
1002
|
loginCommand,
|
|
1003
|
+
doctorCommand,
|
|
1002
1004
|
modelCommand,
|
|
1003
1005
|
runCommand,
|
|
1004
1006
|
statusCommand
|
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
MONK_ACCOUNT_URL,
|
|
4
|
+
MONK_PI_VERSION,
|
|
4
5
|
MONK_WEBSITE,
|
|
5
6
|
doctorCommand,
|
|
6
7
|
getDefaultModel,
|
|
@@ -16,16 +17,169 @@ import {
|
|
|
16
17
|
statusCommand,
|
|
17
18
|
syncPiExtension,
|
|
18
19
|
syncPiModelsJson
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-5XGED4S4.js";
|
|
20
21
|
|
|
21
22
|
// src/cli.ts
|
|
22
23
|
import { Command } from "commander";
|
|
23
|
-
import
|
|
24
|
+
import pc3 from "picocolors";
|
|
24
25
|
|
|
25
|
-
// src/commands/
|
|
26
|
-
import
|
|
26
|
+
// src/commands/auto-fix.ts
|
|
27
|
+
import spawn from "cross-spawn";
|
|
27
28
|
import pc from "picocolors";
|
|
28
29
|
import { select } from "@inquirer/prompts";
|
|
30
|
+
var MAX_CAPTURE_LINES = 200;
|
|
31
|
+
async function autoFixCommand(cmdArgs) {
|
|
32
|
+
const rawCommand = cmdArgs.join(" ").trim();
|
|
33
|
+
if (!rawCommand) {
|
|
34
|
+
printBanner();
|
|
35
|
+
logWarn("\u8BF7\u63D0\u4F9B\u8981\u6267\u884C\u5E76\u76D1\u63A7\u7684\u547D\u4EE4\u3002");
|
|
36
|
+
console.log(` ${pc.bold("\u793A\u4F8B:")}`);
|
|
37
|
+
console.log(` ${pc.cyan('monk-pi run "npm run build"')}`);
|
|
38
|
+
console.log(` ${pc.cyan('monk-pi run "npm test"')}`);
|
|
39
|
+
console.log(` ${pc.cyan('monk-pi run "cargo check"')}`);
|
|
40
|
+
console.log(` ${pc.cyan('monk-pi run "go test ./..."')}`);
|
|
41
|
+
console.log();
|
|
42
|
+
return 1;
|
|
43
|
+
}
|
|
44
|
+
let { key } = resolveApiKey();
|
|
45
|
+
if (!key) {
|
|
46
|
+
printBanner();
|
|
47
|
+
logWarn("\u672A\u68C0\u6D4B\u5230 Monk API Key\uFF0C\u6B63\u5728\u4E3A\u60A8\u542F\u52A8\u9996\u6B21\u914D\u7F6E\u5F15\u5BFC...");
|
|
48
|
+
const ok = await loginCommand();
|
|
49
|
+
if (!ok) return 1;
|
|
50
|
+
key = resolveApiKey().key;
|
|
51
|
+
}
|
|
52
|
+
if (!key) {
|
|
53
|
+
logError("\u672A\u627E\u5230\u6709\u6548\u7684 Monk API Key\uFF0C\u9000\u51FA\u8FD0\u884C\u3002");
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
syncPiModelsJson(key);
|
|
57
|
+
syncPiExtension();
|
|
58
|
+
const defaultModel = getDefaultModel();
|
|
59
|
+
console.log(
|
|
60
|
+
` ${pc.cyan("\u26A1 Monk \u6B63\u5728\u76D1\u63A7\u6267\u884C:")} ${pc.bold(rawCommand)} ${pc.dim("(\u51FA\u9519\u5C06\u81EA\u52A8\u89E6\u53D1\u81EA\u6108\u5411\u5BFC)")}`
|
|
61
|
+
);
|
|
62
|
+
console.log(pc.dim("\u2500".repeat(56)));
|
|
63
|
+
const startTime = Date.now();
|
|
64
|
+
const capturedLines = [];
|
|
65
|
+
const child = spawn(rawCommand, {
|
|
66
|
+
shell: true,
|
|
67
|
+
stdio: ["inherit", "pipe", "pipe"]
|
|
68
|
+
});
|
|
69
|
+
child.stdout?.on("data", (chunk) => {
|
|
70
|
+
process.stdout.write(chunk);
|
|
71
|
+
const lines = chunk.toString("utf-8").split("\n");
|
|
72
|
+
for (const l of lines) {
|
|
73
|
+
if (l.trim()) capturedLines.push(l);
|
|
74
|
+
if (capturedLines.length > MAX_CAPTURE_LINES) capturedLines.shift();
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
child.stderr?.on("data", (chunk) => {
|
|
78
|
+
process.stderr.write(chunk);
|
|
79
|
+
const lines = chunk.toString("utf-8").split("\n");
|
|
80
|
+
for (const l of lines) {
|
|
81
|
+
if (l.trim()) capturedLines.push(l);
|
|
82
|
+
if (capturedLines.length > MAX_CAPTURE_LINES) capturedLines.shift();
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
const exitCode = await new Promise((resolve) => {
|
|
86
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
87
|
+
child.on("error", (err) => {
|
|
88
|
+
console.error(pc.red(`
|
|
89
|
+
\u6267\u884C\u8FDB\u7A0B\u5F02\u5E38: ${err.message}`));
|
|
90
|
+
resolve(1);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
const elapsed = ((Date.now() - startTime) / 1e3).toFixed(1);
|
|
94
|
+
console.log(pc.dim("\u2500".repeat(56)));
|
|
95
|
+
if (exitCode === 0) {
|
|
96
|
+
console.log(
|
|
97
|
+
` ${pc.green("\u2714")} \u547D\u4EE4\u6267\u884C\u6210\u529F ${pc.dim(`(\u8017\u65F6 ${elapsed}s)`)}\uFF0C\u5DE5\u4F5C\u533A\u6B63\u5E38\u3002`
|
|
98
|
+
);
|
|
99
|
+
console.log();
|
|
100
|
+
return 0;
|
|
101
|
+
}
|
|
102
|
+
console.log();
|
|
103
|
+
console.log(
|
|
104
|
+
` ${pc.red("\u2716")} \u547D\u4EE4\u6267\u884C\u5931\u8D25 ${pc.dim(`(\u9000\u51FA\u7801: ${exitCode} \xB7 \u8017\u65F6 ${elapsed}s)`)}`
|
|
105
|
+
);
|
|
106
|
+
console.log();
|
|
107
|
+
const capturedLog = capturedLines.join("\n").trim();
|
|
108
|
+
let action;
|
|
109
|
+
try {
|
|
110
|
+
action = await select({
|
|
111
|
+
message: "\u68C0\u6D4B\u5230\u547D\u4EE4\u62A5\u9519\uFF0C\u8BF7\u9009\u62E9 Monk \u4ECB\u5165\u5904\u7406\u65B9\u5F0F:",
|
|
112
|
+
choices: [
|
|
113
|
+
{
|
|
114
|
+
name: `1. \u547C\u53EB Monk \u5206\u6790\u62A5\u9519\u5E76\u81EA\u52A8\u4FEE\u590D\u4EE3\u7801 ${pc.green("(\u4E00\u952E\u81EA\u6108 Auto-Fix \xB7 \u63A8\u8350)")}`,
|
|
115
|
+
value: "autofix",
|
|
116
|
+
description: "AI \u5C06\u76F4\u63A5\u8BFB\u53D6\u62A5\u9519\u6E90\u7801\u3001\u81EA\u52A8\u7F16\u8F91\u4FEE\u590D\u5E76\u91CD\u65B0\u8FD0\u884C\u9A8C\u8BC1"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
name: "2. \u8FDB\u5165\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\u534F\u52A9\u6392\u67E5 (\u5E26\u5165\u62A5\u9519\u65E5\u5FD7)",
|
|
120
|
+
value: "interactive",
|
|
121
|
+
description: "\u5E26\u7740\u5B8C\u6574\u9519\u8BEF\u8F93\u51FA\u8FDB\u5165\u4EA4\u4E92\u5F0F\u4F1A\u8BDD\uFF0C\u81EA\u7531\u63D0\u95EE\u8BA8\u8BBA"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
name: "3. \u5FFD\u7565\u5E76\u76F4\u63A5\u9000\u51FA\u7EC8\u7AEF",
|
|
125
|
+
value: "exit",
|
|
126
|
+
description: "\u4FDD\u7559\u5F53\u524D\u73AF\u5883\u72B6\u6001\uFF0C\u76F4\u63A5\u9000\u51FA"
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
});
|
|
130
|
+
} catch {
|
|
131
|
+
return exitCode;
|
|
132
|
+
}
|
|
133
|
+
if (action === "exit") {
|
|
134
|
+
return exitCode;
|
|
135
|
+
}
|
|
136
|
+
if (action === "autofix") {
|
|
137
|
+
console.log();
|
|
138
|
+
logInfo("\u6B63\u5728\u62C9\u8D77 Monk Coding \u4E3B\u529B\u6A21\u578B\u6267\u884C\u81EA\u52A8\u4FEE\u590D\u5DE5\u4F5C\u6D41...");
|
|
139
|
+
console.log();
|
|
140
|
+
const autoFixPrompt = [
|
|
141
|
+
`\u6211\u521A\u624D\u5728\u7EC8\u7AEF\u6267\u884C\u547D\u4EE4 \`${rawCommand}\` \u5931\u8D25\uFF0C\u8FDB\u7A0B\u9000\u51FA\u7801\u4E3A ${exitCode}\u3002`,
|
|
142
|
+
"\u4EE5\u4E0B\u662F\u6267\u884C\u8FC7\u7A0B\u4E2D\u6355\u83B7\u7684\u5B8C\u6574\u62A5\u9519\u8F93\u51FA\uFF1A",
|
|
143
|
+
"```",
|
|
144
|
+
capturedLog,
|
|
145
|
+
"```",
|
|
146
|
+
"\u8BF7\u6309\u7167\u4EE5\u4E0B\u6B65\u9AA4\u4E3A\u6211\u8FDB\u884C\u4EE3\u7801\u81EA\u6108\uFF1A",
|
|
147
|
+
"1. \u4ED4\u7EC6\u9605\u8BFB\u62A5\u9519\u5806\u6808\uFF0C\u7CBE\u786E\u5B9A\u4F4D\u51FA\u95EE\u9898\u7684\u6E90\u6587\u4EF6\u4E0E\u9519\u8BEF\u6839\u56E0\uFF08\u5982\u7C7B\u578B\u4E0D\u5339\u914D\u3001\u8BED\u6CD5\u9519\u8BEF\u3001\u7F3A\u5931\u5BFC\u5165\u7B49\uFF09\u3002",
|
|
148
|
+
"2. \u8C03\u7528 read \u5DE5\u5177\u67E5\u9605\u76F8\u5173\u6587\u4EF6\u7684\u4EE3\u7801\u4E0A\u4E0B\u6587\u3002",
|
|
149
|
+
"3. \u8C03\u7528 edit \u5DE5\u5177\u76F4\u63A5\u5BF9\u4EE3\u7801\u8FDB\u884C\u7CBE\u786E\u4FEE\u590D\uFF08\u4E25\u7981\u7834\u574F\u5DF2\u6709\u4EE3\u7801\u67B6\u6784\uFF09\u3002",
|
|
150
|
+
`4. \u4FEE\u590D\u5B8C\u6210\u540E\uFF0C\u5728\u7EC8\u7AEF\u8C03\u7528 bash \u91CD\u65B0\u6267\u884C \`${rawCommand}\` \u9A8C\u8BC1\u662F\u5426\u5DF2\u5F7B\u5E95\u89E3\u51B3\u3002`,
|
|
151
|
+
"5. \u6700\u540E\u7B80\u77ED\u6C47\u62A5\u4FEE\u590D\u5185\u5BB9\u4E0E\u9A8C\u8BC1\u7ED3\u8BBA\u3002"
|
|
152
|
+
].join("\n");
|
|
153
|
+
return launchPi({
|
|
154
|
+
apiKey: key,
|
|
155
|
+
defaultModel,
|
|
156
|
+
passthroughArgs: [autoFixPrompt]
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
if (action === "interactive") {
|
|
160
|
+
console.log();
|
|
161
|
+
logInfo("\u6B63\u5728\u5E26\u7740\u9519\u8BEF\u4E0A\u4E0B\u6587\u8FDB\u5165\u4EA4\u4E92\u5F0F\u4F1A\u8BDD...");
|
|
162
|
+
console.log();
|
|
163
|
+
const interactivePrompt = [
|
|
164
|
+
`\u6267\u884C\u547D\u4EE4 \`${rawCommand}\` \u5931\u8D25 (\u9000\u51FA\u7801: ${exitCode})\uFF0C\u4EE5\u4E0B\u662F\u62A5\u9519\u65E5\u5FD7\uFF1A`,
|
|
165
|
+
"```",
|
|
166
|
+
capturedLog,
|
|
167
|
+
"```",
|
|
168
|
+
"\u8BF7\u5E2E\u6211\u5206\u6790\u6392\u67E5\u62A5\u9519\u539F\u56E0\u5E76\u7ED9\u51FA\u4FEE\u590D\u5EFA\u8BAE\u3002"
|
|
169
|
+
].join("\n");
|
|
170
|
+
return launchPi({
|
|
171
|
+
apiKey: key,
|
|
172
|
+
defaultModel,
|
|
173
|
+
passthroughArgs: [interactivePrompt]
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return exitCode;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// src/commands/resume.ts
|
|
180
|
+
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
181
|
+
import pc2 from "picocolors";
|
|
182
|
+
import { select as select2 } from "@inquirer/prompts";
|
|
29
183
|
function formatRelativeTime(date) {
|
|
30
184
|
const now = Date.now();
|
|
31
185
|
const diff = now - date.getTime();
|
|
@@ -89,7 +243,7 @@ async function resumeCommand(extraArgs = []) {
|
|
|
89
243
|
}
|
|
90
244
|
if (sessions.length === 0) {
|
|
91
245
|
logInfo("\u5F53\u524D\u9879\u76EE\u4E0B\u6682\u65E0\u5386\u53F2\u4F1A\u8BDD\u8BB0\u5F55\u3002");
|
|
92
|
-
console.log(` ${
|
|
246
|
+
console.log(` ${pc2.dim("\u6B63\u5728\u4E3A\u60A8\u5F00\u542F\u5168\u65B0\u4EA4\u4E92\u5F0F\u4F1A\u8BDD...")}`);
|
|
93
247
|
return launchPi({
|
|
94
248
|
apiKey: key,
|
|
95
249
|
defaultModel,
|
|
@@ -98,9 +252,9 @@ async function resumeCommand(extraArgs = []) {
|
|
|
98
252
|
}
|
|
99
253
|
sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
100
254
|
const choices = sessions.slice(0, 15).map((s) => {
|
|
101
|
-
const timeStr =
|
|
102
|
-
const titleStr = s.name ?
|
|
103
|
-
const countStr =
|
|
255
|
+
const timeStr = pc2.cyan(`[${formatRelativeTime(s.modified).padEnd(8)}]`);
|
|
256
|
+
const titleStr = s.name ? pc2.bold(pc2.yellow(s.name)) : formatPromptPreview(s.firstMessage);
|
|
257
|
+
const countStr = pc2.dim(`(${s.messageCount} \u6761\u5BF9\u8BDD)`);
|
|
104
258
|
return {
|
|
105
259
|
name: `${timeStr} ${titleStr} ${countStr}`,
|
|
106
260
|
value: s.path,
|
|
@@ -108,11 +262,11 @@ async function resumeCommand(extraArgs = []) {
|
|
|
108
262
|
};
|
|
109
263
|
});
|
|
110
264
|
choices.push({
|
|
111
|
-
name:
|
|
265
|
+
name: pc2.green("\u2795 [\u5F00\u542F\u5168\u65B0\u4F1A\u8BDD] (Start a fresh session)"),
|
|
112
266
|
value: "__NEW_SESSION__",
|
|
113
267
|
description: "\u4E0D\u52A0\u8F7D\u5386\u53F2\u8BB0\u5F55\uFF0C\u76F4\u63A5\u5F00\u59CB\u65B0\u4EFB\u52A1"
|
|
114
268
|
});
|
|
115
|
-
const selectedPath = await
|
|
269
|
+
const selectedPath = await select2({
|
|
116
270
|
message: "\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\u5386\u53F2\u4F1A\u8BDD (\u6309\u4FEE\u6539\u65F6\u95F4\u6392\u5E8F):",
|
|
117
271
|
choices,
|
|
118
272
|
pageSize: 10
|
|
@@ -142,12 +296,18 @@ var SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
142
296
|
"model",
|
|
143
297
|
"doctor",
|
|
144
298
|
"resume",
|
|
145
|
-
"history"
|
|
299
|
+
"history",
|
|
300
|
+
"run",
|
|
301
|
+
"exec"
|
|
146
302
|
]);
|
|
147
303
|
async function main() {
|
|
304
|
+
if (firstArg === "run" || firstArg === "exec") {
|
|
305
|
+
const exitCode2 = await autoFixCommand(rawArgs.slice(1));
|
|
306
|
+
process.exit(exitCode2);
|
|
307
|
+
}
|
|
148
308
|
if (firstArg && SUBCOMMANDS.has(firstArg)) {
|
|
149
309
|
const program = new Command();
|
|
150
|
-
program.name("monk-pi").description("Monk \xD7 Pi: \u6781\u901F\u9AD8\u6027\u4EF7\u6BD4 Coding Agent Harness").version(
|
|
310
|
+
program.name("monk-pi").description("Monk \xD7 Pi: \u6781\u901F\u9AD8\u6027\u4EF7\u6BD4 Coding Agent Harness").version(MONK_PI_VERSION);
|
|
151
311
|
program.command("login").alias("auth").description("\u914D\u7F6E\u6216\u66F4\u65B0 Monk API Key\uFF0C\u5E76\u81EA\u52A8\u540C\u6B65\u5230 Pi \u914D\u7F6E\u6587\u4EF6").action(async () => {
|
|
152
312
|
await loginCommand();
|
|
153
313
|
});
|
|
@@ -175,53 +335,62 @@ async function main() {
|
|
|
175
335
|
const exitCode2 = await runCommand(["--continue", ...rawArgs.slice(1)]);
|
|
176
336
|
process.exit(exitCode2);
|
|
177
337
|
}
|
|
338
|
+
if (firstArg === "run" || firstArg === "exec") {
|
|
339
|
+
const exitCode2 = await autoFixCommand(rawArgs.slice(1));
|
|
340
|
+
process.exit(exitCode2);
|
|
341
|
+
}
|
|
178
342
|
if (firstArg === "--help" || firstArg === "-h") {
|
|
179
343
|
printBanner();
|
|
180
|
-
console.log(` ${
|
|
181
|
-
console.log(` ${
|
|
182
|
-
console.log(` ${
|
|
344
|
+
console.log(` ${pc3.bold("\u7528\u6CD5:")}`);
|
|
345
|
+
console.log(` ${pc3.yellow("monk-pi")} \u8FDB\u5165\u4EA4\u4E92\u5F0F\u7F16\u7801\u6A21\u5F0F (\u9ED8\u8BA4\u4F7F\u7528 monk-coding)`);
|
|
346
|
+
console.log(` ${pc3.yellow("monk-pi")} [\u9009\u9879/\u63D0\u793A\u8BCD...] \u4F20\u9012\u6307\u4EE4\u6216\u6587\u4EF6\u7ED9 Pi`);
|
|
347
|
+
console.log();
|
|
348
|
+
console.log(` ${pc3.bold("\u793A\u4F8B:")}`);
|
|
349
|
+
console.log(` ${pc3.dim("# \u542F\u52A8\u4EA4\u4E92\u5F0F Agent")}`);
|
|
350
|
+
console.log(` ${pc3.cyan("monk-pi")}`);
|
|
183
351
|
console.log();
|
|
184
|
-
console.log(`
|
|
185
|
-
console.log(` ${
|
|
186
|
-
console.log(` ${pc2.cyan("monk-pi")}`);
|
|
352
|
+
console.log(` ${pc3.dim("# \u5E26\u521D\u59CB\u9700\u6C42\u8FDB\u5165\u4EA4\u4E92\u5F0F\u7EC8\u7AEF")}`);
|
|
353
|
+
console.log(` ${pc3.cyan('monk-pi "\u91CD\u6784\u8FD9\u4E2A\u76EE\u5F55\u4E0B\u7684\u4EE3\u7801"')}`);
|
|
187
354
|
console.log();
|
|
188
|
-
console.log(` ${
|
|
189
|
-
console.log(` ${
|
|
355
|
+
console.log(` ${pc3.dim("# \u975E\u4EA4\u4E92\u5F0F\u547D\u4EE4\u884C\u6A21\u5F0F (\u6253\u5370\u7ED3\u679C\u5E76\u9000\u51FA)")}`);
|
|
356
|
+
console.log(` ${pc3.cyan('monk-pi -p "\u89E3\u91CA\u5F53\u524D package.json \u7684\u4F9D\u8D56"')}`);
|
|
190
357
|
console.log();
|
|
191
|
-
console.log(` ${
|
|
192
|
-
console.log(` ${
|
|
358
|
+
console.log(` ${pc3.dim("# \u6307\u5B9A\u4F7F\u7528\u6781\u901F\u63A8\u7406\u6A21\u578B")}`);
|
|
359
|
+
console.log(` ${pc3.cyan('monk-pi --model monk-fast "\u5FEB\u901F\u5BA1\u67E5\u8FD9\u4E2A\u63D0\u4EA4"')}`);
|
|
193
360
|
console.log();
|
|
194
|
-
console.log(` ${
|
|
195
|
-
console.log(` ${
|
|
361
|
+
console.log(` ${pc3.dim("# \u6062\u590D\u4E0A\u4E00\u8F6E\u5386\u53F2\u4F1A\u8BDD")}`);
|
|
362
|
+
console.log(` ${pc3.cyan("monk-pi --continue (\u6216 monk-pi continue)")}`);
|
|
196
363
|
console.log();
|
|
197
|
-
console.log(` ${
|
|
198
|
-
console.log(` ${
|
|
364
|
+
console.log(` ${pc3.dim("# \u53EF\u89C6\u5316\u6D4F\u89C8\u5E76\u6062\u590D\u4EE5\u5F80\u5386\u53F2\u4EFB\u52A1")}`);
|
|
365
|
+
console.log(` ${pc3.cyan("monk-pi -r (\u6216 monk-pi resume)")}`);
|
|
199
366
|
console.log();
|
|
200
|
-
console.log(` ${
|
|
201
|
-
console.log(` ${
|
|
367
|
+
console.log(` ${pc3.dim("# \u76D1\u63A7\u547D\u4EE4\u8FD0\u884C\u5E76\u4EAB\u53D7\u62A5\u9519\u4E00\u952E\u81EA\u6108")}`);
|
|
368
|
+
console.log(` ${pc3.cyan('monk-pi run "npm run build"')}`);
|
|
369
|
+
console.log(` ${pc3.cyan('monk-pi run "npm test"')}`);
|
|
202
370
|
console.log();
|
|
203
|
-
console.log(` ${
|
|
204
|
-
console.log(` ${
|
|
205
|
-
console.log(` ${
|
|
206
|
-
console.log(` ${
|
|
207
|
-
console.log(` ${
|
|
208
|
-
console.log(` ${
|
|
371
|
+
console.log(` ${pc3.bold("\u4E13\u5C5E\u7BA1\u7406\u6307\u4EE4:")}`);
|
|
372
|
+
console.log(` ${pc3.yellow("monk-pi run <\u547D\u4EE4>")} \u76D1\u63A7\u547D\u4EE4\u8FD0\u884C\u5E76\u5728\u62A5\u9519\u65F6\u4E00\u952E\u547C\u53EB AI \u81EA\u6108\u4EE3\u7801 (Auto-Fix)`);
|
|
373
|
+
console.log(` ${pc3.yellow("monk-pi resume (\u6216 -r)")} \u53EF\u89C6\u5316\u6D4F\u89C8\u5E76\u6062\u590D\u5386\u53F2\u4F1A\u8BDD (\u65AD\u70B9\u7EED\u5199)`);
|
|
374
|
+
console.log(` ${pc3.yellow("monk-pi login")} \u914D\u7F6E / \u66F4\u65B0 Monk API Key`);
|
|
375
|
+
console.log(` ${pc3.yellow("monk-pi status")} \u68C0\u6D4B API \u5EF6\u8FDF\u3001Key \u72B6\u6001\u4E0E\u8FDE\u901A\u6027`);
|
|
376
|
+
console.log(` ${pc3.yellow("monk-pi model [name]")} \u67E5\u770B\u6216\u5207\u6362\u9ED8\u8BA4\u4E3B\u529B\u6A21\u578B`);
|
|
377
|
+
console.log(` ${pc3.yellow("monk-pi doctor")} \u4E00\u952E\u8BCA\u65AD\u73AF\u5883\u4F9D\u8D56\u4E0E\u517C\u5BB9\u914D\u7F6E`);
|
|
209
378
|
console.log();
|
|
210
|
-
console.log(` ${
|
|
211
|
-
console.log(` Monk \u5B98\u7F51: ${
|
|
212
|
-
console.log(` \u7528\u91CF\u67E5\u8BE2: ${
|
|
379
|
+
console.log(` ${pc3.bold("\u76F8\u5173\u94FE\u63A5:")}`);
|
|
380
|
+
console.log(` Monk \u5B98\u7F51: ${pc3.underline(pc3.cyan(MONK_WEBSITE))}`);
|
|
381
|
+
console.log(` \u7528\u91CF\u67E5\u8BE2: ${pc3.underline(pc3.cyan(MONK_ACCOUNT_URL))}`);
|
|
213
382
|
console.log();
|
|
214
383
|
return;
|
|
215
384
|
}
|
|
216
385
|
if (firstArg === "--version" || firstArg === "-v") {
|
|
217
|
-
console.log(
|
|
386
|
+
console.log(`monk-pi v${MONK_PI_VERSION}`);
|
|
218
387
|
return;
|
|
219
388
|
}
|
|
220
389
|
const exitCode = await runCommand(rawArgs);
|
|
221
390
|
process.exit(exitCode);
|
|
222
391
|
}
|
|
223
392
|
main().catch((err) => {
|
|
224
|
-
console.error(
|
|
393
|
+
console.error(pc3.red(`
|
|
225
394
|
[monk-pi \u5F02\u5E38]: ${err.message || err}
|
|
226
395
|
`));
|
|
227
396
|
process.exit(1);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
declare const MONK_BASE_URL = "https://monk.party/v1";
|
|
2
2
|
declare const MONK_WEBSITE = "https://monk.party";
|
|
3
3
|
declare const MONK_ACCOUNT_URL = "https://monk.party/account/";
|
|
4
|
+
declare const MONK_PI_VERSION = "0.11.0";
|
|
4
5
|
declare const MONK_MODELS: readonly [{
|
|
5
6
|
readonly id: "monk-coding";
|
|
6
7
|
readonly name: "Monk Coding (代码主力 - 推荐)";
|
|
@@ -165,4 +166,4 @@ declare function doctorCommand(): Promise<void>;
|
|
|
165
166
|
|
|
166
167
|
declare function runCommand(passthroughArgs: string[]): Promise<number>;
|
|
167
168
|
|
|
168
|
-
export { type CompletionTestResult, DEFAULT_MONK_MODEL, type LaunchPiOptions, MONK_ACCOUNT_URL, MONK_BASE_URL, MONK_MODELS, MONK_WEBSITE, type MonkLocalConfig, type MonkModelId, type PiBinaryType, type ResolvedPi, type ValidateResult, detectPackageManager, detectPi, doctorCommand, getDefaultModel, getMonkConfigFile, getMonkExtensionRaw, getMonkHomeDir, getPiExtensionsDir, getPiHomeDir, getPiModelsFile, getPiMonkExtensionFile, getPiSettingsFile, installPi, launchPi, loadMonkConfig, logError, logInfo, logStep, logSuccess, logWarn, loginCommand, maskKey, modelCommand, openBrowser, printBanner, promptForApiKey, promptInstallPi, promptSelectModel, resolveApiKey, resolvePiBinary, runCommand, saveMonkConfig, statusCommand, syncPiExtension, syncPiModelsJson, testChatCompletion, validateApiKey };
|
|
169
|
+
export { type CompletionTestResult, DEFAULT_MONK_MODEL, type LaunchPiOptions, MONK_ACCOUNT_URL, MONK_BASE_URL, MONK_MODELS, MONK_PI_VERSION, MONK_WEBSITE, type MonkLocalConfig, type MonkModelId, type PiBinaryType, type ResolvedPi, type ValidateResult, detectPackageManager, detectPi, doctorCommand, getDefaultModel, getMonkConfigFile, getMonkExtensionRaw, getMonkHomeDir, getPiExtensionsDir, getPiHomeDir, getPiModelsFile, getPiMonkExtensionFile, getPiSettingsFile, installPi, launchPi, loadMonkConfig, logError, logInfo, logStep, logSuccess, logWarn, loginCommand, maskKey, modelCommand, openBrowser, printBanner, promptForApiKey, promptInstallPi, promptSelectModel, resolveApiKey, resolvePiBinary, runCommand, saveMonkConfig, statusCommand, syncPiExtension, syncPiModelsJson, testChatCompletion, validateApiKey };
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
MONK_ACCOUNT_URL,
|
|
4
4
|
MONK_BASE_URL,
|
|
5
5
|
MONK_MODELS,
|
|
6
|
+
MONK_PI_VERSION,
|
|
6
7
|
MONK_WEBSITE,
|
|
7
8
|
detectPackageManager,
|
|
8
9
|
detectPi,
|
|
@@ -41,12 +42,13 @@ import {
|
|
|
41
42
|
syncPiModelsJson,
|
|
42
43
|
testChatCompletion,
|
|
43
44
|
validateApiKey
|
|
44
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-5XGED4S4.js";
|
|
45
46
|
export {
|
|
46
47
|
DEFAULT_MONK_MODEL,
|
|
47
48
|
MONK_ACCOUNT_URL,
|
|
48
49
|
MONK_BASE_URL,
|
|
49
50
|
MONK_MODELS,
|
|
51
|
+
MONK_PI_VERSION,
|
|
50
52
|
MONK_WEBSITE,
|
|
51
53
|
detectPackageManager,
|
|
52
54
|
detectPi,
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "monk-pi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Zero-config harness for running Pi Coding Agent with Monk API (monk.party)",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"bin":
|
|
6
|
+
"bin": {
|
|
7
|
+
"monk-pi": "./dist/cli.js"
|
|
8
|
+
},
|
|
7
9
|
"main": "./dist/index.js",
|
|
8
10
|
"types": "./dist/index.d.ts",
|
|
9
11
|
"files": [
|