aws-runtime-bridge 1.9.135 → 1.9.139

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 (884) hide show
  1. package/dist/adapter/AcodeSdkAdapter.d.ts +10 -0
  2. package/dist/adapter/AcodeSdkAdapter.js +5 -5
  3. package/dist/adapter/ClaudeSdkAdapter.js +3 -3
  4. package/dist/adapter/CodexSdkAdapter.js +3 -3
  5. package/dist/adapter/OpencodeSdkAdapter.js +3 -3
  6. package/dist/browser/browser-pool.js +1 -1
  7. package/dist/browser/built-in-browser-tools.d.ts +1 -2
  8. package/dist/browser/built-in-browser-tools.js +1 -1
  9. package/dist/browser/ws-server.js +1 -1
  10. package/dist/config.d.ts +4 -0
  11. package/dist/config.js +2 -2
  12. package/dist/index.js +1 -1
  13. package/dist/middleware/auth.js +1 -1
  14. package/dist/remote-desktop/computer-control.d.ts +1 -1
  15. package/dist/remote-desktop/index.d.ts +1 -1
  16. package/dist/remote-desktop/index.js +2 -2
  17. package/dist/remote-desktop/session-manager.d.ts +2 -2
  18. package/dist/remote-desktop/session-manager.js +1 -1
  19. package/dist/remote-desktop/system-backend.js +3 -3
  20. package/dist/routes/ai-sources.js +1 -1
  21. package/dist/routes/background-tasks.js +1 -1
  22. package/dist/routes/browser-listeners.js +1 -1
  23. package/dist/routes/capabilities.d.ts +2 -0
  24. package/dist/routes/capabilities.js +2 -0
  25. package/dist/routes/dashboard.js +1 -1
  26. package/dist/routes/file-change-diff.js +3 -3
  27. package/dist/routes/file-diff-rollback.js +1 -1
  28. package/dist/routes/file-snapshot.js +1 -1
  29. package/dist/routes/git.js +1 -1
  30. package/dist/routes/instance.d.ts +0 -1
  31. package/dist/routes/instance.js +1 -1
  32. package/dist/routes/launch.js +1 -1
  33. package/dist/routes/mcp-extra.d.ts +2 -0
  34. package/dist/routes/mcp-extra.js +3 -0
  35. package/dist/routes/mcp.d.ts +1 -0
  36. package/dist/routes/mcp.js +1 -1
  37. package/dist/routes/plugins.d.ts +2 -0
  38. package/dist/routes/plugins.js +2 -0
  39. package/dist/routes/properties.js +1 -1
  40. package/dist/routes/pty.d.ts +1 -1
  41. package/dist/routes/pty.js +1 -1
  42. package/dist/routes/runtime-binding.js +1 -1
  43. package/dist/routes/skills.d.ts +1 -0
  44. package/dist/routes/skills.js +1 -1
  45. package/dist/routes/sub-agents.js +1 -1
  46. package/dist/routes/task-context.js +1 -1
  47. package/dist/routes/terminal.js +25 -25
  48. package/dist/routes/yml.js +1 -1
  49. package/dist/services/access-control.js +1 -1
  50. package/dist/services/acode-bg-manager.js +1 -1
  51. package/dist/services/agent-capability-sync.d.ts +7 -0
  52. package/dist/services/agent-capability-sync.js +2 -0
  53. package/dist/services/agent-process-manager.d.ts +1 -1
  54. package/dist/services/agent-process-manager.js +1 -1
  55. package/{package/cc-switch-sdk/dist → dist}/services/ai-config-service.d.ts +3 -0
  56. package/dist/services/ai-config-service.js +4 -0
  57. package/dist/services/ai-source-apply.d.ts +1 -1
  58. package/dist/services/ai-source-apply.js +1 -1
  59. package/dist/services/auto-register.js +1 -1
  60. package/dist/services/bridge-package-publish-hooks.js +1 -1
  61. package/dist/services/browser-session-manager.d.ts +3 -3
  62. package/dist/services/browser-session-manager.js +1 -1
  63. package/dist/services/capability-config.d.ts +21 -0
  64. package/dist/services/capability-config.js +3 -0
  65. package/dist/services/cli-commands.js +2 -2
  66. package/dist/services/desktop-mcp-manager.js +1 -1
  67. package/dist/services/fileSnapshotStore.js +1 -1
  68. package/dist/services/instance-ai-config-service.d.ts +1 -0
  69. package/dist/services/instance-ai-config-service.js +1 -1
  70. package/dist/services/instance-features.d.ts +21 -0
  71. package/dist/services/instance-features.js +1 -1
  72. package/dist/services/instance-init-service.d.ts +7 -4
  73. package/dist/services/instance-init-service.js +1 -1
  74. package/dist/services/instance-state.js +1 -1
  75. package/dist/services/jdk-scanner.js +1 -1
  76. package/dist/services/launch-manager.js +1 -1
  77. package/dist/services/legacy-path-migration.d.ts +2 -0
  78. package/dist/services/legacy-path-migration.js +1 -1
  79. package/dist/services/lifecycle-state.js +2 -2
  80. package/dist/services/mcp-deploy.d.ts +49 -0
  81. package/dist/services/mcp-deploy.js +4 -0
  82. package/dist/services/orphan-monitor.js +1 -1
  83. package/dist/services/plugin-event-buffer.d.ts +49 -0
  84. package/dist/services/plugin-event-buffer.js +2 -0
  85. package/dist/services/plugin-manager.d.ts +262 -0
  86. package/dist/services/plugin-manager.js +16 -0
  87. package/dist/services/plugin-package.d.ts +8 -0
  88. package/dist/services/plugin-package.js +2 -0
  89. package/dist/services/process-detail.js +2 -2
  90. package/dist/services/process-detector.js +10 -10
  91. package/dist/services/process-registry.js +1 -1
  92. package/dist/services/process-top.js +2 -2
  93. package/dist/services/runtime-binding.js +4 -4
  94. package/dist/services/sdk-tool-file-change-recorder.js +1 -1
  95. package/dist/services/skill-manager.d.ts +41 -0
  96. package/dist/services/skill-manager.js +3 -0
  97. package/dist/services/startup-config-wizard.js +6 -6
  98. package/dist/services/system-metrics.js +1 -1
  99. package/dist/services/tunnel-client.js +1 -1
  100. package/dist/services/update-notifier.js +2 -2
  101. package/dist/services/windows-service-manager.js +1 -1
  102. package/dist/services/workspace-files.js +1 -1
  103. package/dist/services/workspaceTaskChangeWatcher.js +3 -3
  104. package/dist/types.d.ts +11 -61
  105. package/dist/utils/file-utils.d.ts +9 -6
  106. package/dist/utils/file-utils.js +2 -2
  107. package/dist/utils/instance-ai-config-debug-logger.js +1 -1
  108. package/dist/utils/mcp-utils.d.ts +1 -37
  109. package/dist/utils/mcp-utils.js +1 -1
  110. package/dist/utils/yaml-utils.js +1 -1
  111. package/package/acode/dist/built-in-file-tools.js +2 -2
  112. package/package/acode/dist/commands/commandRegistry.d.ts +2 -0
  113. package/package/acode/dist/commands/commandRegistry.js +1 -1
  114. package/package/acode/dist/index.d.ts +2 -0
  115. package/package/acode/dist/index.js +1 -1
  116. package/package/acode/dist/plugin-tools.d.ts +14 -0
  117. package/package/acode/dist/plugin-tools.js +9 -0
  118. package/package/acode/dist/plugin-types.d.ts +119 -0
  119. package/package/acode/dist/runtime.d.ts +4 -0
  120. package/package/acode/dist/runtime.js +19 -19
  121. package/package/acode/dist/sub-agent-manager.js +1 -1
  122. package/package/acode/dist/types.d.ts +5 -0
  123. package/package/aws-client-agent-mcp/dist/agent-client.d.ts +9 -1
  124. package/package/aws-client-agent-mcp/dist/agent-client.js +1 -1
  125. package/package/aws-client-agent-mcp/dist/http-client.js +1 -1
  126. package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +10 -0
  127. package/package/aws-client-agent-mcp/dist/mcp-server.js +21 -21
  128. package/package/aws-client-agent-mcp/dist/mcp-tools.js +2 -4
  129. package/package/aws-client-agent-mcp/dist/memory-tools.js +12 -14
  130. package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +1 -1
  131. package/package/aws-client-agent-mcp/dist/server-memory-store.js +1 -1
  132. package/package/aws-client-agent-mcp/dist/status-reporter.d.ts +2 -0
  133. package/package/aws-client-agent-mcp/dist/status-reporter.js +3 -2
  134. package/package/aws-client-agent-mcp/dist/types.d.ts +22 -0
  135. package/package.json +4 -10
  136. package/dist/adapters/cc-switch/common.d.ts +0 -41
  137. package/dist/adapters/cc-switch/common.js +0 -2
  138. package/dist/adapters/cc-switch/index.d.ts +0 -19
  139. package/dist/adapters/cc-switch/index.js +0 -2
  140. package/dist/adapters/cc-switch/mcp-acode.d.ts +0 -10
  141. package/dist/adapters/cc-switch/mcp-acode.js +0 -2
  142. package/dist/adapters/cc-switch/mcp-claude.d.ts +0 -10
  143. package/dist/adapters/cc-switch/mcp-claude.js +0 -2
  144. package/dist/adapters/cc-switch/mcp-claudecode.d.ts +0 -10
  145. package/dist/adapters/cc-switch/mcp-claudecode.js +0 -2
  146. package/dist/adapters/cc-switch/mcp-codex.d.ts +0 -10
  147. package/dist/adapters/cc-switch/mcp-codex.js +0 -11
  148. package/dist/adapters/cc-switch/mcp-opencode.d.ts +0 -14
  149. package/dist/adapters/cc-switch/mcp-opencode.js +0 -2
  150. package/dist/adapters/cc-switch/mcp-placeholder.d.ts +0 -9
  151. package/dist/adapters/cc-switch/mcp-placeholder.js +0 -2
  152. package/dist/adapters/cc-switch/skill-acode.d.ts +0 -5
  153. package/dist/adapters/cc-switch/skill-acode.js +0 -2
  154. package/dist/adapters/cc-switch/skill-claude.d.ts +0 -5
  155. package/dist/adapters/cc-switch/skill-claude.js +0 -2
  156. package/dist/adapters/cc-switch/skill-claudecode.d.ts +0 -5
  157. package/dist/adapters/cc-switch/skill-claudecode.js +0 -2
  158. package/dist/adapters/cc-switch/skill-codex.d.ts +0 -4
  159. package/dist/adapters/cc-switch/skill-codex.js +0 -2
  160. package/dist/adapters/cc-switch/skill-directory.d.ts +0 -9
  161. package/dist/adapters/cc-switch/skill-directory.js +0 -3
  162. package/dist/adapters/cc-switch/skill-opencode.d.ts +0 -5
  163. package/dist/adapters/cc-switch/skill-opencode.js +0 -2
  164. package/dist/adapters/cc-switch/skill-placeholder.d.ts +0 -9
  165. package/dist/adapters/cc-switch/skill-placeholder.js +0 -2
  166. package/dist/services/cc-switch-sdk.d.ts +0 -17
  167. package/dist/services/cc-switch-sdk.js +0 -2
  168. package/dist/services/instance-service.d.ts +0 -78
  169. package/dist/services/instance-service.js +0 -2
  170. package/node_modules/@cc-switch/sdk/README.md +0 -541
  171. package/node_modules/@cc-switch/sdk/dist/constants.d.ts +0 -8
  172. package/node_modules/@cc-switch/sdk/dist/constants.js +0 -2
  173. package/node_modules/@cc-switch/sdk/dist/errors.d.ts +0 -5
  174. package/node_modules/@cc-switch/sdk/dist/errors.js +0 -2
  175. package/node_modules/@cc-switch/sdk/dist/index.d.ts +0 -5
  176. package/node_modules/@cc-switch/sdk/dist/index.js +0 -2
  177. package/node_modules/@cc-switch/sdk/dist/schemas.d.ts +0 -7
  178. package/node_modules/@cc-switch/sdk/dist/schemas.js +0 -2
  179. package/node_modules/@cc-switch/sdk/dist/sdk.d.ts +0 -59
  180. package/node_modules/@cc-switch/sdk/dist/sdk.js +0 -2
  181. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.d.ts +0 -81
  182. package/node_modules/@cc-switch/sdk/dist/services/ai-config-service.js +0 -4
  183. package/node_modules/@cc-switch/sdk/dist/services/mcp-model.d.ts +0 -16
  184. package/node_modules/@cc-switch/sdk/dist/services/mcp-model.js +0 -2
  185. package/node_modules/@cc-switch/sdk/dist/services/mcp-service.d.ts +0 -17
  186. package/node_modules/@cc-switch/sdk/dist/services/mcp-service.js +0 -2
  187. package/node_modules/@cc-switch/sdk/dist/services/skill-model.d.ts +0 -16
  188. package/node_modules/@cc-switch/sdk/dist/services/skill-model.js +0 -2
  189. package/node_modules/@cc-switch/sdk/dist/services/skill-service.d.ts +0 -16
  190. package/node_modules/@cc-switch/sdk/dist/services/skill-service.js +0 -2
  191. package/node_modules/@cc-switch/sdk/dist/state.d.ts +0 -3
  192. package/node_modules/@cc-switch/sdk/dist/state.js +0 -2
  193. package/node_modules/@cc-switch/sdk/dist/types.d.ts +0 -78
  194. package/node_modules/@cc-switch/sdk/dist/utils/fs.d.ts +0 -10
  195. package/node_modules/@cc-switch/sdk/dist/utils/fs.js +0 -3
  196. package/node_modules/@cc-switch/sdk/dist/utils/id.d.ts +0 -3
  197. package/node_modules/@cc-switch/sdk/dist/utils/id.js +0 -2
  198. package/node_modules/@cc-switch/sdk/package.json +0 -31
  199. package/node_modules/zod/LICENSE +0 -21
  200. package/node_modules/zod/README.md +0 -208
  201. package/node_modules/zod/index.cjs +0 -33
  202. package/node_modules/zod/index.d.cts +0 -4
  203. package/node_modules/zod/index.d.ts +0 -4
  204. package/node_modules/zod/index.js +0 -4
  205. package/node_modules/zod/locales/index.cjs +0 -17
  206. package/node_modules/zod/locales/index.d.cts +0 -1
  207. package/node_modules/zod/locales/index.d.ts +0 -1
  208. package/node_modules/zod/locales/index.js +0 -1
  209. package/node_modules/zod/locales/package.json +0 -6
  210. package/node_modules/zod/mini/index.cjs +0 -17
  211. package/node_modules/zod/mini/index.d.cts +0 -1
  212. package/node_modules/zod/mini/index.d.ts +0 -1
  213. package/node_modules/zod/mini/index.js +0 -1
  214. package/node_modules/zod/mini/package.json +0 -6
  215. package/node_modules/zod/package.json +0 -135
  216. package/node_modules/zod/src/index.ts +0 -4
  217. package/node_modules/zod/src/locales/index.ts +0 -1
  218. package/node_modules/zod/src/mini/index.ts +0 -1
  219. package/node_modules/zod/src/v3/ZodError.ts +0 -330
  220. package/node_modules/zod/src/v3/benchmarks/datetime.ts +0 -58
  221. package/node_modules/zod/src/v3/benchmarks/discriminatedUnion.ts +0 -80
  222. package/node_modules/zod/src/v3/benchmarks/index.ts +0 -59
  223. package/node_modules/zod/src/v3/benchmarks/ipv4.ts +0 -57
  224. package/node_modules/zod/src/v3/benchmarks/object.ts +0 -69
  225. package/node_modules/zod/src/v3/benchmarks/primitives.ts +0 -162
  226. package/node_modules/zod/src/v3/benchmarks/realworld.ts +0 -63
  227. package/node_modules/zod/src/v3/benchmarks/string.ts +0 -55
  228. package/node_modules/zod/src/v3/benchmarks/union.ts +0 -80
  229. package/node_modules/zod/src/v3/errors.ts +0 -13
  230. package/node_modules/zod/src/v3/external.ts +0 -6
  231. package/node_modules/zod/src/v3/helpers/enumUtil.ts +0 -17
  232. package/node_modules/zod/src/v3/helpers/errorUtil.ts +0 -8
  233. package/node_modules/zod/src/v3/helpers/parseUtil.ts +0 -176
  234. package/node_modules/zod/src/v3/helpers/partialUtil.ts +0 -34
  235. package/node_modules/zod/src/v3/helpers/typeAliases.ts +0 -2
  236. package/node_modules/zod/src/v3/helpers/util.ts +0 -224
  237. package/node_modules/zod/src/v3/index.ts +0 -4
  238. package/node_modules/zod/src/v3/locales/en.ts +0 -124
  239. package/node_modules/zod/src/v3/standard-schema.ts +0 -113
  240. package/node_modules/zod/src/v3/tests/Mocker.ts +0 -54
  241. package/node_modules/zod/src/v3/tests/all-errors.test.ts +0 -157
  242. package/node_modules/zod/src/v3/tests/anyunknown.test.ts +0 -28
  243. package/node_modules/zod/src/v3/tests/array.test.ts +0 -71
  244. package/node_modules/zod/src/v3/tests/async-parsing.test.ts +0 -388
  245. package/node_modules/zod/src/v3/tests/async-refinements.test.ts +0 -46
  246. package/node_modules/zod/src/v3/tests/base.test.ts +0 -29
  247. package/node_modules/zod/src/v3/tests/bigint.test.ts +0 -55
  248. package/node_modules/zod/src/v3/tests/branded.test.ts +0 -53
  249. package/node_modules/zod/src/v3/tests/catch.test.ts +0 -220
  250. package/node_modules/zod/src/v3/tests/coerce.test.ts +0 -133
  251. package/node_modules/zod/src/v3/tests/complex.test.ts +0 -56
  252. package/node_modules/zod/src/v3/tests/custom.test.ts +0 -31
  253. package/node_modules/zod/src/v3/tests/date.test.ts +0 -32
  254. package/node_modules/zod/src/v3/tests/deepmasking.test.ts +0 -186
  255. package/node_modules/zod/src/v3/tests/default.test.ts +0 -112
  256. package/node_modules/zod/src/v3/tests/description.test.ts +0 -33
  257. package/node_modules/zod/src/v3/tests/discriminated-unions.test.ts +0 -315
  258. package/node_modules/zod/src/v3/tests/enum.test.ts +0 -80
  259. package/node_modules/zod/src/v3/tests/error.test.ts +0 -551
  260. package/node_modules/zod/src/v3/tests/firstparty.test.ts +0 -87
  261. package/node_modules/zod/src/v3/tests/firstpartyschematypes.test.ts +0 -21
  262. package/node_modules/zod/src/v3/tests/function.test.ts +0 -257
  263. package/node_modules/zod/src/v3/tests/generics.test.ts +0 -48
  264. package/node_modules/zod/src/v3/tests/instanceof.test.ts +0 -37
  265. package/node_modules/zod/src/v3/tests/intersection.test.ts +0 -110
  266. package/node_modules/zod/src/v3/tests/language-server.source.ts +0 -76
  267. package/node_modules/zod/src/v3/tests/language-server.test.ts +0 -207
  268. package/node_modules/zod/src/v3/tests/literal.test.ts +0 -36
  269. package/node_modules/zod/src/v3/tests/map.test.ts +0 -110
  270. package/node_modules/zod/src/v3/tests/masking.test.ts +0 -4
  271. package/node_modules/zod/src/v3/tests/mocker.test.ts +0 -19
  272. package/node_modules/zod/src/v3/tests/nan.test.ts +0 -21
  273. package/node_modules/zod/src/v3/tests/nativeEnum.test.ts +0 -87
  274. package/node_modules/zod/src/v3/tests/nullable.test.ts +0 -42
  275. package/node_modules/zod/src/v3/tests/number.test.ts +0 -176
  276. package/node_modules/zod/src/v3/tests/object-augmentation.test.ts +0 -29
  277. package/node_modules/zod/src/v3/tests/object-in-es5-env.test.ts +0 -29
  278. package/node_modules/zod/src/v3/tests/object.test.ts +0 -434
  279. package/node_modules/zod/src/v3/tests/optional.test.ts +0 -42
  280. package/node_modules/zod/src/v3/tests/parseUtil.test.ts +0 -23
  281. package/node_modules/zod/src/v3/tests/parser.test.ts +0 -41
  282. package/node_modules/zod/src/v3/tests/partials.test.ts +0 -243
  283. package/node_modules/zod/src/v3/tests/pickomit.test.ts +0 -111
  284. package/node_modules/zod/src/v3/tests/pipeline.test.ts +0 -29
  285. package/node_modules/zod/src/v3/tests/preprocess.test.ts +0 -186
  286. package/node_modules/zod/src/v3/tests/primitive.test.ts +0 -440
  287. package/node_modules/zod/src/v3/tests/promise.test.ts +0 -90
  288. package/node_modules/zod/src/v3/tests/readonly.test.ts +0 -194
  289. package/node_modules/zod/src/v3/tests/record.test.ts +0 -171
  290. package/node_modules/zod/src/v3/tests/recursive.test.ts +0 -197
  291. package/node_modules/zod/src/v3/tests/refine.test.ts +0 -313
  292. package/node_modules/zod/src/v3/tests/safeparse.test.ts +0 -27
  293. package/node_modules/zod/src/v3/tests/set.test.ts +0 -142
  294. package/node_modules/zod/src/v3/tests/standard-schema.test.ts +0 -83
  295. package/node_modules/zod/src/v3/tests/string.test.ts +0 -916
  296. package/node_modules/zod/src/v3/tests/transformer.test.ts +0 -233
  297. package/node_modules/zod/src/v3/tests/tuple.test.ts +0 -90
  298. package/node_modules/zod/src/v3/tests/unions.test.ts +0 -57
  299. package/node_modules/zod/src/v3/tests/validations.test.ts +0 -133
  300. package/node_modules/zod/src/v3/tests/void.test.ts +0 -15
  301. package/node_modules/zod/src/v3/types.ts +0 -5138
  302. package/node_modules/zod/src/v4/classic/checks.ts +0 -31
  303. package/node_modules/zod/src/v4/classic/coerce.ts +0 -27
  304. package/node_modules/zod/src/v4/classic/compat.ts +0 -70
  305. package/node_modules/zod/src/v4/classic/errors.ts +0 -82
  306. package/node_modules/zod/src/v4/classic/external.ts +0 -50
  307. package/node_modules/zod/src/v4/classic/index.ts +0 -5
  308. package/node_modules/zod/src/v4/classic/iso.ts +0 -90
  309. package/node_modules/zod/src/v4/classic/parse.ts +0 -82
  310. package/node_modules/zod/src/v4/classic/schemas.ts +0 -2197
  311. package/node_modules/zod/src/v4/classic/tests/anyunknown.test.ts +0 -26
  312. package/node_modules/zod/src/v4/classic/tests/array.test.ts +0 -264
  313. package/node_modules/zod/src/v4/classic/tests/assignability.test.ts +0 -210
  314. package/node_modules/zod/src/v4/classic/tests/async-parsing.test.ts +0 -381
  315. package/node_modules/zod/src/v4/classic/tests/async-refinements.test.ts +0 -68
  316. package/node_modules/zod/src/v4/classic/tests/base.test.ts +0 -7
  317. package/node_modules/zod/src/v4/classic/tests/bigint.test.ts +0 -54
  318. package/node_modules/zod/src/v4/classic/tests/brand.test.ts +0 -63
  319. package/node_modules/zod/src/v4/classic/tests/catch.test.ts +0 -276
  320. package/node_modules/zod/src/v4/classic/tests/coalesce.test.ts +0 -20
  321. package/node_modules/zod/src/v4/classic/tests/codec-examples.test.ts +0 -573
  322. package/node_modules/zod/src/v4/classic/tests/codec.test.ts +0 -562
  323. package/node_modules/zod/src/v4/classic/tests/coerce.test.ts +0 -160
  324. package/node_modules/zod/src/v4/classic/tests/continuability.test.ts +0 -352
  325. package/node_modules/zod/src/v4/classic/tests/custom.test.ts +0 -40
  326. package/node_modules/zod/src/v4/classic/tests/date.test.ts +0 -31
  327. package/node_modules/zod/src/v4/classic/tests/datetime.test.ts +0 -302
  328. package/node_modules/zod/src/v4/classic/tests/default.test.ts +0 -365
  329. package/node_modules/zod/src/v4/classic/tests/description.test.ts +0 -32
  330. package/node_modules/zod/src/v4/classic/tests/discriminated-unions.test.ts +0 -661
  331. package/node_modules/zod/src/v4/classic/tests/enum.test.ts +0 -285
  332. package/node_modules/zod/src/v4/classic/tests/error-utils.test.ts +0 -595
  333. package/node_modules/zod/src/v4/classic/tests/error.test.ts +0 -711
  334. package/node_modules/zod/src/v4/classic/tests/file.test.ts +0 -96
  335. package/node_modules/zod/src/v4/classic/tests/firstparty.test.ts +0 -179
  336. package/node_modules/zod/src/v4/classic/tests/function.test.ts +0 -308
  337. package/node_modules/zod/src/v4/classic/tests/generics.test.ts +0 -72
  338. package/node_modules/zod/src/v4/classic/tests/hash.test.ts +0 -68
  339. package/node_modules/zod/src/v4/classic/tests/index.test.ts +0 -844
  340. package/node_modules/zod/src/v4/classic/tests/instanceof.test.ts +0 -34
  341. package/node_modules/zod/src/v4/classic/tests/intersection.test.ts +0 -171
  342. package/node_modules/zod/src/v4/classic/tests/json.test.ts +0 -108
  343. package/node_modules/zod/src/v4/classic/tests/lazy.test.ts +0 -227
  344. package/node_modules/zod/src/v4/classic/tests/literal.test.ts +0 -117
  345. package/node_modules/zod/src/v4/classic/tests/map.test.ts +0 -196
  346. package/node_modules/zod/src/v4/classic/tests/nan.test.ts +0 -21
  347. package/node_modules/zod/src/v4/classic/tests/nested-refine.test.ts +0 -168
  348. package/node_modules/zod/src/v4/classic/tests/nonoptional.test.ts +0 -101
  349. package/node_modules/zod/src/v4/classic/tests/nullable.test.ts +0 -22
  350. package/node_modules/zod/src/v4/classic/tests/number.test.ts +0 -270
  351. package/node_modules/zod/src/v4/classic/tests/object.test.ts +0 -609
  352. package/node_modules/zod/src/v4/classic/tests/optional.test.ts +0 -136
  353. package/node_modules/zod/src/v4/classic/tests/partial.test.ts +0 -340
  354. package/node_modules/zod/src/v4/classic/tests/pickomit.test.ts +0 -127
  355. package/node_modules/zod/src/v4/classic/tests/pipe.test.ts +0 -101
  356. package/node_modules/zod/src/v4/classic/tests/prefault.test.ts +0 -74
  357. package/node_modules/zod/src/v4/classic/tests/preprocess.test.ts +0 -282
  358. package/node_modules/zod/src/v4/classic/tests/primitive.test.ts +0 -175
  359. package/node_modules/zod/src/v4/classic/tests/promise.test.ts +0 -81
  360. package/node_modules/zod/src/v4/classic/tests/prototypes.test.ts +0 -23
  361. package/node_modules/zod/src/v4/classic/tests/readonly.test.ts +0 -252
  362. package/node_modules/zod/src/v4/classic/tests/record.test.ts +0 -356
  363. package/node_modules/zod/src/v4/classic/tests/recursive-types.test.ts +0 -582
  364. package/node_modules/zod/src/v4/classic/tests/refine.test.ts +0 -605
  365. package/node_modules/zod/src/v4/classic/tests/registries.test.ts +0 -204
  366. package/node_modules/zod/src/v4/classic/tests/set.test.ts +0 -181
  367. package/node_modules/zod/src/v4/classic/tests/standard-schema.test.ts +0 -57
  368. package/node_modules/zod/src/v4/classic/tests/string-formats.test.ts +0 -125
  369. package/node_modules/zod/src/v4/classic/tests/string.test.ts +0 -1080
  370. package/node_modules/zod/src/v4/classic/tests/stringbool.test.ts +0 -106
  371. package/node_modules/zod/src/v4/classic/tests/template-literal.test.ts +0 -763
  372. package/node_modules/zod/src/v4/classic/tests/to-json-schema.test.ts +0 -2622
  373. package/node_modules/zod/src/v4/classic/tests/transform.test.ts +0 -361
  374. package/node_modules/zod/src/v4/classic/tests/tuple.test.ts +0 -163
  375. package/node_modules/zod/src/v4/classic/tests/union.test.ts +0 -181
  376. package/node_modules/zod/src/v4/classic/tests/validations.test.ts +0 -283
  377. package/node_modules/zod/src/v4/classic/tests/void.test.ts +0 -12
  378. package/node_modules/zod/src/v4/core/api.ts +0 -1621
  379. package/node_modules/zod/src/v4/core/checks.ts +0 -1287
  380. package/node_modules/zod/src/v4/core/config.ts +0 -15
  381. package/node_modules/zod/src/v4/core/core.ts +0 -115
  382. package/node_modules/zod/src/v4/core/doc.ts +0 -44
  383. package/node_modules/zod/src/v4/core/errors.ts +0 -413
  384. package/node_modules/zod/src/v4/core/index.ts +0 -14
  385. package/node_modules/zod/src/v4/core/json-schema.ts +0 -147
  386. package/node_modules/zod/src/v4/core/parse.ts +0 -195
  387. package/node_modules/zod/src/v4/core/regexes.ts +0 -177
  388. package/node_modules/zod/src/v4/core/registries.ts +0 -97
  389. package/node_modules/zod/src/v4/core/schemas.ts +0 -4317
  390. package/node_modules/zod/src/v4/core/standard-schema.ts +0 -64
  391. package/node_modules/zod/src/v4/core/tests/extend.test.ts +0 -18
  392. package/node_modules/zod/src/v4/core/tests/index.test.ts +0 -46
  393. package/node_modules/zod/src/v4/core/tests/locales/be.test.ts +0 -124
  394. package/node_modules/zod/src/v4/core/tests/locales/en.test.ts +0 -22
  395. package/node_modules/zod/src/v4/core/tests/locales/es.test.ts +0 -181
  396. package/node_modules/zod/src/v4/core/tests/locales/ru.test.ts +0 -128
  397. package/node_modules/zod/src/v4/core/tests/locales/tr.test.ts +0 -69
  398. package/node_modules/zod/src/v4/core/to-json-schema.ts +0 -1044
  399. package/node_modules/zod/src/v4/core/util.ts +0 -910
  400. package/node_modules/zod/src/v4/core/versions.ts +0 -5
  401. package/node_modules/zod/src/v4/core/zsf.ts +0 -323
  402. package/node_modules/zod/src/v4/index.ts +0 -4
  403. package/node_modules/zod/src/v4/locales/ar.ts +0 -125
  404. package/node_modules/zod/src/v4/locales/az.ts +0 -121
  405. package/node_modules/zod/src/v4/locales/be.ts +0 -184
  406. package/node_modules/zod/src/v4/locales/bg.ts +0 -136
  407. package/node_modules/zod/src/v4/locales/ca.ts +0 -127
  408. package/node_modules/zod/src/v4/locales/cs.ts +0 -142
  409. package/node_modules/zod/src/v4/locales/da.ts +0 -141
  410. package/node_modules/zod/src/v4/locales/de.ts +0 -124
  411. package/node_modules/zod/src/v4/locales/en.ts +0 -127
  412. package/node_modules/zod/src/v4/locales/eo.ts +0 -125
  413. package/node_modules/zod/src/v4/locales/es.ts +0 -159
  414. package/node_modules/zod/src/v4/locales/fa.ts +0 -134
  415. package/node_modules/zod/src/v4/locales/fi.ts +0 -131
  416. package/node_modules/zod/src/v4/locales/fr-CA.ts +0 -126
  417. package/node_modules/zod/src/v4/locales/fr.ts +0 -124
  418. package/node_modules/zod/src/v4/locales/he.ts +0 -125
  419. package/node_modules/zod/src/v4/locales/hu.ts +0 -126
  420. package/node_modules/zod/src/v4/locales/id.ts +0 -125
  421. package/node_modules/zod/src/v4/locales/index.ts +0 -47
  422. package/node_modules/zod/src/v4/locales/is.ts +0 -127
  423. package/node_modules/zod/src/v4/locales/it.ts +0 -125
  424. package/node_modules/zod/src/v4/locales/ja.ts +0 -122
  425. package/node_modules/zod/src/v4/locales/ka.ts +0 -138
  426. package/node_modules/zod/src/v4/locales/kh.ts +0 -7
  427. package/node_modules/zod/src/v4/locales/km.ts +0 -126
  428. package/node_modules/zod/src/v4/locales/ko.ts +0 -131
  429. package/node_modules/zod/src/v4/locales/lt.ts +0 -265
  430. package/node_modules/zod/src/v4/locales/mk.ts +0 -127
  431. package/node_modules/zod/src/v4/locales/ms.ts +0 -124
  432. package/node_modules/zod/src/v4/locales/nl.ts +0 -126
  433. package/node_modules/zod/src/v4/locales/no.ts +0 -124
  434. package/node_modules/zod/src/v4/locales/ota.ts +0 -125
  435. package/node_modules/zod/src/v4/locales/pl.ts +0 -126
  436. package/node_modules/zod/src/v4/locales/ps.ts +0 -133
  437. package/node_modules/zod/src/v4/locales/pt.ts +0 -123
  438. package/node_modules/zod/src/v4/locales/ru.ts +0 -184
  439. package/node_modules/zod/src/v4/locales/sl.ts +0 -126
  440. package/node_modules/zod/src/v4/locales/sv.ts +0 -127
  441. package/node_modules/zod/src/v4/locales/ta.ts +0 -125
  442. package/node_modules/zod/src/v4/locales/th.ts +0 -126
  443. package/node_modules/zod/src/v4/locales/tr.ts +0 -121
  444. package/node_modules/zod/src/v4/locales/ua.ts +0 -7
  445. package/node_modules/zod/src/v4/locales/uk.ts +0 -126
  446. package/node_modules/zod/src/v4/locales/ur.ts +0 -126
  447. package/node_modules/zod/src/v4/locales/vi.ts +0 -125
  448. package/node_modules/zod/src/v4/locales/yo.ts +0 -131
  449. package/node_modules/zod/src/v4/locales/zh-CN.ts +0 -123
  450. package/node_modules/zod/src/v4/locales/zh-TW.ts +0 -125
  451. package/node_modules/zod/src/v4/mini/checks.ts +0 -32
  452. package/node_modules/zod/src/v4/mini/coerce.ts +0 -22
  453. package/node_modules/zod/src/v4/mini/external.ts +0 -40
  454. package/node_modules/zod/src/v4/mini/index.ts +0 -3
  455. package/node_modules/zod/src/v4/mini/iso.ts +0 -62
  456. package/node_modules/zod/src/v4/mini/parse.ts +0 -14
  457. package/node_modules/zod/src/v4/mini/schemas.ts +0 -1725
  458. package/node_modules/zod/src/v4/mini/tests/assignability.test.ts +0 -129
  459. package/node_modules/zod/src/v4/mini/tests/brand.test.ts +0 -51
  460. package/node_modules/zod/src/v4/mini/tests/checks.test.ts +0 -144
  461. package/node_modules/zod/src/v4/mini/tests/codec.test.ts +0 -529
  462. package/node_modules/zod/src/v4/mini/tests/computed.test.ts +0 -36
  463. package/node_modules/zod/src/v4/mini/tests/error.test.ts +0 -22
  464. package/node_modules/zod/src/v4/mini/tests/functions.test.ts +0 -43
  465. package/node_modules/zod/src/v4/mini/tests/index.test.ts +0 -899
  466. package/node_modules/zod/src/v4/mini/tests/number.test.ts +0 -95
  467. package/node_modules/zod/src/v4/mini/tests/object.test.ts +0 -200
  468. package/node_modules/zod/src/v4/mini/tests/prototypes.test.ts +0 -43
  469. package/node_modules/zod/src/v4/mini/tests/recursive-types.test.ts +0 -275
  470. package/node_modules/zod/src/v4/mini/tests/string.test.ts +0 -315
  471. package/node_modules/zod/src/v4-mini/index.ts +0 -1
  472. package/node_modules/zod/v3/ZodError.cjs +0 -138
  473. package/node_modules/zod/v3/ZodError.d.cts +0 -164
  474. package/node_modules/zod/v3/ZodError.d.ts +0 -164
  475. package/node_modules/zod/v3/ZodError.js +0 -133
  476. package/node_modules/zod/v3/errors.cjs +0 -17
  477. package/node_modules/zod/v3/errors.d.cts +0 -5
  478. package/node_modules/zod/v3/errors.d.ts +0 -5
  479. package/node_modules/zod/v3/errors.js +0 -9
  480. package/node_modules/zod/v3/external.cjs +0 -22
  481. package/node_modules/zod/v3/external.d.cts +0 -6
  482. package/node_modules/zod/v3/external.d.ts +0 -6
  483. package/node_modules/zod/v3/external.js +0 -6
  484. package/node_modules/zod/v3/helpers/enumUtil.cjs +0 -2
  485. package/node_modules/zod/v3/helpers/enumUtil.d.cts +0 -8
  486. package/node_modules/zod/v3/helpers/enumUtil.d.ts +0 -8
  487. package/node_modules/zod/v3/helpers/enumUtil.js +0 -1
  488. package/node_modules/zod/v3/helpers/errorUtil.cjs +0 -9
  489. package/node_modules/zod/v3/helpers/errorUtil.d.cts +0 -9
  490. package/node_modules/zod/v3/helpers/errorUtil.d.ts +0 -9
  491. package/node_modules/zod/v3/helpers/errorUtil.js +0 -6
  492. package/node_modules/zod/v3/helpers/parseUtil.cjs +0 -124
  493. package/node_modules/zod/v3/helpers/parseUtil.d.cts +0 -78
  494. package/node_modules/zod/v3/helpers/parseUtil.d.ts +0 -78
  495. package/node_modules/zod/v3/helpers/parseUtil.js +0 -109
  496. package/node_modules/zod/v3/helpers/partialUtil.cjs +0 -2
  497. package/node_modules/zod/v3/helpers/partialUtil.d.cts +0 -8
  498. package/node_modules/zod/v3/helpers/partialUtil.d.ts +0 -8
  499. package/node_modules/zod/v3/helpers/partialUtil.js +0 -1
  500. package/node_modules/zod/v3/helpers/typeAliases.cjs +0 -2
  501. package/node_modules/zod/v3/helpers/typeAliases.d.cts +0 -2
  502. package/node_modules/zod/v3/helpers/typeAliases.d.ts +0 -2
  503. package/node_modules/zod/v3/helpers/typeAliases.js +0 -1
  504. package/node_modules/zod/v3/helpers/util.cjs +0 -137
  505. package/node_modules/zod/v3/helpers/util.d.cts +0 -85
  506. package/node_modules/zod/v3/helpers/util.d.ts +0 -85
  507. package/node_modules/zod/v3/helpers/util.js +0 -133
  508. package/node_modules/zod/v3/index.cjs +0 -33
  509. package/node_modules/zod/v3/index.d.cts +0 -4
  510. package/node_modules/zod/v3/index.d.ts +0 -4
  511. package/node_modules/zod/v3/index.js +0 -4
  512. package/node_modules/zod/v3/locales/en.cjs +0 -112
  513. package/node_modules/zod/v3/locales/en.d.cts +0 -3
  514. package/node_modules/zod/v3/locales/en.d.ts +0 -3
  515. package/node_modules/zod/v3/locales/en.js +0 -109
  516. package/node_modules/zod/v3/package.json +0 -6
  517. package/node_modules/zod/v3/standard-schema.cjs +0 -2
  518. package/node_modules/zod/v3/standard-schema.d.cts +0 -102
  519. package/node_modules/zod/v3/standard-schema.d.ts +0 -102
  520. package/node_modules/zod/v3/standard-schema.js +0 -1
  521. package/node_modules/zod/v3/types.cjs +0 -3777
  522. package/node_modules/zod/v3/types.d.cts +0 -1034
  523. package/node_modules/zod/v3/types.d.ts +0 -1034
  524. package/node_modules/zod/v3/types.js +0 -3695
  525. package/node_modules/zod/v4/classic/checks.cjs +0 -32
  526. package/node_modules/zod/v4/classic/checks.d.cts +0 -1
  527. package/node_modules/zod/v4/classic/checks.d.ts +0 -1
  528. package/node_modules/zod/v4/classic/checks.js +0 -1
  529. package/node_modules/zod/v4/classic/coerce.cjs +0 -47
  530. package/node_modules/zod/v4/classic/coerce.d.cts +0 -17
  531. package/node_modules/zod/v4/classic/coerce.d.ts +0 -17
  532. package/node_modules/zod/v4/classic/coerce.js +0 -17
  533. package/node_modules/zod/v4/classic/compat.cjs +0 -61
  534. package/node_modules/zod/v4/classic/compat.d.cts +0 -50
  535. package/node_modules/zod/v4/classic/compat.d.ts +0 -50
  536. package/node_modules/zod/v4/classic/compat.js +0 -31
  537. package/node_modules/zod/v4/classic/errors.cjs +0 -74
  538. package/node_modules/zod/v4/classic/errors.d.cts +0 -30
  539. package/node_modules/zod/v4/classic/errors.d.ts +0 -30
  540. package/node_modules/zod/v4/classic/errors.js +0 -48
  541. package/node_modules/zod/v4/classic/external.cjs +0 -70
  542. package/node_modules/zod/v4/classic/external.d.cts +0 -13
  543. package/node_modules/zod/v4/classic/external.d.ts +0 -13
  544. package/node_modules/zod/v4/classic/external.js +0 -18
  545. package/node_modules/zod/v4/classic/index.cjs +0 -33
  546. package/node_modules/zod/v4/classic/index.d.cts +0 -4
  547. package/node_modules/zod/v4/classic/index.d.ts +0 -4
  548. package/node_modules/zod/v4/classic/index.js +0 -4
  549. package/node_modules/zod/v4/classic/iso.cjs +0 -60
  550. package/node_modules/zod/v4/classic/iso.d.cts +0 -22
  551. package/node_modules/zod/v4/classic/iso.d.ts +0 -22
  552. package/node_modules/zod/v4/classic/iso.js +0 -30
  553. package/node_modules/zod/v4/classic/package.json +0 -6
  554. package/node_modules/zod/v4/classic/parse.cjs +0 -41
  555. package/node_modules/zod/v4/classic/parse.d.cts +0 -31
  556. package/node_modules/zod/v4/classic/parse.d.ts +0 -31
  557. package/node_modules/zod/v4/classic/parse.js +0 -15
  558. package/node_modules/zod/v4/classic/schemas.cjs +0 -1151
  559. package/node_modules/zod/v4/classic/schemas.d.cts +0 -673
  560. package/node_modules/zod/v4/classic/schemas.d.ts +0 -673
  561. package/node_modules/zod/v4/classic/schemas.js +0 -1040
  562. package/node_modules/zod/v4/core/api.cjs +0 -1060
  563. package/node_modules/zod/v4/core/api.d.cts +0 -295
  564. package/node_modules/zod/v4/core/api.d.ts +0 -295
  565. package/node_modules/zod/v4/core/api.js +0 -925
  566. package/node_modules/zod/v4/core/checks.cjs +0 -595
  567. package/node_modules/zod/v4/core/checks.d.cts +0 -278
  568. package/node_modules/zod/v4/core/checks.d.ts +0 -278
  569. package/node_modules/zod/v4/core/checks.js +0 -569
  570. package/node_modules/zod/v4/core/core.cjs +0 -74
  571. package/node_modules/zod/v4/core/core.d.cts +0 -52
  572. package/node_modules/zod/v4/core/core.d.ts +0 -52
  573. package/node_modules/zod/v4/core/core.js +0 -67
  574. package/node_modules/zod/v4/core/doc.cjs +0 -39
  575. package/node_modules/zod/v4/core/doc.d.cts +0 -14
  576. package/node_modules/zod/v4/core/doc.d.ts +0 -14
  577. package/node_modules/zod/v4/core/doc.js +0 -35
  578. package/node_modules/zod/v4/core/errors.cjs +0 -213
  579. package/node_modules/zod/v4/core/errors.d.cts +0 -210
  580. package/node_modules/zod/v4/core/errors.d.ts +0 -210
  581. package/node_modules/zod/v4/core/errors.js +0 -182
  582. package/node_modules/zod/v4/core/index.cjs +0 -43
  583. package/node_modules/zod/v4/core/index.d.cts +0 -14
  584. package/node_modules/zod/v4/core/index.d.ts +0 -14
  585. package/node_modules/zod/v4/core/index.js +0 -14
  586. package/node_modules/zod/v4/core/json-schema.cjs +0 -2
  587. package/node_modules/zod/v4/core/json-schema.d.cts +0 -88
  588. package/node_modules/zod/v4/core/json-schema.d.ts +0 -88
  589. package/node_modules/zod/v4/core/json-schema.js +0 -1
  590. package/node_modules/zod/v4/core/package.json +0 -6
  591. package/node_modules/zod/v4/core/parse.cjs +0 -131
  592. package/node_modules/zod/v4/core/parse.d.cts +0 -49
  593. package/node_modules/zod/v4/core/parse.d.ts +0 -49
  594. package/node_modules/zod/v4/core/parse.js +0 -93
  595. package/node_modules/zod/v4/core/regexes.cjs +0 -136
  596. package/node_modules/zod/v4/core/regexes.d.cts +0 -78
  597. package/node_modules/zod/v4/core/regexes.d.ts +0 -78
  598. package/node_modules/zod/v4/core/regexes.js +0 -127
  599. package/node_modules/zod/v4/core/registries.cjs +0 -57
  600. package/node_modules/zod/v4/core/registries.d.cts +0 -35
  601. package/node_modules/zod/v4/core/registries.d.ts +0 -35
  602. package/node_modules/zod/v4/core/registries.js +0 -52
  603. package/node_modules/zod/v4/core/schemas.cjs +0 -1986
  604. package/node_modules/zod/v4/core/schemas.d.cts +0 -1113
  605. package/node_modules/zod/v4/core/schemas.d.ts +0 -1113
  606. package/node_modules/zod/v4/core/schemas.js +0 -1955
  607. package/node_modules/zod/v4/core/standard-schema.cjs +0 -2
  608. package/node_modules/zod/v4/core/standard-schema.d.cts +0 -55
  609. package/node_modules/zod/v4/core/standard-schema.d.ts +0 -55
  610. package/node_modules/zod/v4/core/standard-schema.js +0 -1
  611. package/node_modules/zod/v4/core/to-json-schema.cjs +0 -920
  612. package/node_modules/zod/v4/core/to-json-schema.d.cts +0 -90
  613. package/node_modules/zod/v4/core/to-json-schema.d.ts +0 -90
  614. package/node_modules/zod/v4/core/to-json-schema.js +0 -915
  615. package/node_modules/zod/v4/core/util.cjs +0 -658
  616. package/node_modules/zod/v4/core/util.d.cts +0 -197
  617. package/node_modules/zod/v4/core/util.d.ts +0 -197
  618. package/node_modules/zod/v4/core/util.js +0 -601
  619. package/node_modules/zod/v4/core/versions.cjs +0 -8
  620. package/node_modules/zod/v4/core/versions.d.cts +0 -5
  621. package/node_modules/zod/v4/core/versions.d.ts +0 -5
  622. package/node_modules/zod/v4/core/versions.js +0 -5
  623. package/node_modules/zod/v4/index.cjs +0 -22
  624. package/node_modules/zod/v4/index.d.cts +0 -3
  625. package/node_modules/zod/v4/index.d.ts +0 -3
  626. package/node_modules/zod/v4/index.js +0 -3
  627. package/node_modules/zod/v4/locales/ar.cjs +0 -143
  628. package/node_modules/zod/v4/locales/ar.d.cts +0 -5
  629. package/node_modules/zod/v4/locales/ar.d.ts +0 -4
  630. package/node_modules/zod/v4/locales/ar.js +0 -116
  631. package/node_modules/zod/v4/locales/az.cjs +0 -142
  632. package/node_modules/zod/v4/locales/az.d.cts +0 -5
  633. package/node_modules/zod/v4/locales/az.d.ts +0 -4
  634. package/node_modules/zod/v4/locales/az.js +0 -115
  635. package/node_modules/zod/v4/locales/be.cjs +0 -191
  636. package/node_modules/zod/v4/locales/be.d.cts +0 -5
  637. package/node_modules/zod/v4/locales/be.d.ts +0 -4
  638. package/node_modules/zod/v4/locales/be.js +0 -164
  639. package/node_modules/zod/v4/locales/bg.cjs +0 -156
  640. package/node_modules/zod/v4/locales/bg.d.cts +0 -5
  641. package/node_modules/zod/v4/locales/bg.d.ts +0 -5
  642. package/node_modules/zod/v4/locales/bg.js +0 -128
  643. package/node_modules/zod/v4/locales/ca.cjs +0 -145
  644. package/node_modules/zod/v4/locales/ca.d.cts +0 -5
  645. package/node_modules/zod/v4/locales/ca.d.ts +0 -4
  646. package/node_modules/zod/v4/locales/ca.js +0 -118
  647. package/node_modules/zod/v4/locales/cs.cjs +0 -162
  648. package/node_modules/zod/v4/locales/cs.d.cts +0 -5
  649. package/node_modules/zod/v4/locales/cs.d.ts +0 -4
  650. package/node_modules/zod/v4/locales/cs.js +0 -135
  651. package/node_modules/zod/v4/locales/da.cjs +0 -158
  652. package/node_modules/zod/v4/locales/da.d.cts +0 -5
  653. package/node_modules/zod/v4/locales/da.d.ts +0 -4
  654. package/node_modules/zod/v4/locales/da.js +0 -131
  655. package/node_modules/zod/v4/locales/de.cjs +0 -143
  656. package/node_modules/zod/v4/locales/de.d.cts +0 -5
  657. package/node_modules/zod/v4/locales/de.d.ts +0 -4
  658. package/node_modules/zod/v4/locales/de.js +0 -116
  659. package/node_modules/zod/v4/locales/en.cjs +0 -145
  660. package/node_modules/zod/v4/locales/en.d.cts +0 -5
  661. package/node_modules/zod/v4/locales/en.d.ts +0 -5
  662. package/node_modules/zod/v4/locales/en.js +0 -117
  663. package/node_modules/zod/v4/locales/eo.cjs +0 -144
  664. package/node_modules/zod/v4/locales/eo.d.cts +0 -5
  665. package/node_modules/zod/v4/locales/eo.d.ts +0 -5
  666. package/node_modules/zod/v4/locales/eo.js +0 -116
  667. package/node_modules/zod/v4/locales/es.cjs +0 -176
  668. package/node_modules/zod/v4/locales/es.d.cts +0 -5
  669. package/node_modules/zod/v4/locales/es.d.ts +0 -4
  670. package/node_modules/zod/v4/locales/es.js +0 -149
  671. package/node_modules/zod/v4/locales/fa.cjs +0 -149
  672. package/node_modules/zod/v4/locales/fa.d.cts +0 -5
  673. package/node_modules/zod/v4/locales/fa.d.ts +0 -4
  674. package/node_modules/zod/v4/locales/fa.js +0 -122
  675. package/node_modules/zod/v4/locales/fi.cjs +0 -149
  676. package/node_modules/zod/v4/locales/fi.d.cts +0 -5
  677. package/node_modules/zod/v4/locales/fi.d.ts +0 -4
  678. package/node_modules/zod/v4/locales/fi.js +0 -122
  679. package/node_modules/zod/v4/locales/fr-CA.cjs +0 -144
  680. package/node_modules/zod/v4/locales/fr-CA.d.cts +0 -5
  681. package/node_modules/zod/v4/locales/fr-CA.d.ts +0 -4
  682. package/node_modules/zod/v4/locales/fr-CA.js +0 -117
  683. package/node_modules/zod/v4/locales/fr.cjs +0 -143
  684. package/node_modules/zod/v4/locales/fr.d.cts +0 -5
  685. package/node_modules/zod/v4/locales/fr.d.ts +0 -4
  686. package/node_modules/zod/v4/locales/fr.js +0 -116
  687. package/node_modules/zod/v4/locales/he.cjs +0 -144
  688. package/node_modules/zod/v4/locales/he.d.cts +0 -5
  689. package/node_modules/zod/v4/locales/he.d.ts +0 -4
  690. package/node_modules/zod/v4/locales/he.js +0 -117
  691. package/node_modules/zod/v4/locales/hu.cjs +0 -144
  692. package/node_modules/zod/v4/locales/hu.d.cts +0 -5
  693. package/node_modules/zod/v4/locales/hu.d.ts +0 -4
  694. package/node_modules/zod/v4/locales/hu.js +0 -117
  695. package/node_modules/zod/v4/locales/id.cjs +0 -143
  696. package/node_modules/zod/v4/locales/id.d.cts +0 -5
  697. package/node_modules/zod/v4/locales/id.d.ts +0 -4
  698. package/node_modules/zod/v4/locales/id.js +0 -116
  699. package/node_modules/zod/v4/locales/index.cjs +0 -100
  700. package/node_modules/zod/v4/locales/index.d.cts +0 -47
  701. package/node_modules/zod/v4/locales/index.d.ts +0 -47
  702. package/node_modules/zod/v4/locales/index.js +0 -47
  703. package/node_modules/zod/v4/locales/is.cjs +0 -145
  704. package/node_modules/zod/v4/locales/is.d.cts +0 -5
  705. package/node_modules/zod/v4/locales/is.d.ts +0 -5
  706. package/node_modules/zod/v4/locales/is.js +0 -117
  707. package/node_modules/zod/v4/locales/it.cjs +0 -144
  708. package/node_modules/zod/v4/locales/it.d.cts +0 -5
  709. package/node_modules/zod/v4/locales/it.d.ts +0 -4
  710. package/node_modules/zod/v4/locales/it.js +0 -117
  711. package/node_modules/zod/v4/locales/ja.cjs +0 -142
  712. package/node_modules/zod/v4/locales/ja.d.cts +0 -5
  713. package/node_modules/zod/v4/locales/ja.d.ts +0 -4
  714. package/node_modules/zod/v4/locales/ja.js +0 -115
  715. package/node_modules/zod/v4/locales/ka.cjs +0 -153
  716. package/node_modules/zod/v4/locales/ka.d.cts +0 -5
  717. package/node_modules/zod/v4/locales/ka.d.ts +0 -5
  718. package/node_modules/zod/v4/locales/ka.js +0 -125
  719. package/node_modules/zod/v4/locales/kh.cjs +0 -12
  720. package/node_modules/zod/v4/locales/kh.d.cts +0 -5
  721. package/node_modules/zod/v4/locales/kh.d.ts +0 -5
  722. package/node_modules/zod/v4/locales/kh.js +0 -5
  723. package/node_modules/zod/v4/locales/km.cjs +0 -144
  724. package/node_modules/zod/v4/locales/km.d.cts +0 -5
  725. package/node_modules/zod/v4/locales/km.d.ts +0 -4
  726. package/node_modules/zod/v4/locales/km.js +0 -117
  727. package/node_modules/zod/v4/locales/ko.cjs +0 -148
  728. package/node_modules/zod/v4/locales/ko.d.cts +0 -5
  729. package/node_modules/zod/v4/locales/ko.d.ts +0 -4
  730. package/node_modules/zod/v4/locales/ko.js +0 -121
  731. package/node_modules/zod/v4/locales/lt.cjs +0 -258
  732. package/node_modules/zod/v4/locales/lt.d.cts +0 -5
  733. package/node_modules/zod/v4/locales/lt.d.ts +0 -5
  734. package/node_modules/zod/v4/locales/lt.js +0 -230
  735. package/node_modules/zod/v4/locales/mk.cjs +0 -145
  736. package/node_modules/zod/v4/locales/mk.d.cts +0 -5
  737. package/node_modules/zod/v4/locales/mk.d.ts +0 -4
  738. package/node_modules/zod/v4/locales/mk.js +0 -118
  739. package/node_modules/zod/v4/locales/ms.cjs +0 -143
  740. package/node_modules/zod/v4/locales/ms.d.cts +0 -5
  741. package/node_modules/zod/v4/locales/ms.d.ts +0 -4
  742. package/node_modules/zod/v4/locales/ms.js +0 -116
  743. package/node_modules/zod/v4/locales/nl.cjs +0 -144
  744. package/node_modules/zod/v4/locales/nl.d.cts +0 -5
  745. package/node_modules/zod/v4/locales/nl.d.ts +0 -4
  746. package/node_modules/zod/v4/locales/nl.js +0 -117
  747. package/node_modules/zod/v4/locales/no.cjs +0 -143
  748. package/node_modules/zod/v4/locales/no.d.cts +0 -5
  749. package/node_modules/zod/v4/locales/no.d.ts +0 -4
  750. package/node_modules/zod/v4/locales/no.js +0 -116
  751. package/node_modules/zod/v4/locales/ota.cjs +0 -144
  752. package/node_modules/zod/v4/locales/ota.d.cts +0 -5
  753. package/node_modules/zod/v4/locales/ota.d.ts +0 -4
  754. package/node_modules/zod/v4/locales/ota.js +0 -117
  755. package/node_modules/zod/v4/locales/package.json +0 -6
  756. package/node_modules/zod/v4/locales/pl.cjs +0 -144
  757. package/node_modules/zod/v4/locales/pl.d.cts +0 -5
  758. package/node_modules/zod/v4/locales/pl.d.ts +0 -4
  759. package/node_modules/zod/v4/locales/pl.js +0 -117
  760. package/node_modules/zod/v4/locales/ps.cjs +0 -149
  761. package/node_modules/zod/v4/locales/ps.d.cts +0 -5
  762. package/node_modules/zod/v4/locales/ps.d.ts +0 -4
  763. package/node_modules/zod/v4/locales/ps.js +0 -122
  764. package/node_modules/zod/v4/locales/pt.cjs +0 -143
  765. package/node_modules/zod/v4/locales/pt.d.cts +0 -5
  766. package/node_modules/zod/v4/locales/pt.d.ts +0 -4
  767. package/node_modules/zod/v4/locales/pt.js +0 -116
  768. package/node_modules/zod/v4/locales/ru.cjs +0 -191
  769. package/node_modules/zod/v4/locales/ru.d.cts +0 -5
  770. package/node_modules/zod/v4/locales/ru.d.ts +0 -4
  771. package/node_modules/zod/v4/locales/ru.js +0 -164
  772. package/node_modules/zod/v4/locales/sl.cjs +0 -144
  773. package/node_modules/zod/v4/locales/sl.d.cts +0 -5
  774. package/node_modules/zod/v4/locales/sl.d.ts +0 -4
  775. package/node_modules/zod/v4/locales/sl.js +0 -117
  776. package/node_modules/zod/v4/locales/sv.cjs +0 -145
  777. package/node_modules/zod/v4/locales/sv.d.cts +0 -5
  778. package/node_modules/zod/v4/locales/sv.d.ts +0 -4
  779. package/node_modules/zod/v4/locales/sv.js +0 -118
  780. package/node_modules/zod/v4/locales/ta.cjs +0 -144
  781. package/node_modules/zod/v4/locales/ta.d.cts +0 -5
  782. package/node_modules/zod/v4/locales/ta.d.ts +0 -4
  783. package/node_modules/zod/v4/locales/ta.js +0 -117
  784. package/node_modules/zod/v4/locales/th.cjs +0 -144
  785. package/node_modules/zod/v4/locales/th.d.cts +0 -5
  786. package/node_modules/zod/v4/locales/th.d.ts +0 -4
  787. package/node_modules/zod/v4/locales/th.js +0 -117
  788. package/node_modules/zod/v4/locales/tr.cjs +0 -143
  789. package/node_modules/zod/v4/locales/tr.d.cts +0 -5
  790. package/node_modules/zod/v4/locales/tr.d.ts +0 -5
  791. package/node_modules/zod/v4/locales/tr.js +0 -115
  792. package/node_modules/zod/v4/locales/ua.cjs +0 -12
  793. package/node_modules/zod/v4/locales/ua.d.cts +0 -5
  794. package/node_modules/zod/v4/locales/ua.d.ts +0 -5
  795. package/node_modules/zod/v4/locales/ua.js +0 -5
  796. package/node_modules/zod/v4/locales/uk.cjs +0 -144
  797. package/node_modules/zod/v4/locales/uk.d.cts +0 -5
  798. package/node_modules/zod/v4/locales/uk.d.ts +0 -4
  799. package/node_modules/zod/v4/locales/uk.js +0 -117
  800. package/node_modules/zod/v4/locales/ur.cjs +0 -144
  801. package/node_modules/zod/v4/locales/ur.d.cts +0 -5
  802. package/node_modules/zod/v4/locales/ur.d.ts +0 -4
  803. package/node_modules/zod/v4/locales/ur.js +0 -117
  804. package/node_modules/zod/v4/locales/vi.cjs +0 -143
  805. package/node_modules/zod/v4/locales/vi.d.cts +0 -5
  806. package/node_modules/zod/v4/locales/vi.d.ts +0 -4
  807. package/node_modules/zod/v4/locales/vi.js +0 -116
  808. package/node_modules/zod/v4/locales/yo.cjs +0 -142
  809. package/node_modules/zod/v4/locales/yo.d.cts +0 -5
  810. package/node_modules/zod/v4/locales/yo.d.ts +0 -4
  811. package/node_modules/zod/v4/locales/yo.js +0 -115
  812. package/node_modules/zod/v4/locales/zh-CN.cjs +0 -143
  813. package/node_modules/zod/v4/locales/zh-CN.d.cts +0 -5
  814. package/node_modules/zod/v4/locales/zh-CN.d.ts +0 -4
  815. package/node_modules/zod/v4/locales/zh-CN.js +0 -116
  816. package/node_modules/zod/v4/locales/zh-TW.cjs +0 -144
  817. package/node_modules/zod/v4/locales/zh-TW.d.cts +0 -5
  818. package/node_modules/zod/v4/locales/zh-TW.d.ts +0 -4
  819. package/node_modules/zod/v4/locales/zh-TW.js +0 -117
  820. package/node_modules/zod/v4/mini/checks.cjs +0 -34
  821. package/node_modules/zod/v4/mini/checks.d.cts +0 -1
  822. package/node_modules/zod/v4/mini/checks.d.ts +0 -1
  823. package/node_modules/zod/v4/mini/checks.js +0 -1
  824. package/node_modules/zod/v4/mini/coerce.cjs +0 -47
  825. package/node_modules/zod/v4/mini/coerce.d.cts +0 -7
  826. package/node_modules/zod/v4/mini/coerce.d.ts +0 -7
  827. package/node_modules/zod/v4/mini/coerce.js +0 -17
  828. package/node_modules/zod/v4/mini/external.cjs +0 -62
  829. package/node_modules/zod/v4/mini/external.d.cts +0 -11
  830. package/node_modules/zod/v4/mini/external.d.ts +0 -11
  831. package/node_modules/zod/v4/mini/external.js +0 -13
  832. package/node_modules/zod/v4/mini/index.cjs +0 -32
  833. package/node_modules/zod/v4/mini/index.d.cts +0 -3
  834. package/node_modules/zod/v4/mini/index.d.ts +0 -3
  835. package/node_modules/zod/v4/mini/index.js +0 -3
  836. package/node_modules/zod/v4/mini/iso.cjs +0 -60
  837. package/node_modules/zod/v4/mini/iso.d.cts +0 -22
  838. package/node_modules/zod/v4/mini/iso.d.ts +0 -22
  839. package/node_modules/zod/v4/mini/iso.js +0 -30
  840. package/node_modules/zod/v4/mini/package.json +0 -6
  841. package/node_modules/zod/v4/mini/parse.cjs +0 -16
  842. package/node_modules/zod/v4/mini/parse.d.cts +0 -1
  843. package/node_modules/zod/v4/mini/parse.d.ts +0 -1
  844. package/node_modules/zod/v4/mini/parse.js +0 -1
  845. package/node_modules/zod/v4/mini/schemas.cjs +0 -892
  846. package/node_modules/zod/v4/mini/schemas.d.cts +0 -407
  847. package/node_modules/zod/v4/mini/schemas.d.ts +0 -407
  848. package/node_modules/zod/v4/mini/schemas.js +0 -775
  849. package/node_modules/zod/v4/package.json +0 -6
  850. package/node_modules/zod/v4-mini/index.cjs +0 -17
  851. package/node_modules/zod/v4-mini/index.d.cts +0 -1
  852. package/node_modules/zod/v4-mini/index.d.ts +0 -1
  853. package/node_modules/zod/v4-mini/index.js +0 -1
  854. package/node_modules/zod/v4-mini/package.json +0 -6
  855. package/package/cc-switch-sdk/README.md +0 -541
  856. package/package/cc-switch-sdk/dist/constants.d.ts +0 -8
  857. package/package/cc-switch-sdk/dist/constants.js +0 -2
  858. package/package/cc-switch-sdk/dist/errors.d.ts +0 -5
  859. package/package/cc-switch-sdk/dist/errors.js +0 -2
  860. package/package/cc-switch-sdk/dist/index.d.ts +0 -5
  861. package/package/cc-switch-sdk/dist/index.js +0 -2
  862. package/package/cc-switch-sdk/dist/schemas.d.ts +0 -7
  863. package/package/cc-switch-sdk/dist/schemas.js +0 -2
  864. package/package/cc-switch-sdk/dist/sdk.d.ts +0 -59
  865. package/package/cc-switch-sdk/dist/sdk.js +0 -2
  866. package/package/cc-switch-sdk/dist/services/ai-config-service.js +0 -4
  867. package/package/cc-switch-sdk/dist/services/mcp-model.d.ts +0 -16
  868. package/package/cc-switch-sdk/dist/services/mcp-model.js +0 -2
  869. package/package/cc-switch-sdk/dist/services/mcp-service.d.ts +0 -17
  870. package/package/cc-switch-sdk/dist/services/mcp-service.js +0 -2
  871. package/package/cc-switch-sdk/dist/services/skill-model.d.ts +0 -16
  872. package/package/cc-switch-sdk/dist/services/skill-model.js +0 -2
  873. package/package/cc-switch-sdk/dist/services/skill-service.d.ts +0 -16
  874. package/package/cc-switch-sdk/dist/services/skill-service.js +0 -2
  875. package/package/cc-switch-sdk/dist/state.d.ts +0 -3
  876. package/package/cc-switch-sdk/dist/state.js +0 -2
  877. package/package/cc-switch-sdk/dist/types.d.ts +0 -78
  878. package/package/cc-switch-sdk/dist/types.js +0 -1
  879. package/package/cc-switch-sdk/dist/utils/fs.d.ts +0 -10
  880. package/package/cc-switch-sdk/dist/utils/fs.js +0 -3
  881. package/package/cc-switch-sdk/dist/utils/id.d.ts +0 -3
  882. package/package/cc-switch-sdk/dist/utils/id.js +0 -2
  883. package/package/cc-switch-sdk/package.json +0 -31
  884. /package/{node_modules/@cc-switch/sdk/dist/types.js → package/acode/dist/plugin-types.js} +0 -0
