harnery 0.40.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (595) hide show
  1. package/README.md +1 -1
  2. package/dist/commander.js +4 -0
  3. package/dist/commands/agents.d.ts.map +1 -1
  4. package/dist/commands/agents.js +34 -20
  5. package/dist/commands/artifacts.d.ts.map +1 -1
  6. package/dist/commands/artifacts.js +113 -12
  7. package/dist/commands/browse-ai.d.ts.map +1 -1
  8. package/dist/commands/browse-ai.js +4 -0
  9. package/dist/commands/browse.d.ts +164 -0
  10. package/dist/commands/browse.d.ts.map +1 -1
  11. package/dist/commands/browse.js +388 -45
  12. package/dist/commands/checkpoint.js +8 -12
  13. package/dist/commands/claude-desktop.d.ts.map +1 -1
  14. package/dist/commands/claude-desktop.js +52 -0
  15. package/dist/commands/deinit.d.ts +1 -1
  16. package/dist/commands/deinit.d.ts.map +1 -1
  17. package/dist/commands/deinit.js +8 -4
  18. package/dist/commands/disk.d.ts +6 -0
  19. package/dist/commands/disk.d.ts.map +1 -0
  20. package/dist/commands/disk.js +80 -0
  21. package/dist/commands/docs.d.ts.map +1 -1
  22. package/dist/commands/docs.js +2 -0
  23. package/dist/commands/doctor.d.ts +8 -0
  24. package/dist/commands/doctor.d.ts.map +1 -1
  25. package/dist/commands/doctor.js +58 -3
  26. package/dist/commands/fetch.d.ts.map +1 -1
  27. package/dist/commands/fetch.js +10 -0
  28. package/dist/commands/files.d.ts +16 -0
  29. package/dist/commands/files.d.ts.map +1 -1
  30. package/dist/commands/files.js +54 -2
  31. package/dist/commands/init.d.ts +21 -5
  32. package/dist/commands/init.d.ts.map +1 -1
  33. package/dist/commands/init.js +271 -109
  34. package/dist/commands/instructions.js +5 -4
  35. package/dist/commands/ledger-v3.d.ts.map +1 -1
  36. package/dist/commands/ledger-v3.js +2 -1
  37. package/dist/commands/rm.d.ts +4 -0
  38. package/dist/commands/rm.d.ts.map +1 -0
  39. package/dist/commands/rm.js +87 -0
  40. package/dist/commands/servers.d.ts +7 -0
  41. package/dist/commands/servers.d.ts.map +1 -0
  42. package/dist/commands/servers.js +394 -0
  43. package/dist/commands/tunnel.d.ts.map +1 -1
  44. package/dist/commands/tunnel.js +82 -2
  45. package/dist/commands/webview.d.ts +4 -0
  46. package/dist/commands/webview.d.ts.map +1 -0
  47. package/dist/commands/webview.js +94 -0
  48. package/dist/core/adapter.d.ts +50 -1
  49. package/dist/core/adapter.d.ts.map +1 -1
  50. package/dist/core/adapter.js +59 -1
  51. package/dist/core/adapters/attestation.d.ts.map +1 -1
  52. package/dist/core/adapters/attestation.js +3 -2
  53. package/dist/core/adapters/profiles.d.ts +29 -3
  54. package/dist/core/adapters/profiles.d.ts.map +1 -1
  55. package/dist/core/adapters/profiles.js +53 -1
  56. package/dist/core/adapters/registry.d.ts.map +1 -1
  57. package/dist/core/adapters/registry.js +33 -0
  58. package/dist/core/adapters/types.d.ts +9 -0
  59. package/dist/core/adapters/types.d.ts.map +1 -1
  60. package/dist/core/agents/canonical-emit.d.ts +1 -1
  61. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  62. package/dist/core/agents/canonical-emit.js +2 -7
  63. package/dist/core/agents/cli.js +25 -16
  64. package/dist/core/agents/coord-client.d.ts.map +1 -1
  65. package/dist/core/agents/coord-client.js +7 -2
  66. package/dist/core/agents/render/session-context.d.ts.map +1 -1
  67. package/dist/core/agents/render/session-context.js +2 -0
  68. package/dist/core/agents/rules/claim-conflict.d.ts.map +1 -1
  69. package/dist/core/agents/rules/claim-conflict.js +3 -9
  70. package/dist/core/agents/rules/commit-conflict.d.ts.map +1 -1
  71. package/dist/core/agents/rules/commit-conflict.js +2 -8
  72. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  73. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  74. package/dist/core/agents/rules/stop-hook.js +1 -1
  75. package/dist/core/agents/session-events.d.ts +6 -2
  76. package/dist/core/agents/session-events.d.ts.map +1 -1
  77. package/dist/core/agents/session-events.js +105 -26
  78. package/dist/core/agents/session-finalization-state-v3.d.ts.map +1 -1
  79. package/dist/core/agents/session-finalization-state-v3.js +2 -1
  80. package/dist/core/agents/session-finalizer-v3.d.ts.map +1 -1
  81. package/dist/core/agents/session-finalizer-v3.js +5 -4
  82. package/dist/core/agents/session-name-display.d.ts +28 -0
  83. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  84. package/dist/core/agents/session-name-display.js +43 -0
  85. package/dist/core/agents/state/heartbeat-reader.d.ts +7 -0
  86. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -1
  87. package/dist/core/agents/state/heartbeat-writer.d.ts +10 -0
  88. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  89. package/dist/core/agents/state/heartbeat-writer.js +21 -2
  90. package/dist/core/agents/state/live-coordination-view.d.ts +20 -0
  91. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  92. package/dist/core/agents/state/live-coordination-view.js +61 -0
  93. package/dist/core/agents/state/live-coordination-writer.js +3 -0
  94. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  95. package/dist/core/agents/state/stale-sweep.js +2 -10
  96. package/dist/core/agents/turn-changes.d.ts +17 -0
  97. package/dist/core/agents/turn-changes.d.ts.map +1 -0
  98. package/dist/core/agents/turn-changes.js +76 -0
  99. package/dist/core/artifacts/delivery-card.d.ts.map +1 -1
  100. package/dist/core/artifacts/delivery-card.js +11 -3
  101. package/dist/core/artifacts/index.d.ts +140 -4
  102. package/dist/core/artifacts/index.d.ts.map +1 -1
  103. package/dist/core/artifacts/index.js +526 -52
  104. package/dist/core/config.d.ts +73 -11
  105. package/dist/core/config.d.ts.map +1 -1
  106. package/dist/core/config.js +142 -3
  107. package/dist/core/context/index.d.ts.map +1 -1
  108. package/dist/core/context/index.js +2 -1
  109. package/dist/core/conversations/archive.d.ts.map +1 -1
  110. package/dist/core/conversations/archive.js +4 -3
  111. package/dist/core/diagnostics/bundle.d.ts.map +1 -1
  112. package/dist/core/diagnostics/bundle.js +5 -4
  113. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -1
  114. package/dist/core/events/legacy-storage/canary.js +5 -4
  115. package/dist/core/events/legacy-storage/compression.d.ts.map +1 -1
  116. package/dist/core/events/legacy-storage/compression.js +2 -1
  117. package/dist/core/events/v3/adapter-id.d.ts +10 -2
  118. package/dist/core/events/v3/adapter-id.d.ts.map +1 -1
  119. package/dist/core/events/v3/adapter-id.js +16 -0
  120. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  121. package/dist/core/events/v3/authority-outbox.js +2 -1
  122. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  123. package/dist/core/events/v3/bootstrap.js +5 -4
  124. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  125. package/dist/core/events/v3/capabilities.js +17 -0
  126. package/dist/core/events/v3/contract.d.ts +5 -0
  127. package/dist/core/events/v3/contract.d.ts.map +1 -1
  128. package/dist/core/events/v3/contract.js +7 -1
  129. package/dist/core/events/v3/control-witness.d.ts.map +1 -1
  130. package/dist/core/events/v3/control-witness.js +3 -2
  131. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -1
  132. package/dist/core/events/v3/coordination-transaction-recovery.js +4 -3
  133. package/dist/core/events/v3/fingerprint-keys.d.ts.map +1 -1
  134. package/dist/core/events/v3/fingerprint-keys.js +7 -6
  135. package/dist/core/events/v3/generated.d.ts +1 -1
  136. package/dist/core/events/v3/generated.js +1 -1
  137. package/dist/core/events/v3/live-feed.d.ts.map +1 -1
  138. package/dist/core/events/v3/live-feed.js +5 -4
  139. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  140. package/dist/core/events/v3/producers/command-recorder.js +8 -7
  141. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  142. package/dist/core/events/v3/producers/coordination-recorder.js +8 -7
  143. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -1
  144. package/dist/core/events/v3/producers/diagnostic-summaries.js +5 -4
  145. package/dist/core/events/v3/producers/hook-base.d.ts +1 -0
  146. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  147. package/dist/core/events/v3/producers/hook-base.js +10 -4
  148. package/dist/core/events/v3/producers/hook.d.ts +2 -0
  149. package/dist/core/events/v3/producers/hook.d.ts.map +1 -1
  150. package/dist/core/events/v3/producers/hook.js +16 -1
  151. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  152. package/dist/core/events/v3/producers/intake.js +16 -6
  153. package/dist/core/events/v3/producers/recorder.d.ts +2 -4
  154. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  155. package/dist/core/events/v3/producers/recorder.js +125 -101
  156. package/dist/core/events/v3/projection.js +9 -1
  157. package/dist/core/events/v3/recovery.d.ts.map +1 -1
  158. package/dist/core/events/v3/recovery.js +4 -3
  159. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -1
  160. package/dist/core/events/v3/support-storage/inventory.js +2 -1
  161. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -1
  162. package/dist/core/events/v3/support-storage/maintenance.js +4 -3
  163. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -1
  164. package/dist/core/events/v3/support-storage/pack-reader.js +4 -3
  165. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -1
  166. package/dist/core/events/v3/support-storage/pack-writer.js +6 -5
  167. package/dist/core/events/v3/tool-line-changes.d.ts +8 -0
  168. package/dist/core/events/v3/tool-line-changes.d.ts.map +1 -0
  169. package/dist/core/events/v3/tool-line-changes.js +135 -0
  170. package/dist/core/events/v3/writer.d.ts.map +1 -1
  171. package/dist/core/events/v3/writer.js +8 -7
  172. package/dist/core/governor/planning.d.ts.map +1 -1
  173. package/dist/core/governor/planning.js +6 -5
  174. package/dist/core/governor/service.d.ts.map +1 -1
  175. package/dist/core/governor/service.js +12 -11
  176. package/dist/core/governor/state.d.ts.map +1 -1
  177. package/dist/core/governor/state.js +7 -6
  178. package/dist/core/guard/evaluator.js +1 -0
  179. package/dist/core/guard/storage.d.ts.map +1 -1
  180. package/dist/core/guard/storage.js +3 -2
  181. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts +4 -0
  182. package/dist/core/hooks/adapter/behaviors/claude-code.d.ts.map +1 -0
  183. package/dist/core/hooks/adapter/behaviors/claude-code.js +31 -0
  184. package/dist/core/hooks/adapter/behaviors/codex.d.ts +15 -0
  185. package/dist/core/hooks/adapter/behaviors/codex.d.ts.map +1 -0
  186. package/dist/core/hooks/adapter/behaviors/codex.js +82 -0
  187. package/dist/core/hooks/adapter/behaviors/cursor.d.ts +7 -0
  188. package/dist/core/hooks/adapter/behaviors/cursor.d.ts.map +1 -0
  189. package/dist/core/hooks/adapter/behaviors/cursor.js +35 -0
  190. package/dist/core/hooks/adapter/behaviors/index.d.ts +11 -0
  191. package/dist/core/hooks/adapter/behaviors/index.d.ts.map +1 -0
  192. package/dist/core/hooks/adapter/behaviors/index.js +20 -0
  193. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts +7 -0
  194. package/dist/core/hooks/adapter/behaviors/openclaw.d.ts.map +1 -0
  195. package/dist/core/hooks/adapter/behaviors/openclaw.js +34 -0
  196. package/dist/core/hooks/adapter/behaviors/opencode.d.ts +7 -0
  197. package/dist/core/hooks/adapter/behaviors/opencode.d.ts.map +1 -0
  198. package/dist/core/hooks/adapter/behaviors/opencode.js +34 -0
  199. package/dist/core/hooks/adapter/behaviors/types.d.ts +89 -0
  200. package/dist/core/hooks/adapter/behaviors/types.d.ts.map +1 -0
  201. package/dist/core/hooks/adapter/behaviors/types.js +1 -0
  202. package/dist/core/hooks/adapter/detect.d.ts +1 -1
  203. package/dist/core/hooks/adapter/detect.d.ts.map +1 -1
  204. package/dist/core/hooks/adapter/detect.js +2 -3
  205. package/dist/core/hooks/adapter/events.d.ts +46 -1
  206. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  207. package/dist/core/hooks/adapter/events.js +36 -0
  208. package/dist/core/hooks/adapter/opencode-plugin.d.ts +60 -0
  209. package/dist/core/hooks/adapter/opencode-plugin.d.ts.map +1 -0
  210. package/dist/core/hooks/adapter/opencode-plugin.js +129 -0
  211. package/dist/core/hooks/adapter/output.d.ts +7 -0
  212. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  213. package/dist/core/hooks/adapter/output.js +8 -1
  214. package/dist/core/hooks/adapter/runtime-telemetry.js +3 -1
  215. package/dist/core/hooks/adapter/wiring.d.ts +52 -8
  216. package/dist/core/hooks/adapter/wiring.d.ts.map +1 -1
  217. package/dist/core/hooks/adapter/wiring.js +133 -12
  218. package/dist/core/hooks/cli.js +676 -531
  219. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  220. package/dist/core/hooks/effects/image-capture.js +2 -1
  221. package/dist/core/hooks/prompt-context/contract.d.ts.map +1 -1
  222. package/dist/core/hooks/prompt-context/contract.js +1 -0
  223. package/dist/core/hooks/resolve/transcript.d.ts +1 -1
  224. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  225. package/dist/core/hooks/resolve/transcript.js +35 -4
  226. package/dist/core/hooks/run-markers.d.ts +37 -0
  227. package/dist/core/hooks/run-markers.d.ts.map +1 -0
  228. package/dist/core/hooks/run-markers.js +109 -0
  229. package/dist/core/hooks/session-name-presence.d.ts +3 -1
  230. package/dist/core/hooks/session-name-presence.d.ts.map +1 -1
  231. package/dist/core/hooks/session-name-presence.js +7 -2
  232. package/dist/core/hooks/shell-waiter.d.ts +2 -0
  233. package/dist/core/hooks/shell-waiter.d.ts.map +1 -0
  234. package/dist/core/hooks/shell-waiter.js +173 -0
  235. package/dist/core/resources/service.d.ts.map +1 -1
  236. package/dist/core/resources/service.js +5 -4
  237. package/dist/core/semantic/review.d.ts.map +1 -1
  238. package/dist/core/semantic/review.js +5 -4
  239. package/dist/core/semantic/service.d.ts.map +1 -1
  240. package/dist/core/semantic/service.js +15 -14
  241. package/dist/core/semantic/storage.d.ts.map +1 -1
  242. package/dist/core/semantic/storage.js +5 -4
  243. package/dist/core/servers/index.d.ts +211 -0
  244. package/dist/core/servers/index.d.ts.map +1 -0
  245. package/dist/core/servers/index.js +560 -0
  246. package/dist/core/servers/net.d.ts +58 -0
  247. package/dist/core/servers/net.d.ts.map +1 -0
  248. package/dist/core/servers/net.js +270 -0
  249. package/dist/core/servers/tunnels.d.ts +14 -0
  250. package/dist/core/servers/tunnels.d.ts.map +1 -0
  251. package/dist/core/servers/tunnels.js +33 -0
  252. package/dist/core/storage/atomic-json.d.ts.map +1 -1
  253. package/dist/core/storage/atomic-json.js +7 -3
  254. package/dist/core/storage/builtins.js +1 -0
  255. package/dist/core/storage/durable-history.d.ts.map +1 -1
  256. package/dist/core/storage/durable-history.js +6 -5
  257. package/dist/core/storage/maintenance-providers.d.ts.map +1 -1
  258. package/dist/core/storage/maintenance-providers.js +2 -1
  259. package/dist/core/storage/maintenance.d.ts.map +1 -1
  260. package/dist/core/storage/maintenance.js +7 -6
  261. package/dist/core/storage/metrics.d.ts.map +1 -1
  262. package/dist/core/storage/metrics.js +5 -1
  263. package/dist/core/storage/modes.d.ts +17 -0
  264. package/dist/core/storage/modes.d.ts.map +1 -0
  265. package/dist/core/storage/modes.js +47 -0
  266. package/dist/core/storage/process-log.d.ts.map +1 -1
  267. package/dist/core/storage/process-log.js +3 -2
  268. package/dist/core/storage/receipts.d.ts.map +1 -1
  269. package/dist/core/storage/receipts.js +4 -3
  270. package/dist/core/storage/segments.d.ts.map +1 -1
  271. package/dist/core/storage/segments.js +7 -6
  272. package/dist/core/supervisor/hook-health.d.ts +2 -1
  273. package/dist/core/supervisor/hook-health.d.ts.map +1 -1
  274. package/dist/core/supervisor/hook-health.js +4 -3
  275. package/dist/core/supervisor/service.d.ts.map +1 -1
  276. package/dist/core/supervisor/service.js +7 -6
  277. package/dist/core/work/state.d.ts.map +1 -1
  278. package/dist/core/work/state.js +8 -7
  279. package/dist/core/workflow/adapters.d.ts +7 -0
  280. package/dist/core/workflow/adapters.d.ts.map +1 -1
  281. package/dist/core/workflow/adapters.js +9 -0
  282. package/dist/core/workflow/approvals.d.ts.map +1 -1
  283. package/dist/core/workflow/approvals.js +6 -5
  284. package/dist/core/workflow/billing.d.ts.map +1 -1
  285. package/dist/core/workflow/billing.js +33 -4
  286. package/dist/core/workflow/durable-record.d.ts.map +1 -1
  287. package/dist/core/workflow/durable-record.js +4 -3
  288. package/dist/core/workflow/engine.d.ts.map +1 -1
  289. package/dist/core/workflow/engine.js +30 -1
  290. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  291. package/dist/core/workflow/live-session-v3.js +2 -3
  292. package/dist/core/workflow/run-state.d.ts.map +1 -1
  293. package/dist/core/workflow/run-state.js +3 -2
  294. package/dist/core/workflow/sandbox-projection.d.ts +13 -2
  295. package/dist/core/workflow/sandbox-projection.d.ts.map +1 -1
  296. package/dist/core/workflow/sandbox-projection.js +23 -0
  297. package/dist/core/workflow/spawn-claude.d.ts.map +1 -1
  298. package/dist/core/workflow/spawn-claude.js +6 -1
  299. package/dist/core/workflow/spawn-codex.d.ts +2 -0
  300. package/dist/core/workflow/spawn-codex.d.ts.map +1 -1
  301. package/dist/core/workflow/spawn-codex.js +20 -1
  302. package/dist/core/workflow/spawn-cursor.d.ts.map +1 -1
  303. package/dist/core/workflow/spawn-cursor.js +6 -1
  304. package/dist/core/workflow/spawn-opencode.d.ts +36 -0
  305. package/dist/core/workflow/spawn-opencode.d.ts.map +1 -0
  306. package/dist/core/workflow/spawn-opencode.js +135 -0
  307. package/dist/core/workflow/transcript.d.ts.map +1 -1
  308. package/dist/core/workflow/transcript.js +3 -2
  309. package/dist/core/workflow/types.d.ts +47 -2
  310. package/dist/core/workflow/types.d.ts.map +1 -1
  311. package/dist/core/workflow/worker-access.d.ts +92 -0
  312. package/dist/core/workflow/worker-access.d.ts.map +1 -0
  313. package/dist/core/workflow/worker-access.js +450 -0
  314. package/dist/core/workflow/workspaces/leases.d.ts.map +1 -1
  315. package/dist/core/workflow/workspaces/leases.js +5 -4
  316. package/dist/core/workflow/workspaces/local-git.d.ts.map +1 -1
  317. package/dist/core/workflow/workspaces/local-git.js +3 -2
  318. package/dist/core/workflow/workspaces/paths.d.ts.map +1 -1
  319. package/dist/core/workflow/workspaces/paths.js +2 -1
  320. package/dist/core/workflow/workspaces/state.d.ts.map +1 -1
  321. package/dist/core/workflow/workspaces/state.js +10 -9
  322. package/dist/lazy-commands.js +8 -1
  323. package/dist/lib/agent-browser/client.d.ts +9 -0
  324. package/dist/lib/agent-browser/client.d.ts.map +1 -1
  325. package/dist/lib/agent-browser/client.js +13 -0
  326. package/dist/lib/browser/batch-steps.d.ts +18 -0
  327. package/dist/lib/browser/batch-steps.d.ts.map +1 -0
  328. package/dist/lib/browser/batch-steps.js +82 -0
  329. package/dist/lib/browser/client.d.ts +35 -1
  330. package/dist/lib/browser/client.d.ts.map +1 -1
  331. package/dist/lib/browser/client.js +117 -8
  332. package/dist/lib/browser/collect/collector.d.ts +99 -0
  333. package/dist/lib/browser/collect/collector.d.ts.map +1 -0
  334. package/dist/lib/browser/collect/collector.js +202 -0
  335. package/dist/lib/browser/collect/fields.d.ts +31 -0
  336. package/dist/lib/browser/collect/fields.d.ts.map +1 -0
  337. package/dist/lib/browser/collect/fields.js +75 -0
  338. package/dist/lib/browser/collect/index.d.ts +6 -0
  339. package/dist/lib/browser/collect/index.d.ts.map +1 -0
  340. package/dist/lib/browser/collect/index.js +5 -0
  341. package/dist/lib/browser/collect/page-driver.d.ts +14 -0
  342. package/dist/lib/browser/collect/page-driver.d.ts.map +1 -0
  343. package/dist/lib/browser/collect/page-driver.js +306 -0
  344. package/dist/lib/browser/collect/presets.d.ts +52 -0
  345. package/dist/lib/browser/collect/presets.d.ts.map +1 -0
  346. package/dist/lib/browser/collect/presets.js +176 -0
  347. package/dist/lib/browser/collect/scroll-plan.d.ts +85 -0
  348. package/dist/lib/browser/collect/scroll-plan.d.ts.map +1 -0
  349. package/dist/lib/browser/collect/scroll-plan.js +118 -0
  350. package/dist/lib/browser/identity.d.ts +25 -0
  351. package/dist/lib/browser/identity.d.ts.map +1 -0
  352. package/dist/lib/browser/identity.js +66 -0
  353. package/dist/lib/browser/index.d.ts +3 -2
  354. package/dist/lib/browser/index.d.ts.map +1 -1
  355. package/dist/lib/browser/index.js +2 -1
  356. package/dist/lib/browser/launch-args.d.ts +26 -0
  357. package/dist/lib/browser/launch-args.d.ts.map +1 -1
  358. package/dist/lib/browser/launch-args.js +41 -1
  359. package/dist/lib/browser/page-review-judge.d.ts +2 -0
  360. package/dist/lib/browser/page-review-judge.d.ts.map +1 -1
  361. package/dist/lib/browser/page-review-judge.js +13 -0
  362. package/dist/lib/browser/qa-run-contracts.d.ts +10 -0
  363. package/dist/lib/browser/qa-run-contracts.d.ts.map +1 -1
  364. package/dist/lib/browser/qa-run.d.ts.map +1 -1
  365. package/dist/lib/browser/qa-run.js +1 -0
  366. package/dist/lib/browser/user-agent.d.ts +53 -0
  367. package/dist/lib/browser/user-agent.d.ts.map +1 -0
  368. package/dist/lib/browser/user-agent.js +79 -0
  369. package/dist/lib/browser/windows-chrome.d.ts +59 -0
  370. package/dist/lib/browser/windows-chrome.d.ts.map +1 -0
  371. package/dist/lib/browser/windows-chrome.js +179 -0
  372. package/dist/lib/claude-desktop-share.d.ts +136 -0
  373. package/dist/lib/claude-desktop-share.d.ts.map +1 -0
  374. package/dist/lib/claude-desktop-share.js +394 -0
  375. package/dist/lib/disk-usage.d.ts +50 -0
  376. package/dist/lib/disk-usage.d.ts.map +1 -0
  377. package/dist/lib/disk-usage.js +303 -0
  378. package/dist/lib/docs-lint.d.ts +6 -0
  379. package/dist/lib/docs-lint.d.ts.map +1 -1
  380. package/dist/lib/docs-lint.js +8 -3
  381. package/dist/lib/docs-metadata-managed.d.ts +1 -0
  382. package/dist/lib/docs-metadata-managed.d.ts.map +1 -1
  383. package/dist/lib/docs-metadata-managed.js +17 -1
  384. package/dist/lib/guarded-remove.d.ts +34 -0
  385. package/dist/lib/guarded-remove.d.ts.map +1 -0
  386. package/dist/lib/guarded-remove.js +310 -0
  387. package/dist/lib/identities/assume.d.ts.map +1 -1
  388. package/dist/lib/identities/assume.js +4 -9
  389. package/dist/lib/instructions/apply.d.ts.map +1 -1
  390. package/dist/lib/instructions/apply.js +2 -0
  391. package/dist/lib/instructions/templates.js +8 -8
  392. package/dist/lib/pace/index.d.ts +2 -0
  393. package/dist/lib/pace/index.d.ts.map +1 -0
  394. package/dist/lib/pace/index.js +1 -0
  395. package/dist/lib/pace/pace.d.ts +95 -0
  396. package/dist/lib/pace/pace.d.ts.map +1 -0
  397. package/dist/lib/pace/pace.js +313 -0
  398. package/dist/lib/tunnel/error-page.d.ts +1 -1
  399. package/dist/lib/tunnel/error-page.d.ts.map +1 -1
  400. package/dist/lib/tunnel/error-page.js +19 -8
  401. package/dist/lib/tunnel/forward-headers.d.ts +11 -0
  402. package/dist/lib/tunnel/forward-headers.d.ts.map +1 -0
  403. package/dist/lib/tunnel/forward-headers.js +17 -0
  404. package/dist/lib/tunnel/gate.js +34 -10
  405. package/dist/lib/tunnel/path-scope.d.ts +22 -0
  406. package/dist/lib/tunnel/path-scope.d.ts.map +1 -0
  407. package/dist/lib/tunnel/path-scope.js +62 -0
  408. package/dist/lib/tunnel/state.d.ts +5 -0
  409. package/dist/lib/tunnel/state.d.ts.map +1 -1
  410. package/dist/lib/tunnel/state.js +17 -3
  411. package/dist/lib/webview/index.d.ts +2 -0
  412. package/dist/lib/webview/index.d.ts.map +1 -0
  413. package/dist/lib/webview/index.js +1 -0
  414. package/dist/lib/webview/webview.d.ts +116 -0
  415. package/dist/lib/webview/webview.d.ts.map +1 -0
  416. package/dist/lib/webview/webview.js +289 -0
  417. package/opencode-plugin/package.json +19 -0
  418. package/opencode-plugin/src/index.ts +791 -0
  419. package/package.json +16 -4
  420. package/schemas/config.schema.json +104 -0
  421. package/schemas/event-v3.schema.json +164 -0
  422. package/src/commander.ts +26 -0
  423. package/src/commands/agents.ts +47 -18
  424. package/src/commands/artifacts.ts +171 -19
  425. package/src/commands/browse-ai.ts +8 -0
  426. package/src/commands/browse.ts +570 -48
  427. package/src/commands/checkpoint.ts +7 -9
  428. package/src/commands/claude-desktop.ts +61 -0
  429. package/src/commands/deinit.ts +9 -4
  430. package/src/commands/disk.ts +114 -0
  431. package/src/commands/docs.ts +2 -0
  432. package/src/commands/doctor.ts +63 -3
  433. package/src/commands/fetch.ts +14 -0
  434. package/src/commands/files.ts +93 -2
  435. package/src/commands/init.ts +334 -122
  436. package/src/commands/instructions.ts +8 -4
  437. package/src/commands/ledger-v3.ts +2 -1
  438. package/src/commands/rm.ts +115 -0
  439. package/src/commands/servers.ts +506 -0
  440. package/src/commands/tunnel.ts +102 -2
  441. package/src/commands/webview.ts +159 -0
  442. package/src/core/adapter.ts +102 -1
  443. package/src/core/adapters/attestation.ts +3 -2
  444. package/src/core/adapters/profiles.ts +63 -1
  445. package/src/core/adapters/registry.ts +37 -0
  446. package/src/core/adapters/types.ts +10 -0
  447. package/src/core/agents/canonical-emit.ts +2 -5
  448. package/src/core/agents/cli.ts +26 -17
  449. package/src/core/agents/coord-client.ts +9 -3
  450. package/src/core/agents/render/session-context.ts +1 -0
  451. package/src/core/agents/rules/claim-conflict.ts +3 -8
  452. package/src/core/agents/rules/commit-conflict.ts +2 -7
  453. package/src/core/agents/rules/stop-hook.ts +3 -1
  454. package/src/core/agents/session-events.ts +120 -26
  455. package/src/core/agents/session-finalization-state-v3.ts +2 -1
  456. package/src/core/agents/session-finalizer-v3.ts +5 -4
  457. package/src/core/agents/session-name-display.ts +48 -0
  458. package/src/core/agents/state/heartbeat-reader.ts +7 -0
  459. package/src/core/agents/state/heartbeat-writer.ts +24 -2
  460. package/src/core/agents/state/live-coordination-view.ts +74 -0
  461. package/src/core/agents/state/live-coordination-writer.ts +3 -0
  462. package/src/core/agents/state/stale-sweep.ts +2 -9
  463. package/src/core/agents/turn-changes.ts +97 -0
  464. package/src/core/artifacts/delivery-card.ts +12 -3
  465. package/src/core/artifacts/index.ts +701 -47
  466. package/src/core/config.ts +206 -4
  467. package/src/core/context/index.ts +2 -1
  468. package/src/core/conversations/archive.ts +4 -3
  469. package/src/core/diagnostics/bundle.ts +5 -3
  470. package/src/core/events/legacy-storage/canary.ts +5 -4
  471. package/src/core/events/legacy-storage/compression.ts +2 -1
  472. package/src/core/events/v3/adapter-id.ts +29 -1
  473. package/src/core/events/v3/authority-outbox.ts +2 -1
  474. package/src/core/events/v3/bootstrap.ts +5 -4
  475. package/src/core/events/v3/capabilities.ts +17 -0
  476. package/src/core/events/v3/contract.ts +9 -1
  477. package/src/core/events/v3/control-witness.ts +3 -2
  478. package/src/core/events/v3/coordination-transaction-recovery.ts +4 -3
  479. package/src/core/events/v3/fingerprint-keys.ts +7 -6
  480. package/src/core/events/v3/generated.ts +1 -1
  481. package/src/core/events/v3/live-feed.ts +5 -4
  482. package/src/core/events/v3/producers/command-recorder.ts +8 -6
  483. package/src/core/events/v3/producers/coordination-recorder.ts +8 -7
  484. package/src/core/events/v3/producers/diagnostic-summaries.ts +5 -4
  485. package/src/core/events/v3/producers/hook-base.ts +11 -4
  486. package/src/core/events/v3/producers/hook.ts +19 -1
  487. package/src/core/events/v3/producers/intake.ts +18 -6
  488. package/src/core/events/v3/producers/recorder.ts +139 -114
  489. package/src/core/events/v3/projection.ts +11 -1
  490. package/src/core/events/v3/recovery.ts +4 -3
  491. package/src/core/events/v3/support-storage/inventory.ts +2 -1
  492. package/src/core/events/v3/support-storage/maintenance.ts +8 -3
  493. package/src/core/events/v3/support-storage/pack-reader.ts +4 -3
  494. package/src/core/events/v3/support-storage/pack-writer.ts +6 -5
  495. package/src/core/events/v3/tool-line-changes.ts +139 -0
  496. package/src/core/events/v3/writer.ts +8 -7
  497. package/src/core/governor/planning.ts +6 -5
  498. package/src/core/governor/service.ts +12 -11
  499. package/src/core/governor/state.ts +7 -6
  500. package/src/core/guard/evaluator.ts +1 -0
  501. package/src/core/guard/storage.ts +3 -2
  502. package/src/core/hooks/adapter/behaviors/claude-code.ts +33 -0
  503. package/src/core/hooks/adapter/behaviors/codex.ts +96 -0
  504. package/src/core/hooks/adapter/behaviors/cursor.ts +37 -0
  505. package/src/core/hooks/adapter/behaviors/index.ts +31 -0
  506. package/src/core/hooks/adapter/behaviors/openclaw.ts +36 -0
  507. package/src/core/hooks/adapter/behaviors/opencode.ts +36 -0
  508. package/src/core/hooks/adapter/behaviors/types.ts +110 -0
  509. package/src/core/hooks/adapter/detect.ts +2 -3
  510. package/src/core/hooks/adapter/events.ts +72 -1
  511. package/src/core/hooks/adapter/opencode-plugin.ts +177 -0
  512. package/src/core/hooks/adapter/output.ts +8 -1
  513. package/src/core/hooks/adapter/runtime-telemetry.ts +3 -1
  514. package/src/core/hooks/adapter/wiring.ts +198 -16
  515. package/src/core/hooks/cli.ts +776 -539
  516. package/src/core/hooks/effects/image-capture.ts +2 -1
  517. package/src/core/hooks/prompt-context/contract.ts +1 -0
  518. package/src/core/hooks/resolve/transcript.ts +42 -5
  519. package/src/core/hooks/run-markers.ts +132 -0
  520. package/src/core/hooks/session-name-presence.ts +10 -3
  521. package/src/core/hooks/shell-waiter.ts +166 -0
  522. package/src/core/resources/service.ts +5 -4
  523. package/src/core/semantic/review.ts +5 -4
  524. package/src/core/semantic/service.ts +15 -14
  525. package/src/core/semantic/storage.ts +5 -4
  526. package/src/core/servers/index.ts +712 -0
  527. package/src/core/servers/net.ts +283 -0
  528. package/src/core/servers/tunnels.ts +39 -0
  529. package/src/core/storage/atomic-json.ts +7 -3
  530. package/src/core/storage/builtins.ts +1 -0
  531. package/src/core/storage/durable-history.ts +6 -5
  532. package/src/core/storage/maintenance-providers.ts +2 -1
  533. package/src/core/storage/maintenance.ts +7 -6
  534. package/src/core/storage/metrics.ts +5 -1
  535. package/src/core/storage/modes.ts +53 -0
  536. package/src/core/storage/process-log.ts +3 -2
  537. package/src/core/storage/receipts.ts +4 -3
  538. package/src/core/storage/segments.ts +7 -6
  539. package/src/core/supervisor/hook-health.ts +4 -4
  540. package/src/core/supervisor/service.ts +7 -6
  541. package/src/core/work/state.ts +8 -7
  542. package/src/core/workflow/adapters.ts +15 -0
  543. package/src/core/workflow/approvals.ts +6 -5
  544. package/src/core/workflow/billing.ts +34 -4
  545. package/src/core/workflow/durable-record.ts +4 -3
  546. package/src/core/workflow/engine.ts +38 -1
  547. package/src/core/workflow/live-session-v3.ts +2 -3
  548. package/src/core/workflow/run-state.ts +3 -2
  549. package/src/core/workflow/sandbox-projection.ts +38 -2
  550. package/src/core/workflow/spawn-claude.ts +5 -1
  551. package/src/core/workflow/spawn-codex.ts +18 -1
  552. package/src/core/workflow/spawn-cursor.ts +5 -1
  553. package/src/core/workflow/spawn-opencode.ts +153 -0
  554. package/src/core/workflow/transcript.ts +3 -2
  555. package/src/core/workflow/types.ts +62 -2
  556. package/src/core/workflow/worker-access.ts +525 -0
  557. package/src/core/workflow/workspaces/leases.ts +5 -4
  558. package/src/core/workflow/workspaces/local-git.ts +3 -2
  559. package/src/core/workflow/workspaces/paths.ts +2 -1
  560. package/src/core/workflow/workspaces/state.ts +10 -9
  561. package/src/lazy-commands.ts +11 -1
  562. package/src/lib/agent-browser/client.ts +18 -0
  563. package/src/lib/browser/batch-steps.ts +79 -0
  564. package/src/lib/browser/client.ts +147 -9
  565. package/src/lib/browser/collect/collector.ts +306 -0
  566. package/src/lib/browser/collect/fields.ts +87 -0
  567. package/src/lib/browser/collect/index.ts +47 -0
  568. package/src/lib/browser/collect/page-driver.ts +327 -0
  569. package/src/lib/browser/collect/presets.ts +237 -0
  570. package/src/lib/browser/collect/scroll-plan.ts +179 -0
  571. package/src/lib/browser/identity.ts +64 -0
  572. package/src/lib/browser/index.ts +16 -1
  573. package/src/lib/browser/launch-args.ts +53 -1
  574. package/src/lib/browser/page-review-judge.ts +16 -0
  575. package/src/lib/browser/qa-run-contracts.ts +11 -0
  576. package/src/lib/browser/qa-run.ts +1 -0
  577. package/src/lib/browser/user-agent.ts +130 -0
  578. package/src/lib/browser/windows-chrome.ts +227 -0
  579. package/src/lib/claude-desktop-share.ts +511 -0
  580. package/src/lib/disk-usage.ts +347 -0
  581. package/src/lib/docs-lint.ts +8 -3
  582. package/src/lib/docs-metadata-managed.ts +21 -0
  583. package/src/lib/guarded-remove.ts +376 -0
  584. package/src/lib/identities/assume.ts +7 -7
  585. package/src/lib/instructions/apply.ts +2 -0
  586. package/src/lib/instructions/templates.ts +8 -8
  587. package/src/lib/pace/index.ts +14 -0
  588. package/src/lib/pace/pace.ts +370 -0
  589. package/src/lib/tunnel/error-page.ts +25 -9
  590. package/src/lib/tunnel/forward-headers.ts +16 -0
  591. package/src/lib/tunnel/gate.ts +39 -10
  592. package/src/lib/tunnel/path-scope.ts +73 -0
  593. package/src/lib/tunnel/state.ts +20 -3
  594. package/src/lib/webview/index.ts +13 -0
  595. package/src/lib/webview/webview.ts +457 -0
