shennian 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/README.md +3 -1
  2. package/dist/publish-build-manifest.json +273 -343
  3. package/dist/src/agents/command-spec.js +2 -2
  4. package/dist/src/agents/detect.js +1 -1
  5. package/dist/src/agents/model-registry/discovery.js +2 -2
  6. package/dist/src/agents/model-registry/parsers.d.ts +1 -0
  7. package/dist/src/agents/model-registry/parsers.js +4 -4
  8. package/dist/src/agents/native-capabilities.d.ts +10 -0
  9. package/dist/src/agents/native-capabilities.js +1 -0
  10. package/dist/src/agents/platform-instructions.js +5 -5
  11. package/dist/src/agents/workbuddy.d.ts +44 -0
  12. package/dist/src/agents/workbuddy.js +3 -0
  13. package/dist/src/commands/daemon.d.ts +1 -0
  14. package/dist/src/commands/daemon.js +9 -9
  15. package/dist/src/commands/integration.d.ts +2 -0
  16. package/dist/src/commands/integration.js +1 -0
  17. package/dist/src/commands/manager.js +1 -2
  18. package/dist/src/commands/pair-browser.d.ts +43 -0
  19. package/dist/src/commands/pair-browser.js +1 -0
  20. package/dist/src/commands/pair.d.ts +2 -0
  21. package/dist/src/commands/pair.js +11 -8
  22. package/dist/src/commands/room.d.ts +13 -0
  23. package/dist/src/commands/room.js +4 -0
  24. package/dist/src/commands/upgrade.d.ts +3 -0
  25. package/dist/src/commands/upgrade.js +1 -1
  26. package/dist/src/config/index.d.ts +3 -1
  27. package/dist/src/config/index.js +2 -1
  28. package/dist/src/daemon-ipc/client.d.ts +8 -0
  29. package/dist/src/daemon-ipc/client.js +3 -0
  30. package/dist/src/daemon-ipc/paths.d.ts +7 -0
  31. package/dist/src/daemon-ipc/paths.js +1 -0
  32. package/dist/src/daemon-ipc/protocol.d.ts +30 -0
  33. package/dist/src/daemon-ipc/protocol.js +1 -0
  34. package/dist/src/daemon-ipc/secret.d.ts +3 -0
  35. package/dist/src/daemon-ipc/secret.js +3 -0
  36. package/dist/src/daemon-ipc/server.d.ts +13 -0
  37. package/dist/src/daemon-ipc/server.js +3 -0
  38. package/dist/src/index.js +2 -2
  39. package/dist/src/integrations/claude-room-plugin-lifecycle.d.ts +47 -0
  40. package/dist/src/integrations/claude-room-plugin-lifecycle.js +1 -0
  41. package/dist/src/integrations/codex-room-plugin-lifecycle.d.ts +49 -0
  42. package/dist/src/integrations/codex-room-plugin-lifecycle.js +1 -0
  43. package/dist/src/integrations/room-plugin-bundles.d.ts +23 -0
  44. package/dist/src/integrations/room-plugin-bundles.js +1 -0
  45. package/dist/src/integrations/room-plugin-lifecycle-common.d.ts +17 -0
  46. package/dist/src/integrations/room-plugin-lifecycle-common.js +1 -0
  47. package/dist/src/integrations/room-plugin-shared.d.ts +23 -0
  48. package/dist/src/integrations/room-plugin-shared.js +2 -0
  49. package/dist/src/integrations/room-session-hook.d.ts +30 -0
  50. package/dist/src/integrations/room-session-hook.js +2 -0
  51. package/dist/src/integrations/workbuddy-plugin-bundle.d.ts +15 -0
  52. package/dist/src/integrations/workbuddy-plugin-bundle.js +1 -0
  53. package/dist/src/integrations/workbuddy-plugin-lifecycle.d.ts +52 -0
  54. package/dist/src/integrations/workbuddy-plugin-lifecycle.js +2 -0
  55. package/dist/src/integrations/workbuddy-session-hook.d.ts +22 -0
  56. package/dist/src/integrations/workbuddy-session-hook.js +1 -0
  57. package/dist/src/manager/prompt.d.ts +1 -1
  58. package/dist/src/manager/prompt.js +1 -1
  59. package/dist/src/manager/retired-external-channel-compat.d.ts +78 -0
  60. package/dist/src/manager/retired-external-channel-compat.js +1 -0
  61. package/dist/src/manager/runtime.d.ts +1 -3
  62. package/dist/src/manager/runtime.js +7 -7
  63. package/dist/src/relay/client.d.ts +2 -0
  64. package/dist/src/relay/client.js +1 -1
  65. package/dist/src/room/activation-audit.d.ts +15 -0
  66. package/dist/src/room/activation-audit.js +2 -0
  67. package/dist/src/room/activation-policy.d.ts +8 -0
  68. package/dist/src/room/activation-policy.js +1 -0
  69. package/dist/src/room/activation-service.d.ts +25 -0
  70. package/dist/src/room/activation-service.js +2 -0
  71. package/dist/src/room/attachment-cache.d.ts +40 -0
  72. package/dist/src/room/attachment-cache.js +2 -0
  73. package/dist/src/room/attachment-upload.d.ts +20 -0
  74. package/dist/src/room/attachment-upload.js +1 -0
  75. package/dist/src/room/authorized-action-coordinator.d.ts +40 -0
  76. package/dist/src/room/authorized-action-coordinator.js +1 -0
  77. package/dist/src/room/authorized-action-ipc.d.ts +11 -0
  78. package/dist/src/room/authorized-action-ipc.js +1 -0
  79. package/dist/src/room/device-authorization-client.d.ts +49 -0
  80. package/dist/src/room/device-authorization-client.js +1 -0
  81. package/dist/src/room/host-session-observation-ipc.d.ts +9 -0
  82. package/dist/src/room/host-session-observation-ipc.js +1 -0
  83. package/dist/src/room/host-session-observations.d.ts +54 -0
  84. package/dist/src/room/host-session-observations.js +2 -0
  85. package/dist/src/room/invite-bootstrap.d.ts +35 -0
  86. package/dist/src/room/invite-bootstrap.js +1 -0
  87. package/dist/src/room/invocation-token-ipc.d.ts +9 -0
  88. package/dist/src/room/invocation-token-ipc.js +1 -0
  89. package/dist/src/room/invocation-token.d.ts +53 -0
  90. package/dist/src/room/invocation-token.js +1 -0
  91. package/dist/src/room/jsonl-mirror.d.ts +73 -0
  92. package/dist/src/room/jsonl-mirror.js +6 -0
  93. package/dist/src/room/managed-room-session.d.ts +143 -0
  94. package/dist/src/room/managed-room-session.js +3 -0
  95. package/dist/src/room/mirror-sync-service.d.ts +33 -0
  96. package/dist/src/room/mirror-sync-service.js +1 -0
  97. package/dist/src/room/operator-ipc.d.ts +11 -0
  98. package/dist/src/room/operator-ipc.js +1 -0
  99. package/dist/src/room/pending-authorized-actions.d.ts +69 -0
  100. package/dist/src/room/pending-authorized-actions.js +3 -0
  101. package/dist/src/room/room-action-client.d.ts +208 -0
  102. package/dist/src/room/room-action-client.js +1 -0
  103. package/dist/src/room/room-action-ipc.d.ts +33 -0
  104. package/dist/src/room/room-action-ipc.js +1 -0
  105. package/dist/src/room/room-action-schema.d.ts +3 -0
  106. package/dist/src/room/room-action-schema.js +1 -0
  107. package/dist/src/room/room-authorized-action-executor.d.ts +23 -0
  108. package/dist/src/room/room-authorized-action-executor.js +1 -0
  109. package/dist/src/room/room-binding-client.d.ts +51 -0
  110. package/dist/src/room/room-binding-client.js +1 -0
  111. package/dist/src/room/room-binding-ipc.d.ts +29 -0
  112. package/dist/src/room/room-binding-ipc.js +1 -0
  113. package/dist/src/room/session-registry-ipc.d.ts +14 -0
  114. package/dist/src/room/session-registry-ipc.js +1 -0
  115. package/dist/src/room/session-registry.d.ts +128 -0
  116. package/dist/src/room/session-registry.js +2 -0
  117. package/dist/src/room/tool-schema.d.ts +114 -0
  118. package/dist/src/room/tool-schema.js +1 -0
  119. package/dist/src/room/tool-server.d.ts +5 -0
  120. package/dist/src/room/tool-server.js +3 -0
  121. package/dist/src/session/handlers/agent-capabilities.d.ts +3 -0
  122. package/dist/src/session/handlers/agent-capabilities.js +1 -0
  123. package/dist/src/session/handlers/agent-config.js +1 -1
  124. package/dist/src/session/handlers/chat.js +2 -2
  125. package/dist/src/session/handlers/control.js +1 -1
  126. package/dist/src/session/handlers/fs.d.ts +1 -0
  127. package/dist/src/session/handlers/fs.js +1 -1
  128. package/dist/src/session/manager.d.ts +16 -6
  129. package/dist/src/session/manager.js +1 -1
  130. package/dist/src/session/types.d.ts +5 -0
  131. package/dist/src/upgrade/engine.d.ts +14 -1
  132. package/dist/src/upgrade/engine.js +2 -2
  133. package/dist/src/upgrade/scheduler.d.ts +45 -0
  134. package/dist/src/upgrade/scheduler.js +1 -0
  135. package/node_modules/@shennian/wire/dist/agent-capabilities.d.ts +17 -0
  136. package/node_modules/@shennian/wire/dist/agent-capabilities.d.ts.map +1 -0
  137. package/node_modules/@shennian/wire/dist/agent-capabilities.js +2 -0
  138. package/node_modules/@shennian/wire/dist/agent-capabilities.js.map +1 -0
  139. package/node_modules/@shennian/wire/dist/index.d.ts +2 -1
  140. package/node_modules/@shennian/wire/dist/index.d.ts.map +1 -1
  141. package/node_modules/@shennian/wire/dist/index.js +2 -1
  142. package/node_modules/@shennian/wire/dist/index.js.map +1 -1
  143. package/node_modules/@shennian/wire/dist/machine.d.ts +1 -0
  144. package/node_modules/@shennian/wire/dist/machine.d.ts.map +1 -1
  145. package/node_modules/@shennian/wire/dist/methods.d.ts +1 -1
  146. package/node_modules/@shennian/wire/dist/methods.d.ts.map +1 -1
  147. package/node_modules/@shennian/wire/dist/room.d.ts +112 -0
  148. package/node_modules/@shennian/wire/dist/room.d.ts.map +1 -0
  149. package/node_modules/@shennian/wire/dist/room.js +4 -0
  150. package/node_modules/@shennian/wire/dist/room.js.map +1 -0
  151. package/node_modules/@shennian/wire/dist/session.d.ts +2 -2
  152. package/node_modules/@shennian/wire/dist/session.d.ts.map +1 -1
  153. package/node_modules/@shennian/wire/dist/session.js +1 -1
  154. package/node_modules/@shennian/wire/dist/session.js.map +1 -1
  155. package/package.json +3 -5
  156. package/dist/scripts/wechat-rpa-confirmation.mjs +0 -5
  157. package/dist/src/agents/pi-context.d.ts +0 -42
  158. package/dist/src/agents/pi-context.js +0 -12
  159. package/dist/src/agents/pi.d.ts +0 -70
  160. package/dist/src/agents/pi.js +0 -17
  161. package/dist/src/channels/base.d.ts +0 -144
  162. package/dist/src/channels/base.js +0 -1
  163. package/dist/src/channels/registry.d.ts +0 -8
  164. package/dist/src/channels/registry.js +0 -1
  165. package/dist/src/channels/reply-split.d.ts +0 -1
  166. package/dist/src/channels/reply-split.js +0 -10
  167. package/dist/src/channels/runtime.d.ts +0 -138
  168. package/dist/src/channels/runtime.js +0 -5
  169. package/dist/src/channels/secret-registry.d.ts +0 -35
  170. package/dist/src/channels/secret-registry.js +0 -1
  171. package/dist/src/channels/websocket.d.ts +0 -55
  172. package/dist/src/channels/websocket.js +0 -8
  173. package/dist/src/channels/wechat-channel/anchor.d.ts +0 -10
  174. package/dist/src/channels/wechat-channel/anchor.js +0 -1
  175. package/dist/src/channels/wechat-channel/automation-lane.d.ts +0 -35
  176. package/dist/src/channels/wechat-channel/automation-lane.js +0 -2
  177. package/dist/src/channels/wechat-channel/client.d.ts +0 -283
  178. package/dist/src/channels/wechat-channel/client.js +0 -1
  179. package/dist/src/channels/wechat-channel/cooldown.d.ts +0 -21
  180. package/dist/src/channels/wechat-channel/cooldown.js +0 -1
  181. package/dist/src/channels/wechat-channel/core/fixture-compare.d.ts +0 -52
  182. package/dist/src/channels/wechat-channel/core/fixture-compare.js +0 -1
  183. package/dist/src/channels/wechat-channel/core/media-action-plan.d.ts +0 -3
  184. package/dist/src/channels/wechat-channel/core/media-action-plan.js +0 -1
  185. package/dist/src/channels/wechat-channel/core/schema.d.ts +0 -67
  186. package/dist/src/channels/wechat-channel/core/schema.js +0 -1
  187. package/dist/src/channels/wechat-channel/core/trace-comparator.d.ts +0 -28
  188. package/dist/src/channels/wechat-channel/core/trace-comparator.js +0 -1
  189. package/dist/src/channels/wechat-channel/fingerprint.d.ts +0 -31
  190. package/dist/src/channels/wechat-channel/fingerprint.js +0 -1
  191. package/dist/src/channels/wechat-channel/helper-assets.d.ts +0 -103
  192. package/dist/src/channels/wechat-channel/helper-assets.js +0 -1
  193. package/dist/src/channels/wechat-channel/helper-client.d.ts +0 -87
  194. package/dist/src/channels/wechat-channel/helper-client.js +0 -3
  195. package/dist/src/channels/wechat-channel/helper-protocol.d.ts +0 -122
  196. package/dist/src/channels/wechat-channel/helper-protocol.js +0 -1
  197. package/dist/src/channels/wechat-channel/human-coordination.d.ts +0 -25
  198. package/dist/src/channels/wechat-channel/human-coordination.js +0 -1
  199. package/dist/src/channels/wechat-channel/index.d.ts +0 -21
  200. package/dist/src/channels/wechat-channel/index.js +0 -1
  201. package/dist/src/channels/wechat-channel/ledger.d.ts +0 -48
  202. package/dist/src/channels/wechat-channel/ledger.js +0 -2
  203. package/dist/src/channels/wechat-channel/media-cache-resolver.d.ts +0 -42
  204. package/dist/src/channels/wechat-channel/media-cache-resolver.js +0 -1
  205. package/dist/src/channels/wechat-channel/media-resolver.d.ts +0 -186
  206. package/dist/src/channels/wechat-channel/media-resolver.js +0 -1
  207. package/dist/src/channels/wechat-channel/message-key.d.ts +0 -19
  208. package/dist/src/channels/wechat-channel/message-key.js +0 -1
  209. package/dist/src/channels/wechat-channel/observer.d.ts +0 -171
  210. package/dist/src/channels/wechat-channel/observer.js +0 -7
  211. package/dist/src/channels/wechat-channel/outbound-ledger.d.ts +0 -96
  212. package/dist/src/channels/wechat-channel/outbound-ledger.js +0 -2
  213. package/dist/src/channels/wechat-channel/outbound-sender.d.ts +0 -74
  214. package/dist/src/channels/wechat-channel/outbound-sender.js +0 -1
  215. package/dist/src/channels/wechat-channel/pacing.d.ts +0 -3
  216. package/dist/src/channels/wechat-channel/pacing.js +0 -1
  217. package/dist/src/channels/wechat-channel/preflight.d.ts +0 -46
  218. package/dist/src/channels/wechat-channel/preflight.js +0 -1
  219. package/dist/src/channels/wechat-channel/runner.d.ts +0 -43
  220. package/dist/src/channels/wechat-channel/runner.js +0 -1
  221. package/dist/src/channels/wechat-channel/runtime.d.ts +0 -50
  222. package/dist/src/channels/wechat-channel/runtime.js +0 -1
  223. package/dist/src/channels/wechat-channel/scheduler.d.ts +0 -74
  224. package/dist/src/channels/wechat-channel/scheduler.js +0 -1
  225. package/dist/src/channels/wechat-channel/vector-store.d.ts +0 -44
  226. package/dist/src/channels/wechat-channel/vector-store.js +0 -1
  227. package/dist/src/channels/wechat-rpa/macos-flow.d.ts +0 -55
  228. package/dist/src/channels/wechat-rpa/macos-flow.js +0 -1
  229. package/dist/src/channels/wechat-rpa/macos.d.ts +0 -11
  230. package/dist/src/channels/wechat-rpa/macos.js +0 -21
  231. package/dist/src/channels/wechat-rpa/normalizer.d.ts +0 -49
  232. package/dist/src/channels/wechat-rpa/normalizer.js +0 -7
  233. package/dist/src/channels/wechat-rpa/product-channel.d.ts +0 -76
  234. package/dist/src/channels/wechat-rpa/product-channel.js +0 -16
  235. package/dist/src/channels/wechat-rpa-session-sync.d.ts +0 -26
  236. package/dist/src/channels/wechat-rpa-session-sync.js +0 -1
  237. package/dist/src/channels/wechat-rpa.d.ts +0 -104
  238. package/dist/src/channels/wechat-rpa.js +0 -6
  239. package/dist/src/channels/wecom.d.ts +0 -51
  240. package/dist/src/channels/wecom.js +0 -4
  241. package/dist/src/commands/external-attachments.d.ts +0 -9
  242. package/dist/src/commands/external-attachments.js +0 -1
  243. package/dist/src/commands/external.d.ts +0 -2
  244. package/dist/src/commands/external.js +0 -1
  245. package/dist/src/commands/helper-runtime-official-download.d.ts +0 -80
  246. package/dist/src/commands/helper-runtime-official-download.js +0 -1
  247. package/dist/src/commands/runtime.d.ts +0 -120
  248. package/dist/src/commands/runtime.js +0 -1
  249. package/dist/src/commands/wechat/command.d.ts +0 -3
  250. package/dist/src/commands/wechat/command.js +0 -1
  251. package/dist/src/commands/wechat/direct.d.ts +0 -14
  252. package/dist/src/commands/wechat/direct.js +0 -2
  253. package/dist/src/commands/wechat/doctor.d.ts +0 -2
  254. package/dist/src/commands/wechat/doctor.js +0 -1
  255. package/dist/src/commands/wechat/ipc.d.ts +0 -9
  256. package/dist/src/commands/wechat/ipc.js +0 -1
  257. package/dist/src/commands/wechat/operations.d.ts +0 -3
  258. package/dist/src/commands/wechat/operations.js +0 -4
  259. package/dist/src/commands/wechat/output.d.ts +0 -7
  260. package/dist/src/commands/wechat/output.js +0 -4
  261. package/dist/src/commands/wechat/types.d.ts +0 -142
  262. package/dist/src/commands/wechat/types.js +0 -1
  263. package/dist/src/commands/wechat/utils.d.ts +0 -16
  264. package/dist/src/commands/wechat/utils.js +0 -1
  265. package/dist/src/commands/wechat.d.ts +0 -6
  266. package/dist/src/commands/wechat.js +0 -1
  267. package/dist/src/devtools/wechat-channel-action-smoke.d.ts +0 -105
  268. package/dist/src/devtools/wechat-channel-action-smoke.js +0 -10
  269. package/dist/src/devtools/wechat-channel-download-report.d.ts +0 -111
  270. package/dist/src/devtools/wechat-channel-download-report.js +0 -2
  271. package/dist/src/devtools/wechat-channel-markdown-report.d.ts +0 -6
  272. package/dist/src/devtools/wechat-channel-markdown-report.js +0 -5
  273. package/dist/src/devtools/wechat-channel-product-steps.d.ts +0 -9
  274. package/dist/src/devtools/wechat-channel-product-steps.js +0 -40
  275. package/dist/src/session/handlers/skills.d.ts +0 -7
  276. package/dist/src/session/handlers/skills.js +0 -1
  277. package/dist/src/session/handlers/wechat-helper-runtime.d.ts +0 -33
  278. package/dist/src/session/handlers/wechat-helper-runtime.js +0 -1
  279. package/dist/src/skills/registry.d.ts +0 -16
  280. package/dist/src/skills/registry.js +0 -15
  281. package/dist/src/skills/setup.d.ts +0 -11
  282. package/dist/src/skills/setup.js +0 -1
