aws-runtime-bridge 1.7.47 → 1.7.49
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/OpencodeSdkAdapter.d.ts +1 -1
- package/dist/adapter/OpencodeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/OpencodeSdkAdapter.js +11 -7
- package/dist/adapter/types.d.ts +14 -0
- package/dist/adapter/types.d.ts.map +1 -1
- package/dist/adapter/types.js +46 -2
- package/dist/adapter/types.test.js +33 -1
- package/dist/routes/runtime-binding.d.ts +17 -0
- package/dist/routes/runtime-binding.d.ts.map +1 -1
- package/dist/routes/runtime-binding.js +59 -15
- package/dist/routes/runtime-binding.test.d.ts +2 -0
- package/dist/routes/runtime-binding.test.d.ts.map +1 -0
- package/dist/routes/runtime-binding.test.js +108 -0
- package/dist/routes/terminal.d.ts +15 -0
- package/dist/routes/terminal.d.ts.map +1 -1
- package/dist/routes/terminal.js +82 -5
- package/dist/routes/terminal.test.js +51 -1
- package/dist/services/ai-source-apply.d.ts.map +1 -1
- package/dist/services/ai-source-apply.js +30 -9
- package/dist/services/ai-source-apply.test.js +50 -0
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts +1 -0
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts.map +1 -1
- package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.js +2 -1
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +10 -0
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.js +25 -1
- package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.test.js +49 -0
- package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.js +29 -10
- package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.test.js +25 -8
- package/package/aws-client-agent-mcp/dist/http-client.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.d.ts +5 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.js +23 -8
- package/package/aws-client-agent-mcp/dist/status-reporter.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/status-reporter.test.js +46 -0
- package/package/aws-client-agent-mcp/dist/status-reporter.test.js.map +1 -1
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts +1 -0
- package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts.map +1 -1
- package/package/cc-switch-sdk/dist/services/ai-config-service.js +2 -1
- package/package.json +1 -1
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* 参考:spectrai-community/src/main/adapter/OpenCodeSdkAdapter.ts
|
|
12
12
|
*/
|
|
13
13
|
import { EventEmitter } from 'node:events';
|
|
14
|
-
import type
|
|
14
|
+
import { type AdapterSessionConfig, type BaseProviderAdapter, type ConversationMessage, type SessionStatus } from './types.js';
|
|
15
15
|
export declare class OpencodeSdkAdapter extends EventEmitter implements BaseProviderAdapter {
|
|
16
16
|
readonly providerId = "opencode";
|
|
17
17
|
readonly displayName = "OpenCode";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"OpencodeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/OpencodeSdkAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"OpencodeSdkAdapter.d.ts","sourceRoot":"","sources":["../../src/adapter/OpencodeSdkAdapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAiB3C,OAAO,EAKL,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EAExB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AA4GpB,qBAAa,kBAAmB,SAAQ,YAAa,YAAW,mBAAmB;IACjF,QAAQ,CAAC,UAAU,cAAc;IACjC,QAAQ,CAAC,WAAW,cAAc;IAElC,OAAO,CAAC,QAAQ,CAA2C;IAC3D,OAAO,CAAC,SAAS,CAAC,CAAoB;IAEhC,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+I5E,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CzG,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBnE,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7F,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE;QAAE,gBAAgB,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAUnG,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAclD,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA4BxD,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,mBAAmB,EAAE;IAIzD,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAItC,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3D,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAI9D,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAOpD,OAAO,IAAI,IAAI;IAaf;;;OAGG;YACW,OAAO;YA2BP,aAAa;IAmB3B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAahC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,YAAY;YAYN,UAAU;IAuBxB,OAAO,CAAC,mBAAmB;IA6H3B,OAAO,CAAC,gBAAgB;IAkHxB,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,kBAAkB;IAqC1B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,2BAA2B;CAOpC"}
|
|
@@ -19,7 +19,7 @@ import * as path from 'node:path';
|
|
|
19
19
|
import { v4 as uuidv4 } from 'uuid';
|
|
20
20
|
import { BRIDGE_PACKAGE_ROOT, importBridgeSdkPackage } from '../utils/sdk-package-loader.js';
|
|
21
21
|
import { IdlePollLoop } from './idle-poll-loop.js';
|
|
22
|
-
import { getToolActionInfo } from './types.js';
|
|
22
|
+
import { getToolActionInfo, redactTransientClipboardPastePaths, redactTransientClipboardPastePathsInValue, } from './types.js';
|
|
23
23
|
// ============ 可执行文件查找 ============
|
|
24
24
|
/**
|
|
25
25
|
* 查找 opencode 可执行文件
|
|
@@ -626,8 +626,12 @@ export class OpencodeSdkAdapter extends EventEmitter {
|
|
|
626
626
|
const metadata = part.metadata;
|
|
627
627
|
// 调试日志:查看 metadata 内容
|
|
628
628
|
if (metadata && Object.keys(metadata).length > 0) {
|
|
629
|
-
console.log(`[OpencodeSdkAdapter] Tool "${toolName}" metadata:`, JSON.stringify(metadata));
|
|
629
|
+
console.log(`[OpencodeSdkAdapter] Tool "${toolName}" metadata:`, JSON.stringify(redactTransientClipboardPastePathsInValue(metadata)));
|
|
630
630
|
}
|
|
631
|
+
const displayToolInputValue = redactTransientClipboardPastePathsInValue(toolInput);
|
|
632
|
+
const displayToolInput = displayToolInputValue && typeof displayToolInputValue === 'object' && !Array.isArray(displayToolInputValue)
|
|
633
|
+
? displayToolInputValue
|
|
634
|
+
: {};
|
|
631
635
|
const emitToolStart = () => {
|
|
632
636
|
if (session.emittedToolStarts.has(toolUseId))
|
|
633
637
|
return;
|
|
@@ -637,16 +641,16 @@ export class OpencodeSdkAdapter extends EventEmitter {
|
|
|
637
641
|
type: 'tool_use_start',
|
|
638
642
|
sessionId,
|
|
639
643
|
timestamp: ts,
|
|
640
|
-
data: { toolName, toolInput, toolUseId, ...actionInfo },
|
|
644
|
+
data: { toolName, toolInput: displayToolInput, toolUseId, ...actionInfo },
|
|
641
645
|
});
|
|
642
646
|
session.adapterSession.messages.push({
|
|
643
647
|
id: uuidv4(),
|
|
644
648
|
sessionId,
|
|
645
649
|
role: 'tool_use',
|
|
646
|
-
content: `${toolName}: ${JSON.stringify(
|
|
650
|
+
content: `${toolName}: ${JSON.stringify(displayToolInput).slice(0, 100)}`,
|
|
647
651
|
timestamp: ts,
|
|
648
652
|
toolName,
|
|
649
|
-
toolInput,
|
|
653
|
+
toolInput: displayToolInput,
|
|
650
654
|
toolUseId,
|
|
651
655
|
});
|
|
652
656
|
};
|
|
@@ -657,7 +661,7 @@ export class OpencodeSdkAdapter extends EventEmitter {
|
|
|
657
661
|
}
|
|
658
662
|
else if (state.status === 'completed') {
|
|
659
663
|
emitToolStart();
|
|
660
|
-
const output = state.output;
|
|
664
|
+
const output = redactTransientClipboardPastePaths(state.output);
|
|
661
665
|
this.emitEvent({
|
|
662
666
|
type: 'tool_use_end',
|
|
663
667
|
sessionId,
|
|
@@ -668,7 +672,7 @@ export class OpencodeSdkAdapter extends EventEmitter {
|
|
|
668
672
|
}
|
|
669
673
|
else if (state.status === 'error') {
|
|
670
674
|
emitToolStart();
|
|
671
|
-
const errorStr = state.error;
|
|
675
|
+
const errorStr = redactTransientClipboardPastePaths(state.error);
|
|
672
676
|
this.emitEvent({
|
|
673
677
|
type: 'tool_use_end',
|
|
674
678
|
sessionId,
|
package/dist/adapter/types.d.ts
CHANGED
|
@@ -32,6 +32,20 @@ export interface ToolMetadata {
|
|
|
32
32
|
/** 其他元数据 */
|
|
33
33
|
[key: string]: unknown;
|
|
34
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* 脱敏终端剪贴板生成的临时 paste 文件路径。
|
|
37
|
+
* 主流程:匹配 Windows/POSIX/裸目录形式 -> 替换为稳定占位符,避免临时文件路径进入日志与状态详情。
|
|
38
|
+
*/
|
|
39
|
+
export declare function redactTransientClipboardPastePaths(text: string): string;
|
|
40
|
+
/**
|
|
41
|
+
* 判断输入是否只是终端剪贴板生成的临时 paste 文件路径。
|
|
42
|
+
* 主流程:剥离包裹引号 -> 要求整串匹配,避免误拦截显式读取该文件的正常命令。
|
|
43
|
+
*/
|
|
44
|
+
export declare function isTransientClipboardPasteFilePath(text: string): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* 递归脱敏工具展示参数,保留真实执行输入不变,仅用于日志/状态/时间线展示。
|
|
47
|
+
*/
|
|
48
|
+
export declare function redactTransientClipboardPastePathsInValue(value: unknown): unknown;
|
|
35
49
|
/**
|
|
36
50
|
* 根据工具名称获取动作类型信息
|
|
37
51
|
* @param toolName 工具名称
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapter/types.ts"],"names":[],"mappings":"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"}
|
|
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
|
@@ -5,6 +5,50 @@
|
|
|
5
5
|
* 参考自 SpectrAI 项目的 adapter 设计,用于支持多种 AI Provider
|
|
6
6
|
*/
|
|
7
7
|
import { EventEmitter } from 'node:events';
|
|
8
|
+
const TEMP_CLIPBOARD_PASTE_PLACEHOLDER = '[temp clipboard paste file]';
|
|
9
|
+
const WINDOWS_TEMP_CLIPBOARD_PASTE_PATH = /[A-Z]:(?:\\\\|\\)[^\r\n"'`]*?(?:\\\\|\\)mini-term-clipboard(?:\\\\|\\)paste-\d+\.txt/gi;
|
|
10
|
+
const POSIX_TEMP_CLIPBOARD_PASTE_PATH = /\/[^\r\n"'`]*?\/mini-term-clipboard\/paste-\d+\.txt/gi;
|
|
11
|
+
const BARE_TEMP_CLIPBOARD_PASTE_PATH = /mini-term-clipboard[\\/]paste-\d+\.txt/gi;
|
|
12
|
+
/**
|
|
13
|
+
* 脱敏终端剪贴板生成的临时 paste 文件路径。
|
|
14
|
+
* 主流程:匹配 Windows/POSIX/裸目录形式 -> 替换为稳定占位符,避免临时文件路径进入日志与状态详情。
|
|
15
|
+
*/
|
|
16
|
+
export function redactTransientClipboardPastePaths(text) {
|
|
17
|
+
return text
|
|
18
|
+
.replace(WINDOWS_TEMP_CLIPBOARD_PASTE_PATH, TEMP_CLIPBOARD_PASTE_PLACEHOLDER)
|
|
19
|
+
.replace(POSIX_TEMP_CLIPBOARD_PASTE_PATH, TEMP_CLIPBOARD_PASTE_PLACEHOLDER)
|
|
20
|
+
.replace(BARE_TEMP_CLIPBOARD_PASTE_PATH, TEMP_CLIPBOARD_PASTE_PLACEHOLDER);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 判断输入是否只是终端剪贴板生成的临时 paste 文件路径。
|
|
24
|
+
* 主流程:剥离包裹引号 -> 要求整串匹配,避免误拦截显式读取该文件的正常命令。
|
|
25
|
+
*/
|
|
26
|
+
export function isTransientClipboardPasteFilePath(text) {
|
|
27
|
+
const trimmed = text.trim().replace(/^(["'])(.*)\1$/, '$2');
|
|
28
|
+
return [WINDOWS_TEMP_CLIPBOARD_PASTE_PATH, POSIX_TEMP_CLIPBOARD_PASTE_PATH, BARE_TEMP_CLIPBOARD_PASTE_PATH].some((pattern) => {
|
|
29
|
+
pattern.lastIndex = 0;
|
|
30
|
+
const match = pattern.exec(trimmed);
|
|
31
|
+
return Boolean(match && match[0] === trimmed);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 递归脱敏工具展示参数,保留真实执行输入不变,仅用于日志/状态/时间线展示。
|
|
36
|
+
*/
|
|
37
|
+
export function redactTransientClipboardPastePathsInValue(value) {
|
|
38
|
+
if (typeof value === 'string') {
|
|
39
|
+
return redactTransientClipboardPastePaths(value);
|
|
40
|
+
}
|
|
41
|
+
if (Array.isArray(value)) {
|
|
42
|
+
return value.map((item) => redactTransientClipboardPastePathsInValue(item));
|
|
43
|
+
}
|
|
44
|
+
if (value && typeof value === 'object') {
|
|
45
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
46
|
+
key,
|
|
47
|
+
redactTransientClipboardPastePathsInValue(item),
|
|
48
|
+
]));
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
8
52
|
/**
|
|
9
53
|
* 已知的 MCP 工具名映射表
|
|
10
54
|
* 用于识别 MCP 工具并确定其来源 server
|
|
@@ -59,12 +103,12 @@ export function getToolActionInfo(toolName, toolInput, metadata) {
|
|
|
59
103
|
const firstString = (...values) => {
|
|
60
104
|
for (const value of values) {
|
|
61
105
|
if (typeof value === 'string' && value.trim()) {
|
|
62
|
-
return value;
|
|
106
|
+
return redactTransientClipboardPastePaths(value);
|
|
63
107
|
}
|
|
64
108
|
if (Array.isArray(value) && value.length > 0) {
|
|
65
109
|
const first = value[0];
|
|
66
110
|
if (typeof first === 'string' && first.trim()) {
|
|
67
|
-
return first;
|
|
111
|
+
return redactTransientClipboardPastePaths(first);
|
|
68
112
|
}
|
|
69
113
|
}
|
|
70
114
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from 'vitest';
|
|
2
|
-
import { getToolActionInfo } from './types.js';
|
|
2
|
+
import { getToolActionInfo, isTransientClipboardPasteFilePath, redactTransientClipboardPastePaths, redactTransientClipboardPastePathsInValue, } from './types.js';
|
|
3
3
|
describe('getToolActionInfo', () => {
|
|
4
4
|
it('reports poll_message as a normal MCP tool call', () => {
|
|
5
5
|
expect(getToolActionInfo('poll_message')).toEqual({
|
|
@@ -8,4 +8,36 @@ describe('getToolActionInfo', () => {
|
|
|
8
8
|
actionDetail: 'aws-mcp/poll_message',
|
|
9
9
|
});
|
|
10
10
|
});
|
|
11
|
+
it('redacts transient mini-term paste paths from file action details', () => {
|
|
12
|
+
const info = getToolActionInfo('read', {
|
|
13
|
+
path: 'C:\\Users\\ZHUANG~1\\AppData\\Local\\Temp\\mini-term-clipboard\\paste-1780484619651.txt',
|
|
14
|
+
});
|
|
15
|
+
expect(info).toEqual({
|
|
16
|
+
actionType: 'read_file',
|
|
17
|
+
actionLabel: '读取文件',
|
|
18
|
+
actionDetail: '[temp clipboard paste file]',
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
it('redacts transient mini-term paste paths inside displayed tool input values', () => {
|
|
22
|
+
expect(redactTransientClipboardPastePathsInValue({
|
|
23
|
+
command: 'type "C:\\Users\\ZHUANG~1\\AppData\\Local\\Temp\\mini-term-clipboard\\paste-1780484619651.txt"',
|
|
24
|
+
})).toEqual({
|
|
25
|
+
command: 'type "[temp clipboard paste file]"',
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
it('keeps normal project paths unchanged', () => {
|
|
29
|
+
const info = getToolActionInfo('read', {
|
|
30
|
+
path: 'D:\\code\\AgentsWorkStudio\\README.md',
|
|
31
|
+
});
|
|
32
|
+
expect(info.actionDetail).toBe('D:\\code\\AgentsWorkStudio\\README.md');
|
|
33
|
+
});
|
|
34
|
+
it('detects only standalone transient mini-term paste file paths', () => {
|
|
35
|
+
expect(isTransientClipboardPasteFilePath('"C:\\Users\\ZHUANG~1\\AppData\\Local\\Temp\\mini-term-clipboard\\paste-1780484619651.txt"')).toBe(true);
|
|
36
|
+
expect(isTransientClipboardPasteFilePath('type "C:\\Users\\ZHUANG~1\\AppData\\Local\\Temp\\mini-term-clipboard\\paste-1780484619651.txt"')).toBe(false);
|
|
37
|
+
expect(isTransientClipboardPasteFilePath('D:\\code\\AgentsWorkStudio\\README.md')).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
it('redacts transient mini-term paste paths before terminal display/status output', () => {
|
|
40
|
+
expect(redactTransientClipboardPastePaths('C:\\Users\\ZHUANG~1\\AppData\\Local\\Temp\\mini-term-clipboard\\paste-1780484619651.txt')).toBe('[temp clipboard paste file]');
|
|
41
|
+
expect(redactTransientClipboardPastePaths('type "C:\\Users\\ZHUANG~1\\AppData\\Local\\Temp\\mini-term-clipboard\\paste-1780484619651.txt"')).toBe('type "[temp clipboard paste file]"');
|
|
42
|
+
});
|
|
11
43
|
});
|
|
@@ -1,3 +1,20 @@
|
|
|
1
1
|
export declare const runtimeBindingRouter: import("express-serve-static-core").Router;
|
|
2
|
+
export interface RuntimeTokenRequestInput {
|
|
3
|
+
userId?: unknown;
|
|
4
|
+
serverUrl?: unknown;
|
|
5
|
+
schedulerBaseUrl?: unknown;
|
|
6
|
+
forceRefresh?: unknown;
|
|
7
|
+
rejectedRuntimeAccessToken?: unknown;
|
|
8
|
+
}
|
|
9
|
+
export interface RuntimeTokenRequestResult {
|
|
10
|
+
success: boolean;
|
|
11
|
+
runtimeAccessToken?: string;
|
|
12
|
+
updated?: boolean;
|
|
13
|
+
error?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* 主流程:读取当前 scoped token -> 必要时串行刷新 -> 锁内重读 token,避免多个 MCP 进程强刷时互相废弃新 token。
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveRuntimeTokenRequest(input: RuntimeTokenRequestInput): Promise<RuntimeTokenRequestResult>;
|
|
2
19
|
export declare function logRuntimeBindingStartupState(): void;
|
|
3
20
|
//# sourceMappingURL=runtime-binding.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-binding.d.ts","sourceRoot":"","sources":["../../src/routes/runtime-binding.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runtime-binding.d.ts","sourceRoot":"","sources":["../../src/routes/runtime-binding.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,oBAAoB,4CAAW,CAAC;AAE7C,MAAM,WAAW,wBAAwB;IACvC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0BAA0B,CAAC,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAqCD;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,wBAAwB,GAC9B,OAAO,CAAC,yBAAyB,CAAC,CAyCpC;AAqMD,wBAAgB,6BAA6B,IAAI,IAAI,CAapD"}
|
|
@@ -1,11 +1,68 @@
|
|
|
1
1
|
import { Router } from "express";
|
|
2
|
-
import { clearRuntimeBinding, getRuntimeAccessToken, getRuntimeBindingPublicState, getRuntimePairingCode, hasRuntimeBinding, saveRuntimeBinding, validateRuntimeBindingToken, validateRuntimePairingCode, } from "../services/runtime-binding.js";
|
|
3
2
|
import { validateToken } from "../middleware/auth.js";
|
|
4
3
|
import { requestRuntimeAccessTokenRefresh, requestRuntimeAccessTokenRefreshForServer } from "../services/auto-register.js";
|
|
5
4
|
import { claimMcpLaunchBinding, getMcpLaunchQueueSize } from "../services/mcp-launch-binding-queue.js";
|
|
5
|
+
import { clearRuntimeBinding, getRuntimeAccessToken, getRuntimeBindingPublicState, getRuntimePairingCode, hasRuntimeBinding, saveRuntimeBinding, validateRuntimeBindingToken, validateRuntimePairingCode, } from "../services/runtime-binding.js";
|
|
6
6
|
import { createLogger } from "../utils/logger.js";
|
|
7
7
|
const log = createLogger("runtime-binding-route");
|
|
8
8
|
export const runtimeBindingRouter = Router();
|
|
9
|
+
const runtimeTokenRefreshLocks = new Map();
|
|
10
|
+
function buildRuntimeTokenRefreshLockKey(userId, serverUrl) {
|
|
11
|
+
return `${String(userId || "").trim()}\n${String(serverUrl || "").trim()}`;
|
|
12
|
+
}
|
|
13
|
+
async function withRuntimeTokenRefreshLock(userId, serverUrl, operation) {
|
|
14
|
+
const lockKey = buildRuntimeTokenRefreshLockKey(userId, serverUrl);
|
|
15
|
+
const previous = runtimeTokenRefreshLocks.get(lockKey) ?? Promise.resolve();
|
|
16
|
+
let release;
|
|
17
|
+
const current = new Promise((resolve) => {
|
|
18
|
+
release = resolve;
|
|
19
|
+
});
|
|
20
|
+
const chained = previous.then(() => current);
|
|
21
|
+
runtimeTokenRefreshLocks.set(lockKey, chained);
|
|
22
|
+
await previous;
|
|
23
|
+
try {
|
|
24
|
+
return await operation();
|
|
25
|
+
}
|
|
26
|
+
finally {
|
|
27
|
+
release();
|
|
28
|
+
if (runtimeTokenRefreshLocks.get(lockKey) === chained) {
|
|
29
|
+
runtimeTokenRefreshLocks.delete(lockKey);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 主流程:读取当前 scoped token -> 必要时串行刷新 -> 锁内重读 token,避免多个 MCP 进程强刷时互相废弃新 token。
|
|
35
|
+
*/
|
|
36
|
+
export async function resolveRuntimeTokenRequest(input) {
|
|
37
|
+
const { userId, serverUrl, schedulerBaseUrl, forceRefresh } = input;
|
|
38
|
+
const requestedServerUrl = serverUrl || schedulerBaseUrl;
|
|
39
|
+
const scopedToken = getRuntimeAccessToken(userId, requestedServerUrl);
|
|
40
|
+
if (scopedToken && forceRefresh !== true) {
|
|
41
|
+
return {
|
|
42
|
+
success: true,
|
|
43
|
+
runtimeAccessToken: scopedToken,
|
|
44
|
+
updated: false,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return await withRuntimeTokenRefreshLock(userId, requestedServerUrl, async () => {
|
|
48
|
+
const latestScopedToken = getRuntimeAccessToken(userId, requestedServerUrl);
|
|
49
|
+
const rejectedRuntimeAccessToken = String(input.rejectedRuntimeAccessToken || "").trim();
|
|
50
|
+
if (forceRefresh === true &&
|
|
51
|
+
latestScopedToken &&
|
|
52
|
+
rejectedRuntimeAccessToken &&
|
|
53
|
+
latestScopedToken !== rejectedRuntimeAccessToken) {
|
|
54
|
+
return {
|
|
55
|
+
success: true,
|
|
56
|
+
runtimeAccessToken: latestScopedToken,
|
|
57
|
+
updated: false,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (requestedServerUrl) {
|
|
61
|
+
return await requestRuntimeAccessTokenRefreshForServer(String(requestedServerUrl));
|
|
62
|
+
}
|
|
63
|
+
return await requestRuntimeAccessTokenRefresh();
|
|
64
|
+
});
|
|
65
|
+
}
|
|
9
66
|
function extractRuntimeToken(req) {
|
|
10
67
|
const headerToken = req.header("X-Runtime-Token");
|
|
11
68
|
if (headerToken) {
|
|
@@ -73,20 +130,7 @@ runtimeBindingRouter.post("/binding/request-token", async (req, res) => {
|
|
|
73
130
|
res.status(403).json({ ok: false, error: "loopback request required" });
|
|
74
131
|
return;
|
|
75
132
|
}
|
|
76
|
-
const
|
|
77
|
-
const scopedToken = getRuntimeAccessToken(userId, serverUrl || schedulerBaseUrl);
|
|
78
|
-
if (scopedToken && forceRefresh !== true) {
|
|
79
|
-
res.json({
|
|
80
|
-
ok: true,
|
|
81
|
-
runtimeAccessToken: scopedToken,
|
|
82
|
-
updated: false,
|
|
83
|
-
});
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
const requestedServerUrl = serverUrl || schedulerBaseUrl;
|
|
87
|
-
const result = requestedServerUrl
|
|
88
|
-
? await requestRuntimeAccessTokenRefreshForServer(String(requestedServerUrl))
|
|
89
|
-
: await requestRuntimeAccessTokenRefresh();
|
|
133
|
+
const result = await resolveRuntimeTokenRequest(req.body || {});
|
|
90
134
|
if (!result.success || !result.runtimeAccessToken) {
|
|
91
135
|
res.status(400).json({
|
|
92
136
|
ok: false,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-binding.test.d.ts","sourceRoot":"","sources":["../../src/routes/runtime-binding.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
const getRuntimeAccessTokenMock = vi.hoisted(() => vi.fn());
|
|
3
|
+
const requestRuntimeAccessTokenRefreshMock = vi.hoisted(() => vi.fn());
|
|
4
|
+
const requestRuntimeAccessTokenRefreshForServerMock = vi.hoisted(() => vi.fn());
|
|
5
|
+
vi.mock("../services/runtime-binding.js", () => ({
|
|
6
|
+
clearRuntimeBinding: vi.fn(),
|
|
7
|
+
getRuntimeAccessToken: getRuntimeAccessTokenMock,
|
|
8
|
+
getRuntimeBindingPublicState: vi.fn(() => ({ paired: true })),
|
|
9
|
+
getRuntimePairingCode: vi.fn(() => "000-000"),
|
|
10
|
+
hasRuntimeBinding: vi.fn(() => true),
|
|
11
|
+
saveRuntimeBinding: vi.fn(),
|
|
12
|
+
validateRuntimeBindingToken: vi.fn(() => true),
|
|
13
|
+
validateRuntimePairingCode: vi.fn(() => true),
|
|
14
|
+
}));
|
|
15
|
+
vi.mock("../services/auto-register.js", () => ({
|
|
16
|
+
requestRuntimeAccessTokenRefresh: requestRuntimeAccessTokenRefreshMock,
|
|
17
|
+
requestRuntimeAccessTokenRefreshForServer: requestRuntimeAccessTokenRefreshForServerMock,
|
|
18
|
+
}));
|
|
19
|
+
vi.mock("../services/mcp-launch-binding-queue.js", () => ({
|
|
20
|
+
claimMcpLaunchBinding: vi.fn(),
|
|
21
|
+
getMcpLaunchQueueSize: vi.fn(() => 0),
|
|
22
|
+
}));
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
vi.clearAllMocks();
|
|
25
|
+
});
|
|
26
|
+
describe("runtime binding token request", () => {
|
|
27
|
+
it("reuses a newer scoped token instead of rotating again after another MCP process refreshed it", async () => {
|
|
28
|
+
getRuntimeAccessTokenMock.mockReturnValue("fresh-token-from-other-process");
|
|
29
|
+
const { resolveRuntimeTokenRequest } = await import("./runtime-binding.js");
|
|
30
|
+
const result = await resolveRuntimeTokenRequest({
|
|
31
|
+
userId: "user-1",
|
|
32
|
+
serverUrl: "ws://localhost:7380/ws/agent",
|
|
33
|
+
forceRefresh: true,
|
|
34
|
+
rejectedRuntimeAccessToken: "stale-token",
|
|
35
|
+
});
|
|
36
|
+
expect(result).toEqual({
|
|
37
|
+
success: true,
|
|
38
|
+
runtimeAccessToken: "fresh-token-from-other-process",
|
|
39
|
+
updated: false,
|
|
40
|
+
});
|
|
41
|
+
expect(requestRuntimeAccessTokenRefreshForServerMock).not.toHaveBeenCalled();
|
|
42
|
+
expect(requestRuntimeAccessTokenRefreshMock).not.toHaveBeenCalled();
|
|
43
|
+
});
|
|
44
|
+
it("rotates the runtime token when the latest scoped token is the rejected token", async () => {
|
|
45
|
+
getRuntimeAccessTokenMock.mockReturnValue("stale-token");
|
|
46
|
+
requestRuntimeAccessTokenRefreshForServerMock.mockResolvedValue({
|
|
47
|
+
success: true,
|
|
48
|
+
runtimeAccessToken: "rotated-token",
|
|
49
|
+
updated: true,
|
|
50
|
+
});
|
|
51
|
+
const { resolveRuntimeTokenRequest } = await import("./runtime-binding.js");
|
|
52
|
+
const result = await resolveRuntimeTokenRequest({
|
|
53
|
+
userId: "user-1",
|
|
54
|
+
serverUrl: "ws://localhost:7380/ws/agent",
|
|
55
|
+
forceRefresh: true,
|
|
56
|
+
rejectedRuntimeAccessToken: "stale-token",
|
|
57
|
+
});
|
|
58
|
+
expect(result).toEqual({
|
|
59
|
+
success: true,
|
|
60
|
+
runtimeAccessToken: "rotated-token",
|
|
61
|
+
updated: true,
|
|
62
|
+
});
|
|
63
|
+
expect(requestRuntimeAccessTokenRefreshForServerMock).toHaveBeenCalledWith("ws://localhost:7380/ws/agent");
|
|
64
|
+
});
|
|
65
|
+
it("serializes concurrent force refreshes and lets the loser reuse the winner token", async () => {
|
|
66
|
+
let cachedToken = "stale-token";
|
|
67
|
+
let releaseRefresh = () => undefined;
|
|
68
|
+
const refreshGate = new Promise((resolve) => {
|
|
69
|
+
releaseRefresh = resolve;
|
|
70
|
+
});
|
|
71
|
+
getRuntimeAccessTokenMock.mockImplementation(() => cachedToken);
|
|
72
|
+
requestRuntimeAccessTokenRefreshForServerMock.mockImplementation(async () => {
|
|
73
|
+
await refreshGate;
|
|
74
|
+
cachedToken = "winner-token";
|
|
75
|
+
return {
|
|
76
|
+
success: true,
|
|
77
|
+
runtimeAccessToken: "winner-token",
|
|
78
|
+
updated: true,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
const { resolveRuntimeTokenRequest } = await import("./runtime-binding.js");
|
|
82
|
+
const first = resolveRuntimeTokenRequest({
|
|
83
|
+
userId: "user-1",
|
|
84
|
+
serverUrl: "ws://localhost:7380/ws/agent",
|
|
85
|
+
forceRefresh: true,
|
|
86
|
+
rejectedRuntimeAccessToken: "stale-token",
|
|
87
|
+
});
|
|
88
|
+
const second = resolveRuntimeTokenRequest({
|
|
89
|
+
userId: "user-1",
|
|
90
|
+
serverUrl: "ws://localhost:7380/ws/agent",
|
|
91
|
+
forceRefresh: true,
|
|
92
|
+
rejectedRuntimeAccessToken: "stale-token",
|
|
93
|
+
});
|
|
94
|
+
releaseRefresh();
|
|
95
|
+
const [firstResult, secondResult] = await Promise.all([first, second]);
|
|
96
|
+
expect(firstResult).toEqual({
|
|
97
|
+
success: true,
|
|
98
|
+
runtimeAccessToken: "winner-token",
|
|
99
|
+
updated: true,
|
|
100
|
+
});
|
|
101
|
+
expect(secondResult).toEqual({
|
|
102
|
+
success: true,
|
|
103
|
+
runtimeAccessToken: "winner-token",
|
|
104
|
+
updated: false,
|
|
105
|
+
});
|
|
106
|
+
expect(requestRuntimeAccessTokenRefreshForServerMock).toHaveBeenCalledTimes(1);
|
|
107
|
+
});
|
|
108
|
+
});
|
|
@@ -60,6 +60,21 @@ export declare function evaluatePersistedSessionReuse(session: Pick<PersistedSes
|
|
|
60
60
|
*/
|
|
61
61
|
export declare function formatTerminalPrompt(currentDirectory: string): string;
|
|
62
62
|
export declare function buildRuntimeEnv(agentId: string, workspacePath: string | undefined, baseEnv: NodeJS.ProcessEnv, envOverrides?: Record<string, unknown>): Record<string, string>;
|
|
63
|
+
/**
|
|
64
|
+
* 主流程:SDK 模式输入若只是 mini-term 剪贴板临时文件路径,则展开为文件内容再发给模型。
|
|
65
|
+
* 具体实现:只处理整串匹配的绝对临时 paste 文件路径,避免影响显式 `type "path"` 等正常命令。
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolveSdkInputMessage(input: unknown): Promise<string>;
|
|
68
|
+
export interface ClaudeCodeLaunchConfig {
|
|
69
|
+
envOverrides: Record<string, string>;
|
|
70
|
+
model?: string;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 主流程:将已持久化的 ClaudeCode AI 配置合并到启动配置,再让请求级覆盖保持最高优先级。
|
|
74
|
+
*/
|
|
75
|
+
export declare function buildClaudeCodeLaunchConfig(savedClaudeConfig: {
|
|
76
|
+
env?: Record<string, unknown>;
|
|
77
|
+
} | null | undefined, requestEnvOverrides?: Record<string, unknown>): ClaudeCodeLaunchConfig;
|
|
63
78
|
/**
|
|
64
79
|
* 将 SDK 工具结束事件转换为时间线返回数据状态。
|
|
65
80
|
* 主流程:格式化工具结果 -> 保留 MCP 专用展示 -> 其它工具按动作类型追加到对应时间线事件。
|
|
@@ -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,
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/routes/terminal.ts"],"names":[],"mappings":"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"}
|