@@ -0,0 +1,79 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { dirname, resolve } from "node:path";
5
+ const STORE_PATH = resolve(homedir(), ".cache", "harnery", "user-agent.json");
6
+ /** Windows unless the operator is on a Mac. Linux never presents as Linux. */
7
+ export function hostFamily(platform = process.platform) {
8
+ return platform === "darwin" ? "mac" : "windows";
9
+ }
10
+ /** A current-shape Chrome user agent for the host family and Chrome major. */
11
+ export function normalUserAgent(chromeMajor, family) {
12
+ const os = family === "mac" ? "Macintosh; Intel Mac OS X 10_15_7" : "Windows NT 10.0; Win64; x64";
13
+ return `Mozilla/5.0 (${os}) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/${chromeMajor}.0.0.0 Safari/537.36`;
14
+ }
15
+ /** Major version from `<chrome> --version` output, or `undefined`. */
16
+ export function parseChromeMajor(versionOutput) {
17
+ const match = /(\d+)\.\d+\.\d+\.\d+/.exec(versionOutput);
18
+ return match ? Number(match[1]) : undefined;
19
+ }
20
+ /** Ask an installed Chrome binary for its major version. */
21
+ export function chromeMajorFromExecutable(executable) {
22
+ try {
23
+ const res = spawnSync(executable, ["--version"], { encoding: "utf8", timeout: 5000 });
24
+ return parseChromeMajor(`${res.stdout ?? ""}${res.stderr ?? ""}`);
25
+ }
26
+ catch {
27
+ return undefined;
28
+ }
29
+ }
30
+ export function readStoredUserAgent(path = STORE_PATH) {
31
+ try {
32
+ if (!existsSync(path))
33
+ return undefined;
34
+ const parsed = JSON.parse(readFileSync(path, "utf8"));
35
+ return typeof parsed.userAgent === "string" && parsed.userAgent.length > 0
36
+ ? parsed
37
+ : undefined;
38
+ }
39
+ catch {
40
+ return undefined;
41
+ }
42
+ }
43
+ export function writeStoredUserAgent(entry, path = STORE_PATH) {
44
+ mkdirSync(dirname(path), { recursive: true });
45
+ writeFileSync(path, `${JSON.stringify(entry, null, 2)}\n`, { mode: 0o600 });
46
+ }
47
+ /**
48
+ * The user agent to launch with, or `undefined` for the browser's native
49
+ * string. Precedence: explicit request, then environment, then the stored
50
+ * value (refreshed when the Chrome major moved), then a fresh auto value.
51
+ * An explicit string or `auto` request rewrites the store; `native` does not.
52
+ */
53
+ export function resolveUserAgent(input = {}) {
54
+ const now = input.now ?? (() => new Date().toISOString());
55
+ const family = hostFamily(input.platform);
56
+ const requested = input.requested?.trim();
57
+ if (requested && requested !== "auto") {
58
+ if (requested === "native")
59
+ return undefined;
60
+ writeStoredUserAgent({ userAgent: requested, source: "manual", updatedAt: now() }, input.storePath);
61
+ return requested;
62
+ }
63
+ const env = input.env?.trim();
64
+ if (env && requested !== "auto") {
65
+ return env === "native" ? undefined : env;
66
+ }
67
+ const stored = readStoredUserAgent(input.storePath);
68
+ if (stored &&
69
+ requested !== "auto" &&
70
+ (stored.source === "manual" ||
71
+ input.chromeMajor === undefined ||
72
+ stored.chromeMajor === input.chromeMajor)) {
73
+ return stored.userAgent;
74
+ }
75
+ const major = input.chromeMajor ?? stored?.chromeMajor ?? 149;
76
+ const userAgent = normalUserAgent(major, family);
77
+ writeStoredUserAgent({ userAgent, source: "auto", chromeMajor: major, updatedAt: now() }, input.storePath);
78
+ return userAgent;
79
+ }
@@ -0,0 +1,59 @@
1
+ import type { Cookie } from "../cookies/client.js";
2
+ /** Linux path of the Windows host's Google Chrome, or `undefined`. */
3
+ export declare function windowsChromePath(exists?: (path: string) => boolean, localAppDataLinux?: string): string | undefined;
4
+ /** `%LOCALAPPDATA%` as a Windows path, read through cmd.exe interop. */
5
+ export declare function windowsLocalAppData(): string | undefined;
6
+ /** Windows-side profile used only for `--login --plain` sign-ins under WSL. */
7
+ export declare function windowsPlainProfile(localAppData: string): string;
8
+ /**
9
+ * The registrable domain to harvest for a sign-in URL: the last two labels of
10
+ * the host (`x.com` from `https://x.com/i/flow/login`). Cookies are kept when
11
+ * their domain equals it or is a subdomain of it, so a sign-in that also sets
12
+ * cookies for an identity provider does not copy those into the store.
13
+ */
14
+ export declare function harvestDomain(url: string): string;
15
+ export declare function cookieInDomain(cookieDomain: string, domain: string): boolean;
16
+ /** Shape `Storage.getCookies` returns; extra fields are ignored. */
17
+ interface CdpCookie {
18
+ name: string;
19
+ value: string;
20
+ domain: string;
21
+ path: string;
22
+ expires: number;
23
+ size?: number;
24
+ httpOnly: boolean;
25
+ secure: boolean;
26
+ session?: boolean;
27
+ sameSite?: string;
28
+ }
29
+ /** Keep the sign-in site's cookies and normalize them to the store's shape. */
30
+ export declare function cookiesForDomain(cdpCookies: CdpCookie[], domain: string): Cookie[];
31
+ /**
32
+ * PowerShell that does the whole read on the Windows side: start Chrome
33
+ * headless on the profile, wait for the DevToolsActivePort file it writes,
34
+ * read every cookie with `Storage.getCookies`, write the raw response to
35
+ * stdout, and close the browser. WSL never touches the profile folder, which
36
+ * it may not be able to list. Every wait carries a deadline.
37
+ */
38
+ export declare function harvestScript(): string;
39
+ /**
40
+ * Reopen the Windows profile headless, read its cookies for `domain`, and
41
+ * close it. Returns the cookies in the store's shape.
42
+ */
43
+ export declare function harvestWindowsChromeCookies(input: {
44
+ chromeWindows: string;
45
+ profileWindows: string;
46
+ domain: string;
47
+ startupTimeoutSeconds?: number;
48
+ }): Cookie[];
49
+ /**
50
+ * Close any Chrome still running on `profileWindows`, for when the person ends
51
+ * the sign-in from the terminal while the window is open. The profile must be
52
+ * closed before its cookies can be read. Closing the window first lets Chrome
53
+ * write recent cookies to disk; a forced stop is the fallback after 15 s.
54
+ */
55
+ export declare function stopWindowsChromeProfile(profileWindows: string): void;
56
+ /** Windows form of a `/mnt/<drive>/...` path. */
57
+ export declare function wslPathToWindows(linuxPath: string): string;
58
+ export {};
59
+ //# sourceMappingURL=windows-chrome.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows-chrome.d.ts","sourceRoot":"","sources":["../../../src/lib/browser/windows-chrome.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AA4BnD,sEAAsE;AACtE,wBAAgB,iBAAiB,CAC/B,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAoB,EAC9C,iBAAiB,CAAC,EAAE,MAAM,GACzB,MAAM,GAAG,SAAS,CAKpB;AAED,wEAAwE;AACxE,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAOxD;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEhE;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIjD;AAED,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAG5E;AAED,oEAAoE;AACpE,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAelF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAyBtC;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC,GAAG,MAAM,EAAE,CA2CX;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAkBrE;AAED,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAI1D"}
@@ -0,0 +1,179 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ /**
6
+ * Sign-in through the Windows host's Google Chrome when running under WSL.
7
+ *
8
+ * Some sign-in flows (X is the reported case) reject every browser running
9
+ * inside WSL, including a plain Linux Google Chrome with nothing attached:
10
+ * the sign-in request comes back "429 Too Many Requests" while the same
11
+ * account signs in from the Windows desktop browser without trouble. The
12
+ * Windows Chrome is the client those flows accept, so `browse --login
13
+ * --plain` under WSL opens it on a dedicated Windows-side profile. The
14
+ * person signs in there with nothing attached. Afterwards the profile is
15
+ * reopened headless for a moment, its cookies for the sign-in site are read
16
+ * through the DevTools protocol, and they are merged into the shared cookie
17
+ * store that later `browse` runs attach. The Windows profile cannot be shared
18
+ * with Linux Chromium directly because Windows encrypts its cookie database
19
+ * with keys only Windows can read.
20
+ *
21
+ * Under WSL2's default NAT networking the Windows loopback port is not
22
+ * reachable from Linux, so the DevTools conversation runs inside a short
23
+ * PowerShell script on the Windows side and prints the result to stdout.
24
+ */
25
+ const WINDOWS_CHROME_CANDIDATES = [
26
+ "/mnt/c/Program Files/Google/Chrome/Application/chrome.exe",
27
+ "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
28
+ ];
29
+ /** Linux path of the Windows host's Google Chrome, or `undefined`. */
30
+ export function windowsChromePath(exists = existsSync, localAppDataLinux) {
31
+ const candidates = [...WINDOWS_CHROME_CANDIDATES];
32
+ if (localAppDataLinux)
33
+ candidates.push(join(localAppDataLinux, "Google", "Chrome", "Application", "chrome.exe"));
34
+ return candidates.find((candidate) => exists(candidate));
35
+ }
36
+ /** `%LOCALAPPDATA%` as a Windows path, read through cmd.exe interop. */
37
+ export function windowsLocalAppData() {
38
+ const result = spawnSync("cmd.exe", ["/c", "echo %LOCALAPPDATA%"], {
39
+ encoding: "utf8",
40
+ timeout: 10_000,
41
+ });
42
+ const value = (result.stdout ?? "").replace(/\r/g, "").trim();
43
+ return result.status === 0 && /^[A-Za-z]:\\/.test(value) ? value : undefined;
44
+ }
45
+ /** Windows-side profile used only for `--login --plain` sign-ins under WSL. */
46
+ export function windowsPlainProfile(localAppData) {
47
+ return `${localAppData}\\harnery\\plain-login-profile`;
48
+ }
49
+ /**
50
+ * The registrable domain to harvest for a sign-in URL: the last two labels of
51
+ * the host (`x.com` from `https://x.com/i/flow/login`). Cookies are kept when
52
+ * their domain equals it or is a subdomain of it, so a sign-in that also sets
53
+ * cookies for an identity provider does not copy those into the store.
54
+ */
55
+ export function harvestDomain(url) {
56
+ const host = new URL(url).hostname.toLowerCase();
57
+ const labels = host.split(".").filter(Boolean);
58
+ return labels.length <= 2 ? host : labels.slice(-2).join(".");
59
+ }
60
+ export function cookieInDomain(cookieDomain, domain) {
61
+ const bare = cookieDomain.replace(/^\./, "").toLowerCase();
62
+ return bare === domain || bare.endsWith(`.${domain}`);
63
+ }
64
+ /** Keep the sign-in site's cookies and normalize them to the store's shape. */
65
+ export function cookiesForDomain(cdpCookies, domain) {
66
+ return cdpCookies
67
+ .filter((cookie) => cookieInDomain(cookie.domain, domain))
68
+ .map((cookie) => ({
69
+ name: cookie.name,
70
+ value: cookie.value,
71
+ domain: cookie.domain,
72
+ path: cookie.path || "/",
73
+ expires: typeof cookie.expires === "number" ? cookie.expires : -1,
74
+ ...(cookie.size === undefined ? {} : { size: cookie.size }),
75
+ httpOnly: Boolean(cookie.httpOnly),
76
+ secure: Boolean(cookie.secure),
77
+ ...(cookie.session === undefined ? {} : { session: cookie.session }),
78
+ ...(cookie.sameSite ? { sameSite: cookie.sameSite } : {}),
79
+ }));
80
+ }
81
+ /**
82
+ * PowerShell that does the whole read on the Windows side: start Chrome
83
+ * headless on the profile, wait for the DevToolsActivePort file it writes,
84
+ * read every cookie with `Storage.getCookies`, write the raw response to
85
+ * stdout, and close the browser. WSL never touches the profile folder, which
86
+ * it may not be able to list. Every wait carries a deadline.
87
+ */
88
+ export function harvestScript() {
89
+ return [
90
+ "param([string]$Chrome, [string]$Profile, [int]$StartupSeconds = 30)",
91
+ "$ErrorActionPreference = 'Stop'",
92
+ "$portFile = Join-Path $Profile 'DevToolsActivePort'",
93
+ "if (Test-Path $portFile) { Remove-Item $portFile -Force }",
94
+ "$args = @('--headless=new', '--no-first-run', '--no-default-browser-check', '--remote-debugging-port=0', \"--user-data-dir=$Profile\", 'about:blank')",
95
+ "$proc = Start-Process -FilePath $Chrome -ArgumentList $args -PassThru -WindowStyle Hidden",
96
+ "$deadline = (Get-Date).AddSeconds($StartupSeconds)",
97
+ "while (-not (Test-Path $portFile)) { if ((Get-Date) -gt $deadline) { throw 'Windows Chrome did not open its DevTools port in time.' }; if ($proc.HasExited) { throw 'Windows Chrome exited before opening its DevTools port.' }; Start-Sleep -Milliseconds 250 }",
98
+ "Start-Sleep -Milliseconds 200",
99
+ "$lines = Get-Content $portFile",
100
+ "$port = [int]$lines[0]; $path = $lines[1]",
101
+ "$ws = New-Object System.Net.WebSockets.ClientWebSocket",
102
+ "$cts = New-Object System.Threading.CancellationTokenSource 20000",
103
+ '$ws.ConnectAsync([Uri]("ws://127.0.0.1:$port$path"), $cts.Token).Wait()',
104
+ "function Send($obj) { $b = [Text.Encoding]::UTF8.GetBytes(($obj | ConvertTo-Json -Compress)); $ws.SendAsync([ArraySegment[byte]]$b, 'Text', $true, $cts.Token).Wait() }",
105
+ "function Recv() { $buf = New-Object byte[] 65536; $ms = New-Object IO.MemoryStream; do { $r = $ws.ReceiveAsync([ArraySegment[byte]]$buf, $cts.Token).Result; $ms.Write($buf, 0, $r.Count) } while (-not $r.EndOfMessage); [Text.Encoding]::UTF8.GetString($ms.ToArray()) }",
106
+ "Send @{ id = 1; method = 'Storage.getCookies' }",
107
+ "$out = $null",
108
+ "while ($null -eq $out) { $m = Recv; if ($m -match '\"id\":1[,}]') { $out = $m } }",
109
+ "[Console]::Out.Write($out)",
110
+ "try { Send @{ id = 2; method = 'Browser.close' } } catch {}",
111
+ "if (-not $proc.WaitForExit(10000)) { Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue }",
112
+ ].join("\r\n");
113
+ }
114
+ /**
115
+ * Reopen the Windows profile headless, read its cookies for `domain`, and
116
+ * close it. Returns the cookies in the store's shape.
117
+ */
118
+ export function harvestWindowsChromeCookies(input) {
119
+ const scriptDir = join(tmpdir(), "harnery-windows-chrome");
120
+ mkdirSync(scriptDir, { recursive: true });
121
+ const scriptLinux = join(scriptDir, `harvest-cookies-${process.pid}.ps1`);
122
+ writeFileSync(scriptLinux, harvestScript(), { mode: 0o600 });
123
+ try {
124
+ const scriptWindows = spawnSync("wslpath", ["-w", scriptLinux], {
125
+ encoding: "utf8",
126
+ }).stdout.trim();
127
+ const result = spawnSync("powershell.exe", [
128
+ "-NoProfile",
129
+ "-ExecutionPolicy",
130
+ "Bypass",
131
+ "-File",
132
+ scriptWindows,
133
+ "-Chrome",
134
+ input.chromeWindows,
135
+ "-Profile",
136
+ input.profileWindows,
137
+ "-StartupSeconds",
138
+ String(input.startupTimeoutSeconds ?? 30),
139
+ ], { encoding: "utf8", timeout: 90_000, maxBuffer: 64 * 1024 * 1024 });
140
+ if (result.status !== 0) {
141
+ throw new Error(`Reading cookies from Windows Chrome failed: ${(result.stderr || result.stdout || "no output").trim().slice(0, 400)}`);
142
+ }
143
+ const parsed = JSON.parse(result.stdout);
144
+ if (!parsed.result?.cookies)
145
+ throw new Error(`Windows Chrome returned no cookie list: ${parsed.error?.message ?? "unknown response"}`);
146
+ return cookiesForDomain(parsed.result.cookies, input.domain);
147
+ }
148
+ finally {
149
+ rmSync(scriptLinux, { force: true });
150
+ }
151
+ }
152
+ /**
153
+ * Close any Chrome still running on `profileWindows`, for when the person ends
154
+ * the sign-in from the terminal while the window is open. The profile must be
155
+ * closed before its cookies can be read. Closing the window first lets Chrome
156
+ * write recent cookies to disk; a forced stop is the fallback after 15 s.
157
+ */
158
+ export function stopWindowsChromeProfile(profileWindows) {
159
+ const escaped = profileWindows.replace(/'/g, "''");
160
+ const select = `Get-CimInstance Win32_Process -Filter "Name='chrome.exe'" | Where-Object { $_.CommandLine -like '*${escaped}*' }`;
161
+ spawnSync("powershell.exe", [
162
+ "-NoProfile",
163
+ "-Command",
164
+ [
165
+ `$ids = @(${select} | ForEach-Object { $_.ProcessId })`,
166
+ "foreach ($id in $ids) { $p = Get-Process -Id $id -ErrorAction SilentlyContinue; if ($p -and $p.MainWindowHandle -ne 0) { [void]$p.CloseMainWindow() } }",
167
+ "$deadline = (Get-Date).AddSeconds(15)",
168
+ `while ((Get-Date) -lt $deadline -and @(${select}).Count -gt 0) { Start-Sleep -Milliseconds 250 }`,
169
+ `${select} | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }`,
170
+ ].join("; "),
171
+ ], { encoding: "utf8", timeout: 45_000 });
172
+ }
173
+ /** Windows form of a `/mnt/<drive>/...` path. */
174
+ export function wslPathToWindows(linuxPath) {
175
+ const match = /^\/mnt\/([a-z])\/(.*)$/.exec(linuxPath);
176
+ if (!match)
177
+ throw new Error(`Not a /mnt/<drive> path: ${linuxPath}`);
178
+ return `${match[1].toUpperCase()}:\\${(match[2] ?? "").replace(/\//g, "\\")}`;
179
+ }
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Cross-machine Claude desktop session sharing through a synced folder.
3
+ *
4
+ * The desktop app's sidebar (see claude-desktop.ts) and the transcripts it
5
+ * resumes from (`~/.claude/projects/<slug>/<cliSessionId>.jsonl`) are both
6
+ * machine-local. A user with two computers therefore sees only the sessions
7
+ * started on the one in front of them. `share` closes that gap through any
8
+ * folder both machines sync (iCloud Drive, Dropbox, a network share):
9
+ *
10
+ * <shareDir>/<machine>/manifest.json { machine, home, exported_at }
11
+ * <shareDir>/<machine>/sessions/<cliId>/entry.json
12
+ * <shareDir>/<machine>/sessions/<cliId>/transcript.jsonl
13
+ * <shareDir>/<machine>/sessions/<cliId>/sidecar/ (optional per-session dir)
14
+ *
15
+ * Export publishes this machine's recent sessions under its own directory;
16
+ * import reads every other machine's directory and makes each session
17
+ * listed and resumable here. Each machine writes only its own directory, so
18
+ * the synced folder never has two writers for one file.
19
+ *
20
+ * Transcripts are append-only, which gives a safe merge rule: a remote copy
21
+ * replaces the local one only when the local file is missing or is a strict
22
+ * byte prefix of the remote (the other machine continued the conversation).
23
+ * A local transcript that is longer, diverged, or written in the last few
24
+ * minutes (a live session here) is never overwritten.
25
+ *
26
+ * A synced folder can list a file before its bytes arrive (an iCloud
27
+ * "dataless" placeholder). Reading one blocks until the download finishes, or
28
+ * fails outright, so such sessions are skipped as "not-downloaded", a download
29
+ * is requested, and the next pass picks them up. One session that still fails
30
+ * to copy is reported under `failed` and never stops the rest of the pass.
31
+ */
32
+ export interface ShareOptions {
33
+ shareDir: string;
34
+ machine: string;
35
+ /** Only sessions active within this many days. */
36
+ days: number;
37
+ /** Desktop data dir (the one holding claude-code-sessions/). */
38
+ dataDir: string;
39
+ /** Account whose sidebar receives imported entries. */
40
+ targetAccountUuid: string;
41
+ /** Override for tests. */
42
+ home?: string;
43
+ /** Override for tests (ms since epoch). */
44
+ now?: number;
45
+ /** Local transcripts modified this recently count as live (ms). */
46
+ liveWindowMs?: number;
47
+ /** Override for tests: which of these paths are not downloaded yet. */
48
+ findPlaceholders?: (paths: string[]) => Set<string>;
49
+ /** Override for tests: ask the sync client to download these paths. */
50
+ requestDownload?: (paths: string[]) => void;
51
+ }
52
+ export interface ExportAction {
53
+ cliSessionId: string;
54
+ title: string | null;
55
+ transcript: string;
56
+ bytes: number;
57
+ }
58
+ export type ImportKind = "new" | "updated" | "entry-only";
59
+ export interface ImportAction {
60
+ kind: ImportKind;
61
+ machine: string;
62
+ cliSessionId: string;
63
+ title: string | null;
64
+ cwd: string;
65
+ /** Remote transcript to copy, or null when only the entry changes. */
66
+ transcriptFrom: string | null;
67
+ transcriptTo: string;
68
+ sidecarFrom: string | null;
69
+ entryFrom: string;
70
+ /** Local entry to patch (existing session) or create (new session). */
71
+ entryTo: string;
72
+ entryExists: boolean;
73
+ remoteLastActivityAt: number | null;
74
+ }
75
+ export interface ImportSkip {
76
+ machine: string;
77
+ cliSessionId: string;
78
+ title: string | null;
79
+ reason: "up-to-date" | "local-newer" | "diverged" | "live-here" | "missing-cwd" | "unreadable" | "not-downloaded";
80
+ }
81
+ export interface SharePlan {
82
+ exports: ExportAction[];
83
+ imports: ImportAction[];
84
+ skips: ImportSkip[];
85
+ machines: string[];
86
+ }
87
+ export interface ImportFailure {
88
+ machine: string;
89
+ cliSessionId: string;
90
+ title: string | null;
91
+ error: string;
92
+ }
93
+ /**
94
+ * Paths whose bytes are not on this disk yet. On macOS this reads st_flags
95
+ * (Node's stat does not expose them) in one `stat` call; everywhere else only
96
+ * the `.<name>.icloud` stub convention applies.
97
+ */
98
+ export declare function findPlaceholders(paths: string[]): Set<string>;
99
+ /** Best-effort, fire-and-forget: ask iCloud Drive to fetch these paths. */
100
+ export declare function requestDownload(paths: string[]): void;
101
+ export declare function defaultShareDir(home?: string): string | null;
102
+ /** Claude Code's per-project transcript folder name for a working directory. */
103
+ export declare function projectSlug(cwd: string): string;
104
+ /** Rewrite a path from the remote home to the local one (same layout, different user). */
105
+ export declare function remapHome(p: string, remoteHome: string | null, localHome: string): string;
106
+ /** True when `prefixFile`'s bytes are exactly the start of `fullFile`. */
107
+ export declare function isBytePrefix(prefixFile: string, fullFile: string): boolean;
108
+ export declare function planShare(opts: ShareOptions): SharePlan;
109
+ export declare function applyShare(plan: SharePlan, opts: ShareOptions): {
110
+ exported: number;
111
+ imported: number;
112
+ failed: ImportFailure[];
113
+ };
114
+ export declare function shareSummary(plan: SharePlan): {
115
+ machines: string[];
116
+ export: {
117
+ title: string | null;
118
+ cli_session_id: string;
119
+ bytes: number;
120
+ }[];
121
+ import: {
122
+ kind: ImportKind;
123
+ from_machine: string;
124
+ title: string | null;
125
+ cli_session_id: string;
126
+ }[];
127
+ skipped: {
128
+ from_machine: string;
129
+ title: string | null;
130
+ cli_session_id: string;
131
+ reason: "unreadable" | "up-to-date" | "local-newer" | "diverged" | "live-here" | "missing-cwd" | "not-downloaded";
132
+ }[];
133
+ not_downloaded: number;
134
+ up_to_date: number;
135
+ };
136
+ //# sourceMappingURL=claude-desktop-share.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-desktop-share.d.ts","sourceRoot":"","sources":["../../src/lib/claude-desktop-share.ts"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB,uDAAuD;IACvD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0BAA0B;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAG,CAAC,MAAM,CAAC,CAAC;IACpD,uEAAuE;IACvE,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,YAAY,CAAC;AAE1D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EACF,YAAY,GACZ,aAAa,GACb,UAAU,GACV,WAAW,GACX,aAAa,GACb,YAAY,GACZ,gBAAgB,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAKD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAgB7D;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CASrD;AAED,wBAAgB,eAAe,CAAC,IAAI,SAAY,GAAG,MAAM,GAAG,IAAI,CAI/D;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE/C;AA+BD,0FAA0F;AAC1F,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAIzF;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAuB1E;AA2BD,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CA4HvD;AAsBD,wBAAgB,UAAU,CACxB,IAAI,EAAE,SAAS,EACf,IAAI,EAAE,YAAY,GACjB;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,EAAE,CAAA;CAAE,CAoCjE;AAqCD,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS;;;;;;;;;;;;;;;;;;;;;EAyB3C"}