aws-runtime-bridge 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/README.md +77 -77
  2. package/dist/index.js +0 -0
  3. package/dist/routes/properties.test.js +4 -4
  4. package/dist/utils/yaml-utils.test.js +129 -129
  5. package/node_modules/@cc-switch/sdk/README.md +540 -540
  6. package/node_modules/@cc-switch/sdk/package.json +31 -31
  7. package/package/aws-client-agent-mcp/README.md +288 -288
  8. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +1 -0
  9. package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -1
  10. package/package/aws-client-agent-mcp/dist/agent-client.js +12 -0
  11. package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -1
  12. package/package/aws-client-agent-mcp/dist/agent-client.test.js +31 -0
  13. package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +1 -1
  14. package/package/aws-client-agent-mcp/package.json +52 -52
  15. package/package/cc-switch-sdk/README.md +540 -540
  16. package/package/cc-switch-sdk/package.json +31 -31
  17. package/package.json +78 -78
  18. package/dist/routes/runtime-mcp-proxy.d.ts +0 -3
  19. package/dist/routes/runtime-mcp-proxy.d.ts.map +0 -1
  20. package/dist/routes/runtime-mcp-proxy.js +0 -102
  21. package/dist/routes/runtime-mcp-proxy.test.d.ts +0 -2
  22. package/dist/routes/runtime-mcp-proxy.test.d.ts.map +0 -1
  23. package/dist/routes/runtime-mcp-proxy.test.js +0 -111
  24. package/node_modules/@cc-switch/sdk/dist/sdk-import.test.d.ts +0 -2
  25. package/node_modules/@cc-switch/sdk/dist/sdk-import.test.d.ts.map +0 -1
  26. package/node_modules/@cc-switch/sdk/dist/sdk-import.test.js +0 -119
  27. package/package/cc-switch-sdk/dist/sdk-import.test.d.ts +0 -2
  28. package/package/cc-switch-sdk/dist/sdk-import.test.d.ts.map +0 -1
  29. package/package/cc-switch-sdk/dist/sdk-import.test.js +0 -119
