aws-runtime-bridge 1.1.11 → 1.2.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 (79) hide show
  1. package/dist/adapters/cc-switch/common.d.ts +1 -1
  2. package/dist/adapters/cc-switch/common.d.ts.map +1 -1
  3. package/dist/adapters/cc-switch/index.d.ts +1 -0
  4. package/dist/adapters/cc-switch/index.d.ts.map +1 -1
  5. package/dist/adapters/cc-switch/index.js +5 -5
  6. package/dist/adapters/cc-switch/mcp-claudecode.d.ts.map +1 -1
  7. package/dist/adapters/cc-switch/mcp-claudecode.js +2 -3
  8. package/dist/adapters/cc-switch/mcp-claudecode.test.d.ts +2 -0
  9. package/dist/adapters/cc-switch/mcp-claudecode.test.d.ts.map +1 -0
  10. package/dist/adapters/cc-switch/mcp-claudecode.test.js +74 -0
  11. package/dist/adapters/cc-switch/mcp-opencode.d.ts.map +1 -1
  12. package/dist/adapters/cc-switch/mcp-opencode.js +3 -7
  13. package/dist/adapters/cc-switch/mcp-opencode.test.d.ts +2 -0
  14. package/dist/adapters/cc-switch/mcp-opencode.test.d.ts.map +1 -0
  15. package/dist/adapters/cc-switch/mcp-opencode.test.js +61 -0
  16. package/dist/adapters/cc-switch/skill-claude.d.ts +2 -7
  17. package/dist/adapters/cc-switch/skill-claude.d.ts.map +1 -1
  18. package/dist/adapters/cc-switch/skill-claude.js +3 -83
  19. package/dist/adapters/cc-switch/skill-claudecode.d.ts +2 -7
  20. package/dist/adapters/cc-switch/skill-claudecode.d.ts.map +1 -1
  21. package/dist/adapters/cc-switch/skill-claudecode.js +3 -83
  22. package/dist/adapters/cc-switch/skill-codex.d.ts +5 -0
  23. package/dist/adapters/cc-switch/skill-codex.d.ts.map +1 -0
  24. package/dist/adapters/cc-switch/skill-codex.js +6 -0
  25. package/dist/adapters/cc-switch/skill-directory.d.ts +10 -0
  26. package/dist/adapters/cc-switch/skill-directory.d.ts.map +1 -0
  27. package/dist/adapters/cc-switch/skill-directory.js +137 -0
  28. package/dist/adapters/cc-switch/skill-directory.test.d.ts +2 -0
  29. package/dist/adapters/cc-switch/skill-directory.test.d.ts.map +1 -0
  30. package/dist/adapters/cc-switch/skill-directory.test.js +73 -0
  31. package/dist/adapters/cc-switch/skill-opencode.d.ts +2 -7
  32. package/dist/adapters/cc-switch/skill-opencode.d.ts.map +1 -1
  33. package/dist/adapters/cc-switch/skill-opencode.js +3 -87
  34. package/dist/config.d.ts +2 -0
  35. package/dist/config.d.ts.map +1 -1
  36. package/dist/config.js +5 -0
  37. package/dist/routes/instance.js +4 -5
  38. package/dist/routes/mcp.js +3 -2
  39. package/dist/routes/skills.js +3 -2
  40. package/dist/services/aws-client-agent-mcp.d.ts.map +1 -1
  41. package/dist/services/aws-client-agent-mcp.js +69 -3
  42. package/dist/services/aws-client-agent-mcp.test.js +69 -2
  43. package/dist/services/cc-switch-discovery.test.d.ts +2 -0
  44. package/dist/services/cc-switch-discovery.test.d.ts.map +1 -0
  45. package/dist/services/cc-switch-discovery.test.js +56 -0
  46. package/dist/services/cc-switch-sdk.d.ts +7 -2
  47. package/dist/services/cc-switch-sdk.d.ts.map +1 -1
  48. package/dist/services/cc-switch-sdk.js +15 -5
  49. package/dist/types.d.ts +2 -0
  50. package/dist/types.d.ts.map +1 -1
  51. package/dist/utils/mcp-utils.d.ts.map +1 -1
  52. package/dist/utils/mcp-utils.js +6 -5
  53. package/node_modules/@cc-switch/sdk/dist/constants.d.ts.map +1 -1
  54. package/node_modules/@cc-switch/sdk/dist/constants.js +4 -2
  55. package/node_modules/@cc-switch/sdk/dist/sdk.d.ts.map +1 -1
  56. package/node_modules/@cc-switch/sdk/dist/sdk.js +20 -30
  57. package/node_modules/@cc-switch/sdk/dist/services/mcp-model.d.ts.map +1 -1
  58. package/node_modules/@cc-switch/sdk/dist/services/mcp-model.js +7 -4
  59. package/node_modules/@cc-switch/sdk/dist/services/skill-model.d.ts.map +1 -1
  60. package/node_modules/@cc-switch/sdk/dist/services/skill-model.js +7 -4
  61. package/node_modules/@cc-switch/sdk/dist/types.d.ts +1 -0
  62. package/node_modules/@cc-switch/sdk/dist/types.d.ts.map +1 -1
  63. package/node_modules/@cc-switch/sdk/dist/utils/fs.d.ts +1 -0
  64. package/node_modules/@cc-switch/sdk/dist/utils/fs.d.ts.map +1 -1
  65. package/node_modules/@cc-switch/sdk/dist/utils/fs.js +23 -0
  66. package/package/cc-switch-sdk/dist/constants.d.ts.map +1 -1
  67. package/package/cc-switch-sdk/dist/constants.js +4 -2
  68. package/package/cc-switch-sdk/dist/sdk.d.ts.map +1 -1
  69. package/package/cc-switch-sdk/dist/sdk.js +20 -30
  70. package/package/cc-switch-sdk/dist/services/mcp-model.d.ts.map +1 -1
  71. package/package/cc-switch-sdk/dist/services/mcp-model.js +7 -4
  72. package/package/cc-switch-sdk/dist/services/skill-model.d.ts.map +1 -1
  73. package/package/cc-switch-sdk/dist/services/skill-model.js +7 -4
  74. package/package/cc-switch-sdk/dist/types.d.ts +1 -0
  75. package/package/cc-switch-sdk/dist/types.d.ts.map +1 -1
  76. package/package/cc-switch-sdk/dist/utils/fs.d.ts +1 -0
  77. package/package/cc-switch-sdk/dist/utils/fs.d.ts.map +1 -1
  78. package/package/cc-switch-sdk/dist/utils/fs.js +23 -0
  79. package/package.json +1 -1
