a2acalling 0.6.75 → 0.6.76

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 (1025) hide show
  1. package/.a2a-manifest.json +2 -2
  2. package/.claude/worktrees/agent-a0a8dd02/.a2a-manifest.json +70 -0
  3. package/.claude/worktrees/agent-a0a8dd02/.c8rc.json +16 -0
  4. package/.claude/worktrees/agent-a0a8dd02/.claude/a2a-skill-reference.md +462 -0
  5. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-app.md +42 -0
  6. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-call.md +26 -0
  7. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-contacts.md +31 -0
  8. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-conversations.md +47 -0
  9. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-gui.md +30 -0
  10. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-invite.md +63 -0
  11. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-setup.md +30 -0
  12. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-skills.md +27 -0
  13. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-status.md +46 -0
  14. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-uninstall.md +36 -0
  15. package/.claude/worktrees/agent-a0a8dd02/.claude/commands/a2a-update.md +41 -0
  16. package/.claude/worktrees/agent-a0a8dd02/.node-version +1 -0
  17. package/.claude/worktrees/agent-a0a8dd02/ARCHITECTURE.md +135 -0
  18. package/.claude/worktrees/agent-a0a8dd02/CLAUDE-INSTALL.md +156 -0
  19. package/.claude/worktrees/agent-a0a8dd02/CONVENTIONS.md +179 -0
  20. package/.claude/worktrees/agent-a0a8dd02/README.md +470 -0
  21. package/.claude/worktrees/agent-a0a8dd02/SKILL.md +462 -0
  22. package/.claude/worktrees/agent-a0a8dd02/bin/cli.js +3184 -0
  23. package/.claude/worktrees/agent-a0a8dd02/biome.json +27 -0
  24. package/.claude/worktrees/agent-a0a8dd02/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  25. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  26. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  27. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-02-16-auto-updater.md +1284 -0
  28. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  29. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  30. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  31. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  32. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  33. package/.claude/worktrees/agent-a0a8dd02/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  34. package/.claude/worktrees/agent-a0a8dd02/docs/prompts/e2e-test-agent.md +368 -0
  35. package/.claude/worktrees/agent-a0a8dd02/docs/protocol.md +440 -0
  36. package/.claude/worktrees/agent-a0a8dd02/docs/signing-setup.md +49 -0
  37. package/.claude/worktrees/agent-a0a8dd02/eslint.config.js +16 -0
  38. package/.claude/worktrees/agent-a0a8dd02/knip.json +17 -0
  39. package/.claude/worktrees/agent-a0a8dd02/native/macos/index.html +179 -0
  40. package/.claude/worktrees/agent-a0a8dd02/native/macos/package.json +8 -0
  41. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/Cargo.lock +5875 -0
  42. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/Cargo.toml +25 -0
  43. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/binaries/.gitkeep +0 -0
  44. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/build.rs +3 -0
  45. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/capabilities/default.json +26 -0
  46. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/entitlements.plist +14 -0
  47. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/icons/128x128.png +0 -0
  48. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  49. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/icons/32x32.png +0 -0
  50. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/icons/icon.icns +0 -0
  51. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/icons/tray-connected.png +0 -0
  52. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  53. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/src/discovery.rs +184 -0
  54. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/src/health.rs +67 -0
  55. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/src/lib.rs +256 -0
  56. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/src/main.rs +6 -0
  57. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/src/notifications.rs +180 -0
  58. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/src/server.rs +306 -0
  59. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/src/updater.rs +124 -0
  60. package/.claude/worktrees/agent-a0a8dd02/native/macos/src-tauri/tauri.conf.json +58 -0
  61. package/.claude/worktrees/agent-a0a8dd02/package.json +54 -0
  62. package/.claude/worktrees/agent-a0a8dd02/pkg.config.json +14 -0
  63. package/.claude/worktrees/agent-a0a8dd02/scripts/build-standalone.sh +106 -0
  64. package/.claude/worktrees/agent-a0a8dd02/scripts/cleanup.js +251 -0
  65. package/.claude/worktrees/agent-a0a8dd02/scripts/generate-update-manifest.sh +42 -0
  66. package/.claude/worktrees/agent-a0a8dd02/scripts/install-openclaw.js +986 -0
  67. package/.claude/worktrees/agent-a0a8dd02/scripts/install-skills.js +234 -0
  68. package/.claude/worktrees/agent-a0a8dd02/scripts/postinstall.js +224 -0
  69. package/.claude/worktrees/agent-a0a8dd02/scripts/preuninstall.js +68 -0
  70. package/.claude/worktrees/agent-a0a8dd02/scripts/run-e2e.sh +44 -0
  71. package/.claude/worktrees/agent-a0a8dd02/scripts/smoke-test-standalone.sh +101 -0
  72. package/.claude/worktrees/agent-a0a8dd02/scripts/sync-version.sh +28 -0
  73. package/.claude/worktrees/agent-a0a8dd02/scripts/verify-app-bundle.sh +34 -0
  74. package/.claude/worktrees/agent-a0a8dd02/src/dashboard/public/app.js +2683 -0
  75. package/.claude/worktrees/agent-a0a8dd02/src/dashboard/public/index.html +393 -0
  76. package/.claude/worktrees/agent-a0a8dd02/src/dashboard/public/style.css +1294 -0
  77. package/.claude/worktrees/agent-a0a8dd02/src/index.js +76 -0
  78. package/.claude/worktrees/agent-a0a8dd02/src/lib/agent-card.js +111 -0
  79. package/.claude/worktrees/agent-a0a8dd02/src/lib/call-monitor.js +205 -0
  80. package/.claude/worktrees/agent-a0a8dd02/src/lib/callbook.js +366 -0
  81. package/.claude/worktrees/agent-a0a8dd02/src/lib/claude-subagent.js +696 -0
  82. package/.claude/worktrees/agent-a0a8dd02/src/lib/client.js +683 -0
  83. package/.claude/worktrees/agent-a0a8dd02/src/lib/config.js +480 -0
  84. package/.claude/worktrees/agent-a0a8dd02/src/lib/conversation-driver.js +608 -0
  85. package/.claude/worktrees/agent-a0a8dd02/src/lib/conversations.js +830 -0
  86. package/.claude/worktrees/agent-a0a8dd02/src/lib/crypto.js +113 -0
  87. package/.claude/worktrees/agent-a0a8dd02/src/lib/dashboard-events.js +213 -0
  88. package/.claude/worktrees/agent-a0a8dd02/src/lib/disclosure.js +792 -0
  89. package/.claude/worktrees/agent-a0a8dd02/src/lib/external-ip.js +211 -0
  90. package/.claude/worktrees/agent-a0a8dd02/src/lib/invite-host.js +223 -0
  91. package/.claude/worktrees/agent-a0a8dd02/src/lib/local-request.js +69 -0
  92. package/.claude/worktrees/agent-a0a8dd02/src/lib/logger.js +677 -0
  93. package/.claude/worktrees/agent-a0a8dd02/src/lib/openclaw-integration.js +339 -0
  94. package/.claude/worktrees/agent-a0a8dd02/src/lib/pid-file.js +103 -0
  95. package/.claude/worktrees/agent-a0a8dd02/src/lib/port-scanner.js +83 -0
  96. package/.claude/worktrees/agent-a0a8dd02/src/lib/prompt-template.js +355 -0
  97. package/.claude/worktrees/agent-a0a8dd02/src/lib/runtime-adapter.js +701 -0
  98. package/.claude/worktrees/agent-a0a8dd02/src/lib/summarizer.js +156 -0
  99. package/.claude/worktrees/agent-a0a8dd02/src/lib/summary-formatter.js +168 -0
  100. package/.claude/worktrees/agent-a0a8dd02/src/lib/summary-prompt.js +203 -0
  101. package/.claude/worktrees/agent-a0a8dd02/src/lib/tokens.js +868 -0
  102. package/.claude/worktrees/agent-a0a8dd02/src/lib/turn-timeout.js +52 -0
  103. package/.claude/worktrees/agent-a0a8dd02/src/lib/update-checker.js +93 -0
  104. package/.claude/worktrees/agent-a0a8dd02/src/lib/update-manager.js +313 -0
  105. package/.claude/worktrees/agent-a0a8dd02/src/routes/a2a.js +1213 -0
  106. package/.claude/worktrees/agent-a0a8dd02/src/routes/callbook.js +142 -0
  107. package/.claude/worktrees/agent-a0a8dd02/src/routes/dashboard.js +1578 -0
  108. package/.claude/worktrees/agent-a0a8dd02/src/server.js +1179 -0
  109. package/.claude/worktrees/agent-a3c12538/.a2a-manifest.json +70 -0
  110. package/.claude/worktrees/agent-a3c12538/.c8rc.json +16 -0
  111. package/.claude/worktrees/agent-a3c12538/.claude/a2a-skill-reference.md +462 -0
  112. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-app.md +42 -0
  113. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-call.md +26 -0
  114. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-contacts.md +31 -0
  115. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-conversations.md +47 -0
  116. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-gui.md +30 -0
  117. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-invite.md +63 -0
  118. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-setup.md +30 -0
  119. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-skills.md +27 -0
  120. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-status.md +46 -0
  121. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-uninstall.md +36 -0
  122. package/.claude/worktrees/agent-a3c12538/.claude/commands/a2a-update.md +41 -0
  123. package/.claude/worktrees/agent-a3c12538/.node-version +1 -0
  124. package/.claude/worktrees/agent-a3c12538/ARCHITECTURE.md +135 -0
  125. package/.claude/worktrees/agent-a3c12538/CLAUDE-INSTALL.md +156 -0
  126. package/.claude/worktrees/agent-a3c12538/CONVENTIONS.md +169 -0
  127. package/.claude/worktrees/agent-a3c12538/README.md +470 -0
  128. package/.claude/worktrees/agent-a3c12538/SKILL.md +462 -0
  129. package/.claude/worktrees/agent-a3c12538/bin/cli.js +3184 -0
  130. package/.claude/worktrees/agent-a3c12538/biome.json +27 -0
  131. package/.claude/worktrees/agent-a3c12538/docs/app.js +30 -0
  132. package/.claude/worktrees/agent-a3c12538/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  133. package/.claude/worktrees/agent-a3c12538/docs/assets/icon-32.png +0 -0
  134. package/.claude/worktrees/agent-a3c12538/docs/assets/icon-64.png +0 -0
  135. package/.claude/worktrees/agent-a3c12538/docs/index.html +117 -0
  136. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  137. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  138. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-02-16-auto-updater.md +1284 -0
  139. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  140. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  141. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  142. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  143. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  144. package/.claude/worktrees/agent-a3c12538/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  145. package/.claude/worktrees/agent-a3c12538/docs/prompts/e2e-test-agent.md +368 -0
  146. package/.claude/worktrees/agent-a3c12538/docs/protocol.md +440 -0
  147. package/.claude/worktrees/agent-a3c12538/docs/signing-setup.md +49 -0
  148. package/.claude/worktrees/agent-a3c12538/docs/style.css +209 -0
  149. package/.claude/worktrees/agent-a3c12538/eslint.config.js +16 -0
  150. package/.claude/worktrees/agent-a3c12538/knip.json +17 -0
  151. package/.claude/worktrees/agent-a3c12538/native/macos/index.html +179 -0
  152. package/.claude/worktrees/agent-a3c12538/native/macos/package.json +8 -0
  153. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/Cargo.lock +5875 -0
  154. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/Cargo.toml +24 -0
  155. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/binaries/.gitkeep +0 -0
  156. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/build.rs +3 -0
  157. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/capabilities/default.json +26 -0
  158. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/entitlements.plist +14 -0
  159. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/icons/128x128.png +0 -0
  160. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  161. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/icons/32x32.png +0 -0
  162. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/icons/icon.icns +0 -0
  163. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/icons/tray-connected.png +0 -0
  164. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  165. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/src/discovery.rs +184 -0
  166. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/src/health.rs +67 -0
  167. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/src/lib.rs +226 -0
  168. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/src/main.rs +6 -0
  169. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/src/notifications.rs +180 -0
  170. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/src/server.rs +306 -0
  171. package/.claude/worktrees/agent-a3c12538/native/macos/src-tauri/tauri.conf.json +50 -0
  172. package/.claude/worktrees/agent-a3c12538/package.json +54 -0
  173. package/.claude/worktrees/agent-a3c12538/pkg.config.json +14 -0
  174. package/.claude/worktrees/agent-a3c12538/scripts/build-standalone.sh +106 -0
  175. package/.claude/worktrees/agent-a3c12538/scripts/cleanup.js +251 -0
  176. package/.claude/worktrees/agent-a3c12538/scripts/install-openclaw.js +986 -0
  177. package/.claude/worktrees/agent-a3c12538/scripts/install-skills.js +234 -0
  178. package/.claude/worktrees/agent-a3c12538/scripts/postinstall.js +224 -0
  179. package/.claude/worktrees/agent-a3c12538/scripts/preuninstall.js +68 -0
  180. package/.claude/worktrees/agent-a3c12538/scripts/run-e2e.sh +44 -0
  181. package/.claude/worktrees/agent-a3c12538/scripts/smoke-test-standalone.sh +101 -0
  182. package/.claude/worktrees/agent-a3c12538/scripts/sync-version.sh +28 -0
  183. package/.claude/worktrees/agent-a3c12538/scripts/verify-app-bundle.sh +34 -0
  184. package/.claude/worktrees/agent-a3c12538/src/dashboard/public/app.js +2649 -0
  185. package/.claude/worktrees/agent-a3c12538/src/dashboard/public/index.html +386 -0
  186. package/.claude/worktrees/agent-a3c12538/src/dashboard/public/style.css +1274 -0
  187. package/.claude/worktrees/agent-a3c12538/src/index.js +76 -0
  188. package/.claude/worktrees/agent-a3c12538/src/lib/agent-card.js +111 -0
  189. package/.claude/worktrees/agent-a3c12538/src/lib/call-monitor.js +205 -0
  190. package/.claude/worktrees/agent-a3c12538/src/lib/callbook.js +366 -0
  191. package/.claude/worktrees/agent-a3c12538/src/lib/claude-subagent.js +696 -0
  192. package/.claude/worktrees/agent-a3c12538/src/lib/client.js +683 -0
  193. package/.claude/worktrees/agent-a3c12538/src/lib/config.js +480 -0
  194. package/.claude/worktrees/agent-a3c12538/src/lib/conversation-driver.js +608 -0
  195. package/.claude/worktrees/agent-a3c12538/src/lib/conversations.js +830 -0
  196. package/.claude/worktrees/agent-a3c12538/src/lib/crypto.js +113 -0
  197. package/.claude/worktrees/agent-a3c12538/src/lib/dashboard-events.js +213 -0
  198. package/.claude/worktrees/agent-a3c12538/src/lib/disclosure.js +792 -0
  199. package/.claude/worktrees/agent-a3c12538/src/lib/external-ip.js +211 -0
  200. package/.claude/worktrees/agent-a3c12538/src/lib/invite-host.js +223 -0
  201. package/.claude/worktrees/agent-a3c12538/src/lib/local-request.js +69 -0
  202. package/.claude/worktrees/agent-a3c12538/src/lib/logger.js +677 -0
  203. package/.claude/worktrees/agent-a3c12538/src/lib/openclaw-integration.js +339 -0
  204. package/.claude/worktrees/agent-a3c12538/src/lib/pid-file.js +103 -0
  205. package/.claude/worktrees/agent-a3c12538/src/lib/port-scanner.js +83 -0
  206. package/.claude/worktrees/agent-a3c12538/src/lib/prompt-template.js +355 -0
  207. package/.claude/worktrees/agent-a3c12538/src/lib/runtime-adapter.js +701 -0
  208. package/.claude/worktrees/agent-a3c12538/src/lib/summarizer.js +156 -0
  209. package/.claude/worktrees/agent-a3c12538/src/lib/summary-formatter.js +168 -0
  210. package/.claude/worktrees/agent-a3c12538/src/lib/summary-prompt.js +203 -0
  211. package/.claude/worktrees/agent-a3c12538/src/lib/tokens.js +868 -0
  212. package/.claude/worktrees/agent-a3c12538/src/lib/turn-timeout.js +52 -0
  213. package/.claude/worktrees/agent-a3c12538/src/lib/update-checker.js +93 -0
  214. package/.claude/worktrees/agent-a3c12538/src/lib/update-manager.js +313 -0
  215. package/.claude/worktrees/agent-a3c12538/src/routes/a2a.js +1213 -0
  216. package/.claude/worktrees/agent-a3c12538/src/routes/callbook.js +142 -0
  217. package/.claude/worktrees/agent-a3c12538/src/routes/dashboard.js +1578 -0
  218. package/.claude/worktrees/agent-a3c12538/src/server.js +1179 -0
  219. package/.claude/worktrees/agent-a5b87d75/.a2a-manifest.json +70 -0
  220. package/.claude/worktrees/agent-a5b87d75/.c8rc.json +16 -0
  221. package/.claude/worktrees/agent-a5b87d75/.claude/a2a-skill-reference.md +462 -0
  222. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-app.md +42 -0
  223. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-call.md +26 -0
  224. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-contacts.md +31 -0
  225. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-conversations.md +47 -0
  226. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-gui.md +30 -0
  227. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-invite.md +63 -0
  228. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-setup.md +30 -0
  229. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-skills.md +27 -0
  230. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-status.md +46 -0
  231. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-uninstall.md +36 -0
  232. package/.claude/worktrees/agent-a5b87d75/.claude/commands/a2a-update.md +41 -0
  233. package/.claude/worktrees/agent-a5b87d75/.node-version +1 -0
  234. package/.claude/worktrees/agent-a5b87d75/ARCHITECTURE.md +135 -0
  235. package/.claude/worktrees/agent-a5b87d75/CLAUDE-INSTALL.md +156 -0
  236. package/.claude/worktrees/agent-a5b87d75/CONVENTIONS.md +208 -0
  237. package/.claude/worktrees/agent-a5b87d75/README.md +470 -0
  238. package/.claude/worktrees/agent-a5b87d75/SKILL.md +462 -0
  239. package/.claude/worktrees/agent-a5b87d75/bin/cli.js +3184 -0
  240. package/.claude/worktrees/agent-a5b87d75/biome.json +27 -0
  241. package/.claude/worktrees/agent-a5b87d75/docs/app.js +30 -0
  242. package/.claude/worktrees/agent-a5b87d75/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  243. package/.claude/worktrees/agent-a5b87d75/docs/assets/icon-32.png +0 -0
  244. package/.claude/worktrees/agent-a5b87d75/docs/assets/icon-64.png +0 -0
  245. package/.claude/worktrees/agent-a5b87d75/docs/index.html +117 -0
  246. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  247. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  248. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-02-16-auto-updater.md +1284 -0
  249. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  250. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  251. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  252. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  253. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  254. package/.claude/worktrees/agent-a5b87d75/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  255. package/.claude/worktrees/agent-a5b87d75/docs/prompts/e2e-test-agent.md +368 -0
  256. package/.claude/worktrees/agent-a5b87d75/docs/protocol.md +440 -0
  257. package/.claude/worktrees/agent-a5b87d75/docs/signing-setup.md +49 -0
  258. package/.claude/worktrees/agent-a5b87d75/docs/style.css +209 -0
  259. package/.claude/worktrees/agent-a5b87d75/eslint.config.js +16 -0
  260. package/.claude/worktrees/agent-a5b87d75/knip.json +17 -0
  261. package/.claude/worktrees/agent-a5b87d75/native/macos/index.html +182 -0
  262. package/.claude/worktrees/agent-a5b87d75/native/macos/package.json +8 -0
  263. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/Cargo.lock +5875 -0
  264. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/Cargo.toml +25 -0
  265. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/binaries/.gitkeep +0 -0
  266. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/build.rs +3 -0
  267. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/capabilities/default.json +26 -0
  268. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/dmg-background.png +0 -0
  269. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/dmg-background@2x.png +0 -0
  270. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/entitlements.plist +14 -0
  271. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/128x128.png +0 -0
  272. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  273. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/256x256.png +0 -0
  274. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/32x32.png +0 -0
  275. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/512x512.png +0 -0
  276. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/512x512@2x.png +0 -0
  277. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/icon.icns +0 -0
  278. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/tray-connected.png +0 -0
  279. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  280. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/src/discovery.rs +221 -0
  281. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/src/health.rs +67 -0
  282. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/src/lib.rs +256 -0
  283. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/src/main.rs +6 -0
  284. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/src/notifications.rs +180 -0
  285. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/src/server.rs +306 -0
  286. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/src/updater.rs +124 -0
  287. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/tauri.conf.json +68 -0
  288. package/.claude/worktrees/agent-a5b87d75/native/macos/src-tauri/volume-icon.icns +0 -0
  289. package/.claude/worktrees/agent-a5b87d75/package.json +55 -0
  290. package/.claude/worktrees/agent-a5b87d75/pkg.config.json +14 -0
  291. package/.claude/worktrees/agent-a5b87d75/scripts/build-standalone.sh +106 -0
  292. package/.claude/worktrees/agent-a5b87d75/scripts/cleanup.js +251 -0
  293. package/.claude/worktrees/agent-a5b87d75/scripts/generate-update-manifest.sh +42 -0
  294. package/.claude/worktrees/agent-a5b87d75/scripts/install-openclaw.js +986 -0
  295. package/.claude/worktrees/agent-a5b87d75/scripts/install-skills.js +234 -0
  296. package/.claude/worktrees/agent-a5b87d75/scripts/postinstall.js +224 -0
  297. package/.claude/worktrees/agent-a5b87d75/scripts/preuninstall.js +68 -0
  298. package/.claude/worktrees/agent-a5b87d75/scripts/run-e2e.sh +52 -0
  299. package/.claude/worktrees/agent-a5b87d75/scripts/smoke-test-standalone.sh +101 -0
  300. package/.claude/worktrees/agent-a5b87d75/scripts/sync-version.sh +28 -0
  301. package/.claude/worktrees/agent-a5b87d75/scripts/verify-app-bundle.sh +34 -0
  302. package/.claude/worktrees/agent-a5b87d75/src/dashboard/public/app.js +2683 -0
  303. package/.claude/worktrees/agent-a5b87d75/src/dashboard/public/index.html +393 -0
  304. package/.claude/worktrees/agent-a5b87d75/src/dashboard/public/onboarding.css +269 -0
  305. package/.claude/worktrees/agent-a5b87d75/src/dashboard/public/onboarding.html +96 -0
  306. package/.claude/worktrees/agent-a5b87d75/src/dashboard/public/onboarding.js +277 -0
  307. package/.claude/worktrees/agent-a5b87d75/src/dashboard/public/style.css +1294 -0
  308. package/.claude/worktrees/agent-a5b87d75/src/index.js +76 -0
  309. package/.claude/worktrees/agent-a5b87d75/src/lib/agent-card.js +111 -0
  310. package/.claude/worktrees/agent-a5b87d75/src/lib/call-monitor.js +205 -0
  311. package/.claude/worktrees/agent-a5b87d75/src/lib/callbook.js +366 -0
  312. package/.claude/worktrees/agent-a5b87d75/src/lib/claude-subagent.js +696 -0
  313. package/.claude/worktrees/agent-a5b87d75/src/lib/client.js +683 -0
  314. package/.claude/worktrees/agent-a5b87d75/src/lib/config.js +480 -0
  315. package/.claude/worktrees/agent-a5b87d75/src/lib/conversation-driver.js +608 -0
  316. package/.claude/worktrees/agent-a5b87d75/src/lib/conversations.js +830 -0
  317. package/.claude/worktrees/agent-a5b87d75/src/lib/crypto.js +113 -0
  318. package/.claude/worktrees/agent-a5b87d75/src/lib/dashboard-events.js +213 -0
  319. package/.claude/worktrees/agent-a5b87d75/src/lib/disclosure.js +792 -0
  320. package/.claude/worktrees/agent-a5b87d75/src/lib/external-ip.js +211 -0
  321. package/.claude/worktrees/agent-a5b87d75/src/lib/invite-host.js +223 -0
  322. package/.claude/worktrees/agent-a5b87d75/src/lib/local-request.js +69 -0
  323. package/.claude/worktrees/agent-a5b87d75/src/lib/logger.js +677 -0
  324. package/.claude/worktrees/agent-a5b87d75/src/lib/openclaw-integration.js +339 -0
  325. package/.claude/worktrees/agent-a5b87d75/src/lib/pid-file.js +103 -0
  326. package/.claude/worktrees/agent-a5b87d75/src/lib/port-scanner.js +83 -0
  327. package/.claude/worktrees/agent-a5b87d75/src/lib/prompt-template.js +355 -0
  328. package/.claude/worktrees/agent-a5b87d75/src/lib/runtime-adapter.js +701 -0
  329. package/.claude/worktrees/agent-a5b87d75/src/lib/summarizer.js +156 -0
  330. package/.claude/worktrees/agent-a5b87d75/src/lib/summary-formatter.js +168 -0
  331. package/.claude/worktrees/agent-a5b87d75/src/lib/summary-prompt.js +203 -0
  332. package/.claude/worktrees/agent-a5b87d75/src/lib/tokens.js +868 -0
  333. package/.claude/worktrees/agent-a5b87d75/src/lib/turn-timeout.js +52 -0
  334. package/.claude/worktrees/agent-a5b87d75/src/lib/update-checker.js +93 -0
  335. package/.claude/worktrees/agent-a5b87d75/src/lib/update-manager.js +313 -0
  336. package/.claude/worktrees/agent-a5b87d75/src/routes/a2a.js +1213 -0
  337. package/.claude/worktrees/agent-a5b87d75/src/routes/callbook.js +142 -0
  338. package/.claude/worktrees/agent-a5b87d75/src/routes/dashboard.js +1688 -0
  339. package/.claude/worktrees/agent-a5b87d75/src/server.js +1179 -0
  340. package/.claude/worktrees/agent-acefedbd/.a2a-manifest.json +70 -0
  341. package/.claude/worktrees/agent-acefedbd/.c8rc.json +16 -0
  342. package/.claude/worktrees/agent-acefedbd/.claude/a2a-skill-reference.md +462 -0
  343. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-app.md +42 -0
  344. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-call.md +26 -0
  345. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-contacts.md +31 -0
  346. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-conversations.md +47 -0
  347. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-gui.md +30 -0
  348. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-invite.md +63 -0
  349. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-setup.md +30 -0
  350. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-skills.md +27 -0
  351. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-status.md +46 -0
  352. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-uninstall.md +36 -0
  353. package/.claude/worktrees/agent-acefedbd/.claude/commands/a2a-update.md +41 -0
  354. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.a2a-manifest.json +70 -0
  355. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.c8rc.json +16 -0
  356. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/a2a-skill-reference.md +462 -0
  357. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-app.md +42 -0
  358. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-call.md +26 -0
  359. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-contacts.md +31 -0
  360. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-conversations.md +47 -0
  361. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-gui.md +30 -0
  362. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-invite.md +63 -0
  363. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-setup.md +30 -0
  364. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-skills.md +27 -0
  365. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-status.md +46 -0
  366. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-uninstall.md +36 -0
  367. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.claude/commands/a2a-update.md +41 -0
  368. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/.node-version +1 -0
  369. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/ARCHITECTURE.md +135 -0
  370. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/CLAUDE-INSTALL.md +156 -0
  371. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/CONVENTIONS.md +179 -0
  372. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/README.md +470 -0
  373. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/SKILL.md +462 -0
  374. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/bin/cli.js +3184 -0
  375. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/biome.json +27 -0
  376. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  377. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  378. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  379. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-02-16-auto-updater.md +1284 -0
  380. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  381. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  382. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  383. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  384. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  385. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  386. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/prompts/e2e-test-agent.md +368 -0
  387. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/protocol.md +440 -0
  388. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/docs/signing-setup.md +49 -0
  389. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/eslint.config.js +16 -0
  390. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/knip.json +17 -0
  391. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/index.html +179 -0
  392. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/package.json +8 -0
  393. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/Cargo.lock +5875 -0
  394. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/Cargo.toml +25 -0
  395. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/binaries/.gitkeep +0 -0
  396. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/build.rs +3 -0
  397. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/capabilities/default.json +26 -0
  398. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/entitlements.plist +14 -0
  399. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/icons/128x128.png +0 -0
  400. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  401. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/icons/32x32.png +0 -0
  402. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/icons/icon.icns +0 -0
  403. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/icons/tray-connected.png +0 -0
  404. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  405. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/src/discovery.rs +184 -0
  406. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/src/health.rs +67 -0
  407. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/src/lib.rs +255 -0
  408. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/src/main.rs +6 -0
  409. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/src/notifications.rs +180 -0
  410. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/src/server.rs +306 -0
  411. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/src/updater.rs +117 -0
  412. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/native/macos/src-tauri/tauri.conf.json +58 -0
  413. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/package.json +54 -0
  414. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/pkg.config.json +14 -0
  415. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/build-standalone.sh +106 -0
  416. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/cleanup.js +251 -0
  417. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/generate-update-manifest.sh +42 -0
  418. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/install-openclaw.js +986 -0
  419. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/install-skills.js +234 -0
  420. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/postinstall.js +224 -0
  421. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/preuninstall.js +68 -0
  422. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/run-e2e.sh +44 -0
  423. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/smoke-test-standalone.sh +101 -0
  424. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/sync-version.sh +28 -0
  425. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/scripts/verify-app-bundle.sh +34 -0
  426. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/dashboard/public/app.js +2683 -0
  427. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/dashboard/public/index.html +394 -0
  428. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/dashboard/public/style.css +1294 -0
  429. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/index.js +76 -0
  430. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/agent-card.js +111 -0
  431. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/call-monitor.js +205 -0
  432. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/callbook.js +366 -0
  433. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/claude-subagent.js +696 -0
  434. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/client.js +683 -0
  435. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/config.js +480 -0
  436. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/conversation-driver.js +608 -0
  437. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/conversations.js +830 -0
  438. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/crypto.js +113 -0
  439. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/dashboard-events.js +213 -0
  440. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/disclosure.js +792 -0
  441. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/external-ip.js +211 -0
  442. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/invite-host.js +223 -0
  443. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/local-request.js +69 -0
  444. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/logger.js +677 -0
  445. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/openclaw-integration.js +339 -0
  446. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/pid-file.js +103 -0
  447. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/port-scanner.js +83 -0
  448. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/prompt-template.js +355 -0
  449. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/runtime-adapter.js +701 -0
  450. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/summarizer.js +156 -0
  451. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/summary-formatter.js +168 -0
  452. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/summary-prompt.js +203 -0
  453. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/tokens.js +868 -0
  454. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/turn-timeout.js +52 -0
  455. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/update-checker.js +93 -0
  456. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/lib/update-manager.js +313 -0
  457. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/routes/a2a.js +1213 -0
  458. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/routes/callbook.js +142 -0
  459. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/routes/dashboard.js +1578 -0
  460. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a04dc0fe/src/server.js +1179 -0
  461. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.a2a-manifest.json +70 -0
  462. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.c8rc.json +16 -0
  463. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/a2a-skill-reference.md +462 -0
  464. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-app.md +42 -0
  465. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-call.md +26 -0
  466. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-contacts.md +31 -0
  467. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-conversations.md +47 -0
  468. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-gui.md +30 -0
  469. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-invite.md +63 -0
  470. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-setup.md +30 -0
  471. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-skills.md +27 -0
  472. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-status.md +46 -0
  473. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-uninstall.md +36 -0
  474. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.claude/commands/a2a-update.md +41 -0
  475. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/.node-version +1 -0
  476. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/ARCHITECTURE.md +135 -0
  477. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/CLAUDE-INSTALL.md +156 -0
  478. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/CONVENTIONS.md +178 -0
  479. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/README.md +470 -0
  480. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/SKILL.md +462 -0
  481. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/bin/cli.js +3184 -0
  482. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/biome.json +27 -0
  483. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  484. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  485. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  486. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-02-16-auto-updater.md +1284 -0
  487. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  488. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  489. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  490. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  491. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  492. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  493. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/prompts/e2e-test-agent.md +368 -0
  494. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/protocol.md +440 -0
  495. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/docs/signing-setup.md +49 -0
  496. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/eslint.config.js +16 -0
  497. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/knip.json +17 -0
  498. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/index.html +179 -0
  499. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/package.json +8 -0
  500. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/Cargo.lock +5875 -0
  501. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/Cargo.toml +24 -0
  502. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/binaries/.gitkeep +0 -0
  503. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/build.rs +3 -0
  504. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/capabilities/default.json +26 -0
  505. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/dmg-background.png +0 -0
  506. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/dmg-background@2x.png +0 -0
  507. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/entitlements.plist +14 -0
  508. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/128x128.png +0 -0
  509. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  510. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/256x256.png +0 -0
  511. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/32x32.png +0 -0
  512. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/512x512.png +0 -0
  513. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/512x512@2x.png +0 -0
  514. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/icon.icns +0 -0
  515. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/tray-connected.png +0 -0
  516. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  517. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/src/discovery.rs +184 -0
  518. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/src/health.rs +67 -0
  519. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/src/lib.rs +226 -0
  520. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/src/main.rs +6 -0
  521. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/src/notifications.rs +180 -0
  522. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/src/server.rs +306 -0
  523. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/tauri.conf.json +60 -0
  524. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/native/macos/src-tauri/volume-icon.icns +0 -0
  525. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/package.json +54 -0
  526. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/pkg.config.json +14 -0
  527. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/build-standalone.sh +106 -0
  528. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/cleanup.js +251 -0
  529. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/install-openclaw.js +986 -0
  530. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/install-skills.js +234 -0
  531. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/postinstall.js +224 -0
  532. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/preuninstall.js +68 -0
  533. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/run-e2e.sh +44 -0
  534. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/smoke-test-standalone.sh +101 -0
  535. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/sync-version.sh +28 -0
  536. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/scripts/verify-app-bundle.sh +34 -0
  537. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/dashboard/public/app.js +2649 -0
  538. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/dashboard/public/index.html +386 -0
  539. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/dashboard/public/style.css +1274 -0
  540. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/index.js +76 -0
  541. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/agent-card.js +111 -0
  542. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/call-monitor.js +205 -0
  543. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/callbook.js +366 -0
  544. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/claude-subagent.js +696 -0
  545. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/client.js +683 -0
  546. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/config.js +480 -0
  547. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/conversation-driver.js +608 -0
  548. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/conversations.js +830 -0
  549. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/crypto.js +113 -0
  550. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/dashboard-events.js +213 -0
  551. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/disclosure.js +792 -0
  552. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/external-ip.js +211 -0
  553. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/invite-host.js +223 -0
  554. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/local-request.js +69 -0
  555. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/logger.js +677 -0
  556. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/openclaw-integration.js +339 -0
  557. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/pid-file.js +103 -0
  558. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/port-scanner.js +83 -0
  559. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/prompt-template.js +355 -0
  560. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/runtime-adapter.js +701 -0
  561. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/summarizer.js +156 -0
  562. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/summary-formatter.js +168 -0
  563. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/summary-prompt.js +203 -0
  564. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/tokens.js +868 -0
  565. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/turn-timeout.js +52 -0
  566. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/update-checker.js +93 -0
  567. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/lib/update-manager.js +313 -0
  568. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/routes/a2a.js +1213 -0
  569. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/routes/callbook.js +142 -0
  570. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/routes/dashboard.js +1578 -0
  571. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-a1418bc4/src/server.js +1179 -0
  572. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.a2a-manifest.json +70 -0
  573. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.c8rc.json +16 -0
  574. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/a2a-skill-reference.md +462 -0
  575. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-app.md +42 -0
  576. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-call.md +26 -0
  577. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-contacts.md +31 -0
  578. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-conversations.md +47 -0
  579. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-gui.md +30 -0
  580. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-invite.md +63 -0
  581. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-setup.md +30 -0
  582. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-skills.md +27 -0
  583. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-status.md +46 -0
  584. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-uninstall.md +36 -0
  585. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.claude/commands/a2a-update.md +41 -0
  586. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/.node-version +1 -0
  587. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/ARCHITECTURE.md +135 -0
  588. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/CLAUDE-INSTALL.md +156 -0
  589. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/CONVENTIONS.md +169 -0
  590. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/README.md +470 -0
  591. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/SKILL.md +462 -0
  592. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/bin/cli.js +3184 -0
  593. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/biome.json +27 -0
  594. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/app.js +160 -0
  595. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  596. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/assets/icon-32.png +0 -0
  597. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/assets/icon-64.png +0 -0
  598. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/index.html +166 -0
  599. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  600. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  601. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-02-16-auto-updater.md +1284 -0
  602. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  603. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  604. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  605. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  606. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  607. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  608. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/prompts/e2e-test-agent.md +368 -0
  609. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/protocol.md +440 -0
  610. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/signing-setup.md +49 -0
  611. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/docs/style.css +457 -0
  612. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/eslint.config.js +16 -0
  613. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/knip.json +17 -0
  614. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/index.html +179 -0
  615. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/package.json +8 -0
  616. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/Cargo.lock +5875 -0
  617. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/Cargo.toml +24 -0
  618. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/binaries/.gitkeep +0 -0
  619. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/build.rs +3 -0
  620. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/capabilities/default.json +26 -0
  621. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/entitlements.plist +14 -0
  622. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/icons/128x128.png +0 -0
  623. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  624. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/icons/32x32.png +0 -0
  625. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/icons/icon.icns +0 -0
  626. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/icons/tray-connected.png +0 -0
  627. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  628. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/src/discovery.rs +184 -0
  629. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/src/health.rs +67 -0
  630. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/src/lib.rs +226 -0
  631. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/src/main.rs +6 -0
  632. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/src/notifications.rs +180 -0
  633. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/src/server.rs +306 -0
  634. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/native/macos/src-tauri/tauri.conf.json +50 -0
  635. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/package.json +54 -0
  636. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/pkg.config.json +14 -0
  637. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/build-standalone.sh +106 -0
  638. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/cleanup.js +251 -0
  639. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/install-openclaw.js +986 -0
  640. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/install-skills.js +234 -0
  641. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/postinstall.js +224 -0
  642. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/preuninstall.js +68 -0
  643. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/run-e2e.sh +44 -0
  644. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/smoke-test-standalone.sh +101 -0
  645. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/sync-version.sh +28 -0
  646. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/scripts/verify-app-bundle.sh +34 -0
  647. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/dashboard/public/app.js +2649 -0
  648. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/dashboard/public/index.html +386 -0
  649. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/dashboard/public/style.css +1274 -0
  650. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/index.js +76 -0
  651. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/agent-card.js +111 -0
  652. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/call-monitor.js +205 -0
  653. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/callbook.js +366 -0
  654. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/claude-subagent.js +696 -0
  655. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/client.js +683 -0
  656. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/config.js +480 -0
  657. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/conversation-driver.js +608 -0
  658. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/conversations.js +830 -0
  659. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/crypto.js +113 -0
  660. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/dashboard-events.js +213 -0
  661. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/disclosure.js +792 -0
  662. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/external-ip.js +211 -0
  663. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/invite-host.js +223 -0
  664. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/local-request.js +69 -0
  665. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/logger.js +677 -0
  666. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/openclaw-integration.js +339 -0
  667. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/pid-file.js +103 -0
  668. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/port-scanner.js +83 -0
  669. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/prompt-template.js +355 -0
  670. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/runtime-adapter.js +701 -0
  671. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/summarizer.js +156 -0
  672. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/summary-formatter.js +168 -0
  673. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/summary-prompt.js +203 -0
  674. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/tokens.js +868 -0
  675. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/turn-timeout.js +52 -0
  676. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/update-checker.js +93 -0
  677. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/lib/update-manager.js +313 -0
  678. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/routes/a2a.js +1213 -0
  679. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/routes/callbook.js +142 -0
  680. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/routes/dashboard.js +1578 -0
  681. package/.claude/worktrees/agent-acefedbd/.claude/worktrees/agent-aa4cd927/src/server.js +1179 -0
  682. package/.claude/worktrees/agent-acefedbd/.node-version +1 -0
  683. package/.claude/worktrees/agent-acefedbd/ARCHITECTURE.md +135 -0
  684. package/.claude/worktrees/agent-acefedbd/CLAUDE-INSTALL.md +156 -0
  685. package/.claude/worktrees/agent-acefedbd/CONVENTIONS.md +177 -0
  686. package/.claude/worktrees/agent-acefedbd/README.md +470 -0
  687. package/.claude/worktrees/agent-acefedbd/SKILL.md +462 -0
  688. package/.claude/worktrees/agent-acefedbd/bin/cli.js +3184 -0
  689. package/.claude/worktrees/agent-acefedbd/biome.json +27 -0
  690. package/.claude/worktrees/agent-acefedbd/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  691. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  692. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  693. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-02-16-auto-updater.md +1284 -0
  694. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  695. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  696. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  697. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  698. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  699. package/.claude/worktrees/agent-acefedbd/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  700. package/.claude/worktrees/agent-acefedbd/docs/prompts/e2e-test-agent.md +368 -0
  701. package/.claude/worktrees/agent-acefedbd/docs/protocol.md +440 -0
  702. package/.claude/worktrees/agent-acefedbd/docs/signing-setup.md +49 -0
  703. package/.claude/worktrees/agent-acefedbd/eslint.config.js +16 -0
  704. package/.claude/worktrees/agent-acefedbd/knip.json +17 -0
  705. package/.claude/worktrees/agent-acefedbd/native/macos/index.html +182 -0
  706. package/.claude/worktrees/agent-acefedbd/native/macos/package.json +8 -0
  707. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/Cargo.lock +5875 -0
  708. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/Cargo.toml +24 -0
  709. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/binaries/.gitkeep +0 -0
  710. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/build.rs +3 -0
  711. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/capabilities/default.json +26 -0
  712. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/entitlements.plist +14 -0
  713. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/icons/128x128.png +0 -0
  714. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  715. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/icons/32x32.png +0 -0
  716. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/icons/icon.icns +0 -0
  717. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/icons/tray-connected.png +0 -0
  718. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  719. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/src/discovery.rs +221 -0
  720. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/src/health.rs +67 -0
  721. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/src/lib.rs +226 -0
  722. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/src/main.rs +6 -0
  723. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/src/notifications.rs +180 -0
  724. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/src/server.rs +306 -0
  725. package/.claude/worktrees/agent-acefedbd/native/macos/src-tauri/tauri.conf.json +50 -0
  726. package/.claude/worktrees/agent-acefedbd/package.json +54 -0
  727. package/.claude/worktrees/agent-acefedbd/pkg.config.json +14 -0
  728. package/.claude/worktrees/agent-acefedbd/scripts/build-standalone.sh +106 -0
  729. package/.claude/worktrees/agent-acefedbd/scripts/cleanup.js +251 -0
  730. package/.claude/worktrees/agent-acefedbd/scripts/install-openclaw.js +986 -0
  731. package/.claude/worktrees/agent-acefedbd/scripts/install-skills.js +234 -0
  732. package/.claude/worktrees/agent-acefedbd/scripts/postinstall.js +224 -0
  733. package/.claude/worktrees/agent-acefedbd/scripts/preuninstall.js +68 -0
  734. package/.claude/worktrees/agent-acefedbd/scripts/run-e2e.sh +44 -0
  735. package/.claude/worktrees/agent-acefedbd/scripts/smoke-test-standalone.sh +101 -0
  736. package/.claude/worktrees/agent-acefedbd/scripts/sync-version.sh +28 -0
  737. package/.claude/worktrees/agent-acefedbd/scripts/verify-app-bundle.sh +34 -0
  738. package/.claude/worktrees/agent-acefedbd/src/dashboard/public/app.js +2649 -0
  739. package/.claude/worktrees/agent-acefedbd/src/dashboard/public/index.html +386 -0
  740. package/.claude/worktrees/agent-acefedbd/src/dashboard/public/onboarding.css +269 -0
  741. package/.claude/worktrees/agent-acefedbd/src/dashboard/public/onboarding.html +96 -0
  742. package/.claude/worktrees/agent-acefedbd/src/dashboard/public/onboarding.js +277 -0
  743. package/.claude/worktrees/agent-acefedbd/src/dashboard/public/style.css +1274 -0
  744. package/.claude/worktrees/agent-acefedbd/src/index.js +76 -0
  745. package/.claude/worktrees/agent-acefedbd/src/lib/agent-card.js +111 -0
  746. package/.claude/worktrees/agent-acefedbd/src/lib/call-monitor.js +205 -0
  747. package/.claude/worktrees/agent-acefedbd/src/lib/callbook.js +366 -0
  748. package/.claude/worktrees/agent-acefedbd/src/lib/claude-subagent.js +696 -0
  749. package/.claude/worktrees/agent-acefedbd/src/lib/client.js +683 -0
  750. package/.claude/worktrees/agent-acefedbd/src/lib/config.js +480 -0
  751. package/.claude/worktrees/agent-acefedbd/src/lib/conversation-driver.js +608 -0
  752. package/.claude/worktrees/agent-acefedbd/src/lib/conversations.js +830 -0
  753. package/.claude/worktrees/agent-acefedbd/src/lib/crypto.js +113 -0
  754. package/.claude/worktrees/agent-acefedbd/src/lib/dashboard-events.js +213 -0
  755. package/.claude/worktrees/agent-acefedbd/src/lib/disclosure.js +792 -0
  756. package/.claude/worktrees/agent-acefedbd/src/lib/external-ip.js +211 -0
  757. package/.claude/worktrees/agent-acefedbd/src/lib/invite-host.js +223 -0
  758. package/.claude/worktrees/agent-acefedbd/src/lib/local-request.js +69 -0
  759. package/.claude/worktrees/agent-acefedbd/src/lib/logger.js +677 -0
  760. package/.claude/worktrees/agent-acefedbd/src/lib/openclaw-integration.js +339 -0
  761. package/.claude/worktrees/agent-acefedbd/src/lib/pid-file.js +103 -0
  762. package/.claude/worktrees/agent-acefedbd/src/lib/port-scanner.js +83 -0
  763. package/.claude/worktrees/agent-acefedbd/src/lib/prompt-template.js +355 -0
  764. package/.claude/worktrees/agent-acefedbd/src/lib/runtime-adapter.js +701 -0
  765. package/.claude/worktrees/agent-acefedbd/src/lib/summarizer.js +156 -0
  766. package/.claude/worktrees/agent-acefedbd/src/lib/summary-formatter.js +168 -0
  767. package/.claude/worktrees/agent-acefedbd/src/lib/summary-prompt.js +203 -0
  768. package/.claude/worktrees/agent-acefedbd/src/lib/tokens.js +868 -0
  769. package/.claude/worktrees/agent-acefedbd/src/lib/turn-timeout.js +52 -0
  770. package/.claude/worktrees/agent-acefedbd/src/lib/update-checker.js +93 -0
  771. package/.claude/worktrees/agent-acefedbd/src/lib/update-manager.js +313 -0
  772. package/.claude/worktrees/agent-acefedbd/src/routes/a2a.js +1213 -0
  773. package/.claude/worktrees/agent-acefedbd/src/routes/callbook.js +142 -0
  774. package/.claude/worktrees/agent-acefedbd/src/routes/dashboard.js +1688 -0
  775. package/.claude/worktrees/agent-acefedbd/src/server.js +1179 -0
  776. package/.claude/worktrees/agent-ad420869/.a2a-manifest.json +70 -0
  777. package/.claude/worktrees/agent-ad420869/.c8rc.json +16 -0
  778. package/.claude/worktrees/agent-ad420869/.claude/a2a-skill-reference.md +462 -0
  779. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-app.md +42 -0
  780. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-call.md +26 -0
  781. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-contacts.md +31 -0
  782. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-conversations.md +47 -0
  783. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-gui.md +30 -0
  784. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-invite.md +63 -0
  785. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-setup.md +30 -0
  786. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-skills.md +27 -0
  787. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-status.md +46 -0
  788. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-uninstall.md +36 -0
  789. package/.claude/worktrees/agent-ad420869/.claude/commands/a2a-update.md +41 -0
  790. package/.claude/worktrees/agent-ad420869/.node-version +1 -0
  791. package/.claude/worktrees/agent-ad420869/ARCHITECTURE.md +135 -0
  792. package/.claude/worktrees/agent-ad420869/CLAUDE-INSTALL.md +156 -0
  793. package/.claude/worktrees/agent-ad420869/CONVENTIONS.md +178 -0
  794. package/.claude/worktrees/agent-ad420869/README.md +470 -0
  795. package/.claude/worktrees/agent-ad420869/SKILL.md +462 -0
  796. package/.claude/worktrees/agent-ad420869/bin/cli.js +3184 -0
  797. package/.claude/worktrees/agent-ad420869/biome.json +27 -0
  798. package/.claude/worktrees/agent-ad420869/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  799. package/.claude/worktrees/agent-ad420869/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  800. package/.claude/worktrees/agent-ad420869/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  801. package/.claude/worktrees/agent-ad420869/docs/plans/2026-02-16-auto-updater.md +1284 -0
  802. package/.claude/worktrees/agent-ad420869/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  803. package/.claude/worktrees/agent-ad420869/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  804. package/.claude/worktrees/agent-ad420869/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  805. package/.claude/worktrees/agent-ad420869/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  806. package/.claude/worktrees/agent-ad420869/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  807. package/.claude/worktrees/agent-ad420869/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  808. package/.claude/worktrees/agent-ad420869/docs/prompts/e2e-test-agent.md +368 -0
  809. package/.claude/worktrees/agent-ad420869/docs/protocol.md +440 -0
  810. package/.claude/worktrees/agent-ad420869/docs/signing-setup.md +49 -0
  811. package/.claude/worktrees/agent-ad420869/eslint.config.js +16 -0
  812. package/.claude/worktrees/agent-ad420869/knip.json +17 -0
  813. package/.claude/worktrees/agent-ad420869/native/macos/index.html +182 -0
  814. package/.claude/worktrees/agent-ad420869/native/macos/package.json +8 -0
  815. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/Cargo.lock +5875 -0
  816. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/Cargo.toml +24 -0
  817. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/binaries/.gitkeep +0 -0
  818. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/build.rs +3 -0
  819. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/capabilities/default.json +26 -0
  820. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/entitlements.plist +14 -0
  821. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/icons/128x128.png +0 -0
  822. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  823. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/icons/32x32.png +0 -0
  824. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/icons/icon.icns +0 -0
  825. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/icons/tray-connected.png +0 -0
  826. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  827. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/src/discovery.rs +221 -0
  828. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/src/health.rs +67 -0
  829. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/src/lib.rs +226 -0
  830. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/src/main.rs +6 -0
  831. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/src/notifications.rs +180 -0
  832. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/src/server.rs +306 -0
  833. package/.claude/worktrees/agent-ad420869/native/macos/src-tauri/tauri.conf.json +50 -0
  834. package/.claude/worktrees/agent-ad420869/package.json +54 -0
  835. package/.claude/worktrees/agent-ad420869/pkg.config.json +14 -0
  836. package/.claude/worktrees/agent-ad420869/scripts/build-standalone.sh +106 -0
  837. package/.claude/worktrees/agent-ad420869/scripts/cleanup.js +251 -0
  838. package/.claude/worktrees/agent-ad420869/scripts/install-openclaw.js +986 -0
  839. package/.claude/worktrees/agent-ad420869/scripts/install-skills.js +234 -0
  840. package/.claude/worktrees/agent-ad420869/scripts/postinstall.js +224 -0
  841. package/.claude/worktrees/agent-ad420869/scripts/preuninstall.js +68 -0
  842. package/.claude/worktrees/agent-ad420869/scripts/run-e2e.sh +44 -0
  843. package/.claude/worktrees/agent-ad420869/scripts/smoke-test-standalone.sh +101 -0
  844. package/.claude/worktrees/agent-ad420869/scripts/sync-version.sh +28 -0
  845. package/.claude/worktrees/agent-ad420869/scripts/verify-app-bundle.sh +34 -0
  846. package/.claude/worktrees/agent-ad420869/src/dashboard/public/app.js +2683 -0
  847. package/.claude/worktrees/agent-ad420869/src/dashboard/public/index.html +394 -0
  848. package/.claude/worktrees/agent-ad420869/src/dashboard/public/onboarding.css +269 -0
  849. package/.claude/worktrees/agent-ad420869/src/dashboard/public/onboarding.html +96 -0
  850. package/.claude/worktrees/agent-ad420869/src/dashboard/public/onboarding.js +277 -0
  851. package/.claude/worktrees/agent-ad420869/src/dashboard/public/style.css +1294 -0
  852. package/.claude/worktrees/agent-ad420869/src/index.js +76 -0
  853. package/.claude/worktrees/agent-ad420869/src/lib/agent-card.js +111 -0
  854. package/.claude/worktrees/agent-ad420869/src/lib/call-monitor.js +205 -0
  855. package/.claude/worktrees/agent-ad420869/src/lib/callbook.js +366 -0
  856. package/.claude/worktrees/agent-ad420869/src/lib/claude-subagent.js +696 -0
  857. package/.claude/worktrees/agent-ad420869/src/lib/client.js +683 -0
  858. package/.claude/worktrees/agent-ad420869/src/lib/config.js +480 -0
  859. package/.claude/worktrees/agent-ad420869/src/lib/conversation-driver.js +608 -0
  860. package/.claude/worktrees/agent-ad420869/src/lib/conversations.js +830 -0
  861. package/.claude/worktrees/agent-ad420869/src/lib/crypto.js +113 -0
  862. package/.claude/worktrees/agent-ad420869/src/lib/dashboard-events.js +213 -0
  863. package/.claude/worktrees/agent-ad420869/src/lib/disclosure.js +792 -0
  864. package/.claude/worktrees/agent-ad420869/src/lib/external-ip.js +211 -0
  865. package/.claude/worktrees/agent-ad420869/src/lib/invite-host.js +223 -0
  866. package/.claude/worktrees/agent-ad420869/src/lib/local-request.js +69 -0
  867. package/.claude/worktrees/agent-ad420869/src/lib/logger.js +677 -0
  868. package/.claude/worktrees/agent-ad420869/src/lib/openclaw-integration.js +339 -0
  869. package/.claude/worktrees/agent-ad420869/src/lib/pid-file.js +103 -0
  870. package/.claude/worktrees/agent-ad420869/src/lib/port-scanner.js +83 -0
  871. package/.claude/worktrees/agent-ad420869/src/lib/prompt-template.js +355 -0
  872. package/.claude/worktrees/agent-ad420869/src/lib/runtime-adapter.js +701 -0
  873. package/.claude/worktrees/agent-ad420869/src/lib/summarizer.js +156 -0
  874. package/.claude/worktrees/agent-ad420869/src/lib/summary-formatter.js +168 -0
  875. package/.claude/worktrees/agent-ad420869/src/lib/summary-prompt.js +203 -0
  876. package/.claude/worktrees/agent-ad420869/src/lib/tokens.js +868 -0
  877. package/.claude/worktrees/agent-ad420869/src/lib/turn-timeout.js +52 -0
  878. package/.claude/worktrees/agent-ad420869/src/lib/update-checker.js +93 -0
  879. package/.claude/worktrees/agent-ad420869/src/lib/update-manager.js +313 -0
  880. package/.claude/worktrees/agent-ad420869/src/routes/a2a.js +1213 -0
  881. package/.claude/worktrees/agent-ad420869/src/routes/callbook.js +142 -0
  882. package/.claude/worktrees/agent-ad420869/src/routes/dashboard.js +1688 -0
  883. package/.claude/worktrees/agent-ad420869/src/server.js +1179 -0
  884. package/.claude/worktrees/agent-af1f3b59/.c8rc.json +16 -0
  885. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-app.md +42 -0
  886. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-call.md +26 -0
  887. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-contacts.md +31 -0
  888. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-conversations.md +47 -0
  889. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-gui.md +30 -0
  890. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-invite.md +63 -0
  891. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-setup.md +30 -0
  892. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-skills.md +27 -0
  893. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-status.md +46 -0
  894. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-uninstall.md +36 -0
  895. package/.claude/worktrees/agent-af1f3b59/.claude/commands/a2a-update.md +41 -0
  896. package/.claude/worktrees/agent-af1f3b59/.node-version +1 -0
  897. package/.claude/worktrees/agent-af1f3b59/ARCHITECTURE.md +135 -0
  898. package/.claude/worktrees/agent-af1f3b59/CLAUDE-INSTALL.md +156 -0
  899. package/.claude/worktrees/agent-af1f3b59/CONVENTIONS.md +178 -0
  900. package/.claude/worktrees/agent-af1f3b59/README.md +470 -0
  901. package/.claude/worktrees/agent-af1f3b59/SKILL.md +462 -0
  902. package/.claude/worktrees/agent-af1f3b59/bin/cli.js +3184 -0
  903. package/.claude/worktrees/agent-af1f3b59/biome.json +27 -0
  904. package/.claude/worktrees/agent-af1f3b59/docs/assessments/2026-02-27-google-a2a-protocol-assessment.md +292 -0
  905. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-02-15-port-fallback-warning-design.md +611 -0
  906. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-02-16-a2a-callbook-macos-app.md +1660 -0
  907. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-02-16-auto-updater.md +1284 -0
  908. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-02-16-bugfixes-22-24.md +246 -0
  909. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-02-16-e2e-test-prompt-sequence.md +3085 -0
  910. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-02-16-orphan-process-fix.md +962 -0
  911. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-02-17-claude-code-codex-skills.md +770 -0
  912. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-03-01-a2a-68-openclaw-integration-tests.md +676 -0
  913. package/.claude/worktrees/agent-af1f3b59/docs/plans/2026-03-01-a2a-77-invoke-security-tests.md +661 -0
  914. package/.claude/worktrees/agent-af1f3b59/docs/prompts/e2e-test-agent.md +368 -0
  915. package/.claude/worktrees/agent-af1f3b59/docs/protocol.md +440 -0
  916. package/.claude/worktrees/agent-af1f3b59/docs/signing-setup.md +49 -0
  917. package/.claude/worktrees/agent-af1f3b59/eslint.config.js +16 -0
  918. package/.claude/worktrees/agent-af1f3b59/knip.json +17 -0
  919. package/.claude/worktrees/agent-af1f3b59/native/macos/index.html +179 -0
  920. package/.claude/worktrees/agent-af1f3b59/native/macos/package.json +8 -0
  921. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/Cargo.lock +5875 -0
  922. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/Cargo.toml +24 -0
  923. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/binaries/.gitkeep +0 -0
  924. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/build.rs +3 -0
  925. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/capabilities/default.json +26 -0
  926. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/dmg-background.png +0 -0
  927. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/dmg-background@2x.png +0 -0
  928. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/entitlements.plist +14 -0
  929. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/128x128.png +0 -0
  930. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/128x128@2x.png +0 -0
  931. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/256x256.png +0 -0
  932. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/32x32.png +0 -0
  933. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/512x512.png +0 -0
  934. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/512x512@2x.png +0 -0
  935. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/icon.icns +0 -0
  936. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/tray-connected.png +0 -0
  937. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/icons/tray-disconnected.png +0 -0
  938. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/src/discovery.rs +184 -0
  939. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/src/health.rs +67 -0
  940. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/src/lib.rs +226 -0
  941. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/src/main.rs +6 -0
  942. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/src/notifications.rs +180 -0
  943. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/src/server.rs +306 -0
  944. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/tauri.conf.json +60 -0
  945. package/.claude/worktrees/agent-af1f3b59/native/macos/src-tauri/volume-icon.icns +0 -0
  946. package/.claude/worktrees/agent-af1f3b59/package.json +54 -0
  947. package/.claude/worktrees/agent-af1f3b59/pkg.config.json +14 -0
  948. package/.claude/worktrees/agent-af1f3b59/scripts/build-standalone.sh +106 -0
  949. package/.claude/worktrees/agent-af1f3b59/scripts/cleanup.js +251 -0
  950. package/.claude/worktrees/agent-af1f3b59/scripts/install-openclaw.js +986 -0
  951. package/.claude/worktrees/agent-af1f3b59/scripts/install-skills.js +234 -0
  952. package/.claude/worktrees/agent-af1f3b59/scripts/postinstall.js +224 -0
  953. package/.claude/worktrees/agent-af1f3b59/scripts/preuninstall.js +68 -0
  954. package/.claude/worktrees/agent-af1f3b59/scripts/run-e2e.sh +44 -0
  955. package/.claude/worktrees/agent-af1f3b59/scripts/smoke-test-standalone.sh +101 -0
  956. package/.claude/worktrees/agent-af1f3b59/scripts/sync-version.sh +28 -0
  957. package/.claude/worktrees/agent-af1f3b59/scripts/verify-app-bundle.sh +34 -0
  958. package/.claude/worktrees/agent-af1f3b59/src/dashboard/public/app.js +2649 -0
  959. package/.claude/worktrees/agent-af1f3b59/src/dashboard/public/index.html +386 -0
  960. package/.claude/worktrees/agent-af1f3b59/src/dashboard/public/style.css +1274 -0
  961. package/.claude/worktrees/agent-af1f3b59/src/index.js +76 -0
  962. package/.claude/worktrees/agent-af1f3b59/src/lib/agent-card.js +111 -0
  963. package/.claude/worktrees/agent-af1f3b59/src/lib/call-monitor.js +205 -0
  964. package/.claude/worktrees/agent-af1f3b59/src/lib/callbook.js +366 -0
  965. package/.claude/worktrees/agent-af1f3b59/src/lib/claude-subagent.js +696 -0
  966. package/.claude/worktrees/agent-af1f3b59/src/lib/client.js +683 -0
  967. package/.claude/worktrees/agent-af1f3b59/src/lib/config.js +480 -0
  968. package/.claude/worktrees/agent-af1f3b59/src/lib/conversation-driver.js +608 -0
  969. package/.claude/worktrees/agent-af1f3b59/src/lib/conversations.js +830 -0
  970. package/.claude/worktrees/agent-af1f3b59/src/lib/crypto.js +113 -0
  971. package/.claude/worktrees/agent-af1f3b59/src/lib/dashboard-events.js +213 -0
  972. package/.claude/worktrees/agent-af1f3b59/src/lib/disclosure.js +792 -0
  973. package/.claude/worktrees/agent-af1f3b59/src/lib/external-ip.js +211 -0
  974. package/.claude/worktrees/agent-af1f3b59/src/lib/invite-host.js +223 -0
  975. package/.claude/worktrees/agent-af1f3b59/src/lib/local-request.js +69 -0
  976. package/.claude/worktrees/agent-af1f3b59/src/lib/logger.js +677 -0
  977. package/.claude/worktrees/agent-af1f3b59/src/lib/openclaw-integration.js +339 -0
  978. package/.claude/worktrees/agent-af1f3b59/src/lib/pid-file.js +103 -0
  979. package/.claude/worktrees/agent-af1f3b59/src/lib/port-scanner.js +83 -0
  980. package/.claude/worktrees/agent-af1f3b59/src/lib/prompt-template.js +355 -0
  981. package/.claude/worktrees/agent-af1f3b59/src/lib/runtime-adapter.js +701 -0
  982. package/.claude/worktrees/agent-af1f3b59/src/lib/summarizer.js +156 -0
  983. package/.claude/worktrees/agent-af1f3b59/src/lib/summary-formatter.js +168 -0
  984. package/.claude/worktrees/agent-af1f3b59/src/lib/summary-prompt.js +203 -0
  985. package/.claude/worktrees/agent-af1f3b59/src/lib/tokens.js +868 -0
  986. package/.claude/worktrees/agent-af1f3b59/src/lib/turn-timeout.js +52 -0
  987. package/.claude/worktrees/agent-af1f3b59/src/lib/update-checker.js +93 -0
  988. package/.claude/worktrees/agent-af1f3b59/src/lib/update-manager.js +313 -0
  989. package/.claude/worktrees/agent-af1f3b59/src/routes/a2a.js +1213 -0
  990. package/.claude/worktrees/agent-af1f3b59/src/routes/callbook.js +142 -0
  991. package/.claude/worktrees/agent-af1f3b59/src/routes/dashboard.js +1578 -0
  992. package/.claude/worktrees/agent-af1f3b59/src/server.js +1179 -0
  993. package/CONVENTIONS.md +39 -0
  994. package/docs/app.js +30 -0
  995. package/docs/assets/icon-32.png +0 -0
  996. package/docs/assets/icon-64.png +0 -0
  997. package/docs/index.html +117 -0
  998. package/docs/plans/2026-03-06-a2a-100-tauri-auto-updater.md +519 -0
  999. package/docs/plans/2026-03-06-a2a-101-dmg-installer-polish.md +229 -0
  1000. package/docs/plans/2026-03-06-a2a-102-landing-page.md +611 -0
  1001. package/docs/plans/2026-03-06-a2a-103-standalone-e2e-tests.md +810 -0
  1002. package/docs/plans/2026-03-06-a2a-99-native-onboarding-wizard.md +1261 -0
  1003. package/docs/style.css +209 -0
  1004. package/native/macos/index.html +7 -4
  1005. package/native/macos/src-tauri/Cargo.toml +1 -0
  1006. package/native/macos/src-tauri/dmg-background.png +0 -0
  1007. package/native/macos/src-tauri/dmg-background@2x.png +0 -0
  1008. package/native/macos/src-tauri/icons/256x256.png +0 -0
  1009. package/native/macos/src-tauri/icons/512x512.png +0 -0
  1010. package/native/macos/src-tauri/icons/512x512@2x.png +0 -0
  1011. package/native/macos/src-tauri/src/discovery.rs +37 -0
  1012. package/native/macos/src-tauri/src/lib.rs +32 -2
  1013. package/native/macos/src-tauri/src/updater.rs +124 -0
  1014. package/native/macos/src-tauri/tauri.conf.json +21 -3
  1015. package/native/macos/src-tauri/volume-icon.icns +0 -0
  1016. package/package.json +2 -1
  1017. package/scripts/generate-update-manifest.sh +42 -0
  1018. package/scripts/run-e2e.sh +8 -0
  1019. package/src/dashboard/public/app.js +34 -0
  1020. package/src/dashboard/public/index.html +7 -0
  1021. package/src/dashboard/public/onboarding.css +269 -0
  1022. package/src/dashboard/public/onboarding.html +96 -0
  1023. package/src/dashboard/public/onboarding.js +277 -0
  1024. package/src/dashboard/public/style.css +20 -0
  1025. package/src/routes/dashboard.js +110 -0