package/README.md CHANGED
@@ -1,77 +1,77 @@
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_CALLBACK_TOKEN=replace-with-a-long-random-runtime-callback-token \
50
- AWS_RUNTIME_HOME_DIR=/opt/agentswork/runtime-home \
51
- aws-bridge
52
- ```
53
-
54
- `aws-runtime-bridge` 命令仍作为兼容别名保留。安装 `aws-runtime-bridge` 后,包内会随附
55
- `aws-client-agent-mcp` 的编译产物;bridge 启动时只负责准备该 MCP 产物,不再在 Agent 启动时默认动态注入 `aws-mcp`。
56
-
57
- 请在面板中为目标运行时安装/配置 MCP;这样 Claude Code、Codex、OpenCode、PTY 等不同启动模式都走一致的持久化 MCP 配置链路。
58
-
59
- 如需使用自定义 MCP 可执行文件,可设置:
60
-
61
- ```bash
62
- AWS_CLIENT_AGENT_MCP_COMMAND=/absolute/path/to/aws-client-agent-mcp \
63
- AWS_CLIENT_AGENT_MCP_ARGS='[]' \
64
- aws-bridge
65
- ```
66
-
67
- ## 关键环境变量
68
-
69
- | 变量名 | 说明 | 默认值 |
70
- | --- | --- | --- |
71
- | `AWS_RUNTIME_BRIDGE_PORT` | Bridge HTTP 端口 | `18081` |
72
- | `AWS_RUNTIME_SCHEDULER_BASE_URL` | aws-mcp-server 地址 | `http://localhost:8080` |
73
- | `AWS_RUNTIME_CALLBACK_TOKEN` | 后端调用 bridge 的回调 Token | 无,生产必须显式设置 |
74
- | `AWS_RUNTIME_HOME_DIR` | Bridge 管理配置与状态的主目录 | 当前用户 Home |
75
- | `AWS_RUNTIME_CORS_ORIGINS` | 允许访问 bridge 的来源,逗号分隔 | 本地开发地址 |
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_CALLBACK_TOKEN=replace-with-a-long-random-runtime-callback-token \
50
+ AWS_RUNTIME_HOME_DIR=/opt/agentswork/runtime-home \
51
+ aws-bridge
52
+ ```
53
+
54
+ `aws-runtime-bridge` 命令仍作为兼容别名保留。安装 `aws-runtime-bridge` 后,包内会随附
55
+ `aws-client-agent-mcp` 的编译产物;bridge 启动时只负责准备该 MCP 产物,不再在 Agent 启动时默认动态注入 `aws-mcp`。
56
+
57
+ 请在面板中为目标运行时安装/配置 MCP;这样 Claude Code、Codex、OpenCode、PTY 等不同启动模式都走一致的持久化 MCP 配置链路。
58
+
59
+ 如需使用自定义 MCP 可执行文件,可设置:
60
+
61
+ ```bash
62
+ AWS_CLIENT_AGENT_MCP_COMMAND=/absolute/path/to/aws-client-agent-mcp \
63
+ AWS_CLIENT_AGENT_MCP_ARGS='[]' \
64
+ aws-bridge
65
+ ```
66
+
67
+ ## 关键环境变量
68
+
69
+ | 变量名 | 说明 | 默认值 |
70
+ | --- | --- | --- |
71
+ | `AWS_RUNTIME_BRIDGE_PORT` | Bridge HTTP 端口 | `18081` |
72
+ | `AWS_RUNTIME_SCHEDULER_BASE_URL` | aws-mcp-server 地址 | `http://localhost:8080` |
73
+ | `AWS_RUNTIME_CALLBACK_TOKEN` | 后端调用 bridge 的回调 Token | 无,生产必须显式设置 |
74
+ | `AWS_RUNTIME_HOME_DIR` | Bridge 管理配置与状态的主目录 | 当前用户 Home |
75
+ | `AWS_RUNTIME_CORS_ORIGINS` | 允许访问 bridge 的来源,逗号分隔 | 本地开发地址 |
76
+
77
+ 生产环境中,`AWS_RUNTIME_SCHEDULER_BASE_URL` 必须填写机器实例可访问的 `aws-mcp-server` 地址,不能使用容器内的 `localhost`。
package/dist/index.js CHANGED
File without changes
@@ -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');
@@ -12,95 +12,95 @@ describe('yaml-utils', () => {
12
12
  expect(hasMatchingAgentPath('', 'test')).toBeNull();
13
13
  });
14
14
  it('should return null when no agent key exists', () => {
15
- const yaml = `
16
- other:
17
- - name: test
15
+ const yaml = `
16
+ other:
17
+ - name: test
18
18
  `;
19
19
  expect(hasMatchingAgentPath(yaml, 'test')).toBeNull();
20
20
  });
21
21
  it('should return null when agent is not an array', () => {
22
- const yaml = `
23
- agent:
24
- name: single
22
+ const yaml = `
23
+ agent:
24
+ name: single
25
25
  `;
26
26
  expect(hasMatchingAgentPath(yaml, 'test')).toBeNull();
27
27
  });
28
28
  it('should return null when agent has no path', () => {
29
- const yaml = `
30
- agent:
31
- - name: test
32
- description: no path
29
+ const yaml = `
30
+ agent:
31
+ - name: test
32
+ description: no path
33
33
  `;
34
34
  expect(hasMatchingAgentPath(yaml, 'test')).toBeNull();
35
35
  });
36
36
  it('should match exact path', () => {
37
- const yaml = `
38
- agent:
39
- - name: test
40
- path: src/modules
37
+ const yaml = `
38
+ agent:
39
+ - name: test
40
+ path: src/modules
41
41
  `;
42
42
  expect(hasMatchingAgentPath(yaml, 'src/modules')).toBe('src/modules');
43
43
  });