@@ -30,7 +30,7 @@ export interface OpenCodeConfig {
30
30
  }
31
31
  export type ClaudecodeLocalServer = OpenCodeLocalServer;
32
32
  export type ClaudecodeRemoteServer = OpenCodeRemoteServer;
33
- export type ClaudecodeServer = OpenCodeServer;
33
+ export type ClaudecodeServer = McpServerSpec;
34
34
  export interface ClaudecodeConfig {
35
35
  mcpServers?: Record<string, ClaudecodeServer>;
36
36
  [key: string]: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/common.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEtE,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAExE,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAGD,MAAM,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AACxD,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAC1D,MAAM,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAE9C,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,GAAG,aAAa,CAiB1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAoBrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,GACX,SAAS,CAQX;AAGD,eAAO,MAAM,uBAAuB,8BAAwB,CAAC;AAC7D,eAAO,MAAM,kBAAkB,yBAAmB,CAAC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/common.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEtE,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,MAAM,cAAc,GAAG,mBAAmB,GAAG,oBAAoB,CAAC;AAExE,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC5C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAGD,MAAM,MAAM,qBAAqB,GAAG,mBAAmB,CAAC;AACxD,MAAM,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAC1D,MAAM,MAAM,gBAAgB,GAAG,aAAa,CAAC;AAE7C,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,GAAG,aAAa,CAiB1E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,aAAa,GAAG,cAAc,CAoBrE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,KAAK,GACX,SAAS,CAQX;AAGD,eAAO,MAAM,uBAAuB,8BAAwB,CAAC;AAC7D,eAAO,MAAM,kBAAkB,yBAAmB,CAAC"}
@@ -11,6 +11,7 @@ export { OpenCodeMcpAdapter } from './mcp-opencode.js';
11
11
  export { PlaceholderMcpAdapter } from './mcp-placeholder.js';
12
12
  export { ClaudeSkillAdapter } from './skill-claude.js';
13
13
  export { ClaudecodeSkillAdapter } from './skill-claudecode.js';
14
+ export { CodexSkillAdapter } from './skill-codex.js';
14
15
  export { OpenCodeSkillAdapter } from './skill-opencode.js';
15
16
  export { PlaceholderSkillAdapter } from './skill-placeholder.js';
16
17
  export * from './common.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAYlF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,cAAc,aAAa,CAAC;AAE5B;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAS7E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CASjF"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAWlF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,cAAc,aAAa,CAAC;AAE5B;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,CAS7E;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,CAAC,KAAK,EAAE,aAAa,CAAC,CASjF"}
@@ -3,13 +3,12 @@
3
3
  *
4
4
  * 提供工厂函数创建所有 MCP 和 Skill 适配器实例
5
5
  */
6
- import { ClaudeMcpAdapter } from './mcp-claude.js';
7
6
  import { ClaudecodeMcpAdapter } from './mcp-claudecode.js';
8
7
  import { CodexMcpAdapter } from './mcp-codex.js';
9
8
  import { OpenCodeMcpAdapter } from './mcp-opencode.js';
10
9
  import { PlaceholderMcpAdapter } from './mcp-placeholder.js';
11
- import { ClaudeSkillAdapter } from './skill-claude.js';
12
10
  import { ClaudecodeSkillAdapter } from './skill-claudecode.js';
11
+ import { CodexSkillAdapter } from './skill-codex.js';
13
12
  import { OpenCodeSkillAdapter } from './skill-opencode.js';
14
13
  import { PlaceholderSkillAdapter } from './skill-placeholder.js';
15
14
  // 导出所有适配器类
@@ -20,6 +19,7 @@ export { OpenCodeMcpAdapter } from './mcp-opencode.js';
20
19
  export { PlaceholderMcpAdapter } from './mcp-placeholder.js';
21
20
  export { ClaudeSkillAdapter } from './skill-claude.js';
22
21
  export { ClaudecodeSkillAdapter } from './skill-claudecode.js';
22
+ export { CodexSkillAdapter } from './skill-codex.js';
23
23
  export { OpenCodeSkillAdapter } from './skill-opencode.js';
24
24
  export { PlaceholderSkillAdapter } from './skill-placeholder.js';
25
25
  export * from './common.js';
@@ -28,7 +28,7 @@ export * from './common.js';
28
28
  */
29
29
  export function createMcpAdapters(paths) {
30
30
  return {
31
- claude: new ClaudeMcpAdapter(paths.claudeConfigFile),
31
+ claude: new PlaceholderMcpAdapter("claude"),
32
32
  claudecode: new ClaudecodeMcpAdapter(paths.claudecodeConfigFile),
33
33
  opencode: new OpenCodeMcpAdapter(paths.opencodeConfigFile),
34
34
  codex: new CodexMcpAdapter(paths.codexConfigFile),
@@ -41,10 +41,10 @@ export function createMcpAdapters(paths) {
41
41
  */
42
42
  export function createSkillAdapters(paths) {
43
43
  return {
44
- claude: new ClaudeSkillAdapter(paths.claudeSkillsDir),
44
+ claude: new PlaceholderSkillAdapter("claude"),
45
45
  claudecode: new ClaudecodeSkillAdapter(paths.claudecodeSkillsDir),
46
46
  opencode: new OpenCodeSkillAdapter(paths.opencodeSkillsDir),
47
- codex: new PlaceholderSkillAdapter("codex"),
47
+ codex: new CodexSkillAdapter(paths.codexSkillsDir),
48
48
  gemini: new PlaceholderSkillAdapter("gemini"),
49
49
  openclaw: new PlaceholderSkillAdapter("openclaw"),
50
50
  };
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-claudecode.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/mcp-claudecode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAwC7D,qBAAa,oBAAqB,YAAW,WAAW;IAG1C,OAAO,CAAC,QAAQ,CAAC,UAAU;IAFvC,SAAgB,KAAK,EAAG,YAAY,CAAU;gBAEjB,UAAU,EAAE,MAAM;IAEzC,aAAa,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBrC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CASrD"}
1
+ {"version":3,"file":"mcp-claudecode.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/mcp-claudecode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAuC7D,qBAAa,oBAAqB,YAAW,WAAW;IAG1C,OAAO,CAAC,QAAQ,CAAC,UAAU;IAFvC,SAAgB,KAAK,EAAG,YAAY,CAAU;gBAEjB,UAAU,EAAE,MAAM;IAEzC,aAAa,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBrC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CASrD"}
@@ -3,7 +3,6 @@
3
3
  *
4
4
  * 实现 IMcpAdapter 接口,负责 ClaudeCode 的 MCP 配置读写
5
5
  */
6
- import { toMcpSpecFromClaudecode, toClaudecodeServer } from './common.js';
7
6
  /**
8
7
  * JSON 文件读取工具
9
8
  */
@@ -49,7 +48,7 @@ export class ClaudecodeMcpAdapter {
49
48
  return entries.map(([name, server]) => ({
50
49
  id: createId("mcp"),
51
50
  name,
52
- server: toMcpSpecFromClaudecode(server),
51
+ server,
53
52
  apps: {
54
53
  claude: false,
55
54
  claudecode: true,
@@ -63,7 +62,7 @@ export class ClaudecodeMcpAdapter {
63
62
  async syncServer(server) {
64
63
  const config = await readJsonFile(this.configPath, {});
65
64
  config.mcpServers = config.mcpServers ?? {};
66
- config.mcpServers[server.name] = toClaudecodeServer(server.server);
65
+ config.mcpServers[server.name] = server.server;
67
66
  await writeJsonFile(this.configPath, config);
68
67
  }
69
68
  async removeServer(server) {
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mcp-claudecode.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-claudecode.test.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/mcp-claudecode.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { ClaudecodeMcpAdapter } from './mcp-claudecode.js';
6
+ let tempDir;
7
+ let configPath;
8
+ function buildServer(name = 'agents-work-studio') {
9
+ return {
10
+ id: 'mcp_test',
11
+ name,
12
+ server: {
13
+ type: 'stdio',
14
+ command: 'cmd',
15
+ args: ['/c', 'node', 'D:\\code\\AgentsWorkStudio\\aws-runtime-bridge\\package\\aws-client-agent-mcp\\dist\\index.js'],
16
+ env: {
17
+ AWS_SERVER_URL: 'ws://localhost:8080/ws/agent',
18
+ },
19
+ },
20
+ apps: {
21
+ claude: false,
22
+ claudecode: true,
23
+ codex: false,
24
+ gemini: false,
25
+ opencode: false,
26
+ openclaw: false,
27
+ },
28
+ };
29
+ }
30
+ beforeEach(async () => {
31
+ tempDir = await mkdtemp(path.join(os.tmpdir(), 'claudecode-mcp-adapter-'));
32
+ configPath = path.join(tempDir, '.claude.json');
33
+ });
34
+ afterEach(async () => {
35
+ await rm(tempDir, { recursive: true, force: true });
36
+ });
37
+ describe('ClaudecodeMcpAdapter', () => {
38
+ it('syncs MCP servers into Claude Code global mcpServers', async () => {
39
+ const adapter = new ClaudecodeMcpAdapter(configPath);
40
+ await adapter.syncServer(buildServer());
41
+ const written = JSON.parse(await readFile(configPath, 'utf-8'));
42
+ expect(written.mcpServers?.['agents-work-studio']).toMatchObject({
43
+ type: 'stdio',
44
+ command: 'cmd',
45
+ args: ['/c', 'node', 'D:\\code\\AgentsWorkStudio\\aws-runtime-bridge\\package\\aws-client-agent-mcp\\dist\\index.js'],
46
+ env: {
47
+ AWS_SERVER_URL: 'ws://localhost:8080/ws/agent',
48
+ },
49
+ });
50
+ });
51
+ it('removes MCP servers from Claude Code global mcpServers while preserving other settings', async () => {
52
+ const adapter = new ClaudecodeMcpAdapter(configPath);
53
+ await writeFile(configPath, JSON.stringify({
54
+ env: { ANTHROPIC_MODEL: 'test' },
55
+ mcpServers: {
56
+ 'agents-work-studio': {
57
+ command: 'cmd',
58
+ args: ['/c', 'node', 'old.js'],
59
+ type: 'stdio',
60
+ },
61
+ playwright: {
62
+ command: 'cmd',
63
+ args: ['/c', 'npx', '@playwright/mcp@latest'],
64
+ type: 'stdio',
65
+ },
66
+ },
67
+ }), 'utf-8');
68
+ await adapter.removeServer(buildServer());
69
+ const written = JSON.parse(await readFile(configPath, 'utf-8'));
70
+ expect(written.env?.ANTHROPIC_MODEL).toBe('test');
71
+ expect(written.mcpServers?.['agents-work-studio']).toBeUndefined();
72
+ expect(written.mcpServers?.playwright).toBeDefined();
73
+ });
74
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"mcp-opencode.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/mcp-opencode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAwC7D,qBAAa,kBAAmB,YAAW,WAAW;IAGxC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAFvC,SAAgB,KAAK,EAAG,UAAU,CAAU;gBAEf,UAAU,EAAE,MAAM;IAE/C;;OAEG;IACH,OAAO,CAAC,SAAS;IAUjB;;OAEG;YACW,UAAU;IAQlB,aAAa,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBrC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAUrD"}
1
+ {"version":3,"file":"mcp-opencode.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/mcp-opencode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAwC7D,qBAAa,kBAAmB,YAAW,WAAW;IAGxC,OAAO,CAAC,QAAQ,CAAC,UAAU;IAFvC,SAAgB,KAAK,EAAG,UAAU,CAAU;gBAEf,UAAU,EAAE,MAAM;IAE/C;;OAEG;IACH,OAAO,CAAC,SAAS;IAMjB;;OAEG;YACW,UAAU;IAQlB,aAAa,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAmBrC,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAO5C,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;CAUrD"}
@@ -47,13 +47,9 @@ export class OpenCodeMcpAdapter {
47
47
  * 读取 OpenCode MCP 映射,优先使用合法的 mcp 字段,兼容历史错误写入的 mcpServers。
48
48
  */
49
49
  getMcpMap(config) {
50
- if (config.mcp && typeof config.mcp === "object") {
51
- return config.mcp;
52
- }
53
- if (config.mcpServers && typeof config.mcpServers === "object") {
54
- return config.mcpServers;
55
- }
56
- return {};
50
+ const mcp = config.mcp && typeof config.mcp === "object" ? config.mcp : {};
51
+ const legacyMcpServers = config.mcpServers && typeof config.mcpServers === "object" ? config.mcpServers : {};
52
+ return { ...legacyMcpServers, ...mcp };
57
53
  }
58
54
  /**
59
55
  * 将 MCP 服务器写回 OpenCode 配置,只保留合法的 mcp 字段并清理错误的 mcpServers。
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=mcp-opencode.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-opencode.test.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/mcp-opencode.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,61 @@
1
+ import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';
2
+ import os from 'node:os';
3
+ import path from 'node:path';
4
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
5
+ import { OpenCodeMcpAdapter } from './mcp-opencode.js';
6
+ let tempDir;
7
+ let configPath;
8
+ function buildServer(name = 'new-server') {
9
+ return {
10
+ id: 'mcp_test',
11
+ name,
12
+ server: { type: 'stdio', command: 'node', args: ['server.js'] },
13
+ apps: {
14
+ claude: false,
15
+ claudecode: false,
16
+ codex: false,
17
+ gemini: false,
18
+ opencode: true,
19
+ openclaw: false,
20
+ },
21
+ };
22
+ }
23
+ beforeEach(async () => {
24
+ tempDir = await mkdtemp(path.join(os.tmpdir(), 'opencode-mcp-adapter-'));
25
+ configPath = path.join(tempDir, 'opencode.json');
26
+ });
27
+ afterEach(async () => {
28
+ await rm(tempDir, { recursive: true, force: true });
29
+ });
30
+ describe('OpenCodeMcpAdapter', () => {
31
+ it('imports both current mcp and legacy mcpServers maps', async () => {
32
+ await writeFile(configPath, JSON.stringify({
33
+ mcp: {
34
+ current: { type: 'local', command: ['node', 'current.js'] },
35
+ },
36
+ mcpServers: {
37
+ legacy: { type: 'remote', url: 'http://legacy.example.com/sse' },
38
+ },
39
+ }), 'utf-8');
40
+ const adapter = new OpenCodeMcpAdapter(configPath);
41
+ const imported = await adapter.importServers();
42
+ expect(imported.map((item) => item.name).sort()).toEqual(['current', 'legacy']);
43
+ });
44
+ it('writes merged MCP map back to mcp and removes legacy mcpServers', async () => {
45
+ await writeFile(configPath, JSON.stringify({
46
+ theme: 'dark',
47
+ mcpServers: {
48
+ legacy: { type: 'remote', url: 'http://legacy.example.com/sse' },
49
+ },
50
+ }), 'utf-8');
51
+ const adapter = new OpenCodeMcpAdapter(configPath);
52
+ await adapter.syncServer(buildServer());
53
+ const written = JSON.parse(await readFile(configPath, 'utf-8'));
54
+ expect(written.theme).toBe('dark');
55
+ expect(written.mcpServers).toBeUndefined();
56
+ expect(written.mcp).toMatchObject({
57
+ legacy: { type: 'remote', url: 'http://legacy.example.com/sse' },
58
+ 'new-server': { type: 'local', command: ['node', 'server.js'] },
59
+ });
60
+ });
61
+ });
@@ -3,13 +3,8 @@
3
3
  *
4
4
  * 实现 ISkillAdapter 接口,负责 Claude Desktop 的 Skill 目录管理
5
5
  */
6
- import type { ISkillAdapter, InstalledSkill, SkillSyncMethod } from '@cc-switch/sdk';
7
- export declare class ClaudeSkillAdapter implements ISkillAdapter {
8
- private readonly skillsDir;
9
- readonly appId: "claude";
6
+ import { DirectorySkillAdapter } from './skill-directory.js';
7
+ export declare class ClaudeSkillAdapter extends DirectorySkillAdapter {
10
8
  constructor(skillsDir: string);
11
- importSkills(): Promise<Array<Pick<InstalledSkill, "id" | "name" | "directory" | "description">>>;
12
- syncSkill(skill: InstalledSkill, sourceDir: string, method: SkillSyncMethod): Promise<void>;
13
- removeSkill(skill: InstalledSkill): Promise<void>;
14
9
  }
15
10
  //# sourceMappingURL=skill-claude.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-claude.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/skill-claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAoErF,qBAAa,kBAAmB,YAAW,aAAa;IAG1C,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,SAAgB,KAAK,EAAG,QAAQ,CAAU;gBAEb,SAAS,EAAE,MAAM;IAExC,YAAY,IAAI,OAAO,CAC3B,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,CAAC,CACzE;IAmBK,SAAS,CACb,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC;IAMV,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAKxD"}
1
+ {"version":3,"file":"skill-claude.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/skill-claude.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,qBAAa,kBAAmB,SAAQ,qBAAqB;gBAC/C,SAAS,EAAE,MAAM;CAG9B"}
@@ -3,89 +3,9 @@
3
3
  *
4
4
  * 实现 ISkillAdapter 接口,负责 Claude Desktop 的 Skill 目录管理
5
5
  */
6
- async function ensureDir(dir) {
7
- const fs = await import('node:fs/promises');
8
- await fs.mkdir(dir, { recursive: true });
9
- }
10
- async function removeIfExists(target) {
11
- const fs = await import('node:fs/promises');
12
- try {
13
- await fs.rm(target, { recursive: true, force: true });
14
- }
15
- catch {
16
- // ignore
17
- }
18
- }
19
- async function copyDir(source, target) {
20
- const fs = await import('node:fs/promises');
21
- const path = await import('node:path');
22
- await ensureDir(target);
23
- const entries = await fs.readdir(source, { withFileTypes: true });
24
- for (const entry of entries) {
25
- const srcPath = path.join(source, entry.name);
26
- const tgtPath = path.join(target, entry.name);
27
- if (entry.isDirectory()) {
28
- await copyDir(srcPath, tgtPath);
29
- }
30
- else {
31
- await fs.copyFile(srcPath, tgtPath);
32
- }
33
- }
34
- }
35
- function toNameFromPath(pathStr) {
36
- const base = pathStr.split(/[/\\]/).pop() || pathStr;
37
- return base.replace(/\.skill$/, '').replace(/[-_]/g, ' ');
38
- }
39
- async function materializeSkillDir(sourceDir, targetDir, method) {
40
- const fs = await import('node:fs/promises');
41
- const path = await import('node:path');
42
- await removeIfExists(targetDir);
43
- await ensureDir(path.dirname(targetDir));
44
- if (method === "copy") {
45
- await copyDir(sourceDir, targetDir);
46
- return;
47
- }
48
- if (method === "symlink") {
49
- await fs.symlink(sourceDir, targetDir, "junction");
50
- return;
51
- }
52
- try {
53
- await fs.symlink(sourceDir, targetDir, "junction");
54
- }
55
- catch {
56
- await copyDir(sourceDir, targetDir);
57
- }
58
- }
59
- export class ClaudeSkillAdapter {
6
+ import { DirectorySkillAdapter } from './skill-directory.js';
7
+ export class ClaudeSkillAdapter extends DirectorySkillAdapter {
60
8
  constructor(skillsDir) {
61
- this.skillsDir = skillsDir;
62
- this.appId = "claude";
63
- }
64
- async importSkills() {
65
- const fs = await import('node:fs/promises');
66
- const path = await import('node:path');
67
- await ensureDir(this.skillsDir);
68
- const entries = await fs.readdir(this.skillsDir, { withFileTypes: true });
69
- return entries
70
- .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())
71
- .map((entry) => {
72
- const directory = path.join(this.skillsDir, entry.name);
73
- return {
74
- id: `skill_import_${entry.name}`,
75
- name: toNameFromPath(entry.name),
76
- directory,
77
- description: undefined,
78
- };
79
- });
80
- }
81
- async syncSkill(skill, sourceDir, method) {
82
- const path = await import('node:path');
83
- const targetDir = path.join(this.skillsDir, skill.name);
84
- await materializeSkillDir(sourceDir, targetDir, method);
85
- }
86
- async removeSkill(skill) {
87
- const path = await import('node:path');
88
- const targetDir = path.join(this.skillsDir, skill.name);
89
- await removeIfExists(targetDir);
9
+ super('claude', skillsDir);
90
10
  }
91
11
  }
@@ -3,13 +3,8 @@
3
3
  *
4
4
  * 实现 ISkillAdapter 接口,负责 ClaudeCode 的 Skill 目录管理
5
5
  */
6
- import type { ISkillAdapter, InstalledSkill, SkillSyncMethod } from '@cc-switch/sdk';
7
- export declare class ClaudecodeSkillAdapter implements ISkillAdapter {
8
- private readonly skillsDir;
9
- readonly appId: "claudecode";
6
+ import { DirectorySkillAdapter } from './skill-directory.js';
7
+ export declare class ClaudecodeSkillAdapter extends DirectorySkillAdapter {
10
8
  constructor(skillsDir: string);
11
- importSkills(): Promise<Array<Pick<InstalledSkill, "id" | "name" | "directory" | "description">>>;
12
- syncSkill(skill: InstalledSkill, sourceDir: string, method: SkillSyncMethod): Promise<void>;
13
- removeSkill(skill: InstalledSkill): Promise<void>;
14
9
  }
15
10
  //# sourceMappingURL=skill-claudecode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-claudecode.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/skill-claudecode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAoErF,qBAAa,sBAAuB,YAAW,aAAa;IAG9C,OAAO,CAAC,QAAQ,CAAC,SAAS;IAFtC,SAAgB,KAAK,EAAG,YAAY,CAAU;gBAEjB,SAAS,EAAE,MAAM;IAExC,YAAY,IAAI,OAAO,CAC3B,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,CAAC,CACzE;IAmBK,SAAS,CACb,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC;IAMV,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAKxD"}
1
+ {"version":3,"file":"skill-claudecode.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/skill-claudecode.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,qBAAa,sBAAuB,SAAQ,qBAAqB;gBACnD,SAAS,EAAE,MAAM;CAG9B"}
@@ -3,89 +3,9 @@
3
3
  *
4
4
  * 实现 ISkillAdapter 接口,负责 ClaudeCode 的 Skill 目录管理
5
5
  */
6
- async function ensureDir(dir) {
7
- const fs = await import('node:fs/promises');
8
- await fs.mkdir(dir, { recursive: true });
9
- }
10
- async function removeIfExists(target) {
11
- const fs = await import('node:fs/promises');
12
- try {
13
- await fs.rm(target, { recursive: true, force: true });
14
- }
15
- catch {
16
- // ignore
17
- }
18
- }
19
- async function copyDir(source, target) {
20
- const fs = await import('node:fs/promises');
21
- const path = await import('node:path');
22
- await ensureDir(target);
23
- const entries = await fs.readdir(source, { withFileTypes: true });
24
- for (const entry of entries) {
25
- const srcPath = path.join(source, entry.name);
26
- const tgtPath = path.join(target, entry.name);
27
- if (entry.isDirectory()) {
28
- await copyDir(srcPath, tgtPath);
29
- }
30
- else {
31
- await fs.copyFile(srcPath, tgtPath);
32
- }
33
- }
34
- }
35
- function toNameFromPath(pathStr) {
36
- const base = pathStr.split(/[/\\]/).pop() || pathStr;
37
- return base.replace(/\.skill$/, '').replace(/[-_]/g, ' ');
38
- }
39
- async function materializeSkillDir(sourceDir, targetDir, method) {
40
- const fs = await import('node:fs/promises');
41
- const path = await import('node:path');
42
- await removeIfExists(targetDir);
43
- await ensureDir(path.dirname(targetDir));
44
- if (method === "copy") {
45
- await copyDir(sourceDir, targetDir);
46
- return;
47
- }
48
- if (method === "symlink") {
49
- await fs.symlink(sourceDir, targetDir, "junction");
50
- return;
51
- }
52
- try {
53
- await fs.symlink(sourceDir, targetDir, "junction");
54
- }
55
- catch {
56
- await copyDir(sourceDir, targetDir);
57
- }
58
- }
59
- export class ClaudecodeSkillAdapter {
6
+ import { DirectorySkillAdapter } from './skill-directory.js';
7
+ export class ClaudecodeSkillAdapter extends DirectorySkillAdapter {
60
8
  constructor(skillsDir) {
61
- this.skillsDir = skillsDir;
62
- this.appId = "claudecode";
63
- }
64
- async importSkills() {
65
- const fs = await import('node:fs/promises');
66
- const path = await import('node:path');
67
- await ensureDir(this.skillsDir);
68
- const entries = await fs.readdir(this.skillsDir, { withFileTypes: true });
69
- return entries
70
- .filter((entry) => entry.isDirectory() || entry.isSymbolicLink())
71
- .map((entry) => {
72
- const directory = path.join(this.skillsDir, entry.name);
73
- return {
74
- id: `skill_import_${entry.name}`,
75
- name: toNameFromPath(entry.name),
76
- directory,
77
- description: undefined,
78
- };
79
- });
80
- }
81
- async syncSkill(skill, sourceDir, method) {
82
- const path = await import('node:path');
83
- const targetDir = path.join(this.skillsDir, skill.name);
84
- await materializeSkillDir(sourceDir, targetDir, method);
85
- }
86
- async removeSkill(skill) {
87
- const path = await import('node:path');
88
- const targetDir = path.join(this.skillsDir, skill.name);
89
- await removeIfExists(targetDir);
9
+ super('claudecode', skillsDir);
90
10
  }
91
11
  }
@@ -0,0 +1,5 @@
1
+ import { DirectorySkillAdapter } from './skill-directory.js';
2
+ export declare class CodexSkillAdapter extends DirectorySkillAdapter {
3
+ constructor(skillsDir: string);
4
+ }
5
+ //# sourceMappingURL=skill-codex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-codex.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/skill-codex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE7D,qBAAa,iBAAkB,SAAQ,qBAAqB;gBAC9C,SAAS,EAAE,MAAM;CAG9B"}
@@ -0,0 +1,6 @@
1
+ import { DirectorySkillAdapter } from './skill-directory.js';
2
+ export class CodexSkillAdapter extends DirectorySkillAdapter {
3
+ constructor(skillsDir) {
4
+ super('codex', skillsDir);
5
+ }
6
+ }
@@ -0,0 +1,10 @@
1
+ import type { AppId, ISkillAdapter, InstalledSkill, SkillSyncMethod } from '@cc-switch/sdk';
2
+ export declare class DirectorySkillAdapter implements ISkillAdapter {
3
+ readonly appId: AppId;
4
+ private readonly skillsDir;
5
+ constructor(appId: AppId, skillsDir: string);
6
+ importSkills(): Promise<Array<Pick<InstalledSkill, 'id' | 'name' | 'directory' | 'description'>>>;
7
+ syncSkill(skill: InstalledSkill, sourceDir: string, method: SkillSyncMethod): Promise<void>;
8
+ removeSkill(skill: InstalledSkill): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=skill-directory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-directory.d.ts","sourceRoot":"","sources":["../../../src/adapters/cc-switch/skill-directory.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AA4H5F,qBAAa,qBAAsB,YAAW,aAAa;aAEvC,KAAK,EAAE,KAAK;IAC5B,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADV,KAAK,EAAE,KAAK,EACX,SAAS,EAAE,MAAM;IAG9B,YAAY,IAAI,OAAO,CAC3B,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,aAAa,CAAC,CAAC,CACzE;IA+BK,SAAS,CACb,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC;IAKV,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;CAIxD"}