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,1578 @@
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
+ // All other dashboard API routes require owner access.
506
+ router.use(ensureDashboardAccess);
507
+
508
+ router.get('/events', (req, res) => {
509
+ if (!context.eventStore || !context.eventStore.isAvailable()) {
510
+ return res.status(503).json({
511
+ success: false,
512
+ error: 'event_stream_unavailable',
513
+ message: context.eventStore ? context.eventStore.getDbError() : 'missing_event_store'
514
+ });
515
+ }
516
+
517
+ const lastIdHeader = req.headers['last-event-id'];
518
+ const since = sanitizeString(
519
+ req.query.since || lastIdHeader || req.query.last_event_id || '',
520
+ 32
521
+ );
522
+ const replayLimit = Math.min(500, Math.max(1, Number.parseInt(req.query.replay || '200', 10) || 200));
523
+
524
+ res.status(200);
525
+ res.setHeader('Content-Type', 'text/event-stream');
526
+ res.setHeader('Cache-Control', 'no-cache, no-transform');
527
+ res.setHeader('Connection', 'keep-alive');
528
+ res.flushHeaders?.();
529
+
530
+ let lastSentId = Number.parseInt(String(since || '0'), 10);
531
+ if (!Number.isFinite(lastSentId) || lastSentId < 0) {
532
+ lastSentId = 0;
533
+ }
534
+
535
+ const pendingLive = [];
536
+ const unsubscribe = context.eventStore.subscribe((event) => {
537
+ if (!event || !Number.isFinite(event.id)) return;
538
+ if (event.id <= lastSentId) return;
539
+ pendingLive.push(event);
540
+ });
541
+
542
+ const replay = context.eventStore.listSince(since, { limit: replayLimit });
543
+ for (const row of replay) {
544
+ writeSseEvent(res, row);
545
+ if (Number.isFinite(row.id) && row.id > lastSentId) {
546
+ lastSentId = row.id;
547
+ }
548
+ }
549
+ while (pendingLive.length > 0) {
550
+ const row = pendingLive.shift();
551
+ if (!row || !Number.isFinite(row.id) || row.id <= lastSentId) continue;
552
+ writeSseEvent(res, row);
553
+ lastSentId = row.id;
554
+ }
555
+ res.write(': connected\n\n');
556
+
557
+ const liveUnsubscribe = context.eventStore.subscribe((event) => {
558
+ if (!event || !Number.isFinite(event.id) || event.id <= lastSentId) return;
559
+ writeSseEvent(res, event);
560
+ lastSentId = event.id;
561
+ });
562
+ const heartbeat = setInterval(() => {
563
+ res.write(`: heartbeat ${Date.now()}\n\n`);
564
+ }, 15000);
565
+
566
+ req.on('close', () => {
567
+ clearInterval(heartbeat);
568
+ unsubscribe();
569
+ liveUnsubscribe();
570
+ res.end();
571
+ });
572
+ });
573
+
574
+ router.get('/status', async (req, res) => {
575
+ context.logger.debug('Dashboard status requested', { event: 'dashboard_status' });
576
+ const refreshIp = String(req.query.refresh_ip || 'false') === 'true';
577
+ let resolvedHost = null;
578
+ let warnings = [];
579
+ let inviteResolution = null;
580
+ try {
581
+ // Determine default port based on config hostname:
582
+ // - If hostname has no port (e.g., "149.28.213.47"), assume port 80 (reverse proxy)
583
+ // - If hostname has explicit port, use that
584
+ // - Otherwise fall back to server port or env
585
+ const agent = context.config?.getAgent?.() || {};
586
+ const hostname = agent.hostname || '';
587
+ const hasExplicitPort = hostname.includes(':') && !hostname.startsWith('[');
588
+ let defaultPort;
589
+ if (hasExplicitPort) {
590
+ defaultPort = null; // Will be parsed from hostname
591
+ } else if (hostname && !hostname.includes('localhost')) {
592
+ defaultPort = 80; // External hostname without port = assume reverse proxy on 80
593
+ } else {
594
+ defaultPort = process.env.PORT || process.env.A2A_PORT || 80;
595
+ }
596
+
597
+ const resolved = await resolveInviteHost({
598
+ config: context.config,
599
+ fallbackHost: req.headers.host || process.env.HOSTNAME || 'localhost',
600
+ defaultPort,
601
+ refreshExternalIp: refreshIp,
602
+ forceRefreshExternalIp: refreshIp,
603
+ alwaysLookupExternalIp: true,
604
+ warnOnExternalIpFailure: refreshIp
605
+ });
606
+ inviteResolution = resolved;
607
+ resolvedHost = resolved.host;
608
+ warnings = resolved.warnings || [];
609
+ } catch (err) {
610
+ // Non-fatal: still return base status.
611
+ }
612
+
613
+ const schemeOverride = String(process.env.A2A_PUBLIC_SCHEME || '').trim();
614
+ const inferredScheme = schemeOverride || (isHttpsRequest(req) ? 'https' : 'http');
615
+ const publicBaseUrl = resolvedHost ? `${inferredScheme}://${resolvedHost}` : null;
616
+
617
+ const devices = (context.callbookStore && context.callbookStore.isAvailable())
618
+ ? context.callbookStore.listDevices({ includeRevoked: true, limit: 200 }).devices
619
+ : [];
620
+
621
+ return res.json({
622
+ success: true,
623
+ dashboard: true,
624
+ conversations_enabled: Boolean(context.convStore),
625
+ agent: {
626
+ name: context.agentContext?.name || null,
627
+ owner_name: context.agentContext?.owner || null,
628
+ server_name: sanitizeString(context.config.getAgent?.().server_name || context.config.getAgent?.().serverName || '', 120) || null
629
+ },
630
+ config_file: require('../lib/config').CONFIG_FILE,
631
+ manifest_file: require('../lib/disclosure').MANIFEST_FILE,
632
+ public_base_url: publicBaseUrl,
633
+ public_dashboard_url: publicBaseUrl ? `${publicBaseUrl}/dashboard/` : null,
634
+ callbook_install_base: publicBaseUrl ? `${publicBaseUrl}/api/a2a/callbook/install` : null,
635
+ invite_host: inviteResolution ? {
636
+ host: inviteResolution.host,
637
+ source: inviteResolution.source || null,
638
+ original_host: inviteResolution.originalHost || null
639
+ } : null,
640
+ external_ip: inviteResolution && inviteResolution.externalIpInfo ? {
641
+ ip: inviteResolution.externalIpInfo.ip || null,
642
+ checked_at: inviteResolution.externalIpInfo.checkedAt || null,
643
+ source: inviteResolution.externalIpInfo.source || null,
644
+ from_cache: Boolean(inviteResolution.externalIpInfo.fromCache),
645
+ stale: Boolean(inviteResolution.externalIpInfo.stale),
646
+ error: inviteResolution.externalIpInfo.error || null,
647
+ attempts: inviteResolution.externalIpInfo.attempts || null
648
+ } : null,
649
+ warnings,
650
+ callbook: {
651
+ enabled: Boolean(context.callbookStore && context.callbookStore.isAvailable()),
652
+ device_count: Array.isArray(devices) ? devices.length : 0
653
+ },
654
+ auto_update: resolveAutoUpdateStatus(context)
655
+ });
656
+ });
657
+
658
+ router.get('/update/status', (req, res) => {
659
+ return res.json({
660
+ success: true,
661
+ auto_update: resolveAutoUpdateStatus(context)
662
+ });
663
+ });
664
+
665
+ router.post('/update/check', async (req, res) => {
666
+ const manager = context.getUpdateManager ? context.getUpdateManager() : null;
667
+ if (!manager || typeof manager.triggerCheck !== 'function') {
668
+ return res.status(503).json({
669
+ success: false,
670
+ error: 'updater_unavailable',
671
+ message: 'Auto-updater is not initialized for this server.'
672
+ });
673
+ }
674
+ await manager.triggerCheck({ reason: 'dashboard_manual_check', forceCheck: true });
675
+ return res.json({
676
+ success: true,
677
+ auto_update: resolveAutoUpdateStatus(context)
678
+ });
679
+ });
680
+
681
+ router.post('/update/now', async (req, res) => {
682
+ const manager = context.getUpdateManager ? context.getUpdateManager() : null;
683
+ if (!manager || typeof manager.triggerUpdate !== 'function') {
684
+ return res.status(503).json({
685
+ success: false,
686
+ error: 'updater_unavailable',
687
+ message: 'Auto-updater is not initialized for this server.'
688
+ });
689
+ }
690
+ const force = parseBoolean(req.body && (req.body.force !== undefined ? req.body.force : req.body.force_update));
691
+ await manager.triggerUpdate({
692
+ reason: 'dashboard_manual_update',
693
+ force
694
+ });
695
+ return res.json({
696
+ success: true,
697
+ auto_update: resolveAutoUpdateStatus(context)
698
+ });
699
+ });
700
+
701
+ router.put('/update/config', async (req, res) => {
702
+ const manager = context.getUpdateManager ? context.getUpdateManager() : null;
703
+ const body = req.body || {};
704
+ const enabled = body.enabled !== undefined ? parseBoolean(body.enabled) : undefined;
705
+
706
+ if (enabled === undefined) {
707
+ return res.status(400).json({
708
+ success: false,
709
+ error: 'enabled_required',
710
+ message: 'Pass { enabled: true|false }.'
711
+ });
712
+ }
713
+
714
+ if (manager && typeof manager.setEnabled === 'function') {
715
+ await manager.setEnabled(enabled);
716
+ } else if (context.config && typeof context.config.setAutoUpdate === 'function') {
717
+ context.config.setAutoUpdate({ enabled });
718
+ }
719
+
720
+ return res.json({
721
+ success: true,
722
+ auto_update: resolveAutoUpdateStatus(context)
723
+ });
724
+ });
725
+
726
+ // Callbook Remote: create a short-lived install link (24h by default).
727
+ router.post('/callbook/provision', async (req, res) => {
728
+ const body = req.body || {};
729
+ const label = sanitizeString(body.label || 'Callbook Remote', 120) || null;
730
+ const ttlHoursRaw = body.ttl_hours !== undefined ? body.ttl_hours : body.ttlHours;
731
+ const ttlHours = Math.max(1, Math.min(168, Number.parseInt(String(ttlHoursRaw || '24'), 10) || 24));
732
+ const ttlMs = ttlHours * 60 * 60 * 1000;
733
+
734
+ if (!context.callbookStore || !context.callbookStore.isAvailable()) {
735
+ return res.status(500).json({
736
+ success: false,
737
+ error: 'callbook_storage_unavailable',
738
+ message: 'Callbook session storage is not available on this server.',
739
+ hint: context.callbookStore ? context.callbookStore.getDbError() : 'missing_callbook_store'
740
+ });
741
+ }
742
+
743
+ const created = context.callbookStore.createProvisionCode({ label, ttlMs });
744
+ if (!created.success) {
745
+ return res.status(500).json({
746
+ success: false,
747
+ error: created.error || 'callbook_provision_failed',
748
+ message: created.message || 'Failed to create Callbook Remote install link.'
749
+ });
750
+ }
751
+
752
+ let resolvedHost = null;
753
+ let warnings = [];
754
+ try {
755
+ // Use same port logic as /status endpoint
756
+ const agent = context.config?.getAgent?.() || {};
757
+ const hostname = agent.hostname || '';
758
+ const hasExplicitPort = hostname.includes(':') && !hostname.startsWith('[');
759
+ let defaultPort;
760
+ if (hasExplicitPort) {
761
+ defaultPort = null;
762
+ } else if (hostname && !hostname.includes('localhost')) {
763
+ defaultPort = 80;
764
+ } else {
765
+ defaultPort = process.env.PORT || process.env.A2A_PORT || 80;
766
+ }
767
+
768
+ const resolved = await resolveInviteHost({
769
+ config: context.config,
770
+ fallbackHost: req.headers.host || process.env.HOSTNAME || 'localhost',
771
+ defaultPort,
772
+ refreshExternalIp: true,
773
+ forceRefreshExternalIp: true
774
+ });
775
+ resolvedHost = resolved.host;
776
+ warnings = resolved.warnings || [];
777
+ } catch (err) {
778
+ // Non-fatal: we can still return the code; owner can assemble URL manually.
779
+ }
780
+
781
+ const schemeOverride = String(process.env.A2A_PUBLIC_SCHEME || '').trim();
782
+ const scheme = schemeOverride || (isHttpsRequest(req) ? 'https' : 'http');
783
+ const baseUrl = resolvedHost ? `${scheme}://${resolvedHost}` : null;
784
+ const installUrl = baseUrl ? `${baseUrl}/api/a2a/callbook/install#code=${created.code}` : null;
785
+
786
+ return res.json({
787
+ success: true,
788
+ install_url: installUrl,
789
+ expires_at: created.record.expires_at,
790
+ token: {
791
+ id: created.record.id,
792
+ label: created.record.label
793
+ },
794
+ warnings
795
+ });
796
+ });
797
+
798
+ router.get('/callbook/devices', (req, res) => {
799
+ if (!context.callbookStore || !context.callbookStore.isAvailable()) {
800
+ return res.json({ success: true, devices: [], message: 'Callbook storage not available' });
801
+ }
802
+ const includeRevoked = String(req.query.include_revoked || 'false') === 'true';
803
+ const result = context.callbookStore.listDevices({ includeRevoked, limit: req.query.limit || 200 });
804
+ if (!result.success) {
805
+ return res.status(500).json({ success: false, error: result.error || 'callbook_list_failed', message: result.message });
806
+ }
807
+ return res.json({ success: true, devices: result.devices });
808
+ });
809
+
810
+ router.post('/callbook/devices/:deviceId/revoke', (req, res) => {
811
+ if (!context.callbookStore || !context.callbookStore.isAvailable()) {
812
+ return res.status(500).json({ success: false, error: 'callbook_storage_unavailable' });
813
+ }
814
+ const deviceId = sanitizeString(req.params.deviceId, 120);
815
+ const result = context.callbookStore.revokeDevice(deviceId);
816
+ if (!result.success) {
817
+ return res.status(404).json({ success: false, error: result.error || 'device_not_found' });
818
+ }
819
+ return res.json({ success: true, device: result.device });
820
+ });
821
+
822
+ router.post('/callbook/logout', (req, res) => {
823
+ const cookie = buildSetCookie('a2a_callbook_session', '', {
824
+ httpOnly: true,
825
+ sameSite: 'Lax',
826
+ secure: isHttpsRequest(req),
827
+ maxAgeSeconds: 0
828
+ });
829
+ res.setHeader('Set-Cookie', cookie);
830
+ return res.json({ success: true });
831
+ });
832
+
833
+ router.get('/logs', (req, res) => {
834
+ const limit = Math.min(1000, Math.max(1, Number.parseInt(req.query.limit || '200', 10) || 200));
835
+ const logs = context.logger.list({
836
+ limit,
837
+ level: req.query.level || null,
838
+ component: req.query.component || null,
839
+ event: req.query.event || null,
840
+ errorCode: req.query.error_code || req.query.errorCode || null,
841
+ statusCode: req.query.status_code || req.query.statusCode || null,
842
+ traceId: req.query.trace_id || req.query.traceId || null,
843
+ conversationId: req.query.conversation_id || req.query.conversationId || null,
844
+ tokenId: req.query.token_id || req.query.tokenId || null,
845
+ search: req.query.search || null,
846
+ from: req.query.from || null,
847
+ to: req.query.to || null
848
+ });
849
+ return res.json({ success: true, logs });
850
+ });
851
+
852
+ router.get('/logs/trace/:traceId', (req, res) => {
853
+ const traceId = sanitizeString(req.params.traceId, 120);
854
+ if (!traceId) {
855
+ return res.status(400).json({ success: false, error: 'trace_id_required' });
856
+ }
857
+ const limit = Math.min(1000, Math.max(1, Number.parseInt(req.query.limit || '500', 10) || 500));
858
+ const logs = context.logger.getTrace(traceId, { limit });
859
+ return res.json({ success: true, trace_id: traceId, logs });
860
+ });
861
+
862
+ router.get('/logs/stats', (req, res) => {
863
+ const stats = context.logger.stats({
864
+ from: req.query.from || null,
865
+ to: req.query.to || null
866
+ });
867
+ return res.json({ success: true, stats });
868
+ });
869
+
870
+ // A2A-42: Serve E2E test results for the Health tab.
871
+ // Reads from local persist layer — no external dependencies.
872
+ router.get('/test-results', (req, res) => {
873
+ if (!persistModule) {
874
+ return res.json({
875
+ success: true,
876
+ latest: null,
877
+ history: [],
878
+ has_results: false,
879
+ message: 'Test results module not available'
880
+ });
881
+ }
882
+
883
+ const latest = persistModule.getLatest();
884
+ const limit = Math.min(20, Math.max(1, Number.parseInt(req.query.limit || '10', 10) || 10));
885
+ const history = persistModule.getHistory(limit);
886
+
887
+ return res.json({
888
+ success: true,
889
+ latest,
890
+ history: history.map(r => ({
891
+ status: r.status,
892
+ duration: r.duration,
893
+ startedAt: r.startedAt,
894
+ finishedAt: r.finishedAt,
895
+ summary: r.summary,
896
+ regression: r.regression || null
897
+ })),
898
+ has_results: latest !== null
899
+ });
900
+ });
901
+
902
+ router.get('/debug/call', (req, res) => {
903
+ const traceId = sanitizeString(req.query.trace_id || req.query.traceId || '', 120);
904
+ const conversationId = sanitizeString(req.query.conversation_id || req.query.conversationId || '', 120);
905
+ const limit = Math.min(1000, Math.max(1, Number.parseInt(req.query.limit || '500', 10) || 500));
906
+
907
+ if (!traceId && !conversationId) {
908
+ return res.status(400).json({
909
+ success: false,
910
+ error: 'missing_scope',
911
+ message: 'Provide trace_id or conversation_id.'
912
+ });
913
+ }
914
+
915
+ const logs = traceId
916
+ ? context.logger.getTrace(traceId, { limit })
917
+ : context.logger.list({
918
+ limit,
919
+ conversationId,
920
+ sort_desc: false
921
+ });
922
+
923
+ if (!Array.isArray(logs) || logs.length === 0) {
924
+ return res.status(404).json({
925
+ success: false,
926
+ error: 'no_logs_found',
927
+ message: traceId ? 'No logs for trace_id' : 'No logs for conversation_id'
928
+ });
929
+ }
930
+
931
+ const summary = summarizeDebugLogs(logs);
932
+ const errors = logs.filter(row => row.level === 'error' || row.level === 'warn').slice(0, 20);
933
+ const callSignature = {
934
+ trace_ids: summary.trace_ids,
935
+ conversation_ids: summary.conversation_ids,
936
+ token_ids: summary.token_ids,
937
+ request_ids: summary.request_ids
938
+ };
939
+
940
+ return res.json({
941
+ success: true,
942
+ summary: {
943
+ ...summary,
944
+ ...callSignature,
945
+ errors: errors.map(row => ({
946
+ id: row.id,
947
+ timestamp: row.timestamp,
948
+ level: row.level,
949
+ event: row.event,
950
+ message: row.message,
951
+ error_code: row.error_code,
952
+ status_code: row.status_code,
953
+ hint: row.hint
954
+ })),
955
+ error_codes: findErrorHints(logs)
956
+ },
957
+ logs: summary.timeline_ms === null ? logs : logs
958
+ });
959
+ });
960
+
961
+ router.get('/contacts', (req, res) => {
962
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: true, includeSecrets: true });
963
+ const contactIndex = buildContactIndex(contacts);
964
+ const conversations = context.convStore
965
+ ? context.convStore.listConversations({
966
+ limit: Number.parseInt(req.query.limit || '500', 10) || 500,
967
+ includeMessages: false
968
+ })
969
+ : [];
970
+
971
+ const callMap = new Map();
972
+ for (const contact of contacts) {
973
+ callMap.set(contact.id, []);
974
+ }
975
+ for (const conv of conversations) {
976
+ const contact = resolveConversationContact(conv, contactIndex);
977
+ if (!contact) continue;
978
+ if (!callMap.has(contact.id)) {
979
+ callMap.set(contact.id, []);
980
+ }
981
+ callMap.get(contact.id).push(conv);
982
+ }
983
+
984
+ const result = contacts.map(contact => {
985
+ const calls = (callMap.get(contact.id) || []).sort((a, b) => {
986
+ return String(b.last_message_at || '').localeCompare(String(a.last_message_at || ''));
987
+ });
988
+ const latest = calls[0] || null;
989
+
990
+ return {
991
+ ...toDashboardContact(contact),
992
+ call_count: calls.length,
993
+ last_call_at: latest?.last_message_at || null,
994
+ last_call_id: latest?.id || null,
995
+ last_summary: latest?.summary || null,
996
+ last_owner_summary: latest?.owner_summary || null
997
+ };
998
+ });
999
+
1000
+ res.json({ success: true, contacts: result });
1001
+ });
1002
+
1003
+ router.post('/contacts', (req, res) => {
1004
+ const body = req.body || {};
1005
+ const inviteUrl = sanitizeString(
1006
+ body.invite_url || body.inviteUrl || body.web_address || body.webAddress || body.url || '',
1007
+ 600
1008
+ );
1009
+ const name = sanitizeString(body.name || '', 120) || null;
1010
+ const owner = sanitizeString(body.owner || '', 120) || null;
1011
+ const isMine = parseBoolean(body.is_mine !== undefined ? body.is_mine : body.isMine);
1012
+ const serverName = sanitizeString(body.server_name || body.serverName || '', 120) || null;
1013
+ const notes = sanitizeString(body.notes || '', 800) || null;
1014
+ const tags = sanitizeStringArray(body.tags || [], 30, 40);
1015
+ const fields = (body.fields && typeof body.fields === 'object' && !Array.isArray(body.fields)) ? body.fields : {};
1016
+
1017
+ if (!inviteUrl) {
1018
+ return res.status(400).json({ success: false, error: 'invite_url_required' });
1019
+ }
1020
+
1021
+ try {
1022
+ const result = context.tokenStore.addContact(inviteUrl, {
1023
+ name: name || undefined,
1024
+ owner: owner || undefined,
1025
+ is_mine: isMine,
1026
+ server_name: serverName || undefined,
1027
+ notes: notes || undefined,
1028
+ tags: tags || undefined,
1029
+ fields: fields || undefined
1030
+ });
1031
+ if (!result.success) {
1032
+ return res.status(409).json({ success: false, error: result.error || 'contact_add_failed', contact: result.existing || null });
1033
+ }
1034
+ const stored = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: true })
1035
+ .find(c => c.id === result.contact.id);
1036
+ return res.json({ success: true, contact: stored ? toDashboardContact(stored) : toDashboardContact(result.contact) });
1037
+ } catch (err) {
1038
+ return res.status(400).json({
1039
+ success: false,
1040
+ error: 'invalid_invite_url',
1041
+ message: err.message || 'Invalid invite URL'
1042
+ });
1043
+ }
1044
+ });
1045
+
1046
+ router.put('/contacts/:contactId', (req, res) => {
1047
+ const contactId = sanitizeString(req.params.contactId, 120);
1048
+ if (!contactId) {
1049
+ return res.status(400).json({ success: false, error: 'contact_id_required' });
1050
+ }
1051
+
1052
+ const body = req.body || {};
1053
+ const updates = {};
1054
+ if (body.name !== undefined) updates.name = sanitizeString(body.name, 120);
1055
+ if (body.owner !== undefined) updates.owner = sanitizeString(body.owner, 120);
1056
+ if (body.is_mine !== undefined) updates.is_mine = parseBoolean(body.is_mine);
1057
+ if (body.isMine !== undefined) updates.is_mine = parseBoolean(body.isMine);
1058
+ if (body.server_name !== undefined) updates.server_name = sanitizeString(body.server_name, 120);
1059
+ if (body.serverName !== undefined) updates.server_name = sanitizeString(body.serverName, 120);
1060
+ if (body.notes !== undefined) updates.notes = sanitizeString(body.notes, 800);
1061
+ if (body.tags !== undefined) updates.tags = sanitizeStringArray(body.tags, 30, 40);
1062
+ if (body.fields !== undefined) updates.fields = body.fields;
1063
+ if (body.linked_token_id !== undefined) updates.linked_token_id = sanitizeString(body.linked_token_id, 80);
1064
+ if (body.linkedTokenId !== undefined) updates.linked_token_id = sanitizeString(body.linkedTokenId, 80);
1065
+
1066
+ const result = context.tokenStore.updateContact(contactId, updates);
1067
+ if (!result.success) {
1068
+ return res.status(404).json({ success: false, error: result.error || 'contact_not_found' });
1069
+ }
1070
+
1071
+ const stored = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: true })
1072
+ .find(c => c.id === contactId);
1073
+ return res.json({ success: true, contact: stored ? toDashboardContact(stored) : toDashboardContact(result.contact) });
1074
+ });
1075
+
1076
+ router.delete('/contacts/:contactId', (req, res) => {
1077
+ const contactId = sanitizeString(req.params.contactId, 120);
1078
+ if (!contactId) {
1079
+ return res.status(400).json({ success: false, error: 'contact_id_required' });
1080
+ }
1081
+
1082
+ const result = context.tokenStore.removeContact(contactId);
1083
+ if (!result.success) {
1084
+ return res.status(404).json({ success: false, error: result.error || 'contact_not_found' });
1085
+ }
1086
+
1087
+ return res.json({ success: true, contact: toDashboardContact(result.contact) });
1088
+ });
1089
+
1090
+ router.post('/contacts/:contactId/call', async (req, res) => {
1091
+ const contactId = sanitizeString(req.params.contactId, 120);
1092
+ if (!contactId) {
1093
+ return res.status(400).json({ success: false, error: 'contact_id_required' });
1094
+ }
1095
+
1096
+ const body = req.body || {};
1097
+ const message = sanitizeString(body.message || body.msg || '', 10000);
1098
+ const timeoutSeconds = Math.max(5, Math.min(300, Number.parseInt(String(body.timeout_seconds || body.timeoutSeconds || '60'), 10) || 60));
1099
+ if (!message) {
1100
+ return res.status(400).json({ success: false, error: 'message_required', message: 'Message is required' });
1101
+ }
1102
+
1103
+ const contact = context.tokenStore.getContact(contactId);
1104
+ if (!contact) {
1105
+ return res.status(404).json({ success: false, error: 'contact_not_found' });
1106
+ }
1107
+ if (!contact.host || !contact.token) {
1108
+ return res.status(400).json({ success: false, error: 'contact_not_callable', message: 'This contact has no callable A2A endpoint stored.' });
1109
+ }
1110
+
1111
+ const conversationId = ConversationStore.generateConversationId();
1112
+ const client = new A2AClient({
1113
+ caller: {
1114
+ name: context.agentContext?.name || 'Dashboard',
1115
+ owner: context.agentContext?.owner || 'Agent Owner',
1116
+ instance: context.config.getAgent?.().hostname || null
1117
+ }
1118
+ });
1119
+
1120
+ // Track in local conversation DB (if enabled).
1121
+ if (context.convStore) {
1122
+ try {
1123
+ context.convStore.startConversation({
1124
+ id: conversationId,
1125
+ contactId: contact.id,
1126
+ contactName: contact.name || contact.host,
1127
+ tokenId: null,
1128
+ direction: 'outbound'
1129
+ });
1130
+ context.convStore.addMessage(conversationId, {
1131
+ direction: 'outbound',
1132
+ role: 'user',
1133
+ content: message
1134
+ });
1135
+ } catch (err) {
1136
+ // Best effort; call should still go through.
1137
+ }
1138
+ }
1139
+
1140
+ const url = `a2a://${contact.host}/${contact.token}`;
1141
+ try {
1142
+ const result = await client.call(url, message, { conversationId, timeoutSeconds });
1143
+ const previousStatus = String(contact.status || '');
1144
+ context.tokenStore.updateContactStatus(contact.id, 'online');
1145
+ if (context.eventStore && context.eventStore.isAvailable() && previousStatus !== 'online') {
1146
+ context.eventStore.emitEvent('contact.status.changed', {
1147
+ contact_id: contact.id,
1148
+ contact_name: contact.name || contact.host || null,
1149
+ previous_status: previousStatus || null,
1150
+ status: 'online'
1151
+ }, { contactId: contact.id });
1152
+ }
1153
+
1154
+ if (context.convStore) {
1155
+ try {
1156
+ context.convStore.addMessage(conversationId, {
1157
+ direction: 'inbound',
1158
+ role: 'assistant',
1159
+ content: String(result?.response || '')
1160
+ });
1161
+ // One-shot outbound dashboard calls should be considered concluded.
1162
+ await context.convStore.concludeConversation(conversationId, {});
1163
+ } catch (err) {
1164
+ // ignore
1165
+ }
1166
+ }
1167
+
1168
+ return res.json({
1169
+ success: true,
1170
+ conversation_id: conversationId,
1171
+ response: result?.response || '',
1172
+ remote_trace_id: result?.trace_id || null,
1173
+ remote_request_id: result?.request_id || null,
1174
+ can_continue: result?.can_continue !== false
1175
+ });
1176
+ } catch (err) {
1177
+ const previousStatus = String(contact.status || '');
1178
+ context.tokenStore.updateContactStatus(contact.id, 'offline', err.message);
1179
+ if (context.eventStore && context.eventStore.isAvailable() && previousStatus !== 'offline') {
1180
+ context.eventStore.emitEvent('contact.status.changed', {
1181
+ contact_id: contact.id,
1182
+ contact_name: contact.name || contact.host || null,
1183
+ previous_status: previousStatus || null,
1184
+ status: 'offline',
1185
+ reason: err.message || null
1186
+ }, { contactId: contact.id });
1187
+ }
1188
+ return res.status(502).json({
1189
+ success: false,
1190
+ error: 'contact_call_failed',
1191
+ message: err.message || 'Call failed'
1192
+ });
1193
+ }
1194
+ });
1195
+
1196
+ router.get('/contacts/:contactId/calls', (req, res) => {
1197
+ if (!context.convStore) {
1198
+ return res.json({ success: true, calls: [], message: 'Conversation storage not enabled' });
1199
+ }
1200
+
1201
+ const contactId = req.params.contactId;
1202
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: false });
1203
+ const contactIndex = buildContactIndex(contacts);
1204
+ const contact = contactIndex.byId.get(contactId);
1205
+ if (!contact) {
1206
+ return res.status(404).json({ success: false, error: 'contact_not_found' });
1207
+ }
1208
+
1209
+ const all = context.convStore.listConversations({
1210
+ limit: Number.parseInt(req.query.limit || '500', 10) || 500,
1211
+ includeMessages: false
1212
+ });
1213
+
1214
+ const calls = all
1215
+ .filter(conv => {
1216
+ const resolved = resolveConversationContact(conv, contactIndex);
1217
+ return resolved?.id === contact.id;
1218
+ })
1219
+ .sort((a, b) => String(b.last_message_at || '').localeCompare(String(a.last_message_at || '')))
1220
+ .map(conv => ({
1221
+ ...conv,
1222
+ contact
1223
+ }));
1224
+
1225
+ return res.json({ success: true, contact, calls });
1226
+ });
1227
+
1228
+ router.get('/calls', (req, res) => {
1229
+ if (!context.convStore) {
1230
+ return res.json({ success: true, calls: [], message: 'Conversation storage not enabled' });
1231
+ }
1232
+
1233
+ const limit = Number.parseInt(req.query.limit || '100', 10) || 100;
1234
+ const status = req.query.status || null;
1235
+ const calls = context.convStore.listConversations({
1236
+ limit: Math.min(500, Math.max(1, limit)),
1237
+ status,
1238
+ includeMessages: false
1239
+ });
1240
+
1241
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: false });
1242
+ const contactIndex = buildContactIndex(contacts);
1243
+ const enriched = calls.map(conv => ({
1244
+ ...conv,
1245
+ contact: resolveConversationContact(conv, contactIndex)
1246
+ }));
1247
+
1248
+ return res.json({ success: true, calls: enriched });
1249
+ });
1250
+
1251
+ router.get('/calls/:conversationId', (req, res) => {
1252
+ if (!context.convStore) {
1253
+ return res.status(404).json({
1254
+ success: false,
1255
+ error: 'conversation_storage_disabled'
1256
+ });
1257
+ }
1258
+
1259
+ const conversationId = req.params.conversationId;
1260
+ const contextData = context.convStore.getConversationContext(
1261
+ conversationId,
1262
+ Number.parseInt(req.query.messages || '30', 10) || 30
1263
+ );
1264
+ if (!contextData) {
1265
+ return res.status(404).json({ success: false, error: 'conversation_not_found' });
1266
+ }
1267
+
1268
+ const contacts = context.tokenStore.listContacts({ includeLinkedToken: false, includeSecrets: false });
1269
+ const contactIndex = buildContactIndex(contacts);
1270
+ const contact = resolveConversationContact({
1271
+ contact_name: contextData.contact
1272
+ }, contactIndex);
1273
+
1274
+ return res.json({ success: true, call: { ...contextData, contact } });
1275
+ });
1276
+
1277
+ router.get('/settings', (req, res) => {
1278
+ const cfg = context.config.getAll();
1279
+ const manifest = loadManifest();
1280
+ const configTiers = cfg.tiers || {};
1281
+ const manifestTiers = manifest.tiers || {};
1282
+ const tierIds = new Set([...Object.keys(configTiers), ...Object.keys(manifestTiers)]);
1283
+
1284
+ const tiers = Array.from(tierIds).sort().map(tierId => {
1285
+ const configTier = configTiers[tierId] || {};
1286
+ const manifestTier = manifestTiers[tierId] || {};
1287
+ return {
1288
+ id: tierId,
1289
+ name: configTier.name || tierId,
1290
+ description: configTier.description || '',
1291
+ capabilities: configTier.capabilities || [],
1292
+ allowed_tools: sanitizeStringArray(configTier.allowed_tools || [], 30, 80),
1293
+ topics: sanitizeStringArray(configTier.topics || []),
1294
+ goals: sanitizeStringArray(configTier.goals || []),
1295
+ examples: sanitizeStringArray(configTier.examples || [], 20, 120),
1296
+ manifest: {
1297
+ topics: manifestTier.topics || [],
1298
+ objectives: manifestTier.objectives || [],
1299
+ do_not_discuss: manifestTier.do_not_discuss || []
1300
+ }
1301
+ };
1302
+ });
1303
+
1304
+ res.json({
1305
+ success: true,
1306
+ onboarding_complete: context.config.isOnboarded(),
1307
+ defaults: cfg.defaults || {},
1308
+ agent: (() => { const { private_key, ...pub } = cfg.agent || {}; return pub; })(),
1309
+ tiers,
1310
+ manifest: {
1311
+ never_disclose: manifest.never_disclose || [],
1312
+ personality_notes: manifest.personality_notes || '',
1313
+ updated_at: manifest.updated_at || null
1314
+ }
1315
+ });
1316
+ });
1317
+
1318
+ router.put('/settings/tiers/:tierId', (req, res) => {
1319
+ const tierId = normalizeTierId(req.params.tierId);
1320
+ if (!tierId) {
1321
+ return res.status(400).json({ success: false, error: 'invalid_tier_id' });
1322
+ }
1323
+
1324
+ const body = req.body || {};
1325
+ const update = {};
1326
+ if (body.name !== undefined) update.name = sanitizeString(body.name, 120);
1327
+ if (body.description !== undefined) update.description = sanitizeString(body.description, 300);
1328
+ if (body.capabilities !== undefined) update.capabilities = sanitizeStringArray(body.capabilities, 100, 120);
1329
+ if (body.allowed_tools !== undefined) update.allowed_tools = sanitizeStringArray(body.allowed_tools, 30, 80);
1330
+ if (body.examples !== undefined) update.examples = sanitizeStringArray(body.examples, 20, 120);
1331
+ if (body.topics !== undefined) update.topics = sanitizeStringArray(body.topics, 200, 160);
1332
+ if (body.goals !== undefined) update.goals = sanitizeStringArray(body.goals, 200, 160);
1333
+
1334
+ try {
1335
+ context.config.setTier(tierId, update);
1336
+ } catch (err) {
1337
+ return res.status(400).json({
1338
+ success: false,
1339
+ error: 'invalid_tier_config',
1340
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1341
+ message: err.message
1342
+ });
1343
+ }
1344
+
1345
+ if (body.manifest) {
1346
+ const manifest = loadManifest();
1347
+ manifest.tiers = manifest.tiers || {};
1348
+ manifest.tiers[tierId] = {
1349
+ topics: parseTopicObjects(body.manifest.topics),
1350
+ objectives: parseTopicObjects(body.manifest.objectives),
1351
+ do_not_discuss: parseTopicObjects(body.manifest.do_not_discuss)
1352
+ };
1353
+ saveManifest(manifest);
1354
+ }
1355
+
1356
+ return res.json({ success: true, tier_id: tierId });
1357
+ });
1358
+
1359
+ router.post('/settings/tiers', (req, res) => {
1360
+ const body = req.body || {};
1361
+ const tierId = normalizeTierId(body.id || body.tier_id);
1362
+ if (!tierId) {
1363
+ return res.status(400).json({ success: false, error: 'tier_id_required' });
1364
+ }
1365
+
1366
+ const cfg = context.config.getAll();
1367
+ if (cfg.tiers && cfg.tiers[tierId]) {
1368
+ return res.status(409).json({ success: false, error: 'tier_exists' });
1369
+ }
1370
+
1371
+ const copyFrom = normalizeTierId(body.copy_from || '');
1372
+ if (copyFrom && cfg.tiers && cfg.tiers[copyFrom]) {
1373
+ try {
1374
+ context.config.setTier(tierId, { ...cfg.tiers[copyFrom] });
1375
+ } catch (err) {
1376
+ return res.status(400).json({
1377
+ success: false,
1378
+ error: 'invalid_tier_config',
1379
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1380
+ message: err.message
1381
+ });
1382
+ }
1383
+ } else {
1384
+ try {
1385
+ context.config.setTier(tierId, {
1386
+ name: sanitizeString(body.name || tierId, 120),
1387
+ description: sanitizeString(body.description || 'Custom tier', 300),
1388
+ capabilities: sanitizeStringArray(body.capabilities || []),
1389
+ allowed_tools: sanitizeStringArray(body.allowed_tools || [], 30, 80),
1390
+ topics: sanitizeStringArray(body.topics || []),
1391
+ goals: sanitizeStringArray(body.goals || []),
1392
+ examples: sanitizeStringArray(body.examples || [], 20, 120)
1393
+ });
1394
+ } catch (err) {
1395
+ return res.status(400).json({
1396
+ success: false,
1397
+ error: 'invalid_tier_config',
1398
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1399
+ message: err.message
1400
+ });
1401
+ }
1402
+ }
1403
+
1404
+ return res.json({ success: true, tier_id: tierId });
1405
+ });
1406
+
1407
+ router.post('/settings/tiers/:toTier/copy-from/:fromTier', (req, res) => {
1408
+ const toTier = normalizeTierId(req.params.toTier);
1409
+ const fromTier = normalizeTierId(req.params.fromTier);
1410
+ if (!toTier || !fromTier) {
1411
+ return res.status(400).json({ success: false, error: 'invalid_tier_ids' });
1412
+ }
1413
+
1414
+ const cfg = context.config.getAll();
1415
+ if (!cfg.tiers || !cfg.tiers[fromTier]) {
1416
+ return res.status(404).json({ success: false, error: 'source_tier_not_found' });
1417
+ }
1418
+
1419
+ try {
1420
+ context.config.setTier(toTier, { ...cfg.tiers[fromTier] });
1421
+ } catch (err) {
1422
+ return res.status(400).json({
1423
+ success: false,
1424
+ error: 'invalid_tier_config',
1425
+ code: err.code || 'A2A_CONFIG_INVALID_TIER_CONFIG',
1426
+ message: err.message
1427
+ });
1428
+ }
1429
+
1430
+ const manifest = loadManifest();
1431
+ if (manifest.tiers && manifest.tiers[fromTier]) {
1432
+ manifest.tiers[toTier] = JSON.parse(JSON.stringify(manifest.tiers[fromTier]));
1433
+ saveManifest(manifest);
1434
+ }
1435
+
1436
+ return res.json({ success: true, from_tier: fromTier, to_tier: toTier });
1437
+ });
1438
+
1439
+ router.put('/settings/defaults', (req, res) => {
1440
+ context.config.setDefaults(req.body || {});
1441
+ return res.json({ success: true });
1442
+ });
1443
+
1444
+ router.put('/settings/agent', (req, res) => {
1445
+ context.config.setAgent(req.body || {});
1446
+ return res.json({ success: true });
1447
+ });
1448
+
1449
+ router.put('/settings/manifest', (req, res) => {
1450
+ const body = req.body || {};
1451
+ const manifest = loadManifest();
1452
+ if (body.never_disclose !== undefined) {
1453
+ manifest.never_disclose = sanitizeStringArray(body.never_disclose, 100, 200);
1454
+ }
1455
+ if (body.personality_notes !== undefined) {
1456
+ manifest.personality_notes = sanitizeString(body.personality_notes, 2000);
1457
+ }
1458
+ saveManifest(manifest);
1459
+ return res.json({ success: true });
1460
+ });
1461
+
1462
+ router.get('/invites', (req, res) => {
1463
+ const includeRevoked = String(req.query.include_revoked || 'false') === 'true';
1464
+ const tokens = context.tokenStore.list(includeRevoked);
1465
+ return res.json({ success: true, invites: tokens });
1466
+ });
1467
+
1468
+ router.post('/invites', async (req, res) => {
1469
+ const body = req.body || {};
1470
+ const cfg = context.config.getAll();
1471
+ const tierId = normalizeTierId(body.tier || body.permissions || 'public') || 'public';
1472
+ const tier = (cfg.tiers && cfg.tiers[tierId]) ? cfg.tiers[tierId] : {};
1473
+
1474
+ const name = sanitizeString(body.name || tier.name || 'Agent Invite', 120);
1475
+ const owner = sanitizeString(body.owner || '', 120) || null;
1476
+ const expires = sanitizeString(body.expires || cfg.defaults?.expiration || '7d', 20);
1477
+ const disclosure = sanitizeString(body.disclosure || tier.disclosure || 'minimal', 40);
1478
+ const notify = sanitizeString(body.notify || 'all', 20);
1479
+ const maxCalls = body.max_calls === null || body.max_calls === 'unlimited'
1480
+ ? null
1481
+ : Math.max(1, Number.parseInt(body.max_calls || cfg.defaults?.maxCalls || 100, 10) || 100);
1482
+
1483
+ const allowedTopics = sanitizeStringArray(body.topics || tier.topics || []);
1484
+ const allowedGoals = sanitizeStringArray(body.goals || tier.goals || []);
1485
+ const allowedTools = sanitizeStringArray(body.tools || body.allowed_tools || tier.allowed_tools || [], 30, 80);
1486
+ const { token, record } = context.tokenStore.create({
1487
+ name,
1488
+ owner,
1489
+ expires,
1490
+ permissions: tierId,
1491
+ disclosure,
1492
+ notify,
1493
+ maxCalls,
1494
+ allowedTopics: allowedTopics.length ? allowedTopics : null,
1495
+ allowedGoals: allowedGoals.length ? allowedGoals : null,
1496
+ allowedTools: allowedTools.length ? allowedTools : null,
1497
+ tierSettings: {
1498
+ tierId,
1499
+ ...tier
1500
+ }
1501
+ });
1502
+
1503
+ const resolvedHost = await resolveInviteHost({
1504
+ config: context.config,
1505
+ fallbackHost: req.headers.host || process.env.HOSTNAME || 'localhost',
1506
+ defaultPort: process.env.PORT || process.env.A2A_PORT || 3001,
1507
+ refreshExternalIp: true
1508
+ });
1509
+ const host = resolvedHost.host;
1510
+ const inviteUrl = `a2a://${host}/${token}`;
1511
+ const expiresText = record.expires_at || 'never';
1512
+ const message = formatInviteMessage({
1513
+ owner,
1514
+ agentName: name,
1515
+ inviteUrl,
1516
+ topics: record.allowed_topics || [],
1517
+ goals: record.allowed_goals || [],
1518
+ tools: record.allowed_tools || [],
1519
+ expiresText
1520
+ });
1521
+
1522
+ return res.json({
1523
+ success: true,
1524
+ invite_url: inviteUrl,
1525
+ invite_message: message,
1526
+ warnings: resolvedHost.warnings || [],
1527
+ token: record
1528
+ });
1529
+ });
1530
+
1531
+ router.post('/invites/:tokenId/revoke', (req, res) => {
1532
+ const tokenId = sanitizeString(req.params.tokenId, 80);
1533
+ if (!tokenId) {
1534
+ return res.status(400).json({ success: false, error: 'token_id_required' });
1535
+ }
1536
+
1537
+ const result = context.tokenStore.revoke(tokenId);
1538
+ if (!result.success) {
1539
+ return res.status(404).json({ success: false, error: result.error || 'token_not_found' });
1540
+ }
1541
+
1542
+ return res.json({ success: true, token: result.record });
1543
+ });
1544
+
1545
+ return router;
1546
+ }
1547
+
1548
+ function createDashboardUiRouter(options = {}) {
1549
+ const router = express.Router();
1550
+ const context = buildContext(options);
1551
+ const ensureDashboardAccess = makeEnsureDashboardAccess(context);
1552
+ router.use(ensureDashboardAccess);
1553
+
1554
+ router.use((req, res, next) => {
1555
+ const rawPath = String(req.originalUrl || '').split('?')[0];
1556
+ if (rawPath === req.baseUrl) {
1557
+ return res.redirect(302, `${req.baseUrl}/`);
1558
+ }
1559
+ return next();
1560
+ });
1561
+
1562
+ router.get('/', (req, res) => {
1563
+ const indexPath = path.join(context.staticDir, 'index.html');
1564
+ if (!fs.existsSync(indexPath)) {
1565
+ return res.status(500).send('Dashboard UI missing');
1566
+ }
1567
+ return res.sendFile(indexPath);
1568
+ });
1569
+
1570
+ router.use(express.static(context.staticDir, { index: false }));
1571
+ return router;
1572
+ }
1573
+
1574
+ module.exports = {
1575
+ createDashboardApiRouter,
1576
+ createDashboardUiRouter,
1577
+ DASHBOARD_STATIC_DIR
1578
+ };