44
44
  it('should match path with different separators (backslash)', () => {
45
- const yaml = `
46
- agent:
47
- - name: test
48
- path: src/modules
45
+ const yaml = `
46
+ agent:
47
+ - name: test
48
+ path: src/modules
49
49
  `;
50
50
  expect(hasMatchingAgentPath(yaml, 'src\\modules')).toBe('src/modules');
51
51
  });
52
52
  it('should match path with forward slash when yaml has backslash', () => {
53
- const yaml = `
54
- agent:
55
- - name: test
56
- path: src\\modules
53
+ const yaml = `
54
+ agent:
55
+ - name: test
56
+ path: src\\modules
57
57
  `;
58
58
  expect(hasMatchingAgentPath(yaml, 'src/modules')).toBe('src\\modules');
59
59
  });
60
60
  it('should match current directory "." path', () => {
61
- const yaml = `
62
- agent:
63
- - name: test
64
- path: .
61
+ const yaml = `
62
+ agent:
63
+ - name: test
64
+ path: .
65
65
  `;
66
66
  expect(hasMatchingAgentPath(yaml, '.')).toBe('.');
67
67
  });
68
68
  it('should match empty path when target is "."', () => {
69
- const yaml = `
70
- agent:
71
- - name: test
72
- path: ''
69
+ const yaml = `
70
+ agent:
71
+ - name: test
72
+ path: ''
73
73
  `;
74
74
  expect(hasMatchingAgentPath(yaml, '.')).toBe('');
75
75
  });
76
76
  it('should return null when no matching path found', () => {
77
- const yaml = `
78
- agent:
79
- - name: test
80
- path: other/path
77
+ const yaml = `
78
+ agent:
79
+ - name: test
80
+ path: other/path
81
81
  `;
82
82
  expect(hasMatchingAgentPath(yaml, 'different/path')).toBeNull();
83
83
  });
84
84
  it('should return first matching path from multiple agents', () => {
85
- const yaml = `
86
- agent:
87
- - name: first
88
- path: first/path
89
- - name: second
90
- path: second/path
85
+ const yaml = `
86
+ agent:
87
+ - name: first
88
+ path: first/path
89
+ - name: second
90
+ path: second/path
91
91
  `;
92
92
  expect(hasMatchingAgentPath(yaml, 'first/path')).toBe('first/path');
93
93
  expect(hasMatchingAgentPath(yaml, 'second/path')).toBe('second/path');
94
94
  });
95
95
  it('should handle complex YAML with nested objects', () => {
96
- const yaml = `
97
- agent:
98
- - name: complex
99
- path: complex/path
100
- project: my-project
101
- prompt: |
102
- This is a multi-line
103
- prompt
96
+ const yaml = `
97
+ agent:
98
+ - name: complex
99
+ path: complex/path
100
+ project: my-project
101
+ prompt: |
102
+ This is a multi-line
103
+ prompt
104
104
  `;
105
105
  expect(hasMatchingAgentPath(yaml, 'complex/path')).toBe('complex/path');
106
106
  });
@@ -113,12 +113,12 @@ agent:
113
113
  expect(result.isTemplate).toBe(false);
114
114
  });
115
115
  it('should return matching agent config', () => {
116
- const yaml = `
117
- agent:
118
- - name: my-agent
119
- path: src/modules
120
- project: my-project
121
- prompt: test prompt
116
+ const yaml = `
117
+ agent:
118
+ - name: my-agent
119
+ path: src/modules
120
+ project: my-project
121
+ prompt: test prompt
122
122
  `;
123
123
  const result = extractAgentConfigOrTemplate(yaml, 'src/modules');
124
124
  expect(result.isTemplate).toBe(false);
@@ -127,11 +127,11 @@ agent:
127
127
  expect(result.content).toContain('my-project');
128
128
  });
129
129
  it('should generate template when no matching agent found', () => {
130
- const yaml = `
131
- agent:
132
- - name: other-agent
133
- path: other/path
134
- project: existing-project
130
+ const yaml = `
131
+ agent:
132
+ - name: other-agent
133
+ path: other/path
134
+ project: existing-project
135
135
  `;
136
136
  const result = extractAgentConfigOrTemplate(yaml, 'new/path');
137
137
  expect(result.isTemplate).toBe(true);
@@ -139,10 +139,10 @@ agent:
139
139
  expect(result.content).toContain('new/path');
140
140
  });
141
141
  it('should generate template with empty project when no agents have project', () => {
142
- const yaml = `
143
- agent:
144
- - name: agent1
145
- path: path1
142
+ const yaml = `
143
+ agent:
144
+ - name: agent1
145
+ path: path1
146
146
  `;
147
147
  const result = extractAgentConfigOrTemplate(yaml, 'new/path');
148
148
  expect(result.isTemplate).toBe(true);
@@ -150,21 +150,21 @@ agent:
150
150
  expect(result.content).toContain('project: ""');
151
151
  });
