@wukonglabs/wukong 0.0.8 → 0.0.10
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/exit-codes.js +12 -16
- package/dist/cli/exit-codes.js.map +1 -1
- package/dist/cli/help.d.ts.map +1 -1
- package/dist/cli/help.js +10 -9
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/session-commands.d.ts +28 -0
- package/dist/cli/session-commands.d.ts.map +1 -0
- package/dist/cli/session-commands.js +274 -0
- package/dist/cli/session-commands.js.map +1 -0
- package/dist/cli/summary.js +2 -6
- package/dist/cli/summary.js.map +1 -1
- package/dist/cli/workspace-commands.d.ts +15 -0
- package/dist/cli/workspace-commands.d.ts.map +1 -0
- package/dist/cli/workspace-commands.js +98 -0
- package/dist/cli/workspace-commands.js.map +1 -0
- package/dist/index.js +429 -131
- package/dist/index.js.map +1 -1
- package/dist/sigint-handler.d.ts +62 -0
- package/dist/sigint-handler.d.ts.map +1 -0
- package/dist/sigint-handler.js +62 -0
- package/dist/sigint-handler.js.map +1 -0
- package/dist/tui/app.d.ts +57 -0
- package/dist/tui/app.d.ts.map +1 -0
- package/dist/tui/app.js +194 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/header.d.ts +24 -0
- package/dist/tui/header.d.ts.map +1 -0
- package/dist/tui/header.js +26 -0
- package/dist/tui/header.js.map +1 -0
- package/dist/tui/permission-card.d.ts +27 -0
- package/dist/tui/permission-card.d.ts.map +1 -0
- package/dist/tui/permission-card.js +75 -0
- package/dist/tui/permission-card.js.map +1 -0
- package/dist/tui/plan-panel.d.ts +29 -0
- package/dist/tui/plan-panel.d.ts.map +1 -0
- package/dist/tui/plan-panel.js +26 -0
- package/dist/tui/plan-panel.js.map +1 -0
- package/dist/tui/response-panel.d.ts +49 -0
- package/dist/tui/response-panel.d.ts.map +1 -0
- package/dist/tui/response-panel.js +13 -0
- package/dist/tui/response-panel.js.map +1 -0
- package/dist/tui/run-ink.d.ts +22 -0
- package/dist/tui/run-ink.d.ts.map +1 -0
- package/dist/tui/run-ink.js +31 -0
- package/dist/tui/run-ink.js.map +1 -0
- package/dist/tui/should-use-tui.d.ts +25 -0
- package/dist/tui/should-use-tui.d.ts.map +1 -0
- package/dist/tui/should-use-tui.js +29 -0
- package/dist/tui/should-use-tui.js.map +1 -0
- package/dist/tui/text-input.d.ts +52 -0
- package/dist/tui/text-input.d.ts.map +1 -0
- package/dist/tui/text-input.js +321 -0
- package/dist/tui/text-input.js.map +1 -0
- package/dist/tui/thinking-panel.d.ts +40 -0
- package/dist/tui/thinking-panel.d.ts.map +1 -0
- package/dist/tui/thinking-panel.js +54 -0
- package/dist/tui/thinking-panel.js.map +1 -0
- package/dist/tui/tool-cards.d.ts +30 -0
- package/dist/tui/tool-cards.d.ts.map +1 -0
- package/dist/tui/tool-cards.js +34 -0
- package/dist/tui/tool-cards.js.map +1 -0
- package/dist/tui/use-input-history.d.ts +40 -0
- package/dist/tui/use-input-history.d.ts.map +1 -0
- package/dist/tui/use-input-history.js +123 -0
- package/dist/tui/use-input-history.js.map +1 -0
- package/dist/tui/use-plan-state.d.ts +4 -0
- package/dist/tui/use-plan-state.d.ts.map +1 -0
- package/dist/tui/use-plan-state.js +73 -0
- package/dist/tui/use-plan-state.js.map +1 -0
- package/package.json +7 -2
package/dist/cli/exit-codes.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Wukong CLI 语义化退出码
|
|
4
3
|
*
|
|
@@ -9,10 +8,7 @@
|
|
|
9
8
|
* - 3: LLM 调用失败
|
|
10
9
|
* - 4: 配置/参数错误
|
|
11
10
|
*/
|
|
12
|
-
|
|
13
|
-
exports.EXIT_CODE_DESCRIPTIONS = exports.EXIT_CODES = void 0;
|
|
14
|
-
exports.resolveExitCode = resolveExitCode;
|
|
15
|
-
exports.EXIT_CODES = {
|
|
11
|
+
export const EXIT_CODES = {
|
|
16
12
|
/** 任务成功完成(验证通过或无需验证) */
|
|
17
13
|
SUCCESS: 0,
|
|
18
14
|
/** 任务完成但验证失败(编辑已保存,但 test/lint 未通过) */
|
|
@@ -25,29 +21,29 @@ exports.EXIT_CODES = {
|
|
|
25
21
|
CONFIG_ERROR: 4,
|
|
26
22
|
};
|
|
27
23
|
/** 退出码的人类可读描述 */
|
|
28
|
-
|
|
29
|
-
[
|
|
30
|
-
[
|
|
31
|
-
[
|
|
32
|
-
[
|
|
33
|
-
[
|
|
24
|
+
export const EXIT_CODE_DESCRIPTIONS = {
|
|
25
|
+
[EXIT_CODES.SUCCESS]: 'Task completed successfully',
|
|
26
|
+
[EXIT_CODES.VERIFY_FAILED]: 'Task completed but verification failed',
|
|
27
|
+
[EXIT_CODES.TASK_INCOMPLETE]: 'Task not completed (max steps reached or aborted)',
|
|
28
|
+
[EXIT_CODES.LLM_ERROR]: 'LLM API call failed after retries',
|
|
29
|
+
[EXIT_CODES.CONFIG_ERROR]: 'Configuration or argument error',
|
|
34
30
|
};
|
|
35
31
|
/**
|
|
36
32
|
* 从 AgentResult 推断退出码
|
|
37
33
|
*/
|
|
38
|
-
function resolveExitCode(result) {
|
|
34
|
+
export function resolveExitCode(result) {
|
|
39
35
|
// LLM 错误导致中止
|
|
40
36
|
if (result.aborted) {
|
|
41
|
-
return
|
|
37
|
+
return EXIT_CODES.LLM_ERROR;
|
|
42
38
|
}
|
|
43
39
|
// 达到最大步数 → 任务未完成
|
|
44
40
|
if (result.maxSteps && result.steps >= result.maxSteps) {
|
|
45
|
-
return
|
|
41
|
+
return EXIT_CODES.TASK_INCOMPLETE;
|
|
46
42
|
}
|
|
47
43
|
// 有验证结果且验证失败
|
|
48
44
|
if (result.verificationPassed === false) {
|
|
49
|
-
return
|
|
45
|
+
return EXIT_CODES.VERIFY_FAILED;
|
|
50
46
|
}
|
|
51
|
-
return
|
|
47
|
+
return EXIT_CODES.SUCCESS;
|
|
52
48
|
}
|
|
53
49
|
//# sourceMappingURL=exit-codes.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/cli/exit-codes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"exit-codes.js","sourceRoot":"","sources":["../../src/cli/exit-codes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,wBAAwB;IACxB,OAAO,EAAE,CAAC;IACV,uCAAuC;IACvC,aAAa,EAAE,CAAC;IAChB,qCAAqC;IACrC,eAAe,EAAE,CAAC;IAClB,8BAA8B;IAC9B,SAAS,EAAE,CAAC;IACZ,mCAAmC;IACnC,YAAY,EAAE,CAAC;CACP,CAAC;AAIX,iBAAiB;AACjB,MAAM,CAAC,MAAM,sBAAsB,GAA6B;IAC9D,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,6BAA6B;IACnD,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,wCAAwC;IACpE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,mDAAmD;IACjF,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,mCAAmC;IAC3D,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,iCAAiC;CAC7D,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,MAK/B;IACC,aAAa;IACb,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,UAAU,CAAC,SAAS,CAAC;IAC9B,CAAC;IAED,iBAAiB;IACjB,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;QACvD,OAAO,UAAU,CAAC,eAAe,CAAC;IACpC,CAAC;IAED,aAAa;IACb,IAAI,MAAM,CAAC,kBAAkB,KAAK,KAAK,EAAE,CAAC;QACxC,OAAO,UAAU,CAAC,aAAa,CAAC;IAClC,CAAC;IAED,OAAO,UAAU,CAAC,OAAO,CAAC;AAC5B,CAAC"}
|
package/dist/cli/help.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,eAAO,MAAM,SAAS,
|
|
1
|
+
{"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,eAAO,MAAM,SAAS,QA+Ed,CAAC;AAET;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
package/dist/cli/help.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Wukong CLI 帮助文本
|
|
4
3
|
*
|
|
5
4
|
* 提供 --help 和 --version 的格式化输出
|
|
6
5
|
*/
|
|
7
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
-
exports.HELP_TEXT = exports.VERSION = void 0;
|
|
9
|
-
exports.formatVersion = formatVersion;
|
|
10
6
|
// 从 package.json 中读取版本号在编译时不可靠,硬编码并在发布时更新
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
export const VERSION = '1.0.0';
|
|
8
|
+
export const HELP_TEXT = `
|
|
13
9
|
Wukong (悟空) — CI-First AI Agent CLI
|
|
14
10
|
================================
|
|
15
11
|
|
|
@@ -19,12 +15,17 @@ Wukong (悟空) — CI-First AI Agent CLI
|
|
|
19
15
|
|
|
20
16
|
命令:
|
|
21
17
|
agent 一次性执行模式(CI/CD 推荐)
|
|
18
|
+
session 管理会话(list/show/rm/switch/rename,详见 \`wukong session --help\`)
|
|
19
|
+
workspace 管理已知 workspace(list/rm,详见 \`wukong workspace --help\`)
|
|
22
20
|
(无命令) 进入交互式对话模式
|
|
23
21
|
|
|
24
22
|
核心选项:
|
|
25
23
|
-m, --message <text> 任务描述(agent 模式必填)
|
|
26
24
|
-sp, --system-prompt <text> 自定义 system prompt
|
|
27
|
-
-
|
|
25
|
+
-c, --continue 续接当前 workspace 最近一次会话(交互模式默认)
|
|
26
|
+
-n, --new 强制新开一条会话(CI 模式默认)
|
|
27
|
+
-s, --session-id <uuid> 精确指定要恢复的 session uuid
|
|
28
|
+
(三者互斥;不指定时:交互模式续接、CI 模式新开)
|
|
28
29
|
--json JSON 格式输出(CI 推荐)
|
|
29
30
|
--trace JSON 输出中包含详细 trace(默认省略)
|
|
30
31
|
-y, --yes 跳过所有确认(CI 推荐)
|
|
@@ -87,7 +88,7 @@ CI/CD 推荐用法:
|
|
|
87
88
|
/**
|
|
88
89
|
* 格式化版本字符串
|
|
89
90
|
*/
|
|
90
|
-
function formatVersion() {
|
|
91
|
-
return `wukong v${
|
|
91
|
+
export function formatVersion() {
|
|
92
|
+
return `wukong v${VERSION}`;
|
|
92
93
|
}
|
|
93
94
|
//# sourceMappingURL=help.js.map
|
package/dist/cli/help.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,0CAA0C;AAC1C,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,MAAM,CAAC,MAAM,SAAS,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+ExB,CAAC,IAAI,EAAE,CAAC;AAET;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,WAAW,OAAO,EAAE,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `wukong session` 子命令实现。
|
|
3
|
+
*
|
|
4
|
+
* 消费 SessionManager 暴露的 WorkspaceSessionStore,提供以下命令:
|
|
5
|
+
* session list [--all]
|
|
6
|
+
* session show <uuid>
|
|
7
|
+
* session rm <uuid>
|
|
8
|
+
* session switch <uuid>
|
|
9
|
+
* session rename <uuid> <name>
|
|
10
|
+
*
|
|
11
|
+
* 所有命令默认作用于**当前 workspace**;`list --all` 才跨 workspace。
|
|
12
|
+
*/
|
|
13
|
+
import type { SessionManager, WorkspaceInfo } from "@wukonglabs/wukong-agent-sdk";
|
|
14
|
+
/** 命令上下文,由 CLI 主入口注入 */
|
|
15
|
+
export interface SessionCmdContext {
|
|
16
|
+
manager: SessionManager;
|
|
17
|
+
workspace: WorkspaceInfo;
|
|
18
|
+
/** 子命令后剩下的位置参数(不含 "session" 本身) */
|
|
19
|
+
args: string[];
|
|
20
|
+
}
|
|
21
|
+
/** 命令返回的退出码 */
|
|
22
|
+
export type CmdExitCode = 0 | 1 | 4;
|
|
23
|
+
/**
|
|
24
|
+
* 分派 `wukong session <sub> ...`。
|
|
25
|
+
* @returns 退出码
|
|
26
|
+
*/
|
|
27
|
+
export declare function runSessionCommand(ctx: SessionCmdContext): Promise<CmdExitCode>;
|
|
28
|
+
//# sourceMappingURL=session-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-commands.d.ts","sourceRoot":"","sources":["../../src/cli/session-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,aAAa,EAEd,MAAM,8BAA8B,CAAC;AAEtC,wBAAwB;AACxB,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,cAAc,CAAC;IACxB,SAAS,EAAE,aAAa,CAAC;IACzB,mCAAmC;IACnC,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,eAAe;AACf,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEpC;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CA2BpF"}
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `wukong session` 子命令实现。
|
|
3
|
+
*
|
|
4
|
+
* 消费 SessionManager 暴露的 WorkspaceSessionStore,提供以下命令:
|
|
5
|
+
* session list [--all]
|
|
6
|
+
* session show <uuid>
|
|
7
|
+
* session rm <uuid>
|
|
8
|
+
* session switch <uuid>
|
|
9
|
+
* session rename <uuid> <name>
|
|
10
|
+
*
|
|
11
|
+
* 所有命令默认作用于**当前 workspace**;`list --all` 才跨 workspace。
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* 分派 `wukong session <sub> ...`。
|
|
15
|
+
* @returns 退出码
|
|
16
|
+
*/
|
|
17
|
+
export async function runSessionCommand(ctx) {
|
|
18
|
+
const [sub, ...rest] = ctx.args;
|
|
19
|
+
switch (sub) {
|
|
20
|
+
case "list":
|
|
21
|
+
return await cmdList(ctx, rest);
|
|
22
|
+
case "show":
|
|
23
|
+
return await cmdShow(ctx, rest);
|
|
24
|
+
case "rm":
|
|
25
|
+
case "remove":
|
|
26
|
+
case "delete":
|
|
27
|
+
return await cmdRemove(ctx, rest);
|
|
28
|
+
case "switch":
|
|
29
|
+
return await cmdSwitch(ctx, rest);
|
|
30
|
+
case "rename":
|
|
31
|
+
return await cmdRename(ctx, rest);
|
|
32
|
+
case undefined:
|
|
33
|
+
case "help":
|
|
34
|
+
case "--help":
|
|
35
|
+
case "-h":
|
|
36
|
+
printHelp();
|
|
37
|
+
return sub === undefined ? 4 : 0;
|
|
38
|
+
default:
|
|
39
|
+
process.stderr.write(`❌ 未知子命令: session ${sub}\n\n`);
|
|
40
|
+
printHelp();
|
|
41
|
+
return 4;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// ────────────────────────────────────────────────────────────
|
|
45
|
+
// 命令实现
|
|
46
|
+
// ────────────────────────────────────────────────────────────
|
|
47
|
+
async function cmdList(ctx, args) {
|
|
48
|
+
const all = args.includes("--all") || args.includes("-a");
|
|
49
|
+
if (all) {
|
|
50
|
+
// 跨 workspace 列出所有 session
|
|
51
|
+
const index = await ctx.manager.store.loadIndex();
|
|
52
|
+
const workspaces = Object.entries(index.workspaces).sort((a, b) => b[1].lastActiveAt - a[1].lastActiveAt);
|
|
53
|
+
if (workspaces.length === 0) {
|
|
54
|
+
process.stdout.write("(尚未创建任何 workspace 或 session)\n");
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
for (const [hash, entry] of workspaces) {
|
|
58
|
+
process.stdout.write(`\n📂 ${entry.alias ?? entry.root} ` +
|
|
59
|
+
`[${hash.slice(0, 8)}] ${formatRelative(entry.lastActiveAt)}\n`);
|
|
60
|
+
const metas = await ctx.manager.store.listSessions(hash);
|
|
61
|
+
const latest = await ctx.manager.store.getLatest(hash);
|
|
62
|
+
renderSessionTable(metas, latest);
|
|
63
|
+
}
|
|
64
|
+
return 0;
|
|
65
|
+
}
|
|
66
|
+
// 当前 workspace 的 session 列表
|
|
67
|
+
const metas = await ctx.manager.store.listSessions(ctx.workspace.hash);
|
|
68
|
+
const latest = await ctx.manager.store.getLatest(ctx.workspace.hash);
|
|
69
|
+
process.stdout.write(`📂 当前 workspace: ${ctx.workspace.root}\n`);
|
|
70
|
+
if (metas.length === 0) {
|
|
71
|
+
process.stdout.write("(该 workspace 尚无 session,运行 `wukong` 或 `wukong --new` 创建一条)\n");
|
|
72
|
+
return 0;
|
|
73
|
+
}
|
|
74
|
+
renderSessionTable(metas, latest);
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
async function cmdShow(ctx, args) {
|
|
78
|
+
const input = args[0];
|
|
79
|
+
if (!input) {
|
|
80
|
+
process.stderr.write("❌ 用法: wukong session show <uuid|prefix>\n");
|
|
81
|
+
return 4;
|
|
82
|
+
}
|
|
83
|
+
const uuid = await resolveUuidPrefix(ctx, input);
|
|
84
|
+
if (typeof uuid !== "string")
|
|
85
|
+
return uuid;
|
|
86
|
+
const ref = { workspaceHash: ctx.workspace.hash, sessionUuid: uuid };
|
|
87
|
+
const meta = await ctx.manager.store.loadSessionMeta(ref);
|
|
88
|
+
if (!meta) {
|
|
89
|
+
// 前面 resolveUuidPrefix 已经存在校验,这里理论上不会走到
|
|
90
|
+
process.stderr.write(`❌ 当前 workspace 下不存在 session: ${uuid}\n`);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
const records = await ctx.manager.store.loadRecords(ref);
|
|
94
|
+
const roleStats = countRoles(records);
|
|
95
|
+
const files = extractTouchedFiles(records);
|
|
96
|
+
process.stdout.write(`Session ${uuid}\n`);
|
|
97
|
+
process.stdout.write(` Workspace : ${ctx.workspace.root}\n`);
|
|
98
|
+
if (meta.name)
|
|
99
|
+
process.stdout.write(` Name : ${meta.name}\n`);
|
|
100
|
+
process.stdout.write(` Created : ${new Date(meta.createdAt).toISOString()}\n`);
|
|
101
|
+
process.stdout.write(` Last active : ${new Date(meta.lastActiveAt).toISOString()}\n`);
|
|
102
|
+
process.stdout.write(` Messages : ${meta.messageCount} 条\n`);
|
|
103
|
+
process.stdout.write(` Roles : user=${roleStats.user} assistant=${roleStats.assistant} ` +
|
|
104
|
+
`tool=${roleStats.tool} compaction=${roleStats.compaction}\n`);
|
|
105
|
+
if (files.length > 0) {
|
|
106
|
+
process.stdout.write(` Files touched : ${files.length}\n`);
|
|
107
|
+
for (const f of files.slice(0, 20)) {
|
|
108
|
+
process.stdout.write(` - ${f}\n`);
|
|
109
|
+
}
|
|
110
|
+
if (files.length > 20) {
|
|
111
|
+
process.stdout.write(` ...(共 ${files.length} 个,仅显示前 20)\n`);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return 0;
|
|
115
|
+
}
|
|
116
|
+
async function cmdRemove(ctx, args) {
|
|
117
|
+
const input = args[0];
|
|
118
|
+
if (!input) {
|
|
119
|
+
process.stderr.write("❌ 用法: wukong session rm <uuid|prefix>\n");
|
|
120
|
+
return 4;
|
|
121
|
+
}
|
|
122
|
+
const uuid = await resolveUuidPrefix(ctx, input);
|
|
123
|
+
if (typeof uuid !== "string")
|
|
124
|
+
return uuid;
|
|
125
|
+
const ref = { workspaceHash: ctx.workspace.hash, sessionUuid: uuid };
|
|
126
|
+
await ctx.manager.store.removeSession(ref);
|
|
127
|
+
process.stdout.write(`🗑️ 已删除 session: ${uuid}\n`);
|
|
128
|
+
return 0;
|
|
129
|
+
}
|
|
130
|
+
async function cmdSwitch(ctx, args) {
|
|
131
|
+
const input = args[0];
|
|
132
|
+
if (!input) {
|
|
133
|
+
process.stderr.write("❌ 用法: wukong session switch <uuid|prefix>\n");
|
|
134
|
+
return 4;
|
|
135
|
+
}
|
|
136
|
+
const uuid = await resolveUuidPrefix(ctx, input);
|
|
137
|
+
if (typeof uuid !== "string")
|
|
138
|
+
return uuid;
|
|
139
|
+
await ctx.manager.store.setLatest(ctx.workspace.hash, uuid);
|
|
140
|
+
process.stdout.write(`✓ latest 指针已切换到: ${uuid}\n`);
|
|
141
|
+
return 0;
|
|
142
|
+
}
|
|
143
|
+
async function cmdRename(ctx, args) {
|
|
144
|
+
const [input, ...nameParts] = args;
|
|
145
|
+
const name = nameParts.join(" ").trim();
|
|
146
|
+
if (!input || !name) {
|
|
147
|
+
process.stderr.write("❌ 用法: wukong session rename <uuid|prefix> <name>\n");
|
|
148
|
+
return 4;
|
|
149
|
+
}
|
|
150
|
+
const uuid = await resolveUuidPrefix(ctx, input);
|
|
151
|
+
if (typeof uuid !== "string")
|
|
152
|
+
return uuid;
|
|
153
|
+
const ref = { workspaceHash: ctx.workspace.hash, sessionUuid: uuid };
|
|
154
|
+
const meta = await ctx.manager.store.loadSessionMeta(ref);
|
|
155
|
+
// 前面已经校验存在,meta 不会为 null
|
|
156
|
+
await ctx.manager.store.saveSessionMeta(ref, { ...meta, name });
|
|
157
|
+
process.stdout.write(`✓ session ${uuid.slice(0, 8)} 别名已更新为: ${name}\n`);
|
|
158
|
+
return 0;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 把用户输入的 uuid 前缀展开为完整 uuid。
|
|
162
|
+
* 完整 uuid 也接受(相当于前缀等于自己)。
|
|
163
|
+
*
|
|
164
|
+
* @returns 完整 uuid 或退出码
|
|
165
|
+
*/
|
|
166
|
+
async function resolveUuidPrefix(ctx, input) {
|
|
167
|
+
const metas = await ctx.manager.store.listSessions(ctx.workspace.hash);
|
|
168
|
+
const matches = metas.filter((m) => m.sessionUuid.startsWith(input));
|
|
169
|
+
if (matches.length === 0) {
|
|
170
|
+
process.stderr.write(`❌ 当前 workspace 下未找到匹配的 session: ${input}\n`);
|
|
171
|
+
return 1;
|
|
172
|
+
}
|
|
173
|
+
if (matches.length > 1) {
|
|
174
|
+
process.stderr.write(`❌ 前缀 "${input}" 匹配到多个 session(${matches.length} 个),请提供更长的前缀:\n`);
|
|
175
|
+
for (const m of matches) {
|
|
176
|
+
process.stderr.write(` ${m.sessionUuid}\n`);
|
|
177
|
+
}
|
|
178
|
+
return 4;
|
|
179
|
+
}
|
|
180
|
+
return matches[0].sessionUuid;
|
|
181
|
+
}
|
|
182
|
+
// ────────────────────────────────────────────────────────────
|
|
183
|
+
// 渲染工具
|
|
184
|
+
// ────────────────────────────────────────────────────────────
|
|
185
|
+
function renderSessionTable(metas, latestUuid) {
|
|
186
|
+
if (metas.length === 0) {
|
|
187
|
+
process.stdout.write(" (无 session)\n");
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
for (const m of metas) {
|
|
191
|
+
const isLatest = m.sessionUuid === latestUuid ? "* " : " ";
|
|
192
|
+
const label = m.name ? ` "${m.name}"` : "";
|
|
193
|
+
process.stdout.write(` ${isLatest}${m.sessionUuid.slice(0, 8)}${label}` +
|
|
194
|
+
` ${String(m.messageCount).padStart(4)} 条 ${formatRelative(m.lastActiveAt)}\n`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
function formatRelative(ts) {
|
|
198
|
+
const diff = Date.now() - ts;
|
|
199
|
+
if (diff < 0)
|
|
200
|
+
return new Date(ts).toISOString().slice(0, 16).replace("T", " ");
|
|
201
|
+
const min = Math.floor(diff / 60_000);
|
|
202
|
+
if (min < 1)
|
|
203
|
+
return "刚刚";
|
|
204
|
+
if (min < 60)
|
|
205
|
+
return `${min} 分钟前`;
|
|
206
|
+
const hours = Math.floor(min / 60);
|
|
207
|
+
if (hours < 24)
|
|
208
|
+
return `${hours} 小时前`;
|
|
209
|
+
const days = Math.floor(hours / 24);
|
|
210
|
+
if (days < 30)
|
|
211
|
+
return `${days} 天前`;
|
|
212
|
+
return new Date(ts).toISOString().slice(0, 10);
|
|
213
|
+
}
|
|
214
|
+
function countRoles(records) {
|
|
215
|
+
const stats = { user: 0, assistant: 0, tool: 0, compaction: 0 };
|
|
216
|
+
for (const r of records) {
|
|
217
|
+
if (r.type === "compaction") {
|
|
218
|
+
stats.compaction++;
|
|
219
|
+
}
|
|
220
|
+
else if (r.role === "user")
|
|
221
|
+
stats.user++;
|
|
222
|
+
else if (r.role === "assistant")
|
|
223
|
+
stats.assistant++;
|
|
224
|
+
else if (r.role === "tool")
|
|
225
|
+
stats.tool++;
|
|
226
|
+
}
|
|
227
|
+
return stats;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* 从 tool_call 参数里粗略抽取 path/file 字段,当作"这次 session 碰过的文件"列表。
|
|
231
|
+
* 只做启发式,允许假阳(比如 grep 的 path 参数是搜索路径不是被改的文件),
|
|
232
|
+
* 但更简单粗暴的方式(读所有 write_file/edit_file 的具体参数)只需要看 tool.name 白名单。
|
|
233
|
+
*/
|
|
234
|
+
function extractTouchedFiles(records) {
|
|
235
|
+
const WRITE_TOOLS = new Set(["write_file", "edit_file", "multi_edit", "undo_edit"]);
|
|
236
|
+
const seen = new Set();
|
|
237
|
+
for (const r of records) {
|
|
238
|
+
for (const tc of r.toolCalls ?? []) {
|
|
239
|
+
if (!WRITE_TOOLS.has(tc.name))
|
|
240
|
+
continue;
|
|
241
|
+
try {
|
|
242
|
+
const parsed = JSON.parse(tc.arguments);
|
|
243
|
+
const p = parsed.path ?? parsed.file_path;
|
|
244
|
+
if (p)
|
|
245
|
+
seen.add(p);
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// 参数解析失败,忽略
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return Array.from(seen).sort();
|
|
253
|
+
}
|
|
254
|
+
// ────────────────────────────────────────────────────────────
|
|
255
|
+
// help
|
|
256
|
+
// ────────────────────────────────────────────────────────────
|
|
257
|
+
function printHelp() {
|
|
258
|
+
process.stdout.write(`
|
|
259
|
+
wukong session — 管理会话
|
|
260
|
+
|
|
261
|
+
用法:
|
|
262
|
+
wukong session list [--all|-a] 列出当前 workspace 的所有 session
|
|
263
|
+
(--all 跨 workspace)
|
|
264
|
+
wukong session show <uuid|prefix> 展示某条 session 的摘要
|
|
265
|
+
wukong session rm <uuid|prefix> 删除 session
|
|
266
|
+
wukong session switch <uuid|prefix> 切换 latest 指针
|
|
267
|
+
wukong session rename <uuid|prefix> <name> 给 session 起别名
|
|
268
|
+
|
|
269
|
+
说明:
|
|
270
|
+
* 号标记的 session 是 latest,即 \`wukong\` / \`wukong --continue\` 会续接的那条。
|
|
271
|
+
<uuid> 支持前缀匹配(至少 8 位),多个匹配时会要求更长的前缀。
|
|
272
|
+
`.trimStart());
|
|
273
|
+
}
|
|
274
|
+
//# sourceMappingURL=session-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-commands.js","sourceRoot":"","sources":["../../src/cli/session-commands.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/summary.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* 智能摘要提取
|
|
4
3
|
*
|
|
5
4
|
* 从 Agent 回复中提取一句话摘要用于 JSON 输出,
|
|
6
5
|
* 比硬编码的 "完成,N 步,M tokens" 更有意义。
|
|
7
6
|
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.extractSummary = extractSummary;
|
|
10
|
-
exports.buildJsonSummary = buildJsonSummary;
|
|
11
7
|
/**
|
|
12
8
|
* 从 Agent 回复文本中提取摘要
|
|
13
9
|
*
|
|
@@ -16,7 +12,7 @@ exports.buildJsonSummary = buildJsonSummary;
|
|
|
16
12
|
* 2. 查找带有 ✅ / ✓ / 完成 等标记的句子
|
|
17
13
|
* 3. 取回复的前 120 个字符作为 fallback
|
|
18
14
|
*/
|
|
19
|
-
function extractSummary(agentResponse, fallback) {
|
|
15
|
+
export function extractSummary(agentResponse, fallback) {
|
|
20
16
|
if (!agentResponse || agentResponse.length === 0) {
|
|
21
17
|
return fallback;
|
|
22
18
|
}
|
|
@@ -62,7 +58,7 @@ function extractSummary(agentResponse, fallback) {
|
|
|
62
58
|
*
|
|
63
59
|
* 结合 Agent 回复摘要 + 统计信息
|
|
64
60
|
*/
|
|
65
|
-
function buildJsonSummary(agentResponse, stats) {
|
|
61
|
+
export function buildJsonSummary(agentResponse, stats) {
|
|
66
62
|
const responseSummary = extractSummary(agentResponse, '');
|
|
67
63
|
if (responseSummary) {
|
|
68
64
|
return `${responseSummary} (${stats.steps} 步, ${stats.totalTokens} tokens)`;
|
package/dist/cli/summary.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/cli/summary.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../src/cli/summary.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,aAAqB,EACrB,QAAgB;IAEhB,IAAI,CAAC,aAAa,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,iBAAiB;IACjB,MAAM,OAAO,GAAG,aAAa;SAC1B,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAE,QAAQ;SACxC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAI,OAAO;SACvC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAO,SAAS;SACzC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAU,WAAW;SAC3C,IAAI,EAAE,CAAC;IAEV,eAAe;IACf,MAAM,eAAe,GAAG;QACtB,wDAAwD;QACxD,yBAAyB;QACzB,uCAAuC;KACxC,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACtB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,IAAI,SAAS,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;gBACrD,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1E,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClC,IAAI,KAAK,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;IACrC,CAAC;IAED,YAAY;IACZ,IAAI,OAAO,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC;QAC1B,OAAO,OAAO,CAAC;IACjB,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,aAAqB,EACrB,KAA6C;IAE7C,MAAM,eAAe,GAAG,cAAc,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAE1D,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,GAAG,eAAe,KAAK,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,WAAW,UAAU,CAAC;IAC9E,CAAC;IAED,OAAO,MAAM,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,WAAW,SAAS,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `wukong workspace` 子命令实现。
|
|
3
|
+
*
|
|
4
|
+
* 命令:
|
|
5
|
+
* workspace list 列出所有已知 workspace
|
|
6
|
+
* workspace rm <hash|prefix> 删除整个 workspace(含所有 session)
|
|
7
|
+
*/
|
|
8
|
+
import type { SessionManager } from "@wukonglabs/wukong-agent-sdk";
|
|
9
|
+
export interface WorkspaceCmdContext {
|
|
10
|
+
manager: SessionManager;
|
|
11
|
+
args: string[];
|
|
12
|
+
}
|
|
13
|
+
export type CmdExitCode = 0 | 1 | 4;
|
|
14
|
+
export declare function runWorkspaceCommand(ctx: WorkspaceCmdContext): Promise<CmdExitCode>;
|
|
15
|
+
//# sourceMappingURL=workspace-commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-commands.d.ts","sourceRoot":"","sources":["../../src/cli/workspace-commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEnE,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,cAAc,CAAC;IACxB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEpC,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,mBAAmB,GACvB,OAAO,CAAC,WAAW,CAAC,CAqBtB"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `wukong workspace` 子命令实现。
|
|
3
|
+
*
|
|
4
|
+
* 命令:
|
|
5
|
+
* workspace list 列出所有已知 workspace
|
|
6
|
+
* workspace rm <hash|prefix> 删除整个 workspace(含所有 session)
|
|
7
|
+
*/
|
|
8
|
+
export async function runWorkspaceCommand(ctx) {
|
|
9
|
+
const [sub, ...rest] = ctx.args;
|
|
10
|
+
switch (sub) {
|
|
11
|
+
case "list":
|
|
12
|
+
return await cmdList(ctx);
|
|
13
|
+
case "rm":
|
|
14
|
+
case "remove":
|
|
15
|
+
case "delete":
|
|
16
|
+
return await cmdRemove(ctx, rest);
|
|
17
|
+
case undefined:
|
|
18
|
+
case "help":
|
|
19
|
+
case "--help":
|
|
20
|
+
case "-h":
|
|
21
|
+
printHelp();
|
|
22
|
+
return sub === undefined ? 4 : 0;
|
|
23
|
+
default:
|
|
24
|
+
process.stderr.write(`❌ 未知子命令: workspace ${sub}\n\n`);
|
|
25
|
+
printHelp();
|
|
26
|
+
return 4;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ────────────────────────────────────────────────────────────
|
|
30
|
+
async function cmdList(ctx) {
|
|
31
|
+
const index = await ctx.manager.store.loadIndex();
|
|
32
|
+
const workspaces = Object.entries(index.workspaces).sort((a, b) => b[1].lastActiveAt - a[1].lastActiveAt);
|
|
33
|
+
if (workspaces.length === 0) {
|
|
34
|
+
process.stdout.write("(尚未记录任何 workspace)\n");
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
for (const [hash, entry] of workspaces) {
|
|
38
|
+
const label = entry.alias ? `${entry.alias} (${entry.root})` : entry.root;
|
|
39
|
+
process.stdout.write(`${hash.slice(0, 8)} ${String(entry.sessionCount).padStart(3)} sessions ` +
|
|
40
|
+
`${formatRelative(entry.lastActiveAt)} ${label}\n`);
|
|
41
|
+
}
|
|
42
|
+
return 0;
|
|
43
|
+
}
|
|
44
|
+
async function cmdRemove(ctx, args) {
|
|
45
|
+
const arg = args[0];
|
|
46
|
+
if (!arg) {
|
|
47
|
+
process.stderr.write("❌ 用法: wukong workspace rm <hash|prefix>\n");
|
|
48
|
+
return 4;
|
|
49
|
+
}
|
|
50
|
+
const index = await ctx.manager.store.loadIndex();
|
|
51
|
+
const matches = Object.keys(index.workspaces).filter((h) => h.startsWith(arg));
|
|
52
|
+
if (matches.length === 0) {
|
|
53
|
+
process.stderr.write(`❌ 未找到匹配的 workspace hash: ${arg}\n`);
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
if (matches.length > 1) {
|
|
57
|
+
process.stderr.write(`❌ 前缀 "${arg}" 匹配到多个 workspace(${matches.length} 个),请提供更长的前缀:\n`);
|
|
58
|
+
for (const h of matches)
|
|
59
|
+
process.stderr.write(` ${h}\n`);
|
|
60
|
+
return 4;
|
|
61
|
+
}
|
|
62
|
+
const hash = matches[0];
|
|
63
|
+
const sessionCount = (await ctx.manager.store.listSessions(hash)).length;
|
|
64
|
+
await ctx.manager.store.removeWorkspace(hash);
|
|
65
|
+
process.stdout.write(`🗑️ 已删除 workspace ${hash.slice(0, 8)}(${sessionCount} 条 session,目录已清空)\n`);
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
function formatRelative(ts) {
|
|
69
|
+
const diff = Date.now() - ts;
|
|
70
|
+
if (diff < 0)
|
|
71
|
+
return new Date(ts).toISOString().slice(0, 16).replace("T", " ");
|
|
72
|
+
const min = Math.floor(diff / 60_000);
|
|
73
|
+
if (min < 1)
|
|
74
|
+
return "刚刚";
|
|
75
|
+
if (min < 60)
|
|
76
|
+
return `${min} 分钟前`;
|
|
77
|
+
const hours = Math.floor(min / 60);
|
|
78
|
+
if (hours < 24)
|
|
79
|
+
return `${hours} 小时前`;
|
|
80
|
+
const days = Math.floor(hours / 24);
|
|
81
|
+
if (days < 30)
|
|
82
|
+
return `${days} 天前`;
|
|
83
|
+
return new Date(ts).toISOString().slice(0, 10);
|
|
84
|
+
}
|
|
85
|
+
function printHelp() {
|
|
86
|
+
process.stdout.write(`
|
|
87
|
+
wukong workspace — 管理已知 workspace
|
|
88
|
+
|
|
89
|
+
用法:
|
|
90
|
+
wukong workspace list 列出所有已知 workspace(按最后活跃时间倒序)
|
|
91
|
+
wukong workspace rm <hash|prefix> 删除某个 workspace 的全部 session
|
|
92
|
+
|
|
93
|
+
说明:
|
|
94
|
+
hash 是 workspace root 的 sha256 前 12 位,\`workspace list\` 里的第一列。
|
|
95
|
+
rm 支持前缀匹配,例如 \`wukong workspace rm a1b2\`;多个匹配时会要求更长前缀。
|
|
96
|
+
`.trimStart());
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=workspace-commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-commands.js","sourceRoot":"","sources":["../../src/cli/workspace-commands.ts"],"names":[],"mappings":"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"}
|