@@ -1,2 +1,2 @@
1
- import{randomUUID as a}from"node:crypto";import{ScreenCapture as c}from"./screen-capture.js";import{InputDispatcher as h}from"./input-dispatcher.js";import{ComputerControl as u}from"./computer-control.js";import{SystemBackend as p}from"./system-backend.js";class o{constructor(s,t,e){this.inputDispatcher=null,this.state="active",this.ws=null,this.onFrame=null,this.focusPollTimer=null,this.lastFocusState=null,this.inputChain=Promise.resolve(),this.id=s,this.agentId=t,this.permissions=e,this.screenCapture=new c,this.inputBackend=new p,this.computerControl=new u(this.screenCapture,this.inputBackend)}async init(){const s=await this.screenCapture.listScreens(),t=s[0];return t&&(this.inputDispatcher=new h(this.inputBackend,this.permissions,t),this.inputBackend.setScreenSize(t.width,t.height),this.inputBackend.setActiveScreen(t)),{screens:s}}async switchScreen(s){this.screenCapture.setActiveScreen(s);const t=this.screenCapture.getScreens(),e=s?t.find(i=>i.id===s):t[0];e&&this.inputDispatcher&&(this.inputDispatcher.setScreen(e),this.inputBackend.setScreenSize(e.width,e.height),this.inputBackend.setActiveScreen(e))}startInputBackend(){this.inputBackend.startPersistentProcess()}async enableControl(){this.inputBackend.startPersistentProcess(),this.startFocusPolling(),await this.inputBackend.centerMouse()}stopInputBackend(){this.stopFocusPolling(),this.inputBackend.stopPersistentProcess()}startFocusPolling(){this.stopFocusPolling(),this.focusPollTimer=setInterval(()=>{const s=this.inputBackend.isInputFocused();s!==this.lastFocusState&&(this.lastFocusState=s,this.sendFocusState(s))},o.FOCUS_POLL_INTERVAL_MS)}stopFocusPolling(){this.focusPollTimer&&(clearInterval(this.focusPollTimer),this.focusPollTimer=null),this.lastFocusState=null}sendFocusState(s){!this.ws||this.ws.readyState!==this.ws.OPEN||this.ws.send(JSON.stringify({type:"remote-desktop:focus-state",sessionId:this.id,data:{hasInputFocus:s}}))}attachWebSocket(s){this.ws=s}startFrameLoop(s){this.onFrame=s,this.screenCapture.startLoop(s)}stopFrameLoop(){this.screenCapture.stopLoop(),this.onFrame=null}handleInput(s){if(!this.inputDispatcher)return Promise.resolve();this.screenCapture.requestFrame();const t=this.inputChain.then(async()=>{await this.inputDispatcher.handle(s),this.screenCapture.requestFrame()});return this.inputChain=t.catch(()=>{}),t}close(){this.state="closed",this.stopFocusPolling(),this.stopFrameLoop(),this.inputBackend.stopPersistentProcess(),this.ws=null}}o.FOCUS_POLL_INTERVAL_MS=1e3;class P{constructor(s){this.sessions=new Map,this.agentSessions=new Map,this.permissionManager=s}async createSession(s,t){if(!this.permissionManager.validateToken(t))throw new Error("Invalid token");const e=this.agentSessions.get(s);e&&this.closeSession(e);const i=this.permissionManager.resolvePermissions(t),n=a(),r=new o(n,s,i);return await r.init(),this.sessions.set(n,r),this.agentSessions.set(s,n),{sessionId:n,screens:r.screenCapture.getScreens(),permissions:Array.from(i)}}getSession(s){return this.sessions.get(s)}async handleInput(s,t){const e=this.sessions.get(s);!e||e.state!=="active"||await e.handleInput(t)}closeSession(s){const t=this.sessions.get(s);if(t){t.close(),this.sessions.delete(s);for(const[e,i]of this.agentSessions)if(i===s){this.agentSessions.delete(e);break}}}closeAll(){for(const s of this.sessions.values())s.close();this.sessions.clear(),this.agentSessions.clear()}}export{o as RemoteDesktopSession,P as SessionManager};
1
+ import{randomUUID as a}from"node:crypto";import{ComputerControl as c}from"./computer-control.js";import{InputDispatcher as h}from"./input-dispatcher.js";import{ScreenCapture as u}from"./screen-capture.js";import{SystemBackend as p}from"./system-backend.js";class o{constructor(s,t,e){this.inputDispatcher=null,this.state="active",this.ws=null,this.onFrame=null,this.focusPollTimer=null,this.lastFocusState=null,this.inputChain=Promise.resolve(),this.id=s,this.agentId=t,this.permissions=e,this.screenCapture=new u,this.inputBackend=new p,this.computerControl=new c(this.screenCapture,this.inputBackend)}async init(){const s=await this.screenCapture.listScreens(),t=s[0];return t&&(this.inputDispatcher=new h(this.inputBackend,this.permissions,t),this.inputBackend.setScreenSize(t.width,t.height),this.inputBackend.setActiveScreen(t)),{screens:s}}async switchScreen(s){this.screenCapture.setActiveScreen(s);const t=this.screenCapture.getScreens(),e=s?t.find(i=>i.id===s):t[0];e&&this.inputDispatcher&&(this.inputDispatcher.setScreen(e),this.inputBackend.setScreenSize(e.width,e.height),this.inputBackend.setActiveScreen(e))}startInputBackend(){this.inputBackend.startPersistentProcess()}async enableControl(){this.inputBackend.startPersistentProcess(),this.startFocusPolling(),await this.inputBackend.centerMouse()}stopInputBackend(){this.stopFocusPolling(),this.inputBackend.stopPersistentProcess()}startFocusPolling(){this.stopFocusPolling(),this.focusPollTimer=setInterval(()=>{const s=this.inputBackend.isInputFocused();s!==this.lastFocusState&&(this.lastFocusState=s,this.sendFocusState(s))},o.FOCUS_POLL_INTERVAL_MS)}stopFocusPolling(){this.focusPollTimer&&(clearInterval(this.focusPollTimer),this.focusPollTimer=null),this.lastFocusState=null}sendFocusState(s){!this.ws||this.ws.readyState!==this.ws.OPEN||this.ws.send(JSON.stringify({type:"remote-desktop:focus-state",sessionId:this.id,data:{hasInputFocus:s}}))}attachWebSocket(s){this.ws=s}startFrameLoop(s){this.onFrame=s,this.screenCapture.startLoop(s)}stopFrameLoop(){this.screenCapture.stopLoop(),this.onFrame=null}handleInput(s){if(!this.inputDispatcher)return Promise.resolve();this.screenCapture.requestFrame();const t=this.inputChain.then(async()=>{await this.inputDispatcher.handle(s),this.screenCapture.requestFrame()});return this.inputChain=t.catch(()=>{}),t}close(){this.state="closed",this.stopFocusPolling(),this.stopFrameLoop(),this.inputBackend.stopPersistentProcess(),this.ws=null}}o.FOCUS_POLL_INTERVAL_MS=1e3;class P{constructor(s){this.sessions=new Map,this.agentSessions=new Map,this.permissionManager=s}async createSession(s,t){if(!this.permissionManager.validateToken(t))throw new Error("Invalid token");const e=this.agentSessions.get(s);e&&this.closeSession(e);const i=this.permissionManager.resolvePermissions(t),n=a(),r=new o(n,s,i);return await r.init(),this.sessions.set(n,r),this.agentSessions.set(s,n),{sessionId:n,screens:r.screenCapture.getScreens(),permissions:Array.from(i)}}getSession(s){return this.sessions.get(s)}async handleInput(s,t){const e=this.sessions.get(s);!e||e.state!=="active"||await e.handleInput(t)}closeSession(s){const t=this.sessions.get(s);if(t){t.close(),this.sessions.delete(s);for(const[e,i]of this.agentSessions)if(i===s){this.agentSessions.delete(e);break}}}closeAll(){for(const s of this.sessions.values())s.close();this.sessions.clear(),this.agentSessions.clear()}}export{o as RemoteDesktopSession,P as SessionManager};
2
2
 