152
152
  it('should match current directory "." path', () => {
153
- const yaml = `
154
- agent:
155
- - name: root-agent
156
- path: .
157
- project: root-project
153
+ const yaml = `
154
+ agent:
155
+ - name: root-agent
156
+ path: .
157
+ project: root-project
158
158
  `;
159
159
  const result = extractAgentConfigOrTemplate(yaml, '.');
160
160
  expect(result.isTemplate).toBe(false);
161
161
  expect(result.content).toContain('root-agent');
162
162
  });
163
163
  it('should normalize path separators in output', () => {
164
- const yaml = `
165
- agent:
166
- - name: test
167
- path: src\\modules
164
+ const yaml = `
165
+ agent:
166
+ - name: test
167
+ path: src\\modules
168
168
  `;
169
169
  const result = extractAgentConfigOrTemplate(yaml, 'src/modules');
170
170
  expect(result.isTemplate).toBe(false);
@@ -192,78 +192,78 @@ agent:
192
192
  expect(autoFillPathInYml(invalidYaml, 'test/path')).toBe(invalidYaml);
193
193
  });
194
194
  it('should return original content when no agent key', () => {
195
- const yaml = `
196
- other:
197
- - name: test
195
+ const yaml = `
196
+ other:
197
+ - name: test
198
198
  `;
199
199
  expect(autoFillPathInYml(yaml, 'test/path')).toBe(yaml);
200
200
  });
201
201
  it('should fill empty path', () => {
202
- const yaml = `
203
- agent:
204
- - name: test
205
- path: ''
206
- project: my-project
202
+ const yaml = `
203
+ agent:
204
+ - name: test
205
+ path: ''
206
+ project: my-project
207
207
  `;
208
208
  const result = autoFillPathInYml(yaml, 'new/path');
209
209
  expect(result).toContain('new/path');
210
210
  expect(result).not.toContain("path: ''");
211
211
  });
212
212
  it('should fill undefined path', () => {
213
- const yaml = `
214
- agent:
215
- - name: test
216
- project: my-project
213
+ const yaml = `
214
+ agent:
215
+ - name: test
216
+ project: my-project
217
217
  `;
218
218
  const result = autoFillPathInYml(yaml, 'new/path');
219
219
  expect(result).toContain('new/path');
220
220
  });
221
221
  it('should fill null path', () => {
222
- const yaml = `
223
- agent:
224
- - name: test
225
- path: null
222
+ const yaml = `
223
+ agent:
224
+ - name: test
225
+ path: null
226
226
  `;
227
227
  const result = autoFillPathInYml(yaml, 'new/path');
228
228
  expect(result).toContain('new/path');
229
229
  });
230
230
  it('should fill whitespace-only path', () => {
231
- const yaml = `
232
- agent:
233
- - name: test
234
- path: ' '
231
+ const yaml = `
232
+ agent:
233
+ - name: test
234
+ path: ' '
235
235
  `;
236
236
  const result = autoFillPathInYml(yaml, 'new/path');
237
237
  expect(result).toContain('new/path');
238
238
  });
239
239
  it('should not modify existing non-empty path', () => {
240
- const yaml = `
241
- agent:
242
- - name: test
243
- path: existing/path
240
+ const yaml = `
241
+ agent:
242
+ - name: test
243
+ path: existing/path
244
244
  `;
245
245
  const result = autoFillPathInYml(yaml, 'new/path');
246
246
  expect(result).toContain('existing/path');
247
247
  expect(result).not.toContain('new/path');
248
248
  });
