monk-pi 0.2.0 → 0.10.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -3,19 +3,147 @@ import {
3
3
  MONK_ACCOUNT_URL,
4
4
  MONK_WEBSITE,
5
5
  doctorCommand,
6
+ getDefaultModel,
7
+ launchPi,
8
+ logError,
9
+ logInfo,
10
+ logWarn,
6
11
  loginCommand,
7
12
  modelCommand,
8
13
  printBanner,
14
+ resolveApiKey,
9
15
  runCommand,
10
- statusCommand
11
- } from "./chunk-6OMOTI3T.js";
16
+ statusCommand,
17
+ syncPiExtension,
18
+ syncPiModelsJson
19
+ } from "./chunk-GGAUER4O.js";
12
20
 
13
21
  // src/cli.ts
14
22
  import { Command } from "commander";
23
+ import pc2 from "picocolors";
24
+
25
+ // src/commands/resume.ts
26
+ import { SessionManager } from "@earendil-works/pi-coding-agent";
15
27
  import pc from "picocolors";
28
+ import { select } from "@inquirer/prompts";
29
+ function formatRelativeTime(date) {
30
+ const now = Date.now();
31
+ const diff = now - date.getTime();
32
+ if (diff < 60 * 1e3) return "\u521A\u521A";
33
+ if (diff < 60 * 60 * 1e3) return `${Math.floor(diff / (60 * 1e3))} \u5206\u949F\u524D`;
34
+ if (diff < 24 * 60 * 60 * 1e3) return `${Math.floor(diff / (60 * 60 * 1e3))} \u5C0F\u65F6\u524D`;
35
+ if (diff < 48 * 60 * 60 * 1e3) {
36
+ const hours2 = String(date.getHours()).padStart(2, "0");
37
+ const mins2 = String(date.getMinutes()).padStart(2, "0");
38
+ return `\u6628\u5929 ${hours2}:${mins2}`;
39
+ }
40
+ if (diff < 7 * 24 * 60 * 60 * 1e3) {
41
+ return `${Math.floor(diff / (24 * 60 * 60 * 1e3))} \u5929\u524D`;
42
+ }
43
+ const m = String(date.getMonth() + 1).padStart(2, "0");
44
+ const d = String(date.getDate()).padStart(2, "0");
45
+ const hours = String(date.getHours()).padStart(2, "0");
46
+ const mins = String(date.getMinutes()).padStart(2, "0");
47
+ return `${m}-${d} ${hours}:${mins}`;
48
+ }
49
+ function formatPromptPreview(text) {
50
+ if (!text) return "\uFF08\u7A7A\u767D\u521D\u59CB\u4F1A\u8BDD\uFF09";
51
+ const clean = text.replace(/\s+/g, " ").trim();
52
+ if (clean.length <= 36) return clean;
53
+ return `${clean.slice(0, 36)}...`;
54
+ }
55
+ async function resumeCommand(extraArgs = []) {
56
+ printBanner();
57
+ let { key } = resolveApiKey();
58
+ if (!key) {
59
+ logWarn("\u672A\u68C0\u6D4B\u5230 Monk API Key\uFF0C\u6B63\u5728\u4E3A\u60A8\u542F\u52A8\u9996\u6B21\u914D\u7F6E\u5F15\u5BFC...");
60
+ const ok = await loginCommand();
61
+ if (!ok) return 1;
62
+ key = resolveApiKey().key;
63
+ }
64
+ if (!key) {
65
+ logError("\u672A\u627E\u5230\u6709\u6548\u7684 Monk API Key\uFF0C\u9000\u51FA\u8FD0\u884C\u3002");
66
+ return 1;
67
+ }
68
+ syncPiModelsJson(key);
69
+ syncPiExtension();
70
+ const defaultModel = getDefaultModel();
71
+ const cwd = process.cwd();
72
+ let sessions = [];
73
+ try {
74
+ const list = await SessionManager.list(cwd);
75
+ sessions = list.map((s) => ({
76
+ path: s.path,
77
+ id: s.id,
78
+ name: s.name,
79
+ modified: s.modified ? new Date(s.modified) : /* @__PURE__ */ new Date(),
80
+ messageCount: s.messageCount ?? 0,
81
+ firstMessage: s.firstMessage
82
+ }));
83
+ } catch {
84
+ return launchPi({
85
+ apiKey: key,
86
+ defaultModel,
87
+ passthroughArgs: ["--resume", ...extraArgs]
88
+ });
89
+ }
90
+ if (sessions.length === 0) {
91
+ logInfo("\u5F53\u524D\u9879\u76EE\u4E0B\u6682\u65E0\u5386\u53F2\u4F1A\u8BDD\u8BB0\u5F55\u3002");
92
+ console.log(` ${pc.dim("\u6B63\u5728\u4E3A\u60A8\u5F00\u542F\u5168\u65B0\u4EA4\u4E92\u5F0F\u4F1A\u8BDD...")}`);
93
+ return launchPi({
94
+ apiKey: key,
95
+ defaultModel,
96
+ passthroughArgs: extraArgs
97
+ });
98
+ }
99
+ sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
100
+ const choices = sessions.slice(0, 15).map((s) => {
101
+ const timeStr = pc.cyan(`[${formatRelativeTime(s.modified).padEnd(8)}]`);
102
+ const titleStr = s.name ? pc.bold(pc.yellow(s.name)) : formatPromptPreview(s.firstMessage);
103
+ const countStr = pc.dim(`(${s.messageCount} \u6761\u5BF9\u8BDD)`);
104
+ return {
105
+ name: `${timeStr} ${titleStr} ${countStr}`,
106
+ value: s.path,
107
+ description: s.firstMessage || s.name || "\u672A\u547D\u540D\u4F1A\u8BDD"
108
+ };
109
+ });
110
+ choices.push({
111
+ name: pc.green("\u2795 [\u5F00\u542F\u5168\u65B0\u4F1A\u8BDD] (Start a fresh session)"),
112
+ value: "__NEW_SESSION__",
113
+ description: "\u4E0D\u52A0\u8F7D\u5386\u53F2\u8BB0\u5F55\uFF0C\u76F4\u63A5\u5F00\u59CB\u65B0\u4EFB\u52A1"
114
+ });
115
+ const selectedPath = await select({
116
+ message: "\u8BF7\u9009\u62E9\u8981\u6062\u590D\u7684\u5386\u53F2\u4F1A\u8BDD (\u6309\u4FEE\u6539\u65F6\u95F4\u6392\u5E8F):",
117
+ choices,
118
+ pageSize: 10
119
+ });
120
+ if (selectedPath === "__NEW_SESSION__") {
121
+ return launchPi({
122
+ apiKey: key,
123
+ defaultModel,
124
+ passthroughArgs: extraArgs
125
+ });
126
+ }
127
+ return launchPi({
128
+ apiKey: key,
129
+ defaultModel,
130
+ passthroughArgs: ["--session", selectedPath, ...extraArgs]
131
+ });
132
+ }
133
+
134
+ // src/cli.ts
16
135
  var rawArgs = process.argv.slice(2);