@@ -1,5 +1,5 @@
1
- import{spawn as y,exec as P}from"node:child_process";import{promisify as E}from"node:util";import{mapKey as a}from"./input-backends/key-map.js";import{toOsMouseCoords as p}from"./coords.js";import{initWin32Api as S,MOUSEEVENTF_LEFTDOWN as h,MOUSEEVENTF_LEFTUP as u,MOUSEEVENTF_RIGHTDOWN as m,MOUSEEVENTF_RIGHTUP as d,MOUSEEVENTF_WHEEL as k,MOUSEEVENTF_HWHEEL as v,KEYEVENTF_KEYUP as f}from"./win32-api.js";const r=E(P);function g(){return process.platform==="win32"?"windows":process.platform==="darwin"?"macos":"linux"}class l{constructor(s){this.screenSize={width:1920,height:1080},this.activeScreen=null,this.win32Api=null,this.psProcess=null,this.psReady=!1,this.psReadyPromise=null,this.psBuffer="",this.cliclickProcess=null,this.xdotoolProcess=null,this.platform=s??g()}startPersistentProcess(){if(this.platform==="windows"){if(this.win32Api=S(),this.win32Api){console.log("[remote-desktop] Win32 FFI API ready (koffi)");return}console.warn("[remote-desktop] Win32 FFI unavailable, falling back to PowerShell"),this.startPowerShellProcess()}}startPowerShellProcess(){this.psProcess||this.psReadyPromise||(this.psReadyPromise=new Promise(s=>{const e=y("powershell.exe",["-NoProfile","-NoLogo","-Command","-"],{stdio:["pipe","pipe","pipe"],windowsHide:!0});e.stdin?.write(`${l.WIN32_INIT_TYPES}; [W]::SetProcessDPIAware() | Out-Null; Add-Type -AssemblyName System.Windows.Forms; echo "__READY__"
1
+ import{spawn as y,exec as P}from"node:child_process";import{promisify as E}from"node:util";import{toOsMouseCoords as a}from"./coords.js";import{mapKey as p}from"./input-backends/key-map.js";import{initWin32Api as S,MOUSEEVENTF_LEFTDOWN as h,MOUSEEVENTF_LEFTUP as u,MOUSEEVENTF_RIGHTDOWN as m,MOUSEEVENTF_RIGHTUP as d,MOUSEEVENTF_WHEEL as k,MOUSEEVENTF_HWHEEL as v,KEYEVENTF_KEYUP as f}from"./win32-api.js";const r=E(P);function g(){return process.platform==="win32"?"windows":process.platform==="darwin"?"macos":"linux"}class l{constructor(s){this.screenSize={width:1920,height:1080},this.activeScreen=null,this.win32Api=null,this.psProcess=null,this.psReady=!1,this.psReadyPromise=null,this.psBuffer="",this.cliclickProcess=null,this.xdotoolProcess=null,this.platform=s??g()}startPersistentProcess(){if(this.platform==="windows"){if(this.win32Api=S(),this.win32Api){console.log("[remote-desktop] Win32 FFI API ready (koffi)");return}console.warn("[remote-desktop] Win32 FFI unavailable, falling back to PowerShell"),this.startPowerShellProcess()}}startPowerShellProcess(){this.psProcess||this.psReadyPromise||(this.psReadyPromise=new Promise(s=>{const e=y("powershell.exe",["-NoProfile","-NoLogo","-Command","-"],{stdio:["pipe","pipe","pipe"],windowsHide:!0});e.stdin?.write(`${l.WIN32_INIT_TYPES}; [W]::SetProcessDPIAware() | Out-Null; Add-Type -AssemblyName System.Windows.Forms; echo "__READY__"
2
2
  `),e.stdout?.on("data",t=>{this.psBuffer+=t.toString(),this.psBuffer.includes("__READY__")&&(this.psBuffer="",this.psProcess=e,this.psReady=!0,console.log("[remote-desktop] PowerShell persistent process ready"),s(!0))}),e.stderr?.on("data",t=>{console.warn("[remote-desktop] PowerShell stderr:",t.toString())}),e.on("error",t=>{console.error("[remote-desktop] PowerShell process error:",t),this.psProcess=null,this.psReady=!1,this.psReadyPromise=null,s(!1)}),e.on("exit",()=>{this.psProcess=null,this.psReady=!1,this.psReadyPromise=null,s(!1)})}))}async ensurePowerShell(){return this.psProcess?.stdin?.writable&&this.psReady?!0:(this.psReadyPromise||this.startPowerShellProcess(),await this.psReadyPromise??!1)}stopPersistentProcess(){this.psProcess&&(this.psProcess.stdin?.end(),this.psProcess.kill(),this.psProcess=null,this.psReady=!1,this.psReadyPromise=null),this.cliclickProcess&&(this.cliclickProcess.kill(),this.cliclickProcess=null),this.xdotoolProcess&&(this.xdotoolProcess.kill(),this.xdotoolProcess=null)}psCmd(s){if(this.psProcess?.stdin?.writable&&this.psReady){this.psProcess.stdin.write(s+`
3
- `);return}const e=`${l.WIN32_INIT_TYPES}; [W]::SetProcessDPIAware() | Out-Null; Add-Type -AssemblyName System.Windows.Forms; ${s}`,t=Buffer.from(e,"utf16le").toString("base64");r(`powershell.exe -NoProfile -EncodedCommand ${t}`).catch(i=>{console.warn("[remote-desktop] fallback PowerShell command failed:",i.message)})}async moveMouse(s,e){const{x:t,y:i}=p(this.activeScreen,s,e,this.platform);if(this.platform==="windows"){if(this.win32Api){this.win32Api.setCursorPos(t,i);return}this.psCmd(`[W]::SetCursorPos(${t}, ${i})`)}else this.platform==="macos"?r(`cliclick m:${t},${i}`).catch(o=>this.warnInputErr("macOS moveMouse",o)):r(`xdotool mousemove ${t} ${i}`).catch(o=>this.warnInputErr("linux moveMouse",o))}async moveMouseRelative(s,e){if(this.platform==="windows"){if(this.win32Api){const o=this.win32Api.getCursorPos();o?this.win32Api.setCursorPos(o.x+Math.round(s),o.y+Math.round(e)):this.warnInputErr("win32 moveMouseRelative",new Error("getCursorPos returned null"));return}this.psCmd(`[W]::mouse_event(1, ${Math.round(s)}, ${Math.round(e)}, 0, 0)`);return}const{x:t,y:i}=await this.getMousePos();await this.moveMouse(t+s,i+e)}async centerMouse(){this.activeScreen&&await this.moveMouse(this.activeScreen.x+this.activeScreen.width/2,this.activeScreen.y+this.activeScreen.height/2)}async click(s,e,t){const{x:i,y:o}=p(this.activeScreen,s,e,this.platform);if(this.platform==="windows"){if(this.win32Api){const w=t==="right"?m:h,x=t==="right"?d:u;this.win32Api.setCursorPos(i,o),this.win32Api.mouseEvent(w,0,0,0),this.win32Api.mouseEvent(x,0,0,0);return}const n=t==="right"?8:2,c=t==="right"?16:4;this.psCmd(`[W]::SetCursorPos(${i},${o}); [W]::mouse_event(${n},0,0,0,0); [W]::mouse_event(${c},0,0,0,0)`)}else this.platform==="macos"?r(`cliclick ${t==="right"?"rc":"c"}:${i},${o}`).catch(c=>this.warnInputErr("macOS click",c)):r(`xdotool mousemove ${i} ${o} && xdotool click ${t==="right"?3:1}`).catch(c=>this.warnInputErr("linux click",c))}async doubleClick(s,e){const{x:t,y:i}=p(this.activeScreen,s,e,this.platform);if(this.platform==="windows"){if(this.win32Api){this.win32Api.setCursorPos(t,i);for(let o=0;o<2;o++)this.win32Api.mouseEvent(h,0,0,0),this.win32Api.mouseEvent(u,0,0,0);return}this.psCmd(`[W]::SetCursorPos(${t},${i}); [W]::mouse_event(2,0,0,0,0); [W]::mouse_event(4,0,0,0,0); [W]::mouse_event(2,0,0,0,0); [W]::mouse_event(4,0,0,0,0)`)}else this.platform==="macos"?r(`cliclick dd:${t},${i}`).catch(o=>this.warnInputErr("macOS doubleClick",o)):r(`xdotool mousemove ${t} ${i} && xdotool click --repeat 2 1`).catch(o=>this.warnInputErr("linux doubleClick",o))}async mouseDown(s){if(this.platform==="windows"){if(this.win32Api){const t=s==="right"?m:h;this.win32Api.mouseEvent(t,0,0,0);return}const e=s==="right"?8:2;this.psCmd(`[W]::mouse_event(${e},0,0,0,0)`)}else this.platform==="macos"?r(`cliclick ${s==="right"?"rd":"dd"}:`).catch(t=>this.warnInputErr("macOS mouseDown",t)):r(`xdotool mousedown ${s==="right"?3:1}`).catch(t=>this.warnInputErr("linux mouseDown",t))}async mouseUp(s){if(this.platform==="windows"){if(this.win32Api){const t=s==="right"?d:u;this.win32Api.mouseEvent(t,0,0,0);return}const e=s==="right"?16:4;this.psCmd(`[W]::mouse_event(${e},0,0,0,0)`)}else this.platform==="macos"?r(`cliclick ${s==="right"?"ru":"du"}:`).catch(t=>this.warnInputErr("macOS mouseUp",t)):r(`xdotool mouseup ${s==="right"?3:1}`).catch(t=>this.warnInputErr("linux mouseUp",t))}async scroll(s,e){const t=Math.max(1,Math.round(e));if(this.platform==="windows"){const i=s==="left"||s==="right",o=i?v:k,n=i?s==="right"?t*120:-t*120:s==="down"?-t*120:t*120;if(this.win32Api){this.win32Api.mouseEvent(o,0,0,n);return}this.psCmd(`[W]::mouse_event(${o},0,0,${n},0)`)}else this.platform==="macos"?r(`python3 -c "from Quartz import CGEventCreateScrollWheelEvent2, kCGScrollEventUnitPixel; from CoreGraphics import CGEventPost, kCGHIDEventTap; e = CGEventCreateScrollWheelEvent2(None, kCGScrollEventUnitPixel, ${s==="left"||s==="right"?1:0}, ${(s==="down"||s==="right"?-1:1)*t*10}); CGEventPost(kCGHIDEventTap, e)" 2>/dev/null || true`).catch(n=>this.warnInputErr("macOS scroll",n)):r(`xdotool click --repeat ${t} ${s==="up"?4:s==="down"?5:s==="left"?6:7}`).catch(o=>this.warnInputErr("linux scroll",o))}async type(s){if(this.platform==="windows"){const t=`[System.Windows.Forms.SendKeys]::SendWait('${s.replace(/[{}()[\]^%~+]/g,"{$&}").replace(/\n/g,"{ENTER}").replace(/'/g,"''")}')`;if(await this.ensurePowerShell()){this.psProcess?.stdin?.write(t+`
4
- `);return}this.psCmd(t)}else this.platform==="macos"?r(`cliclick t:'${s.replace(/'/g,"'\\''")}'`).catch(e=>this.warnInputErr("macOS type",e)):r(`xdotool type --clearmodifiers '${s.replace(/'/g,"'\\''")}'`).catch(e=>this.warnInputErr("linux type",e))}async keyPress(s){const e=s.map(a);if(this.platform==="windows"){if(this.win32Api){for(const t of e){const i=this.getVirtualKeyCode(t);i&&(this.win32Api.keybdEvent(i,0),await new Promise(o=>setTimeout(o,10)),this.win32Api.keybdEvent(i,f))}return}for(const t of e){const i=this.getVirtualKeyCode(t);i&&this.psCmd(`[W]::keybd_event(${i},0,0,0); Start-Sleep -Milliseconds 10; [W]::keybd_event(${i},0,2,0)`)}}else this.platform==="macos"?r(`cliclick kp:${e.join("+")}`).catch(t=>this.warnInputErr("macOS keyPress",t)):r(`xdotool key '${e.join("+")}'`).catch(t=>this.warnInputErr("linux keyPress",t))}async keyDown(s){const e=a(s);if(this.platform==="windows"){const t=this.getVirtualKeyCode(e);if(!t)return;if(this.win32Api){this.win32Api.keybdEvent(t,0);return}this.psCmd(`[W]::keybd_event(${t},0,0,0)`)}else this.platform==="macos"?r(`cliclick kd:${e}`).catch(t=>this.warnInputErr("macOS keyDown",t)):r(`xdotool keydown ${e}`).catch(t=>this.warnInputErr("linux keyDown",t))}async keyUp(s){const e=a(s);if(this.platform==="windows"){const t=this.getVirtualKeyCode(e);if(!t)return;if(this.win32Api){this.win32Api.keybdEvent(t,f);return}this.psCmd(`[W]::keybd_event(${t},0,2,0)`)}else this.platform==="macos"?r(`cliclick ku:${e}`).catch(t=>this.warnInputErr("macOS keyUp",t)):r(`xdotool keyup ${e}`).catch(t=>this.warnInputErr("linux keyUp",t))}getScreenSize(){return this.screenSize}setScreenSize(s,e){this.screenSize={width:s,height:e}}setActiveScreen(s){this.activeScreen=s,this.screenSize={width:s.width,height:s.height}}async getMousePos(){if(this.platform==="windows"){if(this.win32Api)return this.win32Api.getCursorPos()??{x:0,y:0};const s=`${l.WIN32_INIT_TYPES}; [W]::SetProcessDPIAware() | Out-Null; Add-Type -AssemblyName System.Windows.Forms; $p = [System.Windows.Forms.Cursor]::Position; Write-Output "$($p.X),$($p.Y)"`,e=Buffer.from(s,"utf16le").toString("base64"),{stdout:t}=await r(`powershell.exe -NoProfile -EncodedCommand ${e}`),[i,o]=t.trim().split(",").map(Number);return{x:i||0,y:o||0}}else if(this.platform==="macos"){const{stdout:s}=await r(`osascript -e 'tell application "System Events" to get position of the mouse'`),[e,t]=s.trim().split(",").map(Number);return{x:e||0,y:t||0}}else{const{stdout:s}=await r("xdotool getmouselocation --shell"),e=s.match(/X=(\d+)/),t=s.match(/Y=(\d+)/);return{x:e?Number(e[1]):0,y:t?Number(t[1]):0}}}isInputFocused(){return this.platform!=="windows"||!this.win32Api?!1:this.win32Api.isInputFocused()}warnInputErr(s,e){console.warn(`[remote-desktop] ${s} failed:`,e?.message??String(e))}getVirtualKeyCode(s){return{a:65,b:66,c:67,d:68,e:69,f:70,g:71,h:72,i:73,j:74,k:75,l:76,m:77,n:78,o:79,p:80,q:81,r:82,s:83,t:84,u:85,v:86,w:87,x:88,y:89,z:90,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,enter:13,return:13,tab:9,escape:27,capslock:20,backspace:8,delete:46,up:38,down:40,left:37,right:39,home:36,end:35,pageup:33,pagedown:34,space:32,shift:16,control:17,alt:18,f1:112,f2:113,f3:114,f4:115,f5:116,f6:117,f7:118,f8:119,f9:120,f10:121,f11:122,f12:123}[s.toLowerCase()]||0}}l.WIN32_INIT_TYPES=`Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class W { [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); [DllImport("user32.dll")] public static extern void mouse_event(uint f, int dx, int dy, int c, IntPtr i); [DllImport("user32.dll")] public static extern bool SetCursorPos(int x, int y); [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, IntPtr dwExtraInfo); }'`;export{l as SystemBackend};
3
+ `);return}const e=`${l.WIN32_INIT_TYPES}; [W]::SetProcessDPIAware() | Out-Null; Add-Type -AssemblyName System.Windows.Forms; ${s}`,t=Buffer.from(e,"utf16le").toString("base64");r(`powershell.exe -NoProfile -EncodedCommand ${t}`).catch(i=>{console.warn("[remote-desktop] fallback PowerShell command failed:",i.message)})}async moveMouse(s,e){const{x:t,y:i}=a(this.activeScreen,s,e,this.platform);if(this.platform==="windows"){if(this.win32Api){this.win32Api.setCursorPos(t,i);return}this.psCmd(`[W]::SetCursorPos(${t}, ${i})`)}else this.platform==="macos"?r(`cliclick m:${t},${i}`).catch(o=>this.warnInputErr("macOS moveMouse",o)):r(`xdotool mousemove ${t} ${i}`).catch(o=>this.warnInputErr("linux moveMouse",o))}async moveMouseRelative(s,e){if(this.platform==="windows"){if(this.win32Api){const o=this.win32Api.getCursorPos();o?this.win32Api.setCursorPos(o.x+Math.round(s),o.y+Math.round(e)):this.warnInputErr("win32 moveMouseRelative",new Error("getCursorPos returned null"));return}this.psCmd(`[W]::mouse_event(1, ${Math.round(s)}, ${Math.round(e)}, 0, 0)`);return}const{x:t,y:i}=await this.getMousePos();await this.moveMouse(t+s,i+e)}async centerMouse(){this.activeScreen&&await this.moveMouse(this.activeScreen.x+this.activeScreen.width/2,this.activeScreen.y+this.activeScreen.height/2)}async click(s,e,t){const{x:i,y:o}=a(this.activeScreen,s,e,this.platform);if(this.platform==="windows"){if(this.win32Api){const w=t==="right"?m:h,x=t==="right"?d:u;this.win32Api.setCursorPos(i,o),this.win32Api.mouseEvent(w,0,0,0),this.win32Api.mouseEvent(x,0,0,0);return}const n=t==="right"?8:2,c=t==="right"?16:4;this.psCmd(`[W]::SetCursorPos(${i},${o}); [W]::mouse_event(${n},0,0,0,0); [W]::mouse_event(${c},0,0,0,0)`)}else this.platform==="macos"?r(`cliclick ${t==="right"?"rc":"c"}:${i},${o}`).catch(c=>this.warnInputErr("macOS click",c)):r(`xdotool mousemove ${i} ${o} && xdotool click ${t==="right"?3:1}`).catch(c=>this.warnInputErr("linux click",c))}async doubleClick(s,e){const{x:t,y:i}=a(this.activeScreen,s,e,this.platform);if(this.platform==="windows"){if(this.win32Api){this.win32Api.setCursorPos(t,i);for(let o=0;o<2;o++)this.win32Api.mouseEvent(h,0,0,0),this.win32Api.mouseEvent(u,0,0,0);return}this.psCmd(`[W]::SetCursorPos(${t},${i}); [W]::mouse_event(2,0,0,0,0); [W]::mouse_event(4,0,0,0,0); [W]::mouse_event(2,0,0,0,0); [W]::mouse_event(4,0,0,0,0)`)}else this.platform==="macos"?r(`cliclick dd:${t},${i}`).catch(o=>this.warnInputErr("macOS doubleClick",o)):r(`xdotool mousemove ${t} ${i} && xdotool click --repeat 2 1`).catch(o=>this.warnInputErr("linux doubleClick",o))}async mouseDown(s){if(this.platform==="windows"){if(this.win32Api){const t=s==="right"?m:h;this.win32Api.mouseEvent(t,0,0,0);return}const e=s==="right"?8:2;this.psCmd(`[W]::mouse_event(${e},0,0,0,0)`)}else this.platform==="macos"?r(`cliclick ${s==="right"?"rd":"dd"}:`).catch(t=>this.warnInputErr("macOS mouseDown",t)):r(`xdotool mousedown ${s==="right"?3:1}`).catch(t=>this.warnInputErr("linux mouseDown",t))}async mouseUp(s){if(this.platform==="windows"){if(this.win32Api){const t=s==="right"?d:u;this.win32Api.mouseEvent(t,0,0,0);return}const e=s==="right"?16:4;this.psCmd(`[W]::mouse_event(${e},0,0,0,0)`)}else this.platform==="macos"?r(`cliclick ${s==="right"?"ru":"du"}:`).catch(t=>this.warnInputErr("macOS mouseUp",t)):r(`xdotool mouseup ${s==="right"?3:1}`).catch(t=>this.warnInputErr("linux mouseUp",t))}async scroll(s,e){const t=Math.max(1,Math.round(e));if(this.platform==="windows"){const i=s==="left"||s==="right",o=i?v:k,n=i?s==="right"?t*120:-t*120:s==="down"?-t*120:t*120;if(this.win32Api){this.win32Api.mouseEvent(o,0,0,n);return}this.psCmd(`[W]::mouse_event(${o},0,0,${n},0)`)}else this.platform==="macos"?r(`python3 -c "from Quartz import CGEventCreateScrollWheelEvent2, kCGScrollEventUnitPixel; from CoreGraphics import CGEventPost, kCGHIDEventTap; e = CGEventCreateScrollWheelEvent2(None, kCGScrollEventUnitPixel, ${s==="left"||s==="right"?1:0}, ${(s==="down"||s==="right"?-1:1)*t*10}); CGEventPost(kCGHIDEventTap, e)" 2>/dev/null || true`).catch(n=>this.warnInputErr("macOS scroll",n)):r(`xdotool click --repeat ${t} ${s==="up"?4:s==="down"?5:s==="left"?6:7}`).catch(o=>this.warnInputErr("linux scroll",o))}async type(s){if(this.platform==="windows"){const t=`[System.Windows.Forms.SendKeys]::SendWait('${s.replace(/[{}()[\]^%~+]/g,"{$&}").replace(/\n/g,"{ENTER}").replace(/'/g,"''")}')`;if(await this.ensurePowerShell()){this.psProcess?.stdin?.write(t+`
4
+ `);return}this.psCmd(t)}else this.platform==="macos"?r(`cliclick t:'${s.replace(/'/g,"'\\''")}'`).catch(e=>this.warnInputErr("macOS type",e)):r(`xdotool type --clearmodifiers '${s.replace(/'/g,"'\\''")}'`).catch(e=>this.warnInputErr("linux type",e))}async keyPress(s){const e=s.map(p);if(this.platform==="windows"){if(this.win32Api){for(const t of e){const i=this.getVirtualKeyCode(t);i&&(this.win32Api.keybdEvent(i,0),await new Promise(o=>setTimeout(o,10)),this.win32Api.keybdEvent(i,f))}return}for(const t of e){const i=this.getVirtualKeyCode(t);i&&this.psCmd(`[W]::keybd_event(${i},0,0,0); Start-Sleep -Milliseconds 10; [W]::keybd_event(${i},0,2,0)`)}}else this.platform==="macos"?r(`cliclick kp:${e.join("+")}`).catch(t=>this.warnInputErr("macOS keyPress",t)):r(`xdotool key '${e.join("+")}'`).catch(t=>this.warnInputErr("linux keyPress",t))}async keyDown(s){const e=p(s);if(this.platform==="windows"){const t=this.getVirtualKeyCode(e);if(!t)return;if(this.win32Api){this.win32Api.keybdEvent(t,0);return}this.psCmd(`[W]::keybd_event(${t},0,0,0)`)}else this.platform==="macos"?r(`cliclick kd:${e}`).catch(t=>this.warnInputErr("macOS keyDown",t)):r(`xdotool keydown ${e}`).catch(t=>this.warnInputErr("linux keyDown",t))}async keyUp(s){const e=p(s);if(this.platform==="windows"){const t=this.getVirtualKeyCode(e);if(!t)return;if(this.win32Api){this.win32Api.keybdEvent(t,f);return}this.psCmd(`[W]::keybd_event(${t},0,2,0)`)}else this.platform==="macos"?r(`cliclick ku:${e}`).catch(t=>this.warnInputErr("macOS keyUp",t)):r(`xdotool keyup ${e}`).catch(t=>this.warnInputErr("linux keyUp",t))}getScreenSize(){return this.screenSize}setScreenSize(s,e){this.screenSize={width:s,height:e}}setActiveScreen(s){this.activeScreen=s,this.screenSize={width:s.width,height:s.height}}async getMousePos(){if(this.platform==="windows"){if(this.win32Api)return this.win32Api.getCursorPos()??{x:0,y:0};const s=`${l.WIN32_INIT_TYPES}; [W]::SetProcessDPIAware() | Out-Null; Add-Type -AssemblyName System.Windows.Forms; $p = [System.Windows.Forms.Cursor]::Position; Write-Output "$($p.X),$($p.Y)"`,e=Buffer.from(s,"utf16le").toString("base64"),{stdout:t}=await r(`powershell.exe -NoProfile -EncodedCommand ${e}`),[i,o]=t.trim().split(",").map(Number);return{x:i||0,y:o||0}}else if(this.platform==="macos"){const{stdout:s}=await r(`osascript -e 'tell application "System Events" to get position of the mouse'`),[e,t]=s.trim().split(",").map(Number);return{x:e||0,y:t||0}}else{const{stdout:s}=await r("xdotool getmouselocation --shell"),e=s.match(/X=(\d+)/),t=s.match(/Y=(\d+)/);return{x:e?Number(e[1]):0,y:t?Number(t[1]):0}}}isInputFocused(){return this.platform!=="windows"||!this.win32Api?!1:this.win32Api.isInputFocused()}warnInputErr(s,e){console.warn(`[remote-desktop] ${s} failed:`,e?.message??String(e))}getVirtualKeyCode(s){return{a:65,b:66,c:67,d:68,e:69,f:70,g:71,h:72,i:73,j:74,k:75,l:76,m:77,n:78,o:79,p:80,q:81,r:82,s:83,t:84,u:85,v:86,w:87,x:88,y:89,z:90,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,enter:13,return:13,tab:9,escape:27,capslock:20,backspace:8,delete:46,up:38,down:40,left:37,right:39,home:36,end:35,pageup:33,pagedown:34,space:32,shift:16,control:17,alt:18,f1:112,f2:113,f3:114,f4:115,f5:116,f6:117,f7:118,f8:119,f9:120,f10:121,f11:122,f12:123}[s.toLowerCase()]||0}}l.WIN32_INIT_TYPES=`Add-Type -TypeDefinition 'using System; using System.Runtime.InteropServices; public class W { [DllImport("user32.dll")] public static extern bool SetProcessDPIAware(); [DllImport("user32.dll")] public static extern void mouse_event(uint f, int dx, int dy, int c, IntPtr i); [DllImport("user32.dll")] public static extern bool SetCursorPos(int x, int y); [DllImport("user32.dll")] public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, IntPtr dwExtraInfo); }'`;export{l as SystemBackend};
5
5
 
@@ -1,2 +1,2 @@
1
- import m from"axios";import{Router as U}from"express";import{validateToken as f}from"../middleware/auth.js";import{applyCurrentAiConfigToInstalledTools as $}from"../services/ai-source-apply.js";import{getAiConfigService as k}from"../services/cc-switch-sdk.js";import{detectToolStatuses as z}from"../services/tool-installer.js";import{createLogger as C}from"../utils/logger.js";import{ensureEnabledTools as F}from"../utils/validation.js";const u=C("ai-sources"),g=U();function S(r){if(!r||typeof r!="object"||Array.isArray(r))return[];const o=r,d=Array.isArray(o.data)?o.data:[],e=new Set;for(const a of d){if(!a||typeof a!="object"||Array.isArray(a))continue;const t=String(a.id||"").trim();t&&e.add(t)}return[...e]}async function R(r,o,d){const e=r.replace(/\/+$/,"");if(d==="anthropic-compatible"){const t=`${e.endsWith("/v1")?e.replace(/\/v1$/,""):e}/v1/models`,n=await m.get(t,{headers:{"x-api-key":o,"anthropic-version":"2023-06-01"},timeout:1e4});return S(n.data)}const a=e.endsWith("/v1")?[`${e}/models`]:[`${e}/models`,`${e}/v1/models`];for(const t of a)try{const n=await m.get(t,{headers:{Authorization:`Bearer ${o}`},timeout:1e4}),s=S(n.data);if(s.length>0)return s}catch{}return[]}g.post("/cc-switch/apply-ai-sources",f,async(r,o)=>{const{agentId:d,template:e,ccSwitchEnabledTools:a,acodeTemplateId:t,claudecodeTemplateId:n,codexTemplateId:s,opencodeTemplateId:i,acodeModelEffort:y,claudecodeModelEffort:T,codexModelEffort:A,opencodeModelEffort:b,acodeSubAgentTemplateId:I,acodeSubAgentModel:h,acodeSubAgentModelEffort:M,acode:E,acodeSubAgent:q,claudecode:v,codex:w,opencode:j}=r.body||{};if(!d){o.status(400).json({error:"agentId is required"});return}try{const l=k(),c=F(a),x=await z(c),p=await $({template:e,requestedSources:{acode:E,claudecode:v,codex:w,opencode:j},toolStatus:x,aiConfigService:l});o.json({ok:!0,agentId:String(d),acodeTemplateId:String(t||""),claudecodeTemplateId:String(n||""),codexTemplateId:String(s||""),opencodeTemplateId:String(i||""),acodeModelEffort:String(y||""),claudecodeModelEffort:String(T||""),codexModelEffort:String(A||""),opencodeModelEffort:String(b||""),acodeSubAgentTemplateId:String(I||""),acodeSubAgentModel:String(h||""),acodeSubAgentModelEffort:String(M||""),generatedFromUnifiedTemplate:p.generatedFromUnifiedTemplate,applied:p.applied,skippedTools:p.skippedTools})}catch(l){const c=l;u.error("Failed to apply AI sources",{error:c?.message,agentId:String(d||"")}),o.status(400).json({error:c?.message||"apply ai sources failed"})}}),g.post("/cc-switch/list-ai-models",f,async(r,o)=>{const{baseUrl:d,apiKey:e,protocolType:a}=r.body||{},t=String(d||"").trim(),n=String(e||"").trim();if(!t||!n){o.status(400).json({error:"baseUrl and apiKey are required"});return}try{const s=await R(t,n,a);o.json({ok:!0,models:s})}catch(s){const i=s;u.error("Failed to list remote AI models",{error:i?.message,baseUrl:t}),o.status(400).json({error:i?.message||"list ai models failed"})}});export{g as aiSourcesRouter};
1
+ import m from"axios";import{Router as U}from"express";import{validateToken as f}from"../middleware/auth.js";import{createAiConfigService as $}from"../services/ai-config-service.js";import{applyCurrentAiConfigToInstalledTools as k}from"../services/ai-source-apply.js";import{detectToolStatuses as z}from"../services/tool-installer.js";import{createLogger as C}from"../utils/logger.js";import{ensureEnabledTools as F}from"../utils/validation.js";const u=C("ai-sources"),g=U();function S(r){if(!r||typeof r!="object"||Array.isArray(r))return[];const o=r,d=Array.isArray(o.data)?o.data:[],e=new Set;for(const a of d){if(!a||typeof a!="object"||Array.isArray(a))continue;const t=String(a.id||"").trim();t&&e.add(t)}return[...e]}async function R(r,o,d){const e=r.replace(/\/+$/,"");if(d==="anthropic-compatible"){const t=`${e.endsWith("/v1")?e.replace(/\/v1$/,""):e}/v1/models`,n=await m.get(t,{headers:{"x-api-key":o,"anthropic-version":"2023-06-01"},timeout:1e4});return S(n.data)}const a=e.endsWith("/v1")?[`${e}/models`]:[`${e}/models`,`${e}/v1/models`];for(const t of a)try{const n=await m.get(t,{headers:{Authorization:`Bearer ${o}`},timeout:1e4}),s=S(n.data);if(s.length>0)return s}catch{}return[]}g.post("/cc-switch/apply-ai-sources",f,async(r,o)=>{const{agentId:d,template:e,ccSwitchEnabledTools:a,acodeTemplateId:t,claudecodeTemplateId:n,codexTemplateId:s,opencodeTemplateId:i,acodeModelEffort:y,claudecodeModelEffort:T,codexModelEffort:A,opencodeModelEffort:b,acodeSubAgentTemplateId:I,acodeSubAgentModel:h,acodeSubAgentModelEffort:M,acode:E,acodeSubAgent:q,claudecode:v,codex:w,opencode:j}=r.body||{};if(!d){o.status(400).json({error:"agentId is required"});return}try{const l=$(),c=F(a),x=await z(c),p=await k({template:e,requestedSources:{acode:E,claudecode:v,codex:w,opencode:j},toolStatus:x,aiConfigService:l});o.json({ok:!0,agentId:String(d),acodeTemplateId:String(t||""),claudecodeTemplateId:String(n||""),codexTemplateId:String(s||""),opencodeTemplateId:String(i||""),acodeModelEffort:String(y||""),claudecodeModelEffort:String(T||""),codexModelEffort:String(A||""),opencodeModelEffort:String(b||""),acodeSubAgentTemplateId:String(I||""),acodeSubAgentModel:String(h||""),acodeSubAgentModelEffort:String(M||""),generatedFromUnifiedTemplate:p.generatedFromUnifiedTemplate,applied:p.applied,skippedTools:p.skippedTools})}catch(l){const c=l;u.error("Failed to apply AI sources",{error:c?.message,agentId:String(d||"")}),o.status(400).json({error:c?.message||"apply ai sources failed"})}}),g.post("/cc-switch/list-ai-models",f,async(r,o)=>{const{baseUrl:d,apiKey:e,protocolType:a}=r.body||{},t=String(d||"").trim(),n=String(e||"").trim();if(!t||!n){o.status(400).json({error:"baseUrl and apiKey are required"});return}try{const s=await R(t,n,a);o.json({ok:!0,models:s})}catch(s){const i=s;u.error("Failed to list remote AI models",{error:i?.message,baseUrl:t}),o.status(400).json({error:i?.message||"list ai models failed"})}});export{g as aiSourcesRouter};
2
2
 
@@ -1,4 +1,4 @@
1
- import{promises as y}from"node:fs";import p from"node:path";import{pathToFileURL as b}from"node:url";import{Router as C}from"express";import{getAcodeDataHome as j}from"../config.js";import{validateToken as m}from"../middleware/auth.js";import{createLogger as B}from"../utils/logger.js";import{getReleasedAcodeEntryPath as T}from"../services/acode-package.js";import{getAcodeBgManager as h}from"../services/acode-bg-manager.js";import{listPtySessions as E}from"./pty.js";let f=null;function I(){return f||(f=(async()=>{try{const e=T(),t=p.join(p.dirname(e),"background-command-store.js"),r=await import(b(t).href);return r.BackgroundCommandStore?new r.BackgroundCommandStore:(g.warn("[acode-bg-tasks] BackgroundCommandStore \u4E0D\u53EF\u7528,\u78C1\u76D8\u515C\u5E95\u7981\u7528"),null)}catch(e){return g.warn("[acode-bg-tasks] \u52A0\u8F7D BackgroundCommandStore \u5931\u8D25: %s",e?.message),null}})().then(e=>(e||(f=null),e)),f)}const g=B("acode-bg-tasks"),k=C();function _(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"_")}function L(e){return p.join(j(),"bg-tasks",_(e),"state.json")}k.get("/acode-bg-tasks/:agentId",m,async(e,t)=>{const r=e.params.agentId,i=Array.isArray(r)?r[0]:r;if(!i||!String(i).trim()){t.status(400).json({ok:!1,error:"agentId is required"});return}const d=L(String(i));try{const n=await y.readFile(d,"utf-8"),s=JSON.parse(n),c=(Array.isArray(s.tasks)?s.tasks:[]).map(o=>{const u=o;return{taskId:u.taskId,status:u.status,command:u.commandPreview??u.command,commandPreview:u.commandPreview,cwd:u.cwd,startedAt:u.startedAt,finishedAt:u.finishedAt,exitCode:u.exitCode,signal:u.signal,outputLineCount:u.outputLineCount,outputBytes:u.outputBytes}});t.json({ok:!0,agentId:String(i),updatedAt:typeof s.updatedAt=="number"?s.updatedAt:null,tasks:c})}catch(n){if((typeof n=="object"&&n!==null?Reflect.get(n,"code"):void 0)==="ENOENT"){t.json({ok:!0,agentId:String(i),updatedAt:null,tasks:[]});return}if(n instanceof SyntaxError){g.warn("[acode-bg-tasks] \u6587\u4EF6\u635F\u574F\uFF08JSON \u89E3\u6790\u5931\u8D25\uFF09: %s",d),t.json({ok:!0,agentId:String(i),updatedAt:null,tasks:[]});return}const a=n;g.error("[acode-bg-tasks] \u8BFB\u53D6\u5931\u8D25: %s",a.message),t.status(500).json({ok:!1,error:a.message})}}),k.get("/acode-agent-pty-sessions/:agentId",m,(e,t)=>{const r=e.params.agentId,i=Array.isArray(r)?r[0]:r;if(!i||!String(i).trim()){t.status(400).json({ok:!1,error:"agentId is required"});return}const d=String(i),s=E().filter(a=>a.ownerUserId===d);t.json({ok:!0,agentId:d,sessions:s})});const v=15e3;function S(e){return{taskId:e.taskId,status:e.status,exitCode:e.exitCode,signal:e.signal,startedAt:e.startedAt,finishedAt:e.finishedAt,command:e.command,lines:e.lines,nextSeq:e.nextSeq,totalLines:e.totalLines,totalBytes:e.totalBytes,truncated:e.truncated}}async function x(e,t){let i=null;try{i=await y.open(e,"r")}catch(d){if(d?.code==="ENOENT")return{text:[],fileExists:!1,truncated:!1};throw d}try{const n=(await i.stat()).size;if(n===0)return{text:[],fileExists:!0,truncated:!1};const s=Math.min(n,2097152),a=n-s,c=Buffer.alloc(s);await i.read(c,0,s,a);const u=c.toString("utf-8").split(`
1
+ import{promises as y}from"node:fs";import p from"node:path";import{pathToFileURL as b}from"node:url";import{Router as C}from"express";import{getAcodeDataHome as j}from"../config.js";import{validateToken as m}from"../middleware/auth.js";import{getAcodeBgManager as h}from"../services/acode-bg-manager.js";import{getReleasedAcodeEntryPath as B}from"../services/acode-package.js";import{createLogger as T}from"../utils/logger.js";import{listPtySessions as E}from"./pty.js";let f=null;function I(){return f||(f=(async()=>{try{const e=B(),t=p.join(p.dirname(e),"background-command-store.js"),r=await import(b(t).href);return r.BackgroundCommandStore?new r.BackgroundCommandStore:(g.warn("[acode-bg-tasks] BackgroundCommandStore \u4E0D\u53EF\u7528,\u78C1\u76D8\u515C\u5E95\u7981\u7528"),null)}catch(e){return g.warn("[acode-bg-tasks] \u52A0\u8F7D BackgroundCommandStore \u5931\u8D25: %s",e?.message),null}})().then(e=>(e||(f=null),e)),f)}const g=T("acode-bg-tasks"),k=C();function _(e){return String(e).replace(/[^a-zA-Z0-9_-]/g,"_")}function L(e){return p.join(j(),"bg-tasks",_(e),"state.json")}k.get("/acode-bg-tasks/:agentId",m,async(e,t)=>{const r=e.params.agentId,i=Array.isArray(r)?r[0]:r;if(!i||!String(i).trim()){t.status(400).json({ok:!1,error:"agentId is required"});return}const d=L(String(i));try{const n=await y.readFile(d,"utf-8"),s=JSON.parse(n),c=(Array.isArray(s.tasks)?s.tasks:[]).map(o=>{const u=o;return{taskId:u.taskId,status:u.status,command:u.commandPreview??u.command,commandPreview:u.commandPreview,cwd:u.cwd,startedAt:u.startedAt,finishedAt:u.finishedAt,exitCode:u.exitCode,signal:u.signal,outputLineCount:u.outputLineCount,outputBytes:u.outputBytes}});t.json({ok:!0,agentId:String(i),updatedAt:typeof s.updatedAt=="number"?s.updatedAt:null,tasks:c})}catch(n){if((typeof n=="object"&&n!==null?Reflect.get(n,"code"):void 0)==="ENOENT"){t.json({ok:!0,agentId:String(i),updatedAt:null,tasks:[]});return}if(n instanceof SyntaxError){g.warn("[acode-bg-tasks] \u6587\u4EF6\u635F\u574F\uFF08JSON \u89E3\u6790\u5931\u8D25\uFF09: %s",d),t.json({ok:!0,agentId:String(i),updatedAt:null,tasks:[]});return}const a=n;g.error("[acode-bg-tasks] \u8BFB\u53D6\u5931\u8D25: %s",a.message),t.status(500).json({ok:!1,error:a.message})}}),k.get("/acode-agent-pty-sessions/:agentId",m,(e,t)=>{const r=e.params.agentId,i=Array.isArray(r)?r[0]:r;if(!i||!String(i).trim()){t.status(400).json({ok:!1,error:"agentId is required"});return}const d=String(i),s=E().filter(a=>a.ownerUserId===d);t.json({ok:!0,agentId:d,sessions:s})});const v=15e3;function S(e){return{taskId:e.taskId,status:e.status,exitCode:e.exitCode,signal:e.signal,startedAt:e.startedAt,finishedAt:e.finishedAt,command:e.command,lines:e.lines,nextSeq:e.nextSeq,totalLines:e.totalLines,totalBytes:e.totalBytes,truncated:e.truncated}}async function x(e,t){let i=null;try{i=await y.open(e,"r")}catch(d){if(d?.code==="ENOENT")return{text:[],fileExists:!1,truncated:!1};throw d}try{const n=(await i.stat()).size;if(n===0)return{text:[],fileExists:!0,truncated:!1};const s=Math.min(n,2097152),a=n-s,c=Buffer.alloc(s);await i.read(c,0,s,a);const u=c.toString("utf-8").split(`
2
2
  `);return a>0&&u.shift(),{text:u.slice(-t),fileExists:!0,truncated:s<n}}finally{await i.close()}}k.get("/acode-bg-tasks/:agentId/:taskId/output",m,(e,t)=>{(async()=>{const r=String(e.params.agentId),i=String(e.params.taskId),d=Math.min(2e3,Math.max(100,Number(e.query.tailLines)||500));try{const n=await h();if(n){const s=n.getTaskOutputSnapshot(r,i);if(s){t.json({ok:!0,source:"memory",...S(s)});return}}}catch(n){g.warn("[acode-bg-tasks] \u5185\u5B58\u5FEB\u7167\u8BFB\u53D6\u5931\u8D25,\u964D\u7EA7\u8D70\u78C1\u76D8: %s",n?.message)}try{const n=await I();if(!n){t.status(503).json({ok:!1,error:"store unavailable"});return}const s=await n.readSession(r);if(!s){t.status(404).json({ok:!1,error:"task_not_found"});return}const a=s.tasks.find(l=>l.taskId===i);if(!a){t.status(404).json({ok:!1,error:"task_not_found"});return}const{text:c,fileExists:o,truncated:u}=await x(a.outputPath,d);t.json({ok:!0,source:"file",taskId:a.taskId,status:a.status,exitCode:a.exitCode,signal:a.signal,startedAt:a.startedAt,finishedAt:a.finishedAt,command:a.command,lines:c,nextSeq:0,totalLines:a.outputLineCount,totalBytes:a.outputBytes,truncated:u||!o})}catch(n){g.error("[acode-bg-tasks] \u78C1\u76D8\u515C\u5E95\u8BFB\u53D6\u5931\u8D25: %s",n?.message),t.status(500).json({ok:!1,error:"internal_error"})}})().catch(r=>{g.error("[acode-bg-tasks] output \u8BFB\u53D6\u5931\u8D25: %s",r?.message),t.status(500).json({ok:!1,error:"internal_error"})})}),k.get("/acode-bg-tasks/:agentId/:taskId/stream",m,(e,t)=>{(async()=>{const r=String(e.params.agentId),i=String(e.params.taskId);t.status(200),t.set({"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),t.flushHeaders?.();const d=(a,c)=>{t.writableEnded||t.destroyed||(c!==void 0&&t.write(`id: ${c}
3
3
  `),t.write(`data: ${JSON.stringify(a)}
4
4
 
@@ -1,2 +1,2 @@
1
- import{Router as u}from"express";import{validateToken as p,validateTokenOrLoopback as f}from"../middleware/auth.js";import{createLogger as w}from"../utils/logger.js";import{addBrowserListener as y,listBrowserListeners as k,removeBrowserListener as h,toggleBrowserListener as j,updateBrowserListener as S,collectAgentListenerEvents as v}from"../services/browser-session-manager.js";const g=w("browser-listeners"),m=u();m.get("/browser-listeners/:agentId/events",f,async(s,r)=>{const n=String(s.params.agentId??"").trim();if(!n){r.status(400).json({ok:!1,error:"agentId is required"});return}try{const o=await v(n);r.json({ok:!0,agentId:n,events:o})}catch(o){const e=o;g.error("[browser-listeners] \u6536\u96C6\u4E8B\u4EF6\u5931\u8D25: %s",e.message),r.status(500).json({ok:!1,error:e.message})}}),m.post("/browser-listeners/:agentId/:browserId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim();if(!n||!o){r.status(400).json({ok:!1,error:"agentId and browserId are required"});return}const e=s.body,t=typeof e.selector=="string"?e.selector.trim():"",d=typeof e.prompt=="string"?e.prompt.trim():"";if(!t){r.status(400).json({ok:!1,error:"selector is required"});return}if(!d){r.status(400).json({ok:!1,error:"prompt is required"});return}const c=typeof e.pathPattern=="string"&&e.pathPattern.trim()?e.pathPattern.trim():"",l=typeof e.enabled=="boolean"?e.enabled:!0,I=Array.isArray(e.changeTypes)?e.changeTypes.filter(i=>typeof i=="string"&&(i==="added"||i==="removed"||i==="changed"||i==="exists")):void 0;try{const i=await y(n,o,{selector:t,pathPattern:c,prompt:d,enabled:l,changeTypes:I});r.json({ok:!0,listener:i})}catch(i){const a=i;g.error("[browser-listeners] \u6DFB\u52A0\u5931\u8D25: %s",a.message),r.status(500).json({ok:!1,error:a.message})}}),m.get("/browser-listeners/:agentId/:browserId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim();if(!n||!o){r.status(400).json({ok:!1,error:"agentId and browserId are required"});return}try{const e=await k(n,o);r.json({ok:!0,agentId:n,browserId:o,listeners:e})}catch(e){const t=e;g.error("[browser-listeners] \u5217\u8868\u5931\u8D25: %s",t.message),r.status(500).json({ok:!1,error:t.message})}}),m.patch("/browser-listeners/:agentId/:browserId/:listenerId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim(),e=String(s.params.listenerId??"").trim();if(!n||!o||!e){r.status(400).json({ok:!1,error:"agentId, browserId and listenerId are required"});return}const t=s.body,d=typeof t.enabled=="boolean"?t.enabled:void 0;try{const c=await j(n,o,e,d);if(!c){r.status(404).json({ok:!1,error:`listener ${e} not found`});return}r.json({ok:!0,listener:c})}catch(c){const l=c;g.error("[browser-listeners] \u5207\u6362\u5931\u8D25: %s",l.message),r.status(500).json({ok:!1,error:l.message})}}),m.put("/browser-listeners/:agentId/:browserId/:listenerId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim(),e=String(s.params.listenerId??"").trim();if(!n||!o||!e){r.status(400).json({ok:!1,error:"agentId, browserId and listenerId are required"});return}const t=s.body,d=typeof t.selector=="string"?t.selector.trim():void 0,c=typeof t.prompt=="string"?t.prompt.trim():void 0,l=typeof t.pathPattern=="string"?t.pathPattern:void 0,I=typeof t.enabled=="boolean"?t.enabled:void 0,i=Array.isArray(t.changeTypes)?t.changeTypes.filter(a=>typeof a=="string"&&(a==="added"||a==="removed"||a==="changed"||a==="exists")):void 0;try{const a=await S(n,o,e,{selector:d,pathPattern:l,prompt:c,enabled:I,changeTypes:i});if(!a){r.status(404).json({ok:!1,error:`listener ${e} not found`});return}r.json({ok:!0,listener:a})}catch(a){const b=a;g.error("[browser-listeners] \u66F4\u65B0\u5931\u8D25: %s",b.message),r.status(500).json({ok:!1,error:b.message})}}),m.delete("/browser-listeners/:agentId/:browserId/:listenerId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim(),e=String(s.params.listenerId??"").trim();if(!n||!o||!e){r.status(400).json({ok:!1,error:"agentId, browserId and listenerId are required"});return}try{const t=await h(n,o,e);r.json({ok:t,listenerId:e,removed:t})}catch(t){const d=t;g.error("[browser-listeners] \u5220\u9664\u5931\u8D25: %s",d.message),r.status(500).json({ok:!1,error:d.message})}});export{m as browserListenersRouter};
1
+ import{Router as u}from"express";import{validateToken as p,validateTokenOrLoopback as f}from"../middleware/auth.js";import{addBrowserListener as w,listBrowserListeners as y,removeBrowserListener as k,toggleBrowserListener as h,updateBrowserListener as j,collectAgentListenerEvents as S}from"../services/browser-session-manager.js";import{createLogger as v}from"../utils/logger.js";const g=v("browser-listeners"),m=u();m.get("/browser-listeners/:agentId/events",f,async(s,r)=>{const n=String(s.params.agentId??"").trim();if(!n){r.status(400).json({ok:!1,error:"agentId is required"});return}try{const o=await S(n);r.json({ok:!0,agentId:n,events:o})}catch(o){const e=o;g.error("[browser-listeners] \u6536\u96C6\u4E8B\u4EF6\u5931\u8D25: %s",e.message),r.status(500).json({ok:!1,error:e.message})}}),m.post("/browser-listeners/:agentId/:browserId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim();if(!n||!o){r.status(400).json({ok:!1,error:"agentId and browserId are required"});return}const e=s.body,t=typeof e.selector=="string"?e.selector.trim():"",d=typeof e.prompt=="string"?e.prompt.trim():"";if(!t){r.status(400).json({ok:!1,error:"selector is required"});return}if(!d){r.status(400).json({ok:!1,error:"prompt is required"});return}const c=typeof e.pathPattern=="string"&&e.pathPattern.trim()?e.pathPattern.trim():"",l=typeof e.enabled=="boolean"?e.enabled:!0,I=Array.isArray(e.changeTypes)?e.changeTypes.filter(i=>typeof i=="string"&&(i==="added"||i==="removed"||i==="changed"||i==="exists")):void 0;try{const i=await w(n,o,{selector:t,pathPattern:c,prompt:d,enabled:l,changeTypes:I});r.json({ok:!0,listener:i})}catch(i){const a=i;g.error("[browser-listeners] \u6DFB\u52A0\u5931\u8D25: %s",a.message),r.status(500).json({ok:!1,error:a.message})}}),m.get("/browser-listeners/:agentId/:browserId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim();if(!n||!o){r.status(400).json({ok:!1,error:"agentId and browserId are required"});return}try{const e=await y(n,o);r.json({ok:!0,agentId:n,browserId:o,listeners:e})}catch(e){const t=e;g.error("[browser-listeners] \u5217\u8868\u5931\u8D25: %s",t.message),r.status(500).json({ok:!1,error:t.message})}}),m.patch("/browser-listeners/:agentId/:browserId/:listenerId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim(),e=String(s.params.listenerId??"").trim();if(!n||!o||!e){r.status(400).json({ok:!1,error:"agentId, browserId and listenerId are required"});return}const t=s.body,d=typeof t.enabled=="boolean"?t.enabled:void 0;try{const c=await h(n,o,e,d);if(!c){r.status(404).json({ok:!1,error:`listener ${e} not found`});return}r.json({ok:!0,listener:c})}catch(c){const l=c;g.error("[browser-listeners] \u5207\u6362\u5931\u8D25: %s",l.message),r.status(500).json({ok:!1,error:l.message})}}),m.put("/browser-listeners/:agentId/:browserId/:listenerId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim(),e=String(s.params.listenerId??"").trim();if(!n||!o||!e){r.status(400).json({ok:!1,error:"agentId, browserId and listenerId are required"});return}const t=s.body,d=typeof t.selector=="string"?t.selector.trim():void 0,c=typeof t.prompt=="string"?t.prompt.trim():void 0,l=typeof t.pathPattern=="string"?t.pathPattern:void 0,I=typeof t.enabled=="boolean"?t.enabled:void 0,i=Array.isArray(t.changeTypes)?t.changeTypes.filter(a=>typeof a=="string"&&(a==="added"||a==="removed"||a==="changed"||a==="exists")):void 0;try{const a=await j(n,o,e,{selector:d,pathPattern:l,prompt:c,enabled:I,changeTypes:i});if(!a){r.status(404).json({ok:!1,error:`listener ${e} not found`});return}r.json({ok:!0,listener:a})}catch(a){const b=a;g.error("[browser-listeners] \u66F4\u65B0\u5931\u8D25: %s",b.message),r.status(500).json({ok:!1,error:b.message})}}),m.delete("/browser-listeners/:agentId/:browserId/:listenerId",p,async(s,r)=>{const n=String(s.params.agentId??"").trim(),o=String(s.params.browserId??"").trim(),e=String(s.params.listenerId??"").trim();if(!n||!o||!e){r.status(400).json({ok:!1,error:"agentId, browserId and listenerId are required"});return}try{const t=await k(n,o,e);r.json({ok:t,listenerId:e,removed:t})}catch(t){const d=t;g.error("[browser-listeners] \u5220\u9664\u5931\u8D25: %s",d.message),r.status(500).json({ok:!1,error:d.message})}});export{m as browserListenersRouter};
2
2
 
@@ -0,0 +1,2 @@
1
+ export declare const capabilitiesRouter: import("express-serve-static-core").Router;
2
+ export type CapabilityTypeName = "skills" | "mcp" | "plugins";
@@ -0,0 +1,2 @@
1
+ import{Router as p}from"express";import{validateToken as c}from"../middleware/auth.js";import{getEffective as d,getDefaults as m,getOverrides as u}from"../services/capability-config.js";import{mcpDeployManager as f}from"../services/mcp-deploy.js";import{pluginManager as g}from"../services/plugin-manager.js";import{skillManager as y}from"../services/skill-manager.js";import{createLogger as b}from"../utils/logger.js";const k=b("capabilities"),D=p();function l(i,t,o){const s=u(i,t),r=m(t),a={};for(const e of o){const n=s[e]!==void 0?"agent":r[e]!==void 0?"bridge":"default";a[e]={enabled:d(i,t,e),source:n}}return a}D.post("/capabilities/state",c,async(i,t)=>{const o=String((i.body??{})?.agentId??"").trim();if(!o){t.status(400).json({ok:!1,error:"agentId is required"});return}try{const s=y.listDeployed().map(e=>e.skillName),r=f.listDeployed().map(e=>e.name),a=(await g.listDeployed()).map(e=>e.pluginName);t.json({ok:!0,agentId:o,skills:l(o,"skills",s),mcp:l(o,"mcp",r),plugins:l(o,"plugins",a),deployedSkills:s,deployedMcp:r,deployedPlugins:a})}catch(s){k.warn("[capabilities/state] \u8BFB\u53D6\u80FD\u529B\u72B6\u6001\u5931\u8D25: %s",s.message),t.status(500).json({ok:!1,error:s.message||"read capability state failed"})}});export{D as capabilitiesRouter};
2
+
@@ -1,4 +1,4 @@
1
- import{Router as $}from"express";import v from"node:fs";import K from"node:path";import I from"node:os";import{execFile as Y}from"node:child_process";import{getRuntimeBindingPublicState as H,getRuntimePairingCode as Q,normalizeSchedulerBaseUrl as X}from"../services/runtime-binding.js";import{getAgentProcessManager as C}from"../services/agent-process-manager.js";import{collectSystemMetrics as Z}from"../services/system-metrics.js";import{loadPersistedSessions as ee}from"../services/terminal-persistence.js";import{createLogger as te}from"../utils/logger.js";import{getBridgeVersion as ne,getRuntimeHomeDir as se,getUserHomeDir as re}from"../config.js";import{runExclusiveConfigWrite as O}from"../utils/config-write-queue.js";import{sdkSessions as ae}from"./terminal.js";import{createSession as oe,getPanelCredentials as N,validateSession as U,destroySession as z,validateCredentials as F,hasConfiguredCredentials as B,isDefaultCredentials as ie,setPanelCredentials as de,getAllSessions as le,getActiveSessionCount as ce,checkLoginAllowed as ue,recordLoginFailure as ge,recordLoginSuccess as pe}from"../services/panel-auth.js";import{getRecentLogs as fe}from"../utils/logger.js";import{autoRegister as me,getRegistrationState as _,getAutoRegisterConfigFilePath as E}from"../services/auto-register.js";import{getAccessControlEntries as be,isValidIpEntry as he,parseAllowIps as ve,refreshAccessControlCache as ye}from"../services/access-control.js";const x=te("dashboard");let T=null;const xe=1e4;let L=null,P=null;const we=3e4;async function D(){Z().then(t=>{L={data:t,ts:Date.now()}}).catch(()=>{}),C().discoverAllProcesses().then(t=>{P={data:t,ts:Date.now()}}).catch(()=>{}),C().cleanupStaleRegistry().catch(()=>{})}D(),setInterval(D,we);const V=ne();async function Se(){const t=await import("node:fs/promises"),n=(await import("node:path")).join(se(),".aws-bridge","lifecycle-state.json");try{const s=await t.readFile(n,"utf8"),i=JSON.parse(s),r=Array.isArray(i.operations)?i.operations:[];return r.length===0?null:(r.sort((a,o)=>new Date(o.updatedAt).getTime()-new Date(a.updatedAt).getTime()),r[0]||null)}catch{return null}}const g=$(),J="panel_sid";function Ie(t){const e={};if(!t)return e;for(const n of t.split(";")){const s=n.indexOf("=");if(s===-1)continue;const i=n.slice(0,s).trim(),r=n.slice(s+1).trim();i&&(e[i]=r)}return e}function A(t){return Ie(t.headers.cookie)[J]}function q(t,e,n){const s=t.secure||t.headers["x-forwarded-proto"]==="https";return`${J}=${e}; HttpOnly; SameSite=Lax; Path=/${s?"; Secure":""}; Max-Age=${n}`}function m(t,e){const n=A(t);return n&&U(n)?!0:t.xhr||t.headers.accept?.includes("application/json")?(e.status(401).json({ok:!1,error:"unauthorized",needLogin:!0}),!1):(e.redirect("/login"),!1)}g.post("/runtime/login",(t,e)=>{const n=t.socket.remoteAddress||"unknown",s=ue(n);if(!s.allowed){e.status(429).set("Retry-After",String(s.retryAfterSec)).json({ok:!1,error:"too many failed login attempts, try again later",retryAfterSec:s.retryAfterSec});return}const{username:i,password:r}=t.body||{};if(!i||!r){e.status(400).json({ok:!1,error:"username and password required"});return}if(!F(String(i),String(r))){ge(n),e.status(401).json({ok:!1,error:"invalid credentials"});return}pe(n);const a=oe(),o=!B();e.setHeader("Set-Cookie",q(t,a,86400)),e.json({ok:!0,needSetup:o})}),g.post("/runtime/logout",(t,e)=>{const n=A(t);n&&z(n),e.setHeader("Set-Cookie",q(t,"",0)),e.json({ok:!0})}),g.get("/runtime/credentials-status",(t,e)=>{if(!m(t,e))return;const n=N();e.json({ok:!0,isDefault:ie(),configured:B(),username:n.username})}),g.post("/runtime/change-credentials",async(t,e)=>{if(!m(t,e))return;const{username:n,password:s,passwordConfirm:i,oldPassword:r}=t.body||{};if(s&&String(s).trim()){if(String(s)!==String(i)){e.status(400).json({ok:!1,error:"passwords do not match"});return}if(B()){if(!r){e.status(400).json({ok:!1,error:"old password required"});return}const o=N();if(!F(o.username,String(r))){e.status(403).json({ok:!1,error:"old password is incorrect"});return}}}if(!n||!String(n).trim()){e.status(400).json({ok:!1,error:"username required"});return}const a=s&&String(s).trim()?String(s).trim():N().password;try{await de(String(n).trim(),a),e.json({ok:!0})}catch(o){const l=o;x.error("Failed to change panel credentials:",l.message),e.status(500).json({ok:!1,error:l.message})}});function W(t){const e=typeof t=="string"?t.trim():"";if(e)return e.length<8?"\u2022\u2022\u2022\u2022":"\u2022\u2022\u2022\u2022"+e.slice(-4)}function G(t){const e=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))):[];return e.length>0?e:["serverUrl","schedulerBaseUrl","userKey"].some(s=>!!String(t[s]??"").trim())?[t]:[]}const ke=["enabled","serverUrl","schedulerBaseUrl","tenantId","userKey","connectionKey","password","instanceName","instanceId","projectId","roleName","workspacePath","registerAddr","registerIp","virtualIp","tunnel","preferSameLanIp","maxRetries","retryInterval"];function Ce(t){const e={};for(const n of ke)t[n]!==void 0&&(e[n]=t[n]);return e}function Be(t,e){const n=String(t.connectionKey??"").trim()||String(e??"").trim();return{serverUrl:String(t.serverUrl??t.schedulerBaseUrl??"").trim(),tenantId:String(t.tenantId??"").trim(),instanceName:String(t.instanceName??"").trim(),instanceId:String(t.instanceId??"").trim()||void 0,registerAddr:String(t.registerAddr??"").trim(),tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,userKeyMasked:W(t.userKey),userKeySet:!!String(t.userKey??"").trim(),connectionKeyMasked:W(n),connectionKeySet:!!n}}function R(t){return X(t)??String(t||"").trim()}g.get("/runtime/server-config",(t,e)=>{if(!m(t,e))return;const n=E();let s={};if(v.existsSync(n))try{s=JSON.parse(v.readFileSync(n,"utf-8"))}catch{e.status(500).json({ok:!1,error:"config.json is not valid JSON; fix it manually first"});return}const i=String(s.connectionKey??"").trim()||void 0,r=G(s).map(a=>Be(a,i));e.json({ok:!0,targets:r})});function M(t,e){const n=new Error(e);return n.status=t,n}g.post("/runtime/server-config",async(t,e)=>{if(!m(t,e))return;const n=(t.body||{}).targets;if(!Array.isArray(n)){e.status(400).json({ok:!1,error:"targets array is required"});return}const s=[];for(let r=0;r<n.length;r++){const a=n[r];if(!a||typeof a!="object"||Array.isArray(a)){e.status(400).json({ok:!1,error:`targets[${r}] must be an object`});return}const o=a,l=String(o.serverUrl??o.schedulerBaseUrl??"").trim();if(!l){e.status(400).json({ok:!1,error:`targets[${r}].serverUrl is required`});return}try{const d=new URL(l);if(!["http:","https:"].includes(d.protocol))throw new Error("protocol must be http or https")}catch{e.status(400).json({ok:!1,error:`targets[${r}].serverUrl must be a valid http(s) URL`});return}const f=o.tunnel;let p;if(f==="auto"||f===""||f==null)p=void 0;else if(f===!0||f==="true")p=!0;else if(f===!1||f==="false")p=!1;else{e.status(400).json({ok:!1,error:`targets[${r}].tunnel must be auto, true or false`});return}const h=String(o.originalServerUrl??"").trim();s.push({serverUrl:l,originalServerUrl:h&&h!==l?h:"",userKey:String(o.userKey??"").trim(),tenantId:String(o.tenantId??"").trim(),instanceName:String(o.instanceName??"").trim(),connectionKey:String(o.connectionKey??"").trim(),registerAddr:String(o.registerAddr??"").trim(),tunnel:p})}const i=new Set;for(const r of s){const a=R(r.serverUrl);if(i.has(a)){e.status(400).json({ok:!1,error:"duplicate serverUrl in targets"});return}i.add(a)}try{const r=E();await O(r,()=>{let a={};if(v.existsSync(r))try{a=JSON.parse(v.readFileSync(r,"utf-8"))}catch{throw M(500,"config.json is not valid JSON; fix it manually first")}const o=String(a.connectionKey??"").trim(),l=G(a),f=l.length>0&&l[0]===a,p=new Map(l.map(d=>[R(String(d.serverUrl??d.schedulerBaseUrl??"").trim()),f?Ce(d):d])),h=[];for(const d of s){let b;if(d.originalServerUrl){const w=R(d.originalServerUrl);b=p.get(w),b&&p.delete(w)}if(!b){const w=R(d.serverUrl);b=p.get(w),b&&p.delete(w)}const c=b?{...b}:{};if(c.serverUrl=d.serverUrl,c.tenantId=d.tenantId,c.instanceName=d.instanceName,c.registerAddr=d.registerAddr,d.tunnel===void 0?delete c.tunnel:c.tunnel=d.tunnel,d.userKey)c.userKey=d.userKey;else if(!String(c.userKey??"").trim())throw M(400,`userKey is required for ${d.serverUrl} (new target without inheritable userKey)`);d.connectionKey?c.connectionKey=d.connectionKey:!String(c.connectionKey??"").trim()&&o&&(c.connectionKey=o),h.push(c)}a.autoRegisterTargets=h;for(const d of["enabled","serverUrl","schedulerBaseUrl","tenantId","userKey","connectionKey","password","instanceName","instanceId","registerAddr","registerIp","virtualIp","tunnel"])delete a[d];v.mkdirSync(K.dirname(r),{recursive:!0}),v.writeFileSync(r,JSON.stringify(a,null,2),"utf-8")}),x.info("Server connection config updated via panel",{configPath:r,targetCount:s.length}),e.json({ok:!0})}catch(r){const a=r,o=Number(a.status)||500;o>=500&&x.error("Failed to save server connection config:",a.message),e.status(o).json({ok:!1,error:a.message})}}),g.get("/runtime/access-control",(t,e)=>{m(t,e)&&e.json({ok:!0,allowIps:be(),defaultAllowIps:["0.0.0.0"]})}),g.post("/runtime/access-control",async(t,e)=>{if(!m(t,e))return;const n=(t.body||{}).allowIps;if(typeof n!="string"&&!Array.isArray(n)){e.status(400).json({ok:!1,error:"allowIps must be a string or an array"});return}const s=ve(n),i=s.filter(r=>!he(r));if(i.length>0){e.status(400).json({ok:!1,error:`invalid IP/CIDR entries: ${i.join(", ")}`});return}try{const r=E();await O(r,()=>{let a={};if(v.existsSync(r))try{a=JSON.parse(v.readFileSync(r,"utf-8"))}catch{throw M(500,"config.json is not valid JSON; fix it manually first")}const o=a.accessControl&&typeof a.accessControl=="object"&&!Array.isArray(a.accessControl)?{...a.accessControl}:{};o.allowIps=s,a.accessControl=o,v.mkdirSync(K.dirname(r),{recursive:!0}),v.writeFileSync(r,JSON.stringify(a,null,2),"utf-8"),ye()}),x.info("Access control config updated via panel",{configPath:r,entryCount:s.length}),e.json({ok:!0,allowIps:s})}catch(r){const a=r,o=Number(a.status)||500;o>=500&&x.error("Failed to save access control config:",a.message),e.status(o).json({ok:!1,error:a.message})}}),g.get("/runtime/node-info",(t,e)=>{if(!m(t,e))return;const n=H(),s=_();e.json({ok:!0,hostname:I.hostname(),platform:I.platform(),arch:I.arch(),uptime:Math.floor(process.uptime()),nodeVersion:process.version,bridgeVersion:V,configPath:E(),homeDir:re(),bindingStatus:n.status,paired:n.paired,instanceId:n.instanceId||s.instanceId,schedulerBaseUrl:n.schedulerBaseUrl,registered:s.registered,pairingCode:n.pairingCode,activeSessions:ce()})}),g.get("/runtime/logs",(t,e)=>{if(!m(t,e))return;const n=t.query.level||void 0,s=Math.min(Number(t.query.count)||200,500),r=n&&["debug","info","warn","error"].includes(n)?n:void 0,a=fe(s,r);e.json({ok:!0,logs:a})}),g.post("/runtime/re-register",async(t,e)=>{if(m(t,e))try{const n=await me();e.json({ok:n})}catch(n){const s=n;e.status(500).json({ok:!1,error:s.message})}}),g.get("/runtime/admin/sessions",(t,e)=>{if(!m(t,e))return;const n=le().map(s=>({token:s.token.slice(0,8)+"...",createdAt:new Date(s.createdAt).toISOString(),lastUsedAt:new Date(s.lastUsedAt).toISOString(),age:Math.floor((Date.now()-s.createdAt)/1e3)}));e.json({ok:!0,sessions:n})}),g.post("/runtime/admin/sessions/:token/destroy",(t,e)=>{m(t,e)&&(z(t.params.token),e.json({ok:!0}))});function Ee(t){return new Promise((e,n)=>{const s=I.platform()==="win32",i=s?"taskkill":"kill",r=s?["/PID",String(t),"/F"]:["-9",String(t)];Y(i,r,{timeout:5e3},a=>a?n(a):e())})}g.post("/runtime/kill-process",async(t,e)=>{if(!m(t,e))return;const n=Number(t.body.pid);if(!n||!Number.isInteger(n)||n<=0){e.status(400).json({ok:!1,error:"Invalid PID"});return}const s=C(),i=()=>{const a=new Set,o=P?.data??[];for(const l of o)typeof l.pid=="number"&&a.add(l.pid);for(const l of s.getAllManagedProcesses())typeof l.pid=="number"&&a.add(l.pid);return a};let r=i();if(r.size===0)try{P={data:await s.discoverAllProcesses(),ts:Date.now()},r=i()}catch{}if(!r.has(n)){x.warn("Rejected kill-process for unrecognized PID",{pid:n}),e.status(404).json({ok:!1,error:"PID is not a bridge-discovered or registered agent process"});return}try{await Ee(n),x.info("Killed process",{pid:n}),e.json({ok:!0})}catch(a){const o=a;x.warn("Failed to kill process",{pid:n,error:o.message}),e.status(500).json({ok:!1,error:o.message})}}),g.get("/runtime/dashboard",async(t,e)=>{if(m(t,e)){if(T&&Date.now()-T.ts<xe)return void e.json(T.data);try{const n=L?.data??null,s=P?.data??null;L||D();const[i,r,a]=await Promise.all([Promise.resolve(H()),Promise.resolve(_()),ee().catch(()=>[])]),l=C().getAllManagedProcesses(),f=Array.from(ae.entries()).map(([S,y])=>({sessionId:S,agentId:y.agentId,workspacePath:y.workspacePath,runtimeStatus:y.currentRuntimeStatus||"running",runtimeActionType:y.currentRuntimeActionType,runtimeActionLabel:y.currentRuntimeActionLabel,providerId:y.providerId}));let p={managed:0,orphan:0,unknown:0},h=[];if(s){p={managed:s.filter(u=>u.managementStatus==="managed").length,orphan:s.filter(u=>u.managementStatus==="orphan").length,unknown:s.filter(u=>u.managementStatus==="unknown").length};const S=new Map(l.map(u=>[u.pid,u]));h=s.map(u=>{const k=S.get(u.pid);return{agentId:u.agentId||k?.agentId,pid:u.pid,managementStatus:u.managementStatus,sessionId:k?.sessionId,state:k?.state,command:u.command,cwd:u.cwd,startedAt:u.startedAt}});const y={managed:0,orphan:1,unknown:2};h.sort((u,k)=>(y[u.managementStatus]??9)-(y[k.managementStatus]??9))}const d=new Set(f.map(S=>S.sessionId)),b=a.filter(S=>!d.has(S.sessionId)),c=i,w=await Se(),j={ok:!0,collectedAt:new Date().toISOString(),bridge:{version:V,hostname:I.hostname(),platform:I.platform(),arch:I.arch(),uptime:Math.floor(process.uptime()),nodeVersion:process.version},binding:{status:c.status,paired:c.paired,instanceId:c.instanceId,userId:c.userId,schedulerBaseUrl:c.schedulerBaseUrl,pairingCode:Q()},registration:{registered:r.registered,instanceId:r.instanceId,lastAttempt:r.lastAttempt?.toISOString(),error:r.error},metrics:n,sessions:{active:f,activeCount:f.length,persisted:b,persistedCount:b.length,total:f.length+b.length},processes:{...p,total:p.managed+p.orphan+p.unknown,list:h,registryCount:l.length},lifecycleOperation:w};T={data:j,ts:Date.now()},e.json(j)}catch(n){const s=n;x.error("Dashboard aggregation failed:",s.message),e.status(500).json({ok:!1,error:s.message})}}}),g.get("/login",(t,e)=>{e.type("text/html; charset=utf-8"),e.send(Pe)}),g.get("/",(t,e)=>{const n=A(t);if(!n||!U(n)){e.redirect("/login");return}if(!B()){e.redirect("/setup");return}const s=t.query.lang==="en"?"en":"zh";e.type("text/html; charset=utf-8"),e.send(Te.replace("{{LANG}}",s))}),g.get("/setup",(t,e)=>{const n=A(t);if(!n||!U(n)){e.redirect("/login");return}e.type("text/html; charset=utf-8"),e.send(Ae)});const Te=`<!DOCTYPE html>
1
+ import{execFile as $}from"node:child_process";import v from"node:fs";import I from"node:os";import K from"node:path";import{Router as Y}from"express";import{getBridgeVersion as Q,getRuntimeHomeDir as X,getUserHomeDir as Z}from"../config.js";import{getAccessControlEntries as ee,isValidIpEntry as te,parseAllowIps as ne,refreshAccessControlCache as se}from"../services/access-control.js";import{getAgentProcessManager as C}from"../services/agent-process-manager.js";import{autoRegister as re,getRegistrationState as H,getAutoRegisterConfigFilePath as B}from"../services/auto-register.js";import{createSession as ae,getPanelCredentials as N,validateSession as U,destroySession as O,validateCredentials as z,hasConfiguredCredentials as E,isDefaultCredentials as oe,setPanelCredentials as ie,getAllSessions as de,getActiveSessionCount as le,checkLoginAllowed as ce,recordLoginFailure as ue,recordLoginSuccess as ge}from"../services/panel-auth.js";import{getRuntimeBindingPublicState as F,getRuntimePairingCode as pe,normalizeSchedulerBaseUrl as fe}from"../services/runtime-binding.js";import{collectSystemMetrics as me}from"../services/system-metrics.js";import{loadPersistedSessions as be}from"../services/terminal-persistence.js";import{runExclusiveConfigWrite as _}from"../utils/config-write-queue.js";import{createLogger as he,getRecentLogs as ve}from"../utils/logger.js";import{sdkSessions as ye}from"./terminal.js";const x=he("dashboard");let T=null;const xe=1e4;let L=null,P=null;const we=3e4;async function D(){me().then(t=>{L={data:t,ts:Date.now()}}).catch(()=>{}),C().discoverAllProcesses().then(t=>{P={data:t,ts:Date.now()}}).catch(()=>{}),C().cleanupStaleRegistry().catch(()=>{})}D(),setInterval(D,we);const V=Q();async function Se(){const t=await import("node:fs/promises"),n=(await import("node:path")).join(X(),".aws-bridge","lifecycle-state.json");try{const s=await t.readFile(n,"utf8"),i=JSON.parse(s),r=Array.isArray(i.operations)?i.operations:[];return r.length===0?null:(r.sort((a,o)=>new Date(o.updatedAt).getTime()-new Date(a.updatedAt).getTime()),r[0]||null)}catch{return null}}const g=Y(),J="panel_sid";function Ie(t){const e={};if(!t)return e;for(const n of t.split(";")){const s=n.indexOf("=");if(s===-1)continue;const i=n.slice(0,s).trim(),r=n.slice(s+1).trim();i&&(e[i]=r)}return e}function A(t){return Ie(t.headers.cookie)[J]}function q(t,e,n){const s=t.secure||t.headers["x-forwarded-proto"]==="https";return`${J}=${e}; HttpOnly; SameSite=Lax; Path=/${s?"; Secure":""}; Max-Age=${n}`}function m(t,e){const n=A(t);return n&&U(n)?!0:t.xhr||t.headers.accept?.includes("application/json")?(e.status(401).json({ok:!1,error:"unauthorized",needLogin:!0}),!1):(e.redirect("/login"),!1)}g.post("/runtime/login",(t,e)=>{const n=t.socket.remoteAddress||"unknown",s=ce(n);if(!s.allowed){e.status(429).set("Retry-After",String(s.retryAfterSec)).json({ok:!1,error:"too many failed login attempts, try again later",retryAfterSec:s.retryAfterSec});return}const{username:i,password:r}=t.body||{};if(!i||!r){e.status(400).json({ok:!1,error:"username and password required"});return}if(!z(String(i),String(r))){ue(n),e.status(401).json({ok:!1,error:"invalid credentials"});return}ge(n);const a=ae(),o=!E();e.setHeader("Set-Cookie",q(t,a,86400)),e.json({ok:!0,needSetup:o})}),g.post("/runtime/logout",(t,e)=>{const n=A(t);n&&O(n),e.setHeader("Set-Cookie",q(t,"",0)),e.json({ok:!0})}),g.get("/runtime/credentials-status",(t,e)=>{if(!m(t,e))return;const n=N();e.json({ok:!0,isDefault:oe(),configured:E(),username:n.username})}),g.post("/runtime/change-credentials",async(t,e)=>{if(!m(t,e))return;const{username:n,password:s,passwordConfirm:i,oldPassword:r}=t.body||{};if(s&&String(s).trim()){if(String(s)!==String(i)){e.status(400).json({ok:!1,error:"passwords do not match"});return}if(E()){if(!r){e.status(400).json({ok:!1,error:"old password required"});return}const o=N();if(!z(o.username,String(r))){e.status(403).json({ok:!1,error:"old password is incorrect"});return}}}if(!n||!String(n).trim()){e.status(400).json({ok:!1,error:"username required"});return}const a=s&&String(s).trim()?String(s).trim():N().password;try{await ie(String(n).trim(),a),e.json({ok:!0})}catch(o){const l=o;x.error("Failed to change panel credentials:",l.message),e.status(500).json({ok:!1,error:l.message})}});function W(t){const e=typeof t=="string"?t.trim():"";if(e)return e.length<8?"\u2022\u2022\u2022\u2022":"\u2022\u2022\u2022\u2022"+e.slice(-4)}function G(t){const e=Array.isArray(t.autoRegisterTargets)?t.autoRegisterTargets.filter(s=>!!(s&&typeof s=="object"&&!Array.isArray(s))):[];return e.length>0?e:["serverUrl","schedulerBaseUrl","userKey"].some(s=>!!String(t[s]??"").trim())?[t]:[]}const ke=["enabled","serverUrl","schedulerBaseUrl","tenantId","userKey","connectionKey","password","instanceName","instanceId","projectId","roleName","workspacePath","registerAddr","registerIp","virtualIp","tunnel","preferSameLanIp","maxRetries","retryInterval"];function Ce(t){const e={};for(const n of ke)t[n]!==void 0&&(e[n]=t[n]);return e}function Be(t,e){const n=String(t.connectionKey??"").trim()||String(e??"").trim();return{serverUrl:String(t.serverUrl??t.schedulerBaseUrl??"").trim(),tenantId:String(t.tenantId??"").trim(),instanceName:String(t.instanceName??"").trim(),instanceId:String(t.instanceId??"").trim()||void 0,registerAddr:String(t.registerAddr??"").trim(),tunnel:typeof t.tunnel=="boolean"?t.tunnel:void 0,userKeyMasked:W(t.userKey),userKeySet:!!String(t.userKey??"").trim(),connectionKeyMasked:W(n),connectionKeySet:!!n}}function R(t){return fe(t)??String(t||"").trim()}g.get("/runtime/server-config",(t,e)=>{if(!m(t,e))return;const n=B();let s={};if(v.existsSync(n))try{s=JSON.parse(v.readFileSync(n,"utf-8"))}catch{e.status(500).json({ok:!1,error:"config.json is not valid JSON; fix it manually first"});return}const i=String(s.connectionKey??"").trim()||void 0,r=G(s).map(a=>Be(a,i));e.json({ok:!0,targets:r})});function M(t,e){const n=new Error(e);return n.status=t,n}g.post("/runtime/server-config",async(t,e)=>{if(!m(t,e))return;const n=(t.body||{}).targets;if(!Array.isArray(n)){e.status(400).json({ok:!1,error:"targets array is required"});return}const s=[];for(let r=0;r<n.length;r++){const a=n[r];if(!a||typeof a!="object"||Array.isArray(a)){e.status(400).json({ok:!1,error:`targets[${r}] must be an object`});return}const o=a,l=String(o.serverUrl??o.schedulerBaseUrl??"").trim();if(!l){e.status(400).json({ok:!1,error:`targets[${r}].serverUrl is required`});return}try{const d=new URL(l);if(!["http:","https:"].includes(d.protocol))throw new Error("protocol must be http or https")}catch{e.status(400).json({ok:!1,error:`targets[${r}].serverUrl must be a valid http(s) URL`});return}const f=o.tunnel;let p;if(f==="auto"||f===""||f==null)p=void 0;else if(f===!0||f==="true")p=!0;else if(f===!1||f==="false")p=!1;else{e.status(400).json({ok:!1,error:`targets[${r}].tunnel must be auto, true or false`});return}const h=String(o.originalServerUrl??"").trim();s.push({serverUrl:l,originalServerUrl:h&&h!==l?h:"",userKey:String(o.userKey??"").trim(),tenantId:String(o.tenantId??"").trim(),instanceName:String(o.instanceName??"").trim(),connectionKey:String(o.connectionKey??"").trim(),registerAddr:String(o.registerAddr??"").trim(),tunnel:p})}const i=new Set;for(const r of s){const a=R(r.serverUrl);if(i.has(a)){e.status(400).json({ok:!1,error:"duplicate serverUrl in targets"});return}i.add(a)}try{const r=B();await _(r,()=>{let a={};if(v.existsSync(r))try{a=JSON.parse(v.readFileSync(r,"utf-8"))}catch{throw M(500,"config.json is not valid JSON; fix it manually first")}const o=String(a.connectionKey??"").trim(),l=G(a),f=l.length>0&&l[0]===a,p=new Map(l.map(d=>[R(String(d.serverUrl??d.schedulerBaseUrl??"").trim()),f?Ce(d):d])),h=[];for(const d of s){let b;if(d.originalServerUrl){const w=R(d.originalServerUrl);b=p.get(w),b&&p.delete(w)}if(!b){const w=R(d.serverUrl);b=p.get(w),b&&p.delete(w)}const c=b?{...b}:{};if(c.serverUrl=d.serverUrl,c.tenantId=d.tenantId,c.instanceName=d.instanceName,c.registerAddr=d.registerAddr,d.tunnel===void 0?delete c.tunnel:c.tunnel=d.tunnel,d.userKey)c.userKey=d.userKey;else if(!String(c.userKey??"").trim())throw M(400,`userKey is required for ${d.serverUrl} (new target without inheritable userKey)`);d.connectionKey?c.connectionKey=d.connectionKey:!String(c.connectionKey??"").trim()&&o&&(c.connectionKey=o),h.push(c)}a.autoRegisterTargets=h;for(const d of["enabled","serverUrl","schedulerBaseUrl","tenantId","userKey","connectionKey","password","instanceName","instanceId","registerAddr","registerIp","virtualIp","tunnel"])delete a[d];v.mkdirSync(K.dirname(r),{recursive:!0}),v.writeFileSync(r,JSON.stringify(a,null,2),"utf-8")}),x.info("Server connection config updated via panel",{configPath:r,targetCount:s.length}),e.json({ok:!0})}catch(r){const a=r,o=Number(a.status)||500;o>=500&&x.error("Failed to save server connection config:",a.message),e.status(o).json({ok:!1,error:a.message})}}),g.get("/runtime/access-control",(t,e)=>{m(t,e)&&e.json({ok:!0,allowIps:ee(),defaultAllowIps:["0.0.0.0"]})}),g.post("/runtime/access-control",async(t,e)=>{if(!m(t,e))return;const n=(t.body||{}).allowIps;if(typeof n!="string"&&!Array.isArray(n)){e.status(400).json({ok:!1,error:"allowIps must be a string or an array"});return}const s=ne(n),i=s.filter(r=>!te(r));if(i.length>0){e.status(400).json({ok:!1,error:`invalid IP/CIDR entries: ${i.join(", ")}`});return}try{const r=B();await _(r,()=>{let a={};if(v.existsSync(r))try{a=JSON.parse(v.readFileSync(r,"utf-8"))}catch{throw M(500,"config.json is not valid JSON; fix it manually first")}const o=a.accessControl&&typeof a.accessControl=="object"&&!Array.isArray(a.accessControl)?{...a.accessControl}:{};o.allowIps=s,a.accessControl=o,v.mkdirSync(K.dirname(r),{recursive:!0}),v.writeFileSync(r,JSON.stringify(a,null,2),"utf-8"),se()}),x.info("Access control config updated via panel",{configPath:r,entryCount:s.length}),e.json({ok:!0,allowIps:s})}catch(r){const a=r,o=Number(a.status)||500;o>=500&&x.error("Failed to save access control config:",a.message),e.status(o).json({ok:!1,error:a.message})}}),g.get("/runtime/node-info",(t,e)=>{if(!m(t,e))return;const n=F(),s=H();e.json({ok:!0,hostname:I.hostname(),platform:I.platform(),arch:I.arch(),uptime:Math.floor(process.uptime()),nodeVersion:process.version,bridgeVersion:V,configPath:B(),homeDir:Z(),bindingStatus:n.status,paired:n.paired,instanceId:n.instanceId||s.instanceId,schedulerBaseUrl:n.schedulerBaseUrl,registered:s.registered,pairingCode:n.pairingCode,activeSessions:le()})}),g.get("/runtime/logs",(t,e)=>{if(!m(t,e))return;const n=t.query.level||void 0,s=Math.min(Number(t.query.count)||200,500),r=n&&["debug","info","warn","error"].includes(n)?n:void 0,a=ve(s,r);e.json({ok:!0,logs:a})}),g.post("/runtime/re-register",async(t,e)=>{if(m(t,e))try{const n=await re();e.json({ok:n})}catch(n){const s=n;e.status(500).json({ok:!1,error:s.message})}}),g.get("/runtime/admin/sessions",(t,e)=>{if(!m(t,e))return;const n=de().map(s=>({token:s.token.slice(0,8)+"...",createdAt:new Date(s.createdAt).toISOString(),lastUsedAt:new Date(s.lastUsedAt).toISOString(),age:Math.floor((Date.now()-s.createdAt)/1e3)}));e.json({ok:!0,sessions:n})}),g.post("/runtime/admin/sessions/:token/destroy",(t,e)=>{m(t,e)&&(O(t.params.token),e.json({ok:!0}))});function Ee(t){return new Promise((e,n)=>{const s=I.platform()==="win32",i=s?"taskkill":"kill",r=s?["/PID",String(t),"/F"]:["-9",String(t)];$(i,r,{timeout:5e3},a=>a?n(a):e())})}g.post("/runtime/kill-process",async(t,e)=>{if(!m(t,e))return;const n=Number(t.body.pid);if(!n||!Number.isInteger(n)||n<=0){e.status(400).json({ok:!1,error:"Invalid PID"});return}const s=C(),i=()=>{const a=new Set,o=P?.data??[];for(const l of o)typeof l.pid=="number"&&a.add(l.pid);for(const l of s.getAllManagedProcesses())typeof l.pid=="number"&&a.add(l.pid);return a};let r=i();if(r.size===0)try{P={data:await s.discoverAllProcesses(),ts:Date.now()},r=i()}catch{}if(!r.has(n)){x.warn("Rejected kill-process for unrecognized PID",{pid:n}),e.status(404).json({ok:!1,error:"PID is not a bridge-discovered or registered agent process"});return}try{await Ee(n),x.info("Killed process",{pid:n}),e.json({ok:!0})}catch(a){const o=a;x.warn("Failed to kill process",{pid:n,error:o.message}),e.status(500).json({ok:!1,error:o.message})}}),g.get("/runtime/dashboard",async(t,e)=>{if(m(t,e)){if(T&&Date.now()-T.ts<xe)return void e.json(T.data);try{const n=L?.data??null,s=P?.data??null;L||D();const[i,r,a]=await Promise.all([Promise.resolve(F()),Promise.resolve(H()),be().catch(()=>[])]),l=C().getAllManagedProcesses(),f=Array.from(ye.entries()).map(([S,y])=>({sessionId:S,agentId:y.agentId,workspacePath:y.workspacePath,runtimeStatus:y.currentRuntimeStatus||"running",runtimeActionType:y.currentRuntimeActionType,runtimeActionLabel:y.currentRuntimeActionLabel,providerId:y.providerId}));let p={managed:0,orphan:0,unknown:0},h=[];if(s){p={managed:s.filter(u=>u.managementStatus==="managed").length,orphan:s.filter(u=>u.managementStatus==="orphan").length,unknown:s.filter(u=>u.managementStatus==="unknown").length};const S=new Map(l.map(u=>[u.pid,u]));h=s.map(u=>{const k=S.get(u.pid);return{agentId:u.agentId||k?.agentId,pid:u.pid,managementStatus:u.managementStatus,sessionId:k?.sessionId,state:k?.state,command:u.command,cwd:u.cwd,startedAt:u.startedAt}});const y={managed:0,orphan:1,unknown:2};h.sort((u,k)=>(y[u.managementStatus]??9)-(y[k.managementStatus]??9))}const d=new Set(f.map(S=>S.sessionId)),b=a.filter(S=>!d.has(S.sessionId)),c=i,w=await Se(),j={ok:!0,collectedAt:new Date().toISOString(),bridge:{version:V,hostname:I.hostname(),platform:I.platform(),arch:I.arch(),uptime:Math.floor(process.uptime()),nodeVersion:process.version},binding:{status:c.status,paired:c.paired,instanceId:c.instanceId,userId:c.userId,schedulerBaseUrl:c.schedulerBaseUrl,pairingCode:pe()},registration:{registered:r.registered,instanceId:r.instanceId,lastAttempt:r.lastAttempt?.toISOString(),error:r.error},metrics:n,sessions:{active:f,activeCount:f.length,persisted:b,persistedCount:b.length,total:f.length+b.length},processes:{...p,total:p.managed+p.orphan+p.unknown,list:h,registryCount:l.length},lifecycleOperation:w};T={data:j,ts:Date.now()},e.json(j)}catch(n){const s=n;x.error("Dashboard aggregation failed:",s.message),e.status(500).json({ok:!1,error:s.message})}}}),g.get("/login",(t,e)=>{e.type("text/html; charset=utf-8"),e.send(Pe)}),g.get("/",(t,e)=>{const n=A(t);if(!n||!U(n)){e.redirect("/login");return}if(!E()){e.redirect("/setup");return}const s=t.query.lang==="en"?"en":"zh";e.type("text/html; charset=utf-8"),e.send(Te.replace("{{LANG}}",s))}),g.get("/setup",(t,e)=>{const n=A(t);if(!n||!U(n)){e.redirect("/login");return}e.type("text/html; charset=utf-8"),e.send(Ae)});const Te=`<!DOCTYPE html>
2
2
  <html lang="{{LANG}}">