249
249
  it('should handle multiple agents', () => {
250
- const yaml = `
251
- agent:
252
- - name: agent1
253
- path: ''
254
- - name: agent2
255
- path: existing/path
256
- - name: agent3
250
+ const yaml = `
251
+ agent:
252
+ - name: agent1
253
+ path: ''
254
+ - name: agent2
255
+ path: existing/path
256
+ - name: agent3
257
257
  `;
258
258
  const result = autoFillPathInYml(yaml, 'new/path');
259
259
  // agent1 should have path filled
260
260
  expect(result).toContain('new/path');
261
261
  });
262
262
  it('should return original content when no modification needed', () => {
263
- const yaml = `
264
- agent:
265
- - name: test
266
- path: existing/path
263
+ const yaml = `
264
+ agent:
265
+ - name: test
266
+ path: existing/path
267
267
  `;
268
268
  const result = autoFillPathInYml(yaml, 'new/path');
269
269
  expect(result).toBe(yaml);
@@ -296,11 +296,11 @@ agent:
296
296
  it('should load config from workspace directory with matching path "."', async () => {
297
297
  const configPath = path.join(workspacePath, relativePath);
298
298
  await fs.mkdir(path.dirname(configPath), { recursive: true });
299
- await fs.writeFile(configPath, `
300
- agent:
301
- - name: local-agent
302
- path: .
303
- project: local-project
299
+ await fs.writeFile(configPath, `
300
+ agent:
301
+ - name: local-agent
302
+ path: .
303
+ project: local-project
304
304
  `, 'utf-8');
305
305
  const result = await loadYmlWithUpwardSearch(workspacePath, relativePath);
306
306
  expect(result.content).not.toBeNull();
@@ -312,11 +312,11 @@ agent:
312
312
  // 在 project/module 目录创建配置,匹配 src 路径
313
313
  const parentConfigPath = path.join(tempRoot, 'project', 'module', relativePath);
314
314
  await fs.mkdir(path.dirname(parentConfigPath), { recursive: true });
315
- await fs.writeFile(parentConfigPath, `
316
- agent:
317
- - name: module-agent
318
- path: src
319
- project: module-project
315
+ await fs.writeFile(parentConfigPath, `
316
+ agent:
317
+ - name: module-agent
318
+ path: src
319
+ project: module-project
320
320
  `, 'utf-8');
321
321
  const result = await loadYmlWithUpwardSearch(workspacePath, relativePath);
322
322
  expect(result.content).not.toBeNull();
@@ -328,10 +328,10 @@ agent:
328
328
  // 在 project/module 目录创建配置,但不匹配 src 路径
329
329
  const parentConfigPath = path.join(tempRoot, 'project', 'module', relativePath);
330
330
  await fs.mkdir(path.dirname(parentConfigPath), { recursive: true });
331
- await fs.writeFile(parentConfigPath, `
332
- agent:
333
- - name: other-agent
334
- path: other/path
331
+ await fs.writeFile(parentConfigPath, `
332
+ agent:
333
+ - name: other-agent
334
+ path: other/path
335
335
  `, 'utf-8');
336
336
  const result = await loadYmlWithUpwardSearch(workspacePath, relativePath);
337
337
  expect(result.content).not.toBeNull();
@@ -342,17 +342,17 @@ agent:
342
342
  // 在 workspace 目录创建匹配的配置
343
343
  const localConfigPath = path.join(workspacePath, relativePath);
344
344
  await fs.mkdir(path.dirname(localConfigPath), { recursive: true });
345
- await fs.writeFile(localConfigPath, `
346
- agent:
347
- - name: local-agent
348
- path: .
345
+ await fs.writeFile(localConfigPath, `
346
+ agent:
347
+ - name: local-agent
348
+ path: .
349
349
  `, 'utf-8');
350
350
  // 在 parent 目录也创建配置
351
351
  const parentConfigPath = path.join(tempRoot, 'project', 'module', relativePath);
352
- await fs.writeFile(parentConfigPath, `
353
- agent:
354
- - name: parent-agent
355
- path: src
352
+ await fs.writeFile(parentConfigPath, `
353
+ agent:
354
+ - name: parent-agent
355
+ path: src
356
356
  `, 'utf-8');
357
357
  const result = await loadYmlWithUpwardSearch(workspacePath, relativePath);
358
358
  // 应该使用 local 的配置,因为更近且匹配