17
136
  var firstArg = rawArgs[0];
18
- var SUBCOMMANDS = /* @__PURE__ */ new Set(["login", "auth", "status", "check", "model", "doctor"]);
137
+ var SUBCOMMANDS = /* @__PURE__ */ new Set([
138
+ "login",
139
+ "auth",
140
+ "status",
141
+ "check",
142
+ "model",
143
+ "doctor",
144
+ "resume",
145
+ "history"
146
+ ]);
19
147
  async function main() {
20
148
  if (firstArg && SUBCOMMANDS.has(firstArg)) {
21
149
  const program = new Command();
@@ -32,40 +160,56 @@ async function main() {
32
160
  program.command("doctor").description("\u5168\u9762\u8BCA\u65AD\u73AF\u5883\u3001Node \u7248\u672C\u3001Pi \u6838\u5FC3\u53CA\u7F51\u7EDC\u517C\u5BB9\u6027").action(async () => {
33
161
  await doctorCommand();
34
162
  });
163
+ program.command("resume").alias("history").description("\u53EF\u89C6\u5316\u6D4F\u89C8\u5E76\u6062\u590D\u5386\u53F2\u4F1A\u8BDD (\u65AD\u70B9\u7EED\u5199)").action(async () => {
164
+ const exitCode2 = await resumeCommand(rawArgs.slice(1));
165
+ process.exit(exitCode2);
166
+ });
35
167
  await program.parseAsync(process.argv);
36
168
  return;
37
169
  }
170
+ if (firstArg === "-r" || firstArg === "--resume") {
171
+ const exitCode2 = await resumeCommand(rawArgs.slice(1));
172
+ process.exit(exitCode2);
173
+ }
174
+ if (firstArg === "continue") {
175
+ const exitCode2 = await runCommand(["--continue", ...rawArgs.slice(1)]);
176
+ process.exit(exitCode2);
177
+ }
38
178
  if (firstArg === "--help" || firstArg === "-h") {
39
179
  printBanner();
40
- console.log(` ${pc.bold("\u7528\u6CD5:")}`);
41
- console.log(` ${pc.yellow("monk-pi")} \u8FDB\u5165\u4EA4\u4E92\u5F0F\u7F16\u7801\u6A21\u5F0F (\u9ED8\u8BA4\u4F7F\u7528 monk-coding)`);
42
- console.log(` ${pc.yellow("monk-pi")} [\u9009\u9879/\u63D0\u793A\u8BCD...] \u4F20\u9012\u6307\u4EE4\u6216\u6587\u4EF6\u7ED9 Pi`);
180
+ console.log(` ${pc2.bold("\u7528\u6CD5:")}`);
181
+ console.log(` ${pc2.yellow("monk-pi")} \u8FDB\u5165\u4EA4\u4E92\u5F0F\u7F16\u7801\u6A21\u5F0F (\u9ED8\u8BA4\u4F7F\u7528 monk-coding)`);
182
+ console.log(` ${pc2.yellow("monk-pi")} [\u9009\u9879/\u63D0\u793A\u8BCD...] \u4F20\u9012\u6307\u4EE4\u6216\u6587\u4EF6\u7ED9 Pi`);
183
+ console.log();
184
+ console.log(` ${pc2.bold("\u793A\u4F8B:")}`);
185
+ console.log(` ${pc2.dim("# \u542F\u52A8\u4EA4\u4E92\u5F0F Agent")}`);
186
+ console.log(` ${pc2.cyan("monk-pi")}`);
43
187
  console.log();
44
- console.log(` ${pc.bold("\u793A\u4F8B:")}`);
45
- console.log(` ${pc.dim("# \u542F\u52A8\u4EA4\u4E92\u5F0F Agent")}`);
46
- console.log(` ${pc.cyan("monk-pi")}`);
188
+ console.log(` ${pc2.dim("# \u5E26\u521D\u59CB\u9700\u6C42\u8FDB\u5165\u4EA4\u4E92\u5F0F\u7EC8\u7AEF")}`);
189
+ console.log(` ${pc2.cyan('monk-pi "\u91CD\u6784\u8FD9\u4E2A\u76EE\u5F55\u4E0B\u7684\u4EE3\u7801"')}`);
47
190
  console.log();
48
- console.log(` ${pc.dim("# \u5E26\u521D\u59CB\u9700\u6C42\u8FDB\u5165\u4EA4\u4E92\u5F0F\u7EC8\u7AEF")}`);
49
- console.log(` ${pc.cyan('monk-pi "\u91CD\u6784\u8FD9\u4E2A\u76EE\u5F55\u4E0B\u7684\u4EE3\u7801"')}`);
191
+ console.log(` ${pc2.dim("# \u975E\u4EA4\u4E92\u5F0F\u547D\u4EE4\u884C\u6A21\u5F0F (\u6253\u5370\u7ED3\u679C\u5E76\u9000\u51FA)")}`);
192
+ console.log(` ${pc2.cyan('monk-pi -p "\u89E3\u91CA\u5F53\u524D package.json \u7684\u4F9D\u8D56"')}`);
50
193
  console.log();
51
- console.log(` ${pc.dim("# \u975E\u4EA4\u4E92\u5F0F\u547D\u4EE4\u884C\u6A21\u5F0F (\u6253\u5370\u7ED3\u679C\u5E76\u9000\u51FA)")}`);
52
- console.log(` ${pc.cyan('monk-pi -p "\u89E3\u91CA\u5F53\u524D package.json \u7684\u4F9D\u8D56"')}`);
194
+ console.log(` ${pc2.dim("# \u6307\u5B9A\u4F7F\u7528\u6781\u901F\u63A8\u7406\u6A21\u578B")}`);
195
+ console.log(` ${pc2.cyan('monk-pi --model monk-fast "\u5FEB\u901F\u5BA1\u67E5\u8FD9\u4E2A\u63D0\u4EA4"')}`);
53
196
  console.log();
54
- console.log(` ${pc.dim("# \u6307\u5B9A\u4F7F\u7528\u6781\u901F\u63A8\u7406\u6A21\u578B")}`);
55
- console.log(` ${pc.cyan('monk-pi --model monk-fast "\u5FEB\u901F\u5BA1\u67E5\u8FD9\u4E2A\u63D0\u4EA4"')}`);
197
+ console.log(` ${pc2.dim("# \u6062\u590D\u4E0A\u4E00\u8F6E\u5386\u53F2\u4F1A\u8BDD")}`);
198
+ console.log(` ${pc2.cyan("monk-pi --continue (\u6216 monk-pi continue)")}`);
56
199
  console.log();
57
- console.log(` ${pc.dim("# \u6062\u590D\u4E0A\u4E00\u8F6E\u5386\u53F2\u4F1A\u8BDD")}`);
58
- console.log(` ${pc.cyan("monk-pi --continue")}`);
200
+ console.log(` ${pc2.dim("# \u53EF\u89C6\u5316\u6D4F\u89C8\u5E76\u6062\u590D\u4EE5\u5F80\u5386\u53F2\u4EFB\u52A1")}`);
201
+ console.log(` ${pc2.cyan("monk-pi -r (\u6216 monk-pi resume)")}`);
59
202
  console.log();
60
- console.log(` ${pc.bold("\u4E13\u5C5E\u7BA1\u7406\u6307\u4EE4:")}`);
61
- console.log(` ${pc.yellow("monk-pi login")} \u914D\u7F6E / \u66F4\u65B0 Monk API Key`);
62
- console.log(` ${pc.yellow("monk-pi status")} \u68C0\u6D4B API \u5EF6\u8FDF\u3001Key \u72B6\u6001\u4E0E\u8FDE\u901A\u6027`);
63
- console.log(` ${pc.yellow("monk-pi model [name]")} \u67E5\u770B\u6216\u5207\u6362\u9ED8\u8BA4\u4E3B\u529B\u6A21\u578B`);
64
- console.log(` ${pc.yellow("monk-pi doctor")} \u4E00\u952E\u8BCA\u65AD\u73AF\u5883\u4F9D\u8D56\u4E0E\u517C\u5BB9\u914D\u7F6E`);
203
+ console.log(` ${pc2.bold("\u4E13\u5C5E\u7BA1\u7406\u6307\u4EE4:")}`);
204
+ console.log(` ${pc2.yellow("monk-pi resume (\u6216 -r)")} \u53EF\u89C6\u5316\u6D4F\u89C8\u5E76\u6062\u590D\u5386\u53F2\u4F1A\u8BDD (\u65AD\u70B9\u7EED\u5199)`);
205
+ console.log(` ${pc2.yellow("monk-pi login")} \u914D\u7F6E / \u66F4\u65B0 Monk API Key`);
206
+ console.log(` ${pc2.yellow("monk-pi status")} \u68C0\u6D4B API \u5EF6\u8FDF\u3001Key \u72B6\u6001\u4E0E\u8FDE\u901A\u6027`);
207
+ console.log(` ${pc2.yellow("monk-pi model [name]")} \u67E5\u770B\u6216\u5207\u6362\u9ED8\u8BA4\u4E3B\u529B\u6A21\u578B`);
208
+ console.log(` ${pc2.yellow("monk-pi doctor")} \u4E00\u952E\u8BCA\u65AD\u73AF\u5883\u4F9D\u8D56\u4E0E\u517C\u5BB9\u914D\u7F6E`);
65
209
  console.log();
66
- console.log(` ${pc.bold("\u76F8\u5173\u94FE\u63A5:")}`);
67
- console.log(` Monk \u5B98\u7F51: ${pc.underline(pc.cyan(MONK_WEBSITE))}`);
68
- console.log(` \u7528\u91CF\u67E5\u8BE2: ${pc.underline(pc.cyan(MONK_ACCOUNT_URL))}`);
210
+ console.log(` ${pc2.bold("\u76F8\u5173\u94FE\u63A5:")}`);
211
+ console.log(` Monk \u5B98\u7F51: ${pc2.underline(pc2.cyan(MONK_WEBSITE))}`);
212
+ console.log(` \u7528\u91CF\u67E5\u8BE2: ${pc2.underline(pc2.cyan(MONK_ACCOUNT_URL))}`);
69
213
  console.log();
70
214
  return;
71
215
  }
@@ -77,7 +221,7 @@ async function main() {
77
221
  process.exit(exitCode);
78
222
  }
79
223
  main().catch((err) => {
80
- console.error(pc.red(`
224
+ console.error(pc2.red(`
81
225
  [monk-pi \u5F02\u5E38]: ${err.message || err}
82
226
  `));
83
227
  process.exit(1);
package/dist/index.d.ts CHANGED
@@ -58,12 +58,17 @@ declare function syncPiModelsJson(apiKey?: string): {
58
58
  path: string;
59
59
  error?: string;
60
60
  };
61
+ /**
62
+ * Resolves the raw source code of monk-extension.ts cleanly from dist or src
63
+ */
64
+ declare function getMonkExtensionRaw(): string;
61
65
  /**
62
66
  * Safely writes or updates the Monk native extension in ~/.pi/agent/extensions/monk.ts
63
67
  */
64
- declare function syncPiExtension(): {
68
+ declare function syncPiExtension(force?: boolean): {
65
69
  success: boolean;
66
70
  path: string;
71
+ updated: boolean;
67
72
  error?: string;
68
73
  };
69
74
  /**
@@ -129,6 +134,7 @@ interface LaunchPiOptions {
129
134
  */
130
135
  declare function launchPi(options: LaunchPiOptions): number;
131
136
 
137
+ declare function openBrowser(url: string): boolean;
132
138
  declare function printBanner(): void;
133
139
  declare function logSuccess(msg: string): void;
134
140
  declare function logInfo(msg: string): void;
@@ -136,7 +142,7 @@ declare function logWarn(msg: string): void;
136
142
  declare function logError(msg: string): void;
137
143
  declare function logStep(step: number, total: number, msg: string): void;
138
144
  /**
139
- * Interactive prompt for API Key
145
+ * Interactive prompt for API Key with one-click browser checkout option
140
146
  */
141
147
  declare function promptForApiKey(currentKey?: string): Promise<string>;
142
148
  /**
@@ -159,4 +165,4 @@ declare function doctorCommand(): Promise<void>;
159
165
 
160
166
  declare function runCommand(passthroughArgs: string[]): Promise<number>;
161
167
 
162
- 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, getMonkHomeDir, getPiExtensionsDir, getPiHomeDir, getPiModelsFile, getPiMonkExtensionFile, getPiSettingsFile, installPi, launchPi, loadMonkConfig, logError, logInfo, logStep, logSuccess, logWarn, loginCommand, maskKey, modelCommand, printBanner, promptForApiKey, promptInstallPi, promptSelectModel, resolveApiKey, resolvePiBinary, runCommand, saveMonkConfig, statusCommand, syncPiExtension, syncPiModelsJson, testChatCompletion, validateApiKey };
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 };
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import {
9
9
  doctorCommand,
10
10
  getDefaultModel,
11
11
  getMonkConfigFile,
12
+ getMonkExtensionRaw,
12
13
  getMonkHomeDir,
13
14
  getPiExtensionsDir,
14
15
  getPiHomeDir,
@@ -26,6 +27,7 @@ import {
26
27
  loginCommand,
27
28
  maskKey,
28
29
  modelCommand,
30
+ openBrowser,
29
31
  printBanner,
30
32
  promptForApiKey,
31
33
  promptInstallPi,
@@ -39,7 +41,7 @@ import {
39
41
  syncPiModelsJson,
40
42
  testChatCompletion,
41
43
  validateApiKey
42
- } from "./chunk-6OMOTI3T.js";
44
+ } from "./chunk-GGAUER4O.js";
43
45
  export {
44
46
  DEFAULT_MONK_MODEL,
45
47
  MONK_ACCOUNT_URL,
@@ -51,6 +53,7 @@ export {
51
53
  doctorCommand,
52
54
  getDefaultModel,
53
55
  getMonkConfigFile,
56
+ getMonkExtensionRaw,
54
57
  getMonkHomeDir,
55
58
  getPiExtensionsDir,
56
59
  getPiHomeDir,
@@ -68,6 +71,7 @@ export {
68
71
  loginCommand,
69
72
  maskKey,
70
73
  modelCommand,
74
+ openBrowser,
71
75
  printBanner,
72
76
  promptForApiKey,
73
77
  promptInstallPi,