3
3
  <head>
4
4
  <meta charset="UTF-8">
@@ -1,5 +1,5 @@
1
- import{promises as m}from"node:fs";import p from"node:path";import{Router as d}from"express";import{createLogger as h}from"../utils/logger.js";import{validateToken as g}from"../middleware/auth.js";import{readBeforeContentFromCache as v,readDiffFromCache as b}from"../services/workspaceTaskChangeWatcher.js";const x=h("file-change-diff"),y=d();function L(s){const n=[];let o=0,e=0;for(const r of s.split(`
2
- `)){const t=r;if(t.startsWith("@@")){const i=t.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);i&&(o=Number(i[1]),e=Number(i[2])),n.push({type:"hunk",text:t,oldLine:o,newLine:e});continue}if(!(t.startsWith("--- ")||t.startsWith("+++ ")||t.startsWith("Index:")||t.startsWith("===")||t.startsWith("\\ No newline"))){if(t.startsWith("+")){n.push({type:"add",text:t,oldLine:null,newLine:e}),e++;continue}if(t.startsWith("-")){n.push({type:"remove",text:t,oldLine:o,newLine:null}),o++;continue}if(t.startsWith(" ")){n.push({type:"context",text:t,oldLine:o,newLine:e}),o++,e++;continue}}}return n}async function W(s,n,o,e){const r=String(o||"").toUpperCase();if(r==="UPDATE"){if(!n)return{available:!1,operation:r,filePath:e,lines:[],error:"\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6 diff \u7F13\u5B58"};const t=await b(s,n);return t===null?{available:!1,operation:r,filePath:e,lines:[],error:`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230 diff \u8865\u4E01\uFF08cacheKey=${n}\uFF09\uFF0C\u7F13\u5B58\u53EF\u80FD\u5DF2\u88AB\u6E05\u7406`}:{available:!0,operation:r,filePath:e,lines:L(t)}}if(r==="DELETE"){if(!n)return{available:!1,operation:r,filePath:e,lines:[],error:"\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6\u53D8\u66F4\u524D\u5185\u5BB9"};const t=await v(s,n);if(t===null)return{available:!1,operation:r,filePath:e,lines:[],error:`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230\u53D8\u66F4\u524D\u5185\u5BB9\uFF08cacheKey=${n}\uFF09\uFF0C\u7F13\u5B58\u53EF\u80FD\u5DF2\u88AB\u6E05\u7406`};const i=t.split(`
1
+ import{promises as m}from"node:fs";import p from"node:path";import{Router as d}from"express";import{validateToken as h}from"../middleware/auth.js";import{readBeforeContentFromCache as g,readDiffFromCache as v}from"../services/workspaceTaskChangeWatcher.js";import{createLogger as b}from"../utils/logger.js";const x=b("file-change-diff"),y=d();function L(s){const n=[];let o=0,e=0;for(const r of s.split(`
2
+ `)){const t=r;if(t.startsWith("@@")){const i=t.match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);i&&(o=Number(i[1]),e=Number(i[2])),n.push({type:"hunk",text:t,oldLine:o,newLine:e});continue}if(!(t.startsWith("--- ")||t.startsWith("+++ ")||t.startsWith("Index:")||t.startsWith("===")||t.startsWith("\\ No newline"))){if(t.startsWith("+")){n.push({type:"add",text:t,oldLine:null,newLine:e}),e++;continue}if(t.startsWith("-")){n.push({type:"remove",text:t,oldLine:o,newLine:null}),o++;continue}if(t.startsWith(" ")){n.push({type:"context",text:t,oldLine:o,newLine:e}),o++,e++;continue}}}return n}async function W(s,n,o,e){const r=String(o||"").toUpperCase();if(r==="UPDATE"){if(!n)return{available:!1,operation:r,filePath:e,lines:[],error:"\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6 diff \u7F13\u5B58"};const t=await v(s,n);return t===null?{available:!1,operation:r,filePath:e,lines:[],error:`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230 diff \u8865\u4E01\uFF08cacheKey=${n}\uFF09\uFF0C\u7F13\u5B58\u53EF\u80FD\u5DF2\u88AB\u6E05\u7406`}:{available:!0,operation:r,filePath:e,lines:L(t)}}if(r==="DELETE"){if(!n)return{available:!1,operation:r,filePath:e,lines:[],error:"\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6\u53D8\u66F4\u524D\u5185\u5BB9"};const t=await g(s,n);if(t===null)return{available:!1,operation:r,filePath:e,lines:[],error:`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230\u53D8\u66F4\u524D\u5185\u5BB9\uFF08cacheKey=${n}\uFF09\uFF0C\u7F13\u5B58\u53EF\u80FD\u5DF2\u88AB\u6E05\u7406`};const i=t.split(`
3
3
  `);i.length>0&&i[i.length-1]===""&&i.pop();const l=i.map((a,f)=>({type:"remove",text:`-${a}`,oldLine:f+1,newLine:null}));return{available:!0,operation:r,filePath:e,lines:l}}if(r==="CREATE")try{const t=p.resolve(s),i=p.resolve(s,e);if(!i.startsWith(t))return{available:!1,operation:r,filePath:e,lines:[],error:"\u8DEF\u5F84\u8D8A\u754C\uFF0C\u62D2\u7EDD\u8BFB\u53D6\u5DE5\u4F5C\u533A\u5916\u6587\u4EF6"};const a=(await m.readFile(i,"utf-8")).split(`
4
- `);a.length>0&&a[a.length-1]===""&&a.pop();const f=a.map((u,c)=>({type:"add",text:`+${u}`,oldLine:null,newLine:c+1}));return{available:!0,operation:r,filePath:e,lines:f}}catch{return{available:!1,operation:r,filePath:e,lines:[],error:"\u65B0\u589E\u6587\u4EF6\u5F53\u524D\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BFB\uFF08\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\uFF09\uFF0C\u65E0\u6CD5\u5C55\u793A\u5185\u5BB9"}}return{available:!1,operation:r,filePath:e,lines:[],error:`\u4E0D\u652F\u6301\u7684\u64CD\u4F5C\u7C7B\u578B: ${r}`}}y.post("/file-change-diff/read",g,async(s,n)=>{const{workspacePath:o,cacheKey:e,operation:r,filePath:t}=s.body||{};if(!o||!String(o).trim()){n.status(400).json({error:"workspacePath is required"});return}if(!r||!String(r).trim()){n.status(400).json({error:"operation is required"});return}if(!t||!String(t).trim()){n.status(400).json({error:"filePath is required"});return}try{const i=await W(String(o).trim(),e?String(e).trim():null,String(r).trim(),String(t).trim());n.json(i)}catch(i){const l=i instanceof Error?i.message:String(i);x.warn(`[file-change-diff] \u8BFB\u53D6 diff \u5931\u8D25: ${l}`),n.status(500).json({ok:!1,error:l})}});export{W as buildChangeDiffResponse,y as fileChangeDiffRouter,L as parseDiffPatchLines};
4
+ `);a.length>0&&a[a.length-1]===""&&a.pop();const f=a.map((u,c)=>({type:"add",text:`+${u}`,oldLine:null,newLine:c+1}));return{available:!0,operation:r,filePath:e,lines:f}}catch{return{available:!1,operation:r,filePath:e,lines:[],error:"\u65B0\u589E\u6587\u4EF6\u5F53\u524D\u4E0D\u5B58\u5728\u6216\u4E0D\u53EF\u8BFB\uFF08\u53EF\u80FD\u5DF2\u88AB\u5220\u9664\uFF09\uFF0C\u65E0\u6CD5\u5C55\u793A\u5185\u5BB9"}}return{available:!1,operation:r,filePath:e,lines:[],error:`\u4E0D\u652F\u6301\u7684\u64CD\u4F5C\u7C7B\u578B: ${r}`}}y.post("/file-change-diff/read",h,async(s,n)=>{const{workspacePath:o,cacheKey:e,operation:r,filePath:t}=s.body||{};if(!o||!String(o).trim()){n.status(400).json({error:"workspacePath is required"});return}if(!r||!String(r).trim()){n.status(400).json({error:"operation is required"});return}if(!t||!String(t).trim()){n.status(400).json({error:"filePath is required"});return}try{const i=await W(String(o).trim(),e?String(e).trim():null,String(r).trim(),String(t).trim());n.json(i)}catch(i){const l=i instanceof Error?i.message:String(i);x.warn(`[file-change-diff] \u8BFB\u53D6 diff \u5931\u8D25: ${l}`),n.status(500).json({ok:!1,error:l})}});export{W as buildChangeDiffResponse,y as fileChangeDiffRouter,L as parseDiffPatchLines};
5
5
 
