aws-runtime-bridge 1.9.0 → 1.9.1
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/adapter/AcodeSdkAdapter.d.ts +2 -0
- package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/AcodeSdkAdapter.js +84 -18
- package/dist/adapter/AcodeSdkAdapter.test.js +275 -13
- package/dist/adapter/acode-tool-names.d.ts +16 -0
- package/dist/adapter/acode-tool-names.d.ts.map +1 -0
- package/dist/adapter/acode-tool-names.js +37 -0
- package/dist/adapter/acode-tool-names.test.d.ts +2 -0
- package/dist/adapter/acode-tool-names.test.d.ts.map +1 -0
- package/dist/adapter/acode-tool-names.test.js +28 -0
- package/dist/adapter/types.d.ts +22 -3
- package/dist/adapter/types.d.ts.map +1 -1
- package/dist/adapter/types.js +2 -1
- package/dist/routes/git.d.ts +10 -0
- package/dist/routes/git.d.ts.map +1 -1
- package/dist/routes/git.js +37 -3
- package/dist/routes/git.test.js +47 -1
- package/dist/routes/sessions.d.ts +1 -1
- package/dist/routes/sessions.d.ts.map +1 -1
- package/dist/routes/sessions.js +11 -4
- package/dist/routes/sessions.test.js +3 -0
- package/dist/routes/terminal.d.ts +28 -8
- package/dist/routes/terminal.d.ts.map +1 -1
- package/dist/routes/terminal.js +260 -44
- package/dist/routes/terminal.stop-options.test.d.ts +2 -0
- package/dist/routes/terminal.stop-options.test.d.ts.map +1 -0
- package/dist/routes/terminal.stop-options.test.js +39 -0
- package/dist/routes/terminal.test.js +87 -4
- package/dist/services/session-output.d.ts +5 -0
- package/dist/services/session-output.d.ts.map +1 -1
- package/package/acode/dist/built-in-file-tools.d.ts +5 -1
- package/package/acode/dist/built-in-file-tools.d.ts.map +1 -1
- package/package/acode/dist/built-in-file-tools.js +14 -203
- package/package/acode/dist/builtins/commandArtifacts.d.ts +25 -0
- package/package/acode/dist/builtins/commandArtifacts.d.ts.map +1 -0
- package/package/acode/dist/builtins/commandArtifacts.js +77 -0
- package/package/acode/dist/builtins/commandOutputEvents.d.ts +21 -0
- package/package/acode/dist/builtins/commandOutputEvents.d.ts.map +1 -0
- package/package/acode/dist/builtins/commandOutputEvents.js +56 -0
- package/package/acode/dist/builtins/shellCommandPreparation.d.ts +15 -0
- package/package/acode/dist/builtins/shellCommandPreparation.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellCommandPreparation.js +44 -0
- package/package/acode/dist/builtins/shellCommandResult.d.ts +30 -0
- package/package/acode/dist/builtins/shellCommandResult.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellCommandResult.js +71 -0
- package/package/acode/dist/builtins/shellCommandRunner.d.ts +14 -0
- package/package/acode/dist/builtins/shellCommandRunner.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellCommandRunner.js +114 -0
- package/package/acode/dist/builtins/shellOutputDecoder.d.ts +5 -0
- package/package/acode/dist/builtins/shellOutputDecoder.d.ts.map +1 -0
- package/package/acode/dist/builtins/shellOutputDecoder.js +30 -0
- package/package/acode/dist/mcpToolNames.d.ts +11 -0
- package/package/acode/dist/mcpToolNames.d.ts.map +1 -0
- package/package/acode/dist/mcpToolNames.js +17 -0
- package/package/acode/dist/runtime.d.ts +19 -0
- package/package/acode/dist/runtime.d.ts.map +1 -1
- package/package/acode/dist/runtime.js +233 -35
- package/package/acode/dist/types.d.ts +1 -1
- package/package/acode/dist/types.d.ts.map +1 -1
- package/package/acode/package.json +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +3 -3
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +10 -7
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +47 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +1 -36
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +3 -169
- package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.js +45 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.test.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.d.ts +11 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.d.ts.map +1 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.js +144 -0
- package/package/aws-client-agent-mcp/dist/memory-tools.js.map +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js +1 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js +43 -3
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { getSemanticToolName, isMessagePollingIdleCommand, isPollMessageToolDescriptor, } from "./acode-tool-names.js";
|
|
3
|
+
describe("ACode tool name helpers", () => {
|
|
4
|
+
it("extracts semantic tool names from MCP prefixes", () => {
|
|
5
|
+
expect(getSemanticToolName("aws-mcp__poll_message")).toBe("poll_message");
|
|
6
|
+
expect(getSemanticToolName("aws-mcp.poll_message")).toBe("poll_message");
|
|
7
|
+
expect(getSemanticToolName("mcp/aws-mcp/get_message")).toBe("get_message");
|
|
8
|
+
});
|
|
9
|
+
it("recognizes only exact poll_message tool descriptors as listeners", () => {
|
|
10
|
+
expect(isPollMessageToolDescriptor({
|
|
11
|
+
name: "aws-mcp__poll_message",
|
|
12
|
+
source: "aws-mcp.poll_message",
|
|
13
|
+
})).toBe(true);
|
|
14
|
+
expect(isPollMessageToolDescriptor({
|
|
15
|
+
name: "other-mcp__not_poll_message",
|
|
16
|
+
source: "other-mcp.not_poll_message",
|
|
17
|
+
})).toBe(false);
|
|
18
|
+
expect(isPollMessageToolDescriptor({
|
|
19
|
+
name: "poll_message_backup",
|
|
20
|
+
source: "other-mcp.poll_message_backup",
|
|
21
|
+
})).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
it("detects configured idle commands that ask the agent to poll messages", () => {
|
|
24
|
+
expect(isMessagePollingIdleCommand("poll_message")).toBe(true);
|
|
25
|
+
expect(isMessagePollingIdleCommand("system: call get_message now")).toBe(true);
|
|
26
|
+
expect(isMessagePollingIdleCommand("continue the current task")).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
});
|
package/dist/adapter/types.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { EventEmitter } from "node:events";
|
|
8
8
|
export type SessionStatus = "starting" | "thinking" | "tool_using" | "waiting_input" | "completed" | "terminated" | "error";
|
|
9
|
-
export type ProviderEventType = "ai_request" | "text_delta" | "thinking" | "tool_use_start" | "tool_use_end" | "permission_request" | "ask_user_question" | "exit_plan_mode" | "turn_complete" | "session_complete" | "error";
|
|
9
|
+
export type ProviderEventType = "ai_request" | "text_delta" | "thinking" | "command_output" | "tool_use_start" | "tool_use_end" | "permission_request" | "ask_user_question" | "exit_plan_mode" | "turn_complete" | "session_complete" | "error";
|
|
10
10
|
/**
|
|
11
11
|
* Agent 工具动作类型分类
|
|
12
12
|
* 用于细粒度显示 agent 当前正在执行的具体动作
|
|
@@ -58,6 +58,7 @@ export interface RuntimeTokenUsage {
|
|
|
58
58
|
inputTokens: number;
|
|
59
59
|
outputTokens: number;
|
|
60
60
|
}
|
|
61
|
+
export type CommandOutputStream = "stdout" | "stderr" | "mixed";
|
|
61
62
|
export interface RuntimeStatusActionInfo {
|
|
62
63
|
actionType?: ToolActionType;
|
|
63
64
|
actionLabel?: string;
|
|
@@ -77,8 +78,14 @@ export interface ProviderEvent {
|
|
|
77
78
|
model?: string;
|
|
78
79
|
/** AI 请求 endpoint 摘要(ai_request,不含密钥) */
|
|
79
80
|
endpoint?: string;
|
|
80
|
-
/** AI
|
|
81
|
-
|
|
81
|
+
/** AI 请求方法(ai_request) */
|
|
82
|
+
requestMethod?: string;
|
|
83
|
+
/** AI 请求完整 URL(ai_request,不含密钥) */
|
|
84
|
+
requestUrl?: string;
|
|
85
|
+
/** AI 请求头(ai_request,敏感值已脱敏) */
|
|
86
|
+
requestHeaders?: Record<string, string>;
|
|
87
|
+
/** AI 请求是否流式返回(ai_request)或命令输出流名(command_output) */
|
|
88
|
+
stream?: boolean | CommandOutputStream;
|
|
82
89
|
/** AI 请求上下文消息数量(ai_request) */
|
|
83
90
|
messageCount?: number;
|
|
84
91
|
/** AI 请求可用工具数量(ai_request) */
|
|
@@ -127,6 +134,14 @@ export interface ProviderEvent {
|
|
|
127
134
|
actionId?: string;
|
|
128
135
|
/** 工具返回数据(tool_use_end) */
|
|
129
136
|
actionResult?: string;
|
|
137
|
+
/** 命令输出批次序号(command_output) */
|
|
138
|
+
sequence?: number;
|
|
139
|
+
/** 命令执行目录(command_output) */
|
|
140
|
+
cwd?: string;
|
|
141
|
+
/** 超长命令落盘路径(command_output) */
|
|
142
|
+
commandFilePath?: string;
|
|
143
|
+
/** 命令行数(command_output) */
|
|
144
|
+
commandLineCount?: number;
|
|
130
145
|
};
|
|
131
146
|
}
|
|
132
147
|
export interface AdapterSessionConfig {
|
|
@@ -288,6 +303,10 @@ export declare abstract class BaseProviderAdapter extends EventEmitter {
|
|
|
288
303
|
* @param sessionId 会话 ID
|
|
289
304
|
*/
|
|
290
305
|
abstract abortCurrentTurn(sessionId: string): Promise<void>;
|
|
306
|
+
/**
|
|
307
|
+
* 重置当前会话上下文但保留 SDK 会话本身。
|
|
308
|
+
*/
|
|
309
|
+
abstract resetContext?(sessionId: string): Promise<void>;
|
|
291
310
|
/**
|
|
292
311
|
* 终止会话
|
|
293
312
|
* @param sessionId 会话 ID
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapter/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,UAAU,GACV,YAAY,GACZ,eAAe,GACf,WAAW,GACX,YAAY,GACZ,OAAO,CAAC;AAIZ,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,YAAY,GACZ,UAAU,GACV,gBAAgB,GAChB,cAAc,GACd,oBAAoB,GACpB,mBAAmB,GACnB,gBAAgB,GAChB,eAAe,GACf,kBAAkB,GAClB,OAAO,CAAC;AAIZ;;;GAGG;AACH,MAAM,MAAM,cAAc,GACtB,OAAO,GACP,KAAK,GACL,MAAM,GACN,WAAW,GACX,YAAY,GACZ,WAAW,GACX,MAAM,GACN,QAAQ,GACR,KAAK,GACL,YAAY,GACZ,KAAK,GACL,UAAU,GACV,OAAO,CAAC;AAEZ;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,aAAa;IACb,UAAU,EAAE,cAAc,CAAC;IAC3B,iBAAiB;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY;IACZ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAUD;;;GAGG;AACH,wBAAgB,kCAAkC,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQvE;AAED;;;GAGG;AACH,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWvE;AAED;;GAEG;AACH,wBAAgB,yCAAyC,CACvD,KAAK,EAAE,OAAO,GACb,OAAO,CAgBT;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapter/types.ts"],"names":[],"mappings":"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"}
|
package/dist/adapter/types.js
CHANGED
|
@@ -84,7 +84,8 @@ const AGENTSWORK_MCP_SERVER_ALIASES = new Set([
|
|
|
84
84
|
]);
|
|
85
85
|
function canonicalizeMcpServer(serverName, toolName) {
|
|
86
86
|
const knownMcpServer = KNOWN_MCP_TOOLS[toolName.toLowerCase()];
|
|
87
|
-
if (knownMcpServer &&
|
|
87
|
+
if (knownMcpServer &&
|
|
88
|
+
AGENTSWORK_MCP_SERVER_ALIASES.has(serverName.toLowerCase())) {
|
|
88
89
|
return knownMcpServer;
|
|
89
90
|
}
|
|
90
91
|
return serverName;
|
package/dist/routes/git.d.ts
CHANGED
|
@@ -54,6 +54,11 @@ interface LatestGitStash {
|
|
|
54
54
|
stashName: string;
|
|
55
55
|
message: string;
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* 生成 AgentsWork 持久化 stash 快照 ref。
|
|
59
|
+
* 主流程:仅接受稳定 stash commit hash,返回项目私有 refs 命名空间下的引用路径。
|
|
60
|
+
*/
|
|
61
|
+
export declare function createAgentsWorkStashSnapshotRef(stashRef: string): string | null;
|
|
57
62
|
/**
|
|
58
63
|
* 解析 git stash list --format 输出行。
|
|
59
64
|
* 主流程:优先返回稳定 stash commit hash 作为 ref,同时保留 stash@{n} 供界面展示。
|
|
@@ -64,6 +69,11 @@ export declare function parseGitStashListLine(line: string): GitStashItem | null
|
|
|
64
69
|
* 主流程:提取稳定 stash commit hash,供无变更快照复用最近快照引用。
|
|
65
70
|
*/
|
|
66
71
|
export declare function parseLatestGitStash(output: string): LatestGitStash | null;
|
|
72
|
+
/**
|
|
73
|
+
* 持久化 stash 快照引用。
|
|
74
|
+
* 具体功能:为稳定 stash commit hash 创建私有 Git ref;失败时记录警告并保留调用方的兼容回退。
|
|
75
|
+
*/
|
|
76
|
+
export declare function persistAgentsWorkStashSnapshotRef(workspacePath: string, stashRef: string): Promise<string | null>;
|
|
67
77
|
/**
|
|
68
78
|
* 解析 git diff 的 name-status 与 numstat 输出,生成前端文件树需要的汇总数据。
|
|
69
79
|
*/
|
package/dist/routes/git.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/routes/git.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"git.d.ts","sourceRoot":"","sources":["../../src/routes/git.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/git.js
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 提供 Git Stash 快照的创建、列表、恢复和删除功能
|
|
5
5
|
*/
|
|
6
|
-
import { Router } from 'express';
|
|
7
6
|
import { spawn } from 'node:child_process';
|
|
8
7
|
import { promises as fs } from 'node:fs';
|
|
9
8
|
import path from 'node:path';
|
|
9
|
+
import { Router } from 'express';
|
|
10
10
|
import { validateToken } from '../middleware/auth.js';
|
|
11
11
|
import { logger } from '../utils/logger.js';
|
|
12
12
|
export const gitRouter = Router();
|
|
@@ -38,6 +38,7 @@ export async function assertGitWorkspacePathAccessible(workspacePath) {
|
|
|
38
38
|
throw new Error(`workspace path is not a directory: ${workspacePath}`);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
const STABLE_STASH_OBJECT_HASH_PATTERN = /^[0-9a-f]{40}$/i;
|
|
41
42
|
/**
|
|
42
43
|
* 判断 Git diff 汇总行是否应该展示在差异树中。
|
|
43
44
|
* 普通 modified 且文本增删均为 0 通常是 filemode/元数据噪声,避免显示为“无差异内容”。
|
|
@@ -71,6 +72,17 @@ export function isGitStashNoChangesOutput(output) {
|
|
|
71
72
|
|| normalized.includes('no changes to save')
|
|
72
73
|
|| normalized.includes('没有本地变更需要保存');
|
|
73
74
|
}
|
|
75
|
+
/**
|
|
76
|
+
* 生成 AgentsWork 持久化 stash 快照 ref。
|
|
77
|
+
* 主流程:仅接受稳定 stash commit hash,返回项目私有 refs 命名空间下的引用路径。
|
|
78
|
+
*/
|
|
79
|
+
export function createAgentsWorkStashSnapshotRef(stashRef) {
|
|
80
|
+
const normalizedRef = String(stashRef || '').trim();
|
|
81
|
+
if (!STABLE_STASH_OBJECT_HASH_PATTERN.test(normalizedRef)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
return `refs/agentswork/stash-snapshots/${normalizedRef.toLowerCase()}`;
|
|
85
|
+
}
|
|
74
86
|
/**
|
|
75
87
|
* 解析 git stash list --format 输出行。
|
|
76
88
|
* 主流程:优先返回稳定 stash commit hash 作为 ref,同时保留 stash@{n} 供界面展示。
|
|
@@ -187,6 +199,22 @@ async function execGitCommand(workspacePath, args) {
|
|
|
187
199
|
});
|
|
188
200
|
});
|
|
189
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* 持久化 stash 快照引用。
|
|
204
|
+
* 具体功能:为稳定 stash commit hash 创建私有 Git ref;失败时记录警告并保留调用方的兼容回退。
|
|
205
|
+
*/
|
|
206
|
+
export async function persistAgentsWorkStashSnapshotRef(workspacePath, stashRef) {
|
|
207
|
+
const persistentRef = createAgentsWorkStashSnapshotRef(stashRef);
|
|
208
|
+
if (!persistentRef) {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
const result = await execGitCommand(workspacePath, ['update-ref', persistentRef, stashRef]);
|
|
212
|
+
if (result.exitCode !== 0) {
|
|
213
|
+
logger.warn(`[Git] 持久化 stash 快照 ref 失败: ref=${persistentRef}, error=${result.stderr || result.stdout}`);
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
return persistentRef;
|
|
217
|
+
}
|
|
190
218
|
function normalizeGitPath(targetPath) {
|
|
191
219
|
return String(targetPath || '').replace(/\\/g, '/').replace(/^\.\//, '').trim();
|
|
192
220
|
}
|
|
@@ -454,9 +482,12 @@ gitRouter.post('/git/stash/create', validateToken, async (req, res) => {
|
|
|
454
482
|
if (isGitStashNoChangesOutput(`${result.stdout}\n${result.stderr}`)) {
|
|
455
483
|
const latestResult = await execGitCommand(normalizedPath, ['stash', 'list', '-n', '1', '--format=%H%x00%gd%x00%gs%x00%cr']);
|
|
456
484
|
const latestStash = latestResult.exitCode === 0 ? parseLatestGitStash(latestResult.stdout) : null;
|
|
485
|
+
const persistentStashRef = latestStash
|
|
486
|
+
? await persistAgentsWorkStashSnapshotRef(normalizedPath, latestStash.ref)
|
|
487
|
+
: null;
|
|
457
488
|
res.json({
|
|
458
489
|
ok: true,
|
|
459
|
-
stashRef: latestStash?.ref ?? null,
|
|
490
|
+
stashRef: persistentStashRef ?? latestStash?.ref ?? null,
|
|
460
491
|
stashName: latestStash?.stashName ?? null,
|
|
461
492
|
message: latestStash
|
|
462
493
|
? `没有本地变更需要保存,已复用最近快照 ${latestStash.stashName}`
|
|
@@ -477,7 +508,10 @@ gitRouter.post('/git/stash/create', validateToken, async (req, res) => {
|
|
|
477
508
|
}
|
|
478
509
|
const listResult = await execGitCommand(normalizedPath, ['stash', 'list', '-n', '1', '--format=%H%x00%gd%x00%gs%x00%cr']);
|
|
479
510
|
const latestStash = listResult.exitCode === 0 ? parseLatestGitStash(listResult.stdout) : null;
|
|
480
|
-
const
|
|
511
|
+
const persistentStashRef = latestStash
|
|
512
|
+
? await persistAgentsWorkStashSnapshotRef(normalizedPath, latestStash.ref)
|
|
513
|
+
: null;
|
|
514
|
+
const stashRef = persistentStashRef ?? latestStash?.ref ?? 'stash@{0}';
|
|
481
515
|
res.json({
|
|
482
516
|
ok: true,
|
|
483
517
|
stashRef,
|
package/dist/routes/git.test.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
|
+
import { execFile } from 'node:child_process';
|
|
2
|
+
import { promises as fs } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
1
6
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { createScopedFilePathspecArgs, createScopedGitPathspecArgs, mergeGitDiffSummaryFiles, normalizeGitCommitMessage, parseGitDiffSummary, parseGitStashListLine, parseGitStatusStagedPaths, parseLatestGitStash, } from './git.js';
|
|
7
|
+
import { createAgentsWorkStashSnapshotRef, createScopedFilePathspecArgs, createScopedGitPathspecArgs, mergeGitDiffSummaryFiles, normalizeGitCommitMessage, parseGitDiffSummary, parseGitStashListLine, parseGitStatusStagedPaths, parseLatestGitStash, persistAgentsWorkStashSnapshotRef, } from './git.js';
|
|
8
|
+
const execFileAsync = promisify(execFile);
|
|
9
|
+
async function runGit(cwd, args) {
|
|
10
|
+
const result = await execFileAsync('git', [...args], { cwd });
|
|
11
|
+
return result.stdout;
|
|
12
|
+
}
|
|
3
13
|
describe('git commit helpers', () => {
|
|
4
14
|
it('normalizes commit messages before executing git commit', () => {
|
|
5
15
|
expect(normalizeGitCommitMessage(' chore: update dashboard ')).toBe('chore: update dashboard');
|
|
@@ -79,4 +89,40 @@ describe('git stash reference helpers', () => {
|
|
|
79
89
|
message: '快照: latest',
|
|
80
90
|
});
|
|
81
91
|
});
|
|
92
|
+
it('keeps flow start snapshots restorable after the original stash selector is removed', async () => {
|
|
93
|
+
let workspacePath = null;
|
|
94
|
+
try {
|
|
95
|
+
workspacePath = await fs.mkdtemp(path.join(tmpdir(), 'aws-stash-ref-'));
|
|
96
|
+
await runGit(workspacePath, ['init']);
|
|
97
|
+
await runGit(workspacePath, ['config', 'core.autocrlf', 'false']);
|
|
98
|
+
await runGit(workspacePath, ['config', 'user.email', 'test@example.com']);
|
|
99
|
+
await runGit(workspacePath, ['config', 'user.name', 'Tester']);
|
|
100
|
+
await fs.writeFile(path.join(workspacePath, 'task.txt'), 'base\n', 'utf8');
|
|
101
|
+
await runGit(workspacePath, ['add', 'task.txt']);
|
|
102
|
+
await runGit(workspacePath, ['commit', '-m', 'init']);
|
|
103
|
+
await fs.writeFile(path.join(workspacePath, 'task.txt'), 'snapshot-content\n', 'utf8');
|
|
104
|
+
await runGit(workspacePath, ['stash', 'push', '-m', 'flow start snapshot']);
|
|
105
|
+
const latest = parseLatestGitStash(await runGit(workspacePath, ['stash', 'list', '-n', '1', '--format=%H%x00%gd%x00%gs%x00%cr']));
|
|
106
|
+
if (!latest) {
|
|
107
|
+
throw new Error('expected a latest stash entry');
|
|
108
|
+
}
|
|
109
|
+
const persistentRef = createAgentsWorkStashSnapshotRef(latest.ref);
|
|
110
|
+
if (!persistentRef) {
|
|
111
|
+
throw new Error('expected a persistent AgentsWork stash ref');
|
|
112
|
+
}
|
|
113
|
+
const persistedRef = await persistAgentsWorkStashSnapshotRef(workspacePath, latest.ref);
|
|
114
|
+
if (!persistedRef) {
|
|
115
|
+
throw new Error('expected the persistent ref to be written');
|
|
116
|
+
}
|
|
117
|
+
expect(persistedRef).toBe(persistentRef);
|
|
118
|
+
await runGit(workspacePath, ['stash', 'drop', latest.stashName]);
|
|
119
|
+
await runGit(workspacePath, ['stash', 'apply', persistedRef]);
|
|
120
|
+
await expect(fs.readFile(path.join(workspacePath, 'task.txt'), 'utf8')).resolves.toBe('snapshot-content\n');
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
if (workspacePath) {
|
|
124
|
+
await fs.rm(workspacePath, { recursive: true, force: true });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}, 15_000);
|
|
82
128
|
});
|
|
@@ -8,5 +8,5 @@ export declare const sessionsRouter: import("express-serve-static-core").Router;
|
|
|
8
8
|
* 解析 active SDK 会话快照状态。
|
|
9
9
|
* 主流程:优先使用 adapter 细粒度状态,其次使用 terminal 路由内存里的最近 runtimeStatus,最后兼容旧会话回退 running。
|
|
10
10
|
*/
|
|
11
|
-
export declare function resolveActiveSdkSessionSnapshotStatus(adapterStatus?: string, currentRuntimeStatus?: string): string;
|
|
11
|
+
export declare function resolveActiveSdkSessionSnapshotStatus(adapterStatus?: string, currentRuntimeStatus?: string, currentRuntimeActionType?: string): string;
|
|
12
12
|
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,eAAO,MAAM,cAAc,4CAAW,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,qCAAqC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../src/routes/sessions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAqBH,eAAO,MAAM,cAAc,4CAAW,CAAC;AAEvC;;;GAGG;AACH,wBAAgB,qCAAqC,CAAC,aAAa,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,EAAE,wBAAwB,CAAC,EAAE,MAAM,GAAG,MAAM,CAgBtJ"}
|
package/dist/routes/sessions.js
CHANGED
|
@@ -17,9 +17,16 @@ export const sessionsRouter = Router();
|
|
|
17
17
|
* 解析 active SDK 会话快照状态。
|
|
18
18
|
* 主流程:优先使用 adapter 细粒度状态,其次使用 terminal 路由内存里的最近 runtimeStatus,最后兼容旧会话回退 running。
|
|
19
19
|
*/
|
|
20
|
-
export function resolveActiveSdkSessionSnapshotStatus(adapterStatus, currentRuntimeStatus) {
|
|
20
|
+
export function resolveActiveSdkSessionSnapshotStatus(adapterStatus, currentRuntimeStatus, currentRuntimeActionType) {
|
|
21
21
|
const normalizedAdapterStatus = String(adapterStatus || '').trim();
|
|
22
22
|
if (normalizedAdapterStatus) {
|
|
23
|
+
const normalizedRuntimeStatus = String(currentRuntimeStatus || '').trim();
|
|
24
|
+
const normalizedActionType = String(currentRuntimeActionType || '').trim().toLowerCase();
|
|
25
|
+
if (normalizedAdapterStatus.toLowerCase() === 'tool_using' &&
|
|
26
|
+
normalizedRuntimeStatus.toLowerCase() === 'waiting_input' &&
|
|
27
|
+
normalizedActionType === 'idle') {
|
|
28
|
+
return normalizedRuntimeStatus;
|
|
29
|
+
}
|
|
23
30
|
return normalizedAdapterStatus;
|
|
24
31
|
}
|
|
25
32
|
const normalizedRuntimeStatus = String(currentRuntimeStatus || '').trim();
|
|
@@ -34,7 +41,7 @@ sessionsRouter.get('/sessions', validateToken, async (_req, res) => {
|
|
|
34
41
|
// 1. 获取 SDK 会话
|
|
35
42
|
const activeSdkSessions = Array.from(sdkSessions.entries()).map(([sessionId, entry]) => {
|
|
36
43
|
const adapter = adapterRegistry.get(entry.providerId || 'claude-code');
|
|
37
|
-
const status = resolveActiveSdkSessionSnapshotStatus(adapter.getSessionStatus(sessionId), entry.currentRuntimeStatus);
|
|
44
|
+
const status = resolveActiveSdkSessionSnapshotStatus(adapter.getSessionStatus(sessionId), entry.currentRuntimeStatus, entry.currentRuntimeActionType);
|
|
38
45
|
return {
|
|
39
46
|
sessionId,
|
|
40
47
|
agentId: entry.agentId,
|
|
@@ -83,7 +90,7 @@ sessionsRouter.post('/sessions/recover', validateToken, async (req, res) => {
|
|
|
83
90
|
const existingSdkSession = Array.from(sdkSessions.entries()).find(([, s]) => s.agentId === agentId);
|
|
84
91
|
if (existingSdkSession) {
|
|
85
92
|
const adapter = adapterRegistry.get(existingSdkSession[1].providerId || 'claude-code');
|
|
86
|
-
const status = resolveActiveSdkSessionSnapshotStatus(adapter.getSessionStatus(existingSdkSession[0]), existingSdkSession[1].currentRuntimeStatus);
|
|
93
|
+
const status = resolveActiveSdkSessionSnapshotStatus(adapter.getSessionStatus(existingSdkSession[0]), existingSdkSession[1].currentRuntimeStatus, existingSdkSession[1].currentRuntimeActionType);
|
|
87
94
|
res.json({
|
|
88
95
|
ok: true,
|
|
89
96
|
sessionId: existingSdkSession[0],
|
|
@@ -361,7 +368,7 @@ sessionsRouter.get('/sessions/by-agent/:agentId', validateToken, async (req, res
|
|
|
361
368
|
if (activeSdkSession) {
|
|
362
369
|
const adapter = adapterRegistry.get(activeSdkSession[1].providerId || 'claude-code');
|
|
363
370
|
const pid = adapter.getSessionPid?.(activeSdkSession[0]);
|
|
364
|
-
const status = resolveActiveSdkSessionSnapshotStatus(adapter.getSessionStatus(activeSdkSession[0]), activeSdkSession[1].currentRuntimeStatus);
|
|
371
|
+
const status = resolveActiveSdkSessionSnapshotStatus(adapter.getSessionStatus(activeSdkSession[0]), activeSdkSession[1].currentRuntimeStatus, activeSdkSession[1].currentRuntimeActionType);
|
|
365
372
|
res.json({
|
|
366
373
|
ok: true,
|
|
367
374
|
sessionId: activeSdkSession[0],
|
|
@@ -54,6 +54,9 @@ describe('active SDK session snapshots', () => {
|
|
|
54
54
|
expect(resolveActiveSdkSessionSnapshotStatus('waiting_input', 'running')).toBe('waiting_input');
|
|
55
55
|
expect(resolveActiveSdkSessionSnapshotStatus('tool_using', undefined)).toBe('tool_using');
|
|
56
56
|
});
|
|
57
|
+
it('keeps idle listener snapshots in waiting_input even if adapter is temporarily tool_using', () => {
|
|
58
|
+
expect(resolveActiveSdkSessionSnapshotStatus('tool_using', 'waiting_input', 'idle')).toBe('waiting_input');
|
|
59
|
+
});
|
|
57
60
|
it('uses current runtime status when adapter status is unavailable', () => {
|
|
58
61
|
expect(resolveActiveSdkSessionSnapshotStatus(undefined, 'thinking')).toBe('thinking');
|
|
59
62
|
});
|
|
@@ -24,10 +24,36 @@ export interface SdkSessionEntry {
|
|
|
24
24
|
currentRuntimeActionDetail?: string;
|
|
25
25
|
}
|
|
26
26
|
export declare const sdkSessions: Map<string, SdkSessionEntry>;
|
|
27
|
+
export interface RuntimeStopOptions {
|
|
28
|
+
statusNotified: boolean;
|
|
29
|
+
reason: string | undefined;
|
|
30
|
+
}
|
|
31
|
+
export type RuntimeContextResetSupport = {
|
|
32
|
+
supported: true;
|
|
33
|
+
} | {
|
|
34
|
+
supported: false;
|
|
35
|
+
statusCode: number;
|
|
36
|
+
error: string;
|
|
37
|
+
};
|
|
38
|
+
export declare function resolveRuntimeContextResetSupport(providerId: string, hasResetContext: boolean): RuntimeContextResetSupport;
|
|
39
|
+
/**
|
|
40
|
+
* Decide whether SDK startup should wait for an external process PID.
|
|
41
|
+
* Main flow: in-process providers return immediately; external CLI providers keep PID probing for orphan cleanup.
|
|
42
|
+
*/
|
|
43
|
+
export declare function shouldProbeSdkProcessPid(providerId: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* 主流程:解析 runtime stop 请求的状态通知选项。
|
|
46
|
+
* 内部上下文重置可抑制 stopped 广播;普通手动停止默认继续通知调度端。
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseRuntimeStopOptions(body: unknown): RuntimeStopOptions;
|
|
27
49
|
export declare function resolveStatusChangeUsage(actionInfo?: RuntimeStatusActionInfo): {
|
|
28
50
|
inputTokens: number;
|
|
29
51
|
outputTokens: number;
|
|
30
52
|
} | undefined;
|
|
53
|
+
export declare function resolveStatusChangeRuntimeState(status: string, actionInfo?: RuntimeStatusActionInfo): {
|
|
54
|
+
status: string;
|
|
55
|
+
actionInfo?: RuntimeStatusActionInfo;
|
|
56
|
+
};
|
|
31
57
|
export declare function buildAcodeCommandOutputPath(workspacePath: string, now?: Date): string;
|
|
32
58
|
export declare function countTerminalOutputLines(output: string): number;
|
|
33
59
|
export declare function formatCommandOutputSpilloverNotice(outputPath: string, lineLimit?: number): string;
|
|
@@ -57,7 +83,7 @@ export declare function parseTerminalDirectoryChangeTarget(command: string): str
|
|
|
57
83
|
* 解析 SDK 会话对外展示状态。
|
|
58
84
|
* 主流程:优先使用 adapter 当前细粒度状态,其次使用路由内存记录的最近状态,最后才兼容旧会话回退 running。
|
|
59
85
|
*/
|
|
60
|
-
export declare function resolveSdkSessionDisplayStatus(adapterStatus?: string, currentRuntimeStatus?: string): string;
|
|
86
|
+
export declare function resolveSdkSessionDisplayStatus(adapterStatus?: string, currentRuntimeStatus?: string, currentRuntimeActionType?: string): string;
|
|
61
87
|
export interface PersistedSessionReuseDecision {
|
|
62
88
|
reusable: boolean;
|
|
63
89
|
reason: "active-pid" | "missing-pid" | "dead-pid" | "in-process-provider";
|
|
@@ -94,13 +120,7 @@ export declare function buildClaudeCodeLaunchConfig(savedClaudeConfig: {
|
|
|
94
120
|
export declare function buildToolResultTimelineActionInfo(event: ProviderEvent): RuntimeStatusActionInfo | undefined;
|
|
95
121
|
export declare function formatSdkOutputEvent(event: ProviderEvent): string | undefined;
|
|
96
122
|
export declare function buildSdkOutputMetadata(event: ProviderEvent): RuntimeOutputMetadata;
|
|
97
|
-
|
|
98
|
-
* 主干流程:把 provider 事件转换为面板运行状态。
|
|
99
|
-
*
|
|
100
|
-
* text_delta 表示助手正在生成;thinking 表示推理/内部过程。
|
|
101
|
-
* tool_use_start 表示正在执行工具;turn_complete 才表示真正空闲。
|
|
102
|
-
*/
|
|
103
|
-
export declare function resolveRuntimeStatusFromProviderEvent(event: ProviderEvent): {
|
|
123
|
+
export declare function resolveRuntimeStatusFromProviderEvent(event: ProviderEvent, currentRuntimeStatus?: string): {
|
|
104
124
|
status: string;
|
|
105
125
|
actionInfo?: RuntimeStatusActionInfo;
|
|
106
126
|
} | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAKxC,OAAO,EAOL,KAAK,oBAAoB,EAEzB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAG7B,MAAM,qBAAqB,CAAC;AAS7B,OAAO,EAIL,KAAK,qBAAqB,EAC3B,MAAM,+BAA+B,CAAC;AASvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,eAAO,MAAM,cAAc,4CAAW,CAAC;AAIvC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,oBAAoB,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAGD,eAAO,MAAM,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"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"}
|