@@ -1 +1 @@
1
- import d from"node:fs";import g from"node:os";import p from"node:path";import{convertMarkdownToPdf as C,defaultPdfOutputPath as j,MarkdownPdfBrowserMissingError as O}from"../../tools/markdown-to-pdf.js";import{createZipArchive as L}from"../archive-zip.js";import{BinaryTextPreviewError as B,decodeTextBufferAuto as U,isAutoTextEncoding as X}from"../../fs/text-decoder.js";const D="__roots__",Z=2e3,H=1024*1024*1024,W=5e3,V=1024*1024*1024;function E(e){return/^[A-Za-z]:([\\/]|$)/.test(e)||/^\\\\[^\\]+\\[^\\]+/.test(e)}function v(e){return E(e)?p.win32:p.posix}function T(e){const t=d.statSync(e);return{name:v(e).basename(e),path:e,isDir:t.isDirectory(),size:t.isFile()?t.size:void 0,modifiedAt:t.mtimeMs}}function Y(){if(g.platform()==="win32"){const e=[];for(let t=65;t<=90;t+=1){const r=`${String.fromCharCode(t)}:\\`;d.existsSync(r)&&e.push({name:r,path:r,isDir:!0})}return e}return[{name:"/",path:"/",isDir:!0}]}function G(e,t){const r=typeof e=="object"&&e&&"code"in e?String(e.code):"";return r==="ENOENT"?`Directory not found: ${t}`:r==="EACCES"||r==="EPERM"?`Permission denied: ${t}`:e instanceof Error?e.message:String(e)}function J(e){if(!e||e==="."||e.trim()!==e||p.posix.isAbsolute(e)||p.win32.isAbsolute(e))return!1;const t=e.replace(/\\/g,"/");return t!==e?!1:t.split("/").every(r=>r&&r!=="."&&r!==".."&&!M(r))}function $(e){const t=e.trim();if(!t||t!==e||e==="."||e===".."||M(e)||/[\\/:]/.test(e)||/[<>|"?*]/.test(e)||/[. ]$/.test(e))return!1;const r=e.split(".")[0]?.toUpperCase();return!(r&&/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/.test(r))}function M(e){return Array.from(e).some(t=>{const r=t.charCodeAt(0);return r>=0&&r<=31})}function K(e){return Array.isArray(e)?e.map(t=>({relativePath:String(t.relativePath||""),size:Number(t.size||0),mimeType:t.mimeType,modifiedAt:t.modifiedAt})):[]}async function ne(e,t){const r=t.params.path||g.homedir(),a=t.params.rootPath||r;if(r===D){e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:D,entries:Y()}});return}const n=e.resolveAuthorizedPath(r,a);if(!n.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:n.error});return}const s=n.path;try{const o=d.readdirSync(s,{withFileTypes:!0}),c=E(s)?p.win32.join:p.join,i=o.map(l=>({name:l.name,path:c(s,l.name),isDir:l.isDirectory()})).sort((l,f)=>l.isDir!==f.isDir?l.isDir?-1:1:l.name.localeCompare(f.name));e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:s,entries:i}})}catch(o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:G(o,s)})}}async function oe(e,t){const r=t.params.path,a=t.params.rootPath||r,n=e.resolveAuthorizedPath(r,a);if(!n.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:n.error});return}const s=n.path,o=t.params.encoding,c=typeof o=="string"?o:"utf8",i=t.params.offset,l=t.params.length;try{const f=d.statSync(s);if(!f.isFile()){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Not a file"});return}if(i!=null&&l!=null){const u=Math.min(l,Math.max(0,f.size-i));if(u<=0){e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{data:"",offset:i,length:0,totalSize:f.size,path:s}});return}const P=d.openSync(s,"r");try{const k=Buffer.alloc(u),S=d.readSync(P,k,0,u,i);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{data:k.subarray(0,S).toString("base64"),offset:i,length:S,totalSize:f.size,path:s}})}finally{d.closeSync(P)}return}const y=t.params.maxSize||(c==="base64"?5*1024*1024:512*1024);if(f.size>y){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`File too large: ${f.size} bytes (max ${y})`,payload:{size:f.size,path:s}});return}if(c==="base64"){const u=d.readFileSync(s);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{data:u.toString("base64"),path:s,size:f.size}});return}if(X(c)){const u=d.readFileSync(s),P=U(u);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{content:P.content,path:s,size:f.size,encoding:P.encoding,encodingFallback:P.fallback}});return}const m=d.readFileSync(s,"utf-8");e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{content:m,path:s,size:f.size}})}catch(f){e.client.sendRes({type:"res",id:t.id,ok:!1,error:f instanceof B?f.message:String(f)})}}async function ie(e,t){const r=t.params.path,a=t.params.content,n=t.params.rootPath||r;if(!r||typeof a!="string"){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path and content are required"});return}const s=e.resolveAuthorizedPath(r,n);if(!s.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:s.error});return}try{const o=d.existsSync(s.path)?d.statSync(s.path):null;if(o&&!o.isFile()){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Not a file"});return}d.writeFileSync(s.path,a,"utf-8");const c=d.statSync(s.path);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:s.path,size:c.size,modifiedAt:c.mtimeMs}})}catch(o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(o)})}}async function de(e,t){const r=t.params.path,a=t.params.newName;if(!r||!a){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path and newName are required"});return}if(!$(a)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid newName"});return}const n=v(r),s=t.params.rootPath||n.dirname(r),o=e.resolveAuthorizedPath(r,s);if(!o.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:o.error});return}try{const c=v(o.path),i=c.join(c.dirname(o.path),a),l=e.resolveAuthorizedPath(i,s);if(!l.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:l.error});return}if(d.existsSync(l.path)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Target already exists"});return}d.renameSync(o.path,l.path),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{oldPath:o.path,newPath:l.path,entry:T(l.path)}})}catch(c){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(c)})}}async function ce(e,t){const r=t.params.path,a=t.params.rootPath||p.dirname(r||"."),n=typeof t.params.title=="string"?t.params.title:void 0;if(!r){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path is required"});return}const s=e.resolveAuthorizedPath(r,a);if(!s.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:s.error});return}if(!/\.mdx?$/i.test(s.path)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Only Markdown files can be exported to PDF"});return}const o=j(s.path),c=e.resolveAuthorizedPath(o,a);if(!c.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:c.error});return}try{const i=await C(s.path,{outputPath:c.path,title:n});e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{sourcePath:s.path,outputPath:i.outputPath,entry:T(i.outputPath)}})}catch(i){if(i instanceof O){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"This machine needs the PDF export component before Markdown files can be exported to PDF.",payload:i.setup});return}e.client.sendRes({type:"res",id:t.id,ok:!1,error:i instanceof Error?i.message:String(i)})}}function Q(e){let t="";for(const a of e.trim())a.charCodeAt(0)<=31||'<>:"/\\|?*'.includes(a)?t.endsWith("-")||(t+="-"):t+=a;return t.replace(/[. ]+$/g,"")||"folder"}async function le(e,t){const r=t.params.path,a=t.params.rootPath||r;if(!r){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path is required"});return}const n=e.resolveAuthorizedPath(r,a);if(!n.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:n.error});return}try{if(!d.statSync(n.path).isDirectory()){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Not a directory"});return}const o=v(n.path),c=Q(o.basename(n.path)),i=p.join(g.tmpdir(),"shennian-archives"),l=p.join(i,`${c}-${Date.now()}-${Math.random().toString(36).slice(2,8)}.zip`),f=L(n.path,l,{maxFiles:W,maxTotalSize:V});e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{sourcePath:n.path,outputPath:f.outputPath,entry:T(f.outputPath),fileCount:f.fileCount,totalSize:f.totalSize}})}catch(s){e.client.sendRes({type:"res",id:t.id,ok:!1,error:s instanceof Error?s.message:String(s)})}}async function fe(e,t){const{name:r,targetPath:a,data:n,direct:s}=t.params;if(!r||!n){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"name and data are required"});return}try{const o=t.params.rootPath||a||g.homedir(),c=e.resolveAuthorizedPath(a||o,o);if(!c.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:c.error});return}const i=c.path,l=s?i:p.join(i,".uploads");s||d.mkdirSync(l,{recursive:!0});const f=p.join(l,p.basename(r)),y=Buffer.from(n,"base64");d.writeFileSync(f,y),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:f}})}catch(o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(o)})}}async function pe(e,t){const{name:r,targetPath:a,totalSize:n,direct:s,kind:o,baseName:c}=t.params,i=K(t.params.manifest),l=o==="folder",f=l&&c||r;if(!f||!l&&!n){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"name and totalSize are required"});return}try{const y=t.params.rootPath||a||g.homedir(),m=e.resolveAuthorizedPath(a||y,y);if(!m.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:m.error});return}const u=m.path,P=s?u:p.join(u,".uploads");s||d.mkdirSync(P,{recursive:!0});const k=`tf-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;if(l){if(!i.length){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"manifest is required for folder uploads"});return}if(i.length>Z){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Too many files: ${i.length}`});return}const x=p.basename(f);if(!$(x)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid folder name"});return}const I=p.join(P,x),R=e.resolveAuthorizedPath(I,y);if(!R.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:R.error});return}const b=new Set;let z=0;const A=new Map;for(const h of i){if(!J(h.relativePath)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Invalid relativePath: ${h.relativePath}`});return}if(!Number.isFinite(h.size)||h.size<0){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Invalid size: ${h.relativePath}`});return}if(b.has(h.relativePath)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Duplicate relativePath: ${h.relativePath}`});return}if(b.add(h.relativePath),z+=h.size,z>H){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Folder too large: ${z} bytes`});return}const _=p.join(R.path,...h.relativePath.split("/")),F=e.resolveAuthorizedPath(_,y);if(!F.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:F.error});return}const w=p.join(g.tmpdir(),`.shennian-upload-${k}-${A.size}`);d.writeFileSync(w,Buffer.alloc(0)),A.set(h.relativePath,{relativePath:h.relativePath,tempPath:w,targetPath:F.path,size:h.size})}e.pendingTransfers.set(k,{tempPath:"",targetPath:R.path,totalSize:z,kind:"folder",rootPath:y,targetDir:R.path,files:A}),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{transferId:k,path:R.path}});return}const S=p.join(g.tmpdir(),`.shennian-upload-${k}`),N=p.join(P,p.basename(f));d.writeFileSync(S,Buffer.alloc(0)),e.pendingTransfers.set(k,{tempPath:S,targetPath:N,totalSize:n,kind:"file"}),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{transferId:k}})}catch(y){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(y)})}}async function he(e,t){const{transferId:r,offset:a,data:n,relativePath:s}=t.params,o=e.pendingTransfers.get(r);if(!o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid transferId"});return}try{const c=o.kind==="folder"?o.files?.get(String(s||"")):{tempPath:o.tempPath,size:o.totalSize};if(!c){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid relativePath"});return}const i=Buffer.from(n,"base64");if(a<0||a+i.length>c.size){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Chunk exceeds declared size"});return}const l=d.openSync(c.tempPath,"r+");try{d.writeSync(l,i,0,i.length,a)}finally{d.closeSync(l)}e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{written:i.length}})}catch(c){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(c)})}}async function ye(e,t){const{transferId:r}=t.params,a=e.pendingTransfers.get(r);if(!a){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid transferId"});return}try{if(a.kind==="folder"){let n=0;for(const s of a.files?.values()??[])d.mkdirSync(p.dirname(s.targetPath),{recursive:!0}),d.renameSync(s.tempPath,s.targetPath),n+=1;e.pendingTransfers.delete(r),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:a.targetDir??a.targetPath,count:n}});return}d.renameSync(a.tempPath,a.targetPath),e.pendingTransfers.delete(r),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:a.targetPath}})}catch{try{d.copyFileSync(a.tempPath,a.targetPath),d.unlinkSync(a.tempPath),e.pendingTransfers.delete(r),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:a.targetPath}})}catch(n){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(n)})}}}async function ue(e,t){const{transferId:r}=t.params,a=e.pendingTransfers.get(r);if(a){const n=a.kind==="folder"?Array.from(a.files?.values()??[]).map(s=>s.tempPath):[a.tempPath];for(const s of n)try{s&&d.unlinkSync(s)}catch{}e.pendingTransfers.delete(r)}e.client.sendRes({type:"res",id:t.id,ok:!0})}function Pe(e){for(const[,t]of e.pendingTransfers){const r=t.kind==="folder"?Array.from(t.files?.values()??[]).map(a=>a.tempPath):[t.tempPath];for(const a of r)try{a&&d.unlinkSync(a)}catch{}}e.pendingTransfers.clear()}export{Pe as cleanupPendingTransfers,le as handleFsArchiveZip,ce as handleFsExportMarkdownPdf,ne as handleFsLs,oe as handleFsRead,de as handleFsRename,fe as handleFsTransfer,ue as handleFsTransferAbort,he as handleFsTransferChunk,ye as handleFsTransferFinish,pe as handleFsTransferStart,ie as handleFsWrite};
1
+ import d from"node:fs";import g from"node:os";import p from"node:path";import{convertMarkdownToPdf as _,defaultPdfOutputPath as j,findChromiumExecutable as O,installManagedChromium as L,managedChromiumBrowsersPath as B,MarkdownPdfBrowserMissingError as U}from"../../tools/markdown-to-pdf.js";import{createZipArchive as X}from"../archive-zip.js";import{BinaryTextPreviewError as Z,decodeTextBufferAuto as H,isAutoTextEncoding as W}from"../../fs/text-decoder.js";const D="__roots__",V=2e3,Y=1024*1024*1024,G=5e3,J=1024*1024*1024;function E(e){return/^[A-Za-z]:([\\/]|$)/.test(e)||/^\\\\[^\\]+\\[^\\]+/.test(e)}function v(e){return E(e)?p.win32:p.posix}function x(e){const t=d.statSync(e);return{name:v(e).basename(e),path:e,isDir:t.isDirectory(),size:t.isFile()?t.size:void 0,modifiedAt:t.mtimeMs}}function K(){if(g.platform()==="win32"){const e=[];for(let t=65;t<=90;t+=1){const r=`${String.fromCharCode(t)}:\\`;d.existsSync(r)&&e.push({name:r,path:r,isDir:!0})}return e}return[{name:"/",path:"/",isDir:!0}]}function Q(e,t){const r=typeof e=="object"&&e&&"code"in e?String(e.code):"";return r==="ENOENT"?`Directory not found: ${t}`:r==="EACCES"||r==="EPERM"?`Permission denied: ${t}`:e instanceof Error?e.message:String(e)}function q(e){if(!e||e==="."||e.trim()!==e||p.posix.isAbsolute(e)||p.win32.isAbsolute(e))return!1;const t=e.replace(/\\/g,"/");return t!==e?!1:t.split("/").every(r=>r&&r!=="."&&r!==".."&&!$(r))}function M(e){const t=e.trim();if(!t||t!==e||e==="."||e===".."||$(e)||/[\\/:]/.test(e)||/[<>|"?*]/.test(e)||/[. ]$/.test(e))return!1;const r=e.split(".")[0]?.toUpperCase();return!(r&&/^(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])$/.test(r))}function $(e){return Array.from(e).some(t=>{const r=t.charCodeAt(0);return r>=0&&r<=31})}function ee(e){return Array.isArray(e)?e.map(t=>({relativePath:String(t.relativePath||""),size:Number(t.size||0),mimeType:t.mimeType,modifiedAt:t.modifiedAt})):[]}async function de(e,t){const r=t.params.path||g.homedir(),a=t.params.rootPath||r;if(r===D){e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:D,entries:K()}});return}const n=e.resolveAuthorizedPath(r,a);if(!n.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:n.error});return}const s=n.path;try{const o=d.readdirSync(s,{withFileTypes:!0}),c=E(s)?p.win32.join:p.join,i=o.map(l=>({name:l.name,path:c(s,l.name),isDir:l.isDirectory()})).sort((l,f)=>l.isDir!==f.isDir?l.isDir?-1:1:l.name.localeCompare(f.name));e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:s,entries:i}})}catch(o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:Q(o,s)})}}async function ce(e,t){const r=t.params.path,a=t.params.rootPath||r,n=e.resolveAuthorizedPath(r,a);if(!n.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:n.error});return}const s=n.path,o=t.params.encoding,c=typeof o=="string"?o:"utf8",i=t.params.offset,l=t.params.length;try{const f=d.statSync(s);if(!f.isFile()){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Not a file"});return}if(i!=null&&l!=null){const u=Math.min(l,Math.max(0,f.size-i));if(u<=0){e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{data:"",offset:i,length:0,totalSize:f.size,path:s}});return}const P=d.openSync(s,"r");try{const k=Buffer.alloc(u),S=d.readSync(P,k,0,u,i);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{data:k.subarray(0,S).toString("base64"),offset:i,length:S,totalSize:f.size,path:s}})}finally{d.closeSync(P)}return}const y=t.params.maxSize||(c==="base64"?5*1024*1024:512*1024);if(f.size>y){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`File too large: ${f.size} bytes (max ${y})`,payload:{size:f.size,path:s}});return}if(c==="base64"){const u=d.readFileSync(s);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{data:u.toString("base64"),path:s,size:f.size}});return}if(W(c)){const u=d.readFileSync(s),P=H(u);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{content:P.content,path:s,size:f.size,encoding:P.encoding,encodingFallback:P.fallback}});return}const R=d.readFileSync(s,"utf-8");e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{content:R,path:s,size:f.size}})}catch(f){e.client.sendRes({type:"res",id:t.id,ok:!1,error:f instanceof Z?f.message:String(f)})}}async function le(e,t){const r=t.params.path,a=t.params.content,n=t.params.rootPath||r;if(!r||typeof a!="string"){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path and content are required"});return}const s=e.resolveAuthorizedPath(r,n);if(!s.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:s.error});return}try{const o=d.existsSync(s.path)?d.statSync(s.path):null;if(o&&!o.isFile()){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Not a file"});return}d.writeFileSync(s.path,a,"utf-8");const c=d.statSync(s.path);e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:s.path,size:c.size,modifiedAt:c.mtimeMs}})}catch(o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(o)})}}async function fe(e,t){const r=t.params.path,a=t.params.newName;if(!r||!a){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path and newName are required"});return}if(!M(a)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid newName"});return}const n=v(r),s=t.params.rootPath||n.dirname(r),o=e.resolveAuthorizedPath(r,s);if(!o.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:o.error});return}try{const c=v(o.path),i=c.join(c.dirname(o.path),a),l=e.resolveAuthorizedPath(i,s);if(!l.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:l.error});return}if(d.existsSync(l.path)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Target already exists"});return}d.renameSync(o.path,l.path),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{oldPath:o.path,newPath:l.path,entry:x(l.path)}})}catch(c){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(c)})}}async function pe(e,t){const r=t.params.path,a=t.params.rootPath||p.dirname(r||"."),n=typeof t.params.title=="string"?t.params.title:void 0;if(!r){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path is required"});return}const s=e.resolveAuthorizedPath(r,a);if(!s.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:s.error});return}if(!/\.mdx?$/i.test(s.path)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Only Markdown files can be exported to PDF"});return}const o=j(s.path),c=e.resolveAuthorizedPath(o,a);if(!c.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:c.error});return}try{const i=await _(s.path,{outputPath:c.path,title:n});e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{sourcePath:s.path,outputPath:i.outputPath,entry:x(i.outputPath)}})}catch(i){if(i instanceof U){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"This machine needs the PDF export component before Markdown files can be exported to PDF.",payload:i.setup});return}e.client.sendRes({type:"res",id:t.id,ok:!1,error:i instanceof Error?i.message:String(i)})}}async function he(e,t){try{await L();const r=await O();e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{ready:!0,browserPath:r,managedPath:B()}})}catch(r){e.client.sendRes({type:"res",id:t.id,ok:!1,error:r instanceof Error?r.message:String(r)})}}function te(e){let t="";for(const a of e.trim())a.charCodeAt(0)<=31||'<>:"/\\|?*'.includes(a)?t.endsWith("-")||(t+="-"):t+=a;return t.replace(/[. ]+$/g,"")||"folder"}async function ye(e,t){const r=t.params.path,a=t.params.rootPath||r;if(!r){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"path is required"});return}const n=e.resolveAuthorizedPath(r,a);if(!n.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:n.error});return}try{if(!d.statSync(n.path).isDirectory()){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Not a directory"});return}const o=v(n.path),c=te(o.basename(n.path)),i=p.join(g.tmpdir(),"shennian-archives"),l=p.join(i,`${c}-${Date.now()}-${Math.random().toString(36).slice(2,8)}.zip`),f=X(n.path,l,{maxFiles:G,maxTotalSize:J});e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{sourcePath:n.path,outputPath:f.outputPath,entry:x(f.outputPath),fileCount:f.fileCount,totalSize:f.totalSize}})}catch(s){e.client.sendRes({type:"res",id:t.id,ok:!1,error:s instanceof Error?s.message:String(s)})}}async function ue(e,t){const{name:r,targetPath:a,data:n,direct:s}=t.params;if(!r||!n){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"name and data are required"});return}try{const o=t.params.rootPath||a||g.homedir(),c=e.resolveAuthorizedPath(a||o,o);if(!c.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:c.error});return}const i=c.path,l=s?i:p.join(i,".uploads");s||d.mkdirSync(l,{recursive:!0});const f=p.join(l,p.basename(r)),y=Buffer.from(n,"base64");d.writeFileSync(f,y),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:f}})}catch(o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(o)})}}async function Pe(e,t){const{name:r,targetPath:a,totalSize:n,direct:s,kind:o,baseName:c}=t.params,i=ee(t.params.manifest),l=o==="folder",f=l&&c||r;if(!f||!l&&!n){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"name and totalSize are required"});return}try{const y=t.params.rootPath||a||g.homedir(),R=e.resolveAuthorizedPath(a||y,y);if(!R.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:R.error});return}const u=R.path,P=s?u:p.join(u,".uploads");s||d.mkdirSync(P,{recursive:!0});const k=`tf-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;if(l){if(!i.length){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"manifest is required for folder uploads"});return}if(i.length>V){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Too many files: ${i.length}`});return}const T=p.basename(f);if(!M(T)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid folder name"});return}const C=p.join(P,T),m=e.resolveAuthorizedPath(C,y);if(!m.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:m.error});return}const b=new Set;let z=0;const A=new Map;for(const h of i){if(!q(h.relativePath)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Invalid relativePath: ${h.relativePath}`});return}if(!Number.isFinite(h.size)||h.size<0){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Invalid size: ${h.relativePath}`});return}if(b.has(h.relativePath)){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Duplicate relativePath: ${h.relativePath}`});return}if(b.add(h.relativePath),z+=h.size,z>Y){e.client.sendRes({type:"res",id:t.id,ok:!1,error:`Folder too large: ${z} bytes`});return}const I=p.join(m.path,...h.relativePath.split("/")),F=e.resolveAuthorizedPath(I,y);if(!F.ok){e.client.sendRes({type:"res",id:t.id,ok:!1,error:F.error});return}const w=p.join(g.tmpdir(),`.shennian-upload-${k}-${A.size}`);d.writeFileSync(w,Buffer.alloc(0)),A.set(h.relativePath,{relativePath:h.relativePath,tempPath:w,targetPath:F.path,size:h.size})}e.pendingTransfers.set(k,{tempPath:"",targetPath:m.path,totalSize:z,kind:"folder",rootPath:y,targetDir:m.path,files:A}),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{transferId:k,path:m.path}});return}const S=p.join(g.tmpdir(),`.shennian-upload-${k}`),N=p.join(P,p.basename(f));d.writeFileSync(S,Buffer.alloc(0)),e.pendingTransfers.set(k,{tempPath:S,targetPath:N,totalSize:n,kind:"file"}),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{transferId:k}})}catch(y){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(y)})}}async function ke(e,t){const{transferId:r,offset:a,data:n,relativePath:s}=t.params,o=e.pendingTransfers.get(r);if(!o){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid transferId"});return}try{const c=o.kind==="folder"?o.files?.get(String(s||"")):{tempPath:o.tempPath,size:o.totalSize};if(!c){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid relativePath"});return}const i=Buffer.from(n,"base64");if(a<0||a+i.length>c.size){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Chunk exceeds declared size"});return}const l=d.openSync(c.tempPath,"r+");try{d.writeSync(l,i,0,i.length,a)}finally{d.closeSync(l)}e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{written:i.length}})}catch(c){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(c)})}}async function ge(e,t){const{transferId:r}=t.params,a=e.pendingTransfers.get(r);if(!a){e.client.sendRes({type:"res",id:t.id,ok:!1,error:"Invalid transferId"});return}try{if(a.kind==="folder"){let n=0;for(const s of a.files?.values()??[])d.mkdirSync(p.dirname(s.targetPath),{recursive:!0}),d.renameSync(s.tempPath,s.targetPath),n+=1;e.pendingTransfers.delete(r),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:a.targetDir??a.targetPath,count:n}});return}d.renameSync(a.tempPath,a.targetPath),e.pendingTransfers.delete(r),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:a.targetPath}})}catch{try{d.copyFileSync(a.tempPath,a.targetPath),d.unlinkSync(a.tempPath),e.pendingTransfers.delete(r),e.client.sendRes({type:"res",id:t.id,ok:!0,payload:{path:a.targetPath}})}catch(n){e.client.sendRes({type:"res",id:t.id,ok:!1,error:String(n)})}}}async function me(e,t){const{transferId:r}=t.params,a=e.pendingTransfers.get(r);if(a){const n=a.kind==="folder"?Array.from(a.files?.values()??[]).map(s=>s.tempPath):[a.tempPath];for(const s of n)try{s&&d.unlinkSync(s)}catch{}e.pendingTransfers.delete(r)}e.client.sendRes({type:"res",id:t.id,ok:!0})}function Re(e){for(const[,t]of e.pendingTransfers){const r=t.kind==="folder"?Array.from(t.files?.values()??[]).map(a=>a.tempPath):[t.tempPath];for(const a of r)try{a&&d.unlinkSync(a)}catch{}}e.pendingTransfers.clear()}export{Re as cleanupPendingTransfers,ye as handleFsArchiveZip,pe as handleFsExportMarkdownPdf,he as handleFsExportMarkdownPdfSetup,de as handleFsLs,ce as handleFsRead,fe as handleFsRename,ue as handleFsTransfer,me as handleFsTransferAbort,ke as handleFsTransferChunk,ge as handleFsTransferFinish,Pe as handleFsTransferStart,le as handleFsWrite};
@@ -1,18 +1,21 @@
1
- import type { ReqFrame } from '@shennian/wire';
1
+ import type { AgentType, ReqFrame } from '@shennian/wire';
2
2
  import type { CliRelayClient } from '../relay/client.js';
3
+ import type { UpgradePolicyController } from './types.js';
4
+ import type { UpgradeIdleState } from '../upgrade/scheduler.js';
3
5
  import type { NativeSessionFusionService } from '../native-fusion/service.js';
4
6
  import '../agents/claude.js';
5
7
  import '../agents/codex.js';
8
+ import '../agents/workbuddy.js';
6
9
  import '../agents/gemini.js';
7
10
  import '../agents/cursor.js';
8
11
  import '../agents/opencode.js';
9
- import '../agents/pi.js';
10
12
  import '../agents/manager.js';
11
13
  export { resolveSessionWorkDir } from '../fs/boundary.js';
12
14
  export declare class SessionManager {
13
15
  private client;
14
16
  private nativeFusion;
15
17
  private cliVersion?;
18
+ private upgradePolicyController;
16
19
  private sessions;
17
20
  /** Track processed request IDs to deduplicate replayed offline messages */
18
21
  private processedReqIds;
@@ -23,13 +26,20 @@ export declare class SessionManager {
23
26
  private managerRuntime;
24
27
  private chatQueue;
25
28
  private activityProbeTimer;
26
- private wechatRuntimeStatusTimer;
27
- private wechatRuntimeStatusInFlight;
28
- constructor(client: CliRelayClient, nativeFusion?: NativeSessionFusionService | null, cliVersion?: string | undefined);
29
+ private activeRequests;
30
+ constructor(client: CliRelayClient, nativeFusion?: NativeSessionFusionService | null, cliVersion?: string | undefined, upgradePolicyController?: UpgradePolicyController | null);
29
31
  private getRuntime;
32
+ getUpgradeIdleState(): UpgradeIdleState;
33
+ activateRoomSession(input: {
34
+ sessionId: string;
35
+ agentType: AgentType;
36
+ agentSessionId: string;
37
+ workDir: string;
38
+ text: string;
39
+ clientMessageId: string;
40
+ }): Promise<void>;
30
41
  private publishSessionActivity;
31
42
  private publishManagedActivitySnapshots;
32
- private publishWeChatRuntimeStatus;
33
43
  private reloadCustomAgents;
34
44
  handleReq(req: ReqFrame): Promise<void>;
35
45
  private evictIdleSessions;
@@ -1 +1 @@
1
- import{getRegisteredAgents as r,unregisterAgent as o}from"../agents/adapter.js";import{loadConfig as h}from"../config/index.js";import{handleUpgradeStart as c,handleUpgradeStatus as l}from"../commands/upgrade.js";import{handleAgentsRefresh as u,handleModelsRefresh as d}from"./handlers/agents.js";import{handleAgentConfigClear as m,handleAgentConfigGet as p,handleAgentConfigTest as f,handleAgentConfigUpsert as g}from"./handlers/agent-config.js";import{handleChatAbort as w,handleChatSend as b}from"./handlers/chat.js";import{handleSessionRefresh as k}from"./handlers/session-refresh.js";import{handleSessionToolDetail as S}from"./handlers/tool-detail.js";import{handleSessionTitleSet as v}from"./handlers/title.js";import{cleanupPendingTransfers as R,handleFsLs as A,handleFsRead as y,handleFsRename as T,handleFsWrite as I,handleFsTransfer as P,handleFsTransferAbort as F,handleFsTransferChunk as C,handleFsTransferFinish as M,handleFsTransferStart as Q,handleFsExportMarkdownPdf as x,handleFsArchiveZip as D}from"./handlers/fs.js";import{handleSkillDoctor as W,handleSkillInstall as z,handleSkillList as E,handleSkillSetup as U,handleSkillUse as V}from"./handlers/skills.js";import{handleRegionProbe as O,handleRegionSwitch as L,handleUpgradeSetPolicy as _}from"./handlers/control.js";import{handleWeChatHelperRuntime as $,runHelperRuntimeAction as j}from"./handlers/wechat-helper-runtime.js";import{ManagerRuntimeService as G,setManagerRuntimeService as n}from"../manager/runtime.js";import{ChatQueueManager as H}from"./queue.js";import{createAuthorizedFsRoot as N,resolveAuthorizedPath as X,resolveSessionWorkDir as Z}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/pi.js";import"../agents/manager.js";import{registerCustomAgent as B}from"../agents/custom.js";const J=50;import{resolveSessionWorkDir as Te}from"../fs/boundary.js";class Re{client;nativeFusion;cliVersion;sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;activityProbeTimer=null;wechatRuntimeStatusTimer=null;wechatRuntimeStatusInFlight=!1;constructor(e,t=null,a){this.client=e,this.nativeFusion=t,this.cliVersion=a,this.managerRuntime=new G({getRuntime:()=>this.getRuntime(),dispatchReq:s=>this.handleReq(s)}),this.chatQueue=new H({getRuntime:()=>this.getRuntime(),dispatchReq:s=>this.handleReq(s)}),n(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents(),this.activityProbeTimer=setInterval(()=>{this.publishManagedActivitySnapshots().catch(s=>{console.error("[session.activity] managed probe failed",s)})},15e3),this.activityProbeTimer.unref?.(),this.publishWeChatRuntimeStatus(),this.wechatRuntimeStatusTimer=setInterval(()=>{this.publishWeChatRuntimeStatus()},3e4),this.wechatRuntimeStatusTimer.unref?.()}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)}}}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(!t.currentRunId||!t.adapter.getStatus)continue;const a=await t.adapter.getStatus().catch(()=>null);if(!a?.active||!a.runPhase)continue;const s=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:a.runId||t.currentRunId,runPhase:a.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:s,canStop:a.canStop??!0});const i=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:a.runId||t.currentRunId,seq:i,runPhase:a.runPhase,canStop:a.canStop??!0},seq:i,id:`agent-status-${a.runId||t.currentRunId}-${Date.now()}`})}}async publishWeChatRuntimeStatus(){if(!this.wechatRuntimeStatusInFlight){this.wechatRuntimeStatusInFlight=!0;try{await j({action:"status"})}catch(e){console.error("[wechat-runtime.status] projection failed",e)}finally{this.wechatRuntimeStatusInFlight=!1}}}reloadCustomAgents(){for(const t of r())t.startsWith("custom:")&&o(t);const e=h();for(const[t,a]of Object.entries(e.customAgents??{}))B(t,a)}async handleReq(e){const t=this.getRuntime();try{switch(e.method){case"chat.send":await b(t,e);break;case"chat.enqueue":await this.chatQueue.handleEnqueue(e);break;case"chat.queue.get":await this.chatQueue.handleGet(e);break;case"chat.queue.edit":await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":await this.chatQueue.handleDelete(e);break;case"chat.abort":await w(t,e);break;case"session.refresh":await k(t,e);break;case"session.tool.detail":await S(t,e);break;case"session.title.set":await v(t,e);break;case"fs.ls":await A(t,e);break;case"fs.read":await y(t,e);break;case"fs.write":await I(t,e);break;case"fs.export.markdown-pdf":await x(t,e);break;case"fs.archive.zip":await D(t,e);break;case"fs.rename":await T(t,e);break;case"skill.list":await E(t,e);break;case"skill.install":await z(t,e);break;case"skill.doctor":await W(t,e);break;case"skill.setup":await U(t,e);break;case"skill.use":await V(t,e);break;case"fs.transfer":await P(t,e);break;case"fs.transfer.start":await Q(t,e);break;case"fs.transfer.chunk":await C(t,e);break;case"fs.transfer.finish":await M(t,e);break;case"fs.transfer.abort":await F(t,e);break;case"region.probe":await O(t,e);break;case"region.switch":await L(t,e);break;case"upgrade.start":await c(this.client,e.id,e.params.version,{currentVersion:this.cliVersion});break;case"upgrade.status":await l(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await _(t,e);break;case"agents.refresh":await u(t,e);break;case"models.refresh":await d(t,e);break;case"agent.config.get":await p(t,e);break;case"agent.config.upsert":await g(t,e);break;case"agent.config.clear":await m(t,e);break;case"agent.config.test":await f(t,e);break;case"manager.channel.get":case"manager.channel.upsert":case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":await t.managerRuntime?.handleAppReq(e);break;case"wechat-rpa.helper.runtime":await $(t,e);break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(a){this.client.sendRes({type:"res",id:e.id,ok:!1,error:a instanceof Error?a.message:String(a)})}}evictIdleSessions(){if(this.sessions.size<J)return;let e=null;for(const[t,a]of this.sessions)(!e||a.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:a});e&&(e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return Z(e)}resolveAuthorizedPath(e,t){return X(e,N(t))}async cleanup(){this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null),this.wechatRuntimeStatusTimer&&(clearInterval(this.wechatRuntimeStatusTimer),this.wechatRuntimeStatusTimer=null);for(const[,e]of this.sessions)e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),R(this.getRuntime()),await this.managerRuntime.stop(),n(null)}}export{Re as SessionManager,Te as resolveSessionWorkDir};
1
+ import{getRegisteredAgents as o,unregisterAgent as c}from"../agents/adapter.js";import{loadConfig as h}from"../config/index.js";import{handleUpgradeStart as l,handleUpgradeStatus as u}from"../commands/upgrade.js";import{handleAgentsRefresh as d,handleModelsRefresh as p}from"./handlers/agents.js";import{handleAgentCapabilitiesList as m}from"./handlers/agent-capabilities.js";import{handleAgentConfigClear as f,handleAgentConfigGet as g,handleAgentConfigTest as b,handleAgentConfigUpsert as w}from"./handlers/agent-config.js";import{handleChatAbort as v,handleChatSend as n}from"./handlers/chat.js";import{handleSessionRefresh as k}from"./handlers/session-refresh.js";import{handleSessionToolDetail as R}from"./handlers/tool-detail.js";import{handleSessionTitleSet as S}from"./handlers/title.js";import{cleanupPendingTransfers as y,handleFsLs as A,handleFsRead as T,handleFsRename as P,handleFsWrite as I,handleFsTransfer as C,handleFsTransferAbort as F,handleFsTransferChunk as M,handleFsTransferFinish as x,handleFsTransferStart as Q,handleFsExportMarkdownPdf as z,handleFsExportMarkdownPdfSetup as D,handleFsArchiveZip as E}from"./handlers/fs.js";import{handleRegionProbe as U,handleRegionSwitch as V,handleUpgradeSetPolicy as O}from"./handlers/control.js";import{ManagerRuntimeService as W,setManagerRuntimeService as r}from"../manager/runtime.js";import{ChatQueueManager as _}from"./queue.js";import{createAuthorizedFsRoot as j,resolveAuthorizedPath as L,resolveSessionWorkDir as $}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/workbuddy.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/manager.js";import{registerCustomAgent as G}from"../agents/custom.js";const N=50;import{resolveSessionWorkDir as ve}from"../fs/boundary.js";class ge{client;nativeFusion;cliVersion;upgradePolicyController;sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;activityProbeTimer=null;activeRequests=0;constructor(e,t=null,s,i=null){this.client=e,this.nativeFusion=t,this.cliVersion=s,this.upgradePolicyController=i,this.managerRuntime=new W({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a)}),this.chatQueue=new _({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a)}),r(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents(),this.activityProbeTimer=setInterval(()=>{this.publishManagedActivitySnapshots().catch(a=>{console.error("[session.activity] managed probe failed",a)})},15e3),this.activityProbeTimer.unref?.()}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)},upgradePolicyController:this.upgradePolicyController}}getUpgradeIdleState(){const e=[];return[...this.sessions.values()].some(t=>t.currentRunId!==null)&&e.push("active-agent-turn"),this.pendingTransfers.size>0&&e.push("file-transfer"),this.activeRequests>0&&e.push("active-daemon-request"),{idle:e.length===0,reasons:e}}async activateRoomSession(e){const t=new Proxy(this.client,{get:(s,i)=>{if(i==="sendRes")return()=>{};const a=Reflect.get(s,i,s);return typeof a=="function"?a.bind(s):a}});await n({...this.getRuntime(),client:t},{type:"req",id:e.clientMessageId,method:"chat.send",params:{...e,waitForDispatch:!0}})}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(!t.currentRunId||!t.adapter.getStatus)continue;const s=await t.adapter.getStatus().catch(()=>null);if(!s?.active||!s.runPhase)continue;const i=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:s.runId||t.currentRunId,runPhase:s.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:i,canStop:s.canStop??!0});const a=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:s.runId||t.currentRunId,seq:a,runPhase:s.runPhase,canStop:s.canStop??!0},seq:a,id:`agent-status-${s.runId||t.currentRunId}-${Date.now()}`})}}reloadCustomAgents(){for(const t of o())t.startsWith("custom:")&&c(t);const e=h();for(const[t,s]of Object.entries(e.customAgents??{}))G(t,s)}async handleReq(e){const t=this.getRuntime();this.activeRequests++;try{switch(e.method){case"chat.send":await n(t,e);break;case"chat.enqueue":await this.chatQueue.handleEnqueue(e);break;case"chat.queue.get":await this.chatQueue.handleGet(e);break;case"chat.queue.edit":await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":await this.chatQueue.handleDelete(e);break;case"chat.abort":await v(t,e);break;case"session.refresh":await k(t,e);break;case"session.tool.detail":await R(t,e);break;case"session.title.set":await S(t,e);break;case"fs.ls":await A(t,e);break;case"fs.read":await T(t,e);break;case"fs.write":await I(t,e);break;case"fs.export.markdown-pdf":await z(t,e);break;case"fs.export.markdown-pdf.setup":await D(t,e);break;case"fs.archive.zip":await E(t,e);break;case"fs.rename":await P(t,e);break;case"fs.transfer":await C(t,e);break;case"fs.transfer.start":await Q(t,e);break;case"fs.transfer.chunk":await M(t,e);break;case"fs.transfer.finish":await x(t,e);break;case"fs.transfer.abort":await F(t,e);break;case"region.probe":await U(t,e);break;case"region.switch":await V(t,e);break;case"upgrade.start":await l(this.client,e.id,e.params.version,{currentVersion:this.cliVersion,confirmedMajor:e.params.confirmedMajor===!0});break;case"upgrade.status":await u(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await O(t,e);break;case"agents.refresh":await d(t,e);break;case"models.refresh":await p(t,e);break;case"agent.config.get":await g(t,e);break;case"agent.config.upsert":await w(t,e);break;case"agent.config.clear":await f(t,e);break;case"agent.config.test":await b(t,e);break;case"agent.capabilities.list":await m(t,e);break;case"skill.list":case"skill.install":case"skill.doctor":case"skill.setup":case"skill.use":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(s){this.client.sendRes({type:"res",id:e.id,ok:!1,error:s instanceof Error?s.message:String(s)})}finally{this.activeRequests--}}evictIdleSessions(){if(this.sessions.size<N)return;let e=null;for(const[t,s]of this.sessions)(!e||s.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:s});e&&(e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return $(e)}resolveAuthorizedPath(e,t){return L(e,j(t))}async cleanup(){this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null);for(const[,e]of this.sessions)e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),y(this.getRuntime()),await this.managerRuntime.stop(),r(null)}}export{ge as SessionManager,ve as resolveSessionWorkDir};
@@ -51,6 +51,10 @@ export type ChatQueueService = {
51
51
  export type SessionActivityPublisher = {
52
52
  publish(sessionId: string, activity: import('@shennian/wire').SessionActivitySnapshot | null): void;
53
53
  };
54
+ export type UpgradePolicyController = {
55
+ setPolicy(policy: 'none' | 'patch'): void;
56
+ getPolicy(): 'none' | 'patch';
57
+ };
54
58
  export type SessionManagerRuntime = {
55
59
  client: CliRelayClient;
56
60
  pendingTransfers: Map<string, PendingTransfer>;
@@ -65,4 +69,5 @@ export type SessionManagerRuntime = {
65
69
  managerRuntime: ManagerRuntimeService | null;
66
70
  chatQueue: ChatQueueService | null;
67
71
  activityPublisher?: SessionActivityPublisher | null;
72
+ upgradePolicyController?: UpgradePolicyController | null;
68
73
  };
@@ -54,10 +54,17 @@ export declare function fetchLatestVersion(): Promise<string>;
54
54
  * 'major' — major differs
55
55
  */
56
56
  export declare function compareVersions(current: string, latest: string): 'none' | 'patch' | 'minor' | 'major';
57
- export declare function copyPackageRuntimeFiles(src: string, dest: string): void;
58
57
  export declare function readUpgradeAttempt(): UpgradeAttempt | null;
59
58
  export declare function writeUpgradeAttempt(attempt: UpgradeAttempt): void;
60
59
  export declare function clearUpgradeAttempt(): void;
60
+ export type UpgradeLock = {
61
+ release(): void;
62
+ };
63
+ export declare function acquireUpgradeLock(filePath?: string, opts?: {
64
+ now?: number;
65
+ pid?: number;
66
+ isProcessAlive?: (pid: number) => boolean;
67
+ }): UpgradeLock;
61
68
  export declare function readUpgradeFailures(filePath?: string): UpgradeFailures;
62
69
  export declare function getUpgradeRetryDelayMs(failureCount: number): number;
63
70
  export declare function isUpgradeVersionInCooldown(version: string, now?: number, failures?: UpgradeFailures): boolean;
@@ -72,6 +79,12 @@ export declare function handleStartupCrashCheck(): Promise<boolean>;
72
79
  export declare function performUpgrade(targetVersion: string, onProgress: (p: UpgradeProgress) => void, opts?: {
73
80
  currentVersion?: string;
74
81
  }): Promise<UpgradeResult>;
82
+ export declare function installShennianVersion(targetVersion: string): Promise<void>;
83
+ export declare function verifyInstalledVersion(targetVersion: string): Promise<void>;
84
+ export declare function rollbackToExactVersion(version: string, deps?: {
85
+ install?: (version: string) => Promise<void>;
86
+ verify?: (version: string) => Promise<void>;
87
+ }): Promise<void>;
75
88
  export type VersionCheckResult = {
76
89
  hasUpdate: false;
77
90
  } | {
@@ -1,3 +1,3 @@
1
- import i from"node:fs";import c from"node:path";import{execSync as w,exec as $}from"node:child_process";import{promisify as C}from"node:util";import{fileURLToPath as R}from"node:url";import{getShennianDir as v,resolveShennianPath as p}from"../config/index.js";const f=C($),u=p("backup"),l=p("upgrade-attempt.json"),D=3,M=7,N="https://registry.npmjs.org",x=[5*6e4,30*6e4,120*6e4,360*6e4];function m(){try{const t=T();if(t)return JSON.parse(i.readFileSync(t,"utf-8")).version}catch{}return"0.0.0"}function T(t=R(import.meta.url)){let r=c.dirname(t);for(let n=0;n<6;n++){const e=c.join(r,"package.json");if(i.existsSync(e)&&JSON.parse(i.readFileSync(e,"utf-8")).name==="shennian")return e;r=c.dirname(r)}return null}async function B(){const t=await fetch("https://registry.npmjs.org/shennian/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!t.ok)throw new Error(`npm registry returned ${t.status}`);return(await t.json()).version}function H(t,r){const n=U=>U.replace(/^v/,"").split(".").map(Number),[e,s,o]=n(t),[a,k,F]=n(r);return a>e?"major":a===e&&k>s?"minor":a===e&&k===s&&F>o?"patch":"none"}function A(){return w("npm root -g",{encoding:"utf-8",stdio:"pipe",windowsHide:!0}).trim()}function E(){return c.join(A(),"shennian")}function j(){const t=A();return c.join(t,"shennian","dist","bin","shennian.js")}function O(t){const r=E(),n=c.join(u,t);i.rmSync(n,{recursive:!0,force:!0}),i.mkdirSync(n,{recursive:!0}),P(r,n)}function d(t){const r=c.join(u,t);if(!i.existsSync(r))throw new Error(`Backup for ${t} not found`);const n=E();i.cpSync(r,n,{recursive:!0,force:!0})}function P(t,r){for(const n of["package.json","README.md","dist"]){const e=c.join(t,n);i.existsSync(e)&&i.cpSync(e,c.join(r,n),{recursive:!0,force:!0})}}function J(){try{if(!i.existsSync(u))return;const t=Date.now()-M*864e5;for(const r of i.readdirSync(u)){const n=c.join(u,r);i.statSync(n).mtimeMs<t&&i.rmSync(n,{recursive:!0,force:!0})}}catch{}}function L(){try{return JSON.parse(i.readFileSync(l,"utf-8"))}catch{return null}}function y(t){i.mkdirSync(v(),{recursive:!0}),i.writeFileSync(l,JSON.stringify(t,null,2))}function g(){try{i.unlinkSync(l)}catch{}}function _(){return p("upgrade-failures.json")}function h(t=_()){try{const r=JSON.parse(i.readFileSync(t,"utf-8"));return!r||typeof r!="object"||!r.versions?{versions:{}}:{versions:r.versions}}catch{return{versions:{}}}}function b(t){i.mkdirSync(v(),{recursive:!0}),i.writeFileSync(_(),JSON.stringify(t,null,2))}function G(t){return x[Math.min(Math.max(t-1,0),x.length-1)]}function W(t,r=Date.now(),n=h()){const e=n.versions[t];return!!(e&&e.nextRetryAt>r)}function Z(t,r,n=Date.now()){const e=h(),s=e.versions[t],o=(s?.failureCount??0)+1,a={version:t,failureCount:o,firstFailedAt:s?.firstFailedAt??n,lastFailedAt:n,nextRetryAt:n+G(o),error:r};return e.versions[t]=a,b(e),a}function S(t){const r=h();r.versions[t]&&(delete r.versions[t],b(r))}async function V(){const t=L();if(!t)return!1;if(Date.now()-t.attemptAt>600*1e3)return g(),!1;if(t.attemptCount++,t.attemptCount>=D){console.error(`[upgrade] New version crashed ${t.attemptCount} times, rolling back to ${t.from}...`);try{return d(t.from),g(),console.error(`[upgrade] Rolled back to ${t.from}. Restarting...`),!0}catch(n){return console.error(`[upgrade] Rollback failed: ${n instanceof Error?n.message:String(n)}`),g(),!1}}return y(t),!1}async function tt(t,r,n={}){const e=n.currentVersion??m(),s=m();if(e===t)return S(t),{ok:!1,error:`Already on version ${t}`};r({step:"checking"});try{w("npm --version",{stdio:"pipe",windowsHide:!0})}catch{return{ok:!1,error:"npm is not available in PATH"}}if(s===t){r({step:"verifying",version:t});try{const o=j(),{stdout:a}=await f(`node "${o}" --version`,{timeout:1e4,windowsHide:!0});if(!a.trim())throw new Error("Empty output from --version check")}catch(o){return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}`}}return y({from:e,to:t,attemptCount:0,attemptAt:Date.now()}),S(t),r({step:"restarting",from:e,to:t}),{ok:!0,from:e,to:t}}r({step:"backing-up"});try{i.mkdirSync(u,{recursive:!0}),O(e)}catch(o){return{ok:!1,error:`Backup failed: ${o instanceof Error?o.message:String(o)}`}}r({step:"installing",version:t});try{await I(t)}catch(o){try{d(e)}catch{}return{ok:!1,error:`npm install failed: ${o instanceof Error?o.message:String(o)}`,rolledBack:!0}}r({step:"verifying",version:t});try{const o=j(),{stdout:a}=await f(`node "${o}" --version`,{timeout:1e4,windowsHide:!0});if(!a.trim())throw new Error("Empty output from --version check")}catch(o){try{d(e)}catch{}return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}`,rolledBack:!0}}return y({from:e,to:t,attemptCount:0,attemptAt:Date.now()}),J(),S(t),r({step:"restarting",from:e,to:t}),{ok:!0,from:e,to:t}}async function I(t){try{await f(`npm install -g shennian@${t}`,{timeout:12e4,windowsHide:!0})}catch(r){const n=r instanceof Error?r.message:String(r);try{await f(`npm install -g shennian@${t} --registry ${N}`,{timeout:12e4,windowsHide:!0})}catch(e){const s=e instanceof Error?e.message:String(e);throw new Error(`${n}
1
+ import i from"node:fs";import p from"node:path";import{execSync as b,execFile as T}from"node:child_process";import{promisify as D}from"node:util";import{fileURLToPath as L}from"node:url";import{getShennianDir as F,resolveShennianPath as d}from"../config/index.js";const f=D(T),m=d("upgrade-attempt.json"),O=3,J="https://registry.npmjs.org",H=10*6e4,$=[5*6e4,30*6e4,120*6e4,360*6e4];function y(){try{const r=I();if(r)return JSON.parse(i.readFileSync(r,"utf-8")).version}catch{}return"0.0.0"}function I(r=L(import.meta.url)){let e=p.dirname(r);for(let n=0;n<6;n++){const t=p.join(e,"package.json");if(i.existsSync(t)&&JSON.parse(i.readFileSync(t,"utf-8")).name==="shennian")return t;e=p.dirname(e)}return null}async function B(){const r=await fetch("https://registry.npmjs.org/shennian/latest",{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!r.ok)throw new Error(`npm registry returned ${r.status}`);return(await r.json()).version}function G(r,e){const n=u=>u.replace(/^v/,"").split(".").map(Number),[t,s,o]=n(r),[a,l,c]=n(e);return a>t?"major":a===t&&l>s?"minor":a===t&&l===s&&c>o?"patch":"none"}function P(){return b("npm root -g",{encoding:"utf-8",stdio:"pipe",windowsHide:!0}).trim()}function Y(){const r=P();return p.join(r,"shennian","dist","bin","shennian.js")}function z(){try{return JSON.parse(i.readFileSync(m,"utf-8"))}catch{return null}}function g(r){i.mkdirSync(F(),{recursive:!0}),i.writeFileSync(m,JSON.stringify(r,null,2))}function h(){try{i.unlinkSync(m)}catch{}}function U(){return d("upgrade-failures.json")}function K(){return d("upgrade.lock")}function _(r=K(),e={}){const n=e.now??Date.now(),t=e.pid??process.pid,s=e.isProcessAlive??(c=>{try{return process.kill(c,0),!0}catch{return!1}});i.mkdirSync(p.dirname(r),{recursive:!0});const o=()=>i.openSync(r,"wx",384);let a;try{a=o()}catch(c){if(c.code!=="EEXIST")throw c;let u=!1;try{const A=JSON.parse(i.readFileSync(r,"utf-8")),v=Number(A.pid),E=Number(A.createdAt);u=!Number.isInteger(v)||!Number.isFinite(E)||n-E>H||!s(v)}catch{u=!0}if(!u)throw new Error("Another Shennian upgrade is already running");i.rmSync(r,{force:!0}),a=o()}i.writeFileSync(a,JSON.stringify({pid:t,createdAt:n})),i.closeSync(a);let l=!1;return{release(){if(!l){l=!0;try{i.unlinkSync(r)}catch{}}}}}function w(r=U()){try{const e=JSON.parse(i.readFileSync(r,"utf-8"));return!e||typeof e!="object"||!e.versions?{versions:{}}:{versions:e.versions}}catch{return{versions:{}}}}function N(r){i.mkdirSync(F(),{recursive:!0}),i.writeFileSync(U(),JSON.stringify(r,null,2))}function X(r){return $[Math.min(Math.max(r-1,0),$.length-1)]}function tr(r,e=Date.now(),n=w()){const t=n.versions[r];return!!(t&&t.nextRetryAt>e)}function nr(r,e,n=Date.now()){const t=w(),s=t.versions[r],o=(s?.failureCount??0)+1,a={version:r,failureCount:o,firstFailedAt:s?.firstFailedAt??n,lastFailedAt:n,nextRetryAt:n+X(o),error:e};return t.versions[r]=a,N(t),a}function k(r){const e=w();e.versions[r]&&(delete e.versions[r],N(e))}async function or(){const r=z();if(!r)return!1;if(Date.now()-r.attemptAt>600*1e3)return h(),!1;if(r.attemptCount++,r.attemptCount>=O){console.error(`[upgrade] New version crashed ${r.attemptCount} times, rolling back to ${r.from}...`);let n;try{n=_()}catch(t){return console.error(`[upgrade] Rollback deferred: ${t instanceof Error?t.message:String(t)}`),!1}try{return await j(r.from),h(),console.error(`[upgrade] Rolled back to ${r.from}. Restarting...`),!0}catch(t){return console.error(`[upgrade] Rollback failed: ${t instanceof Error?t.message:String(t)}`),h(),!1}finally{n.release()}}return g(r),!1}async function ar(r,e,n={}){let t;try{t=_()}catch(s){return{ok:!1,error:s instanceof Error?s.message:String(s)}}try{return await Z(r,e,n)}finally{t.release()}}async function Z(r,e,n={}){const t=n.currentVersion??y(),s=y();if(t===r)return k(r),{ok:!1,error:`Already on version ${r}`};e({step:"checking"});try{b("npm --version",{stdio:"pipe",windowsHide:!0})}catch{return{ok:!1,error:"npm is not available in PATH"}}if(s===r){e({step:"verifying",version:r});try{await x(r)}catch(o){return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}`}}return g({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),k(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}e({step:"backing-up"}),e({step:"installing",version:r});try{await C(r)}catch(o){const a=await M(t);return{ok:!1,error:`npm install failed: ${o instanceof Error?o.message:String(o)}${a.ok?"":`; rollback failed: ${a.error}`}`,rolledBack:a.ok}}e({step:"verifying",version:r});try{await x(r)}catch(o){const a=await M(t);return{ok:!1,error:`Smoke test failed: ${o instanceof Error?o.message:String(o)}${a.ok?"":`; rollback failed: ${a.error}`}`,rolledBack:a.ok}}return g({from:t,to:r,attemptCount:0,attemptAt:Date.now()}),k(r),e({step:"restarting",from:t,to:r}),{ok:!0,from:t,to:r}}function R(r){if(!/^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(r))throw new Error(`Invalid npm version: ${r}`)}function S(){return process.platform==="win32"?"npm.cmd":"npm"}async function C(r){R(r);try{await f(S(),["install","-g",`shennian@${r}`],{timeout:12e4,windowsHide:!0})}catch(e){const n=e instanceof Error?e.message:String(e);try{await f(S(),["install","-g",`shennian@${r}`,"--registry",J],{timeout:12e4,windowsHide:!0})}catch(t){const s=t instanceof Error?t.message:String(t);throw new Error(`${n}
2
2
  --- npmjs fallback ---
3
- ${s}`)}}}async function rt(t){const r=t??m(),n=await B(),e=H(r,n);return e==="none"?{hasUpdate:!1}:{hasUpdate:!0,current:r,latest:n,changeType:e}}export{rt as checkForUpdate,g as clearUpgradeAttempt,S as clearUpgradeFailure,H as compareVersions,P as copyPackageRuntimeFiles,B as fetchLatestVersion,T as findPackageJson,m as getCurrentVersion,G as getUpgradeRetryDelayMs,V as handleStartupCrashCheck,W as isUpgradeVersionInCooldown,tt as performUpgrade,L as readUpgradeAttempt,h as readUpgradeFailures,Z as recordUpgradeFailure,y as writeUpgradeAttempt};
3
+ ${s}`)}}}async function x(r){R(r);const e=Y(),{stdout:n}=await f(process.execPath,[e,"--version"],{timeout:1e4,windowsHide:!0});if(n.trim()!==r)throw new Error(`Version verification failed: expected ${r}, got ${n.trim()||"empty output"}`);await f(S(),["ls","-g",`shennian@${r}`,"--omit=dev","--depth=0"],{timeout:3e4,windowsHide:!0})}async function j(r,e={}){await(e.install??C)(r),await(e.verify??x)(r)}async function M(r){try{return await j(r),{ok:!0}}catch(e){return{ok:!1,error:e instanceof Error?e.message:String(e)}}}async function ir(r){const e=r??y(),n=await B(),t=G(e,n);return t==="none"?{hasUpdate:!1}:{hasUpdate:!0,current:e,latest:n,changeType:t}}export{_ as acquireUpgradeLock,ir as checkForUpdate,h as clearUpgradeAttempt,k as clearUpgradeFailure,G as compareVersions,B as fetchLatestVersion,I as findPackageJson,y as getCurrentVersion,X as getUpgradeRetryDelayMs,or as handleStartupCrashCheck,C as installShennianVersion,tr as isUpgradeVersionInCooldown,ar as performUpgrade,z as readUpgradeAttempt,w as readUpgradeFailures,nr as recordUpgradeFailure,j as rollbackToExactVersion,x as verifyInstalledVersion,g as writeUpgradeAttempt};
@@ -0,0 +1,45 @@
1
+ import type { RuntimeAutoUpgradePolicy } from '../config/index.js';
2
+ import { type VersionCheckResult } from './engine.js';
3
+ export type UpgradeIdleState = {
4
+ idle: boolean;
5
+ reasons: string[];
6
+ };
7
+ export type CliReleasePolicy = {
8
+ automaticPatchEnabled: boolean;
9
+ rolloutPercentage: number;
10
+ pausedVersions: string[];
11
+ blockedVersions: string[];
12
+ killSwitch: boolean;
13
+ };
14
+ type AutoUpgradeSchedulerDeps = {
15
+ currentVersion: string;
16
+ machineId: string;
17
+ serverUrl: string;
18
+ getIdleState: () => UpgradeIdleState;
19
+ startUpgrade: (targetVersion: string) => Promise<void>;
20
+ checkForUpdate?: (currentVersion?: string) => Promise<VersionCheckResult>;
21
+ fetchReleasePolicy?: () => Promise<CliReleasePolicy>;
22
+ inCooldown?: (version: string) => boolean;
23
+ initialDelayMs?: number;
24
+ intervalMs?: number;
25
+ setTimeout?: (handler: () => void, delayMs: number) => ReturnType<typeof setTimeout>;
26
+ clearTimeout?: (timer: ReturnType<typeof setTimeout>) => void;
27
+ };
28
+ export declare function deterministicRolloutBucket(machineId: string): number;
29
+ export declare function isAutomaticPatchAllowed(policy: CliReleasePolicy, machineId: string, currentVersion: string, targetVersion: string): boolean;
30
+ export declare function fetchCliReleasePolicy(serverUrl: string): Promise<CliReleasePolicy>;
31
+ export declare class AutoUpgradeScheduler {
32
+ private deps;
33
+ private policy;
34
+ private timer;
35
+ private started;
36
+ private upgradeInFlight;
37
+ constructor(deps: AutoUpgradeSchedulerDeps);
38
+ start(): void;
39
+ stop(): void;
40
+ setPolicy(policy: RuntimeAutoUpgradePolicy): void;
41
+ getPolicy(): RuntimeAutoUpgradePolicy;
42
+ runOnce(): Promise<void>;
43
+ private arm;
44
+ }
45
+ export {};
@@ -0,0 +1 @@
1
+ import{checkForUpdate as a,isUpgradeVersionInCooldown as l}from"./engine.js";const n={automaticPatchEnabled:!1,rolloutPercentage:0,pausedVersions:[],blockedVersions:[],killSwitch:!0};function o(s){let e=2166136261;for(let t=0;t<s.length;t++)e^=s.charCodeAt(t),e=Math.imul(e,16777619);return(e>>>0)%100}function c(s,e,t,i){if(s.killSwitch||!s.automaticPatchEnabled||s.blockedVersions.includes(i)||s.pausedVersions.includes(i)||s.pausedVersions.includes(t))return!1;const r=Math.max(0,Math.min(100,Math.floor(s.rolloutPercentage)));return o(e)<r}async function h(s){const e=new URL("/api/releases/cli-policy",s),t=await fetch(e,{headers:{Accept:"application/json"},signal:AbortSignal.timeout(1e4)});if(!t.ok)throw new Error(`release policy returned ${t.status}`);const i=await t.json();return{automaticPatchEnabled:i.automaticPatchEnabled===!0,rolloutPercentage:typeof i.rolloutPercentage=="number"?i.rolloutPercentage:0,pausedVersions:Array.isArray(i.pausedVersions)?i.pausedVersions.filter(r=>typeof r=="string"):[],blockedVersions:Array.isArray(i.blockedVersions)?i.blockedVersions.filter(r=>typeof r=="string"):[],killSwitch:i.killSwitch!==!1}}class d{deps;policy="none";timer=null;started=!1;upgradeInFlight=!1;constructor(e){this.deps=e}start(){this.started||(this.started=!0,this.policy==="patch"&&this.arm(this.deps.initialDelayMs??3e4))}stop(){this.started=!1,this.timer&&(this.deps.clearTimeout??clearTimeout)(this.timer),this.timer=null}setPolicy(e){if(this.policy=e,!!this.started){if(e==="none"){this.timer&&(this.deps.clearTimeout??clearTimeout)(this.timer),this.timer=null;return}this.timer||this.arm(0)}}getPolicy(){return this.policy}async runOnce(){if(this.policy!=="patch"||this.upgradeInFlight||!this.deps.getIdleState().idle)return;const t=await(this.deps.checkForUpdate??a)(this.deps.currentVersion);if(!t.hasUpdate||t.changeType!=="patch"||(this.deps.inCooldown??l)(t.latest))return;let i=n;try{i=await(this.deps.fetchReleasePolicy??(()=>h(this.deps.serverUrl)))()}catch{return}if(c(i,this.deps.machineId,t.current,t.latest)){this.upgradeInFlight=!0;try{await this.deps.startUpgrade(t.latest)}finally{this.upgradeInFlight=!1}}}arm(e){if(!this.started||this.timer)return;const t=this.deps.setTimeout??setTimeout;this.timer=t(()=>{this.timer=null,this.runOnce().catch(()=>{}).finally(()=>{this.started&&this.policy==="patch"&&this.arm(this.deps.intervalMs??5*6e4)})},e),this.timer.unref?.()}}export{d as AutoUpgradeScheduler,o as deterministicRolloutBucket,h as fetchCliReleasePolicy,c as isAutomaticPatchAllowed};
@@ -0,0 +1,17 @@
1
+ export type AgentCapabilityProvider = 'codex' | 'claude' | 'workbuddy';
2
+ export type AgentCapabilityKind = 'skill' | 'plugin_skill';
3
+ export type AgentCapabilitySource = 'personal' | 'project' | 'plugin' | 'system';
4
+ export type AgentNativeCapability = {
5
+ id: string;
6
+ name: string;
7
+ description?: string;
8
+ kind: AgentCapabilityKind;
9
+ source: AgentCapabilitySource;
10
+ invocation: string;
11
+ };
12
+ export type AgentCapabilitiesListPayload = {
13
+ supported: boolean;
14
+ agentType: string;
15
+ capabilities: AgentNativeCapability[];
16
+ };
17
+ //# sourceMappingURL=agent-capabilities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-capabilities.d.ts","sourceRoot":"","sources":["../src/agent-capabilities.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,uBAAuB,GAAG,OAAO,GAAG,QAAQ,GAAG,WAAW,CAAA;AAEtE,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,cAAc,CAAA;AAE1D,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAEhF,MAAM,MAAM,qBAAqB,GAAG;IAClC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,mBAAmB,CAAA;IACzB,MAAM,EAAE,qBAAqB,CAAA;IAC7B,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,4BAA4B,GAAG;IACzC,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,YAAY,EAAE,qBAAqB,EAAE,CAAA;CACtC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-capabilities.js","sourceRoot":"","sources":["../src/agent-capabilities.ts"],"names":[],"mappings":""}
@@ -8,8 +8,9 @@ export * from './session.ts';
8
8
  export * from './message-payload.ts';
9
9
  export * from './external-message-format.ts';
10
10
  export * from './native-session.ts';
11
- export * from './skills.ts';
12
11
  export * from './tool-detail.ts';
13
12
  export * from './voice-chief.ts';
14
13
  export * from './project.ts';
14
+ export * from './room.ts';
15
+ export * from './agent-capabilities.ts';
15
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,yBAAyB,CAAA"}
@@ -8,8 +8,9 @@ export * from "./session.js";
8
8
  export * from "./message-payload.js";
9
9
  export * from "./external-message-format.js";
10
10
  export * from "./native-session.js";
11
- export * from "./skills.js";
12
11
  export * from "./tool-detail.js";
13
12
  export * from "./voice-chief.js";
14
13
  export * from "./project.js";
14
+ export * from "./room.js";
15
+ export * from "./agent-capabilities.js";
15
16
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,SAAS,CAAA;AACvB,cAAc,cAAc,CAAA;AAC5B,cAAc,sBAAsB,CAAA;AACpC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,cAAc,kBAAkB,CAAA;AAChC,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,WAAW,CAAA;AACzB,cAAc,yBAAyB,CAAA"}
@@ -1,4 +1,5 @@
1
1
  export type MachinePermission = 'view' | 'use' | 'full' | 'admin';
2
+ /** `minor` is a legacy compatibility value; current daemons normalize it to `none`. */
2
3
  export type AutoUpgradePolicy = 'none' | 'patch' | 'minor';
3
4
  export type Machine = {
4
5
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"machine.d.ts","sourceRoot":"","sources":["../src/machine.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;AAEjE,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAA;AAE1D,MAAM,MAAM,OAAO,GAAG;IACpB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,iFAAiF;IACjF,MAAM,CAAC,EAAE,OAAO,cAAc,EAAE,SAAS,EAAE,CAAA;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,qDAAqD;IACrD,WAAW,CAAC,EAAE,iBAAiB,CAAA;IAC/B,gEAAgE;IAChE,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IAC1B,4CAA4C;IAC5C,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,0BAA0B,GAAG,IAAI,CAAA;CAC9C,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,OAAO,GAAG,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG,SAAS,CAAA;IACrE,UAAU,CAAC,EACP,OAAO,GACP,UAAU,GACV,SAAS,GACT,gBAAgB,GAChB,cAAc,GACd,sBAAsB,GACtB,oBAAoB,GACpB,oBAAoB,GACpB,kBAAkB,GAClB,eAAe,GACf,SAAS,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,gBAAgB,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,IAAI,CAAA;IACpD,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,CAAC,EAAE;QACP,iBAAiB,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;QAClC,uBAAuB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACvC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzC,yBAAyB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACzC,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;QACpC,WAAW,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;KAC7B,GAAG,IAAI,CAAA;CACT,CAAA;AAED,MAAM,MAAM,mBAAmB,GAC3B;IAAE,KAAK,EAAE,UAAU,CAAC;IAAI,SAAS,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/E;IAAE,KAAK,EAAE,YAAY,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC5D;IAAE,KAAK,EAAE,YAAY,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,KAAK,EAAE,SAAS,CAAC;IAAK,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GACrE;IAAE,KAAK,EAAE,QAAQ,CAAC;IAAM,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,KAAK,EAAE,YAAY,CAAC;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAE3E,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B,UAAU,EAAE,iBAAiB,CAAA;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAA"}
1
+ {"version":3,"file":"machine.d.ts","sourceRoot":"","sources":["../src/machine.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export type ReqMethod = 'chat.send' | 'chat.enqueue' | 'chat.queue.get' | 'chat.queue.edit' | 'chat.queue.delete' | 'chat.abort' | 'session.resume' | 'session.history' | 'session.refresh' | 'session.tool.detail' | 'session.title.set' | 'fs.ls' | 'fs.read' | 'fs.write' | 'fs.export.markdown-pdf' | 'fs.archive.zip' | 'fs.transfer' | 'fs.transfer.start' | 'fs.transfer.chunk' | 'fs.transfer.finish' | 'fs.transfer.abort' | 'fs.rename' | 'skill.list' | 'skill.install' | 'skill.doctor' | 'skill.setup' | 'skill.use' | 'region.probe' | 'region.switch' | 'upgrade.start' | 'upgrade.status' | 'upgrade.set-policy' | 'agents.refresh' | 'models.refresh' | 'agent.config.get' | 'agent.config.upsert' | 'agent.config.clear' | 'agent.config.test' | 'manager.channel.get' | 'manager.channel.upsert' | 'session.wechat-rpa.channel.get' | 'session.wechat-rpa.channel.upsert' | 'session.wechat-rpa.channel.sync' | 'session.wechat-rpa.outbound.cancel' | 'manager.wechat-rpa.channel.get' | 'manager.wechat-rpa.channel.upsert' | 'manager.wechat-rpa.channel.sync' | 'manager.wechat-rpa.outbound.cancel' | 'wechat-rpa.helper.runtime' | 'wecom.send' | 'external.send';
1
+ export type ReqMethod = 'chat.send' | 'chat.enqueue' | 'chat.queue.get' | 'chat.queue.edit' | 'chat.queue.delete' | 'chat.abort' | 'session.resume' | 'session.history' | 'session.refresh' | 'session.tool.detail' | 'session.title.set' | 'fs.ls' | 'fs.read' | 'fs.write' | 'fs.export.markdown-pdf' | 'fs.export.markdown-pdf.setup' | 'fs.archive.zip' | 'fs.transfer' | 'fs.transfer.start' | 'fs.transfer.chunk' | 'fs.transfer.finish' | 'fs.transfer.abort' | 'fs.rename' | 'skill.list' | 'skill.install' | 'skill.doctor' | 'skill.setup' | 'skill.use' | 'region.probe' | 'region.switch' | 'upgrade.start' | 'upgrade.status' | 'upgrade.set-policy' | 'agents.refresh' | 'models.refresh' | 'agent.config.get' | 'agent.config.upsert' | 'agent.config.clear' | 'agent.config.test' | 'agent.capabilities.list' | 'manager.channel.get' | 'manager.channel.upsert' | 'session.wechat-rpa.channel.get' | 'session.wechat-rpa.channel.upsert' | 'session.wechat-rpa.channel.sync' | 'session.wechat-rpa.outbound.cancel' | 'manager.wechat-rpa.channel.get' | 'manager.wechat-rpa.channel.upsert' | 'manager.wechat-rpa.channel.sync' | 'manager.wechat-rpa.outbound.cancel' | 'wechat-rpa.helper.runtime' | 'wecom.send' | 'external.send' | 'room.sync' | 'room.send' | 'room.bind' | 'room.unbind';
2
2
  //# sourceMappingURL=methods.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,GACZ,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,mBAAmB,GACnB,OAAO,GACP,SAAS,GACT,UAAU,GACV,wBAAwB,GACxB,gBAAgB,GAChB,aAAa,GACb,mBAAmB,GACnB,mBAAmB,GACnB,oBAAoB,GACpB,mBAAmB,GACnB,WAAW,GACX,YAAY,GACZ,eAAe,GACf,cAAc,GACd,aAAa,GACb,WAAW,GACX,cAAc,GACd,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,qBAAqB,GACrB,wBAAwB,GACxB,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,2BAA2B,GAC3B,YAAY,GACZ,eAAe,CAAA"}
1
+ {"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../src/methods.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GACjB,WAAW,GACX,cAAc,GACd,gBAAgB,GAChB,iBAAiB,GACjB,mBAAmB,GACnB,YAAY,GACZ,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,qBAAqB,GACrB,mBAAmB,GACnB,OAAO,GACP,SAAS,GACT,UAAU,GACV,wBAAwB,GACxB,8BAA8B,GAC9B,gBAAgB,GAChB,aAAa,GACb,mBAAmB,GACnB,mBAAmB,GACnB,oBAAoB,GACpB,mBAAmB,GACnB,WAAW,GAGX,YAAY,GACZ,eAAe,GACf,cAAc,GACd,aAAa,GACb,WAAW,GACX,cAAc,GACd,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,gBAAgB,GAChB,gBAAgB,GAChB,kBAAkB,GAClB,qBAAqB,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,yBAAyB,GACzB,qBAAqB,GACrB,wBAAwB,GACxB,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,gCAAgC,GAChC,mCAAmC,GACnC,iCAAiC,GACjC,oCAAoC,GACpC,2BAA2B,GAC3B,YAAY,GACZ,eAAe,GACf,WAAW,GACX,WAAW,GACX,WAAW,GACX,aAAa,CAAA"}
@@ -0,0 +1,112 @@
1
+ export type RoomVisibility = 'private' | 'public_read';
2
+ export type RoomJoinPolicy = 'open' | 'approval' | 'closed';
3
+ export type RoomStatus = 'active' | 'archived' | 'deleted';
4
+ export type RoomPrincipalType = 'human' | 'agent';
5
+ export type RoomMembershipRole = 'owner' | 'admin' | 'member';
6
+ export type RoomMembershipStatus = 'active' | 'removed' | 'left';
7
+ export type RoomMessageKind = 'text' | 'attachment' | 'mixed' | 'system';
8
+ export type RoomActivationMode = 'auto_follow' | 'mention_only' | 'paused';
9
+ export type RoomActivationCapability = 'managed' | 'idle_resume' | 'notify_only';
10
+ export type RoomBindingMode = 'managed' | 'hook_native';
11
+ export type RoomBindingStatus = 'pending_approval' | 'active' | 'paused' | 'detached';
12
+ export type RoomRuntimeAdapter = 'codex' | 'claude_code' | 'workbuddy';
13
+ export type RoomAttachmentKind = 'image' | 'audio' | 'video' | 'file';
14
+ export type RoomAttachmentStatus = 'pending' | 'uploaded' | 'scanning' | 'ready' | 'rejected' | 'expired' | 'deleted';
15
+ /** JSON-safe representation of the database BIGINT sequence. */
16
+ export type RoomSequence = string;
17
+ export type RoomSummary = {
18
+ id: string;
19
+ name: string;
20
+ status: RoomStatus;
21
+ visibility: RoomVisibility;
22
+ joinPolicy: RoomJoinPolicy;
23
+ humanCount: number;
24
+ agentCount: number;
25
+ lastSequence: RoomSequence;
26
+ lastReadSequence?: RoomSequence;
27
+ unreadCount?: number;
28
+ updatedAt: string;
29
+ };
30
+ export type RoomAuthorSnapshot = {
31
+ membershipId: string;
32
+ principalType: RoomPrincipalType;
33
+ ownerUserId: string;
34
+ displayName: string;
35
+ ownerDisplayName?: string | null;
36
+ avatar?: Record<string, unknown> | null;
37
+ };
38
+ export type RoomMentionSnapshot = {
39
+ membershipId: string;
40
+ principalType: RoomPrincipalType;
41
+ displayName: string;
42
+ };
43
+ export type RoomAttachmentView = {
44
+ attachmentId: string;
45
+ mediaKind: RoomAttachmentKind;
46
+ name: string;
47
+ mimeType: string;
48
+ byteSize: RoomSequence;
49
+ sha256: string;
50
+ width?: number | null;
51
+ height?: number | null;
52
+ durationMs?: number | null;
53
+ status: RoomAttachmentStatus;
54
+ downloadRef: string;
55
+ };
56
+ export type RoomMessageView = {
57
+ id: string;
58
+ roomId: string;
59
+ sequence: RoomSequence;
60
+ kind: RoomMessageKind;
61
+ author: RoomAuthorSnapshot;
62
+ mentions?: RoomMentionSnapshot[];
63
+ text?: string | null;
64
+ replyToMessageId?: string | null;
65
+ attachments: RoomAttachmentView[];
66
+ createdAt: string;
67
+ editedAt?: string | null;
68
+ deletedAt?: string | null;
69
+ activationCause?: {
70
+ causeMessageId: string;
71
+ rootCauseMessageId: string;
72
+ hopCount: number;
73
+ } | null;
74
+ };
75
+ export type RoomMessageCreatedEvent = {
76
+ event: 'room.message.created';
77
+ roomId: string;
78
+ sequence: RoomSequence;
79
+ message: RoomMessageView;
80
+ };
81
+ export type RoomRefreshEvent = {
82
+ event: 'room.created' | 'room.updated' | 'room.membership.updated' | 'room.join_request.created' | 'room.join_request.updated' | 'room.binding.updated';
83
+ roomId: string;
84
+ sequence?: RoomSequence;
85
+ entityId?: string;
86
+ };
87
+ export type RoomEvent = RoomMessageCreatedEvent | RoomRefreshEvent;
88
+ export type RoomSyncParams = {
89
+ roomId: string;
90
+ afterSequence: RoomSequence;
91
+ limit?: number;
92
+ };
93
+ export type RoomSendParams = {
94
+ roomId: string;
95
+ clientMessageId: string;
96
+ text?: string;
97
+ mentionMembershipIds?: string[];
98
+ attachmentIds?: string[];
99
+ replyToMessageId?: string;
100
+ bindingId?: string;
101
+ };
102
+ export type RoomBindParams = {
103
+ roomId: string;
104
+ agentIdentityId: string;
105
+ invocationToken: string;
106
+ activationCapability?: RoomActivationCapability;
107
+ activationMode?: RoomActivationMode;
108
+ };
109
+ export type RoomUnbindParams = {
110
+ bindingId: string;
111
+ };
112
+ //# sourceMappingURL=room.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room.d.ts","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ // @arch docs/features/network-rooms/implementation-plan.md
2
+ // @test src/__tests__/room.test.ts
3
+ export {};
4
+ //# sourceMappingURL=room.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"room.js","sourceRoot":"","sources":["../src/room.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,mCAAmC"}
@@ -1,9 +1,9 @@
1
1
  import type { NativeSessionSourceMode } from './native-session.js';
2
- export type BuiltinAgentType = 'claude' | 'codex' | 'gemini' | 'cursor' | 'openclaw' | 'opencode' | 'pi' | 'manager';
2
+ export type BuiltinAgentType = 'claude' | 'codex' | 'workbuddy' | 'gemini' | 'cursor' | 'openclaw' | 'opencode' | 'pi' | 'manager';
3
3
  export type CustomAgentType = `custom:${string}`;
4
4
  export type AgentType = BuiltinAgentType | CustomAgentType;
5
5
  export declare const DISABLED_BUILTIN_AGENT_TYPES: readonly ["openclaw"];
6
- export declare const AVAILABLE_BUILTIN_AGENT_TYPES: readonly ["claude", "codex", "gemini", "cursor", "opencode", "pi", "manager"];
6
+ export declare const AVAILABLE_BUILTIN_AGENT_TYPES: readonly ["claude", "codex", "workbuddy", "gemini", "cursor", "opencode", "pi", "manager"];
7
7
  export type ModelInfo = {
8
8
  id: string;
9
9
  name: string;