@@ -1,2 +1,2 @@
1
- import{promises as w}from"node:fs";import g from"node:path";import{Router as O}from"express";import*as P from"diff";import{createLogger as R}from"../utils/logger.js";import{validateToken as T}from"../middleware/auth.js";import{readBeforeContentFromCache as U,readDiffFromCache as _}from"../services/workspaceTaskChangeWatcher.js";const k=R("file-diff-rollback"),D=O();async function m(h,u){const r=[],l=[],s=[],i=g.resolve(String(h).trim()),t=[...u].sort((a,c)=>new Date(c.createdAt).getTime()-new Date(a.createdAt).getTime()),o=new Map,p=new Map;for(const a of t){const c=g.join(i,a.relativePath),e=a.relativePath.replace(/\\/g,"/");if(!g.resolve(c).startsWith(i)){const n=`Path escape detected: ${e}`;r.push(n),s.push({relativePath:e,originalOperation:a.originalOperation,status:"preview_failed",reason:n});continue}if(!o.has(e)){let n=null,f=!1;try{n=await w.readFile(c,"utf-8"),f=!0}catch{f=!1}o.set(e,n),p.set(e,f)}switch(a.originalOperation){case"CREATE":{l.push({type:"DELETE",fullPath:c,relativePath:e,originalOperation:"CREATE"}),s.push({relativePath:e,originalOperation:"CREATE",status:"preview_passed",action:"\u5220\u9664\u6587\u4EF6"}),o.set(e,null),p.set(e,!1);break}case"UPDATE":{if(!a.cacheKey){const d="\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6 diff \u8865\u4E01";r.push(`UPDATE rollback failed: ${d} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:d});break}const n=o.get(e)??null;if(n===null){const d="\u6587\u4EF6\u5F53\u524D\u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u5E94\u7528\u53CD\u5411 diff \u8865\u4E01";r.push(`UPDATE rollback failed: ${d} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:d});break}const f=await _(i,a.cacheKey);if(f===null){const d=`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230 diff \u8865\u4E01 (cacheKey=${a.cacheKey})\uFF0C\u65E0\u6CD5\u7CBE\u786E\u56DE\u6EDA`;r.push(`UPDATE rollback failed: ${d} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:d});break}let v=null;try{const d=P.parsePatch(f),E=P.reversePatch(d),$=P.applyPatch(n,E);if($!==!1)v=$;else{const b="\u53CD\u5411 diff \u8865\u4E01\u65E0\u6CD5\u7CBE\u786E\u5E94\u7528\uFF1A\u6587\u4EF6\u5F53\u524D\u5185\u5BB9\u4E0E AI \u53D8\u66F4\u540E\u7684\u9884\u671F\u4E0A\u4E0B\u6587\u4E0D\u5339\u914D\uFF0C\u53EF\u80FD\u5DF2\u88AB\u5176\u4ED6\u4EFB\u52A1\u6216\u7528\u6237\u4FEE\u6539\u4E86\u76F8\u540C\u533A\u57DF\uFF0C\u5B58\u5728\u51B2\u7A81";r.push(`UPDATE rollback failed: ${b} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:b});break}}catch(d){const E=`\u53CD\u5411 diff \u8865\u4E01\u5E94\u7528\u5F02\u5E38: ${d.message}`;r.push(`UPDATE rollback failed: ${E} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:E});break}l.push({type:"WRITE",fullPath:c,relativePath:e,originalOperation:"UPDATE",content:v}),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_passed",action:"\u5E94\u7528\u53CD\u5411 diff \u8865\u4E01"}),o.set(e,v);break}case"DELETE":{if(!a.cacheKey){const f="\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6\u5220\u9664\u524D\u7684\u6587\u4EF6\u5185\u5BB9";r.push(`DELETE rollback failed: ${f} for ${e}`),s.push({relativePath:e,originalOperation:"DELETE",status:"preview_failed",reason:f});break}const n=await U(i,a.cacheKey);if(n===null){const f=`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230\u5220\u9664\u524D\u7684\u6587\u4EF6\u5185\u5BB9 (cacheKey=${a.cacheKey})`;r.push(`DELETE rollback failed: ${f} for ${e}`),s.push({relativePath:e,originalOperation:"DELETE",status:"preview_failed",reason:f});break}l.push({type:"WRITE",fullPath:c,relativePath:e,originalOperation:"DELETE",content:n}),s.push({relativePath:e,originalOperation:"DELETE",status:"preview_passed",action:"\u91CD\u5EFA\u6587\u4EF6"}),o.set(e,n),p.set(e,!0);break}default:{const n=`\u672A\u77E5\u7684\u64CD\u4F5C\u7C7B\u578B "${a.originalOperation}"`;r.push(`${n} for ${e}`),s.push({relativePath:e,originalOperation:a.originalOperation,status:"preview_failed",reason:n});break}}}return{ok:r.length===0,errors:r,plan:l,details:s}}async function A(h,u){let r=0,l=0;const s=[],i=u.map(t=>({...t}));for(const t of h){const o=i.find(p=>p.relativePath===t.relativePath&&p.status==="preview_passed");try{t.type==="DELETE"?(await w.unlink(t.fullPath),k.info(`Rollback executed: deleted created file ${t.relativePath}`),o&&(o.status="success",o.action="\u5220\u9664\u6587\u4EF6"),r++):t.type==="WRITE"&&(await w.mkdir(g.dirname(t.fullPath),{recursive:!0}),await w.writeFile(t.fullPath,t.content,"utf-8"),k.info(`Rollback executed: restored file ${t.relativePath}`),o&&(o.status="success",o.action=t.originalOperation==="UPDATE"?"\u5E94\u7528\u53CD\u5411 diff \u8865\u4E01":"\u91CD\u5EFA\u6587\u4EF6"),r++)}catch(p){const a=`${p.message}`,c=`Rollback failed for ${t.relativePath}: ${a}`;s.push(c),k.warn(c),o&&(o.status="failed",o.reason=a),l++}}return{restored:r,skipped:l,errors:s,details:i}}D.post("/file-diff-rollback/preview",T,async(h,u)=>{const{workspacePath:r,operations:l}=h.body;if(!r||!Array.isArray(l)){u.status(400).json({error:"workspacePath and operations (array) are required"});return}const{ok:s,errors:i,plan:t,details:o}=await m(r,l);u.json({ok:s,errors:i,plan:t.map(p=>({type:p.type,relativePath:p.relativePath})),totalOperations:l.length,plannedOperations:t.length,details:o})}),D.post("/file-diff-rollback/execute",T,async(h,u)=>{const{workspacePath:r,operations:l,skipFailed:s}=h.body;if(!r||!Array.isArray(l)){u.status(400).json({error:"workspacePath and operations (array) are required"});return}const i=await m(r,l);if(!i.ok){if(s&&i.plan.length>0){const a=await A(i.plan,i.details),c=i.details.filter(y=>y.status==="preview_failed").length;k.warn(`Diff rollback partial execute: passed=${a.restored}, skippedFailed=${c}, ioSkipped=${a.skipped}`);const e={ok:a.errors.length===0,restored:a.restored,skipped:a.skipped+c,errors:a.errors,previewFailed:!1,partial:!0,details:a.details};u.json(e);return}const p={ok:!1,restored:0,skipped:l.length,errors:i.errors,previewFailed:!0,details:i.details};k.warn(`Diff rollback preview failed, no files touched: errors=${i.errors.length}`),u.json(p);return}const t=await A(i.plan,i.details),o={ok:t.errors.length===0,restored:t.restored,skipped:t.skipped,errors:t.errors,previewFailed:!1,details:t.details};k.info(`Diff rollback completed: restored=${t.restored}, skipped=${t.skipped}, errors=${t.errors.length}`),u.json(o)});export{D as fileDiffRollbackRouter};
1
+ import{promises as w}from"node:fs";import g from"node:path";import*as P from"diff";import{Router as O}from"express";import{validateToken as b}from"../middleware/auth.js";import{readBeforeContentFromCache as R,readDiffFromCache as U}from"../services/workspaceTaskChangeWatcher.js";import{createLogger as _}from"../utils/logger.js";const k=_("file-diff-rollback"),D=O();async function m(h,u){const r=[],n=[],s=[],i=g.resolve(String(h).trim()),t=[...u].sort((a,c)=>new Date(c.createdAt).getTime()-new Date(a.createdAt).getTime()),o=new Map,l=new Map;for(const a of t){const c=g.join(i,a.relativePath),e=a.relativePath.replace(/\\/g,"/");if(!g.resolve(c).startsWith(i)){const p=`Path escape detected: ${e}`;r.push(p),s.push({relativePath:e,originalOperation:a.originalOperation,status:"preview_failed",reason:p});continue}if(!o.has(e)){let p=null,f=!1;try{p=await w.readFile(c,"utf-8"),f=!0}catch{f=!1}o.set(e,p),l.set(e,f)}switch(a.originalOperation){case"CREATE":{n.push({type:"DELETE",fullPath:c,relativePath:e,originalOperation:"CREATE"}),s.push({relativePath:e,originalOperation:"CREATE",status:"preview_passed",action:"\u5220\u9664\u6587\u4EF6"}),o.set(e,null),l.set(e,!1);break}case"UPDATE":{if(!a.cacheKey){const d="\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6 diff \u8865\u4E01";r.push(`UPDATE rollback failed: ${d} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:d});break}const p=o.get(e)??null;if(p===null){const d="\u6587\u4EF6\u5F53\u524D\u4E0D\u5B58\u5728\uFF0C\u65E0\u6CD5\u5E94\u7528\u53CD\u5411 diff \u8865\u4E01";r.push(`UPDATE rollback failed: ${d} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:d});break}const f=await U(i,a.cacheKey);if(f===null){const d=`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230 diff \u8865\u4E01 (cacheKey=${a.cacheKey})\uFF0C\u65E0\u6CD5\u7CBE\u786E\u56DE\u6EDA`;r.push(`UPDATE rollback failed: ${d} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:d});break}let v=null;try{const d=P.parsePatch(f),E=P.reversePatch(d),T=P.applyPatch(p,E);if(T!==!1)v=T;else{const $="\u53CD\u5411 diff \u8865\u4E01\u65E0\u6CD5\u7CBE\u786E\u5E94\u7528\uFF1A\u6587\u4EF6\u5F53\u524D\u5185\u5BB9\u4E0E AI \u53D8\u66F4\u540E\u7684\u9884\u671F\u4E0A\u4E0B\u6587\u4E0D\u5339\u914D\uFF0C\u53EF\u80FD\u5DF2\u88AB\u5176\u4ED6\u4EFB\u52A1\u6216\u7528\u6237\u4FEE\u6539\u4E86\u76F8\u540C\u533A\u57DF\uFF0C\u5B58\u5728\u51B2\u7A81";r.push(`UPDATE rollback failed: ${$} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:$});break}}catch(d){const E=`\u53CD\u5411 diff \u8865\u4E01\u5E94\u7528\u5F02\u5E38: ${d.message}`;r.push(`UPDATE rollback failed: ${E} for ${e}`),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_failed",reason:E});break}n.push({type:"WRITE",fullPath:c,relativePath:e,originalOperation:"UPDATE",content:v}),s.push({relativePath:e,originalOperation:"UPDATE",status:"preview_passed",action:"\u5E94\u7528\u53CD\u5411 diff \u8865\u4E01"}),o.set(e,v);break}case"DELETE":{if(!a.cacheKey){const f="\u7F3A\u5C11 cacheKey\uFF0C\u65E0\u6CD5\u8BFB\u53D6\u5220\u9664\u524D\u7684\u6587\u4EF6\u5185\u5BB9";r.push(`DELETE rollback failed: ${f} for ${e}`),s.push({relativePath:e,originalOperation:"DELETE",status:"preview_failed",reason:f});break}const p=await R(i,a.cacheKey);if(p===null){const f=`\u672C\u5730\u7F13\u5B58\u4E2D\u627E\u4E0D\u5230\u5220\u9664\u524D\u7684\u6587\u4EF6\u5185\u5BB9 (cacheKey=${a.cacheKey})`;r.push(`DELETE rollback failed: ${f} for ${e}`),s.push({relativePath:e,originalOperation:"DELETE",status:"preview_failed",reason:f});break}n.push({type:"WRITE",fullPath:c,relativePath:e,originalOperation:"DELETE",content:p}),s.push({relativePath:e,originalOperation:"DELETE",status:"preview_passed",action:"\u91CD\u5EFA\u6587\u4EF6"}),o.set(e,p),l.set(e,!0);break}default:{const p=`\u672A\u77E5\u7684\u64CD\u4F5C\u7C7B\u578B "${a.originalOperation}"`;r.push(`${p} for ${e}`),s.push({relativePath:e,originalOperation:a.originalOperation,status:"preview_failed",reason:p});break}}}return{ok:r.length===0,errors:r,plan:n,details:s}}async function A(h,u){let r=0,n=0;const s=[],i=u.map(t=>({...t}));for(const t of h){const o=i.find(l=>l.relativePath===t.relativePath&&l.status==="preview_passed");try{if(t.type==="DELETE")await w.unlink(t.fullPath),k.info(`Rollback executed: deleted created file ${t.relativePath}`),o&&(o.status="success",o.action="\u5220\u9664\u6587\u4EF6"),r++;else if(t.type==="WRITE"){const l=t.content??"";await w.mkdir(g.dirname(t.fullPath),{recursive:!0}),await w.writeFile(t.fullPath,l,"utf-8"),k.info(`Rollback executed: restored file ${t.relativePath}`),o&&(o.status="success",o.action=t.originalOperation==="UPDATE"?"\u5E94\u7528\u53CD\u5411 diff \u8865\u4E01":"\u91CD\u5EFA\u6587\u4EF6"),r++}}catch(l){const a=`${l.message}`,c=`Rollback failed for ${t.relativePath}: ${a}`;s.push(c),k.warn(c),o&&(o.status="failed",o.reason=a),n++}}return{restored:r,skipped:n,errors:s,details:i}}D.post("/file-diff-rollback/preview",b,async(h,u)=>{const{workspacePath:r,operations:n}=h.body;if(!r||!Array.isArray(n)){u.status(400).json({error:"workspacePath and operations (array) are required"});return}const{ok:s,errors:i,plan:t,details:o}=await m(r,n);u.json({ok:s,errors:i,plan:t.map(l=>({type:l.type,relativePath:l.relativePath})),totalOperations:n.length,plannedOperations:t.length,details:o})}),D.post("/file-diff-rollback/execute",b,async(h,u)=>{const{workspacePath:r,operations:n,skipFailed:s}=h.body;if(!r||!Array.isArray(n)){u.status(400).json({error:"workspacePath and operations (array) are required"});return}const i=await m(r,n);if(!i.ok){if(s&&i.plan.length>0){const a=await A(i.plan,i.details),c=i.details.filter(y=>y.status==="preview_failed").length;k.warn(`Diff rollback partial execute: passed=${a.restored}, skippedFailed=${c}, ioSkipped=${a.skipped}`);const e={ok:a.errors.length===0,restored:a.restored,skipped:a.skipped+c,errors:a.errors,previewFailed:!1,partial:!0,details:a.details};u.json(e);return}const l={ok:!1,restored:0,skipped:n.length,errors:i.errors,previewFailed:!0,details:i.details};k.warn(`Diff rollback preview failed, no files touched: errors=${i.errors.length}`),u.json(l);return}const t=await A(i.plan,i.details),o={ok:t.errors.length===0,restored:t.restored,skipped:t.skipped,errors:t.errors,previewFailed:!1,details:t.details};k.info(`Diff rollback completed: restored=${t.restored}, skipped=${t.skipped}, errors=${t.errors.length}`),u.json(o)});export{D as fileDiffRollbackRouter};
2
2
 
@@ -1,2 +1,2 @@
1
- import{Router as c}from"express";import{validateToken as p}from"../middleware/auth.js";import{createLogger as u}from"../utils/logger.js";import{createSnapshot as f,restoreSnapshot as m,listSnapshots as d,deleteSnapshot as g,getSnapshotRootPath as S}from"../services/fileSnapshotStore.js";const h=c(),i=u("file-snapshot");h.post("/file-snapshot/create",p,async(n,t)=>{const{workspacePath:r,snapshotId:s,snapshotName:a,triggerType:o}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"workspacePath is required"});return}try{const e=await f({workspacePath:String(r).trim(),snapshotId:s?String(s).trim():void 0,snapshotName:a?String(a).trim():void 0,triggerType:o?String(o).trim():void 0});if(!e.ok){i.warn(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5931\u8D25: ${e.error}`),t.status(500).json({ok:!1,error:e.error});return}t.json({ok:!0,snapshotId:e.snapshotId,snapshotKey:e.snapshotKey,fileCount:e.fileCount,totalBytes:e.totalBytes,workspaceHash:e.workspaceHash,workspacePath:String(r).trim()})}catch(e){const l=e;i.error(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5F02\u5E38: ${l.message}`),t.status(500).json({ok:!1,error:l.message||"create snapshot failed"})}}),h.post("/file-snapshot/restore",p,async(n,t)=>{const{workspacePath:r,snapshotKey:s,preRestoreBackup:a}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"workspacePath is required"});return}if(!s||!String(s).trim()){t.status(400).json({error:"snapshotKey is required"});return}try{const o=await m({workspacePath:String(r).trim(),snapshotKey:String(s).trim(),preRestoreBackup:a!==!1});if(!o.ok){i.warn(`[FileSnapshot] \u8FD8\u539F\u5FEB\u7167\u5931\u8D25: ${o.error}`),t.status(500).json({ok:!1,error:o.error});return}t.json({ok:!0,filesRestored:o.filesRestored,filesDeleted:o.filesDeleted,filesSkipped:o.filesSkipped,preRestoreSnapshotKey:o.preRestoreSnapshotKey||null,workspacePath:String(r).trim()})}catch(o){const e=o;i.error(`[FileSnapshot] \u8FD8\u539F\u5FEB\u7167\u5F02\u5E38: ${e.message}`),t.status(500).json({ok:!1,error:e.message||"restore snapshot failed"})}}),h.post("/file-snapshot/list",p,async(n,t)=>{const{workspacePath:r}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"workspacePath is required"});return}try{const s=await d(String(r).trim());t.json({ok:!0,snapshots:s,count:s.length,workspacePath:String(r).trim()})}catch(s){const a=s;i.error(`[FileSnapshot] \u5217\u51FA\u5FEB\u7167\u5F02\u5E38: ${a.message}`),t.status(500).json({ok:!1,error:a.message||"list snapshots failed"})}}),h.post("/file-snapshot/delete",p,async(n,t)=>{const{snapshotKey:r}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"snapshotKey is required"});return}try{const s=await g(String(r).trim());if(!s.ok){i.warn(`[FileSnapshot] \u5220\u9664\u5FEB\u7167\u5931\u8D25: ${s.error}`),t.status(s.error?.includes("not found")?404:500).json({ok:!1,error:s.error});return}t.json({ok:!0,snapshotKey:String(r).trim(),message:`\u5DF2\u5220\u9664\u5FEB\u7167 ${r}`})}catch(s){const a=s;i.error(`[FileSnapshot] \u5220\u9664\u5FEB\u7167\u5F02\u5E38: ${a.message}`),t.status(500).json({ok:!1,error:a.message||"delete snapshot failed"})}}),h.post("/file-snapshot/info",p,async(n,t)=>{t.json({ok:!0,snapshotRoot:S()})});export{h as fileSnapshotRouter};
1
+ import{Router as c}from"express";import{validateToken as p}from"../middleware/auth.js";import{createSnapshot as u,restoreSnapshot as f,listSnapshots as m,deleteSnapshot as d,getSnapshotRootPath as g}from"../services/fileSnapshotStore.js";import{createLogger as S}from"../utils/logger.js";const h=c(),i=S("file-snapshot");h.post("/file-snapshot/create",p,async(n,t)=>{const{workspacePath:r,snapshotId:s,snapshotName:a,triggerType:o}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"workspacePath is required"});return}try{const e=await u({workspacePath:String(r).trim(),snapshotId:s?String(s).trim():void 0,snapshotName:a?String(a).trim():void 0,triggerType:o?String(o).trim():void 0});if(!e.ok){i.warn(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5931\u8D25: ${e.error}`),t.status(500).json({ok:!1,error:e.error});return}t.json({ok:!0,snapshotId:e.snapshotId,snapshotKey:e.snapshotKey,fileCount:e.fileCount,totalBytes:e.totalBytes,workspaceHash:e.workspaceHash,workspacePath:String(r).trim()})}catch(e){const l=e;i.error(`[FileSnapshot] \u521B\u5EFA\u5FEB\u7167\u5F02\u5E38: ${l.message}`),t.status(500).json({ok:!1,error:l.message||"create snapshot failed"})}}),h.post("/file-snapshot/restore",p,async(n,t)=>{const{workspacePath:r,snapshotKey:s,preRestoreBackup:a}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"workspacePath is required"});return}if(!s||!String(s).trim()){t.status(400).json({error:"snapshotKey is required"});return}try{const o=await f({workspacePath:String(r).trim(),snapshotKey:String(s).trim(),preRestoreBackup:a!==!1});if(!o.ok){i.warn(`[FileSnapshot] \u8FD8\u539F\u5FEB\u7167\u5931\u8D25: ${o.error}`),t.status(500).json({ok:!1,error:o.error});return}t.json({ok:!0,filesRestored:o.filesRestored,filesDeleted:o.filesDeleted,filesSkipped:o.filesSkipped,preRestoreSnapshotKey:o.preRestoreSnapshotKey||null,workspacePath:String(r).trim()})}catch(o){const e=o;i.error(`[FileSnapshot] \u8FD8\u539F\u5FEB\u7167\u5F02\u5E38: ${e.message}`),t.status(500).json({ok:!1,error:e.message||"restore snapshot failed"})}}),h.post("/file-snapshot/list",p,async(n,t)=>{const{workspacePath:r}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"workspacePath is required"});return}try{const s=await m(String(r).trim());t.json({ok:!0,snapshots:s,count:s.length,workspacePath:String(r).trim()})}catch(s){const a=s;i.error(`[FileSnapshot] \u5217\u51FA\u5FEB\u7167\u5F02\u5E38: ${a.message}`),t.status(500).json({ok:!1,error:a.message||"list snapshots failed"})}}),h.post("/file-snapshot/delete",p,async(n,t)=>{const{snapshotKey:r}=n.body||{};if(!r||!String(r).trim()){t.status(400).json({error:"snapshotKey is required"});return}try{const s=await d(String(r).trim());if(!s.ok){i.warn(`[FileSnapshot] \u5220\u9664\u5FEB\u7167\u5931\u8D25: ${s.error}`),t.status(s.error?.includes("not found")?404:500).json({ok:!1,error:s.error});return}t.json({ok:!0,snapshotKey:String(r).trim(),message:`\u5DF2\u5220\u9664\u5FEB\u7167 ${r}`})}catch(s){const a=s;i.error(`[FileSnapshot] \u5220\u9664\u5FEB\u7167\u5F02\u5E38: ${a.message}`),t.status(500).json({ok:!1,error:a.message||"delete snapshot failed"})}}),h.post("/file-snapshot/info",p,async(n,t)=>{t.json({ok:!0,snapshotRoot:g()})});export{h as fileSnapshotRouter};
2
2
 
