aws-runtime-bridge 1.9.41 → 1.9.45
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/routes/file-browser.d.ts.map +1 -1
- package/dist/routes/file-browser.js +47 -1
- package/dist/routes/processes.d.ts.map +1 -1
- package/dist/routes/processes.js +7 -0
- package/dist/routes/sessions.js +4 -1
- package/dist/routes/terminal.d.ts +12 -0
- package/dist/routes/terminal.d.ts.map +1 -1
- package/dist/routes/terminal.js +40 -0
- package/dist/services/workspace-files.d.ts +48 -0
- package/dist/services/workspace-files.d.ts.map +1 -1
- package/dist/services/workspace-files.js +285 -0
- package/package/acode/dist/runtime.d.ts +11 -1
- package/package/acode/dist/runtime.d.ts.map +1 -1
- package/package/acode/dist/runtime.js +62 -11
- package/package/acode/dist/sub-agent-tools.d.ts.map +1 -1
- package/package/acode/dist/sub-agent-tools.js +5 -4
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +10 -0
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +33 -3
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +8 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.js +24 -21
- package/package/aws-client-agent-mcp/dist/message-buffer.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-browser.d.ts","sourceRoot":"","sources":["../../src/routes/file-browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"file-browser.d.ts","sourceRoot":"","sources":["../../src/routes/file-browser.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,OAAO,MAAM,MAAM,QAAQ,CAAC;AA2B5B,eAAO,MAAM,iBAAiB,4CAAW,CAAC;AAE1C,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAUhD,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,UAAU,mBAAmB;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,eAAe,EAAE,CAAC;CAC1B;AAMD,UAAU,iBAAkB,SAAQ,eAAe;IACjD,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,UAAU,qBAAsB,SAAQ,mBAAmB;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,IAAI,EAAE,iBAAiB,EAAE,CAAC;CAC3B;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,OAAO,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAiBD,wBAAgB,kCAAkC,CAAC,KAAK,EAAE,MAAM,CAAC,WAAW,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAUvI;AAED,wBAAgB,iCAAiC,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,EAAE,CAgBzF;AAyFD;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,SAAK,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAkB5F;AAoCD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAuBpE;AA6BD,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAWhH"}
|
|
@@ -10,7 +10,7 @@ import { Router } from 'express';
|
|
|
10
10
|
import multer from 'multer';
|
|
11
11
|
import { allowHostFileBrowser } from '../config.js';
|
|
12
12
|
import { validateToken } from '../middleware/auth.js';
|
|
13
|
-
import { chmodWorkspaceEntry, createWorkspaceEntry, deleteWorkspaceEntry, extractWorkspaceArchive, getWorkspaceEntryProperties, listWorkspaceDirectory, moveWorkspaceEntry, previewWorkspaceDocument, readWorkspaceFile, renameWorkspaceEntry, resolveWorkspaceDownloadTarget, streamWorkspaceDirectoryZip, uploadWorkspaceFiles, writeWorkspaceFile, } from '../services/workspace-files.js';
|
|
13
|
+
import { chmodWorkspaceEntry, createWorkspaceEntry, deleteWorkspaceEntry, extractWorkspaceArchive, getWorkspaceEntryProperties, listWorkspaceDirectory, moveWorkspaceEntry, previewWorkspaceDocument, readWorkspaceFile, renameWorkspaceEntry, replaceWorkspaceFiles, resolveWorkspaceDownloadTarget, searchWorkspaceFiles, streamWorkspaceDirectoryZip, uploadWorkspaceFiles, writeWorkspaceFile, } from '../services/workspace-files.js';
|
|
14
14
|
import { unwatchWorkspaceFile, watchWorkspaceFile } from '../services/workspace-watch.js';
|
|
15
15
|
import { createLogger } from '../utils/logger.js';
|
|
16
16
|
const log = createLogger('file-browser');
|
|
@@ -736,3 +736,49 @@ fileBrowserRouter.post('/workspace/extract', validateToken, async (req, res) =>
|
|
|
736
736
|
res.status(400).json({ error: err.message });
|
|
737
737
|
}
|
|
738
738
|
});
|
|
739
|
+
/**
|
|
740
|
+
* 在工作区范围内搜索文件内容。
|
|
741
|
+
* POST /api/file-browser/workspace/search
|
|
742
|
+
*/
|
|
743
|
+
fileBrowserRouter.post('/workspace/search', validateToken, async (req, res) => {
|
|
744
|
+
try {
|
|
745
|
+
const { workspacePath, keyword, fileMask, ignoreCase, maxResults, mode } = req.body || {};
|
|
746
|
+
const result = await searchWorkspaceFiles({
|
|
747
|
+
workspacePath: String(workspacePath || ''),
|
|
748
|
+
keyword: String(keyword || ''),
|
|
749
|
+
fileMask: fileMask !== undefined ? String(fileMask) : undefined,
|
|
750
|
+
ignoreCase: toBoolean(ignoreCase),
|
|
751
|
+
maxResults: typeof maxResults === 'number' ? maxResults : undefined,
|
|
752
|
+
mode: mode === 'filename' ? 'filename' : 'content'
|
|
753
|
+
});
|
|
754
|
+
res.json(result);
|
|
755
|
+
}
|
|
756
|
+
catch (error) {
|
|
757
|
+
const err = error;
|
|
758
|
+
log.error('failed to search workspace files:', err);
|
|
759
|
+
res.status(400).json({ error: err.message });
|
|
760
|
+
}
|
|
761
|
+
});
|
|
762
|
+
/**
|
|
763
|
+
* 在工作区范围内批量替换文件内容。
|
|
764
|
+
* POST /api/file-browser/workspace/replace
|
|
765
|
+
*/
|
|
766
|
+
fileBrowserRouter.post('/workspace/replace', validateToken, async (req, res) => {
|
|
767
|
+
try {
|
|
768
|
+
const { workspacePath, keyword, replacement, fileMask, ignoreCase, filePath } = req.body || {};
|
|
769
|
+
const result = await replaceWorkspaceFiles({
|
|
770
|
+
workspacePath: String(workspacePath || ''),
|
|
771
|
+
keyword: String(keyword || ''),
|
|
772
|
+
replacement: String(replacement ?? ''),
|
|
773
|
+
fileMask: fileMask !== undefined ? String(fileMask) : undefined,
|
|
774
|
+
ignoreCase: toBoolean(ignoreCase),
|
|
775
|
+
filePath: filePath !== undefined ? String(filePath) : undefined
|
|
776
|
+
});
|
|
777
|
+
res.json(result);
|
|
778
|
+
}
|
|
779
|
+
catch (error) {
|
|
780
|
+
const err = error;
|
|
781
|
+
log.error('failed to replace workspace files:', err);
|
|
782
|
+
res.status(400).json({ error: err.message });
|
|
783
|
+
}
|
|
784
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"processes.d.ts","sourceRoot":"","sources":["../../src/routes/processes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"processes.d.ts","sourceRoot":"","sources":["../../src/routes/processes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAWH,eAAO,MAAM,eAAe,4CAAW,CAAC"}
|
package/dist/routes/processes.js
CHANGED
|
@@ -8,6 +8,7 @@ import { validateToken } from '../middleware/auth.js';
|
|
|
8
8
|
import { getAgentProcessManager } from '../services/agent-process-manager.js';
|
|
9
9
|
import { discoverAllProcessesFull } from '../services/process-detector.js';
|
|
10
10
|
import { createLogger } from '../utils/logger.js';
|
|
11
|
+
import { cleanupSdkSessionByAgentId } from './terminal.js';
|
|
11
12
|
const log = createLogger('processes');
|
|
12
13
|
export const processesRouter = Router();
|
|
13
14
|
/**
|
|
@@ -158,6 +159,12 @@ processesRouter.post('/processes/:agentId/force-kill', validateToken, async (req
|
|
|
158
159
|
try {
|
|
159
160
|
const manager = getAgentProcessManager();
|
|
160
161
|
const result = await manager.forceKill(agentId);
|
|
162
|
+
// ★ 关键修复:强制终止后清理 bridge 内部内存状态
|
|
163
|
+
// 防止 sdkSessions 残留条目阻塞后续启动
|
|
164
|
+
const cleanedSessionId = cleanupSdkSessionByAgentId(agentId);
|
|
165
|
+
if (cleanedSessionId) {
|
|
166
|
+
log.info(`[processes/force-kill] Cleaned up SDK session after force-kill: agentId=${agentId}, sessionId=${cleanedSessionId}`);
|
|
167
|
+
}
|
|
161
168
|
res.json({
|
|
162
169
|
ok: result.success,
|
|
163
170
|
agentId,
|
package/dist/routes/sessions.js
CHANGED
|
@@ -10,7 +10,7 @@ import { validateToken } from '../middleware/auth.js';
|
|
|
10
10
|
import { isProcessRunning, findOrphanProcessByAgentId, findOrphanProcessByWorkspace } from '../services/process-detector.js';
|
|
11
11
|
import { findPersistedSessionByAgentId, loadPersistedSessions, removePersistedSession, } from '../services/terminal-persistence.js';
|
|
12
12
|
import { createLogger } from '../utils/logger.js';
|
|
13
|
-
import { sdkSessions } from './terminal.js';
|
|
13
|
+
import { sdkSessions, cleanupSdkSessionByAgentId } from './terminal.js';
|
|
14
14
|
const log = createLogger('sessions');
|
|
15
15
|
export const sessionsRouter = Router();
|
|
16
16
|
/**
|
|
@@ -670,6 +670,9 @@ sessionsRouter.post('/terminate-tree', validateToken, async (req, res) => {
|
|
|
670
670
|
const result = await terminateProcessTree(pid);
|
|
671
671
|
// 4. 等待进程完全终止(最多 5 秒)
|
|
672
672
|
const exited = await waitForProcessExit(pid, 5000);
|
|
673
|
+
// ★ 关键修复:terminate-tree 后清理 bridge 内部内存状态
|
|
674
|
+
// 防止 sdkSessions 残留条目阻塞后续启动
|
|
675
|
+
cleanupSdkSessionByAgentId(agentId);
|
|
673
676
|
// 5. 清理持久化状�?
|
|
674
677
|
await import('../services/terminal-persistence.js').then(m => m.removePersistedSession(targetSessionId));
|
|
675
678
|
log.info(`[terminate-tree] Terminated process tree for agentId=${agentId}, pid=${pid}, mode=${mode}, terminated=${result.terminated}, failed=${result.failed}, exited=${exited}`);
|
|
@@ -117,6 +117,18 @@ export interface PersistedSessionReuseDecision {
|
|
|
117
117
|
* Main flow: require a live PID, then reject in-process providers whose adapter control channel cannot be restored.
|
|
118
118
|
*/
|
|
119
119
|
export declare function evaluatePersistedSessionReuse(session: Pick<PersistedSession, "pid"> & Partial<Pick<PersistedSession, "command">>, isPidRunning?: (pid: number) => boolean): PersistedSessionReuseDecision;
|
|
120
|
+
/**
|
|
121
|
+
* 根据 agentId 清理 SDK 会话的所有内存状态。
|
|
122
|
+
*
|
|
123
|
+
* 用于强制停止(force-kill)场景:当进程已被外部/强制手段终止后,
|
|
124
|
+
* 此函数清理 bridge 内部的内存残留(sdkSessions、statusRefreshTimers、
|
|
125
|
+
* startingAgents、terminalCommandStates),防止下次启动时
|
|
126
|
+
* findActiveSdkSessionByAgentId 命中旧条目导致「无法上线」。
|
|
127
|
+
*
|
|
128
|
+
* @param agentId - 要清理的 Agent ID
|
|
129
|
+
* @returns 如果找到并清理了会话则返回 sessionId,否则返回 undefined
|
|
130
|
+
*/
|
|
131
|
+
export declare function cleanupSdkSessionByAgentId(agentId: string): string | undefined;
|
|
120
132
|
/**
|
|
121
133
|
* 生成显示在终端输出流中的工作目录提示符。
|
|
122
134
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"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"}
|
package/dist/routes/terminal.js
CHANGED
|
@@ -551,6 +551,46 @@ export function evaluatePersistedSessionReuse(session, isPidRunning = isProcessR
|
|
|
551
551
|
}
|
|
552
552
|
return { reusable: true, reason: "active-pid" };
|
|
553
553
|
}
|
|
554
|
+
/**
|
|
555
|
+
* 根据 agentId 清理 SDK 会话的所有内存状态。
|
|
556
|
+
*
|
|
557
|
+
* 用于强制停止(force-kill)场景:当进程已被外部/强制手段终止后,
|
|
558
|
+
* 此函数清理 bridge 内部的内存残留(sdkSessions、statusRefreshTimers、
|
|
559
|
+
* startingAgents、terminalCommandStates),防止下次启动时
|
|
560
|
+
* findActiveSdkSessionByAgentId 命中旧条目导致「无法上线」。
|
|
561
|
+
*
|
|
562
|
+
* @param agentId - 要清理的 Agent ID
|
|
563
|
+
* @returns 如果找到并清理了会话则返回 sessionId,否则返回 undefined
|
|
564
|
+
*/
|
|
565
|
+
export function cleanupSdkSessionByAgentId(agentId) {
|
|
566
|
+
// 1. 从 sdkSessions 查找该 agentId 的会话
|
|
567
|
+
const entry = findActiveSdkSessionByAgentId(agentId);
|
|
568
|
+
if (!entry) {
|
|
569
|
+
// 可能不在 sdkSessions 中但还在 other 状态缓存里,继续清理
|
|
570
|
+
log.info(`[cleanupSdkSessionByAgentId] No active SDK session found for agentId=${agentId}, cleaning residual state anyway`);
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
const sessionId = entry.sessionId;
|
|
574
|
+
log.info(`[cleanupSdkSessionByAgentId] Cleaning up SDK session for agentId=${agentId}, sessionId=${sessionId}`);
|
|
575
|
+
// 2. 停止状态刷新定时器
|
|
576
|
+
stopStatusRefresh(sessionId);
|
|
577
|
+
// 3. 从 sdkSessions 中移除
|
|
578
|
+
sdkSessions.delete(sessionId);
|
|
579
|
+
// 4. 清理终端命令进程
|
|
580
|
+
stopTerminalCommandProcess(sessionId);
|
|
581
|
+
// 5. 清理持久化会话
|
|
582
|
+
removePersistedSession(sessionId).catch((err) => {
|
|
583
|
+
log.warn(`[cleanupSdkSessionByAgentId] Failed to remove persisted session for agentId=${agentId}: ${err}`);
|
|
584
|
+
});
|
|
585
|
+
return sessionId;
|
|
586
|
+
}
|
|
587
|
+
// 6. 确保 startingAgents 锁也被释放(防止 Phase 1 锁定后进程被杀导致锁残留)
|
|
588
|
+
if (startingAgents.has(agentId)) {
|
|
589
|
+
startingAgents.delete(agentId);
|
|
590
|
+
log.info(`[cleanupSdkSessionByAgentId] Released startingAgents lock for agentId=${agentId}`);
|
|
591
|
+
}
|
|
592
|
+
return undefined;
|
|
593
|
+
}
|
|
554
594
|
function stopTerminalCommandProcess(sessionId) {
|
|
555
595
|
const state = terminalCommandStates.get(sessionId);
|
|
556
596
|
if (!state?.runningProcess) {
|
|
@@ -90,6 +90,44 @@ interface ChmodWorkspaceEntryParams extends WorkspacePathParams {
|
|
|
90
90
|
mode: string;
|
|
91
91
|
recursive?: boolean;
|
|
92
92
|
}
|
|
93
|
+
export interface SearchWorkspaceFilesParams {
|
|
94
|
+
workspacePath: string;
|
|
95
|
+
keyword: string;
|
|
96
|
+
fileMask?: string;
|
|
97
|
+
ignoreCase?: boolean;
|
|
98
|
+
maxResults?: number;
|
|
99
|
+
mode?: 'content' | 'filename';
|
|
100
|
+
}
|
|
101
|
+
export interface WorkspaceSearchMatch {
|
|
102
|
+
filePath: string;
|
|
103
|
+
lineNumber: number;
|
|
104
|
+
lineContent: string;
|
|
105
|
+
matchStart: number;
|
|
106
|
+
matchEnd: number;
|
|
107
|
+
}
|
|
108
|
+
export interface SearchWorkspaceFilesResult {
|
|
109
|
+
workspacePath: string;
|
|
110
|
+
keyword: string;
|
|
111
|
+
totalFiles: number;
|
|
112
|
+
totalMatches: number;
|
|
113
|
+
matches: WorkspaceSearchMatch[];
|
|
114
|
+
truncated: boolean;
|
|
115
|
+
}
|
|
116
|
+
export interface ReplaceWorkspaceFilesParams {
|
|
117
|
+
workspacePath: string;
|
|
118
|
+
keyword: string;
|
|
119
|
+
replacement: string;
|
|
120
|
+
fileMask?: string;
|
|
121
|
+
ignoreCase?: boolean;
|
|
122
|
+
filePath?: string;
|
|
123
|
+
}
|
|
124
|
+
export interface ReplaceWorkspaceFilesResult {
|
|
125
|
+
workspacePath: string;
|
|
126
|
+
keyword: string;
|
|
127
|
+
replacement: string;
|
|
128
|
+
changedFiles: number;
|
|
129
|
+
changedMatches: number;
|
|
130
|
+
}
|
|
93
131
|
export interface WorkspaceImageProperties {
|
|
94
132
|
format: 'png' | 'jpeg' | 'gif' | 'webp';
|
|
95
133
|
width: number;
|
|
@@ -216,5 +254,15 @@ export declare function streamWorkspaceDirectoryZip(directoryPath: string, outpu
|
|
|
216
254
|
* 解压工作区中的归档文件到指定目录,支持 zip、tar、tar.gz/tgz 与单文件 gz。
|
|
217
255
|
*/
|
|
218
256
|
export declare function extractWorkspaceArchive(params: ExtractWorkspaceArchiveParams): Promise<WorkspaceArchiveExtractResult>;
|
|
257
|
+
/**
|
|
258
|
+
* 在工作区范围内搜索文件内容。
|
|
259
|
+
* 主流程:安全解析工作区根 -> 递归遍历目录 -> 按文件掩码过滤 -> 逐行匹配关键词 -> 返回匹配列表。
|
|
260
|
+
*/
|
|
261
|
+
export declare function searchWorkspaceFiles(params: SearchWorkspaceFilesParams): Promise<SearchWorkspaceFilesResult>;
|
|
262
|
+
/**
|
|
263
|
+
* 在工作区范围内批量替换文件内容。
|
|
264
|
+
* 可指定 filePath 只替换单个文件;未指定时递归替换所有匹配掩码的文件。
|
|
265
|
+
*/
|
|
266
|
+
export declare function replaceWorkspaceFiles(params: ReplaceWorkspaceFilesParams): Promise<ReplaceWorkspaceFilesResult>;
|
|
219
267
|
export {};
|
|
220
268
|
//# sourceMappingURL=workspace-files.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-files.d.ts","sourceRoot":"","sources":["../../src/services/workspace-files.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"workspace-files.d.ts","sourceRoot":"","sources":["../../src/services/workspace-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -988,3 +988,288 @@ export async function extractWorkspaceArchive(params) {
|
|
|
988
988
|
extractedEntries
|
|
989
989
|
};
|
|
990
990
|
}
|
|
991
|
+
/**
|
|
992
|
+
* 展开简单花括号模式,如 *.{ts,tsx} -> *.ts, *.tsx。
|
|
993
|
+
*/
|
|
994
|
+
function expandBracePattern(pattern) {
|
|
995
|
+
const match = pattern.match(/^(.*?)\{([^}]+)\}(.*)$/);
|
|
996
|
+
if (!match) {
|
|
997
|
+
return [pattern];
|
|
998
|
+
}
|
|
999
|
+
const [, prefix, options, suffix] = match;
|
|
1000
|
+
return options.split(',').flatMap((option) => expandBracePattern(prefix + option.trim() + suffix));
|
|
1001
|
+
}
|
|
1002
|
+
/**
|
|
1003
|
+
* 判断文件名是否匹配简单 glob 掩码(支持 *、?、** 与 {a,b,c})。
|
|
1004
|
+
*/
|
|
1005
|
+
function matchesFileMask(fileName, mask) {
|
|
1006
|
+
const normalizedMask = String(mask || '').trim();
|
|
1007
|
+
if (!normalizedMask || normalizedMask === '*' || normalizedMask === '*.*') {
|
|
1008
|
+
return true;
|
|
1009
|
+
}
|
|
1010
|
+
const normalizedFileName = fileName.toLowerCase();
|
|
1011
|
+
const patterns = expandBracePattern(normalizedMask.toLowerCase());
|
|
1012
|
+
return patterns.some((pattern) => {
|
|
1013
|
+
if (pattern === '*')
|
|
1014
|
+
return true;
|
|
1015
|
+
const regexSource = pattern
|
|
1016
|
+
.replace(/\./g, '\\.')
|
|
1017
|
+
.replace(/\*\*/g, '<<GLOBSTAR>>')
|
|
1018
|
+
.replace(/\*/g, '[^/]*')
|
|
1019
|
+
.replace(/\?/g, '[^/]')
|
|
1020
|
+
.replace(/<<GLOBSTAR>>/g, '.*');
|
|
1021
|
+
const regex = new RegExp(`^${regexSource}$`);
|
|
1022
|
+
return regex.test(normalizedFileName);
|
|
1023
|
+
});
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* 跳过明显不适合文本搜索/替换的目录。
|
|
1027
|
+
*/
|
|
1028
|
+
function isSkippedSearchDirectory(name) {
|
|
1029
|
+
return name === '.git' || name === 'node_modules' || name === '.svn' || name === '.hg';
|
|
1030
|
+
}
|
|
1031
|
+
const SEARCH_MAX_FILE_BYTES = 10 * 1024 * 1024;
|
|
1032
|
+
const SEARCH_DEFAULT_MAX_RESULTS = 1000;
|
|
1033
|
+
/**
|
|
1034
|
+
* 在工作区范围内搜索文件内容。
|
|
1035
|
+
* 主流程:安全解析工作区根 -> 递归遍历目录 -> 按文件掩码过滤 -> 逐行匹配关键词 -> 返回匹配列表。
|
|
1036
|
+
*/
|
|
1037
|
+
export async function searchWorkspaceFiles(params) {
|
|
1038
|
+
const { workspaceRoot } = await resolveWorkspaceRoots(params.workspacePath);
|
|
1039
|
+
const keyword = String(params.keyword || '').trim();
|
|
1040
|
+
if (!keyword) {
|
|
1041
|
+
throw new Error('keyword is required');
|
|
1042
|
+
}
|
|
1043
|
+
const ignoreCase = Boolean(params.ignoreCase);
|
|
1044
|
+
const fileMask = String(params.fileMask || '').trim();
|
|
1045
|
+
const maxResults = typeof params.maxResults === 'number' && params.maxResults > 0
|
|
1046
|
+
? params.maxResults
|
|
1047
|
+
: SEARCH_DEFAULT_MAX_RESULTS;
|
|
1048
|
+
const searchKeyword = ignoreCase ? keyword.toLowerCase() : keyword;
|
|
1049
|
+
const mode = params.mode === 'filename' ? 'filename' : 'content';
|
|
1050
|
+
const isFilenameMode = mode === 'filename';
|
|
1051
|
+
const matches = [];
|
|
1052
|
+
let totalFiles = 0;
|
|
1053
|
+
let truncated = false;
|
|
1054
|
+
async function walk(directoryPath) {
|
|
1055
|
+
if (truncated)
|
|
1056
|
+
return;
|
|
1057
|
+
let entries;
|
|
1058
|
+
try {
|
|
1059
|
+
entries = await fs.readdir(directoryPath, { withFileTypes: true });
|
|
1060
|
+
}
|
|
1061
|
+
catch {
|
|
1062
|
+
return;
|
|
1063
|
+
}
|
|
1064
|
+
for (const entry of entries) {
|
|
1065
|
+
if (truncated)
|
|
1066
|
+
return;
|
|
1067
|
+
const entryPath = ensureInsideWorkspace(workspaceRoot, path.join(directoryPath, entry.name));
|
|
1068
|
+
if (entry.isSymbolicLink())
|
|
1069
|
+
continue;
|
|
1070
|
+
if (entry.isDirectory()) {
|
|
1071
|
+
if (isSkippedSearchDirectory(entry.name))
|
|
1072
|
+
continue;
|
|
1073
|
+
await walk(entryPath);
|
|
1074
|
+
continue;
|
|
1075
|
+
}
|
|
1076
|
+
if (!entry.isFile())
|
|
1077
|
+
continue;
|
|
1078
|
+
if (fileMask && !matchesFileMask(entry.name, fileMask))
|
|
1079
|
+
continue;
|
|
1080
|
+
totalFiles += 1;
|
|
1081
|
+
let stat;
|
|
1082
|
+
try {
|
|
1083
|
+
stat = await fs.stat(entryPath);
|
|
1084
|
+
}
|
|
1085
|
+
catch {
|
|
1086
|
+
continue;
|
|
1087
|
+
}
|
|
1088
|
+
if (stat.size > SEARCH_MAX_FILE_BYTES)
|
|
1089
|
+
continue;
|
|
1090
|
+
if (isFilenameMode) {
|
|
1091
|
+
const searchName = ignoreCase ? entry.name.toLowerCase() : entry.name;
|
|
1092
|
+
const matchIndex = searchName.indexOf(searchKeyword);
|
|
1093
|
+
if (matchIndex !== -1) {
|
|
1094
|
+
matches.push({
|
|
1095
|
+
filePath: toDisplayPath(entryPath),
|
|
1096
|
+
lineNumber: 0,
|
|
1097
|
+
lineContent: entry.name,
|
|
1098
|
+
matchStart: matchIndex,
|
|
1099
|
+
matchEnd: matchIndex + keyword.length
|
|
1100
|
+
});
|
|
1101
|
+
if (matches.length >= maxResults) {
|
|
1102
|
+
truncated = true;
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
continue;
|
|
1107
|
+
}
|
|
1108
|
+
let content;
|
|
1109
|
+
try {
|
|
1110
|
+
content = await fs.readFile(entryPath, 'utf-8');
|
|
1111
|
+
}
|
|
1112
|
+
catch {
|
|
1113
|
+
continue;
|
|
1114
|
+
}
|
|
1115
|
+
const lines = content.split(/\r?\n/);
|
|
1116
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
|
|
1117
|
+
const line = lines[lineIndex];
|
|
1118
|
+
const searchLine = ignoreCase ? line.toLowerCase() : line;
|
|
1119
|
+
let searchIndex = 0;
|
|
1120
|
+
while (true) {
|
|
1121
|
+
const matchIndex = searchLine.indexOf(searchKeyword, searchIndex);
|
|
1122
|
+
if (matchIndex === -1)
|
|
1123
|
+
break;
|
|
1124
|
+
matches.push({
|
|
1125
|
+
filePath: toDisplayPath(entryPath),
|
|
1126
|
+
lineNumber: lineIndex + 1,
|
|
1127
|
+
lineContent: line,
|
|
1128
|
+
matchStart: matchIndex,
|
|
1129
|
+
matchEnd: matchIndex + keyword.length
|
|
1130
|
+
});
|
|
1131
|
+
if (matches.length >= maxResults) {
|
|
1132
|
+
truncated = true;
|
|
1133
|
+
return;
|
|
1134
|
+
}
|
|
1135
|
+
searchIndex = matchIndex + 1;
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
await walk(workspaceRoot);
|
|
1141
|
+
return {
|
|
1142
|
+
workspacePath: toDisplayPath(workspaceRoot),
|
|
1143
|
+
keyword,
|
|
1144
|
+
totalFiles,
|
|
1145
|
+
totalMatches: matches.length,
|
|
1146
|
+
matches,
|
|
1147
|
+
truncated
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* 在单个文件内执行安全替换,只写入确实有变化的内容。
|
|
1152
|
+
*/
|
|
1153
|
+
async function replaceInFile(workspaceRoot, filePath, keyword, replacement, ignoreCase) {
|
|
1154
|
+
let content;
|
|
1155
|
+
try {
|
|
1156
|
+
content = await fs.readFile(filePath, 'utf-8');
|
|
1157
|
+
}
|
|
1158
|
+
catch {
|
|
1159
|
+
return { changed: false, count: 0 };
|
|
1160
|
+
}
|
|
1161
|
+
const originalContent = content;
|
|
1162
|
+
let count = 0;
|
|
1163
|
+
if (ignoreCase) {
|
|
1164
|
+
const lowerKeyword = keyword.toLowerCase();
|
|
1165
|
+
let index = 0;
|
|
1166
|
+
while (true) {
|
|
1167
|
+
const lowerContent = content.toLowerCase();
|
|
1168
|
+
const matchIndex = lowerContent.indexOf(lowerKeyword, index);
|
|
1169
|
+
if (matchIndex === -1)
|
|
1170
|
+
break;
|
|
1171
|
+
content = content.slice(0, matchIndex) + replacement + content.slice(matchIndex + keyword.length);
|
|
1172
|
+
count += 1;
|
|
1173
|
+
const step = replacement.length || 1;
|
|
1174
|
+
index = matchIndex + step;
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
else {
|
|
1178
|
+
let index = 0;
|
|
1179
|
+
while (true) {
|
|
1180
|
+
const matchIndex = content.indexOf(keyword, index);
|
|
1181
|
+
if (matchIndex === -1)
|
|
1182
|
+
break;
|
|
1183
|
+
content = content.slice(0, matchIndex) + replacement + content.slice(matchIndex + keyword.length);
|
|
1184
|
+
count += 1;
|
|
1185
|
+
const step = replacement.length || 1;
|
|
1186
|
+
index = matchIndex + step;
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
if (content === originalContent) {
|
|
1190
|
+
return { changed: false, count: 0 };
|
|
1191
|
+
}
|
|
1192
|
+
await ensureWritableParentInsideWorkspace(workspaceRoot, filePath);
|
|
1193
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
|
1194
|
+
return { changed: true, count };
|
|
1195
|
+
}
|
|
1196
|
+
/**
|
|
1197
|
+
* 在工作区范围内批量替换文件内容。
|
|
1198
|
+
* 可指定 filePath 只替换单个文件;未指定时递归替换所有匹配掩码的文件。
|
|
1199
|
+
*/
|
|
1200
|
+
export async function replaceWorkspaceFiles(params) {
|
|
1201
|
+
const { workspaceRoot } = await resolveWorkspaceRoots(params.workspacePath);
|
|
1202
|
+
const keyword = String(params.keyword || '').trim();
|
|
1203
|
+
if (!keyword) {
|
|
1204
|
+
throw new Error('keyword is required');
|
|
1205
|
+
}
|
|
1206
|
+
const replacement = String(params.replacement ?? '');
|
|
1207
|
+
const ignoreCase = Boolean(params.ignoreCase);
|
|
1208
|
+
const fileMask = String(params.fileMask || '').trim();
|
|
1209
|
+
const singleFilePath = String(params.filePath || '').trim();
|
|
1210
|
+
let changedFiles = 0;
|
|
1211
|
+
let changedMatches = 0;
|
|
1212
|
+
if (singleFilePath) {
|
|
1213
|
+
const { resolvedFilePath } = await resolveFileTarget({
|
|
1214
|
+
workspacePath: params.workspacePath,
|
|
1215
|
+
filePath: singleFilePath
|
|
1216
|
+
});
|
|
1217
|
+
const result = await replaceInFile(workspaceRoot, resolvedFilePath, keyword, replacement, ignoreCase);
|
|
1218
|
+
if (result.changed) {
|
|
1219
|
+
changedFiles = 1;
|
|
1220
|
+
changedMatches = result.count;
|
|
1221
|
+
}
|
|
1222
|
+
return {
|
|
1223
|
+
workspacePath: toDisplayPath(workspaceRoot),
|
|
1224
|
+
keyword,
|
|
1225
|
+
replacement,
|
|
1226
|
+
changedFiles,
|
|
1227
|
+
changedMatches
|
|
1228
|
+
};
|
|
1229
|
+
}
|
|
1230
|
+
async function walk(directoryPath) {
|
|
1231
|
+
let entries;
|
|
1232
|
+
try {
|
|
1233
|
+
entries = await fs.readdir(directoryPath, { withFileTypes: true });
|
|
1234
|
+
}
|
|
1235
|
+
catch {
|
|
1236
|
+
return;
|
|
1237
|
+
}
|
|
1238
|
+
for (const entry of entries) {
|
|
1239
|
+
const entryPath = ensureInsideWorkspace(workspaceRoot, path.join(directoryPath, entry.name));
|
|
1240
|
+
if (entry.isSymbolicLink())
|
|
1241
|
+
continue;
|
|
1242
|
+
if (entry.isDirectory()) {
|
|
1243
|
+
if (isSkippedSearchDirectory(entry.name))
|
|
1244
|
+
continue;
|
|
1245
|
+
await walk(entryPath);
|
|
1246
|
+
continue;
|
|
1247
|
+
}
|
|
1248
|
+
if (!entry.isFile())
|
|
1249
|
+
continue;
|
|
1250
|
+
if (fileMask && !matchesFileMask(entry.name, fileMask))
|
|
1251
|
+
continue;
|
|
1252
|
+
try {
|
|
1253
|
+
const stat = await fs.stat(entryPath);
|
|
1254
|
+
if (stat.size > SEARCH_MAX_FILE_BYTES)
|
|
1255
|
+
continue;
|
|
1256
|
+
}
|
|
1257
|
+
catch {
|
|
1258
|
+
continue;
|
|
1259
|
+
}
|
|
1260
|
+
const result = await replaceInFile(workspaceRoot, entryPath, keyword, replacement, ignoreCase);
|
|
1261
|
+
if (result.changed) {
|
|
1262
|
+
changedFiles += 1;
|
|
1263
|
+
changedMatches += result.count;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
await walk(workspaceRoot);
|
|
1268
|
+
return {
|
|
1269
|
+
workspacePath: toDisplayPath(workspaceRoot),
|
|
1270
|
+
keyword,
|
|
1271
|
+
replacement,
|
|
1272
|
+
changedFiles,
|
|
1273
|
+
changedMatches
|
|
1274
|
+
};
|
|
1275
|
+
}
|
|
@@ -29,6 +29,14 @@ export declare class ACodeRuntime extends EventEmitter {
|
|
|
29
29
|
* 子 agent 完成后通过 SubAgentManager 事件回调移除对应 URI。
|
|
30
30
|
*/
|
|
31
31
|
private readonly pendingMemorySubAgents;
|
|
32
|
+
/**
|
|
33
|
+
* memory 委托冷却表(「已解决/已处理」守卫,区别于 pendingMemorySubAgents 的「进行中」守卫)。
|
|
34
|
+
* key = memory URI,value = 冷却到期时间戳(ms)。
|
|
35
|
+
* 子 agent 进入终态时写入;冷却期内即使 memory 仍待处理也不再 spawn 新子任务。
|
|
36
|
+
* 这是切断「委托完成→复发」循环的关键:原实现只有进行中守卫,子 agent 一结束 URI 立即释放,
|
|
37
|
+
* 导致下一轮 poll 对 sticky 的 updating memory 再次委托。
|
|
38
|
+
*/
|
|
39
|
+
private readonly memoryDelegateCooldownUntil;
|
|
32
40
|
private submitQueue;
|
|
33
41
|
private activeTurn;
|
|
34
42
|
private abortRequested;
|
|
@@ -221,7 +229,9 @@ export declare class ACodeRuntime extends EventEmitter {
|
|
|
221
229
|
/**
|
|
222
230
|
* 通过 MCP read_memory 工具读取单条 memory 记录。
|
|
223
231
|
* 注入 _aws_sub_agent=true 避免状态上报污染父 agent 时间线。
|
|
224
|
-
* 返回 null 表示 memory
|
|
232
|
+
* 返回 null 表示 memory 明确不存在(服务端返回 null/undefined 或非对象)。
|
|
233
|
+
* 读取/解析异常(网络抖动、超时、服务端错误)会向上抛出,交由 recheckMemoryDelegate
|
|
234
|
+
* 统一判定为「未完成」,避免被误当作「已处理」。
|
|
225
235
|
*/
|
|
226
236
|
private readMemoryViaMcp;
|
|
227
237
|
/** recheck memory_file_change:检查 memory_status 是否仍为 updating */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAInE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAE/E,OAAO,EAIL,KAAK,UAAU,EAChB,MAAM,0BAA0B,CAAC;AA+BlC,OAAO,KAAK,EAOV,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,KAAK,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,UAAU,CAAC;CACzB;
|
|
1
|
+
{"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../src/runtime.ts"],"names":[],"mappings":"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"}
|