aws-runtime-bridge 1.7.49 → 1.8.0

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 (199) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts +104 -0
  2. package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -0
  3. package/dist/adapter/AcodeSdkAdapter.js +644 -0
  4. package/dist/adapter/AcodeSdkAdapter.test.d.ts +2 -0
  5. package/dist/adapter/AcodeSdkAdapter.test.d.ts.map +1 -0
  6. package/dist/adapter/AcodeSdkAdapter.test.js +1280 -0
  7. package/dist/adapter/AdapterRegistry.d.ts +1 -1
  8. package/dist/adapter/AdapterRegistry.d.ts.map +1 -1
  9. package/dist/adapter/AdapterRegistry.js +2 -0
  10. package/dist/adapter/AdapterRegistry.test.js +10 -1
  11. package/dist/adapter/ClaudeSdkAdapter.test.js +31 -8
  12. package/dist/adapter/CodexSdkAdapter.d.ts.map +1 -1
  13. package/dist/adapter/CodexSdkAdapter.js +2 -0
  14. package/dist/adapter/OpencodeSdkAdapter.d.ts.map +1 -1
  15. package/dist/adapter/OpencodeSdkAdapter.js +2 -0
  16. package/dist/adapter/SdkProviderSpi.d.ts.map +1 -1
  17. package/dist/adapter/SdkProviderSpi.js +10 -1
  18. package/dist/adapter/adapter.test.js +2 -2
  19. package/dist/adapter/idle-poll-loop.d.ts +4 -4
  20. package/dist/adapter/idle-poll-loop.d.ts.map +1 -1
  21. package/dist/adapter/idle-poll-loop.js +3 -3
  22. package/dist/adapter/idle-poll-loop.test.js +15 -1
  23. package/dist/adapter/index.d.ts +1 -0
  24. package/dist/adapter/index.d.ts.map +1 -1
  25. package/dist/adapter/index.js +1 -0
  26. package/dist/adapter/types.d.ts +25 -6
  27. package/dist/adapter/types.d.ts.map +1 -1
  28. package/dist/adapter/types.js +221 -110
  29. package/dist/adapter/types.test.js +10 -3
  30. package/dist/adapters/cc-switch/index.d.ts +2 -0
  31. package/dist/adapters/cc-switch/index.d.ts.map +1 -1
  32. package/dist/adapters/cc-switch/index.js +6 -0
  33. package/dist/adapters/cc-switch/mcp-acode.d.ts +17 -0
  34. package/dist/adapters/cc-switch/mcp-acode.d.ts.map +1 -0
  35. package/dist/adapters/cc-switch/mcp-acode.js +71 -0
  36. package/dist/adapters/cc-switch/mcp-acode.test.d.ts +2 -0
  37. package/dist/adapters/cc-switch/mcp-acode.test.d.ts.map +1 -0
  38. package/dist/adapters/cc-switch/mcp-acode.test.js +80 -0
  39. package/dist/adapters/cc-switch/mcp-claude.d.ts.map +1 -1
  40. package/dist/adapters/cc-switch/mcp-claude.js +1 -0
  41. package/dist/adapters/cc-switch/mcp-claudecode.d.ts.map +1 -1
  42. package/dist/adapters/cc-switch/mcp-claudecode.js +1 -0
  43. package/dist/adapters/cc-switch/mcp-claudecode.test.js +1 -0
  44. package/dist/adapters/cc-switch/mcp-codex.d.ts.map +1 -1
  45. package/dist/adapters/cc-switch/mcp-codex.js +1 -0
  46. package/dist/adapters/cc-switch/mcp-codex.test.js +1 -0
  47. package/dist/adapters/cc-switch/mcp-opencode.d.ts.map +1 -1
  48. package/dist/adapters/cc-switch/mcp-opencode.js +1 -0
  49. package/dist/adapters/cc-switch/mcp-opencode.test.js +1 -0
  50. package/dist/adapters/cc-switch/skill-acode.d.ts +11 -0
  51. package/dist/adapters/cc-switch/skill-acode.d.ts.map +1 -0
  52. package/dist/adapters/cc-switch/skill-acode.js +12 -0
  53. package/dist/adapters/cc-switch/skill-directory.test.js +1 -0
  54. package/dist/config.d.ts +4 -0
  55. package/dist/config.d.ts.map +1 -1
  56. package/dist/config.js +10 -0
  57. package/dist/index.js +2 -0
  58. package/dist/routes/ai-sources.js +3 -2
  59. package/dist/routes/instance.d.ts.map +1 -1
  60. package/dist/routes/instance.js +7 -8
  61. package/dist/routes/instance.test.js +2 -1
  62. package/dist/routes/mcp.js +2 -2
  63. package/dist/routes/mcp.test.js +2 -1
  64. package/dist/routes/runtime-binding.d.ts +3 -2
  65. package/dist/routes/runtime-binding.d.ts.map +1 -1
  66. package/dist/routes/runtime-binding.js +11 -58
  67. package/dist/routes/runtime-binding.test.js +4 -80
  68. package/dist/routes/sessions.d.ts +5 -0
  69. package/dist/routes/sessions.d.ts.map +1 -1
  70. package/dist/routes/sessions.js +36 -16
  71. package/dist/routes/sessions.test.js +13 -0
  72. package/dist/routes/skills.js +2 -2
  73. package/dist/routes/skills.test.js +2 -1
  74. package/dist/routes/terminal.d.ts +27 -7
  75. package/dist/routes/terminal.d.ts.map +1 -1
  76. package/dist/routes/terminal.js +439 -171
  77. package/dist/routes/terminal.test.js +385 -197
  78. package/dist/services/acode-package.d.ts +8 -0
  79. package/dist/services/acode-package.d.ts.map +1 -0
  80. package/dist/services/acode-package.js +82 -0
  81. package/dist/services/ai-source-apply.d.ts +4 -0
  82. package/dist/services/ai-source-apply.d.ts.map +1 -1
  83. package/dist/services/ai-source-apply.js +8 -0
  84. package/dist/services/ai-source-apply.test.js +8 -1
  85. package/dist/services/cc-switch-sdk.d.ts.map +1 -1
  86. package/dist/services/cc-switch-sdk.js +9 -1
  87. package/dist/services/instance-init-service.d.ts.map +1 -1
  88. package/dist/services/instance-init-service.js +3 -2
  89. package/dist/services/instance-init-service.test.js +6 -5
  90. package/dist/services/instance-service.d.ts.map +1 -1
  91. package/dist/services/instance-service.js +1 -0
  92. package/dist/services/instance-state.js +1 -1
  93. package/dist/services/instance-state.test.js +4 -4
  94. package/dist/services/mcp-launch-binding-queue.d.ts +1 -0
  95. package/dist/services/mcp-launch-binding-queue.d.ts.map +1 -1
  96. package/dist/services/mcp-launch-binding-queue.js +8 -2
  97. package/dist/services/mcp-launch-binding-queue.test.js +47 -4
  98. package/dist/services/session-output.d.ts +10 -6
  99. package/dist/services/session-output.d.ts.map +1 -1
  100. package/dist/services/session-output.js +29 -14
  101. package/dist/services/session-output.test.js +93 -39
  102. package/dist/services/tool-installer.d.ts.map +1 -1
  103. package/dist/services/tool-installer.js +10 -0
  104. package/dist/types.d.ts +5 -0
  105. package/dist/types.d.ts.map +1 -1
  106. package/dist/utils/file-utils.d.ts.map +1 -1
  107. package/dist/utils/file-utils.js +1 -0
  108. package/dist/utils/mcp-utils.d.ts.map +1 -1
  109. package/dist/utils/mcp-utils.js +4 -1
  110. package/dist/utils/validation.js +1 -1
  111. package/node_modules/@cc-switch/sdk/dist/constants.d.ts.map +1 -1
  112. package/node_modules/@cc-switch/sdk/dist/constants.js +7 -0
  113. package/node_modules/@cc-switch/sdk/dist/schemas.d.ts.map +1 -1
  114. package/node_modules/@cc-switch/sdk/dist/schemas.js +1 -0
  115. package/node_modules/@cc-switch/sdk/dist/sdk.d.ts.map +1 -1
  116. package/node_modules/@cc-switch/sdk/dist/sdk.js +7 -3
  117. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts +6 -0
  118. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts.map +1 -1
  119. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.js +27 -1
  120. package/node_modules/@cc-switch/sdk/dist/types.d.ts +4 -1
  121. package/node_modules/@cc-switch/sdk/dist/types.d.ts.map +1 -1
  122. package/package/acode/README.md +88 -0
  123. package/package/acode/dist/built-in-file-tools.d.ts +16 -0
  124. package/package/acode/dist/built-in-file-tools.d.ts.map +1 -0
  125. package/package/acode/dist/built-in-file-tools.js +569 -0
  126. package/package/acode/dist/cli.d.ts +3 -0
  127. package/package/acode/dist/cli.d.ts.map +1 -0
  128. package/package/acode/dist/cli.js +37 -0
  129. package/package/acode/dist/commands/commandLoader.d.ts +7 -0
  130. package/package/acode/dist/commands/commandLoader.d.ts.map +1 -0
  131. package/package/acode/dist/commands/commandLoader.js +33 -0
  132. package/package/acode/dist/commands/commandParser.d.ts +7 -0
  133. package/package/acode/dist/commands/commandParser.d.ts.map +1 -0
  134. package/package/acode/dist/commands/commandParser.js +77 -0
  135. package/package/acode/dist/commands/commandRegistry.d.ts +13 -0
  136. package/package/acode/dist/commands/commandRegistry.d.ts.map +1 -0
  137. package/package/acode/dist/commands/commandRegistry.js +30 -0
  138. package/package/acode/dist/config.d.ts +4 -0
  139. package/package/acode/dist/config.d.ts.map +1 -0
  140. package/package/acode/dist/config.js +80 -0
  141. package/package/acode/dist/hooks/hookBus.d.ts +19 -0
  142. package/package/acode/dist/hooks/hookBus.d.ts.map +1 -0
  143. package/package/acode/dist/hooks/hookBus.js +40 -0
  144. package/package/acode/dist/index.d.ts +8 -0
  145. package/package/acode/dist/index.d.ts.map +1 -0
  146. package/package/acode/dist/index.js +7 -0
  147. package/package/acode/dist/runtime.d.ts +42 -0
  148. package/package/acode/dist/runtime.d.ts.map +1 -0
  149. package/package/acode/dist/runtime.js +1283 -0
  150. package/package/acode/dist/types.d.ts +112 -0
  151. package/package/acode/dist/types.d.ts.map +1 -0
  152. package/package/acode/dist/types.js +1 -0
  153. package/package/acode/package.json +24 -0
  154. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +4 -4
  155. package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -1
  156. package/package/aws-client-agent-mcp/dist/agent-client.js +9 -6
  157. package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -1
  158. package/package/aws-client-agent-mcp/dist/agent-client.test.js +21 -0
  159. package/package/aws-client-agent-mcp/dist/agent-client.test.js.map +1 -1
  160. package/package/aws-client-agent-mcp/dist/http-client.d.ts +1 -17
  161. package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -1
  162. package/package/aws-client-agent-mcp/dist/http-client.js +7 -113
  163. package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -1
  164. package/package/aws-client-agent-mcp/dist/http-client.test.js +22 -2
  165. package/package/aws-client-agent-mcp/dist/http-client.test.js.map +1 -1
  166. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +0 -5
  167. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
  168. package/package/aws-client-agent-mcp/dist/mcp-server.js +3 -24
  169. package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
  170. package/package/aws-client-agent-mcp/dist/mcp-server.test.js +90 -5
  171. package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
  172. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.d.ts.map +1 -1
  173. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js +1 -0
  174. package/package/aws-client-agent-mcp/dist/runtime-launch-binding.js.map +1 -1
  175. package/package/aws-client-agent-mcp/dist/status-reporter.d.ts +2 -0
  176. package/package/aws-client-agent-mcp/dist/status-reporter.d.ts.map +1 -1
  177. package/package/aws-client-agent-mcp/dist/status-reporter.js +31 -3
  178. package/package/aws-client-agent-mcp/dist/status-reporter.js.map +1 -1
  179. package/package/aws-client-agent-mcp/dist/types.d.ts +4 -1
  180. package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -1
  181. package/package/aws-client-agent-mcp/dist/types.js.map +1 -1
  182. package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +0 -13
  183. package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -1
  184. package/package/aws-client-agent-mcp/dist/websocket-client.js +5 -100
  185. package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
  186. package/package/aws-client-agent-mcp/dist/websocket-client.test.js +43 -0
  187. package/package/aws-client-agent-mcp/dist/websocket-client.test.js.map +1 -1
  188. package/package/cc-switch-sdk/dist/constants.d.ts.map +1 -1
  189. package/package/cc-switch-sdk/dist/constants.js +7 -0
  190. package/package/cc-switch-sdk/dist/schemas.d.ts.map +1 -1
  191. package/package/cc-switch-sdk/dist/schemas.js +1 -0
  192. package/package/cc-switch-sdk/dist/sdk.d.ts.map +1 -1
  193. package/package/cc-switch-sdk/dist/sdk.js +7 -3
  194. package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts +6 -0
  195. package/package/cc-switch-sdk/dist/services/ai-config-service.d.ts.map +1 -1
  196. package/package/cc-switch-sdk/dist/services/ai-config-service.js +27 -1
  197. package/package/cc-switch-sdk/dist/types.d.ts +4 -1
  198. package/package/cc-switch-sdk/dist/types.d.ts.map +1 -1
  199. package/package.json +8 -4
