aws-runtime-bridge 1.3.0 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -77
- package/dist/config.d.ts +1 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -18
- package/dist/index.js +0 -0
- package/dist/middleware/auth.d.ts +2 -2
- package/dist/middleware/auth.d.ts.map +1 -1
- package/dist/middleware/auth.js +4 -10
- package/dist/routes/instance.d.ts.map +1 -1
- package/dist/routes/instance.js +8 -2
- package/dist/routes/properties.test.js +4 -4
- package/dist/routes/runtime-binding.d.ts.map +1 -1
- package/dist/routes/runtime-binding.js +3 -11
- package/dist/services/auto-register.d.ts.map +1 -1
- package/dist/services/auto-register.js +15 -8
- package/dist/services/auto-register.test.js +4 -0
- package/dist/services/aws-client-agent-mcp.d.ts.map +1 -1
- package/dist/services/aws-client-agent-mcp.js +1 -6
- package/dist/services/aws-client-agent-mcp.test.js +0 -2
- package/dist/services/orphan-monitor.d.ts.map +1 -1
- package/dist/services/orphan-monitor.js +8 -2
- package/dist/services/runtime-binding.d.ts +1 -0
- package/dist/services/runtime-binding.d.ts.map +1 -1
- package/dist/services/runtime-binding.js +31 -3
- package/dist/services/runtime-binding.test.js +42 -2
- package/dist/services/session-output.d.ts.map +1 -1
- package/dist/services/session-output.js +21 -4
- package/dist/utils/file-utils.d.ts.map +1 -1
- package/dist/utils/file-utils.js +7 -2
- package/dist/utils/file-utils.test.js +3 -1
- package/dist/utils/yaml-utils.test.js +129 -129
- package/node_modules/@cc-switch/sdk/README.md +540 -540
- package/node_modules/@cc-switch/sdk/package.json +31 -31
- package/package/aws-client-agent-mcp/README.md +287 -288
- package/package/aws-client-agent-mcp/dist/agent-client.test.js +24 -1
- package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/config.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/config.js +0 -1
- package/package/aws-client-agent-mcp/dist/config.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/config.test.js +0 -7
- package/package/aws-client-agent-mcp/dist/config.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.test.js +0 -1
- package/package/aws-client-agent-mcp/dist/http-client.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js +0 -3
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.js +14 -5
- package/package/aws-client-agent-mcp/dist/runtime-launch-binding.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/types.d.ts +4 -0
- package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/types.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +3 -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 +64 -5
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js +218 -0
- package/package/aws-client-agent-mcp/dist/websocket-client.test.js.map +1 -1
- package/package/aws-client-agent-mcp/package.json +52 -52
- package/package/cc-switch-sdk/README.md +540 -540
- package/package/cc-switch-sdk/package.json +31 -31
- package/package.json +78 -78
- package/dist/routes/runtime-mcp-proxy.d.ts +0 -3
- package/dist/routes/runtime-mcp-proxy.d.ts.map +0 -1
- package/dist/routes/runtime-mcp-proxy.js +0 -102
- package/dist/routes/runtime-mcp-proxy.test.d.ts +0 -2
- package/dist/routes/runtime-mcp-proxy.test.d.ts.map +0 -1
- package/dist/routes/runtime-mcp-proxy.test.js +0 -111
- package/node_modules/@cc-switch/sdk/dist/sdk-import.test.d.ts +0 -2
- package/node_modules/@cc-switch/sdk/dist/sdk-import.test.d.ts.map +0 -1
- package/node_modules/@cc-switch/sdk/dist/sdk-import.test.js +0 -119
- package/package/cc-switch-sdk/dist/sdk-import.test.d.ts +0 -2
- package/package/cc-switch-sdk/dist/sdk-import.test.d.ts.map +0 -1
- package/package/cc-switch-sdk/dist/sdk-import.test.js +0 -119
package/README.md
CHANGED
|
@@ -1,77 +1,75 @@
|
|
|
1
|
-
# aws-runtime-bridge
|
|
2
|
-
|
|
3
|
-
AgentsWorkStudio 机器实例运行时桥接服务,用于在实例上管理 Agent 运行时、终端、配置与回调通信。
|
|
4
|
-
|
|
5
|
-
## 全局安装
|
|
6
|
-
|
|
7
|
-
从 npm 包安装时:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install -g aws-runtime-bridge
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
安装脚本会在 macOS、Linux 与常见 Unix 平台自动为 CLI 入口补齐可执行权限;Windows 平台无需 chmod,会自动跳过该步骤。
|
|
14
|
-
|
|
15
|
-
从当前仓库安装时:
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
cd aws-runtime-bridge
|
|
19
|
-
npm install
|
|
20
|
-
npm run build
|
|
21
|
-
npm install -g .
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
## 启动
|
|
25
|
-
|
|
26
|
-
首次运行 `awsb` / `aws-bridge` 时,如果不存在 `~/.aws-bridge/config.json`,CLI 会进入交互式配置引导;也可以在提示中选择跳过。跳过时仍会创建配置文件并自动生成随机 `connectionKey`,终端会输出该密钥,请保存后在 server/面板连接此 Bridge 时使用。非交互环境(如 systemd、CI、Docker 后台启动)不会阻塞等待输入,也会自动生成 `connectionKey` 并跳过引导。
|
|
27
|
-
|
|
28
|
-
引导会生成类似下面的配置:
|
|
29
|
-
|
|
30
|
-
```json
|
|
31
|
-
{
|
|
32
|
-
"connectionKey": "gkmzjaznX55..",
|
|
33
|
-
"autoRegisterTargets": [
|
|
34
|
-
{
|
|
35
|
-
"serverUrl": "http://127.0.0.1:8080",
|
|
36
|
-
"instanceName": "至强主机",
|
|
37
|
-
"userKey": "aws_live_crh_g0GGrg5IntODg1sFwnas7qf4yGrcwoisDWPBtd8",
|
|
38
|
-
"registerIp": "127.0.0.1"
|
|
39
|
-
}
|
|
40
|
-
]
|
|
41
|
-
}
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
如需在交互式终端中也强制跳过引导,可设置 `AWS_BRIDGE_SKIP_SETUP=true`;此时仍会生成随机 `connectionKey`。
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
AWS_RUNTIME_BRIDGE_PORT=18081 \
|
|
48
|
-
AWS_RUNTIME_SCHEDULER_BASE_URL=http://your-server-host:7380 \
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
`aws-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
|
70
|
-
|
|
|
71
|
-
| `
|
|
72
|
-
| `
|
|
73
|
-
| `
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
生产环境中,`AWS_RUNTIME_SCHEDULER_BASE_URL` 必须填写机器实例可访问的 `aws-mcp-server` 地址,不能使用容器内的 `localhost`。
|
|
1
|
+
# aws-runtime-bridge
|
|
2
|
+
|
|
3
|
+
AgentsWorkStudio 机器实例运行时桥接服务,用于在实例上管理 Agent 运行时、终端、配置与回调通信。
|
|
4
|
+
|
|
5
|
+
## 全局安装
|
|
6
|
+
|
|
7
|
+
从 npm 包安装时:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g aws-runtime-bridge
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
安装脚本会在 macOS、Linux 与常见 Unix 平台自动为 CLI 入口补齐可执行权限;Windows 平台无需 chmod,会自动跳过该步骤。
|
|
14
|
+
|
|
15
|
+
从当前仓库安装时:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
cd aws-runtime-bridge
|
|
19
|
+
npm install
|
|
20
|
+
npm run build
|
|
21
|
+
npm install -g .
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 启动
|
|
25
|
+
|
|
26
|
+
首次运行 `awsb` / `aws-bridge` 时,如果不存在 `~/.aws-bridge/config.json`,CLI 会进入交互式配置引导;也可以在提示中选择跳过。跳过时仍会创建配置文件并自动生成随机 `connectionKey`,终端会输出该密钥,请保存后在 server/面板连接此 Bridge 时使用。非交互环境(如 systemd、CI、Docker 后台启动)不会阻塞等待输入,也会自动生成 `connectionKey` 并跳过引导。
|
|
27
|
+
|
|
28
|
+
引导会生成类似下面的配置:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"connectionKey": "gkmzjaznX55..",
|
|
33
|
+
"autoRegisterTargets": [
|
|
34
|
+
{
|
|
35
|
+
"serverUrl": "http://127.0.0.1:8080",
|
|
36
|
+
"instanceName": "至强主机",
|
|
37
|
+
"userKey": "aws_live_crh_g0GGrg5IntODg1sFwnas7qf4yGrcwoisDWPBtd8",
|
|
38
|
+
"registerIp": "127.0.0.1"
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
如需在交互式终端中也强制跳过引导,可设置 `AWS_BRIDGE_SKIP_SETUP=true`;此时仍会生成随机 `connectionKey`。
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
AWS_RUNTIME_BRIDGE_PORT=18081 \
|
|
48
|
+
AWS_RUNTIME_SCHEDULER_BASE_URL=http://your-server-host:7380 \
|
|
49
|
+
AWS_RUNTIME_HOME_DIR=/opt/agentswork/runtime-home \
|
|
50
|
+
aws-bridge
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`aws-runtime-bridge` 命令仍作为兼容别名保留。安装 `aws-runtime-bridge` 后,包内会随附
|
|
54
|
+
`aws-client-agent-mcp` 的编译产物;bridge 启动时只负责准备该 MCP 产物,不再在 Agent 启动时默认动态注入 `aws-mcp`。
|
|
55
|
+
|
|
56
|
+
请在面板中为目标运行时安装/配置 MCP;这样 Claude Code、Codex、OpenCode、PTY 等不同启动模式都走一致的持久化 MCP 配置链路。
|
|
57
|
+
|
|
58
|
+
如需使用自定义 MCP 可执行文件,可设置:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
AWS_CLIENT_AGENT_MCP_COMMAND=/absolute/path/to/aws-client-agent-mcp \
|
|
62
|
+
AWS_CLIENT_AGENT_MCP_ARGS='[]' \
|
|
63
|
+
aws-bridge
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 关键环境变量
|
|
67
|
+
|
|
68
|
+
| 变量名 | 说明 | 默认值 |
|
|
69
|
+
| --- | --- | --- |
|
|
70
|
+
| `AWS_RUNTIME_BRIDGE_PORT` | Bridge HTTP 端口 | `18081` |
|
|
71
|
+
| `AWS_RUNTIME_SCHEDULER_BASE_URL` | aws-mcp-server 地址 | `http://localhost:8080` |
|
|
72
|
+
| `AWS_RUNTIME_HOME_DIR` | Bridge 管理配置与状态的主目录 | 当前用户 Home |
|
|
73
|
+
| `AWS_RUNTIME_CORS_ORIGINS` | 允许访问 bridge 的来源,逗号分隔 | 本地开发地址 |
|
|
74
|
+
|
|
75
|
+
生产环境中,`AWS_RUNTIME_SCHEDULER_BASE_URL` 必须填写机器实例可访问的 `aws-mcp-server` 地址,不能使用容器内的 `localhost`。
|
package/dist/config.d.ts
CHANGED
|
@@ -7,19 +7,13 @@
|
|
|
7
7
|
export declare const port: number;
|
|
8
8
|
/** 调度器基础 URL */
|
|
9
9
|
export declare const schedulerBaseUrl: string;
|
|
10
|
-
/** 默认运行时回调 Token */
|
|
11
|
-
export declare const DEFAULT_RUNTIME_CALLBACK_TOKEN = "agentswork-runtime-callback";
|
|
12
10
|
/** Node 环境 */
|
|
13
11
|
export declare const nodeEnv: string;
|
|
14
|
-
/** 运行时回调 Token */
|
|
15
|
-
export declare const runtimeToken: string;
|
|
16
|
-
/** 是否显式允许本地开发使用默认 Token */
|
|
17
|
-
export declare const allowDefaultRuntimeToken: boolean;
|
|
18
12
|
/** 是否允许浏览宿主机任意目录(默认关闭,仅建议本地排障启用) */
|
|
19
13
|
export declare const allowHostFileBrowser: boolean;
|
|
20
14
|
/** CORS 允许来源列表,默认仅允许本机开发前端 */
|
|
21
15
|
export declare const allowedCorsOrigins: string[];
|
|
22
|
-
/**
|
|
16
|
+
/** Runtime bridge no longer supports global callback tokens. */
|
|
23
17
|
export declare function validateProductionToken(): void;
|
|
24
18
|
/** 获取运行时主目录 */
|
|
25
19
|
export declare function getRuntimeHomeDir(): string;
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,WAAW;AACX,eAAO,MAAM,IAAI,EAAE,MAElB,CAAC;AAEF,gBAAgB;AAChB,eAAO,MAAM,gBAAgB,EAAE,MACwC,CAAC;AAExE,cAAc;AACd,eAAO,MAAM,OAAO,EAAE,MAA8C,CAAC;AAErE,oCAAoC;AACpC,eAAO,MAAM,oBAAoB,EAAE,OACiB,CAAC;AAErD,8BAA8B;AAC9B,eAAO,MAAM,kBAAkB,EAAE,MAAM,EAMC,CAAC;AAEzC,gEAAgE;AAChE,wBAAgB,uBAAuB,IAAI,IAAI,CAAG;AAElD,eAAe;AACf,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,8CAA8C;AAC9C,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK/D;AAED,2BAA2B;AAC3B,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKlE;AAED,0BAA0B;AAC1B,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED,yBAAyB;AACzB,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED,sBAAsB;AACtB,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK9D;AAED,yBAAyB;AACzB,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK7D;AAED,4BAA4B;AAC5B,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED;;GAEG;AAEH,yBAAyB;AACzB,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,sBAAsB,EACrB,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE1C,eAAe;AACf,eAAO,MAAM,mBAAmB,SACiB,CAAC;AAElD,iCAAiC;AACjC,eAAO,MAAM,2BAA2B,QAEvC,CAAC;AAEF,0CAA0C;AAC1C,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AAEF,qCAAqC;AACrC,eAAO,MAAM,uBAAuB,QAEnC,CAAC;AAEF;;GAEG;AAEH,eAAe;AACf,eAAO,MAAM,qBAAqB,SAA2C,CAAC;AAE9E,YAAY;AACZ,eAAO,MAAM,uBAAuB,QAAkC,CAAC;AAEvE,iBAAiB;AACjB,eAAO,MAAM,sBAAsB,QAAiC,CAAC;AAErE,oBAAoB;AACpB,eAAO,MAAM,2BAA2B,QAAsC,CAAC;AAE/E,WAAW;AACX,eAAO,MAAM,0BAA0B,QAAqC,CAAC;AAE7E,WAAW;AACX,eAAO,MAAM,uBAAuB,QAAkC,CAAC;AAEvE,aAAa;AACb,eAAO,MAAM,4BAA4B,QACH,CAAC;AAEvC,kCAAkC;AAClC,eAAO,MAAM,wBAAwB,QAC4B,CAAC;AAElE,aAAa;AACb,eAAO,MAAM,yBAAyB,QAErC,CAAC;AAEF,iBAAiB;AACjB,eAAO,MAAM,4BAA4B,QAExC,CAAC"}
|
package/dist/config.js
CHANGED
|
@@ -5,19 +5,12 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import os from "node:os";
|
|
7
7
|
import path from "node:path";
|
|
8
|
-
import { logger } from "./utils/logger.js";
|
|
9
8
|
/** 服务端口 */
|
|
10
9
|
export const port = Number(process.env.AWS_RUNTIME_BRIDGE_PORT || 18081);
|
|
11
10
|
/** 调度器基础 URL */
|
|
12
11
|
export const schedulerBaseUrl = process.env.AWS_RUNTIME_SCHEDULER_BASE_URL || "http://localhost:8080";
|
|
13
|
-
/** 默认运行时回调 Token */
|
|
14
|
-
export const DEFAULT_RUNTIME_CALLBACK_TOKEN = "agentswork-runtime-callback";
|
|
15
12
|
/** Node 环境 */
|
|
16
13
|
export const nodeEnv = process.env.NODE_ENV || "development";
|
|
17
|
-
/** 运行时回调 Token */
|
|
18
|
-
export const runtimeToken = process.env.AWS_RUNTIME_CALLBACK_TOKEN || DEFAULT_RUNTIME_CALLBACK_TOKEN;
|
|
19
|
-
/** 是否显式允许本地开发使用默认 Token */
|
|
20
|
-
export const allowDefaultRuntimeToken = process.env.AWS_ALLOW_DEFAULT_RUNTIME_TOKEN === "true";
|
|
21
14
|
/** 是否允许浏览宿主机任意目录(默认关闭,仅建议本地排障启用) */
|
|
22
15
|
export const allowHostFileBrowser = process.env.AWS_ALLOW_HOST_FILE_BROWSER === "true";
|
|
23
16
|
/** CORS 允许来源列表,默认仅允许本机开发前端 */
|
|
@@ -26,17 +19,8 @@ export const allowedCorsOrigins = String(process.env.AWS_RUNTIME_CORS_ORIGINS ||
|
|
|
26
19
|
.split(",")
|
|
27
20
|
.map((origin) => origin.trim())
|
|
28
21
|
.filter((origin) => origin.length > 0);
|
|
29
|
-
/**
|
|
30
|
-
export function validateProductionToken() {
|
|
31
|
-
if (!process.env.AWS_RUNTIME_CALLBACK_TOKEN) {
|
|
32
|
-
if (allowDefaultRuntimeToken) {
|
|
33
|
-
logger.warn("[runtime-bridge] AWS_RUNTIME_CALLBACK_TOKEN not set, using default development token");
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
logger.info("[runtime-bridge] AWS_RUNTIME_CALLBACK_TOKEN not set; starting in unpaired mode. " +
|
|
37
|
-
"Sensitive APIs require a panel/server issued runtime access token after pairing.");
|
|
38
|
-
}
|
|
39
|
-
}
|
|
22
|
+
/** Runtime bridge no longer supports global callback tokens. */
|
|
23
|
+
export function validateProductionToken() { }
|
|
40
24
|
/** 获取运行时主目录 */
|
|
41
25
|
export function getRuntimeHomeDir() {
|
|
42
26
|
return String(process.env.AWS_RUNTIME_HOME_DIR || "").trim() || os.homedir();
|
package/dist/index.js
CHANGED
|
File without changes
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Token 验证中间件
|
|
3
3
|
*
|
|
4
|
-
* 验证请求头中的 X-Runtime-Token
|
|
4
|
+
* 验证请求头中的 X-Runtime-Token 是否为已配对的 connectionKey 或 runtime binding token。
|
|
5
5
|
*/
|
|
6
6
|
import type { Request, Response, NextFunction } from "express";
|
|
7
7
|
/**
|
|
8
8
|
* Token 验证中间件
|
|
9
9
|
* 检查请求头中的 X-Runtime-Token 或 Authorization: Bearer 是否有效。
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* 支持面板/服务器绑定时写入的动态令牌和 bridge 实例 connectionKey。
|
|
12
12
|
*/
|
|
13
13
|
export declare function validateToken(req: Request, res: Response, next: NextFunction): void;
|
|
14
14
|
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/middleware/auth.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA8B/D;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,IAAI,CAmBN"}
|
package/dist/middleware/auth.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Token 验证中间件
|
|
3
3
|
*
|
|
4
|
-
* 验证请求头中的 X-Runtime-Token
|
|
4
|
+
* 验证请求头中的 X-Runtime-Token 是否为已配对的 connectionKey 或 runtime binding token。
|
|
5
5
|
*/
|
|
6
|
-
import { allowDefaultRuntimeToken, runtimeToken } from "../config.js";
|
|
7
6
|
import { hasRuntimeBinding, validateRuntimeBindingToken, } from "../services/runtime-binding.js";
|
|
8
7
|
import { getConfiguredConnectionKeys } from "../services/auto-register.js";
|
|
9
8
|
function extractRuntimeToken(req) {
|
|
@@ -22,16 +21,13 @@ function validateConfiguredToken(token) {
|
|
|
22
21
|
if (getConfiguredConnectionKeys().includes(token)) {
|
|
23
22
|
return true;
|
|
24
23
|
}
|
|
25
|
-
|
|
26
|
-
return token === runtimeToken;
|
|
27
|
-
}
|
|
28
|
-
return allowDefaultRuntimeToken && token === runtimeToken;
|
|
24
|
+
return false;
|
|
29
25
|
}
|
|
30
26
|
/**
|
|
31
27
|
* Token 验证中间件
|
|
32
28
|
* 检查请求头中的 X-Runtime-Token 或 Authorization: Bearer 是否有效。
|
|
33
29
|
*
|
|
34
|
-
*
|
|
30
|
+
* 支持面板/服务器绑定时写入的动态令牌和 bridge 实例 connectionKey。
|
|
35
31
|
*/
|
|
36
32
|
export function validateToken(req, res, next) {
|
|
37
33
|
const token = extractRuntimeToken(req);
|
|
@@ -39,9 +35,7 @@ export function validateToken(req, res, next) {
|
|
|
39
35
|
next();
|
|
40
36
|
return;
|
|
41
37
|
}
|
|
42
|
-
if (!hasRuntimeBinding()
|
|
43
|
-
!process.env.AWS_RUNTIME_CALLBACK_TOKEN &&
|
|
44
|
-
!allowDefaultRuntimeToken) {
|
|
38
|
+
if (!hasRuntimeBinding()) {
|
|
45
39
|
res.status(401).json({
|
|
46
40
|
error: "runtime_bridge_unpaired",
|
|
47
41
|
message: "Runtime bridge is not paired. Add this instance from the panel first.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/routes/instance.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/routes/instance.ts"],"names":[],"mappings":"AA6BA,wBAAgB,qBAAqB,CACnC,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAC/D,IAAI,CAEN;AAED,eAAO,MAAM,cAAc,4CAAW,CAAC;AAyBvC,wBAAgB,4BAA4B,CAAC,gBAAgB,EAAE,MAAM,GAAG;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QACJ,EAAE,EAAE,OAAO,CAAC;QACZ,aAAa,CAAC,EAAE,SAAS,CAAC;QAC1B,oBAAoB,EAAE,OAAO,CAAC;QAC9B,qBAAqB,EAAE,OAAO,CAAC;QAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAqCA"}
|
package/dist/routes/instance.js
CHANGED
|
@@ -2,7 +2,8 @@ import { Router } from "express";
|
|
|
2
2
|
import axios from "axios";
|
|
3
3
|
import { createHash, timingSafeEqual } from "node:crypto";
|
|
4
4
|
import { validateToken } from "../middleware/auth.js";
|
|
5
|
-
import { schedulerBaseUrl
|
|
5
|
+
import { schedulerBaseUrl } from "../config.js";
|
|
6
|
+
import { getRuntimeAccessToken } from "../services/runtime-binding.js";
|
|
6
7
|
import { loadInstanceState, saveInstanceState, } from "../services/instance-state.js";
|
|
7
8
|
import { initInstance } from "../services/instance-init-service.js";
|
|
8
9
|
import { discoverCcSwitchConfiguredItems, loadCcSwitchSdk } from "../services/cc-switch-sdk.js";
|
|
@@ -84,7 +85,12 @@ instanceRouter.get("/connection-check", (req, res) => {
|
|
|
84
85
|
});
|
|
85
86
|
instanceRouter.get("/ping", validateToken, async (_req, res) => {
|
|
86
87
|
try {
|
|
87
|
-
const
|
|
88
|
+
const runtimeAccessToken = getRuntimeAccessToken(undefined, schedulerBaseUrl) || getRuntimeAccessToken();
|
|
89
|
+
if (!runtimeAccessToken) {
|
|
90
|
+
res.status(401).json({ ok: false, error: "runtime_access_token_required" });
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const schedulerResponse = await axios.get(`${schedulerBaseUrl}/api/runtime/ping`, { headers: { "X-Runtime-Token": runtimeAccessToken } });
|
|
88
94
|
res.json({
|
|
89
95
|
ok: true,
|
|
90
96
|
runtimeBridge: "healthy",
|
|
@@ -41,10 +41,10 @@ describe('properties file operations', () => {
|
|
|
41
41
|
}
|
|
42
42
|
return result;
|
|
43
43
|
};
|
|
44
|
-
const props = parseProperties(`
|
|
45
|
-
# Comment
|
|
46
|
-
agent.role.name=Backend Developer
|
|
47
|
-
project.workspace.path=/home/project
|
|
44
|
+
const props = parseProperties(`
|
|
45
|
+
# Comment
|
|
46
|
+
agent.role.name=Backend Developer
|
|
47
|
+
project.workspace.path=/home/project
|
|
48
48
|
`);
|
|
49
49
|
expect(props['agent.role.name']).toBe('Backend Developer');
|
|
50
50
|
expect(props['project.workspace.path']).toBe('/home/project');
|
|
@@ -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":"AAkBA,eAAO,MAAM,oBAAoB,4CAAW,CAAC;AAsN7C,wBAAgB,6BAA6B,IAAI,IAAI,CAapD"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { Router } from "express";
|
|
2
2
|
import { clearRuntimeBinding, getRuntimeAccessToken, getRuntimeBindingPublicState, getRuntimePairingCode, hasRuntimeBinding, saveRuntimeBinding, validateRuntimeBindingToken, validateRuntimePairingCode, } from "../services/runtime-binding.js";
|
|
3
3
|
import { validateToken } from "../middleware/auth.js";
|
|
4
|
-
import { runtimeToken } from "../config.js";
|
|
5
4
|
import { requestRuntimeAccessTokenRefresh, requestRuntimeAccessTokenRefreshForServer } from "../services/auto-register.js";
|
|
6
5
|
import { claimMcpLaunchBinding, getMcpLaunchQueueSize } from "../services/mcp-launch-binding-queue.js";
|
|
7
6
|
import { createLogger } from "../utils/logger.js";
|
|
@@ -74,9 +73,9 @@ runtimeBindingRouter.post("/binding/request-token", async (req, res) => {
|
|
|
74
73
|
res.status(403).json({ ok: false, error: "loopback request required" });
|
|
75
74
|
return;
|
|
76
75
|
}
|
|
77
|
-
const { userId, serverUrl, schedulerBaseUrl } = req.body || {};
|
|
76
|
+
const { userId, serverUrl, schedulerBaseUrl, forceRefresh } = req.body || {};
|
|
78
77
|
const scopedToken = getRuntimeAccessToken(userId, serverUrl || schedulerBaseUrl);
|
|
79
|
-
if (scopedToken) {
|
|
78
|
+
if (scopedToken && forceRefresh !== true) {
|
|
80
79
|
res.json({
|
|
81
80
|
ok: true,
|
|
82
81
|
runtimeAccessToken: scopedToken,
|
|
@@ -137,14 +136,7 @@ runtimeBindingRouter.post("/binding/claim-agent", (req, res) => {
|
|
|
137
136
|
remainingQueueSize: getMcpLaunchQueueSize(workspacePath),
|
|
138
137
|
});
|
|
139
138
|
});
|
|
140
|
-
runtimeBindingRouter.post("/binding/issue", (req, res) => {
|
|
141
|
-
const currentRuntimeToken = extractRuntimeToken(req);
|
|
142
|
-
const authorizedByScheduler = currentRuntimeToken === runtimeToken;
|
|
143
|
-
const authorizedByCurrentBinding = validateRuntimeBindingToken(currentRuntimeToken);
|
|
144
|
-
if (!authorizedByScheduler && !authorizedByCurrentBinding) {
|
|
145
|
-
res.status(401).json({ error: "unauthorized" });
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
139
|
+
runtimeBindingRouter.post("/binding/issue", validateToken, (req, res) => {
|
|
148
140
|
const { accessToken, instanceId, userId, schedulerBaseUrl } = req.body || {};
|
|
149
141
|
const nextToken = String(accessToken || "").trim();
|
|
150
142
|
if (!nextToken) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auto-register.d.ts","sourceRoot":"","sources":["../../src/services/auto-register.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"auto-register.d.ts","sourceRoot":"","sources":["../../src/services/auto-register.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAmDH;;GAEG;AACH,UAAU,kBAAkB;IAC1B,eAAe;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,oBAAoB;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,aAAa;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAwBD,wBAAgB,2BAA2B,IAAI,MAAM,EAAE,CAEtD;AAiED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,MAAM,CAGtD;AAyJD;;;;;;GAMG;AACH,wBAAgB,UAAU,IAAI,kBAAkB,CA2C/C;AAED,wBAAgB,WAAW,IAAI,kBAAkB,EAAE,CA0ClD;AAgPD;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,YAAY,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GACzC,OAAO,CAAC,OAAO,CAAC,CAalB;AAyHD;;GAEG;AACH,wBAAsB,gCAAgC,IAAI,OAAO,CAAC;IAChE,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CAoED;AAED,wBAAsB,yCAAyC,CAC7D,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC;IACT,OAAO,EAAE,OAAO,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CA0ED;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,OAAO,CAAC,CAgCnD;AAED;;GAEG;AACH,wBAAgB,oBAAoB;gBAr5BtB,OAAO;iBACN,MAAM;mBACJ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;kBACvB,IAAI;YACV,MAAM;EAm5Bf;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAEtC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,SAAS,CAElD;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC;IACpD,OAAO,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC,CA0ED"}
|
|
@@ -12,8 +12,8 @@ import os from "node:os";
|
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
import fs from "node:fs";
|
|
14
14
|
import { logger } from "../utils/logger.js";
|
|
15
|
-
import { schedulerBaseUrl
|
|
16
|
-
import { getRuntimeAccessToken, getRuntimeBindingPublicState, loadRuntimeBinding, normalizeSchedulerBaseUrl, saveRuntimeBinding, saveScopedRuntimeAccessToken, } from "./runtime-binding.js";
|
|
15
|
+
import { schedulerBaseUrl } from "../config.js";
|
|
16
|
+
import { clearRuntimeBinding, clearScopedRuntimeAccessToken, getRuntimeAccessToken, getRuntimeBindingPublicState, loadRuntimeBinding, normalizeSchedulerBaseUrl, saveRuntimeBinding, saveScopedRuntimeAccessToken, } from "./runtime-binding.js";
|
|
17
17
|
// 默认配置
|
|
18
18
|
const DEFAULT_CONFIG = {
|
|
19
19
|
enabled: false,
|
|
@@ -466,7 +466,6 @@ async function doRegister(config) {
|
|
|
466
466
|
const response = await axios.post(`${targetServerUrl}/api/instances/register`, request, {
|
|
467
467
|
headers: {
|
|
468
468
|
"Content-Type": "application/json",
|
|
469
|
-
"X-Runtime-Token": runtimeToken,
|
|
470
469
|
},
|
|
471
470
|
timeout: 10000,
|
|
472
471
|
});
|
|
@@ -477,10 +476,15 @@ async function doRegister(config) {
|
|
|
477
476
|
*/
|
|
478
477
|
async function doUnregister(instanceId) {
|
|
479
478
|
const targetServerUrl = resolveLifecycleSchedulerBaseUrl(loadPrimaryLifecycleConfig(), instanceId);
|
|
479
|
+
const binding = loadRuntimeBinding();
|
|
480
|
+
const runtimeAccessToken = getRuntimeAccessToken(binding.userId, targetServerUrl);
|
|
481
|
+
if (!runtimeAccessToken) {
|
|
482
|
+
throw new Error("runtimeAccessToken is required to unregister bridge instance");
|
|
483
|
+
}
|
|
480
484
|
const response = await axios.post(`${targetServerUrl}/api/instances/unregister`, { instanceId }, {
|
|
481
485
|
headers: {
|
|
482
486
|
"Content-Type": "application/json",
|
|
483
|
-
"X-Runtime-Token":
|
|
487
|
+
"X-Runtime-Token": runtimeAccessToken,
|
|
484
488
|
},
|
|
485
489
|
timeout: 10000,
|
|
486
490
|
});
|
|
@@ -557,7 +561,7 @@ async function autoRegisterSingle(config) {
|
|
|
557
561
|
}
|
|
558
562
|
}
|
|
559
563
|
else {
|
|
560
|
-
logger.warn("[AutoRegister] 注册响应未包含 runtime access token,MCP
|
|
564
|
+
logger.warn("[AutoRegister] 注册响应未包含 runtime access token,MCP 将无法访问调度中心,请检查 server 的 bridge 实例 token 颁发逻辑");
|
|
561
565
|
}
|
|
562
566
|
return true;
|
|
563
567
|
}
|
|
@@ -619,7 +623,6 @@ export async function requestRuntimeAccessTokenRefresh() {
|
|
|
619
623
|
}, {
|
|
620
624
|
headers: {
|
|
621
625
|
"Content-Type": "application/json",
|
|
622
|
-
"X-Runtime-Token": runtimeToken,
|
|
623
626
|
},
|
|
624
627
|
timeout: 10000,
|
|
625
628
|
});
|
|
@@ -678,7 +681,6 @@ export async function requestRuntimeAccessTokenRefreshForServer(serverBaseUrl) {
|
|
|
678
681
|
}, {
|
|
679
682
|
headers: {
|
|
680
683
|
"Content-Type": "application/json",
|
|
681
|
-
"X-Runtime-Token": runtimeToken,
|
|
682
684
|
},
|
|
683
685
|
timeout: 10000,
|
|
684
686
|
});
|
|
@@ -720,6 +722,12 @@ export async function unregister() {
|
|
|
720
722
|
const response = await doUnregister(registrationState.instanceId);
|
|
721
723
|
if (response.success) {
|
|
722
724
|
logger.info(`[AutoRegister] ✓ 注销成功: ${registrationState.instanceId}`);
|
|
725
|
+
const targetServerUrl = resolveLifecycleSchedulerBaseUrl(loadPrimaryLifecycleConfig(), registrationState.instanceId);
|
|
726
|
+
const binding = loadRuntimeBinding();
|
|
727
|
+
if (binding.userId) {
|
|
728
|
+
clearScopedRuntimeAccessToken(binding.userId, targetServerUrl);
|
|
729
|
+
}
|
|
730
|
+
clearRuntimeBinding();
|
|
723
731
|
registrationState.registered = false;
|
|
724
732
|
registrationState.instanceId = undefined;
|
|
725
733
|
return true;
|
|
@@ -791,7 +799,6 @@ export async function bridgeRestartCleanup() {
|
|
|
791
799
|
const response = await axios.post(`${targetServerUrl}/api/instances/bridge-restart-cleanup`, requestBody, {
|
|
792
800
|
headers: {
|
|
793
801
|
"Content-Type": "application/json",
|
|
794
|
-
"X-Runtime-Token": runtimeToken,
|
|
795
802
|
},
|
|
796
803
|
timeout: 10000,
|
|
797
804
|
});
|
|
@@ -94,6 +94,10 @@ describe("auto-register scheduler URL selection", () => {
|
|
|
94
94
|
expect(post.mock.calls[1]?.[0]).toBe("http://127.0.0.1:7380/api/instances/bridge-restart-cleanup");
|
|
95
95
|
expect(post.mock.calls[2]?.[0]).toBe("http://127.0.0.1:7380/api/instances/runtime-tokens/refresh");
|
|
96
96
|
expect(post.mock.calls[3]?.[0]).toBe("http://127.0.0.1:7380/api/instances/unregister");
|
|
97
|
+
expect(post.mock.calls[3]?.[2]?.headers?.["X-Runtime-Token"]).toBe("refreshed-token-123456");
|
|
98
|
+
const { getRuntimeAccessToken, loadRuntimeBinding } = await import("./runtime-binding.js");
|
|
99
|
+
expect(getRuntimeAccessToken("user-1", "http://127.0.0.1:7380")).toBeUndefined();
|
|
100
|
+
expect(loadRuntimeBinding().status).toBe("unpaired");
|
|
97
101
|
});
|
|
98
102
|
it("uses the registered target URL instead of the first configured target", async () => {
|
|
99
103
|
const runtimeHome = createRuntimeHome();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aws-client-agent-mcp.d.ts","sourceRoot":"","sources":["../../src/services/aws-client-agent-mcp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"aws-client-agent-mcp.d.ts","sourceRoot":"","sources":["../../src/services/aws-client-agent-mcp.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,mBAAmB,YAAY,CAAC;AAqB7C,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,sCAAsC;IACrD,MAAM,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;IACvC,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,sCAAsC;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAaD,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,MAAM,EAAE,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;CAC3C;AAuBD,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAgLD,wBAAgB,+BAA+B,CAC7C,OAAO,GAAE,sCAA2C,GACnD,MAAM,GAAG,IAAI,CAoDf;AA2ED,wBAAgB,+BAA+B,CAC7C,OAAO,GAAE,sCAA2C,GACnD,kBAAkB,CAEpB;AAED,wBAAgB,gCAAgC,CAC9C,OAAO,GAAE,sCAA2C,GACnD,kBAAkB,CAsBpB;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,uBAAuB,GAC7B,kBAAkB,CAsBpB;AAED,wBAAgB,+BAA+B,IAAI,IAAI,CAgBtD"}
|
|
@@ -4,7 +4,7 @@ import path from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { getRuntimeHomeDir, port, schedulerBaseUrl } from "../config.js";
|
|
6
6
|
import { logger } from "../utils/logger.js";
|
|
7
|
-
import {
|
|
7
|
+
import { loadRuntimeBinding, normalizeSchedulerBaseUrl, } from "./runtime-binding.js";
|
|
8
8
|
export const AWS_MCP_SERVER_NAME = "aws-mcp";
|
|
9
9
|
const AWS_MCP_ALLOWED_ENV_KEYS = [
|
|
10
10
|
"AWS_PROJECT_NAME",
|
|
@@ -12,7 +12,6 @@ const AWS_MCP_ALLOWED_ENV_KEYS = [
|
|
|
12
12
|
"AWS_ROLE_NAME",
|
|
13
13
|
"AWS_SERVER_URL",
|
|
14
14
|
"AWS_MCP_HTTP_URL",
|
|
15
|
-
"AWS_RUNTIME_ACCESS_TOKEN",
|
|
16
15
|
"AWS_RUNTIME_BRIDGE_BASE_URL",
|
|
17
16
|
"AWS_HEARTBEAT_INTERVAL",
|
|
18
17
|
"AWS_HEARTBEAT_TIMEOUT",
|
|
@@ -285,7 +284,6 @@ export function buildAwsMcpServerConfig(input) {
|
|
|
285
284
|
const env = getStringEnv();
|
|
286
285
|
const command = getAwsClientAgentMcpPreparedInfo();
|
|
287
286
|
const effectiveSchedulerBaseUrl = resolveSchedulerBaseUrlForMcp();
|
|
288
|
-
const issuedRuntimeAccessToken = getRuntimeAccessToken();
|
|
289
287
|
return {
|
|
290
288
|
command: command.command,
|
|
291
289
|
args: command.args,
|
|
@@ -297,9 +295,6 @@ export function buildAwsMcpServerConfig(input) {
|
|
|
297
295
|
AWS_MCP_HTTP_URL: env.AWS_MCP_HTTP_URL || toMcpHttpUrl(effectiveSchedulerBaseUrl),
|
|
298
296
|
AWS_RUNTIME_BRIDGE_BASE_URL: env.AWS_RUNTIME_BRIDGE_BASE_URL || `http://127.0.0.1:${port}`,
|
|
299
297
|
AWS_MCP_CLAIM_LAUNCH_BINDING: env.AWS_MCP_CLAIM_LAUNCH_BINDING || "true",
|
|
300
|
-
...(issuedRuntimeAccessToken
|
|
301
|
-
? { AWS_RUNTIME_ACCESS_TOKEN: issuedRuntimeAccessToken }
|
|
302
|
-
: {}),
|
|
303
298
|
},
|
|
304
299
|
};
|
|
305
300
|
}
|
|
@@ -197,7 +197,6 @@ describe('aws-client-agent-mcp service', () => {
|
|
|
197
197
|
});
|
|
198
198
|
it('builds aws-mcp server config with inferred scheduler urls', async () => {
|
|
199
199
|
process.env.AWS_CLIENT_AGENT_MCP_COMMAND = 'aws-client-agent-mcp';
|
|
200
|
-
process.env.AWS_RUNTIME_CALLBACK_TOKEN = 'secret-runtime-token';
|
|
201
200
|
process.env.CUSTOM_SECRET = 'should-not-leak';
|
|
202
201
|
process.env.AWS_RUNTIME_HOME_DIR = mkdtempSync(path.join(os.tmpdir(), 'aws-mcp-config-'));
|
|
203
202
|
process.env.AWS_RUNTIME_SCHEDULER_BASE_URL = '';
|
|
@@ -213,7 +212,6 @@ describe('aws-client-agent-mcp service', () => {
|
|
|
213
212
|
expect(config.env.AWS_WORKSPACE_PATH).toBe('/workspace/demo');
|
|
214
213
|
expect(config.env.AWS_SERVER_URL).toBe('ws://localhost:8080/ws/agent');
|
|
215
214
|
expect(config.env.AWS_MCP_HTTP_URL).toBe('http://localhost:8080/mcp/call');
|
|
216
|
-
expect(config.env.AWS_RUNTIME_CALLBACK_TOKEN).toBeUndefined();
|
|
217
215
|
expect(config.env.CUSTOM_SECRET).toBeUndefined();
|
|
218
216
|
});
|
|
219
217
|
it('repairs duplicated scheduler ports when building MCP URLs', async () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orphan-monitor.d.ts","sourceRoot":"","sources":["../../src/services/orphan-monitor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,gBAAgB,GAChB,sBAAsB,GACtB,kBAAkB,GAClB,qBAAqB,GACrB,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAA2C;IACjE,OAAO,CAAC,OAAO,CAAkB;IAEjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B;;OAEG;IACH,IAAI,IAAI,IAAI;IASZ;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0E3B;;OAEG;YACW,oBAAoB;IA8BlC;;OAEG;YACW,iBAAiB;IAgC/B;;OAEG;YACW,eAAe;IA0B7B;;OAEG;YACW,mBAAmB;IAsBjC;;OAEG;YACW,iBAAiB;
|
|
1
|
+
{"version":3,"file":"orphan-monitor.d.ts","sourceRoot":"","sources":["../../src/services/orphan-monitor.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAyBH;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,iBAAiB,GACjB,gBAAgB,GAChB,sBAAsB,GACtB,kBAAkB,GAClB,qBAAqB,GACrB,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,cAAc,CAA2C;IACjE,OAAO,CAAC,OAAO,CAAkB;IAEjC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB5B;;OAEG;IACH,IAAI,IAAI,IAAI;IASZ;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA0E3B;;OAEG;YACW,oBAAoB;IA8BlC;;OAEG;YACW,iBAAiB;IAgC/B;;OAEG;YACW,eAAe;IA0B7B;;OAEG;YACW,mBAAmB;IAsBjC;;OAEG;YACW,iBAAiB;IA8C/B;;OAEG;IACH,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAIrD;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,GAAG,IAAI;IAOtD;;OAEG;IACH,OAAO,CAAC,IAAI;IAUZ;;OAEG;IACH,SAAS,IAAI;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;CAO3E;AAKD;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED;;GAEG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,IAAI,CAAC,CAGxD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC"}
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
import { createLogger } from '../utils/logger.js';
|
|
7
7
|
import { loadPersistedSessions, savePersistedSessions } from './terminal-persistence.js';
|
|
8
8
|
import { detectOrphanProcesses, checkAllSessionsHealth, terminateProcessTree, waitForProcessExit } from './process-detector.js';
|
|
9
|
-
import { ORPHAN_SCAN_INTERVAL, ORPHAN_AUTO_CLEAN_MODE, ORPHAN_SCAN_ENABLED, schedulerBaseUrl
|
|
9
|
+
import { ORPHAN_SCAN_INTERVAL, ORPHAN_AUTO_CLEAN_MODE, ORPHAN_SCAN_ENABLED, schedulerBaseUrl } from '../config.js';
|
|
10
|
+
import { getRuntimeAccessToken } from './runtime-binding.js';
|
|
10
11
|
const logger = createLogger('orphan-monitor');
|
|
11
12
|
/**
|
|
12
13
|
* 孤儿进程监控器
|
|
@@ -227,11 +228,16 @@ export class OrphanMonitor {
|
|
|
227
228
|
return;
|
|
228
229
|
}
|
|
229
230
|
try {
|
|
231
|
+
const runtimeAccessToken = getRuntimeAccessToken(undefined, schedulerBaseUrl) || getRuntimeAccessToken();
|
|
232
|
+
if (!runtimeAccessToken) {
|
|
233
|
+
logger.debug(`缺少 runtimeAccessToken,跳过上报: ${eventType}`);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
230
236
|
const response = await fetch(`${schedulerBaseUrl}/api/runtime/orphan-event`, {
|
|
231
237
|
method: 'POST',
|
|
232
238
|
headers: {
|
|
233
239
|
'Content-Type': 'application/json',
|
|
234
|
-
'Authorization': `Bearer ${
|
|
240
|
+
'Authorization': `Bearer ${runtimeAccessToken}`,
|
|
235
241
|
},
|
|
236
242
|
body: JSON.stringify({
|
|
237
243
|
agentId,
|
|
@@ -25,6 +25,7 @@ export declare function saveScopedRuntimeAccessToken(input: {
|
|
|
25
25
|
accessToken: string;
|
|
26
26
|
}): string;
|
|
27
27
|
export declare function getScopedRuntimeAccessToken(userId: unknown, serverBaseUrl: unknown): string | undefined;
|
|
28
|
+
export declare function clearScopedRuntimeAccessToken(userId: unknown, serverBaseUrl: unknown): boolean;
|
|
28
29
|
export declare function loadRuntimeBinding(): RuntimeBindingState;
|
|
29
30
|
export declare function getRuntimeBindingPublicState(): Omit<RuntimeBindingState, "tokenHash" | "accessToken"> & {
|
|
30
31
|
paired: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runtime-binding.d.ts","sourceRoot":"","sources":["../../src/services/runtime-binding.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA2DF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAqB5E;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;
|
|
1
|
+
{"version":3,"file":"runtime-binding.d.ts","sourceRoot":"","sources":["../../src/services/runtime-binding.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AA2DF,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAqB5E;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,wBAAgB,4BAA4B,IAAI,MAAM,CAErD;AAiCD,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,OAAO,EACf,aAAa,EAAE,OAAO,GACrB,MAAM,CAYR;AAsCD,wBAAgB,4BAA4B,CAAC,KAAK,EAAE;IAClD,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAWT;AAED,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,OAAO,EACf,aAAa,EAAE,OAAO,GACrB,MAAM,GAAG,SAAS,CAUpB;AAED,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,OAAO,EACf,aAAa,EAAE,OAAO,GACrB,OAAO,CAeT;AAcD,wBAAgB,kBAAkB,IAAI,mBAAmB,CAgBxD;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAClD,mBAAmB,EACnB,WAAW,GAAG,aAAa,CAC5B,GAAG;IAAE,MAAM,EAAE,OAAO,CAAA;CAAE,CAWtB;AAED,wBAAgB,iBAAiB,IAAI,OAAO,CAG3C;AAED,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAcnE;AAED,wBAAgB,qBAAqB,CACnC,MAAM,CAAC,EAAE,OAAO,EAChB,aAAa,CAAC,EAAE,OAAO,GACtB,MAAM,GAAG,SAAS,CAepB;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAEjE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,GAAG,mBAAmB,CAwCtB;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAkB1C"}
|