@@ -29,7 +29,7 @@ ${l.stdout.trim()}`):m.info(`[Git/collectDiff] \u6587\u4EF6\u65E0\u6682\u5B58\u5
29
29
  ...(diff truncated due to length)`:a;return m.info(`[Git/collectDiff] \u6536\u96C6\u5B8C\u6210: diffContent.length=${a.length}, truncated=${c.length}`),{truncatedDiff:c}}function $(r,t,e){try{r.write(`event: ${t}
30
30
  `),r.write(`data: ${JSON.stringify(e)}
31
31
 
32
- `)}catch{}}S.post("/git/generate-commit-message",k,async(r,t)=>{const{workspacePath:e,repositoryPath:i,stagedFiles:s,aiBaseUrl:n,aiApiKey:a,aiModel:o}=r.body||{};if(!e||!String(e).trim()){t.status(400).json({error:"workspacePath is required"});return}if(!Array.isArray(s)||s.length===0){t.status(400).json({error:"stagedFiles is required and must be a non-empty array"});return}if(!n||!String(n).trim()||!a||!String(a).trim()||!o||!String(o).trim()){t.status(400).json({error:"aiBaseUrl, aiApiKey and aiModel are required"});return}try{const{truncatedDiff:c,error:u}=await W(String(i||""),String(e),s);if(u){t.status(u.status).json({error:u.message});return}if(!c){t.json({message:"\u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9"});return}const f=await Wt(n,a,o,c);t.json({message:f})}catch(c){const u=c;m.error(`[Git] generate commit message failed: ${u.message}`),t.status(500).json({error:u.message||"generate commit message failed"})}}),S.post("/git/generate-commit-message-stream",k,async(r,t)=>{const{workspacePath:e,repositoryPath:i,stagedFiles:s,aiBaseUrl:n,aiApiKey:a,aiModel:o}=r.body||{};if(!e||!String(e).trim()){t.status(400).json({error:"workspacePath is required"});return}if(!Array.isArray(s)||s.length===0){t.status(400).json({error:"stagedFiles is required and must be a non-empty array"});return}if(!n||!String(n).trim()||!a||!String(a).trim()||!o||!String(o).trim()){t.status(400).json({error:"aiBaseUrl, aiApiKey and aiModel are required"});return}m.info(`[Git/SSE] \u6536\u5230 generate-commit-message-stream \u8BF7\u6C42: workspacePath=${String(e||"").substring(0,40)}, stagedFiles=${s?.length??0}, aiModel=${o}, aiBaseUrl=${n}`),t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),r.socket?.setNoDelay(!0),t.flushHeaders?.();let c=!1,u=null,f=!1;const l={delta:0},d=`${r.ip}:${r.socket?.remotePort??"?"}`;r.on("close",()=>{c||(c=!0,m.info(`[Git/SSE] \u5BA2\u6237\u7AEF\u65AD\u5F00\u8FDE\u63A5: workspacePath=${String(e||"").substring(0,40)}, deltaEventsSent=${l.delta}, peer=${d}`))}),$(t,"init",{status:"generating"});try{const{truncatedDiff:p,error:g}=await W(String(i||""),String(e),s);if(g){m.warn(`[Git/SSE] collectStagedDiffForAi \u8FD4\u56DE\u9519\u8BEF: ${g.message}`),$(t,"error",{message:g.message}),t.end();return}if(!p){m.info("[Git/SSE] \u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9, \u76F4\u63A5\u8FD4\u56DE done"),$(t,"delta",{contentDelta:"",message:"\u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9"}),$(t,"done",{message:"\u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9"}),t.end();return}m.info(`[Git/SSE] \u6536\u96C6\u5230 diff: truncatedDiff.length=${p.length}`),c&&m.info("[Git/SSE] \u5BA2\u6237\u7AEF\u5728 collectDiff \u671F\u95F4\u65AD\u5F00, \u4F46\u4ECD\u5C1D\u8BD5 AI \u8C03\u7528"),m.info(`[Git/SSE] \u5F00\u59CB\u8C03\u7528 AI streamAiForCommitMessage: aiModel=${o}`),u=new AbortController;let y="";const w=await Lt(n,a,o,p,(P,C)=>{l.delta++,C!==y?(y=C,$(t,"delta",{contentDelta:P,message:C})):$(t,"delta",{contentDelta:P,message:C})},u.signal);m.info(`[Git/SSE] AI streamAiForCommitMessage \u5B8C\u6210: finalMessage=${JSON.stringify(w).substring(0,200)}, deltaEventsSent=${l.delta}`),c||$(t,"done",{message:w}),t.end()}catch(p){const g=p;m.error(`[Git/SSE] stream commit message failed: ${g.message}${g.stack?`
32
+ `)}catch{}}S.post("/git/generate-commit-message",k,async(r,t)=>{const{workspacePath:e,repositoryPath:i,stagedFiles:s,aiBaseUrl:n,aiApiKey:a,aiModel:o}=r.body||{};if(!e||!String(e).trim()){t.status(400).json({error:"workspacePath is required"});return}if(!Array.isArray(s)||s.length===0){t.status(400).json({error:"stagedFiles is required and must be a non-empty array"});return}if(!n||!String(n).trim()||!a||!String(a).trim()||!o||!String(o).trim()){t.status(400).json({error:"aiBaseUrl, aiApiKey and aiModel are required"});return}try{const{truncatedDiff:c,error:u}=await W(String(i||""),String(e),s);if(u){t.status(u.status).json({error:u.message});return}if(!c){t.json({message:"\u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9"});return}const f=await Wt(n,a,o,c);t.json({message:f})}catch(c){const u=c;m.error(`[Git] generate commit message failed: ${u.message}`),t.status(500).json({error:u.message||"generate commit message failed"})}}),S.post("/git/generate-commit-message-stream",k,async(r,t)=>{const{workspacePath:e,repositoryPath:i,stagedFiles:s,aiBaseUrl:n,aiApiKey:a,aiModel:o}=r.body||{};if(!e||!String(e).trim()){t.status(400).json({error:"workspacePath is required"});return}if(!Array.isArray(s)||s.length===0){t.status(400).json({error:"stagedFiles is required and must be a non-empty array"});return}if(!n||!String(n).trim()||!a||!String(a).trim()||!o||!String(o).trim()){t.status(400).json({error:"aiBaseUrl, aiApiKey and aiModel are required"});return}m.info(`[Git/SSE] \u6536\u5230 generate-commit-message-stream \u8BF7\u6C42: workspacePath=${String(e||"").substring(0,40)}, stagedFiles=${s?.length??0}, aiModel=${o}, aiBaseUrl=${n}`),t.status(200),t.setHeader("Content-Type","text/event-stream; charset=utf-8"),t.setHeader("Cache-Control","no-cache, no-transform"),t.setHeader("Connection","keep-alive"),t.setHeader("X-Accel-Buffering","no"),r.socket?.setNoDelay(!0),t.flushHeaders?.();let c=!1,u=null;const f=!1,l={delta:0},d=`${r.ip}:${r.socket?.remotePort??"?"}`;r.on("close",()=>{c||(c=!0,m.info(`[Git/SSE] \u5BA2\u6237\u7AEF\u65AD\u5F00\u8FDE\u63A5: workspacePath=${String(e||"").substring(0,40)}, deltaEventsSent=${l.delta}, peer=${d}`))}),$(t,"init",{status:"generating"});try{const{truncatedDiff:p,error:g}=await W(String(i||""),String(e),s);if(g){m.warn(`[Git/SSE] collectStagedDiffForAi \u8FD4\u56DE\u9519\u8BEF: ${g.message}`),$(t,"error",{message:g.message}),t.end();return}if(!p){m.info("[Git/SSE] \u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9, \u76F4\u63A5\u8FD4\u56DE done"),$(t,"delta",{contentDelta:"",message:"\u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9"}),$(t,"done",{message:"\u6682\u5B58\u533A\u6CA1\u6709\u53D8\u66F4\u5185\u5BB9"}),t.end();return}m.info(`[Git/SSE] \u6536\u96C6\u5230 diff: truncatedDiff.length=${p.length}`),c&&m.info("[Git/SSE] \u5BA2\u6237\u7AEF\u5728 collectDiff \u671F\u95F4\u65AD\u5F00, \u4F46\u4ECD\u5C1D\u8BD5 AI \u8C03\u7528"),m.info(`[Git/SSE] \u5F00\u59CB\u8C03\u7528 AI streamAiForCommitMessage: aiModel=${o}`),u=new AbortController;let y="";const w=await Lt(n,a,o,p,(P,C)=>{l.delta++,C!==y?(y=C,$(t,"delta",{contentDelta:P,message:C})):$(t,"delta",{contentDelta:P,message:C})},u.signal);m.info(`[Git/SSE] AI streamAiForCommitMessage \u5B8C\u6210: finalMessage=${JSON.stringify(w).substring(0,200)}, deltaEventsSent=${l.delta}`),c||$(t,"done",{message:w}),t.end()}catch(p){const g=p;m.error(`[Git/SSE] stream commit message failed: ${g.message}${g.stack?`
33
33
  `+g.stack:""}`),c||$(t,"error",{message:g.message||"generate commit message failed"}),t.end()}}),S.post("/git/unstage-files",k,async(r,t)=>{const{workspacePath:e,repositoryPath:i,filePaths:s}=r.body||{};if(!e||!String(e).trim()){t.status(400).json({error:"workspacePath is required"});return}const a=(Array.isArray(s)?s:[]).map(o=>x(String(o||"").trim())).filter(o=>o.length>0);if(a.length===0){t.status(400).json({error:"filePaths is required and must be a non-empty array"});return}try{const o=await j(String(i||e).trim());if(!o.hasRepository||!o.repositoryRootPath){t.status(400).json({error:"workspace is not inside a git repository"});return}let c="";for(const u of a){const f=G(u,o),l=await h(o.repositoryRootPath,["restore","--staged",...f]);l.exitCode!==0&&(c=l.stderr||`git restore --staged failed for ${u}`)}if(c){t.status(400).json({error:c});return}t.json({ok:!0,filePaths:a,workspacePath:o.workspacePath,repositoryRootPath:o.repositoryRootPath,relativeWorkspacePath:o.relativeWorkspacePath})}catch(o){const c=o;t.status(500).json({error:c.message||"git unstage files failed"})}}),S.post("/git/restore-files",k,async(r,t)=>{const{workspacePath:e,repositoryPath:i,filePaths:s}=r.body||{};if(!e||!String(e).trim()){t.status(400).json({error:"workspacePath is required"});return}const a=(Array.isArray(s)?s:[]).map(o=>x(String(o||"").trim())).filter(o=>o.length>0);if(a.length===0){t.status(400).json({error:"filePaths is required and must be a non-empty array"});return}try{const o=await j(String(i||e).trim());if(!o.hasRepository||!o.repositoryRootPath){t.status(400).json({error:"workspace is not inside a git repository"});return}let c="";for(const u of a){const f=E(u,o),l=G(u,o),p=(await h(o.repositoryRootPath,["ls-files","--error-unmatch","--",f])).exitCode===0,g=p?await h(o.repositoryRootPath,["restore",...l]):await h(o.repositoryRootPath,["clean","-f",...l]);g.exitCode!==0&&(c=g.stderr||`${p?"git restore":"git clean -f"} failed for ${u}`)}if(c){t.status(400).json({error:c});return}t.json({ok:!0,filePaths:a,workspacePath:o.workspacePath,repositoryRootPath:o.repositoryRootPath,relativeWorkspacePath:o.relativeWorkspacePath})}catch(o){const c=o;t.status(500).json({error:c.message||"git restore files failed"})}});function _t(r){const t=r.split(`
34
34
  `),e=[];for(let i=0;i<t.length;i++){const s=t[i],n=s.endsWith("\r")?"\r":"",o=(n?s.slice(0,-1):s).match(/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/);if(!o){e.push(s);continue}let c=0,u=0;for(let f=i+1;f<t.length;f++){const l=t[f].replace(/\r$/,"");if(/^diff --git /.test(l)||/^@@ /.test(l))break;l.startsWith("+")?u++:l.startsWith("-")?c++:l.startsWith(" ")&&(c++,u++)}e.push(`@@ -${o[1]},${c} +${o[2]},${u} @@${n}`)}return e.join(`
35
35
  `)}S.post("/git/revert-hunk",k,async(r,t)=>{const{workspacePath:e,repositoryPath:i,filePath:s,patch:n}=r.body||{};if(!e||!String(e).trim()){t.status(400).json({error:"workspacePath is required"});return}if(!s||!String(s).trim()){t.status(400).json({error:"filePath is required"});return}const a=String(n||"").replace(/^\uFEFF/,"").trim();if(!a){t.status(400).json({error:"patch is required"});return}try{const o=await j(String(i||e).trim());if(!o.hasRepository||!o.repositoryRootPath){t.status(400).json({error:"workspace is not inside a git repository"});return}const c=x(String(s).trim()),u=E(c,o);if(M(u),(a.match(/^diff --git /gm)||[]).length!==1){t.status(400).json({error:"patch must contain exactly one file diff"});return}const l=a.match(/^\+\+\+ b\/(.+)$/m),d=l?x(l[1].trim()):"";if(!d||d!==u){t.status(400).json({error:"patch target path does not match filePath"});return}let p=null;try{p=await b.mkdtemp(R.join(ot.tmpdir(),"agentswork-git-revert-"));const g=R.join(p,"revert.patch");await b.writeFile(g,_t(a)+`
@@ -34,6 +34,5 @@ export declare function buildSchedulerPingFailureResponse(error: Error, configur
34
34
 
35
35
  export declare function buildAmbiguousSchedulerBaseUrlResponse(targetUrls: string[]): AmbiguousSchedulerBaseUrlResponse;
36
36
 
37
- export declare function buildUninstallFailureMessage(requestedTools: string[], toolStatus: Record<string, ToolInstallStatus>): string;
38
37
  export declare function summarizeToolStatus(toolStatus: Record<string, ToolInstallStatus>): Record<string, Pick<ToolInstallStatus, "installed" | "version" | "executable" | "error">>;
39
38
  export {};
@@ -1,2 +1,2 @@
1
- import{Router as H}from"express";import E from"axios";import{spawn as A}from"node:child_process";import{createHash as W,timingSafeEqual as G}from"node:crypto";import{fileURLToPath as V}from"node:url";import T from"node:path";import{adapterRegistry as J}from"../adapter/index.js";import{getBridgeVersion as R,resolveSchedulerBaseUrlFrom as Q}from"../config.js";import{validateToken as S,validateTokenOrPanelSession as v}from"../middleware/auth.js";import{getConfiguredConnectionKeys as _,getRegistrationState as Y,requestRuntimeAccessTokenRefreshForServer as Z,resolveSchedulerBaseUrlFromToken as ee}from"../services/auto-register.js";import{discoverCcSwitchConfiguredItems as te,loadCcSwitchSdk as re}from"../services/cc-switch-sdk.js";import{initInstance as se,syncLegacyStateFromSdk as oe}from"../services/instance-init-service.js";import{setAgentFeatures as ne,getAgentFeatures as x}from"../services/instance-features.js";import{createBridgeLifecycleOperation as C,deliverPendingBridgeLifecycleNotifications as L,loadLifecycleState as ae,removeBridgeLifecycleOperation as ie,upsertBridgeLifecycleOperation as b}from"../services/lifecycle-state.js";import{appendUpdateLog as p,readUpdateLog as ce}from"../services/update-log.js";import{checkBridgeUpdate as O}from"../utils/npm-version.js";import{loadInstanceState as $,saveInstanceState as q}from"../services/instance-state.js";import{getRuntimeAccessToken as le}from"../services/runtime-binding.js";import{detectToolStatuses as U,ensureToolsInstalled as de,SUPPORTED_INSTALLABLE_TOOLS as j,SUPPORTED_UNINSTALLABLE_TOOLS as F,uninstallTools as ue}from"../services/tool-installer.js";import{createLogger as ge}from"../utils/logger.js";const a=ge("instance");import{buildToolStatusDetectionTargets as fe}from"./instance-tool-status.js";let I=null;function We(r){I=r}const d=H();function P(r){return String(r||"").trim()||void 0}function D(r){const t=r.get("host");if(t)return`${r.protocol}://${t}`}function N(){const r=T.resolve(T.dirname(V(import.meta.url)),"..","..");return T.join(r,"dist","index.js")}function pe(){return new Promise((r,t)=>{const e=A(process.execPath,[N(),"update","--no-kill"],{shell:!1,windowsHide:!0});let s="",o="";e.stdout.on("data",n=>{s+=n.toString("utf8")}),e.stderr.on("data",n=>{o+=n.toString("utf8")}),e.on("error",t),e.on("close",n=>{r({exitCode:n,stdout:s,stderr:o})})})}function K(){const r=A(process.execPath,[N(),"service","restart"],{shell:!1,windowsHide:!0,stdio:["ignore","pipe","pipe"]});r.stdout.on("data",t=>{p(String(t)).catch(()=>{})}),r.stderr.on("data",t=>{p(String(t)).catch(()=>{})})}const M=3e3;async function me(r){const t={...r,status:"running",message:"Bridge \u66F4\u65B0\u6B63\u5728\u540E\u53F0\u6267\u884C\u3002"};await b(t);try{a.info("[update-bridge] \u6B63\u5728\u540E\u53F0\u6267\u884C awsb update --yes"),await p(`===== Bridge \u66F4\u65B0\u5F00\u59CB\uFF1Av${R()} -> latest\uFF08\u64CD\u4F5C ${r.operationId}\uFF09 =====`);const e=await pe();if(e.stdout&&await p(e.stdout),e.stderr&&await p(e.stderr),e.exitCode===0){await p("===== Bridge \u66F4\u65B0\u6210\u529F\uFF0C\u51C6\u5907\u81EA\u52A8\u91CD\u542F ===== ");const s={...t,status:"restarting",message:"Bridge \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F..."};await b(s),a.info("[update-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,I){I("BRIDGE_UPDATE_RESTART",!0).catch(o=>{const n=o;a.error("[update-bridge] graceful shutdown failed:",n),process.exit(42)});return}process.exit(42)},M)}else await p(`===== Bridge \u66F4\u65B0\u5931\u8D25\uFF1A\u9000\u51FA\u7801 ${e.exitCode??"unknown"} =====`),await b({...t,status:"failed",message:`Bridge \u66F4\u65B0\u5931\u8D25\uFF0Cnpm \u9000\u51FA\u7801: ${e.exitCode??"unknown"}`,error:e.stderr||e.stdout}),await L()}catch(e){const s=e;a.error("[update-bridge] background update failed:",s),await p(`===== Bridge \u66F4\u65B0\u5F02\u5E38\uFF1A${s.message} =====`).catch(()=>{}),await b({...t,status:"failed",message:"Bridge \u66F4\u65B0\u5931\u8D25\u3002",error:s.message||"update bridge failed"}),await L()}}async function z(r){const t=await import("node:fs/promises"),e=await import("node:path"),s=await import("node:os"),o=e.join(s.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");if(r){await t.mkdir(e.dirname(o),{recursive:!0}),await t.writeFile(o,JSON.stringify({preserveSessions:!0,timestamp:new Date().toISOString()}),"utf-8"),a.info(`[prepare-restart] \u5DF2\u521B\u5EFA\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6: ${o}`);return}try{await t.unlink(o),a.info("[prepare-restart] \u5DF2\u5220\u9664\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6")}catch{}}function he(r){return W("md5").update(r,"utf8").digest("hex")}function Se(r){const t=r.trim().toLowerCase();if(!/^[a-f0-9]{32}$/.test(t))return!1;const e=Buffer.from(t,"hex");return _().map(s=>s.trim()).filter(Boolean).some(s=>{const o=Buffer.from(he(s),"hex");return o.length===e.length&&G(o,e)})}function we(r){const e=_().length>0,s=R();return e?Se(r)?{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!0}}:{status:401,body:{ok:!1,error:"connection_key_mismatch",version:s,connectionKeyMatched:!1,connectionKeyRequired:!0}}:{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!1}}}function be(r,t){const s=t.trim()||"http://localhost:8080",o=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?(?:\/|$)/i.test(s);return{ok:!1,error:r.message||"scheduler ping failed",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:s,hint:o?"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u5728 bridge \u542F\u52A8\u73AF\u5883\u4E2D\u5C06 AWS_RUNTIME_SCHEDULER_BASE_URL \u914D\u7F6E\u4E3A\u8BE5\u5B9E\u4F8B\u53EF\u8BBF\u95EE\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\uFF0C\u4F8B\u5982 http://<server-host>:7380\u3002":"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u786E\u8BA4 AWS_RUNTIME_SCHEDULER_BASE_URL \u6307\u5411\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\u53EF\u4ECE bridge \u673A\u5668\u8BBF\u95EE\uFF0C\u5E76\u4E14\u8FD0\u884C\u65F6\u8BBF\u95EE\u4EE4\u724C\u4ECD\u6709\u6548\u3002"}}function ye(r){if(typeof r!="object"||r===null)return;const t=Reflect.get(r,"response");if(typeof t!="object"||t===null)return;const e=Reflect.get(t,"status");return typeof e=="number"?e:void 0}async function Ie(r,t){try{const e=await E.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":t}});return{schedulerReachable:e.status>=200&&e.status<300,tokenRefreshed:!1}}catch(e){if(ye(e)!==401)throw e;const s=await Z(r);if(!s.success||!s.runtimeAccessToken)throw e;const o=await E.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":s.runtimeAccessToken}});return{schedulerReachable:o.status>=200&&o.status<300,tokenRefreshed:!0}}}function Be(r){return{ok:!1,error:"ambiguous_scheduler_base_url",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:"",autoRegisterTargetUrls:r,hint:"Multiple autoRegisterTargets.serverUrl values were found, so bridge cannot safely infer which scheduler /runtime/ping should call back. Set AWS_RUNTIME_SCHEDULER_BASE_URL explicitly, or use future schedulerId/token-bound multi-scheduler routing."}}function ke(r,t){const e=r.filter(s=>t[s]?.installed);return e.length===0?"":e.map(s=>{const o=t[s],n=o?.error||o?.executable||"command is still available";return`${s}: ${n}`}).join("; ")}function B(r){return Object.fromEntries(Object.entries(r||{}).map(([t,e])=>[t,{installed:!!e?.installed,version:e?.version||null,executable:e?.executable||null,error:e?.error||null}]))}d.get("/check-update",async(r,t)=>{t.json(await O())}),d.get("/update-log",v,async(r,t)=>{try{const e=await ce();t.json({ok:!0,...e})}catch(e){const s=e;a.error("[update-log] Error:",s),t.status(500).json({ok:!1,error:s.message||"read update log failed"})}}),d.get("/healthz",(r,t)=>{t.json({ok:!0,runtimeBridge:"healthy"})}),d.get("/connection-check",(r,t)=>{const e=String(r.header("X-Bridge-Connection-Key-MD5")||""),s=we(e);t.status(s.status).json(s.body)}),d.get("/ping",S,async(r,t)=>{let e=Q(r.header("X-Scheduler-Base-Url"),r.header("X-Bridge-Instance-Id"),r.header("X-Bridge-Instance-Name"));if(e.source==="ambiguous-auto-register-targets"){const o=ee(r.header("X-Runtime-Token"));if(o)e={url:o,source:"token-match",ambiguousTargetUrls:[]};else{const n=r.header("X-Bridge-Instance-Id");if(n){const i=Y(),c=Object.entries(i.registrations).find(([,l])=>l===n)?.[0];c&&(e={url:c,source:"instance-id-match",ambiguousTargetUrls:[]})}if(!e.url||e.source==="ambiguous-auto-register-targets"){t.status(400).json(Be(e.ambiguousTargetUrls));return}}}const s=e.url;try{const o=le(s);if(!o){t.status(401).json({ok:!1,error:"runtime_access_token_required"});return}const n=await Ie(s,o);t.json({ok:!0,runtimeBridge:"healthy",version:R(),schedulerReachable:n.schedulerReachable,tokenRefreshed:n.tokenRefreshed,schedulerBaseUrl:s,instanceId:e.instanceId,instanceName:e.instanceName})}catch(o){const n=o;t.status(502).json(be(n,s))}}),d.post("/init-instance",S,async(r,t)=>{const{agentId:e,workspacePath:s,skillEnabled:o,mcpEnabled:n,ccSwitchEnabledTools:i,skillPackage:c,skillPackages:l,mcpServers:m}=r.body||{};if(!e||!s){t.status(400).json({error:"agentId and workspacePath are required"});return}try{a.info("[init-instance] Request received",{agentId:String(e),workspacePath:String(s),skillEnabled:o,mcpEnabled:n,ccSwitchEnabledTools:i});const u=await se(e,s,{skillEnabled:o,mcpEnabled:n,ccSwitchEnabledTools:i,skillPackage:c,skillPackages:l,mcpServers:m});a.info("[init-instance] Initialization completed",{agentId:String(e),ok:u.ok,logCount:u.logs?.length||0,enabledTools:u.enabledTools}),t.json(u)}catch(u){const g=u;a.error("[init-instance] Initialization failed",{agentId:String(e),workspacePath:String(s),error:g?.message||String(u),stack:g?.stack||null}),t.status(400).json({error:g?.message||"initialize instance failed"})}}),d.post("/features",S,async(r,t)=>{const{agentId:e,features:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}ne(String(e),s),a.info("[instance/features] \u80FD\u529B\u5F00\u5173\u5DF2\u66F4\u65B0",{agentId:String(e),features:x(String(e))});let o=0;for(const n of J.getAll())if(typeof n.applyAgentFeatures=="function")try{await n.applyAgentFeatures(String(e)),o+=1}catch(i){a.error("[instance/features] adapter \u70ED\u540C\u6B65\u5931\u8D25",{agentId:String(e),providerId:n.providerId,error:i?.message||String(i)})}t.json({ok:!0,agentId:String(e),features:x(String(e)),hotSyncedAdapters:o})}),d.post("/cc-switch/state",S,async(r,t)=>{const{agentId:e}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}try{a.info("[cc-switch/state] Request received",{agentId:String(e)});const s=await re(e),o=await te(s),i=(await oe(e,s)).state,c=fe(i.enabledTools||[]);a.info("[cc-switch/state] Detecting SDK statuses",{agentId:String(e),detectionTargets:c});const l=await U(c);a.info("[cc-switch/state] SDK status detection completed",{agentId:String(e),toolStatus:B(l),importedMcpCount:o.mcpServers,importedSkillCount:o.skills}),t.json({ok:!0,agentId:String(e),imported:{mcpServers:o.mcpServers,skills:o.skills},state:{...i,toolStatus:l}})}catch(s){const o=s;a.error("[cc-switch/state] Failed to load state",{agentId:String(e),error:o?.message||String(s),stack:o?.stack||null}),t.status(400).json({error:o?.message||"load state failed"})}}),d.post("/cc-switch/install-tools",S,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const o=Array.isArray(s)?s.map(c=>String(c||"").trim().toLowerCase()).filter(Boolean):[];a.info("[cc-switch/install-tools] Request received",{agentId:String(e),requestedTools:o});const n=new Set(j),i=o.filter(c=>n.has(c));if(a.info("[cc-switch/install-tools] Request normalized",{agentId:String(e),requestedTools:o,installableTools:i,supportedInstallableTools:j}),i.length===0){a.warn("[cc-switch/install-tools] No supported installable tools requested",{agentId:String(e),requestedTools:o}),t.status(400).json({error:`tools must include ${j.join(", ")}`});return}try{const c=await $(e),l=Array.from(new Set([...c.enabledTools||[],...i]));a.info("[cc-switch/install-tools] Starting installer",{agentId:String(e),installableTools:i,previousEnabledTools:c.enabledTools||[],nextEnabledTools:l});const m=await de(i);a.info("[cc-switch/install-tools] Installer completed",{agentId:String(e),toolStatus:B(m)});const u=await U(l);a.info("[cc-switch/install-tools] Refreshed enabled SDK statuses",{agentId:String(e),refreshedToolStatus:B(u)});const g={...u,...m},h=await q(e,{...c,enabledTools:l,toolStatus:g}),y=new Set(i),w=Object.entries(g).filter(([f])=>y.has(f)).filter(([,f])=>!f.installed).map(([f,k])=>({tool:f,error:k.error||null}));w.length>0&&a.warn("[cc-switch/install-tools] Some SDKs remain unavailable",{agentId:String(e),failedTools:w}),a.info("[cc-switch/install-tools] State saved",{agentId:String(e),enabledTools:h.enabledTools,toolStatus:B(g)}),t.json({ok:w.length===0,agentId:String(e),toolStatus:g,failedTools:w,state:h})}catch(c){const l=c;a.error("[cc-switch/install-tools] Install route failed",{agentId:String(e),requestedTools:o,installableTools:i,error:l?.message||String(c),stack:l?.stack||null}),t.status(400).json({error:l?.message||"install tools failed"})}}),d.post("/cc-switch/uninstall-tools",S,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const o=Array.isArray(s)?s.map(c=>String(c||"").trim().toLowerCase()).filter(Boolean):[],n=new Set(F),i=o.filter(c=>n.has(c));if(i.length===0){t.status(400).json({error:`tools must include ${F.join(", ")}`});return}try{const c=await $(e),l=new Set(i),m=(c.enabledTools||[]).filter(k=>!l.has(String(k||"").trim().toLowerCase())),u=await ue(i),h={...await U([...m,...i]),...u},y=ke(i,h),w=y?c.enabledTools||[]:m,f=await q(e,{...c,enabledTools:w,toolStatus:h});if(y){t.status(400).json({ok:!1,agentId:String(e),error:`uninstall incomplete: ${y}`,toolStatus:h,state:f});return}t.json({ok:!0,agentId:String(e),toolStatus:h,state:f})}catch(c){const l=c;t.status(400).json({error:l?.message||"uninstall tools failed"})}}),d.post("/prepare-restart",S,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{};try{a.info(`[prepare-restart] \u6536\u5230\u51C6\u5907\u91CD\u542F\u901A\u77E5\uFF0CpreserveSessions=${e}`),await z(!!e),t.json({ok:!0,preserveSessions:e,message:e?"Bridge will preserve sessions for aws-mcp-server restart":"Bridge will clean up sessions on shutdown"})}catch(s){const o=s;a.error("[prepare-restart] Error:",o),t.status(500).json({error:o.message})}});const Te={update:15*60*1e3,restart:5*60*1e3};async function Re(r){try{const t=await ae(),e=Date.now(),s=Te[r],o=[];for(const n of t.operations){if(n.operationType!==r||!["accepted","running","restarting"].includes(n.status))continue;const i=new Date(n.updatedAt).getTime();if(!Number.isNaN(i)&&e-i<=s)return{operationId:n.operationId};o.push(n.operationId)}for(const n of o)try{await ie(n),a.info(`[${r}-bridge] \u5DF2\u6E05\u7406\u8D85\u65F6\u672A\u4EA4\u4ED8\u7684\u9648\u65E7\u64CD\u4F5C: ${n}`)}catch(i){const c=i;a.warn(`[${r}-bridge] \u6E05\u7406\u9648\u65E7\u64CD\u4F5C\u5931\u8D25\uFF0C\u7EE7\u7EED\u653E\u884C: ${n}, ${c.message}`)}return null}catch(t){const e=t;return a.warn(`[${r}-bridge] \u5728\u9014\u64CD\u4F5C\u68C0\u67E5\u5931\u8D25\uFF0C\u653E\u884C\u8BF7\u6C42: ${e.message}`),null}}async function X(r,t,e){const s=await Re(r);return s?(e.status(409).json({error:t,operationId:s.operationId}),!0):!1}d.post("/update-bridge",v,async(r,t)=>{const e=P(r.body?.requestedByUserId);try{if(!e){t.status(400).json({error:"requestedByUserId is required"});return}if(await X("update","\u5B9E\u4F8B Bridge \u66F4\u65B0\u6B63\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u52FF\u91CD\u590D\u89E6\u53D1",t))return;const s=await O(),o=C({operationType:"update",requestedByUserId:e,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:D(r),status:"accepted",message:"Bridge \u66F4\u65B0\u8BF7\u6C42\u5DF2\u6536\u5230\uFF0C\u5C06\u5728\u540E\u53F0\u6267\u884C\u5E76\u81EA\u52A8\u91CD\u542F\u3002",latestVersion:s.ok&&s.latestVersion||void 0});await b(o),me(o),t.json({ok:!0,operationId:o.operationId,message:"Bridge \u66F4\u65B0\u5DF2\u5728\u540E\u53F0\u5F00\u59CB\uFF0C\u66F4\u65B0\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u91CD\u542F\u5B9E\u4F8B Bridge\u3002"})}catch(s){const o=s;a.error("[update-bridge] Error:",o),t.status(500).json({error:o.message||"update bridge failed"})}}),d.post("/restart-bridge",v,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{},s=P(r.body?.requestedByUserId);try{if(!s){t.status(400).json({error:"requestedByUserId is required"});return}if(await X("restart","\u5B9E\u4F8B Bridge \u6B63\u5728\u91CD\u542F\u4E2D\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5",t))return;a.info(`[restart-bridge] \u6536\u5230\u5B9E\u4F8B Bridge \u91CD\u542F\u8BF7\u6C42\uFF0CpreserveSessions=${e}`);const o=C({operationType:"restart",requestedByUserId:s,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:D(r),status:"accepted",message:"Bridge \u5DF2\u6536\u5230\u91CD\u542F\u8BF7\u6C42\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u53D1\u9001\u786E\u8BA4\u901A\u77E5\u3002"});await b(o),await z(!!e),t.json({ok:!0,operationId:o.operationId,preserveSessions:!!e,message:"Bridge \u6B63\u5728\u91CD\u542F\uFF0C\u670D\u52A1\u7BA1\u7406\u5668\u4F1A\u81EA\u52A8\u62C9\u8D77\u5B9E\u4F8B\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u901A\u8FC7\u6D88\u606F\u4E2D\u5FC3\u901A\u77E5\u7ED3\u679C\u3002"}),a.info("[restart-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,I){I("PANEL_RESTART",!!e).catch(n=>{const i=n;a.error("[restart-bridge] graceful shutdown failed:",i),process.exit(42)});return}process.exit(42)},M)}catch(o){const n=o;a.error("[restart-bridge] Error:",n),t.status(500).json({error:n.message||"restart bridge failed"})}});export{Be as buildAmbiguousSchedulerBaseUrlResponse,we as buildConnectionCheckResponse,be as buildSchedulerPingFailureResponse,ke as buildUninstallFailureMessage,d as instanceRouter,We as setGracefulShutdownFn,B as summarizeToolStatus};
1
+ import{spawn as A}from"node:child_process";import{createHash as W,timingSafeEqual as G}from"node:crypto";import I from"node:path";import{fileURLToPath as V}from"node:url";import _ from"axios";import{Router as J}from"express";import{adapterRegistry as Q}from"../adapter/index.js";import{getBridgeVersion as R,resolveSchedulerBaseUrlFrom as Y}from"../config.js";import{validateToken as h,validateTokenOrPanelSession as T}from"../middleware/auth.js";import{getConfiguredConnectionKeys as O,getRegistrationState as Z,requestRuntimeAccessTokenRefreshForServer as ee,resolveSchedulerBaseUrlFromToken as te}from"../services/auto-register.js";import{getEffective as v,getOverrides as U}from"../services/capability-config.js";import{setAgentFeatures as re,setAgentCapabilities as se,getAgentFeatures as x}from"../services/instance-features.js";import{initInstance as ne}from"../services/instance-init-service.js";import{loadInstanceState as j,saveInstanceState as L}from"../services/instance-state.js";import{createBridgeLifecycleOperation as C,deliverPendingBridgeLifecycleNotifications as P,loadLifecycleState as oe,removeBridgeLifecycleOperation as ae,upsertBridgeLifecycleOperation as b}from"../services/lifecycle-state.js";import{mcpDeployManager as ie}from"../services/mcp-deploy.js";import{pluginManager as ce}from"../services/plugin-manager.js";import{getRuntimeAccessToken as de}from"../services/runtime-binding.js";import{skillManager as le}from"../services/skill-manager.js";import{detectToolStatuses as E,ensureToolsInstalled as ue,SUPPORTED_INSTALLABLE_TOOLS as $,SUPPORTED_UNINSTALLABLE_TOOLS as D,uninstallTools as ge}from"../services/tool-installer.js";import{appendUpdateLog as m,readUpdateLog as pe}from"../services/update-log.js";import{createLogger as fe}from"../utils/logger.js";import{checkBridgeUpdate as N}from"../utils/npm-version.js";const c=fe("instance");import{buildToolStatusDetectionTargets as me}from"./instance-tool-status.js";let B=null;function Ye(r){B=r}const g=J();function M(r){return String(r||"").trim()||void 0}function F(r){const t=r.get("host");if(t)return`${r.protocol}://${t}`}function q(){const r=I.resolve(I.dirname(V(import.meta.url)),"..","..");return I.join(r,"dist","index.js")}function he(){return new Promise((r,t)=>{const e=A(process.execPath,[q(),"update","--no-kill"],{shell:!1,windowsHide:!0});let s="",n="";e.stdout.on("data",o=>{s+=o.toString("utf8")}),e.stderr.on("data",o=>{n+=o.toString("utf8")}),e.on("error",t),e.on("close",o=>{r({exitCode:o,stdout:s,stderr:n})})})}function K(){const r=A(process.execPath,[q(),"service","restart"],{shell:!1,windowsHide:!0,stdio:["ignore","pipe","pipe"]});r.stdout.on("data",t=>{m(String(t)).catch(()=>{})}),r.stderr.on("data",t=>{m(String(t)).catch(()=>{})})}const z=3e3;async function Se(r){const t={...r,status:"running",message:"Bridge \u66F4\u65B0\u6B63\u5728\u540E\u53F0\u6267\u884C\u3002"};await b(t);try{c.info("[update-bridge] \u6B63\u5728\u540E\u53F0\u6267\u884C awsb update --yes"),await m(`===== Bridge \u66F4\u65B0\u5F00\u59CB\uFF1Av${R()} -> latest\uFF08\u64CD\u4F5C ${r.operationId}\uFF09 =====`);const e=await he();if(e.stdout&&await m(e.stdout),e.stderr&&await m(e.stderr),e.exitCode===0){await m("===== Bridge \u66F4\u65B0\u6210\u529F\uFF0C\u51C6\u5907\u81EA\u52A8\u91CD\u542F ===== ");const s={...t,status:"restarting",message:"Bridge \u66F4\u65B0\u5B8C\u6210\uFF0C\u6B63\u5728\u91CD\u542F..."};await b(s),c.info("[update-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,B){B("BRIDGE_UPDATE_RESTART",!0).catch(n=>{const o=n;c.error("[update-bridge] graceful shutdown failed:",o),process.exit(42)});return}process.exit(42)},z)}else await m(`===== Bridge \u66F4\u65B0\u5931\u8D25\uFF1A\u9000\u51FA\u7801 ${e.exitCode??"unknown"} =====`),await b({...t,status:"failed",message:`Bridge \u66F4\u65B0\u5931\u8D25\uFF0Cnpm \u9000\u51FA\u7801: ${e.exitCode??"unknown"}`,error:e.stderr||e.stdout}),await P()}catch(e){const s=e;c.error("[update-bridge] background update failed:",s),await m(`===== Bridge \u66F4\u65B0\u5F02\u5E38\uFF1A${s.message} =====`).catch(()=>{}),await b({...t,status:"failed",message:"Bridge \u66F4\u65B0\u5931\u8D25\u3002",error:s.message||"update bridge failed"}),await P()}}async function X(r){const t=await import("node:fs/promises"),e=await import("node:path"),s=await import("node:os"),n=e.join(s.tmpdir(),"agentswork-runtime-bridge",".preserve-sessions");if(r){await t.mkdir(e.dirname(n),{recursive:!0}),await t.writeFile(n,JSON.stringify({preserveSessions:!0,timestamp:new Date().toISOString()}),"utf-8"),c.info(`[prepare-restart] \u5DF2\u521B\u5EFA\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6: ${n}`);return}try{await t.unlink(n),c.info("[prepare-restart] \u5DF2\u5220\u9664\u4FDD\u7559\u4F1A\u8BDD\u6807\u8BB0\u6587\u4EF6")}catch{}}function ye(r){return W("md5").update(r,"utf8").digest("hex")}function we(r){const t=r.trim().toLowerCase();if(!/^[a-f0-9]{32}$/.test(t))return!1;const e=Buffer.from(t,"hex");return O().map(s=>s.trim()).filter(Boolean).some(s=>{const n=Buffer.from(ye(s),"hex");return n.length===e.length&&G(n,e)})}function be(r){const e=O().length>0,s=R();return e?we(r)?{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!0}}:{status:401,body:{ok:!1,error:"connection_key_mismatch",version:s,connectionKeyMatched:!1,connectionKeyRequired:!0}}:{status:200,body:{ok:!0,runtimeBridge:"healthy",version:s,connectionKeyMatched:!0,connectionKeyRequired:!1}}}function ke(r,t){const s=t.trim()||"http://localhost:8080",n=/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?(?:\/|$)/i.test(s);return{ok:!1,error:r.message||"scheduler ping failed",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:s,hint:n?"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u5728 bridge \u542F\u52A8\u73AF\u5883\u4E2D\u5C06 AWS_RUNTIME_SCHEDULER_BASE_URL \u914D\u7F6E\u4E3A\u8BE5\u5B9E\u4F8B\u53EF\u8BBF\u95EE\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\uFF0C\u4F8B\u5982 http://<server-host>:7380\u3002":"aws-runtime-bridge \u5DF2\u8FDE\u901A\uFF0C\u4F46\u5B83\u56DE\u8FDE\u8C03\u5EA6\u4E2D\u5FC3\u5931\u8D25\u3002\u8BF7\u786E\u8BA4 AWS_RUNTIME_SCHEDULER_BASE_URL \u6307\u5411\u7684\u8C03\u5EA6\u4E2D\u5FC3\u5730\u5740\u53EF\u4ECE bridge \u673A\u5668\u8BBF\u95EE\uFF0C\u5E76\u4E14\u8FD0\u884C\u65F6\u8BBF\u95EE\u4EE4\u724C\u4ECD\u6709\u6548\u3002"}}function Be(r){if(typeof r!="object"||r===null)return;const t=Reflect.get(r,"response");if(typeof t!="object"||t===null)return;const e=Reflect.get(t,"status");return typeof e=="number"?e:void 0}async function Ie(r,t){try{const e=await _.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":t}});return{schedulerReachable:e.status>=200&&e.status<300,tokenRefreshed:!1}}catch(e){if(Be(e)!==401)throw e;const s=await ee(r);if(!s.success||!s.runtimeAccessToken)throw e;const n=await _.get(`${r}/api/runtime/ping`,{headers:{"X-Runtime-Token":s.runtimeAccessToken}});return{schedulerReachable:n.status>=200&&n.status<300,tokenRefreshed:!0}}}function Re(r){return{ok:!1,error:"ambiguous_scheduler_base_url",failureStage:"scheduler_ping",runtimeBridge:"healthy",schedulerBaseUrl:"",autoRegisterTargetUrls:r,hint:"Multiple autoRegisterTargets.serverUrl values were found, so bridge cannot safely infer which scheduler /runtime/ping should call back. Set AWS_RUNTIME_SCHEDULER_BASE_URL explicitly, or use future schedulerId/token-bound multi-scheduler routing."}}function Te(r){return Object.fromEntries(Object.entries(r||{}).map(([t,e])=>[t,{installed:!!e?.installed,version:e?.version||null,executable:e?.executable||null,error:e?.error||null}]))}g.get("/check-update",async(r,t)=>{t.json(await N())}),g.get("/update-log",T,async(r,t)=>{try{const e=await pe();t.json({ok:!0,...e})}catch(e){const s=e;c.error("[update-log] Error:",s),t.status(500).json({ok:!1,error:s.message||"read update log failed"})}}),g.get("/healthz",(r,t)=>{t.json({ok:!0,runtimeBridge:"healthy"})}),g.get("/connection-check",(r,t)=>{const e=String(r.header("X-Bridge-Connection-Key-MD5")||""),s=be(e);t.status(s.status).json(s.body)}),g.get("/ping",h,async(r,t)=>{let e=Y(r.header("X-Scheduler-Base-Url"),r.header("X-Bridge-Instance-Id"),r.header("X-Bridge-Instance-Name"));if(e.source==="ambiguous-auto-register-targets"){const n=te(r.header("X-Runtime-Token"));if(n)e={url:n,source:"token-match",ambiguousTargetUrls:[]};else{const o=r.header("X-Bridge-Instance-Id");if(o){const a=Z(),i=Object.entries(a.registrations).find(([,l])=>l===o)?.[0];i&&(e={url:i,source:"instance-id-match",ambiguousTargetUrls:[]})}if(!e.url||e.source==="ambiguous-auto-register-targets"){t.status(400).json(Re(e.ambiguousTargetUrls));return}}}const s=e.url;try{const n=de(s);if(!n){t.status(401).json({ok:!1,error:"runtime_access_token_required"});return}const o=await Ie(s,n);t.json({ok:!0,runtimeBridge:"healthy",version:R(),schedulerReachable:o.schedulerReachable,tokenRefreshed:o.tokenRefreshed,schedulerBaseUrl:s,instanceId:e.instanceId,instanceName:e.instanceName})}catch(n){const o=n;t.status(502).json(ke(o,s))}}),g.post("/init-instance",h,async(r,t)=>{const{agentId:e,workspacePath:s,skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a,skillPackage:i,skillPackages:l,pluginPackages:f,mcpServers:S}=r.body||{};if(!e||!s){t.status(400).json({error:"agentId and workspacePath are required"});return}try{c.info("[init-instance] Request received",{agentId:String(e),workspacePath:String(s),skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a});const u=await ne(e,s,{skillEnabled:n,mcpEnabled:o,ccSwitchEnabledTools:a,skillPackage:i,skillPackages:l,pluginPackages:f,mcpServers:S});c.info("[init-instance] Initialization completed",{agentId:String(e),ok:u.ok,logCount:u.logs?.length||0,enabledTools:u.enabledTools}),t.json(u)}catch(u){const p=u;c.error("[init-instance] Initialization failed",{agentId:String(e),workspacePath:String(s),error:p?.message||String(u),stack:p?.stack||null}),t.status(400).json({error:p?.message||"initialize instance failed"})}}),g.post("/features",h,async(r,t)=>{const{agentId:e,features:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}re(String(e),s),r.body.capabilities!==void 0&&se(String(e),r.body.capabilities),c.info("[instance/features] \u80FD\u529B\u5F00\u5173\u5DF2\u66F4\u65B0",{agentId:String(e),features:x(String(e))});let n=0;for(const o of Q.getAll())if(typeof o.applyAgentFeatures=="function")try{await o.applyAgentFeatures(String(e)),n+=1}catch(a){c.error("[instance/features] adapter \u70ED\u540C\u6B65\u5931\u8D25",{agentId:String(e),providerId:o.providerId,error:a?.message||String(a)})}t.json({ok:!0,agentId:String(e),features:x(String(e)),hotSyncedAdapters:n})}),g.post("/cc-switch/state",h,async(r,t)=>{const{agentId:e}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}try{c.info("[cc-switch/state] Request received",{agentId:String(e)});const s=await j(e),n=me(s.enabledTools||[]);c.info("[cc-switch/state] Detecting SDK statuses",{agentId:String(e),detectionTargets:n});const o=await E(n),a=await ce.listDeployed(),i=le.listDeployed(),l=ie.listDeployed(),f=U(e,"skills"),S=U(e,"mcp"),u=U(e,"plugins"),p=i.map(d=>({...d,enabled:v(e,"skills",d.skillName),source:f[d.skillName]!==void 0?"agent":"bridge"})),y=l.map(d=>({...d,enabled:v(e,"mcp",d.name),source:S[d.name]!==void 0?"agent":"bridge"})),w=a.map(d=>({...d,enabled:v(e,"plugins",d.pluginName),source:u[d.pluginName]!==void 0?"agent":"bridge"}));c.info("[cc-switch/state] SDK status detection completed",{agentId:String(e),toolStatus:Te(o)}),t.json({ok:!0,agentId:String(e),imported:{mcpServers:0,skills:0},deployedPlugins:w,deployedSkills:p,deployedMcp:y,state:{...s,toolStatus:o}})}catch(s){const n=s;c.error("[cc-switch/state] Failed to load state",{agentId:String(e),error:n?.message||String(s),stack:n?.stack||null}),t.status(400).json({error:n?.message||"load state failed"})}}),g.post("/tools/install",h,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const n=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[],o=new Set($),a=n.filter(i=>o.has(i));if(a.length===0){t.status(400).json({error:`tools must include ${$.join(", ")}`});return}try{const i=await j(e),l=Array.from(new Set([...i.enabledTools||[],...a])),f=await ue(a),u={...await E(l),...f},p=await L(e,{...i,enabledTools:l,toolStatus:u}),y=new Set(a),w=Object.entries(u).filter(([d])=>y.has(d)).filter(([,d])=>!d.installed).map(([d,k])=>({tool:d,error:k.error||null}));t.json({ok:w.length===0,agentId:String(e),toolStatus:u,failedTools:w,state:p})}catch(i){const l=i;t.status(400).json({error:l?.message||"install tools failed"})}}),g.post("/tools/uninstall",h,async(r,t)=>{const{agentId:e,tools:s}=r.body||{};if(!e){t.status(400).json({error:"agentId is required"});return}const n=Array.isArray(s)?s.map(i=>String(i||"").trim().toLowerCase()).filter(Boolean):[],o=new Set(D),a=n.filter(i=>o.has(i));if(a.length===0){t.status(400).json({error:`tools must include ${D.join(", ")}`});return}try{const i=await j(e),l=new Set(a),f=(i.enabledTools||[]).filter(k=>!l.has(String(k||"").trim().toLowerCase())),S=await ge(a),p={...await E([...f,...a]),...S},y=a.filter(k=>p[k]?.installed),w=y.length>0?i.enabledTools||[]:f,d=await L(e,{...i,enabledTools:w,toolStatus:p});if(y.length>0){t.status(400).json({ok:!1,agentId:String(e),error:"uninstall incomplete",toolStatus:p,state:d});return}t.json({ok:!0,agentId:String(e),toolStatus:p,state:d})}catch(i){const l=i;t.status(400).json({error:l?.message||"uninstall tools failed"})}}),g.post("/prepare-restart",h,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{};try{c.info(`[prepare-restart] \u6536\u5230\u51C6\u5907\u91CD\u542F\u901A\u77E5\uFF0CpreserveSessions=${e}`),await X(!!e),t.json({ok:!0,preserveSessions:e,message:e?"Bridge will preserve sessions for aws-mcp-server restart":"Bridge will clean up sessions on shutdown"})}catch(s){const n=s;c.error("[prepare-restart] Error:",n),t.status(500).json({error:n.message})}});const ve={update:15*60*1e3,restart:5*60*1e3};async function Ue(r){try{const t=await oe(),e=Date.now(),s=ve[r],n=[];for(const o of t.operations){if(o.operationType!==r||!["accepted","running","restarting"].includes(o.status))continue;const a=new Date(o.updatedAt).getTime();if(!Number.isNaN(a)&&e-a<=s)return{operationId:o.operationId};n.push(o.operationId)}for(const o of n)try{await ae(o),c.info(`[${r}-bridge] \u5DF2\u6E05\u7406\u8D85\u65F6\u672A\u4EA4\u4ED8\u7684\u9648\u65E7\u64CD\u4F5C: ${o}`)}catch(a){const i=a;c.warn(`[${r}-bridge] \u6E05\u7406\u9648\u65E7\u64CD\u4F5C\u5931\u8D25\uFF0C\u7EE7\u7EED\u653E\u884C: ${o}, ${i.message}`)}return null}catch(t){const e=t;return c.warn(`[${r}-bridge] \u5728\u9014\u64CD\u4F5C\u68C0\u67E5\u5931\u8D25\uFF0C\u653E\u884C\u8BF7\u6C42: ${e.message}`),null}}async function H(r,t,e){const s=await Ue(r);return s?(e.status(409).json({error:t,operationId:s.operationId}),!0):!1}g.post("/update-bridge",T,async(r,t)=>{const e=M(r.body?.requestedByUserId);try{if(!e){t.status(400).json({error:"requestedByUserId is required"});return}if(await H("update","\u5B9E\u4F8B Bridge \u66F4\u65B0\u6B63\u5728\u6267\u884C\u4E2D\uFF0C\u8BF7\u52FF\u91CD\u590D\u89E6\u53D1",t))return;const s=await N(),n=C({operationType:"update",requestedByUserId:e,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:F(r),status:"accepted",message:"Bridge \u66F4\u65B0\u8BF7\u6C42\u5DF2\u6536\u5230\uFF0C\u5C06\u5728\u540E\u53F0\u6267\u884C\u5E76\u81EA\u52A8\u91CD\u542F\u3002",latestVersion:s.ok&&s.latestVersion||void 0});await b(n),Se(n),t.json({ok:!0,operationId:n.operationId,message:"Bridge \u66F4\u65B0\u5DF2\u5728\u540E\u53F0\u5F00\u59CB\uFF0C\u66F4\u65B0\u5B8C\u6210\u540E\u5C06\u81EA\u52A8\u91CD\u542F\u5B9E\u4F8B Bridge\u3002"})}catch(s){const n=s;c.error("[update-bridge] Error:",n),t.status(500).json({error:n.message||"update bridge failed"})}}),g.post("/restart-bridge",T,async(r,t)=>{const{preserveSessions:e=!0}=r.body||{},s=M(r.body?.requestedByUserId);try{if(!s){t.status(400).json({error:"requestedByUserId is required"});return}if(await H("restart","\u5B9E\u4F8B Bridge \u6B63\u5728\u91CD\u542F\u4E2D\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5",t))return;c.info(`[restart-bridge] \u6536\u5230\u5B9E\u4F8B Bridge \u91CD\u542F\u8BF7\u6C42\uFF0CpreserveSessions=${e}`);const n=C({operationType:"restart",requestedByUserId:s,schedulerBaseUrl:r.body?.schedulerBaseUrl,runtimeBridgeBaseUrl:F(r),status:"accepted",message:"Bridge \u5DF2\u6536\u5230\u91CD\u542F\u8BF7\u6C42\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u53D1\u9001\u786E\u8BA4\u901A\u77E5\u3002"});await b(n),await X(!!e),t.json({ok:!0,operationId:n.operationId,preserveSessions:!!e,message:"Bridge \u6B63\u5728\u91CD\u542F\uFF0C\u670D\u52A1\u7BA1\u7406\u5668\u4F1A\u81EA\u52A8\u62C9\u8D77\u5B9E\u4F8B\uFF1B\u4E0B\u6B21\u542F\u52A8\u540E\u4F1A\u901A\u8FC7\u6D88\u606F\u4E2D\u5FC3\u901A\u77E5\u7ED3\u679C\u3002"}),c.info("[restart-bridge] \u6B63\u5728\u6267\u884C awsb service restart"),K(),setTimeout(()=>{if(process.exitCode=42,B){B("PANEL_RESTART",!!e).catch(o=>{const a=o;c.error("[restart-bridge] graceful shutdown failed:",a),process.exit(42)});return}process.exit(42)},z)}catch(n){const o=n;c.error("[restart-bridge] Error:",o),t.status(500).json({error:o.message||"restart bridge failed"})}});export{Re as buildAmbiguousSchedulerBaseUrlResponse,be as buildConnectionCheckResponse,ke as buildSchedulerPingFailureResponse,g as instanceRouter,Ye as setGracefulShutdownFn,Te as summarizeToolStatus};
2
2
 
@@ -1,4 +1,4 @@
1
- import{Router as M}from"express";import b from"node:fs/promises";import w from"node:path";import{validateToken as u}from"../middleware/auth.js";import{METRICS_HISTORY_CAPACITY as v}from"../services/launch-metrics.js";import{getLaunchManager as c}from"../services/launch-manager.js";import{getLaunchStreamHub as j}from"../services/launch-streams.js";import{createLogger as P}from"../utils/logger.js";const l=P("launch"),d=M(),k=3e5,I=20;d.put("/launch-configs/file",u,async(a,t)=>{try{const r=a.body||{},e=typeof r.workspacePath=="string"?r.workspacePath.trim():"";if(!e||!w.isAbsolute(e)){t.status(400).json({error:"workspacePath must be a non-empty absolute path"});return}if(!r.content||typeof r.content!="object"||Array.isArray(r.content)){t.status(400).json({error:"content must be an object"});return}const n=w.join(e,".agentswork","launcher","launcher-config.json");await b.mkdir(w.dirname(n),{recursive:!0});const s=`${n}.${process.pid}.tmp`;await b.writeFile(s,JSON.stringify(r.content,null,2)+`
1
+ import b from"node:fs/promises";import w from"node:path";import{Router as M}from"express";import{validateToken as u}from"../middleware/auth.js";import{getLaunchManager as c}from"../services/launch-manager.js";import{METRICS_HISTORY_CAPACITY as v}from"../services/launch-metrics.js";import{getLaunchStreamHub as j}from"../services/launch-streams.js";import{createLogger as P}from"../utils/logger.js";const l=P("launch"),d=M(),k=3e5,I=20;d.put("/launch-configs/file",u,async(a,t)=>{try{const r=a.body||{},e=typeof r.workspacePath=="string"?r.workspacePath.trim():"";if(!e||!w.isAbsolute(e)){t.status(400).json({error:"workspacePath must be a non-empty absolute path"});return}if(!r.content||typeof r.content!="object"||Array.isArray(r.content)){t.status(400).json({error:"content must be an object"});return}const n=w.join(e,".agentswork","launcher","launcher-config.json");await b.mkdir(w.dirname(n),{recursive:!0});const s=`${n}.${process.pid}.tmp`;await b.writeFile(s,JSON.stringify(r.content,null,2)+`
2
2
  `,"utf-8"),await b.rename(s,n),l.info(`[launch/file] \u542F\u52A8\u9879\u5FEB\u7167\u5DF2\u5199\u5165: ${n}`),t.json({ok:!0,path:n})}catch(r){const e=r;l.error("[launch/file] Error:",e),t.status(500).json({error:e.message})}}),d.get("/launch-configs/file",u,async(a,t)=>{try{const r=typeof a.query.workspacePath=="string"?a.query.workspacePath.trim():"";if(!r||!w.isAbsolute(r)){t.status(400).json({error:"workspacePath must be a non-empty absolute path"});return}const e=w.join(r,".agentswork","launcher","launcher-config.json");try{const n=await b.readFile(e,"utf-8");t.json({ok:!0,found:!0,path:e,content:JSON.parse(n)})}catch(n){if(n.code==="ENOENT"){t.json({ok:!0,found:!1,path:e});return}throw n}}catch(r){const e=r;l.error("[launch/file:read] Error:",e),t.status(500).json({error:e.message})}}),d.get("/launch-configs/runs",u,async(a,t)=>{try{const r=await c().listRuns();t.json({ok:!0,runs:r})}catch(r){const e=r;l.error("[launch/runs] Error:",e),t.status(500).json({error:e.message})}}),d.post("/launch-configs/:id/start",u,async(a,t)=>{const r=a.params.id;try{const e=a.body||{},n=Number(e.waitTimeoutMs),s=Number.isFinite(n)&&n>0?Math.min(n,k):0,o=await c().start({configId:r,command:e.command,cwd:e.cwd,env:e.env,jdkPath:e.jdkPath,workspacePath:e.workspacePath,readinessPattern:e.readinessPattern,startedBy:e.startedBy});if(s>0){const m=await c().waitStartupResult(r,s);t.json({ok:!0,run:o,wait:m});return}t.json({ok:!0,run:o})}catch(e){const n=e;l.warn(`[launch/start] configId=${r}, error=${n.message}`),t.status(400).json({error:n.message})}}),d.post("/launch-configs/:id/restart",u,async(a,t)=>{const r=a.params.id;try{const e=a.body||{},n=Number(e.waitTimeoutMs),s=Number.isFinite(n)&&n>0?Math.min(n,k):0,o=await c().restart({configId:r,command:e.command,cwd:e.cwd,env:e.env,jdkPath:e.jdkPath,workspacePath:e.workspacePath,readinessPattern:e.readinessPattern,startedBy:e.startedBy});if(s>0){const m=await c().waitStartupResult(r,s);t.json({ok:!0,run:o,wait:m});return}t.json({ok:!0,run:o})}catch(e){const n=e;l.warn(`[launch/restart] configId=${r}, error=${n.message}`),t.status(400).json({error:n.message})}}),d.post("/launch-configs/start-batch",u,async(a,t)=>{try{const r=a.body||{};if(!Array.isArray(r.items)||r.items.length===0){t.status(400).json({error:"items must be a non-empty array"});return}if(r.items.length>I){t.status(400).json({error:`items exceeds limit ${I}`});return}const e=Number(r.waitTimeoutMs),n=Number.isFinite(e)&&e>0?Math.min(e,k):0,s=await c().startBatch(r.items,n);t.json({ok:!0,...s})}catch(r){const e=r;l.warn(`[launch/start-batch] error=${e.message}`),t.status(400).json({error:e.message})}}),d.post("/launch-configs/stop-all",u,async(a,t)=>{try{const r=await c().stopAll();t.json({ok:!0,...r})}catch(r){const e=r;l.warn(`[launch/stop-all] error: ${e.message}`),t.status(500).json({error:e.message})}}),d.post("/launch-configs/:id/stop",u,async(a,t)=>{const r=a.params.id;try{const e=a.body?.actor,n=typeof e=="string"&&e.trim()?e.trim():void 0,s=await c().stop(r,"manual",n);t.json({ok:s.success,...s})}catch(e){const n=e;l.warn(`[launch/stop] configId=${r}, error=${n.message}`),t.status(400).json({error:n.message})}}),d.get("/launch-configs/:id/logs",u,async(a,t)=>{const r=a.params.id,e=Number(a.query.since)||0;try{const n=await c().getLogs(r,e);if(!n){t.status(404).json({error:"launch run not found"});return}t.json({ok:!0,...n})}catch(n){const s=n;l.error(`[launch/logs] configId=${r}, error:`,s),t.status(500).json({error:s.message})}}),d.get("/launch-configs/:id/metrics",u,async(a,t)=>{const r=a.params.id,e=Number(a.query.limit),n=Number.isFinite(e)&&e>0?Math.min(Math.floor(e),v):v;try{const s=c().getRun(r);if(!s){t.status(404).json({error:"launch run not found"});return}const o=c().getMetrics(r,n);t.json({ok:!0,configId:r,state:s.state,metrics:o})}catch(s){const o=s;l.error(`[launch/metrics] configId=${r}, error:`,o),t.status(500).json({error:o.message})}}),d.get("/launch-configs/:id/logs/stream",u,async(a,t)=>{const r=a.params.id;if(!c().getRun(r)){t.status(404).json({error:"launch run not found"});return}const n=Number(a.headers["last-event-id"]),s=Number.isFinite(n)&&n>=0?n:-1;t.on("error",()=>{});let o=null,m=null;try{t.writeHead(200,{"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"}),t.write(`: connected
3
3
 
4
4
  `);const g=h=>{t.destroyed||t.write(h)};let f=-1,y=!1;if(o=j().subscribe(r,"logs",h=>{if(t.destroyed)return;g(h),h.startsWith("event: run_state")&&(y=!0);const p=/^id: (\d+)\n/.exec(h);p&&(f=Math.max(f,Number(p[1])))}),a.on("close",()=>{o?.(),m&&clearInterval(m);try{t.end()}catch{}}),s>=-1){const h=await c().getLogs(r,Math.max(s,f));if(h)for(const p of h.entries)p.index<=f||g(`id: ${p.index}
@@ -0,0 +1,2 @@
1
+
2
+ export declare const mcpExtraRouter: import("express-serve-static-core").Router;
@@ -0,0 +1,3 @@
1
+ import{readFileSync as I}from"node:fs";import{Router as j}from"express";import{validateToken as o}from"../middleware/auth.js";import{getAgentMcpExtraFilePath as d}from"../services/instance-ai-config-service.js";import{atomicWriteFileSync as x}from"../utils/file-utils.js";import{createLogger as y}from"../utils/logger.js";const f=y("mcp-extra"),s=j(),v=/^[a-zA-Z0-9_.-]+$/;function u(n){return n!=="__proto__"&&v.test(n)}function c(n){try{const e=JSON.parse(I(d(n),"utf-8"));return e.servers&&typeof e.servers=="object"?e.servers:{}}catch{return{}}}function p(n,e){const t=d(n);x(t,`${JSON.stringify({version:1,servers:e},null,2)}
2
+ `)}function i(n){return(e,t)=>{try{n(e,t)}catch(r){f.error("[mcp-extra] %s %s \u5931\u8D25: %s",e.method,e.path,r instanceof Error?r.message:String(r)),t.headersSent||t.status(500).json({ok:!1,error:r instanceof Error?r.message:String(r)})}}}function g(n,e){const t=String(n.params.agentId??"").trim();if(!t){e.status(400).json({ok:!1,error:"agentId is required"});return}e.json({ok:!0,agentId:t,servers:c(t)})}function l(n,e){const t=String(n.params.agentId??"").trim(),r=String(n.params.name??"").trim(),a=n.body??{};if(!t||!r){e.status(400).json({ok:!1,error:"agentId and name are required"});return}if(!u(r)){e.status(400).json({ok:!1,error:`name \u975E\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5B57\u6BCD\u6570\u5B57 _ . -\uFF09: ${JSON.stringify(r)}`});return}if(typeof a!="object"||Array.isArray(a)){e.status(400).json({ok:!1,error:"body must be an MCP spec object"});return}const m=c(t);m[r]=a,p(t,m),f.info("[mcp-extra] agent=%s \u79C1\u6709 MCP \u5DF2\u4FDD\u5B58: %s",t,r),e.json({ok:!0,agentId:t,name:r,spec:a})}function S(n,e){const t=String(n.params.agentId??"").trim(),r=String(n.params.name??"").trim();if(!t||!r){e.status(400).json({ok:!1,error:"agentId and name are required"});return}if(!u(r)){e.status(400).json({ok:!1,error:`name \u975E\u6CD5\uFF08\u4EC5\u5141\u8BB8\u5B57\u6BCD\u6570\u5B57 _ . -\uFF09: ${JSON.stringify(r)}`});return}const a=c(t),m=r in a;delete a[r],p(t,a),e.json({ok:!0,agentId:t,name:r,existed:m})}s.get("/mcp-extra/:agentId",o,i(g)),s.put("/mcp-extra/:agentId/:name",o,i(l)),s.delete("/mcp-extra/:agentId/:name",o,i(S)),s.post("/mcp-extra/:agentId",o,i(g)),s.post("/mcp-extra/:agentId/:name/save",o,i(l)),s.post("/mcp-extra/:agentId/:name/delete",o,i(S));export{s as mcpExtraRouter};
3
+
@@ -1 +1,2 @@
1
+
1
2
  export declare const mcpRouter: import("express-serve-static-core").Router;
@@ -1,2 +1,2 @@
1
- import{Router as I}from"express";import{validateToken as p}from"../middleware/auth.js";import{discoverCcSwitchConfiguredItems as h,loadCcSwitchSdk as m,runCcSwitchAdapter as f}from"../services/cc-switch-sdk.js";import{syncLegacyStateFromSdk as u}from"../services/instance-init-service.js";import{normalizeSdkAppFlags as l,normalizeSdkMcpServerSpec as w}from"../utils/mcp-utils.js";const g=I(),y=new Set(["acode","claudecode","opencode","codex"]);g.post("/cc-switch/mcp/list",p,async(o,r)=>{const{agentId:e}=o.body||{};if(!e){r.status(400).json({error:"agentId is required"});return}try{const n=await m(e),t=await h(n),a=n.getAllMcpServers(),c=await u(e,n);r.json({ok:!0,agentId:String(e),imported:t,mcpServers:a,state:c.state,configPath:c.configPath})}catch(n){const t=n;r.status(400).json({error:t?.message||"list mcp failed"})}}),g.post("/cc-switch/mcp/get",p,async(o,r)=>{const{agentId:e,mcpId:n}=o.body||{};if(!e||!n){r.status(400).json({error:"agentId and mcpId are required"});return}try{const a=(await m(e)).getMcpServerById(String(n));if(!a){r.status(404).json({error:"mcp not found"});return}r.json({ok:!0,agentId:String(e),mcp:a})}catch(t){const a=t;r.status(400).json({error:a?.message||"get mcp failed"})}}),g.post("/cc-switch/mcp/create",p,async(o,r)=>{const{agentId:e,mcp:n}=o.body||{};if(!e){r.status(400).json({error:"agentId is required"});return}try{const t=String(n?.name||"").trim();if(!t)throw new Error("mcp.name is required");const a=await m(e),c={name:t,server:w(n),description:n?.description==null?void 0:String(n.description),apps:l(n?.apps)},s=await a.createMcpServer(c),d=await u(e,a),i=await f("create-mcp",e,s);r.json({ok:!0,agentId:String(e),mcp:s,state:d.state,configPath:d.configPath,adapterResult:i})}catch(t){const a=t;r.status(400).json({error:a?.message||"create mcp failed"})}}),g.post("/cc-switch/mcp/update",p,async(o,r)=>{const{agentId:e,mcpId:n,mcp:t}=o.body||{};if(!e||!n){r.status(400).json({error:"agentId and mcpId are required"});return}try{const a=await m(e),c={name:t?.name==null?void 0:String(t.name).trim(),server:t?.server||t?.transport||t?.command||t?.url||t?.args||t?.env||t?.headers?w(t):void 0,description:t?.description==null?void 0:String(t.description),apps:l(t?.apps)},s=await a.updateMcpServer(String(n),c),d=await u(e,a),i=await f("update-mcp",e,s);r.json({ok:!0,agentId:String(e),mcp:s,state:d.state,configPath:d.configPath,adapterResult:i})}catch(a){const c=a;r.status(400).json({error:c?.message||"update mcp failed"})}}),g.post("/cc-switch/mcp/toggle-app",p,async(o,r)=>{const{agentId:e,mcpId:n,appId:t,enabled:a}=o.body||{};if(!e||!n||!t){r.status(400).json({error:"agentId, mcpId and appId are required"});return}try{const c=String(t).trim().toLowerCase();if(!y.has(c)){r.status(400).json({error:"appId must be one of acode, claudecode, opencode, codex"});return}const s=await m(e),d=await s.toggleMcpApp(String(n),c,a===!0),i=await u(e,s),S=await f("toggle-mcp-app",e,d,s);r.json({ok:!0,agentId:String(e),mcp:d,state:i.state,configPath:i.configPath,adapterResult:S})}catch(c){const s=c;r.status(400).json({error:s?.message||"toggle mcp app failed"})}}),g.post("/cc-switch/mcp/delete",p,async(o,r)=>{const{agentId:e,mcpId:n}=o.body||{};if(!e||!n){r.status(400).json({error:"agentId and mcpId are required"});return}try{const t=await m(e),a=t.getMcpServerById(String(n));if(!a){r.status(404).json({error:"mcp not found"});return}await t.deleteMcpServer(String(n));const c=await u(e,t),s=await f("delete-mcp",e,a);r.json({ok:!0,agentId:String(e),removedMcp:a,state:c.state,configPath:c.configPath,adapterResult:s})}catch(t){const a=t;r.status(400).json({error:a?.message||"delete mcp failed"})}}),g.post("/cc-switch/add-mcp",p,async(o,r)=>{const{agentId:e,mcp:n}=o.body||{};if(!e){r.status(400).json({error:"agentId is required"});return}try{const t=String(n?.name||"").trim();if(!t)throw new Error("mcp.name is required");const a=await m(e),c={name:t,server:w(n),description:n?.description==null?void 0:String(n.description),apps:l(n?.apps)},s=await a.createMcpServer(c),d=await u(e,a),i=await f("create-mcp",e,s);r.json({ok:!0,agentId:String(e),mcp:s,state:d.state,configPath:d.configPath,adapterResult:i})}catch(t){const a=t;r.status(400).json({error:a?.message||"add mcp failed"})}}),g.post("/cc-switch/remove-mcp",p,async(o,r)=>{const{agentId:e,mcpId:n}=o.body||{};if(!e||!n){r.status(400).json({error:"agentId and mcpId are required"});return}try{const t=await m(e),a=t.getMcpServerById(String(n));if(!a){r.status(404).json({error:"mcp not found"});return}await t.deleteMcpServer(String(n));const c=await u(e,t),s=await f("delete-mcp",e,a);r.json({ok:!0,agentId:String(e),removedMcp:a,state:c.state,configPath:c.configPath,adapterResult:s})}catch(t){const a=t;r.status(400).json({error:a?.message||"remove mcp failed"})}});export{g as mcpRouter};
1
+ import{Router as f}from"express";import{validateToken as a}from"../middleware/auth.js";import{getEffective as u,setDefault as y,setOverride as g}from"../services/capability-config.js";import{mcpDeployManager as m}from"../services/mcp-deploy.js";import{createLogger as b}from"../utils/logger.js";const S=b("mcp"),c=f();function d(o){return(e,n)=>{o(e,n).catch(t=>{S.error("[mcp] %s %s \u5931\u8D25: %s",e.method,e.path,t.message),n.headersSent||n.status(500).json({ok:!1,error:t.message})})}}function v(o){if(!o||typeof o!="object")return null;const e=o,t={type:String(e.type||e.transport||"stdio").trim().toLowerCase()||"stdio"};return e.command!==null&&e.command!==void 0&&String(e.command).trim()&&(t.command=String(e.command).trim()),e.url!==null&&e.url!==void 0&&String(e.url).trim()&&(t.url=String(e.url).trim()),Array.isArray(e.args)&&(t.args=e.args.map(s=>String(s))),e.env&&typeof e.env=="object"&&(t.env=e.env),e.headers&&typeof e.headers=="object"&&(t.headers=e.headers),t}c.post("/mcp/deployed/list",a,d(async(o,e)=>{const t=m.listDeployed().map(s=>({...s,enabled:u("","mcp",s.name)}));e.json({ok:!0,deployedMcp:t})})),c.get("/mcp/deployed",a,d(async(o,e)=>{const t=m.listDeployed().map(s=>({...s,enabled:u("","mcp",s.name)}));e.json({ok:!0,deployedMcp:t})})),c.post("/mcp/deployed/default",a,d(async(o,e)=>{const n=String((o.body??{})?.name??"").trim();if(!n){e.status(400).json({ok:!1,error:"name is required"});return}const t=String((o.body??{})?.agentId??"").trim(),s=(o.body??{})?.enabled,r=s==null?null:!!s;t?g(t,"mcp",n,r):y("mcp",n,r),e.json({ok:!0,name:n,agentId:t,enabled:r})})),c.post("/mcp/deployed/save",a,d(async(o,e)=>{const{name:n,spec:t,defaultEnabled:s,sha256:r}=o.body??{},i=String(n??"").trim();if(!i){e.status(400).json({ok:!1,error:"name is required"});return}const p=v(t);if(!p){e.status(400).json({ok:!1,error:"spec \u975E\u6CD5"});return}const l=m.saveMcp(i,p,s!==!1,r?String(r):void 0);e.status(l.ok?200:400).json(l)})),c.post("/mcp/deployed/remove",a,d(async(o,e)=>{const n=String((o.body??{})?.name??"").trim(),t=m.removeMcp(n);e.status(t.ok?200:400).json(t)})),c.post("/mcp/cc-switch/list",a,d(async(o,e)=>{e.json({ok:!0,mcpServers:[],state:{skills:[],mcpServers:[]}})}));export{c as mcpRouter};
2
2
 
@@ -0,0 +1,2 @@
1
+
2
+ export declare const pluginsRouter: import("express-serve-static-core").Router;