@@ -0,0 +1,8 @@
1
+ export declare function getReleasedAcodeEntryPath(): string;
2
+ /**
3
+ * 释放随 bridge 打包的内置 ACode runtime。
4
+ * 主流程:检查 bundled dist -> 复制 dist 与 metadata -> 链接 bridge node_modules,
5
+ * 确保 ACode 无需安装即可被 Adapter 动态加载。
6
+ */
7
+ export declare function ensureAcodePackageReleased(): string | null;
8
+ //# sourceMappingURL=acode-package.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acode-package.d.ts","sourceRoot":"","sources":["../../src/services/acode-package.ts"],"names":[],"mappings":"AAyDA,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,MAAM,GAAG,IAAI,CAwB1D"}
@@ -0,0 +1,82 @@
1
+ import { existsSync, mkdirSync, rmSync, cpSync, symlinkSync, lstatSync, realpathSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { getRuntimeHomeDir } from '../config.js';
5
+ import { logger } from '../utils/logger.js';
6
+ function getBridgePackageRoot() {
7
+ const currentFile = fileURLToPath(import.meta.url);
8
+ return path.resolve(path.dirname(currentFile), '..', '..');
9
+ }
10
+ function getBundledAcodeRoot(packageRoot = getBridgePackageRoot()) {
11
+ return path.join(packageRoot, 'package', 'acode');
12
+ }
13
+ function getReleasedAcodeRoot() {
14
+ return path.join(getRuntimeHomeDir(), '.agentswork', 'runtime-bridge', 'packages', 'acode');
15
+ }
16
+ function shouldReplaceNodeModulesLink(targetPath) {
17
+ if (!existsSync(targetPath)) {
18
+ return true;
19
+ }
20
+ const stat = lstatSync(targetPath);
21
+ return stat.isSymbolicLink() || stat.isDirectory();
22
+ }
23
+ function isExpectedNodeModulesLink(targetPath, sourcePath) {
24
+ if (!existsSync(targetPath)) {
25
+ return false;
26
+ }
27
+ try {
28
+ return realpathSync(targetPath) === realpathSync(sourcePath);
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ function ensureReleasedNodeModules(packageRoot, releasedRoot) {
35
+ const sourceNodeModules = path.join(packageRoot, 'node_modules');
36
+ const releasedNodeModules = path.join(releasedRoot, 'node_modules');
37
+ if (!existsSync(sourceNodeModules)) {
38
+ logger.warn(`[runtime-bridge] ACode 未找到 bridge node_modules,依赖解析可能失败: ${sourceNodeModules}`);
39
+ return;
40
+ }
41
+ if (isExpectedNodeModulesLink(releasedNodeModules, sourceNodeModules)) {
42
+ return;
43
+ }
44
+ if (!shouldReplaceNodeModulesLink(releasedNodeModules)) {
45
+ logger.warn(`[runtime-bridge] ACode node_modules 路径已存在但不是目录或链接,已保留: ${releasedNodeModules}`);
46
+ return;
47
+ }
48
+ rmSync(releasedNodeModules, { recursive: true, force: true });
49
+ symlinkSync(sourceNodeModules, releasedNodeModules, process.platform === 'win32' ? 'junction' : 'dir');
50
+ }
51
+ export function getReleasedAcodeEntryPath() {
52
+ return path.join(getReleasedAcodeRoot(), 'dist', 'index.js');
53
+ }
54
+ /**
55
+ * 释放随 bridge 打包的内置 ACode runtime。
56
+ * 主流程:检查 bundled dist -> 复制 dist 与 metadata -> 链接 bridge node_modules,
57
+ * 确保 ACode 无需安装即可被 Adapter 动态加载。
58
+ */
59
+ export function ensureAcodePackageReleased() {
60
+ const packageRoot = getBridgePackageRoot();
61
+ const bundledRoot = getBundledAcodeRoot(packageRoot);
62
+ const bundledDist = path.join(bundledRoot, 'dist');
63
+ const bundledEntry = path.join(bundledDist, 'index.js');
64
+ if (!existsSync(bundledEntry)) {
65
+ logger.warn(`[runtime-bridge] 未找到 bundled ACode dist,ACode 启动可能失败: ${bundledEntry}`);
66
+ return null;
67
+ }
68
+ const releasedRoot = getReleasedAcodeRoot();
69
+ const releasedDist = path.join(releasedRoot, 'dist');
70
+ mkdirSync(releasedRoot, { recursive: true });
71
+ rmSync(releasedDist, { recursive: true, force: true });
72
+ cpSync(bundledDist, releasedDist, { recursive: true, force: true, errorOnExist: false });
73
+ for (const fileName of ['package.json', 'README.md']) {
74
+ const source = path.join(bundledRoot, fileName);
75
+ if (existsSync(source)) {
76
+ cpSync(source, path.join(releasedRoot, fileName), { force: true, errorOnExist: false });
77
+ }
78
+ }
79
+ ensureReleasedNodeModules(packageRoot, releasedRoot);
80
+ logger.info(`[runtime-bridge] ACode 已准备: ${getReleasedAcodeEntryPath()}`);
81
+ return getReleasedAcodeEntryPath();
82
+ }
@@ -7,11 +7,13 @@ export interface AiSourceTemplateInput {
7
7
  models?: unknown;
8
8
  }
9
9
  export interface RequestedAiSources {
10
+ acode?: unknown;
10
11
  claudecode?: unknown;
11
12
  codex?: unknown;
12
13
  opencode?: unknown;
13
14
  }
14
15
  export interface AiConfigApplier {
16
+ applyAcodeConfig(config: OpenCodeConfig): Promise<OpenCodeConfig>;
15
17
  applyClaudeCodeConfig(config: ClaudeCodeConfig): Promise<ClaudeCodeConfig>;
16
18
  applyCodexConfig(config: CodexConfig): Promise<CodexConfig>;
17
19
  applyOpenCodeConfig(config: OpenCodeConfig): Promise<OpenCodeConfig>;
@@ -25,12 +27,14 @@ export interface ApplyCurrentAiConfigOptions {
25
27
  export interface AppliedAiConfigSummary {
26
28
  generatedFromUnifiedTemplate: boolean;
27
29
  applied: {
30
+ acode: string[];
28
31
  claudecode: string[];
29
32
  codex: string[];
30
33
  opencode: string[];
31
34
  };
32
35
  skippedTools: string[];
33
36
  merged: {
37
+ acode: OpenCodeConfig | null;
34
38
  claudecode: ClaudeCodeConfig | null;
35
39
  codex: CodexConfig | null;
36
40
  opencode: OpenCodeConfig | null;
@@ -1 +1 @@
1
- {"version":3,"file":"ai-source-apply.d.ts","sourceRoot":"","sources":["../../src/services/ai-source-apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3E,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC9C,eAAe,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,4BAA4B,EAAE,OAAO,CAAC;IACtC,OAAO,EAAE;QACP,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE;QACN,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;QACpC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;QAC1B,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;AAuCD;;GAEG;AACH,wBAAsB,oCAAoC,CACxD,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,sBAAsB,CAAC,CAkDjC"}
1
+ {"version":3,"file":"ai-source-apply.d.ts","sourceRoot":"","sources":["../../src/services/ai-source-apply.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAChB,KAAK,cAAc,EACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAClE,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC3E,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC5D,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CACtE;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,CAAC;IACnD,gBAAgB,CAAC,EAAE,kBAAkB,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAC9C,eAAe,EAAE,eAAe,CAAC;CAClC;AAED,MAAM,WAAW,sBAAsB;IACrC,4BAA4B,EAAE,OAAO,CAAC;IACtC,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE;QACN,KAAK,EAAE,cAAc,GAAG,IAAI,CAAC;QAC7B,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;QACpC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;QAC1B,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;KACjC,CAAC;CACH;AAuCD;;GAEG;AACH,wBAAsB,oCAAoC,CACxD,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,sBAAsB,CAAC,CA6DjC"}
@@ -37,18 +37,24 @@ export async function applyCurrentAiConfigToInstalledTools(options) {
37
37
  const generatedConfig = options.template
38
38
  ? buildToolSpecificAiConfig(normalizeTemplate(options.template))
39
39
  : null;
40
+ const requestedAcodeConfig = normalizeRequestedConfig(options.requestedSources?.acode);
40
41
  const requestedClaudeConfig = normalizeRequestedConfig(options.requestedSources?.claudecode);
41
42
  const requestedCodexConfig = normalizeRequestedConfig(options.requestedSources?.codex);
42
43
  const requestedOpenCodeConfig = normalizeRequestedConfig(options.requestedSources?.opencode);
44
+ const acodeConfig = generatedConfig?.acode || requestedAcodeConfig;
43
45
  const claudeConfig = generatedConfig?.claudecode || requestedClaudeConfig;
44
46
  const codexConfig = generatedConfig?.codex || requestedCodexConfig;
45
47
  const openCodeConfig = generatedConfig?.opencode || requestedOpenCodeConfig;
46
48
  const skippedTools = Object.values(options.toolStatus)
47
49
  .filter((item) => !item.installed)
48
50
  .map((item) => item.tool);
51
+ let mergedAcode = null;
49
52
  let mergedClaude = null;
50
53
  let mergedCodex = null;
51
54
  let mergedOpencode = null;
55
+ if (acodeConfig && isInstalled(options.toolStatus, 'acode')) {
56
+ mergedAcode = await options.aiConfigService.applyAcodeConfig(acodeConfig);
57
+ }
52
58
  if (claudeConfig && isClaudeCodeInstalled(options.toolStatus)) {
53
59
  mergedClaude = await options.aiConfigService.applyClaudeCodeConfig(claudeConfig);
54
60
  }
@@ -61,12 +67,14 @@ export async function applyCurrentAiConfigToInstalledTools(options) {
61
67
  return {
62
68
  generatedFromUnifiedTemplate: Boolean(generatedConfig),
63
69
  applied: {
70
+ acode: acodeConfig && mergedAcode ? Object.keys(acodeConfig) : [],
64
71
  claudecode: claudeConfig && mergedClaude ? Object.keys(claudeConfig) : [],
65
72
  codex: codexConfig && mergedCodex ? Object.keys(codexConfig) : [],
66
73
  opencode: openCodeConfig && mergedOpencode ? Object.keys(openCodeConfig) : [],
67
74
  },
68
75
  skippedTools,
69
76
  merged: {
77
+ acode: mergedAcode,
70
78
  claudecode: mergedClaude,
71
79
  codex: mergedCodex,
72
80
  opencode: mergedOpencode,
@@ -14,6 +14,7 @@ describe('applyCurrentAiConfigToInstalledTools', () => {
14
14
  const applyClaudeCodeConfig = vi.fn(async (config) => config);
15
15
  const applyCodexConfig = vi.fn(async (config) => config);
16
16
  const applyOpenCodeConfig = vi.fn(async (config) => config);
17
+ const applyAcodeConfig = vi.fn(async (config) => config);
17
18
  const { applyCurrentAiConfigToInstalledTools } = await import('./ai-source-apply.js');
18
19
  const result = await applyCurrentAiConfigToInstalledTools({
19
20
  template: {
@@ -27,11 +28,13 @@ describe('applyCurrentAiConfigToInstalledTools', () => {
27
28
  opencode: { provider: { default: { options: { baseURL: 'https://stale.example.com/v1' } } } },
28
29
  },
29
30
  toolStatus: {
31
+ acode: status('acode', true),
30
32
  claude: status('claude', true),
31
33
  codex: status('codex', false),
32
34
  opencode: status('opencode', true),
33
35
  },
34
36
  aiConfigService: {
37
+ applyAcodeConfig,
35
38
  applyClaudeCodeConfig,
36
39
  applyCodexConfig,
37
40
  applyOpenCodeConfig,
@@ -56,9 +59,10 @@ describe('applyCurrentAiConfigToInstalledTools', () => {
56
59
  }),
57
60
  }),
58
61
  }));
62
+ expect(applyAcodeConfig).toHaveBeenCalledOnce();
59
63
  expect(result.applied.codex).toEqual([]);
60
64
  expect(result.skippedTools).toEqual(['codex']);
61
- });
65
+ }, 15_000);
62
66
  it('applies Claude Code config when the installed tool status uses the claudecode alias', async () => {
63
67
  const applyClaudeCodeConfig = vi.fn(async (config) => config);
64
68
  const { applyCurrentAiConfigToInstalledTools } = await import('./ai-source-apply.js');
@@ -72,6 +76,7 @@ describe('applyCurrentAiConfigToInstalledTools', () => {
72
76
  claudecode: status('claudecode', true),
73
77
  },
74
78
  aiConfigService: {
79
+ applyAcodeConfig: vi.fn(async (config) => config),
75
80
  applyClaudeCodeConfig,
76
81
  applyCodexConfig: vi.fn(async (config) => config),
77
82
  applyOpenCodeConfig: vi.fn(async (config) => config),
@@ -83,6 +88,7 @@ describe('applyCurrentAiConfigToInstalledTools', () => {
83
88
  const applyClaudeCodeConfig = vi.fn(async (config) => config);
84
89
  const applyCodexConfig = vi.fn(async (config) => config);
85
90
  const applyOpenCodeConfig = vi.fn(async (config) => config);
91
+ const applyAcodeConfig = vi.fn(async (config) => config);
86
92
  const { applyCurrentAiConfigToInstalledTools } = await import('./ai-source-apply.js');
87
93
  const result = await applyCurrentAiConfigToInstalledTools({
88
94
  template: null,
@@ -109,6 +115,7 @@ describe('applyCurrentAiConfigToInstalledTools', () => {
109
115
  opencode: status('opencode', true),
110
116
  },
111
117
  aiConfigService: {
118
+ applyAcodeConfig,
112
119
  applyClaudeCodeConfig,
113
120
  applyCodexConfig,
114
121
  applyOpenCodeConfig,
@@ -1 +1 @@
1
- {"version":3,"file":"cc-switch-sdk.d.ts","sourceRoot":"","sources":["../../src/services/cc-switch-sdk.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAc,MAAM,gBAAgB,CAAC;AAYzF,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,wBAAgB,mBAAmB,IAAI,gBAAgB,CAatD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CA+B3D;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAI3E;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,+BAA+B,CACnD,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,uBAAuB,CAAC,CAOlC;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAOpD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,eAAe,CAI1F;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CAgBxB;AAED,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,QAAQ,CAW1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAmB7D"}
1
+ {"version":3,"file":"cc-switch-sdk.d.ts","sourceRoot":"","sources":["../../src/services/cc-switch-sdk.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAc,MAAM,gBAAgB,CAAC;AAczF,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE5E,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,wBAAgB,mBAAmB,IAAI,gBAAgB,CAetD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAiC3D;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAI3E;AAED,MAAM,WAAW,uBAAuB;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,+BAA+B,CACnD,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,uBAAuB,CAAC,CAOlC;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAQpD;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,eAAe,CAI1F;AAED,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,OAAO,EAChB,GAAG,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CAgBxB;AAED,wBAAgB,yBAAyB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,QAAQ,CAY1E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAqB7D"}
@@ -7,13 +7,15 @@
7
7
  import path from 'node:path';
8
8
  import { AiConfigService, CcSwitchSdk } from '@cc-switch/sdk';
9
9
  import { createMcpAdapters, createSkillAdapters } from '../adapters/cc-switch/index.js';
10
- import { getClaudeConfigFile, getClaudeMcpConfigFile, getClaudeSkillsDir, getCodexConfigFile, getCodexSkillsDir, getRuntimeHomeDir, getOpencodeConfigFile, getOpencodeSkillsDir, } from '../config.js';
10
+ import { getAcodeConfigFile, getAcodeSkillsDir, getClaudeConfigFile, getClaudeMcpConfigFile, getClaudeSkillsDir, getCodexConfigFile, getCodexSkillsDir, getRuntimeHomeDir, getOpencodeConfigFile, getOpencodeSkillsDir, } from '../config.js';
11
11
  import { getAgentInitRoot } from './instance-state.js';
12
12
  import { InstanceService } from './instance-service.js';
13
13
  export function getCcSwitchAppPaths() {
14
14
  const runtimeHome = path.resolve(getRuntimeHomeDir());
15
15
  return {
16
16
  runtimeHome,
17
+ acodeConfigFile: path.resolve(getAcodeConfigFile(runtimeHome)),
18
+ acodeSkillsDir: path.resolve(getAcodeSkillsDir(runtimeHome)),
17
19
  claudeConfigFile: path.resolve(getClaudeConfigFile(runtimeHome)),
18
20
  claudeMcpConfigFile: path.resolve(getClaudeMcpConfigFile(runtimeHome)),
19
21
  claudeSkillsDir: path.resolve(getClaudeSkillsDir(runtimeHome)),
@@ -30,6 +32,8 @@ export function getCcSwitchSdk(agentId) {
30
32
  const paths = {
31
33
  stateFile: path.join(sdkRoot, 'state.json'),
32
34
  backupDir: path.join(sdkRoot, 'backups'),
35
+ acodeConfigFile: appPaths.acodeConfigFile,
36
+ acodeSkillsDir: appPaths.acodeSkillsDir,
33
37
  claudeConfigFile: appPaths.claudeConfigFile,
34
38
  claudeSkillsDir: appPaths.claudeSkillsDir,
35
39
  claudecodeConfigFile: appPaths.claudeMcpConfigFile,
@@ -67,6 +71,7 @@ export async function discoverCcSwitchConfiguredItems(sdk) {
67
71
  export function getAiConfigService() {
68
72
  const appPaths = getCcSwitchAppPaths();
69
73
  return new AiConfigService({
74
+ acodeConfigFile: appPaths.acodeConfigFile,
70
75
  claudecodeConfigFile: appPaths.claudeConfigFile,
71
76
  codexConfigFile: appPaths.codexConfigFile,
72
77
  opencodeConfigFile: appPaths.opencodeConfigFile,
@@ -97,6 +102,7 @@ export function toSdkAppsFromEnabledTools(enabledTools) {
97
102
  const tools = Array.isArray(enabledTools) ? enabledTools : [];
98
103
  const includes = (name) => tools.includes(name);
99
104
  return {
105
+ acode: includes('acode'),
100
106
  claude: false,
101
107
  claudecode: includes('claudecode') || includes('claude'),
102
108
  codex: includes('codex'),
@@ -108,6 +114,7 @@ export function toSdkAppsFromEnabledTools(enabledTools) {
108
114
  export function toSdkApps(apps) {
109
115
  if (!apps) {
110
116
  return {
117
+ acode: false,
111
118
  claude: false,
112
119
  claudecode: false,
113
120
  codex: false,
@@ -117,6 +124,7 @@ export function toSdkApps(apps) {
117
124
  };
118
125
  }
119
126
  return {
127
+ acode: Boolean(apps.acode),
120
128
  claude: false,
121
129
  claudecode: Boolean(apps.claudecode) || Boolean(apps.claude),
122
130
  codex: Boolean(apps.codex),
@@ -1 +1 @@
1
- {"version":3,"file":"instance-init-service.d.ts","sourceRoot":"","sources":["../../src/services/instance-init-service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,UAAU,EAAS,YAAY,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAC;AAsB9K,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,eAAe,CAAC,CAyB1B;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B,GACA,OAAO,CAAC;IACT,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE;QACL,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,OAAO,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;KACpC,CAAC;IACF,GAAG,EAAE;QACH,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,oBAAoB,EAAE,CAAC;QAC/B,UAAU,EAAE,kBAAkB,EAAE,CAAC;KAClC,CAAC;CACH,CAAC,CA4MD"}
1
+ {"version":3,"file":"instance-init-service.d.ts","sourceRoot":"","sources":["../../src/services/instance-init-service.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,UAAU,EAAS,YAAY,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAC;AAsB9K,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,WAAW,GACf,OAAO,CAAC,eAAe,CAAC,CAyB1B;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE;IACP,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;CAC3B,GACA,OAAO,CAAC;IACT,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,IAAI,CAAC,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE;QACL,OAAO,EAAE,OAAO,CAAC;QACjB,cAAc,EAAE,OAAO,CAAC;QACxB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;KACpC,CAAC;IACF,GAAG,EAAE;QACH,OAAO,EAAE,OAAO,CAAC;QACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE;QACV,MAAM,EAAE,oBAAoB,EAAE,CAAC;QAC/B,UAAU,EAAE,kBAAkB,EAAE,CAAC;KAClC,CAAC;CACH,CAAC,CA6MD"}
@@ -64,7 +64,7 @@ export async function initInstance(agentId, workspacePath, options) {
64
64
  agentId: String(agentId),
65
65
  workspacePath: normalizedWorkspace,
66
66
  initRoot,
67
- enabledTools: installedTools,
67
+ enabledTools: tools,
68
68
  toolStatus: detectedToolStatus,
69
69
  logs,
70
70
  skill: {
@@ -83,6 +83,7 @@ export async function initInstance(agentId, workspacePath, options) {
83
83
  });
84
84
  }
85
85
  pushLog('select-installed-tools', 'success', '已选择可初始化工具', {
86
+ enabledTools: tools,
86
87
  installedTools,
87
88
  });
88
89
  pushLog('load-sdk', 'running', '开始加载 CC Switch SDK');
@@ -154,7 +155,7 @@ export async function initInstance(agentId, workspacePath, options) {
154
155
  }
155
156
  pushLog('persist-state', 'running', '开始保存实例状态');
156
157
  state.initialized = true;
157
- state.enabledTools = installedTools;
158
+ state.enabledTools = tools;
158
159
  state.toolStatus = detectedToolStatus;
159
160
  state.skillEnabled = initResult.skill.enabled;
160
161
  state.mcpEnabled = initResult.mcp.enabled;
@@ -17,6 +17,7 @@ vi.mock('./cc-switch-sdk.js', () => ({
17
17
  const tools = Array.isArray(enabledTools) ? enabledTools : [];
18
18
  return {
19
19
  claude: false,
20
+ acode: false,
20
21
  claudecode: tools.includes('claude') || tools.includes('claudecode'),
21
22
  codex: tools.includes('codex'),
22
23
  gemini: tools.includes('gemini'),
@@ -80,11 +81,11 @@ function status(tool, installed) {
80
81
  error: installed ? null : 'not installed',
81
82
  };
82
83
  }
83
- describe('initInstance installed-only tool initialization', () => {
84
+ describe('initInstance enabled tool initialization', () => {
84
85
  const originalRuntimeHomeDir = process.env.AWS_RUNTIME_HOME_DIR;
85
86
  let runtimeHomeDir;
86
87
  beforeEach(async () => {
87
- runtimeHomeDir = path.join(os.tmpdir(), `aws-init-installed-only-${Date.now()}`);
88
+ runtimeHomeDir = path.join(os.tmpdir(), `aws-init-enabled-tools-${Date.now()}`);
88
89
  process.env.AWS_RUNTIME_HOME_DIR = runtimeHomeDir;
89
90
  activeSdk = new MockSdk();
90
91
  vi.clearAllMocks();
@@ -110,7 +111,7 @@ describe('initInstance installed-only tool initialization', () => {
110
111
  }
111
112
  await fs.rm(runtimeHomeDir, { recursive: true, force: true });
112
113
  });
113
- it('skips uninstalled tools and configures MCP and skills only for installed tools', async () => {
114
+ it('persists requested tools but configures MCP and skills only for installed tools', async () => {
114
115
  detectToolStatusesMock.mockResolvedValue({
115
116
  claude: status('claude', true),
116
117
  opencode: status('opencode', false),
@@ -123,7 +124,7 @@ describe('initInstance installed-only tool initialization', () => {
123
124
  mcpServers: [{ name: 'aws-mcp', command: 'node', args: ['server.js'] }],
124
125
  });
125
126
  expect(ensureToolsInstalledMock).not.toHaveBeenCalled();
126
- expect(result.enabledTools).toEqual(['claude']);
127
+ expect(result.enabledTools).toEqual(['claude', 'opencode', 'codex']);
127
128
  expect(result.ok).toBe(true);
128
129
  expect(installSkillPackageToSdkMock).toHaveBeenCalledWith(activeSdk, expect.objectContaining({ skillName: 'demo-skill' }), expect.any(String), expect.objectContaining({ claudecode: true, opencode: false, codex: false }));
129
130
  expect(activeSdk.createdMcpInputs).toEqual([
@@ -134,6 +135,6 @@ describe('initInstance installed-only tool initialization', () => {
134
135
  ]);
135
136
  const statePath = path.join(runtimeHomeDir, '.aws-bridge', 'instances', 'agent-installed-only', 'state.json');
136
137
  const state = JSON.parse(await fs.readFile(statePath, 'utf-8'));
137
- expect(state.enabledTools).toEqual(['claude']);
138
+ expect(state.enabledTools).toEqual(['claude', 'opencode', 'codex']);
138
139
  });
139
140
  });
@@ -1 +1 @@
1
- {"version":3,"file":"instance-service.d.ts","sourceRoot":"","sources":["../../src/services/instance-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"instance-service.d.ts","sourceRoot":"","sources":["../../src/services/instance-service.ts"],"names":[],"mappings":"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"}
@@ -103,6 +103,7 @@ export class InstanceService {
103
103
  }
104
104
  toAppFlags(appIds) {
105
105
  return {
106
+ acode: appIds.includes("acode"),
106
107
  claude: appIds.includes("claude"),
107
108
  claudecode: appIds.includes("claudecode"),
108
109
  codex: appIds.includes("codex"),
@@ -17,7 +17,7 @@ function createDefaultInstanceState() {
17
17
  initialized: false,
18
18
  skills: [],
19
19
  mcpServers: [],
20
- enabledTools: ['claude', 'opencode', 'codex'],
20
+ enabledTools: ['acode', 'claude', 'opencode', 'codex'],
21
21
  toolStatus: {},
22
22
  skillEnabled: true,
23
23
  mcpEnabled: true,
@@ -68,7 +68,7 @@ describe('instance-state service', () => {
68
68
  expect(state.initialized).toBe(false);
69
69
  expect(state.skills).toEqual([]);
70
70
  expect(state.mcpServers).toEqual([]);
71
- expect(state.enabledTools).toEqual(['claude', 'opencode', 'codex']);
71
+ expect(state.enabledTools).toEqual(['acode', 'claude', 'opencode', 'codex']);
72
72
  expect(state.toolStatus).toEqual({});
73
73
  expect(state.skillEnabled).toBe(true);
74
74
  expect(state.mcpEnabled).toBe(true);
@@ -171,14 +171,14 @@ describe('instance-state service', () => {
171
171
  const result = await saveInstanceState(testAgentId, partialState);
172
172
  expect(result.skills).toEqual([]);
173
173
  expect(result.mcpServers).toEqual([]);
174
- expect(result.enabledTools).toEqual(['claude', 'opencode', 'codex']);
174
+ expect(result.enabledTools).toEqual(['acode', 'claude', 'opencode', 'codex']);
175
175
  });
176
176
  it('should handle empty state object', async () => {
177
177
  const result = await saveInstanceState(testAgentId, {});
178
178
  expect(result.initialized).toBe(false);
179
179
  expect(result.skills).toEqual([]);
180
180
  expect(result.mcpServers).toEqual([]);
181
- expect(result.enabledTools).toEqual(['claude', 'opencode', 'codex']);
181
+ expect(result.enabledTools).toEqual(['acode', 'claude', 'opencode', 'codex']);
182
182
  expect(result.toolStatus).toEqual({});
183
183
  expect(result.skillEnabled).toBe(true);
184
184
  expect(result.mcpEnabled).toBe(true);
@@ -197,7 +197,7 @@ describe('instance-state service', () => {
197
197
  expect(result.initialized).toBe(false);
198
198
  expect(result.skills).toEqual([]);
199
199
  expect(result.mcpServers).toEqual([]);
200
- expect(result.enabledTools).toEqual(['claude', 'opencode', 'codex']);
200
+ expect(result.enabledTools).toEqual(['acode', 'claude', 'opencode', 'codex']);
201
201
  expect(result.toolStatus).toEqual({});
202
202
  expect(result.skillEnabled).toBe(true);
203
203
  expect(result.mcpEnabled).toBe(true);
@@ -24,6 +24,7 @@ export interface ClaimedMcpLaunchBinding extends McpLaunchBinding {
24
24
  schedulerBaseUrl?: string;
25
25
  }
26
26
  export interface McpLaunchBindingClaimRequest {
27
+ agentId?: unknown;
27
28
  workspacePath: unknown;
28
29
  serverUrl?: unknown;
29
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-launch-binding-queue.d.ts","sourceRoot":"","sources":["../../src/services/mcp-launch-binding-queue.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,4BAA4B;IAC3C,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA2DD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,GAAG,IAAI,CA+B7F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,uBAAuB,GAAG,IAAI,CA0C3G;AAED,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,CAOpE;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
1
+ {"version":3,"file":"mcp-launch-binding-queue.d.ts","sourceRoot":"","sources":["../../src/services/mcp-launch-binding-queue.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,uBAAwB,SAAQ,gBAAgB;IAC/D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,4BAA4B;IAC3C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AA2DD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,qBAAqB,GAAG,gBAAgB,GAAG,IAAI,CA+B7F;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,4BAA4B,GAAG,uBAAuB,GAAG,IAAI,CAkD3G;AAED,wBAAgB,qBAAqB,CAAC,aAAa,EAAE,OAAO,GAAG,MAAM,CAOpE;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
@@ -80,18 +80,24 @@ export function enqueueMcpLaunchBinding(input) {
80
80
  }
81
81
  export function claimMcpLaunchBinding(request) {
82
82
  pruneExpiredBindings();
83
+ const requestedAgentId = String(request.agentId || "").trim();
83
84
  const workspaceKey = normalizeWorkspacePath(request.workspacePath);
84
85
  const serverKey = normalizeSchedulerOrigin(request.serverUrl);
85
86
  if (!workspaceKey) {
86
87
  return null;
87
88
  }
88
- let bindingIndex = launchBindings.findIndex((binding) => normalizeWorkspacePath(binding.workspacePath) === workspaceKey &&
89
+ const serverMatches = launchBindings
90
+ .map((binding, index) => ({ binding, index }))
91
+ .filter(({ binding }) => (!requestedAgentId || binding.agentId === requestedAgentId) &&
92
+ normalizeWorkspacePath(binding.workspacePath) === workspaceKey &&
89
93
  serverKey &&
90
94
  normalizeSchedulerOrigin(binding.serverUrl || binding.schedulerBaseUrl) === serverKey);
95
+ let bindingIndex = serverMatches.length === 1 ? serverMatches[0]?.index ?? -1 : -1;
91
96
  if (bindingIndex < 0) {
92
97
  const workspaceMatches = launchBindings
93
98
  .map((binding, index) => ({ binding, index }))
94
- .filter(({ binding }) => normalizeWorkspacePath(binding.workspacePath) === workspaceKey);
99
+ .filter(({ binding }) => (!requestedAgentId || binding.agentId === requestedAgentId) &&
100
+ normalizeWorkspacePath(binding.workspacePath) === workspaceKey);
95
101
  if (workspaceMatches.length === 1) {
96
102
  bindingIndex = workspaceMatches[0]?.index ?? -1;
97
103
  }
@@ -4,7 +4,7 @@ describe('mcp launch binding queue', () => {
4
4
  afterEach(() => {
5
5
  clearMcpLaunchBindingQueues();
6
6
  });
7
- it('claims same-workspace same-server bindings from the front of the queue', () => {
7
+ it('claims same-workspace same-server bindings by agent id', () => {
8
8
  const firstBinding = enqueueMcpLaunchBinding({
9
9
  agentId: 'agent-a',
10
10
  workspacePath: 'C:/repo/demo',
@@ -23,10 +23,12 @@ describe('mcp launch binding queue', () => {
23
23
  });
24
24
  expect(getMcpLaunchQueueSize('C:/repo/demo')).toBe(2);
25
25
  const first = claimMcpLaunchBinding({
26
+ agentId: 'agent-a',
26
27
  workspacePath: 'C:/repo/demo',
27
28
  serverUrl: 'ws://server-a:7380/ws/agent',
28
29
  });
29
30
  const second = claimMcpLaunchBinding({
31
+ agentId: 'agent-b',
30
32
  workspacePath: 'C:/repo/demo',
31
33
  serverUrl: 'ws://server-a:7380/ws/agent',
32
34
  });
@@ -36,19 +38,43 @@ describe('mcp launch binding queue', () => {
36
38
  expect(second?.runtimeAccessToken).toBe('token-b');
37
39
  expect(getMcpLaunchQueueSize('C:/repo/demo')).toBe(0);
38
40
  });
39
- it('claims by workspace path and server URL regardless of agent id', () => {
41
+ it('does not claim another agent token from the same workspace and server', () => {
40
42
  const binding = enqueueMcpLaunchBinding({
41
43
  agentId: 'agent-a',
42
44
  workspacePath: 'C:/repo/demo',
43
45
  serverUrl: 'ws://server:7380/ws/agent',
44
46
  });
45
47
  expect(claimMcpLaunchBinding({
48
+ agentId: 'agent-b',
46
49
  workspacePath: 'C:/repo/demo',
47
50
  serverUrl: 'ws://server:7380/ws/agent',
48
- })?.agentId).toBe('agent-a');
51
+ })).toBeNull();
49
52
  expect(binding?.agentId).toBe('agent-a');
53
+ expect(getMcpLaunchQueueSize('C:/repo/demo')).toBe(1);
54
+ });
55
+ it('skips older same-workspace bindings when claiming a later agent token', () => {
56
+ enqueueMcpLaunchBinding({
57
+ agentId: 'agent-a',
58
+ workspacePath: 'C:/repo/demo',
59
+ serverUrl: 'ws://server:7380/ws/agent',
60
+ runtimeAccessToken: 'token-a',
61
+ });
62
+ enqueueMcpLaunchBinding({
63
+ agentId: 'agent-b',
64
+ workspacePath: 'C:/repo/demo',
65
+ serverUrl: 'ws://server:7380/ws/agent',
66
+ runtimeAccessToken: 'token-b',
67
+ });
68
+ const claimed = claimMcpLaunchBinding({
69
+ agentId: 'agent-b',
70
+ workspacePath: 'C:/repo/demo',
71
+ serverUrl: 'ws://server:7380/ws/agent',
72
+ });
73
+ expect(claimed?.agentId).toBe('agent-b');
74
+ expect(claimed?.runtimeAccessToken).toBe('token-b');
75
+ expect(getMcpLaunchQueueSize('C:/repo/demo')).toBe(1);
50
76
  });
51
- it('ignores explicit binding id and claims the first matching queue entry', () => {
77
+ it('allows legacy claim without agent id only when one binding matches', () => {
52
78
  const binding = enqueueMcpLaunchBinding({
53
79
  agentId: 'agent-a',
54
80
  workspacePath: 'C:/repo/demo',
@@ -60,6 +86,23 @@ describe('mcp launch binding queue', () => {
60
86
  })?.agentId).toBe('agent-a');
61
87
  expect(binding?.id).toBeTruthy();
62
88
  });
89
+ it('rejects legacy claim without agent id when same-workspace same-server bindings are ambiguous', () => {
90
+ enqueueMcpLaunchBinding({
91
+ agentId: 'agent-a',
92
+ workspacePath: 'C:/repo/demo',
93
+ serverUrl: 'ws://server:7380/ws/agent',
94
+ });
95
+ enqueueMcpLaunchBinding({
96
+ agentId: 'agent-b',
97
+ workspacePath: 'C:/repo/demo',
98
+ serverUrl: 'ws://server:7380/ws/agent',
99
+ });
100
+ expect(claimMcpLaunchBinding({
101
+ workspacePath: 'C:/repo/demo',
102
+ serverUrl: 'ws://server:7380/ws/agent',
103
+ })).toBeNull();
104
+ expect(getMcpLaunchQueueSize('C:/repo/demo')).toBe(2);
105
+ });
63
106
  it('matches by server URL as well as workspace path', () => {
64
107
  const firstBinding = enqueueMcpLaunchBinding({ agentId: 'agent-a', workspacePath: 'C:/repo/demo', serverUrl: 'ws://server-a:7380/ws/agent' });
65
108
  const secondBinding = enqueueMcpLaunchBinding({ agentId: 'agent-b', workspacePath: 'C:/repo/demo', serverUrl: 'ws://server-b:7380/ws/agent' });
@@ -3,7 +3,8 @@
3
3
  *
4
4
  * 管理终端会话的输出缓冲和刷新机制
5
5
  */
6
- import type { Session } from '../types.js';
6
+ import type { AxiosResponse } from "axios";
7
+ import type { Session } from "../types.js";
7
8
  interface RuntimeStatusActionInfo {
8
9
  actionType?: string;
9
10
  actionLabel?: string;
@@ -11,6 +12,9 @@ interface RuntimeStatusActionInfo {
11
12
  actionResult?: string;
12
13
  actionId?: string;
13
14
  }
15
+ export interface RuntimeCallbackAuthOptions {
16
+ runtimeAccessToken?: string;
17
+ }
14
18
  /** 活跃会话存储 */
15
19
  export declare const sessions: Map<string, Session>;
16
20
  /**
@@ -24,9 +28,7 @@ export declare const sessions: Map<string, Session>;
24
28
  export declare function sendStatus(agentId: string, sessionId: string | null, status: string, actionInfo?: RuntimeStatusActionInfo, usage?: {
25
29
  inputTokens: number;
26
30
  outputTokens: number;
27
- }): Promise<void | {
28
- data: unknown;
29
- }>;
31
+ }, authOptions?: RuntimeCallbackAuthOptions): Promise<AxiosResponse<unknown> | undefined>;
30
32
  /**
31
33
  * 发送输出到调度器
32
34
  *
@@ -35,7 +37,9 @@ export declare function sendStatus(agentId: string, sessionId: string | null, st
35
37
  * @param sessionId - 会话 ID
36
38
  * @param seq - 序列号
37
39
  */
38
- export declare function sendOutput(agentId: string, output: string, sessionId: string, seq: number): Promise<void>;
40
+ export declare function sendOutput(agentId: string, output: string, sessionId: string, seq: number, metadata?: {
41
+ sourceEventType?: string;
42
+ }, authOptions?: RuntimeCallbackAuthOptions): Promise<void>;
39
43
  /**
40
44
  * 发送 AskUserQuestion 事件到调度器。
41
45
  *
@@ -43,7 +47,7 @@ export declare function sendOutput(agentId: string, output: string, sessionId: s
43
47
  * @param sessionId - SDK 会话 ID
44
48
  * @param questions - 结构化问题列表
45
49
  */
46
- export declare function sendQuestionRequest(agentId: string, sessionId: string, questions: unknown[]): Promise<void>;
50
+ export declare function sendQuestionRequest(agentId: string, sessionId: string, questions: unknown[], authOptions?: RuntimeCallbackAuthOptions): Promise<void>;
47
51
  export interface RuntimeFileChangedPayload {
48
52
  bridgeBaseUrl?: string;
49
53
  workspacePath: string;