@@ -0,0 +1,1688 @@
1
+ /**
2
+ * A2A Dashboard Routes
3
+ *
4
+ * Provides a minimal management dashboard for:
5
+ * - contacts and per-contact call summaries
6
+ * - call history with contact context
7
+ * - tier/topic/goal settings management
8
+ * - invite generation and revocation
9
+ */
10
+
11
+ const express = require('express');
12
+ const fs = require('fs');
13
+ const path = require('path');
14
+ const { TokenStore } = require('../lib/tokens');
15
+ const { ConversationStore } = require('../lib/conversations');
16
+ const { A2AClient } = require('../lib/client');
17
+ const { A2AConfig } = require('../lib/config');
18
+ const { loadManifest, saveManifest } = require('../lib/disclosure');
19
+ const { resolveInviteHost } = require('../lib/invite-host');
20
+ const { CallbookStore } = require('../lib/callbook');
21
+ const { DashboardEventStore } = require('../lib/dashboard-events');
22
+ const { createLogger } = require('../lib/logger');
23
+ const { isDirectLocalRequest } = require('../lib/local-request');
24
+
25
+ const DASHBOARD_STATIC_DIR = path.join(__dirname, '..', 'dashboard', 'public');
26
+
27
+ function parseCookieHeader(headerValue) {
28
+ const raw = String(headerValue || '').trim();
29
+ if (!raw) return {};
30
+ const cookies = {};
31
+ for (const part of raw.split(';')) {
32
+ const idx = part.indexOf('=');
33
+ if (idx === -1) continue;
34
+ const key = part.slice(0, idx).trim();
35
+ const value = part.slice(idx + 1).trim();
36
+ if (!key) continue;
37
+ cookies[key] = decodeURIComponent(value);
38
+ }
39
+ return cookies;
40
+ }
41
+
42
+ function isHttpsRequest(req) {
43
+ const proto = String(req.headers['x-forwarded-proto'] || '')
44
+ .split(',')[0]
45
+ .trim()
46
+ .toLowerCase();
47
+ if (proto === 'https') return true;
48
+ if (req && req.socket && req.socket.encrypted) return true;
49
+ return false;
50
+ }
51
+
52
+ function buildSetCookie(name, value, options = {}) {
53
+ const parts = [];
54
+ parts.push(`${name}=${encodeURIComponent(String(value || ''))}`);
55
+ parts.push('Path=/');
56
+ if (options.httpOnly !== false) parts.push('HttpOnly');
57
+ if (options.sameSite) parts.push(`SameSite=${options.sameSite}`);
58
+ if (options.secure) parts.push('Secure');
59
+ if (Number.isFinite(options.maxAgeSeconds)) {
60
+ parts.push(`Max-Age=${Math.max(0, Math.floor(options.maxAgeSeconds))}`);
61
+ }
62
+ return parts.join('; ');
63
+ }
64
+
65
+ function sanitizeString(value, maxLength = 200) {
66
+ return String(value || '')
67
+ .replace(/\s+/g, ' ')
68
+ .trim()
69
+ .slice(0, maxLength);
70
+ }
71
+
72
+ function parseBoolean(value) {
73
+ if (value === null || value === undefined) return false;
74
+ if (typeof value === 'boolean') return value;
75
+ if (typeof value === 'number') return value !== 0;
76
+ const s = String(value).trim().toLowerCase();
77
+ if (['true', '1', 'yes', 'y', 'on'].includes(s)) return true;
78
+ if (['false', '0', 'no', 'n', 'off', ''].includes(s)) return false;
79
+ return Boolean(value);
80
+ }
81
+
82
+ function resolveAgentContext(options = {}) {
83
+ const provided = options.agentContext && typeof options.agentContext === 'object' ? options.agentContext : null;
84
+ const name = sanitizeString(
85
+ provided?.name || process.env.A2A_AGENT_NAME || process.env.AGENT_NAME || 'a2a-agent',
86
+ 80
87
+ ) || 'a2a-agent';
88
+ const owner = sanitizeString(
89
+ provided?.owner || process.env.A2A_OWNER_NAME || process.env.USER || 'Agent Owner',
90
+ 120
91
+ ) || 'Agent Owner';
92
+
93
+ return { name, owner };
94
+ }
95
+
96
+ function normalizeTierId(value) {
97
+ return sanitizeString(value, 80)
98
+ .toLowerCase()
99
+ .replace(/[^a-z0-9_-]+/g, '-')
100
+ .replace(/^-+|-+$/g, '');
101
+ }
102
+
103
+ function sanitizeStringArray(values, maxItems = 100, itemMaxLength = 200) {
104
+ if (!Array.isArray(values)) {
105
+ return [];
106
+ }
107
+ const unique = [];
108
+ const seen = new Set();
109
+ for (const value of values) {
110
+ const item = sanitizeString(value, itemMaxLength);
111
+ if (!item || seen.has(item)) continue;
112
+ seen.add(item);
113
+ unique.push(item);
114
+ if (unique.length >= maxItems) break;
115
+ }
116
+ return unique;
117
+ }
118
+
119
+ function parseTopicObjects(values) {
120
+ if (!Array.isArray(values)) {
121
+ return [];
122
+ }
123
+ const cleaned = [];
124
+ const seen = new Set();
125
+ for (const entry of values) {
126
+ let topic = '';
127
+ let detail = '';
128
+
129
+ if (typeof entry === 'string') {
130
+ const parts = entry.split(':');
131
+ topic = sanitizeString(parts[0], 120);
132
+ detail = sanitizeString(parts.slice(1).join(':') || parts[0], 250);
133
+ } else if (entry && typeof entry === 'object') {
134
+ topic = sanitizeString(entry.topic, 120);
135
+ detail = sanitizeString(entry.description || entry.topic, 250);
136
+ }
137
+
138
+ if (!topic) continue;
139
+ if (seen.has(topic)) continue;
140
+ seen.add(topic);
141
+ cleaned.push({ topic, description: detail || topic });
142
+ if (cleaned.length >= 100) break;
143
+ }
144
+ return cleaned;
145
+ }
146
+
147
+ function formatInviteMessage({ owner, agentName, inviteUrl, topics, goals, tools, expiresText }) {
148
+ const ownerText = owner || 'Someone';
149
+ const topicsList = topics.length > 0 ? topics.join(' · ') : 'chat';
150
+ const goalsList = (goals || []).join(' · ');
151
+ const toolsList = (tools || []).join(' · ');
152
+ const expirationLine = expiresText === 'never' ? '' : `\n⏰ ${expiresText}`;
153
+ return `📞🗣️ **Agent-to-Agent Call Invite**
154
+
155
+ 👤 **${ownerText}** would like your agent to call **${agentName}** and explore where our owners might collaborate.
156
+
157
+ 💬 ${topicsList}${goalsList ? `\n🎯 ${goalsList}` : ''}
158
+ ${toolsList ? `\n🧰 ${toolsList}` : ''}
159
+
160
+ ${inviteUrl}${expirationLine}
161
+
162
+ ── setup ──
163
+ npm i -g a2acalling && a2a add "${inviteUrl}" "${agentName}" && a2a call "${agentName}" "Hello from my owner!"
164
+ https://github.com/onthegonow/a2a_calling`;
165
+ }
166
+
167
+ function buildContext(options = {}) {
168
+ const tokenStore = options.tokenStore || new TokenStore();
169
+ const config = options.config || new A2AConfig();
170
+ const logger = options.logger || createLogger({ component: 'a2a.dashboard' });
171
+ const callbookStore = options.callbookStore || new CallbookStore(tokenStore.configDir);
172
+ const eventStore = options.eventStore || new DashboardEventStore(tokenStore.configDir);
173
+ const agentContext = resolveAgentContext(options);
174
+ let convStore = options.convStore || null;
175
+ if (!convStore) {
176
+ try {
177
+ convStore = new ConversationStore(tokenStore.configDir, { eventStore });
178
+ if (!convStore.isAvailable()) {
179
+ convStore = null;
180
+ }
181
+ } catch (err) {
182
+ convStore = null;
183
+ }
184
+ }
185
+
186
+ return {
187
+ tokenStore,
188
+ config,
189
+ convStore,
190
+ callbookStore,
191
+ eventStore,
192
+ getUpdateManager: typeof options.getUpdateManager === 'function'
193
+ ? options.getUpdateManager
194
+ : (() => null),
195
+ logger,
196
+ agentContext,
197
+ staticDir: DASHBOARD_STATIC_DIR
198
+ };
199
+ }
200
+
201
+ function resolveAutoUpdateStatus(context) {
202
+ const manager = context.getUpdateManager ? context.getUpdateManager() : null;
203
+ const config = context.config && typeof context.config.getAutoUpdate === 'function'
204
+ ? context.config.getAutoUpdate()
205
+ : {
206
+ enabled: true,
207
+ intervalMs: 60 * 60 * 1000,
208
+ allowMajor: false,
209
+ lastGoodVersion: null
210
+ };
211
+ const runtime = manager && typeof manager.getStatus === 'function'
212
+ ? manager.getStatus()
213
+ : null;
214
+ return {
215
+ enabled: runtime ? Boolean(runtime.enabled) : Boolean(config.enabled),
216
+ interval_ms: runtime && Number.isFinite(runtime.interval_ms) ? runtime.interval_ms : config.intervalMs,
217
+ allow_major: runtime ? Boolean(runtime.allow_major) : Boolean(config.allowMajor),
218
+ state: runtime ? runtime.state : 'up_to_date',
219
+ current_version: runtime ? runtime.current_version : require('../../package.json').version,
220
+ latest_version: runtime ? runtime.latest_version : null,
221
+ target_version: runtime ? runtime.target_version : null,
222
+ active_calls: runtime ? runtime.active_calls : 0,
223
+ last_checked_at: runtime ? runtime.last_checked_at : null,
224
+ last_success_at: runtime ? runtime.last_success_at : null,
225
+ last_error: runtime ? runtime.last_error : null,
226
+ defer_reason: runtime ? runtime.defer_reason : null,
227
+ last_good_version: config.lastGoodVersion || null
228
+ };
229
+ }
230
+
231
+ function buildContactIndex(contacts) {
232
+ const byName = new Map();
233
+ const byId = new Map();
234
+ const byLinkedTokenId = new Map();
235
+
236
+ for (const contact of contacts) {
237
+ const nameKey = sanitizeString(contact.name, 120).toLowerCase();
238
+ if (nameKey) {
239
+ byName.set(nameKey, contact);
240
+ }
241
+ if (contact.id) {
242
+ byId.set(contact.id, contact);
243
+ }
244
+ if (contact.linked_token_id) {
245
+ byLinkedTokenId.set(contact.linked_token_id, contact);
246
+ }
247
+ }
248
+
249
+ return { byName, byId, byLinkedTokenId };
250
+ }
251
+
252
+ function resolveConversationContact(conversation, contactIndex) {
253
+ if (!conversation) return null;
254
+ if (conversation.contact_id && contactIndex.byId.has(conversation.contact_id)) {
255
+ return contactIndex.byId.get(conversation.contact_id);
256
+ }
257
+ if (conversation.contact_id && contactIndex.byLinkedTokenId.has(conversation.contact_id)) {
258
+ return contactIndex.byLinkedTokenId.get(conversation.contact_id);
259
+ }
260
+ const nameKey = sanitizeString(conversation.contact_name, 120).toLowerCase();
261
+ if (nameKey && contactIndex.byName.has(nameKey)) {
262
+ return contactIndex.byName.get(nameKey);
263
+ }
264
+ return null;
265
+ }
266
+
267
+ function toDashboardContact(contact) {
268
+ const canCall = Boolean(
269
+ contact &&
270
+ String(contact.host || '').trim() &&
271
+ contact.token_enc &&
272
+ contact.token_hash
273
+ );
274
+
275
+ return {
276
+ id: contact.id,
277
+ owner: contact.owner || null,
278
+ name: contact.name || null,
279
+ host: contact.host || null,
280
+ web_address: contact.host || null,
281
+ is_mine: Boolean(contact.is_mine),
282
+ server_name: contact.server_name || null,
283
+ notes: contact.notes || null,
284
+ tags: Array.isArray(contact.tags) ? contact.tags : [],
285
+ fields: (contact.fields && typeof contact.fields === 'object' && !Array.isArray(contact.fields)) ? contact.fields : {},
286
+ linked_token_id: contact.linked_token_id || null,
287
+ status: contact.status || 'unknown',
288
+ last_seen: contact.last_seen || null,
289
+ last_check: contact.last_check || null,
290
+ last_error: contact.last_error || null,
291
+ added_at: contact.added_at || null,
292
+ updated_at: contact.updated_at || null,
293
+ can_call: canCall
294
+ };
295
+ }
296
+
297
+ function makeEnsureDashboardAccess(context) {
298
+ return function ensureDashboardAccess(req, res, next) {
299
+ const adminToken = process.env.A2A_ADMIN_TOKEN;
300
+ const headerToken = req.headers['x-admin-token'];
301
+ const queryToken = req.query?.admin_token;
302
+
303
+ if (isDirectLocalRequest(req)) {
304
+ return next();
305
+ }
306
+
307
+ if (adminToken && (headerToken === adminToken || queryToken === adminToken)) {
308
+ return next();
309
+ }
310
+
311
+ const cookies = parseCookieHeader(req.headers.cookie || '');
312
+ const sessionToken = cookies.a2a_callbook_session || null;
313
+ if (sessionToken && context.callbookStore && context.callbookStore.isAvailable()) {
314
+ const session = context.callbookStore.validateSession(sessionToken);
315
+ if (session && session.valid) {
316
+ req.callbook = session;
317
+ return next();
318
+ }
319
+ }
320
+
321
+ const wantsHtml = String(req.headers.accept || '').includes('text/html');
322
+ if (wantsHtml) {
323
+ return res.status(401).send(`<!doctype html>
324
+ <html>
325
+ <head>
326
+ <meta charset="utf-8">
327
+ <meta name="viewport" content="width=device-width, initial-scale=1">
328
+ <title>A2A Dashboard</title>
329
+ </head>
330
+ <body style="font-family: system-ui, -apple-system, Segoe UI, sans-serif; padding: 2rem;">
331
+ <h1>A2A Dashboard Locked</h1>
332
+ <p>This dashboard requires owner access.</p>
333
+ <ul>
334
+ <li>Local access: open <code>http://127.0.0.1:PORT/dashboard/</code> on the server</li>
335
+ <li>Remote access: generate a Callbook Remote install link on the server, then open it on your Mac</li>
336
+ <li>Break-glass: set <code>A2A_ADMIN_TOKEN</code> and send <code>x-admin-token</code> header</li>
337
+ </ul>
338
+ </body>
339
+ </html>`);
340
+ }
341
+
342
+ if (!adminToken && !(context.callbookStore && context.callbookStore.isAvailable())) {
343
+ return res.status(401).json({
344
+ success: false,
345
+ error: 'admin_token_required',
346
+ message: 'Set A2A_ADMIN_TOKEN (or enable callbook session storage) to access dashboard from non-local addresses'
347
+ });
348
+ }
349
+
350
+ return res.status(401).json({
351
+ success: false,
352
+ error: 'unauthorized',
353
+ message: 'Admin token or callbook session required'
354
+ });
355
+ };
356
+ }
357
+
358
+ function summarizeDebugLogs(logs) {
359
+ if (!Array.isArray(logs) || logs.length === 0) {
360
+ return {
361
+ event_count: 0,
362
+ events: [],
363
+ timestamps: [],
364
+ error_count: 0,
365
+ warning_count: 0
366
+ };
367
+ }
368
+
369
+ const normalized = logs.slice().sort((a, b) => {
370
+ const aTime = Number(new Date(a.timestamp));
371
+ const bTime = Number(new Date(b.timestamp));
372
+ if (Number.isNaN(aTime) && Number.isNaN(bTime)) return 0;
373
+ if (Number.isNaN(aTime)) return 1;
374
+ if (Number.isNaN(bTime)) return -1;
375
+ return aTime - bTime;
376
+ });
377
+
378
+ const firstTimestamp = normalized[0]?.timestamp || null;
379
+ const lastTimestamp = normalized[normalized.length - 1]?.timestamp || null;
380
+ const firstMs = firstTimestamp ? Number(new Date(firstTimestamp)) : null;
381
+ const lastMs = lastTimestamp ? Number(new Date(lastTimestamp)) : null;
382
+
383
+ return {
384
+ event_count: normalized.length,
385
+ events: normalized.map(row => row.event).filter(Boolean),
386
+ timestamps: normalized.map(row => row.timestamp),
387
+ first_seen: firstTimestamp,
388
+ last_seen: lastTimestamp,
389
+ timeline_ms: Number.isFinite(firstMs) && Number.isFinite(lastMs) && lastMs >= firstMs
390
+ ? lastMs - firstMs
391
+ : null,
392
+ trace_ids: [...new Set(normalized.map(row => row.trace_id).filter(Boolean))],
393
+ conversation_ids: [...new Set(normalized.map(row => row.conversation_id).filter(Boolean))],
394
+ token_ids: [...new Set(normalized.map(row => row.token_id).filter(Boolean))],
395
+ request_ids: [...new Set(normalized.map(row => row.request_id).filter(Boolean))],
396
+ error_count: normalized.filter(row => row.level === 'error').length,
397
+ warning_count: normalized.filter(row => row.level === 'warn').length,
398
+ hints: [...new Set(normalized
399
+ .filter(row => row.hint)
400
+ .map(row => String(row.hint)))]
401
+ };
402
+ }
403
+
404
+ function findErrorHints(logs) {
405
+ const hints = new Map();
406
+ for (const row of logs) {
407
+ if (!row.error_code) continue;
408
+ if (!hints.has(row.error_code)) {
409
+ hints.set(row.error_code, {
410
+ error_code: row.error_code,
411
+ status_code: row.status_code,
412
+ count: 0
413
+ });
414
+ }
415
+ const existing = hints.get(row.error_code);
416
+ existing.count += 1;
417
+ }
418
+ return Array.from(hints.values());
419
+ }
420
+
421
+ function createDashboardApiRouter(options = {}) {
422
+ const router = express.Router();
423
+ const context = buildContext(options);
424
+ router.use(express.json());
425
+
426
+ // A2A-42: Load E2E persist layer for Health tab. Gracefully null if not available
427
+ // (e.g., installed as npm package without test files).
428
+ let persistModule = null;
429
+ try {
430
+ persistModule = require(path.join(__dirname, '..', '..', 'test', 'e2e', 'persist'));
431
+ } catch {
432
+ // test/e2e/persist.js not available — Health tab will show "no results"
433
+ }
434
+
435
+ const ensureDashboardAccess = makeEnsureDashboardAccess(context);
436
+ const writeSseEvent = (res, event) => {
437
+ const eventName = sanitizeString(event?.type || 'message', 80) || 'message';
438
+ const eventId = Number.parseInt(String(event?.id || ''), 10);
439
+ const payload = {
440
+ id: eventId || null,
441
+ type: eventName,
442
+ created_at: event?.created_at || new Date().toISOString(),
443
+ conversation_id: event?.conversation_id || null,
444
+ contact_id: event?.contact_id || null,
445
+ payload: event?.payload || {}
446
+ };
447
+ if (Number.isFinite(eventId) && eventId > 0) {
448
+ res.write(`id: ${eventId}\n`);
449
+ }
450
+ res.write(`event: ${eventName}\n`);
451
+ res.write(`data: ${JSON.stringify(payload)}\n\n`);
452
+ };
453
+
454
+ // Callbook Remote: exchange a short-lived provisioning code for a long-lived session cookie.
455
+ // This route must be reachable BEFORE dashboard access is established.
456
+ router.post('/callbook/exchange', (req, res) => {
457
+ const body = req.body || {};
458
+ const code = sanitizeString(body.code || '', 500);
459
+ const label = sanitizeString(body.label || '', 120) || null;
460
+
461
+ if (!context.callbookStore || !context.callbookStore.isAvailable()) {
462
+ return res.status(500).json({
463
+ success: false,
464
+ error: 'callbook_storage_unavailable',
465
+ message: 'Callbook session storage is not available on this server.',
466
+ hint: context.callbookStore ? context.callbookStore.getDbError() : 'missing_callbook_store'
467
+ });
468
+ }
469
+
470
+ const result = context.callbookStore.exchangeProvisionCode(code, { label });
471
+ if (!result.success) {
472
+ return res.status(401).json({
473
+ success: false,
474
+ error: result.error || 'invalid_code',
475
+ message: 'Callbook install code is invalid, expired, or already used.'
476
+ });
477
+ }
478
+
479
+ // "Never expires" in DB; for browsers we set a very long cookie lifetime.
480
+ // (Browsers may still evict cookies; owner can always re-provision.)
481
+ const maxAgeSeconds = 10 * 365 * 24 * 60 * 60; // ~10 years
482
+ const cookie = buildSetCookie('a2a_callbook_session', result.sessionToken, {
483
+ httpOnly: true,
484
+ sameSite: 'Lax',
485
+ secure: isHttpsRequest(req),
486
+ maxAgeSeconds
487
+ });
488
+ res.setHeader('Set-Cookie', cookie);
489
+
490
+ if (context.eventStore && context.eventStore.isAvailable()) {
491
+ context.eventStore.emitEvent('invite.used', {
492
+ device_id: result.device?.id || null,
493
+ device_label: result.device?.label || null,
494
+ source: 'callbook_exchange'
495
+ });
496
+ }
497
+
498
+ return res.json({
499
+ success: true,
500
+ device: result.device,
501
+ dashboard_path: '/api/a2a/dashboard/'
502
+ });
503
+ });
504
+
505
+ // A2A-99: Onboarding wizard — served before auth middleware so fresh installs can access it.
506
+ router.get('/onboarding', (req, res) => {
507
+ const onboardingPath = path.join(context.staticDir, 'onboarding.html');
508
+ if (!fs.existsSync(onboardingPath)) {
509
+ return res.status(500).send('Onboarding wizard UI missing');
510
+ }
511
+ return res.sendFile(onboardingPath);
512
+ });
513
+
514
+ // A2A-99: Onboarding status check — lets the wizard and native app check if onboarding is complete.
515
+ router.get('/onboarding/status', (req, res) => {
516
+ return res.json({
517
+ success: true,
518
+ onboarded: context.config.isOnboarded(),
519
+ onboarding: context.config.getOnboarding()
520
+ });
521
+ });
522
+
523
+ // A2A-99: Complete onboarding — writes config + disclosure manifest.
524
+ router.post('/onboarding/complete', async (req, res) => {
525
+ const body = req.body || {};
526
+
527
+ // Validate required fields
528
+ const agentName = sanitizeString(body.agentName || '', 120);
529
+ const defaultTier = sanitizeString(body.defaultTier || 'public', 20);
530
+ const port = Number.parseInt(String(body.port || ''), 10);
531
+ const hostname = sanitizeString(body.hostname || '', 200);
532
+
533
+ if (!agentName) {
534
+ return res.status(400).json({
535
+ success: false,
536
+ error: { code: 'missing_agent_name', message: 'Agent name is required.' }
537
+ });
538
+ }
539
+
540
+ if (!['public', 'friends', 'family'].includes(defaultTier)) {
541
+ return res.status(400).json({
542
+ success: false,
543
+ error: { code: 'invalid_tier', message: 'Default tier must be public, friends, or family.' }
544
+ });
545
+ }
546
+
547
+ if (!Number.isFinite(port) || port < 1 || port > 65535) {
548
+ return res.status(400).json({
549
+ success: false,
550
+ error: { code: 'invalid_port', message: 'Port must be between 1 and 65535.' }
551
+ });
552
+ }
553
+
554
+ // Build and validate disclosure manifest from selected topics
555
+ const disc = require('../lib/disclosure');
556
+ const topics = Array.isArray(body.topics) ? body.topics.map(t => sanitizeString(String(t), 100)).filter(Boolean) : [];
557
+ const manifest = disc.generateDefaultManifest();
558
+
559
+ // A2A-99: Map user-selected topics into the public tier (simplest useful default).
560
+ // Topics in the manifest are objects: { topic: string, description: string }.
561
+ // Users can refine per-tier topics later in the Settings tab.
562
+ if (topics.length > 0) {
563
+ manifest.tiers.public.topics = topics.slice(0, 15).map(t => ({ topic: t, description: t }));
564
+ }
565
+
566
+ const validation = disc.validateDisclosureSubmission(manifest);
567
+ if (!validation.valid) {
568
+ return res.status(400).json({
569
+ success: false,
570
+ error: { code: 'invalid_disclosure', message: validation.errors.join('; ') }
571
+ });
572
+ }
573
+
574
+ try {
575
+ // Write disclosure manifest
576
+ disc.saveManifest(manifest);
577
+
578
+ // Write config
579
+ const effectiveHostname = hostname || `localhost:${port}`;
580
+ context.config.setAgent({ name: agentName, hostname: effectiveHostname });
581
+ context.config.setDefaults({ defaultTier });
582
+ context.config.setOnboarding({ serverPort: port });
583
+ context.config.completeOnboarding();
584
+
585
+ context.logger.info('Onboarding completed via wizard', {
586
+ event: 'onboarding_complete',
587
+ data: { agentName, defaultTier, port, topicCount: topics.length }
588
+ });
589
+
590
+ return res.json({ success: true });
591
+ } catch (err) {
592
+ context.logger.error('Onboarding completion failed', {
593
+ event: 'onboarding_error',
594
+ data: { error: err.message }
595
+ });
596
+ return res.status(500).json({
597
+ success: false,
598
+ error: { code: 'onboarding_failed', message: 'Failed to save onboarding configuration.' }
599
+ });
600
+ }
601
+ });
602
+
603
+ // A2A-99: Port detection for onboarding network step.
604
+ router.get('/onboarding/detect-port', async (req, res) => {
605
+ const { findAvailablePort } = require('../lib/port-scanner');
606
+ const candidates = [80, 3001, 3002, 3003, 3007, 8080, 9001];
607
+ const port = await findAvailablePort(candidates);
608
+ return res.json({
609
+ success: true,
610
+ port: port,
611
+ candidates
612
+ });
613
+ });
614
+
615
+ // All other dashboard API routes require owner access.
616
+ router.use(ensureDashboardAccess);
617
+
618
+ router.get('/events', (req, res) => {
619
+ if (!context.eventStore || !context.eventStore.isAvailable()) {
620
+ return res.status(503).json({
621
+ success: false,
622
+ error: 'event_stream_unavailable',
623
+ message: context.eventStore ? context.eventStore.getDbError() : 'missing_event_store'
624
+ });
625
+ }
626
+
627
+ const lastIdHeader = req.headers['last-event-id'];
628
+ const since = sanitizeString(
629
+ req.query.since || lastIdHeader || req.query.last_event_id || '',
630
+ 32
631
+ );
632
+ const replayLimit = Math.min(500, Math.max(1, Number.parseInt(req.query.replay || '200', 10) || 200));
633
+
634
+ res.status(200);
635
+ res.setHeader('Content-Type', 'text/event-stream');
636
+ res.setHeader('Cache-Control', 'no-cache, no-transform');
637
+ res.setHeader('Connection', 'keep-alive');
638
+ res.flushHeaders?.();
639
+
640
+ let lastSentId = Number.parseInt(String(since || '0'), 10);
641
+ if (!Number.isFinite(lastSentId) || lastSentId < 0) {
642
+ lastSentId = 0;
643
+ }
644
+
645
+ const pendingLive = [];
646
+ const unsubscribe = context.eventStore.subscribe((event) => {
647
+ if (!event || !Number.isFinite(event.id)) return;
648
+ if (event.id <= lastSentId) return;
649
+ pendingLive.push(event);
650
+ });
651
+
652
+ const replay = context.eventStore.listSince(since, { limit: replayLimit });
653
+ for (const row of replay) {
654
+ writeSseEvent(res, row);
655
+ if (Number.isFinite(row.id) && row.id > lastSentId) {
656
+ lastSentId = row.id;
657
+ }
658
+ }
659
+ while (pendingLive.length > 0) {
660
+ const row = pendingLive.shift();
661
+ if (!row || !Number.isFinite(row.id) || row.id <= lastSentId) continue;
662
+ writeSseEvent(res, row);
663
+ lastSentId = row.id;
664
+ }
665
+ res.write(': connected\n\n');
666
+
667
+ const liveUnsubscribe = context.eventStore.subscribe((event) => {
668
+ if (!event || !Number.isFinite(event.id) || event.id <= lastSentId) return;
669
+ writeSseEvent(res, event);
670
+ lastSentId = event.id;
671
+ });
672
+ const heartbeat = setInterval(() => {
673
+ res.write(`: heartbeat ${Date.now()}\n\n`);
674
+ }, 15000);
675
+
676
+ req.on('close', () => {
677
+ clearInterval(heartbeat);
678
+ unsubscribe();
679
+ liveUnsubscribe();
680
+ res.end();
681
+ });
682
+ });
683
+
684
+ router.get('/status', async (req, res) => {
685
+ context.logger.debug('Dashboard status requested', { event: 'dashboard_status' });
686
+ const refreshIp = String(req.query.refresh_ip || 'false') === 'true';
687
+ let resolvedHost = null;
688
+ let warnings = [];
689
+ let inviteResolution = null;
690
+ try {
691
+ // Determine default port based on config hostname:
692
+ // - If hostname has no port (e.g., "149.28.213.47"), assume port 80 (reverse proxy)
693
+ // - If hostname has explicit port, use that
694
+ // - Otherwise fall back to server port or env
695
+ const agent = context.config?.getAgent?.() || {};
696
+ const hostname = agent.hostname || '';
697
+ const hasExplicitPort = hostname.includes(':') && !hostname.startsWith('[');
698
+ let defaultPort;
699
+ if (hasExplicitPort) {
700
+ defaultPort = null; // Will be parsed from hostname
701
+ } else if (hostname && !hostname.includes('localhost')) {
702
+ defaultPort = 80; // External hostname without port = assume reverse proxy on 80
703
+ } else {
704
+ defaultPort = process.env.PORT || process.env.A2A_PORT || 80;
705
+ }
706
+
707
+ const resolved = await resolveInviteHost({
708
+ config: context.config,
709
+ fallbackHost: req.headers.host || process.env.HOSTNAME || 'localhost',
710
+ defaultPort,
711
+ refreshExternalIp: refreshIp,
712
+ forceRefreshExternalIp: refreshIp,
713
+ alwaysLookupExternalIp: true,
714
+ warnOnExternalIpFailure: refreshIp
715
+ });
716
+ inviteResolution = resolved;
717
+ resolvedHost = resolved.host;
718
+ warnings = resolved.warnings || [];
719
+ } catch (err) {
720
+ // Non-fatal: still return base status.
721
+ }
722
+
723
+ const schemeOverride = String(process.env.A2A_PUBLIC_SCHEME || '').trim();
724
+ const inferredScheme = schemeOverride || (isHttpsRequest(req) ? 'https' : 'http');
725
+ const publicBaseUrl = resolvedHost ? `${inferredScheme}://${resolvedHost}` : null;
726
+
727
+ const devices = (context.callbookStore && context.callbookStore.isAvailable())
728
+ ? context.callbookStore.listDevices({ includeRevoked: true, limit: 200 }).devices
729
+ : [];
730
+
731
+ return res.json({
732
+ success: true,
733
+ dashboard: true,
734
+ conversations_enabled: Boolean(context.convStore),
735
+ agent: {
736
+ name: context.agentContext?.name || null,
737
+ owner_name: context.agentContext?.owner || null,
738
+ server_name: sanitizeString(context.config.getAgent?.().server_name || context.config.getAgent?.().serverName || '', 120) || null
739
+ },
740
+ config_file: require('../lib/config').CONFIG_FILE,
741
+ manifest_file: require('../lib/disclosure').MANIFEST_FILE,
742
+ public_base_url: publicBaseUrl,
743
+ public_dashboard_url: publicBaseUrl ? `${publicBaseUrl}/dashboard/` : null,
744
+ callbook_install_base: publicBaseUrl ? `${publicBaseUrl}/api/a2a/callbook/install` : null,
745
+ invite_host: inviteResolution ? {
746
+ host: inviteResolution.host,
747
+ source: inviteResolution.source || null,
748
+ original_host: inviteResolution.originalHost || null
749
+ } : null,
750
+ external_ip: inviteResolution && inviteResolution.externalIpInfo ? {
751
+ ip: inviteResolution.externalIpInfo.ip || null,
752
+ checked_at: inviteResolution.externalIpInfo.checkedAt || null,
753
+ source: inviteResolution.externalIpInfo.source || null,
754
+ from_cache: Boolean(inviteResolution.externalIpInfo.fromCache),
755
+ stale: Boolean(inviteResolution.externalIpInfo.stale),
756
+ error: inviteResolution.externalIpInfo.error || null,
757
+ attempts: inviteResolution.externalIpInfo.attempts || null
758
+ } : null,
759
+ warnings,
760
+ callbook: {
761
+ enabled: Boolean(context.callbookStore && context.callbookStore.isAvailable()),
762
+ device_count: Array.isArray(devices) ? devices.length : 0
763
+ },
764
+ auto_update: resolveAutoUpdateStatus(context)
765
+ });
766
+ });
767
+
768
+ router.get('/update/status', (req, res) => {
769
+ return res.json({
770
+ success: true,
771
+ auto_update: resolveAutoUpdateStatus(context)
772
+ });
773
+ });
774
+
775
+ router.post('/update/check', async (req, res) => {
776
+ const manager = context.getUpdateManager ? context.getUpdateManager() : null;
777
+ if (!manager || typeof manager.triggerCheck !== 'function') {
778
+ return res.status(503).json({
779
+ success: false,
780
+ error: 'updater_unavailable',
781
+ message: 'Auto-updater is not initialized for this server.'
782
+ });
783
+ }
784
+ await manager.triggerCheck({ reason: 'dashboard_manual_check', forceCheck: true });
785
+ return res.json({
786
+ success: true,
787
+ auto_update: resolveAutoUpdateStatus(context)
788
+ });
789
+ });
790
+
791
+ router.post('/update/now', async (req, res) => {
792
+ const manager = context.getUpdateManager ? context.getUpdateManager() : null;
793
+ if (!manager || typeof manager.triggerUpdate !== 'function') {
794
+ return res.status(503).json({
795
+ success: false,
796
+ error: 'updater_unavailable',
797
+ message: 'Auto-updater is not initialized for this server.'
798
+ });
799
+ }
800
+ const force = parseBoolean(req.body && (req.body.force !== undefined ? req.body.force : req.body.force_update));
801
+ await manager.triggerUpdate({
802
+ reason: 'dashboard_manual_update',
803
+ force
804
+ });
805
+ return res.json({
806
+ success: true,
807
+ auto_update: resolveAutoUpdateStatus(context)
808
+ });
809
+ });
810
+
811
+ router.put('/update/config', async (req, res) => {
812
+ const manager = context.getUpdateManager ? context.getUpdateManager() : null;
813
+ const body = req.body || {};
814
+ const enabled = body.enabled !== undefined ? parseBoolean(body.enabled) : undefined;
815
+
816
+ if (enabled === undefined) {
817
+ return res.status(400).json({
818
+ success: false,
819
+ error: 'enabled_required',
820
+ message: 'Pass { enabled: true|false }.'
821
+ });
822
+ }
823
+
824
+ if (manager && typeof manager.setEnabled === 'function') {
825
+ await manager.setEnabled(enabled);
826
+ } else if (context.config && typeof context.config.setAutoUpdate === 'function') {
827
+ context.config.setAutoUpdate({ enabled });
828
+ }
829
+
830
+ return res.json({
831
+ success: true,
832
+ auto_update: resolveAutoUpdateStatus(context)
833
+ });
834
+ });
835
+
836
+ // Callbook Remote: create a short-lived install link (24h by default).
837
+ router.post('/callbook/provision', async (req, res) => {
838
+ const body = req.body || {};
839
+ const label = sanitizeString(body.label || 'Callbook Remote', 120) || null;
840
+ const ttlHoursRaw = body.ttl_hours !== undefined ? body.ttl_hours : body.ttlHours;
841
+ const ttlHours = Math.max(1, Math.min(168, Number.parseInt(String(ttlHoursRaw || '24'), 10) || 24));
842
+ const ttlMs = ttlHours * 60 * 60 * 1000;
843
+
844
+ if (!context.callbookStore || !context.callbookStore.isAvailable()) {
845
+ return res.status(500).json({
846
+ success: false,
847
+ error: 'callbook_storage_unavailable',
848
+ message: 'Callbook session storage is not available on this server.',
849
+ hint: context.callbookStore ? context.callbookStore.getDbError() : 'missing_callbook_store'
850
+ });
851
+ }
852
+
853
+ const created = context.callbookStore.createProvisionCode({ label, ttlMs });
854
+ if (!created.success) {
855
+ return res.status(500).json({
856
+ success: false,
857
+ error: created.error || 'callbook_provision_failed',
858
+ message: created.message || 'Failed to create Callbook Remote install link.'
859
+ });
860
+ }
861
+
862
+ let resolvedHost = null;
863
+ let warnings = [];
864
+ try {
865
+ // Use same port logic as /status endpoint
866
+ const agent = context.config?.getAgent?.() || {};
867
+ const hostname = agent.hostname || '';
868
+ const hasExplicitPort = hostname.includes(':') && !hostname.startsWith('[');
869
+ let defaultPort;
870
+ if (hasExplicitPort) {
871
+ defaultPort = null;
872
+ } else if (hostname && !hostname.includes('localhost')) {
873
+ defaultPort = 80;
874
+ } else {
875
+ defaultPort = process.env.PORT || process.env.A2A_PORT || 80;
876
+ }
877
+
878
+ const resolved = await resolveInviteHost({
879
+ config: context.config,
880
+ fallbackHost: req.headers.host || process.env.HOSTNAME || 'localhost',
881
+ defaultPort,
882
+ refreshExternalIp: true,
883
+ forceRefreshExternalIp: true
884
+ });
885
+ resolvedHost = resolved.host;
886
+ warnings = resolved.warnings || [];
887
+ } catch (err) {
888
+ // Non-fatal: we can still return the code; owner can assemble URL manually.
889
+ }
890
+
891
+ const schemeOverride = String(process.env.A2A_PUBLIC_SCHEME || '').trim();
892
+ const scheme = schemeOverride || (isHttpsRequest(req) ? 'https' : 'http');
893
+ const baseUrl = resolvedHost ? `${scheme}://${resolvedHost}` : null;
894
+ const installUrl = baseUrl ? `${baseUrl}/api/a2a/callbook/install#code=${created.code}` : null;
895
+
896
+ return res.json({
897
+ success: true,
898
+ install_url: installUrl,
899
+ expires_at: created.record.expires_at,
900
+ token: {
901
+ id: created.record.id,
902
+ label: created.record.label
903
+ },
904
+ warnings
905
+ });
906
+ });
907
+
908
+ router.get('/callbook/devices', (req, res) => {
909
+ if (!context.callbookStore || !context.callbookStore.isAvailable()) {
910
+ return res.json({ success: true, devices: [], message: 'Callbook storage not available' });
911
+ }
912
+ const includeRevoked = String(req.query.include_revoked || 'false') === 'true';
913
+ const result = context.callbookStore.listDevices({ includeRevoked, limit: req.query.limit || 200 });
914
+ if (!result.success) {
915
+ return res.status(500).json({ success: false, error: result.error || 'callbook_list_failed', message: result.message });
916
+ }
917
+ return res.json({ success: true, devices: result.devices });
918
+ });
919
+
920
+ router.post('/callbook/devices/:deviceId/revoke', (req, res) => {
921
+ if (!context.callbookStore || !context.callbookStore.isAvailable()) {
922
+ return res.status(500).json({ success: false, error: 'callbook_storage_unavailable' });
923
+ }
924
+ const deviceId = sanitizeString(req.params.deviceId, 120);
925
+ const result = context.callbookStore.revokeDevice(deviceId);
926
+ if (!result.success) {
927
+ return res.status(404).json({ success: false, error: result.error || 'device_not_found' });
928
+ }
929
+ return res.json({ success: true, device: result.device });
930
+ });
931
+
932
+ router.post('/callbook/logout', (req, res) => {
933
+ const cookie = buildSetCookie('a2a_callbook_session', '', {
934
+ httpOnly: true,
935
+ sameSite: 'Lax',
936
+ secure: isHttpsRequest(req),
937
+ maxAgeSeconds: 0
938
+ });
939
+ res.setHeader('Set-Cookie', cookie);
940
+ return res.json({ success: true });
941
+ });
942
+
943
+ router.get('/logs', (req, res) => {
944
+ const limit = Math.min(1000, Math.max(1, Number.parseInt(req.query.limit || '200', 10) || 200));
945
+ const logs = context.logger.list({
946
+ limit,
947
+ level: req.query.level || null,
948
+ component: req.query.component || null,
949
+ event: req.query.event || null,
950
+ errorCode: req.query.error_code || req.query.errorCode || null,
951
+ statusCode: req.query.status_code || req.query.statusCode || null,
952
+ traceId: req.query.trace_id || req.query.traceId || null,
953
+ conversationId: req.query.conversation_id || req.query.conversationId || null,
954
+ tokenId: req.query.token_id || req.query.tokenId || null,
955
+ search: req.query.search || null,
956
+ from: req.query.from || null,
957
+ to: req.query.to || null
958
+ });
959
+ return res.json({ success: true, logs });
960
+ });
961
+
962
+ router.get('/logs/trace/:traceId', (req, res) => {
963
+ const traceId = sanitizeString(req.params.traceId, 120);
964
+ if (!traceId) {
965
+ return res.status(400).json({ success: false, error: 'trace_id_required' });
966
+ }
967
+ const limit = Math.min(1000, Math.max(1, Number.parseInt(req.query.limit || '500', 10) || 500));
968
+ const logs = context.logger.getTrace(traceId, { limit });
969
+ return res.json({ success: true, trace_id: traceId, logs });
970
+ });
971
+
972
+ router.get('/logs/stats', (req, res) => {
973
+ const stats = context.logger.stats({
974
+ from: req.query.from || null,
975
+ to: req.query.to || null
976
+ });
977
+ return res.json({ success: true, stats });
978
+ });
979
+
980
+ // A2A-42: Serve E2E test results for the Health tab.
981
+ // Reads from local persist layer — no external dependencies.
982
+ router.get('/test-results', (req, res) => {
983
+ if (!persistModule) {
984
+ return res.json({
985
+ success: true,
986
+ latest: null,
987
+ history: [],
988
+ has_results: false,
989
+ message: 'Test results module not available'
990
+ });
991
+ }
992
+
993
+ const latest = persistModule.getLatest();
994
+ const limit = Math.min(20, Math.max(1, Number.parseInt(req.query.limit || '10', 10) || 10));
995
+ const history = persistModule.getHistory(limit);
996
+
997
+ return res.json({
998
+ success: true,
999
+ latest,
1000
+ history: history.map(r => ({
1001
+ status: r.status,
1002
+ duration: r.duration,
1003
+ startedAt: r.startedAt,
1004
+ finishedAt: r.finishedAt,
1005
+ summary: r.summary,
1006
+ regression: r.regression || null
1007
+ })),
1008
+ has_results: latest !== null
1009
+ });
1010
+ });
1011
+
1012
+ router.get('/debug/call', (req, res) => {
1013
+ const traceId = sanitizeString(req.query.trace_id || req.query.traceId || '', 120);
1014
+ const conversationId = sanitizeString(req.query.conversation_id || req.query.conversationId || '', 120);
1015
+ const limit = Math.min(1000, Math.max(1, Number.parseInt(req.query.limit || '500', 10) || 500));
1016
+
1017
+ if (!traceId && !conversationId) {
1018
+ return res.status(400).json({
1019
+ success: false,
1020
+ error: 'missing_scope',
1021
+ message: 'Provide trace_id or conversation_id.'
1022
+ });
1023
+ }
1024
+
1025
+ const logs = traceId
1026
+ ? context.logger.getTrace(traceId, { limit })
1027
+ : context.logger.list({
1028
+ limit,
1029
+ conversationId,
1030
+ sort_desc: false
1031
+ });
1032
+
1033
+ if (!Array.isArray(logs) || logs.length === 0) {
1034
+ return res.status(404).json({
1035
+ success: false,
1036
+ error: 'no_logs_found',
1037
+ message: traceId ? 'No logs for trace_id' : 'No logs for conversation_id'
1038
+ });
1039
+ }
1040
+
1041
+ const summary = summarizeDebugLogs(logs);
1042
+ const errors = logs.filter(row => row.level === 'error' || row.level === 'warn').slice(0, 20);
1043
+ const callSignature = {
1044
+ trace_ids: summary.trace_ids,
1045
+ conversation_ids: summary.conversation_ids,
1046
+ token_ids: summary.token_ids,
1047
+ request_ids: summary.request_ids
1048
+ };
1049
+
1050
+ return res.json({
1051
+ success: true,
1052
+ summary: {
1053
+ ...summary,
1054
+ ...callSignature,
1055
+ errors: errors.map(row => ({
1056
+ id: row.id,
1057
+ timestamp: row.timestamp,
1058
+ level: row.level,
1059
+ event: row.event,
1060
+ message: row.message,
1061
+ error_code: row.error_code,
1062
+ status_code: row.status_code,
1063
+ hint: row.hint
1064
+ })),
1065
+ error_codes: findErrorHints(logs)
1066
+ },
1067
+ logs: summary.timeline_ms === null ? logs : logs
1068
+ });
1069
+ });
1070
+
1071
+ router.get('/contacts', (req, res) => {
1072
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: true, includeSecrets: true });
1073
+ const contactIndex = buildContactIndex(contacts);
1074
+ const conversations = context.convStore
1075
+ ? context.convStore.listConversations({
1076
+ limit: Number.parseInt(req.query.limit || '500', 10) || 500,
1077
+ includeMessages: false
1078
+ })
1079
+ : [];
1080
+
1081
+ const callMap = new Map();
1082
+ for (const contact of contacts) {
1083
+ callMap.set(contact.id, []);
1084
+ }
1085
+ for (const conv of conversations) {
1086
+ const contact = resolveConversationContact(conv, contactIndex);
1087
+ if (!contact) continue;
1088
+ if (!callMap.has(contact.id)) {
1089
+ callMap.set(contact.id, []);
1090
+ }
1091
+ callMap.get(contact.id).push(conv);
1092
+ }
1093
+
1094
+ const result = contacts.map(contact => {
1095
+ const calls = (callMap.get(contact.id) || []).sort((a, b) => {
1096
+ return String(b.last_message_at || '').localeCompare(String(a.last_message_at || ''));
1097
+ });
1098
+ const latest = calls[0] || null;
1099
+
1100
+ return {
1101
+ ...toDashboardContact(contact),
1102
+ call_count: calls.length,
1103
+ last_call_at: latest?.last_message_at || null,
1104
+ last_call_id: latest?.id || null,
1105
+ last_summary: latest?.summary || null,
1106
+ last_owner_summary: latest?.owner_summary || null
1107
+ };
1108
+ });
1109
+
1110
+ res.json({ success: true, contacts: result });
1111
+ });
1112
+
1113
+ router.post('/contacts', (req, res) => {
1114
+ const body = req.body || {};
1115
+ const inviteUrl = sanitizeString(
1116
+ body.invite_url || body.inviteUrl || body.web_address || body.webAddress || body.url || '',
1117
+ 600
1118
+ );
1119
+ const name = sanitizeString(body.name || '', 120) || null;
1120
+ const owner = sanitizeString(body.owner || '', 120) || null;
1121
+ const isMine = parseBoolean(body.is_mine !== undefined ? body.is_mine : body.isMine);
1122
+ const serverName = sanitizeString(body.server_name || body.serverName || '', 120) || null;
1123
+ const notes = sanitizeString(body.notes || '', 800) || null;
1124
+ const tags = sanitizeStringArray(body.tags || [], 30, 40);
1125
+ const fields = (body.fields && typeof body.fields === 'object' && !Array.isArray(body.fields)) ? body.fields : {};
1126
+
1127
+ if (!inviteUrl) {
1128
+ return res.status(400).json({ success: false, error: 'invite_url_required' });
1129
+ }
1130
+
1131
+ try {
1132
+ const result = context.tokenStore.addContact(inviteUrl, {
1133
+ name: name || undefined,
1134
+ owner: owner || undefined,
1135
+ is_mine: isMine,
1136
+ server_name: serverName || undefined,
1137
+ notes: notes || undefined,
1138
+ tags: tags || undefined,
1139
+ fields: fields || undefined
1140
+ });
1141
+ if (!result.success) {
1142
+ return res.status(409).json({ success: false, error: result.error || 'contact_add_failed', contact: result.existing || null });
1143
+ }
1144
+ const stored = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: true })
1145
+ .find(c => c.id === result.contact.id);
1146
+ return res.json({ success: true, contact: stored ? toDashboardContact(stored) : toDashboardContact(result.contact) });
1147
+ } catch (err) {
1148
+ return res.status(400).json({
1149
+ success: false,
1150
+ error: 'invalid_invite_url',
1151
+ message: err.message || 'Invalid invite URL'
1152
+ });
1153
+ }
1154
+ });
1155
+
1156
+ router.put('/contacts/:contactId', (req, res) => {
1157
+ const contactId = sanitizeString(req.params.contactId, 120);
1158
+ if (!contactId) {
1159
+ return res.status(400).json({ success: false, error: 'contact_id_required' });
1160
+ }
1161
+
1162
+ const body = req.body || {};
1163
+ const updates = {};
1164
+ if (body.name !== undefined) updates.name = sanitizeString(body.name, 120);
1165
+ if (body.owner !== undefined) updates.owner = sanitizeString(body.owner, 120);
1166
+ if (body.is_mine !== undefined) updates.is_mine = parseBoolean(body.is_mine);
1167
+ if (body.isMine !== undefined) updates.is_mine = parseBoolean(body.isMine);
1168
+ if (body.server_name !== undefined) updates.server_name = sanitizeString(body.server_name, 120);
1169
+ if (body.serverName !== undefined) updates.server_name = sanitizeString(body.serverName, 120);
1170
+ if (body.notes !== undefined) updates.notes = sanitizeString(body.notes, 800);
1171
+ if (body.tags !== undefined) updates.tags = sanitizeStringArray(body.tags, 30, 40);
1172
+ if (body.fields !== undefined) updates.fields = body.fields;
1173
+ if (body.linked_token_id !== undefined) updates.linked_token_id = sanitizeString(body.linked_token_id, 80);
1174
+ if (body.linkedTokenId !== undefined) updates.linked_token_id = sanitizeString(body.linkedTokenId, 80);
1175
+
1176
+ const result = context.tokenStore.updateContact(contactId, updates);
1177
+ if (!result.success) {
1178
+ return res.status(404).json({ success: false, error: result.error || 'contact_not_found' });
1179
+ }
1180
+
1181
+ const stored = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: true })
1182
+ .find(c => c.id === contactId);
1183
+ return res.json({ success: true, contact: stored ? toDashboardContact(stored) : toDashboardContact(result.contact) });
1184
+ });
1185
+
1186
+ router.delete('/contacts/:contactId', (req, res) => {
1187
+ const contactId = sanitizeString(req.params.contactId, 120);
1188
+ if (!contactId) {
1189
+ return res.status(400).json({ success: false, error: 'contact_id_required' });
1190
+ }
1191
+
1192
+ const result = context.tokenStore.removeContact(contactId);
1193
+ if (!result.success) {
1194
+ return res.status(404).json({ success: false, error: result.error || 'contact_not_found' });
1195
+ }
1196
+
1197
+ return res.json({ success: true, contact: toDashboardContact(result.contact) });
1198
+ });
1199
+
1200
+ router.post('/contacts/:contactId/call', async (req, res) => {
1201
+ const contactId = sanitizeString(req.params.contactId, 120);
1202
+ if (!contactId) {
1203
+ return res.status(400).json({ success: false, error: 'contact_id_required' });
1204
+ }
1205
+
1206
+ const body = req.body || {};
1207
+ const message = sanitizeString(body.message || body.msg || '', 10000);
1208
+ const timeoutSeconds = Math.max(5, Math.min(300, Number.parseInt(String(body.timeout_seconds || body.timeoutSeconds || '60'), 10) || 60));
1209
+ if (!message) {
1210
+ return res.status(400).json({ success: false, error: 'message_required', message: 'Message is required' });
1211
+ }
1212
+
1213
+ const contact = context.tokenStore.getContact(contactId);
1214
+ if (!contact) {
1215
+ return res.status(404).json({ success: false, error: 'contact_not_found' });
1216
+ }
1217
+ if (!contact.host || !contact.token) {
1218
+ return res.status(400).json({ success: false, error: 'contact_not_callable', message: 'This contact has no callable A2A endpoint stored.' });
1219
+ }
1220
+
1221
+ const conversationId = ConversationStore.generateConversationId();
1222
+ const client = new A2AClient({
1223
+ caller: {
1224
+ name: context.agentContext?.name || 'Dashboard',
1225
+ owner: context.agentContext?.owner || 'Agent Owner',
1226
+ instance: context.config.getAgent?.().hostname || null
1227
+ }
1228
+ });
1229
+
1230
+ // Track in local conversation DB (if enabled).
1231
+ if (context.convStore) {
1232
+ try {
1233
+ context.convStore.startConversation({
1234
+ id: conversationId,
1235
+ contactId: contact.id,
1236
+ contactName: contact.name || contact.host,
1237
+ tokenId: null,
1238
+ direction: 'outbound'
1239
+ });
1240
+ context.convStore.addMessage(conversationId, {
1241
+ direction: 'outbound',
1242
+ role: 'user',
1243
+ content: message
1244
+ });
1245
+ } catch (err) {
1246
+ // Best effort; call should still go through.
1247
+ }
1248
+ }
1249
+
1250
+ const url = `a2a://${contact.host}/${contact.token}`;
1251
+ try {
1252
+ const result = await client.call(url, message, { conversationId, timeoutSeconds });
1253
+ const previousStatus = String(contact.status || '');
1254
+ context.tokenStore.updateContactStatus(contact.id, 'online');
1255
+ if (context.eventStore && context.eventStore.isAvailable() && previousStatus !== 'online') {
1256
+ context.eventStore.emitEvent('contact.status.changed', {
1257
+ contact_id: contact.id,
1258
+ contact_name: contact.name || contact.host || null,
1259
+ previous_status: previousStatus || null,
1260
+ status: 'online'
1261
+ }, { contactId: contact.id });
1262
+ }
1263
+
1264
+ if (context.convStore) {
1265
+ try {
1266
+ context.convStore.addMessage(conversationId, {
1267
+ direction: 'inbound',
1268
+ role: 'assistant',
1269
+ content: String(result?.response || '')
1270
+ });
1271
+ // One-shot outbound dashboard calls should be considered concluded.
1272
+ await context.convStore.concludeConversation(conversationId, {});
1273
+ } catch (err) {
1274
+ // ignore
1275
+ }
1276
+ }
1277
+
1278
+ return res.json({
1279
+ success: true,
1280
+ conversation_id: conversationId,
1281
+ response: result?.response || '',
1282
+ remote_trace_id: result?.trace_id || null,
1283
+ remote_request_id: result?.request_id || null,
1284
+ can_continue: result?.can_continue !== false
1285
+ });
1286
+ } catch (err) {
1287
+ const previousStatus = String(contact.status || '');
1288
+ context.tokenStore.updateContactStatus(contact.id, 'offline', err.message);
1289
+ if (context.eventStore && context.eventStore.isAvailable() && previousStatus !== 'offline') {
1290
+ context.eventStore.emitEvent('contact.status.changed', {
1291
+ contact_id: contact.id,
1292
+ contact_name: contact.name || contact.host || null,
1293
+ previous_status: previousStatus || null,
1294
+ status: 'offline',
1295
+ reason: err.message || null
1296
+ }, { contactId: contact.id });
1297
+ }
1298
+ return res.status(502).json({
1299
+ success: false,
1300
+ error: 'contact_call_failed',
1301
+ message: err.message || 'Call failed'
1302
+ });
1303
+ }
1304
+ });
1305
+
1306
+ router.get('/contacts/:contactId/calls', (req, res) => {
1307
+ if (!context.convStore) {
1308
+ return res.json({ success: true, calls: [], message: 'Conversation storage not enabled' });
1309
+ }
1310
+
1311
+ const contactId = req.params.contactId;
1312
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: false });
1313
+ const contactIndex = buildContactIndex(contacts);
1314
+ const contact = contactIndex.byId.get(contactId);
1315
+ if (!contact) {
1316
+ return res.status(404).json({ success: false, error: 'contact_not_found' });
1317
+ }
1318
+
1319
+ const all = context.convStore.listConversations({
1320
+ limit: Number.parseInt(req.query.limit || '500', 10) || 500,
1321
+ includeMessages: false
1322
+ });
1323
+
1324
+ const calls = all
1325
+ .filter(conv => {
1326
+ const resolved = resolveConversationContact(conv, contactIndex);
1327
+ return resolved?.id === contact.id;
1328
+ })
1329
+ .sort((a, b) => String(b.last_message_at || '').localeCompare(String(a.last_message_at || '')))
1330
+ .map(conv => ({
1331
+ ...conv,
1332
+ contact
1333
+ }));
1334
+
1335
+ return res.json({ success: true, contact, calls });
1336
+ });
1337
+
1338
+ router.get('/calls', (req, res) => {
1339
+ if (!context.convStore) {
1340
+ return res.json({ success: true, calls: [], message: 'Conversation storage not enabled' });
1341
+ }
1342
+
1343
+ const limit = Number.parseInt(req.query.limit || '100', 10) || 100;
1344
+ const status = req.query.status || null;
1345
+ const calls = context.convStore.listConversations({
1346
+ limit: Math.min(500, Math.max(1, limit)),
1347
+ status,
1348
+ includeMessages: false
1349
+ });
1350
+
1351
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: false });
1352
+ const contactIndex = buildContactIndex(contacts);
1353
+ const enriched = calls.map(conv => ({
1354
+ ...conv,
1355
+ contact: resolveConversationContact(conv, contactIndex)
1356
+ }));
1357
+
1358
+ return res.json({ success: true, calls: enriched });
1359
+ });
1360
+
1361
+ router.get('/calls/:conversationId', (req, res) => {
1362
+ if (!context.convStore) {
1363
+ return res.status(404).json({
1364
+ success: false,
1365
+ error: 'conversation_storage_disabled'
1366
+ });
1367
+ }
1368
+
1369
+ const conversationId = req.params.conversationId;
1370
+ const contextData = context.convStore.getConversationContext(
1371
+ conversationId,
1372
+ Number.parseInt(req.query.messages || '30', 10) || 30
1373
+ );
1374
+ if (!contextData) {
1375
+ return res.status(404).json({ success: false, error: 'conversation_not_found' });
1376
+ }
1377
+
1378
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: false });
1379
+ const contactIndex = buildContactIndex(contacts);
1380
+ const contact = resolveConversationContact({
1381
+ contact_name: contextData.contact
1382
+ }, contactIndex);
1383
+
1384
+ return res.json({ success: true, call: { ...contextData, contact } });
1385
+ });
1386
+
1387
+ router.get('/settings', (req, res) => {
1388
+ const cfg = context.config.getAll();
1389
+ const manifest = loadManifest();
1390
+ const configTiers = cfg.tiers || {};
1391
+ const manifestTiers = manifest.tiers || {};
1392
+ const tierIds = new Set([...Object.keys(configTiers), ...Object.keys(manifestTiers)]);
1393
+
1394
+ const tiers = Array.from(tierIds).sort().map(tierId => {
1395
+ const configTier = configTiers[tierId] || {};
1396
+ const manifestTier = manifestTiers[tierId] || {};
1397
+ return {
1398
+ id: tierId,
1399
+ name: configTier.name || tierId,
1400
+ description: configTier.description || '',
1401
+ capabilities: configTier.capabilities || [],
1402
+ allowed_tools: sanitizeStringArray(configTier.allowed_tools || [], 30, 80),
1403
+ topics: sanitizeStringArray(configTier.topics || []),
1404
+ goals: sanitizeStringArray(configTier.goals || []),
1405
+ examples: sanitizeStringArray(configTier.examples || [], 20, 120),
1406
+ manifest: {
1407
+ topics: manifestTier.topics || [],
1408
+ objectives: manifestTier.objectives || [],
1409
+ do_not_discuss: manifestTier.do_not_discuss || []
1410
+ }
1411
+ };
1412
+ });
1413
+
1414
+ res.json({
1415
+ success: true,
1416
+ onboarding_complete: context.config.isOnboarded(),
1417
+ defaults: cfg.defaults || {},
1418
+ agent: (() => { const { private_key, ...pub } = cfg.agent || {}; return pub; })(),
1419
+ tiers,
1420
+ manifest: {
1421
+ never_disclose: manifest.never_disclose || [],
1422
+ personality_notes: manifest.personality_notes || '',
1423
+ updated_at: manifest.updated_at || null
1424
+ }
1425
+ });
1426
+ });
1427
+
1428
+ router.put('/settings/tiers/:tierId', (req, res) => {
1429
+ const tierId = normalizeTierId(req.params.tierId);
1430
+ if (!tierId) {
1431
+ return res.status(400).json({ success: false, error: 'invalid_tier_id' });
1432
+ }
1433
+
1434
+ const body = req.body || {};
1435
+ const update = {};
1436
+ if (body.name !== undefined) update.name = sanitizeString(body.name, 120);
1437
+ if (body.description !== undefined) update.description = sanitizeString(body.description, 300);
1438
+ if (body.capabilities !== undefined) update.capabilities = sanitizeStringArray(body.capabilities, 100, 120);
1439
+ if (body.allowed_tools !== undefined) update.allowed_tools = sanitizeStringArray(body.allowed_tools, 30, 80);
1440
+ if (body.examples !== undefined) update.examples = sanitizeStringArray(body.examples, 20, 120);
1441
+ if (body.topics !== undefined) update.topics = sanitizeStringArray(body.topics, 200, 160);
1442
+ if (body.goals !== undefined) update.goals = sanitizeStringArray(body.goals, 200, 160);
1443
+
1444
+ try {
1445
+ context.config.setTier(tierId, update);
1446
+ } catch (err) {
1447
+ return res.status(400).json({
1448
+ success: false,
1449
+ error: 'invalid_tier_config',
1450
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1451
+ message: err.message
1452
+ });
1453
+ }
1454
+
1455
+ if (body.manifest) {
1456
+ const manifest = loadManifest();
1457
+ manifest.tiers = manifest.tiers || {};
1458
+ manifest.tiers[tierId] = {
1459
+ topics: parseTopicObjects(body.manifest.topics),
1460
+ objectives: parseTopicObjects(body.manifest.objectives),
1461
+ do_not_discuss: parseTopicObjects(body.manifest.do_not_discuss)
1462
+ };
1463
+ saveManifest(manifest);
1464
+ }
1465
+
1466
+ return res.json({ success: true, tier_id: tierId });
1467
+ });
1468
+
1469
+ router.post('/settings/tiers', (req, res) => {
1470
+ const body = req.body || {};
1471
+ const tierId = normalizeTierId(body.id || body.tier_id);
1472
+ if (!tierId) {
1473
+ return res.status(400).json({ success: false, error: 'tier_id_required' });
1474
+ }
1475
+
1476
+ const cfg = context.config.getAll();
1477
+ if (cfg.tiers && cfg.tiers[tierId]) {
1478
+ return res.status(409).json({ success: false, error: 'tier_exists' });
1479
+ }
1480
+
1481
+ const copyFrom = normalizeTierId(body.copy_from || '');
1482
+ if (copyFrom && cfg.tiers && cfg.tiers[copyFrom]) {
1483
+ try {
1484
+ context.config.setTier(tierId, { ...cfg.tiers[copyFrom] });
1485
+ } catch (err) {
1486
+ return res.status(400).json({
1487
+ success: false,
1488
+ error: 'invalid_tier_config',
1489
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1490
+ message: err.message
1491
+ });
1492
+ }
1493
+ } else {
1494
+ try {
1495
+ context.config.setTier(tierId, {
1496
+ name: sanitizeString(body.name || tierId, 120),
1497
+ description: sanitizeString(body.description || 'Custom tier', 300),
1498
+ capabilities: sanitizeStringArray(body.capabilities || []),
1499
+ allowed_tools: sanitizeStringArray(body.allowed_tools || [], 30, 80),
1500
+ topics: sanitizeStringArray(body.topics || []),
1501
+ goals: sanitizeStringArray(body.goals || []),
1502
+ examples: sanitizeStringArray(body.examples || [], 20, 120)
1503
+ });
1504
+ } catch (err) {
1505
+ return res.status(400).json({
1506
+ success: false,
1507
+ error: 'invalid_tier_config',
1508
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1509
+ message: err.message
1510
+ });
1511
+ }
1512
+ }
1513
+
1514
+ return res.json({ success: true, tier_id: tierId });
1515
+ });
1516
+
1517
+ router.post('/settings/tiers/:toTier/copy-from/:fromTier', (req, res) => {
1518
+ const toTier = normalizeTierId(req.params.toTier);
1519
+ const fromTier = normalizeTierId(req.params.fromTier);
1520
+ if (!toTier || !fromTier) {
1521
+ return res.status(400).json({ success: false, error: 'invalid_tier_ids' });
1522
+ }
1523
+
1524
+ const cfg = context.config.getAll();
1525
+ if (!cfg.tiers || !cfg.tiers[fromTier]) {
1526
+ return res.status(404).json({ success: false, error: 'source_tier_not_found' });
1527
+ }
1528
+
1529
+ try {
1530
+ context.config.setTier(toTier, { ...cfg.tiers[fromTier] });
1531
+ } catch (err) {
1532
+ return res.status(400).json({
1533
+ success: false,
1534
+ error: 'invalid_tier_config',
1535
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1536
+ message: err.message
1537
+ });
1538
+ }
1539
+
1540
+ const manifest = loadManifest();
1541
+ if (manifest.tiers && manifest.tiers[fromTier]) {
1542
+ manifest.tiers[toTier] = JSON.parse(JSON.stringify(manifest.tiers[fromTier]));
1543
+ saveManifest(manifest);
1544
+ }
1545
+
1546
+ return res.json({ success: true, from_tier: fromTier, to_tier: toTier });
1547
+ });
1548
+
1549
+ router.put('/settings/defaults', (req, res) => {
1550
+ context.config.setDefaults(req.body || {});
1551
+ return res.json({ success: true });
1552
+ });
1553
+
1554
+ router.put('/settings/agent', (req, res) => {
1555
+ context.config.setAgent(req.body || {});
1556
+ return res.json({ success: true });
1557
+ });
1558
+
1559
+ router.put('/settings/manifest', (req, res) => {
1560
+ const body = req.body || {};
1561
+ const manifest = loadManifest();
1562
+ if (body.never_disclose !== undefined) {
1563
+ manifest.never_disclose = sanitizeStringArray(body.never_disclose, 100, 200);
1564
+ }
1565
+ if (body.personality_notes !== undefined) {
1566
+ manifest.personality_notes = sanitizeString(body.personality_notes, 2000);
1567
+ }
1568
+ saveManifest(manifest);
1569
+ return res.json({ success: true });
1570
+ });
1571
+
1572
+ router.get('/invites', (req, res) => {
1573
+ const includeRevoked = String(req.query.include_revoked || 'false') === 'true';
1574
+ const tokens = context.tokenStore.list(includeRevoked);
1575
+ return res.json({ success: true, invites: tokens });
1576
+ });
1577
+
1578
+ router.post('/invites', async (req, res) => {
1579
+ const body = req.body || {};
1580
+ const cfg = context.config.getAll();
1581
+ const tierId = normalizeTierId(body.tier || body.permissions || 'public') || 'public';
1582
+ const tier = (cfg.tiers && cfg.tiers[tierId]) ? cfg.tiers[tierId] : {};
1583
+
1584
+ const name = sanitizeString(body.name || tier.name || 'Agent Invite', 120);
1585
+ const owner = sanitizeString(body.owner || '', 120) || null;
1586
+ const expires = sanitizeString(body.expires || cfg.defaults?.expiration || '7d', 20);
1587
+ const disclosure = sanitizeString(body.disclosure || tier.disclosure || 'minimal', 40);
1588
+ const notify = sanitizeString(body.notify || 'all', 20);
1589
+ const maxCalls = body.max_calls === null || body.max_calls === 'unlimited'
1590
+ ? null
1591
+ : Math.max(1, Number.parseInt(body.max_calls || cfg.defaults?.maxCalls || 100, 10) || 100);
1592
+
1593
+ const allowedTopics = sanitizeStringArray(body.topics || tier.topics || []);
1594
+ const allowedGoals = sanitizeStringArray(body.goals || tier.goals || []);
1595
+ const allowedTools = sanitizeStringArray(body.tools || body.allowed_tools || tier.allowed_tools || [], 30, 80);
1596
+ const { token, record } = context.tokenStore.create({
1597
+ name,
1598
+ owner,
1599
+ expires,
1600
+ permissions: tierId,
1601
+ disclosure,
1602
+ notify,
1603
+ maxCalls,
1604
+ allowedTopics: allowedTopics.length ? allowedTopics : null,
1605
+ allowedGoals: allowedGoals.length ? allowedGoals : null,
1606
+ allowedTools: allowedTools.length ? allowedTools : null,
1607
+ tierSettings: {
1608
+ tierId,
1609
+ ...tier
1610
+ }
1611
+ });
1612
+
1613
+ const resolvedHost = await resolveInviteHost({
1614
+ config: context.config,
1615
+ fallbackHost: req.headers.host || process.env.HOSTNAME || 'localhost',
1616
+ defaultPort: process.env.PORT || process.env.A2A_PORT || 3001,
1617
+ refreshExternalIp: true
1618
+ });
1619
+ const host = resolvedHost.host;
1620
+ const inviteUrl = `a2a://${host}/${token}`;
1621
+ const expiresText = record.expires_at || 'never';
1622
+ const message = formatInviteMessage({
1623
+ owner,
1624
+ agentName: name,
1625
+ inviteUrl,
1626
+ topics: record.allowed_topics || [],
1627
+ goals: record.allowed_goals || [],
1628
+ tools: record.allowed_tools || [],
1629
+ expiresText
1630
+ });
1631
+
1632
+ return res.json({
1633
+ success: true,
1634
+ invite_url: inviteUrl,
1635
+ invite_message: message,
1636
+ warnings: resolvedHost.warnings || [],
1637
+ token: record
1638
+ });
1639
+ });
1640
+
1641
+ router.post('/invites/:tokenId/revoke', (req, res) => {
1642
+ const tokenId = sanitizeString(req.params.tokenId, 80);
1643
+ if (!tokenId) {
1644
+ return res.status(400).json({ success: false, error: 'token_id_required' });
1645
+ }
1646
+
1647
+ const result = context.tokenStore.revoke(tokenId);
1648
+ if (!result.success) {
1649
+ return res.status(404).json({ success: false, error: result.error || 'token_not_found' });
1650
+ }
1651
+
1652
+ return res.json({ success: true, token: result.record });
1653
+ });
1654
+
1655
+ return router;
1656
+ }
1657
+
1658
+ function createDashboardUiRouter(options = {}) {
1659
+ const router = express.Router();
1660
+ const context = buildContext(options);
1661
+ const ensureDashboardAccess = makeEnsureDashboardAccess(context);
1662
+ router.use(ensureDashboardAccess);
1663
+
1664
+ router.use((req, res, next) => {
1665
+ const rawPath = String(req.originalUrl || '').split('?')[0];
1666
+ if (rawPath === req.baseUrl) {
1667
+ return res.redirect(302, `${req.baseUrl}/`);
1668
+ }
1669
+ return next();
1670
+ });
1671
+
1672
+ router.get('/', (req, res) => {
1673
+ const indexPath = path.join(context.staticDir, 'index.html');
1674
+ if (!fs.existsSync(indexPath)) {
1675
+ return res.status(500).send('Dashboard UI missing');
1676
+ }
1677
+ return res.sendFile(indexPath);
1678
+ });
1679
+
1680
+ router.use(express.static(context.staticDir, { index: false }));
1681
+ return router;
1682
+ }
1683
+
1684
+ module.exports = {
1685
+ createDashboardApiRouter,
1686
+ createDashboardUiRouter,
1687
+ DASHBOARD_STATIC_DIR
1688
+ };